@openclaw/fs-safe 0.8.2 → 0.8.4

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 (200) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +1 -1
  3. package/dist/absolute-path.d.ts.map +1 -1
  4. package/dist/absolute-path.js +8 -7
  5. package/dist/advanced.d.ts +2 -2
  6. package/dist/advanced.d.ts.map +1 -1
  7. package/dist/advanced.js +2 -2
  8. package/dist/archive-kind.d.ts +1 -0
  9. package/dist/archive-kind.d.ts.map +1 -1
  10. package/dist/archive-kind.js +6 -0
  11. package/dist/archive-limits.d.ts +0 -1
  12. package/dist/archive-limits.d.ts.map +1 -1
  13. package/dist/archive-limits.js +0 -3
  14. package/dist/archive-native.d.ts +1 -0
  15. package/dist/archive-native.d.ts.map +1 -1
  16. package/dist/archive-native.js +20 -76
  17. package/dist/archive-parser-errors.d.ts +2 -0
  18. package/dist/archive-parser-errors.d.ts.map +1 -0
  19. package/dist/archive-parser-errors.js +12 -0
  20. package/dist/archive-plan.d.ts +20 -0
  21. package/dist/archive-plan.d.ts.map +1 -0
  22. package/dist/archive-plan.js +55 -0
  23. package/dist/archive-read.d.ts.map +1 -1
  24. package/dist/archive-read.js +7 -13
  25. package/dist/archive-tar-inspect.d.ts +7 -0
  26. package/dist/archive-tar-inspect.d.ts.map +1 -0
  27. package/dist/archive-tar-inspect.js +59 -0
  28. package/dist/archive-tar-wasm.d.ts +1 -1
  29. package/dist/archive-tar-wasm.d.ts.map +1 -1
  30. package/dist/archive-tar-wasm.js +5 -8
  31. package/dist/archive-tar.d.ts +3 -1
  32. package/dist/archive-tar.d.ts.map +1 -1
  33. package/dist/archive-tar.js +12 -49
  34. package/dist/archive.d.ts +1 -0
  35. package/dist/archive.d.ts.map +1 -1
  36. package/dist/archive.js +54 -33
  37. package/dist/atomic.d.ts +1 -1
  38. package/dist/atomic.d.ts.map +1 -1
  39. package/dist/atomic.js +1 -1
  40. package/dist/bounded-read-stream.d.ts +1 -5
  41. package/dist/bounded-read-stream.d.ts.map +1 -1
  42. package/dist/bounded-read-stream.js +5 -13
  43. package/dist/bounded-read.d.ts.map +1 -1
  44. package/dist/bounded-read.js +31 -4
  45. package/dist/byte-budget.d.ts +0 -1
  46. package/dist/byte-budget.d.ts.map +1 -1
  47. package/dist/byte-budget.js +1 -1
  48. package/dist/directory-durability.js +5 -5
  49. package/dist/directory-guard.d.ts.map +1 -1
  50. package/dist/directory-guard.js +5 -6
  51. package/dist/directory-mode-owner.d.ts.map +1 -1
  52. package/dist/directory-mode-owner.js +2 -0
  53. package/dist/error-detail.d.ts +1 -0
  54. package/dist/error-detail.d.ts.map +1 -1
  55. package/dist/error-detail.js +6 -0
  56. package/dist/file-store-boundary.d.ts +1 -1
  57. package/dist/file-store-boundary.d.ts.map +1 -1
  58. package/dist/file-store-boundary.js +3 -14
  59. package/dist/file-store-prune.js +17 -8
  60. package/dist/file-store.js +3 -3
  61. package/dist/file-sync.d.ts +5 -0
  62. package/dist/file-sync.d.ts.map +1 -0
  63. package/dist/file-sync.js +19 -0
  64. package/dist/guarded-mkdir.d.ts.map +1 -1
  65. package/dist/guarded-mkdir.js +5 -4
  66. package/dist/guarded-mutation.d.ts +3 -0
  67. package/dist/guarded-mutation.d.ts.map +1 -1
  68. package/dist/guarded-mutation.js +5 -1
  69. package/dist/home-dir.d.ts +0 -10
  70. package/dist/home-dir.d.ts.map +1 -1
  71. package/dist/home-dir.js +0 -28
  72. package/dist/json-durable-queue-ownership.d.ts +1 -0
  73. package/dist/json-durable-queue-ownership.d.ts.map +1 -1
  74. package/dist/json-durable-queue-ownership.js +139 -18
  75. package/dist/json-durable-queue.d.ts.map +1 -1
  76. package/dist/json-durable-queue.js +5 -10
  77. package/dist/json-store.d.ts.map +1 -1
  78. package/dist/json-store.js +1 -1
  79. package/dist/local-roots.d.ts.map +1 -1
  80. package/dist/local-roots.js +2 -3
  81. package/dist/move-path-cleanup.d.ts +1 -1
  82. package/dist/move-path-cleanup.d.ts.map +1 -1
  83. package/dist/move-path-cleanup.js +4 -2
  84. package/dist/move-path.d.ts +9 -0
  85. package/dist/move-path.d.ts.map +1 -1
  86. package/dist/move-path.js +53 -16
  87. package/dist/native-binding.d.ts +2 -1
  88. package/dist/native-binding.d.ts.map +1 -1
  89. package/dist/native-operations.d.ts +0 -1
  90. package/dist/native-operations.d.ts.map +1 -1
  91. package/dist/native-operations.js +0 -10
  92. package/dist/native-pinned-write-windows.d.ts.map +1 -1
  93. package/dist/native-pinned-write-windows.js +8 -4
  94. package/dist/native-pinned-write.js +3 -3
  95. package/dist/native-staged-file.d.ts +10 -3
  96. package/dist/native-staged-file.d.ts.map +1 -1
  97. package/dist/native-staged-file.js +38 -13
  98. package/dist/opened-realpath.d.ts +12 -1
  99. package/dist/opened-realpath.d.ts.map +1 -1
  100. package/dist/opened-realpath.js +16 -14
  101. package/dist/output.d.ts.map +1 -1
  102. package/dist/output.js +26 -2
  103. package/dist/path-policy.js +3 -3
  104. package/dist/permissions.d.ts +1 -0
  105. package/dist/permissions.d.ts.map +1 -1
  106. package/dist/permissions.js +3 -0
  107. package/dist/pinned-write.d.ts +2 -2
  108. package/dist/pinned-write.d.ts.map +1 -1
  109. package/dist/pinned-write.js +17 -22
  110. package/dist/private-temp-workspace.js +1 -1
  111. package/dist/publish-file.js +2 -2
  112. package/dist/regular-file.js +8 -8
  113. package/dist/replace-file-copy-source.d.ts.map +1 -1
  114. package/dist/replace-file-copy-source.js +2 -7
  115. package/dist/replace-file-descriptor.d.ts.map +1 -1
  116. package/dist/replace-file-descriptor.js +11 -20
  117. package/dist/replace-file-temp-owner.d.ts.map +1 -1
  118. package/dist/replace-file-temp-owner.js +15 -14
  119. package/dist/replace-file.d.ts.map +1 -1
  120. package/dist/replace-file.js +21 -8
  121. package/dist/root-context.js +5 -5
  122. package/dist/root-errors.d.ts +1 -0
  123. package/dist/root-errors.d.ts.map +1 -1
  124. package/dist/root-errors.js +9 -0
  125. package/dist/root-file.d.ts.map +1 -1
  126. package/dist/root-file.js +17 -28
  127. package/dist/root-impl.d.ts +2 -1
  128. package/dist/root-impl.d.ts.map +1 -1
  129. package/dist/root-impl.js +46 -58
  130. package/dist/root-path-existing.d.ts.map +1 -1
  131. package/dist/root-path-existing.js +2 -3
  132. package/dist/root-path-symlink.d.ts.map +1 -1
  133. package/dist/root-path-symlink.js +2 -3
  134. package/dist/root-path.d.ts.map +1 -1
  135. package/dist/root-path.js +51 -97
  136. package/dist/root-paths.d.ts.map +1 -1
  137. package/dist/root-paths.js +16 -15
  138. package/dist/root-write-mode.d.ts +6 -0
  139. package/dist/root-write-mode.d.ts.map +1 -0
  140. package/dist/root-write-mode.js +61 -0
  141. package/dist/root-write-verification.js +8 -8
  142. package/dist/safe-path-segment.d.ts +1 -0
  143. package/dist/safe-path-segment.d.ts.map +1 -1
  144. package/dist/safe-path-segment.js +1 -1
  145. package/dist/secret-file.d.ts.map +1 -1
  146. package/dist/secret-file.js +4 -11
  147. package/dist/secret-read-async.d.ts.map +1 -1
  148. package/dist/secret-read-async.js +2 -10
  149. package/dist/secret-read-policy.d.ts +4 -0
  150. package/dist/secret-read-policy.d.ts.map +1 -1
  151. package/dist/secret-read-policy.js +12 -0
  152. package/dist/sibling-staged-file.d.ts.map +1 -1
  153. package/dist/sibling-staged-file.js +2 -7
  154. package/dist/sidecar-lock-policy.d.ts +0 -1
  155. package/dist/sidecar-lock-policy.d.ts.map +1 -1
  156. package/dist/sidecar-lock-policy.js +0 -4
  157. package/dist/strict-file-identity.d.ts +1 -1
  158. package/dist/strict-file-identity.d.ts.map +1 -1
  159. package/dist/string-coerce.d.ts +0 -9
  160. package/dist/string-coerce.d.ts.map +1 -1
  161. package/dist/string-coerce.js +0 -56
  162. package/dist/symlink-parents.d.ts.map +1 -1
  163. package/dist/symlink-parents.js +1 -2
  164. package/dist/temp-target.d.ts.map +1 -1
  165. package/dist/temp-target.js +1 -12
  166. package/docs/archive.md +57 -0
  167. package/docs/atomic.md +53 -19
  168. package/docs/reading.md +2 -0
  169. package/docs/root.md +10 -1
  170. package/docs/staged-file.md +6 -2
  171. package/docs/types.md +2 -1
  172. package/docs/writing.md +30 -2
  173. package/package.json +8 -8
  174. package/dist/archive-tar-extract.d.ts +0 -11
  175. package/dist/archive-tar-extract.d.ts.map +0 -1
  176. package/dist/archive-tar-extract.js +0 -49
  177. package/dist/fsync.d.ts +0 -2
  178. package/dist/fsync.d.ts.map +0 -1
  179. package/dist/fsync.js +0 -1
  180. package/dist/json-durable-queue-retirement.d.ts +0 -9
  181. package/dist/json-durable-queue-retirement.d.ts.map +0 -1
  182. package/dist/json-durable-queue-retirement.js +0 -126
  183. package/dist/json-durable-queue-transfer-lock.d.ts +0 -2
  184. package/dist/json-durable-queue-transfer-lock.d.ts.map +0 -1
  185. package/dist/json-durable-queue-transfer-lock.js +0 -19
  186. package/dist/mode.d.ts +0 -2
  187. package/dist/mode.d.ts.map +0 -1
  188. package/dist/mode.js +0 -3
  189. package/dist/output-sibling.d.ts +0 -8
  190. package/dist/output-sibling.d.ts.map +0 -1
  191. package/dist/output-sibling.js +0 -30
  192. package/dist/read-error.d.ts +0 -2
  193. package/dist/read-error.d.ts.map +0 -1
  194. package/dist/read-error.js +0 -11
  195. package/dist/short-path.d.ts +0 -2
  196. package/dist/short-path.d.ts.map +0 -1
  197. package/dist/short-path.js +0 -7
  198. package/dist/staged-file.d.ts +0 -10
  199. package/dist/staged-file.d.ts.map +0 -1
  200. package/dist/staged-file.js +0 -15
