@photostructure/fs-metadata 1.0.1 → 1.1.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 +38 -0
- package/CLAUDE.md +13 -0
- package/claude.sh +29 -5
- package/dist/index.cjs +86 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -3
- package/dist/index.d.mts +39 -3
- package/dist/index.d.ts +39 -3
- package/dist/index.mjs +86 -27
- package/dist/index.mjs.map +1 -1
- package/doc/SECURITY_AUDIT_2025.md +1 -1
- package/doc/SECURITY_AUDIT_2026.md +361 -0
- package/doc/TPP-GUIDE.md +144 -0
- package/doc/system-volume-detection.md +268 -0
- package/package.json +11 -11
- 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/src/common/volume_metadata.h +10 -3
- package/src/common/volume_mount_points.h +7 -1
- package/src/darwin/da_mutex.h +23 -0
- package/src/darwin/raii_utils.h +39 -0
- package/src/darwin/system_volume.h +156 -0
- package/src/darwin/volume_metadata.cpp +18 -2
- package/src/darwin/volume_mount_points.cpp +46 -14
- package/src/index.ts +22 -0
- package/src/linux/mtab.ts +6 -0
- package/src/options.ts +7 -17
- package/src/path.ts +16 -1
- package/src/system_volume.ts +5 -9
- package/src/test-utils/assert.ts +4 -0
- package/src/types/mount_point.ts +28 -1
- package/src/volume_metadata.ts +97 -2
- package/src/windows/system_volume.h +21 -16
- package/src/windows/volume_metadata.cpp +13 -7
- package/src/windows/volume_mount_points.cpp +11 -7
package/dist/index.d.cts
CHANGED
|
@@ -88,11 +88,36 @@ interface MountPoint {
|
|
|
88
88
|
* Indicates if this volume is primarily for system use (e.g., swap, snap
|
|
89
89
|
* loopbacks, EFI boot, or only system directories).
|
|
90
90
|
*
|
|
91
|
-
*
|
|
91
|
+
* On macOS, the sealed APFS system snapshot at `/` is detected natively via
|
|
92
|
+
* `MNT_SNAPSHOT`; other infrastructure volumes under `/System/Volumes/*` are
|
|
93
|
+
* detected via APFS volume roles (IOKit). Note that `/System/Volumes/Data`
|
|
94
|
+
* is **not** a system volume — it holds all user data, accessed via firmlinks.
|
|
92
95
|
*
|
|
93
96
|
* @see {@link Options.systemPathPatterns} and {@link Options.systemFsTypes}
|
|
94
97
|
*/
|
|
95
98
|
isSystemVolume?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* The APFS volume role, if available. Only present on macOS for APFS volumes.
|
|
101
|
+
*
|
|
102
|
+
* Common roles: `"System"`, `"Data"`, `"VM"`, `"Preboot"`, `"Recovery"`,
|
|
103
|
+
* `"Update"`, `"Hardware"`, `"xART"`, `"Prelogin"`, `"Backup"`.
|
|
104
|
+
*
|
|
105
|
+
* Used for system volume detection: volumes with a non-`"Data"` role and
|
|
106
|
+
* `MNT_DONTBROWSE` are classified as system volumes.
|
|
107
|
+
*
|
|
108
|
+
* @see https://eclecticlight.co/2024/11/21/how-do-apfs-volume-roles-work/
|
|
109
|
+
*/
|
|
110
|
+
volumeRole?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Whether the volume is mounted read-only.
|
|
113
|
+
*
|
|
114
|
+
* Examples of read-only volumes include the macOS APFS system snapshot at
|
|
115
|
+
* `/`, mounted ISO images, and write-protected media.
|
|
116
|
+
*
|
|
117
|
+
* Note that the macOS root volume (`/`) UUID changes on every OS update, so
|
|
118
|
+
* consumers should avoid using it for persistent identification.
|
|
119
|
+
*/
|
|
120
|
+
isReadOnly?: boolean;
|
|
96
121
|
/**
|
|
97
122
|
* If there are non-critical errors while extracting metadata, those errors
|
|
98
123
|
* may be added to this field.
|
|
@@ -262,7 +287,7 @@ declare function getTimeoutMsDefault(): number;
|
|
|
262
287
|
/**
|
|
263
288
|
* System paths and globs that indicate system volumes
|
|
264
289
|
*/
|
|
265
|
-
declare const SystemPathPatternsDefault: readonly ["/boot", "/boot/efi", "/dev", "/dev/**", "/proc/**", "/run", "/run/credentials/**", "/run/flatpak/**", "/run/lock", "/run/snapd/**", "/run/user/*/doc", "/run/user/*/gvfs", "/snap/**", "/sys/**", "/tmp", "/var/tmp", "**/#snapshot", "/run/docker/**", "/var/lib/docker/**", "/run/containerd/**", "/var/lib/containerd/**", "/run/containers/**", "/var/lib/containers/**", "/var/lib/kubelet/**", "/var/lib/lxc/**", "/var/lib/lxd/**", "/mnt/wslg/distro", "/mnt/wslg/doc", "/mnt/wslg/versions.txt", "/usr/lib/wsl/drivers", "/private/var/vm"
|
|
290
|
+
declare const SystemPathPatternsDefault: readonly ["/boot", "/boot/efi", "/dev", "/dev/**", "/proc/**", "/run", "/run/credentials/**", "/run/flatpak/**", "/run/lock", "/run/snapd/**", "/run/user/*/doc", "/run/user/*/gvfs", "/snap/**", "/sys/**", "/tmp", "/var/tmp", "**/#snapshot", "/run/docker/**", "/var/lib/docker/**", "/run/containerd/**", "/var/lib/containerd/**", "/run/containers/**", "/var/lib/containers/**", "/var/lib/kubelet/**", "/var/lib/lxc/**", "/var/lib/lxd/**", "/mnt/wslg/distro", "/mnt/wslg/doc", "/mnt/wslg/versions.txt", "/usr/lib/wsl/drivers", "/private/var/vm"];
|
|
266
291
|
/**
|
|
267
292
|
* Filesystem types that indicate system/virtual volumes.
|
|
268
293
|
*
|
|
@@ -332,6 +357,17 @@ declare function getVolumeMountPoints(opts?: Partial<GetVolumeMountPointOptions>
|
|
|
332
357
|
* @param opts Optional filesystem operation settings
|
|
333
358
|
*/
|
|
334
359
|
declare function getVolumeMetadata(mountPoint: string, opts?: Partial<Pick<Options, "timeoutMs">>): Promise<VolumeMetadata>;
|
|
360
|
+
/**
|
|
361
|
+
* Get metadata for the volume that contains the given file or directory path.
|
|
362
|
+
*
|
|
363
|
+
* Unlike {@link getVolumeMetadata}, this accepts any path — not just mount
|
|
364
|
+
* points. Symlinks are resolved, and macOS APFS firmlinks (e.g. `/Users` →
|
|
365
|
+
* `/System/Volumes/Data`) are handled correctly, mirroring what `df` does.
|
|
366
|
+
*
|
|
367
|
+
* @param pathname Path to any file or directory
|
|
368
|
+
* @param opts Optional filesystem operation settings
|
|
369
|
+
*/
|
|
370
|
+
declare function getVolumeMetadataForPath(pathname: string, opts?: Partial<Pick<Options, "timeoutMs" | "linuxMountTablePaths">>): Promise<VolumeMetadata>;
|
|
335
371
|
/**
|
|
336
372
|
* Retrieves metadata for all mounted volumes with optional filtering and
|
|
337
373
|
* concurrency control.
|
|
@@ -393,4 +429,4 @@ declare function getHiddenMetadata(pathname: string): Promise<HiddenMetadata>;
|
|
|
393
429
|
*/
|
|
394
430
|
declare function setHidden(pathname: string, hidden: boolean, method?: HideMethod): Promise<SetHiddenResult>;
|
|
395
431
|
|
|
396
|
-
export { type GetVolumeMountPointOptions, type HiddenMetadata, type HideMethod, IncludeSystemVolumesDefault, LinuxMountTablePathsDefault, type MountPoint, NetworkFsTypesDefault, type Options, OptionsDefault, type SetHiddenResult, SkipNetworkVolumesDefault, type StringEnum, type StringEnumKeys, type StringEnumType, SystemFsTypesDefault, SystemPathPatternsDefault, type SystemVolumeConfig, type VolumeHealthStatus, VolumeHealthStatuses, type VolumeMetadata, getAllVolumeMetadata, getHiddenMetadata, getTimeoutMsDefault, getVolumeMetadata, getVolumeMountPoints, isHidden, isHiddenRecursive, optionsWithDefaults, setHidden };
|
|
432
|
+
export { type GetVolumeMountPointOptions, type HiddenMetadata, type HideMethod, IncludeSystemVolumesDefault, LinuxMountTablePathsDefault, type MountPoint, NetworkFsTypesDefault, type Options, OptionsDefault, type SetHiddenResult, SkipNetworkVolumesDefault, type StringEnum, type StringEnumKeys, type StringEnumType, SystemFsTypesDefault, SystemPathPatternsDefault, type SystemVolumeConfig, type VolumeHealthStatus, VolumeHealthStatuses, type VolumeMetadata, getAllVolumeMetadata, getHiddenMetadata, getTimeoutMsDefault, getVolumeMetadata, getVolumeMetadataForPath, getVolumeMountPoints, isHidden, isHiddenRecursive, optionsWithDefaults, setHidden };
|
package/dist/index.d.mts
CHANGED
|
@@ -88,11 +88,36 @@ interface MountPoint {
|
|
|
88
88
|
* Indicates if this volume is primarily for system use (e.g., swap, snap
|
|
89
89
|
* loopbacks, EFI boot, or only system directories).
|
|
90
90
|
*
|
|
91
|
-
*
|
|
91
|
+
* On macOS, the sealed APFS system snapshot at `/` is detected natively via
|
|
92
|
+
* `MNT_SNAPSHOT`; other infrastructure volumes under `/System/Volumes/*` are
|
|
93
|
+
* detected via APFS volume roles (IOKit). Note that `/System/Volumes/Data`
|
|
94
|
+
* is **not** a system volume — it holds all user data, accessed via firmlinks.
|
|
92
95
|
*
|
|
93
96
|
* @see {@link Options.systemPathPatterns} and {@link Options.systemFsTypes}
|
|
94
97
|
*/
|
|
95
98
|
isSystemVolume?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* The APFS volume role, if available. Only present on macOS for APFS volumes.
|
|
101
|
+
*
|
|
102
|
+
* Common roles: `"System"`, `"Data"`, `"VM"`, `"Preboot"`, `"Recovery"`,
|
|
103
|
+
* `"Update"`, `"Hardware"`, `"xART"`, `"Prelogin"`, `"Backup"`.
|
|
104
|
+
*
|
|
105
|
+
* Used for system volume detection: volumes with a non-`"Data"` role and
|
|
106
|
+
* `MNT_DONTBROWSE` are classified as system volumes.
|
|
107
|
+
*
|
|
108
|
+
* @see https://eclecticlight.co/2024/11/21/how-do-apfs-volume-roles-work/
|
|
109
|
+
*/
|
|
110
|
+
volumeRole?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Whether the volume is mounted read-only.
|
|
113
|
+
*
|
|
114
|
+
* Examples of read-only volumes include the macOS APFS system snapshot at
|
|
115
|
+
* `/`, mounted ISO images, and write-protected media.
|
|
116
|
+
*
|
|
117
|
+
* Note that the macOS root volume (`/`) UUID changes on every OS update, so
|
|
118
|
+
* consumers should avoid using it for persistent identification.
|
|
119
|
+
*/
|
|
120
|
+
isReadOnly?: boolean;
|
|
96
121
|
/**
|
|
97
122
|
* If there are non-critical errors while extracting metadata, those errors
|
|
98
123
|
* may be added to this field.
|
|
@@ -262,7 +287,7 @@ declare function getTimeoutMsDefault(): number;
|
|
|
262
287
|
/**
|
|
263
288
|
* System paths and globs that indicate system volumes
|
|
264
289
|
*/
|
|
265
|
-
declare const SystemPathPatternsDefault: readonly ["/boot", "/boot/efi", "/dev", "/dev/**", "/proc/**", "/run", "/run/credentials/**", "/run/flatpak/**", "/run/lock", "/run/snapd/**", "/run/user/*/doc", "/run/user/*/gvfs", "/snap/**", "/sys/**", "/tmp", "/var/tmp", "**/#snapshot", "/run/docker/**", "/var/lib/docker/**", "/run/containerd/**", "/var/lib/containerd/**", "/run/containers/**", "/var/lib/containers/**", "/var/lib/kubelet/**", "/var/lib/lxc/**", "/var/lib/lxd/**", "/mnt/wslg/distro", "/mnt/wslg/doc", "/mnt/wslg/versions.txt", "/usr/lib/wsl/drivers", "/private/var/vm"
|
|
290
|
+
declare const SystemPathPatternsDefault: readonly ["/boot", "/boot/efi", "/dev", "/dev/**", "/proc/**", "/run", "/run/credentials/**", "/run/flatpak/**", "/run/lock", "/run/snapd/**", "/run/user/*/doc", "/run/user/*/gvfs", "/snap/**", "/sys/**", "/tmp", "/var/tmp", "**/#snapshot", "/run/docker/**", "/var/lib/docker/**", "/run/containerd/**", "/var/lib/containerd/**", "/run/containers/**", "/var/lib/containers/**", "/var/lib/kubelet/**", "/var/lib/lxc/**", "/var/lib/lxd/**", "/mnt/wslg/distro", "/mnt/wslg/doc", "/mnt/wslg/versions.txt", "/usr/lib/wsl/drivers", "/private/var/vm"];
|
|
266
291
|
/**
|
|
267
292
|
* Filesystem types that indicate system/virtual volumes.
|
|
268
293
|
*
|
|
@@ -332,6 +357,17 @@ declare function getVolumeMountPoints(opts?: Partial<GetVolumeMountPointOptions>
|
|
|
332
357
|
* @param opts Optional filesystem operation settings
|
|
333
358
|
*/
|
|
334
359
|
declare function getVolumeMetadata(mountPoint: string, opts?: Partial<Pick<Options, "timeoutMs">>): Promise<VolumeMetadata>;
|
|
360
|
+
/**
|
|
361
|
+
* Get metadata for the volume that contains the given file or directory path.
|
|
362
|
+
*
|
|
363
|
+
* Unlike {@link getVolumeMetadata}, this accepts any path — not just mount
|
|
364
|
+
* points. Symlinks are resolved, and macOS APFS firmlinks (e.g. `/Users` →
|
|
365
|
+
* `/System/Volumes/Data`) are handled correctly, mirroring what `df` does.
|
|
366
|
+
*
|
|
367
|
+
* @param pathname Path to any file or directory
|
|
368
|
+
* @param opts Optional filesystem operation settings
|
|
369
|
+
*/
|
|
370
|
+
declare function getVolumeMetadataForPath(pathname: string, opts?: Partial<Pick<Options, "timeoutMs" | "linuxMountTablePaths">>): Promise<VolumeMetadata>;
|
|
335
371
|
/**
|
|
336
372
|
* Retrieves metadata for all mounted volumes with optional filtering and
|
|
337
373
|
* concurrency control.
|
|
@@ -393,4 +429,4 @@ declare function getHiddenMetadata(pathname: string): Promise<HiddenMetadata>;
|
|
|
393
429
|
*/
|
|
394
430
|
declare function setHidden(pathname: string, hidden: boolean, method?: HideMethod): Promise<SetHiddenResult>;
|
|
395
431
|
|
|
396
|
-
export { type GetVolumeMountPointOptions, type HiddenMetadata, type HideMethod, IncludeSystemVolumesDefault, LinuxMountTablePathsDefault, type MountPoint, NetworkFsTypesDefault, type Options, OptionsDefault, type SetHiddenResult, SkipNetworkVolumesDefault, type StringEnum, type StringEnumKeys, type StringEnumType, SystemFsTypesDefault, SystemPathPatternsDefault, type SystemVolumeConfig, type VolumeHealthStatus, VolumeHealthStatuses, type VolumeMetadata, getAllVolumeMetadata, getHiddenMetadata, getTimeoutMsDefault, getVolumeMetadata, getVolumeMountPoints, isHidden, isHiddenRecursive, optionsWithDefaults, setHidden };
|
|
432
|
+
export { type GetVolumeMountPointOptions, type HiddenMetadata, type HideMethod, IncludeSystemVolumesDefault, LinuxMountTablePathsDefault, type MountPoint, NetworkFsTypesDefault, type Options, OptionsDefault, type SetHiddenResult, SkipNetworkVolumesDefault, type StringEnum, type StringEnumKeys, type StringEnumType, SystemFsTypesDefault, SystemPathPatternsDefault, type SystemVolumeConfig, type VolumeHealthStatus, VolumeHealthStatuses, type VolumeMetadata, getAllVolumeMetadata, getHiddenMetadata, getTimeoutMsDefault, getVolumeMetadata, getVolumeMetadataForPath, getVolumeMountPoints, isHidden, isHiddenRecursive, optionsWithDefaults, setHidden };
|
package/dist/index.d.ts
CHANGED
|
@@ -88,11 +88,36 @@ interface MountPoint {
|
|
|
88
88
|
* Indicates if this volume is primarily for system use (e.g., swap, snap
|
|
89
89
|
* loopbacks, EFI boot, or only system directories).
|
|
90
90
|
*
|
|
91
|
-
*
|
|
91
|
+
* On macOS, the sealed APFS system snapshot at `/` is detected natively via
|
|
92
|
+
* `MNT_SNAPSHOT`; other infrastructure volumes under `/System/Volumes/*` are
|
|
93
|
+
* detected via APFS volume roles (IOKit). Note that `/System/Volumes/Data`
|
|
94
|
+
* is **not** a system volume — it holds all user data, accessed via firmlinks.
|
|
92
95
|
*
|
|
93
96
|
* @see {@link Options.systemPathPatterns} and {@link Options.systemFsTypes}
|
|
94
97
|
*/
|
|
95
98
|
isSystemVolume?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* The APFS volume role, if available. Only present on macOS for APFS volumes.
|
|
101
|
+
*
|
|
102
|
+
* Common roles: `"System"`, `"Data"`, `"VM"`, `"Preboot"`, `"Recovery"`,
|
|
103
|
+
* `"Update"`, `"Hardware"`, `"xART"`, `"Prelogin"`, `"Backup"`.
|
|
104
|
+
*
|
|
105
|
+
* Used for system volume detection: volumes with a non-`"Data"` role and
|
|
106
|
+
* `MNT_DONTBROWSE` are classified as system volumes.
|
|
107
|
+
*
|
|
108
|
+
* @see https://eclecticlight.co/2024/11/21/how-do-apfs-volume-roles-work/
|
|
109
|
+
*/
|
|
110
|
+
volumeRole?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Whether the volume is mounted read-only.
|
|
113
|
+
*
|
|
114
|
+
* Examples of read-only volumes include the macOS APFS system snapshot at
|
|
115
|
+
* `/`, mounted ISO images, and write-protected media.
|
|
116
|
+
*
|
|
117
|
+
* Note that the macOS root volume (`/`) UUID changes on every OS update, so
|
|
118
|
+
* consumers should avoid using it for persistent identification.
|
|
119
|
+
*/
|
|
120
|
+
isReadOnly?: boolean;
|
|
96
121
|
/**
|
|
97
122
|
* If there are non-critical errors while extracting metadata, those errors
|
|
98
123
|
* may be added to this field.
|
|
@@ -262,7 +287,7 @@ declare function getTimeoutMsDefault(): number;
|
|
|
262
287
|
/**
|
|
263
288
|
* System paths and globs that indicate system volumes
|
|
264
289
|
*/
|
|
265
|
-
declare const SystemPathPatternsDefault: readonly ["/boot", "/boot/efi", "/dev", "/dev/**", "/proc/**", "/run", "/run/credentials/**", "/run/flatpak/**", "/run/lock", "/run/snapd/**", "/run/user/*/doc", "/run/user/*/gvfs", "/snap/**", "/sys/**", "/tmp", "/var/tmp", "**/#snapshot", "/run/docker/**", "/var/lib/docker/**", "/run/containerd/**", "/var/lib/containerd/**", "/run/containers/**", "/var/lib/containers/**", "/var/lib/kubelet/**", "/var/lib/lxc/**", "/var/lib/lxd/**", "/mnt/wslg/distro", "/mnt/wslg/doc", "/mnt/wslg/versions.txt", "/usr/lib/wsl/drivers", "/private/var/vm"
|
|
290
|
+
declare const SystemPathPatternsDefault: readonly ["/boot", "/boot/efi", "/dev", "/dev/**", "/proc/**", "/run", "/run/credentials/**", "/run/flatpak/**", "/run/lock", "/run/snapd/**", "/run/user/*/doc", "/run/user/*/gvfs", "/snap/**", "/sys/**", "/tmp", "/var/tmp", "**/#snapshot", "/run/docker/**", "/var/lib/docker/**", "/run/containerd/**", "/var/lib/containerd/**", "/run/containers/**", "/var/lib/containers/**", "/var/lib/kubelet/**", "/var/lib/lxc/**", "/var/lib/lxd/**", "/mnt/wslg/distro", "/mnt/wslg/doc", "/mnt/wslg/versions.txt", "/usr/lib/wsl/drivers", "/private/var/vm"];
|
|
266
291
|
/**
|
|
267
292
|
* Filesystem types that indicate system/virtual volumes.
|
|
268
293
|
*
|
|
@@ -332,6 +357,17 @@ declare function getVolumeMountPoints(opts?: Partial<GetVolumeMountPointOptions>
|
|
|
332
357
|
* @param opts Optional filesystem operation settings
|
|
333
358
|
*/
|
|
334
359
|
declare function getVolumeMetadata(mountPoint: string, opts?: Partial<Pick<Options, "timeoutMs">>): Promise<VolumeMetadata>;
|
|
360
|
+
/**
|
|
361
|
+
* Get metadata for the volume that contains the given file or directory path.
|
|
362
|
+
*
|
|
363
|
+
* Unlike {@link getVolumeMetadata}, this accepts any path — not just mount
|
|
364
|
+
* points. Symlinks are resolved, and macOS APFS firmlinks (e.g. `/Users` →
|
|
365
|
+
* `/System/Volumes/Data`) are handled correctly, mirroring what `df` does.
|
|
366
|
+
*
|
|
367
|
+
* @param pathname Path to any file or directory
|
|
368
|
+
* @param opts Optional filesystem operation settings
|
|
369
|
+
*/
|
|
370
|
+
declare function getVolumeMetadataForPath(pathname: string, opts?: Partial<Pick<Options, "timeoutMs" | "linuxMountTablePaths">>): Promise<VolumeMetadata>;
|
|
335
371
|
/**
|
|
336
372
|
* Retrieves metadata for all mounted volumes with optional filtering and
|
|
337
373
|
* concurrency control.
|
|
@@ -393,4 +429,4 @@ declare function getHiddenMetadata(pathname: string): Promise<HiddenMetadata>;
|
|
|
393
429
|
*/
|
|
394
430
|
declare function setHidden(pathname: string, hidden: boolean, method?: HideMethod): Promise<SetHiddenResult>;
|
|
395
431
|
|
|
396
|
-
export { type GetVolumeMountPointOptions, type HiddenMetadata, type HideMethod, IncludeSystemVolumesDefault, LinuxMountTablePathsDefault, type MountPoint, NetworkFsTypesDefault, type Options, OptionsDefault, type SetHiddenResult, SkipNetworkVolumesDefault, type StringEnum, type StringEnumKeys, type StringEnumType, SystemFsTypesDefault, SystemPathPatternsDefault, type SystemVolumeConfig, type VolumeHealthStatus, VolumeHealthStatuses, type VolumeMetadata, getAllVolumeMetadata, getHiddenMetadata, getTimeoutMsDefault, getVolumeMetadata, getVolumeMountPoints, isHidden, isHiddenRecursive, optionsWithDefaults, setHidden };
|
|
432
|
+
export { type GetVolumeMountPointOptions, type HiddenMetadata, type HideMethod, IncludeSystemVolumesDefault, LinuxMountTablePathsDefault, type MountPoint, NetworkFsTypesDefault, type Options, OptionsDefault, type SetHiddenResult, SkipNetworkVolumesDefault, type StringEnum, type StringEnumKeys, type StringEnumType, SystemFsTypesDefault, SystemPathPatternsDefault, type SystemVolumeConfig, type VolumeHealthStatus, VolumeHealthStatuses, type VolumeMetadata, getAllVolumeMetadata, getHiddenMetadata, getTimeoutMsDefault, getVolumeMetadata, getVolumeMetadataForPath, getVolumeMountPoints, isHidden, isHiddenRecursive, optionsWithDefaults, setHidden };
|
package/dist/index.mjs
CHANGED
|
@@ -388,7 +388,7 @@ function toError(cause) {
|
|
|
388
388
|
}
|
|
389
389
|
|
|
390
390
|
// src/path.ts
|
|
391
|
-
import { dirname as dirname2, resolve as resolve2 } from "path";
|
|
391
|
+
import { dirname as dirname2, resolve as resolve2, sep } from "path";
|
|
392
392
|
function normalizePath(mountPoint) {
|
|
393
393
|
if (isBlank(mountPoint)) return void 0;
|
|
394
394
|
if (mountPoint.includes("..")) {
|
|
@@ -417,6 +417,11 @@ function isRootDirectory(path2) {
|
|
|
417
417
|
const n = normalizePath(path2);
|
|
418
418
|
return n == null ? false : isWindows ? dirname2(n) === n : n === "/";
|
|
419
419
|
}
|
|
420
|
+
function isAncestorOrSelf(ancestor, descendant) {
|
|
421
|
+
if (ancestor === descendant) return true;
|
|
422
|
+
const prefix = isRootDirectory(ancestor) ? ancestor : ancestor + sep;
|
|
423
|
+
return descendant.startsWith(prefix);
|
|
424
|
+
}
|
|
420
425
|
|
|
421
426
|
// src/hidden.ts
|
|
422
427
|
var HiddenSupportByPlatform = {
|
|
@@ -643,23 +648,13 @@ var SystemPathPatternsDefault = [
|
|
|
643
648
|
"/mnt/wslg/doc",
|
|
644
649
|
"/mnt/wslg/versions.txt",
|
|
645
650
|
"/usr/lib/wsl/drivers",
|
|
646
|
-
// macOS system
|
|
647
|
-
"
|
|
648
|
-
//
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
"/
|
|
653
|
-
"/System/Volumes/Reserved",
|
|
654
|
-
"/System/Volumes/Update",
|
|
655
|
-
"/System/Volumes/VM",
|
|
656
|
-
"/System/Volumes/xarts",
|
|
657
|
-
// macOS per-volume metadata (Spotlight, FSEvents, versioning, Trash):
|
|
658
|
-
// https://eclecticlight.co/2021/01/28/spotlight-on-search-how-spotlight-works/
|
|
659
|
-
"**/.DocumentRevisions-V100",
|
|
660
|
-
"**/.fseventsd",
|
|
661
|
-
"**/.Spotlight-V100",
|
|
662
|
-
"**/.Trashes"
|
|
651
|
+
// macOS system volumes are detected natively via APFS volume roles
|
|
652
|
+
// (IOKit IOMedia "Role" property) with MNT_SNAPSHOT as a fallback.
|
|
653
|
+
// No path patterns needed. See src/darwin/system_volume.h.
|
|
654
|
+
//
|
|
655
|
+
// /private/var/vm is the macOS swap directory (not a mount point on most
|
|
656
|
+
// systems, but included for completeness if it appears as one).
|
|
657
|
+
"/private/var/vm"
|
|
663
658
|
];
|
|
664
659
|
var SystemFsTypesDefault = [
|
|
665
660
|
"autofs",
|
|
@@ -834,6 +829,10 @@ async function directoryStatus(dir, timeoutMs, canReaddirImpl = canReaddir) {
|
|
|
834
829
|
return { status: VolumeHealthStatuses.unknown };
|
|
835
830
|
}
|
|
836
831
|
|
|
832
|
+
// src/volume_metadata.ts
|
|
833
|
+
import { realpath } from "fs/promises";
|
|
834
|
+
import { dirname as dirname4 } from "path";
|
|
835
|
+
|
|
837
836
|
// src/linux/dev_disk.ts
|
|
838
837
|
import { readdir, readlink } from "fs/promises";
|
|
839
838
|
import { join as join3, resolve as resolve3 } from "path";
|
|
@@ -1118,20 +1117,20 @@ function isSystemVolume(mountPoint, fstype, config = {}) {
|
|
|
1118
1117
|
}
|
|
1119
1118
|
function assignSystemVolume(mp, config) {
|
|
1120
1119
|
const result = isSystemVolume(mp.mountPoint, mp.fstype, config);
|
|
1121
|
-
|
|
1122
|
-
mp.isSystemVolume ??= result;
|
|
1123
|
-
} else {
|
|
1124
|
-
mp.isSystemVolume = result;
|
|
1125
|
-
}
|
|
1120
|
+
mp.isSystemVolume = mp.isSystemVolume || result;
|
|
1126
1121
|
}
|
|
1127
1122
|
|
|
1128
1123
|
// src/linux/mtab.ts
|
|
1124
|
+
function isReadOnlyMount(fs_mntops) {
|
|
1125
|
+
return fs_mntops?.split(",").includes("ro") ?? false;
|
|
1126
|
+
}
|
|
1129
1127
|
function mountEntryToMountPoint(entry) {
|
|
1130
1128
|
const mountPoint = normalizePosixPath(entry.fs_file);
|
|
1131
1129
|
const fstype = toNotBlank(entry.fs_vfstype) ?? toNotBlank(entry.fs_spec);
|
|
1132
1130
|
return mountPoint == null || fstype == null ? void 0 : {
|
|
1133
1131
|
mountPoint,
|
|
1134
|
-
fstype
|
|
1132
|
+
fstype,
|
|
1133
|
+
isReadOnly: isReadOnlyMount(entry.fs_mntops)
|
|
1135
1134
|
};
|
|
1136
1135
|
}
|
|
1137
1136
|
function mountEntryToPartialVolumeMetadata(entry, options = {}) {
|
|
@@ -1141,6 +1140,7 @@ function mountEntryToPartialVolumeMetadata(entry, options = {}) {
|
|
|
1141
1140
|
fstype: entry.fs_vfstype,
|
|
1142
1141
|
mountFrom: entry.fs_spec,
|
|
1143
1142
|
isSystemVolume: isSystemVolume(entry.fs_file, entry.fs_vfstype, options),
|
|
1143
|
+
isReadOnly: isReadOnlyMount(entry.fs_mntops),
|
|
1144
1144
|
remote: false,
|
|
1145
1145
|
// < default to false, but it may be overridden by extractRemoteInfo
|
|
1146
1146
|
...extractRemoteInfo(entry.fs_spec, networkFsTypes)
|
|
@@ -1424,6 +1424,57 @@ async function _getVolumeMetadata(o, nativeFn2) {
|
|
|
1424
1424
|
debug("[getVolumeMetadata] final result for %s: %o", o.mountPoint, result);
|
|
1425
1425
|
return compactValues(result);
|
|
1426
1426
|
}
|
|
1427
|
+
async function getVolumeMetadataForPathImpl(pathname, opts, nativeFn2) {
|
|
1428
|
+
if (isBlank(pathname)) {
|
|
1429
|
+
throw new TypeError("Invalid pathname: got " + JSON.stringify(pathname));
|
|
1430
|
+
}
|
|
1431
|
+
const resolved = await realpath(pathname);
|
|
1432
|
+
const resolvedStat = await statAsync(resolved);
|
|
1433
|
+
const dir = resolvedStat.isDirectory() ? resolved : dirname4(resolved);
|
|
1434
|
+
if (isMacOS) {
|
|
1435
|
+
const probe = await getVolumeMetadataImpl(
|
|
1436
|
+
{ ...opts, mountPoint: dir },
|
|
1437
|
+
nativeFn2
|
|
1438
|
+
);
|
|
1439
|
+
const canonicalMountPoint = isNotBlank(probe.mountName) ? probe.mountName : dir;
|
|
1440
|
+
if (canonicalMountPoint === dir) return probe;
|
|
1441
|
+
return getVolumeMetadataImpl(
|
|
1442
|
+
{ ...opts, mountPoint: canonicalMountPoint },
|
|
1443
|
+
nativeFn2
|
|
1444
|
+
);
|
|
1445
|
+
}
|
|
1446
|
+
const targetDev = resolvedStat.dev;
|
|
1447
|
+
const mountPoints = await getVolumeMountPointsImpl(
|
|
1448
|
+
{ ...opts, includeSystemVolumes: true },
|
|
1449
|
+
nativeFn2
|
|
1450
|
+
);
|
|
1451
|
+
const prefixMatches = [];
|
|
1452
|
+
const deviceMatches = [];
|
|
1453
|
+
await Promise.all(
|
|
1454
|
+
mountPoints.map(async ({ mountPoint: mountPoint2 }) => {
|
|
1455
|
+
try {
|
|
1456
|
+
const mpDev = (await statAsync(mountPoint2)).dev;
|
|
1457
|
+
if (mpDev !== targetDev) return;
|
|
1458
|
+
if (isAncestorOrSelf(mountPoint2, resolved)) {
|
|
1459
|
+
prefixMatches.push(mountPoint2);
|
|
1460
|
+
} else {
|
|
1461
|
+
deviceMatches.push(mountPoint2);
|
|
1462
|
+
}
|
|
1463
|
+
} catch {
|
|
1464
|
+
}
|
|
1465
|
+
})
|
|
1466
|
+
);
|
|
1467
|
+
const candidates = prefixMatches.length > 0 ? prefixMatches : deviceMatches;
|
|
1468
|
+
if (candidates.length === 0) {
|
|
1469
|
+
throw new Error(
|
|
1470
|
+
"No mount point found for path: " + JSON.stringify(pathname)
|
|
1471
|
+
);
|
|
1472
|
+
}
|
|
1473
|
+
const mountPoint = candidates.reduce(
|
|
1474
|
+
(a, b) => a.length >= b.length ? a : b
|
|
1475
|
+
);
|
|
1476
|
+
return getVolumeMetadataImpl({ ...opts, mountPoint }, nativeFn2);
|
|
1477
|
+
}
|
|
1427
1478
|
async function getAllVolumeMetadataImpl(opts, nativeFn2) {
|
|
1428
1479
|
const o = optionsWithDefaults(opts);
|
|
1429
1480
|
debug("[getAllVolumeMetadata] starting with options: %o", o);
|
|
@@ -1479,11 +1530,11 @@ async function getAllVolumeMetadataImpl(opts, nativeFn2) {
|
|
|
1479
1530
|
var nativeFn = defer2(async () => {
|
|
1480
1531
|
const start = Date.now();
|
|
1481
1532
|
try {
|
|
1482
|
-
const
|
|
1483
|
-
const dir = await findAncestorDir(
|
|
1533
|
+
const dirname5 = _dirname();
|
|
1534
|
+
const dir = await findAncestorDir(dirname5, "binding.gyp");
|
|
1484
1535
|
if (dir == null) {
|
|
1485
1536
|
throw new Error(
|
|
1486
|
-
"Could not find bindings.gyp in any ancestor directory of " +
|
|
1537
|
+
"Could not find bindings.gyp in any ancestor directory of " + dirname5
|
|
1487
1538
|
);
|
|
1488
1539
|
}
|
|
1489
1540
|
const bindings = NodeGypBuild(dir);
|
|
@@ -1506,6 +1557,13 @@ function getVolumeMetadata(mountPoint, opts) {
|
|
|
1506
1557
|
nativeFn
|
|
1507
1558
|
);
|
|
1508
1559
|
}
|
|
1560
|
+
function getVolumeMetadataForPath(pathname, opts) {
|
|
1561
|
+
return getVolumeMetadataForPathImpl(
|
|
1562
|
+
pathname,
|
|
1563
|
+
optionsWithDefaults(opts),
|
|
1564
|
+
nativeFn
|
|
1565
|
+
);
|
|
1566
|
+
}
|
|
1509
1567
|
function getAllVolumeMetadata(opts) {
|
|
1510
1568
|
return getAllVolumeMetadataImpl(optionsWithDefaults(opts), nativeFn);
|
|
1511
1569
|
}
|
|
@@ -1534,6 +1592,7 @@ export {
|
|
|
1534
1592
|
getHiddenMetadata,
|
|
1535
1593
|
getTimeoutMsDefault,
|
|
1536
1594
|
getVolumeMetadata,
|
|
1595
|
+
getVolumeMetadataForPath,
|
|
1537
1596
|
getVolumeMountPoints,
|
|
1538
1597
|
isHidden,
|
|
1539
1598
|
isHiddenRecursive,
|