@photostructure/fs-metadata 0.1.2 → 0.1.4
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/binding.gyp +13 -0
- package/dist/cjs/array.cjs +57 -0
- package/dist/cjs/array.js.map +1 -0
- package/dist/cjs/async.cjs +116 -0
- package/dist/cjs/async.js.map +1 -0
- package/dist/cjs/cache.cjs +28 -0
- package/dist/cjs/cache.js.map +1 -0
- package/dist/cjs/debuglog.cjs +35 -0
- package/dist/cjs/debuglog.js.map +1 -0
- package/dist/cjs/defer.cjs +26 -0
- package/dist/cjs/defer.js.map +1 -0
- package/dist/cjs/error.cjs +63 -0
- package/dist/cjs/error.js.map +1 -0
- package/dist/cjs/exports.cjs +14 -0
- package/dist/cjs/exports.js.map +1 -0
- package/dist/cjs/fs.cjs +81 -0
- package/dist/cjs/fs.js.map +1 -0
- package/dist/cjs/glob.cjs +117 -0
- package/dist/cjs/glob.js.map +1 -0
- package/dist/cjs/hidden.cjs +163 -0
- package/dist/cjs/hidden.js.map +1 -0
- package/dist/cjs/index.cjs +23 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/linux/dev_disk.cjs +66 -0
- package/dist/cjs/linux/dev_disk.js.map +1 -0
- package/dist/cjs/linux/mount_points.cjs +81 -0
- package/dist/cjs/linux/mount_points.js.map +1 -0
- package/dist/cjs/linux/mtab.cjs +88 -0
- package/dist/cjs/linux/mtab.js.map +1 -0
- package/dist/cjs/mount_point.cjs +67 -0
- package/dist/cjs/mount_point.js.map +1 -0
- package/dist/cjs/number.cjs +41 -0
- package/dist/cjs/number.js.map +1 -0
- package/dist/cjs/object.cjs +59 -0
- package/dist/cjs/object.js.map +1 -0
- package/dist/cjs/options.cjs +115 -0
- package/dist/cjs/options.js.map +1 -0
- package/dist/cjs/path.cjs +50 -0
- package/dist/cjs/path.js.map +1 -0
- package/dist/cjs/platform.cjs +10 -0
- package/dist/cjs/platform.js.map +1 -0
- package/dist/cjs/random.cjs +43 -0
- package/dist/cjs/random.js.map +1 -0
- package/dist/cjs/remote_info.cjs +123 -0
- package/dist/cjs/remote_info.js.map +1 -0
- package/dist/cjs/setup.cjs +47 -0
- package/dist/cjs/setup.js.map +1 -0
- package/dist/cjs/string.cjs +89 -0
- package/dist/cjs/string.js.map +1 -0
- package/dist/cjs/string_enum.cjs +27 -0
- package/dist/cjs/string_enum.js.map +1 -0
- package/dist/cjs/system_volume.cjs +44 -0
- package/dist/cjs/system_volume.js.map +1 -0
- package/dist/cjs/types/native_bindings.cjs +4 -0
- package/dist/cjs/types/native_bindings.js.map +1 -0
- package/dist/cjs/unc.cjs +52 -0
- package/dist/cjs/unc.js.map +1 -0
- package/dist/cjs/units.cjs +35 -0
- package/dist/cjs/units.js.map +1 -0
- package/dist/cjs/uuid.cjs +25 -0
- package/dist/cjs/uuid.js.map +1 -0
- package/dist/cjs/volume_health_status.cjs +50 -0
- package/dist/cjs/volume_health_status.js.map +1 -0
- package/dist/cjs/volume_metadata.cjs +169 -0
- package/dist/cjs/volume_metadata.js.map +1 -0
- package/dist/esm/array.js +50 -0
- package/dist/esm/array.js.map +1 -0
- package/dist/esm/async.js +109 -0
- package/dist/esm/async.js.map +1 -0
- package/dist/esm/cache.js +25 -0
- package/dist/esm/cache.js.map +1 -0
- package/dist/esm/debuglog.js +30 -0
- package/dist/esm/debuglog.js.map +1 -0
- package/dist/esm/defer.js +23 -0
- package/dist/esm/defer.js.map +1 -0
- package/dist/esm/error.js +58 -0
- package/dist/esm/error.js.map +1 -0
- package/dist/esm/exports.js +4 -0
- package/dist/esm/exports.js.map +1 -0
- package/dist/esm/fs.js +73 -0
- package/dist/esm/fs.js.map +1 -0
- package/dist/esm/glob.js +113 -0
- package/dist/esm/glob.js.map +1 -0
- package/dist/esm/hidden.js +155 -0
- package/dist/esm/hidden.js.map +1 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/linux/dev_disk.js +61 -0
- package/dist/esm/linux/dev_disk.js.map +1 -0
- package/dist/esm/linux/mount_points.js +77 -0
- package/dist/esm/linux/mount_points.js.map +1 -0
- package/dist/esm/linux/mtab.js +82 -0
- package/dist/esm/linux/mtab.js.map +1 -0
- package/dist/esm/mount_point.js +63 -0
- package/dist/esm/mount_point.js.map +1 -0
- package/dist/esm/number.js +32 -0
- package/dist/esm/number.js.map +1 -0
- package/dist/esm/object.js +52 -0
- package/dist/esm/object.js.map +1 -0
- package/dist/esm/options.js +111 -0
- package/dist/esm/options.js.map +1 -0
- package/dist/esm/path.js +44 -0
- package/dist/esm/path.js.map +1 -0
- package/dist/esm/platform.js +7 -0
- package/dist/esm/platform.js.map +1 -0
- package/dist/esm/random.js +37 -0
- package/dist/esm/random.js.map +1 -0
- package/dist/esm/remote_info.js +116 -0
- package/dist/esm/remote_info.js.map +1 -0
- package/dist/esm/setup.js +41 -0
- package/dist/esm/setup.js.map +1 -0
- package/dist/esm/string.js +78 -0
- package/dist/esm/string.js.map +1 -0
- package/dist/esm/string_enum.js +24 -0
- package/dist/esm/string_enum.js.map +1 -0
- package/dist/esm/system_volume.js +40 -0
- package/dist/esm/system_volume.js.map +1 -0
- package/dist/esm/types/native_bindings.js +3 -0
- package/dist/esm/types/native_bindings.js.map +1 -0
- package/dist/esm/unc.js +49 -0
- package/dist/esm/unc.js.map +1 -0
- package/dist/esm/units.js +31 -0
- package/dist/esm/units.js.map +1 -0
- package/dist/esm/uuid.js +22 -0
- package/dist/esm/uuid.js.map +1 -0
- package/dist/esm/volume_health_status.js +46 -0
- package/dist/esm/volume_health_status.js.map +1 -0
- package/dist/esm/volume_metadata.js +164 -0
- package/dist/esm/volume_metadata.js.map +1 -0
- package/dist/types/array.d.ts +31 -0
- package/dist/types/array.d.ts.map +1 -0
- package/dist/types/array.js +50 -0
- package/dist/types/array.js.map +1 -0
- package/dist/types/async.d.ts +43 -0
- package/dist/types/async.d.ts.map +1 -0
- package/dist/types/async.js +109 -0
- package/dist/types/async.js.map +1 -0
- package/dist/types/cache.d.ts +5 -0
- package/dist/types/cache.d.ts.map +1 -0
- package/dist/types/cache.js +25 -0
- package/dist/types/cache.js.map +1 -0
- package/dist/types/debuglog.d.ts +9 -0
- package/dist/types/debuglog.d.ts.map +1 -0
- package/dist/types/debuglog.js +30 -0
- package/dist/types/debuglog.js.map +1 -0
- package/dist/types/defer.d.ts +12 -0
- package/dist/types/defer.d.ts.map +1 -0
- package/dist/types/defer.js +23 -0
- package/dist/types/defer.js.map +1 -0
- package/dist/types/error.d.ts +18 -0
- package/dist/types/error.d.ts.map +1 -0
- package/dist/types/error.js +58 -0
- package/dist/types/error.js.map +1 -0
- package/dist/types/exports.d.ts +99 -0
- package/dist/types/exports.d.ts.map +1 -0
- package/dist/types/exports.js +4 -0
- package/dist/types/exports.js.map +1 -0
- package/dist/types/fs.d.ts +23 -0
- package/dist/types/fs.d.ts.map +1 -0
- package/dist/types/fs.js +73 -0
- package/dist/types/fs.js.map +1 -0
- package/dist/types/glob.d.ts +18 -0
- package/dist/types/glob.d.ts.map +1 -0
- package/dist/types/glob.js +113 -0
- package/dist/types/glob.js.map +1 -0
- package/dist/types/hidden.d.ts +67 -0
- package/dist/types/hidden.d.ts.map +1 -0
- package/dist/types/hidden.js +155 -0
- package/dist/types/hidden.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/linux/dev_disk.d.ts +14 -0
- package/dist/types/linux/dev_disk.d.ts.map +1 -0
- package/dist/types/linux/dev_disk.js +61 -0
- package/dist/types/linux/dev_disk.js.map +1 -0
- package/dist/types/linux/mount_points.d.ts +7 -0
- package/dist/types/linux/mount_points.d.ts.map +1 -0
- package/dist/types/linux/mount_points.js +77 -0
- package/dist/types/linux/mount_points.js.map +1 -0
- package/dist/types/linux/mtab.d.ts +48 -0
- package/dist/types/linux/mtab.d.ts.map +1 -0
- package/dist/types/linux/mtab.js +82 -0
- package/dist/types/linux/mtab.js.map +1 -0
- package/dist/types/mount_point.d.ts +56 -0
- package/dist/types/mount_point.d.ts.map +1 -0
- package/dist/types/mount_point.js +63 -0
- package/dist/types/mount_point.js.map +1 -0
- package/dist/types/number.d.ts +8 -0
- package/dist/types/number.d.ts.map +1 -0
- package/dist/types/number.js +32 -0
- package/dist/types/number.js.map +1 -0
- package/dist/types/object.d.ts +18 -0
- package/dist/types/object.d.ts.map +1 -0
- package/dist/types/object.js +52 -0
- package/dist/types/object.js.map +1 -0
- package/dist/types/options.d.ts +80 -0
- package/dist/types/options.d.ts.map +1 -0
- package/dist/types/options.js +111 -0
- package/dist/types/options.js.map +1 -0
- package/dist/types/path.d.ts +18 -0
- package/dist/types/path.d.ts.map +1 -0
- package/dist/types/path.js +44 -0
- package/dist/types/path.js.map +1 -0
- package/dist/types/platform.d.ts +4 -0
- package/dist/types/platform.d.ts.map +1 -0
- package/dist/types/platform.js +7 -0
- package/dist/types/platform.js.map +1 -0
- package/dist/types/random.d.ts +13 -0
- package/dist/types/random.d.ts.map +1 -0
- package/dist/types/random.js +37 -0
- package/dist/types/random.js.map +1 -0
- package/dist/types/remote_info.d.ts +39 -0
- package/dist/types/remote_info.d.ts.map +1 -0
- package/dist/types/remote_info.js +116 -0
- package/dist/types/remote_info.js.map +1 -0
- package/dist/types/setup.d.ts +3 -0
- package/dist/types/setup.d.ts.map +1 -0
- package/dist/types/setup.js +41 -0
- package/dist/types/setup.js.map +1 -0
- package/dist/types/string.d.ts +38 -0
- package/dist/types/string.d.ts.map +1 -0
- package/dist/types/string.js +78 -0
- package/dist/types/string.js.map +1 -0
- package/dist/types/string_enum.d.ts +20 -0
- package/dist/types/string_enum.d.ts.map +1 -0
- package/dist/types/string_enum.js +24 -0
- package/dist/types/string_enum.js.map +1 -0
- package/dist/types/system_volume.d.ts +15 -0
- package/dist/types/system_volume.d.ts.map +1 -0
- package/dist/types/system_volume.js +40 -0
- package/dist/types/system_volume.js.map +1 -0
- package/dist/types/types/native_bindings.d.ts +52 -0
- package/dist/types/types/native_bindings.d.ts.map +1 -0
- package/dist/types/types/native_bindings.js +3 -0
- package/dist/types/types/native_bindings.js.map +1 -0
- package/dist/types/unc.d.ts +12 -0
- package/dist/types/unc.d.ts.map +1 -0
- package/dist/types/unc.js +49 -0
- package/dist/types/unc.js.map +1 -0
- package/dist/types/units.d.ts +17 -0
- package/dist/types/units.d.ts.map +1 -0
- package/dist/types/units.js +31 -0
- package/dist/types/units.js.map +1 -0
- package/dist/types/uuid.d.ts +17 -0
- package/dist/types/uuid.d.ts.map +1 -0
- package/dist/types/uuid.js +22 -0
- package/dist/types/uuid.js.map +1 -0
- package/dist/types/volume_health_status.d.ts +25 -0
- package/dist/types/volume_health_status.d.ts.map +1 -0
- package/dist/types/volume_health_status.js +46 -0
- package/dist/types/volume_health_status.js.map +1 -0
- package/dist/types/volume_metadata.d.ts +55 -0
- package/dist/types/volume_metadata.d.ts.map +1 -0
- package/dist/types/volume_metadata.js +164 -0
- package/dist/types/volume_metadata.js.map +1 -0
- package/package.json +11 -12
- package/prebuilds/darwin-arm64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/win32-x64/@photostructure+fs-metadata.glibc.node +0 -0
- package/scripts/fix-cjs.mjs +35 -0
package/dist/cjs/unc.cjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/unc.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.parseUNCPath = parseUNCPath;
|
|
5
|
+
const string_js_1 = require("./string.cjs");
|
|
6
|
+
/**
|
|
7
|
+
* Checks if a string is formatted as a valid UNC path.
|
|
8
|
+
* A valid UNC path starts with double backslashes or slashes,
|
|
9
|
+
* followed by a server/host name, and then a share name.
|
|
10
|
+
* The path must use consistent slashes (all forward or all backward).
|
|
11
|
+
*
|
|
12
|
+
* @param path - The string to check
|
|
13
|
+
* @returns boolean - True if the string is a valid UNC path, false otherwise
|
|
14
|
+
*/
|
|
15
|
+
function parseUNCPath(path) {
|
|
16
|
+
if (path == null || (0, string_js_1.isBlank)(path) || !(0, string_js_1.isString)(path)) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
// Check for two forward slashes or two backslashes at start
|
|
20
|
+
if (!path.startsWith("\\\\") && !path.startsWith("//")) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// Determine slash type from the start of the path
|
|
24
|
+
const isForwardSlash = path.startsWith("//");
|
|
25
|
+
const slashChar = isForwardSlash ? "/" : "\\";
|
|
26
|
+
// Split path using the correct slash type
|
|
27
|
+
const parts = path.slice(2).split(slashChar);
|
|
28
|
+
// Check minimum required parts (server and share)
|
|
29
|
+
if (parts.length < 2) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
// Validate server and share names exist and aren't empty
|
|
33
|
+
const [remoteHost, remoteShare] = parts;
|
|
34
|
+
if (remoteHost == null ||
|
|
35
|
+
(0, string_js_1.isBlank)(remoteHost) ||
|
|
36
|
+
remoteShare == null ||
|
|
37
|
+
(0, string_js_1.isBlank)(remoteShare)) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// Check for invalid characters in server and share names
|
|
41
|
+
const invalidChars = /[<>:"|?*]/;
|
|
42
|
+
if (invalidChars.test(remoteHost) || invalidChars.test(remoteShare)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// Check for mixed slash usage
|
|
46
|
+
const wrongSlash = isForwardSlash ? "\\" : "/";
|
|
47
|
+
if (path.includes(wrongSlash)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
return { remoteHost, remoteShare, remote: true };
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=unc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unc.js","sourceRoot":"","sources":["../../src/unc.ts"],"names":[],"mappings":";AAAA,aAAa;;AAcb,oCAgDC;AA3DD,2CAAgD;AAEhD;;;;;;;;GAQG;AACH,SAAgB,YAAY,CAC1B,IAA+B;IAE/B,IAAI,IAAI,IAAI,IAAI,IAAI,IAAA,mBAAO,EAAC,IAAI,CAAC,IAAI,CAAC,IAAA,oBAAQ,EAAC,IAAI,CAAC,EAAE,CAAC;QACrD,OAAO;IACT,CAAC;IAED,4DAA4D;IAC5D,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACvD,OAAO;IACT,CAAC;IAED,kDAAkD;IAClD,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAE9C,0CAA0C;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAE7C,kDAAkD;IAClD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO;IACT,CAAC;IAED,yDAAyD;IACzD,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC;IACxC,IACE,UAAU,IAAI,IAAI;QAClB,IAAA,mBAAO,EAAC,UAAU,CAAC;QACnB,WAAW,IAAI,IAAI;QACnB,IAAA,mBAAO,EAAC,WAAW,CAAC,EACpB,CAAC;QACD,OAAO;IACT,CAAC;IAED,yDAAyD;IACzD,MAAM,YAAY,GAAG,WAAW,CAAC;IACjC,IAAI,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QACpE,OAAO;IACT,CAAC;IAED,8BAA8B;IAC9B,MAAM,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;IAC/C,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/units.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.GiB = exports.MiB = exports.KiB = void 0;
|
|
5
|
+
exports.fmtBytes = fmtBytes;
|
|
6
|
+
/**
|
|
7
|
+
* KiB = 1024 bytes
|
|
8
|
+
* @see https://en.wikipedia.org/wiki/Kibibyte
|
|
9
|
+
*/
|
|
10
|
+
exports.KiB = 1024;
|
|
11
|
+
/**
|
|
12
|
+
* MiB = 1024 KiB
|
|
13
|
+
* @see https://en.wikipedia.org/wiki/Mebibyte
|
|
14
|
+
*/
|
|
15
|
+
exports.MiB = 1024 * exports.KiB;
|
|
16
|
+
/**
|
|
17
|
+
* GiB = 1024 MiB
|
|
18
|
+
* @see https://en.wikipedia.org/wiki/Gibibyte
|
|
19
|
+
*/
|
|
20
|
+
exports.GiB = 1024 * exports.MiB;
|
|
21
|
+
function fmtBytes(bytes) {
|
|
22
|
+
if (bytes < exports.KiB) {
|
|
23
|
+
return `${bytes} B`;
|
|
24
|
+
}
|
|
25
|
+
else if (bytes < exports.MiB) {
|
|
26
|
+
return `${(bytes / exports.KiB).toFixed(2)} KiB`;
|
|
27
|
+
}
|
|
28
|
+
else if (bytes < exports.GiB) {
|
|
29
|
+
return `${(bytes / exports.MiB).toFixed(2)} MiB`;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
return `${(bytes / exports.GiB).toFixed(2)} GiB`;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=units.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"units.js","sourceRoot":"","sources":["../../src/units.ts"],"names":[],"mappings":";AAAA,eAAe;;;AAoBf,4BAUC;AA5BD;;;GAGG;AACU,QAAA,GAAG,GAAG,IAAI,CAAC;AAExB;;;GAGG;AACU,QAAA,GAAG,GAAG,IAAI,GAAG,WAAG,CAAC;AAE9B;;;GAGG;AACU,QAAA,GAAG,GAAG,IAAI,GAAG,WAAG,CAAC;AAE9B,SAAgB,QAAQ,CAAC,KAAa;IACpC,IAAI,KAAK,GAAG,WAAG,EAAE,CAAC;QAChB,OAAO,GAAG,KAAK,IAAI,CAAC;IACtB,CAAC;SAAM,IAAI,KAAK,GAAG,WAAG,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC,KAAK,GAAG,WAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3C,CAAC;SAAM,IAAI,KAAK,GAAG,WAAG,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC,KAAK,GAAG,WAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3C,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,CAAC,KAAK,GAAG,WAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/uuid.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.extractUUID = extractUUID;
|
|
5
|
+
const string_js_1 = require("./string.cjs");
|
|
6
|
+
const uuidRegex = /[a-z0-9][a-z0-9-]{7,}/i;
|
|
7
|
+
/**
|
|
8
|
+
* Some volume UUIDs are short, like, `ABCD1234`.
|
|
9
|
+
*
|
|
10
|
+
* Some volume UUIDs are in hexadecimal, but others and use G-Z. We will allow
|
|
11
|
+
* that.
|
|
12
|
+
*
|
|
13
|
+
* Some Windows syscalls wrap the UUID in a "\\\\?\\Volume{...}\\" prefix and
|
|
14
|
+
* suffix. This function will strip out that prefix and suffix.
|
|
15
|
+
*
|
|
16
|
+
* We will ignore any UUID-ish string that is not at least 8 characters long
|
|
17
|
+
* (and return `undefined` if no other, longer uuid-ish string is found).
|
|
18
|
+
*
|
|
19
|
+
* UUIDs cannot start with a hyphen, and can only contain a-z, 0-9, and hyphens
|
|
20
|
+
* (case-insensitive).
|
|
21
|
+
*/
|
|
22
|
+
function extractUUID(uuid) {
|
|
23
|
+
return (0, string_js_1.toS)(uuid).match(uuidRegex)?.[0];
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=uuid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uuid.js","sourceRoot":"","sources":["../../src/uuid.ts"],"names":[],"mappings":";AAAA,cAAc;;AAqBd,kCAEC;AArBD,2CAAkC;AAElC,MAAM,SAAS,GAAG,wBAAwB,CAAC;AAE3C;;;;;;;;;;;;;;GAcG;AACH,SAAgB,WAAW,CAAC,IAAwB;IAClD,OAAO,IAAA,eAAG,EAAC,IAAI,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/volume_health_status.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.VolumeHealthStatuses = void 0;
|
|
5
|
+
exports.directoryStatus = directoryStatus;
|
|
6
|
+
const async_js_1 = require("./async.cjs");
|
|
7
|
+
const debuglog_js_1 = require("./debuglog.cjs");
|
|
8
|
+
const error_js_1 = require("./error.cjs");
|
|
9
|
+
const fs_js_1 = require("./fs.cjs");
|
|
10
|
+
const object_js_1 = require("./object.cjs");
|
|
11
|
+
const string_enum_js_1 = require("./string_enum.cjs");
|
|
12
|
+
/**
|
|
13
|
+
* Health statuses for volumes (mostly applicable to Windows).
|
|
14
|
+
*
|
|
15
|
+
* - `healthy`: Volume is "OK": accessible and functioning normally
|
|
16
|
+
* - `timeout`: Volume could not be accessed before the specified timeout. It
|
|
17
|
+
* may be inaccessible or disconnected.
|
|
18
|
+
* - `inaccessible`: Volume exists but can't be accessed (permissions/locks)
|
|
19
|
+
* - `disconnected`: Network volume that's offline
|
|
20
|
+
* - `unknown`: Status can't be determined
|
|
21
|
+
*/
|
|
22
|
+
exports.VolumeHealthStatuses = (0, string_enum_js_1.stringEnum)("healthy", "timeout", "inaccessible", "disconnected", "unknown");
|
|
23
|
+
/**
|
|
24
|
+
* Attempt to read a directory to determine if it's accessible, and if an error
|
|
25
|
+
* is thrown, convert to a health status.
|
|
26
|
+
* @returns the "health status" of the directory, based on the success of `readdir(dir)`.
|
|
27
|
+
* @throws never
|
|
28
|
+
*/
|
|
29
|
+
async function directoryStatus(dir, timeoutMs, canReaddirImpl = fs_js_1.canReaddir) {
|
|
30
|
+
try {
|
|
31
|
+
if (await canReaddirImpl(dir, timeoutMs)) {
|
|
32
|
+
return { status: exports.VolumeHealthStatuses.healthy };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
(0, debuglog_js_1.debug)("[directoryStatus] %s: %s", dir, error);
|
|
37
|
+
let status = exports.VolumeHealthStatuses.unknown;
|
|
38
|
+
if (error instanceof async_js_1.TimeoutError) {
|
|
39
|
+
status = exports.VolumeHealthStatuses.timeout;
|
|
40
|
+
}
|
|
41
|
+
else if ((0, object_js_1.isObject)(error) && error instanceof Error && "code" in error) {
|
|
42
|
+
if (error.code === "EPERM" || error.code === "EACCES") {
|
|
43
|
+
status = exports.VolumeHealthStatuses.inaccessible;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { status, error: (0, error_js_1.toError)(error) };
|
|
47
|
+
}
|
|
48
|
+
return { status: exports.VolumeHealthStatuses.unknown };
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=volume_health_status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"volume_health_status.js","sourceRoot":"","sources":["../../src/volume_health_status.ts"],"names":[],"mappings":";AAAA,8BAA8B;;;AAmC9B,0CAsBC;AAvDD,yCAA0C;AAC1C,+CAAsC;AACtC,yCAAqC;AACrC,mCAAqC;AACrC,2CAAuC;AACvC,qDAA8D;AAE9D;;;;;;;;;GASG;AACU,QAAA,oBAAoB,GAAG,IAAA,2BAAU,EAC5C,SAAS,EACT,SAAS,EACT,cAAc,EACd,cAAc,EACd,SAAS,CACV,CAAC;AAIF;;;;;GAKG;AACI,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,SAAiB,EACjB,iBAAoC,kBAAU;IAE9C,IAAI,CAAC;QACH,IAAI,MAAM,cAAc,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,CAAC;YACzC,OAAO,EAAE,MAAM,EAAE,4BAAoB,CAAC,OAAO,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAA,mBAAK,EAAC,0BAA0B,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QAC9C,IAAI,MAAM,GAAuB,4BAAoB,CAAC,OAAO,CAAC;QAC9D,IAAI,KAAK,YAAY,uBAAY,EAAE,CAAC;YAClC,MAAM,GAAG,4BAAoB,CAAC,OAAO,CAAC;QACxC,CAAC;aAAM,IAAI,IAAA,oBAAQ,EAAC,KAAK,CAAC,IAAI,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;YACxE,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtD,MAAM,GAAG,4BAAoB,CAAC,YAAY,CAAC;YAC7C,CAAC;QACH,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAA,kBAAO,EAAC,KAAK,CAAC,EAAE,CAAC;IAC3C,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,4BAAoB,CAAC,OAAO,EAAE,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/volume_metadata.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports._ = void 0;
|
|
5
|
+
exports.getVolumeMetadata = getVolumeMetadata;
|
|
6
|
+
exports.getAllVolumeMetadata = getAllVolumeMetadata;
|
|
7
|
+
const async_js_1 = require("./async.cjs");
|
|
8
|
+
const debuglog_js_1 = require("./debuglog.cjs");
|
|
9
|
+
const error_js_1 = require("./error.cjs");
|
|
10
|
+
const dev_disk_js_1 = require("./linux/dev_disk.cjs");
|
|
11
|
+
const mount_points_js_1 = require("./linux/mount_points.cjs");
|
|
12
|
+
const mtab_js_1 = require("./linux/mtab.cjs");
|
|
13
|
+
const mount_point_js_1 = require("./mount_point.cjs");
|
|
14
|
+
const object_js_1 = require("./object.cjs");
|
|
15
|
+
const options_js_1 = require("./options.cjs");
|
|
16
|
+
const path_js_1 = require("./path.cjs");
|
|
17
|
+
const platform_js_1 = require("./platform.cjs");
|
|
18
|
+
const remote_info_js_1 = require("./remote_info.cjs");
|
|
19
|
+
const string_js_1 = require("./string.cjs");
|
|
20
|
+
const system_volume_js_1 = require("./system_volume.cjs");
|
|
21
|
+
const unc_js_1 = require("./unc.cjs");
|
|
22
|
+
const uuid_js_1 = require("./uuid.cjs");
|
|
23
|
+
const volume_health_status_js_1 = require("./volume_health_status.cjs");
|
|
24
|
+
async function getVolumeMetadata(o, nativeFn) {
|
|
25
|
+
if ((0, string_js_1.isBlank)(o.mountPoint)) {
|
|
26
|
+
throw new TypeError("Invalid mountPoint: got " + JSON.stringify(o.mountPoint));
|
|
27
|
+
}
|
|
28
|
+
const p = _getVolumeMetadata(o, nativeFn);
|
|
29
|
+
// we rely on the native bindings on Windows to do proper timeouts
|
|
30
|
+
return platform_js_1.isWindows
|
|
31
|
+
? p
|
|
32
|
+
: (0, async_js_1.withTimeout)({
|
|
33
|
+
desc: "getVolumeMetadata()",
|
|
34
|
+
timeoutMs: o.timeoutMs,
|
|
35
|
+
promise: p,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
async function _getVolumeMetadata(o, nativeFn) {
|
|
39
|
+
o = (0, options_js_1.optionsWithDefaults)(o);
|
|
40
|
+
const norm = (0, path_js_1.normalizePath)(o.mountPoint);
|
|
41
|
+
if (norm == null) {
|
|
42
|
+
throw new Error("Invalid mountPoint: " + JSON.stringify(o.mountPoint));
|
|
43
|
+
}
|
|
44
|
+
o.mountPoint = norm;
|
|
45
|
+
(0, debuglog_js_1.debug)("[getVolumeMetadata] starting metadata collection for %s", o.mountPoint);
|
|
46
|
+
(0, debuglog_js_1.debug)("[getVolumeMetadata] options: %o", o);
|
|
47
|
+
const { status, error } = await (0, volume_health_status_js_1.directoryStatus)(o.mountPoint, o.timeoutMs);
|
|
48
|
+
if (status !== volume_health_status_js_1.VolumeHealthStatuses.healthy) {
|
|
49
|
+
(0, debuglog_js_1.debug)("[getVolumeMetadata] directoryStatus error: %s", error);
|
|
50
|
+
throw error ?? new Error("Volume not healthy: " + status);
|
|
51
|
+
}
|
|
52
|
+
(0, debuglog_js_1.debug)("[getVolumeMetadata] readdir status: %s", status);
|
|
53
|
+
let remote = false;
|
|
54
|
+
// Get filesystem info from mtab first on Linux
|
|
55
|
+
let mtabInfo;
|
|
56
|
+
let device;
|
|
57
|
+
if (platform_js_1.isLinux) {
|
|
58
|
+
(0, debuglog_js_1.debug)("[getVolumeMetadata] collecting Linux mtab info");
|
|
59
|
+
try {
|
|
60
|
+
const m = await (0, mount_points_js_1.getLinuxMtabMetadata)(o.mountPoint, o);
|
|
61
|
+
mtabInfo = (0, mtab_js_1.mountEntryToPartialVolumeMetadata)(m, o);
|
|
62
|
+
(0, debuglog_js_1.debug)("[getVolumeMetadata] mtab info: %o", mtabInfo);
|
|
63
|
+
if (mtabInfo.remote) {
|
|
64
|
+
remote = true;
|
|
65
|
+
}
|
|
66
|
+
if ((0, string_js_1.isNotBlank)(m.fs_spec)) {
|
|
67
|
+
device = m.fs_spec;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
(0, debuglog_js_1.debug)("[getVolumeMetadata] failed to get mtab info: " + err);
|
|
72
|
+
// this may be a GIO mount. Ignore the error and continue.
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if ((0, string_js_1.isNotBlank)(device)) {
|
|
76
|
+
o.device = device;
|
|
77
|
+
(0, debuglog_js_1.debug)("[getVolumeMetadata] using device: %s", device);
|
|
78
|
+
}
|
|
79
|
+
(0, debuglog_js_1.debug)("[getVolumeMetadata] requesting native metadata");
|
|
80
|
+
const metadata = (await (await nativeFn()).getVolumeMetadata(o));
|
|
81
|
+
(0, debuglog_js_1.debug)("[getVolumeMetadata] native metadata: %o", metadata);
|
|
82
|
+
// Some OS implementations leave it up to us to extract remote info:
|
|
83
|
+
const remoteInfo = mtabInfo ??
|
|
84
|
+
(0, remote_info_js_1.extractRemoteInfo)(metadata.uri) ??
|
|
85
|
+
(0, remote_info_js_1.extractRemoteInfo)(metadata.mountFrom) ??
|
|
86
|
+
(platform_js_1.isWindows ? (0, unc_js_1.parseUNCPath)(o.mountPoint) : undefined);
|
|
87
|
+
(0, debuglog_js_1.debug)("[getVolumeMetadata] extracted remote info: %o", remoteInfo);
|
|
88
|
+
remote ||=
|
|
89
|
+
(0, remote_info_js_1.isRemoteFsType)(metadata.fstype) ||
|
|
90
|
+
(remoteInfo?.remote ?? metadata.remote ?? false);
|
|
91
|
+
(0, debuglog_js_1.debug)("[getVolumeMetadata] assembling: %o", {
|
|
92
|
+
status,
|
|
93
|
+
mtabInfo,
|
|
94
|
+
remoteInfo,
|
|
95
|
+
metadata,
|
|
96
|
+
mountPoint: o.mountPoint,
|
|
97
|
+
remote,
|
|
98
|
+
});
|
|
99
|
+
const result = (0, object_js_1.compactValues)({
|
|
100
|
+
status, // < let the implementation's status win by having this first
|
|
101
|
+
...(0, object_js_1.compactValues)(remoteInfo),
|
|
102
|
+
...(0, object_js_1.compactValues)(metadata),
|
|
103
|
+
...(0, object_js_1.compactValues)(mtabInfo),
|
|
104
|
+
mountPoint: o.mountPoint,
|
|
105
|
+
remote,
|
|
106
|
+
});
|
|
107
|
+
// Backfill if blkid or gio failed us:
|
|
108
|
+
if (platform_js_1.isLinux && (0, string_js_1.isNotBlank)(device)) {
|
|
109
|
+
// Sometimes blkid doesn't have the UUID in cache. Try to get it from
|
|
110
|
+
// /dev/disk/by-uuid:
|
|
111
|
+
result.uuid ??= (await (0, dev_disk_js_1.getUuidFromDevDisk)(device)) ?? "";
|
|
112
|
+
result.label ??= (await (0, dev_disk_js_1.getLabelFromDevDisk)(device)) ?? "";
|
|
113
|
+
}
|
|
114
|
+
(0, system_volume_js_1.assignSystemVolume)(result, o);
|
|
115
|
+
// Fix microsoft's UUID format:
|
|
116
|
+
result.uuid = (0, uuid_js_1.extractUUID)(result.uuid) ?? result.uuid ?? "";
|
|
117
|
+
(0, debuglog_js_1.debug)("[getVolumeMetadata] final result for %s: %o", o.mountPoint, result);
|
|
118
|
+
return (0, object_js_1.compactValues)(result);
|
|
119
|
+
}
|
|
120
|
+
async function getAllVolumeMetadata(opts, nativeFn) {
|
|
121
|
+
const o = (0, options_js_1.optionsWithDefaults)(opts);
|
|
122
|
+
(0, debuglog_js_1.debug)("[getAllVolumeMetadata] starting with options: %o", o);
|
|
123
|
+
const arr = await (0, mount_point_js_1.getVolumeMountPoints)(o, nativeFn);
|
|
124
|
+
(0, debuglog_js_1.debug)("[getAllVolumeMetadata] found %d mount points", arr.length);
|
|
125
|
+
const unhealthyMountPoints = arr
|
|
126
|
+
.filter((ea) => ea.status != null && ea.status !== volume_health_status_js_1.VolumeHealthStatuses.healthy)
|
|
127
|
+
.map((ea) => ({
|
|
128
|
+
mountPoint: ea.mountPoint,
|
|
129
|
+
error: new error_js_1.WrappedError("volume not healthy: " + ea.status, {
|
|
130
|
+
name: "Skipped",
|
|
131
|
+
}),
|
|
132
|
+
}));
|
|
133
|
+
const includeSystemVolumes = opts?.includeSystemVolumes ?? options_js_1.IncludeSystemVolumesDefault;
|
|
134
|
+
const systemMountPoints = includeSystemVolumes
|
|
135
|
+
? []
|
|
136
|
+
: arr
|
|
137
|
+
.filter((ea) => ea.isSystemVolume)
|
|
138
|
+
.map((ea) => ({
|
|
139
|
+
mountPoint: ea.mountPoint,
|
|
140
|
+
error: new error_js_1.WrappedError("system volume", { name: "Skipped" }),
|
|
141
|
+
}));
|
|
142
|
+
const healthy = arr.filter((ea) => ea.status == null || ea.status === volume_health_status_js_1.VolumeHealthStatuses.healthy);
|
|
143
|
+
(0, debuglog_js_1.debug)("[getAllVolumeMetadata] ", {
|
|
144
|
+
allMountPoints: arr.map((ea) => ea.mountPoint),
|
|
145
|
+
healthyMountPoints: healthy.map((ea) => ea.mountPoint),
|
|
146
|
+
});
|
|
147
|
+
(0, debuglog_js_1.debug)("[getAllVolumeMetadata] processing %d healthy volumes with max concurrency %d", healthy.length, o.maxConcurrency);
|
|
148
|
+
const results = await (0, async_js_1.mapConcurrent)({
|
|
149
|
+
maxConcurrency: o.maxConcurrency,
|
|
150
|
+
items: (opts?.includeSystemVolumes ?? options_js_1.IncludeSystemVolumesDefault)
|
|
151
|
+
? healthy
|
|
152
|
+
: healthy.filter((ea) => !ea.isSystemVolume),
|
|
153
|
+
fn: async (mp) => getVolumeMetadata({ ...mp, ...o }, nativeFn).catch((error) => ({
|
|
154
|
+
mountPoint: mp.mountPoint,
|
|
155
|
+
error,
|
|
156
|
+
})),
|
|
157
|
+
});
|
|
158
|
+
(0, debuglog_js_1.debug)("[getAllVolumeMetadata] completed processing all volumes");
|
|
159
|
+
return arr.map((result) => (results.find((ea) => ea.mountPoint === result.mountPoint) ??
|
|
160
|
+
unhealthyMountPoints.find((ea) => ea.mountPoint === result.mountPoint) ??
|
|
161
|
+
systemMountPoints.find((ea) => ea.mountPoint === result.mountPoint) ?? {
|
|
162
|
+
...result,
|
|
163
|
+
error: new error_js_1.WrappedError("Mount point metadata not retrieved", {
|
|
164
|
+
name: "NotApplicableError",
|
|
165
|
+
}),
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
168
|
+
exports._ = undefined;
|
|
169
|
+
//# sourceMappingURL=volume_metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"volume_metadata.js","sourceRoot":"","sources":["../../src/volume_metadata.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// src/array.ts
|
|
2
|
+
/**
|
|
3
|
+
* @return a new array whose elements return true based on the given `predicate`
|
|
4
|
+
* function.
|
|
5
|
+
*/
|
|
6
|
+
export async function asyncFilter(arr, predicate) {
|
|
7
|
+
const results = await Promise.all(arr.map(async (ea) => predicate(ea)));
|
|
8
|
+
return arr.filter((_item, index) => results[index]);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Remove duplicate elements from an array.
|
|
12
|
+
*
|
|
13
|
+
* - Primitive values are compared using strict equality.
|
|
14
|
+
* - Objects and arrays are compared by reference.
|
|
15
|
+
*
|
|
16
|
+
* @return A new array with duplicate elements removed
|
|
17
|
+
*/
|
|
18
|
+
export function uniq(arr) {
|
|
19
|
+
return Array.from(new Set(arr));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Remove duplicate elements from an array based on a key function.
|
|
23
|
+
* @param keyFn A function that returns a key for each element. Elements that
|
|
24
|
+
* the key function returns nullish will be removed from the returned array.
|
|
25
|
+
* @return a new array omitting duplicate elements based on a key function.
|
|
26
|
+
*/
|
|
27
|
+
export function uniqBy(arr, keyFn) {
|
|
28
|
+
const seen = new Set();
|
|
29
|
+
return arr.filter((item) => {
|
|
30
|
+
const key = keyFn(item);
|
|
31
|
+
if (key == null || seen.has(key))
|
|
32
|
+
return false;
|
|
33
|
+
seen.add(key);
|
|
34
|
+
return true;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* @return an array of specified length, with each element created by calling
|
|
39
|
+
* the provided function.
|
|
40
|
+
*/
|
|
41
|
+
export function times(length, fn) {
|
|
42
|
+
return Array.from({ length }, (_, i) => fn(i));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* @return a new array with elements that are not `null` or `undefined`.
|
|
46
|
+
*/
|
|
47
|
+
export function compact(arr) {
|
|
48
|
+
return arr == null ? [] : arr.filter((ea) => ea != null);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=array.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array.js","sourceRoot":"","sources":["../../src/array.ts"],"names":[],"mappings":"AAAA,eAAe;AAEf;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,GAAQ,EACR,SAAkD;IAElD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACxE,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAAI,GAAQ;IAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAClC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAO,GAAQ,EAAE,KAAiC;IACtE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAK,CAAC;IAC1B,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACzB,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,KAAK,CAAI,MAAc,EAAE,EAAwB;IAC/D,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAI,GAAyC;IAClE,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAW,EAAE,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { availableParallelism } from "node:os";
|
|
2
|
+
import { env } from "node:process";
|
|
3
|
+
import { gt0, isNumber } from "./number.js";
|
|
4
|
+
import { isBlank } from "./string.js";
|
|
5
|
+
/**
|
|
6
|
+
* An error that is thrown when a promise does not resolve within the specified
|
|
7
|
+
* time.
|
|
8
|
+
*/
|
|
9
|
+
export class TimeoutError extends Error {
|
|
10
|
+
constructor(message, captureStackTrace = true) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = "TimeoutError";
|
|
13
|
+
// Capture the stack trace up to the calling site
|
|
14
|
+
if (captureStackTrace && Error.captureStackTrace) {
|
|
15
|
+
Error.captureStackTrace(this, this.constructor);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Rejects the promise with a TimeoutError if it does not resolve within the
|
|
21
|
+
* specified time.
|
|
22
|
+
*
|
|
23
|
+
* @param promise The promise to wrap.
|
|
24
|
+
* @param timeoutMs The timeout in milliseconds. Timeouts are disabled if this is 0.
|
|
25
|
+
* @returns A promise that resolves when the input promise resolves, or rejects
|
|
26
|
+
* with a TimeoutError if the input promise does not resolve within the
|
|
27
|
+
* specified time.
|
|
28
|
+
* @throws {TimeoutError} if the input promise does not resolve within the
|
|
29
|
+
* specified time.
|
|
30
|
+
* @throws {TypeError} if timeoutMs is not a number that is greater than 0.
|
|
31
|
+
*/
|
|
32
|
+
export async function withTimeout(opts) {
|
|
33
|
+
const desc = isBlank(opts.desc) ? "thenOrTimeout()" : opts.desc;
|
|
34
|
+
if (!isNumber(opts.timeoutMs)) {
|
|
35
|
+
throw new TypeError(desc +
|
|
36
|
+
": Expected timeoutMs to be numeric, but got " +
|
|
37
|
+
JSON.stringify(opts.timeoutMs));
|
|
38
|
+
}
|
|
39
|
+
const timeoutMs = Math.floor(opts.timeoutMs);
|
|
40
|
+
if (timeoutMs < 0) {
|
|
41
|
+
throw new TypeError(desc + ": Expected timeoutMs to be > 0, but got " + timeoutMs);
|
|
42
|
+
}
|
|
43
|
+
if (timeoutMs === 0) {
|
|
44
|
+
return opts.promise;
|
|
45
|
+
}
|
|
46
|
+
// Create error here to captured the caller's stack trace. If we create it in
|
|
47
|
+
// the timeout callback, the stack trace will be truncated to this function.
|
|
48
|
+
const timeoutError = new TimeoutError(`${desc}: timeout after ${timeoutMs}ms`);
|
|
49
|
+
if (env["NODE_ENV"] === "test" && timeoutMs === 1) {
|
|
50
|
+
timeoutError.message += "(timeout test)";
|
|
51
|
+
opts.promise.catch(() => { }); // < avoid unhandled rejection warnings
|
|
52
|
+
throw timeoutError;
|
|
53
|
+
}
|
|
54
|
+
let timeoutId;
|
|
55
|
+
opts.promise
|
|
56
|
+
.catch(() => { }) // < avoid unhandled rejection warnings
|
|
57
|
+
.finally(() => {
|
|
58
|
+
if (timeoutId != null) {
|
|
59
|
+
clearTimeout(timeoutId);
|
|
60
|
+
timeoutId = undefined;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
64
|
+
timeoutId = setTimeout(() => {
|
|
65
|
+
if (timeoutId != null) {
|
|
66
|
+
timeoutError.message += "(timeout callback)";
|
|
67
|
+
reject(timeoutError);
|
|
68
|
+
}
|
|
69
|
+
timeoutId = undefined;
|
|
70
|
+
}, timeoutMs);
|
|
71
|
+
});
|
|
72
|
+
return Promise.race([opts.promise, timeoutPromise]);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Delay for the specified number of milliseconds.
|
|
76
|
+
*
|
|
77
|
+
* @param ms The number of milliseconds to delay
|
|
78
|
+
* @param t Optional value to resolve with after delay
|
|
79
|
+
* @returns Promise that resolves with the provided value (or void if none provided)
|
|
80
|
+
*/
|
|
81
|
+
export async function delay(ms, t) {
|
|
82
|
+
return new Promise((resolve) => setTimeout(() => resolve(t), ms));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Apply `fn` to every item in `items` with a maximum concurrency of
|
|
86
|
+
* `maxConcurrency`.
|
|
87
|
+
*/
|
|
88
|
+
export async function mapConcurrent({ items, fn, maxConcurrency = availableParallelism(), }) {
|
|
89
|
+
// Validate maxConcurrency
|
|
90
|
+
if (!gt0(maxConcurrency)) {
|
|
91
|
+
throw new Error(`maxConcurrency must be a positive integer, got: ${maxConcurrency}`);
|
|
92
|
+
}
|
|
93
|
+
if (typeof fn !== "function") {
|
|
94
|
+
throw new TypeError(`fn must be a function, got: ${typeof fn}`);
|
|
95
|
+
}
|
|
96
|
+
const results = [];
|
|
97
|
+
const executing = new Set();
|
|
98
|
+
for (const [index, item] of items.entries()) {
|
|
99
|
+
// Create a wrapped promise that handles cleanup
|
|
100
|
+
while (executing.size >= maxConcurrency) {
|
|
101
|
+
await Promise.race(executing);
|
|
102
|
+
}
|
|
103
|
+
const p = (results[index] = fn(item).catch((error) => error));
|
|
104
|
+
executing.add(p);
|
|
105
|
+
p.finally(() => executing.delete(p));
|
|
106
|
+
}
|
|
107
|
+
return Promise.all(results);
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=async.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async.js","sourceRoot":"","sources":["../../src/async.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache the result of a function for a given time-to-live (TTL).
|
|
3
|
+
*/
|
|
4
|
+
export function ttlCache(fn, ttl) {
|
|
5
|
+
if (ttl <= 0)
|
|
6
|
+
return fn;
|
|
7
|
+
const cache = new Map();
|
|
8
|
+
return (...args) => {
|
|
9
|
+
const key = JSON.stringify(args);
|
|
10
|
+
const entry = cache.get(key);
|
|
11
|
+
if (entry) {
|
|
12
|
+
return entry.r;
|
|
13
|
+
}
|
|
14
|
+
const result = fn(...args);
|
|
15
|
+
const timeoutId = setTimeout(() => {
|
|
16
|
+
const currentEntry = cache.get(key);
|
|
17
|
+
if (currentEntry?.t === timeoutId) {
|
|
18
|
+
cache.delete(key);
|
|
19
|
+
}
|
|
20
|
+
}, ttl);
|
|
21
|
+
cache.set(key, { r: result, t: timeoutId });
|
|
22
|
+
return result;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,UAAU,QAAQ,CACtB,EAAwB,EACxB,GAAW;IAEX,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAExB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE/C,OAAO,CAAC,GAAG,IAAU,EAAK,EAAE;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE7B,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,CAAC,CAAC,CAAC;QACjB,CAAC;QAED,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QAE3B,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,YAAY,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC;gBAClC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACpB,CAAC;QACH,CAAC,EAAE,GAAG,CAAC,CAAC;QAER,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;QAE5C,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { debuglog, format } from "node:util";
|
|
2
|
+
import { defer } from "./defer.js";
|
|
3
|
+
// allow tests to reset the debug log context
|
|
4
|
+
export const debugLogContext = defer(() => {
|
|
5
|
+
for (const ea of ["fs-metadata", "fs-meta"]) {
|
|
6
|
+
if (debuglog(ea).enabled) {
|
|
7
|
+
return ea;
|
|
8
|
+
}
|
|
9
|
+
if (debuglog(ea.toUpperCase()).enabled) {
|
|
10
|
+
return ea;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return "photostructure:fs-metadata";
|
|
14
|
+
});
|
|
15
|
+
export const isDebugEnabled = defer(() => {
|
|
16
|
+
return debuglog(debugLogContext()).enabled ?? false;
|
|
17
|
+
});
|
|
18
|
+
export function debug(msg, ...args) {
|
|
19
|
+
if (!isDebugEnabled())
|
|
20
|
+
return;
|
|
21
|
+
const now = new Date();
|
|
22
|
+
// Format: [HH:MM:SS.mmm] prefix: message
|
|
23
|
+
const timestamp = `[${now.getHours().toString().padStart(2, "0")}:${now.getMinutes().toString().padStart(2, "0")}:${now.getSeconds().toString().padStart(2, "0")}.${now.getMilliseconds().toString().padStart(3, "0")}] ${debugLogContext()} `;
|
|
24
|
+
process.stderr.write(timestamp + format(msg, ...args) + "\n");
|
|
25
|
+
}
|
|
26
|
+
export function resetDebugLog() {
|
|
27
|
+
debugLogContext.reset();
|
|
28
|
+
isDebugEnabled.reset();
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=debuglog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debuglog.js","sourceRoot":"","sources":["../../src/debuglog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,6CAA6C;AAE7C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC,GAAG,EAAE;IACxC,KAAK,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC;QAC5C,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACvC,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,OAAO,4BAA4B,CAAC;AACtC,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC,GAAG,EAAE;IACvC,OAAO,QAAQ,CAAC,eAAe,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,MAAM,UAAU,KAAK,CAAC,GAAW,EAAE,GAAG,IAAe;IACnD,IAAI,CAAC,cAAc,EAAE;QAAE,OAAO;IAC9B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,yCAAyC;IACzC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,eAAe,EAAE,GAAG,CAAC;IAE/O,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,eAAe,CAAC,KAAK,EAAE,CAAC;IACxB,cAAc,CAAC,KAAK,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/defer.ts
|
|
2
|
+
/**
|
|
3
|
+
* Creates a deferred value that is computed once on first access and cached for
|
|
4
|
+
* subsequent accesses.
|
|
5
|
+
* @param thunk A function that takes no arguments and returns a value
|
|
6
|
+
* @returns A function that returns the computed value
|
|
7
|
+
*/
|
|
8
|
+
export function defer(thunk) {
|
|
9
|
+
let computed = false;
|
|
10
|
+
let value;
|
|
11
|
+
const fn = () => {
|
|
12
|
+
if (!computed) {
|
|
13
|
+
computed = true;
|
|
14
|
+
value = thunk();
|
|
15
|
+
}
|
|
16
|
+
return value;
|
|
17
|
+
};
|
|
18
|
+
fn.reset = () => {
|
|
19
|
+
computed = false;
|
|
20
|
+
};
|
|
21
|
+
return fn;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=defer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defer.js","sourceRoot":"","sources":["../../src/defer.ts"],"names":[],"mappings":"AAAA,eAAe;AAMf;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CAAI,KAAc;IACrC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,KAAQ,CAAC;IAEb,MAAM,EAAE,GAAG,GAAG,EAAE;QACd,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,IAAI,CAAC;YAChB,KAAK,GAAG,KAAK,EAAE,CAAC;QAClB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,EAAE,CAAC,KAAK,GAAG,GAAG,EAAE;QACd,QAAQ,GAAG,KAAK,CAAC;IACnB,CAAC,CAAC;IAEF,OAAO,EAAE,CAAC;AACZ,CAAC"}
|