-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
// SPDX-FileCopyrightText: 2024 Shota FUJI <pockawoooh@gmail.com>
//
// SPDX-License-Identifier: Apache-2.0
import type { FileSystemWriter } from "./interface.ts";
const enum NodeType {
File,
Directory,
}
function nodeTypeToString(nodeType: NodeType): string {
switch (nodeType) {
case NodeType.File:
return "file";
case NodeType.Directory:
return "directory";
}
}
const SEP = "/";
/**
* Wraps the given FileSystem Writer and returns a new FileSystem Writer
* that checks tree structure so there won't be a directory and a file
* having same name.
*
* If you're writing to native file system, you won't need this function
* as the native file system validates using its own constraints.
*/
export function validateTree(childWriter: FileSystemWriter): FileSystemWriter {
const nodes = new Map<string, NodeType>();
return {
write(path, content) {
setNodeTypeRecur(path, NodeType.File, nodes);
return childWriter.write(path, content);
},
};
}
function setNodeTypeRecur(
path: readonly string[],
nodeType: NodeType,
map: Map<string, NodeType>,
): void {
if (path.length === 0) {
return;
}
const key = path.join(SEP);
const found = map.get(key);
if (typeof found !== "undefined" && found !== nodeType) {
const ns = nodeTypeToString(nodeType);
const fs = nodeTypeToString(found);
throw new Error(
`Attempt to write a ${ns} at "${key}", but there already is a ${fs}.`,
);
}
map.set(key, nodeType);
return setNodeTypeRecur(path.slice(0, -1), NodeType.Directory, map);
}