@photostructure/fs-metadata 0.1.6 → 0.3.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/CODE_OF_CONDUCT.md +128 -0
  3. package/CONTRIBUTING.md +46 -0
  4. package/README.md +4 -65
  5. package/SECURITY.md +9 -0
  6. package/dist/index.cjs +247 -229
  7. package/dist/index.cjs.map +1 -0
  8. package/dist/index.mjs +245 -227
  9. package/dist/index.mjs.map +1 -0
  10. package/dist/types/array.d.ts +0 -5
  11. package/dist/types/debuglog.d.ts +0 -1
  12. package/dist/types/exports.d.ts +2 -1
  13. package/dist/types/mount_point.d.ts +1 -9
  14. package/dist/types/number.d.ts +0 -4
  15. package/dist/types/object.d.ts +0 -4
  16. package/dist/types/options.d.ts +4 -4
  17. package/dist/types/volume_metadata.d.ts +3 -3
  18. package/dist/types/volume_mount_points.d.ts +9 -0
  19. package/package.json +9 -9
  20. package/prebuilds/darwin-arm64/@photostructure+fs-metadata.glibc.node +0 -0
  21. package/prebuilds/win32-x64/@photostructure+fs-metadata.glibc.node +0 -0
  22. package/src/array.ts +44 -0
  23. package/src/async.ts +145 -0
  24. package/src/debuglog.ts +30 -0
  25. package/src/defer.ts +30 -0
  26. package/src/error.ts +79 -0
  27. package/src/exports.ts +156 -0
  28. package/src/fs.ts +89 -0
  29. package/src/glob.ts +127 -0
  30. package/src/hidden.ts +249 -0
  31. package/src/index.cts +15 -0
  32. package/src/index.mts +17 -0
  33. package/src/linux/dev_disk.ts +77 -0
  34. package/src/linux/mount_points.ts +91 -0
  35. package/src/linux/mtab.ts +136 -0
  36. package/src/mount_point.ts +58 -0
  37. package/src/number.ts +21 -0
  38. package/src/object.ts +55 -0
  39. package/src/options.ts +179 -0
  40. package/src/path.ts +54 -0
  41. package/src/platform.ts +9 -0
  42. package/src/random.ts +40 -0
  43. package/src/remote_info.ts +161 -0
  44. package/src/setup.ts +69 -0
  45. package/src/string.ts +99 -0
  46. package/src/string_enum.ts +41 -0
  47. package/src/system_volume.ts +75 -0
  48. package/src/test-utils/assert.ts +69 -0
  49. package/src/test-utils/hidden-tests.ts +33 -0
  50. package/src/test-utils/jest-matchers.ts +29 -0
  51. package/src/test-utils/platform.ts +39 -0
  52. package/src/types/native_bindings.ts +64 -0
  53. package/src/types/node-gyp-build.d.ts +6 -0
  54. package/src/unc.ts +63 -0
  55. package/src/units.ts +31 -0
  56. package/src/uuid.ts +24 -0
  57. package/src/volume_health_status.ts +58 -0
  58. package/src/volume_metadata.ts +294 -0
  59. package/src/volume_mount_points.ts +109 -0
  60. package/tsup.config.ts +8 -0
  61. package/dist/types/cache.d.ts +0 -4
package/dist/index.mjs CHANGED
@@ -462,20 +462,6 @@ async function setHidden(pathname, hide, method, nativeFn) {
462
462
  return { pathname: norm, actions };
463
463
  }
464
464
 
465
- // src/array.ts
466
- function uniqBy(arr, keyFn) {
467
- const seen = /* @__PURE__ */ new Set();
468
- return arr.filter((item) => {
469
- const key = keyFn(item);
470
- if (key == null || seen.has(key)) return false;
471
- seen.add(key);
472
- return true;
473
- });
474
- }
475
-
476
- // src/linux/mount_points.ts
477
- import { readFile } from "node:fs/promises";
478
-
479
465
  // src/options.ts
