@openclaw/fs-safe 0.12.0 → 0.13.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 (383) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +12 -7
  3. package/dist/absolute-path.d.ts.map +1 -1
  4. package/dist/absolute-path.js +32 -11
  5. package/dist/advanced.d.ts +2 -0
  6. package/dist/advanced.d.ts.map +1 -1
  7. package/dist/advanced.js +2 -0
  8. package/dist/archive-input.d.ts.map +1 -1
  9. package/dist/archive-input.js +6 -2
  10. package/dist/archive-merge.d.ts.map +1 -1
  11. package/dist/archive-merge.js +15 -2
  12. package/dist/archive-native.d.ts.map +1 -1
  13. package/dist/archive-native.js +7 -19
  14. package/dist/archive-plan.js +1 -1
  15. package/dist/archive-read.d.ts.map +1 -1
  16. package/dist/archive-read.js +18 -13
  17. package/dist/archive-staging.d.ts.map +1 -1
  18. package/dist/archive-staging.js +43 -10
  19. package/dist/archive-tar-inspect.d.ts.map +1 -1
  20. package/dist/archive-tar-inspect.js +4 -1
  21. package/dist/archive-zip-admission.d.ts +1 -1
  22. package/dist/archive-zip-admission.d.ts.map +1 -1
  23. package/dist/archive-zip-admission.js +2 -2
  24. package/dist/archive-zip-directory.d.ts +3 -0
  25. package/dist/archive-zip-directory.d.ts.map +1 -1
  26. package/dist/archive-zip-directory.js +13 -2
  27. package/dist/archive-zip-loader.d.ts +3 -2
  28. package/dist/archive-zip-loader.d.ts.map +1 -1
  29. package/dist/archive-zip-loader.js +30 -4
  30. package/dist/archive-zip-manifest.d.ts +5 -0
  31. package/dist/archive-zip-manifest.d.ts.map +1 -0
  32. package/dist/archive-zip-manifest.js +22 -0
  33. package/dist/archive-zip-names.d.ts +6 -1
  34. package/dist/archive-zip-names.d.ts.map +1 -1
  35. package/dist/archive-zip-names.js +35 -14
  36. package/dist/archive-zip-preflight.d.ts.map +1 -1
  37. package/dist/archive-zip-preflight.js +3 -2
  38. package/dist/archive.d.ts.map +1 -1
  39. package/dist/archive.js +9 -4
  40. package/dist/darwin-acl.d.ts +4 -0
  41. package/dist/darwin-acl.d.ts.map +1 -0
  42. package/dist/darwin-acl.js +24 -0
  43. package/dist/deny-mutations.d.ts.map +1 -1
  44. package/dist/deny-mutations.js +8 -2
  45. package/dist/directory-durability.d.ts.map +1 -1
  46. package/dist/directory-durability.js +67 -23
  47. package/dist/directory-entry-path.d.ts +3 -0
  48. package/dist/directory-entry-path.d.ts.map +1 -0
  49. package/dist/directory-entry-path.js +21 -0
  50. package/dist/directory-guard.d.ts +17 -1
  51. package/dist/directory-guard.d.ts.map +1 -1
  52. package/dist/directory-guard.js +134 -48
  53. package/dist/directory-mode-node.d.ts +12 -0
  54. package/dist/directory-mode-node.d.ts.map +1 -1
  55. package/dist/directory-mode-node.js +102 -4
  56. package/dist/effective-uid.d.ts +2 -0
  57. package/dist/effective-uid.d.ts.map +1 -0
  58. package/dist/effective-uid.js +25 -0
  59. package/dist/file-handle-transfer.d.ts.map +1 -1
  60. package/dist/file-handle-transfer.js +98 -27
  61. package/dist/file-hash.d.ts.map +1 -1
  62. package/dist/file-hash.js +3 -0
  63. package/dist/file-lock-sync.d.ts.map +1 -1
  64. package/dist/file-lock-sync.js +36 -6
  65. package/dist/file-lock.d.ts.map +1 -1
  66. package/dist/file-lock.js +29 -9
  67. package/dist/file-observation.d.ts +1 -1
  68. package/dist/file-observation.d.ts.map +1 -1
  69. package/dist/file-store-boundary.d.ts +6 -2
  70. package/dist/file-store-boundary.d.ts.map +1 -1
  71. package/dist/file-store-boundary.js +20 -65
  72. package/dist/file-store-copy-source.d.ts +5 -0
  73. package/dist/file-store-copy-source.d.ts.map +1 -0
  74. package/dist/file-store-copy-source.js +31 -0
  75. package/dist/file-store-path.d.ts.map +1 -1
  76. package/dist/file-store-path.js +4 -1
  77. package/dist/file-store-sync-directory.d.ts +16 -0
  78. package/dist/file-store-sync-directory.d.ts.map +1 -0
  79. package/dist/file-store-sync-directory.js +349 -0
  80. package/dist/file-store.d.ts.map +1 -1
  81. package/dist/file-store.js +11 -28
  82. package/dist/filename.d.ts.map +1 -1
  83. package/dist/filename.js +65 -20
  84. package/dist/fs.d.ts.map +1 -1
  85. package/dist/fs.js +3 -2
  86. package/dist/guarded-mkdir.d.ts +8 -0
  87. package/dist/guarded-mkdir.d.ts.map +1 -1
  88. package/dist/guarded-mkdir.js +176 -27
  89. package/dist/guest.d.ts.map +1 -1
  90. package/dist/guest.js +4 -1
  91. package/dist/home-dir.d.ts.map +1 -1
  92. package/dist/home-dir.js +73 -10
  93. package/dist/install-path.d.ts.map +1 -1
  94. package/dist/install-path.js +54 -19
  95. package/dist/json-durable-queue-ownership.d.ts +6 -0
  96. package/dist/json-durable-queue-ownership.d.ts.map +1 -1
  97. package/dist/json-durable-queue-ownership.js +89 -42
  98. package/dist/json-durable-queue-paths.d.ts +11 -0
  99. package/dist/json-durable-queue-paths.d.ts.map +1 -0
  100. package/dist/json-durable-queue-paths.js +42 -0
  101. package/dist/json-durable-queue-read.d.ts.map +1 -1
  102. package/dist/json-durable-queue-read.js +2 -0
  103. package/dist/json-durable-queue.d.ts.map +1 -1
  104. package/dist/json-durable-queue.js +50 -58
  105. package/dist/json-store.d.ts.map +1 -1
  106. package/dist/json-store.js +5 -1
  107. package/dist/json.d.ts.map +1 -1
  108. package/dist/json.js +54 -22
  109. package/dist/local-file-access.d.ts.map +1 -1
  110. package/dist/local-file-access.js +4 -0
  111. package/dist/local-file-descriptor.d.ts +17 -0
  112. package/dist/local-file-descriptor.d.ts.map +1 -0
  113. package/dist/local-file-descriptor.js +84 -0
  114. package/dist/local-roots.d.ts.map +1 -1
  115. package/dist/local-roots.js +35 -7
  116. package/dist/move-path-cleanup.d.ts +2 -0
  117. package/dist/move-path-cleanup.d.ts.map +1 -1
  118. package/dist/move-path-cleanup.js +44 -18
  119. package/dist/move-path.d.ts.map +1 -1
  120. package/dist/move-path.js +31 -6
  121. package/dist/native-binding.d.ts +14 -0
  122. package/dist/native-binding.d.ts.map +1 -1
  123. package/dist/native-directory-observation.d.ts +17 -0
  124. package/dist/native-directory-observation.d.ts.map +1 -0
  125. package/dist/native-directory-observation.js +37 -0
  126. package/dist/native-parent-admission.d.ts +31 -0
  127. package/dist/native-parent-admission.d.ts.map +1 -0
  128. package/dist/native-parent-admission.js +124 -0
  129. package/dist/native-pinned-write-windows.d.ts +0 -1
  130. package/dist/native-pinned-write-windows.d.ts.map +1 -1
  131. package/dist/native-pinned-write-windows.js +0 -3
  132. package/dist/native-pinned-write.d.ts.map +1 -1
  133. package/dist/native-pinned-write.js +309 -40
  134. package/dist/output.d.ts.map +1 -1
  135. package/dist/output.js +15 -5
  136. package/dist/overwrite-file-handle.d.ts.map +1 -1
  137. package/dist/overwrite-file-handle.js +5 -1
  138. package/dist/owner-dacl.d.ts.map +1 -1
  139. package/dist/owner-dacl.js +2 -0
  140. package/dist/path-policy.d.ts.map +1 -1
  141. package/dist/path-policy.js +7 -2
  142. package/dist/path-prefix.d.ts +7 -0
  143. package/dist/path-prefix.d.ts.map +1 -0
  144. package/dist/path-prefix.js +82 -0
  145. package/dist/path-scope-lexical.d.ts.map +1 -1
  146. package/dist/path-scope-lexical.js +18 -8
  147. package/dist/path-segment-route.d.ts +7 -0
  148. package/dist/path-segment-route.d.ts.map +1 -0
  149. package/dist/path-segment-route.js +24 -0
  150. package/dist/path-suffix-aliases.d.ts +10 -0
  151. package/dist/path-suffix-aliases.d.ts.map +1 -0
  152. package/dist/path-suffix-aliases.js +386 -0
  153. package/dist/path.d.ts.map +1 -1
  154. package/dist/path.js +16 -5
  155. package/dist/permissions-windows.d.ts.map +1 -1
  156. package/dist/permissions-windows.js +14 -3
  157. package/dist/permissions.d.ts.map +1 -1
  158. package/dist/permissions.js +37 -8
  159. package/dist/pinned-mutation-admission.d.ts +25 -0
  160. package/dist/pinned-mutation-admission.d.ts.map +1 -0
  161. package/dist/pinned-mutation-admission.js +425 -0
  162. package/dist/pinned-mutation-observation.d.ts +34 -0
  163. package/dist/pinned-mutation-observation.d.ts.map +1 -0
  164. package/dist/pinned-mutation-observation.js +142 -0
  165. package/dist/pinned-mutation-shared-route.d.ts +24 -0
  166. package/dist/pinned-mutation-shared-route.d.ts.map +1 -0
  167. package/dist/pinned-mutation-shared-route.js +70 -0
  168. package/dist/pinned-open.d.ts +6 -0
  169. package/dist/pinned-open.d.ts.map +1 -1
  170. package/dist/pinned-open.js +28 -10
  171. package/dist/pinned-write-types.d.ts +75 -0
  172. package/dist/pinned-write-types.d.ts.map +1 -0
  173. package/dist/pinned-write-types.js +1 -0
  174. package/dist/pinned-write.d.ts +7 -33
  175. package/dist/pinned-write.d.ts.map +1 -1
  176. package/dist/pinned-write.js +151 -17
  177. package/dist/private-directory.d.ts.map +1 -1
  178. package/dist/private-directory.js +2 -0
  179. package/dist/private-producer-handoff.d.ts +16 -0
  180. package/dist/private-producer-handoff.d.ts.map +1 -0
  181. package/dist/private-producer-handoff.js +272 -0
  182. package/dist/private-temp-workspace.d.ts +2 -39
  183. package/dist/private-temp-workspace.d.ts.map +1 -1
  184. package/dist/private-temp-workspace.js +183 -77
  185. package/dist/publish-file.d.ts.map +1 -1
  186. package/dist/publish-file.js +33 -29
  187. package/dist/regular-file.d.ts.map +1 -1
  188. package/dist/regular-file.js +56 -45
  189. package/dist/replace-directory.d.ts.map +1 -1
  190. package/dist/replace-directory.js +12 -5
  191. package/dist/replace-file-temp-owner.d.ts +1 -0
  192. package/dist/replace-file-temp-owner.d.ts.map +1 -1
  193. package/dist/replace-file-temp-owner.js +12 -1
  194. package/dist/replace-file.d.ts.map +1 -1
  195. package/dist/replace-file.js +24 -24
  196. package/dist/root-boundary.d.ts +4 -0
  197. package/dist/root-boundary.d.ts.map +1 -1
  198. package/dist/root-boundary.js +6 -1
  199. package/dist/root-context.d.ts +12 -1
  200. package/dist/root-context.d.ts.map +1 -1
  201. package/dist/root-context.js +57 -11
  202. package/dist/root-directory-creation.d.ts +13 -0
  203. package/dist/root-directory-creation.d.ts.map +1 -0
  204. package/dist/root-directory-creation.js +212 -0
  205. package/dist/root-directory-list.d.ts +16 -4
  206. package/dist/root-directory-list.d.ts.map +1 -1
  207. package/dist/root-directory-list.js +180 -39
  208. package/dist/root-directory.d.ts +23 -0
  209. package/dist/root-directory.d.ts.map +1 -0
  210. package/dist/root-directory.js +141 -0
  211. package/dist/root-errors.d.ts.map +1 -1
  212. package/dist/root-errors.js +12 -1
  213. package/dist/root-file-final-admission.d.ts +21 -0
  214. package/dist/root-file-final-admission.d.ts.map +1 -0
  215. package/dist/root-file-final-admission.js +83 -0
  216. package/dist/root-file.d.ts.map +1 -1
  217. package/dist/root-file.js +103 -24
  218. package/dist/root-impl.d.ts +1 -0
  219. package/dist/root-impl.d.ts.map +1 -1
  220. package/dist/root-impl.js +289 -317
  221. package/dist/root-move-noreplace.d.ts +14 -0
  222. package/dist/root-move-noreplace.d.ts.map +1 -0
  223. package/dist/root-move-noreplace.js +202 -0
  224. package/dist/root-observed-path.d.ts +9 -0
  225. package/dist/root-observed-path.d.ts.map +1 -0
  226. package/dist/root-observed-path.js +95 -0
  227. package/dist/root-path-errors.d.ts +12 -0
  228. package/dist/root-path-errors.d.ts.map +1 -0
  229. package/dist/root-path-errors.js +13 -0
  230. package/dist/root-path-existing.d.ts.map +1 -1
  231. package/dist/root-path-existing.js +53 -20
  232. package/dist/root-path-observation.d.ts +63 -0
  233. package/dist/root-path-observation.d.ts.map +1 -0
  234. package/dist/root-path-observation.js +180 -0
  235. package/dist/root-path-stat.d.ts +5 -0
  236. package/dist/root-path-stat.d.ts.map +1 -0
  237. package/dist/root-path-stat.js +101 -0
  238. package/dist/root-path-symlink.d.ts.map +1 -1
  239. package/dist/root-path-symlink.js +23 -4
  240. package/dist/root-path.d.ts +11 -0
  241. package/dist/root-path.d.ts.map +1 -1
  242. package/dist/root-path.js +215 -53
  243. package/dist/root-paths-lexical.d.ts +9 -0
  244. package/dist/root-paths-lexical.d.ts.map +1 -0
  245. package/dist/root-paths-lexical.js +22 -0
  246. package/dist/root-paths.d.ts +3 -25
  247. package/dist/root-paths.d.ts.map +1 -1
  248. package/dist/root-paths.js +77 -154
  249. package/dist/root-read-admission.d.ts +26 -0
  250. package/dist/root-read-admission.d.ts.map +1 -0
  251. package/dist/root-read-admission.js +94 -0
  252. package/dist/root-remove-identity.d.ts +15 -0
  253. package/dist/root-remove-identity.d.ts.map +1 -0
  254. package/dist/root-remove-identity.js +89 -0
  255. package/dist/root-remove-receipt.d.ts +17 -0
  256. package/dist/root-remove-receipt.d.ts.map +1 -0
  257. package/dist/root-remove-receipt.js +37 -0
  258. package/dist/root-remove.d.ts +2 -1
  259. package/dist/root-remove.d.ts.map +1 -1
  260. package/dist/root-remove.js +172 -10
  261. package/dist/root-write-admission.d.ts +68 -0
  262. package/dist/root-write-admission.d.ts.map +1 -0
  263. package/dist/root-write-admission.js +322 -0
  264. package/dist/root-write-compatibility.d.ts +13 -0
  265. package/dist/root-write-compatibility.d.ts.map +1 -0
  266. package/dist/root-write-compatibility.js +74 -0
  267. package/dist/root-write-complete-parent.d.ts +42 -0
  268. package/dist/root-write-complete-parent.d.ts.map +1 -0
  269. package/dist/root-write-complete-parent.js +195 -0
  270. package/dist/root-write-publication.d.ts +24 -0
  271. package/dist/root-write-publication.d.ts.map +1 -0
  272. package/dist/root-write-publication.js +85 -0
  273. package/dist/root-write-verification.d.ts.map +1 -1
  274. package/dist/root-write-verification.js +6 -4
  275. package/dist/secret-file.d.ts.map +1 -1
  276. package/dist/secret-file.js +62 -24
  277. package/dist/secret-read-async.d.ts.map +1 -1
  278. package/dist/secret-read-async.js +18 -13
  279. package/dist/secret-read-policy.d.ts.map +1 -1
  280. package/dist/secret-read-policy.js +5 -1
  281. package/dist/secure-file.d.ts.map +1 -1
  282. package/dist/secure-file.js +92 -7
  283. package/dist/secure-temp-dir.d.ts +6 -3
  284. package/dist/secure-temp-dir.d.ts.map +1 -1
  285. package/dist/secure-temp-dir.js +121 -101
  286. package/dist/secure-temp-repair.d.ts +35 -0
  287. package/dist/secure-temp-repair.d.ts.map +1 -0
  288. package/dist/secure-temp-repair.js +106 -0
  289. package/dist/sibling-staged-file.d.ts +3 -2
  290. package/dist/sibling-staged-file.d.ts.map +1 -1
  291. package/dist/sibling-staged-file.js +179 -55
  292. package/dist/sibling-temp.d.ts.map +1 -1
  293. package/dist/sibling-temp.js +27 -13
  294. package/dist/sidecar-lock-acquire.d.ts.map +1 -1
  295. package/dist/sidecar-lock-acquire.js +44 -14
  296. package/dist/sidecar-lock-root.d.ts.map +1 -1
  297. package/dist/sidecar-lock-root.js +4 -2
  298. package/dist/staged-directory.d.ts +14 -5
  299. package/dist/staged-directory.d.ts.map +1 -1
  300. package/dist/staged-directory.js +54 -3
  301. package/dist/standalone-publication-path.d.ts +2 -0
  302. package/dist/standalone-publication-path.d.ts.map +1 -0
  303. package/dist/standalone-publication-path.js +6 -0
  304. package/dist/stat-observation.d.ts +11 -0
  305. package/dist/stat-observation.d.ts.map +1 -0
  306. package/dist/stat-observation.js +64 -0
  307. package/dist/strict-file-identity.d.ts.map +1 -1
  308. package/dist/strict-file-identity.js +39 -2
  309. package/dist/symlink-parents.d.ts.map +1 -1
  310. package/dist/symlink-parents.js +7 -2
  311. package/dist/temp-target.d.ts +2 -0
  312. package/dist/temp-target.d.ts.map +1 -1
  313. package/dist/temp-target.js +130 -3
  314. package/dist/temp-workspace-admission.d.ts +22 -0
  315. package/dist/temp-workspace-admission.d.ts.map +1 -0
  316. package/dist/temp-workspace-admission.js +374 -0
  317. package/dist/temp-workspace-child-admission.d.ts +13 -0
  318. package/dist/temp-workspace-child-admission.d.ts.map +1 -0
  319. package/dist/temp-workspace-child-admission.js +95 -0
  320. package/dist/temp-workspace-descriptor.d.ts +48 -0
  321. package/dist/temp-workspace-descriptor.d.ts.map +1 -0
  322. package/dist/temp-workspace-descriptor.js +363 -0
  323. package/dist/temp-workspace-identity.d.ts +15 -0
  324. package/dist/temp-workspace-identity.d.ts.map +1 -0
  325. package/dist/temp-workspace-identity.js +41 -0
  326. package/dist/temp-workspace-owner.d.ts +7 -6
  327. package/dist/temp-workspace-owner.d.ts.map +1 -1
  328. package/dist/temp-workspace-owner.js +121 -61
  329. package/dist/temp-workspace-permissions.d.ts +4 -0
  330. package/dist/temp-workspace-permissions.d.ts.map +1 -0
  331. package/dist/temp-workspace-permissions.js +32 -0
  332. package/dist/temp-workspace-types.d.ts +40 -0
  333. package/dist/temp-workspace-types.d.ts.map +1 -0
  334. package/dist/temp-workspace-types.js +1 -0
  335. package/dist/temp.d.ts +1 -1
  336. package/dist/temp.d.ts.map +1 -1
  337. package/dist/temp.js +1 -1
  338. package/dist/test-hooks.d.ts +7 -0
  339. package/dist/test-hooks.d.ts.map +1 -1
  340. package/dist/text-atomic.d.ts.map +1 -1
  341. package/dist/text-atomic.js +3 -1
  342. package/dist/trash.d.ts.map +1 -1
  343. package/dist/trash.js +54 -8
  344. package/dist/walk.d.ts.map +1 -1
  345. package/dist/walk.js +9 -6
  346. package/dist/windows-owner.d.ts.map +1 -1
  347. package/dist/windows-owner.js +5 -0
  348. package/dist/windows-path-alias.d.ts +39 -0
  349. package/dist/windows-path-alias.d.ts.map +1 -0
  350. package/dist/windows-path-alias.js +153 -0
  351. package/docs/advanced.md +25 -0
  352. package/docs/archive.md +23 -2
  353. package/docs/atomic.md +27 -3
  354. package/docs/copy.md +3 -0
  355. package/docs/durability.md +14 -0
  356. package/docs/errors.md +14 -6
  357. package/docs/file-store.md +24 -3
  358. package/docs/filename.md +14 -7
  359. package/docs/install-path.md +2 -2
  360. package/docs/install.md +8 -7
  361. package/docs/json-store.md +5 -1
  362. package/docs/json.md +11 -0
  363. package/docs/mutation-policy-proof.md +65 -0
  364. package/docs/native-helper.md +26 -9
  365. package/docs/native.md +32 -8
  366. package/docs/output.md +33 -11
  367. package/docs/path-prefix.md +64 -0
  368. package/docs/path-suffix-aliases.md +159 -0
  369. package/docs/path.md +11 -0
  370. package/docs/private-file-store.md +14 -0
  371. package/docs/public-api.md +9 -0
  372. package/docs/quickstart.md +1 -1
  373. package/docs/reading.md +8 -1
  374. package/docs/root.md +18 -3
  375. package/docs/secret-file.md +3 -0
  376. package/docs/secure-file.md +6 -2
  377. package/docs/security-model.md +75 -8
  378. package/docs/sidecar-lock.md +28 -1
  379. package/docs/store.md +5 -1
  380. package/docs/temp.md +260 -36
  381. package/docs/test-hooks.md +14 -0
  382. package/docs/writing.md +38 -8
  383. package/package.json +10 -10
