@photostructure/fs-metadata 0.1.3 → 0.1.5
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.cjs +1318 -0
- package/dist/index.mjs +1270 -0
- package/dist/{cjs → types}/array.d.ts +0 -1
- package/dist/{cjs → types}/async.d.ts +0 -1
- package/dist/{cjs → types}/cache.d.ts +0 -1
- package/dist/{cjs → types}/debuglog.d.ts +0 -1
- package/dist/{esm → types}/defer.d.ts +0 -1
- package/dist/{esm → types}/error.d.ts +0 -1
- package/dist/{esm → types}/exports.d.ts +0 -1
- package/dist/{esm → types}/fs.d.ts +0 -1
- package/dist/{cjs → types}/glob.d.ts +0 -1
- package/dist/{cjs → types}/hidden.d.ts +0 -1
- package/dist/{esm → types}/index.d.ts +0 -1
- package/dist/{esm → types}/linux/dev_disk.d.ts +0 -1
- package/dist/{cjs → types}/linux/mount_points.d.ts +0 -1
- package/dist/{cjs → types}/linux/mtab.d.ts +0 -1
- package/dist/{cjs → types}/mount_point.d.ts +0 -1
- package/dist/{cjs → types}/number.d.ts +0 -1
- package/dist/{esm → types}/object.d.ts +0 -1
- package/dist/{cjs → types}/options.d.ts +0 -1
- package/dist/{cjs → types}/path.d.ts +0 -1
- package/dist/{cjs → types}/platform.d.ts +0 -1
- package/dist/{cjs → types}/random.d.ts +0 -1
- package/dist/{esm → types}/remote_info.d.ts +0 -1
- package/dist/{cjs → types}/setup.d.ts +0 -1
- package/dist/{cjs → types}/string.d.ts +0 -1
- package/dist/{esm → types}/string_enum.d.ts +0 -1
- package/dist/{cjs → types}/system_volume.d.ts +0 -1
- package/dist/{cjs → types}/types/native_bindings.d.ts +0 -1
- package/dist/{esm → types}/unc.d.ts +0 -1
- package/dist/{esm → types}/units.d.ts +0 -1
- package/dist/{esm → types}/uuid.d.ts +0 -1
- package/dist/{esm → types}/volume_health_status.d.ts +0 -1
- package/dist/{cjs → types}/volume_metadata.d.ts +0 -1
- package/jest.config.cjs +33 -0
- package/package.json +27 -37
- package/prebuilds/darwin-arm64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/linux-arm64/@photostructure+fs-metadata.musl.node +0 -0
- package/prebuilds/linux-x64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/linux-x64/@photostructure+fs-metadata.musl.node +0 -0
- package/prebuilds/win32-x64/@photostructure+fs-metadata.glibc.node +0 -0
- package/src/darwin/volume_metadata.cpp +26 -12
- package/src/linux/volume_metadata.cpp +21 -4
- package/dist/cjs/array.d.ts.map +0 -1
- package/dist/cjs/array.js +0 -57
- package/dist/cjs/array.js.map +0 -1
- package/dist/cjs/async.d.ts.map +0 -1
- package/dist/cjs/async.js +0 -116
- package/dist/cjs/async.js.map +0 -1
- package/dist/cjs/cache.d.ts.map +0 -1
- package/dist/cjs/cache.js +0 -28
- package/dist/cjs/cache.js.map +0 -1
- package/dist/cjs/debuglog.d.ts.map +0 -1
- package/dist/cjs/debuglog.js +0 -35
- package/dist/cjs/debuglog.js.map +0 -1
- package/dist/cjs/defer.d.ts +0 -12
- package/dist/cjs/defer.d.ts.map +0 -1
- package/dist/cjs/defer.js +0 -26
- package/dist/cjs/defer.js.map +0 -1
- package/dist/cjs/error.d.ts +0 -18
- package/dist/cjs/error.d.ts.map +0 -1
- package/dist/cjs/error.js +0 -63
- package/dist/cjs/error.js.map +0 -1
- package/dist/cjs/exports.d.ts +0 -99
- package/dist/cjs/exports.d.ts.map +0 -1
- package/dist/cjs/exports.js +0 -14
- package/dist/cjs/exports.js.map +0 -1
- package/dist/cjs/fs.d.ts +0 -23
- package/dist/cjs/fs.d.ts.map +0 -1
- package/dist/cjs/fs.js +0 -81
- package/dist/cjs/fs.js.map +0 -1
- package/dist/cjs/glob.d.ts.map +0 -1
- package/dist/cjs/glob.js +0 -117
- package/dist/cjs/glob.js.map +0 -1
- package/dist/cjs/hidden.d.ts.map +0 -1
- package/dist/cjs/hidden.js +0 -163
- package/dist/cjs/hidden.js.map +0 -1
- package/dist/cjs/index.cjs +0 -23
- package/dist/cjs/index.cjs.map +0 -1
- package/dist/cjs/index.d.cts.map +0 -1
- package/dist/cjs/linux/dev_disk.d.ts +0 -14
- package/dist/cjs/linux/dev_disk.d.ts.map +0 -1
- package/dist/cjs/linux/dev_disk.js +0 -66
- package/dist/cjs/linux/dev_disk.js.map +0 -1
- package/dist/cjs/linux/mount_points.d.ts.map +0 -1
- package/dist/cjs/linux/mount_points.js +0 -81
- package/dist/cjs/linux/mount_points.js.map +0 -1
- package/dist/cjs/linux/mtab.d.ts.map +0 -1
- package/dist/cjs/linux/mtab.js +0 -88
- package/dist/cjs/linux/mtab.js.map +0 -1
- package/dist/cjs/mount_point.d.ts.map +0 -1
- package/dist/cjs/mount_point.js +0 -67
- package/dist/cjs/mount_point.js.map +0 -1
- package/dist/cjs/number.d.ts.map +0 -1
- package/dist/cjs/number.js +0 -41
- package/dist/cjs/number.js.map +0 -1
- package/dist/cjs/object.d.ts +0 -18
- package/dist/cjs/object.d.ts.map +0 -1
- package/dist/cjs/object.js +0 -59
- package/dist/cjs/object.js.map +0 -1
- package/dist/cjs/options.d.ts.map +0 -1
- package/dist/cjs/options.js +0 -115
- package/dist/cjs/options.js.map +0 -1
- package/dist/cjs/path.d.ts.map +0 -1
- package/dist/cjs/path.js +0 -50
- package/dist/cjs/path.js.map +0 -1
- package/dist/cjs/platform.d.ts.map +0 -1
- package/dist/cjs/platform.js +0 -10
- package/dist/cjs/platform.js.map +0 -1
- package/dist/cjs/random.d.ts.map +0 -1
- package/dist/cjs/random.js +0 -43
- package/dist/cjs/random.js.map +0 -1
- package/dist/cjs/remote_info.d.ts +0 -39
- package/dist/cjs/remote_info.d.ts.map +0 -1
- package/dist/cjs/remote_info.js +0 -123
- package/dist/cjs/remote_info.js.map +0 -1
- package/dist/cjs/setup.d.ts.map +0 -1
- package/dist/cjs/setup.js +0 -47
- package/dist/cjs/setup.js.map +0 -1
- package/dist/cjs/string.d.ts.map +0 -1
- package/dist/cjs/string.js +0 -89
- package/dist/cjs/string.js.map +0 -1
- package/dist/cjs/string_enum.d.ts +0 -20
- package/dist/cjs/string_enum.d.ts.map +0 -1
- package/dist/cjs/string_enum.js +0 -27
- package/dist/cjs/string_enum.js.map +0 -1
- package/dist/cjs/system_volume.d.ts.map +0 -1
- package/dist/cjs/system_volume.js +0 -44
- package/dist/cjs/system_volume.js.map +0 -1
- package/dist/cjs/types/native_bindings.d.ts.map +0 -1
- package/dist/cjs/types/native_bindings.js +0 -4
- package/dist/cjs/types/native_bindings.js.map +0 -1
- package/dist/cjs/unc.d.ts +0 -12
- package/dist/cjs/unc.d.ts.map +0 -1
- package/dist/cjs/unc.js +0 -52
- package/dist/cjs/unc.js.map +0 -1
- package/dist/cjs/units.d.ts +0 -17
- package/dist/cjs/units.d.ts.map +0 -1
- package/dist/cjs/units.js +0 -35
- package/dist/cjs/units.js.map +0 -1
- package/dist/cjs/uuid.d.ts +0 -17
- package/dist/cjs/uuid.d.ts.map +0 -1
- package/dist/cjs/uuid.js +0 -25
- package/dist/cjs/uuid.js.map +0 -1
- package/dist/cjs/volume_health_status.d.ts +0 -25
- package/dist/cjs/volume_health_status.d.ts.map +0 -1
- package/dist/cjs/volume_health_status.js +0 -50
- package/dist/cjs/volume_health_status.js.map +0 -1
- package/dist/cjs/volume_metadata.d.ts.map +0 -1
- package/dist/cjs/volume_metadata.js +0 -169
- package/dist/cjs/volume_metadata.js.map +0 -1
- package/dist/esm/array.d.ts +0 -31
- package/dist/esm/array.d.ts.map +0 -1
- package/dist/esm/array.js +0 -50
- package/dist/esm/array.js.map +0 -1
- package/dist/esm/async.d.ts +0 -43
- package/dist/esm/async.d.ts.map +0 -1
- package/dist/esm/async.js +0 -109
- package/dist/esm/async.js.map +0 -1
- package/dist/esm/cache.d.ts +0 -5
- package/dist/esm/cache.d.ts.map +0 -1
- package/dist/esm/cache.js +0 -25
- package/dist/esm/cache.js.map +0 -1
- package/dist/esm/debuglog.d.ts +0 -9
- package/dist/esm/debuglog.d.ts.map +0 -1
- package/dist/esm/debuglog.js +0 -30
- package/dist/esm/debuglog.js.map +0 -1
- package/dist/esm/defer.d.ts.map +0 -1
- package/dist/esm/defer.js +0 -23
- package/dist/esm/defer.js.map +0 -1
- package/dist/esm/error.d.ts.map +0 -1
- package/dist/esm/error.js +0 -58
- package/dist/esm/error.js.map +0 -1
- package/dist/esm/exports.d.ts.map +0 -1
- package/dist/esm/exports.js +0 -4
- package/dist/esm/exports.js.map +0 -1
- package/dist/esm/fs.d.ts.map +0 -1
- package/dist/esm/fs.js +0 -73
- package/dist/esm/fs.js.map +0 -1
- package/dist/esm/glob.d.ts +0 -18
- package/dist/esm/glob.d.ts.map +0 -1
- package/dist/esm/glob.js +0 -113
- package/dist/esm/glob.js.map +0 -1
- package/dist/esm/hidden.d.ts +0 -67
- package/dist/esm/hidden.d.ts.map +0 -1
- package/dist/esm/hidden.js +0 -155
- package/dist/esm/hidden.js.map +0 -1
- package/dist/esm/index.d.ts.map +0 -1
- package/dist/esm/index.js +0 -7
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/linux/dev_disk.d.ts.map +0 -1
- package/dist/esm/linux/dev_disk.js +0 -61
- package/dist/esm/linux/dev_disk.js.map +0 -1
- package/dist/esm/linux/mount_points.d.ts +0 -7
- package/dist/esm/linux/mount_points.d.ts.map +0 -1
- package/dist/esm/linux/mount_points.js +0 -77
- package/dist/esm/linux/mount_points.js.map +0 -1
- package/dist/esm/linux/mtab.d.ts +0 -48
- package/dist/esm/linux/mtab.d.ts.map +0 -1
- package/dist/esm/linux/mtab.js +0 -82
- package/dist/esm/linux/mtab.js.map +0 -1
- package/dist/esm/mount_point.d.ts +0 -56
- package/dist/esm/mount_point.d.ts.map +0 -1
- package/dist/esm/mount_point.js +0 -63
- package/dist/esm/mount_point.js.map +0 -1
- package/dist/esm/number.d.ts +0 -8
- package/dist/esm/number.d.ts.map +0 -1
- package/dist/esm/number.js +0 -32
- package/dist/esm/number.js.map +0 -1
- package/dist/esm/object.d.ts.map +0 -1
- package/dist/esm/object.js +0 -52
- package/dist/esm/object.js.map +0 -1
- package/dist/esm/options.d.ts +0 -80
- package/dist/esm/options.d.ts.map +0 -1
- package/dist/esm/options.js +0 -111
- package/dist/esm/options.js.map +0 -1
- package/dist/esm/path.d.ts +0 -18
- package/dist/esm/path.d.ts.map +0 -1
- package/dist/esm/path.js +0 -44
- package/dist/esm/path.js.map +0 -1
- package/dist/esm/platform.d.ts +0 -4
- package/dist/esm/platform.d.ts.map +0 -1
- package/dist/esm/platform.js +0 -7
- package/dist/esm/platform.js.map +0 -1
- package/dist/esm/random.d.ts +0 -13
- package/dist/esm/random.d.ts.map +0 -1
- package/dist/esm/random.js +0 -37
- package/dist/esm/random.js.map +0 -1
- package/dist/esm/remote_info.d.ts.map +0 -1
- package/dist/esm/remote_info.js +0 -116
- package/dist/esm/remote_info.js.map +0 -1
- package/dist/esm/setup.d.ts +0 -3
- package/dist/esm/setup.d.ts.map +0 -1
- package/dist/esm/setup.js +0 -41
- package/dist/esm/setup.js.map +0 -1
- package/dist/esm/string.d.ts +0 -38
- package/dist/esm/string.d.ts.map +0 -1
- package/dist/esm/string.js +0 -78
- package/dist/esm/string.js.map +0 -1
- package/dist/esm/string_enum.d.ts.map +0 -1
- package/dist/esm/string_enum.js +0 -24
- package/dist/esm/string_enum.js.map +0 -1
- package/dist/esm/system_volume.d.ts +0 -15
- package/dist/esm/system_volume.d.ts.map +0 -1
- package/dist/esm/system_volume.js +0 -40
- package/dist/esm/system_volume.js.map +0 -1
- package/dist/esm/types/native_bindings.d.ts +0 -52
- package/dist/esm/types/native_bindings.d.ts.map +0 -1
- package/dist/esm/types/native_bindings.js +0 -3
- package/dist/esm/types/native_bindings.js.map +0 -1
- package/dist/esm/unc.d.ts.map +0 -1
- package/dist/esm/unc.js +0 -49
- package/dist/esm/unc.js.map +0 -1
- package/dist/esm/units.d.ts.map +0 -1
- package/dist/esm/units.js +0 -31
- package/dist/esm/units.js.map +0 -1
- package/dist/esm/uuid.d.ts.map +0 -1
- package/dist/esm/uuid.js +0 -22
- package/dist/esm/uuid.js.map +0 -1
- package/dist/esm/volume_health_status.d.ts.map +0 -1
- package/dist/esm/volume_health_status.js +0 -46
- package/dist/esm/volume_health_status.js.map +0 -1
- package/dist/esm/volume_metadata.d.ts +0 -55
- package/dist/esm/volume_metadata.d.ts.map +0 -1
- package/dist/esm/volume_metadata.js +0 -164
- package/dist/esm/volume_metadata.js.map +0 -1
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1318 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.cts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
IncludeSystemVolumesDefault: () => IncludeSystemVolumesDefault,
|
|
34
|
+
LinuxMountTablePathsDefault: () => LinuxMountTablePathsDefault,
|
|
35
|
+
OptionsDefault: () => OptionsDefault,
|
|
36
|
+
SystemFsTypesDefault: () => SystemFsTypesDefault,
|
|
37
|
+
SystemPathPatternsDefault: () => SystemPathPatternsDefault,
|
|
38
|
+
TimeoutMsDefault: () => TimeoutMsDefault,
|
|
39
|
+
VolumeHealthStatuses: () => VolumeHealthStatuses,
|
|
40
|
+
getAllVolumeMetadata: () => getAllVolumeMetadata2,
|
|
41
|
+
getHiddenMetadata: () => getHiddenMetadata2,
|
|
42
|
+
getVolumeMetadata: () => getVolumeMetadata2,
|
|
43
|
+
getVolumeMountPoints: () => getVolumeMountPoints2,
|
|
44
|
+
isHidden: () => isHidden2,
|
|
45
|
+
isHiddenRecursive: () => isHiddenRecursive2,
|
|
46
|
+
optionsWithDefaults: () => optionsWithDefaults,
|
|
47
|
+
setHidden: () => setHidden2
|
|
48
|
+
});
|
|
49
|
+
module.exports = __toCommonJS(index_exports);
|
|
50
|
+
|
|
51
|
+
// src/setup.ts
|
|
52
|
+
var import_node_gyp_build = __toESM(require("node-gyp-build"));
|
|
53
|
+
|
|
54
|
+
// src/debuglog.ts
|
|
55
|
+
var import_node_util = require("util");
|
|
56
|
+
|
|
57
|
+
// src/defer.ts
|
|
58
|
+
function defer(thunk) {
|
|
59
|
+
let computed = false;
|
|
60
|
+
let value;
|
|
61
|
+
const fn = () => {
|
|
62
|
+
if (!computed) {
|
|
63
|
+
computed = true;
|
|
64
|
+
value = thunk();
|
|
65
|
+
}
|
|
66
|
+
return value;
|
|
67
|
+
};
|
|
68
|
+
fn.reset = () => {
|
|
69
|
+
computed = false;
|
|
70
|
+
};
|
|
71
|
+
return fn;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// src/debuglog.ts
|
|
75
|
+
var debugLogContext = defer(() => {
|
|
76
|
+
for (const ea of ["fs-metadata", "fs-meta"]) {
|
|
77
|
+
if ((0, import_node_util.debuglog)(ea).enabled) {
|
|
78
|
+
return ea;
|
|
79
|
+
}
|
|
80
|
+
if ((0, import_node_util.debuglog)(ea.toUpperCase()).enabled) {
|
|
81
|
+
return ea;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return "photostructure:fs-metadata";
|
|
85
|
+
});
|
|
86
|
+
var isDebugEnabled = defer(() => {
|
|
87
|
+
return (0, import_node_util.debuglog)(debugLogContext()).enabled ?? false;
|
|
88
|
+
});
|
|
89
|
+
function debug(msg, ...args) {
|
|
90
|
+
if (!isDebugEnabled()) return;
|
|
91
|
+
const now = /* @__PURE__ */ new Date();
|
|
92
|
+
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()} `;
|
|
93
|
+
process.stderr.write(timestamp + (0, import_node_util.format)(msg, ...args) + "\n");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// src/fs.ts
|
|
97
|
+
var import_node_fs = require("fs");
|
|
98
|
+
var import_promises = require("fs/promises");
|
|
99
|
+
var import_node_path = require("path");
|
|
100
|
+
|
|
101
|
+
// src/async.ts
|
|
102
|
+
var import_node_os = require("os");
|
|
103
|
+
var import_node_process = require("process");
|
|
104
|
+
|
|
105
|
+
// src/number.ts
|
|
106
|
+
function isNumber(value) {
|
|
107
|
+
return typeof value === "number" && isFinite(value);
|
|
108
|
+
}
|
|
109
|
+
var INTEGER_REGEX = /^-?\d+$/;
|
|
110
|
+
function toInt(value) {
|
|
111
|
+
try {
|
|
112
|
+
if (value == null) return;
|
|
113
|
+
const s = String(value).trim();
|
|
114
|
+
return INTEGER_REGEX.test(s) ? parseInt(s) : void 0;
|
|
115
|
+
} catch {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function gt0(value) {
|
|
120
|
+
return isNumber(value) && value > 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// src/string.ts
|
|
124
|
+
function isString(input) {
|
|
125
|
+
return typeof input === "string";
|
|
126
|
+
}
|
|
127
|
+
function toS(input) {
|
|
128
|
+
return isString(input) ? input : input == null ? "" : String(input);
|
|
129
|
+
}
|
|
130
|
+
function isNotBlank(input) {
|
|
131
|
+
return typeof input === "string" && input.trim().length > 0;
|
|
132
|
+
}
|
|
133
|
+
function isBlank(input) {
|
|
134
|
+
return !isNotBlank(input);
|
|
135
|
+
}
|
|
136
|
+
function toNotBlank(input) {
|
|
137
|
+
return isNotBlank(input) ? input : void 0;
|
|
138
|
+
}
|
|
139
|
+
function decodeEscapeSequences(input) {
|
|
140
|
+
const escapeRegex = /\\(?:([0-7]{2,6})|x([0-9a-fA-F]{2,4}))/g;
|
|
141
|
+
return input.replace(escapeRegex, (match, octal, hex) => {
|
|
142
|
+
if (octal != null) {
|
|
143
|
+
return String.fromCharCode(parseInt(octal, 8));
|
|
144
|
+
}
|
|
145
|
+
if (hex != null) {
|
|
146
|
+
return String.fromCharCode(parseInt(hex, 16));
|
|
147
|
+
}
|
|
148
|
+
throw new Error(`Invalid escape sequence: ${match}`);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
function sortObjectsByLocale(arr, fn, locales, options) {
|
|
152
|
+
return arr.sort((a, b) => fn(a).localeCompare(fn(b), locales, options));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// src/async.ts
|
|
156
|
+
var TimeoutError = class extends Error {
|
|
157
|
+
constructor(message, captureStackTrace = true) {
|
|
158
|
+
super(message);
|
|
159
|
+
this.name = "TimeoutError";
|
|
160
|
+
if (captureStackTrace && Error.captureStackTrace) {
|
|
161
|
+
Error.captureStackTrace(this, this.constructor);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
async function withTimeout(opts) {
|
|
166
|
+
const desc = isBlank(opts.desc) ? "thenOrTimeout()" : opts.desc;
|
|
167
|
+
if (!isNumber(opts.timeoutMs)) {
|
|
168
|
+
throw new TypeError(
|
|
169
|
+
desc + ": Expected timeoutMs to be numeric, but got " + JSON.stringify(opts.timeoutMs)
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
const timeoutMs = Math.floor(opts.timeoutMs);
|
|
173
|
+
if (timeoutMs < 0) {
|
|
174
|
+
throw new TypeError(
|
|
175
|
+
desc + ": Expected timeoutMs to be > 0, but got " + timeoutMs
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
if (timeoutMs === 0) {
|
|
179
|
+
return opts.promise;
|
|
180
|
+
}
|
|
181
|
+
const timeoutError = new TimeoutError(
|
|
182
|
+
`${desc}: timeout after ${timeoutMs}ms`
|
|
183
|
+
);
|
|
184
|
+
if (import_node_process.env["NODE_ENV"] === "test" && timeoutMs === 1) {
|
|
185
|
+
timeoutError.message += "(timeout test)";
|
|
186
|
+
opts.promise.catch(() => {
|
|
187
|
+
});
|
|
188
|
+
throw timeoutError;
|
|
189
|
+
}
|
|
190
|
+
let timeoutId;
|
|
191
|
+
opts.promise.catch(() => {
|
|
192
|
+
}).finally(() => {
|
|
193
|
+
if (timeoutId != null) {
|
|
194
|
+
clearTimeout(timeoutId);
|
|
195
|
+
timeoutId = void 0;
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
199
|
+
timeoutId = setTimeout(() => {
|
|
200
|
+
if (timeoutId != null) {
|
|
201
|
+
timeoutError.message += "(timeout callback)";
|
|
202
|
+
reject(timeoutError);
|
|
203
|
+
}
|
|
204
|
+
timeoutId = void 0;
|
|
205
|
+
}, timeoutMs);
|
|
206
|
+
});
|
|
207
|
+
return Promise.race([opts.promise, timeoutPromise]);
|
|
208
|
+
}
|
|
209
|
+
async function mapConcurrent({
|
|
210
|
+
items,
|
|
211
|
+
fn,
|
|
212
|
+
maxConcurrency = (0, import_node_os.availableParallelism)()
|
|
213
|
+
}) {
|
|
214
|
+
if (!gt0(maxConcurrency)) {
|
|
215
|
+
throw new Error(
|
|
216
|
+
`maxConcurrency must be a positive integer, got: ${maxConcurrency}`
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
if (typeof fn !== "function") {
|
|
220
|
+
throw new TypeError(`fn must be a function, got: ${typeof fn}`);
|
|
221
|
+
}
|
|
222
|
+
const results = [];
|
|
223
|
+
const executing = /* @__PURE__ */ new Set();
|
|
224
|
+
for (const [index, item] of items.entries()) {
|
|
225
|
+
while (executing.size >= maxConcurrency) {
|
|
226
|
+
await Promise.race(executing);
|
|
227
|
+
}
|
|
228
|
+
const p2 = results[index] = fn(item).catch((error) => error);
|
|
229
|
+
executing.add(p2);
|
|
230
|
+
p2.finally(() => executing.delete(p2));
|
|
231
|
+
}
|
|
232
|
+
return Promise.all(results);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// src/fs.ts
|
|
236
|
+
async function statAsync(path, options) {
|
|
237
|
+
return (0, import_promises.stat)(path, options);
|
|
238
|
+
}
|
|
239
|
+
async function canStatAsync(path) {
|
|
240
|
+
try {
|
|
241
|
+
return null != await statAsync(path);
|
|
242
|
+
} catch {
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
async function findAncestorDir(dir, file) {
|
|
247
|
+
dir = (0, import_node_path.resolve)(dir);
|
|
248
|
+
try {
|
|
249
|
+
const s = await statAsync((0, import_node_path.join)(dir, file));
|
|
250
|
+
if (s.isFile()) return dir;
|
|
251
|
+
} catch {
|
|
252
|
+
}
|
|
253
|
+
const parent = (0, import_node_path.resolve)(dir, "..");
|
|
254
|
+
return parent === dir ? void 0 : findAncestorDir(parent, file);
|
|
255
|
+
}
|
|
256
|
+
async function canReaddir(dir, timeoutMs) {
|
|
257
|
+
return withTimeout({
|
|
258
|
+
desc: "canReaddir()",
|
|
259
|
+
promise: _canReaddir(dir),
|
|
260
|
+
timeoutMs
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
async function _canReaddir(dir) {
|
|
264
|
+
let d = void 0;
|
|
265
|
+
try {
|
|
266
|
+
d = await (0, import_promises.opendir)(dir);
|
|
267
|
+
await d.read();
|
|
268
|
+
return true;
|
|
269
|
+
} finally {
|
|
270
|
+
if (d != null) void d.close();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// src/hidden.ts
|
|
275
|
+
var import_promises2 = require("fs/promises");
|
|
276
|
+
var import_node_path3 = require("path");
|
|
277
|
+
|
|
278
|
+
// src/object.ts
|
|
279
|
+
function isObject(value) {
|
|
280
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
281
|
+
}
|
|
282
|
+
function map(obj, fn) {
|
|
283
|
+
return obj == null ? void 0 : fn(obj);
|
|
284
|
+
}
|
|
285
|
+
function omit(obj, ...keys) {
|
|
286
|
+
const result = {};
|
|
287
|
+
const keysSet = new Set(keys);
|
|
288
|
+
for (const key of Object.keys(obj)) {
|
|
289
|
+
if (!keysSet.has(key)) {
|
|
290
|
+
result[key] = obj[key];
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return result;
|
|
294
|
+
}
|
|
295
|
+
function compactValues(obj) {
|
|
296
|
+
const result = {};
|
|
297
|
+
if (obj == null || !isObject(obj)) return {};
|
|
298
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
299
|
+
if (value != null && (!isString(value) || isNotBlank(value))) {
|
|
300
|
+
result[key] = value;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return result;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// src/error.ts
|
|
307
|
+
function toMessage(context, cause) {
|
|
308
|
+
const causeStr = cause instanceof Error ? cause.message : typeof cause === "string" ? cause : cause ? JSON.stringify(cause) : "";
|
|
309
|
+
return context + (isBlank(causeStr) ? "" : ": " + causeStr);
|
|
310
|
+
}
|
|
311
|
+
var WrappedError = class extends Error {
|
|
312
|
+
errno;
|
|
313
|
+
code;
|
|
314
|
+
syscall;
|
|
315
|
+
path;
|
|
316
|
+
constructor(context, options) {
|
|
317
|
+
super(toMessage(context, options?.cause));
|
|
318
|
+
const cause = map(options?.cause, toError);
|
|
319
|
+
const opts = { ...compactValues(cause), ...compactValues(options) };
|
|
320
|
+
if (isNotBlank(options?.name)) {
|
|
321
|
+
this.name = options.name;
|
|
322
|
+
}
|
|
323
|
+
if (cause != null) {
|
|
324
|
+
this.cause = cause;
|
|
325
|
+
if (cause instanceof Error) {
|
|
326
|
+
this.stack = `${this.stack}
|
|
327
|
+
Caused by: ${cause.stack}`;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
if (isNumber(opts.errno)) {
|
|
331
|
+
this.errno = opts.errno;
|
|
332
|
+
}
|
|
333
|
+
if (isNotBlank(opts.code)) {
|
|
334
|
+
this.code = opts.code;
|
|
335
|
+
}
|
|
336
|
+
if (isNotBlank(opts.syscall)) {
|
|
337
|
+
this.syscall = opts.syscall;
|
|
338
|
+
}
|
|
339
|
+
if (isNotBlank(options?.path)) {
|
|
340
|
+
this.path = options.path;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
get details() {
|
|
344
|
+
return compactValues(omit(this, "name", "message", "cause"));
|
|
345
|
+
}
|
|
346
|
+
toString() {
|
|
347
|
+
const details = this.details;
|
|
348
|
+
const detailsStr = Object.keys(details).length === 0 ? "" : " " + JSON.stringify(details);
|
|
349
|
+
return `${super.toString()}${detailsStr}`;
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
function toError(cause) {
|
|
353
|
+
return cause instanceof Error ? cause : new Error(String(cause));
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// src/path.ts
|
|
357
|
+
var import_node_path2 = require("path");
|
|
358
|
+
|
|
359
|
+
// src/platform.ts
|
|
360
|
+
var import_node_os2 = require("os");
|
|
361
|
+
var p = (0, import_node_os2.platform)();
|
|
362
|
+
var isLinux = p === "linux";
|
|
363
|
+
var isWindows = p === "win32";
|
|
364
|
+
var isMacOS = p === "darwin";
|
|
365
|
+
|
|
366
|
+
// src/path.ts
|
|
367
|
+
function normalizePath(mountPoint) {
|
|
368
|
+
if (isBlank(mountPoint)) return void 0;
|
|
369
|
+
const result = isWindows ? normalizeWindowsPath(mountPoint) : normalizePosixPath(mountPoint);
|
|
370
|
+
return result != null ? (0, import_node_path2.resolve)(result) : void 0;
|
|
371
|
+
}
|
|
372
|
+
function normalizePosixPath(mountPoint) {
|
|
373
|
+
return isBlank(mountPoint) ? void 0 : mountPoint === "/" ? mountPoint : mountPoint.replace(/\/+$/, "");
|
|
374
|
+
}
|
|
375
|
+
function normalizeWindowsPath(mountPoint) {
|
|
376
|
+
return /^[a-z]:$/i.test(mountPoint) ? mountPoint.toUpperCase() + "\\" : mountPoint;
|
|
377
|
+
}
|
|
378
|
+
function isRootDirectory(path) {
|
|
379
|
+
const n = normalizePath(path);
|
|
380
|
+
return n == null ? false : isWindows ? (0, import_node_path2.dirname)(n) === n : n === "/";
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// src/hidden.ts
|
|
384
|
+
var HiddenSupportByPlatform = {
|
|
385
|
+
win32: {
|
|
386
|
+
supported: {
|
|
387
|
+
dotPrefix: false,
|
|
388
|
+
systemFlag: true
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
darwin: {
|
|
392
|
+
supported: {
|
|
393
|
+
dotPrefix: true,
|
|
394
|
+
systemFlag: true
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
linux: {
|
|
398
|
+
supported: {
|
|
399
|
+
dotPrefix: true,
|
|
400
|
+
systemFlag: false
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
var LocalSupport = HiddenSupportByPlatform[process.platform]?.supported ?? {
|
|
405
|
+
dotPrefix: false,
|
|
406
|
+
systemFlag: false
|
|
407
|
+
};
|
|
408
|
+
async function isHidden(pathname, nativeFn) {
|
|
409
|
+
const norm = normalizePath(pathname);
|
|
410
|
+
if (norm == null) {
|
|
411
|
+
throw new Error("Invalid pathname: " + JSON.stringify(pathname));
|
|
412
|
+
}
|
|
413
|
+
return LocalSupport.dotPrefix && isPosixHidden(norm) || LocalSupport.systemFlag && isSystemHidden(norm, nativeFn);
|
|
414
|
+
}
|
|
415
|
+
async function isHiddenRecursive(path, nativeFn) {
|
|
416
|
+
let norm = normalizePath(path);
|
|
417
|
+
if (norm == null) {
|
|
418
|
+
throw new Error("Invalid path: " + JSON.stringify(path));
|
|
419
|
+
}
|
|
420
|
+
while (!isRootDirectory(norm)) {
|
|
421
|
+
if (await isHidden(norm, nativeFn)) {
|
|
422
|
+
return true;
|
|
423
|
+
}
|
|
424
|
+
norm = (0, import_node_path3.dirname)(norm);
|
|
425
|
+
}
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
function createHiddenPosixPath(pathname, hidden) {
|
|
429
|
+
const norm = normalizePath(pathname);
|
|
430
|
+
if (norm == null) {
|
|
431
|
+
throw new Error("Invalid pathname: " + JSON.stringify(pathname));
|
|
432
|
+
}
|
|
433
|
+
const dir = (0, import_node_path3.dirname)(norm);
|
|
434
|
+
const srcBase = (0, import_node_path3.basename)(norm).replace(/^\./, "");
|
|
435
|
+
const dest = (0, import_node_path3.join)(dir, (hidden ? "." : "") + srcBase);
|
|
436
|
+
return dest;
|
|
437
|
+
}
|
|
438
|
+
async function setHiddenPosix(pathname, hidden) {
|
|
439
|
+
if (LocalSupport.dotPrefix) {
|
|
440
|
+
const dest = createHiddenPosixPath(pathname, hidden);
|
|
441
|
+
if (pathname !== dest) await (0, import_promises2.rename)(pathname, dest);
|
|
442
|
+
return dest;
|
|
443
|
+
}
|
|
444
|
+
throw new Error("Unsupported platform");
|
|
445
|
+
}
|
|
446
|
+
function isPosixHidden(pathname) {
|
|
447
|
+
if (!LocalSupport.dotPrefix) return false;
|
|
448
|
+
const b = (0, import_node_path3.basename)(pathname);
|
|
449
|
+
return b.startsWith(".") && b !== "." && b !== "..";
|
|
450
|
+
}
|
|
451
|
+
async function isSystemHidden(pathname, nativeFn) {
|
|
452
|
+
if (!LocalSupport.systemFlag) {
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
if (isWindows && isRootDirectory(pathname)) {
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
return await canStatAsync(pathname) && await (await nativeFn()).isHidden(pathname);
|
|
459
|
+
}
|
|
460
|
+
async function getHiddenMetadata(pathname, nativeFn) {
|
|
461
|
+
const norm = normalizePath(pathname);
|
|
462
|
+
if (norm == null) {
|
|
463
|
+
throw new Error("Invalid pathname: " + JSON.stringify(pathname));
|
|
464
|
+
}
|
|
465
|
+
const dotPrefix = isPosixHidden(norm);
|
|
466
|
+
const systemFlag = await isSystemHidden(norm, nativeFn);
|
|
467
|
+
return {
|
|
468
|
+
hidden: dotPrefix || systemFlag,
|
|
469
|
+
dotPrefix,
|
|
470
|
+
systemFlag,
|
|
471
|
+
supported: LocalSupport
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
async function setHidden(pathname, hide, method, nativeFn) {
|
|
475
|
+
let norm = normalizePath(pathname);
|
|
476
|
+
if (norm == null) {
|
|
477
|
+
throw new Error("Invalid pathname: " + JSON.stringify(pathname));
|
|
478
|
+
}
|
|
479
|
+
if (method === "dotPrefix" && !LocalSupport.dotPrefix) {
|
|
480
|
+
throw new Error("Dot prefix hiding is not supported on this platform");
|
|
481
|
+
}
|
|
482
|
+
if (method === "systemFlag" && !LocalSupport.systemFlag) {
|
|
483
|
+
throw new Error("System flag hiding is not supported on this platform");
|
|
484
|
+
}
|
|
485
|
+
try {
|
|
486
|
+
await statAsync(norm);
|
|
487
|
+
} catch (cause) {
|
|
488
|
+
throw new WrappedError("setHidden()", { cause });
|
|
489
|
+
}
|
|
490
|
+
if (isWindows && isRootDirectory(norm)) {
|
|
491
|
+
throw new Error("Cannot hide root directory on Windows");
|
|
492
|
+
}
|
|
493
|
+
const actions = {
|
|
494
|
+
dotPrefix: false,
|
|
495
|
+
systemFlag: false
|
|
496
|
+
};
|
|
497
|
+
let acted = false;
|
|
498
|
+
if (LocalSupport.dotPrefix && ["auto", "all", "dotPrefix"].includes(method)) {
|
|
499
|
+
if (isPosixHidden(norm) !== hide) {
|
|
500
|
+
norm = await setHiddenPosix(norm, hide);
|
|
501
|
+
actions.dotPrefix = true;
|
|
502
|
+
}
|
|
503
|
+
acted = true;
|
|
504
|
+
}
|
|
505
|
+
if (LocalSupport.systemFlag && (["all", "systemFlag"].includes(method) || !acted && method === "auto")) {
|
|
506
|
+
await (await nativeFn()).setHidden(norm, hide);
|
|
507
|
+
actions.systemFlag = true;
|
|
508
|
+
}
|
|
509
|
+
return { pathname: norm, actions };
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// src/array.ts
|
|
513
|
+
function uniqBy(arr, keyFn) {
|
|
514
|
+
const seen = /* @__PURE__ */ new Set();
|
|
515
|
+
return arr.filter((item) => {
|
|
516
|
+
const key = keyFn(item);
|
|
517
|
+
if (key == null || seen.has(key)) return false;
|
|
518
|
+
seen.add(key);
|
|
519
|
+
return true;
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// src/linux/mount_points.ts
|
|
524
|
+
var import_promises3 = require("fs/promises");
|
|
525
|
+
|
|
526
|
+
// src/options.ts
|
|
527
|
+
var import_node_os3 = require("os");
|
|
528
|
+
var TimeoutMsDefault = 5e3;
|
|
529
|
+
var SystemPathPatternsDefault = [
|
|
530
|
+
"/boot",
|
|
531
|
+
"/boot/efi",
|
|
532
|
+
"/dev",
|
|
533
|
+
"/dev/**",
|
|
534
|
+
"/proc/**",
|
|
535
|
+
"/run",
|
|
536
|
+
"/run/credentials/**",
|
|
537
|
+
"/run/lock",
|
|
538
|
+
"/run/snapd/**",
|
|
539
|
+
"/run/user/*/doc",
|
|
540
|
+
"/run/user/*/gvfs",
|
|
541
|
+
"/snap/**",
|
|
542
|
+
"/sys/**",
|
|
543
|
+
// windows for linux:
|
|
544
|
+
"/mnt/wslg/distro",
|
|
545
|
+
"/mnt/wslg/doc",
|
|
546
|
+
"/mnt/wslg/versions.txt",
|
|
547
|
+
"/usr/lib/wsl/drivers",
|
|
548
|
+
// MacOS stuff:
|
|
549
|
+
"/private/var/vm",
|
|
550
|
+
// macOS swap
|
|
551
|
+
"/System/Volumes/Hardware",
|
|
552
|
+
"/System/Volumes/iSCPreboot",
|
|
553
|
+
"/System/Volumes/Preboot",
|
|
554
|
+
"/System/Volumes/Recovery",
|
|
555
|
+
"/System/Volumes/Reserved",
|
|
556
|
+
"/System/Volumes/Update",
|
|
557
|
+
"/System/Volumes/VM",
|
|
558
|
+
"/System/Volumes/xarts"
|
|
559
|
+
];
|
|
560
|
+
var SystemFsTypesDefault = /* @__PURE__ */ new Set([
|
|
561
|
+
"autofs",
|
|
562
|
+
"binfmt_misc",
|
|
563
|
+
"cgroup",
|
|
564
|
+
"cgroup2",
|
|
565
|
+
"configfs",
|
|
566
|
+
"debugfs",
|
|
567
|
+
"devpts",
|
|
568
|
+
"devtmpfs",
|
|
569
|
+
"efivarfs",
|
|
570
|
+
"fusectl",
|
|
571
|
+
"fuse.snapfuse",
|
|
572
|
+
"hugetlbfs",
|
|
573
|
+
"mqueue",
|
|
574
|
+
"none",
|
|
575
|
+
"proc",
|
|
576
|
+
"pstore",
|
|
577
|
+
"rootfs",
|
|
578
|
+
"securityfs",
|
|
579
|
+
"snap*",
|
|
580
|
+
"squashfs",
|
|
581
|
+
"sysfs",
|
|
582
|
+
"tmpfs"
|
|
583
|
+
]);
|
|
584
|
+
var LinuxMountTablePathsDefault = [
|
|
585
|
+
"/proc/self/mounts",
|
|
586
|
+
"/proc/mounts",
|
|
587
|
+
"/etc/mtab"
|
|
588
|
+
];
|
|
589
|
+
var IncludeSystemVolumesDefault = isWindows;
|
|
590
|
+
var OptionsDefault = {
|
|
591
|
+
timeoutMs: TimeoutMsDefault,
|
|
592
|
+
maxConcurrency: (0, import_node_os3.availableParallelism)(),
|
|
593
|
+
systemPathPatterns: [...SystemPathPatternsDefault],
|
|
594
|
+
systemFsTypes: new Set(SystemFsTypesDefault),
|
|
595
|
+
linuxMountTablePaths: LinuxMountTablePathsDefault,
|
|
596
|
+
includeSystemVolumes: IncludeSystemVolumesDefault
|
|
597
|
+
};
|
|
598
|
+
function optionsWithDefaults(overrides = {}) {
|
|
599
|
+
if (!isObject(overrides)) {
|
|
600
|
+
throw new TypeError(
|
|
601
|
+
"options(): expected an object, got " + typeof overrides + ": " + JSON.stringify(overrides)
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
return {
|
|
605
|
+
...OptionsDefault,
|
|
606
|
+
...compactValues(overrides)
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// src/glob.ts
|
|
611
|
+
var cache = /* @__PURE__ */ new Map();
|
|
612
|
+
function compileGlob(patterns) {
|
|
613
|
+
if (patterns == null || patterns.length === 0) {
|
|
614
|
+
return NeverMatchRE;
|
|
615
|
+
}
|
|
616
|
+
const patternsKey = JSON.stringify(patterns);
|
|
617
|
+
{
|
|
618
|
+
const prior = cache.get(patternsKey);
|
|
619
|
+
if (prior != null) {
|
|
620
|
+
return prior;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
const sorted = patterns.slice().filter(isNotBlank).sort();
|
|
624
|
+
const sortedKey = JSON.stringify(sorted);
|
|
625
|
+
{
|
|
626
|
+
const prior = cache.get(sortedKey);
|
|
627
|
+
if (prior != null) {
|
|
628
|
+
cache.set(patternsKey, prior);
|
|
629
|
+
return prior;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
const result = _compileGlob(sorted);
|
|
633
|
+
if (cache.size > 256) {
|
|
634
|
+
cache.clear();
|
|
635
|
+
}
|
|
636
|
+
cache.set(patternsKey, result);
|
|
637
|
+
cache.set(sortedKey, result);
|
|
638
|
+
return result;
|
|
639
|
+
}
|
|
640
|
+
function _compileGlob(patterns) {
|
|
641
|
+
const regexPatterns = patterns.map((pattern) => {
|
|
642
|
+
let regex = "";
|
|
643
|
+
let i = 0;
|
|
644
|
+
while (i < pattern.length) {
|
|
645
|
+
if (pattern[i] === "*" && pattern[i + 1] === "*") {
|
|
646
|
+
regex += ".*";
|
|
647
|
+
i += 2;
|
|
648
|
+
if (pattern[i] === "/") {
|
|
649
|
+
i++;
|
|
650
|
+
}
|
|
651
|
+
continue;
|
|
652
|
+
}
|
|
653
|
+
if (pattern[i] === "*") {
|
|
654
|
+
regex += "[^/]*";
|
|
655
|
+
i++;
|
|
656
|
+
continue;
|
|
657
|
+
}
|
|
658
|
+
if (pattern[i] === "?") {
|
|
659
|
+
regex += "[^/]";
|
|
660
|
+
i++;
|
|
661
|
+
continue;
|
|
662
|
+
}
|
|
663
|
+
if (pattern[i] === ".") {
|
|
664
|
+
regex += "\\.";
|
|
665
|
+
i++;
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
if (pattern[i] === "/") {
|
|
669
|
+
if (i === pattern.length - 1) {
|
|
670
|
+
regex += "(?:/|$)";
|
|
671
|
+
i++;
|
|
672
|
+
continue;
|
|
673
|
+
} else if (isWindows) {
|
|
674
|
+
regex += "[\\/\\\\]";
|
|
675
|
+
i++;
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
if (/[+^${}()|[\]\\]/.test(pattern[i])) {
|
|
680
|
+
regex += "\\" + pattern[i];
|
|
681
|
+
i++;
|
|
682
|
+
continue;
|
|
683
|
+
}
|
|
684
|
+
regex += pattern[i];
|
|
685
|
+
i++;
|
|
686
|
+
}
|
|
687
|
+
return regex;
|
|
688
|
+
});
|
|
689
|
+
const final = regexPatterns.filter((ea) => ea.length > 0);
|
|
690
|
+
return final.length === 0 ? (
|
|
691
|
+
// Empty pattern matches nothing
|
|
692
|
+
NeverMatchRE
|
|
693
|
+
) : new RegExp(`^(?:${final.join("|")})$`, "i");
|
|
694
|
+
}
|
|
695
|
+
var NeverMatchRE = /(?!)/;
|
|
696
|
+
|
|
697
|
+
// src/system_volume.ts
|
|
698
|
+
function isSystemVolume(mountPoint, fstype, config = {}) {
|
|
699
|
+
debug("[isSystemVolume] checking %s (fstype: %s)", mountPoint, fstype);
|
|
700
|
+
if (isWindows) {
|
|
701
|
+
const systemDrive = normalizePath(process.env["SystemDrive"]);
|
|
702
|
+
if (systemDrive != null && mountPoint === systemDrive) {
|
|
703
|
+
debug("[isSystemVolume] %s is the Windows system drive", mountPoint);
|
|
704
|
+
return true;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
const result = isNotBlank(fstype) && (config.systemFsTypes ?? SystemFsTypesDefault).has(fstype) || compileGlob(config.systemPathPatterns ?? SystemPathPatternsDefault).test(
|
|
708
|
+
mountPoint
|
|
709
|
+
);
|
|
710
|
+
debug("[isSystemVolume] %s -> %s", mountPoint, result);
|
|
711
|
+
return result;
|
|
712
|
+
}
|
|
713
|
+
function assignSystemVolume(mp, config) {
|
|
714
|
+
const result = isSystemVolume(mp.mountPoint, mp.fstype, config);
|
|
715
|
+
if (isWindows) {
|
|
716
|
+
mp.isSystemVolume ??= result;
|
|
717
|
+
} else {
|
|
718
|
+
mp.isSystemVolume = result;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
// src/remote_info.ts
|
|
723
|
+
function isRemoteInfo(obj) {
|
|
724
|
+
if (!isObject(obj)) return false;
|
|
725
|
+
const { remoteHost, remoteShare } = obj;
|
|
726
|
+
return isNotBlank(remoteHost) && isNotBlank(remoteShare);
|
|
727
|
+
}
|
|
728
|
+
var NETWORK_FS_TYPES = /* @__PURE__ */ new Set([
|
|
729
|
+
"9p",
|
|
730
|
+
"afp",
|
|
731
|
+
"afs",
|
|
732
|
+
"beegfs",
|
|
733
|
+
"ceph",
|
|
734
|
+
"cifs",
|
|
735
|
+
"ftp",
|
|
736
|
+
"fuse.cephfs",
|
|
737
|
+
"fuse.glusterfs",
|
|
738
|
+
"fuse.sshfs",
|
|
739
|
+
"fuse",
|
|
740
|
+
"gfs2",
|
|
741
|
+
"glusterfs",
|
|
742
|
+
"lustre",
|
|
743
|
+
"ncpfs",
|
|
744
|
+
"nfs",
|
|
745
|
+
"nfs4",
|
|
746
|
+
"smb",
|
|
747
|
+
"smbfs",
|
|
748
|
+
"sshfs",
|
|
749
|
+
"webdav"
|
|
750
|
+
]);
|
|
751
|
+
function normalizeProtocol(protocol) {
|
|
752
|
+
return (protocol ?? "").toLowerCase().replace(/:$/, "");
|
|
753
|
+
}
|
|
754
|
+
function isRemoteFsType(fstype) {
|
|
755
|
+
return isNotBlank(fstype) && NETWORK_FS_TYPES.has(normalizeProtocol(fstype));
|
|
756
|
+
}
|
|
757
|
+
function parseURL(s) {
|
|
758
|
+
try {
|
|
759
|
+
return isBlank(s) ? void 0 : new URL(s);
|
|
760
|
+
} catch {
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
function extractRemoteInfo(fsSpec) {
|
|
765
|
+
if (fsSpec == null || isBlank(fsSpec)) return;
|
|
766
|
+
if (isWindows) {
|
|
767
|
+
fsSpec = fsSpec.replace(/\\/g, "/");
|
|
768
|
+
}
|
|
769
|
+
const url = parseURL(fsSpec);
|
|
770
|
+
if (url?.protocol === "file:") {
|
|
771
|
+
return {
|
|
772
|
+
remote: false,
|
|
773
|
+
uri: fsSpec
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
const patterns = [
|
|
777
|
+
// CIFS/SMB pattern: //hostname/share or //user@host/share
|
|
778
|
+
{
|
|
779
|
+
regex: /^\/\/(?:(?<remoteUser>[^/@]+)@)?(?<remoteHost>[^/@]+)\/(?<remoteShare>.+)$/
|
|
780
|
+
},
|
|
781
|
+
// NFS pattern: hostname:/share
|
|
782
|
+
{
|
|
783
|
+
protocol: "nfs",
|
|
784
|
+
regex: /^(?<remoteHost>[^:]+):\/(?!\/)(?<remoteShare>.+)$/
|
|
785
|
+
}
|
|
786
|
+
];
|
|
787
|
+
for (const { protocol, regex } of patterns) {
|
|
788
|
+
const o = compactValues({
|
|
789
|
+
protocol,
|
|
790
|
+
remote: true,
|
|
791
|
+
...fsSpec.match(regex)?.groups ?? {}
|
|
792
|
+
});
|
|
793
|
+
if (isRemoteInfo(o)) {
|
|
794
|
+
debug("[extractRemoteInfo] matched pattern: %o", o);
|
|
795
|
+
return o;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
try {
|
|
799
|
+
const parsed = new URL(fsSpec);
|
|
800
|
+
if (parsed != null) {
|
|
801
|
+
debug("[extractRemoteInfo] parsed URL: %o", parsed);
|
|
802
|
+
const protocol = normalizeProtocol(parsed.protocol);
|
|
803
|
+
if (!isRemoteFsType(protocol)) {
|
|
804
|
+
return {
|
|
805
|
+
uri: fsSpec,
|
|
806
|
+
remote: false
|
|
807
|
+
};
|
|
808
|
+
} else {
|
|
809
|
+
return compactValues({
|
|
810
|
+
uri: fsSpec,
|
|
811
|
+
protocol,
|
|
812
|
+
remote: true,
|
|
813
|
+
remoteUser: parsed.username,
|
|
814
|
+
remoteHost: parsed.hostname,
|
|
815
|
+
// URL pathname includes leading slash:
|
|
816
|
+
remoteShare: parsed.pathname.replace(/^\//, "")
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
} catch {
|
|
821
|
+
}
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// src/linux/mtab.ts
|
|
826
|
+
function mountEntryToMountPoint(entry) {
|
|
827
|
+
const mountPoint = normalizePosixPath(entry.fs_file);
|
|
828
|
+
const fstype = toNotBlank(entry.fs_vfstype) ?? toNotBlank(entry.fs_spec);
|
|
829
|
+
return mountPoint == null || fstype == null ? void 0 : {
|
|
830
|
+
mountPoint,
|
|
831
|
+
fstype
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
function mountEntryToPartialVolumeMetadata(entry, options = {}) {
|
|
835
|
+
return {
|
|
836
|
+
mountPoint: entry.fs_file,
|
|
837
|
+
fstype: entry.fs_vfstype,
|
|
838
|
+
mountFrom: entry.fs_spec,
|
|
839
|
+
isSystemVolume: isSystemVolume(entry.fs_file, entry.fs_vfstype, options),
|
|
840
|
+
remote: false,
|
|
841
|
+
// < default to false
|
|
842
|
+
...extractRemoteInfo(entry.fs_spec)
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
function parseMtab(content) {
|
|
846
|
+
const entries = [];
|
|
847
|
+
const lines = content.split("\n");
|
|
848
|
+
for (const line of lines) {
|
|
849
|
+
if (isBlank(line) || line.trim().startsWith("#")) {
|
|
850
|
+
continue;
|
|
851
|
+
}
|
|
852
|
+
const fields = line.trim().match(/(?:[^\s\\]+|\\.)+/g)?.map(decodeEscapeSequences);
|
|
853
|
+
if (!fields || fields.length < 3) {
|
|
854
|
+
continue;
|
|
855
|
+
}
|
|
856
|
+
const fs_file = normalizePosixPath(fields[1]);
|
|
857
|
+
if (fs_file != null) {
|
|
858
|
+
entries.push({
|
|
859
|
+
fs_spec: fields[0],
|
|
860
|
+
// normalizeLinuxPath DOES NOT resolve()!
|
|
861
|
+
fs_file,
|
|
862
|
+
fs_vfstype: fields[2],
|
|
863
|
+
fs_mntops: fields[3],
|
|
864
|
+
fs_freq: toInt(fields[4]),
|
|
865
|
+
fs_passno: toInt(fields[5])
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
return entries;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// src/linux/mount_points.ts
|
|
873
|
+
async function getLinuxMountPoints(native, opts) {
|
|
874
|
+
const o = optionsWithDefaults(opts);
|
|
875
|
+
const raw = [];
|
|
876
|
+
try {
|
|
877
|
+
const arr = await (await native()).getGioMountPoints?.();
|
|
878
|
+
debug("[getLinuxMountPoints] GIO mount points: %o", arr);
|
|
879
|
+
if (arr != null) raw.push(...arr);
|
|
880
|
+
} catch (error) {
|
|
881
|
+
debug("Failed to get GIO mount points: %s", error);
|
|
882
|
+
}
|
|
883
|
+
let cause;
|
|
884
|
+
for (const input of o.linuxMountTablePaths) {
|
|
885
|
+
try {
|
|
886
|
+
const mtabContent = await (0, import_promises3.readFile)(input, "utf8");
|
|
887
|
+
const arr = parseMtab(mtabContent).map((ea) => mountEntryToMountPoint(ea)).filter((ea) => ea != null);
|
|
888
|
+
debug("[getLinuxMountPoints] %s mount points: %o", input, arr);
|
|
889
|
+
if (arr.length > 0) {
|
|
890
|
+
raw.push(...arr);
|
|
891
|
+
break;
|
|
892
|
+
}
|
|
893
|
+
} catch (error) {
|
|
894
|
+
cause ??= toError(error);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
const byMountPoint = /* @__PURE__ */ new Map();
|
|
898
|
+
for (const ea of raw) {
|
|
899
|
+
const prior = byMountPoint.get(ea.mountPoint);
|
|
900
|
+
const merged = { ...compactValues(prior), ...compactValues(ea) };
|
|
901
|
+
if (isMountPoint(merged)) {
|
|
902
|
+
assignSystemVolume(merged, o);
|
|
903
|
+
byMountPoint.set(merged.mountPoint, merged);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
if (byMountPoint.size === 0) {
|
|
907
|
+
throw new WrappedError(
|
|
908
|
+
`Failed to find any mount points (tried: ${JSON.stringify(o.linuxMountTablePaths)})`,
|
|
909
|
+
{ cause }
|
|
910
|
+
);
|
|
911
|
+
}
|
|
912
|
+
const results = [...byMountPoint.values()];
|
|
913
|
+
debug("[getLinuxMountPoints] found %d mount points", results.length);
|
|
914
|
+
return o.includeSystemVolumes ? results : results.filter((ea) => !ea.isSystemVolume);
|
|
915
|
+
}
|
|
916
|
+
async function getLinuxMtabMetadata(mountPoint, opts) {
|
|
917
|
+
let caughtError;
|
|
918
|
+
const inputs = optionsWithDefaults(opts).linuxMountTablePaths;
|
|
919
|
+
for (const input of inputs) {
|
|
920
|
+
try {
|
|
921
|
+
const mtabContent = await (0, import_promises3.readFile)(input, "utf8");
|
|
922
|
+
for (const ea of parseMtab(mtabContent)) {
|
|
923
|
+
if (ea.fs_file === mountPoint) {
|
|
924
|
+
return ea;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
} catch (error) {
|
|
928
|
+
caughtError ??= toError(error);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
throw new WrappedError(
|
|
932
|
+
`Failed to find mount point ${mountPoint} in an linuxMountTablePaths (tried: ${JSON.stringify(inputs)})`,
|
|
933
|
+
caughtError
|
|
934
|
+
);
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
// src/string_enum.ts
|
|
938
|
+
function stringEnum(...o) {
|
|
939
|
+
const set = new Set(o);
|
|
940
|
+
const dict = {};
|
|
941
|
+
for (const key of o) {
|
|
942
|
+
dict[key] = key;
|
|
943
|
+
}
|
|
944
|
+
return {
|
|
945
|
+
...dict,
|
|
946
|
+
values: Object.freeze([...set]),
|
|
947
|
+
size: set.size,
|
|
948
|
+
get: (s) => s != null && set.has(s) ? s : void 0
|
|
949
|
+
};
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
// src/volume_health_status.ts
|
|
953
|
+
var VolumeHealthStatuses = stringEnum(
|
|
954
|
+
"healthy",
|
|
955
|
+
"timeout",
|
|
956
|
+
"inaccessible",
|
|
957
|
+
"disconnected",
|
|
958
|
+
"unknown"
|
|
959
|
+
);
|
|
960
|
+
async function directoryStatus(dir, timeoutMs, canReaddirImpl = canReaddir) {
|
|
961
|
+
try {
|
|
962
|
+
if (await canReaddirImpl(dir, timeoutMs)) {
|
|
963
|
+
return { status: VolumeHealthStatuses.healthy };
|
|
964
|
+
}
|
|
965
|
+
} catch (error) {
|
|
966
|
+
debug("[directoryStatus] %s: %s", dir, error);
|
|
967
|
+
let status = VolumeHealthStatuses.unknown;
|
|
968
|
+
if (error instanceof TimeoutError) {
|
|
969
|
+
status = VolumeHealthStatuses.timeout;
|
|
970
|
+
} else if (isObject(error) && error instanceof Error && "code" in error) {
|
|
971
|
+
if (error.code === "EPERM" || error.code === "EACCES") {
|
|
972
|
+
status = VolumeHealthStatuses.inaccessible;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
return { status, error: toError(error) };
|
|
976
|
+
}
|
|
977
|
+
return { status: VolumeHealthStatuses.unknown };
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
// src/mount_point.ts
|
|
981
|
+
function isMountPoint(obj) {
|
|
982
|
+
if (!isObject(obj)) return false;
|
|
983
|
+
return "mountPoint" in obj && isNotBlank(obj.mountPoint);
|
|
984
|
+
}
|
|
985
|
+
async function getVolumeMountPoints(opts, nativeFn) {
|
|
986
|
+
const p2 = _getVolumeMountPoints(opts, nativeFn);
|
|
987
|
+
return isWindows ? p2 : withTimeout({ desc: "getVolumeMountPoints", ...opts, promise: p2 });
|
|
988
|
+
}
|
|
989
|
+
async function _getVolumeMountPoints(o, nativeFn) {
|
|
990
|
+
debug("[getVolumeMountPoints] gathering mount points with options: %o", o);
|
|
991
|
+
const result = await (isWindows || isMacOS ? (async () => {
|
|
992
|
+
debug("[getVolumeMountPoints] using native implementation");
|
|
993
|
+
const points = await (await nativeFn()).getVolumeMountPoints(o);
|
|
994
|
+
debug(
|
|
995
|
+
"[getVolumeMountPoints] native returned %d mount points",
|
|
996
|
+
points.length
|
|
997
|
+
);
|
|
998
|
+
return points;
|
|
999
|
+
})() : getLinuxMountPoints(nativeFn, o));
|
|
1000
|
+
debug("[getVolumeMountPoints] raw mount points: %o", result);
|
|
1001
|
+
const compacted = result.map((ea) => compactValues(ea)).filter((ea) => isNotBlank(ea.mountPoint));
|
|
1002
|
+
const filtered = o.includeSystemVolumes ? compacted : compacted.filter((ea) => !ea.isSystemVolume);
|
|
1003
|
+
const uniq = uniqBy(filtered, (ea) => toNotBlank(ea.mountPoint));
|
|
1004
|
+
debug("[getVolumeMountPoints] found %d unique mount points", uniq.length);
|
|
1005
|
+
const results = sortObjectsByLocale(uniq, (ea) => ea.mountPoint);
|
|
1006
|
+
debug(
|
|
1007
|
+
"[getVolumeMountPoints] getting status for %d mount points",
|
|
1008
|
+
results.length
|
|
1009
|
+
);
|
|
1010
|
+
await mapConcurrent({
|
|
1011
|
+
maxConcurrency: o.maxConcurrency,
|
|
1012
|
+
items: results,
|
|
1013
|
+
fn: async (mp) => {
|
|
1014
|
+
assignSystemVolume(mp, o);
|
|
1015
|
+
if ((toNotBlank(mp.status) ?? "healthy") === "healthy") {
|
|
1016
|
+
debug("[getVolumeMountPoints] checking status of %s", mp.mountPoint);
|
|
1017
|
+
mp.status = (await directoryStatus(mp.mountPoint, o.timeoutMs)).status;
|
|
1018
|
+
debug(
|
|
1019
|
+
"[getVolumeMountPoints] status for %s: %s",
|
|
1020
|
+
mp.mountPoint,
|
|
1021
|
+
mp.status
|
|
1022
|
+
);
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
});
|
|
1026
|
+
debug(
|
|
1027
|
+
"[getVolumeMountPoints] completed with %d mount points",
|
|
1028
|
+
results.length
|
|
1029
|
+
);
|
|
1030
|
+
return results;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
// src/linux/dev_disk.ts
|
|
1034
|
+
var import_promises4 = require("fs/promises");
|
|
1035
|
+
var import_node_path4 = require("path");
|
|
1036
|
+
async function getUuidFromDevDisk(devicePath) {
|
|
1037
|
+
try {
|
|
1038
|
+
const result = await getBasenameLinkedTo(
|
|
1039
|
+
"/dev/disk/by-uuid",
|
|
1040
|
+
(0, import_node_path4.resolve)(devicePath)
|
|
1041
|
+
);
|
|
1042
|
+
debug("[getUuidFromDevDisk] result: %o", result);
|
|
1043
|
+
return result;
|
|
1044
|
+
} catch (error) {
|
|
1045
|
+
debug("[getUuidFromDevDisk] failed: " + error);
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
async function getLabelFromDevDisk(devicePath) {
|
|
1050
|
+
try {
|
|
1051
|
+
const result = await getBasenameLinkedTo(
|
|
1052
|
+
"/dev/disk/by-label",
|
|
1053
|
+
(0, import_node_path4.resolve)(devicePath)
|
|
1054
|
+
);
|
|
1055
|
+
debug("[getLabelFromDevDisk] result: %o", result);
|
|
1056
|
+
return result;
|
|
1057
|
+
} catch (error) {
|
|
1058
|
+
debug("[getLabelFromDevDisk] failed: " + error);
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
async function getBasenameLinkedTo(linkDir, linkPath) {
|
|
1063
|
+
for await (const ea of readLinks(linkDir)) {
|
|
1064
|
+
if (ea.linkTarget === linkPath) {
|
|
1065
|
+
return decodeEscapeSequences(ea.dirent.name);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
return;
|
|
1069
|
+
}
|
|
1070
|
+
async function* readLinks(directory) {
|
|
1071
|
+
for (const dirent of await (0, import_promises4.readdir)(directory, { withFileTypes: true })) {
|
|
1072
|
+
if (dirent.isSymbolicLink()) {
|
|
1073
|
+
try {
|
|
1074
|
+
const linkTarget = (0, import_node_path4.resolve)(
|
|
1075
|
+
directory,
|
|
1076
|
+
await (0, import_promises4.readlink)((0, import_node_path4.join)(directory, dirent.name))
|
|
1077
|
+
);
|
|
1078
|
+
yield { dirent, linkTarget };
|
|
1079
|
+
} catch {
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
// src/unc.ts
|
|
1086
|
+
function parseUNCPath(path) {
|
|
1087
|
+
if (path == null || isBlank(path) || !isString(path)) {
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
if (!path.startsWith("\\\\") && !path.startsWith("//")) {
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
1093
|
+
const isForwardSlash = path.startsWith("//");
|
|
1094
|
+
const slashChar = isForwardSlash ? "/" : "\\";
|
|
1095
|
+
const parts = path.slice(2).split(slashChar);
|
|
1096
|
+
if (parts.length < 2) {
|
|
1097
|
+
return;
|
|
1098
|
+
}
|
|
1099
|
+
const [remoteHost, remoteShare] = parts;
|
|
1100
|
+
if (remoteHost == null || isBlank(remoteHost) || remoteShare == null || isBlank(remoteShare)) {
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
const invalidChars = /[<>:"|?*]/;
|
|
1104
|
+
if (invalidChars.test(remoteHost) || invalidChars.test(remoteShare)) {
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
const wrongSlash = isForwardSlash ? "\\" : "/";
|
|
1108
|
+
if (path.includes(wrongSlash)) {
|
|
1109
|
+
return;
|
|
1110
|
+
}
|
|
1111
|
+
return { remoteHost, remoteShare, remote: true };
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
// src/uuid.ts
|
|
1115
|
+
var uuidRegex = /[a-z0-9][a-z0-9-]{7,}/i;
|
|
1116
|
+
function extractUUID(uuid) {
|
|
1117
|
+
return toS(uuid).match(uuidRegex)?.[0];
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
// src/volume_metadata.ts
|
|
1121
|
+
async function getVolumeMetadata(o, nativeFn) {
|
|
1122
|
+
if (isBlank(o.mountPoint)) {
|
|
1123
|
+
throw new TypeError(
|
|
1124
|
+
"Invalid mountPoint: got " + JSON.stringify(o.mountPoint)
|
|
1125
|
+
);
|
|
1126
|
+
}
|
|
1127
|
+
const p2 = _getVolumeMetadata(o, nativeFn);
|
|
1128
|
+
return isWindows ? p2 : withTimeout({
|
|
1129
|
+
desc: "getVolumeMetadata()",
|
|
1130
|
+
timeoutMs: o.timeoutMs,
|
|
1131
|
+
promise: p2
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
async function _getVolumeMetadata(o, nativeFn) {
|
|
1135
|
+
o = optionsWithDefaults(o);
|
|
1136
|
+
const norm = normalizePath(o.mountPoint);
|
|
1137
|
+
if (norm == null) {
|
|
1138
|
+
throw new Error("Invalid mountPoint: " + JSON.stringify(o.mountPoint));
|
|
1139
|
+
}
|
|
1140
|
+
o.mountPoint = norm;
|
|
1141
|
+
debug(
|
|
1142
|
+
"[getVolumeMetadata] starting metadata collection for %s",
|
|
1143
|
+
o.mountPoint
|
|
1144
|
+
);
|
|
1145
|
+
debug("[getVolumeMetadata] options: %o", o);
|
|
1146
|
+
const { status, error } = await directoryStatus(o.mountPoint, o.timeoutMs);
|
|
1147
|
+
if (status !== VolumeHealthStatuses.healthy) {
|
|
1148
|
+
debug("[getVolumeMetadata] directoryStatus error: %s", error);
|
|
1149
|
+
throw error ?? new Error("Volume not healthy: " + status);
|
|
1150
|
+
}
|
|
1151
|
+
debug("[getVolumeMetadata] readdir status: %s", status);
|
|
1152
|
+
let remote = false;
|
|
1153
|
+
let mtabInfo;
|
|
1154
|
+
let device;
|
|
1155
|
+
if (isLinux) {
|
|
1156
|
+
debug("[getVolumeMetadata] collecting Linux mtab info");
|
|
1157
|
+
try {
|
|
1158
|
+
const m = await getLinuxMtabMetadata(o.mountPoint, o);
|
|
1159
|
+
mtabInfo = mountEntryToPartialVolumeMetadata(m, o);
|
|
1160
|
+
debug("[getVolumeMetadata] mtab info: %o", mtabInfo);
|
|
1161
|
+
if (mtabInfo.remote) {
|
|
1162
|
+
remote = true;
|
|
1163
|
+
}
|
|
1164
|
+
if (isNotBlank(m.fs_spec)) {
|
|
1165
|
+
device = m.fs_spec;
|
|
1166
|
+
}
|
|
1167
|
+
} catch (err) {
|
|
1168
|
+
debug("[getVolumeMetadata] failed to get mtab info: " + err);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
if (isNotBlank(device)) {
|
|
1172
|
+
o.device = device;
|
|
1173
|
+
debug("[getVolumeMetadata] using device: %s", device);
|
|
1174
|
+
}
|
|
1175
|
+
debug("[getVolumeMetadata] requesting native metadata");
|
|
1176
|
+
const metadata = await (await nativeFn()).getVolumeMetadata(o);
|
|
1177
|
+
debug("[getVolumeMetadata] native metadata: %o", metadata);
|
|
1178
|
+
const remoteInfo = mtabInfo ?? extractRemoteInfo(metadata.uri) ?? extractRemoteInfo(metadata.mountFrom) ?? (isWindows ? parseUNCPath(o.mountPoint) : void 0);
|
|
1179
|
+
debug("[getVolumeMetadata] extracted remote info: %o", remoteInfo);
|
|
1180
|
+
remote ||= isRemoteFsType(metadata.fstype) || (remoteInfo?.remote ?? metadata.remote ?? false);
|
|
1181
|
+
debug("[getVolumeMetadata] assembling: %o", {
|
|
1182
|
+
status,
|
|
1183
|
+
mtabInfo,
|
|
1184
|
+
remoteInfo,
|
|
1185
|
+
metadata,
|
|
1186
|
+
mountPoint: o.mountPoint,
|
|
1187
|
+
remote
|
|
1188
|
+
});
|
|
1189
|
+
const result = compactValues({
|
|
1190
|
+
status,
|
|
1191
|
+
// < let the implementation's status win by having this first
|
|
1192
|
+
...compactValues(remoteInfo),
|
|
1193
|
+
...compactValues(metadata),
|
|
1194
|
+
...compactValues(mtabInfo),
|
|
1195
|
+
mountPoint: o.mountPoint,
|
|
1196
|
+
remote
|
|
1197
|
+
});
|
|
1198
|
+
if (isLinux && isNotBlank(device)) {
|
|
1199
|
+
result.uuid ??= await getUuidFromDevDisk(device) ?? "";
|
|
1200
|
+
result.label ??= await getLabelFromDevDisk(device) ?? "";
|
|
1201
|
+
}
|
|
1202
|
+
assignSystemVolume(result, o);
|
|
1203
|
+
result.uuid = extractUUID(result.uuid) ?? result.uuid ?? "";
|
|
1204
|
+
debug("[getVolumeMetadata] final result for %s: %o", o.mountPoint, result);
|
|
1205
|
+
return compactValues(result);
|
|
1206
|
+
}
|
|
1207
|
+
async function getAllVolumeMetadata(opts, nativeFn) {
|
|
1208
|
+
const o = optionsWithDefaults(opts);
|
|
1209
|
+
debug("[getAllVolumeMetadata] starting with options: %o", o);
|
|
1210
|
+
const arr = await getVolumeMountPoints(o, nativeFn);
|
|
1211
|
+
debug("[getAllVolumeMetadata] found %d mount points", arr.length);
|
|
1212
|
+
const unhealthyMountPoints = arr.filter(
|
|
1213
|
+
(ea) => ea.status != null && ea.status !== VolumeHealthStatuses.healthy
|
|
1214
|
+
).map((ea) => ({
|
|
1215
|
+
mountPoint: ea.mountPoint,
|
|
1216
|
+
error: new WrappedError("volume not healthy: " + ea.status, {
|
|
1217
|
+
name: "Skipped"
|
|
1218
|
+
})
|
|
1219
|
+
}));
|
|
1220
|
+
const includeSystemVolumes = opts?.includeSystemVolumes ?? IncludeSystemVolumesDefault;
|
|
1221
|
+
const systemMountPoints = includeSystemVolumes ? [] : arr.filter((ea) => ea.isSystemVolume).map((ea) => ({
|
|
1222
|
+
mountPoint: ea.mountPoint,
|
|
1223
|
+
error: new WrappedError("system volume", { name: "Skipped" })
|
|
1224
|
+
}));
|
|
1225
|
+
const healthy = arr.filter(
|
|
1226
|
+
(ea) => ea.status == null || ea.status === VolumeHealthStatuses.healthy
|
|
1227
|
+
);
|
|
1228
|
+
debug("[getAllVolumeMetadata] ", {
|
|
1229
|
+
allMountPoints: arr.map((ea) => ea.mountPoint),
|
|
1230
|
+
healthyMountPoints: healthy.map((ea) => ea.mountPoint)
|
|
1231
|
+
});
|
|
1232
|
+
debug(
|
|
1233
|
+
"[getAllVolumeMetadata] processing %d healthy volumes with max concurrency %d",
|
|
1234
|
+
healthy.length,
|
|
1235
|
+
o.maxConcurrency
|
|
1236
|
+
);
|
|
1237
|
+
const results = await mapConcurrent({
|
|
1238
|
+
maxConcurrency: o.maxConcurrency,
|
|
1239
|
+
items: opts?.includeSystemVolumes ?? IncludeSystemVolumesDefault ? healthy : healthy.filter((ea) => !ea.isSystemVolume),
|
|
1240
|
+
fn: async (mp) => getVolumeMetadata({ ...mp, ...o }, nativeFn).catch((error) => ({
|
|
1241
|
+
mountPoint: mp.mountPoint,
|
|
1242
|
+
error
|
|
1243
|
+
}))
|
|
1244
|
+
});
|
|
1245
|
+
debug("[getAllVolumeMetadata] completed processing all volumes");
|
|
1246
|
+
return arr.map(
|
|
1247
|
+
(result) => results.find((ea) => ea.mountPoint === result.mountPoint) ?? unhealthyMountPoints.find(
|
|
1248
|
+
(ea) => ea.mountPoint === result.mountPoint
|
|
1249
|
+
) ?? systemMountPoints.find((ea) => ea.mountPoint === result.mountPoint) ?? {
|
|
1250
|
+
...result,
|
|
1251
|
+
error: new WrappedError("Mount point metadata not retrieved", {
|
|
1252
|
+
name: "NotApplicableError"
|
|
1253
|
+
})
|
|
1254
|
+
}
|
|
1255
|
+
);
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
// src/setup.ts
|
|
1259
|
+
function setup(dirname3) {
|
|
1260
|
+
const nativeFn = defer(async () => {
|
|
1261
|
+
const start = Date.now();
|
|
1262
|
+
try {
|
|
1263
|
+
const dir = await findAncestorDir(dirname3, "binding.gyp");
|
|
1264
|
+
if (dir == null) {
|
|
1265
|
+
throw new Error(
|
|
1266
|
+
"Could not find bindings.gyp in any ancestor directory of " + dirname3
|
|
1267
|
+
);
|
|
1268
|
+
}
|
|
1269
|
+
const bindings = (0, import_node_gyp_build.default)(dir);
|
|
1270
|
+
bindings.setDebugLogging(isDebugEnabled());
|
|
1271
|
+
bindings.setDebugPrefix(debugLogContext() + ":native");
|
|
1272
|
+
return bindings;
|
|
1273
|
+
} catch (error) {
|
|
1274
|
+
debug("Loading native bindings failed: %s", error);
|
|
1275
|
+
throw error;
|
|
1276
|
+
} finally {
|
|
1277
|
+
debug(`Native bindings took %d ms to load`, Date.now() - start);
|
|
1278
|
+
}
|
|
1279
|
+
});
|
|
1280
|
+
return {
|
|
1281
|
+
getVolumeMountPoints: (opts = {}) => getVolumeMountPoints(optionsWithDefaults(opts), nativeFn),
|
|
1282
|
+
getVolumeMetadata: (mountPoint, opts = {}) => getVolumeMetadata({ ...optionsWithDefaults(opts), mountPoint }, nativeFn),
|
|
1283
|
+
getAllVolumeMetadata: (opts = {}) => getAllVolumeMetadata(optionsWithDefaults(opts), nativeFn),
|
|
1284
|
+
isHidden: (pathname) => isHidden(pathname, nativeFn),
|
|
1285
|
+
isHiddenRecursive: (pathname) => isHiddenRecursive(pathname, nativeFn),
|
|
1286
|
+
getHiddenMetadata: (pathname) => getHiddenMetadata(pathname, nativeFn),
|
|
1287
|
+
setHidden: (pathname, hidden, method = "auto") => setHidden(pathname, hidden, method, nativeFn)
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
// src/index.cts
|
|
1292
|
+
var {
|
|
1293
|
+
getVolumeMountPoints: getVolumeMountPoints2,
|
|
1294
|
+
getVolumeMetadata: getVolumeMetadata2,
|
|
1295
|
+
getAllVolumeMetadata: getAllVolumeMetadata2,
|
|
1296
|
+
isHidden: isHidden2,
|
|
1297
|
+
isHiddenRecursive: isHiddenRecursive2,
|
|
1298
|
+
getHiddenMetadata: getHiddenMetadata2,
|
|
1299
|
+
setHidden: setHidden2
|
|
1300
|
+
} = setup(__dirname);
|
|
1301
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1302
|
+
0 && (module.exports = {
|
|
1303
|
+
IncludeSystemVolumesDefault,
|
|
1304
|
+
LinuxMountTablePathsDefault,
|
|
1305
|
+
OptionsDefault,
|
|
1306
|
+
SystemFsTypesDefault,
|
|
1307
|
+
SystemPathPatternsDefault,
|
|
1308
|
+
TimeoutMsDefault,
|
|
1309
|
+
VolumeHealthStatuses,
|
|
1310
|
+
getAllVolumeMetadata,
|
|
1311
|
+
getHiddenMetadata,
|
|
1312
|
+
getVolumeMetadata,
|
|
1313
|
+
getVolumeMountPoints,
|
|
1314
|
+
isHidden,
|
|
1315
|
+
isHiddenRecursive,
|
|
1316
|
+
optionsWithDefaults,
|
|
1317
|
+
setHidden
|
|
1318
|
+
});
|