@zthun/crumbtrail-fs 2.0.0 → 2.0.2

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/dist/index.js CHANGED
@@ -1,103 +1,507 @@
1
- import { omitBy, isUndefined } from "lodash-es";
2
- import { glob } from "glob";
3
- import { access } from "node:fs/promises";
4
- import { isAbsolute, resolve, dirname } from "node:path";
5
- import { cwd } from "node:process";
6
- var ZFileSystemNodeType = /* @__PURE__ */ ((ZFileSystemNodeType2) => {
7
- ZFileSystemNodeType2["File"] = "file";
8
- ZFileSystemNodeType2["Folder"] = "folder";
9
- return ZFileSystemNodeType2;
10
- })(ZFileSystemNodeType || {});
11
- class ZFileSystemNodeBuilder {
12
- constructor() {
13
- this.file = this.type.bind(
14
- this,
15
- "file"
16
- /* File */
17
- );
18
- this.folder = this.type.bind(
19
- this,
20
- "folder"
21
- /* Folder */
22
- );
23
- this._node = {
24
- path: "/",
25
- type: "folder"
26
- /* Folder */
27
- };
28
- }
29
- created(at) {
30
- this._node.created = at instanceof Date ? at.toJSON() : at;
31
- return this;
32
- }
33
- updated(at) {
34
- this._node.updated = at instanceof Date ? at.toJSON() : at;
35
- return this;
36
- }
37
- size(bytes) {
38
- this._node.size = typeof bytes == "number" ? BigInt(bytes) : bytes;
39
- return this;
40
- }
41
- path(path) {
42
- this._node.path = path;
43
- return this;
44
- }
45
- type(type) {
46
- this._node.type = type;
47
- return this;
48
- }
49
- build() {
50
- const clone = structuredClone(this._node);
51
- return omitBy(clone, isUndefined);
52
- }
53
- }
54
- class ZFileSystemService {
55
- async info(path) {
56
- const [file] = await this.search(path);
57
- return file;
58
- }
59
- async search(pattern, options) {
60
- const paths = await glob(pattern, {
61
- ...options,
62
- stat: true,
63
- withFileTypes: true
64
- });
65
- return paths.map((path) => {
66
- let info = new ZFileSystemNodeBuilder().path(path.fullpath()).created(path.birthtime).updated(path.atime).size(path.size);
67
- info = path.isFile() ? info.file() : info.folder().size(void 0);
68
- return info.build();
69
- });
70
- }
71
- async walk(search, options) {
72
- const start = (options == null ? void 0 : options.start) || cwd();
73
- const stop = (options == null ? void 0 : options.stop) || "/";
74
- const mode = options == null ? void 0 : options.mode;
75
- const _test = async (path) => {
76
- try {
77
- await access(path, mode);
78
- return true;
79
- } catch {
80
- return false;
81
- }
1
+ import { omitBy, isUndefined } from 'lodash-es';
2
+ import { glob } from 'glob';
3
+ import { access } from 'node:fs/promises';
4
+ import { dirname, resolve, isAbsolute } from 'node:path';
5
+ import { cwd } from 'node:process';
6
+
7
+ function _class_call_check$1(instance, Constructor) {
8
+ if (!(instance instanceof Constructor)) {
9
+ throw new TypeError("Cannot call a class as a function");
10
+ }
11
+ }
12
+ function _defineProperties$1(target, props) {
13
+ for(var i = 0; i < props.length; i++){
14
+ var descriptor = props[i];
15
+ descriptor.enumerable = descriptor.enumerable || false;
16
+ descriptor.configurable = true;
17
+ if ("value" in descriptor) descriptor.writable = true;
18
+ Object.defineProperty(target, descriptor.key, descriptor);
19
+ }
20
+ }
21
+ function _create_class$1(Constructor, protoProps, staticProps) {
22
+ if (protoProps) _defineProperties$1(Constructor.prototype, protoProps);
23
+ return Constructor;
24
+ }
25
+ function _define_property$1(obj, key, value) {
26
+ if (key in obj) {
27
+ Object.defineProperty(obj, key, {
28
+ value: value,
29
+ enumerable: true,
30
+ configurable: true,
31
+ writable: true
32
+ });
33
+ } else {
34
+ obj[key] = value;
35
+ }
36
+ return obj;
37
+ }
38
+ function _instanceof(left, right) {
39
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
40
+ return !!right[Symbol.hasInstance](left);
41
+ } else {
42
+ return left instanceof right;
43
+ }
44
+ }
45
+ /**
46
+ * Represents a type of a file system node.
47
+ */ var ZFileSystemNodeType = /*#__PURE__*/ function(ZFileSystemNodeType) {
48
+ ZFileSystemNodeType["File"] = "file";
49
+ ZFileSystemNodeType["Folder"] = "folder";
50
+ return ZFileSystemNodeType;
51
+ }({});
52
+ /**
53
+ * Represents a builder for a file system node.
54
+ */ var ZFileSystemNodeBuilder = /*#__PURE__*/ function() {
55
+ function ZFileSystemNodeBuilder() {
56
+ _class_call_check$1(this, ZFileSystemNodeBuilder);
57
+ _define_property$1(this, "_node", void 0);
58
+ _define_property$1(this, "file", this.type.bind(this, "file"));
59
+ _define_property$1(this, "folder", this.type.bind(this, "folder"));
60
+ this._node = {
61
+ path: "/",
62
+ type: "folder"
63
+ };
64
+ }
65
+ _create_class$1(ZFileSystemNodeBuilder, [
66
+ {
67
+ key: "created",
68
+ value: function created(at) {
69
+ this._node.created = _instanceof(at, Date) ? at.toJSON() : at;
70
+ return this;
71
+ }
72
+ },
73
+ {
74
+ key: "updated",
75
+ value: function updated(at) {
76
+ this._node.updated = _instanceof(at, Date) ? at.toJSON() : at;
77
+ return this;
78
+ }
79
+ },
80
+ {
81
+ key: "size",
82
+ value: function size(bytes) {
83
+ this._node.size = typeof bytes == "number" ? BigInt(bytes) : bytes;
84
+ return this;
85
+ }
86
+ },
87
+ {
88
+ key: "path",
89
+ value: function path(path) {
90
+ this._node.path = path;
91
+ return this;
92
+ }
93
+ },
94
+ {
95
+ key: "type",
96
+ value: function type(type) {
97
+ this._node.type = type;
98
+ return this;
99
+ }
100
+ },
101
+ {
102
+ key: "build",
103
+ value: function build() {
104
+ var clone = structuredClone(this._node);
105
+ return omitBy(clone, isUndefined);
106
+ }
107
+ }
108
+ ]);
109
+ return ZFileSystemNodeBuilder;
110
+ }();
111
+
112
+ function _array_like_to_array(arr, len) {
113
+ if (len == null || len > arr.length) len = arr.length;
114
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
115
+ return arr2;
116
+ }
117
+ function _array_with_holes(arr) {
118
+ if (Array.isArray(arr)) return arr;
119
+ }
120
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
121
+ try {
122
+ var info = gen[key](arg);
123
+ var value = info.value;
124
+ } catch (error) {
125
+ reject(error);
126
+ return;
127
+ }
128
+ if (info.done) {
129
+ resolve(value);
130
+ } else {
131
+ Promise.resolve(value).then(_next, _throw);
132
+ }
133
+ }
134
+ function _async_to_generator(fn) {
135
+ return function() {
136
+ var self = this, args = arguments;
137
+ return new Promise(function(resolve, reject) {
138
+ var gen = fn.apply(self, args);
139
+ function _next(value) {
140
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
141
+ }
142
+ function _throw(err) {
143
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
144
+ }
145
+ _next(undefined);
146
+ });
82
147
  };
83
- if (isAbsolute(search)) {
84
- return await _test(search) ? search : null;
85
- }
86
- let dir = start;
87
- do {
88
- const path = resolve(dir, search);
89
- const exists = await _test(path);
90
- if (exists) {
91
- return path;
92
- }
93
- dir = dir === stop ? "" : dirname(dir);
94
- } while (dir.length);
95
- return null;
96
- }
97
- }
98
- export {
99
- ZFileSystemNodeBuilder,
100
- ZFileSystemNodeType,
101
- ZFileSystemService
102
- };
148
+ }
149
+ function _class_call_check(instance, Constructor) {
150
+ if (!(instance instanceof Constructor)) {
151
+ throw new TypeError("Cannot call a class as a function");
152
+ }
153
+ }
154
+ function _defineProperties(target, props) {
155
+ for(var i = 0; i < props.length; i++){
156
+ var descriptor = props[i];
157
+ descriptor.enumerable = descriptor.enumerable || false;
158
+ descriptor.configurable = true;
159
+ if ("value" in descriptor) descriptor.writable = true;
160
+ Object.defineProperty(target, descriptor.key, descriptor);
161
+ }
162
+ }
163
+ function _create_class(Constructor, protoProps, staticProps) {
164
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
165
+ return Constructor;
166
+ }
167
+ function _define_property(obj, key, value) {
168
+ if (key in obj) {
169
+ Object.defineProperty(obj, key, {
170
+ value: value,
171
+ enumerable: true,
172
+ configurable: true,
173
+ writable: true
174
+ });
175
+ } else {
176
+ obj[key] = value;
177
+ }
178
+ return obj;
179
+ }
180
+ function _iterable_to_array_limit(arr, i) {
181
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
182
+ if (_i == null) return;
183
+ var _arr = [];
184
+ var _n = true;
185
+ var _d = false;
186
+ var _s, _e;
187
+ try {
188
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
189
+ _arr.push(_s.value);
190
+ if (i && _arr.length === i) break;
191
+ }
192
+ } catch (err) {
193
+ _d = true;
194
+ _e = err;
195
+ } finally{
196
+ try {
197
+ if (!_n && _i["return"] != null) _i["return"]();
198
+ } finally{
199
+ if (_d) throw _e;
200
+ }
201
+ }
202
+ return _arr;
203
+ }
204
+ function _non_iterable_rest() {
205
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
206
+ }
207
+ function _object_spread(target) {
208
+ for(var i = 1; i < arguments.length; i++){
209
+ var source = arguments[i] != null ? arguments[i] : {};
210
+ var ownKeys = Object.keys(source);
211
+ if (typeof Object.getOwnPropertySymbols === "function") {
212
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
213
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
214
+ }));
215
+ }
216
+ ownKeys.forEach(function(key) {
217
+ _define_property(target, key, source[key]);
218
+ });
219
+ }
220
+ return target;
221
+ }
222
+ function ownKeys(object, enumerableOnly) {
223
+ var keys = Object.keys(object);
224
+ if (Object.getOwnPropertySymbols) {
225
+ var symbols = Object.getOwnPropertySymbols(object);
226
+ keys.push.apply(keys, symbols);
227
+ }
228
+ return keys;
229
+ }
230
+ function _object_spread_props(target, source) {
231
+ source = source != null ? source : {};
232
+ if (Object.getOwnPropertyDescriptors) {
233
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
234
+ } else {
235
+ ownKeys(Object(source)).forEach(function(key) {
236
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
237
+ });
238
+ }
239
+ return target;
240
+ }
241
+ function _sliced_to_array(arr, i) {
242
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
243
+ }
244
+ function _unsupported_iterable_to_array(o, minLen) {
245
+ if (!o) return;
246
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
247
+ var n = Object.prototype.toString.call(o).slice(8, -1);
248
+ if (n === "Object" && o.constructor) n = o.constructor.name;
249
+ if (n === "Map" || n === "Set") return Array.from(n);
250
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
251
+ }
252
+ function _ts_generator(thisArg, body) {
253
+ var f, y, t, _ = {
254
+ label: 0,
255
+ sent: function() {
256
+ if (t[0] & 1) throw t[1];
257
+ return t[1];
258
+ },
259
+ trys: [],
260
+ ops: []
261
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
262
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
263
+ return this;
264
+ }), g;
265
+ function verb(n) {
266
+ return function(v) {
267
+ return step([
268
+ n,
269
+ v
270
+ ]);
271
+ };
272
+ }
273
+ function step(op) {
274
+ if (f) throw new TypeError("Generator is already executing.");
275
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
276
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
277
+ if (y = 0, t) op = [
278
+ op[0] & 2,
279
+ t.value
280
+ ];
281
+ switch(op[0]){
282
+ case 0:
283
+ case 1:
284
+ t = op;
285
+ break;
286
+ case 4:
287
+ _.label++;
288
+ return {
289
+ value: op[1],
290
+ done: false
291
+ };
292
+ case 5:
293
+ _.label++;
294
+ y = op[1];
295
+ op = [
296
+ 0
297
+ ];
298
+ continue;
299
+ case 7:
300
+ op = _.ops.pop();
301
+ _.trys.pop();
302
+ continue;
303
+ default:
304
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
305
+ _ = 0;
306
+ continue;
307
+ }
308
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
309
+ _.label = op[1];
310
+ break;
311
+ }
312
+ if (op[0] === 6 && _.label < t[1]) {
313
+ _.label = t[1];
314
+ t = op;
315
+ break;
316
+ }
317
+ if (t && _.label < t[2]) {
318
+ _.label = t[2];
319
+ _.ops.push(op);
320
+ break;
321
+ }
322
+ if (t[2]) _.ops.pop();
323
+ _.trys.pop();
324
+ continue;
325
+ }
326
+ op = body.call(thisArg, _);
327
+ } catch (e) {
328
+ op = [
329
+ 6,
330
+ e
331
+ ];
332
+ y = 0;
333
+ } finally{
334
+ f = t = 0;
335
+ }
336
+ if (op[0] & 5) throw op[1];
337
+ return {
338
+ value: op[0] ? op[1] : void 0,
339
+ done: true
340
+ };
341
+ }
342
+ }
343
+ /**
344
+ * Represents a node implementation of a file system service.
345
+ */ var ZFileSystemService = /*#__PURE__*/ function() {
346
+ function ZFileSystemService() {
347
+ _class_call_check(this, ZFileSystemService);
348
+ }
349
+ _create_class(ZFileSystemService, [
350
+ {
351
+ key: "info",
352
+ value: function info(path) {
353
+ return _async_to_generator(function() {
354
+ var _ref, file;
355
+ return _ts_generator(this, function(_state) {
356
+ switch(_state.label){
357
+ case 0:
358
+ return [
359
+ 4,
360
+ this.search(path)
361
+ ];
362
+ case 1:
363
+ _ref = _sliced_to_array.apply(void 0, [
364
+ _state.sent(),
365
+ 1
366
+ ]), file = _ref[0];
367
+ return [
368
+ 2,
369
+ file
370
+ ];
371
+ }
372
+ });
373
+ }).call(this);
374
+ }
375
+ },
376
+ {
377
+ key: "search",
378
+ value: function search(pattern, options) {
379
+ return _async_to_generator(function() {
380
+ var paths;
381
+ return _ts_generator(this, function(_state) {
382
+ switch(_state.label){
383
+ case 0:
384
+ return [
385
+ 4,
386
+ glob(pattern, _object_spread_props(_object_spread({}, options), {
387
+ stat: true,
388
+ withFileTypes: true
389
+ }))
390
+ ];
391
+ case 1:
392
+ paths = _state.sent();
393
+ return [
394
+ 2,
395
+ paths.map(function(path) {
396
+ var info = new ZFileSystemNodeBuilder().path(path.fullpath()).created(path.birthtime).updated(path.atime).size(path.size);
397
+ // Note that for folders, node will return the size of the underlying OS metadata,
398
+ // hence, why we 0 out the size on a folder here.
399
+ info = path.isFile() ? info.file() : info.folder().size(undefined);
400
+ return info.build();
401
+ })
402
+ ];
403
+ }
404
+ });
405
+ })();
406
+ }
407
+ },
408
+ {
409
+ key: "walk",
410
+ value: function walk(search, options) {
411
+ return _async_to_generator(function() {
412
+ var start, stop, mode, _test, dir, path, exists;
413
+ return _ts_generator(this, function(_state) {
414
+ switch(_state.label){
415
+ case 0:
416
+ start = (options === null || options === void 0 ? void 0 : options.start) || cwd();
417
+ stop = (options === null || options === void 0 ? void 0 : options.stop) || "/";
418
+ mode = options === null || options === void 0 ? void 0 : options.mode;
419
+ _test = function(path) {
420
+ return _async_to_generator(function() {
421
+ return _ts_generator(this, function(_state) {
422
+ switch(_state.label){
423
+ case 0:
424
+ _state.trys.push([
425
+ 0,
426
+ 2,
427
+ ,
428
+ 3
429
+ ]);
430
+ return [
431
+ 4,
432
+ access(path, mode)
433
+ ];
434
+ case 1:
435
+ _state.sent();
436
+ return [
437
+ 2,
438
+ true
439
+ ];
440
+ case 2:
441
+ _state.sent();
442
+ return [
443
+ 2,
444
+ false
445
+ ];
446
+ case 3:
447
+ return [
448
+ 2
449
+ ];
450
+ }
451
+ });
452
+ })();
453
+ };
454
+ if (!isAbsolute(search)) return [
455
+ 3,
456
+ 2
457
+ ];
458
+ return [
459
+ 4,
460
+ _test(search)
461
+ ];
462
+ case 1:
463
+ return [
464
+ 2,
465
+ _state.sent() ? search : null
466
+ ];
467
+ case 2:
468
+ dir = start;
469
+ _state.label = 3;
470
+ case 3:
471
+ path = resolve(dir, search);
472
+ return [
473
+ 4,
474
+ _test(path)
475
+ ];
476
+ case 4:
477
+ exists = _state.sent();
478
+ if (exists) {
479
+ return [
480
+ 2,
481
+ path
482
+ ];
483
+ }
484
+ dir = dir === stop ? "" : dirname(dir);
485
+ _state.label = 5;
486
+ case 5:
487
+ if (dir.length) return [
488
+ 3,
489
+ 3
490
+ ];
491
+ _state.label = 6;
492
+ case 6:
493
+ return [
494
+ 2,
495
+ null
496
+ ];
497
+ }
498
+ });
499
+ })();
500
+ }
501
+ }
502
+ ]);
503
+ return ZFileSystemService;
504
+ }();
505
+
506
+ export { ZFileSystemNodeBuilder, ZFileSystemNodeType, ZFileSystemService };
103
507
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/file-system/file-system-node.mts","../src/file-system/file-system-service.mts"],"sourcesContent":["import { isUndefined, omitBy } from \"lodash-es\";\n\n/**\n * Represents a type of a file system node.\n */\nexport enum ZFileSystemNodeType {\n File = \"file\",\n Folder = \"folder\",\n}\n\nexport interface IZFileSystemNode {\n /**\n * The absolute path of the node.\n */\n path: string;\n\n /**\n * The type of the node (file or folder).\n */\n type: ZFileSystemNodeType;\n\n /**\n * The creation date of the node.\n */\n created?: string;\n\n /**\n * The modification date of the node.\n */\n updated?: string;\n\n /**\n * The size of the node in bytes.\n */\n size?: bigint;\n}\n\n/**\n * Represents a builder for a file system node.\n */\nexport class ZFileSystemNodeBuilder {\n private _node: IZFileSystemNode;\n\n public constructor() {\n this._node = {\n path: \"/\",\n type: ZFileSystemNodeType.Folder,\n };\n }\n\n public created(at?: Date | string | undefined) {\n this._node.created = at instanceof Date ? at.toJSON() : at;\n return this;\n }\n\n public updated(at?: Date | string | undefined) {\n this._node.updated = at instanceof Date ? at.toJSON() : at;\n return this;\n }\n\n public size(bytes: bigint | number | undefined) {\n this._node.size = typeof bytes == \"number\" ? BigInt(bytes) : bytes;\n return this;\n }\n\n public path(path: string) {\n this._node.path = path;\n return this;\n }\n\n public type(type: ZFileSystemNodeType) {\n this._node.type = type;\n return this;\n }\n\n public file = this.type.bind(this, ZFileSystemNodeType.File);\n public folder = this.type.bind(this, ZFileSystemNodeType.Folder);\n\n public build() {\n const clone = structuredClone(this._node);\n return omitBy<IZFileSystemNode>(clone, isUndefined) as IZFileSystemNode;\n }\n}\n","import { glob } from \"glob\";\nimport { access } from \"node:fs/promises\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport { cwd } from \"node:process\";\nimport {\n IZFileSystemNode,\n ZFileSystemNodeBuilder,\n} from \"./file-system-node.mjs\";\n\n/**\n * Represents options for searches.\n */\nexport interface IZFileSystemSearchOptions {\n /**\n * The directory to search in.\n *\n * If this is not set, then the cwd of the application is used.\n */\n cwd?: string;\n}\n\n/**\n * Represents options for directory walking.\n */\nexport interface IZFileSystemWalkOptions {\n /**\n * The starting directory.\n *\n * The default is the current working directory\n *\n * @see process.cwd for more information.\n */\n start?: string;\n\n /**\n * The directory to stop at.\n *\n * The default is the root of the file system.\n */\n stop?: string;\n\n /**\n * The type of mode that the path must support in order\n * to be approved.\n *\n * The default is undefined and left up to the node api.\n */\n mode?: number;\n}\n\n/**\n * Represents a service to enumerate the file system.\n */\nexport interface IZFileSystemService {\n /**\n * Gets information about a node.\n *\n * @param path -\n * The path to get information for.\n *\n * @returns\n * Information about the node.\n */\n info(path: string): Promise<IZFileSystemNode>;\n\n /**\n * Reads all nodes that match a pattern.\n *\n * @param pattern -\n * The pattern string to match against.\n * @param options -\n * The options for the search.\n *\n * @returns\n * A list of path strings that match the given patterns.\n */\n search(\n pattern: string,\n options?: IZFileSystemSearchOptions,\n ): Promise<IZFileSystemNode[]>;\n\n /**\n * Walks up a directory tree to search for existence of a given path.\n *\n * @param search -\n * The path to search for. This is the candidate folder path that\n * may or may not exist somewhere from the start directory all the\n * way up the directory tree.\n * @param options -\n * The given options for the search.\n *\n * @returns\n * The fully qualified path to the first path that matches the search\n * starting at the options start or the current working directory if not\n * specified. Returns null if no such directory exists.\n *\n * @example\n *\n * ```ts\n * import { resolve } from 'path'\n *\n * // Find any folder named .vscode from the current working directory all the way\n * // up the directory tree. Returns null if no vscode directory can be found.\n * const service = new ZFileSystemService();\n * const vscode = service.walk('.vscode');\n *\n * // Walk the directory tree from the current script and find the .config folder.\n * const config = service.walk('.config', { start: __dirname });\n *\n * // Walk the directory tree from the current script and stop when we reach\n * // at most 2 directories up.\n * const start = __dirname;\n * const stop = resolve(__dirname, '../..');\n * const file = service.walk('path/to/file.json', { start, stop });\n * ```\n */\n walk(\n search: string,\n options?: IZFileSystemWalkOptions,\n ): Promise<string | null>;\n}\n\n/**\n * Represents a node implementation of a file system service.\n */\nexport class ZFileSystemService implements IZFileSystemService {\n public async info(path: string): Promise<IZFileSystemNode> {\n const [file] = await this.search(path);\n return file;\n }\n\n public async search(\n pattern: string | string[],\n options?: IZFileSystemSearchOptions,\n ): Promise<IZFileSystemNode[]> {\n const paths = await glob(pattern, {\n ...options,\n stat: true,\n withFileTypes: true,\n });\n\n return paths.map((path) => {\n let info = new ZFileSystemNodeBuilder()\n .path(path.fullpath())\n .created(path.birthtime)\n .updated(path.atime)\n .size(path.size);\n\n // Note that for folders, node will return the size of the underlying OS metadata,\n // hence, why we 0 out the size on a folder here.\n info = path.isFile() ? info.file() : info.folder().size(undefined);\n\n return info.build();\n });\n }\n\n public async walk(search: string, options?: IZFileSystemWalkOptions) {\n const start = options?.start || cwd();\n const stop = options?.stop || \"/\";\n const mode = options?.mode;\n\n const _test = async (path: string) => {\n try {\n await access(path, mode);\n return true;\n } catch {\n return false;\n }\n };\n\n if (isAbsolute(search)) {\n return (await _test(search)) ? search : null;\n }\n\n let dir = start;\n do {\n const path = resolve(dir, search);\n const exists = await _test(path);\n\n if (exists) {\n return path;\n }\n\n dir = dir === stop ? \"\" : dirname(dir);\n } while (dir.length);\n\n return null;\n }\n}\n"],"names":["ZFileSystemNodeType"],"mappings":";;;;;AAKY,IAAA,wCAAAA,yBAAL;AACLA,uBAAA,MAAO,IAAA;AACPA,uBAAA,QAAS,IAAA;AAFCA,SAAAA;AAAA,GAAA,uBAAA,CAAA,CAAA;AAmCL,MAAM,uBAAuB;AAAA,EAG3B,cAAc;AAgCrB,SAAO,OAAO,KAAK,KAAK;AAAA,MAAK;AAAA,MAAM;AAAA;AAAA,IAAwB;AAC3D,SAAO,SAAS,KAAK,KAAK;AAAA,MAAK;AAAA,MAAM;AAAA;AAAA,IAA0B;AAhC7D,SAAK,QAAQ;AAAA,MACX,MAAM;AAAA,MACN,MAAM;AAAA;AAAA,IACR;AAAA,EAAA;AAAA,EAGK,QAAQ,IAAgC;AAC7C,SAAK,MAAM,UAAU,cAAc,OAAO,GAAG,WAAW;AACjD,WAAA;AAAA,EAAA;AAAA,EAGF,QAAQ,IAAgC;AAC7C,SAAK,MAAM,UAAU,cAAc,OAAO,GAAG,WAAW;AACjD,WAAA;AAAA,EAAA;AAAA,EAGF,KAAK,OAAoC;AAC9C,SAAK,MAAM,OAAO,OAAO,SAAS,WAAW,OAAO,KAAK,IAAI;AACtD,WAAA;AAAA,EAAA;AAAA,EAGF,KAAK,MAAc;AACxB,SAAK,MAAM,OAAO;AACX,WAAA;AAAA,EAAA;AAAA,EAGF,KAAK,MAA2B;AACrC,SAAK,MAAM,OAAO;AACX,WAAA;AAAA,EAAA;AAAA,EAMF,QAAQ;AACP,UAAA,QAAQ,gBAAgB,KAAK,KAAK;AACjC,WAAA,OAAyB,OAAO,WAAW;AAAA,EAAA;AAEtD;AC2CO,MAAM,mBAAkD;AAAA,EAC7D,MAAa,KAAK,MAAyC;AACzD,UAAM,CAAC,IAAI,IAAI,MAAM,KAAK,OAAO,IAAI;AAC9B,WAAA;AAAA,EAAA;AAAA,EAGT,MAAa,OACX,SACA,SAC6B;AACvB,UAAA,QAAQ,MAAM,KAAK,SAAS;AAAA,MAChC,GAAG;AAAA,MACH,MAAM;AAAA,MACN,eAAe;AAAA,IAAA,CAChB;AAEM,WAAA,MAAM,IAAI,CAAC,SAAS;AACzB,UAAI,OAAO,IAAI,yBACZ,KAAK,KAAK,SAAU,CAAA,EACpB,QAAQ,KAAK,SAAS,EACtB,QAAQ,KAAK,KAAK,EAClB,KAAK,KAAK,IAAI;AAIV,aAAA,KAAK,OAAO,IAAI,KAAK,SAAS,KAAK,OAAA,EAAS,KAAK,MAAS;AAEjE,aAAO,KAAK,MAAM;AAAA,IAAA,CACnB;AAAA,EAAA;AAAA,EAGH,MAAa,KAAK,QAAgB,SAAmC;AAC7D,UAAA,SAAQ,mCAAS,UAAS,IAAI;AAC9B,UAAA,QAAO,mCAAS,SAAQ;AAC9B,UAAM,OAAO,mCAAS;AAEhB,UAAA,QAAQ,OAAO,SAAiB;AAChC,UAAA;AACI,cAAA,OAAO,MAAM,IAAI;AAChB,eAAA;AAAA,MAAA,QACD;AACC,eAAA;AAAA,MAAA;AAAA,IAEX;AAEI,QAAA,WAAW,MAAM,GAAG;AACtB,aAAQ,MAAM,MAAM,MAAM,IAAK,SAAS;AAAA,IAAA;AAG1C,QAAI,MAAM;AACP,OAAA;AACK,YAAA,OAAO,QAAQ,KAAK,MAAM;AAC1B,YAAA,SAAS,MAAM,MAAM,IAAI;AAE/B,UAAI,QAAQ;AACH,eAAA;AAAA,MAAA;AAGT,YAAM,QAAQ,OAAO,KAAK,QAAQ,GAAG;AAAA,aAC9B,IAAI;AAEN,WAAA;AAAA,EAAA;AAEX;"}
1
+ {"version":3,"file":"index.js","sources":["../src/file-system/file-system-node.mts","../src/file-system/file-system-service.mts"],"sourcesContent":["import { isUndefined, omitBy } from \"lodash-es\";\n\n/**\n * Represents a type of a file system node.\n */\nexport enum ZFileSystemNodeType {\n File = \"file\",\n Folder = \"folder\",\n}\n\nexport interface IZFileSystemNode {\n /**\n * The absolute path of the node.\n */\n path: string;\n\n /**\n * The type of the node (file or folder).\n */\n type: ZFileSystemNodeType;\n\n /**\n * The creation date of the node.\n */\n created?: string;\n\n /**\n * The modification date of the node.\n */\n updated?: string;\n\n /**\n * The size of the node in bytes.\n */\n size?: bigint;\n}\n\n/**\n * Represents a builder for a file system node.\n */\nexport class ZFileSystemNodeBuilder {\n private _node: IZFileSystemNode;\n\n public constructor() {\n this._node = {\n path: \"/\",\n type: ZFileSystemNodeType.Folder,\n };\n }\n\n public created(at?: Date | string | undefined) {\n this._node.created = at instanceof Date ? at.toJSON() : at;\n return this;\n }\n\n public updated(at?: Date | string | undefined) {\n this._node.updated = at instanceof Date ? at.toJSON() : at;\n return this;\n }\n\n public size(bytes: bigint | number | undefined) {\n this._node.size = typeof bytes == \"number\" ? BigInt(bytes) : bytes;\n return this;\n }\n\n public path(path: string) {\n this._node.path = path;\n return this;\n }\n\n public type(type: ZFileSystemNodeType) {\n this._node.type = type;\n return this;\n }\n\n public file = this.type.bind(this, ZFileSystemNodeType.File);\n public folder = this.type.bind(this, ZFileSystemNodeType.Folder);\n\n public build() {\n const clone = structuredClone(this._node);\n return omitBy<IZFileSystemNode>(clone, isUndefined) as IZFileSystemNode;\n }\n}\n","import { glob } from \"glob\";\nimport { access } from \"node:fs/promises\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport { cwd } from \"node:process\";\nimport type { IZFileSystemNode } from \"./file-system-node.mjs\";\nimport { ZFileSystemNodeBuilder } from \"./file-system-node.mjs\";\n\n/**\n * Represents options for searches.\n */\nexport interface IZFileSystemSearchOptions {\n /**\n * The directory to search in.\n *\n * If this is not set, then the cwd of the application is used.\n */\n cwd?: string;\n}\n\n/**\n * Represents options for directory walking.\n */\nexport interface IZFileSystemWalkOptions {\n /**\n * The starting directory.\n *\n * The default is the current working directory\n *\n * @see process.cwd for more information.\n */\n start?: string;\n\n /**\n * The directory to stop at.\n *\n * The default is the root of the file system.\n */\n stop?: string;\n\n /**\n * The type of mode that the path must support in order\n * to be approved.\n *\n * The default is undefined and left up to the node api.\n */\n mode?: number;\n}\n\n/**\n * Represents a service to enumerate the file system.\n */\nexport interface IZFileSystemService {\n /**\n * Gets information about a node.\n *\n * @param path -\n * The path to get information for.\n *\n * @returns\n * Information about the node.\n */\n info(path: string): Promise<IZFileSystemNode>;\n\n /**\n * Reads all nodes that match a pattern.\n *\n * @param pattern -\n * The pattern string to match against.\n * @param options -\n * The options for the search.\n *\n * @returns\n * A list of path strings that match the given patterns.\n */\n search(\n pattern: string,\n options?: IZFileSystemSearchOptions,\n ): Promise<IZFileSystemNode[]>;\n\n /**\n * Walks up a directory tree to search for existence of a given path.\n *\n * @param search -\n * The path to search for. This is the candidate folder path that\n * may or may not exist somewhere from the start directory all the\n * way up the directory tree.\n * @param options -\n * The given options for the search.\n *\n * @returns\n * The fully qualified path to the first path that matches the search\n * starting at the options start or the current working directory if not\n * specified. Returns null if no such directory exists.\n *\n * @example\n *\n * ```ts\n * import { resolve } from 'path'\n *\n * // Find any folder named .vscode from the current working directory all the way\n * // up the directory tree. Returns null if no vscode directory can be found.\n * const service = new ZFileSystemService();\n * const vscode = service.walk('.vscode');\n *\n * // Walk the directory tree from the current script and find the .config folder.\n * const config = service.walk('.config', { start: __dirname });\n *\n * // Walk the directory tree from the current script and stop when we reach\n * // at most 2 directories up.\n * const start = __dirname;\n * const stop = resolve(__dirname, '../..');\n * const file = service.walk('path/to/file.json', { start, stop });\n * ```\n */\n walk(\n search: string,\n options?: IZFileSystemWalkOptions,\n ): Promise<string | null>;\n}\n\n/**\n * Represents a node implementation of a file system service.\n */\nexport class ZFileSystemService implements IZFileSystemService {\n public async info(path: string): Promise<IZFileSystemNode> {\n const [file] = await this.search(path);\n return file;\n }\n\n public async search(\n pattern: string | string[],\n options?: IZFileSystemSearchOptions,\n ): Promise<IZFileSystemNode[]> {\n const paths = await glob(pattern, {\n ...options,\n stat: true,\n withFileTypes: true,\n });\n\n return paths.map((path) => {\n let info = new ZFileSystemNodeBuilder()\n .path(path.fullpath())\n .created(path.birthtime)\n .updated(path.atime)\n .size(path.size);\n\n // Note that for folders, node will return the size of the underlying OS metadata,\n // hence, why we 0 out the size on a folder here.\n info = path.isFile() ? info.file() : info.folder().size(undefined);\n\n return info.build();\n });\n }\n\n public async walk(search: string, options?: IZFileSystemWalkOptions) {\n const start = options?.start || cwd();\n const stop = options?.stop || \"/\";\n const mode = options?.mode;\n\n const _test = async (path: string) => {\n try {\n await access(path, mode);\n return true;\n } catch {\n return false;\n }\n };\n\n if (isAbsolute(search)) {\n return (await _test(search)) ? search : null;\n }\n\n let dir = start;\n do {\n const path = resolve(dir, search);\n const exists = await _test(path);\n\n if (exists) {\n return path;\n }\n\n dir = dir === stop ? \"\" : dirname(dir);\n } while (dir.length);\n\n return null;\n }\n}\n"],"names":["ZFileSystemNodeType","ZFileSystemNodeBuilder","_define_property","_node","file","type","bind","folder","path","created","at","Date","toJSON","updated","size","bytes","BigInt","build","clone","structuredClone","omitBy","isUndefined","ZFileSystemService","info","search","pattern","options","paths","glob","stat","withFileTypes","map","fullpath","birthtime","atime","isFile","undefined","walk","start","stop","mode","_test","dir","exists","cwd","access","isAbsolute","resolve","dirname","length"],"mappings":"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"}