@photostructure/fs-metadata 0.8.1 → 0.9.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 CHANGED
@@ -14,6 +14,19 @@ Fixed for any bug fixes.
14
14
  Security in case of vulnerabilities.
15
15
  -->
16
16
 
17
+ ## 0.9.0 - 2025-12-28
18
+
19
+ ### Added
20
+
21
+ - New `networkFsTypes` option for configuring network filesystem detection
22
+ - `NetworkFsTypesDefault` and `SkipNetworkVolumesDefault` exports
23
+
24
+ ### Changed
25
+
26
+ - Expanded `SystemFsTypesDefault` with `bpf`, `tracefs`, `nsfs`, `ramfs`, `rpc_pipefs`, `fuse.lxcfs`, `fuse.portal`
27
+ - Expanded `SystemPathPatternsDefault` with macOS metadata paths, kubelet, LXC/LXD, Flatpak paths
28
+ - `isRemoteFsType()` and `extractRemoteInfo()` accept optional `networkFsTypes` parameter
29
+
17
30
  ## 0.8.1 - 2025-12-28
18
31
 
19
32
  ### Changed
@@ -104,9 +117,9 @@ Security in case of vulnerabilities.
104
117
 
105
118
  - `Packaging`: Improved ESM/CJS support with common `__dirname` implementation thanks to `tsup` [shims](https://tsup.egoist.dev/#inject-cjs-and-esm-shims).
106
119
 
107
- This change simplifies the implementation and improves inline jsdocs as the exported code and docs have been inlined.
120
+ This change simplifies the implementation and improves inline js docs as the exported code and docs have been inlined.
108
121
 
109
- - `Packaging`: Re-enabled test coverage assertions (after finding the magicks to get istanbul to see what the tests were exercising)
122
+ - `Packaging`: Re-enabled test coverage assertions (after finding the magics to get istanbul to see what the tests were exercising)
110
123
 
111
124
  - `Packaging`: Added debuglog tests
112
125
 
package/README.md CHANGED
@@ -48,6 +48,7 @@ console.log(metadata);
48
48
 
49
49
  ## Documentation
50
50
 
51
+ - [Security reporting](./SECURITY.md) - How to report security issues
51
52
  - [API Reference](https://photostructure.github.io/fs-metadata/modules.html)
52
53
  - [Examples](./doc/examples.md) - Common usage patterns and recipes
53
54
  - [Gotchas](./doc/gotchas.md) - Platform quirks, timeouts, and troubleshooting
@@ -59,3 +60,7 @@ console.log(metadata);
59
60
  - **Timeouts**: Configure [timeout duration](https://photostructure.github.io/fs-metadata/functions/getTimeoutMsDefault.html) for slow devices
60
61
  - Set `FS_METADATA_TIMEOUT_MS` environment variable to override the default (5000ms)
61
62
  - **System Volumes**: Control [system volume filtering](https://photostructure.github.io/fs-metadata/interfaces/Options.html)
63
+
64
+ ## Development
65
+
66
+ Development of this library was assisted by AI coding tools. All changes are human-reviewed and tested.
package/binding.gyp CHANGED
@@ -31,11 +31,13 @@
31
31
  "-lblkid"
32
32
  ],
33
33
  "cflags": [
34
- "-fPIC"
34
+ "-fPIC",
35
+ "-fstack-protector-strong"
35
36
  ],
36
37
  "cflags_cc": [
37
38
  "-fexceptions",
38
- "-fPIC"
39
+ "-fPIC",
40
+ "-fstack-protector-strong"
39
41
  ],
40
42
  "conditions": [
41
43
  [
@@ -179,14 +181,19 @@
179
181
  "CLANG_CXX_LANGUAGE_STANDARD": "c++17",
180
182
  "GCC_ENABLE_CPP_EXCEPTIONS": "YES",
181
183
  "CLANG_CXX_LIBRARY": "libc++",
182
- "MACOSX_DEPLOYMENT_TARGET": "10.15"
184
+ "MACOSX_DEPLOYMENT_TARGET": "10.15",
185
+ "OTHER_CFLAGS": [
186
+ "-fstack-protector-strong"
187
+ ]
183
188
  },
184
189
  "cflags": [
185
190
  "-fexceptions",
186
- "-fPIC"
191
+ "-fPIC",
192
+ "-fstack-protector-strong"
187
193
  ],
188
194
  "cflags_cc": [
189
- "-fexceptions"
195
+ "-fexceptions",
196
+ "-fstack-protector-strong"
190
197
  ],
191
198
  "link_settings": {
192
199
  "libraries": [
package/dist/index.cjs CHANGED
@@ -32,7 +32,9 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  IncludeSystemVolumesDefault: () => IncludeSystemVolumesDefault,
34
34
  LinuxMountTablePathsDefault: () => LinuxMountTablePathsDefault,
35
+ NetworkFsTypesDefault: () => NetworkFsTypesDefault,
35
36
  OptionsDefault: () => OptionsDefault,
37
+ SkipNetworkVolumesDefault: () => SkipNetworkVolumesDefault,
36
38
  SystemFsTypesDefault: () => SystemFsTypesDefault,
37
39
  SystemPathPatternsDefault: () => SystemPathPatternsDefault,
38
40
  VolumeHealthStatuses: () => VolumeHealthStatuses,
@@ -628,6 +630,7 @@ var SystemPathPatternsDefault = [
628
630
  "/proc/**",
629
631
  "/run",
630
632
  "/run/credentials/**",
633
+ "/run/flatpak/**",
631
634
  "/run/lock",
632
635
  "/run/snapd/**",
633
636
  "/run/user/*/doc",
@@ -657,12 +660,21 @@ var SystemPathPatternsDefault = [
657
660
  // - Rootless and rootful container storage
658
661
  "/run/containers/**",
659
662
  "/var/lib/containers/**",
660
- // windows for linux:
663
+ //
664
+ // Kubernetes: https://kubernetes.io/docs/reference/node/kubelet-files/
665
+ // - kubelet stores pod data, device plugins, and seccomp profiles
666
+ "/var/lib/kubelet/**",
667
+ //
668
+ // LXC/LXD: https://linuxcontainers.org/
669
+ // - Linux container storage and configuration
670
+ "/var/lib/lxc/**",
671
+ "/var/lib/lxd/**",
672
+ // WSL (Windows Subsystem for Linux):
661
673
  "/mnt/wslg/distro",
662
674
  "/mnt/wslg/doc",
663
675
  "/mnt/wslg/versions.txt",
664
676
  "/usr/lib/wsl/drivers",
665
- // MacOS stuff:
677
+ // macOS system paths:
666
678
  "/private/var/vm",
667
679
  // macOS swap
668
680
  "/System/Volumes/Hardware",
@@ -672,11 +684,20 @@ var SystemPathPatternsDefault = [
672
684
  "/System/Volumes/Reserved",
673
685
  "/System/Volumes/Update",
674
686
  "/System/Volumes/VM",
675
- "/System/Volumes/xarts"
687
+ "/System/Volumes/xarts",
688
+ // macOS per-volume metadata (Spotlight, FSEvents, versioning, Trash):
689
+ // https://eclecticlight.co/2021/01/28/spotlight-on-search-how-spotlight-works/
690
+ "**/.DocumentRevisions-V100",
691
+ "**/.fseventsd",
692
+ "**/.Spotlight-V100",
693
+ "**/.Trashes"
676
694
  ];
677
695
  var SystemFsTypesDefault = [
678
696
  "autofs",
679
697
  "binfmt_misc",
698
+ // BPF filesystem for persistent BPF objects
699
+ // https://docs.kernel.org/bpf/
700
+ "bpf",
680
701
  "cgroup",
681
702
  "cgroup2",
682
703
  "configfs",
@@ -685,24 +706,98 @@ var SystemFsTypesDefault = [
685
706
  "devtmpfs",
686
707
  "efivarfs",
687
708
  "fusectl",
709
+ // LXC container filesystem virtualization
710
+ // https://linuxcontainers.org/lxcfs/
711
+ "fuse.lxcfs",
712
+ // XDG Desktop Portal for Flatpak sandboxed app file access
713
+ // https://flatpak.github.io/xdg-desktop-portal/
714
+ "fuse.portal",
688
715
  "fuse.snapfuse",
689
716
  "hugetlbfs",
690
717
  "mqueue",
691
718
  "none",
719
+ // Linux namespace filesystem (internal kernel use)
720
+ // https://man7.org/linux/man-pages/man7/namespaces.7.html
721
+ "nsfs",
692
722
  "proc",
693
723
  "pstore",
724
+ // RAM-based filesystem (predecessor to tmpfs)
725
+ // https://www.kernel.org/doc/html/latest/filesystems/ramfs-rootfs-initramfs.html
726
+ "ramfs",
694
727
  "rootfs",
728
+ // NFS RPC communication pipe filesystem
729
+ // https://man7.org/linux/man-pages/man8/rpc.gssd.8.html
730
+ "rpc_pipefs",
695
731
  "securityfs",
696
732
  "snap*",
697
733
  "squashfs",
698
734
  "sysfs",
699
- "tmpfs"
735
+ "tmpfs",
736
+ // Kernel function tracing filesystem
737
+ // https://www.kernel.org/doc/html/latest/trace/ftrace.html
738
+ "tracefs"
700
739
  ];
701
740
  var LinuxMountTablePathsDefault = [
702
741
  "/proc/self/mounts",
703
742
  "/proc/mounts",
704
743
  "/etc/mtab"
705
744
  ];
745
+ var NetworkFsTypesDefault = [
746
+ // Plan 9 filesystem (VM host-guest, also network)
747
+ // https://www.kernel.org/doc/html/latest/filesystems/9p.html
748
+ "9p",
749
+ // Apple Filing Protocol (legacy macOS/netatalk)
750
+ "afp",
751
+ // Andrew File System (distributed) - not to be confused with Apple's APFS
752
+ // https://www.openafs.org/
753
+ "afs",
754
+ // BeeGFS parallel filesystem (HPC)
755
+ // https://www.beegfs.io/
756
+ "beegfs",
757
+ // Ceph distributed filesystem
758
+ // https://docs.ceph.com/
759
+ "ceph",
760
+ // Windows/Samba shares (SMB/CIFS)
761
+ // https://www.samba.org/
762
+ "cifs",
763
+ // FTP filesystem mount
764
+ "ftp",
765
+ // Generic FUSE (often remote, treated conservatively)
766
+ "fuse",
767
+ // rclone cloud storage mount (Google Drive, S3, etc.)
768
+ // https://rclone.org/commands/rclone_mount/
769
+ "fuse.rclone",
770
+ // Amazon S3 FUSE mount
771
+ // https://github.com/s3fs-fuse/s3fs-fuse
772
+ "fuse.s3fs",
773
+ // SSH filesystem
774
+ // https://github.com/libfuse/sshfs
775
+ "fuse.sshfs",
776
+ // Red Hat Global File System (cluster)
777
+ "gfs",
778
+ "gfs2",
779
+ // GlusterFS distributed filesystem
780
+ // https://www.gluster.org/
781
+ "glusterfs",
782
+ // Lustre parallel filesystem (HPC)
783
+ // https://www.lustre.org/
784
+ "lustre",
785
+ // Novell NetWare (legacy)
786
+ "ncpfs",
787
+ "ncp",
788
+ // Network File System
789
+ // https://man7.org/linux/man-pages/man5/nfs.5.html
790
+ "nfs",
791
+ "nfs4",
792
+ // SMB filesystem
793
+ "smb",
794
+ "smbfs",
795
+ // SSH filesystem (non-FUSE variant)
796
+ "sshfs",
797
+ // WebDAV filesystem
798
+ // https://savannah.nongnu.org/projects/davfs2
799
+ "webdav"
800
+ ];
706
801
  var IncludeSystemVolumesDefault = isWindows;
707
802
  var SkipNetworkVolumesDefault = false;
708
803
  var OptionsDefault = {
@@ -711,6 +806,7 @@ var OptionsDefault = {
711
806
  systemPathPatterns: [...SystemPathPatternsDefault],
712
807
  systemFsTypes: [...SystemFsTypesDefault],
713
808
  linuxMountTablePaths: [...LinuxMountTablePathsDefault],
809
+ networkFsTypes: [...NetworkFsTypesDefault],
714
810
  includeSystemVolumes: IncludeSystemVolumesDefault,
715
811
  skipNetworkVolumes: SkipNetworkVolumesDefault
716
812
  };
@@ -835,38 +931,15 @@ function isRemoteInfo(obj) {
835
931
  const { remoteHost, remoteShare } = obj;
836
932
  return isNotBlank(remoteHost) && isNotBlank(remoteShare);
837
933
  }
838
- var NETWORK_FS_TYPE_ARRAY = [
839
- "9p",
840
- "afp",
841
- "afs",
842
- "beegfs",
843
- "ceph",
844
- "cifs",
845
- "ftp",
846
- "fuse",
847
- "gfs2",
848
- "glusterfs",
849
- "lustre",
850
- "ncpfs",
851
- "nfs",
852
- "nfs4",
853
- "smb",
854
- "smbfs",
855
- "sshfs",
856
- "webdav"
857
- ];
858
- var NETWORK_FS_TYPES = new Set(NETWORK_FS_TYPE_ARRAY);
859
934
  var FS_TYPE_ALIASES = /* @__PURE__ */ new Map([
860
935
  ["nfs1", "nfs"],
861
936
  ["nfs2", "nfs"],
862
937
  ["nfs3", "nfs"],
863
- ["nfs4", "nfs4"],
864
938
  ["fuse.sshfs", "sshfs"],
865
939
  ["sshfs.fuse", "sshfs"],
866
940
  ["davfs2", "webdav"],
867
941
  ["davfs", "webdav"],
868
942
  ["cifs.smb", "cifs"],
869
- ["smbfs", "cifs"],
870
943
  ["cephfs", "ceph"],
871
944
  ["fuse.ceph", "ceph"],
872
945
  ["fuse.cephfs", "ceph"],
@@ -877,8 +950,12 @@ function normalizeFsType(fstype) {
877
950
  const norm = toS(fstype).toLowerCase().replace(/:$/, "");
878
951
  return FS_TYPE_ALIASES.get(norm) ?? norm;
879
952
  }
880
- function isRemoteFsType(fstype) {
881
- return isNotBlank(fstype) && NETWORK_FS_TYPES.has(normalizeFsType(fstype));
953
+ function isRemoteFsType(fstype, networkFsTypes = NetworkFsTypesDefault) {
954
+ if (!isNotBlank(fstype)) return false;
955
+ const normalized = normalizeFsType(fstype);
956
+ return networkFsTypes.some(
957
+ (nft) => nft === normalized || normalized.startsWith(nft + ".")
958
+ );
882
959
  }
883
960
  function parseURL(s) {
884
961
  try {
@@ -887,7 +964,7 @@ function parseURL(s) {
887
964
  return;
888
965
  }
889
966
  }
890
- function extractRemoteInfo(fsSpec) {
967
+ function extractRemoteInfo(fsSpec, networkFsTypes = NetworkFsTypesDefault) {
891
968
  if (fsSpec == null || isBlank(fsSpec)) return;
892
969
  if (isWindows) {
893
970
  fsSpec = fsSpec.replace(/\\/g, "/");
@@ -936,7 +1013,7 @@ function extractRemoteInfo(fsSpec) {
936
1013
  if (parsed != null) {
937
1014
  debug("[extractRemoteInfo] parsed URL: %o", parsed);
938
1015
  const fstype = normalizeFsType(parsed.protocol);
939
- if (!isRemoteFsType(fstype)) {
1016
+ if (!isRemoteFsType(fstype, networkFsTypes)) {
940
1017
  return {
941
1018
  uri: fsSpec,
942
1019
  remote: false
@@ -1089,6 +1166,7 @@ function mountEntryToMountPoint(entry) {
1089
1166
  };
1090
1167
  }
1091
1168
  function mountEntryToPartialVolumeMetadata(entry, options = {}) {
1169
+ const networkFsTypes = options.networkFsTypes ?? NetworkFsTypesDefault;
1092
1170
  return {
1093
1171
  mountPoint: entry.fs_file,
1094
1172
  fstype: entry.fs_vfstype,
@@ -1096,7 +1174,7 @@ function mountEntryToPartialVolumeMetadata(entry, options = {}) {
1096
1174
  isSystemVolume: isSystemVolume(entry.fs_file, entry.fs_vfstype, options),
1097
1175
  remote: false,
1098
1176
  // < default to false, but it may be overridden by extractRemoteInfo
1099
- ...extractRemoteInfo(entry.fs_spec)
1177
+ ...extractRemoteInfo(entry.fs_spec, networkFsTypes)
1100
1178
  };
1101
1179
  }
1102
1180
  function parseMtab(content) {
@@ -1348,9 +1426,9 @@ async function _getVolumeMetadata(o, nativeFn2) {
1348
1426
  debug("[getVolumeMetadata] requesting native metadata");
1349
1427
  const metadata = await (await nativeFn2()).getVolumeMetadata(o);
1350
1428
  debug("[getVolumeMetadata] native metadata: %o", metadata);
1351
- const remoteInfo = mtabInfo ?? extractRemoteInfo(metadata.uri) ?? extractRemoteInfo(metadata.mountFrom) ?? (isWindows ? parseUNCPath(o.mountPoint) : void 0);
1429
+ const remoteInfo = mtabInfo ?? extractRemoteInfo(metadata.uri, o.networkFsTypes) ?? extractRemoteInfo(metadata.mountFrom, o.networkFsTypes) ?? (isWindows ? parseUNCPath(o.mountPoint) : void 0);
1352
1430
  debug("[getVolumeMetadata] extracted remote info: %o", remoteInfo);
1353
- remote ||= isRemoteFsType(metadata.fstype) || (remoteInfo?.remote ?? metadata.remote ?? false);
1431
+ remote ||= isRemoteFsType(metadata.fstype, o.networkFsTypes) || (remoteInfo?.remote ?? metadata.remote ?? false);
1354
1432
  debug("[getVolumeMetadata] assembling: %o", {
1355
1433
  status,
1356
1434
  mtabInfo,
@@ -1478,7 +1556,9 @@ function setHidden(pathname, hidden, method = "auto") {
1478
1556
  0 && (module.exports = {
1479
1557
  IncludeSystemVolumesDefault,
1480
1558
  LinuxMountTablePathsDefault,
1559
+ NetworkFsTypesDefault,
1481
1560
  OptionsDefault,
1561
+ SkipNetworkVolumesDefault,
1482
1562
  SystemFsTypesDefault,
1483
1563
  SystemPathPatternsDefault,
1484
1564
  VolumeHealthStatuses,