@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
package/dist/root-path.js CHANGED
@@ -1,13 +1,18 @@
1
- import fs from "node:fs";
1
+ import fs, {} from "node:fs";
2
2
  import path from "node:path";
3
- import { formatErrorDetail, shortPath } from "./error-detail.js";
3
+ import { shortPath } from "./error-detail.js";
4
+ import { pathEscapeError, sanitizeRootPathError, symlinkEscapeError } from "./root-path-errors.js";
4
5
  import { FsSafeError } from "./errors.js";
6
+ import { isNativeDirectoryObservationGuard } from "./native-directory-observation.js";
5
7
  import { assertNoNulPathInput, isNotFoundPathError, isPathRelativeEscape, } from "./path.js";
6
8
  import { absolutePathWithRawSegments, rawPathRelativeToCanonicalRoot, resolvePathViaExistingAncestor, resolvePathViaExistingAncestorSync, } from "./root-path-existing.js";
7
9
  import { admitPathInsideRoot, } from "./root-boundary.js";
10
+ import { RootPathObservationError, captureRootPathObservedDirectory, createRootPathTraversalObservation, inspectRootPathTraversalEntry, } from "./root-path-observation.js";
8
11
  import { resolveSymlinkHopPath, resolveSymlinkHopPathSync } from "./root-path-symlink.js";
9
12
  import { assertNoDriveRelativePathSegments } from "./safe-path-segment.js";
13
+ import { assertNoWindowsPathAlias, pathForWindowsFilesystem, resolvePathFromBasePreservingWindowsRoot, resolvePathPreservingWindowsRoot, } from "./windows-path-alias.js";
10
14
  export { resolvePathViaExistingAncestorSync } from "./root-path-existing.js";
