tiny-readdir 1.3.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +0 -3
- package/dist/index.d.ts +2 -8
- package/dist/index.js +60 -36
- package/dist/types.d.ts +9 -3
- package/dist/types.js +1 -2
- package/{LICENSE → license} +0 -0
- package/package.json +16 -26
- package/{README.md → readme.md} +0 -0
- package/src/index.ts +66 -43
- package/src/types.ts +12 -4
- package/test/index.js +100 -0
- package/tsconfig.json +1 -26
- package/.github/FUNDING.yml +0 -2
package/.editorconfig
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { Options, Result } from './types';
|
|
1
|
+
import type { Options, Result } from './types';
|
|
2
2
|
declare const readdir: (rootPath: string, options?: Options | undefined) => Promise<Result>;
|
|
3
|
-
|
|
4
|
-
default: typeof readdir;
|
|
5
|
-
}
|
|
6
|
-
declare namespace _default {
|
|
7
|
-
export type type = readdir;
|
|
8
|
-
}
|
|
9
|
-
export = _default;
|
|
3
|
+
export default readdir;
|
package/dist/index.js
CHANGED
|
@@ -1,74 +1,88 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/* IMPORT */
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import Limiter from 'promise-concurrency-limiter';
|
|
6
5
|
/* HELPERS */
|
|
7
|
-
const limiter = new
|
|
8
|
-
/*
|
|
6
|
+
const limiter = new Limiter({ concurrency: 500 });
|
|
7
|
+
/* MAIN */
|
|
9
8
|
const readdir = (rootPath, options) => {
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
const
|
|
9
|
+
const followSymlinks = options?.followSymlinks ?? false;
|
|
10
|
+
const maxDepth = options?.depth ?? Infinity;
|
|
11
|
+
const isIgnored = options?.ignore ?? (() => false);
|
|
12
|
+
const signal = options?.signal ?? { aborted: false };
|
|
13
|
+
const directories = [];
|
|
14
|
+
const files = [];
|
|
15
|
+
const symlinks = [];
|
|
16
|
+
const map = {};
|
|
17
|
+
const visited = new Set();
|
|
18
|
+
const resultEmpty = { directories: [], files: [], symlinks: [], map: {} };
|
|
19
|
+
const result = { directories, files, symlinks, map };
|
|
20
|
+
const handleDirectory = (dirmap, subPath, depth) => {
|
|
21
|
+
if (visited.has(subPath))
|
|
22
|
+
return;
|
|
23
|
+
dirmap.directories.push(subPath);
|
|
13
24
|
directories.push(subPath);
|
|
25
|
+
visited.add(subPath);
|
|
14
26
|
if (depth >= maxDepth)
|
|
15
27
|
return;
|
|
16
|
-
return limiter.add(() =>
|
|
28
|
+
return limiter.add(() => populateResultFromPath(subPath, depth + 1));
|
|
17
29
|
};
|
|
18
|
-
const handleFile = (subPath) => {
|
|
30
|
+
const handleFile = (dirmap, subPath) => {
|
|
31
|
+
if (visited.has(subPath))
|
|
32
|
+
return;
|
|
33
|
+
dirmap.files.push(subPath);
|
|
19
34
|
files.push(subPath);
|
|
35
|
+
visited.add(subPath);
|
|
20
36
|
};
|
|
21
|
-
const handleSymlink = (subPath, depth) => {
|
|
37
|
+
const handleSymlink = (dirmap, subPath, depth) => {
|
|
38
|
+
if (visited.has(subPath))
|
|
39
|
+
return;
|
|
40
|
+
dirmap.symlinks.push(subPath);
|
|
22
41
|
symlinks.push(subPath);
|
|
42
|
+
visited.add(subPath);
|
|
23
43
|
if (!followSymlinks)
|
|
24
44
|
return;
|
|
25
45
|
if (depth >= maxDepth)
|
|
26
46
|
return;
|
|
27
|
-
return limiter.add(
|
|
28
|
-
try {
|
|
29
|
-
const realPath = await fs.promises.realpath(subPath), stat = await fs.promises.stat(realPath);
|
|
30
|
-
await handleStat(realPath, stat, depth + 1);
|
|
31
|
-
}
|
|
32
|
-
catch (_a) { }
|
|
33
|
-
});
|
|
47
|
+
return limiter.add(() => populateResultFromSymlink(subPath, depth + 1));
|
|
34
48
|
};
|
|
35
|
-
const handleStat = (rootPath, stat, depth) => {
|
|
49
|
+
const handleStat = (dirmap, rootPath, stat, depth) => {
|
|
36
50
|
if (signal.aborted)
|
|
37
51
|
return;
|
|
38
52
|
if (isIgnored(rootPath))
|
|
39
53
|
return;
|
|
40
54
|
if (stat.isDirectory()) {
|
|
41
|
-
return handleDirectory(rootPath, depth);
|
|
55
|
+
return handleDirectory(dirmap, rootPath, depth);
|
|
42
56
|
}
|
|
43
57
|
else if (stat.isFile()) {
|
|
44
|
-
return handleFile(rootPath);
|
|
58
|
+
return handleFile(dirmap, rootPath);
|
|
45
59
|
}
|
|
46
60
|
else if (stat.isSymbolicLink()) {
|
|
47
|
-
return handleSymlink(rootPath, depth);
|
|
61
|
+
return handleSymlink(dirmap, rootPath, depth);
|
|
48
62
|
}
|
|
49
63
|
};
|
|
50
|
-
const handleDirent = (rootPath, dirent, depth) => {
|
|
64
|
+
const handleDirent = (dirmap, rootPath, dirent, depth) => {
|
|
51
65
|
if (signal.aborted)
|
|
52
66
|
return;
|
|
53
|
-
const subPath = path.
|
|
67
|
+
const subPath = `${rootPath}${path.sep}${dirent.name}`;
|
|
54
68
|
if (isIgnored(subPath))
|
|
55
69
|
return;
|
|
56
70
|
if (dirent.isDirectory()) {
|
|
57
|
-
return handleDirectory(subPath, depth);
|
|
71
|
+
return handleDirectory(dirmap, subPath, depth);
|
|
58
72
|
}
|
|
59
73
|
else if (dirent.isFile()) {
|
|
60
|
-
return handleFile(subPath);
|
|
74
|
+
return handleFile(dirmap, subPath);
|
|
61
75
|
}
|
|
62
76
|
else if (dirent.isSymbolicLink()) {
|
|
63
|
-
return handleSymlink(subPath, depth);
|
|
77
|
+
return handleSymlink(dirmap, subPath, depth);
|
|
64
78
|
}
|
|
65
79
|
};
|
|
66
|
-
const handleDirents = (rootPath, dirents, depth) => {
|
|
80
|
+
const handleDirents = (dirmap, rootPath, dirents, depth) => {
|
|
67
81
|
return Promise.all(dirents.map((dirent) => {
|
|
68
|
-
return handleDirent(rootPath, dirent, depth);
|
|
82
|
+
return handleDirent(dirmap, rootPath, dirent, depth);
|
|
69
83
|
}));
|
|
70
84
|
};
|
|
71
|
-
const
|
|
85
|
+
const populateResultFromPath = async (rootPath, depth) => {
|
|
72
86
|
if (signal.aborted)
|
|
73
87
|
return;
|
|
74
88
|
if (depth > maxDepth)
|
|
@@ -76,12 +90,24 @@ const readdir = (rootPath, options) => {
|
|
|
76
90
|
const dirents = await fs.promises.readdir(rootPath, { withFileTypes: true }).catch(() => []);
|
|
77
91
|
if (signal.aborted)
|
|
78
92
|
return;
|
|
93
|
+
const dirmap = map[rootPath] = { directories: [], files: [], symlinks: [] };
|
|
79
94
|
if (!dirents.length)
|
|
80
95
|
return;
|
|
81
|
-
await handleDirents(rootPath, dirents, depth);
|
|
96
|
+
await handleDirents(dirmap, rootPath, dirents, depth);
|
|
97
|
+
};
|
|
98
|
+
const populateResultFromSymlink = async (rootPath, depth) => {
|
|
99
|
+
try {
|
|
100
|
+
const realPath = await fs.promises.realpath(rootPath);
|
|
101
|
+
const stat = await fs.promises.stat(realPath);
|
|
102
|
+
const dirmap = map[rootPath] = { directories: [], files: [], symlinks: [] };
|
|
103
|
+
await handleStat(dirmap, realPath, stat, depth);
|
|
104
|
+
}
|
|
105
|
+
catch { }
|
|
82
106
|
};
|
|
83
107
|
const getResult = async (rootPath, depth = 1) => {
|
|
84
|
-
|
|
108
|
+
rootPath = path.normalize(rootPath);
|
|
109
|
+
visited.add(rootPath);
|
|
110
|
+
await populateResultFromPath(rootPath, depth);
|
|
85
111
|
if (signal.aborted)
|
|
86
112
|
return resultEmpty;
|
|
87
113
|
return result;
|
|
@@ -89,6 +115,4 @@ const readdir = (rootPath, options) => {
|
|
|
89
115
|
return getResult(rootPath);
|
|
90
116
|
};
|
|
91
117
|
/* EXPORT */
|
|
92
|
-
|
|
93
|
-
module.exports.default = readdir;
|
|
94
|
-
Object.defineProperty(module.exports, "__esModule", { value: true });
|
|
118
|
+
export default readdir;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare type Promisable<T> = T |
|
|
1
|
+
declare type Promisable<T> = Promise<T> | T;
|
|
2
2
|
declare type Options = {
|
|
3
3
|
depth?: number;
|
|
4
4
|
followSymlinks?: boolean;
|
|
@@ -7,9 +7,15 @@ declare type Options = {
|
|
|
7
7
|
aborted: boolean;
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
|
-
declare type
|
|
10
|
+
declare type ResultDirectory = {
|
|
11
11
|
directories: string[];
|
|
12
12
|
files: string[];
|
|
13
13
|
symlinks: string[];
|
|
14
14
|
};
|
|
15
|
-
|
|
15
|
+
declare type ResultDirectories = {
|
|
16
|
+
[path: string]: ResultDirectory;
|
|
17
|
+
};
|
|
18
|
+
declare type Result = ResultDirectory & {
|
|
19
|
+
map: ResultDirectories;
|
|
20
|
+
};
|
|
21
|
+
export type { Promisable, Options, ResultDirectory, ResultDirectories, Result };
|
package/dist/types.js
CHANGED
package/{LICENSE → license}
RENAMED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,26 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiny-readdir",
|
|
3
|
+
"repository": "github:fabiospampinato/tiny-readdir",
|
|
3
4
|
"description": "A simple promisified recursive readdir function.",
|
|
4
|
-
"version": "
|
|
5
|
+
"version": "2.0.0",
|
|
6
|
+
"type": "module",
|
|
5
7
|
"main": "dist/index.js",
|
|
6
|
-
"
|
|
8
|
+
"exports": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
7
10
|
"scripts": {
|
|
8
|
-
"clean": "
|
|
9
|
-
"compile": "
|
|
10
|
-
"compile:watch": "
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"url": "https://github.com/fabiospampinato/tiny-readdir/issues"
|
|
15
|
-
},
|
|
16
|
-
"license": "MIT",
|
|
17
|
-
"author": {
|
|
18
|
-
"name": "Fabio Spampinato",
|
|
19
|
-
"email": "spampinabio@gmail.com"
|
|
20
|
-
},
|
|
21
|
-
"repository": {
|
|
22
|
-
"type": "git",
|
|
23
|
-
"url": "https://github.com/fabiospampinato/tiny-readdir.git"
|
|
11
|
+
"clean": "tsex clean",
|
|
12
|
+
"compile": "tsex compile",
|
|
13
|
+
"compile:watch": "tsex compile --watch",
|
|
14
|
+
"test": "tsex test",
|
|
15
|
+
"test:watch": "tsex test --watch",
|
|
16
|
+
"prepublishOnly": "npm run clean && npm run compile && npm run test"
|
|
24
17
|
},
|
|
25
18
|
"keywords": [
|
|
26
19
|
"readdir",
|
|
@@ -29,16 +22,13 @@
|
|
|
29
22
|
"simple",
|
|
30
23
|
"tiny"
|
|
31
24
|
],
|
|
32
|
-
"engines": {
|
|
33
|
-
"node": ">= 10.12.0"
|
|
34
|
-
},
|
|
35
25
|
"dependencies": {
|
|
36
|
-
"promise-concurrency-limiter": "^
|
|
26
|
+
"promise-concurrency-limiter": "^2.0.0"
|
|
37
27
|
},
|
|
38
28
|
"devDependencies": {
|
|
39
|
-
"@types/node": "^
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"typescript
|
|
29
|
+
"@types/node": "^17.0.23",
|
|
30
|
+
"fava": "^0.0.6",
|
|
31
|
+
"tsex": "^1.1.1",
|
|
32
|
+
"typescript": "^4.6.3"
|
|
43
33
|
}
|
|
44
34
|
}
|
package/{README.md → readme.md}
RENAMED
|
File without changes
|
package/src/index.ts
CHANGED
|
@@ -1,69 +1,72 @@
|
|
|
1
1
|
|
|
2
2
|
/* IMPORT */
|
|
3
3
|
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
6
|
import Limiter from 'promise-concurrency-limiter';
|
|
7
|
-
import {Promisable, Options, Result} from './types';
|
|
7
|
+
import type {Promisable, Options, ResultDirectory, ResultDirectories, Result} from './types';
|
|
8
8
|
|
|
9
9
|
/* HELPERS */
|
|
10
10
|
|
|
11
11
|
const limiter = new Limiter ({ concurrency: 500 });
|
|
12
12
|
|
|
13
|
-
/*
|
|
13
|
+
/* MAIN */
|
|
14
14
|
|
|
15
15
|
const readdir = ( rootPath: string, options?: Options ): Promise<Result> => {
|
|
16
16
|
|
|
17
|
-
const followSymlinks = options?.followSymlinks ?? false
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
const followSymlinks = options?.followSymlinks ?? false;
|
|
18
|
+
const maxDepth = options?.depth ?? Infinity;
|
|
19
|
+
const isIgnored = options?.ignore ?? (() => false);
|
|
20
|
+
const signal = options?.signal ?? { aborted: false };
|
|
21
|
+
const directories: string[] = [];
|
|
22
|
+
const files: string[] = [];
|
|
23
|
+
const symlinks: string[] = [];
|
|
24
|
+
const map: ResultDirectories = {};
|
|
25
|
+
const visited = new Set<string> ();
|
|
26
|
+
const resultEmpty: Result = { directories: [], files: [], symlinks: [], map: {} };
|
|
27
|
+
const result: Result = { directories, files, symlinks, map };
|
|
26
28
|
|
|
27
|
-
const handleDirectory = ( subPath: string, depth: number ): Promisable<void> => {
|
|
29
|
+
const handleDirectory = ( dirmap: ResultDirectory, subPath: string, depth: number ): Promisable<void> => {
|
|
28
30
|
|
|
31
|
+
if ( visited.has ( subPath ) ) return;
|
|
32
|
+
|
|
33
|
+
dirmap.directories.push ( subPath );
|
|
29
34
|
directories.push ( subPath );
|
|
35
|
+
visited.add ( subPath );
|
|
30
36
|
|
|
31
37
|
if ( depth >= maxDepth ) return;
|
|
32
38
|
|
|
33
|
-
return limiter.add ( () =>
|
|
39
|
+
return limiter.add ( () => populateResultFromPath ( subPath, depth + 1 ) );
|
|
34
40
|
|
|
35
41
|
};
|
|
36
42
|
|
|
37
|
-
const handleFile = ( subPath: string ): void => {
|
|
43
|
+
const handleFile = ( dirmap: ResultDirectory, subPath: string ): void => {
|
|
44
|
+
|
|
45
|
+
if ( visited.has ( subPath ) ) return;
|
|
38
46
|
|
|
47
|
+
dirmap.files.push ( subPath );
|
|
39
48
|
files.push ( subPath );
|
|
49
|
+
visited.add ( subPath );
|
|
40
50
|
|
|
41
51
|
};
|
|
42
52
|
|
|
43
|
-
const handleSymlink = ( subPath: string, depth: number ): Promisable<void> => {
|
|
53
|
+
const handleSymlink = ( dirmap: ResultDirectory, subPath: string, depth: number ): Promisable<void> => {
|
|
54
|
+
|
|
55
|
+
if ( visited.has ( subPath ) ) return;
|
|
44
56
|
|
|
57
|
+
dirmap.symlinks.push ( subPath );
|
|
45
58
|
symlinks.push ( subPath );
|
|
59
|
+
visited.add ( subPath );
|
|
46
60
|
|
|
47
61
|
if ( !followSymlinks ) return;
|
|
48
62
|
|
|
49
63
|
if ( depth >= maxDepth ) return;
|
|
50
64
|
|
|
51
|
-
return limiter.add (
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
|
|
55
|
-
const realPath = await fs.promises.realpath ( subPath ),
|
|
56
|
-
stat = await fs.promises.stat ( realPath );
|
|
57
|
-
|
|
58
|
-
await handleStat ( realPath, stat, depth + 1 );
|
|
59
|
-
|
|
60
|
-
} catch {}
|
|
61
|
-
|
|
62
|
-
});
|
|
65
|
+
return limiter.add ( () => populateResultFromSymlink ( subPath, depth + 1 ) );
|
|
63
66
|
|
|
64
67
|
};
|
|
65
68
|
|
|
66
|
-
const handleStat = ( rootPath: string, stat: fs.Stats, depth: number ): Promisable<void> => {
|
|
69
|
+
const handleStat = ( dirmap: ResultDirectory, rootPath: string, stat: fs.Stats, depth: number ): Promisable<void> => {
|
|
67
70
|
|
|
68
71
|
if ( signal.aborted ) return;
|
|
69
72
|
|
|
@@ -71,55 +74,55 @@ const readdir = ( rootPath: string, options?: Options ): Promise<Result> => {
|
|
|
71
74
|
|
|
72
75
|
if ( stat.isDirectory () ) {
|
|
73
76
|
|
|
74
|
-
return handleDirectory ( rootPath, depth );
|
|
77
|
+
return handleDirectory ( dirmap, rootPath, depth );
|
|
75
78
|
|
|
76
79
|
} else if ( stat.isFile () ) {
|
|
77
80
|
|
|
78
|
-
return handleFile ( rootPath );
|
|
81
|
+
return handleFile ( dirmap, rootPath );
|
|
79
82
|
|
|
80
83
|
} else if ( stat.isSymbolicLink () ) {
|
|
81
84
|
|
|
82
|
-
return handleSymlink ( rootPath, depth );
|
|
85
|
+
return handleSymlink ( dirmap, rootPath, depth );
|
|
83
86
|
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
};
|
|
87
90
|
|
|
88
|
-
const handleDirent = ( rootPath: string, dirent: fs.Dirent, depth: number ): Promisable<void> => {
|
|
91
|
+
const handleDirent = ( dirmap: ResultDirectory, rootPath: string, dirent: fs.Dirent, depth: number ): Promisable<void> => {
|
|
89
92
|
|
|
90
93
|
if ( signal.aborted ) return;
|
|
91
94
|
|
|
92
|
-
const subPath = path.
|
|
95
|
+
const subPath = `${rootPath}${path.sep}${dirent.name}`;
|
|
93
96
|
|
|
94
97
|
if ( isIgnored ( subPath ) ) return;
|
|
95
98
|
|
|
96
99
|
if ( dirent.isDirectory () ) {
|
|
97
100
|
|
|
98
|
-
return handleDirectory ( subPath, depth );
|
|
101
|
+
return handleDirectory ( dirmap, subPath, depth );
|
|
99
102
|
|
|
100
103
|
} else if ( dirent.isFile () ) {
|
|
101
104
|
|
|
102
|
-
return handleFile ( subPath );
|
|
105
|
+
return handleFile ( dirmap, subPath );
|
|
103
106
|
|
|
104
107
|
} else if ( dirent.isSymbolicLink () ) {
|
|
105
108
|
|
|
106
|
-
return handleSymlink ( subPath, depth );
|
|
109
|
+
return handleSymlink ( dirmap, subPath, depth );
|
|
107
110
|
|
|
108
111
|
}
|
|
109
112
|
|
|
110
113
|
};
|
|
111
114
|
|
|
112
|
-
const handleDirents = ( rootPath: string, dirents: fs.Dirent[], depth: number ): Promise<void[]> => {
|
|
115
|
+
const handleDirents = ( dirmap: ResultDirectory, rootPath: string, dirents: fs.Dirent[], depth: number ): Promise<void[]> => {
|
|
113
116
|
|
|
114
117
|
return Promise.all ( dirents.map ( ( dirent ): Promisable<void> => {
|
|
115
118
|
|
|
116
|
-
return handleDirent ( rootPath, dirent, depth );
|
|
119
|
+
return handleDirent ( dirmap, rootPath, dirent, depth );
|
|
117
120
|
|
|
118
121
|
}));
|
|
119
122
|
|
|
120
123
|
};
|
|
121
124
|
|
|
122
|
-
const
|
|
125
|
+
const populateResultFromPath = async ( rootPath: string, depth: number ): Promise<void> => {
|
|
123
126
|
|
|
124
127
|
if ( signal.aborted ) return;
|
|
125
128
|
|
|
@@ -129,15 +132,35 @@ const readdir = ( rootPath: string, options?: Options ): Promise<Result> => {
|
|
|
129
132
|
|
|
130
133
|
if ( signal.aborted ) return;
|
|
131
134
|
|
|
135
|
+
const dirmap = map[rootPath] = { directories: [], files: [], symlinks: [] };
|
|
136
|
+
|
|
132
137
|
if ( !dirents.length ) return;
|
|
133
138
|
|
|
134
|
-
await handleDirents ( rootPath, dirents, depth );
|
|
139
|
+
await handleDirents ( dirmap, rootPath, dirents, depth );
|
|
140
|
+
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const populateResultFromSymlink = async ( rootPath: string, depth: number ): Promise<void> => {
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
|
|
147
|
+
const realPath = await fs.promises.realpath ( rootPath );
|
|
148
|
+
const stat = await fs.promises.stat ( realPath );
|
|
149
|
+
const dirmap = map[rootPath] = { directories: [], files: [], symlinks: [] };
|
|
150
|
+
|
|
151
|
+
await handleStat ( dirmap, realPath, stat, depth );
|
|
152
|
+
|
|
153
|
+
} catch {}
|
|
135
154
|
|
|
136
155
|
};
|
|
137
156
|
|
|
138
157
|
const getResult = async ( rootPath: string, depth: number = 1 ): Promise<Result> => {
|
|
139
158
|
|
|
140
|
-
|
|
159
|
+
rootPath = path.normalize ( rootPath );
|
|
160
|
+
|
|
161
|
+
visited.add ( rootPath );
|
|
162
|
+
|
|
163
|
+
await populateResultFromPath ( rootPath, depth );
|
|
141
164
|
|
|
142
165
|
if ( signal.aborted ) return resultEmpty;
|
|
143
166
|
|
package/src/types.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
/* HELPERS */
|
|
3
3
|
|
|
4
|
-
type Promisable<T> = T |
|
|
4
|
+
type Promisable<T> = Promise<T> | T;
|
|
5
5
|
|
|
6
|
-
/*
|
|
6
|
+
/* MAIN */
|
|
7
7
|
|
|
8
8
|
type Options = {
|
|
9
9
|
depth?: number,
|
|
@@ -12,12 +12,20 @@ type Options = {
|
|
|
12
12
|
signal?: { aborted: boolean }
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
type
|
|
15
|
+
type ResultDirectory = {
|
|
16
16
|
directories: string[],
|
|
17
17
|
files: string[],
|
|
18
18
|
symlinks: string[]
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
type ResultDirectories = {
|
|
22
|
+
[path: string]: ResultDirectory
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type Result = ResultDirectory & {
|
|
26
|
+
map: ResultDirectories
|
|
27
|
+
};
|
|
28
|
+
|
|
21
29
|
/* EXPORT */
|
|
22
30
|
|
|
23
|
-
export {Promisable, Options, Result};
|
|
31
|
+
export type {Promisable, Options, ResultDirectory, ResultDirectories, Result};
|
package/test/index.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
|
|
2
|
+
/* IMPORT */
|
|
3
|
+
|
|
4
|
+
import {describe} from 'fava';
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import readdir from '../dist/index.js';
|
|
8
|
+
|
|
9
|
+
/* MAIN */
|
|
10
|
+
|
|
11
|
+
describe ( 'Tiny Readdir', it => {
|
|
12
|
+
|
|
13
|
+
it ( 'works', async t => {
|
|
14
|
+
|
|
15
|
+
const cwdPath = process.cwd ();
|
|
16
|
+
const root1Path = path.join ( cwdPath, 'test', 'root1' );
|
|
17
|
+
const root2Path = path.join ( cwdPath, 'test', 'root2' );
|
|
18
|
+
const folder1Path = path.join ( root1Path, 'folder1' );
|
|
19
|
+
const folder2Path = path.join ( root1Path, 'folder2' );
|
|
20
|
+
const folder1DeepPath = path.join ( folder1Path, 'deep' );
|
|
21
|
+
const file1aPath = path.join ( folder1Path, 'file1a.txt' );
|
|
22
|
+
const file1bPath = path.join ( folder1Path, 'file1b.txt' );
|
|
23
|
+
const file2Path = path.join ( folder2Path, 'file2.txt' );
|
|
24
|
+
const fileDeep1Path = path.join ( folder1DeepPath, 'file1.txt' );
|
|
25
|
+
const symlink1FromPath = path.join ( root1Path, 'symlink' );
|
|
26
|
+
const symlink1ToPath = root2Path;
|
|
27
|
+
const symlink2FromPath = path.join ( root2Path, 'symlink' );
|
|
28
|
+
const symlink2ToPath = root1Path;
|
|
29
|
+
|
|
30
|
+
fs.mkdirSync ( root1Path );
|
|
31
|
+
fs.mkdirSync ( root2Path );
|
|
32
|
+
fs.mkdirSync ( folder1Path );
|
|
33
|
+
fs.mkdirSync ( folder2Path );
|
|
34
|
+
fs.mkdirSync ( folder1DeepPath );
|
|
35
|
+
fs.writeFileSync ( file1aPath, '' );
|
|
36
|
+
fs.writeFileSync ( file1bPath, '' );
|
|
37
|
+
fs.writeFileSync ( file2Path, '' );
|
|
38
|
+
fs.writeFileSync ( fileDeep1Path, '' );
|
|
39
|
+
fs.symlinkSync ( symlink1ToPath, symlink1FromPath );
|
|
40
|
+
fs.symlinkSync ( symlink2ToPath, symlink2FromPath );
|
|
41
|
+
|
|
42
|
+
const expected = {
|
|
43
|
+
directories: [folder1Path, folder2Path, folder1DeepPath, root2Path],
|
|
44
|
+
files: [file1aPath, file1bPath, file2Path, fileDeep1Path],
|
|
45
|
+
symlinks: [symlink1FromPath, symlink2FromPath],
|
|
46
|
+
map: {
|
|
47
|
+
[root1Path]: {
|
|
48
|
+
directories: [folder1Path, folder2Path],
|
|
49
|
+
files: [],
|
|
50
|
+
symlinks: [symlink1FromPath]
|
|
51
|
+
},
|
|
52
|
+
[root2Path]: {
|
|
53
|
+
directories: [],
|
|
54
|
+
files: [],
|
|
55
|
+
symlinks: [symlink2FromPath]
|
|
56
|
+
},
|
|
57
|
+
[folder1Path]: {
|
|
58
|
+
directories: [folder1DeepPath],
|
|
59
|
+
files: [file1aPath, file1bPath],
|
|
60
|
+
symlinks: []
|
|
61
|
+
},
|
|
62
|
+
[folder2Path]: {
|
|
63
|
+
directories: [],
|
|
64
|
+
files: [file2Path],
|
|
65
|
+
symlinks: []
|
|
66
|
+
},
|
|
67
|
+
[folder1DeepPath]: {
|
|
68
|
+
directories: [],
|
|
69
|
+
files: [fileDeep1Path],
|
|
70
|
+
symlinks: []
|
|
71
|
+
},
|
|
72
|
+
[symlink1FromPath]: {
|
|
73
|
+
directories: [root2Path],
|
|
74
|
+
files: [],
|
|
75
|
+
symlinks: []
|
|
76
|
+
},
|
|
77
|
+
[symlink2FromPath]: {
|
|
78
|
+
directories: [],
|
|
79
|
+
files: [],
|
|
80
|
+
symlinks: []
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
|
|
87
|
+
const result = await readdir ( root1Path, { followSymlinks: true } );
|
|
88
|
+
|
|
89
|
+
t.deepEqual ( result, expected );
|
|
90
|
+
|
|
91
|
+
} finally {
|
|
92
|
+
|
|
93
|
+
fs.rmSync ( root1Path, { recursive: true } );
|
|
94
|
+
fs.rmSync ( root2Path, { recursive: true } );
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
});
|
package/tsconfig.json
CHANGED
|
@@ -1,28 +1,3 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"alwaysStrict": true,
|
|
4
|
-
"declaration": true,
|
|
5
|
-
"emitDecoratorMetadata": true,
|
|
6
|
-
"experimentalDecorators": true,
|
|
7
|
-
"forceConsistentCasingInFileNames": true,
|
|
8
|
-
"inlineSourceMap": false,
|
|
9
|
-
"jsx": "react",
|
|
10
|
-
"lib": ["dom", "scripthost", "es2015", "es2016", "es2017", "es2018", "es2019", "es2020"],
|
|
11
|
-
"module": "commonjs",
|
|
12
|
-
"moduleResolution": "node",
|
|
13
|
-
"newLine": "LF",
|
|
14
|
-
"noFallthroughCasesInSwitch": true,
|
|
15
|
-
"noUnusedLocals": true,
|
|
16
|
-
"noUnusedParameters": false,
|
|
17
|
-
"outDir": "dist",
|
|
18
|
-
"pretty": true,
|
|
19
|
-
"strictNullChecks": true,
|
|
20
|
-
"target": "es2018"
|
|
21
|
-
},
|
|
22
|
-
"include": [
|
|
23
|
-
"src"
|
|
24
|
-
],
|
|
25
|
-
"exclude": [
|
|
26
|
-
"node_modules"
|
|
27
|
-
]
|
|
2
|
+
"extends": "tsex/tsconfig.json"
|
|
28
3
|
}
|
package/.github/FUNDING.yml
DELETED