@openclaw/fs-safe 0.17.0 → 0.18.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 (644) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/absolute-path.d.ts +0 -1
  3. package/dist/advanced.d.ts +0 -1
  4. package/dist/archive-crc32.d.ts +0 -1
  5. package/dist/archive-deadline.d.ts +0 -1
  6. package/dist/archive-durability.d.ts +0 -1
  7. package/dist/archive-entry.d.ts +0 -1
  8. package/dist/archive-errors.d.ts +0 -1
  9. package/dist/archive-gzip-tail.d.ts +0 -1
  10. package/dist/archive-input.d.ts +0 -1
  11. package/dist/archive-kind.d.ts +0 -1
  12. package/dist/archive-limits.d.ts +0 -1
  13. package/dist/archive-merge.d.ts +2 -4
  14. package/dist/archive-merge.js +14 -4
  15. package/dist/archive-native.d.ts +3 -15
  16. package/dist/archive-native.js +46 -71
  17. package/dist/archive-options.d.ts +7 -2
  18. package/dist/archive-parser-errors.d.ts +0 -1
  19. package/dist/archive-plan.d.ts +10 -1
  20. package/dist/archive-plan.js +31 -21
  21. package/dist/archive-policy.d.ts +0 -1
  22. package/dist/archive-read.d.ts +0 -1
  23. package/dist/archive-staging.d.ts +0 -1
  24. package/dist/archive-tar-inspect.d.ts +0 -1
  25. package/dist/archive-tar-stream.d.ts +0 -1
  26. package/dist/archive-tar-wasm.d.ts +0 -1
  27. package/dist/archive-tar.d.ts +0 -1
  28. package/dist/archive-zip-admission.d.ts +0 -1
  29. package/dist/archive-zip-count.d.ts +0 -1
  30. package/dist/archive-zip-directory.d.ts +0 -1
  31. package/dist/archive-zip-entry.d.ts +0 -1
  32. package/dist/archive-zip-integrity.d.ts +0 -1
  33. package/dist/archive-zip-loader.d.ts +0 -1
  34. package/dist/archive-zip-manifest.d.ts +0 -1
  35. package/dist/archive-zip-names.d.ts +0 -1
  36. package/dist/archive-zip-preflight.d.ts +0 -1
  37. package/dist/archive.d.ts +0 -1
  38. package/dist/archive.js +87 -164
  39. package/dist/async-lock.d.ts +0 -1
  40. package/dist/atomic.d.ts +0 -1
  41. package/dist/bounded-read-stream.d.ts +0 -1
  42. package/dist/bounded-read.d.ts +0 -1
  43. package/dist/byte-budget.d.ts +0 -1
  44. package/dist/byte-view.d.ts +0 -1
  45. package/dist/clone-metadata.d.ts +0 -1
  46. package/dist/config.d.ts +0 -1
  47. package/dist/containment.d.ts +0 -1
  48. package/dist/copy-file-input.d.ts +0 -1
  49. package/dist/copy-policy.d.ts +0 -1
  50. package/dist/copy-publication.d.ts +0 -1
  51. package/dist/copy-tree-portable.d.ts +0 -1
  52. package/dist/copy-tree-portable.js +9 -6
  53. package/dist/copy.d.ts +0 -1
  54. package/dist/copy.js +5 -5
  55. package/dist/create-directory.d.ts +0 -2
  56. package/dist/create-directory.js +3 -22
  57. package/dist/create-file-async.d.ts +0 -1
  58. package/dist/create-file.d.ts +0 -1
  59. package/dist/create-file.js +3 -14
  60. package/dist/create-owned-file.d.ts +0 -1
  61. package/dist/create.d.ts +1 -2
  62. package/dist/create.js +1 -1
  63. package/dist/creation-darwin.d.ts +0 -1
  64. package/dist/creation-file-state.d.ts +0 -1
  65. package/dist/creation-path.d.ts +2 -1
  66. package/dist/creation-path.js +12 -0
  67. package/dist/creation-permissions.d.ts +0 -1
  68. package/dist/creation-permissions.js +28 -38
  69. package/dist/deny-mutations.d.ts +2 -3
  70. package/dist/deny-mutations.js +55 -35
  71. package/dist/device-path.d.ts +0 -1
  72. package/dist/directory-durability.d.ts +0 -1
  73. package/dist/directory-entry-path.d.ts +0 -1
  74. package/dist/directory-guard.d.ts +2 -7
  75. package/dist/directory-guard.js +25 -56
  76. package/dist/directory-mode-node.d.ts +0 -1
  77. package/dist/directory-mode-owner.d.ts +0 -1
  78. package/dist/directory-receipt.d.ts +0 -1
  79. package/dist/durability.d.ts +0 -1
  80. package/dist/effective-uid.d.ts +0 -1
  81. package/dist/error-detail.d.ts +0 -1
  82. package/dist/errors.d.ts +0 -1
  83. package/dist/file-cleanup.d.ts +0 -1
  84. package/dist/file-contents.d.ts +0 -1
  85. package/dist/file-handle-transfer.d.ts +0 -1
  86. package/dist/file-hash.d.ts +0 -1
  87. package/dist/file-hash.js +170 -66
  88. package/dist/file-identity.d.ts +0 -1
  89. package/dist/file-lock-sync-acquisition.d.ts +22 -0
  90. package/dist/file-lock-sync-acquisition.js +98 -0
  91. package/dist/file-lock-sync-admission.d.ts +0 -2
  92. package/dist/file-lock-sync-admission.js +9 -48
  93. package/dist/file-lock-sync-root-acquire.d.ts +0 -1
  94. package/dist/file-lock-sync-root-acquire.js +32 -98
  95. package/dist/file-lock-sync-root-arbitration.d.ts +0 -1
  96. package/dist/file-lock-sync-root-held.d.ts +0 -1
  97. package/dist/file-lock-sync-root-io.d.ts +0 -1
  98. package/dist/file-lock-sync-root-mutation.d.ts +4 -5
  99. package/dist/file-lock-sync-root-mutation.js +7 -9
  100. package/dist/file-lock-sync-root-options.d.ts +0 -1
  101. package/dist/file-lock-sync-root-registration.d.ts +0 -1
  102. package/dist/file-lock-sync-root.d.ts +1 -2
  103. package/dist/file-lock-sync-root.js +14 -87
  104. package/dist/file-lock-sync-stale-admission.d.ts +2 -7
  105. package/dist/file-lock-sync-stale-admission.js +21 -23
  106. package/dist/file-lock-sync.d.ts +0 -1
  107. package/dist/file-lock-sync.js +38 -117
  108. package/dist/file-lock.d.ts +0 -1
  109. package/dist/file-observation.d.ts +0 -1
  110. package/dist/file-store-boundary.d.ts +0 -2
  111. package/dist/file-store-boundary.js +6 -26
  112. package/dist/file-store-copy-source.d.ts +1 -2
  113. package/dist/file-store-copy-source.js +1 -1
  114. package/dist/file-store-limit.d.ts +1 -2
  115. package/dist/file-store-limit.js +2 -3
  116. package/dist/file-store-path.d.ts +0 -1
  117. package/dist/file-store-prune.d.ts +0 -1
  118. package/dist/file-store-sync-directory.d.ts +0 -1
  119. package/dist/file-store-sync-directory.js +194 -231
  120. package/dist/file-store-sync-write.d.ts +0 -1
  121. package/dist/file-store-sync-write.js +16 -26
  122. package/dist/file-store.d.ts +0 -1
  123. package/dist/file-store.js +3 -4
  124. package/dist/file-sync.d.ts +0 -1
  125. package/dist/filename.d.ts +0 -1
  126. package/dist/filename.js +1 -7
  127. package/dist/fs.d.ts +0 -1
  128. package/dist/guarded-mkdir.d.ts +0 -1
  129. package/dist/guarded-mutation.d.ts +0 -7
  130. package/dist/guarded-mutation.js +6 -11
  131. package/dist/guest-dispatch-python.d.ts +0 -1
  132. package/dist/guest-dispatch-python.js +41 -90
  133. package/dist/guest-native-python.d.ts +0 -1
  134. package/dist/guest.d.ts +0 -1
  135. package/dist/home-dir.d.ts +0 -1
  136. package/dist/index.d.ts +0 -1
  137. package/dist/install-path.d.ts +0 -1
  138. package/dist/json-document-store.d.ts +0 -1
  139. package/dist/json-durable-queue-directory.d.ts +13 -1
  140. package/dist/json-durable-queue-directory.js +134 -0
  141. package/dist/json-durable-queue-ownership.d.ts +0 -1
  142. package/dist/json-durable-queue-ownership.js +42 -61
  143. package/dist/json-durable-queue-read.d.ts +0 -1
  144. package/dist/json-durable-queue-read.js +6 -6
  145. package/dist/json-durable-queue.d.ts +0 -1
  146. package/dist/json-durable-queue.js +7 -130
  147. package/dist/json-store.d.ts +0 -1
  148. package/dist/json-stringify.d.ts +0 -1
  149. package/dist/json.d.ts +0 -1
  150. package/dist/json.js +6 -15
  151. package/dist/local-file-access.d.ts +0 -1
  152. package/dist/local-file-access.js +3 -10
  153. package/dist/local-file-descriptor.d.ts +0 -1
  154. package/dist/local-roots.d.ts +0 -1
  155. package/dist/lock-config.d.ts +0 -1
  156. package/dist/move-path-cleanup.d.ts +0 -1
  157. package/dist/move-path-stage.d.ts +0 -1
  158. package/dist/move-path.d.ts +0 -1
  159. package/dist/mutation-authority.d.ts +0 -1
  160. package/dist/native-binding.d.ts +0 -1
  161. package/dist/native-config.d.ts +0 -1
  162. package/dist/native-directory-observation.d.ts +0 -1
  163. package/dist/native-fallback-warning.d.ts +0 -1
  164. package/dist/native-operations.d.ts +1 -5
  165. package/dist/native-operations.js +2 -6
  166. package/dist/native-parent-admission.d.ts +0 -1
  167. package/dist/native-pinned-write-windows.d.ts +0 -1
  168. package/dist/native-pinned-write.d.ts +0 -1
  169. package/dist/native-pinned-write.js +4 -10
  170. package/dist/native-policy-directory-observation.d.ts +0 -1
  171. package/dist/native-policy-parent-windows.d.ts +0 -1
  172. package/dist/native-rename-outcome.d.ts +0 -1
  173. package/dist/native-staged-file.d.ts +15 -3
  174. package/dist/native-staged-file.js +55 -63
  175. package/dist/native.d.ts +0 -1
  176. package/dist/opened-file-failure.d.ts +0 -1
  177. package/dist/opened-realpath.d.ts +0 -1
  178. package/dist/output.d.ts +0 -1
  179. package/dist/overwrite-file-handle.d.ts +0 -1
  180. package/dist/owner-dacl.d.ts +0 -1
  181. package/dist/path-case.d.ts +0 -1
  182. package/dist/path-policy.d.ts +0 -1
  183. package/dist/path-prefix.d.ts +0 -1
  184. package/dist/path-scope-lexical.d.ts +0 -1
  185. package/dist/path-segment-route.d.ts +0 -1
  186. package/dist/path-suffix-aliases.d.ts +0 -1
  187. package/dist/path.d.ts +0 -1
  188. package/dist/permission-exec.d.ts +0 -1
  189. package/dist/permission-exec.js +19 -25
  190. package/dist/permissions-public.d.ts +0 -1
  191. package/dist/permissions-windows.d.ts +2 -10
  192. package/dist/permissions-windows.js +10 -30
  193. package/dist/permissions.d.ts +0 -1
  194. package/dist/permissions.js +8 -16
  195. package/dist/pinned-mutation-admission.d.ts +0 -1
  196. package/dist/pinned-mutation-observation.d.ts +0 -1
  197. package/dist/pinned-mutation-shared-route.d.ts +0 -1
  198. package/dist/pinned-open.d.ts +1 -1
  199. package/dist/pinned-open.js +1 -1
  200. package/dist/pinned-operation.d.ts +0 -1
  201. package/dist/pinned-write-input.d.ts +0 -1
  202. package/dist/pinned-write-mode.d.ts +0 -1
  203. package/dist/pinned-write-staged.d.ts +0 -1
  204. package/dist/pinned-write-types.d.ts +9 -21
  205. package/dist/pinned-write.d.ts +0 -1
  206. package/dist/positional-read.d.ts +0 -1
  207. package/dist/private-directory.d.ts +0 -1
  208. package/dist/private-producer-handoff-sync.d.ts +0 -1
  209. package/dist/private-producer-handoff-sync.js +9 -51
  210. package/dist/private-producer-handoff.d.ts +20 -1
  211. package/dist/private-producer-handoff.js +69 -46
  212. package/dist/private-temp-workspace.d.ts +0 -1
  213. package/dist/private-temp-workspace.js +11 -36
  214. package/dist/publish-copy-stage.d.ts +0 -1
  215. package/dist/publish-file-failure.d.ts +0 -1
  216. package/dist/publish-file.d.ts +0 -1
  217. package/dist/read-open-flags.d.ts +0 -1
  218. package/dist/read-opened-file.d.ts +0 -1
  219. package/dist/realpath.d.ts +0 -1
  220. package/dist/recursive-mkdir-path.d.ts +0 -1
  221. package/dist/regular-file.d.ts +0 -1
  222. package/dist/regular-file.js +77 -139
  223. package/dist/replace-directory.d.ts +0 -1
  224. package/dist/replace-file-copy-fallback.d.ts +0 -1
  225. package/dist/replace-file-copy-fallback.js +14 -3
  226. package/dist/replace-file-copy-source.d.ts +0 -1
  227. package/dist/replace-file-copy-source.js +6 -1
  228. package/dist/replace-file-descriptor.d.ts +0 -1
  229. package/dist/replace-file-descriptor.js +6 -1
  230. package/dist/replace-file-mode.d.ts +0 -1
  231. package/dist/replace-file-rename-policy.d.ts +0 -1
  232. package/dist/replace-file-temp-owner.d.ts +12 -13
  233. package/dist/replace-file-temp-owner.js +66 -85
  234. package/dist/replace-file.d.ts +0 -1
  235. package/dist/retained-directory-replacement.d.ts +0 -1
  236. package/dist/root-boundary.d.ts +0 -1
  237. package/dist/root-context.d.ts +0 -1
  238. package/dist/root-create-input.d.ts +0 -1
  239. package/dist/root-directory-creation.d.ts +0 -1
  240. package/dist/root-directory-list.d.ts +0 -1
  241. package/dist/root-directory.d.ts +0 -1
  242. package/dist/root-entries.d.ts +0 -1
  243. package/dist/root-errors.d.ts +0 -1
  244. package/dist/root-file-final-admission.d.ts +0 -1
  245. package/dist/root-file.d.ts +0 -1
  246. package/dist/root-impl.d.ts +2 -10
  247. package/dist/root-impl.js +114 -91
  248. package/dist/root-move-noreplace.d.ts +0 -1
  249. package/dist/root-move-preflight.d.ts +0 -1
  250. package/dist/root-observed-path.d.ts +0 -1
  251. package/dist/root-options.d.ts +0 -1
  252. package/dist/root-path-errors.d.ts +0 -1
  253. package/dist/root-path-existing.d.ts +3 -1
  254. package/dist/root-path-existing.js +39 -18
  255. package/dist/root-path-observation.d.ts +0 -1
  256. package/dist/root-path-stat.d.ts +0 -1
  257. package/dist/root-path.d.ts +0 -1
  258. package/dist/root-path.js +60 -188
  259. package/dist/root-paths-lexical.d.ts +0 -1
  260. package/dist/root-paths.d.ts +0 -1
  261. package/dist/root-read-admission.d.ts +0 -1
  262. package/dist/root-read-admission.js +31 -44
  263. package/dist/root-remove-identity.d.ts +0 -1
  264. package/dist/root-remove-receipt.d.ts +0 -1
  265. package/dist/root-remove.d.ts +0 -1
  266. package/dist/root-symlink-policy.d.ts +0 -1
  267. package/dist/root-walk.d.ts +0 -1
  268. package/dist/root-write-admission.d.ts +0 -1
  269. package/dist/root-write-compatibility.d.ts +0 -1
  270. package/dist/root-write-complete-parent.d.ts +0 -1
  271. package/dist/root-write-lock-binding.d.ts +0 -1
  272. package/dist/root-write-mode.d.ts +0 -1
  273. package/dist/root-write-publication.d.ts +0 -1
  274. package/dist/root-write-verification.d.ts +0 -1
  275. package/dist/root.d.ts +0 -1
  276. package/dist/safe-path-segment.d.ts +1 -2
  277. package/dist/safe-path-segment.js +2 -5
  278. package/dist/secret-file.d.ts +0 -1
  279. package/dist/secret-file.js +7 -17
  280. package/dist/secret-read-async.d.ts +0 -1
  281. package/dist/secret-read-async.js +5 -5
  282. package/dist/secret-read-policy.d.ts +0 -1
  283. package/dist/secret.d.ts +0 -1
  284. package/dist/secure-file-windows.d.ts +0 -6
  285. package/dist/secure-file-windows.js +13 -28
  286. package/dist/secure-file.d.ts +0 -1
  287. package/dist/secure-file.js +9 -9
  288. package/dist/secure-temp-dir.d.ts +0 -1
  289. package/dist/secure-temp-repair.d.ts +0 -1
  290. package/dist/sibling-staged-file.d.ts +0 -1
  291. package/dist/sibling-staged-file.js +32 -39
  292. package/dist/sibling-temp.d.ts +0 -1
  293. package/dist/sidecar-lock-acquire.d.ts +1 -2
  294. package/dist/sidecar-lock-acquire.js +31 -52
  295. package/dist/sidecar-lock-admission-context.d.ts +0 -1
  296. package/dist/sidecar-lock-admission-parser.d.ts +0 -1
  297. package/dist/sidecar-lock-admission.d.ts +1 -5
  298. package/dist/sidecar-lock-admission.js +1 -7
  299. package/dist/sidecar-lock-handle.d.ts +0 -1
  300. package/dist/sidecar-lock-policy.d.ts +3 -1
  301. package/dist/sidecar-lock-policy.js +16 -0
  302. package/dist/sidecar-lock-reclaim.d.ts +0 -1
  303. package/dist/sidecar-lock-registration.d.ts +13 -0
  304. package/dist/sidecar-lock-registration.js +47 -0
  305. package/dist/sidecar-lock-root.d.ts +0 -1
  306. package/dist/sidecar-lock-stale-admission.d.ts +0 -1
  307. package/dist/sidecar-lock-target.d.ts +0 -1
  308. package/dist/sidecar-lock-types.d.ts +0 -1
  309. package/dist/sidecar-lock.d.ts +0 -1
  310. package/dist/sidecar-lock.js +16 -83
  311. package/dist/staged-directory.d.ts +0 -1
  312. package/dist/staged-file-settlement.d.ts +0 -1
  313. package/dist/staged-file-types.d.ts +0 -1
  314. package/dist/standalone-publication-path.d.ts +0 -1
  315. package/dist/stat-observation.d.ts +0 -1
  316. package/dist/store.d.ts +0 -1
  317. package/dist/strict-file-identity.d.ts +0 -1
  318. package/dist/string-coerce.d.ts +0 -1
  319. package/dist/suppressed-error.d.ts +0 -1
  320. package/dist/symlink-parents.d.ts +0 -1
  321. package/dist/temp-cleanup.d.ts +0 -1
  322. package/dist/temp-target.d.ts +0 -1
  323. package/dist/temp-target.js +7 -46
  324. package/dist/temp-workspace-admission.d.ts +0 -8
  325. package/dist/temp-workspace-admission.js +0 -4
  326. package/dist/temp-workspace-child-admission.d.ts +0 -4
  327. package/dist/temp-workspace-child-admission.js +0 -12
  328. package/dist/temp-workspace-descriptor.d.ts +0 -6
  329. package/dist/temp-workspace-descriptor.js +0 -2
  330. package/dist/temp-workspace-identity.d.ts +0 -1
  331. package/dist/temp-workspace-owner.d.ts +1 -1
  332. package/dist/temp-workspace-owner.js +45 -22
  333. package/dist/temp-workspace-permissions.d.ts +0 -1
  334. package/dist/temp-workspace-types.d.ts +0 -1
  335. package/dist/temp.d.ts +0 -1
  336. package/dist/test-hooks.d.ts +0 -1
  337. package/dist/text-atomic.d.ts +0 -1
  338. package/dist/timing.d.ts +0 -1
  339. package/dist/trash.d.ts +0 -1
  340. package/dist/types.d.ts +0 -1
  341. package/dist/unicode-path.d.ts +0 -1
  342. package/dist/walk.d.ts +0 -1
  343. package/dist/windows-command.d.ts +0 -1
  344. package/dist/windows-owner.d.ts +0 -1
  345. package/dist/windows-owner.js +4 -1
  346. package/dist/windows-path-alias.d.ts +0 -1
  347. package/dist/windows-path-alias.js +7 -43
  348. package/dist/windows-path-syntax.d.ts +5 -0
  349. package/dist/windows-path-syntax.js +21 -0
  350. package/dist/windows-security-command.d.ts +0 -1
  351. package/dist/windows-security-facts.d.ts +0 -1
  352. package/dist/write-file-handle.d.ts +0 -1
  353. package/dist/write-open-flags.d.ts +0 -1
  354. package/dist/write-queue.d.ts +0 -1
  355. package/docs/atomic.md +14 -0
  356. package/docs/copy.md +2 -0
  357. package/docs/mutation-policy-proof.md +6 -4
  358. package/docs/permissions.md +6 -0
  359. package/docs/root.md +10 -0
  360. package/docs/secret-file.md +4 -0
  361. package/docs/writing.md +9 -3
  362. package/package.json +8 -9
  363. package/dist/absolute-path.d.ts.map +0 -1
  364. package/dist/advanced.d.ts.map +0 -1
  365. package/dist/archive-crc32.d.ts.map +0 -1
  366. package/dist/archive-deadline.d.ts.map +0 -1
  367. package/dist/archive-durability.d.ts.map +0 -1
  368. package/dist/archive-entry.d.ts.map +0 -1
  369. package/dist/archive-errors.d.ts.map +0 -1
  370. package/dist/archive-gzip-tail.d.ts.map +0 -1
  371. package/dist/archive-input.d.ts.map +0 -1
  372. package/dist/archive-kind.d.ts.map +0 -1
  373. package/dist/archive-limits.d.ts.map +0 -1
  374. package/dist/archive-merge.d.ts.map +0 -1
  375. package/dist/archive-native.d.ts.map +0 -1
  376. package/dist/archive-options.d.ts.map +0 -1
  377. package/dist/archive-parser-errors.d.ts.map +0 -1
  378. package/dist/archive-plan.d.ts.map +0 -1
  379. package/dist/archive-policy.d.ts.map +0 -1
  380. package/dist/archive-read.d.ts.map +0 -1
  381. package/dist/archive-staging.d.ts.map +0 -1
  382. package/dist/archive-tar-inspect.d.ts.map +0 -1
  383. package/dist/archive-tar-stream.d.ts.map +0 -1
  384. package/dist/archive-tar-wasm.d.ts.map +0 -1
  385. package/dist/archive-tar.d.ts.map +0 -1
  386. package/dist/archive-zip-admission.d.ts.map +0 -1
  387. package/dist/archive-zip-count.d.ts.map +0 -1
  388. package/dist/archive-zip-directory.d.ts.map +0 -1
  389. package/dist/archive-zip-entry.d.ts.map +0 -1
  390. package/dist/archive-zip-integrity.d.ts.map +0 -1
  391. package/dist/archive-zip-loader.d.ts.map +0 -1
  392. package/dist/archive-zip-manifest.d.ts.map +0 -1
  393. package/dist/archive-zip-names.d.ts.map +0 -1
  394. package/dist/archive-zip-preflight.d.ts.map +0 -1
  395. package/dist/archive.d.ts.map +0 -1
  396. package/dist/async-lock.d.ts.map +0 -1
  397. package/dist/atomic.d.ts.map +0 -1
  398. package/dist/bounded-read-stream.d.ts.map +0 -1
  399. package/dist/bounded-read.d.ts.map +0 -1
  400. package/dist/byte-budget.d.ts.map +0 -1
  401. package/dist/byte-view.d.ts.map +0 -1
  402. package/dist/clone-metadata.d.ts.map +0 -1
  403. package/dist/config.d.ts.map +0 -1
  404. package/dist/containment.d.ts.map +0 -1
  405. package/dist/copy-file-input.d.ts.map +0 -1
  406. package/dist/copy-policy.d.ts.map +0 -1
  407. package/dist/copy-publication.d.ts.map +0 -1
  408. package/dist/copy-tree-portable.d.ts.map +0 -1
  409. package/dist/copy.d.ts.map +0 -1
  410. package/dist/create-directory.d.ts.map +0 -1
  411. package/dist/create-file-async.d.ts.map +0 -1
  412. package/dist/create-file.d.ts.map +0 -1
  413. package/dist/create-owned-file.d.ts.map +0 -1
  414. package/dist/create.d.ts.map +0 -1
  415. package/dist/creation-darwin.d.ts.map +0 -1
  416. package/dist/creation-file-state.d.ts.map +0 -1
  417. package/dist/creation-path.d.ts.map +0 -1
  418. package/dist/creation-permissions.d.ts.map +0 -1
  419. package/dist/deny-mutations.d.ts.map +0 -1
  420. package/dist/device-path.d.ts.map +0 -1
  421. package/dist/directory-durability.d.ts.map +0 -1
  422. package/dist/directory-entry-path.d.ts.map +0 -1
  423. package/dist/directory-guard.d.ts.map +0 -1
  424. package/dist/directory-mode-node.d.ts.map +0 -1
  425. package/dist/directory-mode-owner.d.ts.map +0 -1
  426. package/dist/directory-receipt.d.ts.map +0 -1
  427. package/dist/durability.d.ts.map +0 -1
  428. package/dist/effective-uid.d.ts.map +0 -1
  429. package/dist/error-detail.d.ts.map +0 -1
  430. package/dist/errors.d.ts.map +0 -1
  431. package/dist/file-cleanup.d.ts.map +0 -1
  432. package/dist/file-contents.d.ts.map +0 -1
  433. package/dist/file-handle-transfer.d.ts.map +0 -1
  434. package/dist/file-hash.d.ts.map +0 -1
  435. package/dist/file-identity.d.ts.map +0 -1
  436. package/dist/file-lock-sync-admission.d.ts.map +0 -1
  437. package/dist/file-lock-sync-root-acquire.d.ts.map +0 -1
  438. package/dist/file-lock-sync-root-arbitration.d.ts.map +0 -1
  439. package/dist/file-lock-sync-root-held.d.ts.map +0 -1
  440. package/dist/file-lock-sync-root-io.d.ts.map +0 -1
  441. package/dist/file-lock-sync-root-mutation.d.ts.map +0 -1
  442. package/dist/file-lock-sync-root-options.d.ts.map +0 -1
  443. package/dist/file-lock-sync-root-registration.d.ts.map +0 -1
  444. package/dist/file-lock-sync-root.d.ts.map +0 -1
  445. package/dist/file-lock-sync-stale-admission.d.ts.map +0 -1
  446. package/dist/file-lock-sync.d.ts.map +0 -1
  447. package/dist/file-lock.d.ts.map +0 -1
  448. package/dist/file-observation.d.ts.map +0 -1
  449. package/dist/file-store-boundary.d.ts.map +0 -1
  450. package/dist/file-store-copy-source.d.ts.map +0 -1
  451. package/dist/file-store-limit.d.ts.map +0 -1
  452. package/dist/file-store-path.d.ts.map +0 -1
  453. package/dist/file-store-prune.d.ts.map +0 -1
  454. package/dist/file-store-sync-directory.d.ts.map +0 -1
  455. package/dist/file-store-sync-write.d.ts.map +0 -1
  456. package/dist/file-store.d.ts.map +0 -1
  457. package/dist/file-sync.d.ts.map +0 -1
  458. package/dist/filename.d.ts.map +0 -1
  459. package/dist/fs.d.ts.map +0 -1
  460. package/dist/guarded-mkdir.d.ts.map +0 -1
  461. package/dist/guarded-mutation.d.ts.map +0 -1
  462. package/dist/guest-dispatch-python.d.ts.map +0 -1
  463. package/dist/guest-native-python.d.ts.map +0 -1
  464. package/dist/guest.d.ts.map +0 -1
  465. package/dist/home-dir.d.ts.map +0 -1
  466. package/dist/index.d.ts.map +0 -1
  467. package/dist/install-path.d.ts.map +0 -1
  468. package/dist/json-document-store.d.ts.map +0 -1
  469. package/dist/json-durable-queue-directory.d.ts.map +0 -1
  470. package/dist/json-durable-queue-ownership.d.ts.map +0 -1
  471. package/dist/json-durable-queue-paths.d.ts +0 -11
  472. package/dist/json-durable-queue-paths.d.ts.map +0 -1
  473. package/dist/json-durable-queue-paths.js +0 -20
  474. package/dist/json-durable-queue-read.d.ts.map +0 -1
  475. package/dist/json-durable-queue.d.ts.map +0 -1
  476. package/dist/json-store.d.ts.map +0 -1
  477. package/dist/json-stringify.d.ts.map +0 -1
  478. package/dist/json.d.ts.map +0 -1
  479. package/dist/local-file-access.d.ts.map +0 -1
  480. package/dist/local-file-descriptor.d.ts.map +0 -1
  481. package/dist/local-roots.d.ts.map +0 -1
  482. package/dist/lock-config.d.ts.map +0 -1
  483. package/dist/move-path-cleanup.d.ts.map +0 -1
  484. package/dist/move-path-stage.d.ts.map +0 -1
  485. package/dist/move-path.d.ts.map +0 -1
  486. package/dist/mutation-authority.d.ts.map +0 -1
  487. package/dist/native-binding.d.ts.map +0 -1
  488. package/dist/native-config.d.ts.map +0 -1
  489. package/dist/native-directory-observation.d.ts.map +0 -1
  490. package/dist/native-fallback-warning.d.ts.map +0 -1
  491. package/dist/native-operations.d.ts.map +0 -1
  492. package/dist/native-parent-admission.d.ts.map +0 -1
  493. package/dist/native-pinned-write-windows.d.ts.map +0 -1
  494. package/dist/native-pinned-write.d.ts.map +0 -1
  495. package/dist/native-policy-directory-observation.d.ts.map +0 -1
  496. package/dist/native-policy-parent-windows.d.ts.map +0 -1
  497. package/dist/native-rename-outcome.d.ts.map +0 -1
  498. package/dist/native-staged-file.d.ts.map +0 -1
  499. package/dist/native.d.ts.map +0 -1
  500. package/dist/opened-file-failure.d.ts.map +0 -1
  501. package/dist/opened-realpath.d.ts.map +0 -1
  502. package/dist/output.d.ts.map +0 -1
  503. package/dist/overwrite-file-handle.d.ts.map +0 -1
  504. package/dist/owner-dacl.d.ts.map +0 -1
  505. package/dist/path-case.d.ts.map +0 -1
  506. package/dist/path-policy.d.ts.map +0 -1
  507. package/dist/path-prefix.d.ts.map +0 -1
  508. package/dist/path-scope-lexical.d.ts.map +0 -1
  509. package/dist/path-segment-route.d.ts.map +0 -1
  510. package/dist/path-suffix-aliases.d.ts.map +0 -1
  511. package/dist/path.d.ts.map +0 -1
  512. package/dist/permission-exec.d.ts.map +0 -1
  513. package/dist/permissions-public.d.ts.map +0 -1
  514. package/dist/permissions-windows.d.ts.map +0 -1
  515. package/dist/permissions.d.ts.map +0 -1
  516. package/dist/pinned-mutation-admission.d.ts.map +0 -1
  517. package/dist/pinned-mutation-observation.d.ts.map +0 -1
  518. package/dist/pinned-mutation-shared-route.d.ts.map +0 -1
  519. package/dist/pinned-open.d.ts.map +0 -1
  520. package/dist/pinned-operation.d.ts.map +0 -1
  521. package/dist/pinned-write-input.d.ts.map +0 -1
  522. package/dist/pinned-write-mode.d.ts.map +0 -1
  523. package/dist/pinned-write-staged.d.ts.map +0 -1
  524. package/dist/pinned-write-types.d.ts.map +0 -1
  525. package/dist/pinned-write.d.ts.map +0 -1
  526. package/dist/positional-read.d.ts.map +0 -1
  527. package/dist/private-directory.d.ts.map +0 -1
  528. package/dist/private-producer-handoff-sync.d.ts.map +0 -1
  529. package/dist/private-producer-handoff.d.ts.map +0 -1
  530. package/dist/private-temp-workspace.d.ts.map +0 -1
  531. package/dist/publish-copy-stage.d.ts.map +0 -1
  532. package/dist/publish-file-failure.d.ts.map +0 -1
  533. package/dist/publish-file.d.ts.map +0 -1
  534. package/dist/read-open-flags.d.ts.map +0 -1
  535. package/dist/read-opened-file.d.ts.map +0 -1
  536. package/dist/realpath.d.ts.map +0 -1
  537. package/dist/recursive-mkdir-path.d.ts.map +0 -1
  538. package/dist/regular-file.d.ts.map +0 -1
  539. package/dist/replace-directory.d.ts.map +0 -1
  540. package/dist/replace-file-copy-fallback.d.ts.map +0 -1
  541. package/dist/replace-file-copy-source.d.ts.map +0 -1
  542. package/dist/replace-file-descriptor.d.ts.map +0 -1
  543. package/dist/replace-file-mode.d.ts.map +0 -1
  544. package/dist/replace-file-rename-policy.d.ts.map +0 -1
  545. package/dist/replace-file-temp-owner.d.ts.map +0 -1
  546. package/dist/replace-file.d.ts.map +0 -1
  547. package/dist/retained-directory-replacement.d.ts.map +0 -1
  548. package/dist/root-boundary.d.ts.map +0 -1
  549. package/dist/root-context.d.ts.map +0 -1
  550. package/dist/root-create-input.d.ts.map +0 -1
  551. package/dist/root-directory-creation.d.ts.map +0 -1
  552. package/dist/root-directory-list.d.ts.map +0 -1
  553. package/dist/root-directory.d.ts.map +0 -1
  554. package/dist/root-entries.d.ts.map +0 -1
  555. package/dist/root-errors.d.ts.map +0 -1
  556. package/dist/root-file-final-admission.d.ts.map +0 -1
  557. package/dist/root-file.d.ts.map +0 -1
  558. package/dist/root-impl.d.ts.map +0 -1
  559. package/dist/root-move-noreplace.d.ts.map +0 -1
  560. package/dist/root-move-preflight.d.ts.map +0 -1
  561. package/dist/root-observed-path.d.ts.map +0 -1
  562. package/dist/root-options.d.ts.map +0 -1
  563. package/dist/root-path-errors.d.ts.map +0 -1
  564. package/dist/root-path-existing.d.ts.map +0 -1
  565. package/dist/root-path-observation.d.ts.map +0 -1
  566. package/dist/root-path-stat.d.ts.map +0 -1
  567. package/dist/root-path-symlink.d.ts +0 -7
  568. package/dist/root-path-symlink.d.ts.map +0 -1
  569. package/dist/root-path-symlink.js +0 -55
  570. package/dist/root-path.d.ts.map +0 -1
  571. package/dist/root-paths-lexical.d.ts.map +0 -1
  572. package/dist/root-paths.d.ts.map +0 -1
  573. package/dist/root-read-admission.d.ts.map +0 -1
  574. package/dist/root-remove-identity.d.ts.map +0 -1
  575. package/dist/root-remove-receipt.d.ts.map +0 -1
  576. package/dist/root-remove.d.ts.map +0 -1
  577. package/dist/root-symlink-policy.d.ts.map +0 -1
  578. package/dist/root-walk.d.ts.map +0 -1
  579. package/dist/root-write-admission.d.ts.map +0 -1
  580. package/dist/root-write-compatibility.d.ts.map +0 -1
  581. package/dist/root-write-complete-parent.d.ts.map +0 -1
  582. package/dist/root-write-lock-binding.d.ts.map +0 -1
  583. package/dist/root-write-mode.d.ts.map +0 -1
  584. package/dist/root-write-publication.d.ts.map +0 -1
  585. package/dist/root-write-verification.d.ts.map +0 -1
  586. package/dist/root.d.ts.map +0 -1
  587. package/dist/safe-path-segment.d.ts.map +0 -1
  588. package/dist/secret-file.d.ts.map +0 -1
  589. package/dist/secret-read-async.d.ts.map +0 -1
  590. package/dist/secret-read-policy.d.ts.map +0 -1
  591. package/dist/secret.d.ts.map +0 -1
  592. package/dist/secure-file-windows.d.ts.map +0 -1
  593. package/dist/secure-file.d.ts.map +0 -1
  594. package/dist/secure-temp-dir.d.ts.map +0 -1
  595. package/dist/secure-temp-repair.d.ts.map +0 -1
  596. package/dist/sibling-staged-file.d.ts.map +0 -1
  597. package/dist/sibling-temp.d.ts.map +0 -1
  598. package/dist/sidecar-lock-acquire.d.ts.map +0 -1
  599. package/dist/sidecar-lock-admission-context.d.ts.map +0 -1
  600. package/dist/sidecar-lock-admission-parser.d.ts.map +0 -1
  601. package/dist/sidecar-lock-admission.d.ts.map +0 -1
  602. package/dist/sidecar-lock-handle.d.ts.map +0 -1
  603. package/dist/sidecar-lock-policy.d.ts.map +0 -1
  604. package/dist/sidecar-lock-reclaim.d.ts.map +0 -1
  605. package/dist/sidecar-lock-root.d.ts.map +0 -1
  606. package/dist/sidecar-lock-stale-admission.d.ts.map +0 -1
  607. package/dist/sidecar-lock-target.d.ts.map +0 -1
  608. package/dist/sidecar-lock-types.d.ts.map +0 -1
  609. package/dist/sidecar-lock.d.ts.map +0 -1
  610. package/dist/staged-directory.d.ts.map +0 -1
  611. package/dist/staged-file-settlement.d.ts.map +0 -1
  612. package/dist/staged-file-types.d.ts.map +0 -1
  613. package/dist/standalone-publication-path.d.ts.map +0 -1
  614. package/dist/stat-observation.d.ts.map +0 -1
  615. package/dist/store.d.ts.map +0 -1
  616. package/dist/strict-file-identity.d.ts.map +0 -1
  617. package/dist/string-coerce.d.ts.map +0 -1
  618. package/dist/suppressed-error.d.ts.map +0 -1
  619. package/dist/symlink-parents.d.ts.map +0 -1
  620. package/dist/temp-cleanup.d.ts.map +0 -1
  621. package/dist/temp-target.d.ts.map +0 -1
  622. package/dist/temp-workspace-admission.d.ts.map +0 -1
  623. package/dist/temp-workspace-child-admission.d.ts.map +0 -1
  624. package/dist/temp-workspace-descriptor.d.ts.map +0 -1
  625. package/dist/temp-workspace-identity.d.ts.map +0 -1
  626. package/dist/temp-workspace-owner.d.ts.map +0 -1
  627. package/dist/temp-workspace-permissions.d.ts.map +0 -1
  628. package/dist/temp-workspace-types.d.ts.map +0 -1
  629. package/dist/temp.d.ts.map +0 -1
  630. package/dist/test-hooks.d.ts.map +0 -1
  631. package/dist/text-atomic.d.ts.map +0 -1
  632. package/dist/timing.d.ts.map +0 -1
  633. package/dist/trash.d.ts.map +0 -1
  634. package/dist/types.d.ts.map +0 -1
  635. package/dist/unicode-path.d.ts.map +0 -1
  636. package/dist/walk.d.ts.map +0 -1
  637. package/dist/windows-command.d.ts.map +0 -1
  638. package/dist/windows-owner.d.ts.map +0 -1
  639. package/dist/windows-path-alias.d.ts.map +0 -1
  640. package/dist/windows-security-command.d.ts.map +0 -1
  641. package/dist/windows-security-facts.d.ts.map +0 -1
  642. package/dist/write-file-handle.d.ts.map +0 -1
  643. package/dist/write-open-flags.d.ts.map +0 -1
  644. package/dist/write-queue.d.ts.map +0 -1
