@photostructure/fs-metadata 0.6.0 → 0.7.0
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/CHANGELOG.md +11 -6
- package/CLAUDE.md +160 -136
- package/CODE_OF_CONDUCT.md +11 -11
- package/CONTRIBUTING.md +2 -2
- package/README.md +34 -84
- package/binding.gyp +98 -23
- package/claude.sh +23 -0
- package/dist/index.cjs +53 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.mjs +52 -21
- package/dist/index.mjs.map +1 -1
- package/{C++_REVIEW_TODO.md → doc/C++_REVIEW_TODO.md} +97 -25
- package/doc/GPG_RELEASE_HOWTO.md +505 -0
- package/doc/MACOS_API_REFERENCE.md +469 -0
- package/doc/SECURITY_AUDIT_2025.md +809 -0
- package/doc/SSH_RELEASE_HOWTO.md +207 -0
- package/doc/WINDOWS_API_REFERENCE.md +422 -0
- package/doc/WINDOWS_ARM64_SECURITY.md +161 -0
- package/doc/WINDOWS_DEBUG_GUIDE.md +96 -0
- package/doc/examples.md +267 -0
- package/doc/gotchas.md +297 -0
- package/doc/logo.png +0 -0
- package/doc/logo.svg +85 -0
- package/doc/macos-asan-sip-issue.md +71 -0
- package/doc/social.png +0 -0
- package/doc/social.svg +125 -0
- package/doc/windows-build.md +226 -0
- package/doc/windows-clang-tidy.md +72 -0
- package/doc/windows-memory-testing.md +108 -0
- package/doc/windows-prebuildify-arm64.md +232 -0
- package/jest.config.cjs +24 -0
- package/package.json +68 -44
- package/prebuilds/darwin-arm64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/darwin-x64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/linux-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-arm64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/win32-x64/@photostructure+fs-metadata.glibc.node +0 -0
- package/scripts/check-memory.ts +186 -0
- package/scripts/clang-tidy.ts +832 -0
- package/scripts/install.cjs +42 -0
- package/scripts/is-platform.mjs +1 -1
- package/scripts/macos-asan.sh +155 -0
- package/scripts/post-build.mjs +3 -3
- package/scripts/prebuild-linux-glibc.sh +119 -0
- package/scripts/prebuildify-wrapper.ts +77 -0
- package/scripts/precommit.ts +70 -0
- package/scripts/sanitizers-test.sh +7 -1
- package/scripts/{configure.mjs → setup-native.mjs} +4 -1
- package/src/binding.cpp +1 -1
- package/src/common/error_utils.h +0 -6
- package/src/common/volume_metadata.h +6 -0
- package/src/darwin/hidden.cpp +73 -25
- package/src/darwin/path_security.h +149 -0
- package/src/darwin/raii_utils.h +104 -4
- package/src/darwin/volume_metadata.cpp +132 -58
- package/src/darwin/volume_mount_points.cpp +80 -47
- package/src/hidden.ts +36 -13
- package/src/linux/gio_mount_points.cpp +17 -18
- package/src/linux/gio_utils.cpp +92 -37
- package/src/linux/gio_utils.h +11 -5
- package/src/linux/gio_volume_metadata.cpp +111 -48
- package/src/linux/volume_metadata.cpp +67 -4
- package/src/object.ts +1 -0
- package/src/options.ts +6 -0
- package/src/path.ts +11 -0
- package/src/platform.ts +25 -0
- package/src/remote_info.ts +5 -3
- package/src/stack_path.ts +8 -6
- package/src/string_enum.ts +1 -0
- package/src/test-utils/benchmark-harness.ts +192 -0
- package/src/test-utils/debuglog-child.ts +30 -2
- package/src/test-utils/debuglog-enabled-child.ts +38 -8
- package/src/test-utils/jest-setup.ts +14 -0
- package/src/test-utils/memory-test-core.ts +336 -0
- package/src/test-utils/memory-test-runner.ts +108 -0
- package/src/test-utils/platform.ts +46 -1
- package/src/test-utils/worker-thread-helper.cjs +157 -26
- package/src/types/native_bindings.ts +1 -1
- package/src/types/options.ts +6 -0
- package/src/windows/drive_status.h +133 -163
- package/src/windows/error_utils.h +54 -3
- package/src/windows/fs_meta.h +1 -1
- package/src/windows/hidden.cpp +60 -43
- package/src/windows/security_utils.h +250 -0
- package/src/windows/string.h +68 -11
- package/src/windows/system_volume.h +1 -1
- package/src/windows/thread_pool.h +206 -0
- package/src/windows/volume_metadata.cpp +11 -6
- package/src/windows/volume_mount_points.cpp +8 -7
- package/src/windows/windows_arch.h +39 -0
- package/scripts/check-memory.mjs +0 -123
- package/scripts/clang-tidy.mjs +0 -73
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Standalone memory test runner for use in CI environments
|
|
5
|
+
*
|
|
6
|
+
* This script runs memory tests without Jest to avoid worker process issues
|
|
7
|
+
* particularly on Windows CI. It uses the same test logic as the Jest tests
|
|
8
|
+
* but with a simpler execution model.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { MemoryTestResult, runAllMemoryTests } from "./memory-test-core";
|
|
12
|
+
|
|
13
|
+
// ANSI color codes for output (disable on Windows for better compatibility)
|
|
14
|
+
const isWindows = process.platform === "win32";
|
|
15
|
+
const colors = {
|
|
16
|
+
RED: isWindows ? "" : "\x1b[31m",
|
|
17
|
+
GREEN: isWindows ? "" : "\x1b[32m",
|
|
18
|
+
YELLOW: isWindows ? "" : "\x1b[33m",
|
|
19
|
+
BLUE: isWindows ? "" : "\x1b[34m",
|
|
20
|
+
RESET: isWindows ? "" : "\x1b[0m",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function formatMemory(bytes: number): string {
|
|
24
|
+
return `${(bytes / 1024 / 1024).toFixed(2)} MB`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function printResult(result: MemoryTestResult): void {
|
|
28
|
+
const statusSymbol = result.passed ? "✓" : "✗";
|
|
29
|
+
const statusColor = result.passed ? colors.GREEN : colors.RED;
|
|
30
|
+
|
|
31
|
+
console.log(
|
|
32
|
+
`\n${statusColor}${statusSymbol} ${result.testName}${colors.RESET}`,
|
|
33
|
+
);
|
|
34
|
+
console.log(` Initial memory: ${formatMemory(result.initialMemory)}`);
|
|
35
|
+
console.log(` Final memory: ${formatMemory(result.finalMemory)}`);
|
|
36
|
+
console.log(` Memory increase: ${formatMemory(result.memoryIncrease)}`);
|
|
37
|
+
console.log(` Memory slope: ${result.slope.toFixed(6)}`);
|
|
38
|
+
|
|
39
|
+
if (result.errorMessage) {
|
|
40
|
+
console.log(` ${colors.RED}Error: ${result.errorMessage}${colors.RESET}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function main(): Promise<void> {
|
|
45
|
+
console.log(
|
|
46
|
+
`${colors.BLUE}=== Standalone Memory Test Runner ===${colors.RESET}`,
|
|
47
|
+
);
|
|
48
|
+
console.log(`Platform: ${process.platform}`);
|
|
49
|
+
console.log(`Node version: ${process.version}`);
|
|
50
|
+
console.log(`Process architecture: ${process.arch}`);
|
|
51
|
+
|
|
52
|
+
// Check if garbage collection is exposed
|
|
53
|
+
if (!global.gc) {
|
|
54
|
+
console.error(
|
|
55
|
+
`${colors.RED}Error: Garbage collection is not exposed.${colors.RESET}`,
|
|
56
|
+
);
|
|
57
|
+
console.error(
|
|
58
|
+
"Please run with: NODE_OPTIONS='--expose-gc' tsx scripts/memory-test-runner.ts",
|
|
59
|
+
);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.log("\nRunning memory tests...");
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const startTime = Date.now();
|
|
67
|
+
const results = await runAllMemoryTests();
|
|
68
|
+
const duration = Date.now() - startTime;
|
|
69
|
+
|
|
70
|
+
// Print individual results
|
|
71
|
+
for (const result of results) {
|
|
72
|
+
printResult(result);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Summary
|
|
76
|
+
const passed = results.filter((r) => r.passed).length;
|
|
77
|
+
const failed = results.filter((r) => !r.passed).length;
|
|
78
|
+
const total = results.length;
|
|
79
|
+
|
|
80
|
+
console.log(`\n${colors.BLUE}=== Test Summary ===${colors.RESET}`);
|
|
81
|
+
console.log(`Total tests: ${total}`);
|
|
82
|
+
console.log(`${colors.GREEN}Passed: ${passed}${colors.RESET}`);
|
|
83
|
+
if (failed > 0) {
|
|
84
|
+
console.log(`${colors.RED}Failed: ${failed}${colors.RESET}`);
|
|
85
|
+
}
|
|
86
|
+
console.log(`Duration: ${(duration / 1000).toFixed(2)}s`);
|
|
87
|
+
|
|
88
|
+
if (failed > 0) {
|
|
89
|
+
console.log(`\n${colors.RED}Memory tests failed!${colors.RESET}`);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
} else {
|
|
92
|
+
console.log(`\n${colors.GREEN}All memory tests passed!${colors.RESET}`);
|
|
93
|
+
process.exit(0);
|
|
94
|
+
}
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error(
|
|
97
|
+
`\n${colors.RED}Fatal error running memory tests:${colors.RESET}`,
|
|
98
|
+
);
|
|
99
|
+
console.error(error);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Run the tests
|
|
105
|
+
main().catch((error) => {
|
|
106
|
+
console.error(`${colors.RED}Unhandled error:${colors.RESET}`, error);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
});
|
|
@@ -5,7 +5,7 @@ import { homedir } from "node:os";
|
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { env, platform } from "node:process";
|
|
7
7
|
import { normalizePath } from "../path";
|
|
8
|
-
import { isMacOS, isWindows } from "../platform";
|
|
8
|
+
import { isAlpine, isARM64, isMacOS, isWindows } from "../platform";
|
|
9
9
|
import { toNotBlank } from "../string";
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -45,3 +45,48 @@ export function tmpDirNotHidden() {
|
|
|
45
45
|
mkdirSync(dir, { recursive: true });
|
|
46
46
|
return dir;
|
|
47
47
|
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Skip timing-sensitive tests on Alpine ARM64 due to emulation timing issues
|
|
51
|
+
*/
|
|
52
|
+
export const itSkipAlpineARM64 = isAlpine() && isARM64 ? it.skip : it;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Skip timing-sensitive describe blocks on Alpine ARM64 due to emulation timing issues
|
|
56
|
+
*/
|
|
57
|
+
export const describeSkipAlpineARM64 =
|
|
58
|
+
isAlpine() && isARM64 ? describe.skip : describe;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Skip tests on ARM64 CI environments due to various issues:
|
|
62
|
+
* - Alpine ARM64: emulation timing issues
|
|
63
|
+
* - Windows ARM64: Jest worker process failures
|
|
64
|
+
*/
|
|
65
|
+
export const describeSkipARM64CI =
|
|
66
|
+
isARM64 && env["CI"] ? describe.skip : describe;
|
|
67
|
+
|
|
68
|
+
export const itSkipARM64CI = isARM64 && env["CI"] ? it.skip : it;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Skip tests on Windows CI environments due to Jest worker process failures
|
|
72
|
+
* These tests pass locally but fail in GitHub Actions with:
|
|
73
|
+
* "Jest worker encountered 4 child process exceptions, exceeding retry limit"
|
|
74
|
+
*/
|
|
75
|
+
export const describeSkipWindowsCI =
|
|
76
|
+
isWindows && env["CI"] ? describe.skip : describe;
|
|
77
|
+
|
|
78
|
+
export const itSkipWindowsCI = isWindows && env["CI"] ? it.skip : it;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Platform-specific tests that are stable in CI environments
|
|
82
|
+
* (skips on Windows CI due to Jest worker process issues)
|
|
83
|
+
* @param supported The platforms to run tests on
|
|
84
|
+
* @returns jest.Describe function that runs on specified platforms but skips on Windows CI
|
|
85
|
+
*/
|
|
86
|
+
export function describePlatformStable(...supported: NodeJS.Platform[]) {
|
|
87
|
+
// Skip on Windows CI due to Jest worker process failures
|
|
88
|
+
if (isWindows && env["CI"]) {
|
|
89
|
+
return describe.skip;
|
|
90
|
+
}
|
|
91
|
+
return describePlatform(...supported);
|
|
92
|
+
}
|
|
@@ -3,18 +3,101 @@
|
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
4
4
|
/* eslint-disable no-undef */
|
|
5
5
|
|
|
6
|
-
const { parentPort, workerData } = require(
|
|
7
|
-
const path = require(
|
|
6
|
+
const { parentPort, workerData } = require("node:worker_threads");
|
|
7
|
+
const path = require("node:path");
|
|
8
|
+
|
|
9
|
+
// Windows ARM64 Jest worker workaround
|
|
10
|
+
if (
|
|
11
|
+
process.platform === "win32" &&
|
|
12
|
+
process.arch === "arm64" &&
|
|
13
|
+
process.env.CI
|
|
14
|
+
) {
|
|
15
|
+
console.error("[Worker] Windows ARM64 detected in CI, applying workarounds");
|
|
16
|
+
// Ensure we're using the correct module paths
|
|
17
|
+
if (!global.__dirname && typeof __dirname === "undefined") {
|
|
18
|
+
console.error("[Worker] __dirname is undefined, using workaround");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
8
21
|
|
|
9
22
|
// Use eval with the worker data to create the module functions
|
|
10
23
|
const createModule = () => {
|
|
11
|
-
const nodeGypBuild = require(
|
|
12
|
-
|
|
13
|
-
|
|
24
|
+
const nodeGypBuild = require("node-gyp-build");
|
|
25
|
+
|
|
26
|
+
// Debug logging for CI
|
|
27
|
+
if (process.env.CI || process.env.DEBUG_WORKER) {
|
|
28
|
+
console.error("[Worker] Environment:");
|
|
29
|
+
console.error(" - Platform:", process.platform);
|
|
30
|
+
console.error(" - Architecture:", process.arch);
|
|
31
|
+
console.error(" - Node version:", process.version);
|
|
32
|
+
console.error(" - Current directory:", process.cwd());
|
|
33
|
+
console.error(" - __dirname:", __dirname);
|
|
34
|
+
console.error(" - Worker ID:", require("node:worker_threads").threadId);
|
|
35
|
+
console.error(
|
|
36
|
+
" - Is main thread:",
|
|
37
|
+
require("node:worker_threads").isMainThread,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Try multiple paths to find the native module
|
|
42
|
+
let binding;
|
|
43
|
+
const possiblePaths = [
|
|
44
|
+
path.join(__dirname, "../.."), // Original path
|
|
45
|
+
process.cwd(), // Current working directory
|
|
46
|
+
path.resolve(__dirname, "../.."), // Absolute resolved path
|
|
47
|
+
path.join(process.cwd(), "prebuilds"), // Direct prebuilds path
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
// Add Windows-specific paths if on Windows
|
|
51
|
+
if (process.platform === "win32") {
|
|
52
|
+
// Try normalized Windows paths
|
|
53
|
+
possiblePaths.push(
|
|
54
|
+
path.win32.resolve(__dirname, "../.."),
|
|
55
|
+
path.win32.join(process.cwd()),
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let lastError;
|
|
60
|
+
for (const tryPath of possiblePaths) {
|
|
61
|
+
try {
|
|
62
|
+
if (process.env.CI || process.env.DEBUG_WORKER) {
|
|
63
|
+
console.error("[Worker] Trying path:", tryPath);
|
|
64
|
+
// Also check if prebuilds directory exists
|
|
65
|
+
const fs = require("fs");
|
|
66
|
+
const prebuildsPath = path.join(tryPath, "prebuilds");
|
|
67
|
+
if (fs.existsSync(prebuildsPath)) {
|
|
68
|
+
console.error("[Worker] Prebuilds found at:", prebuildsPath);
|
|
69
|
+
const files = fs.readdirSync(prebuildsPath);
|
|
70
|
+
console.error("[Worker] Prebuild directories:", files);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
binding = nodeGypBuild(tryPath);
|
|
74
|
+
if (process.env.CI || process.env.DEBUG_WORKER) {
|
|
75
|
+
console.error("[Worker] Success! Loaded from:", tryPath);
|
|
76
|
+
console.error("[Worker] Binding functions:", Object.keys(binding));
|
|
77
|
+
}
|
|
78
|
+
break;
|
|
79
|
+
} catch (err) {
|
|
80
|
+
lastError = err;
|
|
81
|
+
if (process.env.CI || process.env.DEBUG_WORKER) {
|
|
82
|
+
console.error("[Worker] Failed to load from", tryPath);
|
|
83
|
+
console.error("[Worker] Error:", err.message);
|
|
84
|
+
if (err.stack && process.env.DEBUG_WORKER) {
|
|
85
|
+
console.error("[Worker] Stack:", err.stack);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!binding) {
|
|
92
|
+
const errorMsg = `Failed to load native module from any path. Tried: ${possiblePaths.join(", ")}. Last error: ${lastError?.message || "unknown"}`;
|
|
93
|
+
console.error("[Worker] FATAL:", errorMsg);
|
|
94
|
+
throw new Error(errorMsg);
|
|
95
|
+
}
|
|
96
|
+
|
|
14
97
|
// Platform detection
|
|
15
98
|
const platform = process.platform;
|
|
16
|
-
const isLinux = platform ===
|
|
17
|
-
|
|
99
|
+
const isLinux = platform === "linux";
|
|
100
|
+
|
|
18
101
|
// For Linux, we need a simplified implementation since the main one is complex
|
|
19
102
|
if (isLinux) {
|
|
20
103
|
return {
|
|
@@ -22,10 +105,10 @@ const createModule = () => {
|
|
|
22
105
|
// Return the same mount points as the main thread would
|
|
23
106
|
// This is a simplified version for testing
|
|
24
107
|
return [
|
|
25
|
-
{ mountPoint:
|
|
26
|
-
{ mountPoint:
|
|
27
|
-
{ mountPoint:
|
|
28
|
-
{ mountPoint:
|
|
108
|
+
{ mountPoint: "/", fstype: "ext4", isSystemVolume: true },
|
|
109
|
+
{ mountPoint: "/boot", fstype: "ext4", isSystemVolume: true },
|
|
110
|
+
{ mountPoint: "/boot/efi", fstype: "vfat", isSystemVolume: true },
|
|
111
|
+
{ mountPoint: "/home", fstype: "ext4", isSystemVolume: false },
|
|
29
112
|
];
|
|
30
113
|
},
|
|
31
114
|
getVolumeMetadata: async (mountPoint, options) => {
|
|
@@ -33,15 +116,15 @@ const createModule = () => {
|
|
|
33
116
|
},
|
|
34
117
|
isHidden: async (filePath) => {
|
|
35
118
|
const basename = path.basename(filePath);
|
|
36
|
-
return basename.startsWith(
|
|
119
|
+
return basename.startsWith(".");
|
|
37
120
|
},
|
|
38
121
|
setHidden: async (/* filePath, hidden */) => {
|
|
39
122
|
// Linux doesn't support hidden attribute
|
|
40
123
|
return;
|
|
41
|
-
}
|
|
124
|
+
},
|
|
42
125
|
};
|
|
43
126
|
}
|
|
44
|
-
|
|
127
|
+
|
|
45
128
|
// For Windows and macOS, use the native binding directly
|
|
46
129
|
return {
|
|
47
130
|
getVolumeMountPoints: async () => {
|
|
@@ -51,38 +134,86 @@ const createModule = () => {
|
|
|
51
134
|
return binding.getVolumeMetadata({ mountPoint, ...options });
|
|
52
135
|
},
|
|
53
136
|
isHidden: binding.isHidden,
|
|
54
|
-
setHidden: binding.setHidden
|
|
137
|
+
setHidden: binding.setHidden,
|
|
55
138
|
};
|
|
56
139
|
};
|
|
57
140
|
|
|
58
|
-
|
|
141
|
+
let fsMetadata;
|
|
142
|
+
try {
|
|
143
|
+
fsMetadata = createModule();
|
|
144
|
+
} catch (error) {
|
|
145
|
+
console.error("[Worker] Failed to create module:", error.message);
|
|
146
|
+
console.error("[Worker] Stack:", error.stack);
|
|
147
|
+
// Send error back to parent
|
|
148
|
+
parentPort.postMessage({
|
|
149
|
+
success: false,
|
|
150
|
+
error: `Module initialization failed: ${error.message}`,
|
|
151
|
+
stack: error.stack,
|
|
152
|
+
platform: process.platform,
|
|
153
|
+
arch: process.arch,
|
|
154
|
+
task: "module_init",
|
|
155
|
+
});
|
|
156
|
+
parentPort.close();
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
59
159
|
|
|
60
160
|
async function runWorkerTask() {
|
|
61
161
|
try {
|
|
62
162
|
const { task, ...params } = workerData;
|
|
163
|
+
|
|
164
|
+
if (process.env.CI || process.env.DEBUG_WORKER) {
|
|
165
|
+
console.error("[Worker] Running task:", task, "with params:", params);
|
|
166
|
+
}
|
|
167
|
+
|
|
63
168
|
let result;
|
|
64
|
-
|
|
169
|
+
|
|
65
170
|
switch (task) {
|
|
66
|
-
case
|
|
171
|
+
case "getVolumeMountPoints":
|
|
67
172
|
result = await fsMetadata.getVolumeMountPoints();
|
|
68
173
|
break;
|
|
69
|
-
case
|
|
70
|
-
result = await fsMetadata.getVolumeMetadata(
|
|
174
|
+
case "getVolumeMetadata":
|
|
175
|
+
result = await fsMetadata.getVolumeMetadata(
|
|
176
|
+
params.mountPoint,
|
|
177
|
+
params.options,
|
|
178
|
+
);
|
|
71
179
|
break;
|
|
72
|
-
case
|
|
180
|
+
case "isHidden":
|
|
73
181
|
result = await fsMetadata.isHidden(params.path);
|
|
74
182
|
break;
|
|
75
|
-
case
|
|
183
|
+
case "setHidden":
|
|
76
184
|
result = await fsMetadata.setHidden(params.path, params.hidden);
|
|
77
185
|
break;
|
|
78
186
|
default:
|
|
79
|
-
throw new Error(
|
|
187
|
+
throw new Error("Unknown task: " + task);
|
|
80
188
|
}
|
|
81
|
-
|
|
189
|
+
|
|
190
|
+
if (process.env.CI || process.env.DEBUG_WORKER) {
|
|
191
|
+
console.error("[Worker] Task completed successfully");
|
|
192
|
+
}
|
|
193
|
+
|
|
82
194
|
parentPort.postMessage({ success: true, result });
|
|
83
195
|
} catch (error) {
|
|
84
|
-
|
|
196
|
+
if (process.env.CI || process.env.DEBUG_WORKER) {
|
|
197
|
+
console.error("[Worker] Task failed:", error.message);
|
|
198
|
+
console.error("[Worker] Error stack:", error.stack);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Include more error details
|
|
202
|
+
const errorInfo = {
|
|
203
|
+
success: false,
|
|
204
|
+
error: error.message,
|
|
205
|
+
stack: process.env.CI ? error.stack : undefined,
|
|
206
|
+
platform: process.platform,
|
|
207
|
+
arch: process.arch,
|
|
208
|
+
task: workerData.task,
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
parentPort.postMessage(errorInfo);
|
|
85
212
|
}
|
|
213
|
+
|
|
214
|
+
// Close the parent port to signal we're done
|
|
215
|
+
// This allows the worker to exit naturally
|
|
216
|
+
parentPort.close();
|
|
86
217
|
}
|
|
87
218
|
|
|
88
|
-
runWorkerTask();
|
|
219
|
+
runWorkerTask();
|
|
@@ -59,6 +59,6 @@ export interface NativeBindings {
|
|
|
59
59
|
export type GetVolumeMetadataOptions = {
|
|
60
60
|
mountPoint: string;
|
|
61
61
|
device?: string;
|
|
62
|
-
} & Partial<Pick<Options, "timeoutMs">>;
|
|
62
|
+
} & Partial<Pick<Options, "timeoutMs" | "skipNetworkVolumes">>;
|
|
63
63
|
|
|
64
64
|
export type NativeBindingsFn = () => NativeBindings | Promise<NativeBindings>;
|
package/src/types/options.ts
CHANGED