@openclaw/fs-safe 0.9.0 → 0.11.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 (326) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/LICENSE +1 -0
  3. package/README.md +52 -4
  4. package/dist/absolute-path.d.ts.map +1 -1
  5. package/dist/absolute-path.js +3 -2
  6. package/dist/advanced.d.ts +5 -0
  7. package/dist/advanced.d.ts.map +1 -1
  8. package/dist/advanced.js +5 -0
  9. package/dist/archive-crc32.d.ts.map +1 -1
  10. package/dist/archive-crc32.js +6 -1
  11. package/dist/archive-deadline.d.ts.map +1 -1
  12. package/dist/archive-deadline.js +3 -4
  13. package/dist/archive-durability.d.ts +6 -6
  14. package/dist/archive-durability.d.ts.map +1 -1
  15. package/dist/archive-durability.js +1 -1
  16. package/dist/archive-entry.d.ts.map +1 -1
  17. package/dist/archive-entry.js +4 -5
  18. package/dist/archive-gzip-tail.d.ts +3 -0
  19. package/dist/archive-gzip-tail.d.ts.map +1 -1
  20. package/dist/archive-gzip-tail.js +23 -3
  21. package/dist/archive-input.d.ts.map +1 -1
  22. package/dist/archive-input.js +4 -2
  23. package/dist/archive-merge.d.ts +5 -1
  24. package/dist/archive-merge.d.ts.map +1 -1
  25. package/dist/archive-merge.js +16 -13
  26. package/dist/archive-native.d.ts.map +1 -1
  27. package/dist/archive-native.js +7 -6
  28. package/dist/archive-parser.wasm +0 -0
  29. package/dist/archive-read.d.ts.map +1 -1
  30. package/dist/archive-read.js +83 -74
  31. package/dist/archive-staging.d.ts +6 -3
  32. package/dist/archive-staging.d.ts.map +1 -1
  33. package/dist/archive-staging.js +42 -22
  34. package/dist/archive-tar-stream.d.ts +11 -4
  35. package/dist/archive-tar-stream.d.ts.map +1 -1
  36. package/dist/archive-tar-stream.js +23 -10
  37. package/dist/archive-tar-wasm.d.ts.map +1 -1
  38. package/dist/archive-tar-wasm.js +18 -14
  39. package/dist/archive-zip-admission.d.ts +1 -1
  40. package/dist/archive-zip-admission.d.ts.map +1 -1
  41. package/dist/archive-zip-admission.js +48 -12
  42. package/dist/archive-zip-loader.d.ts +6 -0
  43. package/dist/archive-zip-loader.d.ts.map +1 -0
  44. package/dist/archive-zip-loader.js +38 -0
  45. package/dist/archive-zip-names.d.ts.map +1 -1
  46. package/dist/archive-zip-names.js +13 -8
  47. package/dist/archive-zip-preflight.d.ts +2 -3
  48. package/dist/archive-zip-preflight.d.ts.map +1 -1
  49. package/dist/archive-zip-preflight.js +2 -34
  50. package/dist/archive.d.ts.map +1 -1
  51. package/dist/archive.js +12 -10
  52. package/dist/bounded-read.d.ts +12 -0
  53. package/dist/bounded-read.d.ts.map +1 -1
  54. package/dist/bounded-read.js +82 -45
  55. package/dist/clone-metadata.d.ts +19 -0
  56. package/dist/clone-metadata.d.ts.map +1 -0
  57. package/dist/clone-metadata.js +32 -0
  58. package/dist/copy-file-input.d.ts +22 -0
  59. package/dist/copy-file-input.d.ts.map +1 -0
  60. package/dist/copy-file-input.js +69 -0
  61. package/dist/copy-policy.d.ts +3 -0
  62. package/dist/copy-policy.d.ts.map +1 -0
  63. package/dist/copy-policy.js +8 -0
  64. package/dist/copy-publication.d.ts +10 -1
  65. package/dist/copy-publication.d.ts.map +1 -1
  66. package/dist/copy-publication.js +27 -0
  67. package/dist/copy-tree-portable.d.ts +9 -0
  68. package/dist/copy-tree-portable.d.ts.map +1 -0
  69. package/dist/copy-tree-portable.js +222 -0
  70. package/dist/copy.d.ts +16 -0
  71. package/dist/copy.d.ts.map +1 -0
  72. package/dist/copy.js +125 -0
  73. package/dist/directory-durability.d.ts.map +1 -1
  74. package/dist/directory-durability.js +5 -4
  75. package/dist/directory-guard.d.ts +11 -1
  76. package/dist/directory-guard.d.ts.map +1 -1
  77. package/dist/directory-guard.js +53 -11
  78. package/dist/durability.d.ts +1 -1
  79. package/dist/durability.d.ts.map +1 -1
  80. package/dist/durability.js +1 -1
  81. package/dist/error-detail.d.ts.map +1 -1
  82. package/dist/error-detail.js +4 -1
  83. package/dist/file-handle-transfer.d.ts +14 -0
  84. package/dist/file-handle-transfer.d.ts.map +1 -0
  85. package/dist/file-handle-transfer.js +64 -0
  86. package/dist/file-hash.d.ts +9 -2
  87. package/dist/file-hash.d.ts.map +1 -1
  88. package/dist/file-hash.js +135 -39
  89. package/dist/file-lock-sync.d.ts.map +1 -1
  90. package/dist/file-lock-sync.js +8 -4
  91. package/dist/file-store-boundary.d.ts.map +1 -1
  92. package/dist/file-store-boundary.js +7 -5
  93. package/dist/file-store-path.d.ts +3 -0
  94. package/dist/file-store-path.d.ts.map +1 -0
  95. package/dist/file-store-path.js +27 -0
  96. package/dist/file-store-prune.d.ts.map +1 -1
  97. package/dist/file-store-prune.js +6 -4
  98. package/dist/file-store-sync-write.d.ts.map +1 -1
  99. package/dist/file-store-sync-write.js +56 -44
  100. package/dist/file-store.d.ts.map +1 -1
  101. package/dist/file-store.js +2 -18
  102. package/dist/filename.d.ts.map +1 -1
  103. package/dist/filename.js +4 -13
  104. package/dist/guarded-mkdir.d.ts +1 -0
  105. package/dist/guarded-mkdir.d.ts.map +1 -1
  106. package/dist/guarded-mkdir.js +4 -2
  107. package/dist/guarded-mutation.d.ts +2 -0
  108. package/dist/guarded-mutation.d.ts.map +1 -1
  109. package/dist/guarded-mutation.js +8 -4
  110. package/dist/guest-dispatch-python.d.ts +2 -0
  111. package/dist/guest-dispatch-python.d.ts.map +1 -0
  112. package/dist/guest-dispatch-python.js +117 -0
  113. package/dist/guest-native-python.d.ts +4 -0
  114. package/dist/guest-native-python.d.ts.map +1 -0
  115. package/dist/guest-native-python.js +135 -0
  116. package/dist/guest.d.ts +9 -0
  117. package/dist/guest.d.ts.map +1 -0
  118. package/dist/guest.js +413 -0
  119. package/dist/home-dir.d.ts.map +1 -1
  120. package/dist/home-dir.js +9 -7
  121. package/dist/index.d.ts +1 -1
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/install-path.d.ts.map +1 -1
  124. package/dist/install-path.js +5 -8
  125. package/dist/json-durable-queue-directory.js +3 -3
  126. package/dist/json-durable-queue.d.ts.map +1 -1
  127. package/dist/json-durable-queue.js +19 -18
  128. package/dist/json.d.ts.map +1 -1
  129. package/dist/json.js +2 -1
  130. package/dist/local-roots.d.ts.map +1 -1
  131. package/dist/local-roots.js +24 -25
  132. package/dist/move-path-stage.d.ts +8 -0
  133. package/dist/move-path-stage.d.ts.map +1 -0
  134. package/dist/move-path-stage.js +56 -0
  135. package/dist/move-path.d.ts.map +1 -1
  136. package/dist/move-path.js +30 -34
  137. package/dist/mutation-authority.d.ts +9 -0
  138. package/dist/mutation-authority.d.ts.map +1 -0
  139. package/dist/mutation-authority.js +36 -0
  140. package/dist/native-binding.d.ts +29 -1
  141. package/dist/native-binding.d.ts.map +1 -1
  142. package/dist/native-operations.d.ts +1 -1
  143. package/dist/native-operations.d.ts.map +1 -1
  144. package/dist/native-operations.js +11 -5
  145. package/dist/native-pinned-write-windows.d.ts.map +1 -1
  146. package/dist/native-pinned-write-windows.js +19 -7
  147. package/dist/native-pinned-write.d.ts.map +1 -1
  148. package/dist/native-pinned-write.js +3 -1
  149. package/dist/native-staged-file.d.ts +3 -3
  150. package/dist/native-staged-file.d.ts.map +1 -1
  151. package/dist/native-staged-file.js +35 -8
  152. package/dist/opened-realpath.d.ts.map +1 -1
  153. package/dist/opened-realpath.js +5 -4
  154. package/dist/output.d.ts +2 -0
  155. package/dist/output.d.ts.map +1 -1
  156. package/dist/output.js +2 -0
  157. package/dist/overwrite-file-handle.d.ts +8 -0
  158. package/dist/overwrite-file-handle.d.ts.map +1 -0
  159. package/dist/overwrite-file-handle.js +42 -0
  160. package/dist/path-case.d.ts +7 -0
  161. package/dist/path-case.d.ts.map +1 -0
  162. package/dist/path-case.js +136 -0
  163. package/dist/path.d.ts.map +1 -1
  164. package/dist/path.js +5 -2
  165. package/dist/permissions-windows.d.ts +1 -1
  166. package/dist/permissions-windows.d.ts.map +1 -1
  167. package/dist/permissions-windows.js +85 -53
  168. package/dist/pinned-open.d.ts.map +1 -1
  169. package/dist/pinned-open.js +3 -1
  170. package/dist/pinned-operation.js +1 -1
  171. package/dist/pinned-write.d.ts +7 -3
  172. package/dist/pinned-write.d.ts.map +1 -1
  173. package/dist/pinned-write.js +51 -30
  174. package/dist/positional-read.d.ts +9 -0
  175. package/dist/positional-read.d.ts.map +1 -0
  176. package/dist/positional-read.js +36 -0
  177. package/dist/private-temp-workspace.d.ts.map +1 -1
  178. package/dist/private-temp-workspace.js +6 -4
  179. package/dist/publish-copy-stage.d.ts +13 -0
  180. package/dist/publish-copy-stage.d.ts.map +1 -0
  181. package/dist/publish-copy-stage.js +47 -0
  182. package/dist/publish-file.d.ts.map +1 -1
  183. package/dist/publish-file.js +6 -5
  184. package/dist/realpath.d.ts +4 -0
  185. package/dist/realpath.d.ts.map +1 -0
  186. package/dist/realpath.js +43 -0
  187. package/dist/recursive-mkdir-path.d.ts +3 -0
  188. package/dist/recursive-mkdir-path.d.ts.map +1 -0
  189. package/dist/recursive-mkdir-path.js +8 -0
  190. package/dist/replace-directory.d.ts.map +1 -1
  191. package/dist/replace-directory.js +2 -1
  192. package/dist/replace-file-copy-fallback.d.ts.map +1 -1
  193. package/dist/replace-file-copy-fallback.js +23 -31
  194. package/dist/replace-file-copy-source.d.ts.map +1 -1
  195. package/dist/replace-file-copy-source.js +7 -12
  196. package/dist/replace-file-mode.d.ts +3 -0
  197. package/dist/replace-file-mode.d.ts.map +1 -0
  198. package/dist/replace-file-mode.js +10 -0
  199. package/dist/replace-file-temp-owner.d.ts.map +1 -1
  200. package/dist/replace-file-temp-owner.js +6 -2
  201. package/dist/replace-file.d.ts +1 -0
  202. package/dist/replace-file.d.ts.map +1 -1
  203. package/dist/replace-file.js +14 -8
  204. package/dist/root-context.d.ts +3 -0
  205. package/dist/root-context.d.ts.map +1 -1
  206. package/dist/root-context.js +53 -28
  207. package/dist/root-create-input.d.ts +10 -0
  208. package/dist/root-create-input.d.ts.map +1 -0
  209. package/dist/root-create-input.js +80 -0
  210. package/dist/root-directory-list.d.ts +26 -0
  211. package/dist/root-directory-list.d.ts.map +1 -0
  212. package/dist/root-directory-list.js +219 -0
  213. package/dist/root-entries.d.ts +11 -0
  214. package/dist/root-entries.d.ts.map +1 -0
  215. package/dist/root-entries.js +61 -0
  216. package/dist/root-errors.d.ts +6 -5
  217. package/dist/root-errors.d.ts.map +1 -1
  218. package/dist/root-errors.js +16 -12
  219. package/dist/root-file.d.ts +2 -0
  220. package/dist/root-file.d.ts.map +1 -1
  221. package/dist/root-file.js +12 -4
  222. package/dist/root-impl.d.ts +17 -51
  223. package/dist/root-impl.d.ts.map +1 -1
  224. package/dist/root-impl.js +358 -234
  225. package/dist/root-options.d.ts +77 -0
  226. package/dist/root-options.d.ts.map +1 -0
  227. package/dist/root-options.js +18 -0
  228. package/dist/root-path-existing.d.ts +5 -0
  229. package/dist/root-path-existing.d.ts.map +1 -1
  230. package/dist/root-path-existing.js +59 -3
  231. package/dist/root-path-symlink.d.ts.map +1 -1
  232. package/dist/root-path-symlink.js +3 -2
  233. package/dist/root-path.d.ts +1 -0
  234. package/dist/root-path.d.ts.map +1 -1
  235. package/dist/root-path.js +74 -162
  236. package/dist/root-paths.d.ts.map +1 -1
  237. package/dist/root-paths.js +13 -9
  238. package/dist/root-remove.d.ts +5 -0
  239. package/dist/root-remove.d.ts.map +1 -0
  240. package/dist/root-remove.js +286 -0
  241. package/dist/root-symlink-policy.d.ts +14 -0
  242. package/dist/root-symlink-policy.d.ts.map +1 -0
  243. package/dist/root-symlink-policy.js +34 -0
  244. package/dist/root-walk.d.ts +5 -4
  245. package/dist/root-walk.d.ts.map +1 -1
  246. package/dist/root-walk.js +99 -50
  247. package/dist/root-write-mode.d.ts.map +1 -1
  248. package/dist/root-write-mode.js +3 -5
  249. package/dist/root.d.ts +4 -1
  250. package/dist/root.d.ts.map +1 -1
  251. package/dist/secret-file.d.ts.map +1 -1
  252. package/dist/secret-file.js +2 -1
  253. package/dist/secret-read-async.d.ts.map +1 -1
  254. package/dist/secret-read-async.js +2 -1
  255. package/dist/secure-file.d.ts.map +1 -1
  256. package/dist/secure-file.js +25 -8
  257. package/dist/secure-temp-dir.d.ts.map +1 -1
  258. package/dist/secure-temp-dir.js +2 -1
  259. package/dist/sibling-staged-file.d.ts +1 -0
  260. package/dist/sibling-staged-file.d.ts.map +1 -1
  261. package/dist/sibling-staged-file.js +42 -8
  262. package/dist/sibling-temp.d.ts +2 -0
  263. package/dist/sibling-temp.d.ts.map +1 -1
  264. package/dist/sibling-temp.js +6 -4
  265. package/dist/sidecar-lock-acquire.d.ts.map +1 -1
  266. package/dist/sidecar-lock-acquire.js +17 -5
  267. package/dist/sidecar-lock-policy.d.ts +2 -0
  268. package/dist/sidecar-lock-policy.d.ts.map +1 -1
  269. package/dist/sidecar-lock-policy.js +20 -1
  270. package/dist/staged-directory.d.ts.map +1 -1
  271. package/dist/staged-directory.js +4 -3
  272. package/dist/temp-cleanup.d.ts.map +1 -1
  273. package/dist/temp-cleanup.js +3 -2
  274. package/dist/temp-target.d.ts +14 -12
  275. package/dist/temp-target.d.ts.map +1 -1
  276. package/dist/temp-target.js +12 -6
  277. package/dist/timing.d.ts +1 -0
  278. package/dist/timing.d.ts.map +1 -1
  279. package/dist/timing.js +25 -6
  280. package/dist/trash.d.ts.map +1 -1
  281. package/dist/trash.js +9 -7
  282. package/dist/unicode-path.d.ts +3 -0
  283. package/dist/unicode-path.d.ts.map +1 -0
  284. package/dist/unicode-path.js +13 -0
  285. package/dist/walk.d.ts.map +1 -1
  286. package/dist/walk.js +9 -28
  287. package/dist/windows-owner.d.ts +9 -12
  288. package/dist/windows-owner.d.ts.map +1 -1
  289. package/dist/windows-owner.js +24 -58
  290. package/dist/write-file-handle.d.ts +7 -0
  291. package/dist/write-file-handle.d.ts.map +1 -0
  292. package/dist/write-file-handle.js +26 -0
  293. package/docs/advanced.md +22 -4
  294. package/docs/archive.md +44 -9
  295. package/docs/atomic.md +24 -1
  296. package/docs/config.md +1 -0
  297. package/docs/contributing.md +36 -1
  298. package/docs/copy.md +155 -0
  299. package/docs/directory-identity.md +85 -0
  300. package/docs/durability.md +53 -3
  301. package/docs/entries.md +109 -0
  302. package/docs/errors.md +4 -4
  303. package/docs/file-store.md +15 -0
  304. package/docs/guest.md +141 -0
  305. package/docs/in-place-write.md +81 -0
  306. package/docs/index.md +2 -0
  307. package/docs/install.md +31 -0
  308. package/docs/local-roots.md +8 -1
  309. package/docs/native-helper.md +10 -3
  310. package/docs/native.md +18 -1
  311. package/docs/output.md +32 -6
  312. package/docs/path-case.md +64 -0
  313. package/docs/path-scope.md +1 -1
  314. package/docs/permissions.md +29 -10
  315. package/docs/positional-read.md +63 -0
  316. package/docs/public-api.md +31 -2
  317. package/docs/root.md +196 -6
  318. package/docs/secure-file.md +2 -0
  319. package/docs/security-model.md +14 -0
  320. package/docs/sidecar-lock.md +12 -3
  321. package/docs/temp.md +35 -6
  322. package/docs/timing.md +2 -0
  323. package/docs/types.md +19 -12
  324. package/docs/walk.md +54 -5
  325. package/docs/writing.md +173 -5
  326. package/package.json +19 -8
