Surge_by_SukkaW/Build/lib/tree-dir.ts

70 lines
1.8 KiB
TypeScript

import fsp from 'node:fs/promises';
import { sep } from 'node:path';
import type { VoidOrVoidArray } from './misc';
// eslint-disable-next-line sukka/no-export-const-enum -- TODO: fix this in the future
export const enum TreeFileType {
FILE = 1,
DIRECTORY = 2
}
interface TreeFile {
type: TreeFileType.FILE,
name: string,
path: string
}
interface TreeDirectoryType {
type: TreeFileType.DIRECTORY,
name: string,
path: string,
children: TreeTypeArray
}
export type TreeType = TreeDirectoryType | TreeFile;
export type TreeTypeArray = TreeType[];
export async function treeDir(rootPath: string): Promise<TreeTypeArray> {
const tree: TreeTypeArray = [];
const promises: Array<Promise<VoidOrVoidArray>> = [];
const walk = async (dir: string, node: TreeTypeArray, dirRelativeToRoot = ''): Promise<VoidOrVoidArray> => {
for await (const child of await fsp.opendir(dir)) {
// Ignore hidden files
if (child.name[0] === '.' || child.name === 'CNAME') {
continue;
}
const childFullPath = child.parentPath + sep + child.name;
const childRelativeToRoot = dirRelativeToRoot + sep + child.name;
if (child.isDirectory()) {
const newNode: TreeDirectoryType = {
type: TreeFileType.DIRECTORY,
name: child.name,
path: childRelativeToRoot,
children: []
};
node.push(newNode);
promises.push(walk(childFullPath, newNode.children, childRelativeToRoot));
continue;
}
if (child.isFile()) {
const newNode: TreeFile = {
type: TreeFileType.FILE,
name: child.name,
path: childRelativeToRoot
};
node.push(newNode);
continue;
}
}
};
await walk(rootPath, tree);
await Promise.all(promises);
return tree;
}