@photostructure/fs-metadata 0.1.5 → 0.2.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 (60) hide show
  1. package/CHANGELOG.md +30 -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 +234 -225
  7. package/dist/index.cjs.map +1 -0
  8. package/dist/index.mjs +232 -223
  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/volume_metadata.d.ts +3 -3
  17. package/dist/types/volume_mount_points.d.ts +9 -0
  18. package/package.json +9 -9
  19. package/prebuilds/darwin-arm64/@photostructure+fs-metadata.glibc.node +0 -0
  20. package/prebuilds/win32-x64/@photostructure+fs-metadata.glibc.node +0 -0
  21. package/src/array.ts +44 -0
  22. package/src/async.ts +145 -0
  23. package/src/debuglog.ts +30 -0
  24. package/src/defer.ts +30 -0
  25. package/src/error.ts +79 -0
  26. package/src/exports.ts +156 -0
  27. package/src/fs.ts +89 -0
  28. package/src/glob.ts +127 -0
  29. package/src/hidden.ts +249 -0
  30. package/src/index.cts +15 -0
  31. package/src/index.mts +17 -0
  32. package/src/linux/dev_disk.ts +77 -0
  33. package/src/linux/mount_points.ts +91 -0
  34. package/src/linux/mtab.ts +136 -0
  35. package/src/mount_point.ts +58 -0
  36. package/src/number.ts +21 -0
  37. package/src/object.ts +55 -0
  38. package/src/options.ts +179 -0
  39. package/src/path.ts +54 -0
  40. package/src/platform.ts +9 -0
  41. package/src/random.ts +40 -0
  42. package/src/remote_info.ts +161 -0
  43. package/src/setup.ts +69 -0
  44. package/src/string.ts +99 -0
  45. package/src/string_enum.ts +41 -0
  46. package/src/system_volume.ts +67 -0
  47. package/src/test-utils/assert.ts +69 -0
  48. package/src/test-utils/hidden-tests.ts +33 -0
  49. package/src/test-utils/jest-matchers.ts +29 -0
  50. package/src/test-utils/platform.ts +39 -0
  51. package/src/types/native_bindings.ts +64 -0
  52. package/src/types/node-gyp-build.d.ts +6 -0
  53. package/src/unc.ts +63 -0
  54. package/src/units.ts +31 -0
  55. package/src/uuid.ts +24 -0
  56. package/src/volume_health_status.ts +58 -0
  57. package/src/volume_metadata.ts +294 -0
  58. package/src/volume_mount_points.ts +109 -0
  59. package/tsup.config.ts +8 -0
  60. package/dist/types/cache.d.ts +0 -4
package/dist/index.cjs CHANGED
@@ -509,20 +509,6 @@ async function setHidden(pathname, hide, method, nativeFn) {
509
509
  return { pathname: norm, actions };
510
510
  }
511
511
 
512
- // src/array.ts
513
- function uniqBy(arr, keyFn) {
514
- const seen = /* @__PURE__ */ new Set();
515
- return arr.filter((item) => {
516
- const key = keyFn(item);
517
- if (key == null || seen.has(key)) return false;
518
- seen.add(key);
519
- return true;
520
- });
521
- }
522
-
523
- // src/linux/mount_points.ts
524
- var import_promises3 = require("fs/promises");
525
-
526
512
  // src/options.ts
527
513
  var import_node_os3 = require("os");
528
514
  var TimeoutMsDefault = 5e3;
@@ -540,6 +526,8 @@ var SystemPathPatternsDefault = [
540
526
  "/run/user/*/gvfs",
541
527
  "/snap/**",
542
528
  "/sys/**",
529
+ "**/#snapshot",
530
+ // Synology and Kubernetes volume snapshots
543
531
  // windows for linux:
544
532
  "/mnt/wslg/distro",
545
533
  "/mnt/wslg/doc",
@@ -607,116 +595,65 @@ function optionsWithDefaults(overrides = {}) {
607
595
  };
608
596
  }
609
597
 
