@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
@@ -28,116 +28,6 @@ function inspectStoreDirectory(params) {
28
28
  return stat;
29
29
  }, params.expected);
30
30
  }
31
- function observeStoreDirectory(params) {
32
- return {
33
- dir: params.dir,
34
- stat: inspectStoreDirectory(params),
35
- };
36
- }
37
- function inspectReceiptCurrent(receipt, messagePrefix, root) {
38
- try {
39
- const stat = inspectStoreDirectory({
40
- dir: receipt.dir,
41
- expected: receipt.stat,
42
- messagePrefix,
43
- root,
44
- });
45
- if (stat.dev !== receipt.stat.dev || stat.ino !== receipt.stat.ino) {
46
- throw changedStoreDirectory(messagePrefix);
47
- }
48
- return stat;
49
- }
50
- catch (error) {
51
- if (error instanceof FsSafeError && error.code === "outside-workspace")
52
- throw error;
53
- throw changedStoreDirectory(messagePrefix, error);
54
- }
55
- }
56
- function assertRootCurrent(rootReceipt, rootReal, messagePrefix) {
57
- const stat = inspectReceiptCurrent(rootReceipt, messagePrefix, true);
58
- try {
59
- if (storeDirectoryRealPath(rootReceipt.dir) !== rootReal) {
60
- throw changedStoreDirectory(messagePrefix);
61
- }
62
- }
63
- catch (error) {
64
- if (error instanceof FsSafeError && error.code === "outside-workspace")
65
- throw error;
66
- throw changedStoreDirectory(messagePrefix, error);
67
- }
68
- return stat;
69
- }
70
- function assertAdmittedEdgeCurrent(receipts, rootReal, messagePrefix) {
71
- const rootReceipt = receipts[0];
72
- const targetIndex = receipts.length - 1;
73
- const targetReceipt = receipts[targetIndex];
74
- if (!rootReceipt || !targetReceipt) {
75
- throw new FsSafeError("helper-failed", "store directory receipt is missing");
76
- }
77
- const rootStat = rootReal === undefined
78
- ? inspectReceiptCurrent(rootReceipt, messagePrefix, true)
79
- : assertRootCurrent(rootReceipt, rootReal, messagePrefix);
80
- if (targetIndex === 0)
81
- return rootStat;
82
- const parent = receipts[targetIndex - 1];
83
- if (!parent)
84
- throw new FsSafeError("helper-failed", "store directory receipt is missing");
85
- if (targetIndex > 1)
86
- inspectReceiptCurrent(parent, messagePrefix, false);
87
- const targetStat = inspectReceiptCurrent(targetReceipt, messagePrefix, false);
88
- if (path.dirname(targetReceipt.dir) !== parent.dir) {
89
- throw changedStoreDirectory(messagePrefix);
90
- }
91
- return targetStat;
92
- }
93
- function assertModeTargetCurrent(receipts, rootReal, messagePrefix) {
94
- const root = receipts[0];
95
- const target = receipts.at(-1);
96
- if (!root || !target)
97
- throw new FsSafeError("helper-failed", "store directory receipt is missing");
98
- // The target's canonical observation shares the exact identity fence. Keep
99
- // the trailing root canonical check: an ancestor relocation can retain IDs.
100
- assertAdmittedEdgeCurrent(receipts, undefined, messagePrefix);
101
- let targetReal;
102
- try {
103
- targetReal = storeDirectoryRealPath(target.dir);
104
- }
105
- catch (error) {
106
- throw changedStoreDirectory(messagePrefix, error);
107
- }
108
- if (target === root ? targetReal !== rootReal : !isPathInside(rootReal, targetReal)) {
109
- throw changedStoreDirectory(messagePrefix);
110
- }
111
- return assertAdmittedEdgeCurrent(receipts, rootReal, messagePrefix);
112
- }
113
- function assertReceiptChain(receipts, rootReal, messagePrefix) {
114
- const rootReceipt = receipts[0];
115
- const finalReceipt = receipts.at(-1);
116
- if (!rootReceipt || !finalReceipt) {
117
- throw new FsSafeError("helper-failed", "store directory receipt is missing");
118
- }
119
- assertRootCurrent(rootReceipt, rootReal, messagePrefix);
120
- let finalStat = rootReceipt.stat;
121
- for (const [index, receipt] of receipts.entries()) {
122
- if (index === 0)
123
- continue;
124
- finalStat = inspectReceiptCurrent(receipt, messagePrefix, false);
125
- }
126
- let finalReal;
127
- try {
128
- finalReal = storeDirectoryRealPath(finalReceipt.dir);
129
- }
130
- catch (error) {
131
- throw changedStoreDirectory(messagePrefix, error);
132
- }
133
- if (!isPathInside(rootReal, finalReal))
134
- throw changedStoreDirectory(messagePrefix);
135
- assertRootCurrent(rootReceipt, rootReal, messagePrefix);
136
- if (finalReceipt !== rootReceipt) {
137
- finalStat = inspectReceiptCurrent(finalReceipt, messagePrefix, false);
138
- }
139
- return { finalReal, finalStat };
140
- }
141
31
  function directoryOpenFlags() {
142
32
  const { O_DIRECTORY, O_NOFOLLOW, O_NONBLOCK, O_RDONLY } = fs.constants;
143
33
  if ([O_DIRECTORY, O_NOFOLLOW, O_NONBLOCK, O_RDONLY]
@@ -169,106 +59,209 @@ function hasErrorCode(error, code) {
169
59
  }
170
60
  return false;
171
61
  }
172
- function openStoreDirectoryForMode(params) {
173
- let openError;
174
- try {
175
- return fs.openSync(pathForWindowsFilesystem(params.receipt.dir), directoryOpenFlags());
176
- }
177
- catch (error) {
178
- openError = error;
62
+ class StoreDirectoryChain {
63
+ messagePrefix;
64
+ receipts = [];
65
+ rootReal;
66
+ constructor(rootDir, messagePrefix) {
67
+ this.messagePrefix = messagePrefix;
68
+ this.observe(rootDir);
69
+ this.rootReal = storeDirectoryRealPath(rootDir);
70
+ }
71
+ observe(dir) {
72
+ this.receipts.push({
73
+ dir,
74
+ stat: inspectStoreDirectory({
75
+ dir,
76
+ messagePrefix: this.messagePrefix,
77
+ root: this.receipts.length === 0,
78
+ }),
79
+ });
179
80
  }
180
- const searchFlags = hasErrorCode(openError, "EACCES") ? directorySearchFlags() : undefined;
181
- if (searchFlags !== undefined) {
81
+ inspectReceipt(receipt, root = false) {
182
82
  try {
183
- return fs.openSync(pathForWindowsFilesystem(params.receipt.dir), searchFlags);
83
+ const stat = inspectStoreDirectory({
84
+ dir: receipt.dir,
85
+ expected: receipt.stat,
86
+ messagePrefix: this.messagePrefix,
87
+ root,
88
+ });
89
+ if (stat.dev !== receipt.stat.dev || stat.ino !== receipt.stat.ino) {
90
+ throw changedStoreDirectory(this.messagePrefix);
91
+ }
92
+ return stat;
184
93
  }
185
- catch (searchError) {
186
- openError = createSuppressedError(searchError, openError, "ordinary and search-only directory opens both failed");
94
+ catch (error) {
95
+ if (error instanceof FsSafeError && error.code === "outside-workspace")
96
+ throw error;
97
+ throw changedStoreDirectory(this.messagePrefix, error);
187
98
  }
188
99
  }
189
- try {
190
- assertModeTargetCurrent(params.receipts, params.rootReal, params.messagePrefix);
191
- }
192
- catch (boundaryError) {
193
- throw changedStoreDirectory(params.messagePrefix, createSuppressedError(boundaryError, openError, "directory acquisition and boundary revalidation both failed"));
194
- }
195
- if (hasErrorCode(openError, "EACCES")) {
196
- throw new FsSafeError("permission-unverified", `${params.messagePrefix} directory cannot be safely mode-repaired through a Node descriptor`, { cause: openError });
197
- }
198
- throw openError;
199
- }
200
- function requestedDirectoryMode(mode) {
201
- return BigInt(mode & 0o7777);
202
- }
203
- function inspectOpenedStoreDirectory(descriptor, receipt, messagePrefix) {
204
- try {
205
- const stat = inspectFileIdentitySync(() => fs.fstatSync(descriptor, { bigint: true }), receipt.stat);
206
- if (!stat.isDirectory() || stat.isSymbolicLink()) {
207
- throw changedStoreDirectory(messagePrefix);
100
+ assertRoot() {
101
+ const root = this.receipts[0];
102
+ const stat = this.inspectReceipt(root, true);
103
+ try {
104
+ if (storeDirectoryRealPath(root.dir) !== this.rootReal) {
105
+ throw changedStoreDirectory(this.messagePrefix);
106
+ }
107
+ }
108
+ catch (error) {
109
+ if (error instanceof FsSafeError && error.code === "outside-workspace")
110
+ throw error;
111
+ throw changedStoreDirectory(this.messagePrefix, error);
208
112
  }
209
113
  return stat;
210
114
  }
211
- catch (error) {
212
- if (error instanceof FsSafeError && error.code === "outside-workspace")
213
- throw error;
214
- throw changedStoreDirectory(messagePrefix, error);
215
- }
216
- }
217
- function finalizeDirectoryMode(params) {
218
- const receipt = params.receipts.at(-1);
219
- if (!receipt)
220
- throw new FsSafeError("helper-failed", "store directory receipt is missing");
221
- const requestedMode = requestedDirectoryMode(params.mode);
222
- if ((receipt.stat.mode & 4095n) === requestedMode || process.platform === "win32") {
223
- const current = assertAdmittedEdgeCurrent(params.receipts, params.rootReal, params.messagePrefix);
224
- // Identity can remain stable while permissions change after the first receipt.
225
- if (process.platform === "win32" || (current.mode & 4095n) === requestedMode) {
226
- return { ...receipt, stat: current };
115
+ assertEdge(canonicalRoot = true) {
116
+ const targetIndex = this.receipts.length - 1;
117
+ const rootStat = canonicalRoot
118
+ ? this.assertRoot() : this.inspectReceipt(this.receipts[0], true);
119
+ if (targetIndex === 0)
120
+ return rootStat;
121
+ const parent = this.receipts[targetIndex - 1];
122
+ if (targetIndex > 1)
123
+ this.inspectReceipt(parent);
124
+ const target = this.receipts[targetIndex];
125
+ const targetStat = this.inspectReceipt(target);
126
+ if (path.dirname(target.dir) !== parent.dir) {
127
+ throw changedStoreDirectory(this.messagePrefix);
227
128
  }
228
- }
229
- // Repair owns the stronger pre/post mode-target fence below, including an
230
- // admission check on acquisition failure; no earlier admission is needed.
231
- const descriptor = openStoreDirectoryForMode({
232
- receipt,
233
- receipts: params.receipts,
234
- rootReal: params.rootReal,
235
- messagePrefix: params.messagePrefix,
236
- });
237
- let finalStat;
238
- let operationFailed = false;
239
- let operationError;
240
- try {
241
- const opened = inspectOpenedStoreDirectory(descriptor, receipt, params.messagePrefix);
242
- assertModeTargetCurrent(params.receipts, params.rootReal, params.messagePrefix);
243
- if ((opened.mode & 4095n) !== requestedMode) {
244
- fs.fchmodSync(descriptor, Number(requestedMode));
129
+ return targetStat;
130
+ }
131
+ assertModeTarget() {
132
+ const root = this.receipts[0];
133
+ const target = this.receipts.at(-1);
134
+ // The target's canonical observation shares the exact identity fence. Keep
135
+ // the trailing root canonical check: an ancestor relocation can retain IDs.
136
+ this.assertEdge(false);
137
+ let targetReal;
138
+ try {
139
+ targetReal = storeDirectoryRealPath(target.dir);
245
140
  }
246
- const finalized = inspectOpenedStoreDirectory(descriptor, receipt, params.messagePrefix);
247
- const pathname = assertModeTargetCurrent(params.receipts, params.rootReal, params.messagePrefix);
248
- if ((finalized.mode & 4095n) !== requestedMode ||
249
- (pathname.mode & 4095n) !== requestedMode) {
250
- throw new FsSafeError("insecure-permissions", `${params.messagePrefix} directory mode could not be finalized`);
141
+ catch (error) {
142
+ throw changedStoreDirectory(this.messagePrefix, error);
251
143
  }
252
- finalStat = pathname;
253
- }
254
- catch (error) {
255
- operationFailed = true;
256
- operationError = error;
144
+ if (target === root ? targetReal !== this.rootReal : !isPathInside(this.rootReal, targetReal)) {
145
+ throw changedStoreDirectory(this.messagePrefix);
146
+ }
147
+ return this.assertEdge();
148
+ }
149
+ finish(dir) {
150
+ const root = this.receipts[0];
151
+ const target = this.receipts.at(-1);
152
+ this.assertRoot();
153
+ let finalStat = root.stat;
154
+ for (const [index, receipt] of this.receipts.entries()) {
155
+ if (index === 0)
156
+ continue;
157
+ finalStat = this.inspectReceipt(receipt);
158
+ }
159
+ let finalReal;
160
+ try {
161
+ finalReal = storeDirectoryRealPath(target.dir);
162
+ }
163
+ catch (error) {
164
+ throw changedStoreDirectory(this.messagePrefix, error);
165
+ }
166
+ if (!isPathInside(this.rootReal, finalReal))
167
+ throw changedStoreDirectory(this.messagePrefix);
168
+ this.assertRoot();
169
+ if (target !== root)
170
+ finalStat = this.inspectReceipt(target);
171
+ return { dir, realPath: finalReal, exactStat: finalStat };
172
+ }
173
+ openForMode(receipt) {
174
+ let openError;
175
+ try {
176
+ return fs.openSync(pathForWindowsFilesystem(receipt.dir), directoryOpenFlags());
177
+ }
178
+ catch (error) {
179
+ openError = error;
180
+ }
181
+ const searchFlags = hasErrorCode(openError, "EACCES") ? directorySearchFlags() : undefined;
182
+ if (searchFlags !== undefined) {
183
+ try {
184
+ return fs.openSync(pathForWindowsFilesystem(receipt.dir), searchFlags);
185
+ }
186
+ catch (searchError) {
187
+ openError = createSuppressedError(searchError, openError, "ordinary and search-only directory opens both failed");
188
+ }
189
+ }
190
+ try {
191
+ this.assertModeTarget();
192
+ }
193
+ catch (boundaryError) {
194
+ throw changedStoreDirectory(this.messagePrefix, createSuppressedError(boundaryError, openError, "directory acquisition and boundary revalidation both failed"));
195
+ }
196
+ if (hasErrorCode(openError, "EACCES")) {
197
+ throw new FsSafeError("permission-unverified", `${this.messagePrefix} directory cannot be safely mode-repaired through a Node descriptor`, { cause: openError });
198
+ }
199
+ throw openError;
257
200
  }
258
- try {
259
- fs.closeSync(descriptor);
201
+ inspectOpened(descriptor, receipt) {
202
+ try {
203
+ const stat = inspectFileIdentitySync(() => fs.fstatSync(descriptor, { bigint: true }), receipt.stat);
204
+ if (!stat.isDirectory() || stat.isSymbolicLink()) {
205
+ throw changedStoreDirectory(this.messagePrefix);
206
+ }
207
+ return stat;
208
+ }
209
+ catch (error) {
210
+ if (error instanceof FsSafeError && error.code === "outside-workspace")
211
+ throw error;
212
+ throw changedStoreDirectory(this.messagePrefix, error);
213
+ }
260
214
  }
261
- catch (closeError) {
262
- if (operationFailed) {
263
- throw createSuppressedError(closeError, operationError, "store directory finalization and close both failed");
215
+ finalizeMode(mode) {
216
+ const receipt = this.receipts.at(-1);
217
+ const requestedMode = BigInt(mode & 0o7777);
218
+ if ((receipt.stat.mode & 4095n) === requestedMode || process.platform === "win32") {
219
+ const current = this.assertEdge();
220
+ // Identity can remain stable while permissions change after the first receipt.
221
+ if (process.platform === "win32" || (current.mode & 4095n) === requestedMode) {
222
+ this.receipts[this.receipts.length - 1] = { ...receipt, stat: current };
223
+ return;
224
+ }
225
+ }
226
+ // Repair owns the stronger pre/post mode-target fence below, including an
227
+ // admission check on acquisition failure; no earlier admission is needed.
228
+ const descriptor = this.openForMode(receipt);
229
+ let finalStat;
230
+ let operationFailed = false;
231
+ let operationError;
232
+ try {
233
+ const opened = this.inspectOpened(descriptor, receipt);
234
+ this.assertModeTarget();
235
+ if ((opened.mode & 4095n) !== requestedMode) {
236
+ fs.fchmodSync(descriptor, Number(requestedMode));
237
+ }
238
+ const finalized = this.inspectOpened(descriptor, receipt);
239
+ const pathname = this.assertModeTarget();
240
+ if ((finalized.mode & 4095n) !== requestedMode ||
241
+ (pathname.mode & 4095n) !== requestedMode) {
242
+ throw new FsSafeError("insecure-permissions", `${this.messagePrefix} directory mode could not be finalized`);
243
+ }
244
+ finalStat = pathname;
264
245
  }
265
- throw closeError;
246
+ catch (error) {
247
+ operationFailed = true;
248
+ operationError = error;
249
+ }
250
+ try {
251
+ fs.closeSync(descriptor);
252
+ }
253
+ catch (closeError) {
254
+ if (operationFailed) {
255
+ throw createSuppressedError(closeError, operationError, "store directory finalization and close both failed");
256
+ }
257
+ throw closeError;
258
+ }
259
+ if (operationFailed)
260
+ throw operationError;
261
+ if (!finalStat)
262
+ throw new FsSafeError("helper-failed", "store directory mode receipt is missing");
263
+ this.receipts[this.receipts.length - 1] = { ...receipt, stat: finalStat };
266
264
  }
267
- if (operationFailed)
268
- throw operationError;
269
- if (!finalStat)
270
- throw new FsSafeError("helper-failed", "store directory mode receipt is missing");
271
- return { ...receipt, stat: finalStat };
272
265
  }
273
266
  export function ensureSyncStoreDirectory(params) {
274
267
  assertNoWindowsPathAlias(params.rootDir, "filesystem", "store root uses a Windows filesystem namespace alias");
@@ -282,53 +275,23 @@ export function ensureSyncStoreDirectory(params) {
282
275
  throw new FsSafeError("outside-workspace", "file path escapes store root");
283
276
  }
284
277
  fs.mkdirSync(recursiveMkdirPath(pathForWindowsFilesystem(rootDir)), { recursive: true, mode: params.mode });
285
- const receipts = [observeStoreDirectory({
286
- dir: rootDir,
287
- messagePrefix: params.messagePrefix,
288
- root: true,
289
- })];
290
- const rootReal = storeDirectoryRealPath(rootDir);
291
- receipts[0] = finalizeDirectoryMode({
292
- receipts,
293
- rootReal,
294
- mode: params.mode,
295
- messagePrefix: params.messagePrefix,
296
- });
278
+ const chain = new StoreDirectoryChain(rootDir, params.messagePrefix);
279
+ chain.finalizeMode(params.mode);
297
280
  let current = rootDir;
298
281
  for (const segment of relative.split(path.sep).filter(Boolean)) {
299
282
  current = path.join(current, segment);
300
- let receipt;
301
283
  try {
302
- receipt = observeStoreDirectory({
303
- dir: current,
304
- messagePrefix: params.messagePrefix,
305
- root: false,
306
- });
284
+ chain.observe(current);
307
285
  }
308
286
  catch (error) {
309
287
  if (error.code !== "ENOENT")
310
288
  throw error;
311
289
  fs.mkdirSync(pathForWindowsFilesystem(current), { mode: params.mode });
312
- receipt = observeStoreDirectory({
313
- dir: current,
314
- messagePrefix: params.messagePrefix,
315
- root: false,
316
- });
290
+ chain.observe(current);
317
291
  }
318
- receipts.push(receipt);
319
- receipts[receipts.length - 1] = finalizeDirectoryMode({
320
- receipts,
321
- rootReal,
322
- mode: params.mode,
323
- messagePrefix: params.messagePrefix,
324
- });
292
+ chain.finalizeMode(params.mode);
325
293
  }
326
- const finalChain = assertReceiptChain(receipts, rootReal, params.messagePrefix);
327
- return {
328
- dir,
329
- realPath: finalChain.finalReal,
330
- exactStat: finalChain.finalStat,
331
- };
294
+ return chain.finish(dir);
332
295
  }
333
296
  export function assertSyncStoreDirectoryReceipt(receipt) {
334
297
  try {
@@ -7,4 +7,3 @@ export declare function writeFileSyncAtomic(params: {
7
7
  dirMode: number;
8
8
  mode: number;
9
9
  }): string;
10
- //# sourceMappingURL=file-store-sync-write.d.ts.map
@@ -4,21 +4,14 @@ import path from "node:path";
4
4
  import { syncDirectorySync } from "./directory-durability.js";
5
5
  import { createDirectoryReceiptFromIdentity } from "./directory-receipt.js";
6
6
  import { FsSafeError } from "./errors.js";
7
- import { assertSyncDirectoryGuard, ensureParentSync, ensureStoreDirectorySync, } from "./file-store-boundary.js";
7
+ import { ensureParentSync, ensureStoreDirectorySync, } from "./file-store-boundary.js";
8
+ import { assertSyncStoreDirectoryReceipt } from "./file-store-sync-directory.js";
8
9
  import { isPathInside } from "./path.js";
9
10
  import { resolveReadOpenFlags } from "./read-open-flags.js";
10
11
  import { writeTempFileSync } from "./replace-file-descriptor.js";
11
12
  import { SyncAtomicTempOwner } from "./replace-file-temp-owner.js";
12
13
  import { inspectFileIdentitySync } from "./strict-file-identity.js";
13
14
  import { getFsSafeTestHooks } from "./test-hooks.js";
14
- function ensurePrivateDirectorySync(rootDir, targetDir, mode) {
15
- return ensureStoreDirectorySync({
16
- rootDir,
17
- targetDir,
18
- mode,
19
- messagePrefix: "private store",
20
- });
21
- }
22
15
  function verifyStoreFile(fd, expected, filePath) {
23
16
  const assertFile = (stat, allowUnknown = false) => {
24
17
  const unknown = allowUnknown && process.platform === "win32" && (stat.dev === 0n || stat.ino === 0n);
@@ -55,7 +48,12 @@ export function writeFileSyncAtomic(params) {
55
48
  }
56
49
  let parentGuard;
57
50
  if (params.privateMode) {
58
- parentGuard = ensurePrivateDirectorySync(params.rootDir, path.dirname(filePath), params.dirMode);
51
+ parentGuard = ensureStoreDirectorySync({
52
+ rootDir: params.rootDir,
53
+ targetDir: path.dirname(filePath),
54
+ mode: params.dirMode,
55
+ messagePrefix: "private store",
56
+ });
59
57
  try {
60
58
  const stat = fs.lstatSync(filePath);
61
59
  if (stat.isSymbolicLink() || !stat.isFile()) {
@@ -75,14 +73,12 @@ export function writeFileSyncAtomic(params) {
75
73
  mode: params.dirMode,
76
74
  });
77
75
  }
78
- const tempPath = path.join(parentGuard?.dir ?? path.dirname(filePath), `.fs-safe-${process.pid}-${randomUUID()}.tmp`);
76
+ const tempPath = path.join(parentGuard.dir, `.fs-safe-${process.pid}-${randomUUID()}.tmp`);
79
77
  const owner = new SyncAtomicTempOwner(tempPath);
80
78
  let originalFailure;
81
79
  try {
82
80
  getFsSafeTestHooks()?.beforeFileStoreSyncPrivateWrite?.(filePath);
83
- if (parentGuard) {
84
- assertSyncDirectoryGuard(parentGuard);
85
- }
81
+ assertSyncStoreDirectoryReceipt(parentGuard);
86
82
  owner.start();
87
83
  const temp = writeTempFileSync({
88
84
  fsModule: fs, tempPath, content: params.content, mode: params.mode, sync: false,
@@ -101,14 +97,10 @@ export function writeFileSyncAtomic(params) {
101
97
  if (params.durable)
102
98
  fs.fsyncSync(temp.fd);
103
99
  verifyStoreFile(temp.fd, owner.identity, tempPath);
104
- if (parentGuard) {
105
- assertSyncDirectoryGuard(parentGuard);
106
- }
100
+ assertSyncStoreDirectoryReceipt(parentGuard);
107
101
  fs.renameSync(tempPath, filePath);
108
102
  owner.markRenamed();
109
- if (parentGuard) {
110
- assertSyncDirectoryGuard(parentGuard);
111
- }
103
+ assertSyncStoreDirectoryReceipt(parentGuard);
112
104
  try {
113
105
  verifyStoreFile(temp.fd, owner.identity, filePath);
114
106
  }
@@ -120,13 +112,11 @@ export function writeFileSyncAtomic(params) {
120
112
  cause: error instanceof Error ? error : undefined,
121
113
  });
122
114
  }
123
- if (parentGuard) {
124
- assertSyncDirectoryGuard(parentGuard);
125
- if (params.durable) {
126
- syncDirectorySync(createDirectoryReceiptFromIdentity(parentGuard.dir, parentGuard.realPath, parentGuard.exactStat), { label: "store parent" });
127
- }
128
- assertSyncDirectoryGuard(parentGuard);
115
+ assertSyncStoreDirectoryReceipt(parentGuard);
116
+ if (params.durable) {
117
+ syncDirectorySync(createDirectoryReceiptFromIdentity(parentGuard.dir, parentGuard.realPath, parentGuard.exactStat), { label: "store parent" });
129
118
  }
119
+ assertSyncStoreDirectoryReceipt(parentGuard);
130
120
  return filePath;
131
121
  }
132
122
  catch (error) {
@@ -63,4 +63,3 @@ export type FileStoreSync = {
63
63
  };
64
64
  export declare function fileStore(options: FileStoreOptions): FileStore;
65
65
  export declare function fileStoreSync(options: FileStoreOptions): FileStoreSync;
66
- //# sourceMappingURL=file-store.d.ts.map
@@ -74,18 +74,17 @@ async function copyIntoRoot(params) {
74
74
  throw new FsSafeError("not-file", "source path is not a file");
75
75
  }
76
76
  assertFileStoreMaxBytes(sourceStat.size, params.maxBytes);
77
- const dirMode = params.dirMode ?? 0o700;
78
77
  const scopedRoot = await openWritableStoreRoot({
79
78
  rootDir: params.rootDir,
80
- dirMode,
79
+ dirMode: params.dirMode,
81
80
  maxBytes: params.maxBytes,
82
81
  });
83
- await ensureParentInRoot(scopedRoot, relativePath, dirMode);
82
+ await ensureParentInRoot(scopedRoot, relativePath, params.dirMode);
84
83
  await scopedRoot.copyIn(relativePath, params.sourcePath, {
85
84
  durable: params.durable,
86
85
  maxBytes: params.maxBytes,
87
86
  mkdir: false,
88
- mode: params.mode ?? 0o600,
87
+ mode: params.mode,
89
88
  });
90
89
  return destination;
91
90
  }
@@ -2,4 +2,3 @@ import fs from "node:fs";
2
2
  import type { FileHandle } from "node:fs/promises";
3
3
  export declare function syncFileBestEffort(handle: Pick<FileHandle, "sync">): Promise<void>;
4
4
  export declare function syncFileBestEffortSync(fd: number, fsModule?: Pick<typeof fs, "fsyncSync">): void;
5
- //# sourceMappingURL=file-sync.d.ts.map
@@ -6,4 +6,3 @@ export declare function fitFileNameToPortableComponent(params: {
6
6
  suffix: string;
7
7
  }): string;
8
8
  export declare function sanitizeUntrustedFileName(fileName: string, fallbackName: string): string;
9
- //# sourceMappingURL=filename.d.ts.map
package/dist/filename.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { WINDOWS_RESERVED_DEVICE_NAMES } from "./device-path.js";
3
3
  import { maxNormalizedUtf8Bytes } from "./unicode-path.js";
4
+ import { hasWindowsDrivePrefix } from "./windows-path-syntax.js";
4
5
  const INVALID_FILE_NAME_CHARACTERS = /[\u0000-\u001f\u007f-\u009f<>:"/\\|?*]/g;
5
6
  const HAS_INVALID_FILE_NAME_CHARACTER = /[\u0000-\u001f\u007f-\u009f<>:"/\\|?*]/;
6
7
  const HAS_RETAINED_FILE_NAME_CHARACTER = /[^\u0000-\u001f\u007f-\u009f<>:"/\\|?*\s]/;
@@ -53,13 +54,6 @@ function isBoundedSanitizedFileName(fileName, trimmedFileName) {
53
54
  !HAS_INVALID_FILE_NAME_CHARACTER.test(fileName) &&
54
55
  suffixWindowsReservedDeviceName(fileName) === fileName;
55
56
  }
56
- function hasWindowsDrivePrefix(value) {
57
- if (value.length < 2 || value.charCodeAt(1) !== 0x3a)
58
- return false;
59
- const firstCodeUnit = value.charCodeAt(0);
60
- return (firstCodeUnit >= 0x41 && firstCodeUnit <= 0x5a) ||
61
- (firstCodeUnit >= 0x61 && firstCodeUnit <= 0x7a);
62
- }
63
57
  function normalizedFileNameBytes(value) {
64
58
  return maxNormalizedUtf8Bytes(value, true);
65
59
  }
package/dist/fs.d.ts CHANGED
@@ -10,4 +10,3 @@ export declare function pathExists(filePath: string): Promise<boolean>;
10
10
  * semantics.
11
11
  */
12
12
  export declare function pathExistsSync(filePath: string): boolean;
13
- //# sourceMappingURL=fs.d.ts.map
@@ -23,4 +23,3 @@ export declare function mkdirPathComponentsWithGuards(params: {
23
23
  retainedTargetPath?: string;
24
24
  rootIdentity?: RootBoundaryIdentity;
25
25
  }): Promise<string>;
26
- //# sourceMappingURL=guarded-mkdir.d.ts.map
@@ -13,21 +13,15 @@ export declare function guardedRename(params: {
13
13
  onRenamed?: () => void;
14
14
  from: string;
15
15
  to: string;
16
- targetRoot?: string;
17
- verifyAfter?: boolean;
18
16
  }): Promise<void>;
19
17
  export declare function guardedRenameSync(params: {
20
18
  from: string;
21
19
  to: string;
22
- targetRoot?: string;
23
- verifyAfter?: boolean;
24
20
  }): void;
25
21
  export declare function guardedRm(params: {
26
22
  target: string;
27
23
  assertBeforeMutation?: () => void;
28
24
  recursive?: boolean;
29
- force?: boolean;
30
- verifyAfter?: boolean;
31
25
  }): Promise<void>;
32
26
  export declare function guardedRmSync(params: {
33
27
  target: string;
@@ -36,4 +30,3 @@ export declare function guardedRmSync(params: {
36
30
  force?: boolean;
37
31
  verifyAfter?: boolean;
38
32
  }): void;
39
- //# sourceMappingURL=guarded-mutation.d.ts.map