@@ -0,0 +1,77 @@
1
+ import type { DenyMutationPolicy } from "./deny-mutations.js";
2
+ import type { RenameIdentityPolicy } from "./pinned-write.js";
3
+ import type { MutationSymlinkPolicy, SymlinkPolicy } from "./root-symlink-policy.js";
4
+ import type { CopyCloneMode } from "./copy-policy.js";
5
+ import type { RootCopyPublicationReceipt } from "./copy-publication.js";
6
+ import type { Root } from "./root-impl.js";
7
+ export declare const DEFAULT_ROOT_MAX_BYTES: number;
8
+ export type RootOptions = {
9
+ rootDir: string;
10
+ defaults?: RootDefaults;
11
+ };
12
+ export type HardlinkPolicy = "reject" | "allow";
13
+ export type WritableOpenMode = "replace" | "append" | "update";
14
+ export type RootDefaults = {
15
+ assertBeforeMutation?: () => void;
16
+ durable?: boolean;
17
+ hardlinks?: HardlinkPolicy;
18
+ maxBytes?: number;
19
+ mkdir?: boolean;
20
+ mode?: number;
21
+ denyMutations?: DenyMutationPolicy;
22
+ nonBlockingRead?: boolean;
23
+ renameIdentity?: RenameIdentityPolicy;
24
+ symlinks?: SymlinkPolicy;
25
+ mutationSymlinks?: MutationSymlinkPolicy;
26
+ };
27
+ export type RootReadOptions = Pick<RootDefaults, "hardlinks" | "maxBytes" | "nonBlockingRead" | "symlinks">;
28
+ export type RootOpenOptions = Omit<RootReadOptions, "maxBytes">;
29
+ export type RootWriteOptions = Pick<RootDefaults, "assertBeforeMutation" | "denyMutations" | "mutationSymlinks" | "durable" | "mkdir" | "mode" | "renameIdentity"> & {
30
+ encoding?: BufferEncoding;
31
+ overwrite?: boolean;
32
+ };
33
+ export type RootOpenWritableOptions = Pick<RootDefaults, "assertBeforeMutation" | "denyMutations" | "mutationSymlinks" | "mkdir" | "mode"> & {
34
+ writeMode?: WritableOpenMode;
35
+ };
36
+ export type RootCopyOptions = Pick<RootDefaults, "assertBeforeMutation" | "denyMutations" | "mutationSymlinks" | "durable" | "maxBytes" | "mkdir" | "mode"> & {
37
+ sourceHardlinks?: HardlinkPolicy;
38
+ overwrite?: boolean;
39
+ clone?: CopyCloneMode;
40
+ signal?: AbortSignal;
41
+ preserveSourceMode?: boolean;
42
+ onDestinationPublished?: (receipt: RootCopyPublicationReceipt) => void;
43
+ };
44
+ export type RootCopySource = string | {
45
+ root: Pick<Root, "open" | "stat">;
46
+ relativePath: string;
47
+ };
48
+ export type RootWriteJsonOptions = RootWriteOptions & {
49
+ replacer?: Parameters<typeof JSON.stringify>[1];
50
+ space?: Parameters<typeof JSON.stringify>[2];
51
+ trailingNewline?: boolean;
52
+ };
53
+ export type RootCreateOptions = Omit<RootWriteOptions, "overwrite">;
54
+ export type RootCreateStreamOptions = Omit<RootCreateOptions, "encoding" | "renameIdentity"> & {
55
+ maxBytes?: number;
56
+ signal?: AbortSignal;
57
+ };
58
+ export type RootCreateJsonOptions = Omit<RootWriteJsonOptions, "overwrite">;
59
+ export type RootAppendOptions = RootWriteOptions & {
60
+ prependNewlineIfNeeded?: boolean;
61
+ };
62
+ export type RootMoveOptions = Pick<RootDefaults, "assertBeforeMutation" | "denyMutations" | "mutationSymlinks"> & {
63
+ overwrite?: boolean;
64
+ };
65
+ export type RootRemoveOptions = Pick<RootDefaults, "assertBeforeMutation" | "denyMutations" | "mutationSymlinks"> & {
66
+ recursive?: boolean;
67
+ force?: boolean;
68
+ order?: "filesystem" | "sorted";
69
+ maxEntries?: number;
70
+ maxDepth?: number;
71
+ signal?: AbortSignal;
72
+ };
73
+ export type RootMkdirOptions = Pick<RootDefaults, "assertBeforeMutation" | "denyMutations" | "mutationSymlinks">;
74
+ export type RootReadParams = Omit<RootReadOptions, "nonBlockingRead">;
75
+ export declare function readDefaults(defaults: RootDefaults): RootReadParams;
76
+ export declare function mergeReadOptions(defaults: RootDefaults, options: RootReadOptions): RootReadParams;
77
+ //# sourceMappingURL=root-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root-options.d.ts","sourceRoot":"","sources":["../src/root-options.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { normalizeMaxBytes } from "./byte-budget.js";
2
+ export const DEFAULT_ROOT_MAX_BYTES = 16 * 1024 * 1024;
3
+ export function readDefaults(defaults) {
4
+ return {
5
+ hardlinks: defaults.hardlinks,
6
+ maxBytes: normalizeMaxBytes(defaults.maxBytes, { defaultValue: DEFAULT_ROOT_MAX_BYTES }),
7
+ symlinks: defaults.symlinks,
8
+ };
9
+ }
10
+ export function mergeReadOptions(defaults, options) {
11
+ const merged = readDefaults(defaults);
12
+ if (options.hardlinks !== undefined)
13
+ merged.hardlinks = options.hardlinks;
14
+ merged.maxBytes = normalizeMaxBytes(options.maxBytes, { defaultValue: merged.maxBytes });
15
+ if (options.symlinks !== undefined)
16
+ merged.symlinks = options.symlinks;
17
+ return merged;
18
+ }
@@ -1,3 +1,8 @@
1
+ export declare function absolutePathWithRawSegments(candidate: string): string;
2
+ export declare function rawPathRelativeToCanonicalRoot(candidate: string, rootCanonicalPath: string, options?: {
3
+ rejectSymlinks?: boolean;
4
+ rejectFinalSymlink?: boolean;
5
+ }): string | undefined;
1
6
  export declare function resolvePathViaExistingAncestor(targetPath: string): Promise<string>;
