UNPKG

counterfact

Version:

Generate a TypeScript-based mock server from an OpenAPI spec in seconds — with stateful routes, hot reload, and REPL support.

47 lines (46 loc) 1.92 kB
import { existsSync } from "node:fs"; import fs from "node:fs/promises"; /* eslint-disable security/detect-non-literal-fs-filename -- discovery walks directories rooted at basePath and uses Dirent-provided names. */ import { toForwardSlashPath, pathJoin } from "../util/forward-slash-path.js"; import { escapePathForWindows } from "../util/windows-escape.js"; const JS_EXTENSIONS = new Set(["cjs", "cts", "js", "mjs", "mts", "ts"]); /** * Recursively discovers JavaScript/TypeScript source files under a base * directory. * * Only files with one of the following extensions are returned: * `js`, `mjs`, `cjs`, `ts`, `mts`, `cts`. */ export class FileDiscovery { basePath; constructor(basePath) { this.basePath = toForwardSlashPath(basePath); } /** * Returns an array of absolute file paths for all JS/TS files found * recursively under `basePath/directory`. * * @param directory - Sub-directory relative to `basePath` to start from. * Defaults to `""` (the base path itself). * @throws When `basePath/directory` does not exist. */ async findFiles(directory = "") { const fullDir = pathJoin(this.basePath, directory); if (!existsSync(fullDir)) { throw new Error(`Directory does not exist ${fullDir}`); } const entries = await fs.readdir(fullDir, { withFileTypes: true }); const results = await Promise.all(entries.map(async (entry) => { if (entry.isDirectory()) { return this.findFiles(pathJoin(directory, entry.name)); } const extension = entry.name.split(".").at(-1); if (!JS_EXTENSIONS.has(extension ?? "")) { return []; } const fullPath = pathJoin(this.basePath, directory, entry.name); return [escapePathForWindows(fullPath)]; })); return results.flat(); } }