-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
84 lines (76 loc) · 2.22 KB
/
index.ts
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { dirname as _dirname } from "path";
export type TreeNode = string;
export interface TreeEdges {
[dirname: string]: TreeNode[];
}
export interface PathItem {
path: string;
type: "file" | "dir";
}
export interface Data {
[key: string]: PathItem;
}
export interface TreeData {
nodes: TreeNode[];
edges: TreeEdges;
data: Data;
}
/**
* vscodeのファイルツリーと同じ順序にならべる.
*/
export const compareBasename = (a: PathItem, b: PathItem): 0 | -1 | 1 => {
if (a.type === "dir" && b.type === "file") {
return -1;
}
if (a.type === "file" && b.type === "dir") {
return 1;
}
if (a.path.toLowerCase() < b.path.toLowerCase()) {
return -1;
}
if (a.path.toLowerCase() > b.path.toLowerCase()) {
return 1;
}
return 0;
};
export const getParentDirectories = (pathItem: PathItem): string[] => {
const rootDirPath = pathItem.type === "file" ? _dirname(pathItem.path) : pathItem.path;
const dirs: Set<string> = new Set([rootDirPath]);
const _getDir = (_path: string): string[] => {
const _parentDirPath = _dirname(_path);
if (_parentDirPath === "." || _parentDirPath === "/") {
return Array.from(dirs);
}
dirs.add(_parentDirPath);
return _getDir(_parentDirPath);
};
return _getDir(rootDirPath);
};
export const collect = (pathItems: PathItem[]): TreeData => {
const directoryItems: PathItem[] = Array.from(new Set(pathItems.map(getParentDirectories).flat())).map((path) => ({
type: "dir",
path,
}));
const fileItems = pathItems.filter((item) => item.type === "file");
const allItems = directoryItems.concat(fileItems).sort(compareBasename);
const nodes = allItems.map((item) => `${item.type}:${item.path}`);
const edges = allItems.reduce<TreeData["edges"]>((allEdges, node) => {
const parentDirname = _dirname(node.path);
const key = `dir:${parentDirname}`;
if (allEdges[key]) {
allEdges[key].push(`${node.type}:${node.path}`);
} else {
allEdges[key] = [`${node.type}:${node.path}`];
}
return allEdges;
}, {});
const data: Data = allItems.reduce<TreeData["data"]>((allData, item) => {
allData[`${item.type}:${item.path}`] = item;
return allData;
}, {});
return {
nodes,
edges,
data,
};
};