610
- // src/glob.ts
611
- var cache = /* @__PURE__ */ new Map();
612
- function compileGlob(patterns) {
613
- if (patterns == null || patterns.length === 0) {
614
- return NeverMatchRE;
598
+ // src/linux/dev_disk.ts
599
+ var import_promises3 = require("fs/promises");
600
+ var import_node_path4 = require("path");
601
+ async function getUuidFromDevDisk(devicePath) {
602
+ try {
603
+ const result = await getBasenameLinkedTo(
604
+ "/dev/disk/by-uuid",
605
+ (0, import_node_path4.resolve)(devicePath)
606
+ );
607
+ debug("[getUuidFromDevDisk] result: %o", result);
608
+ return result;
609
+ } catch (error) {
610
+ debug("[getUuidFromDevDisk] failed: " + error);
611
+ return;
615
612
  }
616
- const patternsKey = JSON.stringify(patterns);
617
- {
618
- const prior = cache.get(patternsKey);
619
- if (prior != null) {
620
- return prior;
621
- }
613
+ }
614
+ async function getLabelFromDevDisk(devicePath) {
615
+ try {
616
+ const result = await getBasenameLinkedTo(
617
+ "/dev/disk/by-label",
618
+ (0, import_node_path4.resolve)(devicePath)
619
+ );
620
+ debug("[getLabelFromDevDisk] result: %o", result);
621
+ return result;
622
+ } catch (error) {
623
+ debug("[getLabelFromDevDisk] failed: " + error);
624
+ return;
622
625
  }
623
- const sorted = patterns.slice().filter(isNotBlank).sort();
624
- const sortedKey = JSON.stringify(sorted);
625
- {
626
- const prior = cache.get(sortedKey);
627
- if (prior != null) {
628
- cache.set(patternsKey, prior);
629
- return prior;
626
+ }
627
+ async function getBasenameLinkedTo(linkDir, linkPath) {
628
+ for await (const ea of readLinks(linkDir)) {
629
+ if (ea.linkTarget === linkPath) {
630
+ return decodeEscapeSequences(ea.dirent.name);
630
631
  }
631
632
  }
632
- const result = _compileGlob(sorted);
633
- if (cache.size > 256) {
634
- cache.clear();
635
- }
636
- cache.set(patternsKey, result);
637
- cache.set(sortedKey, result);
638
- return result;
633
+ return;
639
634
  }
640
- function _compileGlob(patterns) {
641
- const regexPatterns = patterns.map((pattern) => {
642
- let regex = "";
643
- let i = 0;
644
- while (i < pattern.length) {
645
- if (pattern[i] === "*" && pattern[i + 1] === "*") {
646
- regex += ".*";
647
- i += 2;
648
- if (pattern[i] === "/") {
649
- i++;
650
- }
651
- continue;
652
- }
653
- if (pattern[i] === "*") {
654
- regex += "[^/]*";
655
- i++;
656
- continue;
657
- }
658
- if (pattern[i] === "?") {
659
- regex += "[^/]";
660
- i++;
661
- continue;
662
- }
663
- if (pattern[i] === ".") {
664
- regex += "\\.";
665
- i++;
666
- continue;
667
- }
668
- if (pattern[i] === "/") {
669
- if (i === pattern.length - 1) {
670
- regex += "(?:/|$)";
671
- i++;
672
- continue;
673
- } else if (isWindows) {
674
- regex += "[\\/\\\\]";
675
- i++;
676
- continue;
677
- }
678
- }
679
- if (/[+^${}()|[\]\\]/.test(pattern[i])) {
680
- regex += "\\" + pattern[i];
681
- i++;
682
- continue;
635
+ async function* readLinks(directory) {
636
+ for (const dirent of await (0, import_promises3.readdir)(directory, { withFileTypes: true })) {
637
+ if (dirent.isSymbolicLink()) {
638
+ try {
639
+ const linkTarget = (0, import_node_path4.resolve)(
640
+ directory,
641
+ await (0, import_promises3.readlink)((0, import_node_path4.join)(directory, dirent.name))
642
+ );
643
+ yield { dirent, linkTarget };
644
+ } catch {
683
645
  }
684
- regex += pattern[i];
685
- i++;
686
- }
687
- return regex;
688
- });
689
- const final = regexPatterns.filter((ea) => ea.length > 0);
690
- return final.length === 0 ? (
691
- // Empty pattern matches nothing
692
- NeverMatchRE
693
- ) : new RegExp(`^(?:${final.join("|")})$`, "i");
694
- }
695
- var NeverMatchRE = /(?!)/;
696
-
697
- // src/system_volume.ts
698
- function isSystemVolume(mountPoint, fstype, config = {}) {
699
- debug("[isSystemVolume] checking %s (fstype: %s)", mountPoint, fstype);
700
- if (isWindows) {
701
- const systemDrive = normalizePath(process.env["SystemDrive"]);
702
- if (systemDrive != null && mountPoint === systemDrive) {
703
- debug("[isSystemVolume] %s is the Windows system drive", mountPoint);
704
- return true;
705
646
  }
706
647
  }
707
- const result = isNotBlank(fstype) && (config.systemFsTypes ?? SystemFsTypesDefault).has(fstype) || compileGlob(config.systemPathPatterns ?? SystemPathPatternsDefault).test(
708
- mountPoint
709
- );
710
- debug("[isSystemVolume] %s -> %s", mountPoint, result);
711
- return result;
712
648
  }
713
- function assignSystemVolume(mp, config) {
714
- const result = isSystemVolume(mp.mountPoint, mp.fstype, config);
715
- if (isWindows) {
716
- mp.isSystemVolume ??= result;
717
- } else {
718
- mp.isSystemVolume = result;
719
- }
649
+
650
+ // src/linux/mount_points.ts
651
+ var import_promises4 = require("fs/promises");
652
+
653
+ // src/mount_point.ts
654
+ function isMountPoint(obj) {
655
+ if (!isObject(obj)) return false;
656
+ return "mountPoint" in obj && isNotBlank(obj.mountPoint);
720
657
  }
721
658
 
722
659
  // src/remote_info.ts
@@ -822,6 +759,118 @@ function extractRemoteInfo(fsSpec) {
822
759
  return;
823
760
  }
824
761
 
762
+ // src/glob.ts
763
+ var cache = /* @__PURE__ */ new Map();
764
+ function compileGlob(patterns) {
765
+ if (patterns == null || patterns.length === 0) {
766
+ return NeverMatchRE;
767
+ }
768
+ const patternsKey = JSON.stringify(patterns);
769
+ {
770
+ const prior = cache.get(patternsKey);
771
+ if (prior != null) {
772
+ return prior;
773
+ }
774
+ }
775
+ const sorted = patterns.slice().filter(isNotBlank).sort();
776
+ const sortedKey = JSON.stringify(sorted);
777
+ {
778
+ const prior = cache.get(sortedKey);
779
+ if (prior != null) {
780
+ cache.set(patternsKey, prior);
781
+ return prior;
782
+ }
783
+ }
784
+ const result = _compileGlob(sorted);
785
+ if (cache.size > 256) {
786
+ cache.clear();
787
+ }
788
+ cache.set(patternsKey, result);
789
+ cache.set(sortedKey, result);
790
+ return result;
791
+ }
792
+ function _compileGlob(patterns) {
793
+ const regexPatterns = patterns.map((pattern) => {
794
+ let regex = "";
795
+ let i = 0;
796
+ while (i < pattern.length) {
797
+ if (pattern[i] === "*" && pattern[i + 1] === "*") {
798
+ regex += ".*";
799
+ i += 2;
800
+ if (pattern[i] === "/") {
801
+ i++;
802
+ }
803
+ continue;
804
+ }
805
+ if (pattern[i] === "*") {
806
+ regex += "[^/]*";
807
+ i++;
808
+ continue;
809
+ }
810
+ if (pattern[i] === "?") {
811
+ regex += "[^/]";
812
+ i++;
813
+ continue;
814
+ }
815
+ if (pattern[i] === ".") {
816
+ regex += "\\.";
817
+ i++;
818
+ continue;
819
+ }
820
+ if (pattern[i] === "/") {
821
+ if (i === pattern.length - 1) {
822
+ regex += "(?:/|$)";
823
+ i++;
824
+ continue;
825
+ } else if (isWindows) {
826
+ regex += "[\\/\\\\]";
827
+ i++;
828
+ continue;
829
+ }
830
+ }
831
+ if (/[+^${}()|[\]\\]/.test(pattern[i])) {
832
+ regex += "\\" + pattern[i];
833
+ i++;
834
+ continue;
835
+ }
836
+ regex += pattern[i];
837
+ i++;
838
+ }
839
+ return regex;
840
+ });
841
+ const final = regexPatterns.filter((ea) => ea.length > 0);
842
+ return final.length === 0 ? (
843
+ // Empty pattern matches nothing
844
+ NeverMatchRE
845
+ ) : new RegExp(`^(?:${final.join("|")})$`, "i");
846
+ }
847
+ var NeverMatchRE = /(?!)/;
848
+
849
+ // src/system_volume.ts
850
+ function isSystemVolume(mountPoint, fstype, config = {}) {
851
+ debug("[isSystemVolume] checking %s (fstype: %s)", mountPoint, fstype);
852
+ if (isWindows) {
853
+ const systemDrive = normalizePath(process.env["SystemDrive"]);
854
+ if (systemDrive != null && mountPoint === systemDrive) {
855
+ debug("[isSystemVolume] %s is the Windows system drive", mountPoint);
856
+ return true;
857
+ }
858
+ }
859
+ const result = isNotBlank(fstype) && (config.systemFsTypes ?? SystemFsTypesDefault).has(fstype) || compileGlob(config.systemPathPatterns ?? SystemPathPatternsDefault).test(
860
+ mountPoint
861
+ );
862
+ debug("[isSystemVolume] %s -> %s", mountPoint, result);
863
+ return result;
864
+ }
865
+ function assignSystemVolume(mp, config) {
866
+ const result = isSystemVolume(mp.mountPoint, mp.fstype, config);
867
+ if (isWindows) {
868
+ mp.isSystemVolume ??= result;
869
+ } else {
870
+ mp.isSystemVolume = result;
871
+ }
872
+ }
873
+
825
874
  // src/linux/mtab.ts
826
875
  function mountEntryToMountPoint(entry) {
827
876
  const mountPoint = normalizePosixPath(entry.fs_file);
@@ -883,7 +932,7 @@ async function getLinuxMountPoints(native, opts) {
883
932
  let cause;
884
933
  for (const input of o.linuxMountTablePaths) {
885
934
  try {
886
- const mtabContent = await (0, import_promises3.readFile)(input, "utf8");
935
+ const mtabContent = await (0, import_promises4.readFile)(input, "utf8");
887
936
  const arr = parseMtab(mtabContent).map((ea) => mountEntryToMountPoint(ea)).filter((ea) => ea != null);
888
937
  debug("[getLinuxMountPoints] %s mount points: %o", input, arr);
889
938
  if (arr.length > 0) {
@@ -899,7 +948,6 @@ async function getLinuxMountPoints(native, opts) {
899
948
  const prior = byMountPoint.get(ea.mountPoint);
900
949
  const merged = { ...compactValues(prior), ...compactValues(ea) };
901
950
  if (isMountPoint(merged)) {
902
- assignSystemVolume(merged, o);
903
951
  byMountPoint.set(merged.mountPoint, merged);
904
952
  }
905
953
  }
@@ -910,15 +958,17 @@ async function getLinuxMountPoints(native, opts) {
910
958
  );
911
959
  }
912
960
  const results = [...byMountPoint.values()];
913
- debug("[getLinuxMountPoints] found %d mount points", results.length);
914
- return o.includeSystemVolumes ? results : results.filter((ea) => !ea.isSystemVolume);
961
+ debug("[getLinuxMountPoints] %o", {
962
+ results: results.map((ea) => ea.mountPoint)
963
+ });
964
+ return results;
915
965
  }
916
966
  async function getLinuxMtabMetadata(mountPoint, opts) {
917
967
  let caughtError;
918
968
  const inputs = optionsWithDefaults(opts).linuxMountTablePaths;
919
969
  for (const input of inputs) {
920
970
  try {
921
- const mtabContent = await (0, import_promises3.readFile)(input, "utf8");
971
+ const mtabContent = await (0, import_promises4.readFile)(input, "utf8");
922
972
  for (const ea of parseMtab(mtabContent)) {
923
973
  if (ea.fs_file === mountPoint) {
924
974
  return ea;
@@ -934,6 +984,41 @@ async function getLinuxMtabMetadata(mountPoint, opts) {
934
984
  );
935
985
  }
936
986
 
987
+ // src/unc.ts
988
+ function parseUNCPath(path) {
989
+ if (path == null || isBlank(path) || !isString(path)) {
990
+ return;
991
+ }
992
+ if (!path.startsWith("\\\\") && !path.startsWith("//")) {
993
+ return;
994
+ }
995
+ const isForwardSlash = path.startsWith("//");
996
+ const slashChar = isForwardSlash ? "/" : "\\";
997
+ const parts = path.slice(2).split(slashChar);
998
+ if (parts.length < 2) {
999
+ return;
1000
+ }
1001
+ const [remoteHost, remoteShare] = parts;
1002
+ if (remoteHost == null || isBlank(remoteHost) || remoteShare == null || isBlank(remoteShare)) {
1003
+ return;
1004
+ }
1005
+ const invalidChars = /[<>:"|?*]/;
1006
+ if (invalidChars.test(remoteHost) || invalidChars.test(remoteShare)) {
1007
+ return;
1008
+ }
1009
+ const wrongSlash = isForwardSlash ? "\\" : "/";
1010
+ if (path.includes(wrongSlash)) {
1011
+ return;
1012
+ }
1013
+ return { remoteHost, remoteShare, remote: true };
1014
+ }
1015
+
1016
+ // src/uuid.ts
1017
+ var uuidRegex = /[a-z0-9][a-z0-9-]{7,}/i;
1018
+ function extractUUID(uuid) {
1019
+ return toS(uuid).match(uuidRegex)?.[0];
1020
+ }
1021
+
937
1022
  // src/string_enum.ts
938
1023
  function stringEnum(...o) {
939
1024
  const set = new Set(o);
@@ -977,18 +1062,25 @@ async function directoryStatus(dir, timeoutMs, canReaddirImpl = canReaddir) {
977
1062
  return { status: VolumeHealthStatuses.unknown };
978
1063
  }
979
1064
 
980
- // src/mount_point.ts
981
- function isMountPoint(obj) {
982
- if (!isObject(obj)) return false;
983
- return "mountPoint" in obj && isNotBlank(obj.mountPoint);
1065
+ // src/array.ts
1066
+ function uniqBy(arr, keyFn) {
1067
+ const seen = /* @__PURE__ */ new Set();
1068
+ return arr.filter((item) => {
1069
+ const key = keyFn(item);
1070
+ if (key == null || seen.has(key)) return false;
1071
+ seen.add(key);
1072
+ return true;
1073
+ });
984
1074
  }
1075
+
1076
+ // src/volume_mount_points.ts
985
1077
  async function getVolumeMountPoints(opts, nativeFn) {
986
1078
  const p2 = _getVolumeMountPoints(opts, nativeFn);
987
1079
  return isWindows ? p2 : withTimeout({ desc: "getVolumeMountPoints", ...opts, promise: p2 });
988
1080
  }
989
1081
  async function _getVolumeMountPoints(o, nativeFn) {
990
1082
  debug("[getVolumeMountPoints] gathering mount points with options: %o", o);
991
- const result = await (isWindows || isMacOS ? (async () => {
1083
+ const raw = await (isWindows || isMacOS ? (async () => {
992
1084
  debug("[getVolumeMountPoints] using native implementation");
993
1085
  const points = await (await nativeFn()).getVolumeMountPoints(o);
994
1086
  debug(
@@ -997,8 +1089,11 @@ async function _getVolumeMountPoints(o, nativeFn) {
997
1089
  );
998
1090
  return points;
999
1091
  })() : getLinuxMountPoints(nativeFn, o));
1000
- debug("[getVolumeMountPoints] raw mount points: %o", result);
1001
- const compacted = result.map((ea) => compactValues(ea)).filter((ea) => isNotBlank(ea.mountPoint));
1092
+ debug("[getVolumeMountPoints] raw mount points: %o", raw);
1093
+ const compacted = raw.map((ea) => compactValues(ea)).filter((ea) => isNotBlank(ea.mountPoint));
1094
+ for (const ea of compacted) {
1095
+ assignSystemVolume(ea, o);
1096
+ }
1002
1097
  const filtered = o.includeSystemVolumes ? compacted : compacted.filter((ea) => !ea.isSystemVolume);
1003
1098
  const uniq = uniqBy(filtered, (ea) => toNotBlank(ea.mountPoint));
1004
1099
  debug("[getVolumeMountPoints] found %d unique mount points", uniq.length);
@@ -1009,18 +1104,18 @@ async function _getVolumeMountPoints(o, nativeFn) {
1009
1104
  );
1010
1105
  await mapConcurrent({
1011
1106
  maxConcurrency: o.maxConcurrency,
1012
- items: results,
1107
+ items: results.filter(
1108
+ // trust but verify
1109
+ (ea) => isBlank(ea.status) || ea.status === "healthy"
1110
+ ),
1013
1111
  fn: async (mp) => {
1014
- assignSystemVolume(mp, o);
1015
- if ((toNotBlank(mp.status) ?? "healthy") === "healthy") {
1016
- debug("[getVolumeMountPoints] checking status of %s", mp.mountPoint);
1017
- mp.status = (await directoryStatus(mp.mountPoint, o.timeoutMs)).status;
1018
- debug(
1019
- "[getVolumeMountPoints] status for %s: %s",
1020
- mp.mountPoint,
1021
- mp.status
1022
- );
1023
- }
1112
+ debug("[getVolumeMountPoints] checking status of %s", mp.mountPoint);
1113
+ mp.status = (await directoryStatus(mp.mountPoint, o.timeoutMs)).status;
1114
+ debug(
1115
+ "[getVolumeMountPoints] status for %s: %s",
1116
+ mp.mountPoint,
1117
+ mp.status
1118
+ );
1024
1119
  }
1025
1120
  });
1026
1121
  debug(
@@ -1030,93 +1125,6 @@ async function _getVolumeMountPoints(o, nativeFn) {
1030
1125
  return results;
1031
1126
  }
1032
1127
 
1033
- // src/linux/dev_disk.ts
1034
- var import_promises4 = require("fs/promises");
1035
- var import_node_path4 = require("path");
1036
- async function getUuidFromDevDisk(devicePath) {
1037
- try {
1038
- const result = await getBasenameLinkedTo(
1039
- "/dev/disk/by-uuid",
1040
- (0, import_node_path4.resolve)(devicePath)
1041
- );
1042
- debug("[getUuidFromDevDisk] result: %o", result);
1043
- return result;
1044
- } catch (error) {
1045
- debug("[getUuidFromDevDisk] failed: " + error);
1046
- return;
1047
- }
1048
- }
1049
- async function getLabelFromDevDisk(devicePath) {
1050
- try {
1051
- const result = await getBasenameLinkedTo(
1052
- "/dev/disk/by-label",
1053
- (0, import_node_path4.resolve)(devicePath)
1054
- );
1055
- debug("[getLabelFromDevDisk] result: %o", result);
1056
- return result;
1057
- } catch (error) {
1058
- debug("[getLabelFromDevDisk] failed: " + error);
1059
- return;
1060
- }
1061
- }
1062
- async function getBasenameLinkedTo(linkDir, linkPath) {
1063
- for await (const ea of readLinks(linkDir)) {
1064
- if (ea.linkTarget === linkPath) {
1065
- return decodeEscapeSequences(ea.dirent.name);
1066
- }
1067
- }
1068
- return;
1069
- }
1070
- async function* readLinks(directory) {
1071
- for (const dirent of await (0, import_promises4.readdir)(directory, { withFileTypes: true })) {
1072
- if (dirent.isSymbolicLink()) {
1073
- try {
1074
- const linkTarget = (0, import_node_path4.resolve)(
1075
- directory,
1076
- await (0, import_promises4.readlink)((0, import_node_path4.join)(directory, dirent.name))
1077
- );
1078
- yield { dirent, linkTarget };
1079
- } catch {
1080
- }
1081
- }
1082
- }
1083
- }
1084
-
1085
- // src/unc.ts
1086
- function parseUNCPath(path) {
1087
- if (path == null || isBlank(path) || !isString(path)) {
1088
- return;
1089
- }
1090
- if (!path.startsWith("\\\\") && !path.startsWith("//")) {
1091
- return;
1092
- }
1093
- const isForwardSlash = path.startsWith("//");
1094
- const slashChar = isForwardSlash ? "/" : "\\";
1095
- const parts = path.slice(2).split(slashChar);
1096
- if (parts.length < 2) {
1097
- return;
1098
- }
1099
- const [remoteHost, remoteShare] = parts;
1100
- if (remoteHost == null || isBlank(remoteHost) || remoteShare == null || isBlank(remoteShare)) {
1101
- return;
1102
- }
1103
- const invalidChars = /[<>:"|?*]/;
1104
- if (invalidChars.test(remoteHost) || invalidChars.test(remoteShare)) {
1105
- return;
1106
- }
1107
- const wrongSlash = isForwardSlash ? "\\" : "/";
1108
- if (path.includes(wrongSlash)) {
1109
- return;
1110
- }
1111
- return { remoteHost, remoteShare, remote: true };
1112
- }
1113
-
1114
- // src/uuid.ts
1115
- var uuidRegex = /[a-z0-9][a-z0-9-]{7,}/i;
1116
- function extractUUID(uuid) {
1117
- return toS(uuid).match(uuidRegex)?.[0];
1118
- }
1119
-
1120
1128
  // src/volume_metadata.ts
1121
1129
  async function getVolumeMetadata(o, nativeFn) {
1122
1130
  if (isBlank(o.mountPoint)) {
@@ -1316,3 +1324,4 @@ var {
1316
1324
  optionsWithDefaults,
1317
1325
  setHidden
1318
1326
  });
1327
+ //# sourceMappingURL=index.cjs.map