-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
opendir.ts
89 lines (69 loc) Β· 2.06 KB
/
opendir.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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import {NoParamCallback} from 'fs';
import {Dir, DirentNoPath, FakeFS} from '../FakeFS';
import * as errors from '../errors';
import {Filename, Path} from '../path';
export type CustomDirOptions = {
onClose?: () => void;
};
export class CustomDir<P extends Path> implements Dir<P> {
constructor(
public readonly path: P,
private readonly nextDirent: () => DirentNoPath | null,
private readonly opts: CustomDirOptions = {},
) {}
public closed: boolean = false;
throwIfClosed() {
if (this.closed) {
throw errors.ERR_DIR_CLOSED();
}
}
async * [Symbol.asyncIterator]() {
try {
let dirent: DirentNoPath | null;
// eslint-disable-next-line no-cond-assign
while ((dirent = await this.read()) !== null) {
yield dirent;
}
} finally {
await this.close();
}
}
read(): Promise<DirentNoPath>;
read(cb: (err: NodeJS.ErrnoException | null, dirent: DirentNoPath | null) => void): void;
read(cb?: (err: NodeJS.ErrnoException | null, dirent: DirentNoPath | null) => void) {
const dirent = this.readSync();
if (typeof cb !== `undefined`)
return cb(null, dirent);
return Promise.resolve(dirent);
}
readSync() {
this.throwIfClosed();
return this.nextDirent();
}
close(): Promise<void>;
close(cb: NoParamCallback): void;
close(cb?: NoParamCallback) {
this.closeSync();
if (typeof cb !== `undefined`)
return cb(null);
return Promise.resolve();
}
closeSync() {
this.throwIfClosed();
this.opts.onClose?.();
this.closed = true;
}
}
export function opendir<P extends Path>(fakeFs: FakeFS<P>, path: P, entries: Array<Filename>, opts?: CustomDirOptions) {
const nextDirent = () => {
const filename = entries.shift();
if (typeof filename === `undefined`)
return null;
const entryPath = fakeFs.pathUtils.join(path, filename);
return Object.assign(fakeFs.statSync(entryPath), {
name: filename,
path: undefined,
});
};
return new CustomDir(path, nextDirent, opts);
}