package/dist/root-impl.js CHANGED
@@ -73,6 +73,7 @@ import { PATH_ALIAS_POLICIES } from "./path-policy.js";
73
73
  import { assertNoNulPathInput, hasNodeErrorCode, isNotFoundPathError, isSymlinkOpenError, } from "./path.js";
74
74
  import { readOpenedFileSafely } from "./read-opened-file.js";
75
75
  import { cleanupPinnedFilePath } from "./file-cleanup.js";
76
+ import { sameFileIdentity } from "./file-identity.js";
76
77
  import { removePathIfIdentityUnchanged } from "./replace-file-temp-owner.js";
77
78
  import { realpathSync } from "./realpath.js";
78
79
  import { mkdirPathFallback, prepareRootWriteTarget, tryMkdirAtExactParent } from "./root-directory-creation.js";
@@ -186,30 +187,19 @@ async function openVerifiedLocalFile(filePath, options) {
186
187
  }
187
188
  }
188
189
  export class RootHandle {
189
- rootGuard;
190
- rootIdentity;
190
+ context;
191
191
  rootDir;
192
192
  rootReal;
193
193
  rootWithSep;
194
194
  defaults;
195
195
  constructor(context, defaults = {}) {
196
- this.rootGuard = context.rootGuard;
197
- this.rootIdentity = context.rootIdentity;
196
+ this.context = context;
198
197
  this.rootDir = context.rootDir;
199
198
  this.rootReal = context.rootReal;
200
199
  this.rootWithSep = context.rootWithSep;
201
200
  this.defaults = defaults;
202
201
  registerFileLockSyncRootAdapter(this, context, defaults);
203
202
  }
204
- get context() {
205
- return {
206
- rootDir: this.rootDir,
207
- rootGuard: this.rootGuard,
208
- rootIdentity: this.rootIdentity,
209
- rootReal: this.rootReal,
210
- rootWithSep: this.rootWithSep,
211
- };
212
- }
213
203
  mutationOptions(options) {
214
204
  return {
215
205
  ...options,
@@ -224,9 +214,9 @@ export class RootHandle {
224
214
  }
225
215
  async open(relativePath, options = {}) {
226
216
  return await openFileInRoot(this.context, {
227
- relativePath,
228
217
  ...readDefaults(this.defaults),
229
218
  ...options,
219
+ relativePath,
230
220
  });
231
221
  }
232
222
  async read(relativePath, options = {}) {
@@ -246,9 +236,11 @@ export class RootHandle {
246
236
  return JSON.parse(await this.readText(relativePath, options));
247
237
  }
248
238
  async readAbsolute(filePath, options = {}) {
249
- return await readPathInRoot(this.context, {
250
- filePath,
251
- ...mergeReadOptions(this.defaults, options),
239
+ const context = this.context;
240
+ const readOptions = mergeReadOptions(this.defaults, options);
241
+ return await readFileInRoot(context, {
242
+ relativePath: rootRelativeReadPath(context, filePath),
243
+ ...readOptions,
252
244
  });
253
245
  }
254
246
  reader(options = {}) {
@@ -260,10 +252,11 @@ export class RootHandle {
260
252
  assertValidRootDestinationPath(relativePath);
261
253
  const writeMode = options.writeMode ?? "replace";
262
254
  const target = await openWritableFileInRoot(this.context, {
263
- relativePath,
264
255
  mkdir: this.defaults.mkdir,
265
256
  mode: this.defaults.mode,
266
257
  ...this.mutationOptions(options),
258
+ relativePath,
259
+ expectedWritePath: undefined,
267
260
  append: writeMode === "append",
268
261
  truncateExisting: writeMode === "replace",
269
262
  }).catch(rethrowMutationAuthorityError);
@@ -272,11 +265,11 @@ export class RootHandle {
272
265
  async append(relativePath, data, options = {}) {
273
266
  assertValidRootDestinationPath(relativePath);
274
267
  await appendFileInRoot(this.context, {
275
- relativePath,
276
- data,
277
268
  mkdir: this.defaults.mkdir,
278
269
  mode: this.defaults.mode,
279
270
  ...this.mutationOptions(options),
271
+ relativePath,
272
+ data,
280
273
  durable: options.durable ?? this.defaults.durable ?? true,
281
274
  }).catch(rethrowMutationAuthorityError);
282
275
  }
@@ -285,33 +278,34 @@ export class RootHandle {
285
278
  validateRemoveOptions(options);
286
279
  options.signal?.throwIfAborted();
287
280
  await removePathInRoot(this.context, {
288
- relativePath,
289
281
  ...this.mutationOptions(options),
282
+ relativePath,
290
283
  }).catch(rethrowMutationAuthorityError);
291
284
  }
292
285
  async mkdir(relativePath, options = {}) {
293
286
  assertValidRootDestinationPath(relativePath);
294
287
  await mkdirPathInRoot(this.context, {
295
- relativePath,
296
288
  ...this.mutationOptions(options),
289
+ relativePath,
290
+ allowRoot: false,
297
291
  }).catch(rethrowMutationAuthorityError);
298
292
  }
299
293
  async ensureRoot(options = {}) {
300
294
  await mkdirPathInRoot(this.context, {
295
+ ...this.mutationOptions(options),
301
296
  relativePath: "",
302
297
  allowRoot: true,
303
- ...this.mutationOptions(options),
304
298
  }).catch(rethrowMutationAuthorityError);
305
299
  }
306
300
  async write(relativePath, data, options = {}) {
307
301
  assertValidRootDestinationPath(relativePath);
308
302
  await writeFileInRoot(this.context, {
309
- relativePath,
310
- data,
311
303
  mkdir: this.defaults.mkdir,
312
304
  mode: this.defaults.mode,
313
305
  renameIdentity: this.defaults.renameIdentity,
314
306
  ...this.mutationOptions(options),
307
+ relativePath,
308
+ data,
315
309
  durable: options.durable ?? this.defaults.durable ?? true,
316
310
  }).catch(rethrowMutationAuthorityError);
317
311
  }
@@ -319,11 +313,11 @@ export class RootHandle {
319
313
  assertValidRootDestinationPath(relativePath);
320
314
  const durable = options.durable ?? this.defaults.durable ?? true;
321
315
  await writeFileInRoot(this.context, {
322
- relativePath,
323
- data,
324
316
  mkdir: this.defaults.mkdir,
325
317
  mode: this.defaults.mode,
326
318
  ...this.mutationOptions(createInputOptions(data, options, this.defaults.maxBytes)),
319
+ relativePath,
320
+ data,
327
321
  durable: durable !== false,
328
322
  strictFileSync: durable === "file",
329
323
  overwrite: false,
@@ -343,12 +337,13 @@ export class RootHandle {
343
337
  options.signal?.throwIfAborted();
344
338
  assertValidRootDestinationPath(relativePath);
345
339
  const { maxBytes, ...copyOptions } = this.mutationOptions(options);
340
+ const copySource = typeof source === "string" ? source : { root: source.root, relativePath: source.relativePath };
346
341
  await copyFileInRoot(this.context, {
347
- source: typeof source === "string" ? source : { root: source.root, relativePath: source.relativePath },
348
- relativePath,
349
342
  maxBytes: normalizeMaxBytes(maxBytes, { defaultValue: this.defaults.maxBytes }),
350
343
  mkdir: this.defaults.mkdir,
351
344
  ...copyOptions,
345
+ source: copySource,
346
+ relativePath,
352
347
  mode: options.mode ?? this.defaults.mode,
353
348
  durable: options.durable ?? this.defaults.durable ?? true,
354
349
  verifyPublished: options[onCopyPublication],
@@ -409,7 +404,7 @@ export class RootHandle {
409
404
  walk(relativePath, options) {
410
405
  assertValidRootRelativePath(relativePath);
411
406
  return walkRoot({
412
- rootReal: this.rootReal,
407
+ rootReal: this.context.rootReal,
413
408
  stat: relative => this.stat(relative),
414
409
  list: async (relative, listingOptions) => {
415
410
  validatePinnedOperationPayload({ relativePath: relative });
@@ -468,15 +463,6 @@ async function readFileInRoot(root, params) {
468
463
  await opened.handle.close().catch(() => { });
469
464
  }
470
465
  }
471
- async function readPathInRoot(root, params) {
472
- const relativePath = rootRelativeReadPath(root, params.filePath);
473
- return await readFileInRoot(root, {
474
- relativePath,
475
- hardlinks: params.hardlinks,
476
- maxBytes: params.maxBytes,
477
- symlinks: params.symlinks,
478
- });
479
- }
480
466
  export async function readLocalFileSafely(params) {
481
467
  const maxBytes = normalizeMaxBytes(params.maxBytes);
482
468
  const opened = await openLocalFileSafely({ filePath: params.filePath });
@@ -502,7 +488,7 @@ function buildAtomicWriteTempPath(targetPath) {
502
488
  function rootWriteQueueKey(root, relativePath) {
503
489
  return `${root.rootReal}\0${relativePath}`;
504
490
  }
505
- async function openWritableFileInRoot(root, params) {
491
+ async function openWritableFileInRoot(root, params, options) {
506
492
  const guardedTarget = params.denyMutations === undefined && params.mutationSymlinks === undefined
507
493
  ? undefined
508
494
  : await resolveGuardedWriteTargetInRoot(root, {
@@ -566,6 +552,17 @@ async function openWritableFileInRoot(root, params) {
566
552
  if (!isNotFoundPathError(err)) {
567
553
  throw err;
568
554
  }
555
+ if (options?.createIfMissing === false) {
556
+ const parentGuard = writePathSelection?.parentGuard ??
557
+ await createAsyncDirectoryGuard(path.dirname(ioPath), { bigint: true });
558
+ assertRootIdentityCurrentSync(root);
559
+ if (!admitPathInsideRoot({
560
+ rootPath: root.rootReal, candidatePath: parentGuard.realPath, rootIdentity: root.rootIdentity,
561
+ }))
562
+ throw outsideWorkspaceError();
563
+ assertSyncDirectoryGuard(parentGuard);
564
+ return { missing: true, targetPath: ioPath, parentGuard, writeSelection: writePathSelection };
565
+ }
569
566
  if (writePathSelection)
570
567
  await refreshRootWritePathSelection(writePathSelection);
571
568
  params.assertBeforeMutation?.();
@@ -790,16 +787,11 @@ async function mkdirPathInRoot(root, params) {
790
787
  const policy = params.denyMutations === undefined && params.mutationSymlinks === undefined
791
788
  ? undefined
792
789
  : snapshotPinnedMutationPolicy(params.denyMutations, params.mutationSymlinks);
790
+ const resolution = { relativePath: params.relativePath, allowRoot: params.allowRoot, ...policy };
793
791
  const resolveCurrent = policy
794
- ? async () => await resolvePinnedPathInRoot(root, {
795
- ...params,
796
- denyMutations: policy.denyMutations,
797
- mutationSymlinks: policy.mutationSymlinks,
798
- })
792
+ ? async () => await resolvePinnedPathInRoot(root, resolution)
799
793
  : undefined;
800
- const resolved = resolveCurrent
801
- ? await resolveCurrent()
802
- : await resolvePinnedPathInRoot(root, params);
794
+ const resolved = await resolvePinnedPathInRoot(root, resolution);
803
795
  const prepared = policy && resolved.relativePosix !== ""
804
796
  ? await preparePinnedWriteMutationAdmission({
805
797
  rootReal: resolved.rootReal,
@@ -995,20 +987,9 @@ async function copyFileInRoot(root, params) {
995
987
  }
996
988
  }
997
989
  async function resolvePinnedPathInRoot(root, params) {
998
- return await resolvePinnedOperationPathInRoot(root, {
999
- allowRoot: params.allowRoot,
1000
- denyMutations: params.denyMutations,
1001
- mutationSymlinks: params.mutationSymlinks,
1002
- protectDenyMutationAncestors: params.remove === true,
1003
- relativePath: params.relativePath,
1004
- policy: params.remove ? PATH_ALIAS_POLICIES.unlinkTarget : PATH_ALIAS_POLICIES.strict,
1005
- removalReceipts: params.removalReceipts,
1006
- });
1007
- }
1008
- async function resolvePinnedOperationPathInRoot(root, params) {
1009
990
  const resolved = await resolvePinnedRootPathInRoot(root, {
1010
991
  relativePath: params.relativePath,
1011
- policy: params.policy,
992
+ policy: params.remove ? PATH_ALIAS_POLICIES.unlinkTarget : PATH_ALIAS_POLICIES.strict,
1012
993
  mutationSymlinks: params.mutationSymlinks,
1013
994
  removalReceipts: params.removalReceipts,
1014
995
  });
@@ -1035,7 +1016,7 @@ async function resolvePinnedOperationPathInRoot(root, params) {
1035
1016
  }
1036
1017
  resolved.canonicalPath = admittedCanonicalPath.path;
1037
1018
  await assertMutationNotDenied(resolved.canonicalPath, params.denyMutations, {
1038
- protectAncestors: params.protectDenyMutationAncestors,
1019
+ protectAncestors: params.remove === true,
1039
1020
  });
1040
1021
  return { rootReal: resolved.rootReal, resolved: resolved.canonicalPath, relativePosix };
1041
1022
  }
@@ -1222,48 +1203,59 @@ async function writeFileFallbackUnlocked(root, params, expectedWritePath) {
1222
1203
  await writeMissingFileFallback(root, params, expectedWritePath);
1223
1204
  return;
1224
1205
  }
1225
- const { opened: target, identity: targetIdentity, writeSelection: retainedSelection } = await openWritableFileInRoot(root, {
1206
+ const admissionParams = {
1226
1207
  relativePath: params.relativePath,
1227
1208
  mkdir: params.mkdir,
1228
- // Private, writable placeholder: Windows cannot rename over a read-only file.
1229
- mode: 0o600,
1230
1209
  denyMutations: params.denyMutations,
1231
1210
  assertBeforeMutation: params.assertBeforeMutation,
1232
1211
  mutationSymlinks: params.mutationSymlinks,
1233
1212
  truncateExisting: false,
1234
1213
  expectedWritePath,
1235
- });
1214
+ };
1215
+ const admission = await openWritableFileInRoot(root, admissionParams, { createIfMissing: false });
1216
+ const existing = "missing" in admission ? undefined : admission;
1217
+ const target = existing?.opened;
1218
+ const retainedSelection = existing?.writeSelection;
1219
+ const missingSelection = "missing" in admission ? admission.writeSelection : undefined;
1236
1220
  const policyEnabled = params.denyMutations !== undefined || params.mutationSymlinks !== undefined;
1237
- const destinationPath = retainedSelection?.selectedPath ?? target.realPath;
1238
- const mode = params.mode ?? (target.stat.mode & 0o777);
1239
- if (policyEnabled && !retainedSelection) {
1240
- await target.handle.close().catch(() => undefined);
1221
+ const destinationPath = "missing" in admission ? admission.targetPath
1222
+ : retainedSelection?.selectedPath ?? admission.opened.realPath;
1223
+ let mode = params.mode ?? (target ? target.stat.mode & 0o777 : undefined);
1224
+ if (policyEnabled && !retainedSelection && !missingSelection) {
1225
+ await target?.handle.close().catch(() => undefined);
1241
1226
  throw new FsSafeError("path-mismatch", "write admission state was not retained");
1242
1227
  }
1243
- const destinationGuard = retainedSelection?.parentGuard ??
1228
+ const destinationGuard = "missing" in admission ? admission.parentGuard : retainedSelection?.parentGuard ??
1244
1229
  await createAsyncDirectoryGuard(path.dirname(destinationPath), { bigint: true }).catch(async (error) => {
1245
- await target.handle.close().catch(() => undefined);
1230
+ await target?.handle.close().catch(() => undefined);
1246
1231
  throw error;
1247
1232
  });
1248
1233
  let tempPath = null;
1249
1234
  let unregisterTempPath = null;
1250
1235
  let writtenHandle;
1251
1236
  let writtenIdentity;
1252
- let placeholderIdentity;
1253
- let published = false;
1237
+ let lateTargetHandle;
1254
1238
  try {
1255
- if (target.createdForWrite)
1256
- placeholderIdentity = targetIdentity;
1257
1239
  tempPath = buildAtomicWriteTempPath(destinationPath);
1258
1240
  if (retainedSelection) {
1259
- await refreshRetainedRootWriteAdmission(root, retainedSelection, true, target.handle.fd);
1241
+ await refreshRetainedRootWriteAdmission(root, retainedSelection, true, target?.handle.fd);
1242
+ }
1243
+ else if (missingSelection) {
1244
+ await refreshRootWritePathSelection(missingSelection);
1260
1245
  }
1261
1246
  params.assertBeforeMutation?.();
1262
1247
  if (retainedSelection) {
1263
- assertRootWriteSelectionSync(root, retainedSelection, true, target.handle.fd);
1248
+ assertRootWriteSelectionSync(root, retainedSelection, true, target?.handle.fd);
1264
1249
  }
1250
+ else if (missingSelection) {
1251
+ assertRootWritePathSelectionSync(root, missingSelection);
1252
+ }
1253
+ assertRootIdentityCurrentSync(root);
1254
+ assertSyncDirectoryGuard(destinationGuard);
1265
1255
  writtenHandle = await fs.open(tempPath, OPEN_WRITE_CREATE_FLAGS, 0o600);
1266
1256
  writtenIdentity = fsSync.fstatSync(writtenHandle.fd, { bigint: true });
1257
+ // Preserve the creation mask when no existing destination supplies a mode.
1258
+ mode ??= Number(writtenIdentity.mode & 511n);
1267
1259
  unregisterTempPath = registerTempPathForExit(tempPath, { identity: writtenIdentity, singleLinkFile: true });
1268
1260
  await writeAllToFile(writtenHandle, params.data, {
1269
1261
  encoding: params.encoding, assertBeforeMutation: params.assertBeforeMutation,
@@ -1278,24 +1270,42 @@ async function writeFileFallbackUnlocked(root, params, expectedWritePath) {
1278
1270
  root, targetPath: commitTempPath, fd: commitHandle.fd,
1279
1271
  expectedIdentity: commitIdentity, parentGuard: destinationGuard,
1280
1272
  });
1281
- if (target.createdForWrite) {
1282
- await cleanupPinnedFilePath({
1283
- pathname: destinationPath, handle: target.handle, identity: placeholderIdentity, parentGuard: destinationGuard,
1284
- });
1273
+ assertRootIdentityCurrentSync(root);
1274
+ assertSyncDirectoryGuard(destinationGuard);
1275
+ let publicationIdentity = inspectFallbackReplacementDestination(destinationPath);
1276
+ // A raced file needs its own access admission, not the old handle's rights.
1277
+ if (publicationIdentity && (!existing || !sameFileIdentity(publicationIdentity, existing.identity))) {
1278
+ const admitted = await openWritableFileInRoot(root, {
1279
+ ...admissionParams, mkdir: false, expectedWritePath: destinationPath,
1280
+ }, { createIfMissing: false });
1281
+ lateTargetHandle = "missing" in admitted ? undefined : admitted.opened.handle;
1282
+ publicationIdentity = "missing" in admitted ? undefined : admitted.identity;
1283
+ await lateTargetHandle?.close();
1285
1284
  }
1286
1285
  // Windows cannot replace a destination while its old handle remains open.
1287
- await target.handle.close();
1286
+ await target?.handle.close();
1288
1287
  if (retainedSelection) {
1289
- await refreshRetainedRootWriteAdmission(root, retainedSelection, !target.createdForWrite);
1288
+ await refreshRetainedRootWriteAdmission(root, retainedSelection, true);
1289
+ }
1290
+ else if (missingSelection) {
1291
+ await refreshRootWritePathSelection(missingSelection);
1290
1292
  }
1291
1293
  assertFinalSymlinkRejected(destinationPath, params.mutationSymlinks !== undefined);
1292
1294
  params.assertBeforeMutation?.();
1293
1295
  if (retainedSelection) {
1294
- assertRootWriteSelectionSync(root, retainedSelection, !target.createdForWrite);
1296
+ assertRootWriteSelectionSync(root, retainedSelection, true);
1297
+ }
1298
+ else if (missingSelection) {
1299
+ assertRootWritePathSelectionSync(root, missingSelection);
1300
+ }
1301
+ assertRootIdentityCurrentSync(root);
1302
+ assertSyncDirectoryGuard(destinationGuard);
1303
+ const current = inspectFallbackReplacementDestination(destinationPath);
1304
+ if (publicationIdentity ? !current || !sameFileIdentity(current, publicationIdentity) : current) {
1305
+ throw new FsSafeError("path-mismatch", "write destination changed before publication");
1295
1306
  }
1296
1307
  await fs.rename(commitTempPath, destinationPath);
1297
1308
  tempPath = null;
1298
- published = true;
1299
1309
  });
1300
1310
  unregisterTempPath();
1301
1311
  unregisterTempPath = null;
@@ -1308,12 +1318,8 @@ async function writeFileFallbackUnlocked(root, params, expectedWritePath) {
1308
1318
  });
1309
1319
  }
1310
1320
  finally {
1311
- if (!published && target.createdForWrite) {
1312
- await cleanupPinnedFilePath({
1313
- pathname: destinationPath, handle: target.handle, identity: placeholderIdentity, parentGuard: destinationGuard,
1314
- });
1315
- }
1316
- await target.handle.close().catch(() => undefined);
1321
+ await target?.handle.close().catch(() => undefined);
1322
+ await lateTargetHandle?.close().catch(() => undefined);
1317
1323
  if (tempPath && writtenHandle) {
1318
1324
  await cleanupPinnedFilePath({
1319
1325
  pathname: tempPath, handle: writtenHandle, identity: writtenIdentity, parentGuard: destinationGuard,
@@ -1323,6 +1329,23 @@ async function writeFileFallbackUnlocked(root, params, expectedWritePath) {
1323
1329
  unregisterTempPath?.();
1324
1330
  }
1325
1331
  }
1332
+ function inspectFallbackReplacementDestination(targetPath) {
1333
+ let current;
1334
+ try {
1335
+ current = inspectFileIdentitySync(() => fsSync.lstatSync(targetPath, { bigint: true }));
1336
+ }
1337
+ catch (error) {
1338
+ if (isNotFoundPathError(error))
1339
+ return;
1340
+ throw error;
1341
+ }
1342
+ if (current.isSymbolicLink() || !current.isFile()) {
1343
+ throw new FsSafeError("path-mismatch", "write destination changed before publication");
1344
+ }
1345
+ if (current.nlink > 1n)
1346
+ throw hardlinkedPathNotAllowedError();
1347
+ return current;
1348
+ }
1326
1349
  async function writeMissingFileFallback(root, params, expectedWritePath) {
1327
1350
  const guardedTarget = params.denyMutations === undefined && params.mutationSymlinks === undefined
1328
1351
  ? undefined
@@ -13,4 +13,3 @@ export declare function movePathNoReplaceNative(root: RootContext, params: {
13
13
  targetPath: string;
14
14
  targetParentPath: string;
15
15
  }): Promise<void>;
16
- //# sourceMappingURL=root-move-noreplace.d.ts.map
@@ -5,4 +5,3 @@ export declare function assertMoveMutationAllowed(root: RootContext, params: {
5
5
  toRelative: string;
6
6
  denyMutations?: DenyMutationPolicy;
7
7
  }): Promise<void>;
8
- //# sourceMappingURL=root-move-preflight.d.ts.map
@@ -6,4 +6,3 @@ export type PinnedObservedPath = {
6
6
  receipt?: RootPathObservationReceipt;
7
7
  };
8
8
  export declare function resolvePinnedObservedPathInRoot(root: RootContext, relativePath: string, kind: RootPathObservationKind): Promise<PinnedObservedPath | undefined>;
9
- //# sourceMappingURL=root-observed-path.d.ts.map
@@ -82,4 +82,3 @@ export type RootMkdirOptions = Pick<RootDefaults, "assertBeforeMutation" | "deny
82
82
  export type RootReadParams = Omit<RootReadOptions, "nonBlockingRead">;
83
83
  export declare function readDefaults(defaults: RootDefaults): RootReadParams;
84
84
  export declare function mergeReadOptions(defaults: RootDefaults, options: RootReadOptions): RootReadParams;
85
- //# sourceMappingURL=root-options.d.ts.map
@@ -10,4 +10,3 @@ export declare function symlinkEscapeError(params: {
10
10
  rootCanonicalPath: string;
11
11
  symlinkPath: string;
12
12
  }): Error;
13
- //# sourceMappingURL=root-path-errors.d.ts.map
@@ -7,4 +7,6 @@ export declare function rawPathRelativeToCanonicalRoot(candidate: string, rootCa
7
7
  }): string | undefined;
8
8
  export declare function resolvePathViaExistingAncestor(targetPath: string): Promise<string>;
9
9
  export declare function resolvePathViaExistingAncestorSync(targetPath: string): string;
10
- //# sourceMappingURL=root-path-existing.d.ts.map
10
+ export type RootPathMetadataMode = "native" | "ordinary";
11
+ export declare function resolveExistingAncestor(targetPath: string, mode: RootPathMetadataMode): string;
12
+ export declare function resolveSymlinkHopPath(symlinkPath: string, mode: RootPathMetadataMode, rejectUnresolved?: boolean): string;
@@ -2,9 +2,9 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { FsSafeError } from "./errors.js";
4
4
  import { formatErrorDetail } from "./error-detail.js";
5
- import { isNotFoundPathError, isPathInside } from "./path.js";
5
+ import { isNotFoundPathError, isPathInside, isSymlinkOpenError } from "./path.js";
6
6
  import { realpathSync } from "./realpath.js";
7
- import { assertNoWindowsPathAlias, pathForWindowsFilesystem, resolvePathPreservingWindowsRoot, } from "./windows-path-alias.js";
7
+ import { assertNoWindowsPathAlias, pathForWindowsFilesystem, resolvePathFromBasePreservingWindowsRoot, resolvePathPreservingWindowsRoot, } from "./windows-path-alias.js";
8
8
  import { admitPathInsideRoot } from "./root-boundary.js";
9
9
  export function absolutePathWithRawSegments(candidate) {
10
10
  if (path.sep !== "\\") {
@@ -81,9 +81,6 @@ export function rawPathRelativeToCanonicalRoot(candidate, rootCanonicalPath, opt
81
81
  }
82
82
  return undefined;
83
83
  }
84
- function isFilesystemRoot(candidate) {
85
- return path.parse(candidate).root === candidate;
86
- }
87
84
  function pathExists(targetPath) {
88
85
  try {
89
86
  return fs.lstatSync(pathForWindowsFilesystem(targetPath), { throwIfNoEntry: false }) !== undefined;
@@ -96,28 +93,25 @@ function pathExists(targetPath) {
96
93
  }
97
94
  }
98
95
  export async function resolvePathViaExistingAncestor(targetPath) {
99
- return resolveExistingAncestor(targetPath, pathExists, realpathSync.native);
96
+ return resolveExistingAncestor(targetPath, "native");
100
97
  }
101
98
  function pathExistsSync(targetPath) {
102
99
  return fs.existsSync(pathForWindowsFilesystem(targetPath));
103
100
  }
104
101
  export function resolvePathViaExistingAncestorSync(targetPath) {
105
- return resolveExistingAncestor(targetPath, pathExistsSync, realpathSync);
102
+ return resolveExistingAncestor(targetPath, "ordinary");
106
103
  }
107
- function resolveExistingAncestor(targetPath, exists, canonicalize) {
104
+ export function resolveExistingAncestor(targetPath, mode) {
105
+ const exists = mode === "native" ? pathExists : pathExistsSync;
106
+ const canonicalize = mode === "native" ? realpathSync.native : realpathSync;
108
107
  assertNoWindowsPathAlias(targetPath);
109
108
  const normalized = resolvePathPreservingWindowsRoot(targetPath);
110
109
  assertNoWindowsPathAlias(normalized);
111
110
  let cursor = normalized;
112
- const missingSuffix = [];
113
- while (!isFilesystemRoot(cursor) &&
111
+ const filesystemRoot = path.parse(normalized).root;
112
+ while (cursor !== filesystemRoot &&
114
113
  !exists(cursor)) {
115
- missingSuffix.unshift(path.basename(cursor));
116
- const parent = path.dirname(cursor);
117
- if (parent === cursor) {
118
- break;
119
- }
120
- cursor = parent;
114
+ cursor = path.dirname(cursor);
121
115
  }
122
116
  if (!exists(cursor)) {
123
117
  return normalized;
@@ -132,9 +126,36 @@ function resolveExistingAncestor(targetPath, exists, canonicalize) {
132
126
  assertNoWindowsPathAlias(rawResolvedAncestor);
133
127
  const resolvedAncestor = resolvePathPreservingWindowsRoot(rawResolvedAncestor);
134
128
  assertNoWindowsPathAlias(resolvedAncestor);
135
- const resolved = missingSuffix.length === 0
129
+ // Keep a leading suffix separator relative to the canonical ancestor.
130
+ const resolved = cursor === normalized
136
131
  ? resolvedAncestor
137
- : path.resolve(resolvedAncestor, ...missingSuffix);
132
+ : path.resolve(resolvedAncestor, `.${path.sep}${normalized.slice(cursor.length)}`);
138
133
  assertNoWindowsPathAlias(resolved);
139
134
  return resolved;
140
135
  }
136
+ export function resolveSymlinkHopPath(symlinkPath, mode, rejectUnresolved) {
137
+ try {
138
+ const canonicalize = mode === "native" ? realpathSync.native : realpathSync;
139
+ const rawRealPath = canonicalize(symlinkPath);
140
+ assertNoWindowsPathAlias(rawRealPath, "filesystem", "resolved symlink path uses a Windows filesystem namespace alias");
141
+ const realPath = resolvePathPreservingWindowsRoot(rawRealPath);
142
+ assertNoWindowsPathAlias(realPath, "filesystem", "resolved symlink path uses a Windows filesystem namespace alias");
143
+ return realPath;
144
+ }
145
+ catch (error) {
146
+ if (isSymlinkOpenError(error) || (rejectUnresolved && isNotFoundPathError(error))) {
147
+ throw new FsSafeError("symlink", "symlink path could not be resolved", {
148
+ cause: error instanceof Error ? error : undefined,
149
+ });
150
+ }
151
+ if (!isNotFoundPathError(error))
152
+ throw error;
153
+ const linkTarget = fs.readlinkSync(symlinkPath);
154
+ assertNoWindowsPathAlias(linkTarget, "filesystem", "symlink target uses a Windows filesystem namespace alias");
155
+ const linkDir = resolvePathPreservingWindowsRoot(path.dirname(symlinkPath));
156
+ const targetPath = resolvePathFromBasePreservingWindowsRoot(linkDir, linkTarget);
157
+ const resolved = resolveExistingAncestor(targetPath, mode);
158
+ assertNoWindowsPathAlias(resolved, "filesystem", "resolved symlink path uses a Windows filesystem namespace alias");
159
+ return resolved;
160
+ }
161
+ }
@@ -60,4 +60,3 @@ export type RootPathTraversalContext = {
60
60
  export declare function createRootPathTraversalObservation(context: RootPathTraversalContext, request?: RootPathObservationRequest): RootPathTraversalObservation | undefined;
61
61
  export declare function inspectRootPathTraversalEntry(pathname: string, directorySlot: boolean, observation: RootPathTraversalObservation): RootPathObservedTraversalEntry;
62
62
  export declare function captureRootPathObservedDirectory(observation: RootPathTraversalObservation, observed: RootPathObservedTraversalEntry, publicPath: string, canonicalPath: string, rootCanonicalPath: string, rootIdentity?: RootBoundaryIdentity): boolean;
63
- //# sourceMappingURL=root-path-observation.d.ts.map
@@ -2,4 +2,3 @@ import type { RootContext } from "./root-context.js";
2
2
  import type { RootPathObservationReceipt } from "./root-path.js";
3
3
  import type { PathStat } from "./types.js";
4
4
  export declare function statResolvedPathInRoot(root: RootContext, resolvedPath: string, receipt?: RootPathObservationReceipt): Promise<PathStat>;
5
- //# sourceMappingURL=root-path-stat.d.ts.map
@@ -51,4 +51,3 @@ export declare function resolveRootPathWithObservation(params: ResolveRootPathPa
51
51
  export declare function resolveRootPathForRemoval(params: ResolveRootPathParams, receipts: RemovalPathReceipts): Promise<ResolvedRootPath>;
52
52
  export declare function resolveRootPathSync(params: ResolveRootPathParams): ResolvedRootPath;
53
53
  export declare function resolveRootPathSyncWithCanonicalRootObservation(params: ResolveRootPathParams, observeRoot: (rootCanonicalPath: string) => void): ResolvedRootPath;
54
- //# sourceMappingURL=root-path.d.ts.map