@photostructure/fs-metadata 0.0.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/LICENSE.txt +7 -0
- package/README.md +311 -0
- package/binding.gyp +111 -0
- package/package.json +121 -0
- 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/scripts/configure.mjs +36 -0
- package/src/binding.cpp +68 -0
- package/src/common/error_utils.h +19 -0
- package/src/common/metadata_worker.h +69 -0
- package/src/common/mount_point.h +13 -0
- package/src/common/volume_metadata.h +34 -0
- package/src/common/volume_mount_points.h +8 -0
- package/src/darwin/fs_meta.h +18 -0
- package/src/darwin/volume_metadata.cpp +235 -0
- package/src/darwin/volume_mount_points.cpp +65 -0
- package/src/linux/blkid_cache.cpp +42 -0
- package/src/linux/blkid_cache.h +27 -0
- package/src/linux/gio_utils.cpp +151 -0
- package/src/linux/gio_utils.h +27 -0
- package/src/linux/gio_worker.cpp +87 -0
- package/src/linux/gio_worker.h +32 -0
- package/src/linux/volume_metadata.cpp +92 -0
- package/src/windows/error_utils.h +22 -0
- package/src/windows/fs_meta.h +43 -0
- package/src/windows/volume_metadata.cpp +194 -0
- package/src/windows/volume_mount_points.cpp +62 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright (c) 2024 Matthew McEachen
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# @photostructure/fs-metadata
|
|
2
|
+
|
|
3
|
+
A cross-platform native Node.js module for retrieving filesystem metadata including mount points, volume information, and space utilization statistics.
|
|
4
|
+
|
|
5
|
+
Built and supported by [PhotoStructure](https://photostructure.com).
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@photostructure/fs-metadata)
|
|
8
|
+
[](https://github.com/photostructure/fs-metadata/actions/workflows/test.yml)
|
|
9
|
+
[](https://github.com/photostructure/fs-metadata/issues)
|
|
10
|
+
[](https://snyk.io/test/github/photostructure/fs-metadata?targetFile=package.json)
|
|
11
|
+
[](https://nodejs.org/dist/latest/docs/api/n-api.html#node-api-version-matrix)
|
|
12
|
+
[](https://github.com/photostructure/fs-metadata)
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- List all mounted volumes/drives on the system
|
|
17
|
+
- Get detailed volume metadata including:
|
|
18
|
+
- Total size, used space, and available space
|
|
19
|
+
- Filesystem type and volume label
|
|
20
|
+
- Volume UUID (when available)
|
|
21
|
+
- Remote/network share information
|
|
22
|
+
- Cross-platform support:
|
|
23
|
+
- Windows (x64, arm64)
|
|
24
|
+
- macOS (x64, arm64)
|
|
25
|
+
- Linux (x64, arm64) (including Gnome GIO/`GVfs` mounts, if available)
|
|
26
|
+
- Written in modern TypeScript with full type definitions
|
|
27
|
+
- Native async implementations avoid blocking the event loop
|
|
28
|
+
- Support for both ESM and CJS consumers
|
|
29
|
+
- Comprehensive test coverage
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install @photostructure/fs-metadata
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import {
|
|
41
|
+
getVolumeMountPoints,
|
|
42
|
+
getVolumeMetadata,
|
|
43
|
+
} from "@photostructure/fs-metadata";
|
|
44
|
+
|
|
45
|
+
// List all mounted volumes
|
|
46
|
+
const mountPoints = await getVolumeMountPoints();
|
|
47
|
+
console.dir({ mountPoints });
|
|
48
|
+
// Example output: ['C:\\', 'D:\\'] on Windows
|
|
49
|
+
// Example output: ['/', '/home', '/Users'] on Unix-like systems
|
|
50
|
+
|
|
51
|
+
// Get metadata for a specific volume
|
|
52
|
+
const metadata = await getVolumeMetadata("C:\\"); // Windows
|
|
53
|
+
// Or for Unix-like systems:
|
|
54
|
+
// const metadata = await getVolumeMetadata('/');
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
If you're using CommonJS:
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
const {
|
|
61
|
+
getVolumeMountPoints,
|
|
62
|
+
getVolumeMetadata,
|
|
63
|
+
} = require("@photostructure/fs-metadata");
|
|
64
|
+
|
|
65
|
+
// Usage is the same as the ESM example above
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Documentation
|
|
69
|
+
|
|
70
|
+
[Read the API here](https://photostructure.github.io/fs-metadata/modules.html)
|
|
71
|
+
|
|
72
|
+
## Options
|
|
73
|
+
|
|
74
|
+
### Timeouts
|
|
75
|
+
|
|
76
|
+
There is a [default timeout](https://photostructure.github.io/fs-metadata/variables/TimeoutMsDefault.html) applied to all operations. This may not be sufficient for some OSes and volumes--especially powered-down optical drives (which may take 10s of seconds to wake up). Disable timeouts by setting `{timeoutMs: 0}`.
|
|
77
|
+
|
|
78
|
+
### Filtering
|
|
79
|
+
|
|
80
|
+
Linux and macOS have a (surprisingly large) number of mountpoints that are for internal use (especially if your Linux distribution uses `snap` and/or other loopback ~~hacks~~ systems).
|
|
81
|
+
|
|
82
|
+
This library tries to avoid those with a bunch of exclusion patterns--see the [Options](https://photostructure.github.io/fs-metadata/interfaces/Options.html) interface for details.
|
|
83
|
+
|
|
84
|
+
To disable these filters, provide an empty array for these `excluded*` fields, like so:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
const allMountPoints = await getVolumeMountPoints({
|
|
88
|
+
excludedFileSystemTypes: [],
|
|
89
|
+
excludedMountPointGlobs: [],
|
|
90
|
+
onlyDirectories: false,
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Platform-Specific Behaviors
|
|
95
|
+
|
|
96
|
+
This module's results are inherently platform-specific. Here are some things to
|
|
97
|
+
keep in mind:
|
|
98
|
+
|
|
99
|
+
### Mount Points
|
|
100
|
+
|
|
101
|
+
#### Windows
|
|
102
|
+
|
|
103
|
+
- Mount points are drive letters with trailing backslash (e.g., `C:\`, `D:\`)
|
|
104
|
+
- Network shares appear as mounted drives with UNC paths
|
|
105
|
+
- Volume GUIDs are available through Windows API
|
|
106
|
+
- Hidden and system volumes may be included
|
|
107
|
+
|
|
108
|
+
#### macOS
|
|
109
|
+
|
|
110
|
+
- Uses forward slashes for paths (e.g., `/`, `/Users`)
|
|
111
|
+
- Volume UUIDs may be available through the DiskArbitration framework
|
|
112
|
+
- Time Machine volumes should be detected and handled appropriately
|
|
113
|
+
|
|
114
|
+
#### Linux
|
|
115
|
+
|
|
116
|
+
- Uses forward slashes for paths (e.g., `/`, `/home`)
|
|
117
|
+
- Network mounts (NFS/CIFS) handled through mount table
|
|
118
|
+
- If `GIO` support is installed, it will be queried for additional mountpoints and volume metadata
|
|
119
|
+
- Depending on your distribution, you may want to use `{ linuxMountTablePath: "/etc/mtab" }` instead of the default, `/proc/mounts`.
|
|
120
|
+
- UUID detection is via `libblkid`, which must be installed.
|
|
121
|
+
|
|
122
|
+
### Volume Metadata
|
|
123
|
+
|
|
124
|
+
#### Windows
|
|
125
|
+
|
|
126
|
+
- Size information from GetDiskFreeSpaceEx
|
|
127
|
+
- Volume information (label, filesystem) from GetVolumeInformation
|
|
128
|
+
- Remote status from GetDriveType
|
|
129
|
+
- `fileSystem` will be `NTFS` for remote filesystems, as that's how Windows presents the local volume. Fixing this to be more accurate requires additional heuristics that have diminshing returns.
|
|
130
|
+
- The UUID is the volume serial number that the operating system assigns when a hard disk is formatted, and **not the physical UUID assigned by the manufacturer**. This lets us avoid one more syscall (and it's a doozy, the Windows Management Instrumentation (WMI) Win32_PhysicalMedia function loves to hang).
|
|
131
|
+
|
|
132
|
+
#### macOS
|
|
133
|
+
|
|
134
|
+
- Size calculations via statvfs
|
|
135
|
+
- Volume details through DiskArbitration framework
|
|
136
|
+
- Network share detection via volume characteristics
|
|
137
|
+
- Time Machine volume detection
|
|
138
|
+
|
|
139
|
+
#### Linux
|
|
140
|
+
|
|
141
|
+
- Size information from statvfs
|
|
142
|
+
- Filesystem type from mount table
|
|
143
|
+
- Block device metadata via libblkid
|
|
144
|
+
- Network filesystem detection from mount options
|
|
145
|
+
- Optional GIO integration for additional metadata
|
|
146
|
+
|
|
147
|
+
### Filesystem Types
|
|
148
|
+
|
|
149
|
+
#### Windows
|
|
150
|
+
|
|
151
|
+
- NTFS
|
|
152
|
+
- FAT32
|
|
153
|
+
- exFAT
|
|
154
|
+
- ReFS
|
|
155
|
+
- Network shares (CIFS/SMB)
|
|
156
|
+
|
|
157
|
+
#### macOS
|
|
158
|
+
|
|
159
|
+
- APFS (default since macOS High Sierra)
|
|
160
|
+
- HFS+ (legacy)
|
|
161
|
+
- FAT32
|
|
162
|
+
- exFAT
|
|
163
|
+
- Network shares (AFP, SMB, NFS)
|
|
164
|
+
|
|
165
|
+
#### Linux
|
|
166
|
+
|
|
167
|
+
- ext2/3/4
|
|
168
|
+
- XFS
|
|
169
|
+
- Btrfs
|
|
170
|
+
- ZFS
|
|
171
|
+
- Network filesystems (NFS, CIFS)
|
|
172
|
+
- Pseudo filesystems (procfs, sysfs) - excluded by default
|
|
173
|
+
|
|
174
|
+
### Default Excluded Mount Points
|
|
175
|
+
|
|
176
|
+
#### Windows
|
|
177
|
+
|
|
178
|
+
- None by default
|
|
179
|
+
|
|
180
|
+
#### macOS
|
|
181
|
+
|
|
182
|
+
- `/dev`
|
|
183
|
+
- `/dev/fd`
|
|
184
|
+
- System volume internal mounts
|
|
185
|
+
|
|
186
|
+
#### Linux
|
|
187
|
+
|
|
188
|
+
- `/proc`
|
|
189
|
+
- `/sys`
|
|
190
|
+
- `/dev`
|
|
191
|
+
- `/run`
|
|
192
|
+
- Snap mounts
|
|
193
|
+
- Other virtual filesystems
|
|
194
|
+
|
|
195
|
+
### Network Share Metadata
|
|
196
|
+
|
|
197
|
+
#### Windows
|
|
198
|
+
|
|
199
|
+
- UNC paths parsed for host/share information
|
|
200
|
+
- SMB/CIFS protocol support
|
|
201
|
+
- Network status via GetDriveType
|
|
202
|
+
|
|
203
|
+
#### macOS
|
|
204
|
+
|
|
205
|
+
- AFP and SMB protocol support
|
|
206
|
+
- Network status via volume characteristics
|
|
207
|
+
- Host/share parsing from mount URLs
|
|
208
|
+
|
|
209
|
+
#### Linux
|
|
210
|
+
|
|
211
|
+
- NFS and CIFS support
|
|
212
|
+
- Network detection from filesystem type
|
|
213
|
+
- Remote info parsed from mount spec
|
|
214
|
+
|
|
215
|
+
### Performance Considerations
|
|
216
|
+
|
|
217
|
+
#### Windows
|
|
218
|
+
|
|
219
|
+
- Drive letter enumeration is fast
|
|
220
|
+
- Volume metadata queries may block
|
|
221
|
+
|
|
222
|
+
#### macOS
|
|
223
|
+
|
|
224
|
+
- DiskArbitration queries are generally fast
|
|
225
|
+
- Network volume operations may be slow
|
|
226
|
+
|
|
227
|
+
#### Linux
|
|
228
|
+
|
|
229
|
+
- Mount table parsing is fast
|
|
230
|
+
- Block device operations may block
|
|
231
|
+
- GIO operations are asynchronous
|
|
232
|
+
|
|
233
|
+
### Error Handling
|
|
234
|
+
|
|
235
|
+
#### Windows
|
|
236
|
+
|
|
237
|
+
- Access denied errors for restricted volumes
|
|
238
|
+
- Network timeout errors for disconnected shares
|
|
239
|
+
- Invalid drive letter errors
|
|
240
|
+
|
|
241
|
+
#### macOS
|
|
242
|
+
|
|
243
|
+
- DiskArbitration framework errors
|
|
244
|
+
- Network disconnection handling
|
|
245
|
+
- Volume unmount detection
|
|
246
|
+
|
|
247
|
+
#### Linux
|
|
248
|
+
|
|
249
|
+
- Mount table parsing errors
|
|
250
|
+
- Block device access errors
|
|
251
|
+
- GIO operation failures
|
|
252
|
+
- Network filesystem timeouts
|
|
253
|
+
|
|
254
|
+
### Configuration Options
|
|
255
|
+
|
|
256
|
+
Common options across platforms:
|
|
257
|
+
|
|
258
|
+
- Timeout duration
|
|
259
|
+
- Excluded mount point patterns
|
|
260
|
+
- Directory-only filter
|
|
261
|
+
|
|
262
|
+
Platform-specific options:
|
|
263
|
+
|
|
264
|
+
- Linux: Mount table path selection
|
|
265
|
+
- Linux: GIO support enable/disable
|
|
266
|
+
- Windows: Network share handling
|
|
267
|
+
- macOS: Time Machine volume handling
|
|
268
|
+
|
|
269
|
+
### Recommendations
|
|
270
|
+
|
|
271
|
+
#### Windows
|
|
272
|
+
|
|
273
|
+
- Handle access denied errors gracefully
|
|
274
|
+
- Check drive type before operations
|
|
275
|
+
|
|
276
|
+
#### macOS
|
|
277
|
+
|
|
278
|
+
- Monitor volume mount/unmount notifications
|
|
279
|
+
- Handle Time Machine volumes appropriately
|
|
280
|
+
- Check network status before operations
|
|
281
|
+
|
|
282
|
+
#### Linux
|
|
283
|
+
|
|
284
|
+
- Use default mount table when possible
|
|
285
|
+
- Enable GIO support if available
|
|
286
|
+
- Handle remote filesystem timeouts
|
|
287
|
+
|
|
288
|
+
## Building from Source
|
|
289
|
+
|
|
290
|
+
Requirements:
|
|
291
|
+
|
|
292
|
+
- Supported Node.js version
|
|
293
|
+
- Python 3
|
|
294
|
+
- C++ build tools:
|
|
295
|
+
- Windows: Visual Studio Build Tools
|
|
296
|
+
- macOS: Xcode Command Line Tools
|
|
297
|
+
- Linux: GCC and development headers
|
|
298
|
+
|
|
299
|
+
## License
|
|
300
|
+
|
|
301
|
+
MIT
|
|
302
|
+
|
|
303
|
+
## Contributing
|
|
304
|
+
|
|
305
|
+
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
|
306
|
+
|
|
307
|
+
Please make sure to update tests and documentation as appropriate.
|
|
308
|
+
|
|
309
|
+
## Security
|
|
310
|
+
|
|
311
|
+
If you discover a security vulnerability, please send an email to [security@photostructure.com](mailto:security@photostructure.com)
|
package/binding.gyp
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
{
|
|
2
|
+
"variables": {
|
|
3
|
+
"enable_gio%": "false"
|
|
4
|
+
},
|
|
5
|
+
"targets": [
|
|
6
|
+
{
|
|
7
|
+
"target_name": "node_fs_meta",
|
|
8
|
+
"sources": [
|
|
9
|
+
"src/binding.cpp"
|
|
10
|
+
],
|
|
11
|
+
"include_dirs": [
|
|
12
|
+
"<!@(node -p \"require('node-addon-api').include\")",
|
|
13
|
+
"src"
|
|
14
|
+
],
|
|
15
|
+
"dependencies": [
|
|
16
|
+
"<!(node -p \"require('node-addon-api').gyp\")"
|
|
17
|
+
],
|
|
18
|
+
"defines": [
|
|
19
|
+
"NAPI_CPP_EXCEPTIONS"
|
|
20
|
+
],
|
|
21
|
+
"conditions": [
|
|
22
|
+
[
|
|
23
|
+
"OS=='linux'",
|
|
24
|
+
{
|
|
25
|
+
"sources": [
|
|
26
|
+
"src/linux/blkid_cache.cpp",
|
|
27
|
+
"src/linux/volume_metadata.cpp"
|
|
28
|
+
],
|
|
29
|
+
"libraries": [
|
|
30
|
+
"-lblkid"
|
|
31
|
+
],
|
|
32
|
+
"cflags": [
|
|
33
|
+
"-fPIC"
|
|
34
|
+
],
|
|
35
|
+
"cflags_cc": [
|
|
36
|
+
"-fexceptions",
|
|
37
|
+
"-fPIC"
|
|
38
|
+
],
|
|
39
|
+
"conditions": [
|
|
40
|
+
[
|
|
41
|
+
"enable_gio=='true'",
|
|
42
|
+
{
|
|
43
|
+
"sources": [
|
|
44
|
+
"src/linux/gio_utils.cpp",
|
|
45
|
+
"src/linux/gio_worker.cpp"
|
|
46
|
+
],
|
|
47
|
+
"defines": [
|
|
48
|
+
"ENABLE_GIO=1"
|
|
49
|
+
],
|
|
50
|
+
"libraries": [
|
|
51
|
+
"<!@(pkg-config --libs gio-2.0)"
|
|
52
|
+
],
|
|
53
|
+
"cflags": [
|
|
54
|
+
"<!@(pkg-config --cflags gio-2.0)"
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
[
|
|
62
|
+
"OS=='win'",
|
|
63
|
+
{
|
|
64
|
+
"sources": [
|
|
65
|
+
"src/windows/volume_mount_points.cpp",
|
|
66
|
+
"src/windows/volume_metadata.cpp"
|
|
67
|
+
],
|
|
68
|
+
"libraries": [
|
|
69
|
+
"-lMpr.lib"
|
|
70
|
+
],
|
|
71
|
+
"msvs_settings": {
|
|
72
|
+
"VCCLCompilerTool": {
|
|
73
|
+
"ExceptionHandling": 1,
|
|
74
|
+
"RuntimeTypeInfo": "true"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
[
|
|
80
|
+
"OS=='mac'",
|
|
81
|
+
{
|
|
82
|
+
"sources": [
|
|
83
|
+
"src/darwin/volume_mount_points.cpp",
|
|
84
|
+
"src/darwin/volume_metadata.cpp"
|
|
85
|
+
],
|
|
86
|
+
"xcode_settings": {
|
|
87
|
+
"CLANG_CXX_LANGUAGE_STANDARD": "c++17",
|
|
88
|
+
"GCC_ENABLE_CPP_EXCEPTIONS": "YES",
|
|
89
|
+
"CLANG_CXX_LIBRARY": "libc++",
|
|
90
|
+
"MACOSX_DEPLOYMENT_TARGET": "10.15"
|
|
91
|
+
},
|
|
92
|
+
"cflags": [
|
|
93
|
+
"-fexceptions",
|
|
94
|
+
"-fPIC"
|
|
95
|
+
],
|
|
96
|
+
"cflags_cc": [
|
|
97
|
+
"-fexceptions"
|
|
98
|
+
],
|
|
99
|
+
"link_settings": {
|
|
100
|
+
"libraries": [
|
|
101
|
+
"DiskArbitration.framework",
|
|
102
|
+
"Foundation.framework",
|
|
103
|
+
"IOKit.framework"
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@photostructure/fs-metadata",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Cross-platform native filesystem metadata retrieval for Node.js",
|
|
5
|
+
"homepage": "https://photostructure.github.io/fs-metadata/",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/cjs/index.cjs",
|
|
8
|
+
"module": "dist/esm/index.mjs",
|
|
9
|
+
"// exports": "https://nodejs.org/api/packages.html#conditional-exports",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"require": {
|
|
13
|
+
"default": "./lib/cjs/index.cjs",
|
|
14
|
+
"types": "./lib/cjs/index.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"import": {
|
|
17
|
+
"default": "./lib/esm/index.js",
|
|
18
|
+
"types": "./lib/esm/index.d.ts"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+ssh://git@github.com/photostructure/fs-metadata.git"
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"scripts": {
|
|
28
|
+
"install": "node-gyp-build",
|
|
29
|
+
"clean": "run-p clean:*",
|
|
30
|
+
"clean:dist": "rimraf dist",
|
|
31
|
+
"clean:gyp": "node-gyp clean",
|
|
32
|
+
"// scripts/configure.js checks if gio is installed": "",
|
|
33
|
+
"configure": "node scripts/configure.mjs",
|
|
34
|
+
"// prebuild": "is called by .github/workflows/build.yml",
|
|
35
|
+
"preprebuild": "run-s clean configure",
|
|
36
|
+
"prebuild": "prebuildify --napi --tag-libc --strip",
|
|
37
|
+
"tsc": "run-p tsc:*",
|
|
38
|
+
"tsc:esm": "tsc -p tsconfig.esm.json",
|
|
39
|
+
"tsc:cjs": "tsc -p tsconfig.cjs.json",
|
|
40
|
+
"tsc:tests": "tsc -p tsconfig.json",
|
|
41
|
+
"watch": "tsc --watch",
|
|
42
|
+
"docs": "typedoc --out docs src/index.ts",
|
|
43
|
+
"jest:coverage": "jest --coverage",
|
|
44
|
+
"jest:watch": "npm t -- --watch",
|
|
45
|
+
"jest:clear": "jest --clearCache",
|
|
46
|
+
"// tests": "is called by .github/workflows/test.yml",
|
|
47
|
+
"tests": "run-s test test:memory",
|
|
48
|
+
"test": "node --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js",
|
|
49
|
+
"// test:memory:todo": "set up valgrind or similar",
|
|
50
|
+
"test:memory": "cross-env TEST_MEMORY=1 node --expose-gc --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js src/__tests__/memory.test.ts",
|
|
51
|
+
"lint": "eslint",
|
|
52
|
+
"lint:fix": "eslint --fix",
|
|
53
|
+
"fmt": "run-p fmt:*",
|
|
54
|
+
"// fmt:cpp": "on ubuntu: `sudo apt install clang-format`",
|
|
55
|
+
"fmt:cpp": "clang-format --style=LLVM -i src/*/*.cpp src/*/*.h || true",
|
|
56
|
+
"fmt:js": "prettier --write \"scripts/**/*.?js\" \"*.?js\"",
|
|
57
|
+
"fmt:json": "prettier --write \"**/*.json\"",
|
|
58
|
+
"fmt:pkg": "npm pkg fix",
|
|
59
|
+
"fmt:ts": "prettier --write \"src/**/*.ts\"",
|
|
60
|
+
"// precommit": "is called manually before committing",
|
|
61
|
+
"precommit": "run-s clean fmt lint prebuild tsc tests",
|
|
62
|
+
"// release": "is called by .github/workflows/release.yml and should only be run via GitHub Actions",
|
|
63
|
+
"prerelease": "tsc",
|
|
64
|
+
"release": "release-it"
|
|
65
|
+
},
|
|
66
|
+
"gypfile": true,
|
|
67
|
+
"publishConfig": {
|
|
68
|
+
"access": "public"
|
|
69
|
+
},
|
|
70
|
+
"engines": {
|
|
71
|
+
"node": ">=18.0.0"
|
|
72
|
+
},
|
|
73
|
+
"os": [
|
|
74
|
+
"darwin",
|
|
75
|
+
"linux",
|
|
76
|
+
"win32"
|
|
77
|
+
],
|
|
78
|
+
"cpu": [
|
|
79
|
+
"x64",
|
|
80
|
+
"arm64"
|
|
81
|
+
],
|
|
82
|
+
"keywords": [
|
|
83
|
+
"filesystem",
|
|
84
|
+
"metadata",
|
|
85
|
+
"native",
|
|
86
|
+
"node-addon",
|
|
87
|
+
"windows",
|
|
88
|
+
"linux",
|
|
89
|
+
"macos",
|
|
90
|
+
"cross-platform"
|
|
91
|
+
],
|
|
92
|
+
"dependencies": {
|
|
93
|
+
"node-addon-api": "^8.2.2",
|
|
94
|
+
"node-gyp-build": "^4.8.4"
|
|
95
|
+
},
|
|
96
|
+
"devDependencies": {
|
|
97
|
+
"@eslint/js": "^9.15.0",
|
|
98
|
+
"@types/jest": "^29.5.14",
|
|
99
|
+
"@types/node": "^22.9.1",
|
|
100
|
+
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
|
101
|
+
"@typescript-eslint/parser": "^8.15.0",
|
|
102
|
+
"cross-env": "^7.0.3",
|
|
103
|
+
"eslint": "^9.15.0",
|
|
104
|
+
"globals": "^15.12.0",
|
|
105
|
+
"jest": "^29.7.0",
|
|
106
|
+
"jest-environment-node": "^29.7.0",
|
|
107
|
+
"jest-extended": "^4.0.2",
|
|
108
|
+
"node-gyp": "^10.2.0",
|
|
109
|
+
"npm-run-all": "4.1.5",
|
|
110
|
+
"prebuildify": "^6.0.1",
|
|
111
|
+
"prettier": "^3.3.3",
|
|
112
|
+
"prettier-plugin-organize-imports": "4.1.0",
|
|
113
|
+
"release-it": "^17.10.0",
|
|
114
|
+
"rimraf": "^5.0.9",
|
|
115
|
+
"terser": "^5.36.0",
|
|
116
|
+
"ts-jest": "^29.2.5",
|
|
117
|
+
"typedoc": "^0.26.11",
|
|
118
|
+
"typescript": "^5.6.3",
|
|
119
|
+
"typescript-eslint": "^8.15.0"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// scripts/configure.mjs
|
|
4
|
+
|
|
5
|
+
import { execSync } from "node:child_process";
|
|
6
|
+
import { writeFileSync } from "node:fs";
|
|
7
|
+
import { platform } from "node:os";
|
|
8
|
+
import { argv } from "node:process";
|
|
9
|
+
import { pathToFileURL } from "node:url";
|
|
10
|
+
|
|
11
|
+
function hasGio() {
|
|
12
|
+
if (platform() !== "linux") return false;
|
|
13
|
+
try {
|
|
14
|
+
execSync("pkg-config --exists gio-2.0", { stdio: "ignore" });
|
|
15
|
+
return true;
|
|
16
|
+
} catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function configure() {
|
|
22
|
+
// Create a gyp config file that node-gyp will read
|
|
23
|
+
const config = {
|
|
24
|
+
variables: {
|
|
25
|
+
"enable_gio%": hasGio() ? "true" : "false",
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const payload = JSON.stringify(config, null, 2);
|
|
30
|
+
writeFileSync("config.gypi", payload);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// If the script is run directly, call the configure function
|
|
34
|
+
if (import.meta.url === pathToFileURL(argv[1]).href) {
|
|
35
|
+
configure();
|
|
36
|
+
}
|
package/src/binding.cpp
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// src/binding.cpp
|
|
2
|
+
|
|
3
|
+
#include <napi.h>
|
|
4
|
+
#include <string>
|
|
5
|
+
|
|
6
|
+
#if defined(_WIN32)
|
|
7
|
+
#include "windows/fs_meta.h"
|
|
8
|
+
#elif defined(__APPLE__)
|
|
9
|
+
#include "darwin/fs_meta.h"
|
|
10
|
+
#elif defined(__linux__)
|
|
11
|
+
#include "common/volume_metadata.h"
|
|
12
|
+
#ifdef ENABLE_GIO
|
|
13
|
+
#include "linux/gio_utils.h"
|
|
14
|
+
#endif
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
namespace {
|
|
18
|
+
|
|
19
|
+
Napi::Value GetVolumeMetadata(const Napi::CallbackInfo& info) {
|
|
20
|
+
Napi::Env env = info.Env();
|
|
21
|
+
|
|
22
|
+
if (info.Length() < 1 || !info[0].IsString()) {
|
|
23
|
+
throw Napi::TypeError::New(env, "String expected for mountPoint");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
std::string mountPoint = info[0].As<Napi::String>();
|
|
27
|
+
Napi::Object options = info.Length() > 1 && info[1].IsObject()
|
|
28
|
+
? info[1].As<Napi::Object>()
|
|
29
|
+
: Napi::Object::New(env);
|
|
30
|
+
|
|
31
|
+
return FSMeta::GetVolumeMetadata(env, mountPoint, options);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#ifdef ENABLE_GIO
|
|
35
|
+
Napi::Value GetGioMountPoints(const Napi::CallbackInfo& info) {
|
|
36
|
+
Napi::Env env = info.Env();
|
|
37
|
+
return FSMeta::gio::GetMountPoints(env);
|
|
38
|
+
}
|
|
39
|
+
#endif
|
|
40
|
+
|
|
41
|
+
#if defined(_WIN32) || defined(__APPLE__)
|
|
42
|
+
Napi::Value GetVolumeMountPoints(const Napi::CallbackInfo& info) {
|
|
43
|
+
Napi::Env env = info.Env();
|
|
44
|
+
return FSMeta::GetVolumeMountPoints(env);
|
|
45
|
+
}
|
|
46
|
+
#endif
|
|
47
|
+
|
|
48
|
+
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
|
49
|
+
|
|
50
|
+
#if defined(_WIN32) || defined(__APPLE__)
|
|
51
|
+
exports.Set("getVolumeMountPoints",
|
|
52
|
+
Napi::Function::New(env, GetVolumeMountPoints));
|
|
53
|
+
#endif
|
|
54
|
+
|
|
55
|
+
exports.Set("getVolumeMetadata",
|
|
56
|
+
Napi::Function::New(env, GetVolumeMetadata));
|
|
57
|
+
|
|
58
|
+
#ifdef ENABLE_GIO
|
|
59
|
+
exports.Set("getGioMountPoints",
|
|
60
|
+
Napi::Function::New(env, GetGioMountPoints));
|
|
61
|
+
#endif
|
|
62
|
+
|
|
63
|
+
return exports;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
NODE_API_MODULE(node_fs_meta, Init)
|
|
67
|
+
|
|
68
|
+
} // namespace
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/common/error_utils.h
|
|
2
|
+
#pragma once
|
|
3
|
+
#include <stdexcept>
|
|
4
|
+
#include <string>
|
|
5
|
+
|
|
6
|
+
namespace FSMeta {
|
|
7
|
+
|
|
8
|
+
class FSException : public std::runtime_error {
|
|
9
|
+
public:
|
|
10
|
+
explicit FSException(const std::string &message)
|
|
11
|
+
: std::runtime_error(message) {}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
inline std::string CreateErrorMessage(const char *operation, int error) {
|
|
15
|
+
return std::string(operation) +
|
|
16
|
+
" failed with error: " + std::to_string(error);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
} // namespace FSMeta
|