480
466
  import { availableParallelism as availableParallelism2 } from "node:os";
481
467
  var TimeoutMsDefault = 5e3;
@@ -493,6 +479,8 @@ var SystemPathPatternsDefault = [
493
479
  "/run/user/*/gvfs",
494
480
  "/snap/**",
495
481
  "/sys/**",
482
+ "**/#snapshot",
483
+ // Synology and Kubernetes volume snapshots
496
484
  // windows for linux:
497
485
  "/mnt/wslg/distro",
498
486
  "/mnt/wslg/doc",
@@ -510,7 +498,7 @@ var SystemPathPatternsDefault = [
510
498
  "/System/Volumes/VM",
511
499
  "/System/Volumes/xarts"
512
500
  ];
513
- var SystemFsTypesDefault = /* @__PURE__ */ new Set([
501
+ var SystemFsTypesDefault = [
514
502
  "autofs",
515
503
  "binfmt_misc",
516
504
  "cgroup",
@@ -533,7 +521,7 @@ var SystemFsTypesDefault = /* @__PURE__ */ new Set([
533
521
  "squashfs",
534
522
  "sysfs",
535
523
  "tmpfs"
536
- ]);
524
+ ];
537
525
  var LinuxMountTablePathsDefault = [
538
526
  "/proc/self/mounts",
539
527
  "/proc/mounts",
@@ -544,8 +532,8 @@ var OptionsDefault = {
544
532
  timeoutMs: TimeoutMsDefault,
545
533
  maxConcurrency: availableParallelism2(),
546
534
  systemPathPatterns: [...SystemPathPatternsDefault],
547
- systemFsTypes: new Set(SystemFsTypesDefault),
548
- linuxMountTablePaths: LinuxMountTablePathsDefault,
535
+ systemFsTypes: [...SystemFsTypesDefault],
536
+ linuxMountTablePaths: [...LinuxMountTablePathsDefault],
549
537
  includeSystemVolumes: IncludeSystemVolumesDefault
550
538
  };
551
539
  function optionsWithDefaults(overrides = {}) {
@@ -560,116 +548,65 @@ function optionsWithDefaults(overrides = {}) {
560
548
  };
561
549
  }
562
550
 
563
- // src/glob.ts
564
- var cache = /* @__PURE__ */ new Map();
565
- function compileGlob(patterns) {
566
- if (patterns == null || patterns.length === 0) {
567
- return NeverMatchRE;
551
+ // src/linux/dev_disk.ts
552
+ import { readdir, readlink } from "node:fs/promises";
553
+ import { join as join3, resolve as resolve3 } from "node:path";
554
+ async function getUuidFromDevDisk(devicePath) {
555
+ try {
556
+ const result = await getBasenameLinkedTo(
557
+ "/dev/disk/by-uuid",
558
+ resolve3(devicePath)
559
+ );
560
+ debug("[getUuidFromDevDisk] result: %o", result);
561
+ return result;
562
+ } catch (error) {
563
+ debug("[getUuidFromDevDisk] failed: " + error);
564
+ return;
568
565
  }
569
- const patternsKey = JSON.stringify(patterns);
570
- {
571
- const prior = cache.get(patternsKey);
572
- if (prior != null) {
573
- return prior;
574
- }
566
+ }
567
+ async function getLabelFromDevDisk(devicePath) {
568
+ try {
569
+ const result = await getBasenameLinkedTo(
570
+ "/dev/disk/by-label",
571
+ resolve3(devicePath)
572
+ );
573
+ debug("[getLabelFromDevDisk] result: %o", result);
574
+ return result;
575
+ } catch (error) {
576
+ debug("[getLabelFromDevDisk] failed: " + error);
577
+ return;
575
578
  }
576
- const sorted = patterns.slice().filter(isNotBlank).sort();
577
- const sortedKey = JSON.stringify(sorted);
578
- {
579
- const prior = cache.get(sortedKey);
580
- if (prior != null) {
581
- cache.set(patternsKey, prior);
582
- return prior;
579
+ }
580
+ async function getBasenameLinkedTo(linkDir, linkPath) {
581
+ for await (const ea of readLinks(linkDir)) {
582
+ if (ea.linkTarget === linkPath) {
583
+ return decodeEscapeSequences(ea.dirent.name);
583
584
  }
584
585
  }
585
- const result = _compileGlob(sorted);
586
- if (cache.size > 256) {
587
- cache.clear();
588
- }
589
- cache.set(patternsKey, result);
590
- cache.set(sortedKey, result);
591
- return result;
586
+ return;
592
587
  }
593
- function _compileGlob(patterns) {
594
- const regexPatterns = patterns.map((pattern) => {
595
- let regex = "";
596
- let i = 0;
597
- while (i < pattern.length) {
598
- if (pattern[i] === "*" && pattern[i + 1] === "*") {
599
- regex += ".*";
600
- i += 2;
601
- if (pattern[i] === "/") {
602
- i++;
603
- }
604
- continue;
605
- }
606
- if (pattern[i] === "*") {
607
- regex += "[^/]*";
608
- i++;
609
- continue;
610
- }
611
- if (pattern[i] === "?") {
612
- regex += "[^/]";
613
- i++;
614
- continue;
615
- }
616
- if (pattern[i] === ".") {
617
- regex += "\\.";
618
- i++;
619
- continue;
620
- }
621
- if (pattern[i] === "/") {
622
- if (i === pattern.length - 1) {
623
- regex += "(?:/|$)";
624
- i++;
625
- continue;
626
- } else if (isWindows) {
627
- regex += "[\\/\\\\]";
628
- i++;
629
- continue;
630
- }
631
- }
632
- if (/[+^${}()|[\]\\]/.test(pattern[i])) {
633
- regex += "\\" + pattern[i];
634
- i++;
635
- continue;
588
+ async function* readLinks(directory) {
589
+ for (const dirent of await readdir(directory, { withFileTypes: true })) {
590
+ if (dirent.isSymbolicLink()) {
591
+ try {
592
+ const linkTarget = resolve3(
593
+ directory,
594
+ await readlink(join3(directory, dirent.name))
595
+ );
596
+ yield { dirent, linkTarget };
597
+ } catch {
636
598
  }
637
- regex += pattern[i];
638
- i++;
639
- }
640
- return regex;
641
- });
642
- const final = regexPatterns.filter((ea) => ea.length > 0);
643
- return final.length === 0 ? (
644
- // Empty pattern matches nothing
645
- NeverMatchRE
646
- ) : new RegExp(`^(?:${final.join("|")})$`, "i");
647
- }
648
- var NeverMatchRE = /(?!)/;
649
-
650
- // src/system_volume.ts
651
- function isSystemVolume(mountPoint, fstype, config = {}) {
652
- debug("[isSystemVolume] checking %s (fstype: %s)", mountPoint, fstype);
653
- if (isWindows) {
654
- const systemDrive = normalizePath(process.env["SystemDrive"]);
655
- if (systemDrive != null && mountPoint === systemDrive) {
656
- debug("[isSystemVolume] %s is the Windows system drive", mountPoint);
657
- return true;
658
599
  }
659
600
  }
660
- const result = isNotBlank(fstype) && (config.systemFsTypes ?? SystemFsTypesDefault).has(fstype) || compileGlob(config.systemPathPatterns ?? SystemPathPatternsDefault).test(
661
- mountPoint
662
- );
663
- debug("[isSystemVolume] %s -> %s", mountPoint, result);
664
- return result;
665
601
  }
666
- function assignSystemVolume(mp, config) {
667
- const result = isSystemVolume(mp.mountPoint, mp.fstype, config);
668
- if (isWindows) {
669
- mp.isSystemVolume ??= result;
670
- } else {
671
- mp.isSystemVolume = result;
672
- }
602
+
603
+ // src/linux/mount_points.ts
604
+ import { readFile } from "node:fs/promises";
605
+
606
+ // src/mount_point.ts
607
+ function isMountPoint(obj) {
608
+ if (!isObject(obj)) return false;
609
+ return "mountPoint" in obj && isNotBlank(obj.mountPoint);
673
610
  }
674
611
 
675
612
  // src/remote_info.ts
@@ -775,6 +712,127 @@ function extractRemoteInfo(fsSpec) {
775
712
  return;
776
713
  }
777
714
 
715
+ // src/glob.ts
716
+ var cache = /* @__PURE__ */ new Map();
717
+ function compileGlob(patterns) {
718
+ if (patterns == null || patterns.length === 0) {
719
+ return NeverMatchRE;
720
+ }
721
+ const patternsKey = JSON.stringify(patterns);
722
+ {
723
+ const prior = cache.get(patternsKey);
724
+ if (prior != null) {
725
+ return prior;
726
+ }
727
+ }
728
+ const sorted = patterns.slice().filter(isNotBlank).sort();
729
+ const sortedKey = JSON.stringify(sorted);
730
+ {
731
+ const prior = cache.get(sortedKey);
732
+ if (prior != null) {
733
+ cache.set(patternsKey, prior);
734
+ return prior;
735
+ }
736
+ }
737
+ const result = _compileGlob(sorted);
738
+ if (cache.size > 256) {
739
+ cache.clear();
740
+ }
741
+ cache.set(patternsKey, result);
742
+ cache.set(sortedKey, result);
743
+ return result;
744
+ }
745
+ function _compileGlob(patterns) {
746
+ const regexPatterns = patterns.map((pattern) => {
747
+ let regex = "";
748
+ let i = 0;
749
+ while (i < pattern.length) {
750
+ if (pattern[i] === "*" && pattern[i + 1] === "*") {
751
+ regex += ".*";
752
+ i += 2;
753
+ if (pattern[i] === "/") {
754
+ i++;
755
+ }
756
+ continue;
757
+ }
758
+ if (pattern[i] === "*") {
759
+ regex += "[^/]*";
760
+ i++;
761
+ continue;
762
+ }
763
+ if (pattern[i] === "?") {
764
+ regex += "[^/]";
765
+ i++;
766
+ continue;
767
+ }
768
+ if (pattern[i] === ".") {
769
+ regex += "\\.";
770
+ i++;
771
+ continue;
772
+ }
773
+ if (pattern[i] === "/") {
774
+ if (i === pattern.length - 1) {
775
+ regex += "(?:/|$)";
776
+ i++;
777
+ continue;
778
+ } else if (isWindows) {
779
+ regex += "[\\/\\\\]";
780
+ i++;
781
+ continue;
782
+ }
783
+ }
784
+ if (/[+^${}()|[\]\\]/.test(pattern[i])) {
785
+ regex += "\\" + pattern[i];
786
+ i++;
787
+ continue;
788
+ }
789
+ regex += pattern[i];
790
+ i++;
791
+ }
792
+ return regex;
793
+ });
794
+ const final = regexPatterns.filter((ea) => ea.length > 0);
795
+ return final.length === 0 ? (
796
+ // Empty pattern matches nothing
797
+ NeverMatchRE
798
+ ) : new RegExp(`^(?:${final.join("|")})$`, "i");
799
+ }
800
+ var NeverMatchRE = /(?!)/;
801
+
802
+ // src/system_volume.ts
803
+ function isSystemVolume(mountPoint, fstype, config = {}) {
804
+ if (isWindows) {
805
+ const systemDrive = normalizePath(process.env["SystemDrive"]);
806
+ if (systemDrive != null && mountPoint === systemDrive) {
807
+ debug("[isSystemVolume] %s is the Windows system drive", mountPoint);
808
+ return true;
809
+ }
810
+ }
811
+ const isSystemFsType = isNotBlank(fstype) && (config.systemFsTypes ?? SystemFsTypesDefault).includes(
812
+ fstype
813
+ );
814
+ const hasSystemPath = compileGlob(
815
+ config.systemPathPatterns ?? SystemPathPatternsDefault
816
+ ).test(mountPoint);
817
+ const result = isSystemFsType || hasSystemPath;
818
+ debug("[isSystemVolume]", {
819
+ mountPoint,
820
+ fstype,
821
+ result,
822
+ isSystemFsType,
823
+ hasSystemPath
824
+ });
825
+ return result;
826
+ }
827
+ function assignSystemVolume(mp, config) {
828
+ const result = isSystemVolume(mp.mountPoint, mp.fstype, config);
829
+ if (isWindows) {
830
+ mp.isSystemVolume ??= result;
831
+ } else {
832
+ mp.isSystemVolume = result;
833
+ }
834
+ }
835
+
778
836
  // src/linux/mtab.ts
779
837
  function mountEntryToMountPoint(entry) {
780
838
  const mountPoint = normalizePosixPath(entry.fs_file);
@@ -852,7 +910,6 @@ async function getLinuxMountPoints(native, opts) {
852
910
  const prior = byMountPoint.get(ea.mountPoint);
853
911
  const merged = { ...compactValues(prior), ...compactValues(ea) };
854
912
  if (isMountPoint(merged)) {
855
- assignSystemVolume(merged, o);
856
913
  byMountPoint.set(merged.mountPoint, merged);
857
914
  }
858
915
  }
@@ -863,8 +920,10 @@ async function getLinuxMountPoints(native, opts) {
863
920
  );
864
921
  }
865
922
  const results = [...byMountPoint.values()];
866
- debug("[getLinuxMountPoints] found %d mount points", results.length);
867
- return o.includeSystemVolumes ? results : results.filter((ea) => !ea.isSystemVolume);
923
+ debug("[getLinuxMountPoints] %o", {
924
+ results: results.map((ea) => ea.mountPoint)
925
+ });
926
+ return results;
868
927
  }
869
928
  async function getLinuxMtabMetadata(mountPoint, opts) {
870
929
  let caughtError;
@@ -887,6 +946,41 @@ async function getLinuxMtabMetadata(mountPoint, opts) {
887
946
  );
888
947
  }
889
948
 
949
+ // src/unc.ts
950
+ function parseUNCPath(path) {
951
+ if (path == null || isBlank(path) || !isString(path)) {
952
+ return;
953
+ }
954
+ if (!path.startsWith("\\\\") && !path.startsWith("//")) {
955
+ return;
956
+ }
957
+ const isForwardSlash = path.startsWith("//");
958
+ const slashChar = isForwardSlash ? "/" : "\\";
959
+ const parts = path.slice(2).split(slashChar);
960
+ if (parts.length < 2) {
961
+ return;
962
+ }
963
+ const [remoteHost, remoteShare] = parts;
964
+ if (remoteHost == null || isBlank(remoteHost) || remoteShare == null || isBlank(remoteShare)) {
965
+ return;
966
+ }
967
+ const invalidChars = /[<>:"|?*]/;
968
+ if (invalidChars.test(remoteHost) || invalidChars.test(remoteShare)) {
969
+ return;
970
+ }
971
+ const wrongSlash = isForwardSlash ? "\\" : "/";
972
+ if (path.includes(wrongSlash)) {
973
+ return;
974
+ }
975
+ return { remoteHost, remoteShare, remote: true };
976
+ }
977
+
978
+ // src/uuid.ts
979
+ var uuidRegex = /[a-z0-9][a-z0-9-]{7,}/i;
980
+ function extractUUID(uuid) {
981
+ return toS(uuid).match(uuidRegex)?.[0];
982
+ }
983
+
890
984
  // src/string_enum.ts
891
985
  function stringEnum(...o) {
892
986
  const set = new Set(o);
@@ -930,18 +1024,25 @@ async function directoryStatus(dir, timeoutMs, canReaddirImpl = canReaddir) {
930
1024
  return { status: VolumeHealthStatuses.unknown };
931
1025
  }
932
1026
 
933
- // src/mount_point.ts
934
- function isMountPoint(obj) {
935
- if (!isObject(obj)) return false;
936
- return "mountPoint" in obj && isNotBlank(obj.mountPoint);
1027
+ // src/array.ts
1028
+ function uniqBy(arr, keyFn) {
1029
+ const seen = /* @__PURE__ */ new Set();
1030
+ return arr.filter((item) => {
1031
+ const key = keyFn(item);
1032
+ if (key == null || seen.has(key)) return false;
1033
+ seen.add(key);
1034
+ return true;
1035
+ });
937
1036
  }
1037
+
1038
+ // src/volume_mount_points.ts
938
1039
  async function getVolumeMountPoints(opts, nativeFn) {
939
1040
  const p2 = _getVolumeMountPoints(opts, nativeFn);
940
1041
  return isWindows ? p2 : withTimeout({ desc: "getVolumeMountPoints", ...opts, promise: p2 });
941
1042
  }
942
1043
  async function _getVolumeMountPoints(o, nativeFn) {
943
1044
  debug("[getVolumeMountPoints] gathering mount points with options: %o", o);
944
- const result = await (isWindows || isMacOS ? (async () => {
1045
+ const raw = await (isWindows || isMacOS ? (async () => {
945
1046
  debug("[getVolumeMountPoints] using native implementation");
946
1047
  const points = await (await nativeFn()).getVolumeMountPoints(o);
947
1048
  debug(
@@ -950,8 +1051,11 @@ async function _getVolumeMountPoints(o, nativeFn) {
950
1051
  );
951
1052
  return points;
952
1053
  })() : getLinuxMountPoints(nativeFn, o));
953
- debug("[getVolumeMountPoints] raw mount points: %o", result);
954
- const compacted = result.map((ea) => compactValues(ea)).filter((ea) => isNotBlank(ea.mountPoint));
1054
+ debug("[getVolumeMountPoints] raw mount points: %o", raw);
1055
+ const compacted = raw.map((ea) => compactValues(ea)).filter((ea) => isNotBlank(ea.mountPoint));
1056
+ for (const ea of compacted) {
1057
+ assignSystemVolume(ea, o);
1058
+ }
955
1059
  const filtered = o.includeSystemVolumes ? compacted : compacted.filter((ea) => !ea.isSystemVolume);
956
1060
  const uniq = uniqBy(filtered, (ea) => toNotBlank(ea.mountPoint));
957
1061
  debug("[getVolumeMountPoints] found %d unique mount points", uniq.length);
@@ -962,18 +1066,18 @@ async function _getVolumeMountPoints(o, nativeFn) {
962
1066
  );
963
1067
  await mapConcurrent({
964
1068
  maxConcurrency: o.maxConcurrency,
965
- items: results,
1069
+ items: results.filter(
1070
+ // trust but verify
1071
+ (ea) => isBlank(ea.status) || ea.status === "healthy"
1072
+ ),
966
1073
  fn: async (mp) => {
967
- assignSystemVolume(mp, o);
968
- if ((toNotBlank(mp.status) ?? "healthy") === "healthy") {
969
- debug("[getVolumeMountPoints] checking status of %s", mp.mountPoint);
970
- mp.status = (await directoryStatus(mp.mountPoint, o.timeoutMs)).status;
971
- debug(
972
- "[getVolumeMountPoints] status for %s: %s",
973
- mp.mountPoint,
974
- mp.status
975
- );
976
- }
1074
+ debug("[getVolumeMountPoints] checking status of %s", mp.mountPoint);
1075
+ mp.status = (await directoryStatus(mp.mountPoint, o.timeoutMs)).status;
1076
+ debug(
1077
+ "[getVolumeMountPoints] status for %s: %s",
1078
+ mp.mountPoint,
1079
+ mp.status
1080
+ );
977
1081
  }
978
1082
  });
979
1083
  debug(
@@ -983,93 +1087,6 @@ async function _getVolumeMountPoints(o, nativeFn) {
983
1087
  return results;
984
1088
  }
985
1089
 
986
- // src/linux/dev_disk.ts
987
- import { readdir, readlink } from "node:fs/promises";
988
- import { join as join3, resolve as resolve3 } from "node:path";
989
- async function getUuidFromDevDisk(devicePath) {
990
- try {
991
- const result = await getBasenameLinkedTo(
992
- "/dev/disk/by-uuid",
993
- resolve3(devicePath)
994
- );
995
- debug("[getUuidFromDevDisk] result: %o", result);
996
- return result;
997
- } catch (error) {
998
- debug("[getUuidFromDevDisk] failed: " + error);
999
- return;
1000
- }
1001
- }
1002
- async function getLabelFromDevDisk(devicePath) {
1003
- try {
1004
- const result = await getBasenameLinkedTo(
1005
- "/dev/disk/by-label",
1006
- resolve3(devicePath)
1007
- );
1008
- debug("[getLabelFromDevDisk] result: %o", result);
1009
- return result;
1010
- } catch (error) {
1011
- debug("[getLabelFromDevDisk] failed: " + error);
1012
- return;
1013
- }
1014
- }
1015
- async function getBasenameLinkedTo(linkDir, linkPath) {
1016
- for await (const ea of readLinks(linkDir)) {
1017
- if (ea.linkTarget === linkPath) {
1018
- return decodeEscapeSequences(ea.dirent.name);
1019
- }
1020
- }
1021
- return;
1022
- }
1023
- async function* readLinks(directory) {
1024
- for (const dirent of await readdir(directory, { withFileTypes: true })) {
1025
- if (dirent.isSymbolicLink()) {
1026
- try {
1027
- const linkTarget = resolve3(
1028
- directory,
1029
- await readlink(join3(directory, dirent.name))
1030
- );
1031
- yield { dirent, linkTarget };
1032
- } catch {
1033
- }
1034
- }
1035
- }
1036
- }
1037
-
1038
- // src/unc.ts
1039
- function parseUNCPath(path) {
1040
- if (path == null || isBlank(path) || !isString(path)) {
1041
- return;
1042
- }
1043
- if (!path.startsWith("\\\\") && !path.startsWith("//")) {
1044
- return;
1045
- }
1046
- const isForwardSlash = path.startsWith("//");
1047
- const slashChar = isForwardSlash ? "/" : "\\";
1048
- const parts = path.slice(2).split(slashChar);
1049
- if (parts.length < 2) {
1050
- return;
1051
- }
1052
- const [remoteHost, remoteShare] = parts;
1053
- if (remoteHost == null || isBlank(remoteHost) || remoteShare == null || isBlank(remoteShare)) {
1054
- return;
1055
- }
1056
- const invalidChars = /[<>:"|?*]/;
1057
- if (invalidChars.test(remoteHost) || invalidChars.test(remoteShare)) {
1058
- return;
1059
- }
1060
- const wrongSlash = isForwardSlash ? "\\" : "/";
1061
- if (path.includes(wrongSlash)) {
1062
- return;
1063
- }
1064
- return { remoteHost, remoteShare, remote: true };
1065
- }
1066
-
1067
- // src/uuid.ts
1068
- var uuidRegex = /[a-z0-9][a-z0-9-]{7,}/i;
1069
- function extractUUID(uuid) {
1070
- return toS(uuid).match(uuidRegex)?.[0];
1071
- }
1072
-
1073
1090
  // src/volume_metadata.ts
1074
1091
  async function getVolumeMetadata(o, nativeFn) {
1075
1092
  if (isBlank(o.mountPoint)) {
@@ -1268,3 +1285,4 @@ export {
1268
1285
  optionsWithDefaults,
1269
1286
  setHidden2 as setHidden
1270
1287
  };
1288
+ //# sourceMappingURL=index.mjs.map