-
-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathfile-discovery.ts
More file actions
60 lines (47 loc) · 1.73 KB
/
file-discovery.ts
File metadata and controls
60 lines (47 loc) · 1.73 KB
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
import { existsSync } from "node:fs";
import fs from "node:fs/promises";
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 {
private readonly basePath: string;
public constructor(basePath: string) {
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.
*/
public async findFiles(directory = ""): Promise<string[]> {
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();
}
}