-
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathfind-all.ts
43 lines (40 loc) · 1.35 KB
/
find-all.ts
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
import path from 'path';
import { promises as fs } from 'fs';
/**
* find all tsconfig.json files in dir
*
* @param {string} dir - path to dir (absolute or relative to cwd)
* @param {TSConfckFindAllOptions} options - options
* @returns {Promise<string[]>} list of absolute paths to all found tsconfig.json files
*/
export async function findAll(dir: string, options?: TSConfckFindAllOptions): Promise<string[]> {
const files = [];
for await (const tsconfigFile of findTSConfig(path.resolve(dir), options)) {
files.push(tsconfigFile);
}
return files;
}
async function* findTSConfig(
dir: string,
options?: TSConfckFindAllOptions,
visited: Set<string> = new Set<string>()
): AsyncGenerator<string> {
if (!visited.has(dir)) {
const dirents = await fs.readdir(dir, { withFileTypes: true });
for (const dirent of dirents) {
if (dirent.isDirectory() && (!options?.skip || !options.skip(dirent.name))) {
yield* findTSConfig(path.resolve(dir, dirent.name), options, visited);
} else if (dirent.isFile() && dirent.name === 'tsconfig.json') {
yield path.resolve(dir, dirent.name);
}
}
}
}
export interface TSConfckFindAllOptions {
/**
* helper to skip subdirectories when scanning for tsconfig.json
*
* eg ` dir => dir === 'node_modules' || dir === '.git'`
*/ // eslint-disable-next-line no-unused-vars
skip?: (dir: string) => boolean;
}