@nestia/sdk
Version:
Nestia SDK and Swagger generator
67 lines (57 loc) • 2.13 kB
text/typescript
import fs from "fs";
import glob from "glob";
import path from "path";
export namespace SourceFinder {
interface IProps {
exclude?: string[];
include: string[];
filter: (location: string) => Promise<boolean>;
}
export const find = async (props: IProps): Promise<string[]> => {
const dict: Set<string> = new Set();
await emplace(props.filter)(props.include)((str) => dict.add(str));
if (props.exclude?.length)
await emplace(props.filter)(props.exclude)((str) => dict.delete(str));
return [...dict];
};
const emplace =
(filter: (file: string) => Promise<boolean>) =>
(input: string[]) =>
async (closure: (location: string) => void): Promise<void> => {
for (const pattern of input) {
if (_Is_file(pattern)) {
closure(path.resolve(pattern));
continue;
}
for (const file of await _Glob(pattern)) {
const stats: fs.Stats = await fs.promises.stat(file);
if (stats.isDirectory() === true)
await iterate(filter)(closure)(file);
else if (stats.isFile() && (await filter(file))) closure(file);
}
}
};
const iterate =
(filter: (location: string) => Promise<boolean>) =>
(closure: (location: string) => void) =>
async (location: string): Promise<void> => {
const directory: string[] = await fs.promises.readdir(location);
for (const file of directory) {
const next: string = path.resolve(`${location}/${file}`);
const stats: fs.Stats = await fs.promises.stat(next);
if (stats.isDirectory() === true) await iterate(filter)(closure)(next);
else if (stats.isFile() && (await filter(next))) closure(next);
}
};
const _Glob = (pattern: string): Promise<string[]> =>
new Promise((resolve, reject) => {
glob(pattern, (err, matches) => {
if (err) reject(err);
else resolve(matches.map((str) => path.resolve(str)));
});
});
const _Is_file = (pattern: string): boolean =>
pattern.endsWith(".ts") &&
!pattern.endsWith(".d.ts") &&
fs.existsSync(pattern);
}