2
7
  export declare function resolvePathViaExistingAncestorSync(targetPath: string): string;
3
8
  //# sourceMappingURL=root-path-existing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"root-path-existing.d.ts","sourceRoot":"","sources":["../src/root-path-existing.ts"],"names":[],"mappings":"AAoBA,wBAAsB,8BAA8B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BxF;AAED,wBAAgB,kCAAkC,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA0B7E"}
1
+ {"version":3,"file":"root-path-existing.d.ts","sourceRoot":"","sources":["../src/root-path-existing.ts"],"names":[],"mappings":"AAOA,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAO,GACvE,MAAM,GAAG,SAAS,CAuCpB;AAkBD,wBAAsB,8BAA8B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BxF;AAED,wBAAgB,kCAAkC,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA0B7E"}
@@ -1,6 +1,62 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { isNotFoundPathError } from "./path.js";
3
+ import { FsSafeError } from "./errors.js";
4
+ import { formatErrorDetail } from "./error-detail.js";
5
+ import { isNotFoundPathError, isPathInside } from "./path.js";
6
+ import { realpathSync } from "./realpath.js";
7
+ export function absolutePathWithRawSegments(candidate) {
8
+ if (path.isAbsolute(candidate))
9
+ return candidate;
10
+ const drive = path.parse(candidate).root;
11
+ const base = drive ? path.resolve(drive) : process.cwd();
12
+ return `${base}${path.sep}${candidate.slice(drive.length)}`;
13
+ }
14
+ export function rawPathRelativeToCanonicalRoot(candidate, rootCanonicalPath, options = {}) {
15
+ const absolute = absolutePathWithRawSegments(candidate);
16
+ const raw = process.platform === "win32" ? absolute.replaceAll("/", path.sep) : absolute;
17
+ const filesystemRoot = path.parse(raw).root;
18
+ const segments = raw.slice(filesystemRoot.length).split(path.sep);
19
+ const finalComponentIndex = segments.findLastIndex(segment => segment !== "" && segment !== ".");
20
+ let prefix = filesystemRoot;
21
+ let traversedSymlink = false;
22
+ for (let index = 0; index < segments.length; index += 1) {
23
+ prefix += `${prefix.endsWith(path.sep) ? "" : path.sep}${segments[index]}`;
24
+ let canonical;
25
+ let isSymlink = false;
26
+ try {
27
+ const stat = fs.lstatSync(prefix);
28
+ isSymlink = stat.isSymbolicLink();
29
+ // Check the original leaf before canonicalization can erase an entry alias.
30
+ if (isSymlink && options.rejectFinalSymlink && index === finalComponentIndex) {
31
+ throw new FsSafeError("symlink", "final symlink not allowed");
32
+ }
33
+ if (!isSymlink && !stat.isDirectory() && index < segments.length - 1)
34
+ return undefined;
35
+ traversedSymlink ||= isSymlink;
36
+ canonical = realpathSync.native(prefix);
37
+ if (isSymlink && index < segments.length - 1 && !fs.statSync(canonical).isDirectory())
38
+ return undefined;
39
+ if (isSymlink && !isPathInside(rootCanonicalPath, canonical) && !isPathInside(canonical, rootCanonicalPath)) {
40
+ throw new FsSafeError("outside-workspace", `symlink prefix resolves outside the root ancestry: ${formatErrorDetail(candidate)}`);
41
+ }
42
+ }
43
+ catch (error) {
44
+ if (error instanceof FsSafeError)
45
+ throw error;
46
+ if (isSymlink)
47
+ return undefined;
48
+ continue;
49
+ }
50
+ if (!isPathInside(rootCanonicalPath, canonical))
51
+ continue;
52
+ if (options.rejectSymlinks && traversedSymlink) {
53
+ throw new FsSafeError("symlink", "symlink path component not allowed");
54
+ }
55
+ return [path.relative(rootCanonicalPath, canonical), ...segments.slice(index + 1)]
56
+ .filter(Boolean).join(path.sep);
57
+ }
58
+ return undefined;
59
+ }
4
60
  function isFilesystemRoot(candidate) {
5
61
  return path.parse(candidate).root === candidate;
6
62
  }