@@ -1,3 +1,4 @@
1
+ import fsSync, {} from "node:fs";
1
2
  import fs from "node:fs/promises";
2
3
  import path from "node:path";
3
4
  import { FsSafeError } from "./errors.js";
@@ -10,29 +11,29 @@ export async function pruneExpiredStoreEntries(params) {
10
11
  const maxDepth = params.options.maxDepth;
11
12
  const pruneEmptyDirs = (recursive || maxDepth !== undefined) && (params.options.pruneEmptyDirs ?? false);
12
13
  await fs.mkdir(params.rootDir, { recursive: true, mode: params.dirMode });
13
- const rootReal = await fs.realpath(params.rootDir);
14
+ const rootReal = fsSync.realpathSync.native(params.rootDir);
14
15
  const scopedRoot = await root(rootReal);
15
16
  const rootGuard = {
16
17
  dir: rootReal,
17
18
  realPath: rootReal,
18
- stat: await fs.lstat(rootReal),
19
+ stat: fsSync.lstatSync(rootReal),
19
20
  };
20
21
  async function assertRootGuard() {
21
- const stat = await fs.lstat(rootGuard.dir);
22
+ const stat = fsSync.lstatSync(rootGuard.dir);
22
23
  if (stat.isSymbolicLink() ||
23
24
  !stat.isDirectory() ||
24
25
  stat.dev !== rootGuard.stat.dev ||
25
26
  stat.ino !== rootGuard.stat.ino ||
26
- (await fs.realpath(rootGuard.dir)) !== rootGuard.realPath) {
27
+ fsSync.realpathSync.native(rootGuard.dir) !== rootGuard.realPath) {
27
28
  throw new FsSafeError("path-mismatch", "store root changed during prune");
28
29
  }
29
30
  }
30
31
  async function readStableDirectory(dir) {
31
- const before = await fs.lstat(dir).catch(() => null);
32
+ const before = observeOrNull(() => fsSync.lstatSync(dir));
32
33
  if (!before || before.isSymbolicLink() || !before.isDirectory()) {
33
34
  return null;
34
35
  }
35
- const real = await fs.realpath(dir).catch(() => null);
36
+ const real = observeOrNull(() => fsSync.realpathSync.native(dir));
36
37
  if (!real || !isPathInside(rootReal, real)) {
37
38
  return null;
38
39
  }
@@ -40,7 +41,7 @@ export async function pruneExpiredStoreEntries(params) {
40
41
  if (!entries) {
41
42
  return null;
42
43
  }
43
- const after = await fs.lstat(dir).catch(() => null);
44
+ const after = observeOrNull(() => fsSync.lstatSync(dir));
44
45
  if (!after || before.dev !== after.dev || before.ino !== after.ino) {
45
46
  return null;
46
47
  }
@@ -54,7 +55,7 @@ export async function pruneExpiredStoreEntries(params) {
54
55
  for (const entry of entries) {
55
56
  const fullPath = path.join(dir, entry.name);
56
57
  const relativePath = relativeDir ? `${relativeDir}/${entry.name}` : entry.name;
57
- const stat = await fs.lstat(fullPath).catch(() => null);
58
+ const stat = observeOrNull(() => fsSync.lstatSync(fullPath));
58
59
  if (!stat || stat.isSymbolicLink()) {
59
60
  continue;
60
61
  }
@@ -84,3 +85,11 @@ export async function pruneExpiredStoreEntries(params) {
84
85
  }
85
86
  await pruneDir(rootReal, "", 0);
86
87
  }
88
+ function observeOrNull(observe) {
89
+ try {
90
+ return observe();
91
+ }
92
+ catch {
93
+ return null;
94
+ }
95
+ }
@@ -11,7 +11,7 @@ import { writeFileSyncAtomic } from "./file-store-sync-write.js";
11
11
  import { createJsonStore } from "./json-document-store.js";
12
12
  import { stringifyJsonDocument } from "./json-stringify.js";
13
13
  import { isNotFoundPathError, resolveSafeRelativePath, splitSafeRelativePath } from "./path.js";
14
- import { throwFsSafeReadError } from "./read-error.js";
14
+ import { throwFsSafeReadError } from "./root-errors.js";
15
15
  import { root } from "./root.js";
16
16
  import { DEFAULT_ROOT_MAX_BYTES } from "./root-impl.js";
17
17
  import { readRegularFile } from "./regular-file.js";
@@ -66,7 +66,7 @@ function handleSyncStoreReadOpenFailure(opened) {
66
66
  });
67
67
  }
68
68
  async function readFileStoreCopySource(params) {
69
- const sourceStat = await fs.lstat(params.sourcePath);
69
+ const sourceStat = syncFs.lstatSync(params.sourcePath);
70
70
  if (sourceStat.isSymbolicLink() || !sourceStat.isFile()) {
71
71
  throw new FsSafeError("not-file", "source path is not a file");
72
72
  }
@@ -93,7 +93,7 @@ async function readFileStoreCopySource(params) {
93
93
  async function copyIntoRoot(params) {
94
94
  const relativePath = assertRelativePath(params.relativePath);
95
95
  const destination = resolveStorePath(params.rootDir, relativePath);
96
- const sourceStat = await fs.lstat(params.sourcePath);
96
+ const sourceStat = syncFs.lstatSync(params.sourcePath);
97
97
  if (sourceStat.isSymbolicLink() || !sourceStat.isFile()) {
98
98
  throw new FsSafeError("not-file", "source path is not a file");
99
99
  }
@@ -0,0 +1,5 @@
1
+ import fs from "node:fs";
2
+ import type { FileHandle } from "node:fs/promises";
3
+ export declare function syncFileBestEffort(handle: Pick<FileHandle, "sync">): Promise<void>;
4
+ export declare function syncFileBestEffortSync(fd: number, fsModule?: Pick<typeof fs, "fsyncSync">): void;
5
+ //# sourceMappingURL=file-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-sync.d.ts","sourceRoot":"","sources":["../src/file-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAMxF;AAED,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,MAAM,EACV,QAAQ,GAAE,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAM,GAC1C,IAAI,CAMN"}
@@ -0,0 +1,19 @@
1
+ import fs from "node:fs";
2
+ export async function syncFileBestEffort(handle) {
3
+ try {
4
+ await handle.sync();
5
+ }
6
+ catch (error) {
7
+ if (error?.code !== "EPERM")
8
+ throw error;
9
+ }
10
+ }
11
+ export function syncFileBestEffortSync(fd, fsModule = fs) {
12
+ try {
13
+ fsModule.fsyncSync(fd);
14
+ }
15
+ catch (error) {
16
+ if (error?.code !== "EPERM")
17
+ throw error;
18
+ }
19
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"guarded-mkdir.d.ts","sourceRoot":"","sources":["../src/guarded-mkdir.ts"],"names":[],"mappings":"AAyBA;;;;;GAKG;AACH,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,CAAC,CAuDlB"}
1
+ {"version":3,"file":"guarded-mkdir.d.ts","sourceRoot":"","sources":["../src/guarded-mkdir.ts"],"names":[],"mappings":"AA0BA;;;;;GAKG;AACH,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,CAAC,CAuDlB"}
@@ -1,3 +1,4 @@
1
+ import fsSync from "node:fs";
1
2
  import fs from "node:fs/promises";
2
3
  import path from "node:path";
3
4
  import { assertAsyncDirectoryGuard, createAsyncDirectoryGuard } from "./directory-guard.js";
@@ -10,7 +11,7 @@ function isSameOrChildPath(candidate, parent) {
10
11
  }
11
12
  async function realpathOrThrowNotFile(target) {
12
13
  try {
13
- return path.resolve(await fs.realpath(target));
14
+ return path.resolve(fsSync.realpathSync.native(target));
14
15
  }
15
16
  catch (error) {
16
17
  if (isNotFoundPathError(error)) {
@@ -29,7 +30,7 @@ async function realpathOrThrowNotFile(target) {
29
30
  */
30
31
  export async function mkdirPathComponentsWithGuards(params) {
31
32
  const root = path.resolve(params.rootReal);
32
- const rootCanonical = path.resolve(await fs.realpath(root));
33
+ const rootCanonical = path.resolve(fsSync.realpathSync.native(root));
33
34
  const target = path.resolve(params.targetPath);
34
35
  const relative = path.relative(root, target);
35
36
  if (isPathRelativeEscape(relative)) {
@@ -49,7 +50,7 @@ export async function mkdirPathComponentsWithGuards(params) {
49
50
  throw error;
50
51
  }
51
52
  }
52
- const stat = await fs.lstat(next);
53
+ const stat = fsSync.lstatSync(next);
53
54
  if ((params.rejectSymlinks && stat.isSymbolicLink()) || (!stat.isSymbolicLink() && !stat.isDirectory())) {
54
55
  throw directoryComponentNotDirectoryError();
55
56
  }
@@ -69,7 +70,7 @@ export async function mkdirPathComponentsWithGuards(params) {
69
70
  // every subsequent segment. Callers that need the final directory
70
71
  // (e.g. to guard it themselves after this function returns) must use
71
72
  // the returned resolved path, not their own lexical parent path.
72
- const targetStat = await fs.stat(nextReal);
73
+ const targetStat = fsSync.statSync(nextReal);
73
74
  if (!targetStat.isDirectory()) {
74
75
  throw directoryComponentNotDirectoryError();
75
76
  }
@@ -1,3 +1,4 @@
1
+ import { type BigIntStats } from "node:fs";
1
2
  import { type AnyAsyncDirectoryGuard, type SyncDirectoryGuard } from "./directory-guard.js";
2
3
  export declare function withAsyncDirectoryGuards<T>(guards: readonly AnyAsyncDirectoryGuard[], mutate: () => Promise<T>, options?: {
3
4
  verifyAfter?: boolean;
@@ -8,6 +9,8 @@ export declare function withSyncDirectoryGuards<T>(guards: readonly SyncDirector
8
9
  }): T;
9
10
  export declare function guardedRename(params: {
10
11
  assertBeforeRename?: () => void;
12
+ onSourceInspected?: (identity: Pick<BigIntStats, "dev" | "ino">) => void;
13
+ onRenamed?: () => void;
11
14
  from: string;
12
15
  to: string;
13
16
  targetRoot?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"guarded-mutation.d.ts","sourceRoot":"","sources":["../src/guarded-mutation.ts"],"names":[],"mappings":"AAGA,OAAO,EAOL,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACxB,MAAM,sBAAsB,CAAC;AAE9B,wBAAsB,wBAAwB,CAAC,CAAC,EAC9C,MAAM,EAAE,SAAS,sBAAsB,EAAE,EACzC,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACxB,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACrE,GACL,OAAO,CAAC,CAAC,CAAC,CAyBZ;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,MAAM,EAAE,MAAM,CAAC,EACf,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACtC,CAAC,CAWH;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAC1C,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,OAAO,CAAC,IAAI,CAAC,CAchB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,IAAI,CAUP;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,IAAI,CAWP"}
1
+ {"version":3,"file":"guarded-mutation.d.ts","sourceRoot":"","sources":["../src/guarded-mutation.ts"],"names":[],"mappings":"AAAA,OAAe,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAGnD,OAAO,EAOL,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACxB,MAAM,sBAAsB,CAAC;AAE9B,wBAAsB,wBAAwB,CAAC,CAAC,EAC9C,MAAM,EAAE,SAAS,sBAAsB,EAAE,EACzC,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACxB,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACrE,GACL,OAAO,CAAC,CAAC,CAAC,CAyBZ;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,MAAM,EAAE,MAAM,CAAC,EACf,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACtC,CAAC,CAWH;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAC1C,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC;IACzE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,IAAI,CAUP;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,IAAI,CAWP"}
@@ -1,4 +1,4 @@
1
- import fsSync from "node:fs";
1
+ import fsSync, {} from "node:fs";
2
2
  import fs from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { assertAsyncDirectoryGuard, assertSyncDirectoryGuard, createAsyncDirectoryGuard, createNearestExistingDirectoryGuard, createNearestExistingSyncDirectoryGuard, createSyncDirectoryGuard, } from "./directory-guard.js";
@@ -48,9 +48,13 @@ export async function guardedRename(params) {
48
48
  ? await createNearestExistingDirectoryGuard(params.targetRoot, path.dirname(params.to))
49
49
  : await createAsyncDirectoryGuard(path.dirname(params.to));
50
50
  await withAsyncDirectoryGuards([sourceGuard, targetGuard], async () => {
51
+ if (params.onSourceInspected) {
52
+ params.onSourceInspected(await fs.lstat(params.from, { bigint: true }));
53
+ }
51
54
  // Authority must survive all awaited guards; do not yield before rename dispatch.
52
55
  params.assertBeforeRename?.();
53
56
  await fs.rename(params.from, params.to);
57
+ params.onRenamed?.();
54
58
  }, { verifyAfter: params.verifyAfter });
55
59
  }
56
60
  export function guardedRenameSync(params) {
@@ -1,7 +1,5 @@
1
1
  export declare function resolveEffectiveHomeDir(env?: NodeJS.ProcessEnv, homedir?: () => string): string | undefined;
2
- export declare function resolveOsHomeDir(env?: NodeJS.ProcessEnv, homedir?: () => string): string | undefined;
3
2
  export declare function resolveRequiredHomeDir(env?: NodeJS.ProcessEnv, homedir?: () => string): string;
4
- export declare function resolveRequiredOsHomeDir(env?: NodeJS.ProcessEnv, homedir?: () => string): string;
5
3
  export declare function expandHomePrefix(input: string, opts?: {
6
4
  home?: string;
7
5
  env?: NodeJS.ProcessEnv;
@@ -11,12 +9,4 @@ export declare function resolveHomeRelativePath(input: string, opts?: {
11
9
  env?: NodeJS.ProcessEnv;
12
10
  homedir?: () => string;
13
11
  }): string;
14
- export declare function resolveUserPath(input: string, optsOrEnv?: {
15
- env?: NodeJS.ProcessEnv;
16
- homedir?: () => string;
17
- } | NodeJS.ProcessEnv, homedir?: () => string): string;
18
- export declare function resolveOsHomeRelativePath(input: string, opts?: {
19
- env?: NodeJS.ProcessEnv;
20
- homedir?: () => string;
21
- }): string;
22
12
  //# sourceMappingURL=home-dir.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"home-dir.d.ts","sourceRoot":"","sources":["../src/home-dir.ts"],"names":[],"mappings":"AAeA,wBAAgB,uBAAuB,CACrC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,OAAO,GAAE,MAAM,MAAmB,GACjC,MAAM,GAAG,SAAS,CAGpB;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,OAAO,GAAE,MAAM,MAAmB,GACjC,MAAM,GAAG,SAAS,CAGpB;AAyCD,wBAAgB,sBAAsB,CACpC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,OAAO,GAAE,MAAM,MAAmB,GACjC,MAAM,CAER;AAED,wBAAgB,wBAAwB,CACtC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,OAAO,GAAE,MAAM,MAAmB,GACjC,MAAM,CAER;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;IACL,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC;CACxB,GACA,MAAM,CAYR;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;IACL,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC;CACxB,GACA,MAAM,CAcR;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EACN;IACE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC;CACxB,GACD,MAAM,CAAC,UAAU,EACrB,OAAO,CAAC,EAAE,MAAM,MAAM,GACrB,MAAM,CAMR;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;IACL,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC;CACxB,GACA,MAAM,CAcR"}
1
+ {"version":3,"file":"home-dir.d.ts","sourceRoot":"","sources":["../src/home-dir.ts"],"names":[],"mappings":"AAeA,wBAAgB,uBAAuB,CACrC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,OAAO,GAAE,MAAM,MAAmB,GACjC,MAAM,GAAG,SAAS,CAGpB;AAyCD,wBAAgB,sBAAsB,CACpC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,OAAO,GAAE,MAAM,MAAmB,GACjC,MAAM,CAER;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;IACL,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC;CACxB,GACA,MAAM,CAYR;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;IACL,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC;CACxB,GACA,MAAM,CAcR"}
package/dist/home-dir.js CHANGED
@@ -15,10 +15,6 @@ export function resolveEffectiveHomeDir(env = process.env, homedir = os.homedir)
15
15
  const raw = resolveRawHomeDir(env, homedir);
16
16
  return raw ? path.resolve(raw) : undefined;
17
17
  }
18
- export function resolveOsHomeDir(env = process.env, homedir = os.homedir) {
19
- const raw = resolveRawOsHomeDir(env, homedir);
20
- return raw ? path.resolve(raw) : undefined;
21
- }
22
18
  function resolveRawHomeDir(env, homedir) {
23
19
  const explicitHome = normalize(env.OPENCLAW_HOME);
24
20
  if (!explicitHome) {
@@ -59,9 +55,6 @@ function normalizeSafe(homedir) {
59
55
  export function resolveRequiredHomeDir(env = process.env, homedir = os.homedir) {
60
56
  return resolveEffectiveHomeDir(env, homedir) ?? path.resolve(process.cwd());
61
57
  }
62
- export function resolveRequiredOsHomeDir(env = process.env, homedir = os.homedir) {
63
- return resolveOsHomeDir(env, homedir) ?? path.resolve(process.cwd());
64
- }
65
58
  export function expandHomePrefix(input, opts) {
66
59
  const segments = path.normalize(input).split(path.sep);
67
60
  if (segments[0] !== "~") {
@@ -89,24 +82,3 @@ export function resolveHomeRelativePath(input, opts) {
89
82
  });
90
83
  return path.resolve(expanded);
91
84
  }
92
- export function resolveUserPath(input, optsOrEnv, homedir) {
93
- const opts = optsOrEnv && ("env" in optsOrEnv || "homedir" in optsOrEnv)
94
- ? optsOrEnv
95
- : { env: optsOrEnv, homedir };
96
- return resolveHomeRelativePath(input, opts);
97
- }
98
- export function resolveOsHomeRelativePath(input, opts) {
99
- if (!input) {
100
- return input;
101
- }
102
- const segments = path.normalize(input).split(path.sep);
103
- if (segments[0] !== "~") {
104
- return path.resolve(input);
105
- }
106
- const expanded = expandHomePrefix(input, {
107
- home: resolveRequiredOsHomeDir(opts?.env ?? process.env, opts?.homedir ?? os.homedir),
108
- env: opts?.env,
109
- homedir: opts?.homedir,
110
- });
111
- return path.resolve(expanded);
112
- }
@@ -13,4 +13,5 @@ export declare function moveDurableQueueEntryToFailed(params: {
13
13
  paths: DurableQueueEntryPathsLike;
14
14
  failedPath: string;
15
15
  }): Promise<void>;
16
+ export declare function getErrorCode(error: unknown): string | null;
16
17
  //# sourceMappingURL=json-durable-queue-ownership.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"json-durable-queue-ownership.d.ts","sourceRoot":"","sources":["../src/json-durable-queue-ownership.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAQF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,0BAA0B,GAAG,MAAM,CAKpF;AAwED,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,0BAA0B,EACjC,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACtC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB;AAED,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,OAAO,CAAC,CAalB;AAED,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,IAAI,CAAC,CAyBf;AAED,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,KAAK,EAAE,0BAA0B,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDhB"}
1
+ {"version":3,"file":"json-durable-queue-ownership.d.ts","sourceRoot":"","sources":["../src/json-durable-queue-ownership.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,0BAA0B,GAAG,MAAM,CAKpF;AA+DD,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,0BAA0B,EACjC,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACtC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB;AAED,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,OAAO,CAAC,CAalB;AAED,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,IAAI,CAAC,CAyBf;AAED,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,KAAK,EAAE,0BAA0B,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDhB;AAKD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAI1D"}
@@ -1,16 +1,11 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { withSidecarLock } from "./sidecar-lock.js";
1
3
  import fs from "node:fs/promises";
2
4
  import path from "node:path";
3
5
  import { syncDirectory } from "./directory-durability.js";
4
6
  import { FsSafeError } from "./errors.js";
5
- import { sameFileIdentityForCleanup } from "./file-identity.js";
6
- import { recoverDurableQueueRetirement, retireDurableQueueSource, } from "./json-durable-queue-retirement.js";
7
- import { withQueueTransferLock } from "./json-durable-queue-transfer-lock.js";
7
+ import { sameFileIdentityForCleanup, sha256Hex } from "./file-identity.js";
8
8
  import { serializePathWrite } from "./write-queue.js";
9
- function getErrorCode(error) {
10
- return error && typeof error === "object" && "code" in error
11
- ? String(error.code)
12
- : null;
13
- }
14
9
  export function durableQueueProcessingPath(paths) {
15
10
  if (paths.processingPath)
16
11
  return paths.processingPath;
@@ -18,16 +13,6 @@ export function durableQueueProcessingPath(paths) {
18
13
  ? `${paths.jsonPath.slice(0, -".json".length)}.processing`
19
14
  : `${paths.jsonPath}.processing`;
20
15
  }
21
- async function lstatOrNull(filePath) {
22
- try {
23
- return await fs.lstat(filePath, { bigint: true });
24
- }
25
- catch (error) {
26
- if (getErrorCode(error) === "ENOENT")
27
- return null;
28
- throw error;
29
- }
30
- }
31
16
  async function regularQueueFileIdentity(filePath) {
32
17
  const identity = await lstatOrNull(filePath);
33
18
  if (!identity)
@@ -169,3 +154,139 @@ export async function moveDurableQueueEntryToFailed(params) {
169
154
  await syncDirectory(path.dirname(sourcePath));
170
155
  });
171
156
  }
157
+ const RETIREMENT_ROOT_NAME = ".fs-safe-retirements";
158
+ const RETIREMENT_ENTRY_NAME = "entry";
159
+ export function getErrorCode(error) {
160
+ return error && typeof error === "object" && "code" in error
161
+ ? String(error.code)
162
+ : null;
163
+ }
164
+ async function lstatOrNull(filePath) {
165
+ try {
166
+ return await fs.lstat(filePath, { bigint: true });
167
+ }
168
+ catch (error) {
169
+ if (getErrorCode(error) === "ENOENT")
170
+ return null;
171
+ throw error;
172
+ }
173
+ }
174
+ function assertDirectory(identity, label) {
175
+ if (identity.isSymbolicLink() || !identity.isDirectory()) {
176
+ throw new FsSafeError("path-mismatch", `${label} is not an owned directory`);
177
+ }
178
+ }
179
+ async function regularFileIdentity(filePath) {
180
+ const identity = await lstatOrNull(filePath);
181
+ if (!identity)
182
+ return null;
183
+ if (identity.isSymbolicLink() || !identity.isFile()) {
184
+ throw new FsSafeError("path-mismatch", "queue retirement path is not a regular file");
185
+ }
186
+ return identity;
187
+ }
188
+ function retirementPaths(jsonPath) {
189
+ const rootPath = path.join(path.dirname(jsonPath), RETIREMENT_ROOT_NAME);
190
+ const dirPath = path.join(rootPath, path.basename(jsonPath));
191
+ return { dirPath, entryPath: path.join(dirPath, RETIREMENT_ENTRY_NAME), rootPath };
192
+ }
193
+ async function inspectRetirementRoot(jsonPath) {
194
+ const rootPath = retirementPaths(jsonPath).rootPath;
195
+ const root = await lstatOrNull(rootPath);
196
+ if (!root)
197
+ return null;
198
+ assertDirectory(root, "queue retirement root");
199
+ return rootPath;
200
+ }
201
+ async function ensureRetirementRoot(jsonPath) {
202
+ const parentPath = path.dirname(jsonPath);
203
+ const rootPath = retirementPaths(jsonPath).rootPath;
204
+ await fs.mkdir(rootPath, { mode: 0o700 }).catch((error) => {
205
+ if (getErrorCode(error) !== "EEXIST")
206
+ throw error;
207
+ });
208
+ const root = await fs.lstat(rootPath, { bigint: true });
209
+ assertDirectory(root, "queue retirement root");
210
+ await syncDirectory(parentPath);
211
+ return rootPath;
212
+ }
213
+ async function removeRetirementRecord(params) {
214
+ await fs.rmdir(params.dirPath).catch((error) => {
215
+ if (getErrorCode(error) !== "ENOENT")
216
+ throw error;
217
+ });
218
+ await syncDirectory(params.rootPath);
219
+ }
220
+ async function recoverDurableQueueRetirement(params) {
221
+ const rootPath = await inspectRetirementRoot(params.jsonPath);
222
+ if (!rootPath)
223
+ return;
224
+ const { dirPath, entryPath } = retirementPaths(params.jsonPath);
225
+ const dir = await lstatOrNull(dirPath);
226
+ if (!dir)
227
+ return;
228
+ assertDirectory(dir, "queue retirement record");
229
+ const names = await fs.readdir(dirPath);
230
+ if (names.length === 0) {
231
+ await removeRetirementRecord({ dirPath, rootPath });
232
+ return;
233
+ }
234
+ if (names.length !== 1 || names[0] !== RETIREMENT_ENTRY_NAME) {
235
+ throw new FsSafeError("path-mismatch", "queue retirement record is ambiguous");
236
+ }
237
+ const entry = await regularFileIdentity(entryPath);
238
+ const processing = await regularFileIdentity(params.processingPath);
239
+ if (!entry || !processing) {
240
+ throw new FsSafeError("path-mismatch", "queue retirement ownership is incomplete");
241
+ }
242
+ if (!sameFileIdentityForCleanup(entry, processing)) {
243
+ const pending = await regularFileIdentity(params.jsonPath);
244
+ if (!pending) {
245
+ await fs.link(entryPath, params.jsonPath);
246
+ await syncDirectory(path.dirname(params.jsonPath));
247
+ }
248
+ else if (sameFileIdentityForCleanup(pending, entry)) {
249
+ await syncDirectory(path.dirname(params.jsonPath));
250
+ }
251
+ else if (pending.nlink > 1n) {
252
+ throw new FsSafeError("path-mismatch", "queue replacement identity is ambiguous");
253
+ }
254
+ }
255
+ await fs.unlink(entryPath);
256
+ await syncDirectory(dirPath);
257
+ await removeRetirementRecord({ dirPath, rootPath });
258
+ }
259
+ async function retireDurableQueueSource(params) {
260
+ await recoverDurableQueueRetirement(params);
261
+ const rootPath = await ensureRetirementRoot(params.jsonPath);
262
+ const { dirPath, entryPath } = retirementPaths(params.jsonPath);
263
+ await fs.mkdir(dirPath, { mode: 0o700 });
264
+ await syncDirectory(rootPath);
265
+ try {
266
+ await fs.rename(params.jsonPath, entryPath);
267
+ }
268
+ catch (error) {
269
+ if (getErrorCode(error) !== "ENOENT")
270
+ throw error;
271
+ await removeRetirementRecord({ dirPath, rootPath });
272
+ return;
273
+ }
274
+ await syncDirectory(dirPath);
275
+ await syncDirectory(path.dirname(params.jsonPath));
276
+ await recoverDurableQueueRetirement(params);
277
+ }
278
+ async function withQueueTransferLock(filePath, run) {
279
+ const lockPath = path.join(path.dirname(filePath), `.fs-safe-transfer-${sha256Hex(path.basename(filePath)).slice(0, 32)}.lock`);
280
+ return await withSidecarLock(filePath, {
281
+ managerKey: "fs-safe.queue-transfer",
282
+ lockPath,
283
+ staleMs: 30_000,
284
+ staleRecovery: "fail-closed",
285
+ timeoutMs: 45_000,
286
+ payload: () => ({
287
+ ownerToken: randomUUID(),
288
+ createdAt: new Date().toISOString(),
289
+ }),
290
+ retry: { retries: 180, minTimeout: 25, maxTimeout: 250, factor: 1.1 },
291
+ }, run);
292
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"json-durable-queue.d.ts","sourceRoot":"","sources":["../src/json-durable-queue.ts"],"names":[],"mappings":"AAkBA,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,0BAA0B,CAAC,CAAC,IAAI;IAC1C,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,2BAA2B,CAAC,CAAC,IAAI;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAOF,eAAO,MAAM,0CAA0C,QAAmB,CAAC;AAY3E,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;AAED,wBAAsB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUpF;AAmBD,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,GACT,0BAA0B,CAO5B;AAED,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhB;AAgLD,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhB;AA6DD,wBAAsB,yBAAyB,CAAC,CAAC,EAC/C,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,OAAO,CAAC,CAAC,CAAC,CASZ;AAED,wBAAsB,wBAAwB,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/F;AAED,wBAAsB,yBAAyB,CAAC,CAAC,EAAE,MAAM,EAAE;IACzD,KAAK,EAAE,0BAA0B,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAsBpB;AAED,wBAAsB,kCAAkC,CAAC,CAAC,EACxD,OAAO,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACtC,OAAO,CAAC,CAAC,EAAE,CAAC,CA8Dd;AAED,wBAAsB,iCAAiC,CAAC,MAAM,EAAE;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;CACZ,GAAG,OAAO,CAAC,IAAI,CAAC,CAShB"}
1
+ {"version":3,"file":"json-durable-queue.d.ts","sourceRoot":"","sources":["../src/json-durable-queue.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,0BAA0B,CAAC,CAAC,IAAI;IAC1C,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,2BAA2B,CAAC,CAAC,IAAI;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAOF,eAAO,MAAM,0CAA0C,QAAmB,CAAC;AAM3E,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;AAED,wBAAsB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUpF;AAmBD,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,GACT,0BAA0B,CAO5B;AAED,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhB;AAgLD,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhB;AA6DD,wBAAsB,yBAAyB,CAAC,CAAC,EAC/C,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,OAAO,CAAC,CAAC,CAAC,CASZ;AAED,wBAAsB,wBAAwB,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/F;AAED,wBAAsB,yBAAyB,CAAC,CAAC,EAAE,MAAM,EAAE;IACzD,KAAK,EAAE,0BAA0B,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAsBpB;AAED,wBAAsB,kCAAkC,CAAC,CAAC,EACxD,OAAO,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACtC,OAAO,CAAC,CAAC,EAAE,CAAC,CA8Dd;AAED,wBAAsB,iCAAiC,CAAC,MAAM,EAAE;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;CACZ,GAAG,OAAO,CAAC,IAAI,CAAC,CAShB"}
@@ -3,18 +3,13 @@ import path from "node:path";
3
3
  import { normalizeMaxBytes } from "./byte-budget.js";
4
4
  import { syncDirectory } from "./directory-durability.js";
5
5
  import { syncQueueDirectoryCreation } from "./json-durable-queue-directory.js";
6
- import { acknowledgeDurableQueueEntry, claimDurableQueueEntry, completeDeliveredQueueEntry, moveDurableQueueEntryToFailed, } from "./json-durable-queue-ownership.js";
6
+ import { getErrorCode, acknowledgeDurableQueueEntry, claimDurableQueueEntry, completeDeliveredQueueEntry, moveDurableQueueEntryToFailed, } from "./json-durable-queue-ownership.js";
7
7
  import { stringifyJsonDocument } from "./json-stringify.js";
8
8
  import { resolveReadOpenFlags } from "./read-open-flags.js";
9
9
  import { replaceFileAtomicWithDirectorySync } from "./replace-file.js";
10
10
  import { assertSafePathSegment } from "./safe-path-segment.js";
11
11
  import { inspectFileIdentity } from "./strict-file-identity.js";
12
12
  export const DEFAULT_JSON_DURABLE_QUEUE_ENTRY_MAX_BYTES = 16 * 1024 * 1024;
13
- function getErrnoCode(error) {
14
- return error && typeof error === "object" && "code" in error
15
- ? String(error.code)
16
- : null;
17
- }
18
13
  function assertSafeQueueEntryId(id) {
19
14
  assertSafePathSegment(id, { label: "queue entry id" });
20
15
  }
@@ -27,7 +22,7 @@ export async function jsonDurableQueueEntryExists(filePath) {
27
22
  return stat.isFile();
28
23
  }
29
24
  catch (error) {
30
- if (getErrnoCode(error) === "ENOENT") {
25
+ if (getErrorCode(error) === "ENOENT") {
31
26
  return false;
32
27
  }
33
28
  throw error;
@@ -41,7 +36,7 @@ async function unlinkStaleTmpBestEffort(filePath, now, maxAgeMs) {
41
36
  }
42
37
  }
43
38
  catch (error) {
44
- if (getErrnoCode(error) !== "ENOENT") {
39
+ if (getErrorCode(error) !== "ENOENT") {
45
40
  throw error;
46
41
  }
47
42
  }
@@ -302,7 +297,7 @@ export async function loadJsonDurableQueueEntry(params) {
302
297
  return result.entry;
303
298
  }
304
299
  catch (error) {
305
- if (getErrnoCode(error) === "ENOENT") {
300
+ if (getErrorCode(error) === "ENOENT") {
306
301
  return null;
307
302
  }
308
303
  throw error;
@@ -314,7 +309,7 @@ export async function loadPendingJsonDurableQueueEntries(options) {
314
309
  files = await fs.promises.readdir(options.queueDir);
315
310
  }
316
311
  catch (error) {
317
- if (getErrnoCode(error) === "ENOENT") {
312
+ if (getErrorCode(error) === "ENOENT") {
318
313
  return [];
319
314
  }
320
315
  throw error;
@@ -1 +1 @@
1
- {"version":3,"file":"json-store.d.ts","sourceRoot":"","sources":["../src/json-store.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,SAAS,EACd,KAAK,oBAAoB,EAC1B,MAAM,0BAA0B,CAAC;AAElC,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,oBAAoB,GAAG;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,oBAAoB,EAAE,CAAC;AAEtE,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAQvE"}
1
+ {"version":3,"file":"json-store.d.ts","sourceRoot":"","sources":["../src/json-store.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,SAAS,EACd,KAAK,oBAAoB,EAC1B,MAAM,0BAA0B,CAAC;AAElC,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,oBAAoB,GAAG;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,oBAAoB,EAAE,CAAC;AAEtE,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAQvE"}
@@ -1,6 +1,6 @@
1
1
  import path from "node:path";
2
2
  import { fileStore } from "./file-store.js";
3
- import { createJsonStore, } from "./json-document-store.js";
3
+ import {} from "./json-document-store.js";
4
4
  export function jsonStore(options) {
5
5
  const filePath = path.resolve(options.filePath);
6
6
  return fileStore({
@@ -1 +1 @@
1
- {"version":3,"file":"local-roots.d.ts","sourceRoot":"","sources":["../src/local-roots.ts"],"names":[],"mappings":"AAQA,OAAO,EAAQ,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAE3F,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG;IAC9C,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAAG,sBAAsB,GAAG;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG,sBAAsB,GAAG;IACnE,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B,CAAC;AAgDF,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,oCAAoC,GAC5C,oBAAoB,GAAG,IAAI,CAuC7B;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CA4CtC"}
1
+ {"version":3,"file":"local-roots.d.ts","sourceRoot":"","sources":["../src/local-roots.ts"],"names":[],"mappings":"AAQA,OAAO,EAAQ,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAE3F,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG;IAC9C,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAAG,sBAAsB,GAAG;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG,sBAAsB,GAAG;IACnE,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B,CAAC;AAgDF,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,oCAAoC,GAC5C,oBAAoB,GAAG,IAAI,CAuC7B;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CA2CtC"}
@@ -2,7 +2,7 @@ import fsSync from "node:fs";
2
2
  import path from "node:path";
3
3
  import { normalizeMaxBytes } from "./byte-budget.js";
4
4
  import { FsSafeError } from "./errors.js";
5
- import { expandHomePrefix, resolveUserPath } from "./home-dir.js";
5
+ import { expandHomePrefix, resolveHomeRelativePath } from "./home-dir.js";
6
6
  import { isFileUrl, safeFileURLToPath } from "./local-file-access.js";
7
7
  import { isPathInside } from "./path.js";
8
8
  import { resolveRootPathSync } from "./root-path.js";
@@ -20,7 +20,7 @@ function resolveLocalPathInput(input, label) {
20
20
  if (input.includes("\0")) {
21
21
  throw new FsSafeError("invalid-path", `${label} must not contain NUL bytes`);
22
22
  }
23
- return resolveUserPath(input);
23
+ return resolveHomeRelativePath(input);
24
24
  }
25
25
  function resolveLocalRootInput(input, label) {
26
26
  const trimmed = input.trim();
@@ -106,7 +106,6 @@ export async function readLocalFileFromRoots(options) {
106
106
  }
107
107
  const readOptions = {
108
108
  hardlinks: options.hardlinks,
109
- nonBlockingRead: options.nonBlockingRead,
110
109
  symlinks: options.symlinks,
111
110
  };
112
111
  // Leave maxBytes absent when the caller omits it so Root's own default
@@ -38,6 +38,6 @@ export declare function sameIdentity(a: EntryIdentity, b: EntryIdentity): boolea
38
38
  export declare function sourceChangedError(sourcePath: string): Error;
39
39
  export declare function assertSourceStillMatches(sourcePath: string, identity: EntryIdentity): Promise<void>;
40
40
  export declare function createCleanupCopiedEntryState(sourcePath: string, manifest: CopiedEntryManifest): CleanupCopiedEntryState;
41
- export declare function cleanupCopiedEntry(sourcePath: string, manifest: CopiedEntryManifest, state: CleanupCopiedEntryState): Promise<CleanupCopiedEntryResult>;
41
+ export declare function cleanupCopiedEntry(sourcePath: string, manifest: CopiedEntryManifest, state: CleanupCopiedEntryState, assertBeforeMutation: () => void): Promise<CleanupCopiedEntryResult>;
42
42
  export {};
43
43
  //# sourceMappingURL=move-path-cleanup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"move-path-cleanup.d.ts","sourceRoot":"","sources":["../src/move-path-cleanup.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAC3B,CAAC,aAAa,GAAG;IACf,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,mBAAmB,CAAA;KAAE,CAAC,CAAC;IACjE,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC,GACF,CAAC,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEvC,KAAK,wBAAwB,GAAG,SAAS,GAAG,OAAO,CAAC;AAEpD,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE,aAAa,CAAC;IACxB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC7C,CAAC;AAEF,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,aAAa,CAUhB;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAUxE;AAMD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,KAAK,CAI5D;AAED,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,aAAa,GACtB,OAAO,CAAC,IAAI,CAAC,CAIf;AA0BD,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,mBAAmB,GAC5B,uBAAuB,CAuBzB;AAsDD,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,mBAAmB,EAC7B,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,wBAAwB,CAAC,CAkDnC"}
1
+ {"version":3,"file":"move-path-cleanup.d.ts","sourceRoot":"","sources":["../src/move-path-cleanup.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAC3B,CAAC,aAAa,GAAG;IACf,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,mBAAmB,CAAA;KAAE,CAAC,CAAC;IACjE,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC,GACF,CAAC,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEvC,KAAK,wBAAwB,GAAG,SAAS,GAAG,OAAO,CAAC;AAEpD,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE,aAAa,CAAC;IACxB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC7C,CAAC;AAEF,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,aAAa,CAUhB;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAUxE;AAMD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,KAAK,CAI5D;AAED,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,aAAa,GACtB,OAAO,CAAC,IAAI,CAAC,CAIf;AA0BD,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,mBAAmB,GAC5B,uBAAuB,CAuBzB;AAsDD,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,mBAAmB,EAC7B,KAAK,EAAE,uBAAuB,EAC9B,oBAAoB,EAAE,MAAM,IAAI,GAC/B,OAAO,CAAC,wBAAwB,CAAC,CAyDnC"}