@openclaw/fs-safe 0.14.0 → 0.15.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 (235) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +10 -4
  3. package/dist/advanced.d.ts +1 -1
  4. package/dist/advanced.d.ts.map +1 -1
  5. package/dist/advanced.js +1 -1
  6. package/dist/archive-merge.d.ts.map +1 -1
  7. package/dist/archive-merge.js +113 -46
  8. package/dist/archive-read.d.ts.map +1 -1
  9. package/dist/archive-read.js +4 -4
  10. package/dist/archive-zip-directory.d.ts +4 -0
  11. package/dist/archive-zip-directory.d.ts.map +1 -1
  12. package/dist/archive-zip-directory.js +2 -0
  13. package/dist/archive-zip-entry.d.ts +6 -2
  14. package/dist/archive-zip-entry.d.ts.map +1 -1
  15. package/dist/archive-zip-entry.js +23 -8
  16. package/dist/archive-zip-integrity.d.ts.map +1 -1
  17. package/dist/archive-zip-integrity.js +3 -4
  18. package/dist/archive-zip-loader.d.ts.map +1 -1
  19. package/dist/archive-zip-loader.js +107 -31
  20. package/dist/archive-zip-names.d.ts +1 -0
  21. package/dist/archive-zip-names.d.ts.map +1 -1
  22. package/dist/archive-zip-names.js +6 -0
  23. package/dist/archive.js +6 -5
  24. package/dist/bounded-read-stream.d.ts +0 -1
  25. package/dist/bounded-read-stream.d.ts.map +1 -1
  26. package/dist/bounded-read-stream.js +0 -6
  27. package/dist/copy-publication.d.ts +6 -0
  28. package/dist/copy-publication.d.ts.map +1 -1
  29. package/dist/copy-publication.js +3 -0
  30. package/dist/copy-tree-portable.d.ts.map +1 -1
  31. package/dist/copy-tree-portable.js +44 -24
  32. package/dist/copy.d.ts.map +1 -1
  33. package/dist/copy.js +29 -11
  34. package/dist/directory-mode-owner.js +5 -5
  35. package/dist/file-handle-transfer.d.ts +2 -0
  36. package/dist/file-handle-transfer.d.ts.map +1 -1
  37. package/dist/file-handle-transfer.js +57 -2
  38. package/dist/file-identity.d.ts.map +1 -1
  39. package/dist/file-identity.js +18 -4
  40. package/dist/file-lock-sync-admission.d.ts +19 -0
  41. package/dist/file-lock-sync-admission.d.ts.map +1 -0
  42. package/dist/file-lock-sync-admission.js +93 -0
  43. package/dist/file-lock-sync-root-acquire.d.ts +4 -0
  44. package/dist/file-lock-sync-root-acquire.d.ts.map +1 -0
  45. package/dist/file-lock-sync-root-acquire.js +370 -0
  46. package/dist/file-lock-sync-root-arbitration.d.ts +18 -0
  47. package/dist/file-lock-sync-root-arbitration.d.ts.map +1 -0
  48. package/dist/file-lock-sync-root-arbitration.js +66 -0
  49. package/dist/file-lock-sync-root-held.d.ts +34 -0
  50. package/dist/file-lock-sync-root-held.d.ts.map +1 -0
  51. package/dist/file-lock-sync-root-held.js +393 -0
  52. package/dist/file-lock-sync-root-io.d.ts +44 -0
  53. package/dist/file-lock-sync-root-io.d.ts.map +1 -0
  54. package/dist/file-lock-sync-root-io.js +209 -0
  55. package/dist/file-lock-sync-root-mutation.d.ts +17 -0
  56. package/dist/file-lock-sync-root-mutation.d.ts.map +1 -0
  57. package/dist/file-lock-sync-root-mutation.js +277 -0
  58. package/dist/file-lock-sync-root-options.d.ts +20 -0
  59. package/dist/file-lock-sync-root-options.d.ts.map +1 -0
  60. package/dist/file-lock-sync-root-options.js +58 -0
  61. package/dist/file-lock-sync-root-registration.d.ts +2 -0
  62. package/dist/file-lock-sync-root-registration.d.ts.map +1 -0
  63. package/dist/file-lock-sync-root-registration.js +90 -0
  64. package/dist/file-lock-sync-root.d.ts +36 -0
  65. package/dist/file-lock-sync-root.d.ts.map +1 -0
  66. package/dist/file-lock-sync-root.js +361 -0
  67. package/dist/file-lock-sync-stale-admission.d.ts +24 -0
  68. package/dist/file-lock-sync-stale-admission.d.ts.map +1 -0
  69. package/dist/file-lock-sync-stale-admission.js +205 -0
  70. package/dist/file-lock-sync.d.ts.map +1 -1
  71. package/dist/file-lock-sync.js +245 -205
  72. package/dist/file-store-prune.d.ts.map +1 -1
  73. package/dist/file-store-prune.js +5 -1
  74. package/dist/file-store-sync-write.js +3 -3
  75. package/dist/file-store.d.ts.map +1 -1
  76. package/dist/file-store.js +47 -12
  77. package/dist/json-document-store.d.ts.map +1 -1
  78. package/dist/json-document-store.js +22 -15
  79. package/dist/json-durable-queue-ownership.d.ts +0 -1
  80. package/dist/json-durable-queue-ownership.d.ts.map +1 -1
  81. package/dist/json-durable-queue-ownership.js +0 -6
  82. package/dist/native-binding.d.ts +2 -0
  83. package/dist/native-binding.d.ts.map +1 -1
  84. package/dist/native-parent-admission.d.ts +3 -2
  85. package/dist/native-parent-admission.d.ts.map +1 -1
  86. package/dist/native-parent-admission.js +24 -5
  87. package/dist/native-pinned-write-windows.d.ts.map +1 -1
  88. package/dist/native-pinned-write-windows.js +7 -7
  89. package/dist/native-pinned-write.d.ts.map +1 -1
  90. package/dist/native-pinned-write.js +7 -11
  91. package/dist/native-policy-parent-windows.d.ts +14 -0
  92. package/dist/native-policy-parent-windows.d.ts.map +1 -0
  93. package/dist/native-policy-parent-windows.js +200 -0
  94. package/dist/native-rename-outcome.d.ts +4 -0
  95. package/dist/native-rename-outcome.d.ts.map +1 -0
  96. package/dist/native-rename-outcome.js +8 -0
  97. package/dist/native-staged-file.d.ts +2 -2
  98. package/dist/native-staged-file.d.ts.map +1 -1
  99. package/dist/native-staged-file.js +42 -40
  100. package/dist/output.d.ts.map +1 -1
  101. package/dist/output.js +12 -8
  102. package/dist/path-prefix.d.ts.map +1 -1
  103. package/dist/path-prefix.js +30 -8
  104. package/dist/path-suffix-aliases.d.ts +2 -0
  105. package/dist/path-suffix-aliases.d.ts.map +1 -1
  106. package/dist/path-suffix-aliases.js +25 -17
  107. package/dist/permission-exec.d.ts +2 -0
  108. package/dist/permission-exec.d.ts.map +1 -1
  109. package/dist/permission-exec.js +150 -21
  110. package/dist/permissions-windows.js +1 -1
  111. package/dist/pinned-mutation-admission.d.ts.map +1 -1
  112. package/dist/pinned-mutation-admission.js +10 -5
  113. package/dist/pinned-mutation-observation.d.ts +0 -1
  114. package/dist/pinned-mutation-observation.d.ts.map +1 -1
  115. package/dist/pinned-mutation-observation.js +0 -19
  116. package/dist/pinned-mutation-shared-route.d.ts +1 -0
  117. package/dist/pinned-mutation-shared-route.d.ts.map +1 -1
  118. package/dist/pinned-mutation-shared-route.js +1 -1
  119. package/dist/pinned-write-types.d.ts +2 -0
  120. package/dist/pinned-write-types.d.ts.map +1 -1
  121. package/dist/private-temp-workspace.d.ts.map +1 -1
  122. package/dist/private-temp-workspace.js +75 -121
  123. package/dist/regular-file.d.ts.map +1 -1
  124. package/dist/regular-file.js +1 -15
  125. package/dist/replace-directory.d.ts.map +1 -1
  126. package/dist/replace-directory.js +256 -18
  127. package/dist/replace-file-copy-fallback.d.ts.map +1 -1
  128. package/dist/replace-file-copy-fallback.js +62 -70
  129. package/dist/replace-file-copy-source.d.ts.map +1 -1
  130. package/dist/replace-file-copy-source.js +10 -12
  131. package/dist/replace-file-temp-owner.d.ts +5 -2
  132. package/dist/replace-file-temp-owner.d.ts.map +1 -1
  133. package/dist/replace-file-temp-owner.js +65 -30
  134. package/dist/replace-file.js +6 -6
  135. package/dist/retained-directory-replacement.d.ts +26 -0
  136. package/dist/retained-directory-replacement.d.ts.map +1 -0
  137. package/dist/retained-directory-replacement.js +193 -0
  138. package/dist/root-boundary.d.ts +1 -0
  139. package/dist/root-boundary.d.ts.map +1 -1
  140. package/dist/root-boundary.js +4 -0
  141. package/dist/root-context.d.ts +0 -8
  142. package/dist/root-context.d.ts.map +1 -1
  143. package/dist/root-context.js +0 -3
  144. package/dist/root-create-input.d.ts +6 -0
  145. package/dist/root-create-input.d.ts.map +1 -1
  146. package/dist/root-create-input.js +5 -1
  147. package/dist/root-directory-list.d.ts +1 -0
  148. package/dist/root-directory-list.d.ts.map +1 -1
  149. package/dist/root-directory-list.js +1 -0
  150. package/dist/root-impl.d.ts.map +1 -1
  151. package/dist/root-impl.js +18 -10
  152. package/dist/root-move-noreplace.d.ts.map +1 -1
  153. package/dist/root-move-noreplace.js +2 -2
  154. package/dist/root-path-errors.d.ts +1 -0
  155. package/dist/root-path-errors.d.ts.map +1 -1
  156. package/dist/root-path-errors.js +11 -2
  157. package/dist/root-path-existing.d.ts.map +1 -1
  158. package/dist/root-path-existing.js +11 -35
  159. package/dist/root-path.js +1 -13
  160. package/dist/root-remove.d.ts +1 -0
  161. package/dist/root-remove.d.ts.map +1 -1
  162. package/dist/root-remove.js +4 -0
  163. package/dist/root-walk.d.ts +1 -1
  164. package/dist/root-walk.d.ts.map +1 -1
  165. package/dist/root-walk.js +17 -2
  166. package/dist/root-write-admission.d.ts +0 -2
  167. package/dist/root-write-admission.d.ts.map +1 -1
  168. package/dist/root-write-admission.js +1 -15
  169. package/dist/root-write-complete-parent.d.ts.map +1 -1
  170. package/dist/root-write-complete-parent.js +7 -23
  171. package/dist/root-write-verification.d.ts.map +1 -1
  172. package/dist/root-write-verification.js +29 -42
  173. package/dist/secret-file.d.ts.map +1 -1
  174. package/dist/secret-file.js +2 -24
  175. package/dist/secret-read-async.d.ts.map +1 -1
  176. package/dist/secret-read-async.js +3 -24
  177. package/dist/secret-read-policy.d.ts +6 -2
  178. package/dist/secret-read-policy.d.ts.map +1 -1
  179. package/dist/secret-read-policy.js +26 -2
  180. package/dist/sibling-temp.d.ts.map +1 -1
  181. package/dist/sibling-temp.js +23 -12
  182. package/dist/sidecar-lock-acquire.d.ts +2 -28
  183. package/dist/sidecar-lock-acquire.d.ts.map +1 -1
  184. package/dist/sidecar-lock-acquire.js +288 -199
  185. package/dist/sidecar-lock-admission-context.d.ts +19 -0
  186. package/dist/sidecar-lock-admission-context.d.ts.map +1 -0
  187. package/dist/sidecar-lock-admission-context.js +60 -0
  188. package/dist/sidecar-lock-admission-parser.d.ts +43 -0
  189. package/dist/sidecar-lock-admission-parser.d.ts.map +1 -0
  190. package/dist/sidecar-lock-admission-parser.js +113 -0
  191. package/dist/sidecar-lock-admission.d.ts +35 -0
  192. package/dist/sidecar-lock-admission.d.ts.map +1 -0
  193. package/dist/sidecar-lock-admission.js +7 -0
  194. package/dist/sidecar-lock-reclaim.d.ts +9 -4
  195. package/dist/sidecar-lock-reclaim.d.ts.map +1 -1
  196. package/dist/sidecar-lock-reclaim.js +80 -25
  197. package/dist/sidecar-lock-stale-admission.d.ts +39 -0
  198. package/dist/sidecar-lock-stale-admission.d.ts.map +1 -0
  199. package/dist/sidecar-lock-stale-admission.js +232 -0
  200. package/dist/sidecar-lock-target.d.ts +8 -0
  201. package/dist/sidecar-lock-target.d.ts.map +1 -0
  202. package/dist/sidecar-lock-target.js +55 -0
  203. package/dist/sidecar-lock.d.ts.map +1 -1
  204. package/dist/sidecar-lock.js +100 -16
  205. package/dist/temp-workspace-descriptor.d.ts.map +1 -1
  206. package/dist/temp-workspace-descriptor.js +9 -27
  207. package/dist/temp-workspace-owner.d.ts.map +1 -1
  208. package/dist/temp-workspace-owner.js +8 -8
  209. package/dist/walk.d.ts +5 -1
  210. package/dist/walk.d.ts.map +1 -1
  211. package/dist/walk.js +19 -6
  212. package/dist/windows-owner.d.ts.map +1 -1
  213. package/dist/windows-owner.js +2 -2
  214. package/docs/advanced.md +1 -1
  215. package/docs/archive.md +36 -9
  216. package/docs/atomic.md +85 -8
  217. package/docs/copy.md +35 -0
  218. package/docs/file-store.md +19 -0
  219. package/docs/json-store.md +5 -0
  220. package/docs/native-helper.md +10 -3
  221. package/docs/output.md +6 -0
  222. package/docs/path-prefix.md +10 -0
  223. package/docs/path-suffix-aliases.md +51 -6
  224. package/docs/permissions.md +13 -0
  225. package/docs/public-api.md +3 -2
  226. package/docs/root.md +22 -3
  227. package/docs/sidecar-lock.md +109 -4
  228. package/docs/staged-file.md +7 -3
  229. package/docs/temp.md +20 -3
  230. package/docs/walk.md +67 -1
  231. package/docs/writing.md +5 -1
  232. package/package.json +10 -10
  233. package/dist/darwin-acl.d.ts +0 -4
  234. package/dist/darwin-acl.d.ts.map +0 -1
  235. package/dist/darwin-acl.js +0 -24
