@catbee/utils 0.0.1 → 0.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/README.md +303 -107
- package/build/esm/config.d.ts +12 -0
- package/build/esm/config.js +12 -0
- package/build/esm/config.js.map +1 -1
- package/build/esm/index.d.ts +1 -0
- package/build/esm/index.js +1 -0
- package/build/esm/index.js.map +1 -1
- package/build/esm/types/api-response.d.ts +82 -0
- package/build/esm/types/api-response.js.map +1 -1
- package/build/esm/utils/array.utils.d.ts +64 -1
- package/build/esm/utils/array.utils.js +139 -2
- package/build/esm/utils/array.utils.js.map +1 -1
- package/build/esm/utils/async.utils.d.ts +60 -1
- package/build/esm/utils/async.utils.js +160 -2
- package/build/esm/utils/async.utils.js.map +1 -1
- package/build/esm/utils/cache.utils.d.ts +67 -4
- package/build/esm/utils/cache.utils.js +210 -28
- package/build/esm/utils/cache.utils.js.map +1 -1
- package/build/esm/utils/context-store.utils.d.ts +101 -0
- package/build/esm/utils/context-store.utils.js +182 -0
- package/build/esm/utils/context-store.utils.js.map +1 -1
- package/build/esm/utils/crypto.utils.d.ts +110 -8
- package/build/esm/utils/crypto.utils.js +298 -15
- package/build/esm/utils/crypto.utils.js.map +1 -1
- package/build/esm/utils/decorators.utils.d.ts +40 -0
- package/build/esm/utils/decorators.utils.js +312 -0
- package/build/esm/utils/decorators.utils.js.map +1 -0
- package/build/esm/utils/dir.utils.d.ts +121 -0
- package/build/esm/utils/dir.utils.js +577 -0
- package/build/esm/utils/dir.utils.js.map +1 -1
- package/build/esm/utils/env.utils.d.ts +83 -0
- package/build/esm/utils/env.utils.js +233 -0
- package/build/esm/utils/env.utils.js.map +1 -1
- package/build/esm/utils/exception.utils.d.ts +116 -0
- package/build/esm/utils/exception.utils.js +322 -0
- package/build/esm/utils/exception.utils.js.map +1 -1
- package/build/esm/utils/fs.utils.d.ts +132 -0
- package/build/esm/utils/fs.utils.js +421 -0
- package/build/esm/utils/fs.utils.js.map +1 -1
- package/build/esm/utils/http-status-codes.d.ts +87 -178
- package/build/esm/utils/http-status-codes.js +92 -178
- package/build/esm/utils/http-status-codes.js.map +1 -1
- package/build/esm/utils/id.utils.d.ts +11 -10
- package/build/esm/utils/id.utils.js +29 -20
- package/build/esm/utils/id.utils.js.map +1 -1
- package/build/esm/utils/logger.utils.d.ts +24 -0
- package/build/esm/utils/logger.utils.js +54 -0
- package/build/esm/utils/logger.utils.js.map +1 -1
- package/build/esm/utils/middleware.utils.d.ts +72 -0
- package/build/esm/utils/middleware.utils.js +158 -0
- package/build/esm/utils/middleware.utils.js.map +1 -0
- package/build/esm/utils/obj.utils.d.ts +65 -3
- package/build/esm/utils/obj.utils.js +205 -6
- package/build/esm/utils/obj.utils.js.map +1 -1
- package/build/esm/utils/response.utils.d.ts +101 -0
- package/build/esm/utils/response.utils.js +153 -0
- package/build/esm/utils/response.utils.js.map +1 -1
- package/build/esm/utils/string.utils.d.ts +61 -5
- package/build/esm/utils/string.utils.js +101 -11
- package/build/esm/utils/string.utils.js.map +1 -1
- package/build/esm/utils/url.utils.d.ts +117 -0
- package/build/esm/utils/url.utils.js +287 -0
- package/build/esm/utils/url.utils.js.map +1 -1
- package/build/esm/utils/validate.utils.d.ts +110 -0
- package/build/esm/utils/validate.utils.js +186 -0
- package/build/esm/utils/validate.utils.js.map +1 -1
- package/build/esnext/config.d.ts +12 -0
- package/build/esnext/config.js +12 -0
- package/build/esnext/config.js.map +1 -1
- package/build/esnext/index.d.ts +1 -0
- package/build/esnext/index.js +1 -0
- package/build/esnext/index.js.map +1 -1
- package/build/esnext/types/api-response.d.ts +82 -0
- package/build/esnext/types/api-response.js.map +1 -1
- package/build/esnext/utils/array.utils.d.ts +64 -1
- package/build/esnext/utils/array.utils.js +129 -2
- package/build/esnext/utils/array.utils.js.map +1 -1
- package/build/esnext/utils/async.utils.d.ts +60 -1
- package/build/esnext/utils/async.utils.js +117 -1
- package/build/esnext/utils/async.utils.js.map +1 -1
- package/build/esnext/utils/cache.utils.d.ts +67 -4
- package/build/esnext/utils/cache.utils.js +137 -9
- package/build/esnext/utils/cache.utils.js.map +1 -1
- package/build/esnext/utils/context-store.utils.d.ts +101 -0
- package/build/esnext/utils/context-store.utils.js +168 -0
- package/build/esnext/utils/context-store.utils.js.map +1 -1
- package/build/esnext/utils/crypto.utils.d.ts +110 -8
- package/build/esnext/utils/crypto.utils.js +205 -15
- package/build/esnext/utils/crypto.utils.js.map +1 -1
- package/build/esnext/utils/decorators.utils.d.ts +40 -0
- package/build/esnext/utils/decorators.utils.js +155 -0
- package/build/esnext/utils/decorators.utils.js.map +1 -0
- package/build/esnext/utils/dir.utils.d.ts +121 -0
- package/build/esnext/utils/dir.utils.js +306 -0
- package/build/esnext/utils/dir.utils.js.map +1 -1
- package/build/esnext/utils/env.utils.d.ts +83 -0
- package/build/esnext/utils/env.utils.js +185 -0
- package/build/esnext/utils/env.utils.js.map +1 -1
- package/build/esnext/utils/exception.utils.d.ts +116 -0
- package/build/esnext/utils/exception.utils.js +213 -0
- package/build/esnext/utils/exception.utils.js.map +1 -1
- package/build/esnext/utils/fs.utils.d.ts +132 -0
- package/build/esnext/utils/fs.utils.js +268 -0
- package/build/esnext/utils/fs.utils.js.map +1 -1
- package/build/esnext/utils/http-status-codes.d.ts +87 -178
- package/build/esnext/utils/http-status-codes.js +92 -178
- package/build/esnext/utils/http-status-codes.js.map +1 -1
- package/build/esnext/utils/id.utils.d.ts +11 -10
- package/build/esnext/utils/id.utils.js +27 -19
- package/build/esnext/utils/id.utils.js.map +1 -1
- package/build/esnext/utils/logger.utils.d.ts +24 -0
- package/build/esnext/utils/logger.utils.js +42 -0
- package/build/esnext/utils/logger.utils.js.map +1 -1
- package/build/esnext/utils/middleware.utils.d.ts +72 -0
- package/build/esnext/utils/middleware.utils.js +157 -0
- package/build/esnext/utils/middleware.utils.js.map +1 -0
- package/build/esnext/utils/obj.utils.d.ts +65 -3
- package/build/esnext/utils/obj.utils.js +167 -3
- package/build/esnext/utils/obj.utils.js.map +1 -1
- package/build/esnext/utils/response.utils.d.ts +101 -0
- package/build/esnext/utils/response.utils.js +138 -0
- package/build/esnext/utils/response.utils.js.map +1 -1
- package/build/esnext/utils/string.utils.d.ts +61 -5
- package/build/esnext/utils/string.utils.js +110 -14
- package/build/esnext/utils/string.utils.js.map +1 -1
- package/build/esnext/utils/url.utils.d.ts +117 -0
- package/build/esnext/utils/url.utils.js +248 -0
- package/build/esnext/utils/url.utils.js.map +1 -1
- package/build/esnext/utils/validate.utils.d.ts +110 -0
- package/build/esnext/utils/validate.utils.js +184 -0
- package/build/esnext/utils/validate.utils.js.map +1 -1
- package/build/src/config.d.ts +12 -0
- package/build/src/config.js +12 -0
- package/build/src/config.js.map +1 -1
- package/build/src/index.d.ts +1 -0
- package/build/src/index.js +1 -0
- package/build/src/index.js.map +1 -1
- package/build/src/types/api-response.d.ts +82 -0
- package/build/src/types/api-response.js.map +1 -1
- package/build/src/utils/array.utils.d.ts +64 -1
- package/build/src/utils/array.utils.js +137 -4
- package/build/src/utils/array.utils.js.map +1 -1
- package/build/src/utils/async.utils.d.ts +60 -1
- package/build/src/utils/async.utils.js +124 -4
- package/build/src/utils/async.utils.js.map +1 -1
- package/build/src/utils/cache.utils.d.ts +67 -4
- package/build/src/utils/cache.utils.js +137 -9
- package/build/src/utils/cache.utils.js.map +1 -1
- package/build/src/utils/context-store.utils.d.ts +101 -0
- package/build/src/utils/context-store.utils.js +171 -1
- package/build/src/utils/context-store.utils.js.map +1 -1
- package/build/src/utils/crypto.utils.d.ts +110 -8
- package/build/src/utils/crypto.utils.js +224 -27
- package/build/src/utils/crypto.utils.js.map +1 -1
- package/build/src/utils/decorators.utils.d.ts +40 -0
- package/build/src/utils/decorators.utils.js +165 -0
- package/build/src/utils/decorators.utils.js.map +1 -0
- package/build/src/utils/dir.utils.d.ts +121 -0
- package/build/src/utils/dir.utils.js +316 -0
- package/build/src/utils/dir.utils.js.map +1 -1
- package/build/src/utils/env.utils.d.ts +83 -0
- package/build/src/utils/env.utils.js +186 -1
- package/build/src/utils/env.utils.js.map +1 -1
- package/build/src/utils/exception.utils.d.ts +116 -0
- package/build/src/utils/exception.utils.js +226 -1
- package/build/src/utils/exception.utils.js.map +1 -1
- package/build/src/utils/fs.utils.d.ts +132 -0
- package/build/src/utils/fs.utils.js +282 -0
- package/build/src/utils/fs.utils.js.map +1 -1
- package/build/src/utils/http-status-codes.d.ts +87 -178
- package/build/src/utils/http-status-codes.js +92 -178
- package/build/src/utils/http-status-codes.js.map +1 -1
- package/build/src/utils/id.utils.d.ts +11 -10
- package/build/src/utils/id.utils.js +27 -19
- package/build/src/utils/id.utils.js.map +1 -1
- package/build/src/utils/logger.utils.d.ts +24 -0
- package/build/src/utils/logger.utils.js +45 -0
- package/build/src/utils/logger.utils.js.map +1 -1
- package/build/src/utils/middleware.utils.d.ts +72 -0
- package/build/src/utils/middleware.utils.js +163 -0
- package/build/src/utils/middleware.utils.js.map +1 -0
- package/build/src/utils/obj.utils.d.ts +65 -3
- package/build/src/utils/obj.utils.js +177 -7
- package/build/src/utils/obj.utils.js.map +1 -1
- package/build/src/utils/response.utils.d.ts +101 -0
- package/build/src/utils/response.utils.js +146 -1
- package/build/src/utils/response.utils.js.map +1 -1
- package/build/src/utils/string.utils.d.ts +61 -5
- package/build/src/utils/string.utils.js +122 -20
- package/build/src/utils/string.utils.js.map +1 -1
- package/build/src/utils/url.utils.d.ts +117 -0
- package/build/src/utils/url.utils.js +257 -0
- package/build/src/utils/url.utils.js.map +1 -1
- package/build/src/utils/validate.utils.d.ts +110 -0
- package/build/src/utils/validate.utils.js +198 -0
- package/build/src/utils/validate.utils.js.map +1 -1
- package/package.json +20 -12
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
1
12
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
13
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
14
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -70,9 +81,12 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
70
81
|
}
|
|
71
82
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
72
83
|
};
|
|
84
|
+
import os from "os";
|
|
73
85
|
import fs from "fs";
|
|
74
86
|
import fsp from "fs/promises";
|
|
75
87
|
import path from "path";
|
|
88
|
+
import { glob } from "glob";
|
|
89
|
+
import { randomBytes } from "crypto";
|
|
76
90
|
/**
|
|
77
91
|
* Ensures that a directory exists, creating parent directories if needed (like `mkdir -p`).
|
|
78
92
|
*
|
|
@@ -397,4 +411,567 @@ export function watchDir(dirPath, callback) {
|
|
|
397
411
|
});
|
|
398
412
|
return function () { return watcher.close(); };
|
|
399
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Finds files matching a glob pattern.
|
|
416
|
+
*
|
|
417
|
+
* @param {string} pattern - Glob pattern to match files.
|
|
418
|
+
* @param {object} [options] - Options for glob pattern matching.
|
|
419
|
+
* @param {string} [options.cwd] - Current working directory for relative patterns.
|
|
420
|
+
* @param {boolean} [options.dot=false] - Include dotfiles in matches.
|
|
421
|
+
* @param {boolean} [options.nodir=true] - Only match files, not directories.
|
|
422
|
+
* @returns {Promise<string[]>} Array of matched file paths.
|
|
423
|
+
* @throws {Error} If pattern matching fails.
|
|
424
|
+
*/
|
|
425
|
+
export function findFilesByPattern(pattern_1) {
|
|
426
|
+
return __awaiter(this, arguments, void 0, function (pattern, options) {
|
|
427
|
+
var defaultOptions;
|
|
428
|
+
if (options === void 0) { options = {}; }
|
|
429
|
+
return __generator(this, function (_a) {
|
|
430
|
+
defaultOptions = __assign({ nodir: true }, options);
|
|
431
|
+
return [2 /*return*/, glob(pattern, defaultOptions)];
|
|
432
|
+
});
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Gets all subdirectories in a directory.
|
|
437
|
+
*
|
|
438
|
+
* @param {string} dirPath - The directory to search in.
|
|
439
|
+
* @param {boolean} [recursive=false] - Whether to include subdirectories recursively.
|
|
440
|
+
* @returns {Promise<string[]>} Array of absolute subdirectory paths.
|
|
441
|
+
* @throws {Error} If directory cannot be read.
|
|
442
|
+
*/
|
|
443
|
+
export function getSubdirectories(dirPath_1) {
|
|
444
|
+
return __awaiter(this, arguments, void 0, function (dirPath, recursive) {
|
|
445
|
+
var entries, dirs, nestedDirs;
|
|
446
|
+
if (recursive === void 0) { recursive = false; }
|
|
447
|
+
return __generator(this, function (_a) {
|
|
448
|
+
switch (_a.label) {
|
|
449
|
+
case 0: return [4 /*yield*/, fsp.readdir(dirPath, { withFileTypes: true })];
|
|
450
|
+
case 1:
|
|
451
|
+
entries = _a.sent();
|
|
452
|
+
dirs = entries
|
|
453
|
+
.filter(function (entry) { return entry.isDirectory(); })
|
|
454
|
+
.map(function (entry) { return path.join(dirPath, entry.name); });
|
|
455
|
+
if (!(recursive && dirs.length > 0)) return [3 /*break*/, 3];
|
|
456
|
+
return [4 /*yield*/, Promise.all(dirs.map(function (dir) { return getSubdirectories(dir, true); }))];
|
|
457
|
+
case 2:
|
|
458
|
+
nestedDirs = _a.sent();
|
|
459
|
+
return [2 /*return*/, __spreadArray(__spreadArray([], __read(dirs), false), __read(nestedDirs.flat()), false)];
|
|
460
|
+
case 3: return [2 /*return*/, dirs];
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Ensures a directory exists and is empty.
|
|
467
|
+
*
|
|
468
|
+
* @param {string} dirPath - Path to the directory.
|
|
469
|
+
* @returns {Promise<void>} Resolves when the directory exists and is empty.
|
|
470
|
+
* @throws {Error} If directory cannot be created or emptied.
|
|
471
|
+
*/
|
|
472
|
+
export function ensureEmptyDir(dirPath) {
|
|
473
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
474
|
+
var error_1;
|
|
475
|
+
return __generator(this, function (_a) {
|
|
476
|
+
switch (_a.label) {
|
|
477
|
+
case 0: return [4 /*yield*/, isDirectory(dirPath)];
|
|
478
|
+
case 1:
|
|
479
|
+
if (!_a.sent()) return [3 /*break*/, 3];
|
|
480
|
+
return [4 /*yield*/, emptyDir(dirPath)];
|
|
481
|
+
case 2:
|
|
482
|
+
_a.sent();
|
|
483
|
+
return [3 /*break*/, 8];
|
|
484
|
+
case 3:
|
|
485
|
+
_a.trys.push([3, 5, , 6]);
|
|
486
|
+
return [4 /*yield*/, fsp.unlink(dirPath)];
|
|
487
|
+
case 4:
|
|
488
|
+
_a.sent();
|
|
489
|
+
return [3 /*break*/, 6];
|
|
490
|
+
case 5:
|
|
491
|
+
error_1 = _a.sent();
|
|
492
|
+
// Ignore if file doesn't exist
|
|
493
|
+
if (error_1.code !== "ENOENT") {
|
|
494
|
+
throw error_1;
|
|
495
|
+
}
|
|
496
|
+
return [3 /*break*/, 6];
|
|
497
|
+
case 6: return [4 /*yield*/, ensureDir(dirPath)];
|
|
498
|
+
case 7:
|
|
499
|
+
_a.sent();
|
|
500
|
+
_a.label = 8;
|
|
501
|
+
case 8: return [2 /*return*/];
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Creates a temporary directory with optional auto-cleanup.
|
|
508
|
+
*
|
|
509
|
+
* @param {object} [options] - Options for the temporary directory.
|
|
510
|
+
* @param {string} [options.prefix='tmp-'] - Prefix for the directory name.
|
|
511
|
+
* @param {string} [options.parentDir=os.tmpdir()] - Parent directory.
|
|
512
|
+
* @param {boolean} [options.cleanup=false] - Whether to register cleanup on process exit.
|
|
513
|
+
* @returns {Promise<{ path: string, cleanup: () => Promise<void> }>} Object with directory path and cleanup function.
|
|
514
|
+
* @throws {Error} If directory cannot be created.
|
|
515
|
+
*/
|
|
516
|
+
export function createTempDir() {
|
|
517
|
+
return __awaiter(this, arguments, void 0, function (options) {
|
|
518
|
+
var prefix, parentDir, dirName, tempDirPath, cleanup;
|
|
519
|
+
var _this = this;
|
|
520
|
+
if (options === void 0) { options = {}; }
|
|
521
|
+
return __generator(this, function (_a) {
|
|
522
|
+
switch (_a.label) {
|
|
523
|
+
case 0:
|
|
524
|
+
prefix = options.prefix || "tmp-";
|
|
525
|
+
parentDir = options.parentDir || os.tmpdir();
|
|
526
|
+
dirName = "".concat(prefix).concat(randomBytes(6).toString("hex"));
|
|
527
|
+
tempDirPath = path.join(parentDir, dirName);
|
|
528
|
+
return [4 /*yield*/, ensureDir(tempDirPath)];
|
|
529
|
+
case 1:
|
|
530
|
+
_a.sent();
|
|
531
|
+
cleanup = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
532
|
+
var _a;
|
|
533
|
+
return __generator(this, function (_b) {
|
|
534
|
+
switch (_b.label) {
|
|
535
|
+
case 0:
|
|
536
|
+
_b.trys.push([0, 2, , 3]);
|
|
537
|
+
return [4 /*yield*/, deleteDirRecursive(tempDirPath)];
|
|
538
|
+
case 1:
|
|
539
|
+
_b.sent();
|
|
540
|
+
return [3 /*break*/, 3];
|
|
541
|
+
case 2:
|
|
542
|
+
_a = _b.sent();
|
|
543
|
+
return [3 /*break*/, 3];
|
|
544
|
+
case 3: return [2 /*return*/];
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
}); };
|
|
548
|
+
if (options.cleanup) {
|
|
549
|
+
process.once("exit", function () {
|
|
550
|
+
try {
|
|
551
|
+
fs.rmSync(tempDirPath, { recursive: true, force: true });
|
|
552
|
+
}
|
|
553
|
+
catch (_a) {
|
|
554
|
+
// Ignore cleanup errors on exit
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
// Handle signals for better cleanup
|
|
558
|
+
["SIGINT", "SIGTERM", "SIGUSR1", "SIGUSR2"].forEach(function (signal) {
|
|
559
|
+
process.once(signal, function () {
|
|
560
|
+
cleanup().then(function () { return process.exit(); });
|
|
561
|
+
});
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
return [2 /*return*/, { path: tempDirPath, cleanup: cleanup }];
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Finds the newest file in a directory.
|
|
571
|
+
*
|
|
572
|
+
* @param {string} dirPath - Directory to search.
|
|
573
|
+
* @param {boolean} [recursive=false] - Whether to search subdirectories.
|
|
574
|
+
* @returns {Promise<string | null>} Path to the newest file or null if no files.
|
|
575
|
+
* @throws {Error} If directory cannot be read.
|
|
576
|
+
*/
|
|
577
|
+
export function findNewestFile(dirPath_1) {
|
|
578
|
+
return __awaiter(this, arguments, void 0, function (dirPath, recursive) {
|
|
579
|
+
var files, stats;
|
|
580
|
+
var _this = this;
|
|
581
|
+
if (recursive === void 0) { recursive = false; }
|
|
582
|
+
return __generator(this, function (_a) {
|
|
583
|
+
switch (_a.label) {
|
|
584
|
+
case 0: return [4 /*yield*/, listFiles(dirPath, recursive)];
|
|
585
|
+
case 1:
|
|
586
|
+
files = _a.sent();
|
|
587
|
+
if (files.length === 0)
|
|
588
|
+
return [2 /*return*/, null];
|
|
589
|
+
return [4 /*yield*/, Promise.all(files.map(function (file) { return __awaiter(_this, void 0, void 0, function () {
|
|
590
|
+
var _a;
|
|
591
|
+
return __generator(this, function (_b) {
|
|
592
|
+
switch (_b.label) {
|
|
593
|
+
case 0:
|
|
594
|
+
_a = {
|
|
595
|
+
path: file
|
|
596
|
+
};
|
|
597
|
+
return [4 /*yield*/, fsp.stat(file)];
|
|
598
|
+
case 1: return [2 /*return*/, (_a.mtime = (_b.sent()).mtime,
|
|
599
|
+
_a)];
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
}); }))];
|
|
603
|
+
case 2:
|
|
604
|
+
stats = _a.sent();
|
|
605
|
+
return [2 /*return*/, stats.sort(function (a, b) { return b.mtime.getTime() - a.mtime.getTime(); })[0].path];
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Finds the oldest file in a directory.
|
|
612
|
+
*
|
|
613
|
+
* @param {string} dirPath - Directory to search.
|
|
614
|
+
* @param {boolean} [recursive=false] - Whether to search subdirectories.
|
|
615
|
+
* @returns {Promise<string | null>} Path to the oldest file or null if no files.
|
|
616
|
+
* @throws {Error} If directory cannot be read.
|
|
617
|
+
*/
|
|
618
|
+
export function findOldestFile(dirPath_1) {
|
|
619
|
+
return __awaiter(this, arguments, void 0, function (dirPath, recursive) {
|
|
620
|
+
var files, stats;
|
|
621
|
+
var _this = this;
|
|
622
|
+
if (recursive === void 0) { recursive = false; }
|
|
623
|
+
return __generator(this, function (_a) {
|
|
624
|
+
switch (_a.label) {
|
|
625
|
+
case 0: return [4 /*yield*/, listFiles(dirPath, recursive)];
|
|
626
|
+
case 1:
|
|
627
|
+
files = _a.sent();
|
|
628
|
+
if (files.length === 0)
|
|
629
|
+
return [2 /*return*/, null];
|
|
630
|
+
return [4 /*yield*/, Promise.all(files.map(function (file) { return __awaiter(_this, void 0, void 0, function () {
|
|
631
|
+
var _a;
|
|
632
|
+
return __generator(this, function (_b) {
|
|
633
|
+
switch (_b.label) {
|
|
634
|
+
case 0:
|
|
635
|
+
_a = {
|
|
636
|
+
path: file
|
|
637
|
+
};
|
|
638
|
+
return [4 /*yield*/, fsp.stat(file)];
|
|
639
|
+
case 1: return [2 /*return*/, (_a.mtime = (_b.sent()).mtime,
|
|
640
|
+
_a)];
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
}); }))];
|
|
644
|
+
case 2:
|
|
645
|
+
stats = _a.sent();
|
|
646
|
+
return [2 /*return*/, stats.sort(function (a, b) { return a.mtime.getTime() - b.mtime.getTime(); })[0].path];
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Finds files or directories in a directory matching a predicate function.
|
|
653
|
+
*
|
|
654
|
+
* @param {string} dirPath - Directory to search.
|
|
655
|
+
* @param {(path: string, stat: fs.Stats) => boolean | Promise<boolean>} predicate - Function to test each path.
|
|
656
|
+
* @param {boolean} [recursive=false] - Whether to search subdirectories.
|
|
657
|
+
* @returns {Promise<string[]>} Array of matching paths.
|
|
658
|
+
* @throws {Error} If directory cannot be read.
|
|
659
|
+
*/
|
|
660
|
+
export function findInDir(dirPath_1, predicate_1) {
|
|
661
|
+
return __awaiter(this, arguments, void 0, function (dirPath, predicate, recursive) {
|
|
662
|
+
var entries, results, entries_5, entries_5_1, entry, entryPath, stat, nestedResults, e_5_1;
|
|
663
|
+
var e_5, _a;
|
|
664
|
+
if (recursive === void 0) { recursive = false; }
|
|
665
|
+
return __generator(this, function (_b) {
|
|
666
|
+
switch (_b.label) {
|
|
667
|
+
case 0: return [4 /*yield*/, fsp.readdir(dirPath, { withFileTypes: true })];
|
|
668
|
+
case 1:
|
|
669
|
+
entries = _b.sent();
|
|
670
|
+
results = [];
|
|
671
|
+
_b.label = 2;
|
|
672
|
+
case 2:
|
|
673
|
+
_b.trys.push([2, 9, 10, 11]);
|
|
674
|
+
entries_5 = __values(entries), entries_5_1 = entries_5.next();
|
|
675
|
+
_b.label = 3;
|
|
676
|
+
case 3:
|
|
677
|
+
if (!!entries_5_1.done) return [3 /*break*/, 8];
|
|
678
|
+
entry = entries_5_1.value;
|
|
679
|
+
entryPath = path.join(dirPath, entry.name);
|
|
680
|
+
return [4 /*yield*/, fsp.stat(entryPath)];
|
|
681
|
+
case 4:
|
|
682
|
+
stat = _b.sent();
|
|
683
|
+
return [4 /*yield*/, predicate(entryPath, stat)];
|
|
684
|
+
case 5:
|
|
685
|
+
if (_b.sent()) {
|
|
686
|
+
results.push(entryPath);
|
|
687
|
+
}
|
|
688
|
+
if (!(recursive && entry.isDirectory())) return [3 /*break*/, 7];
|
|
689
|
+
return [4 /*yield*/, findInDir(entryPath, predicate, true)];
|
|
690
|
+
case 6:
|
|
691
|
+
nestedResults = _b.sent();
|
|
692
|
+
results.push.apply(results, __spreadArray([], __read(nestedResults), false));
|
|
693
|
+
_b.label = 7;
|
|
694
|
+
case 7:
|
|
695
|
+
entries_5_1 = entries_5.next();
|
|
696
|
+
return [3 /*break*/, 3];
|
|
697
|
+
case 8: return [3 /*break*/, 11];
|
|
698
|
+
case 9:
|
|
699
|
+
e_5_1 = _b.sent();
|
|
700
|
+
e_5 = { error: e_5_1 };
|
|
701
|
+
return [3 /*break*/, 11];
|
|
702
|
+
case 10:
|
|
703
|
+
try {
|
|
704
|
+
if (entries_5_1 && !entries_5_1.done && (_a = entries_5.return)) _a.call(entries_5);
|
|
705
|
+
}
|
|
706
|
+
finally { if (e_5) throw e_5.error; }
|
|
707
|
+
return [7 /*endfinally*/];
|
|
708
|
+
case 11: return [2 /*return*/, results];
|
|
709
|
+
}
|
|
710
|
+
});
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Watches a directory recursively for file changes.
|
|
715
|
+
*
|
|
716
|
+
* @param {string} dirPath - Base directory path to watch.
|
|
717
|
+
* @param {(eventType: "rename" | "change", filename: string) => void} callback - Callback for each change event.
|
|
718
|
+
* @param {boolean} [includeSubdirs=true] - Whether to watch subdirectories.
|
|
719
|
+
* @returns {Promise<() => void>} A function to stop watching the directory.
|
|
720
|
+
* @throws {Error} If directory cannot be watched.
|
|
721
|
+
*/
|
|
722
|
+
export function watchDirRecursive(dirPath_1, callback_1) {
|
|
723
|
+
return __awaiter(this, arguments, void 0, function (dirPath, callback, includeSubdirs) {
|
|
724
|
+
var normalizedBasePath, watchers, addWatcher, subdirs, subdirs_1, subdirs_1_1, subdir;
|
|
725
|
+
var e_6, _a;
|
|
726
|
+
var _this = this;
|
|
727
|
+
if (includeSubdirs === void 0) { includeSubdirs = true; }
|
|
728
|
+
return __generator(this, function (_b) {
|
|
729
|
+
switch (_b.label) {
|
|
730
|
+
case 0:
|
|
731
|
+
normalizedBasePath = path.normalize(dirPath);
|
|
732
|
+
watchers = [];
|
|
733
|
+
addWatcher = function (dir) {
|
|
734
|
+
try {
|
|
735
|
+
var watcher = fs.watch(dir, function (eventType, filename) {
|
|
736
|
+
if (!filename)
|
|
737
|
+
return;
|
|
738
|
+
var fullPath = path.join(dir, filename);
|
|
739
|
+
// Make the path relative to the base directory
|
|
740
|
+
var relativePath = path.relative(normalizedBasePath, fullPath);
|
|
741
|
+
callback(eventType, relativePath);
|
|
742
|
+
// If a new directory is created, we should watch it
|
|
743
|
+
if (eventType === "rename" && includeSubdirs) {
|
|
744
|
+
setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
745
|
+
var _a;
|
|
746
|
+
return __generator(this, function (_b) {
|
|
747
|
+
switch (_b.label) {
|
|
748
|
+
case 0:
|
|
749
|
+
_b.trys.push([0, 2, , 3]);
|
|
750
|
+
return [4 /*yield*/, isDirectory(fullPath)];
|
|
751
|
+
case 1:
|
|
752
|
+
if (_b.sent()) {
|
|
753
|
+
addWatcher(fullPath);
|
|
754
|
+
}
|
|
755
|
+
return [3 /*break*/, 3];
|
|
756
|
+
case 2:
|
|
757
|
+
_a = _b.sent();
|
|
758
|
+
return [3 /*break*/, 3];
|
|
759
|
+
case 3: return [2 /*return*/];
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
}); }, 100);
|
|
763
|
+
}
|
|
764
|
+
});
|
|
765
|
+
watchers.push(watcher);
|
|
766
|
+
}
|
|
767
|
+
catch (_a) {
|
|
768
|
+
// Silently ignore directories we can't watch
|
|
769
|
+
}
|
|
770
|
+
};
|
|
771
|
+
// Add watcher for the base directory
|
|
772
|
+
addWatcher(normalizedBasePath);
|
|
773
|
+
if (!includeSubdirs) return [3 /*break*/, 2];
|
|
774
|
+
return [4 /*yield*/, getSubdirectories(normalizedBasePath, true)];
|
|
775
|
+
case 1:
|
|
776
|
+
subdirs = _b.sent();
|
|
777
|
+
try {
|
|
778
|
+
for (subdirs_1 = __values(subdirs), subdirs_1_1 = subdirs_1.next(); !subdirs_1_1.done; subdirs_1_1 = subdirs_1.next()) {
|
|
779
|
+
subdir = subdirs_1_1.value;
|
|
780
|
+
addWatcher(subdir);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
784
|
+
finally {
|
|
785
|
+
try {
|
|
786
|
+
if (subdirs_1_1 && !subdirs_1_1.done && (_a = subdirs_1.return)) _a.call(subdirs_1);
|
|
787
|
+
}
|
|
788
|
+
finally { if (e_6) throw e_6.error; }
|
|
789
|
+
}
|
|
790
|
+
_b.label = 2;
|
|
791
|
+
case 2:
|
|
792
|
+
// Return a function to close all watchers
|
|
793
|
+
return [2 /*return*/, function () {
|
|
794
|
+
watchers.forEach(function (watcher) { return watcher.close(); });
|
|
795
|
+
}];
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
/**
|
|
801
|
+
* Gets detailed directory statistics including file count, directory count, and size.
|
|
802
|
+
*
|
|
803
|
+
* @param {string} dirPath - Path to the directory.
|
|
804
|
+
* @returns {Promise<{ fileCount: number, dirCount: number, totalSize: number }>} Directory statistics.
|
|
805
|
+
* @throws {Error} If directory cannot be read.
|
|
806
|
+
*/
|
|
807
|
+
export function getDirStats(dirPath) {
|
|
808
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
809
|
+
function processDir(currentPath) {
|
|
810
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
811
|
+
var entries, entries_6, entries_6_1, entry, entryPath, stat, e_7_1;
|
|
812
|
+
var e_7, _a;
|
|
813
|
+
return __generator(this, function (_b) {
|
|
814
|
+
switch (_b.label) {
|
|
815
|
+
case 0: return [4 /*yield*/, fsp.readdir(currentPath, { withFileTypes: true })];
|
|
816
|
+
case 1:
|
|
817
|
+
entries = _b.sent();
|
|
818
|
+
_b.label = 2;
|
|
819
|
+
case 2:
|
|
820
|
+
_b.trys.push([2, 9, 10, 11]);
|
|
821
|
+
entries_6 = __values(entries), entries_6_1 = entries_6.next();
|
|
822
|
+
_b.label = 3;
|
|
823
|
+
case 3:
|
|
824
|
+
if (!!entries_6_1.done) return [3 /*break*/, 8];
|
|
825
|
+
entry = entries_6_1.value;
|
|
826
|
+
entryPath = path.join(currentPath, entry.name);
|
|
827
|
+
if (!entry.isDirectory()) return [3 /*break*/, 5];
|
|
828
|
+
dirCount++;
|
|
829
|
+
return [4 /*yield*/, processDir(entryPath)];
|
|
830
|
+
case 4:
|
|
831
|
+
_b.sent();
|
|
832
|
+
return [3 /*break*/, 7];
|
|
833
|
+
case 5:
|
|
834
|
+
if (!entry.isFile()) return [3 /*break*/, 7];
|
|
835
|
+
fileCount++;
|
|
836
|
+
return [4 /*yield*/, fsp.stat(entryPath)];
|
|
837
|
+
case 6:
|
|
838
|
+
stat = _b.sent();
|
|
839
|
+
totalSize += stat.size;
|
|
840
|
+
_b.label = 7;
|
|
841
|
+
case 7:
|
|
842
|
+
entries_6_1 = entries_6.next();
|
|
843
|
+
return [3 /*break*/, 3];
|
|
844
|
+
case 8: return [3 /*break*/, 11];
|
|
845
|
+
case 9:
|
|
846
|
+
e_7_1 = _b.sent();
|
|
847
|
+
e_7 = { error: e_7_1 };
|
|
848
|
+
return [3 /*break*/, 11];
|
|
849
|
+
case 10:
|
|
850
|
+
try {
|
|
851
|
+
if (entries_6_1 && !entries_6_1.done && (_a = entries_6.return)) _a.call(entries_6);
|
|
852
|
+
}
|
|
853
|
+
finally { if (e_7) throw e_7.error; }
|
|
854
|
+
return [7 /*endfinally*/];
|
|
855
|
+
case 11: return [2 /*return*/];
|
|
856
|
+
}
|
|
857
|
+
});
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
var fileCount, dirCount, totalSize;
|
|
861
|
+
return __generator(this, function (_a) {
|
|
862
|
+
switch (_a.label) {
|
|
863
|
+
case 0:
|
|
864
|
+
fileCount = 0;
|
|
865
|
+
dirCount = 0;
|
|
866
|
+
totalSize = 0;
|
|
867
|
+
return [4 /*yield*/, processDir(dirPath)];
|
|
868
|
+
case 1:
|
|
869
|
+
_a.sent();
|
|
870
|
+
return [2 /*return*/, { fileCount: fileCount, dirCount: dirCount, totalSize: totalSize }];
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
* Walks through a directory hierarchy, calling a visitor function for each entry.
|
|
877
|
+
*
|
|
878
|
+
* @param {string} dirPath - Starting directory path.
|
|
879
|
+
* @param {object} options - Options for walking the directory.
|
|
880
|
+
* @param {(entry: { path: string, name: string, isDirectory: boolean, stats: fs.Stats }) => boolean | void | Promise<boolean | void>} options.visitorFn -
|
|
881
|
+
* Function called for each file/directory. Return false to skip a directory.
|
|
882
|
+
* @param {'pre' | 'post'} [options.traversalOrder='pre'] - Whether to visit directories before or after their contents.
|
|
883
|
+
* @throws {Error} If directory cannot be read.
|
|
884
|
+
*/
|
|
885
|
+
export function walkDir(dirPath, options) {
|
|
886
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
887
|
+
var traversalOrder, entries, entries_7, entries_7_1, entry, entryPath, stats, entryInfo, shouldContinue, e_8_1, stats, entryInfo;
|
|
888
|
+
var e_8, _a;
|
|
889
|
+
return __generator(this, function (_b) {
|
|
890
|
+
switch (_b.label) {
|
|
891
|
+
case 0:
|
|
892
|
+
traversalOrder = options.traversalOrder || "pre";
|
|
893
|
+
return [4 /*yield*/, fsp.readdir(dirPath, { withFileTypes: true })];
|
|
894
|
+
case 1:
|
|
895
|
+
entries = _b.sent();
|
|
896
|
+
_b.label = 2;
|
|
897
|
+
case 2:
|
|
898
|
+
_b.trys.push([2, 16, 17, 18]);
|
|
899
|
+
entries_7 = __values(entries), entries_7_1 = entries_7.next();
|
|
900
|
+
_b.label = 3;
|
|
901
|
+
case 3:
|
|
902
|
+
if (!!entries_7_1.done) return [3 /*break*/, 15];
|
|
903
|
+
entry = entries_7_1.value;
|
|
904
|
+
entryPath = path.join(dirPath, entry.name);
|
|
905
|
+
return [4 /*yield*/, fsp.stat(entryPath)];
|
|
906
|
+
case 4:
|
|
907
|
+
stats = _b.sent();
|
|
908
|
+
entryInfo = {
|
|
909
|
+
path: entryPath,
|
|
910
|
+
name: entry.name,
|
|
911
|
+
isDirectory: entry.isDirectory(),
|
|
912
|
+
stats: stats,
|
|
913
|
+
};
|
|
914
|
+
if (!entry.isDirectory()) return [3 /*break*/, 12];
|
|
915
|
+
if (!(traversalOrder === "pre")) return [3 /*break*/, 8];
|
|
916
|
+
return [4 /*yield*/, options.visitorFn(entryInfo)];
|
|
917
|
+
case 5:
|
|
918
|
+
shouldContinue = _b.sent();
|
|
919
|
+
if (!(shouldContinue !== false)) return [3 /*break*/, 7];
|
|
920
|
+
return [4 /*yield*/, walkDir(entryPath, options)];
|
|
921
|
+
case 6:
|
|
922
|
+
_b.sent();
|
|
923
|
+
_b.label = 7;
|
|
924
|
+
case 7: return [3 /*break*/, 11];
|
|
925
|
+
case 8:
|
|
926
|
+
// Post-order: visit directory after its contents
|
|
927
|
+
return [4 /*yield*/, walkDir(entryPath, options)];
|
|
928
|
+
case 9:
|
|
929
|
+
// Post-order: visit directory after its contents
|
|
930
|
+
_b.sent();
|
|
931
|
+
return [4 /*yield*/, options.visitorFn(entryInfo)];
|
|
932
|
+
case 10:
|
|
933
|
+
_b.sent();
|
|
934
|
+
_b.label = 11;
|
|
935
|
+
case 11: return [3 /*break*/, 14];
|
|
936
|
+
case 12:
|
|
937
|
+
// Files are always visited when encountered
|
|
938
|
+
return [4 /*yield*/, options.visitorFn(entryInfo)];
|
|
939
|
+
case 13:
|
|
940
|
+
// Files are always visited when encountered
|
|
941
|
+
_b.sent();
|
|
942
|
+
_b.label = 14;
|
|
943
|
+
case 14:
|
|
944
|
+
entries_7_1 = entries_7.next();
|
|
945
|
+
return [3 /*break*/, 3];
|
|
946
|
+
case 15: return [3 /*break*/, 18];
|
|
947
|
+
case 16:
|
|
948
|
+
e_8_1 = _b.sent();
|
|
949
|
+
e_8 = { error: e_8_1 };
|
|
950
|
+
return [3 /*break*/, 18];
|
|
951
|
+
case 17:
|
|
952
|
+
try {
|
|
953
|
+
if (entries_7_1 && !entries_7_1.done && (_a = entries_7.return)) _a.call(entries_7);
|
|
954
|
+
}
|
|
955
|
+
finally { if (e_8) throw e_8.error; }
|
|
956
|
+
return [7 /*endfinally*/];
|
|
957
|
+
case 18:
|
|
958
|
+
if (!(traversalOrder === "post")) return [3 /*break*/, 21];
|
|
959
|
+
return [4 /*yield*/, fsp.stat(dirPath)];
|
|
960
|
+
case 19:
|
|
961
|
+
stats = _b.sent();
|
|
962
|
+
entryInfo = {
|
|
963
|
+
path: dirPath,
|
|
964
|
+
name: path.basename(dirPath),
|
|
965
|
+
isDirectory: true,
|
|
966
|
+
stats: stats,
|
|
967
|
+
};
|
|
968
|
+
return [4 /*yield*/, options.visitorFn(entryInfo)];
|
|
969
|
+
case 20:
|
|
970
|
+
_b.sent();
|
|
971
|
+
_b.label = 21;
|
|
972
|
+
case 21: return [2 /*return*/];
|
|
973
|
+
}
|
|
974
|
+
});
|
|
975
|
+
});
|
|
976
|
+
}
|
|
400
977
|
//# sourceMappingURL=dir.utils.js.map
|