Press n or j to go to the next uncovered block, b, p or k for the previous block.
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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | 1x 1x 1x 1x 1x 23x 23x 23x 23x 23x 18x 18x 18x 18x 18x 13x 13x 13x 13x 11x 13x 13x 13x 13x 13x 18x 30x 17x 17x 30x 18x 18x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 25x 25x 25x 5x 5x 5x 5x 5x 5x 5x 5x 25x 20x 20x 4x 4x 4x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 25x 10x 10x | import fs from "node:fs/promises"; import { readdir } from "node:fs/promises"; import path from "node:path"; import { getLogger } from "./log"; import { directoryExists, fileExists } from "./plainstack-fs"; type FileModule<T> = { defaultExport?: T; namedExports: Record<string, T>; filename: string; extension: string; absolutePath: string; relativePath: string; }; export async function loadModule<T>( filePath: string, load: (module: unknown) => Promise<T>, ): Promise<Pick<FileModule<T>, "defaultExport" | "namedExports"> | undefined> { if (!(await fileExists(filePath))) return undefined; const module = await import(filePath); const result: { defaultExport?: T; namedExports: Record<string, T> } = { namedExports: {}, }; // handle default export if ("default" in module) { const defaultExport = module.default; if ( defaultExport && typeof defaultExport === "object" && "default" in defaultExport ) { result.defaultExport = await load(defaultExport.default); } else { result.defaultExport = await load(defaultExport); } } // handle named exports for (const [key, value] of Object.entries(module)) { if (key !== "default") { result.namedExports[key] = await load(value); } } return result; } export async function loadModulesfromDir<T>( baseDir: string, load: (module: unknown) => Promise<T>, extensions: string[] = [".ts", ".tsx"], currentDir: string = baseDir, ): Promise<FileModule<T>[]> { const modules: FileModule<T>[] = []; const log = getLogger("manifest"); if (!(await directoryExists(currentDir))) { log.debug(`directory ${currentDir} does not exist`); return []; } const files = await readdir(currentDir); log.debug(`found ${files.length} files in ${currentDir}`); for (const file of files) { const absolutePath = path.join(currentDir, file); const stat = await fs.stat(absolutePath); if (stat.isDirectory()) { log.debug(`found directory: ${absolutePath}`); const subModules = await loadModulesfromDir( baseDir, load, extensions, absolutePath, ); modules.push(...subModules); } else if (stat.isFile()) { log.debug(`found file: ${absolutePath}`); if (!extensions.includes(path.extname(file))) { log.debug(`skipping file ${absolutePath} with unsupported extension`); continue; } const relativePath = path.relative(baseDir, absolutePath); const result = await loadModule(absolutePath, load); if (!result) continue; modules.push({ defaultExport: result.defaultExport, namedExports: result.namedExports, filename: path.parse(file).name, extension: path.extname(file), absolutePath, relativePath, }); } } return modules; } |