@@ -107,30 +107,83 @@ function throwTempWorkspaceOpenFailure(failure) {
107
107
  },
108
108
  });
109
109
  }
110
- async function createTempWorkspace(options, scopedPrefix = false) {
110
+ function tempWorkspaceSettings(options) {
111
111
  const rootDir = options.rootDir;
112
112
  assertNoWindowsPathAlias(rootDir, "filesystem", "temp workspace root uses a Windows filesystem namespace alias");
113
113
  const dirMode = options.dirMode ?? 0o700;
114
114
  validateTempWorkspaceDirMode(dirMode);
115
115
  const mode = options.mode ?? 0o600;
116
116
  const cleanupSafety = resolveTempWorkspaceCleanupSafety(options.cleanupSafety);
117
- const admission = await admitTempWorkspaceRoot(rootDir);
118
- const root = admission.dir;
117
+ return { rootDir, dirMode, mode, cleanupSafety };
118
+ }
119
+ function tempWorkspaceChildPrefix(root, options, scopedPrefix) {
119
120
  assertNoWindowsPathAlias(root, "filesystem", "temp workspace root uses a Windows filesystem namespace alias");
120
- // Capture and sanitize caller-controlled prefix data before retaining descriptors.
121
- const rawPrefix = options.prefix;
122
- const workspacePrefix = scopedPrefix
123
- ? `${sanitizeTempPrefix(rawPrefix)}${randomUUID()}-`
124
- : rawPrefix;
121
+ // Capture and sanitize caller-controlled data before retaining descriptors.
122
+ const prefix = options.prefix;
123
+ const workspacePrefix = scopedPrefix ? `${sanitizeTempPrefix(prefix)}${randomUUID()}-` : prefix;
125
124
  const childPrefix = path.join(root, sanitizeTempPrefix(workspacePrefix));
126
125
  assertNoWindowsPathAlias(childPrefix, "filesystem", "temp workspace path uses a Windows filesystem namespace alias");
126
+ return childPrefix;
127
+ }
128
+ function throwTempWorkspaceCreationFailure(error, retainedChild, capability, owner) {
129
+ try {
130
+ if (owner)
131
+ owner.cleanupSync();
132
+ else {
133
+ const closeErrors = [];
134
+ try {
135
+ retainedChild?.close();
136
+ }
137
+ catch (closeError) {
138
+ closeErrors.push(closeError);
139
+ }
140
+ try {
141
+ capability.close();
142
+ }
143
+ catch (closeError) {
144
+ closeErrors.push(closeError);
145
+ }
146
+ if (closeErrors.length === 1)
147
+ throw closeErrors[0];
148
+ if (closeErrors.length > 1) {
149
+ throw new AggregateError(closeErrors, "temp workspace admission descriptor close failed");
150
+ }
151
+ }
152
+ }
153
+ catch (cleanupError) {
154
+ throw new AggregateError([error, cleanupError], "temp workspace creation and cleanup both failed");
155
+ }
156
+ throw error;
157
+ }
158
+ function registerTempWorkspace(dir, retainedChild, capability, admission, dirMode) {
159
+ let owner;
160
+ let stat;
161
+ let unregisterTempDir;
162
+ try {
163
+ const retainChildDescriptor = capability.admitChildDescriptor(retainedChild.ensureReadable());
164
+ // Final adoption orders ancestry and cleanup-parent authority before the
165
+ // original child's descriptor and named security-state checks.
166
+ if (capability.parent)
167
+ capability.assertAncestryCurrent();
168
+ else
169
+ admission.assertAncestry();
170
+ stat = retainedChild.finalizeAdmission(admission.ownerUid, dirMode);
171
+ owner = new TempWorkspaceCleanupOwner(retainedChild, capability, retainChildDescriptor);
172
+ unregisterTempDir = registerTempPathForExit(dir, { cleanupSync: () => owner.cleanupSync() });
173
+ }
174
+ catch (error) {
175
+ throwTempWorkspaceCreationFailure(error, retainedChild, capability, owner);
176
+ }
177
+ return { owner: owner, unregisterTempDir, identity: { dev: Number(stat.dev), ino: Number(stat.ino) } };
178
+ }
179
+ async function createTempWorkspace(options, scopedPrefix = false) {
180
+ const { rootDir, dirMode, mode, cleanupSafety } = tempWorkspaceSettings(options);
181
+ const admission = await admitTempWorkspaceRoot(rootDir);
182
+ const root = admission.dir;
183
+ const childPrefix = tempWorkspaceChildPrefix(root, options, scopedPrefix);
127
184
  const capability = new TempWorkspaceCleanupCapability(root, cleanupSafety, admission, dirMode);
128
185
  let dir;
129
- let stat;
130
186
  let retainedChild;
131
- let retainChildDescriptor = false;
132
- let cleanupOwner;
133
- let unregisterTempDir;
134
187
  try {
135
188
  // Native capability discovery is complete before this synchronous
136
189
  // boundary. The existing canonical-root route now captures the complete
@@ -143,7 +196,7 @@ async function createTempWorkspace(options, scopedPrefix = false) {
143
196
  capability.assertCurrent();
144
197
  else
145
198
  admission.assertCurrent();
146
- stat = inspectDirectoryIdentitySync(dir);
199
+ const stat = inspectDirectoryIdentitySync(dir);
147
200
  const needsModeInitialization = validateInitialTempWorkspaceChild(stat, admission.ownerUid, dirMode);
148
201
  // Retain while the child still has its private creation mode so an
149
202
  // explicit dirMode such as 0 cannot make identity descriptor acquisition fail.
@@ -151,52 +204,11 @@ async function createTempWorkspace(options, scopedPrefix = false) {
151
204
  const modeInitialization = admitRetainedTempWorkspaceChild(retainedChild, needsModeInitialization, admission, dirMode);
152
205
  if (modeInitialization)
153
206
  await modeInitialization;
154
- retainChildDescriptor = capability.admitChildDescriptor(retainedChild.ensureReadable());
155
- // Final adoption order is deliberate: complete ancestry, retained cleanup
156
- // parent, then descriptor and named checks of the original child identity.
157
- if (capability.parent)
158
- capability.assertAncestryCurrent();
159
- else
160
- admission.assertAncestry();
161
- stat = retainedChild.finalizeAdmission(admission.ownerUid, dirMode);
162
- cleanupOwner = new TempWorkspaceCleanupOwner(retainedChild, capability, retainChildDescriptor);
163
- retainedChild = undefined;
164
- unregisterTempDir = registerTempPathForExit(dir, {
165
- cleanupSync: () => cleanupOwner.cleanupSync(),
166
- });
167
207
  }
168
208
  catch (error) {
169
- try {
170
- if (cleanupOwner)
171
- cleanupOwner.cleanupSync();
172
- else {
173
- const closeErrors = [];
174
- try {
175
- retainedChild?.close();
176
- }
177
- catch (closeError) {
178
- closeErrors.push(closeError);
179
- }
180
- try {
181
- capability.close();
182
- }
183
- catch (closeError) {
184
- closeErrors.push(closeError);
185
- }
186
- if (closeErrors.length === 1)
187
- throw closeErrors[0];
188
- if (closeErrors.length > 1) {
189
- throw new AggregateError(closeErrors, "temp workspace admission descriptor close failed");
190
- }
191
- }
192
- }
193
- catch (cleanupError) {
194
- throw new AggregateError([error, cleanupError], "temp workspace creation and cleanup both failed");
195
- }
196
- throw error;
209
+ throwTempWorkspaceCreationFailure(error, retainedChild, capability);
197
210
  }
198
- const owner = cleanupOwner;
199
- const identity = { dev: Number(stat.dev), ino: Number(stat.ino) };
211
+ const { owner, identity, unregisterTempDir } = registerTempWorkspace(dir, retainedChild, capability, admission, dirMode);
200
212
  // Once registered, even a store-construction failure remains exit-cleanable.
201
213
  const store = fileStore({ rootDir: dir, private: true, dirMode, mode });
202
214
  return {
@@ -250,30 +262,13 @@ export async function withTempWorkspace(options, run) {
250
262
  }
251
263
  }
252
264
  function createTempWorkspaceSync(options, scopedPrefix = false) {
253
- const rootDir = options.rootDir;
254
- assertNoWindowsPathAlias(rootDir, "filesystem", "temp workspace root uses a Windows filesystem namespace alias");
255
- const dirMode = options.dirMode ?? 0o700;
256
- validateTempWorkspaceDirMode(dirMode);
257
- const mode = options.mode ?? 0o600;
258
- const cleanupSafety = resolveTempWorkspaceCleanupSafety(options.cleanupSafety);
265
+ const { rootDir, dirMode, mode, cleanupSafety } = tempWorkspaceSettings(options);
259
266
  const admission = admitTempWorkspaceRootSync(rootDir);
260
267
  const root = admission.dir;
261
- assertNoWindowsPathAlias(root, "filesystem", "temp workspace root uses a Windows filesystem namespace alias");
262
- // Capture and sanitize caller-controlled prefix data before retaining descriptors.
263
- const rawPrefix = options.prefix;
264
- const workspacePrefix = scopedPrefix
265
- ? `${sanitizeTempPrefix(rawPrefix)}${randomUUID()}-`
266
- : rawPrefix;
267
- const childPrefix = path.join(root, sanitizeTempPrefix(workspacePrefix));
268
- assertNoWindowsPathAlias(childPrefix, "filesystem", "temp workspace path uses a Windows filesystem namespace alias");
268
+ const childPrefix = tempWorkspaceChildPrefix(root, options, scopedPrefix);
269
269
  const capability = new TempWorkspaceCleanupCapability(root, cleanupSafety, admission, dirMode);
270
270
  let dir;
271
- let stat;
272
271
  let retainedChild;
273
- let retainChildDescriptor = false;
274
- let needsModeInitialization;
275
- let cleanupOwner;
276
- let unregisterTempDir;
277
272
  try {
278
273
  const directRequestedMode = canCreateTempWorkspaceWithRequestedMode(dirMode);
279
274
  if (directRequestedMode) {
@@ -288,64 +283,23 @@ function createTempWorkspaceSync(options, scopedPrefix = false) {
288
283
  capability.assertCurrent();
289
284
  else
290
285
  admission.assertCurrent();
286
+ let stat;
291
287
  if (directRequestedMode) {
292
288
  const created = TempWorkspaceRetainedChild.retainCreated(dir);
293
289
  retainedChild = created.retained;
294
290
  stat = created.stat;
295
- needsModeInitialization = validateInitialTempWorkspaceChild(stat, admission.ownerUid, dirMode);
296
291
  }
297
292
  else {
298
293
  stat = inspectDirectoryIdentitySync(dir);
299
- needsModeInitialization = validateInitialTempWorkspaceChild(stat, admission.ownerUid, dirMode);
300
- retainedChild = TempWorkspaceRetainedChild.retain(dir, stat);
301
294
  }
295
+ const needsModeInitialization = validateInitialTempWorkspaceChild(stat, admission.ownerUid, dirMode);
296
+ retainedChild ??= TempWorkspaceRetainedChild.retain(dir, stat);
302
297
  admitRetainedTempWorkspaceChildSync(retainedChild, needsModeInitialization, admission, dirMode);
303
- retainChildDescriptor = capability.admitChildDescriptor(retainedChild.ensureReadable());
304
- // Match async adoption: complete ancestry and retained cleanup authority
305
- // precede descriptor and named child security-state checks.
306
- if (capability.parent)
307
- capability.assertAncestryCurrent();
308
- else
309
- admission.assertAncestry();
310
- stat = retainedChild.finalizeAdmission(admission.ownerUid, dirMode);
311
- cleanupOwner = new TempWorkspaceCleanupOwner(retainedChild, capability, retainChildDescriptor);
312
- retainedChild = undefined;
313
- unregisterTempDir = registerTempPathForExit(dir, {
314
- cleanupSync: () => cleanupOwner.cleanupSync(),
315
- });
316
298
  }
317
299
  catch (error) {
318
- try {
319
- if (cleanupOwner)
320
- cleanupOwner.cleanupSync();
321
- else {
322
- const closeErrors = [];
323
- try {
324
- retainedChild?.close();
325
- }
326
- catch (closeError) {
327
- closeErrors.push(closeError);
328
- }
329
- try {
330
- capability.close();
331
- }
332
- catch (closeError) {
333
- closeErrors.push(closeError);
334
- }
335
- if (closeErrors.length === 1)
336
- throw closeErrors[0];
337
- if (closeErrors.length > 1) {
338
- throw new AggregateError(closeErrors, "temp workspace admission descriptor close failed");
339
- }
340
- }
341
- }
342
- catch (cleanupError) {
343
- throw new AggregateError([error, cleanupError], "temp workspace creation and cleanup both failed");
344
- }
345
- throw error;
300
+ throwTempWorkspaceCreationFailure(error, retainedChild, capability);
346
301
  }
347
- const owner = cleanupOwner;
348
- const identity = { dev: Number(stat.dev), ino: Number(stat.ino) };
302
+ const { owner, identity, unregisterTempDir } = registerTempWorkspace(dir, retainedChild, capability, admission, dirMode);
349
303
  // Once registered, even a store-construction failure remains exit-cleanable.
350
304
  const store = fileStoreSync({ rootDir: dir, private: true, dirMode, mode });
351
305
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"regular-file.d.ts","sourceRoot":"","sources":["../src/regular-file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,KAAK,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,MAAM,MAAM,SAAS,CAAC;AAuB7B,MAAM,MAAM,qBAAqB,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC;AAExF,KAAK,8BAA8B,GAAG,IAAI,CACxC,OAAO,MAAM,CAAC,SAAS,EACvB,UAAU,GAAG,SAAS,GAAG,UAAU,CACpC,GACC,OAAO,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,SAAS,EAAE,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC;AAEtE,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,wBAAgB,6BAA6B,CAC3C,SAAS,GAAE,8BAAiD,GAC3D,MAAM,CASR;AAaD,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAetF;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,qBAAqB,CAe3E;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC,CA+D3C;AA2DD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IACpF,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,KAAK,CAAC;CACb,CAsCA;AAmBD,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFxF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAkF7E"}
1
+ {"version":3,"file":"regular-file.d.ts","sourceRoot":"","sources":["../src/regular-file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,KAAK,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,MAAM,MAAM,SAAS,CAAC;AAuB7B,MAAM,MAAM,qBAAqB,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC;AAExF,KAAK,8BAA8B,GAAG,IAAI,CACxC,OAAO,MAAM,CAAC,SAAS,EACvB,UAAU,GAAG,SAAS,GAAG,UAAU,CACpC,GACC,OAAO,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,SAAS,EAAE,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC;AAEtE,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,wBAAgB,6BAA6B,CAC3C,SAAS,GAAE,8BAAiD,GAC3D,MAAM,CASR;AAaD,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAEtF;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,qBAAqB,CAe3E;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC,CA+D3C;AA2DD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IACpF,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,KAAK,CAAC;CACb,CAsCA;AAmBD,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFxF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAkF7E"}
@@ -30,21 +30,7 @@ function translateBoundedReadOverflow(error, filePath, maxBytes) {
30
30
  throw error;
31
31
  }
32
32
  export async function statRegularFile(filePath) {
33
- assertNoWindowsPathAlias(filePath, "filesystem", "file path uses a Windows filesystem namespace alias");
34
- let stat;
35
- try {
36
- stat = fsSync.lstatSync(filePath);
37
- }
38
- catch (err) {
39
- if (isNotFoundPathError(err)) {
40
- return { missing: true };
41
- }
42
- throw err;
43
- }
44
- if (stat.isSymbolicLink() || !stat.isFile()) {
45
- throw new Error("path must be a regular file");
46
- }
47
- return { missing: false, stat };
33
+ return statRegularFileSync(filePath);
48
34
  }
49
35
  export function statRegularFileSync(filePath) {
50
36
  assertNoWindowsPathAlias(filePath, "filesystem", "file path uses a Windows filesystem namespace alias");
@@ -1 +1 @@
1
- {"version":3,"file":"replace-directory.d.ts","sourceRoot":"","sources":["../src/replace-directory.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,IAAI,CAAC,CAiBf"}
1
+ {"version":3,"file":"replace-directory.d.ts","sourceRoot":"","sources":["../src/replace-directory.ts"],"names":[],"mappings":"AAuBA,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAqIF,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,IAAI,CAAC,CAiBf"}
@@ -1,12 +1,94 @@
1
1
  import { randomUUID } from "node:crypto";
2
+ import fsSync from "node:fs";
2
3
  import fs from "node:fs/promises";
3
4
  import path from "node:path";
4
- import { guardedRename, guardedRm } from "./guarded-mutation.js";
5
+ import { assertSyncDirectoryGuard, createAsyncDirectoryGuard, inspectDirectoryIdentitySync, } from "./directory-guard.js";
6
+ import { FsSafeError } from "./errors.js";
7
+ import { classifyNativeRenameFailure, NATIVE_RENAME_SOURCE_IDENTITY_MISMATCH, } from "./native-rename-outcome.js";
5
8
  import { recursiveMkdirPath } from "./recursive-mkdir-path.js";
9
+ import { RetainedDirectoryReplacement } from "./retained-directory-replacement.js";
6
10
  import { assertSafePathPrefix } from "./safe-path-segment.js";
7
11
  import { admitStandalonePublicationPath } from "./standalone-publication-path.js";
8
12
  import { serializePathWrite } from "./write-queue.js";
9
13
  import { assertNoWindowsPathAlias } from "./windows-path-alias.js";
14
+ function distinctGuards(source, target) {
15
+ return source === target ? [source] : [source, target];
16
+ }
17
+ function assertGuardsCurrent(guards) {
18
+ for (const guard of guards)
19
+ assertSyncDirectoryGuard(guard);
20
+ }
21
+ function copyOperationalCode(target, source) {
22
+ const code = source?.code;
23
+ if (typeof code === "string") {
24
+ Object.defineProperty(target, "code", { configurable: true, value: code });
25
+ }
26
+ }
27
+ function replacementFailure(error, message, details) {
28
+ if (error instanceof FsSafeError) {
29
+ return new FsSafeError(error.code, message, { cause: error, details });
30
+ }
31
+ const failure = new Error(message, { cause: error });
32
+ copyOperationalCode(failure, error);
33
+ Object.defineProperty(failure, "details", { configurable: true, value: details });
34
+ return failure;
35
+ }
36
+ function replacementAggregate(error, recoveryError, message, details) {
37
+ const combined = new AggregateError([error, recoveryError], "directory replacement operation and recovery both failed");
38
+ if (error instanceof FsSafeError) {
39
+ return new FsSafeError(error.code, message, { cause: combined, details });
40
+ }
41
+ const failure = new Error(message, { cause: combined });
42
+ copyOperationalCode(failure, error);
43
+ Object.defineProperty(failure, "details", { configurable: true, value: details });
44
+ return failure;
45
+ }
46
+ function isMissingDirectoryEntry(error) {
47
+ return error?.code === "ENOENT";
48
+ }
49
+ function observeOptionalDirectory(pathname) {
50
+ let initial;
51
+ try {
52
+ initial = fsSync.lstatSync(pathname, { bigint: true });
53
+ }
54
+ catch (error) {
55
+ if (isMissingDirectoryEntry(error))
56
+ return undefined;
57
+ throw error;
58
+ }
59
+ return inspectDirectoryIdentitySync(pathname, undefined, initial);
60
+ }
61
+ function normalizeNativeRenameFailure(error) {
62
+ const code = error?.code;
63
+ if (code === NATIVE_RENAME_SOURCE_IDENTITY_MISMATCH) {
64
+ return new FsSafeError("path-mismatch", "directory replacement source identity changed before native rename", { cause: error });
65
+ }
66
+ if (code === "EINVAL" || code === "ENOSYS" || code === "ENOTSUP" ||
67
+ code === "EOPNOTSUPP") {
68
+ return new FsSafeError("helper-unavailable", "native no-replace directory rename is unavailable on this filesystem", { cause: error });
69
+ }
70
+ return error;
71
+ }
72
+ function renameRetainedDirectory(params) {
73
+ const guards = distinctGuards(params.sourceParent, params.targetParent);
74
+ assertGuardsCurrent(guards);
75
+ const initial = fsSync.lstatSync(params.from, { bigint: true });
76
+ const identity = inspectDirectoryIdentitySync(params.from, params.expectedSource, initial);
77
+ try {
78
+ params.renameNoReplace(identity);
79
+ }
80
+ catch (error) {
81
+ if (classifyNativeRenameFailure(error) === "indeterminate") {
82
+ params.onIndeterminate();
83
+ }
84
+ throw normalizeNativeRenameFailure(error);
85
+ }
86
+ // Record the transition synchronously before any post-rename observation.
87
+ params.onRenamed?.(identity);
88
+ inspectDirectoryIdentitySync(params.to, identity);
89
+ assertGuardsCurrent(guards);
90
+ return identity;
91
+ }
10
92
  export async function replaceDirectoryAtomic(options) {
11
93
  const stagedDirInput = admitStandalonePublicationPath(options.stagedDir, "staged directory uses a Windows filesystem namespace alias");
12
94
  const targetDirInput = admitStandalonePublicationPath(options.targetDir, "target directory uses a Windows filesystem namespace alias");
@@ -23,28 +105,184 @@ async function replaceDirectoryAtomicUnserialized(stagedDir, targetDir, backupPr
23
105
  const parentDir = path.dirname(targetDir);
24
106
  const backupPrefix = assertSafePathPrefix(backupPrefixInput ?? ".fs-safe-dir-backup-", { label: "atomic directory backup prefix" });
25
107
  const backupDir = path.join(parentDir, `${backupPrefix}${process.pid}-${randomUUID()}`);
26
- let backupCreated = false;
108
+ const backup = {
109
+ identity: undefined,
110
+ transition: "not-renamed",
111
+ };
112
+ const publication = {
113
+ status: "not-published",
114
+ };
115
+ let operationFailed = false;
116
+ let operationError;
117
+ let operationDetails = {
118
+ phase: "backup",
119
+ publication: publication.status,
120
+ recovery: "none",
121
+ };
122
+ const retainedBinding = RetainedDirectoryReplacement.requireBinding();
27
123
  await fs.mkdir(recursiveMkdirPath(parentDir), { recursive: true });
124
+ const targetParent = await createAsyncDirectoryGuard(parentDir, { bigint: true });
125
+ const stagedParentDir = path.dirname(stagedDir);
126
+ const stagedParent = stagedParentDir === parentDir
127
+ ? targetParent
128
+ : await createAsyncDirectoryGuard(stagedParentDir, { bigint: true });
129
+ const stagedIdentity = inspectDirectoryIdentitySync(stagedDir);
130
+ const targetIdentity = observeOptionalDirectory(targetDir);
131
+ const retained = RetainedDirectoryReplacement.retain({
132
+ targetParent: {
133
+ path: parentDir,
134
+ realPath: targetParent.realPath,
135
+ identity: targetParent.stat,
136
+ },
137
+ stagedParent: {
138
+ path: stagedParentDir,
139
+ realPath: stagedParent.realPath,
140
+ identity: stagedParent.stat,
141
+ },
142
+ ...(targetIdentity ? {
143
+ originalTarget: { path: targetDir, identity: targetIdentity },
144
+ } : {}),
145
+ }, retainedBinding);
146
+ const targetBasename = path.basename(targetDir);
147
+ const stagedBasename = path.basename(stagedDir);
148
+ const backupBasename = path.basename(backupDir);
149
+ const details = (phase, recovery) => {
150
+ operationDetails = {
151
+ phase,
152
+ publication: publication.status,
153
+ recovery,
154
+ ...(backup.transition === "not-renamed" ? {} : { backupPath: backupDir }),
155
+ };
156
+ return operationDetails;
157
+ };
158
+ const rollback = (error, failedPhase, identity) => {
159
+ const rollbackState = {
160
+ transition: "not-renamed",
161
+ };
162
+ try {
163
+ renameRetainedDirectory({
164
+ from: backupDir,
165
+ to: targetDir,
166
+ sourceParent: targetParent,
167
+ targetParent,
168
+ expectedSource: identity,
169
+ renameNoReplace: expectedSource => {
170
+ retained.renameNoReplace("target", backupBasename, targetBasename, expectedSource);
171
+ },
172
+ onIndeterminate() {
173
+ rollbackState.transition = "indeterminate";
174
+ backup.transition = "indeterminate";
175
+ },
176
+ onRenamed() {
177
+ rollbackState.transition = "renamed";
178
+ backup.transition = "not-renamed";
179
+ },
180
+ });
181
+ }
182
+ catch (rollbackError) {
183
+ const recovery = rollbackState.transition === "renamed"
184
+ ? "restored-unverified"
185
+ : rollbackState.transition === "indeterminate"
186
+ ? "indeterminate"
187
+ : "backup-path-preserved";
188
+ throw replacementAggregate(error, rollbackError, `directory ${failedPhase} and rollback failed`, details("rollback", recovery));
189
+ }
190
+ throw replacementFailure(error, `directory ${failedPhase} failed after restoring the original target`, details(failedPhase, "restored"));
191
+ };
28
192
  try {
29
- await guardedRename({ from: targetDir, to: backupDir });
30
- backupCreated = true;
31
- }
32
- catch (err) {
33
- if (err.code !== "ENOENT") {
34
- throw err;
193
+ if (targetIdentity) {
194
+ try {
195
+ backup.identity = renameRetainedDirectory({
196
+ from: targetDir,
197
+ to: backupDir,
198
+ sourceParent: targetParent,
199
+ targetParent,
200
+ expectedSource: targetIdentity,
201
+ renameNoReplace: expectedSource => {
202
+ retained.renameNoReplace("target", targetBasename, backupBasename, expectedSource);
203
+ },
204
+ onIndeterminate() {
205
+ backup.transition = "indeterminate";
206
+ },
207
+ onRenamed(identity) {
208
+ backup.identity = identity;
209
+ backup.transition = "renamed";
210
+ },
211
+ });
212
+ }
213
+ catch (err) {
214
+ if (backup.transition === "renamed" && backup.identity) {
215
+ rollback(err, "backup", backup.identity);
216
+ }
217
+ const recovery = backup.transition === "indeterminate" ? "indeterminate" : "none";
218
+ throw replacementFailure(err, "directory backup failed before publication", details("backup", recovery));
219
+ }
220
+ }
221
+ try {
222
+ renameRetainedDirectory({
223
+ from: stagedDir,
224
+ to: targetDir,
225
+ sourceParent: stagedParent,
226
+ targetParent,
227
+ expectedSource: stagedIdentity,
228
+ renameNoReplace: expectedSource => {
229
+ retained.renameNoReplace("staged", stagedBasename, targetBasename, expectedSource);
230
+ },
231
+ onIndeterminate() {
232
+ publication.status = "indeterminate";
233
+ },
234
+ onRenamed() {
235
+ publication.status = "published";
236
+ },
237
+ });
238
+ }
239
+ catch (err) {
240
+ if (publication.status === "published") {
241
+ throw replacementFailure(err, "published directory failed retained identity verification", details("publish", backup.transition === "renamed" ? "backup-path-preserved" : "none"));
242
+ }
243
+ if (publication.status === "indeterminate") {
244
+ throw replacementFailure(err, "directory publication outcome is indeterminate", details("publish", backup.transition === "renamed" ? "backup-path-preserved" : "none"));
245
+ }
246
+ if (backup.transition === "renamed" && backup.identity) {
247
+ rollback(err, "publish", backup.identity);
248
+ }
249
+ throw replacementFailure(err, "directory publication failed before commit", details("publish", "none"));
250
+ }
251
+ details("publish", backup.transition === "renamed" ? "backup-path-preserved" : "none");
252
+ if (backup.transition === "renamed" && backup.identity) {
253
+ let cleanupAttempted = false;
254
+ try {
255
+ assertSyncDirectoryGuard(targetParent);
256
+ inspectDirectoryIdentitySync(backupDir, backup.identity);
257
+ cleanupAttempted = true;
258
+ const outcome = await retained.removeOriginal(backupBasename);
259
+ if (outcome !== "removed") {
260
+ throw new FsSafeError("path-mismatch", "retained backup changed before bounded cleanup");
261
+ }
262
+ backup.transition = "not-renamed";
263
+ details("cleanup", "none");
264
+ }
265
+ catch (error) {
266
+ throw replacementFailure(error, "published directory but retained backup cleanup failed", {
267
+ ...details("cleanup", cleanupAttempted ? "cleanup-incomplete" : "backup-path-preserved"),
268
+ });
269
+ }
35
270
  }
36
271
  }
37
- try {
38
- await guardedRename({ from: stagedDir, to: targetDir });
272
+ catch (error) {
273
+ operationFailed = true;
274
+ operationError = error;
275
+ throw error;
39
276
  }
40
- catch (err) {
41
- if (backupCreated) {
42
- await guardedRename({ from: backupDir, to: targetDir }).catch(() => undefined);
43
- backupCreated = false;
277
+ finally {
278
+ try {
279
+ retained.close();
280
+ }
281
+ catch (closeError) {
282
+ if (operationFailed) {
283
+ throw replacementAggregate(operationError, closeError, "directory replacement and retained descriptor close failed", operationDetails);
284
+ }
285
+ throw replacementFailure(closeError, "directory replacement retained descriptor close failed", operationDetails);
44
286
  }
45
- throw err;
46
- }
47
- if (backupCreated) {
48
- await guardedRm({ target: backupDir, recursive: true, force: true, verifyAfter: false });
49
287
  }
50
288
  }
@@ -1 +1 @@
1
- {"version":3,"file":"replace-file-copy-fallback.d.ts","sourceRoot":"","sources":["../src/replace-file-copy-fallback.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,EAAE,EAAE,KAAK,WAAW,EAAc,MAAM,SAAS,CAAC;AAQ/D,MAAM,MAAM,oCAAoC,GAAG,QAAQ,CAAC;AAC5D,MAAM,MAAM,oCAAoC,GAAG,kBAAkB,GAAG,MAAM,CAAC;AAC/E,MAAM,MAAM,+BAA+B,GAAG,UAAU,GAAG,gBAAgB,CAAC;AAC5E,MAAM,MAAM,sCAAsC,GAAG;IACnD,OAAO,EAAE,+BAA+B,CAAC;CAC1C,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,cAAc,kBAAkB,EAAE,KAAK,CAAC;IAC/C,IAAI,EAAE,cAAc,kBAAkB,EAAE,IAAI,CAAC;IAC7C,EAAE,EAAE,cAAc,kBAAkB,EAAE,EAAE,CAAC;IACzC,MAAM,EAAE,cAAc,kBAAkB,EAAE,MAAM,CAAC;CAClD,CAAC;AAEF,KAAK,cAAc,GAAG,IAAI,CACxB,OAAO,MAAM,EACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,eAAe,GACf,WAAW,GACX,UAAU,GACV,UAAU,GACV,QAAQ,GACR,YAAY,GACZ,WAAW,CACd,CAAC;AAyFF,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,oCAAoC,GAC5C,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,oCAAoC,GAC5C,IAAI,CAwBN;AA+HD,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,QAAQ,EAAE,eAAe,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,oCAAoC,CAAC;IAC5D,OAAO,EAAE,oCAAoC,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,WAAW,CAAC;IACrC,IAAI,EAAE,OAAO,CAAC;CACf,GAAG,OAAO,CAAC,IAAI,CAAC,CA4DhB;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,oCAAoC,CAAC;IAC5D,OAAO,EAAE,oCAAoC,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,WAAW,CAAC;IACrC,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,IAAI,EAAE,OAAO,CAAC;CACf,GAAG,IAAI,CAkEP"}
1
+ {"version":3,"file":"replace-file-copy-fallback.d.ts","sourceRoot":"","sources":["../src/replace-file-copy-fallback.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,EAAE,EAAE,KAAK,WAAW,EAAc,MAAM,SAAS,CAAC;AAQ/D,MAAM,MAAM,oCAAoC,GAAG,QAAQ,CAAC;AAC5D,MAAM,MAAM,oCAAoC,GAAG,kBAAkB,GAAG,MAAM,CAAC;AAC/E,MAAM,MAAM,+BAA+B,GAAG,UAAU,GAAG,gBAAgB,CAAC;AAC5E,MAAM,MAAM,sCAAsC,GAAG;IACnD,OAAO,EAAE,+BAA+B,CAAC;CAC1C,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,cAAc,kBAAkB,EAAE,KAAK,CAAC;IAC/C,IAAI,EAAE,cAAc,kBAAkB,EAAE,IAAI,CAAC;IAC7C,EAAE,EAAE,cAAc,kBAAkB,EAAE,EAAE,CAAC;IACzC,MAAM,EAAE,cAAc,kBAAkB,EAAE,MAAM,CAAC;CAClD,CAAC;AAEF,KAAK,cAAc,GAAG,IAAI,CACxB,OAAO,MAAM,EACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,eAAe,GACf,WAAW,GACX,UAAU,GACV,UAAU,GACV,QAAQ,GACR,YAAY,GACZ,WAAW,CACd,CAAC;AAqHF,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,oCAAoC,GAC5C,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,oCAAoC,GAC5C,IAAI,CAIN;AA+HD,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,QAAQ,EAAE,eAAe,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,oCAAoC,CAAC;IAC5D,OAAO,EAAE,oCAAoC,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,WAAW,CAAC;IACrC,IAAI,EAAE,OAAO,CAAC;CACf,GAAG,OAAO,CAAC,IAAI,CAAC,CAuEhB;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,oCAAoC,CAAC;IAC5D,OAAO,EAAE,oCAAoC,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,WAAW,CAAC;IACrC,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,IAAI,EAAE,OAAO,CAAC;CACf,GAAG,IAAI,CAuEP"}