tree-dir.ts 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import fsp from 'fs/promises';
  2. import { sep, relative } from 'path';
  3. interface TreeFileType {
  4. type: 'file',
  5. name: string,
  6. path: string
  7. }
  8. interface TreeDirectoryType {
  9. type: 'directory',
  10. name: string,
  11. path: string,
  12. children: TreeTypeArray
  13. }
  14. export type TreeType = TreeDirectoryType | TreeFileType;
  15. export type TreeTypeArray = TreeType[];
  16. type VoidOrVoidArray = void | VoidOrVoidArray[];
  17. export const treeDir = async (rootPath: string): Promise<TreeTypeArray> => {
  18. const tree: TreeTypeArray = [];
  19. const walk = async (dir: string, node: TreeTypeArray): Promise<VoidOrVoidArray> => {
  20. const promises: Array<Promise<VoidOrVoidArray>> = [];
  21. for await (const child of await fsp.opendir(dir)) {
  22. const childFullPath = child.parentPath + sep + child.name;
  23. const childRelativeToRoot = relative(rootPath, childFullPath);
  24. if (child.isDirectory()) {
  25. const newNode: TreeDirectoryType = {
  26. type: 'directory',
  27. name: child.name,
  28. path: childRelativeToRoot,
  29. children: []
  30. };
  31. node.push(newNode);
  32. promises.push(walk(childFullPath, newNode.children));
  33. continue;
  34. }
  35. if (child.isFile()) {
  36. const newNode: TreeFileType = {
  37. type: 'file',
  38. name: child.name,
  39. path: childRelativeToRoot
  40. };
  41. node.push(newNode);
  42. continue;
  43. }
  44. }
  45. return Promise.all(promises);
  46. };
  47. await walk(rootPath, tree);
  48. return tree;
  49. };