15
+ export { RootPathObservationError, } from "./root-path-observation.js";
11
16
  export const ROOT_PATH_ALIAS_POLICIES = {
12
17
  strict: Object.freeze({
13
18
  allowFinalSymlinkForUnlink: false,
@@ -26,14 +31,47 @@ export async function resolveRootPath(params) {
26
31
  throw sanitizeRootPathError(error);
27
32
  }
28
33
  }
29
- async function resolveRootPathInternal(params) {
30
- assertValidRootPathInputs(params);
31
- params = { ...params, absolutePath: absolutePathWithRawSegments(params.absolutePath) };
32
- const rootPath = path.resolve(params.rootPath);
33
- const rootCanonicalPath = params.rootCanonicalPath
34
- ? path.resolve(params.rootCanonicalPath)
34
+ export async function resolveRootPathWithCanonicalRootObservation(params, observeRoot) {
35
+ try {
36
+ return await resolveRootPathInternal(params, undefined, undefined, observeRoot);
37
+ }
38
+ catch (error) {
39
+ throw sanitizeRootPathError(error);
40
+ }
41
+ }
42
+ async function resolveRootPathInternal(params, observationRequest, observationOutput, observeRoot, removalReceipts) {
43
+ const input = captureValidRootPathInputs(params);
44
+ const rawAbsolutePath = absolutePathWithRawSegments(input.absolutePath);
45
+ const rootPath = resolvePathPreservingWindowsRoot(input.rootPath);
46
+ const absolutePath = resolvePathPreservingWindowsRoot(rawAbsolutePath);
47
+ const rootCanonicalPath = input.rootCanonicalPath
48
+ ? resolvePathPreservingWindowsRoot(input.rootCanonicalPath)
35
49
  : await resolvePathViaExistingAncestor(rootPath);
36
- return resolveRootPathLexicalAsync(prepareRootTraversal(params, rootPath, rootCanonicalPath));
50
+ assertNoWindowsPathAlias(rootPath);
51
+ assertNoWindowsPathAlias(absolutePath);
52
+ assertNoWindowsPathAlias(rootCanonicalPath);
53
+ observeRoot?.(rootCanonicalPath);
54
+ return resolveRootPathLexicalAsync(prepareRootTraversal(input, rootPath, rootCanonicalPath, absolutePath, rawAbsolutePath), observationRequest, observationOutput, removalReceipts);
55
+ }
56
+ export async function resolveRootPathWithObservation(params, request) {
57
+ const output = {};
58
+ try {
59
+ const resolved = await resolveRootPathInternal(params, request, output);
60
+ return output.receipt ? { resolved, receipt: output.receipt } : { resolved };
61
+ }
62
+ catch (error) {
63
+ throw sanitizeRootPathError(error);
64
+ }
65
+ }
66
+ // Removal receipts are separate from metadata observations and canonical-root
67
+ // callbacks; the public resolver's options and result remain unchanged.
68
+ export async function resolveRootPathForRemoval(params, receipts) {
69
+ try {
70
+ return await resolveRootPathInternal(params, undefined, undefined, undefined, receipts);
71
+ }
72
+ catch (error) {
73
+ throw sanitizeRootPathError(error);
74
+ }
37
75
  }
38
76
  export function resolveRootPathSync(params) {
39
77
  try {
@@ -43,18 +81,30 @@ export function resolveRootPathSync(params) {
43
81
  throw sanitizeRootPathError(error);
44
82
  }
45
83
  }
46
- function resolveRootPathSyncInternal(params) {
47
- assertValidRootPathInputs(params);
48
- params = { ...params, absolutePath: absolutePathWithRawSegments(params.absolutePath) };
49
- const rootPath = path.resolve(params.rootPath);
50
- const rootCanonicalPath = params.rootCanonicalPath
51
- ? path.resolve(params.rootCanonicalPath)
84
+ export function resolveRootPathSyncWithCanonicalRootObservation(params, observeRoot) {
85
+ try {
86
+ return resolveRootPathSyncInternal(params, observeRoot);
87
+ }
88
+ catch (error) {
89
+ throw sanitizeRootPathError(error);
90
+ }
91
+ }
92
+ function resolveRootPathSyncInternal(params, observeRoot) {
93
+ const input = captureValidRootPathInputs(params);
94
+ const rawAbsolutePath = absolutePathWithRawSegments(input.absolutePath);
95
+ const rootPath = resolvePathPreservingWindowsRoot(input.rootPath);
96
+ const absolutePath = resolvePathPreservingWindowsRoot(rawAbsolutePath);
97
+ const rootCanonicalPath = input.rootCanonicalPath
98
+ ? resolvePathPreservingWindowsRoot(input.rootCanonicalPath)
52
99
  : resolvePathViaExistingAncestorSync(rootPath);
53
- return resolveRootPathLexicalSync(prepareRootTraversal(params, rootPath, rootCanonicalPath));
100
+ assertNoWindowsPathAlias(rootPath);
101
+ assertNoWindowsPathAlias(absolutePath);
102
+ assertNoWindowsPathAlias(rootCanonicalPath);
103
+ observeRoot?.(rootCanonicalPath);
104
+ return resolveRootPathLexicalSync(prepareRootTraversal(input, rootPath, rootCanonicalPath, absolutePath, rawAbsolutePath));
54
105
  }
55
- function prepareRootTraversal(params, rootPath, rootCanonicalPath) {
56
- const callerAbsolutePath = path.resolve(params.absolutePath);
57
- let raw = params.absolutePath;
106
+ function prepareRootTraversal(params, rootPath, rootCanonicalPath, absolutePath, rawAbsolutePath) {
107
+ let raw = rawAbsolutePath;
58
108
  let trustedAbsolutePath = false;
59
109
  const direct = admitRawPathInsideRoot(rootPath, raw, params.rootIdentity);
60
110
  if (direct) {
@@ -72,30 +122,49 @@ function prepareRootTraversal(params, rootPath, rootCanonicalPath) {
72
122
  raw = relative === "" ? rootPath : `${rootPath}${path.sep}${relative}`;
73
123
  }
74
124
  return {
75
- params: raw === params.absolutePath ? params : { ...params, absolutePath: raw },
125
+ params,
126
+ rawAbsolutePath: raw,
76
127
  rootPath,
77
128
  rootCanonicalPath,
78
129
  // Preserve the caller-spelling receipt for ordinary aliases. Only a
79
130
  // Windows case-fold admission must return the identity-gated Root spelling,
80
131
  // because downstream I/O must not reuse the ambiguous caller prefix.
81
- absolutePath: trustedAbsolutePath ? path.resolve(raw) : callerAbsolutePath,
132
+ absolutePath: trustedAbsolutePath ? resolvePathPreservingWindowsRoot(raw) : absolutePath,
133
+ observationEligible: raw === rawAbsolutePath && !trustedAbsolutePath,
82
134
  };
83
135
  }
84
- function sanitizeRootPathError(error) {
85
- if (error instanceof Error) {
86
- error.message = formatErrorDetail(error.message);
87
- }
88
- return error;
89
- }
90
- function assertValidRootPathInputs(params) {
91
- assertNoNulPathInput(params.rootPath, "root path contains a NUL byte");
92
- assertNoNulPathInput(params.absolutePath, "absolute path contains a NUL byte");
93
- assertNoEmbeddedDriveRelativeSegment(params.rootPath, "root path");
94
- assertNoEmbeddedDriveRelativeSegment(params.absolutePath, "absolute path");
95
- if (params.rootCanonicalPath !== undefined) {
96
- assertNoNulPathInput(params.rootCanonicalPath, "canonical root path contains a NUL byte");
97
- assertNoEmbeddedDriveRelativeSegment(params.rootCanonicalPath, "canonical root path");
136
+ function captureValidRootPathInputs(params) {
137
+ const rootPath = params.rootPath;
138
+ assertNoNulPathInput(rootPath, "root path contains a NUL byte");
139
+ const absolutePath = params.absolutePath;
140
+ assertNoNulPathInput(absolutePath, "absolute path contains a NUL byte");
141
+ assertNoWindowsPathAlias(rootPath, "filesystem", "root path uses a Windows filesystem namespace alias");
142
+ assertNoWindowsPathAlias(absolutePath, "filesystem", "absolute path uses a Windows filesystem namespace alias");
143
+ assertNoEmbeddedDriveRelativeSegment(rootPath, "root path");
144
+ assertNoEmbeddedDriveRelativeSegment(absolutePath, "absolute path");
145
+ const rootCanonicalPath = params.rootCanonicalPath;
146
+ if (rootCanonicalPath !== undefined) {
147
+ assertNoNulPathInput(rootCanonicalPath, "canonical root path contains a NUL byte");
148
+ assertNoWindowsPathAlias(rootCanonicalPath, "filesystem", "canonical root path uses a Windows filesystem namespace alias");
149
+ assertNoEmbeddedDriveRelativeSegment(rootCanonicalPath, "canonical root path");
98
150
  }
151
+ // Keep traversal policy with the admitted paths across ancestor and symlink
152
+ // resolution. Caller-owned flags and getters must not change a running walk.
153
+ const policy = params.policy;
154
+ const rootIdentity = params.rootIdentity;
155
+ return {
156
+ rootPath,
157
+ absolutePath,
158
+ rootCanonicalPath,
159
+ rootIdentity: rootIdentity == null ? undefined : { dev: rootIdentity.dev, ino: rootIdentity.ino },
160
+ boundaryLabel: params.boundaryLabel,
161
+ policy: policy == null ? undefined : {
162
+ allowFinalSymlinkForUnlink: policy.allowFinalSymlinkForUnlink,
163
+ },
164
+ rejectSymlinks: params.rejectSymlinks,
165
+ rejectFinalSymlink: params.rejectFinalSymlink,
166
+ rejectUnresolvedSymlinks: params.rejectUnresolvedSymlinks,
167
+ };
99
168
  }
100
169
  function assertNoEmbeddedDriveRelativeSegment(filePath, label) {
101
170
  if (process.platform !== "win32") {
@@ -105,13 +174,15 @@ function assertNoEmbeddedDriveRelativeSegment(filePath, label) {
105
174
  assertNoDriveRelativePathSegments(filePath.slice(root.length).replaceAll("\\", "/"), label);
106
175
  }
107
176
  function createLexicalTraversalState(params) {
108
- const rawAbsolutePath = params.params.absolutePath;
177
+ const rawAbsolutePath = params.rawAbsolutePath;
109
178
  const relative = admitRawPathInsideRoot(params.rootPath, rawAbsolutePath, params.params.rootIdentity)?.relativePath;
110
179
  if (relative === undefined)
111
180
  throw new Error("Path traversal must begin at the root");
112
181
  const segments = splitTraversalSegments(relative);
113
182
  return {
114
183
  segments,
184
+ relativePath: relative,
185
+ reuseLexicalCanonical: false,
115
186
  finalComponentIndex: segments.findLastIndex((segment) => segment !== "."),
116
187
  allowFinalSymlink: params.params.policy?.allowFinalSymlinkForUnlink === true,
117
188
  canonicalCursor: params.rootCanonicalPath,
@@ -127,8 +198,16 @@ function createLexicalTraversalContext(params) {
127
198
  rootPath: params.rootPath,
128
199
  rootCanonicalPath: params.rootCanonicalPath,
129
200
  absolutePath: params.absolutePath,
201
+ observationEligible: params.observationEligible,
130
202
  };
131
203
  }
204
+ function createLexicalTraversalObservation(context, request) {
205
+ const observation = createRootPathTraversalObservation(context, request);
206
+ if (observation && observation.targetIndex >= 0) {
207
+ context.state.reuseLexicalCanonical = true;
208
+ }
209
+ return observation;
210
+ }
132
211
  function splitTraversalSegments(value) {
133
212
  const segments = value
134
213
  .split(process.platform === "win32" ? /[\\/]+/ : /\/+/)
@@ -141,7 +220,9 @@ function admitRawPathInsideRoot(rootPath, candidatePath, rootIdentity) {
141
220
  if (!path.isAbsolute(candidatePath)) {
142
221
  return undefined;
143
222
  }
144
- const root = path.resolve(rootPath);
223
+ // Every caller supplies the already-resolved root selected by
224
+ // resolveRootPathInternal; resolving it again is redundant on each traversal.
225
+ const root = rootPath;
145
226
  const candidate = process.platform === "win32"
146
227
  ? candidatePath.replaceAll("/", path.sep)
147
228
  : candidatePath;
@@ -171,7 +252,14 @@ function assertLexicalCursorInsideBoundary(context, candidatePath) {
171
252
  });
172
253
  }
173
254
  function advanceCanonicalCursorForSegment(context, segment) {
174
- context.state.canonicalCursor = assertLexicalCursorInsideBoundary(context, path.resolve(context.state.canonicalCursor, segment));
255
+ const candidatePath = context.state.reuseLexicalCanonical
256
+ ? context.state.lexicalCursor
257
+ : resolvePathFromBasePreservingWindowsRoot(context.state.canonicalCursor, segment);
258
+ context.state.canonicalCursor = assertLexicalCursorInsideBoundary(context, candidatePath);
259
+ }
260
+ function disableLexicalTraversalObservation(context, observation) {
261
+ observation.enabled = false;
262
+ context.state.reuseLexicalCanonical = false;
175
263
  }
176
264
  function finalizeLexicalResolution(context, kind) {
177
265
  context.state.canonicalCursor = assertLexicalCursorInsideBoundary(context, context.state.canonicalCursor);
@@ -215,7 +303,7 @@ function applyResolvedSymlinkHop(context, linkCanonical) {
215
303
  context.state.lexicalCursor = admitted;
216
304
  }
217
305
  function applyParentTraversalStep(context) {
218
- context.state.lexicalCursor = path.resolve(context.state.lexicalCursor, "..");
306
+ context.state.lexicalCursor = resolvePathFromBasePreservingWindowsRoot(context.state.lexicalCursor, "..");
219
307
  advanceCanonicalCursorForSegment(context, "..");
220
308
  if (context.state.missingDepth > 0)
221
309
  context.state.missingDepth -= 1;
@@ -228,12 +316,13 @@ function assertDirectoryBeforeMoreSegments(stat, pathname, isLast) {
228
316
  function assertResolvedLinkDirectory(pathname, isLast) {
229
317
  if (isLast)
230
318
  return;
231
- const stat = fs.statSync(pathname);
319
+ const stat = fs.statSync(pathForWindowsFilesystem(pathname));
232
320
  assertDirectoryBeforeMoreSegments(stat, pathname, isLast);
233
321
  }
234
- async function resolveRootPathLexicalAsync(params) {
322
+ async function resolveRootPathLexicalAsync(params, observationRequest, observationOutput, removalReceipts) {
235
323
  const context = createLexicalTraversalContext(params);
236
324
  const { state } = context;
325
+ const observation = createLexicalTraversalObservation(context, observationRequest);
237
326
  for (let idx = 0; idx < state.segments.length; idx += 1) {
238
327
  const segment = state.segments[idx] ?? "";
239
328
  const isLast = idx === state.segments.length - 1;
@@ -250,14 +339,56 @@ async function resolveRootPathLexicalAsync(params) {
250
339
  continue;
251
340
  }
252
341
  let stat;
342
+ let observed;
253
343
  try {
254
- stat = fs.lstatSync(state.lexicalCursor);
344
+ if (removalReceipts && !isLast) {
345
+ const directoryStat = fs.lstatSync(pathForWindowsFilesystem(state.lexicalCursor), { bigint: true });
346
+ if (directoryStat.isDirectory() && !directoryStat.isSymbolicLink()) {
347
+ removalReceipts.observeDirectory(state.lexicalCursor, directoryStat);
348
+ }
349
+ stat = directoryStat;
350
+ }
351
+ else {
352
+ const directorySlot = observation?.enabled === true && idx === observation.directoryIndex;
353
+ const targetSlot = observation?.enabled === true && idx === observation.targetIndex;
354
+ const observeExactly = directorySlot || targetSlot;
355
+ if (observeExactly) {
356
+ observed = inspectRootPathTraversalEntry(state.lexicalCursor, directorySlot, observation);
357
+ }
358
+ stat = isNativeDirectoryObservationGuard(observed)
359
+ ? undefined
360
+ : observed?.stat ?? fs.lstatSync(state.lexicalCursor);
361
+ }
255
362
  }
256
363
  catch (error) {
364
+ if (observation?.enabled && observation.request.kind === "stat" &&
365
+ idx === observation.targetIndex && observation.directoryGuard) {
366
+ const parentReceipt = {
367
+ kind: "stat-parent",
368
+ rootGuard: observation.request.rootGuard,
369
+ directoryGuard: observation.directoryGuard,
370
+ directoryObserver: observation.directoryObserver,
371
+ targetPath: state.lexicalCursor,
372
+ };
373
+ // Stop here: the generic missing-path fallback would re-admit a parent.
374
+ // Preserve observation-only versus ordinary traversal error precedence.
375
+ throw new RootPathObservationError(error instanceof RootPathObservationError ? error.error : sanitizeRootPathError(error), parentReceipt, !(error instanceof RootPathObservationError));
376
+ }
257
377
  if (handleLexicalLstatFailure(context, error, segment))
258
378
  continue;
259
379
  throw error;
260
380
  }
381
+ if (isNativeDirectoryObservationGuard(observed)) {
382
+ advanceCanonicalCursorForSegment(context, segment);
383
+ captureRootPathObservedDirectory(observation, observed, state.lexicalCursor, state.canonicalCursor, context.rootCanonicalPath, context.resolveParams.rootIdentity);
384
+ if (idx === observation.targetIndex) {
385
+ observation.targetPath = state.canonicalCursor;
386
+ observation.target = observed;
387
+ }
388
+ continue;
389
+ }
390
+ if (!stat)
391
+ throw new Error("directory observation did not return metadata");
261
392
  const isSymbolicLink = stat.isSymbolicLink();
262
393
  if (!isSymbolicLink)
263
394
  assertDirectoryBeforeMoreSegments(stat, state.lexicalCursor, isLast);
@@ -271,10 +402,24 @@ async function resolveRootPathLexicalAsync(params) {
271
402
  if (disposition !== "resolve-link") {
272
403
  state.preserveFinalSymlink = disposition === "break";
273
404
  advanceCanonicalCursorForSegment(context, segment);
405
+ if (observation?.enabled && isSymbolicLink) {
406
+ disableLexicalTraversalObservation(context, observation);
407
+ }
408
+ if (observation?.enabled && idx === observation.directoryIndex) {
409
+ const captured = observed?.identity && captureRootPathObservedDirectory(observation, observed, state.canonicalCursor, state.canonicalCursor, context.rootCanonicalPath, context.resolveParams.rootIdentity);
410
+ if (!captured)
411
+ disableLexicalTraversalObservation(context, observation);
412
+ }
413
+ if (observation?.enabled && idx === observation.targetIndex) {
414
+ observation.targetPath = state.canonicalCursor;
415
+ observation.target = observed?.identity ? observed : undefined;
416
+ }
274
417
  if (state.preserveFinalSymlink)
275
418
  break;
276
419
  continue;
277
420
  }
421
+ if (observation?.enabled)
422
+ disableLexicalTraversalObservation(context, observation);
278
423
  const linkCanonical = await resolveSymlinkHopPath(state.lexicalCursor, {
279
424
  rejectUnresolved: context.resolveParams.rejectUnresolvedSymlinks,
280
425
  });
@@ -284,7 +429,26 @@ async function resolveRootPathLexicalAsync(params) {
284
429
  }
285
430
  assertResolvedLinkDirectory(linkCanonical, isLast);
286
431
  }
287
- const kind = await getPathKind(state.canonicalCursor, state.preserveFinalSymlink);
432
+ const completeObservation = observation?.enabled === true && observation.directoryGuard !== undefined &&
433
+ observation.targetPath === state.canonicalCursor && observation.target !== undefined;
434
+ const kind = completeObservation
435
+ ? {
436
+ exists: true,
437
+ kind: isNativeDirectoryObservationGuard(observation.target)
438
+ ? "directory"
439
+ : toResolvedKind(observation.target.stat),
440
+ }
441
+ : await getPathKind(state.canonicalCursor, state.preserveFinalSymlink);
442
+ if (completeObservation && observationOutput) {
443
+ observationOutput.receipt = {
444
+ kind: observation.request.kind,
445
+ rootGuard: observation.request.rootGuard,
446
+ directoryGuard: observation.directoryGuard,
447
+ directoryObserver: observation.directoryObserver,
448
+ targetPath: observation.targetPath,
449
+ target: observation.target,
450
+ };
451
+ }
288
452
  return finalizeLexicalResolution(context, kind);
289
453
  }
290
454
  function resolveRootPathLexicalSync(params) {
@@ -356,9 +520,10 @@ function buildResolvedRootPath(params) {
356
520
  }
357
521
  async function getPathKind(absolutePath, preserveFinalSymlink) {
358
522
  try {
523
+ const operationPath = pathForWindowsFilesystem(absolutePath);
359
524
  const stat = preserveFinalSymlink
360
- ? fs.lstatSync(absolutePath)
361
- : fs.statSync(absolutePath);
525
+ ? fs.lstatSync(operationPath)
526
+ : fs.statSync(operationPath);
362
527
  return { exists: true, kind: toResolvedKind(stat) };
363
528
  }
364
529
  catch (error) {
@@ -370,7 +535,10 @@ async function getPathKind(absolutePath, preserveFinalSymlink) {
370
535
  }
371
536
  function getPathKindSync(absolutePath, preserveFinalSymlink) {
372
537
  try {
373
- const stat = preserveFinalSymlink ? fs.lstatSync(absolutePath) : fs.statSync(absolutePath);
538
+ const operationPath = pathForWindowsFilesystem(absolutePath);
539
+ const stat = preserveFinalSymlink
540
+ ? fs.lstatSync(operationPath)
541
+ : fs.statSync(operationPath);
374
542
  return { exists: true, kind: toResolvedKind(stat) };
375
543
  }
376
544
  catch (error) {
@@ -393,7 +561,7 @@ function toResolvedKind(stat) {
393
561
  return "other";
394
562
  }
395
563
  function relativeInsideRoot(rootPath, targetPath) {
396
- const relative = path.relative(path.resolve(rootPath), path.resolve(targetPath));
564
+ const relative = path.relative(resolvePathPreservingWindowsRoot(rootPath), resolvePathPreservingWindowsRoot(targetPath));
397
565
  if (!relative || relative === ".") {
398
566
  return "";
399
567
  }
@@ -413,9 +581,3 @@ function assertInsideBoundary(params) {
413
581
  }
414
582
  throw new Error(`Path resolves outside ${params.boundaryLabel} (${shortPath(params.rootCanonicalPath)}): ${shortPath(params.absolutePath)}`);
415
583
  }
416
- function pathEscapeError(params) {
417
- return new Error(`Path escapes ${params.boundaryLabel} (${shortPath(params.rootPath)}): ${shortPath(params.absolutePath)}`);
418
- }
419
- function symlinkEscapeError(params) {
420
- return new Error(`Symlink escapes ${params.boundaryLabel} (${shortPath(params.rootCanonicalPath)}): ${shortPath(params.symlinkPath)}`);
421
- }
@@ -0,0 +1,9 @@
1
+ import { type ResolvePathWithinRootParams } from "./path-scope-lexical.js";
2
+ export declare function resolvePathWithinRoot(params: ResolvePathWithinRootParams): {
3
+ ok: true;
4
+ path: string;
5
+ } | {
6
+ ok: false;
7
+ error: string;
8
+ };
9
+ //# sourceMappingURL=root-paths-lexical.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root-paths-lexical.d.ts","sourceRoot":"","sources":["../src/root-paths-lexical.ts"],"names":[],"mappings":"AACA,OAAO,EAAmC,KAAK,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAU5G,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,2BAA2B,GAClC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAgB3D"}
@@ -0,0 +1,22 @@
1
+ import path from "node:path";
2
+ import { resolvePathWithinNormalizedRoot } from "./path-scope-lexical.js";
3
+ import { hasWindowsPathAlias, resolvePathPreservingWindowsRoot, } from "./windows-path-alias.js";
4
+ function invalidPath(scopeLabel) {
5
+ return { ok: false, error: `Invalid path: must stay within ${scopeLabel}` };
6
+ }
7
+ export function resolvePathWithinRoot(params) {
8
+ const rootDir = params.rootDir;
9
+ if (typeof rootDir !== "string")
10
+ path.resolve(rootDir);
11
+ const requestedPath = params.requestedPath;
12
+ const scopeLabel = params.scopeLabel;
13
+ const defaultFileName = params.defaultFileName;
14
+ if (hasWindowsPathAlias(rootDir, "filesystem") ||
15
+ hasWindowsPathAlias(requestedPath, "filesystem") ||
16
+ (defaultFileName !== undefined &&
17
+ hasWindowsPathAlias(defaultFileName, "filesystem"))) {
18
+ return invalidPath(scopeLabel);
19
+ }
20
+ const root = resolvePathPreservingWindowsRoot(rootDir);
21
+ return resolvePathWithinNormalizedRoot({ rootDir, requestedPath, scopeLabel, defaultFileName }, root);
22
+ }
@@ -1,17 +1,10 @@
1
- import { FsSafeError } from "./errors.js";
2
- import { type ResolvePathWithinRootParams } from "./path-scope-lexical.js";
1
+ import { type DirectoryResult } from "./root-directory.js";
2
+ export { resolvePathWithinRoot } from "./root-paths-lexical.js";
3
+ export { ensureDirectoryWithinRoot } from "./root-directory.js";
3
4
  type InvalidPathResult = {
4
5
  ok: false;
5
6
  error: string;
6
7
  };
7
- type DirectoryResult = {
8
- ok: true;
9
- path: string;
10
- } | {
11
- ok: false;
12
- error: string;
13
- diagnostic?: FsSafeError;
14
- };
15
8
  type ResolvePathsWithinRootParams = {
16
9
  rootDir: string;
17
10
  requestedPaths: string[];
@@ -51,13 +44,6 @@ export type PathScope = {
51
44
  mode?: number;
52
45
  }): Promise<DirectoryResult>;
53
46
  };
54
- export declare function resolvePathWithinRoot(params: ResolvePathWithinRootParams): {
55
- ok: true;
56
- path: string;
57
- } | {
58
- ok: false;
59
- error: string;
60
- };
61
47
  export declare function resolveWritablePathWithinRoot(params: {
62
48
  rootDir: string;
63
49
  requestedPath: string;
@@ -70,16 +56,8 @@ export declare function resolveWritablePathWithinRoot(params: {
70
56
  ok: false;
71
57
  error: string;
72
58
  }>;
73
- export declare function ensureDirectoryWithinRoot(params: {
74
- rootDir: string;
75
- requestedPath: string;
76
- scopeLabel: string;
77
- defaultDirName?: string;
78
- mode?: number;
79
- }): Promise<DirectoryResult>;
80
59
  export declare function resolvePathsWithinRoot(params: ResolvePathsWithinRootParams): ResolvePathsWithinRootResult;
81
60
  export declare function resolveExistingPathsWithinRoot(params: ResolvePathsWithinRootParams): Promise<ResolvePathsWithinRootResult>;
82
61
  export declare function resolveStrictExistingPathsWithinRoot(params: ResolvePathsWithinRootParams): Promise<ResolvePathsWithinRootResult>;
83
62
  export declare function pathScope(rootDir: string, options: PathScopeOptions): PathScope;
84
- export {};
85
63
  //# sourceMappingURL=root-paths.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"root-paths.d.ts","sourceRoot":"","sources":["../src/root-paths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"root-paths.d.ts","sourceRoot":"","sources":["../src/root-paths.ts"],"names":[],"mappings":"AAgBA,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,KAAK,iBAAiB,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AACtD,KAAK,4BAA4B,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AACF,KAAK,4BAA4B,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,iBAAiB,CAAC;AACtF,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AACF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AACF,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CACL,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,uBAAuB,GAChC;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7D,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,4BAA4B,CAAC;IACnE,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAC1E,KAAK,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAC;IACvE,QAAQ,CACN,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtE,SAAS,CACP,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,uBAAuB,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GACpD,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7B,CAAC;AAoEF,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA0CrE;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,4BAA4B,GACnC,4BAA4B,CA2B9B;AAED,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,4BAA4B,GACnC,OAAO,CAAC,4BAA4B,CAAC,CAEvC;AAED,wBAAsB,oCAAoC,CACxD,MAAM,EAAE,4BAA4B,GACnC,OAAO,CAAC,4BAA4B,CAAC,CAEvC;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAyC/E"}