@@ -32,7 +88,7 @@ export async function resolvePathViaExistingAncestor(targetPath) {
32
88
  return normalized;
33
89
  }
34
90
  try {
35
- const resolvedAncestor = path.resolve(fs.realpathSync.native(cursor));
91
+ const resolvedAncestor = path.resolve(realpathSync.native(cursor));
36
92
  return missingSuffix.length === 0
37
93
  ? resolvedAncestor
38
94
  : path.resolve(resolvedAncestor, ...missingSuffix);
@@ -57,7 +113,7 @@ export function resolvePathViaExistingAncestorSync(targetPath) {
57
113
  return normalized;
58
114
  }
59
115
  try {
60
- const resolvedAncestor = path.resolve(fs.realpathSync(cursor));
116
+ const resolvedAncestor = path.resolve(realpathSync(cursor));
61
117
  return missingSuffix.length === 0
62
118
  ? resolvedAncestor
63
119
  : path.resolve(resolvedAncestor, ...missingSuffix);
@@ -1 +1 @@
1
- {"version":3,"file":"root-path-symlink.d.ts","sourceRoot":"","sources":["../src/root-path-symlink.ts"],"names":[],"mappings":"AASA,KAAK,wBAAwB,GAAG;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAiBF,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,wBAA6B,GACrC,MAAM,CAQR"}
1
+ {"version":3,"file":"root-path-symlink.d.ts","sourceRoot":"","sources":["../src/root-path-symlink.ts"],"names":[],"mappings":"AAUA,KAAK,wBAAwB,GAAG;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAiBF,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,wBAA6B,GACrC,MAAM,CAQR"}
@@ -2,6 +2,7 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { FsSafeError } from "./errors.js";
4
4
  import { isNotFoundPathError, isSymlinkOpenError } from "./path.js";
5
+ import { realpathSync } from "./realpath.js";
5
6
  import { resolvePathViaExistingAncestor, resolvePathViaExistingAncestorSync, } from "./root-path-existing.js";
6
7
  function normalizeSymlinkResolutionError(error, options) {
7
8
  if (isSymlinkOpenError(error) ||
@@ -15,7 +16,7 @@ function normalizeSymlinkResolutionError(error, options) {
15
16
  }
16
17
  export async function resolveSymlinkHopPath(symlinkPath, options = {}) {
17
18
  try {
18
- return path.resolve(fs.realpathSync.native(symlinkPath));
19
+ return path.resolve(realpathSync.native(symlinkPath));
19
20
  }
20
21
  catch (error) {
21
22
  normalizeSymlinkResolutionError(error, options);
@@ -25,7 +26,7 @@ export async function resolveSymlinkHopPath(symlinkPath, options = {}) {
25
26
  }
26
27
  export function resolveSymlinkHopPathSync(symlinkPath, options = {}) {
27
28
  try {
28
- return path.resolve(fs.realpathSync(symlinkPath));
29
+ return path.resolve(realpathSync(symlinkPath));
29
30
  }
30
31
  catch (error) {
31
32
  normalizeSymlinkResolutionError(error, options);
@@ -21,6 +21,7 @@ type ResolveRootPathParams = {
21
21
  intent?: RootPathIntent;
22
22
  policy?: RootPathAliasPolicy;
23
23
  rejectSymlinks?: boolean;
24
+ rejectFinalSymlink?: boolean;
24
25
  rejectUnresolvedSymlinks?: boolean;
25
26
  skipLexicalRootCheck?: boolean;
26
27
  rootCanonicalPath?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"root-path.d.ts","sourceRoot":"","sources":["../src/root-path.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,kCAAkC,EAAE,MAAM,yBAAyB,CAAC;AAE7E,KAAK,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEtE,MAAM,MAAM,mBAAmB,GAAG;IAChC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC,CAAC;AAEF,eAAO,MAAM,wBAAwB;aACnC,MAAM;;;;aAIN,YAAY;;;;CAIJ,CAAC;AAEX,KAAK,qBAAqB,GAAG;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,KAAK,oBAAoB,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;AAEnF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,oBAAoB,CAAC;CAC5B,CAAC;AAEF,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CAM3B;AAsCD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,qBAAqB,GAAG,gBAAgB,CAMnF"}
1
+ {"version":3,"file":"root-path.d.ts","sourceRoot":"","sources":["../src/root-path.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,kCAAkC,EAAE,MAAM,yBAAyB,CAAC;AAE7E,KAAK,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEtE,MAAM,MAAM,mBAAmB,GAAG;IAChC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC,CAAC;AAEF,eAAO,MAAM,wBAAwB;aACnC,MAAM;;;;aAIN,YAAY;;;;CAIJ,CAAC;AAEX,KAAK,qBAAqB,GAAG;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,KAAK,oBAAoB,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;AAEnF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,oBAAoB,CAAC;CAC5B,CAAC;AAEF,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CAM3B;AAeD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,qBAAqB,GAAG,gBAAgB,CAMnF"}
package/dist/root-path.js CHANGED
@@ -3,7 +3,7 @@ import path from "node:path";
3
3
  import { formatErrorDetail, shortPath } from "./error-detail.js";
4
4
  import { FsSafeError } from "./errors.js";
5
5
  import { assertNoNulPathInput, isNotFoundPathError, isPathInside, isPathRelativeEscape, } from "./path.js";
6
- import { resolvePathViaExistingAncestor, resolvePathViaExistingAncestorSync, } from "./root-path-existing.js";
6
+ import { absolutePathWithRawSegments, rawPathRelativeToCanonicalRoot, resolvePathViaExistingAncestor, resolvePathViaExistingAncestorSync, } from "./root-path-existing.js";
7
7
  import { resolveSymlinkHopPath, resolveSymlinkHopPathSync } from "./root-path-symlink.js";
8
8
  import { assertNoDriveRelativePathSegments } from "./safe-path-segment.js";
9
9
  export { resolvePathViaExistingAncestorSync } from "./root-path-existing.js";
@@ -27,34 +27,13 @@ export async function resolveRootPath(params) {
27
27
  }
28
28
  async function resolveRootPathInternal(params) {
29
29
  assertValidRootPathInputs(params);
30
+ params = { ...params, absolutePath: absolutePathWithRawSegments(params.absolutePath) };
30
31
  const rootPath = path.resolve(params.rootPath);
31
32
  const absolutePath = path.resolve(params.absolutePath);
32
33
  const rootCanonicalPath = params.rootCanonicalPath
33
34
  ? path.resolve(params.rootCanonicalPath)
34
35
  : await resolvePathViaExistingAncestor(rootPath);
35
- const context = createBoundaryResolutionContext({
36
- resolveParams: params,
37
- rootPath,
38
- absolutePath,
39
- rootCanonicalPath,
40
- outsideLexicalCanonicalPath: await resolveOutsideLexicalCanonicalPathAsync({
41
- rootPath,
42
- absolutePath,
43
- }),
44
- });
45
- const outsideResult = await resolveOutsideRootPathAsync({
46
- boundaryLabel: params.boundaryLabel,
47
- context,
48
- });
49
- if (outsideResult) {
50
- return outsideResult;
51
- }
52
- return resolveRootPathLexicalAsync({
53
- params,
54
- absolutePath: context.absolutePath,
55
- rootPath: context.rootPath,
56
- rootCanonicalPath: context.rootCanonicalPath,
57
- });
36
+ return resolveRootPathLexicalAsync(prepareRootTraversal(params, rootPath, rootCanonicalPath, absolutePath));
58
37
  }
59
38
  export function resolveRootPathSync(params) {
60
39
  try {
@@ -66,34 +45,28 @@ export function resolveRootPathSync(params) {
66
45
  }
67
46
  function resolveRootPathSyncInternal(params) {
68
47
  assertValidRootPathInputs(params);
48
+ params = { ...params, absolutePath: absolutePathWithRawSegments(params.absolutePath) };
69
49
  const rootPath = path.resolve(params.rootPath);
70
50
  const absolutePath = path.resolve(params.absolutePath);
71
51
  const rootCanonicalPath = params.rootCanonicalPath
72
52
  ? path.resolve(params.rootCanonicalPath)
73
53
  : resolvePathViaExistingAncestorSync(rootPath);
74
- const context = createBoundaryResolutionContext({
75
- resolveParams: params,
76
- rootPath,
77
- absolutePath,
78
- rootCanonicalPath,
79
- outsideLexicalCanonicalPath: resolveOutsideLexicalCanonicalPathSync({
80
- rootPath,
81
- absolutePath,
82
- }),
83
- });
84
- const outsideResult = resolveOutsideRootPathSync({
85
- boundaryLabel: params.boundaryLabel,
86
- context,
87
- });
88
- if (outsideResult) {
89
- return outsideResult;
54
+ return resolveRootPathLexicalSync(prepareRootTraversal(params, rootPath, rootCanonicalPath, absolutePath));
55
+ }
56
+ function prepareRootTraversal(params, rootPath, rootCanonicalPath, absolutePath) {
57
+ let raw = params.absolutePath;
58
+ if (rawPathRelativeToRoot(rootPath, raw) === undefined) {
59
+ const relative = rawPathRelativeToRoot(rootCanonicalPath, raw)
60
+ ?? rawPathRelativeToCanonicalRoot(raw, rootCanonicalPath, params);
61
+ if (relative === undefined) {
62
+ throw pathEscapeError({ rootPath, absolutePath: raw, boundaryLabel: params.boundaryLabel });
63
+ }
64
+ raw = `${rootPath}${path.sep}${relative}`;
90
65
  }
91
- return resolveRootPathLexicalSync({
92
- params,
93
- absolutePath: context.absolutePath,
94
- rootPath: context.rootPath,
95
- rootCanonicalPath: context.rootCanonicalPath,
96
- });
66
+ return {
67
+ params: raw === params.absolutePath ? params : { ...params, absolutePath: raw },
68
+ rootPath, rootCanonicalPath, absolutePath,
69
+ };
97
70
  }
98
71
  function sanitizeRootPathError(error) {
99
72
  if (error instanceof Error) {
@@ -120,14 +93,18 @@ function assertNoEmbeddedDriveRelativeSegment(filePath, label) {
120
93
  }
121
94
  function createLexicalTraversalState(params) {
122
95
  const rawAbsolutePath = params.params.absolutePath;
123
- const rawRelativePath = rawPathRelativeToRoot(params.rootPath, rawAbsolutePath);
124
- const relative = rawRelativePath ?? path.relative(params.rootPath, params.absolutePath);
96
+ const relative = rawPathRelativeToRoot(params.rootPath, rawAbsolutePath);
97
+ if (relative === undefined)
98
+ throw new Error("Path traversal must begin at the root");
99
+ const segments = splitTraversalSegments(relative);
125
100
  return {
126
- segments: splitTraversalSegments(relative),
101
+ segments,
102
+ finalComponentIndex: segments.findLastIndex((segment) => segment !== "."),
127
103
  allowFinalSymlink: params.params.policy?.allowFinalSymlinkForUnlink === true,
128
104
  canonicalCursor: params.rootCanonicalPath,
129
105
  lexicalCursor: params.rootPath,
130
106
  preserveFinalSymlink: false,
107
+ missingDepth: 0,
131
108
  };
132
109
  }
133
110
  function createLexicalTraversalContext(params) {
@@ -140,9 +117,12 @@ function createLexicalTraversalContext(params) {
140
117
  };
141
118
  }
142
119
  function splitTraversalSegments(value) {
143
- return value
120
+ const segments = value
144
121
  .split(process.platform === "win32" ? /[\\/]+/ : /\/+/)
145
- .filter((segment) => Boolean(segment) && segment !== ".");
122
+ .filter(Boolean);
123
+ if (value.endsWith("/") || (process.platform === "win32" && value.endsWith("\\")))
124
+ segments.push(".");
125
+ return segments;
146
126
  }
147
127
  function rawPathRelativeToRoot(rootPath, candidatePath) {
148
128
  if (!path.isAbsolute(candidatePath)) {
@@ -170,12 +150,6 @@ function assertLexicalCursorInsideBoundary(context, candidatePath) {
170
150
  absolutePath: context.absolutePath,
171
151
  });
172
152
  }
173
- function applyMissingSuffixToCanonicalCursor(context, missingFromIndex) {
174
- const missingSuffix = context.state.segments.slice(missingFromIndex);
175
- for (const segment of missingSuffix) {
176
- advanceCanonicalCursorForSegment(context, segment);
177
- }
178
- }
179
153
  function advanceCanonicalCursorForSegment(context, segment) {
180
154
  context.state.canonicalCursor = path.resolve(context.state.canonicalCursor, segment);
181
155
  assertLexicalCursorInsideBoundary(context, context.state.canonicalCursor);
@@ -190,17 +164,18 @@ function finalizeLexicalResolution(context, kind) {
190
164
  kind,
191
165
  });
192
166
  }
193
- function handleLexicalLstatFailure(context, error, missingFromIndex) {
167
+ function handleLexicalLstatFailure(context, error, segment) {
194
168
  if (!isNotFoundPathError(error)) {
195
169
  return false;
196
170
  }
197
- applyMissingSuffixToCanonicalCursor(context, missingFromIndex);
171
+ advanceCanonicalCursorForSegment(context, segment);
172
+ context.state.missingDepth = 1;
198
173
  return true;
199
174
  }
200
175
  function lexicalStatDisposition(params) {
201
176
  if (!params.isSymbolicLink)
202
177
  return "continue";
203
- if (params.rejectSymlinks === true && params.isLast) {
178
+ if (params.rejectFinalSymlink || (params.rejectSymlinks === true && params.isLast)) {
204
179
  throw new FsSafeError("symlink", "symlink path component not allowed");
205
180
  }
206
181
  return params.allowFinalSymlink && params.isLast ? "break" : "resolve-link";
@@ -219,6 +194,19 @@ function applyResolvedSymlinkHop(context, linkCanonical) {
219
194
  function applyParentTraversalStep(context) {
220
195
  context.state.lexicalCursor = path.resolve(context.state.lexicalCursor, "..");
221
196
  advanceCanonicalCursorForSegment(context, "..");
197
+ if (context.state.missingDepth > 0)
198
+ context.state.missingDepth -= 1;
199
+ }
200
+ function assertDirectoryBeforeMoreSegments(stat, pathname, isLast) {
201
+ if (!isLast && !stat.isDirectory()) {
202
+ throw Object.assign(new Error(`Path component is not a directory: ${pathname}`), { code: "ENOTDIR" });
203
+ }
204
+ }
205
+ function assertResolvedLinkDirectory(pathname, isLast) {
206
+ if (isLast)
207
+ return;
208
+ const stat = fs.statSync(pathname);
209
+ assertDirectoryBeforeMoreSegments(stat, pathname, isLast);
222
210
  }
223
211
  async function resolveRootPathLexicalAsync(params) {
224
212
  const context = createLexicalTraversalContext(params);
@@ -226,25 +214,35 @@ async function resolveRootPathLexicalAsync(params) {
226
214
  for (let idx = 0; idx < state.segments.length; idx += 1) {
227
215
  const segment = state.segments[idx] ?? "";
228
216
  const isLast = idx === state.segments.length - 1;
217
+ if (segment === ".")
218
+ continue;
229
219
  if (segment === "..") {
230
220
  applyParentTraversalStep(context);
231
221
  continue;
232
222
  }
233
223
  state.lexicalCursor = path.join(state.lexicalCursor, segment);
224
+ if (state.missingDepth > 0) {
225
+ advanceCanonicalCursorForSegment(context, segment);
226
+ state.missingDepth += 1;
227
+ continue;
228
+ }
234
229
  let stat;
235
230
  try {
236
231
  stat = fs.lstatSync(state.lexicalCursor);
237
232
  }
238
233
  catch (error) {
239
- if (handleLexicalLstatFailure(context, error, idx))
240
- break;
234
+ if (handleLexicalLstatFailure(context, error, segment))
235
+ continue;
241
236
  throw error;
242
237
  }
243
238
  const isSymbolicLink = stat.isSymbolicLink();
239
+ if (!isSymbolicLink)
240
+ assertDirectoryBeforeMoreSegments(stat, state.lexicalCursor, isLast);
244
241
  const disposition = lexicalStatDisposition({
245
242
  isSymbolicLink,
246
243
  isLast,
247
244
  rejectSymlinks: isSymbolicLink ? context.resolveParams.rejectSymlinks : undefined,
245
+ rejectFinalSymlink: context.resolveParams.rejectFinalSymlink === true && idx === state.finalComponentIndex,
248
246
  allowFinalSymlink: state.allowFinalSymlink,
249
247
  });
250
248
  if (disposition !== "resolve-link") {
@@ -261,6 +259,7 @@ async function resolveRootPathLexicalAsync(params) {
261
259
  if (context.resolveParams.rejectSymlinks === true) {
262
260
  throw new FsSafeError("symlink", "symlink path component not allowed");
263
261
  }
262
+ assertResolvedLinkDirectory(linkCanonical, isLast);
264
263
  }
265
264
  const kind = await getPathKind(state.canonicalCursor, state.preserveFinalSymlink);
266
265
  return finalizeLexicalResolution(context, kind);
@@ -271,25 +270,35 @@ function resolveRootPathLexicalSync(params) {
271
270
  for (let idx = 0; idx < state.segments.length; idx += 1) {
272
271
  const segment = state.segments[idx] ?? "";
273
272
  const isLast = idx === state.segments.length - 1;
273
+ if (segment === ".")
274
+ continue;
274
275
  if (segment === "..") {
275
276
  applyParentTraversalStep(context);
276
277
  continue;
277
278
  }
278
279
  state.lexicalCursor = path.join(state.lexicalCursor, segment);
280
+ if (state.missingDepth > 0) {
281
+ advanceCanonicalCursorForSegment(context, segment);
282
+ state.missingDepth += 1;
283
+ continue;
284
+ }
279
285
  let stat;
280
286
  try {
281
287
  stat = fs.lstatSync(state.lexicalCursor);
282
288
  }
283
289
  catch (error) {
284
- if (handleLexicalLstatFailure(context, error, idx))
285
- break;
290
+ if (handleLexicalLstatFailure(context, error, segment))
291
+ continue;
286
292
  throw error;
287
293
  }
288
294
  const isSymbolicLink = stat.isSymbolicLink();
295
+ if (!isSymbolicLink)
296
+ assertDirectoryBeforeMoreSegments(stat, state.lexicalCursor, isLast);
289
297
  const disposition = lexicalStatDisposition({
290
298
  isSymbolicLink,
291
299
  isLast,
292
300
  rejectSymlinks: isSymbolicLink ? context.resolveParams.rejectSymlinks : undefined,
301
+ rejectFinalSymlink: context.resolveParams.rejectFinalSymlink === true && idx === state.finalComponentIndex,
293
302
  allowFinalSymlink: state.allowFinalSymlink,
294
303
  });
295
304
  if (disposition !== "resolve-link") {
@@ -306,108 +315,11 @@ function resolveRootPathLexicalSync(params) {
306
315
  if (context.resolveParams.rejectSymlinks === true) {
307
316
  throw new FsSafeError("symlink", "symlink path component not allowed");
308
317
  }
318
+ assertResolvedLinkDirectory(linkCanonical, isLast);
309
319
  }
310
320
  const kind = getPathKindSync(state.canonicalCursor, state.preserveFinalSymlink);
311
321
  return finalizeLexicalResolution(context, kind);
312
322
  }
313
- function resolveCanonicalOutsideLexicalPath(params) {
314
- return params.outsideLexicalCanonicalPath ?? params.absolutePath;
315
- }
316
- function createBoundaryResolutionContext(params) {
317
- const lexicalInside = isPathInside(params.rootPath, params.absolutePath);
318
- const canonicalOutsideLexicalPath = resolveCanonicalOutsideLexicalPath({
319
- absolutePath: params.absolutePath,
320
- outsideLexicalCanonicalPath: params.outsideLexicalCanonicalPath,
321
- });
322
- assertLexicalBoundaryOrCanonicalAlias({
323
- skipLexicalRootCheck: params.resolveParams.skipLexicalRootCheck,
324
- lexicalInside,
325
- canonicalOutsideLexicalPath,
326
- rootCanonicalPath: params.rootCanonicalPath,
327
- boundaryLabel: params.resolveParams.boundaryLabel,
328
- rootPath: params.rootPath,
329
- absolutePath: params.absolutePath,
330
- });
331
- return {
332
- rootPath: params.rootPath,
333
- absolutePath: params.absolutePath,
334
- rootCanonicalPath: params.rootCanonicalPath,
335
- lexicalInside,
336
- canonicalOutsideLexicalPath,
337
- };
338
- }
339
- async function resolveOutsideRootPathAsync(params) {
340
- if (params.context.lexicalInside) {
341
- return null;
342
- }
343
- const kind = await getPathKind(params.context.absolutePath, false);
344
- return buildOutsideRootPathFromContext({
345
- boundaryLabel: params.boundaryLabel,
346
- context: params.context,
347
- kind,
348
- });
349
- }
350
- function resolveOutsideRootPathSync(params) {
351
- if (params.context.lexicalInside) {
352
- return null;
353
- }
354
- const kind = getPathKindSync(params.context.absolutePath, false);
355
- return buildOutsideRootPathFromContext({
356
- boundaryLabel: params.boundaryLabel,
357
- context: params.context,
358
- kind,
359
- });
360
- }
361
- function buildOutsideRootPathFromContext(params) {
362
- return buildOutsideLexicalRootPath({
363
- boundaryLabel: params.boundaryLabel,
364
- rootCanonicalPath: params.context.rootCanonicalPath,
365
- absolutePath: params.context.absolutePath,
366
- canonicalOutsideLexicalPath: params.context.canonicalOutsideLexicalPath,
367
- rootPath: params.context.rootPath,
368
- kind: params.kind,
369
- });
370
- }
371
- async function resolveOutsideLexicalCanonicalPathAsync(params) {
372
- if (isPathInside(params.rootPath, params.absolutePath)) {
373
- return undefined;
374
- }
375
- return await resolvePathViaExistingAncestor(params.absolutePath);
376
- }
377
- function resolveOutsideLexicalCanonicalPathSync(params) {
378
- if (isPathInside(params.rootPath, params.absolutePath)) {
379
- return undefined;
380
- }
381
- return resolvePathViaExistingAncestorSync(params.absolutePath);
382
- }
383
- function buildOutsideLexicalRootPath(params) {
384
- assertInsideBoundary({
385
- boundaryLabel: params.boundaryLabel,
386
- rootCanonicalPath: params.rootCanonicalPath,
387
- candidatePath: params.canonicalOutsideLexicalPath,
388
- absolutePath: params.absolutePath,
389
- });
390
- return buildResolvedRootPath({
391
- absolutePath: params.absolutePath,
392
- canonicalPath: params.canonicalOutsideLexicalPath,
393
- rootPath: params.rootPath,
394
- rootCanonicalPath: params.rootCanonicalPath,
395
- kind: params.kind,
396
- });
397
- }
398
- function assertLexicalBoundaryOrCanonicalAlias(params) {
399
- if (params.skipLexicalRootCheck || params.lexicalInside) {
400
- return;
401
- }
402
- if (isPathInside(params.rootCanonicalPath, params.canonicalOutsideLexicalPath)) {
403
- return;
404
- }
405
- throw pathEscapeError({
406
- boundaryLabel: params.boundaryLabel,
407
- rootPath: params.rootPath,
408
- absolutePath: params.absolutePath,
409
- });
410
- }
411
323
  function buildResolvedRootPath(params) {
412
324
  return {
413
325
  absolutePath: params.absolutePath,
@@ -1 +1 @@
1
- {"version":3,"file":"root-paths.d.ts","sourceRoot":"","sources":["../src/root-paths.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAW1C,KAAK,iBAAiB,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AACtD,KAAK,eAAe,GAChB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,WAAW,CAAA;CAAE,CAAC;AAC3D,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;AA4DF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAkB5D;AAED,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,CAiCrE;AAuDD,wBAAsB,yBAAyB,CAAC,MAAM,EAAE;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAAC,eAAe,CAAC,CA2E3B;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,4BAA4B,GACnC,4BAA4B,CAc9B;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,CAwC/E"}
1
+ {"version":3,"file":"root-paths.d.ts","sourceRoot":"","sources":["../src/root-paths.ts"],"names":[],"mappings":"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"}