62 lines
1.2 KiB
TypeScript
62 lines
1.2 KiB
TypeScript
import * as path from '@std/path';
|
|
|
|
export type WALK_OPTIONS<T> = {
|
|
max_depth?: number;
|
|
depth?: number;
|
|
index?: number;
|
|
filter?: (entry: WALK_ENTRY<T>) => boolean;
|
|
sort?: (a: WALK_ENTRY<T>, b: WALK_ENTRY<T>) => number;
|
|
};
|
|
|
|
export type WALK_ENTRY<T> = {
|
|
path: string;
|
|
info: Deno.FileInfo;
|
|
depth: number;
|
|
load: () => T;
|
|
};
|
|
|
|
export async function* walk<T>(
|
|
root: string | URL,
|
|
{
|
|
depth = 0,
|
|
filter = undefined,
|
|
sort = undefined
|
|
}: WALK_OPTIONS<T> = {}
|
|
): AsyncIterableIterator<WALK_ENTRY<T>> {
|
|
const root_path = typeof root === 'string' ? path.resolve(root) : path.resolve(path.fromFileUrl(root));
|
|
|
|
const entries: WALK_ENTRY<T>[] = [];
|
|
|
|
for await (const dir_entry of Deno.readDir(root_path)) {
|
|
const full_path = path.join(root, dir_entry.name);
|
|
const info = await Deno.lstat(full_path);
|
|
const entry = {
|
|
path: full_path,
|
|
info,
|
|
depth,
|
|
load: function () {
|
|
return JSON.parse(Deno.readTextFileSync(this.path)) as T;
|
|
}
|
|
};
|
|
|
|
entries.push(entry);
|
|
}
|
|
|
|
if (sort) {
|
|
entries.sort(sort);
|
|
}
|
|
|
|
for (const entry of entries) {
|
|
if (!filter || filter(entry)) {
|
|
yield entry;
|
|
}
|
|
|
|
if (entry.info.isDirectory) {
|
|
yield* walk(entry.path, {
|
|
depth: depth + 1,
|
|
filter,
|
|
sort
|
|
});
|
|
}
|
|
}
|
|
}
|