tree-dir.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import fsp from 'node:fs/promises';
  2. import { sep } from 'node:path';
  3. // eslint-disable-next-line sukka/no-export-const-enum -- TODO: fix this in the future
  4. export const enum TreeFileType {
  5. FILE = 1,
  6. DIRECTORY = 2
  7. }
  8. interface TreeFile {
  9. type: TreeFileType.FILE,
  10. name: string,
  11. path: string
  12. }
  13. interface TreeDirectoryType {
  14. type: TreeFileType.DIRECTORY,
  15. name: string,
  16. path: string,
  17. children: TreeTypeArray
  18. }
  19. export type TreeType = TreeDirectoryType | TreeFile;
  20. export type TreeTypeArray = TreeType[];
  21. type VoidOrVoidArray = void | VoidOrVoidArray[];
  22. export async function treeDir(rootPath: string): Promise<TreeTypeArray> {
  23. const tree: TreeTypeArray = [];
  24. const walk = async (dir: string, node: TreeTypeArray, dirRelativeToRoot = ''): Promise<VoidOrVoidArray> => {
  25. const promises: Array<Promise<VoidOrVoidArray>> = [];
  26. for await (const child of await fsp.opendir(dir)) {
  27. // Ignore hidden files
  28. if (child.name[0] === '.' || child.name === 'CNAME') {
  29. continue;
  30. }
  31. const childFullPath = child.parentPath + sep + child.name;
  32. const childRelativeToRoot = dirRelativeToRoot + sep + child.name;
  33. if (child.isDirectory()) {
  34. const newNode: TreeDirectoryType = {
  35. type: TreeFileType.DIRECTORY,
  36. name: child.name,
  37. path: childRelativeToRoot,
  38. children: []
  39. };
  40. node.push(newNode);
  41. promises.push(walk(childFullPath, newNode.children, childRelativeToRoot));
  42. continue;
  43. }
  44. if (child.isFile()) {
  45. const newNode: TreeFile = {
  46. type: TreeFileType.FILE,
  47. name: child.name,
  48. path: childRelativeToRoot
  49. };
  50. node.push(newNode);
  51. continue;
  52. }
  53. }
  54. return Promise.all(promises);
  55. };
  56. await walk(rootPath, tree);
  57. return tree;
  58. }