@photostructure/fs-metadata 0.6.1 → 0.7.1
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 +7 -1
- package/CLAUDE.md +141 -315
- package/CODE_OF_CONDUCT.md +11 -11
- package/CONTRIBUTING.md +1 -1
- package/README.md +34 -103
- package/binding.gyp +97 -22
- package/claude.sh +23 -0
- package/dist/index.cjs +51 -21
- 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 +51 -21
- package/dist/index.mjs.map +1 -1
- package/doc/C++_REVIEW_TODO.md +97 -25
- package/doc/GPG_RELEASE_HOWTO.md +44 -13
- package/doc/MACOS_API_REFERENCE.md +469 -0
- package/doc/SECURITY_AUDIT_2025.md +809 -0
- package/doc/SSH_RELEASE_HOWTO.md +28 -24
- package/doc/WINDOWS_API_REFERENCE.md +422 -0
- package/doc/WINDOWS_ARM64_SECURITY.md +161 -0
- package/doc/WINDOWS_DEBUG_GUIDE.md +9 -2
- 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 +23 -0
- package/package.json +61 -36
- 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 +690 -99
- 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 +12 -1
- package/scripts/prebuildify-wrapper.ts +77 -0
- package/scripts/precommit.ts +45 -20
- package/scripts/sanitizers-test.sh +1 -1
- 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/remote_info.ts +5 -3
- package/src/stack_path.ts +8 -6
- package/src/string_enum.ts +1 -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 +154 -27
- 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
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Windows ARM64 Security Configuration
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This document explains the security compilation flags used for ARM64 builds on Windows and why certain x64-specific flags are intentionally omitted.
|
|
6
|
+
|
|
7
|
+
## ARM64 Security Flags in binding.gyp
|
|
8
|
+
|
|
9
|
+
### Compiler Flags (`VCCLCompilerTool`)
|
|
10
|
+
|
|
11
|
+
#### `/guard:cf` - Control Flow Guard ✅ ENABLED
|
|
12
|
+
|
|
13
|
+
- **Supported**: Yes, ARM64 supports Control Flow Guard
|
|
14
|
+
- **Purpose**: Prevents exploitation of memory corruption vulnerabilities
|
|
15
|
+
- **Status**: Fully supported on ARM64 Windows since Windows 10
|
|
16
|
+
|
|
17
|
+
#### `/ZH:SHA_256` - Hash Algorithm ✅ ENABLED
|
|
18
|
+
|
|
19
|
+
- **Supported**: Yes, platform-independent
|
|
20
|
+
- **Purpose**: Specifies SHA-256 hash algorithm for file checksums
|
|
21
|
+
- **Status**: Standard security practice across all architectures
|
|
22
|
+
|
|
23
|
+
#### `/sdl` - Security Development Lifecycle ✅ ENABLED
|
|
24
|
+
|
|
25
|
+
- **Supported**: Yes, platform-independent
|
|
26
|
+
- **Purpose**: Enables additional compile-time security checks
|
|
27
|
+
- **Status**: Recommended for all builds
|
|
28
|
+
|
|
29
|
+
### Linker Flags (`VCLinkerTool`)
|
|
30
|
+
|
|
31
|
+
#### `/guard:cf` - Control Flow Guard at Link Time ✅ ENABLED
|
|
32
|
+
|
|
33
|
+
- **Supported**: Yes, ARM64 supports CFG
|
|
34
|
+
- **Purpose**: Enables CFG checks during linking
|
|
35
|
+
- **Status**: Must match compiler flag
|
|
36
|
+
|
|
37
|
+
#### `/DYNAMICBASE` - ASLR ✅ ENABLED
|
|
38
|
+
|
|
39
|
+
- **Supported**: Yes, ARM64 supports ASLR
|
|
40
|
+
- **Purpose**: Address Space Layout Randomization
|
|
41
|
+
- **Status**: Critical security feature, enabled on all architectures
|
|
42
|
+
|
|
43
|
+
## Flags Intentionally Omitted for ARM64
|
|
44
|
+
|
|
45
|
+
### `/Qspectre` - Spectre Mitigation ❌ NOT AVAILABLE
|
|
46
|
+
|
|
47
|
+
**Why omitted**: This flag is x64/x86-specific and not available for ARM64
|
|
48
|
+
|
|
49
|
+
- **Spectre vulnerability**: CPU speculative execution side-channel attack
|
|
50
|
+
- **x64 mitigation**: Compiler inserts speculation barriers
|
|
51
|
+
- **ARM64 status**: ARM processors have different speculative execution behavior
|
|
52
|
+
- **Alternative**: ARM64 has hardware-level mitigations built into the CPU architecture
|
|
53
|
+
- **Reference**: [Microsoft ARM64 Security](https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/arm64-exception-handling)
|
|
54
|
+
|
|
55
|
+
### `/CETCOMPAT` - Control-flow Enforcement Technology ❌ NOT AVAILABLE
|
|
56
|
+
|
|
57
|
+
**Why omitted**: Intel CET is x64-specific and not available for ARM64
|
|
58
|
+
|
|
59
|
+
- **Intel CET**: Hardware-based control-flow integrity (shadow stack)
|
|
60
|
+
- **x64 status**: Available on recent Intel CPUs (11th gen+)
|
|
61
|
+
- **ARM64 alternative**: ARM has different hardware security features:
|
|
62
|
+
- **PAC (Pointer Authentication Codes)**: Cryptographic signatures on pointers
|
|
63
|
+
- **BTI (Branch Target Identification)**: Forward-edge control flow integrity
|
|
64
|
+
- **Future**: When compiler support for ARM64 shadow stack stabilizes, we may add it
|
|
65
|
+
- **Reference**: [ARM Pointer Authentication](https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#pointer-authentication-on-arm64)
|
|
66
|
+
|
|
67
|
+
## ARM64-Specific Security Features
|
|
68
|
+
|
|
69
|
+
While ARM64 doesn't support `/Qspectre` or `/CETCOMPAT`, it has equivalent or superior hardware-level security features:
|
|
70
|
+
|
|
71
|
+
### 1. Pointer Authentication (PAC)
|
|
72
|
+
|
|
73
|
+
- Cryptographically signs pointers to prevent corruption
|
|
74
|
+
- Protects return addresses and function pointers
|
|
75
|
+
- Hardware-accelerated, minimal performance overhead
|
|
76
|
+
- **Status**: Supported in hardware, compiler support evolving
|
|
77
|
+
|
|
78
|
+
### 2. Branch Target Identification (BTI)
|
|
79
|
+
|
|
80
|
+
- Ensures indirect branches land on valid targets
|
|
81
|
+
- Prevents code-reuse attacks (ROP/JOP)
|
|
82
|
+
- Hardware-enforced control flow integrity
|
|
83
|
+
- **Status**: Supported in hardware, compiler support evolving
|
|
84
|
+
|
|
85
|
+
### 3. Memory Tagging Extension (MTE)
|
|
86
|
+
|
|
87
|
+
- Hardware-based memory safety
|
|
88
|
+
- Detects use-after-free and buffer overflows
|
|
89
|
+
- Probabilistic detection with ~0-15% overhead
|
|
90
|
+
- **Status**: ARMv8.5-A+, not yet in consumer Windows devices
|
|
91
|
+
|
|
92
|
+
## Comparison: x64 vs ARM64 Security
|
|
93
|
+
|
|
94
|
+
| Feature | x64 | ARM64 | Notes |
|
|
95
|
+
| ------------------ | ------------------------------- | ----------------------- | ----------------------------- |
|
|
96
|
+
| Control Flow Guard | ✅ `/guard:cf` | ✅ `/guard:cf` | Same implementation |
|
|
97
|
+
| ASLR | ✅ `/DYNAMICBASE` | ✅ `/DYNAMICBASE` | Same implementation |
|
|
98
|
+
| Spectre Mitigation | ✅ `/Qspectre` | ⚠️ Hardware mitigations | Different approaches |
|
|
99
|
+
| Shadow Stack | ✅ `/CETCOMPAT` (Intel CET) | ⚠️ PAC (different tech) | Both protect return addresses |
|
|
100
|
+
| Branch Protection | ✅ CET Indirect Branch Tracking | ✅ BTI | Similar purpose |
|
|
101
|
+
| Memory Safety | ⚠️ Software-based | ✅ MTE (future) | ARM has hardware advantage |
|
|
102
|
+
|
|
103
|
+
## Build Configuration
|
|
104
|
+
|
|
105
|
+
### Current ARM64 Flags (binding.gyp)
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"target_arch=='arm64'": {
|
|
110
|
+
"defines": ["_M_ARM64", "_WIN64"],
|
|
111
|
+
"msvs_settings": {
|
|
112
|
+
"VCCLCompilerTool": {
|
|
113
|
+
"AdditionalOptions": ["/guard:cf", "/ZH:SHA_256", "/sdl"],
|
|
114
|
+
"ExceptionHandling": 1,
|
|
115
|
+
"RuntimeTypeInfo": "true"
|
|
116
|
+
},
|
|
117
|
+
"VCLinkerTool": {
|
|
118
|
+
"AdditionalOptions": ["/guard:cf", "/DYNAMICBASE"]
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Security Posture
|
|
126
|
+
|
|
127
|
+
✅ **Current**: ARM64 builds have equivalent or better security than x64
|
|
128
|
+
|
|
129
|
+
- All applicable mitigations are enabled
|
|
130
|
+
- ARM64 hardware features provide additional protection
|
|
131
|
+
- No security regression compared to x64
|
|
132
|
+
|
|
133
|
+
⏳ **Future Improvements**:
|
|
134
|
+
|
|
135
|
+
- Monitor compiler support for ARM64 shadow stack
|
|
136
|
+
- Evaluate PAC/BTI enablement when stable
|
|
137
|
+
- Consider MTE when available in consumer devices
|
|
138
|
+
|
|
139
|
+
## Testing
|
|
140
|
+
|
|
141
|
+
ARM64 builds are tested on:
|
|
142
|
+
|
|
143
|
+
- Windows 11 ARM64 (native)
|
|
144
|
+
- Windows 10 ARM64 (emulation on x64)
|
|
145
|
+
|
|
146
|
+
Security features are validated through:
|
|
147
|
+
|
|
148
|
+
- Static analysis during compilation
|
|
149
|
+
- Runtime testing on ARM64 devices
|
|
150
|
+
- Memory safety tests (windows-memory-check.test.ts)
|
|
151
|
+
|
|
152
|
+
## References
|
|
153
|
+
|
|
154
|
+
- [Microsoft ARM64 ABI](https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions)
|
|
155
|
+
- [ARM Security Features](https://developer.arm.com/documentation/102433/0100)
|
|
156
|
+
- [Windows ARM64 Security](https://learn.microsoft.com/en-us/windows/arm/overview)
|
|
157
|
+
- [Control Flow Guard on ARM64](https://learn.microsoft.com/en-us/windows/win32/secbp/control-flow-guard)
|
|
158
|
+
|
|
159
|
+
## Last Updated
|
|
160
|
+
|
|
161
|
+
2025-10-23 - Initial documentation of ARM64 security configuration
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Windows and Alpine Linux Debugging Guide for debuglog.test.ts
|
|
2
2
|
|
|
3
3
|
## Issue Summary
|
|
4
|
+
|
|
4
5
|
The debuglog.test.ts file was failing on:
|
|
6
|
+
|
|
5
7
|
1. **Windows CI**: "Converting circular structure to JSON" error in Jest's message passing system when `execFileSync` threw errors with circular references
|
|
6
8
|
2. **Alpine Linux**: `ETIMEDOUT` errors when spawning child processes with `npx`
|
|
7
9
|
|
|
@@ -28,11 +30,13 @@ The debuglog.test.ts file was failing on:
|
|
|
28
30
|
To test these changes on your Windows test box:
|
|
29
31
|
|
|
30
32
|
1. **Run the specific test file:**
|
|
33
|
+
|
|
31
34
|
```powershell
|
|
32
35
|
npm test -- src/debuglog.test.ts
|
|
33
36
|
```
|
|
34
37
|
|
|
35
38
|
2. **Run with verbose output to see debugging info:**
|
|
39
|
+
|
|
36
40
|
```powershell
|
|
37
41
|
npm test -- src/debuglog.test.ts --verbose
|
|
38
42
|
```
|
|
@@ -43,11 +47,12 @@ To test these changes on your Windows test box:
|
|
|
43
47
|
- Whether `npx tsx` is available and working correctly
|
|
44
48
|
|
|
45
49
|
4. **To test individual child scripts directly:**
|
|
50
|
+
|
|
46
51
|
```powershell
|
|
47
52
|
# Test debuglog-child.ts
|
|
48
53
|
$env:NODE_DEBUG="fs-metadata"
|
|
49
54
|
npx tsx src/test-utils/debuglog-child.ts
|
|
50
|
-
|
|
55
|
+
|
|
51
56
|
# Test debuglog-enabled-child.ts
|
|
52
57
|
$env:NODE_DEBUG="fs-metadata"
|
|
53
58
|
npx tsx src/test-utils/debuglog-enabled-child.ts
|
|
@@ -61,12 +66,14 @@ To test these changes on your Windows test box:
|
|
|
61
66
|
## Debugging Tips
|
|
62
67
|
|
|
63
68
|
1. **Enable Node.js debugging:**
|
|
69
|
+
|
|
64
70
|
```powershell
|
|
65
71
|
$env:NODE_OPTIONS="--trace-warnings"
|
|
66
72
|
npm test -- src/debuglog.test.ts
|
|
67
73
|
```
|
|
68
74
|
|
|
69
75
|
2. **Check npx/tsx availability:**
|
|
76
|
+
|
|
70
77
|
```powershell
|
|
71
78
|
npx --version
|
|
72
79
|
npx tsx --version
|
|
@@ -86,4 +93,4 @@ To test these changes on your Windows test box:
|
|
|
86
93
|
|
|
87
94
|
## Rollback Plan
|
|
88
95
|
|
|
89
|
-
If these changes cause new issues, the previous approach using execFileSync can be restored by reverting this commit. The key difference is the switch from execFileSync to spawnSync and the enhanced error handling.
|
|
96
|
+
If these changes cause new issues, the previous approach using execFileSync can be restored by reverting this commit. The key difference is the switch from execFileSync to spawnSync and the enhanced error handling.
|
package/doc/examples.md
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
This guide provides practical examples for using `@photostructure/fs-metadata`.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
### List All Mounted Volumes
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { getVolumeMountPoints } from "@photostructure/fs-metadata";
|
|
11
|
+
|
|
12
|
+
const mountPoints = await getVolumeMountPoints();
|
|
13
|
+
|
|
14
|
+
// Example output on Windows:
|
|
15
|
+
// [
|
|
16
|
+
// { mountPoint: 'C:\\', status: 'healthy' },
|
|
17
|
+
// { mountPoint: 'D:\\', status: 'healthy' },
|
|
18
|
+
// { mountPoint: 'E:\\', status: 'unavailable' }
|
|
19
|
+
// ]
|
|
20
|
+
|
|
21
|
+
// Example output on Linux:
|
|
22
|
+
// [
|
|
23
|
+
// { mountPoint: '/', status: 'healthy' },
|
|
24
|
+
// { mountPoint: '/home', status: 'healthy' },
|
|
25
|
+
// { mountPoint: '/mnt/nas', status: 'timeout' }
|
|
26
|
+
// ]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Get Volume Metadata
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { getVolumeMetadata } from "@photostructure/fs-metadata";
|
|
33
|
+
|
|
34
|
+
const metadata = await getVolumeMetadata("/");
|
|
35
|
+
|
|
36
|
+
// Example output:
|
|
37
|
+
// {
|
|
38
|
+
// mountPoint: '/',
|
|
39
|
+
// mountFrom: '/dev/sda1',
|
|
40
|
+
// fstype: 'ext4',
|
|
41
|
+
// size: 500107862016,
|
|
42
|
+
// used: 234567890123,
|
|
43
|
+
// available: 239539971893,
|
|
44
|
+
// status: 'healthy'
|
|
45
|
+
// }
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Get All Volume Metadata
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { getAllVolumeMetadata } from "@photostructure/fs-metadata";
|
|
52
|
+
|
|
53
|
+
// Get all volumes including system volumes
|
|
54
|
+
const allVolumes = await getAllVolumeMetadata({ includeSystemVolumes: true });
|
|
55
|
+
|
|
56
|
+
// Filter healthy volumes only
|
|
57
|
+
const healthyVolumes = allVolumes.filter((v) => v.status === "healthy");
|
|
58
|
+
|
|
59
|
+
// Calculate total storage
|
|
60
|
+
const totalStorage = healthyVolumes.reduce((sum, v) => sum + v.size, 0);
|
|
61
|
+
const totalUsed = healthyVolumes.reduce((sum, v) => sum + v.used, 0);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Hidden Files
|
|
65
|
+
|
|
66
|
+
### Check if File is Hidden
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { isHidden } from "@photostructure/fs-metadata";
|
|
70
|
+
|
|
71
|
+
// Simple check
|
|
72
|
+
const hidden = await isHidden("/path/to/file.txt");
|
|
73
|
+
|
|
74
|
+
// Check with timeout
|
|
75
|
+
const hidden2 = await isHidden("/mnt/slow-network/file.txt", {
|
|
76
|
+
timeoutMs: 5000,
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Set Hidden Attribute
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { setHidden } from "@photostructure/fs-metadata";
|
|
84
|
+
|
|
85
|
+
// Hide a file
|
|
86
|
+
await setHidden("/path/to/file.txt", true);
|
|
87
|
+
|
|
88
|
+
// Unhide a file
|
|
89
|
+
await setHidden("/path/to/.hidden-file", false);
|
|
90
|
+
|
|
91
|
+
// Note: On POSIX systems (Linux/macOS), this will rename the file
|
|
92
|
+
// to add/remove a leading dot. On Windows, it sets the hidden attribute.
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Recursive Hidden Check
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import { isHiddenRecursive } from "@photostructure/fs-metadata";
|
|
99
|
+
|
|
100
|
+
// Check if file or any parent directory is hidden
|
|
101
|
+
const hidden = await isHiddenRecursive("/home/user/.config/app/settings.json");
|
|
102
|
+
// Returns true because .config is hidden
|
|
103
|
+
|
|
104
|
+
// Works with Windows hidden attributes too
|
|
105
|
+
const hidden2 = await isHiddenRecursive("C:\\Users\\Public\\Desktop\\file.txt");
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Get Hidden Metadata
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { getHiddenMetadata } from "@photostructure/fs-metadata";
|
|
112
|
+
|
|
113
|
+
const metadata = await getHiddenMetadata("/path/to/file");
|
|
114
|
+
|
|
115
|
+
// Example output:
|
|
116
|
+
// {
|
|
117
|
+
// hidden: true,
|
|
118
|
+
// hiddenByAncestor: false,
|
|
119
|
+
// localSupport: 'native', // or 'posix' or 'none'
|
|
120
|
+
// exists: true
|
|
121
|
+
// }
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## CommonJS Usage
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
const {
|
|
128
|
+
getVolumeMountPoints,
|
|
129
|
+
getVolumeMetadata,
|
|
130
|
+
isHidden,
|
|
131
|
+
setHidden,
|
|
132
|
+
} = require("@photostructure/fs-metadata");
|
|
133
|
+
|
|
134
|
+
async function main() {
|
|
135
|
+
const mountPoints = await getVolumeMountPoints();
|
|
136
|
+
console.log("Mount points:", mountPoints);
|
|
137
|
+
|
|
138
|
+
const metadata = await getVolumeMetadata(mountPoints[0].mountPoint);
|
|
139
|
+
console.log("Volume metadata:", metadata);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
main().catch(console.error);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Error Handling
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import {
|
|
149
|
+
getVolumeMetadata,
|
|
150
|
+
VolumeMountPointNotAccessibleError,
|
|
151
|
+
TimeoutError,
|
|
152
|
+
} from "@photostructure/fs-metadata";
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
const metadata = await getVolumeMetadata("/mnt/network-drive", {
|
|
156
|
+
timeoutMs: 10000, // 10 second timeout
|
|
157
|
+
});
|
|
158
|
+
} catch (error) {
|
|
159
|
+
if (error instanceof TimeoutError) {
|
|
160
|
+
console.error("Operation timed out - network drive may be unreachable");
|
|
161
|
+
} else if (error instanceof VolumeMountPointNotAccessibleError) {
|
|
162
|
+
console.error("Volume is not accessible:", error.message);
|
|
163
|
+
} else {
|
|
164
|
+
console.error("Unexpected error:", error);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Working with Network Volumes
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import {
|
|
173
|
+
getVolumeMountPoints,
|
|
174
|
+
getVolumeMetadata,
|
|
175
|
+
} from "@photostructure/fs-metadata";
|
|
176
|
+
|
|
177
|
+
// Network volumes may timeout or be unavailable
|
|
178
|
+
const mountPoints = await getVolumeMountPoints({ timeoutMs: 30000 });
|
|
179
|
+
|
|
180
|
+
// Filter out unhealthy volumes
|
|
181
|
+
const availableVolumes = mountPoints.filter((mp) => mp.status === "healthy");
|
|
182
|
+
|
|
183
|
+
// Get metadata with extended timeout for network drives
|
|
184
|
+
for (const mp of availableVolumes) {
|
|
185
|
+
try {
|
|
186
|
+
const metadata = await getVolumeMetadata(mp.mountPoint, {
|
|
187
|
+
timeoutMs: 20000, // 20 seconds for network volumes
|
|
188
|
+
});
|
|
189
|
+
console.log(
|
|
190
|
+
`${mp.mountPoint}: ${metadata.used} of ${metadata.size} bytes used`,
|
|
191
|
+
);
|
|
192
|
+
} catch (error) {
|
|
193
|
+
console.error(
|
|
194
|
+
`Failed to get metadata for ${mp.mountPoint}:`,
|
|
195
|
+
error.message,
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Platform-Specific Examples
|
|
202
|
+
|
|
203
|
+
### Windows: List Drive Letters
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
import { getVolumeMountPoints } from "@photostructure/fs-metadata";
|
|
207
|
+
|
|
208
|
+
const volumes = await getVolumeMountPoints();
|
|
209
|
+
const driveLetters = volumes
|
|
210
|
+
.filter((v) => v.status === "healthy")
|
|
211
|
+
.map((v) => v.mountPoint)
|
|
212
|
+
.filter((mp) => /^[A-Z]:\\$/.test(mp))
|
|
213
|
+
.sort();
|
|
214
|
+
|
|
215
|
+
console.log("Available drives:", driveLetters);
|
|
216
|
+
// Output: ["C:\\", "D:\\", "E:\\"]
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Linux: Filter System Volumes
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { getAllVolumeMetadata } from "@photostructure/fs-metadata";
|
|
223
|
+
|
|
224
|
+
// Get only user-accessible volumes (excludes /proc, /sys, etc.)
|
|
225
|
+
const userVolumes = await getAllVolumeMetadata({
|
|
226
|
+
includeSystemVolumes: false,
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Custom filtering for specific filesystem types
|
|
230
|
+
const dataVolumes = userVolumes.filter((v) =>
|
|
231
|
+
["ext4", "xfs", "btrfs", "zfs"].includes(v.fstype),
|
|
232
|
+
);
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### macOS: APFS Volumes
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
import { getAllVolumeMetadata } from "@photostructure/fs-metadata";
|
|
239
|
+
|
|
240
|
+
const volumes = await getAllVolumeMetadata();
|
|
241
|
+
|
|
242
|
+
// Find APFS volumes
|
|
243
|
+
const apfsVolumes = volumes.filter((v) => v.fstype === "apfs");
|
|
244
|
+
|
|
245
|
+
// APFS containers share space, so available space might be the same
|
|
246
|
+
const containers = new Map();
|
|
247
|
+
for (const vol of apfsVolumes) {
|
|
248
|
+
const key = `${vol.size}-${vol.available}`;
|
|
249
|
+
if (!containers.has(key)) {
|
|
250
|
+
containers.set(key, []);
|
|
251
|
+
}
|
|
252
|
+
containers.get(key).push(vol.mountPoint);
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Debug Logging
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
// Enable debug logging before importing
|
|
260
|
+
process.env.NODE_DEBUG = "fs-meta";
|
|
261
|
+
|
|
262
|
+
import { getVolumeMetadata } from "@photostructure/fs-metadata";
|
|
263
|
+
|
|
264
|
+
// Now operations will log debug information to stderr
|
|
265
|
+
const metadata = await getVolumeMetadata("/");
|
|
266
|
+
// Debug output includes native code operations and timing information
|
|
267
|
+
```
|