source: imaps-frontend/node_modules/readdirp/index.js

main
Last change on this file was 0c6b92a, checked in by stefan toskovski <stefantoska84@…>, 5 weeks ago

Pred finalna verzija

  • Property mode set to 100644
File size: 9.1 KB
RevLine 
[0c6b92a]1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.readdirpPromise = exports.readdirp = exports.ReaddirpStream = void 0;
4const promises_1 = require("fs/promises");
5const stream_1 = require("stream");
6const path_1 = require("path");
7function defaultOptions() {
8 return {
9 root: '.',
10 fileFilter: (_path) => true,
11 directoryFilter: (_path) => true,
12 type: FILE_TYPE,
13 lstat: false,
14 depth: 2147483648,
15 alwaysStat: false,
16 highWaterMark: 4096,
17 };
18}
19const RECURSIVE_ERROR_CODE = 'READDIRP_RECURSIVE_ERROR';
20const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP', RECURSIVE_ERROR_CODE]);
21const FILE_TYPE = 'files';
22const DIR_TYPE = 'directories';
23const FILE_DIR_TYPE = 'files_directories';
24const EVERYTHING_TYPE = 'all';
25const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE];
26const DIR_TYPES = new Set([DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE]);
27const FILE_TYPES = new Set([FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE]);
28const isNormalFlowError = (error) => NORMAL_FLOW_ERRORS.has(error.code);
29const wantBigintFsStats = process.platform === 'win32';
30const emptyFn = (_path) => true;
31const normalizeFilter = (filter) => {
32 if (filter === undefined)
33 return emptyFn;
34 if (typeof filter === 'function')
35 return filter;
36 if (typeof filter === 'string') {
37 const fl = filter.trim();
38 return (entry) => entry.basename === fl;
39 }
40 if (Array.isArray(filter)) {
41 const trItems = filter.map((item) => item.trim());
42 return (entry) => trItems.some((f) => entry.basename === f);
43 }
44 return emptyFn;
45};
46class ReaddirpStream extends stream_1.Readable {
47 constructor(options = {}) {
48 super({
49 objectMode: true,
50 autoDestroy: true,
51 highWaterMark: options.highWaterMark,
52 });
53 const opts = { ...defaultOptions(), ...options };
54 const { root, type } = opts;
55 this._fileFilter = normalizeFilter(opts.fileFilter);
56 this._directoryFilter = normalizeFilter(opts.directoryFilter);
57 const statMethod = opts.lstat ? promises_1.lstat : promises_1.stat;
58 // Use bigint stats if it's windows and stat() supports options (node 10+).
59 if (wantBigintFsStats) {
60 this._stat = (path) => statMethod(path, { bigint: true });
61 }
62 else {
63 this._stat = statMethod;
64 }
65 this._maxDepth = opts.depth;
66 this._wantsDir = DIR_TYPES.has(type);
67 this._wantsFile = FILE_TYPES.has(type);
68 this._wantsEverything = type === EVERYTHING_TYPE;
69 this._root = (0, path_1.resolve)(root);
70 this._isDirent = !opts.alwaysStat;
71 this._statsProp = this._isDirent ? 'dirent' : 'stats';
72 this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent };
73 // Launch stream with one parent, the root dir.
74 this.parents = [this._exploreDir(root, 1)];
75 this.reading = false;
76 this.parent = undefined;
77 }
78 async _read(batch) {
79 if (this.reading)
80 return;
81 this.reading = true;
82 try {
83 while (!this.destroyed && batch > 0) {
84 const par = this.parent;
85 const fil = par && par.files;
86 if (fil && fil.length > 0) {
87 const { path, depth } = par;
88 const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path));
89 const awaited = await Promise.all(slice);
90 for (const entry of awaited) {
91 if (!entry) {
92 batch--;
93 return;
94 }
95 if (this.destroyed)
96 return;
97 const entryType = await this._getEntryType(entry);
98 if (entryType === 'directory' && this._directoryFilter(entry)) {
99 if (depth <= this._maxDepth) {
100 this.parents.push(this._exploreDir(entry.fullPath, depth + 1));
101 }
102 if (this._wantsDir) {
103 this.push(entry);
104 batch--;
105 }
106 }
107 else if ((entryType === 'file' || this._includeAsFile(entry)) &&
108 this._fileFilter(entry)) {
109 if (this._wantsFile) {
110 this.push(entry);
111 batch--;
112 }
113 }
114 }
115 }
116 else {
117 const parent = this.parents.pop();
118 if (!parent) {
119 this.push(null);
120 break;
121 }
122 this.parent = await parent;
123 if (this.destroyed)
124 return;
125 }
126 }
127 }
128 catch (error) {
129 this.destroy(error);
130 }
131 finally {
132 this.reading = false;
133 }
134 }
135 async _exploreDir(path, depth) {
136 let files;
137 try {
138 files = await (0, promises_1.readdir)(path, this._rdOptions);
139 }
140 catch (error) {
141 this._onError(error);
142 }
143 return { files, depth, path };
144 }
145 async _formatEntry(dirent, path) {
146 let entry;
147 const basename = this._isDirent ? dirent.name : dirent;
148 try {
149 const fullPath = (0, path_1.resolve)((0, path_1.join)(path, basename));
150 entry = { path: (0, path_1.relative)(this._root, fullPath), fullPath, basename };
151 entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
152 }
153 catch (err) {
154 this._onError(err);
155 return;
156 }
157 return entry;
158 }
159 _onError(err) {
160 if (isNormalFlowError(err) && !this.destroyed) {
161 this.emit('warn', err);
162 }
163 else {
164 this.destroy(err);
165 }
166 }
167 async _getEntryType(entry) {
168 // entry may be undefined, because a warning or an error were emitted
169 // and the statsProp is undefined
170 if (!entry && this._statsProp in entry) {
171 return '';
172 }
173 const stats = entry[this._statsProp];
174 if (stats.isFile())
175 return 'file';
176 if (stats.isDirectory())
177 return 'directory';
178 if (stats && stats.isSymbolicLink()) {
179 const full = entry.fullPath;
180 try {
181 const entryRealPath = await (0, promises_1.realpath)(full);
182 const entryRealPathStats = await (0, promises_1.lstat)(entryRealPath);
183 if (entryRealPathStats.isFile()) {
184 return 'file';
185 }
186 if (entryRealPathStats.isDirectory()) {
187 const len = entryRealPath.length;
188 if (full.startsWith(entryRealPath) && full.substr(len, 1) === path_1.sep) {
189 const recursiveError = new Error(`Circular symlink detected: "${full}" points to "${entryRealPath}"`);
190 // @ts-ignore
191 recursiveError.code = RECURSIVE_ERROR_CODE;
192 return this._onError(recursiveError);
193 }
194 return 'directory';
195 }
196 }
197 catch (error) {
198 this._onError(error);
199 return '';
200 }
201 }
202 }
203 _includeAsFile(entry) {
204 const stats = entry && entry[this._statsProp];
205 return stats && this._wantsEverything && !stats.isDirectory();
206 }
207}
208exports.ReaddirpStream = ReaddirpStream;
209/**
210 * Main function which ends up calling readdirRec and reads all files and directories in given root recursively.
211 * @param root Root directory
212 * @param options Options to specify root (start directory), filters and recursion depth
213 */
214const readdirp = (root, options = {}) => {
215 // @ts-ignore
216 let type = options.entryType || options.type;
217 if (type === 'both')
218 type = FILE_DIR_TYPE; // backwards-compatibility
219 if (type)
220 options.type = type;
221 if (!root) {
222 throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)');
223 }
224 else if (typeof root !== 'string') {
225 throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)');
226 }
227 else if (type && !ALL_TYPES.includes(type)) {
228 throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`);
229 }
230 options.root = root;
231 return new ReaddirpStream(options);
232};
233exports.readdirp = readdirp;
234const readdirpPromise = (root, options = {}) => {
235 return new Promise((resolve, reject) => {
236 const files = [];
237 (0, exports.readdirp)(root, options)
238 .on('data', (entry) => files.push(entry))
239 .on('end', () => resolve(files))
240 .on('error', (error) => reject(error));
241 });
242};
243exports.readdirpPromise = readdirpPromise;
244exports.default = exports.readdirp;
Note: See TracBrowser for help on using the repository browser.