@@ -1,10 +1,10 @@
1
1
  import fsSync, { constants } from "node:fs";
2
2
  import fs from "node:fs/promises";
3
3
  import { FsSafeError } from "./errors.js";
4
- import { inspectDirectoryIdentity } from "./directory-guard.js";
5
- import { inspectFileIdentity } from "./strict-file-identity.js";
4
+ import { inspectDirectoryIdentity, inspectDirectoryIdentitySync } from "./directory-guard.js";
5
+ import { inspectFileIdentity, inspectFileIdentitySync } from "./strict-file-identity.js";
6
6
  import { assertOwnedDirectory, ownDirectoryMode } from "./directory-mode-owner.js";
7
- function searchOnlyFlags() {
7
+ export function nodeDirectorySearchOnlyFlags() {
8
8
  if (process.arch !== "x64" && process.arch !== "arm64")
9
9
  return undefined;
10
10
  // Darwin SDK O_SEARCH = O_EXEC (0x40000000) | O_DIRECTORY, on x64/arm64.
@@ -41,7 +41,7 @@ export async function pinNodeDirectoryForMode(dirPath, options = {}) {
41
41
  const handle = await fs.open(dirPath, constants.O_RDONLY | flags).catch(async (error) => {
42
42
  if (error.code !== "EACCES")
43
43
  throw error;
44
- const route = searchOnlyFlags();
44
+ const route = nodeDirectorySearchOnlyFlags();
45
45
  if (!route)
46
46
  throw error;
47
47
  proc = route.proc;
@@ -91,3 +91,101 @@ export async function pinNodeDirectoryForMode(dirPath, options = {}) {
91
91
  throw error;
92
92
  }
93
93
  }
94
+ /** Synchronous counterpart with the same no-follow, identity, and owner checks. */
95
+ export function pinNodeDirectoryForModeSync(dirPath, options = {}) {
96
+ const expected = inspectDirectoryIdentitySync(dirPath, options.expectedIdentity);
97
+ const assertOwner = (stat) => {
98
+ if (options.ownerUid !== undefined && stat.uid !== BigInt(options.ownerUid)) {
99
+ throw new FsSafeError("not-owned", "directory mode target must retain its expected owner");
100
+ }
101
+ };
102
+ assertOwner(expected);
103
+ if (process.platform === "win32") {
104
+ return {
105
+ apply: (_mode, check) => {
106
+ check?.();
107
+ assertOwner(inspectDirectoryIdentitySync(dirPath, expected));
108
+ check?.();
109
+ },
110
+ close: () => undefined,
111
+ };
112
+ }
113
+ if ([constants.O_DIRECTORY, constants.O_NOFOLLOW, constants.O_NONBLOCK, constants.O_RDONLY]
114
+ .some((flag) => typeof flag !== "number")) {
115
+ throw new FsSafeError("helper-unavailable", "no-follow directory mode descriptors are unavailable");
116
+ }
117
+ const flags = constants.O_DIRECTORY | constants.O_NOFOLLOW | constants.O_NONBLOCK;
118
+ let fd;
119
+ let proc = false;
120
+ try {
121
+ fd = fsSync.openSync(dirPath, constants.O_RDONLY | flags);
122
+ }
123
+ catch (error) {
124
+ if (error.code !== "EACCES")
125
+ throw error;
126
+ const route = nodeDirectorySearchOnlyFlags();
127
+ if (!route)
128
+ throw error;
129
+ proc = route.proc;
130
+ fd = fsSync.openSync(dirPath, route.flags | flags);
131
+ }
132
+ let closed = false;
133
+ const inspect = () => {
134
+ if (closed)
135
+ throw new FsSafeError("path-mismatch", "directory mode descriptor is closed");
136
+ const stat = inspectFileIdentitySync(() => fsSync.fstatSync(fd, { bigint: true }), expected);
137
+ assertOwnedDirectory(expected, stat);
138
+ assertOwner(stat);
139
+ inspectDirectoryIdentitySync(dirPath, expected);
140
+ return Number(stat.mode & 4095n);
141
+ };
142
+ const procPath = `/proc/self/fd/${fd}`;
143
+ const assertProcAuthority = () => {
144
+ if (fsSync.statfsSync("/proc/self/fd", { bigint: true }).type !== 0x9fa0n) {
145
+ throw new FsSafeError("path-mismatch", "directory mode requires a trusted procfs fd namespace");
146
+ }
147
+ const opened = inspectFileIdentitySync(() => fsSync.fstatSync(fd, { bigint: true }), expected);
148
+ const followed = inspectFileIdentitySync(() => fsSync.statSync(procPath, { bigint: true }), expected);
149
+ assertOwnedDirectory(opened, followed);
150
+ assertOwner(opened);
151
+ assertOwner(followed);
152
+ };
153
+ try {
154
+ inspect();
155
+ return {
156
+ apply: (mode, check) => {
157
+ mode &= 0o7777;
158
+ check?.();
159
+ const currentMode = inspect();
160
+ check?.();
161
+ if (currentMode !== mode) {
162
+ if (proc)
163
+ assertProcAuthority();
164
+ check?.();
165
+ inspect();
166
+ if (proc)
167
+ fsSync.chmodSync(procPath, mode);
168
+ else
169
+ fsSync.fchmodSync(fd, mode);
170
+ if (proc)
171
+ assertProcAuthority();
172
+ }
173
+ const finalMode = inspect();
174
+ check?.();
175
+ if (finalMode !== mode) {
176
+ throw new FsSafeError("path-mismatch", "directory final mode could not be verified");
177
+ }
178
+ },
179
+ close: () => {
180
+ if (closed)
181
+ return;
182
+ closed = true;
183
+ fsSync.closeSync(fd);
184
+ },
185
+ };
186
+ }
187
+ catch (error) {
188
+ fsSync.closeSync(fd);
189
+ throw error;
190
+ }
191
+ }
@@ -0,0 +1,2 @@
1
+ export declare function resolveEffectiveUid(): number;
2
+ //# sourceMappingURL=effective-uid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effective-uid.d.ts","sourceRoot":"","sources":["../src/effective-uid.ts"],"names":[],"mappings":"AAUA,wBAAgB,mBAAmB,IAAI,MAAM,CAe5C"}
@@ -0,0 +1,25 @@
1
+ function isValidUid(value) {
2
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
3
+ }
4
+ function unavailable(cause) {
5
+ return new Error("Effective user identity is unavailable.", {
6
+ ...(cause === undefined ? {} : { cause }),
7
+ });
8
+ }
9
+ export function resolveEffectiveUid() {
10
+ const provider = process.geteuid;
11
+ if (typeof provider !== "function") {
12
+ throw unavailable();
13
+ }
14
+ let uid;
15
+ try {
16
+ uid = provider.call(process);
17
+ }
18
+ catch (cause) {
19
+ throw unavailable(cause);
20
+ }
21
+ if (!isValidUid(uid)) {
22
+ throw unavailable();
23
+ }
24
+ return uid;
25
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"file-handle-transfer.d.ts","sourceRoot":"","sources":["../src/file-handle-transfer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAWnD,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;CACnC,CAAC;AAEF,uFAAuF;AACvF,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CA4BjB;AAGD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,UAAU,GAAG,MAAM,EAC3B,OAAO,EAAE,qBAAqB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7E,OAAO,CAAC,MAAM,CAAC,CAyBjB"}
1
+ {"version":3,"file":"file-handle-transfer.d.ts","sourceRoot":"","sources":["../src/file-handle-transfer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAWnD,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;CACnC,CAAC;AAkDF,uFAAuF;AACvF,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CA0CjB;AAGD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,UAAU,GAAG,MAAM,EAC3B,OAAO,EAAE,qBAAqB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7E,OAAO,CAAC,MAAM,CAAC,CAwBjB"}
@@ -3,61 +3,132 @@ import { FsSafeError } from "./errors.js";
3
3
  import { assertSynchronousCallbackResult, composeMutationAssertions, rethrowMutationAuthorityError, } from "./mutation-authority.js";
4
4
  import { writeAllToFile } from "./write-file-handle.js";
5
5
  import { inspectFileIdentity } from "./strict-file-identity.js";
6
+ const NO_CALLBACK_ARGUMENTS = Object.freeze([]);
7
+ function defineReceiverValue(receiver, key, value) {
8
+ Object.defineProperty(receiver, key, {
9
+ value, enumerable: true, writable: true, configurable: true,
10
+ });
11
+ }
12
+ function copyTransferReceiver(options, maxBytes, sizeHint, signal, onChunk, assertBeforeMutation) {
13
+ const receiver = {};
14
+ const spreadSource = Object(options);
15
+ // Preserve the former late object-spread boundary, including proxy traps and
16
+ // unrelated getter failures. Authority-bearing values stay on their early
17
+ // snapshots, while descriptors still run in original own-key order.
18
+ for (const key of Reflect.ownKeys(spreadSource)) {
19
+ if (!Object.getOwnPropertyDescriptor(spreadSource, key)?.enumerable)
20
+ continue;
21
+ let value;
22
+ switch (key) {
23
+ case "maxBytes":
24
+ value = maxBytes;
25
+ break;
26
+ case "signal":
27
+ value = signal;
28
+ break;
29
+ case "onChunk":
30
+ value = onChunk;
31
+ break;
32
+ case "assertBeforeMutation":
33
+ value = assertBeforeMutation;
34
+ break;
35
+ default: value = Reflect.get(spreadSource, key);
36
+ }
37
+ // Create a data property so an enumerable __proto__ key cannot alter the
38
+ // ordinary receiver prototype, matching object spread.
39
+ defineReceiverValue(receiver, key, value);
40
+ }
41
+ // Match the explicit fields that followed the former spread. Updating an
42
+ // existing key retains its original position; absent keys append in order.
43
+ defineReceiverValue(receiver, "maxBytes", maxBytes);
44
+ defineReceiverValue(receiver, "sizeHint", sizeHint);
45
+ defineReceiverValue(receiver, "targetPosition", 0);
46
+ defineReceiverValue(receiver, "assertBeforeMutation", assertBeforeMutation);
47
+ return receiver;
48
+ }
6
49
  /** Copies caller-owned regular files from offset zero without moving either cursor. */
7
50
  export async function copyFileHandle(source, target, options = {}) {
8
- options.signal?.throwIfAborted();
51
+ // Snapshot caller-owned options before the first await. This preserves
52
+ // inherited/non-enumerable callbacks and prevents accessor mutation from
53
+ // replacing cancellation or mutation authority mid-transfer.
54
+ const signal = options.signal;
55
+ signal?.throwIfAborted();
9
56
  const maxBytes = normalizeMaxBytes(options.maxBytes);
57
+ const onChunk = options.onChunk;
58
+ const assertBeforeMutation = composeMutationAssertions(undefined, options.assertBeforeMutation);
10
59
  const sourceStat = await inspectFileIdentity(() => {
11
- options.signal?.throwIfAborted();
60
+ signal?.throwIfAborted();
12
61
  return source.stat({ bigint: true });
13
62
  });
14
- options.signal?.throwIfAborted();
63
+ signal?.throwIfAborted();
15
64
  if (!sourceStat.isFile())
16
65
  throw new FsSafeError("not-file", "copy source handle must be a regular file");
17
66
  if (maxBytes !== undefined && Number.isFinite(maxBytes) && sourceStat.size > BigInt(maxBytes)) {
18
67
  throw new FsSafeError("too-large", `file exceeds limit of ${maxBytes} bytes`);
19
68
  }
20
69
  const targetStat = await inspectFileIdentity(() => {
21
- options.signal?.throwIfAborted();
70
+ signal?.throwIfAborted();
22
71
  return target.stat({ bigint: true });
23
72
  });
24
- options.signal?.throwIfAborted();
73
+ signal?.throwIfAborted();
25
74
  if (!targetStat.isFile())
26
75
  throw new FsSafeError("not-file", "copy target handle must be a regular file");
27
76
  if (sourceStat.dev === targetStat.dev && sourceStat.ino === targetStat.ino) {
28
77
  throw new FsSafeError("path-alias", "copy source and target handles refer to the same file");
29
78
  }
30
- return await transferFileHandle(source, target, {
31
- ...options,
32
- maxBytes,
33
- sizeHint: Number(sourceStat.size),
34
- targetPosition: 0,
35
- assertBeforeMutation: composeMutationAssertions(undefined, options.assertBeforeMutation),
36
- }).catch(rethrowMutationAuthorityError);
79
+ const sizeHint = Number(sourceStat.size);
80
+ const callbackThis = copyTransferReceiver(options, maxBytes, sizeHint, signal, onChunk, assertBeforeMutation);
81
+ const beforeWrite = () => {
82
+ signal?.throwIfAborted();
83
+ assertBeforeMutation?.();
84
+ };
85
+ return await transferFileHandleCore(source, target, sizeHint, maxBytes, 0, signal, onChunk, beforeWrite, callbackThis).catch(rethrowMutationAuthorityError);
37
86
  }
38
87
  // Root.copyIn supplies already-admitted identities and retains its owned target cursor.
39
- export async function transferFileHandle(source, target, options) {
40
- const maxBytes = options.maxBytes ?? Infinity;
41
- const buffer = Buffer.allocUnsafe(Math.min(512 * 1024, Math.max(64 * 1024, options.sizeHint), maxBytes + 1));
88
+ export function transferFileHandle(source, target, options) {
89
+ try {
90
+ const maxBytes = options.maxBytes;
91
+ const sizeHint = options.sizeHint;
92
+ const targetPosition = options.targetPosition;
93
+ const signal = options.signal;
94
+ const onChunk = options.onChunk;
95
+ const assertBeforeMutation = options.assertBeforeMutation;
96
+ const beforeWrite = signal === undefined && assertBeforeMutation === undefined
97
+ ? undefined
98
+ : () => {
99
+ signal?.throwIfAborted();
100
+ if (assertBeforeMutation) {
101
+ Reflect.apply(assertBeforeMutation, options, NO_CALLBACK_ARGUMENTS);
102
+ }
103
+ };
104
+ return transferFileHandleCore(source, target, sizeHint, maxBytes, targetPosition, signal, onChunk, beforeWrite, options);
105
+ }
106
+ catch (error) {
107
+ // Keep the former async-function contract for synchronous option getters.
108
+ return Promise.reject(error);
109
+ }
110
+ }
111
+ async function transferFileHandleCore(source, target, sizeHint, maxBytes, targetPosition, signal, onChunk, beforeWrite, callbackThis) {
112
+ const limit = maxBytes ?? Infinity;
113
+ const buffer = Buffer.allocUnsafe(Math.min(512 * 1024, Math.max(64 * 1024, sizeHint), limit + 1));
42
114
  let position = 0;
43
115
  while (true) {
44
- options.signal?.throwIfAborted();
45
- const { bytesRead } = await source.read(buffer, 0, Math.min(buffer.length, maxBytes - position + 1), position);
46
- options.signal?.throwIfAborted();
47
- if (bytesRead > maxBytes - position) {
48
- throw new FsSafeError("too-large", `file exceeds limit of ${maxBytes} bytes`);
116
+ signal?.throwIfAborted();
117
+ const { bytesRead } = await source.read(buffer, 0, Math.min(buffer.length, limit - position + 1), position);
118
+ signal?.throwIfAborted();
119
+ if (bytesRead > limit - position) {
120
+ throw new FsSafeError("too-large", `file exceeds limit of ${limit} bytes`);
49
121
  }
50
122
  if (bytesRead === 0)
51
123
  return position;
52
124
  const chunk = buffer.subarray(0, bytesRead);
53
- if (options.onChunk)
54
- assertSynchronousCallbackResult(options.onChunk(chunk), "onChunk");
125
+ if (onChunk) {
126
+ const returned = Function.prototype.call.call(onChunk, callbackThis, chunk);
127
+ assertSynchronousCallbackResult(returned, "onChunk");
128
+ }
55
129
  await writeAllToFile(target, chunk, {
56
- position: options.targetPosition === undefined ? undefined : options.targetPosition + position,
57
- assertBeforeMutation: () => {
58
- options.signal?.throwIfAborted();
59
- options.assertBeforeMutation?.();
60
- },
130
+ position: targetPosition === undefined ? undefined : targetPosition + position,
131
+ assertBeforeMutation: beforeWrite,
61
132
  });
62
133
  position += bytesRead;
63
134
  }
@@ -1 +1 @@
1
- {"version":3,"file":"file-hash.d.ts","sourceRoot":"","sources":["../src/file-hash.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAInE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,UAAU,CAAC;AAClD,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,CAAC;AAElD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,EAClB,MAAM,GAAE,aAAa,GAAG,SAA8B,EACtD,EAAE,QAAmB,EAAE,MAAM,EAAE,GAAE,iBAAsB,GACtD,OAAO,CAAC,gBAAgB,CAAC,CAwD3B;AAyDD,wBAAsB,UAAU,CAC9B,KAAK,EAAE,eAAe,EACtB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAM3B;AAuDD,8FAA8F;AAC9F,wBAAgB,cAAc,CAC5B,KAAK,EAAE,mBAAmB,EAC1B,OAAO,GAAE,iBAAsB,GAC9B,gBAAgB,CAMlB"}
1
+ {"version":3,"file":"file-hash.d.ts","sourceRoot":"","sources":["../src/file-hash.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAKnE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,UAAU,CAAC;AAClD,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,CAAC;AAElD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,EAClB,MAAM,GAAE,aAAa,GAAG,SAA8B,EACtD,EAAE,QAAmB,EAAE,MAAM,EAAE,GAAE,iBAAsB,GACtD,OAAO,CAAC,gBAAgB,CAAC,CAwD3B;AA0DD,wBAAsB,UAAU,CAC9B,KAAK,EAAE,eAAe,EACtB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAM3B;AAwDD,8FAA8F;AAC9F,wBAAgB,cAAc,CAC5B,KAAK,EAAE,mBAAmB,EAC1B,OAAO,GAAE,iBAAsB,GAC9B,gBAAgB,CAMlB"}
package/dist/file-hash.js CHANGED
@@ -6,6 +6,7 @@ import { FsSafeError } from "./errors.js";
6
6
  import { getNativeBinding } from "./native.js";
7
7
  import { resolveReadOpenFlags } from "./read-open-flags.js";
8
8
  import { inspectFileIdentity, inspectFileIdentitySync } from "./strict-file-identity.js";
9
+ import { assertNoWindowsPathAlias } from "./windows-path-alias.js";
9
10
  export async function hashFileHandle(handle, native = getNativeBinding(), { maxBytes = Infinity, signal } = {}) {
10
11
  signal?.throwIfAborted();
11
12
  const stat = fsSync.fstatSync(handle.fd);
@@ -88,6 +89,7 @@ function rethrowHashOpenError(error) {
88
89
  throw error;
89
90
  }
90
91
  async function hashPath(filePath, options) {
92
+ assertNoWindowsPathAlias(filePath, "filesystem", "SHA-256 path uses a Windows filesystem namespace alias");
91
93
  const before = await inspectFileIdentity(() => hashPathIdentity(filePath));
92
94
  let handle;
93
95
  try {
@@ -145,6 +147,7 @@ function hashDescriptorSync(fd, { maxBytes = Infinity, signal }) {
145
147
  }
146
148
  }
147
149
  function hashPathSync(filePath, options) {
150
+ assertNoWindowsPathAlias(filePath, "filesystem", "SHA-256 path uses a Windows filesystem namespace alias");
148
151
  const before = inspectFileIdentitySync(() => hashPathIdentity(filePath));
149
152
  let fd;
150
153
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"file-lock-sync.d.ts","sourceRoot":"","sources":["../src/file-lock-sync.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EASL,KAAK,wBAAwB,EAC9B,MAAM,2BAA2B,CAAC;AAWnC,OAAO,KAAK,EACV,0BAA0B,EAC1B,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,yBAAyB,CAAC;AAMjC,MAAM,MAAM,0BAA0B,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,uBAAuB,CAAC;IAChC,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,QAAQ,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,iBAAiB,EAAE,KAAK,CAAC;KAC1B,KAAK,OAAO,CAAC;IACd,qBAAqB,CAAC,EAAE,CAAC,QAAQ,EAAE,wBAAwB,KAAK,OAAO,CAAC;IACxE,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAC3D,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,IAAI,OAAO,CAAC;IAC3B,OAAO,IAAI,IAAI,CAAC;IAChB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;CAC1B,CAAC;AAoJF,wBAAgB,mBAAmB,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,GAC5C,kBAAkB,CA0MpB;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,EAC7C,EAAE,EAAE,MAAM,CAAC,GACV,CAAC,CAOH"}
1
+ {"version":3,"file":"file-lock-sync.d.ts","sourceRoot":"","sources":["../src/file-lock-sync.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EASL,KAAK,wBAAwB,EAC9B,MAAM,2BAA2B,CAAC;AAWnC,OAAO,KAAK,EACV,0BAA0B,EAC1B,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,yBAAyB,CAAC;AAQjC,MAAM,MAAM,0BAA0B,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,uBAAuB,CAAC;IAChC,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,QAAQ,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,iBAAiB,EAAE,KAAK,CAAC;KAC1B,KAAK,OAAO,CAAC;IACd,qBAAqB,CAAC,EAAE,CAAC,QAAQ,EAAE,wBAAwB,KAAK,OAAO,CAAC;IACxE,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAC3D,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,IAAI,OAAO,CAAC;IAC3B,OAAO,IAAI,IAAI,CAAC;IAChB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;CAC1B,CAAC;AA8JF,wBAAgB,mBAAmB,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,GAC5C,kBAAkB,CA4NpB;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,EAC7C,EAAE,EAAE,MAAM,CAAC,GACV,CAAC,CAOH"}
@@ -5,8 +5,10 @@ import { readSidecarLockSnapshotSync, readSidecarLockRawSnapshotSync, parseSidec
5
5
  import { computeSidecarLockDelayMs, isTransientLockFileDenial, maxTransientLockDenials, sidecarLockPayloadCreatedAtMs, validateSidecarLockStaleMs, validateSidecarLockCompromiseCheckIntervalMs, validateSidecarLockRetryOptions, validateSidecarLockTimeoutMs, } from "./sidecar-lock-policy.js";
6
6
  import { getFsSafeLockConfig } from "./lock-config.js";
7
7
  import { sleepSync } from "./timing.js";
8
+ import { assertNoWindowsPathAlias } from "./windows-path-alias.js";
8
9
  import { realpathSync } from "./realpath.js";
9
10
  import { recursiveMkdirPath } from "./recursive-mkdir-path.js";
11
+ import { createSuppressedError } from "./suppressed-error.js";
10
12
  const SYNC_HELD_LOCKS_KEY = Symbol.for("fsSafe.syncSidecarLocks");
11
13
  const SYNC_CLEANUP_REGISTERED_KEY = Symbol.for("fsSafe.syncSidecarLockCleanupRegistered");
12
14
  const SYNC_CLEANUP_HANDLER_KEY = Symbol.for("fsSafe.syncSidecarLockCleanupHandler");
@@ -97,26 +99,36 @@ function canonicalLockParentSync(parent) {
97
99
  }
98
100
  function normalizeTargetPath(targetPath) {
99
101
  const resolved = path.resolve(targetPath);
102
+ assertNoWindowsPathAlias(resolved);
100
103
  fs.mkdirSync(recursiveMkdirPath(path.dirname(resolved)), { recursive: true });
104
+ let parent;
101
105
  try {
102
- return path.join(canonicalLockParentSync(path.dirname(resolved)), path.basename(resolved));
106
+ parent = canonicalLockParentSync(path.dirname(resolved));
103
107
  }
104
108
  catch {
105
109
  return resolved;
106
110
  }
111
+ assertNoWindowsPathAlias(parent);
112
+ const normalized = path.join(parent, path.basename(resolved));
113
+ assertNoWindowsPathAlias(normalized);
114
+ return normalized;
107
115
  }
108
116
  function boundedLockPath(lockPath, lockRoot) {
109
117
  const resolved = path.resolve(lockPath);
118
+ assertNoWindowsPathAlias(resolved);
110
119
  if (!lockRoot)
111
120
  return resolved;
112
121
  relativeSidecarLockPath(lockRoot, resolved);
113
122
  const parent = path.dirname(resolved);
114
123
  const parentReal = canonicalLockParentSync(parent);
124
+ assertNoWindowsPathAlias(parentReal);
115
125
  const parentRelative = path.relative(lockRoot.rootReal, parentReal);
116
126
  if (parentRelative === ".." || parentRelative.startsWith(`..${path.sep}`) || path.isAbsolute(parentRelative)) {
117
127
  throw new FsSafeError("outside-workspace", "sidecar lock parent is outside lockRoot");
118
128
  }
119
- return path.join(parentReal, path.basename(resolved));
129
+ const bounded = path.join(parentReal, path.basename(resolved));
130
+ assertNoWindowsPathAlias(bounded);
131
+ return bounded;
120
132
  }
121
133
  function defaultShouldReclaim(snapshot, staleMs, nowMs) {
122
134
  const createdAtMs = sidecarLockPayloadCreatedAtMs(snapshot.payload);
@@ -145,8 +157,12 @@ export function acquireFileLockSync(targetPath, options) {
145
157
  const staleMs = options.staleMs ?? defaults.staleMs ?? 30_000;
146
158
  validateSidecarLockStaleMs(staleMs);
147
159
  validateSidecarLockCompromiseCheckIntervalMs(options.compromiseCheckIntervalMs);
160
+ const explicitLockPath = options.lockPath;
161
+ assertNoWindowsPathAlias(targetPath);
162
+ if (explicitLockPath !== undefined)
163
+ assertNoWindowsPathAlias(explicitLockPath);
148
164
  const normalizedTargetPath = normalizeTargetPath(targetPath);
149
- const lockPath = boundedLockPath(options.lockPath ?? `${normalizedTargetPath}.lock`, options.lockRoot);
165
+ const lockPath = boundedLockPath(explicitLockPath ?? `${normalizedTargetPath}.lock`, options.lockRoot);
150
166
  const heldLocks = getSyncHeldLocks();
151
167
  const held = heldLocks.get(normalizedTargetPath);
152
168
  if (held &&
@@ -256,10 +272,24 @@ export function acquireFileLockSync(targetPath, options) {
256
272
  }
257
273
  catch (error) {
258
274
  if (fd !== undefined) {
259
- const failed = { payload: null, stat: fs.fstatSync(fd) };
260
- fs.closeSync(fd);
275
+ const failed = { payload: null };
276
+ try {
277
+ failed.stat = fs.fstatSync(fd);
278
+ }
279
+ catch {
280
+ // Missing identity leaves the sidecar in place, but must not skip close.
281
+ }
282
+ const failedFd = fd;
283
+ // A close error may still free the number; consume ownership before closing.
261
284
  fd = undefined;
262
- removeSidecarLockIfUnchangedSync(lockPath, failed);
285
+ try {
286
+ fs.closeSync(failedFd);
287
+ if (failed.stat)
288
+ removeSidecarLockIfUnchangedSync(lockPath, failed);
289
+ }
290
+ catch (cleanupError) {
291
+ throw createSuppressedError(error, cleanupError, "file lock acquisition and cleanup both failed");
292
+ }
263
293
  }
264
294
  if (lockFileCreateDenied && retryLockFileDenial(error))
265
295
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"file-lock.d.ts","sourceRoot":"","sources":["../src/file-lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC9B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,MAAM,oBAAoB,GAAG,uBAAuB,CAAC;AAC3D,MAAM,MAAM,qBAAqB,GAAG,wBAAwB,CAAC;AAE7D,MAAM,MAAM,sBAAsB,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,IAAI,CACjF,yBAAyB,CAAC,QAAQ,CAAC,EACnC,YAAY,GAAG,SAAS,CACzB,GAAG;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,iBAAiB,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AACrD,YAAY,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAEpE,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,sBAAsB,CAAC,QAAQ,CAAC,GACxC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3B,QAAQ,CAAC,CAAC,EAAE,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClD,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,sBAAsB,CAAC,QAAQ,CAAC,EACzC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAAC;IACd,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,KAAK,IAAI,IAAI,CAAC;IACd,WAAW,IAAI,iBAAiB,EAAE,CAAC;CACpC,CAAC;AAmBF,wBAAsB,eAAe,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5E,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,sBAAsB,CAAC,QAAQ,CAAC,GACxC,OAAO,CAAC,cAAc,CAAC,CAGzB;AAED,wBAAsB,YAAY,CAAC,CAAC,EAAE,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5E,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,sBAAsB,CAAC,QAAQ,CAAC,EACzC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAGZ;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAelE;AAED,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAEzF"}
1
+ {"version":3,"file":"file-lock.d.ts","sourceRoot":"","sources":["../src/file-lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC9B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,MAAM,oBAAoB,GAAG,uBAAuB,CAAC;AAC3D,MAAM,MAAM,qBAAqB,GAAG,wBAAwB,CAAC;AAE7D,MAAM,MAAM,sBAAsB,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,IAAI,CACjF,yBAAyB,CAAC,QAAQ,CAAC,EACnC,YAAY,GAAG,SAAS,CACzB,GAAG;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,iBAAiB,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AACrD,YAAY,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAEpE,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,sBAAsB,CAAC,QAAQ,CAAC,GACxC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3B,QAAQ,CAAC,CAAC,EAAE,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClD,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,sBAAsB,CAAC,QAAQ,CAAC,EACzC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAAC;IACd,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,KAAK,IAAI,IAAI,CAAC;IACd,WAAW,IAAI,iBAAiB,EAAE,CAAC;CACpC,CAAC;AAiCF,wBAAsB,eAAe,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5E,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,sBAAsB,CAAC,QAAQ,CAAC,GACxC,OAAO,CAAC,cAAc,CAAC,CAGzB;AAED,wBAAsB,YAAY,CAAC,CAAC,EAAE,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5E,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,sBAAsB,CAAC,QAAQ,CAAC,EACzC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAGZ;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAmBlE;AAED,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAEzF"}
package/dist/file-lock.js CHANGED
@@ -5,13 +5,29 @@ function resolveFileLockManagerKey(targetPath, managerKey) {
5
5
  return managerKey ?? `fs-safe.file-lock:${targetPath}`;
6
6
  }
7
7
  function withLockDefaults(options) {
8
+ const { managerKey: _managerKey, lockPath } = options;
9
+ const acquireOptions = {};
10
+ for (const key of Reflect.ownKeys(options)) {
11
+ // Node 22 object-rest can read excluded accessors; exclude before copying.
12
+ if (key === "managerKey" || key === "lockPath")
13
+ continue;
14
+ if (!Object.getOwnPropertyDescriptor(options, key)?.enumerable)
15
+ continue;
16
+ Object.defineProperty(acquireOptions, key, {
17
+ value: Reflect.get(options, key),
18
+ enumerable: true,
19
+ writable: true,
20
+ configurable: true,
21
+ });
22
+ }
8
23
  const defaults = getFsSafeLockConfig();
9
24
  return {
10
- ...options,
11
- retry: options.retry ?? defaults.retry,
12
- staleMs: options.staleMs ?? defaults.staleMs ?? 30_000,
13
- staleRecovery: options.staleRecovery ?? defaults.staleRecovery,
14
- timeoutMs: options.timeoutMs ?? defaults.timeoutMs,
25
+ ...acquireOptions,
26
+ retry: acquireOptions.retry ?? defaults.retry,
27
+ staleMs: acquireOptions.staleMs ?? defaults.staleMs ?? 30_000,
28
+ staleRecovery: acquireOptions.staleRecovery ?? defaults.staleRecovery,
29
+ timeoutMs: acquireOptions.timeoutMs ?? defaults.timeoutMs,
30
+ ...(lockPath === undefined ? {} : { lockPath }),
15
31
  };
16
32
  }
17
33
  export async function acquireFileLock(targetPath, options) {
@@ -26,12 +42,16 @@ export function createFileLockManager(key) {
26
42
  const manager = createSidecarLockManager(key);
27
43
  return {
28
44
  acquire: async (targetPath, options) => {
29
- const { managerKey: _managerKey, ...acquireOptions } = options;
30
- return await manager.acquire({ ...withLockDefaults(acquireOptions), targetPath });
45
+ return await manager.acquire({
46
+ ...withLockDefaults(options),
47
+ targetPath,
48
+ });
31
49
  },
32
50
  withLock: async (targetPath, options, fn) => {
33
- const { managerKey: _managerKey, ...acquireOptions } = options;
34
- return await manager.withLock({ ...withLockDefaults(acquireOptions), targetPath }, fn);
51
+ return await manager.withLock({
52
+ ...withLockDefaults(options),
53
+ targetPath,
54
+ }, fn);
35
55
  },
36
56
  drain: manager.drain,
37
57
  reset: manager.reset,
@@ -1,4 +1,4 @@
1
- type FailureKind = "identity" | "resolution" | `open:${string}` | `exclusive-create:${string}` | `unlinked:${string}` | `changed:${string}`;
1
+ type FailureKind = "identity" | "resolution" | `open:${string}` | `exclusive-create:${string}` | `unlinked:${string}` | `changed:${string}` | `stat-leaf-missing:${string}`;
2
2
  export declare function recordFileObservationFailure(error: unknown, kind: FailureKind): void;
3
3
  export declare function isFileObservationFailure(error: unknown, kind: FailureKind): boolean;
4
4
  export declare function fileObservation(): {
@@ -1 +1 @@
1
- {"version":3,"file":"file-observation.d.ts","sourceRoot":"","sources":["../src/file-observation.ts"],"names":[],"mappings":"AAEA,KAAK,WAAW,GAAG,UAAU,GAAG,YAAY,GAAG,QAAQ,MAAM,EAAE,GAAG,oBAAoB,MAAM,EAAE,GAAG,YAAY,MAAM,EAAE,GAAG,WAAW,MAAM,EAAE,CAAC;AAG5I,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAMpF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAEnF;AAGD,wBAAgB,eAAe;IAG3B,GAAG,CAAC,CAAC,aAAa,MAAM,CAAC,GAAG,CAAC;IAC7B,GAAG,QAAQ,OAAO,QAAQ,WAAW,GAAG,OAAO;EAElD"}
1
+ {"version":3,"file":"file-observation.d.ts","sourceRoot":"","sources":["../src/file-observation.ts"],"names":[],"mappings":"AAEA,KAAK,WAAW,GAAG,UAAU,GAAG,YAAY,GAAG,QAAQ,MAAM,EAAE,GAAG,oBAAoB,MAAM,EAAE,GAAG,YAAY,MAAM,EAAE,GAAG,WAAW,MAAM,EAAE,GAAG,qBAAqB,MAAM,EAAE,CAAC;AAG5K,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAMpF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAEnF;AAGD,wBAAgB,eAAe;IAG3B,GAAG,CAAC,CAAC,aAAa,MAAM,CAAC,GAAG,CAAC;IAC7B,GAAG,QAAQ,OAAO,QAAQ,WAAW,GAAG,OAAO;EAElD"}
@@ -1,8 +1,12 @@
1
+ import { type BigIntStats } from "node:fs";
1
2
  import type { Readable } from "node:stream";
2
- import { type SyncDirectoryGuard } from "./directory-guard.js";
3
+ import type { SyncDirectoryGuard } from "./directory-guard.js";
3
4
  import { type Root } from "./root.js";
4
5
  import { prepareSecretFileWrite } from "./secret-file.js";
5
- export type SyncParentGuard = SyncDirectoryGuard;
6
+ export type SyncParentGuard = SyncDirectoryGuard & {
7
+ /** Exact authority retained separately from the legacy numeric durability receipt. */
8
+ readonly exactStat: BigIntStats;
9
+ };
6
10
  export declare function ensureParentInRoot(scopedRoot: Root, relativePath: string, mode: number): Promise<void>;
7
11
  export declare function openWritableStoreRoot(params: {
8
12
  rootDir: string;
@@ -1 +1 @@
1
- {"version":3,"file":"file-store-boundary.d.ts","sourceRoot":"","sources":["../src/file-store-boundary.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAa,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIvD,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAA4C,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAGhF,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAK1D,MAAM,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAOjD,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,IAAI,EAChB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhB;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,GACnD,OAAO,CAAC,IAAI,CAAC,CASf;AAsCD,wBAAsB,uBAAuB,CAAC,MAAM,EAAE;IACpD,MAAM,EAAE,QAAQ,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAwC1D;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAWrE;AAUD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,eAAe,CAOlB;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,eAAe,GAAG,OAAO,CAAC;CAC1C,GAAG,eAAe,CAyDlB"}
1
+ {"version":3,"file":"file-store-boundary.d.ts","sourceRoot":"","sources":["../src/file-store-boundary.ts"],"names":[],"mappings":"AAAA,OAAe,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAGnD,OAAO,KAAK,EAAa,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAO/D,OAAO,EAA4C,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAGhF,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAK1D,MAAM,MAAM,eAAe,GAAG,kBAAkB,GAAG;IACjD,sFAAsF;IACtF,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;CACjC,CAAC;AAOF,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,IAAI,EAChB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMhB;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,GACnD,OAAO,CAAC,IAAI,CAAC,CAUf;AAsCD,wBAAsB,uBAAuB,CAAC,MAAM,EAAE;IACpD,MAAM,EAAE,QAAQ,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAwC1D;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAMrE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,eAAe,CASlB;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,eAAe,GAAG,OAAO,CAAC;CAC1C,GAAG,eAAe,CAUlB"}