@openclaw/openshell-sandbox 2026.9.4 → 2026.9.6
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.
- package/assets/activity.svg +3 -0
- package/assets/icon.png +0 -0
- package/dist/index.js +49 -75
- package/node_modules/@openclaw/fs-safe/CHANGELOG.md +487 -0
- package/node_modules/@openclaw/fs-safe/LICENSE +1 -0
- package/node_modules/@openclaw/fs-safe/README.md +106 -16
- package/node_modules/@openclaw/fs-safe/dist/absolute-path.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/absolute-path.js +30 -14
- package/node_modules/@openclaw/fs-safe/dist/advanced.d.ts +13 -3
- package/node_modules/@openclaw/fs-safe/dist/advanced.js +11 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-crc32.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-crc32.js +6 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-deadline.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-deadline.js +23 -25
- package/node_modules/@openclaw/fs-safe/dist/archive-durability.d.ts +23 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-durability.js +180 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-entry.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-entry.js +8 -8
- package/node_modules/@openclaw/fs-safe/dist/archive-errors.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-gzip-tail.d.ts +3 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-gzip-tail.js +33 -8
- package/node_modules/@openclaw/fs-safe/dist/archive-input.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-input.js +14 -8
- package/node_modules/@openclaw/fs-safe/dist/archive-kind.d.ts +0 -2
- package/node_modules/@openclaw/fs-safe/dist/archive-kind.js +8 -19
- package/node_modules/@openclaw/fs-safe/dist/archive-limits.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-merge.d.ts +8 -4
- package/node_modules/@openclaw/fs-safe/dist/archive-merge.js +185 -59
- package/node_modules/@openclaw/fs-safe/dist/archive-parser-errors.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-parser.wasm +0 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-plan.d.ts +72 -2
- package/node_modules/@openclaw/fs-safe/dist/archive-plan.js +86 -22
- package/node_modules/@openclaw/fs-safe/dist/archive-read.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-read.js +132 -114
- package/node_modules/@openclaw/fs-safe/dist/archive-staging.d.ts +6 -4
- package/node_modules/@openclaw/fs-safe/dist/archive-staging.js +100 -42
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-stream.d.ts +14 -5
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-stream.js +68 -36
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-wasm.d.ts +17 -6
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-wasm.js +129 -25
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-admission.d.ts +2 -3
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-admission.js +50 -14
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-count.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-count.js +21 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-directory.d.ts +7 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-directory.js +38 -3
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-entry.d.ts +6 -3
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-entry.js +24 -9
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-integrity.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-integrity.js +3 -4
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-loader.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-loader.js +147 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-manifest.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-manifest.js +22 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-names.d.ts +7 -2
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-names.js +67 -18
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-preflight.d.ts +2 -4
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-preflight.js +4 -35
- package/node_modules/@openclaw/fs-safe/dist/archive.d.ts +8 -6
- package/node_modules/@openclaw/fs-safe/dist/archive.js +225 -171
- package/node_modules/@openclaw/fs-safe/dist/async-lock.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/atomic.d.ts +3 -2
- package/node_modules/@openclaw/fs-safe/dist/bounded-read-stream.d.ts +0 -2
- package/node_modules/@openclaw/fs-safe/dist/bounded-read-stream.js +0 -6
- package/node_modules/@openclaw/fs-safe/dist/bounded-read.d.ts +12 -1
- package/node_modules/@openclaw/fs-safe/dist/bounded-read.js +83 -46
- package/node_modules/@openclaw/fs-safe/dist/byte-budget.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/byte-view.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/byte-view.js +13 -0
- package/node_modules/@openclaw/fs-safe/dist/clone-metadata.d.ts +19 -0
- package/node_modules/@openclaw/fs-safe/dist/clone-metadata.js +36 -0
- package/node_modules/@openclaw/fs-safe/dist/config.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/containment.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/copy-file-input.d.ts +21 -0
- package/node_modules/@openclaw/fs-safe/dist/copy-file-input.js +71 -0
- package/node_modules/@openclaw/fs-safe/dist/copy-policy.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/copy-policy.js +8 -0
- package/node_modules/@openclaw/fs-safe/dist/copy-publication.d.ts +20 -0
- package/node_modules/@openclaw/fs-safe/dist/copy-publication.js +33 -0
- package/node_modules/@openclaw/fs-safe/dist/copy-tree-portable.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/copy-tree-portable.js +245 -0
- package/node_modules/@openclaw/fs-safe/dist/copy.d.ts +15 -0
- package/node_modules/@openclaw/fs-safe/dist/copy.js +143 -0
- package/node_modules/@openclaw/fs-safe/dist/create-owned-file.d.ts +7 -0
- package/node_modules/@openclaw/fs-safe/dist/create-owned-file.js +16 -0
- package/node_modules/@openclaw/fs-safe/dist/create.d.ts +17 -0
- package/node_modules/@openclaw/fs-safe/dist/create.js +388 -0
- package/node_modules/@openclaw/fs-safe/dist/creation-boundary.d.ts +60 -0
- package/node_modules/@openclaw/fs-safe/dist/creation-boundary.js +371 -0
- package/node_modules/@openclaw/fs-safe/dist/deny-mutations.d.ts +2 -3
- package/node_modules/@openclaw/fs-safe/dist/deny-mutations.js +61 -35
- package/node_modules/@openclaw/fs-safe/dist/device-path.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/device-path.js +5 -3
- package/node_modules/@openclaw/fs-safe/dist/directory-durability.d.ts +7 -8
- package/node_modules/@openclaw/fs-safe/dist/directory-durability.js +48 -61
- package/node_modules/@openclaw/fs-safe/dist/directory-entry-path.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-entry-path.js +21 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-guard.d.ts +31 -7
- package/node_modules/@openclaw/fs-safe/dist/directory-guard.js +136 -39
- package/node_modules/@openclaw/fs-safe/dist/directory-mode-node.d.ts +14 -1
- package/node_modules/@openclaw/fs-safe/dist/directory-mode-node.js +125 -9
- package/node_modules/@openclaw/fs-safe/dist/directory-mode-owner.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/directory-mode-owner.js +5 -5
- package/node_modules/@openclaw/fs-safe/dist/directory-receipt.d.ts +23 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-receipt.js +123 -0
- package/node_modules/@openclaw/fs-safe/dist/durability.d.ts +3 -3
- package/node_modules/@openclaw/fs-safe/dist/durability.js +1 -1
- package/node_modules/@openclaw/fs-safe/dist/effective-uid.d.ts +1 -0
- package/node_modules/@openclaw/fs-safe/dist/effective-uid.js +25 -0
- package/node_modules/@openclaw/fs-safe/dist/error-detail.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/error-detail.js +4 -1
- package/node_modules/@openclaw/fs-safe/dist/errors.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-cleanup.d.ts +19 -0
- package/node_modules/@openclaw/fs-safe/dist/file-cleanup.js +81 -0
- package/node_modules/@openclaw/fs-safe/dist/file-contents.d.ts +5 -0
- package/node_modules/@openclaw/fs-safe/dist/file-contents.js +40 -0
- package/node_modules/@openclaw/fs-safe/dist/file-handle-transfer.d.ts +15 -0
- package/node_modules/@openclaw/fs-safe/dist/file-handle-transfer.js +190 -0
- package/node_modules/@openclaw/fs-safe/dist/file-hash.d.ts +9 -3
- package/node_modules/@openclaw/fs-safe/dist/file-hash.js +273 -50
- package/node_modules/@openclaw/fs-safe/dist/file-identity.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-identity.js +18 -4
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-acquisition.d.ts +22 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-acquisition.js +98 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-admission.d.ts +17 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-admission.js +54 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-acquire.d.ts +3 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-acquire.js +303 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-arbitration.d.ts +17 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-arbitration.js +66 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-held.d.ts +32 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-held.js +395 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-io.d.ts +43 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-io.js +209 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-mutation.d.ts +16 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-mutation.js +275 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-options.d.ts +19 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-options.js +58 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-registration.d.ts +1 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-registration.js +90 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root.d.ts +36 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root.js +288 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-stale-admission.d.ts +19 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-stale-admission.js +199 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync.d.ts +4 -22
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync.js +226 -234
- package/node_modules/@openclaw/fs-safe/dist/file-lock.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-lock.js +29 -9
- package/node_modules/@openclaw/fs-safe/dist/file-observation.d.ts +1 -2
- package/node_modules/@openclaw/fs-safe/dist/file-store-boundary.d.ts +9 -4
- package/node_modules/@openclaw/fs-safe/dist/file-store-boundary.js +69 -81
- package/node_modules/@openclaw/fs-safe/dist/file-store-prune.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-store-prune.js +20 -6
- package/node_modules/@openclaw/fs-safe/dist/file-store-sync-directory.d.ts +15 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-sync-directory.js +319 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-sync-write.d.ts +1 -1
- package/node_modules/@openclaw/fs-safe/dist/file-store-sync-write.js +74 -73
- package/node_modules/@openclaw/fs-safe/dist/file-store.d.ts +4 -1
- package/node_modules/@openclaw/fs-safe/dist/file-store.js +71 -66
- package/node_modules/@openclaw/fs-safe/dist/file-sync.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/filename.d.ts +1 -1
- package/node_modules/@openclaw/fs-safe/dist/filename.js +83 -36
- package/node_modules/@openclaw/fs-safe/dist/fs.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/fs.js +3 -3
- package/node_modules/@openclaw/fs-safe/dist/guarded-mkdir.d.ts +12 -1
- package/node_modules/@openclaw/fs-safe/dist/guarded-mkdir.js +227 -33
- package/node_modules/@openclaw/fs-safe/dist/guarded-mutation.d.ts +2 -7
- package/node_modules/@openclaw/fs-safe/dist/guarded-mutation.js +15 -16
- package/node_modules/@openclaw/fs-safe/dist/guest-dispatch-python.d.ts +1 -0
- package/node_modules/@openclaw/fs-safe/dist/guest-dispatch-python.js +68 -0
- package/node_modules/@openclaw/fs-safe/dist/guest-native-python.d.ts +3 -0
- package/node_modules/@openclaw/fs-safe/dist/guest-native-python.js +135 -0
- package/node_modules/@openclaw/fs-safe/dist/guest.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/guest.js +424 -0
- package/node_modules/@openclaw/fs-safe/dist/home-dir.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/home-dir.js +81 -16
- package/node_modules/@openclaw/fs-safe/dist/index.d.ts +9 -7
- package/node_modules/@openclaw/fs-safe/dist/install-path.d.ts +6 -1
- package/node_modules/@openclaw/fs-safe/dist/install-path.js +73 -31
- package/node_modules/@openclaw/fs-safe/dist/json-document-store.d.ts +3 -1
- package/node_modules/@openclaw/fs-safe/dist/json-document-store.js +23 -15
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-directory.d.ts +13 -1
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-directory.js +137 -3
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-ownership.d.ts +8 -2
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-ownership.js +153 -90
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-read.d.ts +5 -0
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-read.js +65 -0
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue.d.ts +1 -2
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue.js +93 -261
- package/node_modules/@openclaw/fs-safe/dist/json-store.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/json-store.js +4 -1
- package/node_modules/@openclaw/fs-safe/dist/json-stringify.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/json.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/json.js +90 -110
- package/node_modules/@openclaw/fs-safe/dist/local-file-access.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/local-file-access.js +7 -10
- package/node_modules/@openclaw/fs-safe/dist/local-file-descriptor.d.ts +16 -0
- package/node_modules/@openclaw/fs-safe/dist/local-file-descriptor.js +84 -0
- package/node_modules/@openclaw/fs-safe/dist/local-roots.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/local-roots.js +63 -38
- package/node_modules/@openclaw/fs-safe/dist/lock-config.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/move-path-cleanup.d.ts +7 -20
- package/node_modules/@openclaw/fs-safe/dist/move-path-cleanup.js +100 -37
- package/node_modules/@openclaw/fs-safe/dist/move-path-stage.d.ts +7 -0
- package/node_modules/@openclaw/fs-safe/dist/move-path-stage.js +56 -0
- package/node_modules/@openclaw/fs-safe/dist/move-path.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/move-path.js +120 -64
- package/node_modules/@openclaw/fs-safe/dist/mutation-authority.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/mutation-authority.js +36 -0
- package/node_modules/@openclaw/fs-safe/dist/native-binding.d.ts +71 -2
- package/node_modules/@openclaw/fs-safe/dist/native-binding.js +8 -1
- package/node_modules/@openclaw/fs-safe/dist/native-config.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/native-directory-observation.d.ts +16 -0
- package/node_modules/@openclaw/fs-safe/dist/native-directory-observation.js +37 -0
- package/node_modules/@openclaw/fs-safe/dist/native-fallback-warning.d.ts +3 -0
- package/node_modules/@openclaw/fs-safe/dist/native-fallback-warning.js +11 -0
- package/node_modules/@openclaw/fs-safe/dist/native-operations.d.ts +1 -7
- package/node_modules/@openclaw/fs-safe/dist/native-operations.js +6 -27
- package/node_modules/@openclaw/fs-safe/dist/native-parent-admission.d.ts +34 -0
- package/node_modules/@openclaw/fs-safe/dist/native-parent-admission.js +147 -0
- package/node_modules/@openclaw/fs-safe/dist/native-pinned-write-windows.d.ts +2 -4
- package/node_modules/@openclaw/fs-safe/dist/native-pinned-write-windows.js +194 -38
- package/node_modules/@openclaw/fs-safe/dist/native-pinned-write.d.ts +1 -2
- package/node_modules/@openclaw/fs-safe/dist/native-pinned-write.js +360 -49
- package/node_modules/@openclaw/fs-safe/dist/native-policy-directory-observation.d.ts +11 -0
- package/node_modules/@openclaw/fs-safe/dist/native-policy-directory-observation.js +61 -0
- package/node_modules/@openclaw/fs-safe/dist/native-policy-parent-windows.d.ts +13 -0
- package/node_modules/@openclaw/fs-safe/dist/native-policy-parent-windows.js +209 -0
- package/node_modules/@openclaw/fs-safe/dist/native-rename-outcome.d.ts +3 -0
- package/node_modules/@openclaw/fs-safe/dist/native-rename-outcome.js +8 -0
- package/node_modules/@openclaw/fs-safe/dist/native-staged-file.d.ts +23 -9
- package/node_modules/@openclaw/fs-safe/dist/native-staged-file.js +180 -100
- package/node_modules/@openclaw/fs-safe/dist/native.d.ts +1 -2
- package/node_modules/@openclaw/fs-safe/dist/native.js +9 -4
- package/node_modules/@openclaw/fs-safe/dist/opened-file-failure.d.ts +1 -2
- package/node_modules/@openclaw/fs-safe/dist/opened-file-failure.js +3 -2
- package/node_modules/@openclaw/fs-safe/dist/opened-realpath.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/opened-realpath.js +16 -6
- package/node_modules/@openclaw/fs-safe/dist/output.d.ts +2 -1
- package/node_modules/@openclaw/fs-safe/dist/output.js +28 -12
- package/node_modules/@openclaw/fs-safe/dist/overwrite-file-handle.d.ts +7 -0
- package/node_modules/@openclaw/fs-safe/dist/overwrite-file-handle.js +46 -0
- package/node_modules/@openclaw/fs-safe/dist/owner-dacl.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/owner-dacl.js +12 -4
- package/node_modules/@openclaw/fs-safe/dist/path-case.d.ts +6 -0
- package/node_modules/@openclaw/fs-safe/dist/path-case.js +136 -0
- package/node_modules/@openclaw/fs-safe/dist/path-policy.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/path-policy.js +7 -2
- package/node_modules/@openclaw/fs-safe/dist/path-prefix.d.ts +6 -0
- package/node_modules/@openclaw/fs-safe/dist/path-prefix.js +104 -0
- package/node_modules/@openclaw/fs-safe/dist/path-scope-lexical.d.ts +13 -0
- package/node_modules/@openclaw/fs-safe/dist/path-scope-lexical.js +37 -0
- package/node_modules/@openclaw/fs-safe/dist/path-segment-route.d.ts +6 -0
- package/node_modules/@openclaw/fs-safe/dist/path-segment-route.js +24 -0
- package/node_modules/@openclaw/fs-safe/dist/path-suffix-aliases.d.ts +11 -0
- package/node_modules/@openclaw/fs-safe/dist/path-suffix-aliases.js +394 -0
- package/node_modules/@openclaw/fs-safe/dist/path.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/path.js +40 -7
- package/node_modules/@openclaw/fs-safe/dist/permission-exec.d.ts +2 -1
- package/node_modules/@openclaw/fs-safe/dist/permission-exec.js +144 -21
- package/node_modules/@openclaw/fs-safe/dist/permissions-public.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/permissions-windows.d.ts +2 -10
- package/node_modules/@openclaw/fs-safe/dist/permissions-windows.js +106 -83
- package/node_modules/@openclaw/fs-safe/dist/permissions.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/permissions.js +37 -30
- package/node_modules/@openclaw/fs-safe/dist/pinned-mutation-admission.d.ts +24 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-mutation-admission.js +419 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-mutation-observation.d.ts +38 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-mutation-observation.js +205 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-mutation-shared-route.d.ts +24 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-mutation-shared-route.js +70 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-open.d.ts +7 -1
- package/node_modules/@openclaw/fs-safe/dist/pinned-open.js +35 -10
- package/node_modules/@openclaw/fs-safe/dist/pinned-operation.d.ts +1 -2
- package/node_modules/@openclaw/fs-safe/dist/pinned-operation.js +4 -17
- package/node_modules/@openclaw/fs-safe/dist/pinned-write-input.d.ts +3 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-write-input.js +35 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-write-mode.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-write-mode.js +31 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-write-staged.d.ts +5 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-write-staged.js +185 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-write-types.d.ts +68 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-write.d.ts +6 -30
- package/node_modules/@openclaw/fs-safe/dist/pinned-write.js +202 -154
- package/node_modules/@openclaw/fs-safe/dist/positional-read.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/positional-read.js +36 -0
- package/node_modules/@openclaw/fs-safe/dist/private-directory.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/private-directory.js +20 -4
- package/node_modules/@openclaw/fs-safe/dist/private-producer-handoff-sync.d.ts +3 -0
- package/node_modules/@openclaw/fs-safe/dist/private-producer-handoff-sync.js +72 -0
- package/node_modules/@openclaw/fs-safe/dist/private-producer-handoff.d.ts +53 -0
- package/node_modules/@openclaw/fs-safe/dist/private-producer-handoff.js +358 -0
- package/node_modules/@openclaw/fs-safe/dist/private-temp-workspace.d.ts +2 -40
- package/node_modules/@openclaw/fs-safe/dist/private-temp-workspace.js +145 -103
- package/node_modules/@openclaw/fs-safe/dist/publish-copy-stage.d.ts +13 -0
- package/node_modules/@openclaw/fs-safe/dist/publish-copy-stage.js +56 -0
- package/node_modules/@openclaw/fs-safe/dist/publish-file-failure.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/publish-file.d.ts +2 -4
- package/node_modules/@openclaw/fs-safe/dist/publish-file.js +110 -144
- package/node_modules/@openclaw/fs-safe/dist/read-open-flags.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/read-opened-file.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/realpath.d.ts +3 -0
- package/node_modules/@openclaw/fs-safe/dist/realpath.js +43 -0
- package/node_modules/@openclaw/fs-safe/dist/recursive-mkdir-path.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/recursive-mkdir-path.js +8 -0
- package/node_modules/@openclaw/fs-safe/dist/regular-file.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/regular-file.js +127 -201
- package/node_modules/@openclaw/fs-safe/dist/replace-directory.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/replace-directory.js +269 -24
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-fallback.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-fallback.js +130 -120
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-source.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-source.js +36 -42
- package/node_modules/@openclaw/fs-safe/dist/replace-file-descriptor.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/replace-file-descriptor.js +16 -17
- package/node_modules/@openclaw/fs-safe/dist/replace-file-mode.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-mode.js +10 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-rename-policy.d.ts +1 -3
- package/node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.d.ts +18 -22
- package/node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.js +123 -143
- package/node_modules/@openclaw/fs-safe/dist/replace-file.d.ts +4 -4
- package/node_modules/@openclaw/fs-safe/dist/replace-file.js +58 -51
- package/node_modules/@openclaw/fs-safe/dist/retained-directory-replacement.d.ts +25 -0
- package/node_modules/@openclaw/fs-safe/dist/retained-directory-replacement.js +193 -0
- package/node_modules/@openclaw/fs-safe/dist/root-boundary.d.ts +29 -0
- package/node_modules/@openclaw/fs-safe/dist/root-boundary.js +186 -0
- package/node_modules/@openclaw/fs-safe/dist/root-context.d.ts +15 -10
- package/node_modules/@openclaw/fs-safe/dist/root-context.js +133 -42
- package/node_modules/@openclaw/fs-safe/dist/root-create-input.d.ts +16 -0
- package/node_modules/@openclaw/fs-safe/dist/root-create-input.js +93 -0
- package/node_modules/@openclaw/fs-safe/dist/root-directory-creation.d.ts +12 -0
- package/node_modules/@openclaw/fs-safe/dist/root-directory-creation.js +225 -0
- package/node_modules/@openclaw/fs-safe/dist/root-directory-list.d.ts +38 -0
- package/node_modules/@openclaw/fs-safe/dist/root-directory-list.js +382 -0
- package/node_modules/@openclaw/fs-safe/dist/root-directory.d.ts +22 -0
- package/node_modules/@openclaw/fs-safe/dist/root-directory.js +141 -0
- package/node_modules/@openclaw/fs-safe/dist/root-entries.d.ts +10 -0
- package/node_modules/@openclaw/fs-safe/dist/root-entries.js +61 -0
- package/node_modules/@openclaw/fs-safe/dist/root-errors.d.ts +10 -6
- package/node_modules/@openclaw/fs-safe/dist/root-errors.js +32 -15
- package/node_modules/@openclaw/fs-safe/dist/root-file-final-admission.d.ts +20 -0
- package/node_modules/@openclaw/fs-safe/dist/root-file-final-admission.js +86 -0
- package/node_modules/@openclaw/fs-safe/dist/root-file.d.ts +2 -1
- package/node_modules/@openclaw/fs-safe/dist/root-file.js +113 -25
- package/node_modules/@openclaw/fs-safe/dist/root-impl.d.ts +17 -63
- package/node_modules/@openclaw/fs-safe/dist/root-impl.js +803 -590
- package/node_modules/@openclaw/fs-safe/dist/root-move-noreplace.d.ts +15 -0
- package/node_modules/@openclaw/fs-safe/dist/root-move-noreplace.js +205 -0
- package/node_modules/@openclaw/fs-safe/dist/root-move-preflight.d.ts +7 -0
- package/node_modules/@openclaw/fs-safe/dist/root-move-preflight.js +16 -0
- package/node_modules/@openclaw/fs-safe/dist/root-observed-path.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/root-observed-path.js +93 -0
- package/node_modules/@openclaw/fs-safe/dist/root-options.d.ts +84 -0
- package/node_modules/@openclaw/fs-safe/dist/root-options.js +18 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path-errors.d.ts +12 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path-errors.js +22 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path-existing.d.ts +10 -1
- package/node_modules/@openclaw/fs-safe/dist/root-path-existing.js +133 -41
- package/node_modules/@openclaw/fs-safe/dist/root-path-observation.d.ts +62 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path-observation.js +180 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path-stat.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path-stat.js +151 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path.d.ts +14 -1
- package/node_modules/@openclaw/fs-safe/dist/root-path.js +292 -330
- package/node_modules/@openclaw/fs-safe/dist/root-paths-lexical.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/root-paths-lexical.js +22 -0
- package/node_modules/@openclaw/fs-safe/dist/root-paths.d.ts +3 -30
- package/node_modules/@openclaw/fs-safe/dist/root-paths.js +89 -174
- package/node_modules/@openclaw/fs-safe/dist/root-public-types.d.ts +11 -0
- package/node_modules/@openclaw/fs-safe/dist/root-public-types.js +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root-read-admission.d.ts +25 -0
- package/node_modules/@openclaw/fs-safe/dist/root-read-admission.js +86 -0
- package/node_modules/@openclaw/fs-safe/dist/root-remove-identity.d.ts +14 -0
- package/node_modules/@openclaw/fs-safe/dist/root-remove-identity.js +87 -0
- package/node_modules/@openclaw/fs-safe/dist/root-remove-receipt.d.ts +16 -0
- package/node_modules/@openclaw/fs-safe/dist/root-remove-receipt.js +37 -0
- package/node_modules/@openclaw/fs-safe/dist/root-remove.d.ts +6 -0
- package/node_modules/@openclaw/fs-safe/dist/root-remove.js +464 -0
- package/node_modules/@openclaw/fs-safe/dist/root-symlink-policy.d.ts +13 -0
- package/node_modules/@openclaw/fs-safe/dist/root-symlink-policy.js +34 -0
- package/node_modules/@openclaw/fs-safe/dist/root-walk.d.ts +6 -6
- package/node_modules/@openclaw/fs-safe/dist/root-walk.js +116 -51
- package/node_modules/@openclaw/fs-safe/dist/root-write-admission.d.ts +65 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-admission.js +304 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-compatibility.d.ts +11 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-compatibility.js +23 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-complete-parent.d.ts +41 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-complete-parent.js +180 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-lock-binding.d.ts +14 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-lock-binding.js +162 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-mode.d.ts +2 -1
- package/node_modules/@openclaw/fs-safe/dist/root-write-mode.js +22 -11
- package/node_modules/@openclaw/fs-safe/dist/root-write-publication.d.ts +23 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-publication.js +85 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-verification.d.ts +1 -2
- package/node_modules/@openclaw/fs-safe/dist/root-write-verification.js +35 -37
- package/node_modules/@openclaw/fs-safe/dist/root.d.ts +2 -4
- package/node_modules/@openclaw/fs-safe/dist/safe-path-segment.d.ts +1 -2
- package/node_modules/@openclaw/fs-safe/dist/safe-path-segment.js +5 -6
- package/node_modules/@openclaw/fs-safe/dist/secret-file.d.ts +1 -1
- package/node_modules/@openclaw/fs-safe/dist/secret-file.js +60 -52
- package/node_modules/@openclaw/fs-safe/dist/secret-read-async.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/secret-read-async.js +13 -28
- package/node_modules/@openclaw/fs-safe/dist/secret-read-policy.d.ts +6 -3
- package/node_modules/@openclaw/fs-safe/dist/secret-read-policy.js +31 -3
- package/node_modules/@openclaw/fs-safe/dist/secret.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/secure-file-windows.d.ts +10 -0
- package/node_modules/@openclaw/fs-safe/dist/secure-file-windows.js +88 -0
- package/node_modules/@openclaw/fs-safe/dist/secure-file.d.ts +1 -2
- package/node_modules/@openclaw/fs-safe/dist/secure-file.js +143 -28
- package/node_modules/@openclaw/fs-safe/dist/secure-temp-dir.d.ts +6 -4
- package/node_modules/@openclaw/fs-safe/dist/secure-temp-dir.js +122 -101
- package/node_modules/@openclaw/fs-safe/dist/secure-temp-repair.d.ts +34 -0
- package/node_modules/@openclaw/fs-safe/dist/secure-temp-repair.js +110 -0
- package/node_modules/@openclaw/fs-safe/dist/sibling-staged-file.d.ts +4 -2
- package/node_modules/@openclaw/fs-safe/dist/sibling-staged-file.js +215 -57
- package/node_modules/@openclaw/fs-safe/dist/sibling-temp.d.ts +2 -1
- package/node_modules/@openclaw/fs-safe/dist/sibling-temp.js +64 -27
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-acquire.d.ts +2 -29
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-acquire.js +298 -192
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-admission-context.d.ts +18 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-admission-context.js +60 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-admission-parser.d.ts +42 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-admission-parser.js +113 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-admission.d.ts +31 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-admission.js +1 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-handle.d.ts +3 -1
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-handle.js +6 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-policy.d.ts +6 -1
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-policy.js +45 -3
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.d.ts +10 -6
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.js +106 -36
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-registration.d.ts +13 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-registration.js +47 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-root.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-root.js +5 -2
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-stale-admission.d.ts +38 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-stale-admission.js +228 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-target.d.ts +7 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-target.js +55 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-types.d.ts +22 -17
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock.js +47 -32
- package/node_modules/@openclaw/fs-safe/dist/staged-directory.d.ts +18 -7
- package/node_modules/@openclaw/fs-safe/dist/staged-directory.js +98 -10
- package/node_modules/@openclaw/fs-safe/dist/staged-file-settlement.d.ts +16 -0
- package/node_modules/@openclaw/fs-safe/dist/staged-file-settlement.js +57 -0
- package/node_modules/@openclaw/fs-safe/dist/staged-file-types.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/stat-observation.d.ts +10 -0
- package/node_modules/@openclaw/fs-safe/dist/stat-observation.js +64 -0
- package/node_modules/@openclaw/fs-safe/dist/store.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/strict-file-identity.d.ts +1 -2
- package/node_modules/@openclaw/fs-safe/dist/strict-file-identity.js +41 -4
- package/node_modules/@openclaw/fs-safe/dist/string-coerce.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/suppressed-error.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/symlink-parents.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/symlink-parents.js +9 -29
- package/node_modules/@openclaw/fs-safe/dist/temp-cleanup.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/temp-cleanup.js +3 -2
- package/node_modules/@openclaw/fs-safe/dist/temp-target.d.ts +16 -13
- package/node_modules/@openclaw/fs-safe/dist/temp-target.js +120 -19
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-admission.d.ts +14 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-admission.js +392 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-child-admission.d.ts +23 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-child-admission.js +151 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-descriptor.d.ts +42 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-descriptor.js +342 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-owner.d.ts +8 -7
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-owner.js +156 -73
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-types.d.ts +39 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-types.js +1 -0
- package/node_modules/@openclaw/fs-safe/dist/temp.d.ts +1 -2
- package/node_modules/@openclaw/fs-safe/dist/temp.js +1 -1
- package/node_modules/@openclaw/fs-safe/dist/test-hooks.d.ts +7 -1
- package/node_modules/@openclaw/fs-safe/dist/text-atomic.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/text-atomic.js +3 -1
- package/node_modules/@openclaw/fs-safe/dist/timing.d.ts +1 -1
- package/node_modules/@openclaw/fs-safe/dist/timing.js +25 -6
- package/node_modules/@openclaw/fs-safe/dist/trash.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/trash.js +61 -13
- package/node_modules/@openclaw/fs-safe/dist/types.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/unicode-path.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/unicode-path.js +16 -0
- package/node_modules/@openclaw/fs-safe/dist/walk.d.ts +5 -2
- package/node_modules/@openclaw/fs-safe/dist/walk.js +47 -47
- package/node_modules/@openclaw/fs-safe/dist/windows-command.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/windows-owner.d.ts +9 -13
- package/node_modules/@openclaw/fs-safe/dist/windows-owner.js +36 -61
- package/node_modules/@openclaw/fs-safe/dist/windows-path-alias.d.ts +39 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-path-alias.js +122 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-path-syntax.d.ts +5 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-path-syntax.js +21 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-security-bridge.cs +336 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-security-bridge.ps1 +15 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-security-command.d.ts +25 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-security-command.js +363 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-security-facts.d.ts +5 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-security-facts.js +108 -0
- package/node_modules/@openclaw/fs-safe/dist/write-file-handle.d.ts +13 -0
- package/node_modules/@openclaw/fs-safe/dist/write-file-handle.js +49 -0
- package/node_modules/@openclaw/fs-safe/dist/write-open-flags.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/write-open-flags.js +1 -9
- package/node_modules/@openclaw/fs-safe/dist/write-queue.d.ts +0 -1
- package/node_modules/@openclaw/fs-safe/dist/write-queue.js +1 -4
- package/node_modules/@openclaw/fs-safe/docs/advanced.md +123 -7
- package/node_modules/@openclaw/fs-safe/docs/archive.md +227 -42
- package/node_modules/@openclaw/fs-safe/docs/atomic.md +199 -12
- package/node_modules/@openclaw/fs-safe/docs/config.md +7 -2
- package/node_modules/@openclaw/fs-safe/docs/contributing.md +88 -6
- package/node_modules/@openclaw/fs-safe/docs/copy.md +197 -0
- package/node_modules/@openclaw/fs-safe/docs/creation.md +132 -0
- package/node_modules/@openclaw/fs-safe/docs/directory-identity.md +85 -0
- package/node_modules/@openclaw/fs-safe/docs/durability.md +130 -5
- package/node_modules/@openclaw/fs-safe/docs/entries.md +109 -0
- package/node_modules/@openclaw/fs-safe/docs/errors.md +18 -10
- package/node_modules/@openclaw/fs-safe/docs/file-contents.md +68 -0
- package/node_modules/@openclaw/fs-safe/docs/file-store.md +112 -6
- package/node_modules/@openclaw/fs-safe/docs/filename.md +21 -7
- package/node_modules/@openclaw/fs-safe/docs/guest.md +146 -0
- package/node_modules/@openclaw/fs-safe/docs/in-place-write.md +81 -0
- package/node_modules/@openclaw/fs-safe/docs/index.md +2 -0
- package/node_modules/@openclaw/fs-safe/docs/install-path.md +61 -15
- package/node_modules/@openclaw/fs-safe/docs/install.md +69 -10
- package/node_modules/@openclaw/fs-safe/docs/json-store.md +20 -1
- package/node_modules/@openclaw/fs-safe/docs/json.md +16 -4
- package/node_modules/@openclaw/fs-safe/docs/local-roots.md +10 -1
- package/node_modules/@openclaw/fs-safe/docs/migrating-to-0.5.md +15 -6
- package/node_modules/@openclaw/fs-safe/docs/migrating-to-0.6.md +9 -4
- package/node_modules/@openclaw/fs-safe/docs/mutation-policy-proof.md +69 -0
- package/node_modules/@openclaw/fs-safe/docs/native-helper.md +75 -16
- package/node_modules/@openclaw/fs-safe/docs/native.md +108 -15
- package/node_modules/@openclaw/fs-safe/docs/output.md +61 -7
- package/node_modules/@openclaw/fs-safe/docs/path-case.md +64 -0
- package/node_modules/@openclaw/fs-safe/docs/path-prefix.md +74 -0
- package/node_modules/@openclaw/fs-safe/docs/path-scope.md +1 -1
- package/node_modules/@openclaw/fs-safe/docs/path-suffix-aliases.md +204 -0
- package/node_modules/@openclaw/fs-safe/docs/path.md +16 -5
- package/node_modules/@openclaw/fs-safe/docs/permissions.md +106 -20
- package/node_modules/@openclaw/fs-safe/docs/positional-read.md +63 -0
- package/node_modules/@openclaw/fs-safe/docs/private-file-store.md +14 -0
- package/node_modules/@openclaw/fs-safe/docs/public-api.md +51 -2
- package/node_modules/@openclaw/fs-safe/docs/quickstart.md +1 -1
- package/node_modules/@openclaw/fs-safe/docs/reading.md +16 -3
- package/node_modules/@openclaw/fs-safe/docs/regular-file.md +3 -0
- package/node_modules/@openclaw/fs-safe/docs/root.md +294 -15
- package/node_modules/@openclaw/fs-safe/docs/secret-file.md +28 -2
- package/node_modules/@openclaw/fs-safe/docs/secure-file.md +28 -16
- package/node_modules/@openclaw/fs-safe/docs/security-model.md +90 -9
- package/node_modules/@openclaw/fs-safe/docs/sidecar-lock.md +163 -7
- package/node_modules/@openclaw/fs-safe/docs/staged-file.md +16 -6
- package/node_modules/@openclaw/fs-safe/docs/store.md +35 -2
- package/node_modules/@openclaw/fs-safe/docs/temp.md +313 -29
- package/node_modules/@openclaw/fs-safe/docs/test-hooks.md +14 -0
- package/node_modules/@openclaw/fs-safe/docs/timing.md +2 -0
- package/node_modules/@openclaw/fs-safe/docs/types.md +35 -12
- package/node_modules/@openclaw/fs-safe/docs/walk.md +128 -6
- package/node_modules/@openclaw/fs-safe/docs/writing.md +314 -20
- package/node_modules/@openclaw/fs-safe/package.json +33 -20
- package/node_modules/@openclaw/fs-safe-darwin-arm64/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-darwin-arm64/package.json +1 -1
- package/node_modules/@openclaw/fs-safe-darwin-x64/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-darwin-x64/package.json +1 -1
- package/node_modules/@openclaw/fs-safe-linux-arm64-gnu/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-linux-arm64-gnu/package.json +1 -1
- package/node_modules/@openclaw/fs-safe-linux-arm64-musl/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-linux-arm64-musl/package.json +1 -1
- package/node_modules/@openclaw/fs-safe-linux-x64-gnu/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-linux-x64-gnu/package.json +1 -1
- package/node_modules/@openclaw/fs-safe-linux-x64-musl/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-linux-x64-musl/package.json +1 -1
- package/node_modules/@openclaw/fs-safe-win32-x64-msvc/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-win32-x64-msvc/package.json +1 -1
- package/node_modules/jszip/.github/FUNDING.yml +1 -0
- package/node_modules/jszip/.github/actions/setup/action.yml +23 -0
- package/node_modules/jszip/.github/workflows/benchmark.yml +38 -0
- package/node_modules/jszip/.github/workflows/main.yml +55 -0
- package/node_modules/jszip/CHANGES.md +6 -0
- package/node_modules/jszip/dist/jszip.js +28 -19
- package/node_modules/jszip/dist/jszip.min.js +2 -2
- package/node_modules/jszip/index.d.ts +14 -0
- package/node_modules/jszip/lib/index.js +1 -1
- package/node_modules/jszip/lib/utils.js +26 -17
- package/node_modules/jszip/package.json +2 -2
- package/node_modules/p-limit/index.d.ts +1 -1
- package/node_modules/p-limit/index.js +6 -1
- package/node_modules/p-limit/package.json +1 -1
- package/node_modules/p-limit/readme.md +8 -0
- package/node_modules/zod/README.md +29 -2
- package/node_modules/zod/compile.cjs +96 -0
- package/node_modules/zod/compile.d.cts +1 -0
- package/node_modules/zod/compile.d.ts +1 -0
- package/node_modules/zod/compile.js +52 -0
- package/node_modules/zod/index.cjs +21 -2
- package/node_modules/zod/index.d.cts +1 -2
- package/node_modules/zod/index.d.ts +1 -2
- package/node_modules/zod/index.js +5 -2
- package/node_modules/zod/locales/index.cjs +19 -0
- package/node_modules/zod/mini/index.cjs +19 -0
- package/node_modules/zod/package.json +20 -8
- package/node_modules/zod/src/compile.ts +56 -0
- package/node_modules/zod/src/index.ts +5 -2
- package/node_modules/zod/src/v3/ZodError.ts +22 -12
- package/node_modules/zod/src/v3/helpers/errorUtil.ts +1 -1
- package/node_modules/zod/src/v3/tests/error.test.ts +35 -0
- package/node_modules/zod/src/v3/tests/intersection.test.ts +18 -0
- package/node_modules/zod/src/v3/tests/language-server.test.ts +1 -2
- package/node_modules/zod/src/v3/tests/object.test.ts +3 -6
- package/node_modules/zod/src/v3/tests/readonly.test.ts +0 -80
- package/node_modules/zod/src/v3/tests/string.test.ts +6 -0
- package/node_modules/zod/src/v3/types.ts +5 -5
- package/node_modules/zod/src/v4/classic/checks.ts +1 -0
- package/node_modules/zod/src/v4/classic/compat.ts +26 -18
- package/node_modules/zod/src/v4/classic/deep-partial.ts +76 -0
- package/node_modules/zod/src/v4/classic/errors.ts +59 -44
- package/node_modules/zod/src/v4/classic/external.ts +14 -9
- package/node_modules/zod/src/v4/classic/from-json-schema.ts +363 -78
- package/node_modules/zod/src/v4/classic/in-out.ts +45 -0
- package/node_modules/zod/src/v4/classic/index.ts +2 -2
- package/node_modules/zod/src/v4/classic/iso.ts +2 -72
- package/node_modules/zod/src/v4/classic/parse.ts +10 -4
- package/node_modules/zod/src/v4/classic/schemas.ts +640 -375
- package/node_modules/zod/src/v4/classic/tests/apply.test.ts +27 -0
- package/node_modules/zod/src/v4/classic/tests/array.test.ts +2 -2
- package/node_modules/zod/src/v4/classic/tests/assignability.test.ts +186 -0
- package/node_modules/zod/src/v4/classic/tests/bigint.test.ts +36 -1
- package/node_modules/zod/src/v4/classic/tests/catch.test.ts +278 -0
- package/node_modules/zod/src/v4/classic/tests/codec-examples.test.ts +1 -2
- package/node_modules/zod/src/v4/classic/tests/codec.test.ts +2 -1
- package/node_modules/zod/src/v4/classic/tests/continuability.test.ts +3 -3
- package/node_modules/zod/src/v4/classic/tests/credit-card.test.ts +76 -0
- package/node_modules/zod/src/v4/classic/tests/cyclic-data.test.ts +985 -0
- package/node_modules/zod/src/v4/classic/tests/date.test.ts +30 -0
- package/node_modules/zod/src/v4/classic/tests/datetime.test.ts +32 -18
- package/node_modules/zod/src/v4/classic/tests/deep-partial.test.ts +380 -0
- package/node_modules/zod/src/v4/classic/tests/default-locale.test.ts +32 -0
- package/node_modules/zod/src/v4/classic/tests/default.test.ts +46 -0
- package/node_modules/zod/src/v4/classic/tests/detached-methods.test.ts +31 -7
- package/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +261 -13
- package/node_modules/zod/src/v4/classic/tests/enum.test.ts +20 -0
- package/node_modules/zod/src/v4/classic/tests/error-utils.test.ts +112 -2
- package/node_modules/zod/src/v4/classic/tests/error.test.ts +403 -6
- package/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +582 -10
- package/node_modules/zod/src/v4/classic/tests/function.test.ts +31 -0
- package/node_modules/zod/src/v4/classic/tests/global-config.test.ts +2 -9
- package/node_modules/zod/src/v4/classic/tests/hash.test.ts +1 -2
- package/node_modules/zod/src/v4/classic/tests/iban.test.ts +81 -0
- package/node_modules/zod/src/v4/classic/tests/in-out.test.ts +159 -0
- package/node_modules/zod/src/v4/classic/tests/index.test.ts +21 -2
- package/node_modules/zod/src/v4/classic/tests/instance-footprint.test.ts +319 -0
- package/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +67 -0
- package/node_modules/zod/src/v4/classic/tests/intersection.test.ts +136 -0
- package/node_modules/zod/src/v4/classic/tests/issue-schema.test.ts +215 -0
- package/node_modules/zod/src/v4/classic/tests/jitless-allows-eval.test.ts +3 -10
- package/node_modules/zod/src/v4/classic/tests/lazy.test.ts +36 -1
- package/node_modules/zod/src/v4/classic/tests/literal.test.ts +12 -1
- package/node_modules/zod/src/v4/classic/tests/map.test.ts +12 -0
- package/node_modules/zod/src/v4/classic/tests/number.test.ts +85 -9
- package/node_modules/zod/src/v4/classic/tests/object.test.ts +301 -12
- package/node_modules/zod/src/v4/classic/tests/optin-ladder.test.ts +235 -0
- package/node_modules/zod/src/v4/classic/tests/optional.test.ts +49 -16
- package/node_modules/zod/src/v4/classic/tests/partial.test.ts +51 -4
- package/node_modules/zod/src/v4/classic/tests/prefault.test.ts +70 -0
- package/node_modules/zod/src/v4/classic/tests/preprocess-types.test.ts +20 -2
- package/node_modules/zod/src/v4/classic/tests/properties.test.ts +141 -0
- package/node_modules/zod/src/v4/classic/tests/readonly.test.ts +0 -68
- package/node_modules/zod/src/v4/classic/tests/record.test.ts +186 -18
- package/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +79 -3
- package/node_modules/zod/src/v4/classic/tests/redos.test.ts +68 -0
- package/node_modules/zod/src/v4/classic/tests/refine.test.ts +60 -0
- package/node_modules/zod/src/v4/classic/tests/set.test.ts +9 -0
- package/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +19 -0
- package/node_modules/zod/src/v4/classic/tests/string.test.ts +222 -6
- package/node_modules/zod/src/v4/classic/tests/stringbool.test.ts +18 -0
- package/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +44 -3
- package/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +1812 -204
- package/node_modules/zod/src/v4/classic/tests/tuple.test.ts +45 -30
- package/node_modules/zod/src/v4/classic/tests/union.test.ts +39 -2
- package/node_modules/zod/src/v4/classic/tests/validate.test.ts +645 -0
- package/node_modules/zod/src/v4/classic/tests/validations.test.ts +2 -2
- package/node_modules/zod/src/v4/core/api.ts +87 -35
- package/node_modules/zod/src/v4/core/checks.ts +119 -146
- package/node_modules/zod/src/v4/core/compile.ts +2313 -0
- package/node_modules/zod/src/v4/core/core.ts +99 -22
- package/node_modules/zod/src/v4/core/doc.ts +17 -9
- package/node_modules/zod/src/v4/core/errors.ts +113 -25
- package/node_modules/zod/src/v4/core/index.ts +3 -0
- package/node_modules/zod/src/v4/core/json-schema-generator.ts +8 -3
- package/node_modules/zod/src/v4/core/json-schema-processors.ts +424 -156
- package/node_modules/zod/src/v4/core/json-schema.ts +2 -1
- package/node_modules/zod/src/v4/core/memoizer.ts +331 -0
- package/node_modules/zod/src/v4/core/parse.ts +164 -50
- package/node_modules/zod/src/v4/core/regexes.ts +42 -15
- package/node_modules/zod/src/v4/core/registries.ts +2 -2
- package/node_modules/zod/src/v4/core/schemas.ts +1000 -538
- package/node_modules/zod/src/v4/core/tests/cached.test.ts +54 -0
- package/node_modules/zod/src/v4/core/tests/compile-differential.test.ts +1004 -0
- package/node_modules/zod/src/v4/core/tests/compile-generative.test.ts +445 -0
- package/node_modules/zod/src/v4/core/tests/compile-global.test.ts +89 -0
- package/node_modules/zod/src/v4/core/tests/compile-off-by-default.test.ts +26 -0
- package/node_modules/zod/src/v4/core/tests/compile-stats.test.ts +34 -0
- package/node_modules/zod/src/v4/core/tests/compile.test.ts +2036 -0
- package/node_modules/zod/src/v4/core/tests/email-regex.test.ts +140 -0
- package/node_modules/zod/src/v4/core/tests/locales/el.test.ts +1 -2
- package/node_modules/zod/src/v4/core/tests/locales/es.test.ts +1 -2
- package/node_modules/zod/src/v4/core/tests/locales/fr.test.ts +3 -3
- package/node_modules/zod/src/v4/core/tests/locales/parity.test.ts +42 -0
- package/node_modules/zod/src/v4/core/tests/locales/tg.test.ts +85 -0
- package/node_modules/zod/src/v4/core/tests/locales/tk.test.ts +69 -0
- package/node_modules/zod/src/v4/core/tests/polyfill-collision.test.ts +46 -0
- package/node_modules/zod/src/v4/core/tests/treeshake.test.ts +51 -0
- package/node_modules/zod/src/v4/core/tests/url-no-canparse.test.ts +133 -0
- package/node_modules/zod/src/v4/core/to-json-schema.ts +283 -48
- package/node_modules/zod/src/v4/core/util.ts +454 -157
- package/node_modules/zod/src/v4/core/versions.ts +2 -2
- package/node_modules/zod/src/v4/core/visit.ts +193 -0
- package/node_modules/zod/src/v4/index.ts +3 -3
- package/node_modules/zod/src/v4/locales/ar.ts +5 -0
- package/node_modules/zod/src/v4/locales/az.ts +5 -0
- package/node_modules/zod/src/v4/locales/be.ts +12 -0
- package/node_modules/zod/src/v4/locales/bg.ts +5 -0
- package/node_modules/zod/src/v4/locales/bn.ts +123 -0
- package/node_modules/zod/src/v4/locales/ca.ts +5 -0
- package/node_modules/zod/src/v4/locales/ckb.ts +140 -0
- package/node_modules/zod/src/v4/locales/cs.ts +5 -0
- package/node_modules/zod/src/v4/locales/da.ts +7 -2
- package/node_modules/zod/src/v4/locales/de.ts +5 -0
- package/node_modules/zod/src/v4/locales/el.ts +3 -0
- package/node_modules/zod/src/v4/locales/en.ts +17 -4
- package/node_modules/zod/src/v4/locales/eo.ts +5 -0
- package/node_modules/zod/src/v4/locales/es.ts +4 -0
- package/node_modules/zod/src/v4/locales/fa.ts +5 -0
- package/node_modules/zod/src/v4/locales/fi.ts +5 -0
- package/node_modules/zod/src/v4/locales/fr-CA.ts +5 -0
- package/node_modules/zod/src/v4/locales/fr.ts +21 -14
- package/node_modules/zod/src/v4/locales/gu.ts +123 -0
- package/node_modules/zod/src/v4/locales/he.ts +8 -1
- package/node_modules/zod/src/v4/locales/hi.ts +126 -0
- package/node_modules/zod/src/v4/locales/hr.ts +4 -0
- package/node_modules/zod/src/v4/locales/hu.ts +5 -0
- package/node_modules/zod/src/v4/locales/hy.ts +11 -0
- package/node_modules/zod/src/v4/locales/id.ts +5 -0
- package/node_modules/zod/src/v4/locales/index.ts +11 -0
- package/node_modules/zod/src/v4/locales/is.ts +5 -0
- package/node_modules/zod/src/v4/locales/it.ts +5 -0
- package/node_modules/zod/src/v4/locales/ja.ts +5 -0
- package/node_modules/zod/src/v4/locales/ka.ts +5 -0
- package/node_modules/zod/src/v4/locales/km.ts +5 -0
- package/node_modules/zod/src/v4/locales/kn.ts +126 -0
- package/node_modules/zod/src/v4/locales/ko.ts +5 -0
- package/node_modules/zod/src/v4/locales/lt.ts +4 -0
- package/node_modules/zod/src/v4/locales/mk.ts +5 -0
- package/node_modules/zod/src/v4/locales/ms.ts +5 -0
- package/node_modules/zod/src/v4/locales/ne.ts +128 -0
- package/node_modules/zod/src/v4/locales/nl.ts +5 -0
- package/node_modules/zod/src/v4/locales/nn.ts +121 -0
- package/node_modules/zod/src/v4/locales/no.ts +7 -2
- package/node_modules/zod/src/v4/locales/ota.ts +5 -0
- package/node_modules/zod/src/v4/locales/pl.ts +5 -0
- package/node_modules/zod/src/v4/locales/ps.ts +5 -0
- package/node_modules/zod/src/v4/locales/pt-BR.ts +161 -0
- package/node_modules/zod/src/v4/locales/pt.ts +101 -58
- package/node_modules/zod/src/v4/locales/ro.ts +3 -0
- package/node_modules/zod/src/v4/locales/ru.ts +12 -0
- package/node_modules/zod/src/v4/locales/sk.ts +123 -0
- package/node_modules/zod/src/v4/locales/sl.ts +5 -0
- package/node_modules/zod/src/v4/locales/sv.ts +7 -2
- package/node_modules/zod/src/v4/locales/ta.ts +5 -0
- package/node_modules/zod/src/v4/locales/tg.ts +135 -0
- package/node_modules/zod/src/v4/locales/th.ts +5 -0
- package/node_modules/zod/src/v4/locales/tk.ts +113 -0
- package/node_modules/zod/src/v4/locales/tr.ts +5 -0
- package/node_modules/zod/src/v4/locales/uk.ts +5 -0
- package/node_modules/zod/src/v4/locales/ur.ts +5 -0
- package/node_modules/zod/src/v4/locales/uz.ts +3 -0
- package/node_modules/zod/src/v4/locales/vi.ts +5 -0
- package/node_modules/zod/src/v4/locales/yo.ts +5 -0
- package/node_modules/zod/src/v4/locales/zh-CN.ts +5 -0
- package/node_modules/zod/src/v4/locales/zh-TW.ts +5 -0
- package/node_modules/zod/src/v4/mini/checks.ts +1 -0
- package/node_modules/zod/src/v4/mini/deep-partial.ts +73 -0
- package/node_modules/zod/src/v4/mini/external.ts +12 -1
- package/node_modules/zod/src/v4/mini/in-out.ts +45 -0
- package/node_modules/zod/src/v4/mini/parse.ts +2 -0
- package/node_modules/zod/src/v4/mini/schemas.ts +167 -63
- package/node_modules/zod/src/v4/mini/tests/apply.test.ts +33 -0
- package/node_modules/zod/src/v4/mini/tests/assignability.test.ts +62 -1
- package/node_modules/zod/src/v4/mini/tests/checks.test.ts +14 -0
- package/node_modules/zod/src/v4/mini/tests/codec.test.ts +35 -1
- package/node_modules/zod/src/v4/mini/tests/computed.test.ts +11 -17
- package/node_modules/zod/src/v4/mini/tests/cyclic-data.test.ts +84 -0
- package/node_modules/zod/src/v4/mini/tests/deep-partial.test.ts +54 -0
- package/node_modules/zod/src/v4/mini/tests/error.test.ts +23 -4
- package/node_modules/zod/src/v4/mini/tests/functions.test.ts +9 -0
- package/node_modules/zod/src/v4/mini/tests/index.test.ts +158 -5
- package/node_modules/zod/src/v4/mini/tests/number.test.ts +14 -0
- package/node_modules/zod/src/v4/mini/tests/object.test.ts +65 -0
- package/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +16 -0
- package/node_modules/zod/src/v4/mini/tests/string.test.ts +44 -0
- package/node_modules/zod/v3/ZodError.cjs +41 -12
- package/node_modules/zod/v3/ZodError.d.cts +1 -1
- package/node_modules/zod/v3/ZodError.d.ts +1 -1
- package/node_modules/zod/v3/ZodError.js +22 -12
- package/node_modules/zod/v3/errors.cjs +19 -0
- package/node_modules/zod/v3/external.cjs +19 -0
- package/node_modules/zod/v3/helpers/enumUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/errorUtil.cjs +20 -1
- package/node_modules/zod/v3/helpers/errorUtil.js +1 -1
- package/node_modules/zod/v3/helpers/parseUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/partialUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/typeAliases.cjs +19 -0
- package/node_modules/zod/v3/helpers/util.cjs +19 -0
- package/node_modules/zod/v3/index.cjs +19 -0
- package/node_modules/zod/v3/standard-schema.cjs +19 -0
- package/node_modules/zod/v3/types.cjs +26 -5
- package/node_modules/zod/v3/types.js +7 -5
- package/node_modules/zod/v4/classic/checks.cjs +21 -1
- package/node_modules/zod/v4/classic/checks.d.cts +1 -1
- package/node_modules/zod/v4/classic/checks.d.ts +1 -1
- package/node_modules/zod/v4/classic/checks.js +1 -1
- package/node_modules/zod/v4/classic/coerce.cjs +19 -0
- package/node_modules/zod/v4/classic/compat.cjs +19 -0
- package/node_modules/zod/v4/classic/compat.d.cts +9 -11
- package/node_modules/zod/v4/classic/compat.d.ts +9 -11
- package/node_modules/zod/v4/classic/deep-partial.cjs +58 -0
- package/node_modules/zod/v4/classic/deep-partial.d.cts +14 -0
- package/node_modules/zod/v4/classic/deep-partial.d.ts +14 -0
- package/node_modules/zod/v4/classic/deep-partial.js +13 -0
- package/node_modules/zod/v4/classic/errors.cjs +62 -34
- package/node_modules/zod/v4/classic/errors.d.cts +3 -4
- package/node_modules/zod/v4/classic/errors.d.ts +3 -4
- package/node_modules/zod/v4/classic/errors.js +43 -34
- package/node_modules/zod/v4/classic/external.cjs +51 -27
- package/node_modules/zod/v4/classic/external.d.cts +5 -2
- package/node_modules/zod/v4/classic/external.d.ts +5 -2
- package/node_modules/zod/v4/classic/external.js +5 -8
- package/node_modules/zod/v4/classic/from-json-schema.cjs +376 -75
- package/node_modules/zod/v4/classic/from-json-schema.js +357 -75
- package/node_modules/zod/v4/classic/in-out.cjs +82 -0
- package/node_modules/zod/v4/classic/in-out.d.cts +8 -0
- package/node_modules/zod/v4/classic/in-out.d.ts +8 -0
- package/node_modules/zod/v4/classic/in-out.js +36 -0
- package/node_modules/zod/v4/classic/index.cjs +21 -2
- package/node_modules/zod/v4/classic/index.d.cts +1 -2
- package/node_modules/zod/v4/classic/index.d.ts +1 -2
- package/node_modules/zod/v4/classic/index.js +2 -2
- package/node_modules/zod/v4/classic/iso.cjs +30 -22
- package/node_modules/zod/v4/classic/iso.d.cts +2 -17
- package/node_modules/zod/v4/classic/iso.d.ts +2 -17
- package/node_modules/zod/v4/classic/iso.js +2 -17
- package/node_modules/zod/v4/classic/parse.cjs +23 -1
- package/node_modules/zod/v4/classic/parse.d.cts +17 -4
- package/node_modules/zod/v4/classic/parse.d.ts +17 -4
- package/node_modules/zod/v4/classic/parse.js +1 -0
- package/node_modules/zod/v4/classic/schemas.cjs +591 -426
- package/node_modules/zod/v4/classic/schemas.d.cts +68 -19
- package/node_modules/zod/v4/classic/schemas.d.ts +68 -19
- package/node_modules/zod/v4/classic/schemas.js +564 -424
- package/node_modules/zod/v4/core/api.cjs +66 -24
- package/node_modules/zod/v4/core/api.d.cts +22 -12
- package/node_modules/zod/v4/core/api.d.ts +22 -12
- package/node_modules/zod/v4/core/api.js +44 -24
- package/node_modules/zod/v4/core/checks.cjs +88 -128
- package/node_modules/zod/v4/core/checks.d.cts +29 -13
- package/node_modules/zod/v4/core/checks.d.ts +29 -13
- package/node_modules/zod/v4/core/checks.js +68 -127
- package/node_modules/zod/v4/core/compile.cjs +1908 -0
- package/node_modules/zod/v4/core/compile.d.cts +65 -0
- package/node_modules/zod/v4/core/compile.d.ts +65 -0
- package/node_modules/zod/v4/core/compile.js +1858 -0
- package/node_modules/zod/v4/core/core.cjs +101 -19
- package/node_modules/zod/v4/core/core.d.cts +16 -4
- package/node_modules/zod/v4/core/core.d.ts +16 -4
- package/node_modules/zod/v4/core/core.js +83 -20
- package/node_modules/zod/v4/core/doc.cjs +31 -9
- package/node_modules/zod/v4/core/doc.d.cts +3 -1
- package/node_modules/zod/v4/core/doc.d.ts +3 -1
- package/node_modules/zod/v4/core/doc.js +12 -9
- package/node_modules/zod/v4/core/errors.cjs +126 -25
- package/node_modules/zod/v4/core/errors.d.cts +4 -0
- package/node_modules/zod/v4/core/errors.d.ts +4 -0
- package/node_modules/zod/v4/core/errors.js +107 -25
- package/node_modules/zod/v4/core/index.cjs +24 -1
- package/node_modules/zod/v4/core/index.d.cts +3 -0
- package/node_modules/zod/v4/core/index.d.ts +3 -0
- package/node_modules/zod/v4/core/index.js +3 -0
- package/node_modules/zod/v4/core/json-schema-generator.cjs +24 -1
- package/node_modules/zod/v4/core/json-schema-generator.d.cts +2 -2
- package/node_modules/zod/v4/core/json-schema-generator.d.ts +2 -2
- package/node_modules/zod/v4/core/json-schema-generator.js +6 -2
- package/node_modules/zod/v4/core/json-schema-processors.cjs +441 -156
- package/node_modules/zod/v4/core/json-schema-processors.d.cts +16 -0
- package/node_modules/zod/v4/core/json-schema-processors.d.ts +16 -0
- package/node_modules/zod/v4/core/json-schema-processors.js +400 -158
- package/node_modules/zod/v4/core/json-schema.cjs +19 -0
- package/node_modules/zod/v4/core/json-schema.d.cts +2 -1
- package/node_modules/zod/v4/core/json-schema.d.ts +2 -1
- package/node_modules/zod/v4/core/memoizer.cjs +360 -0
- package/node_modules/zod/v4/core/memoizer.d.cts +15 -0
- package/node_modules/zod/v4/core/memoizer.d.ts +15 -0
- package/node_modules/zod/v4/core/memoizer.js +311 -0
- package/node_modules/zod/v4/core/parse.cjs +148 -46
- package/node_modules/zod/v4/core/parse.d.cts +14 -11
- package/node_modules/zod/v4/core/parse.d.ts +14 -11
- package/node_modules/zod/v4/core/parse.js +127 -45
- package/node_modules/zod/v4/core/regexes.cjs +54 -17
- package/node_modules/zod/v4/core/regexes.d.cts +5 -0
- package/node_modules/zod/v4/core/regexes.d.ts +5 -0
- package/node_modules/zod/v4/core/regexes.js +32 -15
- package/node_modules/zod/v4/core/registries.cjs +19 -0
- package/node_modules/zod/v4/core/registries.js +2 -2
- package/node_modules/zod/v4/core/schemas.cjs +785 -386
- package/node_modules/zod/v4/core/schemas.d.cts +123 -34
- package/node_modules/zod/v4/core/schemas.d.ts +123 -34
- package/node_modules/zod/v4/core/schemas.js +753 -386
- package/node_modules/zod/v4/core/standard-schema.cjs +19 -0
- package/node_modules/zod/v4/core/to-json-schema.cjs +269 -45
- package/node_modules/zod/v4/core/to-json-schema.d.cts +45 -5
- package/node_modules/zod/v4/core/to-json-schema.d.ts +45 -5
- package/node_modules/zod/v4/core/to-json-schema.js +247 -44
- package/node_modules/zod/v4/core/util.cjs +372 -157
- package/node_modules/zod/v4/core/util.d.cts +79 -1
- package/node_modules/zod/v4/core/util.d.ts +79 -1
- package/node_modules/zod/v4/core/util.js +341 -156
- package/node_modules/zod/v4/core/versions.cjs +21 -2
- package/node_modules/zod/v4/core/versions.d.cts +1 -1
- package/node_modules/zod/v4/core/versions.d.ts +1 -1
- package/node_modules/zod/v4/core/versions.js +2 -2
- package/node_modules/zod/v4/core/visit.cjs +214 -0
- package/node_modules/zod/v4/core/visit.d.cts +30 -0
- package/node_modules/zod/v4/core/visit.d.ts +30 -0
- package/node_modules/zod/v4/core/visit.js +169 -0
- package/node_modules/zod/v4/index.cjs +34 -5
- package/node_modules/zod/v4/index.d.cts +2 -2
- package/node_modules/zod/v4/index.d.ts +2 -2
- package/node_modules/zod/v4/index.js +3 -2
- package/node_modules/zod/v4/locales/ar.cjs +5 -0
- package/node_modules/zod/v4/locales/ar.js +5 -0
- package/node_modules/zod/v4/locales/az.cjs +5 -0
- package/node_modules/zod/v4/locales/az.js +5 -0
- package/node_modules/zod/v4/locales/be.cjs +12 -0
- package/node_modules/zod/v4/locales/be.js +12 -0
- package/node_modules/zod/v4/locales/bg.cjs +5 -0
- package/node_modules/zod/v4/locales/bg.js +5 -0
- package/node_modules/zod/v4/locales/bn.cjs +140 -0
- package/node_modules/zod/v4/locales/bn.d.cts +5 -0
- package/node_modules/zod/v4/locales/bn.d.ts +4 -0
- package/node_modules/zod/v4/locales/bn.js +113 -0
- package/node_modules/zod/v4/locales/ca.cjs +5 -0
- package/node_modules/zod/v4/locales/ca.js +5 -0
- package/node_modules/zod/v4/locales/ckb.cjs +160 -0
- package/node_modules/zod/v4/locales/ckb.d.cts +5 -0
- package/node_modules/zod/v4/locales/ckb.d.ts +4 -0
- package/node_modules/zod/v4/locales/ckb.js +133 -0
- package/node_modules/zod/v4/locales/cs.cjs +5 -0
- package/node_modules/zod/v4/locales/cs.js +5 -0
- package/node_modules/zod/v4/locales/da.cjs +7 -2
- package/node_modules/zod/v4/locales/da.js +7 -2
- package/node_modules/zod/v4/locales/de.cjs +5 -0
- package/node_modules/zod/v4/locales/de.js +5 -0
- package/node_modules/zod/v4/locales/el.cjs +3 -0
- package/node_modules/zod/v4/locales/el.js +3 -0
- package/node_modules/zod/v4/locales/en.cjs +16 -4
- package/node_modules/zod/v4/locales/en.js +16 -4
- package/node_modules/zod/v4/locales/eo.cjs +5 -0
- package/node_modules/zod/v4/locales/eo.js +5 -0
- package/node_modules/zod/v4/locales/es.cjs +4 -0
- package/node_modules/zod/v4/locales/es.js +4 -0
- package/node_modules/zod/v4/locales/fa.cjs +5 -0
- package/node_modules/zod/v4/locales/fa.js +5 -0
- package/node_modules/zod/v4/locales/fi.cjs +5 -0
- package/node_modules/zod/v4/locales/fi.js +5 -0
- package/node_modules/zod/v4/locales/fr-CA.cjs +5 -0
- package/node_modules/zod/v4/locales/fr-CA.js +5 -0
- package/node_modules/zod/v4/locales/fr.cjs +18 -14
- package/node_modules/zod/v4/locales/fr.js +18 -14
- package/node_modules/zod/v4/locales/gu.cjs +140 -0
- package/node_modules/zod/v4/locales/gu.d.cts +5 -0
- package/node_modules/zod/v4/locales/gu.d.ts +4 -0
- package/node_modules/zod/v4/locales/gu.js +113 -0
- package/node_modules/zod/v4/locales/he.cjs +7 -0
- package/node_modules/zod/v4/locales/he.js +7 -0
- package/node_modules/zod/v4/locales/hi.cjs +138 -0
- package/node_modules/zod/v4/locales/hi.d.cts +5 -0
- package/node_modules/zod/v4/locales/hi.d.ts +4 -0
- package/node_modules/zod/v4/locales/hi.js +111 -0
- package/node_modules/zod/v4/locales/hr.cjs +4 -0
- package/node_modules/zod/v4/locales/hr.js +4 -0
- package/node_modules/zod/v4/locales/hu.cjs +5 -0
- package/node_modules/zod/v4/locales/hu.js +5 -0
- package/node_modules/zod/v4/locales/hy.cjs +11 -0
- package/node_modules/zod/v4/locales/hy.js +11 -0
- package/node_modules/zod/v4/locales/id.cjs +5 -0
- package/node_modules/zod/v4/locales/id.js +5 -0
- package/node_modules/zod/v4/locales/index.cjs +43 -2
- package/node_modules/zod/v4/locales/index.d.cts +11 -0
- package/node_modules/zod/v4/locales/index.d.ts +11 -0
- package/node_modules/zod/v4/locales/index.js +11 -0
- package/node_modules/zod/v4/locales/is.cjs +5 -0
- package/node_modules/zod/v4/locales/is.js +5 -0
- package/node_modules/zod/v4/locales/it.cjs +5 -0
- package/node_modules/zod/v4/locales/it.js +5 -0
- package/node_modules/zod/v4/locales/ja.cjs +5 -0
- package/node_modules/zod/v4/locales/ja.js +5 -0
- package/node_modules/zod/v4/locales/ka.cjs +5 -0
- package/node_modules/zod/v4/locales/ka.js +5 -0
- package/node_modules/zod/v4/locales/km.cjs +5 -0
- package/node_modules/zod/v4/locales/km.js +5 -0
- package/node_modules/zod/v4/locales/kn.cjs +143 -0
- package/node_modules/zod/v4/locales/kn.d.cts +5 -0
- package/node_modules/zod/v4/locales/kn.d.ts +4 -0
- package/node_modules/zod/v4/locales/kn.js +116 -0
- package/node_modules/zod/v4/locales/ko.cjs +5 -0
- package/node_modules/zod/v4/locales/ko.js +5 -0
- package/node_modules/zod/v4/locales/lt.cjs +4 -0
- package/node_modules/zod/v4/locales/lt.js +4 -0
- package/node_modules/zod/v4/locales/mk.cjs +5 -0
- package/node_modules/zod/v4/locales/mk.js +5 -0
- package/node_modules/zod/v4/locales/ms.cjs +5 -0
- package/node_modules/zod/v4/locales/ms.js +5 -0
- package/node_modules/zod/v4/locales/ne.cjs +138 -0
- package/node_modules/zod/v4/locales/ne.d.cts +5 -0
- package/node_modules/zod/v4/locales/ne.d.ts +4 -0
- package/node_modules/zod/v4/locales/ne.js +111 -0
- package/node_modules/zod/v4/locales/nl.cjs +5 -0
- package/node_modules/zod/v4/locales/nl.js +5 -0
- package/node_modules/zod/v4/locales/nn.cjs +140 -0
- package/node_modules/zod/v4/locales/nn.d.cts +5 -0
- package/node_modules/zod/v4/locales/nn.d.ts +4 -0
- package/node_modules/zod/v4/locales/nn.js +113 -0
- package/node_modules/zod/v4/locales/no.cjs +7 -2
- package/node_modules/zod/v4/locales/no.js +7 -2
- package/node_modules/zod/v4/locales/ota.cjs +5 -0
- package/node_modules/zod/v4/locales/ota.js +5 -0
- package/node_modules/zod/v4/locales/pl.cjs +5 -0
- package/node_modules/zod/v4/locales/pl.js +5 -0
- package/node_modules/zod/v4/locales/ps.cjs +5 -0
- package/node_modules/zod/v4/locales/ps.js +5 -0
- package/node_modules/zod/v4/locales/pt-BR.cjs +170 -0
- package/node_modules/zod/v4/locales/pt-BR.d.cts +5 -0
- package/node_modules/zod/v4/locales/pt-BR.d.ts +4 -0
- package/node_modules/zod/v4/locales/pt-BR.js +143 -0
- package/node_modules/zod/v4/locales/pt.cjs +89 -55
- package/node_modules/zod/v4/locales/pt.js +89 -55
- package/node_modules/zod/v4/locales/ro.cjs +3 -0
- package/node_modules/zod/v4/locales/ro.js +3 -0
- package/node_modules/zod/v4/locales/ru.cjs +12 -0
- package/node_modules/zod/v4/locales/ru.js +12 -0
- package/node_modules/zod/v4/locales/sk.cjs +143 -0
- package/node_modules/zod/v4/locales/sk.d.cts +5 -0
- package/node_modules/zod/v4/locales/sk.d.ts +4 -0
- package/node_modules/zod/v4/locales/sk.js +116 -0
- package/node_modules/zod/v4/locales/sl.cjs +5 -0
- package/node_modules/zod/v4/locales/sl.js +5 -0
- package/node_modules/zod/v4/locales/sv.cjs +7 -2
- package/node_modules/zod/v4/locales/sv.js +7 -2
- package/node_modules/zod/v4/locales/ta.cjs +5 -0
- package/node_modules/zod/v4/locales/ta.js +5 -0
- package/node_modules/zod/v4/locales/tg.cjs +144 -0
- package/node_modules/zod/v4/locales/tg.d.cts +5 -0
- package/node_modules/zod/v4/locales/tg.d.ts +4 -0
- package/node_modules/zod/v4/locales/tg.js +117 -0
- package/node_modules/zod/v4/locales/th.cjs +5 -0
- package/node_modules/zod/v4/locales/th.js +5 -0
- package/node_modules/zod/v4/locales/tk.cjs +134 -0
- package/node_modules/zod/v4/locales/tk.d.cts +5 -0
- package/node_modules/zod/v4/locales/tk.d.ts +4 -0
- package/node_modules/zod/v4/locales/tk.js +107 -0
- package/node_modules/zod/v4/locales/tr.cjs +5 -0
- package/node_modules/zod/v4/locales/tr.js +5 -0
- package/node_modules/zod/v4/locales/uk.cjs +5 -0
- package/node_modules/zod/v4/locales/uk.js +5 -0
- package/node_modules/zod/v4/locales/ur.cjs +5 -0
- package/node_modules/zod/v4/locales/ur.js +5 -0
- package/node_modules/zod/v4/locales/uz.cjs +3 -0
- package/node_modules/zod/v4/locales/uz.js +3 -0
- package/node_modules/zod/v4/locales/vi.cjs +5 -0
- package/node_modules/zod/v4/locales/vi.js +5 -0
- package/node_modules/zod/v4/locales/yo.cjs +5 -0
- package/node_modules/zod/v4/locales/yo.js +5 -0
- package/node_modules/zod/v4/locales/zh-CN.cjs +5 -0
- package/node_modules/zod/v4/locales/zh-CN.js +5 -0
- package/node_modules/zod/v4/locales/zh-TW.cjs +5 -0
- package/node_modules/zod/v4/locales/zh-TW.js +5 -0
- package/node_modules/zod/v4/mini/checks.cjs +21 -1
- package/node_modules/zod/v4/mini/checks.d.cts +1 -1
- package/node_modules/zod/v4/mini/checks.d.ts +1 -1
- package/node_modules/zod/v4/mini/checks.js +1 -1
- package/node_modules/zod/v4/mini/coerce.cjs +19 -0
- package/node_modules/zod/v4/mini/deep-partial.cjs +58 -0
- package/node_modules/zod/v4/mini/deep-partial.d.cts +14 -0
- package/node_modules/zod/v4/mini/deep-partial.d.ts +14 -0
- package/node_modules/zod/v4/mini/deep-partial.js +13 -0
- package/node_modules/zod/v4/mini/external.cjs +33 -1
- package/node_modules/zod/v4/mini/external.d.cts +5 -2
- package/node_modules/zod/v4/mini/external.d.ts +5 -2
- package/node_modules/zod/v4/mini/external.js +3 -1
- package/node_modules/zod/v4/mini/in-out.cjs +82 -0
- package/node_modules/zod/v4/mini/in-out.d.cts +8 -0
- package/node_modules/zod/v4/mini/in-out.d.ts +8 -0
- package/node_modules/zod/v4/mini/in-out.js +36 -0
- package/node_modules/zod/v4/mini/index.cjs +19 -0
- package/node_modules/zod/v4/mini/iso.cjs +19 -0
- package/node_modules/zod/v4/mini/parse.cjs +22 -1
- package/node_modules/zod/v4/mini/parse.d.cts +1 -1
- package/node_modules/zod/v4/mini/parse.d.ts +1 -1
- package/node_modules/zod/v4/mini/parse.js +1 -1
- package/node_modules/zod/v4/mini/schemas.cjs +117 -53
- package/node_modules/zod/v4/mini/schemas.d.cts +49 -14
- package/node_modules/zod/v4/mini/schemas.d.ts +49 -14
- package/node_modules/zod/v4/mini/schemas.js +92 -51
- package/node_modules/zod/v4-mini/index.cjs +19 -0
- package/openclaw.plugin.json +21 -1
- package/package.json +10 -8
- package/node_modules/@openclaw/fs-safe/dist/absolute-path.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/advanced.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-crc32.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-deadline.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-entry.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-errors.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-gzip-tail.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-input.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-kind.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-limits.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-merge.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-native.d.ts +0 -20
- package/node_modules/@openclaw/fs-safe/dist/archive-native.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-native.js +0 -107
- package/node_modules/@openclaw/fs-safe/dist/archive-options.d.ts +0 -21
- package/node_modules/@openclaw/fs-safe/dist/archive-options.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-parser-errors.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-plan.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-policy.d.ts +0 -22
- package/node_modules/@openclaw/fs-safe/dist/archive-policy.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-policy.js +0 -38
- package/node_modules/@openclaw/fs-safe/dist/archive-read.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-staging.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-inspect.d.ts +0 -7
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-inspect.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-inspect.js +0 -59
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-stream.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-wasm.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-tar.d.ts +0 -19
- package/node_modules/@openclaw/fs-safe/dist/archive-tar.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-tar.js +0 -21
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-admission.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-count.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-directory.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-entry.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-integrity.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-names.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-preflight.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/archive.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/async-lock.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/atomic.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/bounded-read-stream.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/bounded-read.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/byte-budget.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/config.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/containment.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/deny-mutations.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/device-path.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/directory-durability.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/directory-guard.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/directory-mode-node.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/directory-mode-owner.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/durability.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/error-detail.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/errors.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-hash.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-identity.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-lock.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-observation.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-store-boundary.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-store-limit.d.ts +0 -2
- package/node_modules/@openclaw/fs-safe/dist/file-store-limit.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-store-limit.js +0 -8
- package/node_modules/@openclaw/fs-safe/dist/file-store-prune.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-store-sync-write.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-store.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/file-sync.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/filename.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/fs.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/guarded-mkdir.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/guarded-mutation.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/home-dir.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/index.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/install-path.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/json-document-store.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-directory.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-ownership.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/json-store.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/json-stringify.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/json.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/local-file-access.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/local-roots.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/lock-config.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/move-path-cleanup.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/move-path.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/native-binding.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/native-config.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/native-operations.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/native-pinned-write-windows.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/native-pinned-write.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/native-staged-file.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/native.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/opened-file-failure.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/opened-realpath.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/output.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/owner-dacl.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/path-policy.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/path.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/permission-exec.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/permissions-public.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/permissions-windows.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/permissions.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/pinned-open.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/pinned-operation.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/pinned-write.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/private-directory.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/private-temp-workspace.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/publish-file-failure.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/publish-file.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/read-open-flags.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/read-opened-file.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/regular-file.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/replace-directory.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-fallback.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-source.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/replace-file-descriptor.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/replace-file-rename-policy.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/replace-file.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/root-context.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/root-errors.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/root-file.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/root-impl.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/root-path-existing.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/root-path-symlink.d.ts +0 -7
- package/node_modules/@openclaw/fs-safe/dist/root-path-symlink.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/root-path-symlink.js +0 -35
- package/node_modules/@openclaw/fs-safe/dist/root-path.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/root-paths.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/root-walk.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/root-write-mode.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/root-write-verification.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/root.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/safe-path-segment.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/secret-file.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/secret-read-async.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/secret-read-policy.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/secret.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/secure-file.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/secure-temp-dir.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/sibling-staged-file.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/sibling-temp.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-acquire.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-handle.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-policy.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-root.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-types.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/staged-directory.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/staged-file-types.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/store.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/strict-file-identity.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/string-coerce.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/suppressed-error.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/symlink-parents.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/temp-cleanup.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/temp-target.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-owner.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/temp.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/test-hooks.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/text-atomic.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/timing.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/trash.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/types.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/walk.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/windows-command.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/windows-owner.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/write-open-flags.d.ts.map +0 -1
- package/node_modules/@openclaw/fs-safe/dist/write-queue.d.ts.map +0 -1
- package/node_modules/jszip/.github/workflows/pr.yaml +0 -58
- package/node_modules/jszip/.jekyll-metadata +0 -0
- package/node_modules/jszip/.travis.yml +0 -17
- package/node_modules/jszip/deps.js +0 -37
- package/node_modules/jszip/graph.svg +0 -601
- package/node_modules/zod/src/v4/core/config.ts +0 -15
- /package/node_modules/@openclaw/fs-safe/dist/{archive-options.js → pinned-write-types.js} +0 -0
|
@@ -1,36 +1,117 @@
|
|
|
1
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
+
if (value !== null && value !== void 0) {
|
|
3
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
+
var dispose, inner;
|
|
5
|
+
if (async) {
|
|
6
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
+
dispose = value[Symbol.asyncDispose];
|
|
8
|
+
}
|
|
9
|
+
if (dispose === void 0) {
|
|
10
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
if (async) inner = dispose;
|
|
13
|
+
}
|
|
14
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
+
}
|
|
18
|
+
else if (async) {
|
|
19
|
+
env.stack.push({ async: true });
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
+
return function (env) {
|
|
25
|
+
function fail(e) {
|
|
26
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
+
env.hasError = true;
|
|
28
|
+
}
|
|
29
|
+
var r, s = 0;
|
|
30
|
+
function next() {
|
|
31
|
+
while (r = env.stack.pop()) {
|
|
32
|
+
try {
|
|
33
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
+
if (r.dispose) {
|
|
35
|
+
var result = r.dispose.call(r.value);
|
|
36
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
+
}
|
|
38
|
+
else s |= 1;
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
fail(e);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
+
if (env.hasError) throw env.error;
|
|
46
|
+
}
|
|
47
|
+
return next();
|
|
48
|
+
};
|
|
49
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
+
var e = new Error(message);
|
|
51
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
+
});
|
|
1
53
|
import { randomUUID } from "node:crypto";
|
|
2
54
|
import fsSync, { constants as fsConstants } from "node:fs";
|
|
3
55
|
import fs from "node:fs/promises";
|
|
4
56
|
import path from "node:path";
|
|
5
57
|
import { normalizeMaxBytes } from "./byte-budget.js";
|
|
6
|
-
import {
|
|
58
|
+
import { assertCopySourceCurrent, resolveFileCopyCloneMode } from "./copy-file-input.js";
|
|
59
|
+
import { assertPrivateFileCreationAvailable, resolveCreationPermissions } from "./creation-boundary.js";
|
|
60
|
+
import { assertAsyncDirectoryGuard, assertSyncDirectoryGuard, createAsyncDirectoryGuard, createNearestExistingDirectoryGuard } from "./directory-guard.js";
|
|
7
61
|
import { FsSafeError } from "./errors.js";
|
|
8
62
|
import { syncDirectoryBestEffort } from "./directory-durability.js";
|
|
9
|
-
import { sameFileIdentity, sameFileIdentityForCleanup, } from "./file-identity.js";
|
|
10
|
-
import { mkdirPathComponentsWithGuards } from "./guarded-mkdir.js";
|
|
11
63
|
import { withAsyncDirectoryGuards } from "./guarded-mutation.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
64
|
+
import { openLocalFileDescriptor } from "./local-file-descriptor.js";
|
|
65
|
+
import { assertMutationNotDenied, mergeDenyMutationPolicies } from "./deny-mutations.js";
|
|
66
|
+
import { resolveOpenedFileRealPathForFd } from "./opened-realpath.js";
|
|
67
|
+
import { openedPathResolutionError, recordExclusiveCreateFailure, recordOpenedFileFailure } from "./opened-file-failure.js";
|
|
68
|
+
import { runPinnedWriteHelper, runPinnedWriteWithRenamePolicy } from "./pinned-write.js";
|
|
69
|
+
import { preparePinnedWriteMutationAdmission, snapshotPinnedMutationPolicy } from "./pinned-mutation-admission.js";
|
|
16
70
|
import { getNativeBinding } from "./native.js";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { assertNoNulPathInput,
|
|
71
|
+
import { validatePinnedRelativePath } from "./pinned-operation.js";
|
|
72
|
+
import { PATH_ALIAS_POLICIES } from "./path-policy.js";
|
|
73
|
+
import { assertNoNulPathInput, hasNodeErrorCode, isNotFoundPathError, isSymlinkOpenError, } from "./path.js";
|
|
20
74
|
import { readOpenedFileSafely } from "./read-opened-file.js";
|
|
21
|
-
import {
|
|
75
|
+
import { cleanupPinnedFilePath } from "./file-cleanup.js";
|
|
76
|
+
import { sameFileIdentity } from "./file-identity.js";
|
|
77
|
+
import { removePathIfIdentityUnchanged } from "./replace-file-temp-owner.js";
|
|
78
|
+
import { realpathSync } from "./realpath.js";
|
|
79
|
+
import { mkdirPathFallback, prepareRootWriteTarget, tryMkdirAtExactParent } from "./root-directory-creation.js";
|
|
22
80
|
import { isNonRegularWriteOpenError, resolveNonblockingWriteFlag } from "./write-open-flags.js";
|
|
23
|
-
import { resolveRootPath } from "./root-path.js";
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
81
|
+
import { resolveRootPath, resolveRootPathSync, resolveRootPathForRemoval } from "./root-path.js";
|
|
82
|
+
import { RemovalPathReceipts } from "./root-remove-receipt.js";
|
|
83
|
+
import { admitPathInsideRoot } from "./root-boundary.js";
|
|
84
|
+
import { listDirectoryPath, openRootDirectoryListing } from "./root-directory-list.js";
|
|
85
|
+
import { statResolvedPathInRoot } from "./root-path-stat.js";
|
|
86
|
+
import { entriesInRoot } from "./root-entries.js";
|
|
87
|
+
import { assertMoveMutationAllowed } from "./root-move-preflight.js";
|
|
88
|
+
import { assertRootIdentityCurrent, assertRootIdentityCurrentSync, assertValidRootDestinationPath, assertValidRootRelativePath, ensureTrailingSep, expandRelativePathWithHome, resolvePathInRoot, resolveRootContext, rootRelativeReadPath, } from "./root-context.js";
|
|
89
|
+
import { errorCauseOptions, fileNotFoundError, hardlinkedPathNotAllowedError, isAlreadyExistsError, normalizePinnedPathError, normalizePinnedWriteError, outsideWorkspaceError, } from "./root-errors.js";
|
|
26
90
|
import { getFsSafeTestHooks } from "./test-hooks.js";
|
|
27
91
|
import { stringifyJsonDocument } from "./json-stringify.js";
|
|
28
92
|
import { walkRoot } from "./root-walk.js";
|
|
29
93
|
import { registerTempPathForExit } from "./temp-cleanup.js";
|
|
94
|
+
import { removePathInRootFallback, validateRemoveOptions } from "./root-remove.js";
|
|
30
95
|
import { serializePathWrite } from "./write-queue.js";
|
|
31
96
|
import { verifyAtomicWriteResult } from "./root-write-verification.js";
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
97
|
+
import { assertRootWritePathSelectionSync, assertRootWriteSelectionSync, createRootWriteSelectionForFd, prepareGuardedRootWritePathSelection, resolveGuardedWritePathInRoot, resolveGuardedWriteTargetInRoot, resolvePinnedWriteTargetInRoot, refreshRetainedRootWriteAdmission, refreshRootWritePathSelection, } from "./root-write-admission.js";
|
|
98
|
+
import { prepareSharedRootWriteTarget } from "./root-write-complete-parent.js";
|
|
99
|
+
import { finishRootFallbackWrite } from "./root-write-publication.js";
|
|
100
|
+
import { withRootFallbackCompatibilityLock } from "./root-write-compatibility.js";
|
|
101
|
+
import { assertRootFallbackWritePath } from "./root-write-lock-binding.js";
|
|
102
|
+
import { inspectFileIdentity, inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
103
|
+
import { admitMoveSourceStat, movePathNoReplaceNative } from "./root-move-noreplace.js";
|
|
104
|
+
import { admitRootReadHandle, inspectOpenedPathIdentitySync } from "./root-read-admission.js";
|
|
105
|
+
import { createCopyPublicationObserver, onCopyPublication, onCopySourceAdmission } from "./copy-publication.js";
|
|
106
|
+
import { writeAllToFile } from "./write-file-handle.js";
|
|
107
|
+
import { createInputOptions, rethrowCreateInputError, rootWriteInput } from "./root-create-input.js";
|
|
108
|
+
import { assertFinalSymlinkRejected, mutationSymlinkResolution, readSymlinkResolution } from "./root-symlink-policy.js";
|
|
109
|
+
import { assertNoWindowsPathAlias, resolvePathPreservingWindowsRoot } from "./windows-path-alias.js";
|
|
110
|
+
import { resolvePinnedObservedPathInRoot } from "./root-observed-path.js";
|
|
111
|
+
import { registerFileLockSyncRootAdapter } from "./file-lock-sync-root.js";
|
|
112
|
+
import { mergeReadOptions, readDefaults, } from "./root-options.js";
|
|
113
|
+
import { composeMutationAssertions, MutationAuthorityError, rethrowMutationAuthorityError } from "./mutation-authority.js";
|
|
114
|
+
export { DEFAULT_ROOT_MAX_BYTES } from "./root-options.js";
|
|
34
115
|
export { resolveOpenedFileRealPathForHandle } from "./opened-realpath.js";
|
|
35
116
|
function logWarn(message) {
|
|
36
117
|
if (process.env.FS_SAFE_DEBUG_WARNINGS === "1") {
|
|
@@ -38,8 +119,6 @@ function logWarn(message) {
|
|
|
38
119
|
}
|
|
39
120
|
}
|
|
40
121
|
const SUPPORTS_NOFOLLOW = process.platform !== "win32" && "O_NOFOLLOW" in fsConstants;
|
|
41
|
-
const OPEN_READ_FLAGS = resolveReadOpenFlags();
|
|
42
|
-
const OPEN_READ_FOLLOW_FLAGS = resolveReadOpenFlags({ followSymlinks: true });
|
|
43
122
|
const OPEN_WRITE_EXISTING_FLAGS = fsConstants.O_WRONLY | (SUPPORTS_NOFOLLOW ? fsConstants.O_NOFOLLOW : 0) |
|
|
44
123
|
resolveNonblockingWriteFlag();
|
|
45
124
|
const OPEN_WRITE_CREATE_FLAGS = fsConstants.O_WRONLY |
|
|
@@ -53,22 +132,6 @@ const OPEN_APPEND_CREATE_FLAGS = fsConstants.O_RDWR |
|
|
|
53
132
|
fsConstants.O_CREAT |
|
|
54
133
|
fsConstants.O_EXCL |
|
|
55
134
|
(SUPPORTS_NOFOLLOW ? fsConstants.O_NOFOLLOW : 0);
|
|
56
|
-
export const DEFAULT_ROOT_MAX_BYTES = 16 * 1024 * 1024;
|
|
57
|
-
function pathStatFromStats(stat) {
|
|
58
|
-
return {
|
|
59
|
-
dev: Number(stat.dev),
|
|
60
|
-
gid: Number(stat.gid),
|
|
61
|
-
ino: Number(stat.ino),
|
|
62
|
-
isDirectory: stat.isDirectory(),
|
|
63
|
-
isFile: stat.isFile(),
|
|
64
|
-
isSymbolicLink: stat.isSymbolicLink(),
|
|
65
|
-
mode: stat.mode,
|
|
66
|
-
mtimeMs: stat.mtimeMs,
|
|
67
|
-
nlink: stat.nlink,
|
|
68
|
-
size: stat.size,
|
|
69
|
-
uid: stat.uid,
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
135
|
function openResult(params) {
|
|
73
136
|
return {
|
|
74
137
|
handle: params.handle,
|
|
@@ -79,69 +142,9 @@ function openResult(params) {
|
|
|
79
142
|
};
|
|
80
143
|
}
|
|
81
144
|
async function openVerifiedLocalFile(filePath, options) {
|
|
82
|
-
assertNoUnsafeDeviceReadPath(filePath);
|
|
83
145
|
const fsSafeTestHooks = getFsSafeTestHooks();
|
|
84
|
-
|
|
85
|
-
let observedBeforeOpen = false;
|
|
86
|
-
// Reject directories before opening so we never surface EISDIR to callers (e.g. tool
|
|
87
|
-
// results that get sent to messaging channels). See openclaw/openclaw#31186.
|
|
146
|
+
const { handle, stat, identity, preOpenStat } = await openLocalFileDescriptor(filePath, options);
|
|
88
147
|
try {
|
|
89
|
-
preOpenStat = await inspectFileIdentity(async () => {
|
|
90
|
-
const stat = fsSync.lstatSync(filePath, { bigint: true });
|
|
91
|
-
observedBeforeOpen = true;
|
|
92
|
-
if (stat.isSymbolicLink() && options?.symlinks !== "follow-within-root") {
|
|
93
|
-
throw new FsSafeError("symlink", "symlink not allowed");
|
|
94
|
-
}
|
|
95
|
-
if (!stat.isFile() && !stat.isSymbolicLink()) {
|
|
96
|
-
throw new FsSafeError("not-file", "not a file");
|
|
97
|
-
}
|
|
98
|
-
return stat;
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
catch (err) {
|
|
102
|
-
if (err instanceof FsSafeError || observedBeforeOpen) {
|
|
103
|
-
throw err;
|
|
104
|
-
}
|
|
105
|
-
// Only an initial lookup failure falls through; a failed re-inspection aborts.
|
|
106
|
-
}
|
|
107
|
-
if (preOpenStat) {
|
|
108
|
-
await fsSafeTestHooks?.afterPreOpenLstat?.(filePath);
|
|
109
|
-
}
|
|
110
|
-
const openFlags = options?.symlinks === "follow-within-root"
|
|
111
|
-
? OPEN_READ_FOLLOW_FLAGS
|
|
112
|
-
: OPEN_READ_FLAGS;
|
|
113
|
-
await fsSafeTestHooks?.beforeOpen?.(filePath, openFlags);
|
|
114
|
-
let handle;
|
|
115
|
-
try {
|
|
116
|
-
handle = await fs.open(filePath, openFlags).catch((error) => recordFileOpenFailure(isNotFoundPathError(error) ? fileNotFoundError() : error, filePath));
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
if (isSymlinkOpenError(err)) {
|
|
120
|
-
throw new FsSafeError("symlink", "symlink open blocked", { cause: err });
|
|
121
|
-
}
|
|
122
|
-
// Defensive: if open still throws EISDIR (e.g. race), sanitize so it never leaks.
|
|
123
|
-
if (hasNodeErrorCode(err, "EISDIR")) {
|
|
124
|
-
throw new FsSafeError("not-file", "not a file");
|
|
125
|
-
}
|
|
126
|
-
throw err;
|
|
127
|
-
}
|
|
128
|
-
try {
|
|
129
|
-
await fsSafeTestHooks?.afterOpen?.(filePath, handle);
|
|
130
|
-
const stat = fsSync.fstatSync(handle.fd);
|
|
131
|
-
if (!stat.isFile()) {
|
|
132
|
-
throw new FsSafeError("not-file", "not a file");
|
|
133
|
-
}
|
|
134
|
-
// Keep numeric Stats for the public receipt, never for identity verification.
|
|
135
|
-
let openedIdentity;
|
|
136
|
-
const identity = await inspectFileIdentity(async () => (openedIdentity = fsSync.fstatSync(handle.fd, { bigint: true })), preOpenStat && !preOpenStat.isSymbolicLink() ? preOpenStat : undefined).catch(async (error) => {
|
|
137
|
-
if ([0, 1].includes(stat.nlink)) {
|
|
138
|
-
await recordPreOpenFileChange(error, handle, filePath, preOpenStat, openedIdentity);
|
|
139
|
-
}
|
|
140
|
-
throw error;
|
|
141
|
-
});
|
|
142
|
-
if (options?.hardlinks === "reject" && stat.nlink > 1) {
|
|
143
|
-
throw hardlinkedPathNotAllowedError();
|
|
144
|
-
}
|
|
145
148
|
const inspectPathIdentity = async (inspect) => {
|
|
146
149
|
try {
|
|
147
150
|
return await inspectFileIdentity(inspect, identity);
|
|
@@ -154,15 +157,7 @@ async function openVerifiedLocalFile(filePath, options) {
|
|
|
154
157
|
throw failure;
|
|
155
158
|
}
|
|
156
159
|
};
|
|
157
|
-
await inspectPathIdentity(async () =>
|
|
158
|
-
const pathStat = options?.symlinks === "follow-within-root"
|
|
159
|
-
? fsSync.statSync(filePath, { bigint: true })
|
|
160
|
-
: fsSync.lstatSync(filePath, { bigint: true });
|
|
161
|
-
if (pathStat.isSymbolicLink() && options?.symlinks !== "follow-within-root") {
|
|
162
|
-
throw new FsSafeError("symlink", "symlink not allowed");
|
|
163
|
-
}
|
|
164
|
-
return pathStat;
|
|
165
|
-
});
|
|
160
|
+
await inspectPathIdentity(async () => inspectOpenedPathIdentitySync(filePath, options?.symlinks));
|
|
166
161
|
await fsSafeTestHooks?.afterOpenedPathIdentityCheck?.(filePath, handle);
|
|
167
162
|
const resolved = await resolveOpenedFileRealPathForFd(handle.fd, identity, filePath)
|
|
168
163
|
.catch(async (error) => {
|
|
@@ -172,6 +167,7 @@ async function openVerifiedLocalFile(filePath, options) {
|
|
|
172
167
|
throw error;
|
|
173
168
|
});
|
|
174
169
|
const { realPath } = resolved;
|
|
170
|
+
assertNoWindowsPathAlias(realPath, "filesystem", "resolved file path uses a Windows filesystem namespace alias");
|
|
175
171
|
let resolvedStat = resolved.stat;
|
|
176
172
|
await inspectPathIdentity(async () => {
|
|
177
173
|
// Reuse the post-realpath observation; unknown Windows identities still
|
|
@@ -191,41 +187,36 @@ async function openVerifiedLocalFile(filePath, options) {
|
|
|
191
187
|
}
|
|
192
188
|
}
|
|
193
189
|
export class RootHandle {
|
|
194
|
-
|
|
190
|
+
context;
|
|
195
191
|
rootDir;
|
|
196
192
|
rootReal;
|
|
197
193
|
rootWithSep;
|
|
198
194
|
defaults;
|
|
199
195
|
constructor(context, defaults = {}) {
|
|
200
|
-
this.
|
|
196
|
+
this.context = context;
|
|
201
197
|
this.rootDir = context.rootDir;
|
|
202
198
|
this.rootReal = context.rootReal;
|
|
203
199
|
this.rootWithSep = context.rootWithSep;
|
|
204
200
|
this.defaults = defaults;
|
|
205
|
-
|
|
206
|
-
get context() {
|
|
207
|
-
return {
|
|
208
|
-
rootDir: this.rootDir,
|
|
209
|
-
rootIdentity: this.rootIdentity,
|
|
210
|
-
rootReal: this.rootReal,
|
|
211
|
-
rootWithSep: this.rootWithSep,
|
|
212
|
-
};
|
|
201
|
+
registerFileLockSyncRootAdapter(this, context, defaults);
|
|
213
202
|
}
|
|
214
203
|
mutationOptions(options) {
|
|
215
204
|
return {
|
|
216
205
|
...options,
|
|
206
|
+
assertBeforeMutation: composeMutationAssertions(this.defaults.assertBeforeMutation, options.assertBeforeMutation),
|
|
207
|
+
mutationSymlinks: options.mutationSymlinks ?? this.defaults.mutationSymlinks,
|
|
217
208
|
denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
|
|
218
209
|
};
|
|
219
210
|
}
|
|
220
211
|
async resolve(relativePath) {
|
|
221
212
|
assertValidRootDestinationPath(relativePath);
|
|
222
|
-
return (await resolvePathInRoot(this.context, relativePath, { allowFinalSymlink: true })).resolved;
|
|
213
|
+
return (await resolvePathInRoot(this.context, relativePath, { allowFinalSymlink: true, resolveCanonical: true })).resolved;
|
|
223
214
|
}
|
|
224
215
|
async open(relativePath, options = {}) {
|
|
225
216
|
return await openFileInRoot(this.context, {
|
|
226
|
-
relativePath,
|
|
227
217
|
...readDefaults(this.defaults),
|
|
228
218
|
...options,
|
|
219
|
+
relativePath,
|
|
229
220
|
});
|
|
230
221
|
}
|
|
231
222
|
async read(relativePath, options = {}) {
|
|
@@ -245,9 +236,11 @@ export class RootHandle {
|
|
|
245
236
|
return JSON.parse(await this.readText(relativePath, options));
|
|
246
237
|
}
|
|
247
238
|
async readAbsolute(filePath, options = {}) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
239
|
+
const context = this.context;
|
|
240
|
+
const readOptions = mergeReadOptions(this.defaults, options);
|
|
241
|
+
return await readFileInRoot(context, {
|
|
242
|
+
relativePath: rootRelativeReadPath(context, filePath),
|
|
243
|
+
...readOptions,
|
|
251
244
|
});
|
|
252
245
|
}
|
|
253
246
|
reader(options = {}) {
|
|
@@ -258,70 +251,80 @@ export class RootHandle {
|
|
|
258
251
|
async openWritable(relativePath, options = {}) {
|
|
259
252
|
assertValidRootDestinationPath(relativePath);
|
|
260
253
|
const writeMode = options.writeMode ?? "replace";
|
|
261
|
-
|
|
262
|
-
relativePath,
|
|
254
|
+
const target = await openWritableFileInRoot(this.context, {
|
|
263
255
|
mkdir: this.defaults.mkdir,
|
|
264
256
|
mode: this.defaults.mode,
|
|
265
257
|
...this.mutationOptions(options),
|
|
258
|
+
relativePath,
|
|
259
|
+
expectedWritePath: undefined,
|
|
266
260
|
append: writeMode === "append",
|
|
267
261
|
truncateExisting: writeMode === "replace",
|
|
268
|
-
});
|
|
262
|
+
}).catch(rethrowMutationAuthorityError);
|
|
263
|
+
return target.opened;
|
|
269
264
|
}
|
|
270
265
|
async append(relativePath, data, options = {}) {
|
|
271
266
|
assertValidRootDestinationPath(relativePath);
|
|
272
267
|
await appendFileInRoot(this.context, {
|
|
273
|
-
relativePath,
|
|
274
|
-
data,
|
|
275
268
|
mkdir: this.defaults.mkdir,
|
|
276
269
|
mode: this.defaults.mode,
|
|
277
270
|
...this.mutationOptions(options),
|
|
271
|
+
relativePath,
|
|
272
|
+
data,
|
|
278
273
|
durable: options.durable ?? this.defaults.durable ?? true,
|
|
279
|
-
});
|
|
274
|
+
}).catch(rethrowMutationAuthorityError);
|
|
280
275
|
}
|
|
281
276
|
async remove(relativePath, options = {}) {
|
|
282
277
|
assertValidRootRelativePath(relativePath);
|
|
278
|
+
validateRemoveOptions(options);
|
|
279
|
+
options.signal?.throwIfAborted();
|
|
283
280
|
await removePathInRoot(this.context, {
|
|
284
|
-
relativePath,
|
|
285
281
|
...this.mutationOptions(options),
|
|
286
|
-
|
|
282
|
+
relativePath,
|
|
283
|
+
}).catch(rethrowMutationAuthorityError);
|
|
287
284
|
}
|
|
288
285
|
async mkdir(relativePath, options = {}) {
|
|
289
286
|
assertValidRootDestinationPath(relativePath);
|
|
290
287
|
await mkdirPathInRoot(this.context, {
|
|
291
|
-
relativePath,
|
|
292
288
|
...this.mutationOptions(options),
|
|
293
|
-
|
|
289
|
+
relativePath,
|
|
290
|
+
allowRoot: false,
|
|
291
|
+
}).catch(rethrowMutationAuthorityError);
|
|
294
292
|
}
|
|
295
293
|
async ensureRoot(options = {}) {
|
|
296
294
|
await mkdirPathInRoot(this.context, {
|
|
295
|
+
...this.mutationOptions(options),
|
|
297
296
|
relativePath: "",
|
|
298
297
|
allowRoot: true,
|
|
299
|
-
|
|
300
|
-
});
|
|
298
|
+
}).catch(rethrowMutationAuthorityError);
|
|
301
299
|
}
|
|
302
300
|
async write(relativePath, data, options = {}) {
|
|
303
301
|
assertValidRootDestinationPath(relativePath);
|
|
304
302
|
await writeFileInRoot(this.context, {
|
|
305
|
-
relativePath,
|
|
306
|
-
data,
|
|
307
303
|
mkdir: this.defaults.mkdir,
|
|
308
304
|
mode: this.defaults.mode,
|
|
309
305
|
renameIdentity: this.defaults.renameIdentity,
|
|
310
306
|
...this.mutationOptions(options),
|
|
307
|
+
atomic: undefined,
|
|
308
|
+
private: undefined,
|
|
309
|
+
strictFileSync: undefined,
|
|
310
|
+
relativePath,
|
|
311
|
+
data,
|
|
311
312
|
durable: options.durable ?? this.defaults.durable ?? true,
|
|
312
|
-
});
|
|
313
|
+
}).catch(rethrowMutationAuthorityError);
|
|
313
314
|
}
|
|
314
315
|
async create(relativePath, data, options = {}) {
|
|
315
316
|
assertValidRootDestinationPath(relativePath);
|
|
317
|
+
const durable = options.durable ?? this.defaults.durable ?? true;
|
|
316
318
|
await writeFileInRoot(this.context, {
|
|
317
|
-
relativePath,
|
|
318
|
-
data,
|
|
319
319
|
mkdir: this.defaults.mkdir,
|
|
320
320
|
mode: this.defaults.mode,
|
|
321
|
-
...this.mutationOptions(options),
|
|
322
|
-
|
|
321
|
+
...this.mutationOptions(createInputOptions(data, options, this.defaults.maxBytes)),
|
|
322
|
+
relativePath,
|
|
323
|
+
data,
|
|
324
|
+
durable: durable !== false,
|
|
325
|
+
strictFileSync: durable === "file",
|
|
323
326
|
overwrite: false,
|
|
324
|
-
});
|
|
327
|
+
}).catch(rethrowMutationAuthorityError).catch(rethrowCreateInputError);
|
|
325
328
|
}
|
|
326
329
|
async writeJson(relativePath, data, options = {}) {
|
|
327
330
|
const { replacer, space, trailingNewline = true, ...writeOptions } = options;
|
|
@@ -333,17 +336,22 @@ export class RootHandle {
|
|
|
333
336
|
const json = stringifyJsonDocument(data, replacer, space);
|
|
334
337
|
await this.create(relativePath, trailingNewline ? `${json}\n` : json, writeOptions);
|
|
335
338
|
}
|
|
336
|
-
async copyIn(relativePath,
|
|
339
|
+
async copyIn(relativePath, source, options = {}) {
|
|
340
|
+
options.signal?.throwIfAborted();
|
|
337
341
|
assertValidRootDestinationPath(relativePath);
|
|
338
342
|
const { maxBytes, ...copyOptions } = this.mutationOptions(options);
|
|
343
|
+
const copySource = typeof source === "string" ? source : { root: source.root, relativePath: source.relativePath };
|
|
339
344
|
await copyFileInRoot(this.context, {
|
|
340
|
-
sourcePath,
|
|
341
|
-
relativePath,
|
|
342
345
|
maxBytes: normalizeMaxBytes(maxBytes, { defaultValue: this.defaults.maxBytes }),
|
|
343
346
|
mkdir: this.defaults.mkdir,
|
|
344
|
-
mode: this.defaults.mode,
|
|
345
347
|
...copyOptions,
|
|
346
|
-
|
|
348
|
+
source: copySource,
|
|
349
|
+
relativePath,
|
|
350
|
+
mode: options.mode ?? this.defaults.mode,
|
|
351
|
+
durable: options.durable ?? this.defaults.durable ?? true,
|
|
352
|
+
verifyPublished: options[onCopyPublication],
|
|
353
|
+
admitSource: options[onCopySourceAdmission],
|
|
354
|
+
}).catch(rethrowMutationAuthorityError);
|
|
347
355
|
}
|
|
348
356
|
async exists(relativePath) {
|
|
349
357
|
try {
|
|
@@ -359,19 +367,23 @@ export class RootHandle {
|
|
|
359
367
|
}
|
|
360
368
|
async stat(relativePath) {
|
|
361
369
|
assertValidRootRelativePath(relativePath);
|
|
362
|
-
|
|
370
|
+
validatePinnedRelativePath(relativePath);
|
|
363
371
|
return await statPathFallback(this.context, relativePath);
|
|
364
372
|
}
|
|
365
373
|
async list(relativePath, options = {}) {
|
|
366
374
|
assertValidRootRelativePath(relativePath);
|
|
367
|
-
|
|
375
|
+
validatePinnedRelativePath(relativePath);
|
|
368
376
|
return await listPathFallback(this.context, relativePath, options.withFileTypes === true);
|
|
369
377
|
}
|
|
370
378
|
async move(fromRelative, toRelative, options = {}) {
|
|
371
379
|
assertValidRootRelativePath(fromRelative);
|
|
372
380
|
assertValidRootDestinationPath(toRelative);
|
|
373
|
-
|
|
374
|
-
|
|
381
|
+
validatePinnedRelativePath(fromRelative);
|
|
382
|
+
validatePinnedRelativePath(toRelative);
|
|
383
|
+
const mutationOptions = this.mutationOptions(options);
|
|
384
|
+
const { assertBeforeMutation } = mutationOptions;
|
|
385
|
+
const { denyMutations, mutationSymlinks } = snapshotPinnedMutationPolicy(mutationOptions.denyMutations, mutationOptions.mutationSymlinks) ?? {};
|
|
386
|
+
const overwrite = options.overwrite ?? false;
|
|
375
387
|
await assertMoveMutationAllowed(this.context, {
|
|
376
388
|
fromRelative,
|
|
377
389
|
toRelative,
|
|
@@ -380,53 +392,71 @@ export class RootHandle {
|
|
|
380
392
|
await movePathFallback(this.context, {
|
|
381
393
|
fromRelative,
|
|
382
394
|
denyMutations,
|
|
383
|
-
|
|
395
|
+
assertBeforeMutation,
|
|
396
|
+
mutationSymlinks,
|
|
397
|
+
overwrite,
|
|
384
398
|
toRelative,
|
|
399
|
+
}).catch(rethrowMutationAuthorityError);
|
|
400
|
+
}
|
|
401
|
+
entries(relativePath, options = {}) {
|
|
402
|
+
assertValidRootRelativePath(relativePath);
|
|
403
|
+
return entriesInRoot(this.context, relativePath, {
|
|
404
|
+
...options,
|
|
405
|
+
symlinks: options.symlinks ?? this.defaults.symlinks,
|
|
385
406
|
});
|
|
386
407
|
}
|
|
387
408
|
walk(relativePath, options) {
|
|
388
409
|
assertValidRootRelativePath(relativePath);
|
|
389
|
-
return walkRoot(
|
|
410
|
+
return walkRoot({
|
|
411
|
+
rootReal: this.context.rootReal,
|
|
412
|
+
stat: relative => this.stat(relative),
|
|
413
|
+
list: async (relative, listingOptions) => {
|
|
414
|
+
validatePinnedRelativePath(relative);
|
|
415
|
+
const resolved = await resolvePinnedPathInRoot(this.context, { relativePath: relative, allowRoot: true });
|
|
416
|
+
return await openRootDirectoryListing(this.context, resolved.resolved, listingOptions);
|
|
417
|
+
},
|
|
418
|
+
}, relativePath, options);
|
|
390
419
|
}
|
|
391
420
|
}
|
|
392
|
-
function readDefaults(defaults) {
|
|
393
|
-
return {
|
|
394
|
-
hardlinks: defaults.hardlinks,
|
|
395
|
-
maxBytes: normalizeMaxBytes(defaults.maxBytes, { defaultValue: DEFAULT_ROOT_MAX_BYTES }),
|
|
396
|
-
symlinks: defaults.symlinks,
|
|
397
|
-
};
|
|
398
|
-
}
|
|
399
|
-
function mergeReadOptions(defaults, options) {
|
|
400
|
-
const merged = readDefaults(defaults);
|
|
401
|
-
if (options.hardlinks !== undefined)
|
|
402
|
-
merged.hardlinks = options.hardlinks;
|
|
403
|
-
merged.maxBytes = normalizeMaxBytes(options.maxBytes, { defaultValue: merged.maxBytes });
|
|
404
|
-
if (options.symlinks !== undefined)
|
|
405
|
-
merged.symlinks = options.symlinks;
|
|
406
|
-
return merged;
|
|
407
|
-
}
|
|
408
421
|
export async function root(rootDir, defaults = {}) {
|
|
409
422
|
normalizeMaxBytes(defaults.maxBytes);
|
|
410
423
|
return new RootHandle(await resolveRootContext(rootDir), defaults);
|
|
411
424
|
}
|
|
425
|
+
// Internal callers that already hold an exact admitted directory capability must
|
|
426
|
+
// not recapture a different filesystem object while constructing the Root.
|
|
427
|
+
export function rootFromDirectoryGuard(guard, defaults = {}) {
|
|
428
|
+
normalizeMaxBytes(defaults.maxBytes);
|
|
429
|
+
return new RootHandle({
|
|
430
|
+
rootDir: resolvePathPreservingWindowsRoot(guard.dir),
|
|
431
|
+
rootGuard: { dir: guard.realPath, realPath: guard.realPath, stat: guard.stat },
|
|
432
|
+
rootIdentity: { dev: guard.stat.dev, ino: guard.stat.ino },
|
|
433
|
+
rootReal: guard.realPath,
|
|
434
|
+
rootWithSep: ensureTrailingSep(guard.realPath),
|
|
435
|
+
}, defaults);
|
|
436
|
+
}
|
|
412
437
|
async function openFileInRoot(root, params) {
|
|
413
|
-
const {
|
|
438
|
+
const { resolved } = await resolvePathInRoot(root, params.relativePath, {
|
|
414
439
|
allowFinalSymlink: true,
|
|
415
440
|
rejectUnsafeDeviceReads: true,
|
|
416
|
-
|
|
441
|
+
...readSymlinkResolution(params.symlinks),
|
|
442
|
+
resolveCanonical: true,
|
|
417
443
|
});
|
|
418
|
-
const
|
|
444
|
+
const fsSafeTestHooks = getFsSafeTestHooks();
|
|
445
|
+
if (fsSafeTestHooks?.afterRootReadPathResolution) {
|
|
446
|
+
await fsSafeTestHooks.afterRootReadPathResolution(resolved);
|
|
447
|
+
}
|
|
448
|
+
const { handle, stat, identity } = await openLocalFileDescriptor(resolved, {
|
|
419
449
|
symlinks: params.symlinks,
|
|
420
450
|
});
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
}
|
|
429
|
-
return
|
|
451
|
+
// The admission helper owns the descriptor until the complete root/file/root
|
|
452
|
+
// fence succeeds, then transfers that still-open handle to the caller.
|
|
453
|
+
const admitted = await admitRootReadHandle({
|
|
454
|
+
root, filePath: resolved, opened: { handle, stat }, identity,
|
|
455
|
+
hardlinks: params.hardlinks, symlinks: params.symlinks,
|
|
456
|
+
beforeFinalFence: fsSafeTestHooks?.beforeRootReadFinalFence,
|
|
457
|
+
afterPathIdentityCheck: fsSafeTestHooks?.afterRootReadFinalPathIdentityCheck,
|
|
458
|
+
});
|
|
459
|
+
return openResult(admitted);
|
|
430
460
|
}
|
|
431
461
|
async function readFileInRoot(root, params) {
|
|
432
462
|
const opened = await openFileInRoot(root, params);
|
|
@@ -437,15 +467,6 @@ async function readFileInRoot(root, params) {
|
|
|
437
467
|
await opened.handle.close().catch(() => { });
|
|
438
468
|
}
|
|
439
469
|
}
|
|
440
|
-
async function readPathInRoot(root, params) {
|
|
441
|
-
const relativePath = rootRelativeReadPath(root, params.filePath);
|
|
442
|
-
return await readFileInRoot(root, {
|
|
443
|
-
relativePath,
|
|
444
|
-
hardlinks: params.hardlinks,
|
|
445
|
-
maxBytes: params.maxBytes,
|
|
446
|
-
symlinks: params.symlinks,
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
470
|
export async function readLocalFileSafely(params) {
|
|
450
471
|
const maxBytes = normalizeMaxBytes(params.maxBytes);
|
|
451
472
|
const opened = await openLocalFileSafely({ filePath: params.filePath });
|
|
@@ -457,8 +478,10 @@ export async function readLocalFileSafely(params) {
|
|
|
457
478
|
}
|
|
458
479
|
}
|
|
459
480
|
export async function openLocalFileSafely(params) {
|
|
460
|
-
|
|
461
|
-
|
|
481
|
+
const filePath = params.filePath;
|
|
482
|
+
assertNoNulPathInput(filePath, "file path contains a NUL byte");
|
|
483
|
+
assertNoWindowsPathAlias(filePath, "filesystem", "file path uses a Windows filesystem namespace alias");
|
|
484
|
+
return (await openVerifiedLocalFile(filePath)).opened;
|
|
462
485
|
}
|
|
463
486
|
function emitWriteBoundaryWarning(reason) {
|
|
464
487
|
logWarn(`security: fs-safe write boundary warning (${reason})`);
|
|
@@ -469,70 +492,37 @@ function buildAtomicWriteTempPath(targetPath) {
|
|
|
469
492
|
function rootWriteQueueKey(root, relativePath) {
|
|
470
493
|
return `${root.rootReal}\0${relativePath}`;
|
|
471
494
|
}
|
|
472
|
-
async function
|
|
473
|
-
const
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
}
|
|
481
|
-
async function writeTempFileForAtomicReplace(params) {
|
|
482
|
-
const tempHandle = await fs.open(params.tempPath, OPEN_WRITE_CREATE_FLAGS, params.mode);
|
|
483
|
-
try {
|
|
484
|
-
if (typeof params.data === "string") {
|
|
485
|
-
await tempHandle.writeFile(params.data, params.encoding ?? "utf8");
|
|
486
|
-
}
|
|
487
|
-
else {
|
|
488
|
-
await tempHandle.writeFile(params.data);
|
|
489
|
-
}
|
|
490
|
-
return {
|
|
491
|
-
handle: tempHandle,
|
|
492
|
-
identity: fsSync.fstatSync(tempHandle.fd, { bigint: true }),
|
|
493
|
-
};
|
|
494
|
-
}
|
|
495
|
-
catch (error) {
|
|
496
|
-
await tempHandle.close().catch(() => { });
|
|
497
|
-
throw error;
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
async function resolveGuardedWritePathInRoot(root, params) {
|
|
501
|
-
const resolvedPath = await resolvePathInRoot(root, params.relativePath, {
|
|
502
|
-
aliasErrorCode: "path-alias",
|
|
503
|
-
allowFinalSymlink: params.allowFinalSymlink,
|
|
504
|
-
});
|
|
505
|
-
await assertMutationNotDenied(resolvedPath.resolved, params.denyMutations, params.protectDeniedAncestors ? { protectAncestors: true } : undefined);
|
|
506
|
-
if (await (params.shouldAssertNoPathAlias?.(resolvedPath) ?? true)) {
|
|
507
|
-
try {
|
|
508
|
-
await assertNoPathAliasEscape({
|
|
509
|
-
absolutePath: resolvedPath.resolved,
|
|
510
|
-
rootPath: resolvedPath.rootReal,
|
|
511
|
-
boundaryLabel: "root",
|
|
512
|
-
});
|
|
513
|
-
}
|
|
514
|
-
catch (error) {
|
|
515
|
-
throw new FsSafeError("path-alias", "path alias escape blocked", {
|
|
516
|
-
cause: error instanceof Error ? error : undefined,
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
return resolvedPath;
|
|
521
|
-
}
|
|
522
|
-
async function openWritableFileInRoot(root, params) {
|
|
523
|
-
const { rootReal, rootWithSep, resolved } = await resolveGuardedWritePathInRoot(root, {
|
|
495
|
+
async function openWritableFileInRoot(root, params, options) {
|
|
496
|
+
const guardedTarget = params.denyMutations === undefined && params.mutationSymlinks === undefined
|
|
497
|
+
? undefined
|
|
498
|
+
: await resolveGuardedWriteTargetInRoot(root, {
|
|
499
|
+
relativePath: params.relativePath,
|
|
500
|
+
denyMutations: params.denyMutations,
|
|
501
|
+
mutationSymlinks: params.mutationSymlinks,
|
|
502
|
+
});
|
|
503
|
+
const { resolved } = guardedTarget?.resolvedPath ?? await resolveGuardedWritePathInRoot(root, {
|
|
524
504
|
relativePath: params.relativePath,
|
|
525
|
-
denyMutations: params.denyMutations,
|
|
526
505
|
});
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
:
|
|
506
|
+
const prepared = guardedTarget ? await prepareSharedRootWriteTarget(root, {
|
|
507
|
+
relativePath: params.relativePath, guardedTarget, mkdir: params.mkdir,
|
|
508
|
+
assertBeforeMutation: params.assertBeforeMutation,
|
|
509
|
+
}) : undefined;
|
|
510
|
+
const preparedParent = prepared?.preparedParent;
|
|
511
|
+
let ioPath = prepared?.targetPath ?? (params.mkdir === false ? resolved :
|
|
512
|
+
await prepareRootWriteTarget(root, resolved, params.assertBeforeMutation));
|
|
513
|
+
const operationTargetPath = ioPath;
|
|
530
514
|
try {
|
|
531
|
-
|
|
532
|
-
|
|
515
|
+
assertFinalSymlinkRejected(ioPath, params.mutationSymlinks !== undefined);
|
|
516
|
+
const resolvedRealPath = params.mutationSymlinks === undefined ? realpathSync.native(ioPath) : ioPath;
|
|
517
|
+
const admittedRealPath = admitPathInsideRoot({
|
|
518
|
+
rootPath: root.rootReal,
|
|
519
|
+
candidatePath: resolvedRealPath,
|
|
520
|
+
rootIdentity: root.rootIdentity,
|
|
521
|
+
});
|
|
522
|
+
if (!admittedRealPath) {
|
|
533
523
|
throw outsideWorkspaceError();
|
|
534
524
|
}
|
|
535
|
-
ioPath =
|
|
525
|
+
ioPath = admittedRealPath.path;
|
|
536
526
|
}
|
|
537
527
|
catch (err) {
|
|
538
528
|
if (err instanceof FsSafeError) {
|
|
@@ -542,13 +532,20 @@ async function openWritableFileInRoot(root, params) {
|
|
|
542
532
|
throw err;
|
|
543
533
|
}
|
|
544
534
|
}
|
|
535
|
+
assertRootFallbackWritePath(params.expectedWritePath, ioPath);
|
|
545
536
|
const mode = params.mode ?? 0o600;
|
|
546
537
|
let handle;
|
|
547
538
|
let createdForWrite = false;
|
|
539
|
+
let writePathSelection = undefined;
|
|
548
540
|
const existingFlags = params.append ? OPEN_APPEND_EXISTING_FLAGS : OPEN_WRITE_EXISTING_FLAGS;
|
|
549
541
|
const createFlags = params.append ? OPEN_APPEND_CREATE_FLAGS : OPEN_WRITE_CREATE_FLAGS;
|
|
550
542
|
try {
|
|
543
|
+
writePathSelection = guardedTarget
|
|
544
|
+
? await prepareGuardedRootWritePathSelection(guardedTarget, ioPath, operationTargetPath, preparedParent)
|
|
545
|
+
: undefined;
|
|
551
546
|
try {
|
|
547
|
+
if (writePathSelection)
|
|
548
|
+
assertRootWritePathSelectionSync(root, writePathSelection);
|
|
552
549
|
handle = await fs.open(ioPath, existingFlags, mode);
|
|
553
550
|
}
|
|
554
551
|
catch (err) {
|
|
@@ -558,6 +555,22 @@ async function openWritableFileInRoot(root, params) {
|
|
|
558
555
|
if (!isNotFoundPathError(err)) {
|
|
559
556
|
throw err;
|
|
560
557
|
}
|
|
558
|
+
if (options?.createIfMissing === false) {
|
|
559
|
+
const parentGuard = writePathSelection?.parentGuard ??
|
|
560
|
+
await createAsyncDirectoryGuard(path.dirname(ioPath), { bigint: true });
|
|
561
|
+
assertRootIdentityCurrentSync(root);
|
|
562
|
+
if (!admitPathInsideRoot({
|
|
563
|
+
rootPath: root.rootReal, candidatePath: parentGuard.realPath, rootIdentity: root.rootIdentity,
|
|
564
|
+
}))
|
|
565
|
+
throw outsideWorkspaceError();
|
|
566
|
+
assertSyncDirectoryGuard(parentGuard);
|
|
567
|
+
return { missing: true, targetPath: ioPath, parentGuard, writeSelection: writePathSelection };
|
|
568
|
+
}
|
|
569
|
+
if (writePathSelection)
|
|
570
|
+
await refreshRootWritePathSelection(writePathSelection);
|
|
571
|
+
params.assertBeforeMutation?.();
|
|
572
|
+
if (writePathSelection)
|
|
573
|
+
assertRootWritePathSelectionSync(root, writePathSelection);
|
|
561
574
|
handle = await fs.open(ioPath, createFlags, mode);
|
|
562
575
|
createdForWrite = true;
|
|
563
576
|
}
|
|
@@ -578,47 +591,91 @@ async function openWritableFileInRoot(root, params) {
|
|
|
578
591
|
let createdIdentity = null;
|
|
579
592
|
try {
|
|
580
593
|
const stat = fsSync.fstatSync(handle.fd);
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
throw new FsSafeError("not-file", "path is not a regular file under root");
|
|
586
|
-
}
|
|
587
|
-
if (stat.nlink > 1) {
|
|
588
|
-
throw hardlinkedPathNotAllowedError();
|
|
589
|
-
}
|
|
590
|
-
try {
|
|
591
|
-
const lstat = fsSync.lstatSync(ioPath);
|
|
592
|
-
if (lstat.isSymbolicLink() || !lstat.isFile()) {
|
|
593
|
-
throw new FsSafeError(lstat.isSymbolicLink() ? "symlink" : "not-file", "path is not a regular file under root");
|
|
594
|
-
}
|
|
595
|
-
if (!sameFileIdentity(stat, lstat)) {
|
|
596
|
-
throw new FsSafeError("path-mismatch", "path changed during write");
|
|
594
|
+
const identity = inspectFileIdentitySync(() => {
|
|
595
|
+
const observed = fsSync.fstatSync(handle.fd, { bigint: true });
|
|
596
|
+
if (!observed.isFile()) {
|
|
597
|
+
throw new FsSafeError("not-file", "path is not a regular file under root");
|
|
597
598
|
}
|
|
599
|
+
if (observed.nlink > 1n)
|
|
600
|
+
throw hardlinkedPathNotAllowedError();
|
|
601
|
+
return observed;
|
|
602
|
+
});
|
|
603
|
+
if (createdForWrite)
|
|
604
|
+
createdIdentity = identity;
|
|
605
|
+
let observedIoPath = false;
|
|
606
|
+
try {
|
|
607
|
+
inspectFileIdentitySync(() => {
|
|
608
|
+
const lstat = fsSync.lstatSync(ioPath, { bigint: true });
|
|
609
|
+
observedIoPath = true;
|
|
610
|
+
if (lstat.isSymbolicLink() || !lstat.isFile()) {
|
|
611
|
+
throw new FsSafeError(lstat.isSymbolicLink() ? "symlink" : "not-file", "path is not a regular file under root");
|
|
612
|
+
}
|
|
613
|
+
if (lstat.nlink > 1n)
|
|
614
|
+
throw hardlinkedPathNotAllowedError();
|
|
615
|
+
return lstat;
|
|
616
|
+
}, identity);
|
|
598
617
|
}
|
|
599
618
|
catch (err) {
|
|
600
|
-
if (
|
|
619
|
+
if (isNotFoundPathError(err) && !observedIoPath) {
|
|
620
|
+
// The opened file may have been renamed before its first pathname
|
|
621
|
+
// observation. The descriptor-bound resolver below must still find it.
|
|
622
|
+
}
|
|
623
|
+
else if (err instanceof FsSafeError && err.code === "path-mismatch") {
|
|
624
|
+
throw new FsSafeError("path-mismatch", "path changed during write", { cause: err });
|
|
625
|
+
}
|
|
626
|
+
else {
|
|
601
627
|
throw err;
|
|
602
628
|
}
|
|
603
629
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
630
|
+
let realPath = (await resolveOpenedFileRealPathForFd(handle.fd, identity, ioPath)).realPath;
|
|
631
|
+
assertNoWindowsPathAlias(realPath, "filesystem", "resolved file path uses a Windows filesystem namespace alias");
|
|
632
|
+
try {
|
|
633
|
+
inspectFileIdentitySync(() => {
|
|
634
|
+
const realStat = fsSync.statSync(realPath, { bigint: true });
|
|
635
|
+
if (!realStat.isFile()) {
|
|
636
|
+
throw new FsSafeError("not-file", "path is not a regular file under root");
|
|
637
|
+
}
|
|
638
|
+
if (realStat.nlink > 1n)
|
|
639
|
+
throw hardlinkedPathNotAllowedError();
|
|
640
|
+
return realStat;
|
|
641
|
+
}, identity);
|
|
609
642
|
}
|
|
610
|
-
|
|
611
|
-
|
|
643
|
+
catch (err) {
|
|
644
|
+
if (err instanceof FsSafeError && err.code === "path-mismatch") {
|
|
645
|
+
throw new FsSafeError("path-mismatch", "path mismatch", { cause: err });
|
|
646
|
+
}
|
|
647
|
+
throw err;
|
|
612
648
|
}
|
|
613
|
-
|
|
649
|
+
const admittedRealPath = admitPathInsideRoot({
|
|
650
|
+
rootPath: root.rootReal,
|
|
651
|
+
candidatePath: realPath,
|
|
652
|
+
rootIdentity: root.rootIdentity,
|
|
653
|
+
});
|
|
654
|
+
if (!admittedRealPath) {
|
|
614
655
|
throw outsideWorkspaceError();
|
|
615
656
|
}
|
|
657
|
+
realPath = admittedRealPath.path;
|
|
658
|
+
realPathForCleanup = realPath;
|
|
659
|
+
assertRootFallbackWritePath(params.expectedWritePath, realPath);
|
|
660
|
+
const writeSelection = writePathSelection
|
|
661
|
+
? createRootWriteSelectionForFd(writePathSelection, handle.fd)
|
|
662
|
+
: undefined;
|
|
616
663
|
// Truncate only after boundary and identity checks complete. This avoids
|
|
617
664
|
// irreversible side effects if a symlink target changes before validation.
|
|
618
665
|
if (params.append !== true && params.truncateExisting !== false && !createdForWrite) {
|
|
666
|
+
if (writeSelection)
|
|
667
|
+
await refreshRetainedRootWriteAdmission(root, writeSelection, true, handle.fd);
|
|
668
|
+
assertFinalSymlinkRejected(ioPath, params.mutationSymlinks !== undefined);
|
|
669
|
+
params.assertBeforeMutation?.();
|
|
670
|
+
if (writeSelection)
|
|
671
|
+
assertRootWriteSelectionSync(root, writeSelection, true, handle.fd);
|
|
619
672
|
await handle.truncate(0);
|
|
620
673
|
}
|
|
621
|
-
|
|
674
|
+
if (writeSelection) {
|
|
675
|
+
await refreshRetainedRootWriteAdmission(root, writeSelection, true, handle.fd);
|
|
676
|
+
assertRootWriteSelectionSync(root, writeSelection, true, handle.fd);
|
|
677
|
+
}
|
|
678
|
+
const result = {
|
|
622
679
|
handle,
|
|
623
680
|
containment: "best-effort",
|
|
624
681
|
createdForWrite,
|
|
@@ -626,6 +683,7 @@ async function openWritableFileInRoot(root, params) {
|
|
|
626
683
|
stat,
|
|
627
684
|
[Symbol.asyncDispose]: () => handle.close().catch(() => undefined),
|
|
628
685
|
};
|
|
686
|
+
return { opened: result, identity, writeSelection };
|
|
629
687
|
}
|
|
630
688
|
catch (err) {
|
|
631
689
|
const cleanupCreatedPath = createdForWrite && err instanceof FsSafeError;
|
|
@@ -638,96 +696,179 @@ async function openWritableFileInRoot(root, params) {
|
|
|
638
696
|
}
|
|
639
697
|
}
|
|
640
698
|
async function appendFileInRoot(root, params) {
|
|
641
|
-
const
|
|
642
|
-
relativePath: params.relativePath,
|
|
643
|
-
mkdir: params.mkdir,
|
|
644
|
-
mode: params.mode,
|
|
645
|
-
denyMutations: params.denyMutations,
|
|
646
|
-
truncateExisting: false,
|
|
647
|
-
append: true,
|
|
648
|
-
});
|
|
699
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
649
700
|
try {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
701
|
+
const { opened: target, identity } = await openWritableFileInRoot(root, {
|
|
702
|
+
relativePath: params.relativePath,
|
|
703
|
+
mkdir: params.mkdir,
|
|
704
|
+
mode: params.mode,
|
|
705
|
+
denyMutations: params.denyMutations,
|
|
706
|
+
assertBeforeMutation: params.assertBeforeMutation,
|
|
707
|
+
mutationSymlinks: params.mutationSymlinks,
|
|
708
|
+
truncateExisting: false,
|
|
709
|
+
append: true,
|
|
710
|
+
});
|
|
711
|
+
let dispatched = false;
|
|
712
|
+
// Reverse disposal order closes the handle before path cleanup and retains both failures.
|
|
713
|
+
const cleanup = __addDisposableResource(env_1, {
|
|
714
|
+
async [Symbol.asyncDispose]() {
|
|
715
|
+
if (!dispatched && target.createdForWrite) {
|
|
716
|
+
await removePathIfIdentityUnchanged(target.realPath, identity);
|
|
717
|
+
}
|
|
718
|
+
},
|
|
719
|
+
}, true);
|
|
720
|
+
const handle = __addDisposableResource(env_1, target.handle, true);
|
|
721
|
+
try {
|
|
722
|
+
let prefix = "";
|
|
723
|
+
if (params.prependNewlineIfNeeded === true &&
|
|
724
|
+
!target.createdForWrite &&
|
|
725
|
+
target.stat.size > 0 &&
|
|
726
|
+
params.data.length > 0 &&
|
|
727
|
+
((typeof params.data === "string" && !params.data.startsWith("\n")) ||
|
|
728
|
+
(Buffer.isBuffer(params.data) && params.data[0] !== 0x0a))) {
|
|
729
|
+
const newline = Buffer.from("\n", typeof params.data === "string" ? params.encoding : "utf8");
|
|
730
|
+
const tail = Buffer.alloc(newline.length);
|
|
731
|
+
const { bytesRead } = await target.handle.read(tail, 0, tail.length, Math.max(0, target.stat.size - tail.length));
|
|
732
|
+
if (bytesRead > 0 && (bytesRead !== newline.length || !tail.equals(newline))) {
|
|
733
|
+
prefix = "\n";
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
const payload = typeof params.data === "string" ? `${prefix}${params.data}`
|
|
737
|
+
: prefix.length > 0 ? Buffer.concat([Buffer.from(prefix, "utf8"), params.data]) : params.data;
|
|
738
|
+
await writeAllToFile(target.handle, payload, {
|
|
739
|
+
encoding: params.encoding,
|
|
740
|
+
assertBeforeMutation: () => {
|
|
741
|
+
assertFinalSymlinkRejected(target.realPath, params.mutationSymlinks !== undefined);
|
|
742
|
+
params.assertBeforeMutation?.();
|
|
743
|
+
dispatched = true;
|
|
744
|
+
},
|
|
745
|
+
});
|
|
746
|
+
// A successful empty append still creates the file, as Node's appendFile does.
|
|
747
|
+
dispatched = true;
|
|
748
|
+
if (params.durable !== false)
|
|
749
|
+
await target.handle.sync();
|
|
750
|
+
if (params.durable !== false && target.createdForWrite) {
|
|
751
|
+
await syncDirectoryBestEffort(path.dirname(target.realPath));
|
|
660
752
|
}
|
|
661
753
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
}
|
|
665
|
-
else {
|
|
666
|
-
const payload = prefix.length > 0 ? Buffer.concat([Buffer.from(prefix, "utf8"), params.data]) : params.data;
|
|
667
|
-
await target.handle.appendFile(payload);
|
|
668
|
-
}
|
|
669
|
-
if (params.durable !== false)
|
|
670
|
-
await target.handle.sync();
|
|
671
|
-
if (params.durable !== false && target.createdForWrite) {
|
|
672
|
-
await syncDirectoryBestEffort(path.dirname(target.realPath));
|
|
754
|
+
catch (error) {
|
|
755
|
+
rethrowMutationAuthorityError(error);
|
|
673
756
|
}
|
|
674
757
|
}
|
|
758
|
+
catch (e_1) {
|
|
759
|
+
env_1.error = e_1;
|
|
760
|
+
env_1.hasError = true;
|
|
761
|
+
}
|
|
675
762
|
finally {
|
|
676
|
-
|
|
763
|
+
const result_1 = __disposeResources(env_1);
|
|
764
|
+
if (result_1)
|
|
765
|
+
await result_1;
|
|
677
766
|
}
|
|
678
767
|
}
|
|
679
768
|
async function removePathInRoot(root, params) {
|
|
680
|
-
|
|
769
|
+
validatePinnedRelativePath(params.relativePath);
|
|
770
|
+
const removalReceipts = params.recursive ? undefined : new RemovalPathReceipts();
|
|
681
771
|
const resolved = await resolvePinnedPathInRoot(root, {
|
|
682
772
|
relativePath: params.relativePath,
|
|
683
773
|
denyMutations: params.denyMutations,
|
|
774
|
+
mutationSymlinks: params.mutationSymlinks,
|
|
684
775
|
remove: true,
|
|
776
|
+
removalReceipts,
|
|
685
777
|
});
|
|
686
778
|
try {
|
|
687
|
-
await
|
|
779
|
+
await removePathInRootFallback(root, resolved.resolved, params, removalReceipts);
|
|
688
780
|
}
|
|
689
781
|
catch (error) {
|
|
782
|
+
if (params.recursive)
|
|
783
|
+
throw error;
|
|
690
784
|
throw normalizePinnedPathError(error);
|
|
691
785
|
}
|
|
692
786
|
}
|
|
693
787
|
async function mkdirPathInRoot(root, params) {
|
|
694
|
-
|
|
695
|
-
|
|
788
|
+
const privateMode = resolveCreationPermissions(params, true).private;
|
|
789
|
+
validatePinnedRelativePath(params.relativePath);
|
|
790
|
+
const policy = params.denyMutations === undefined && params.mutationSymlinks === undefined
|
|
791
|
+
? undefined
|
|
792
|
+
: snapshotPinnedMutationPolicy(params.denyMutations, params.mutationSymlinks);
|
|
793
|
+
const resolution = { relativePath: params.relativePath, allowRoot: params.allowRoot, ...policy };
|
|
794
|
+
const resolveCurrent = policy
|
|
795
|
+
? async () => await resolvePinnedPathInRoot(root, resolution)
|
|
796
|
+
: undefined;
|
|
797
|
+
const resolved = await resolvePinnedPathInRoot(root, resolution);
|
|
798
|
+
const prepared = policy && resolved.relativePosix !== ""
|
|
799
|
+
? await preparePinnedWriteMutationAdmission({
|
|
800
|
+
rootReal: resolved.rootReal,
|
|
801
|
+
rootWithSep: ensureTrailingSep(resolved.rootReal),
|
|
802
|
+
rootIdentity: root.rootIdentity,
|
|
803
|
+
resolvedTargetPath: resolved.resolved,
|
|
804
|
+
originalPath: params.relativePath,
|
|
805
|
+
defaultRelativeParentPath: path.posix.dirname(resolved.relativePosix) === "."
|
|
806
|
+
? ""
|
|
807
|
+
: path.posix.dirname(resolved.relativePosix),
|
|
808
|
+
policy,
|
|
809
|
+
resolveCurrent: resolveCurrent,
|
|
810
|
+
})
|
|
811
|
+
: undefined;
|
|
812
|
+
if (prepared?.mutationAdmission) {
|
|
813
|
+
await getFsSafeTestHooks()?.beforePinnedWriteParentAdmission?.(resolved.resolved);
|
|
814
|
+
}
|
|
696
815
|
try {
|
|
697
|
-
|
|
816
|
+
if (!privateMode && prepared?.mutationAdmission && params.assertBeforeMutation === undefined &&
|
|
817
|
+
await tryMkdirAtExactParent(root, resolved.resolved, prepared.mutationAdmission))
|
|
818
|
+
return;
|
|
819
|
+
await mkdirPathFallback(root, resolved, params.assertBeforeMutation, policy?.mutationSymlinks !== undefined, prepared?.mutationAdmission, privateMode);
|
|
698
820
|
}
|
|
699
821
|
catch (error) {
|
|
700
822
|
throw normalizePinnedPathError(error);
|
|
701
823
|
}
|
|
702
824
|
}
|
|
703
825
|
async function writeFileInRoot(root, params) {
|
|
826
|
+
if (params.private !== undefined) {
|
|
827
|
+
const permissions = resolveCreationPermissions(params, false);
|
|
828
|
+
params = { ...params, private: permissions.private, mode: permissions.mode };
|
|
829
|
+
}
|
|
830
|
+
const input = rootWriteInput(params);
|
|
704
831
|
await serializePathWrite(rootWriteQueueKey(root, params.relativePath), async () => {
|
|
705
|
-
if (process.platform === "win32" &&
|
|
832
|
+
if (!params.private && input.kind === "buffer" && !input.stageBeforePublish && process.platform === "win32" &&
|
|
706
833
|
(params.renameIdentity === "verify-content-with-lock" || !getNativeBinding())) {
|
|
707
|
-
await writeFileFallback(root, params);
|
|
834
|
+
await writeFileFallback(root, { ...params, data: input.data });
|
|
708
835
|
return;
|
|
709
836
|
}
|
|
710
|
-
const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode, params.denyMutations, params.overwrite);
|
|
837
|
+
const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode, params.denyMutations, params.overwrite, params.mutationSymlinks);
|
|
711
838
|
await serializePathWrite(pinned.targetPath, async () => {
|
|
712
|
-
await commitPinnedWriteInRoot(root, pinned, params);
|
|
839
|
+
await commitPinnedWriteInRoot(root, pinned, params, input);
|
|
713
840
|
});
|
|
714
841
|
});
|
|
715
842
|
}
|
|
716
|
-
async function commitPinnedWriteInRoot(root, pinned, params) {
|
|
843
|
+
async function commitPinnedWriteInRoot(root, pinned, params, input) {
|
|
717
844
|
let verifyingPublication = false;
|
|
718
845
|
try {
|
|
846
|
+
if (params.private)
|
|
847
|
+
assertPrivateFileCreationAvailable();
|
|
848
|
+
if (params.private && params.mkdir !== false) {
|
|
849
|
+
const target = await prepareRootWriteTarget(root, pinned.targetPath, params.assertBeforeMutation, pinned.mutationAdmission, true);
|
|
850
|
+
if (target !== pinned.targetPath) {
|
|
851
|
+
throw new FsSafeError("path-mismatch", "private creation parent changed during admission");
|
|
852
|
+
}
|
|
853
|
+
}
|
|
719
854
|
await runPinnedWriteWithRenamePolicy({
|
|
720
855
|
rootPath: pinned.rootReal,
|
|
721
856
|
relativeParentPath: pinned.relativeParentPath,
|
|
722
857
|
basename: pinned.basename,
|
|
723
858
|
targetPath: pinned.targetPath,
|
|
724
859
|
renameIdentity: params.renameIdentity,
|
|
725
|
-
mkdir: params.mkdir !== false,
|
|
860
|
+
mkdir: !params.private && params.mkdir !== false,
|
|
861
|
+
private: params.private,
|
|
726
862
|
mode: params.mode ?? pinned.mode,
|
|
727
863
|
sync: params.durable !== false,
|
|
864
|
+
strictFileSync: params.strictFileSync,
|
|
728
865
|
overwrite: params.overwrite,
|
|
729
|
-
|
|
866
|
+
rejectFinalSymlink: params.mutationSymlinks !== undefined,
|
|
867
|
+
input,
|
|
868
|
+
maxBytes: input.kind === "buffer" ? undefined : params.maxBytes,
|
|
730
869
|
rootIdentity: root.rootIdentity,
|
|
870
|
+
mutationAdmission: pinned.mutationAdmission,
|
|
871
|
+
assertBeforeMutation: params.assertBeforeMutation,
|
|
731
872
|
verifyPublished: async (fd, expectedIdentity, parentGuard) => {
|
|
732
873
|
verifyingPublication = true;
|
|
733
874
|
try {
|
|
@@ -754,52 +895,91 @@ async function commitPinnedWriteInRoot(root, pinned, params) {
|
|
|
754
895
|
throw error;
|
|
755
896
|
}
|
|
756
897
|
if (params.overwrite === false && isAlreadyExistsError(error)) {
|
|
757
|
-
throw new FsSafeError("already-exists", "file already exists",
|
|
758
|
-
cause: error instanceof Error ? error : undefined,
|
|
759
|
-
});
|
|
898
|
+
throw new FsSafeError("already-exists", "file already exists", errorCauseOptions(error));
|
|
760
899
|
}
|
|
761
900
|
throw normalizePinnedWriteError(error);
|
|
762
901
|
}
|
|
763
902
|
}
|
|
764
903
|
async function copyFileInRoot(root, params) {
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
904
|
+
params.signal?.throwIfAborted();
|
|
905
|
+
const clone = resolveFileCopyCloneMode(params.clone);
|
|
906
|
+
let source;
|
|
907
|
+
let sourceIdentity;
|
|
908
|
+
if (typeof params.source === "string") {
|
|
909
|
+
assertNoNulPathInput(params.source, "source path contains a NUL byte");
|
|
910
|
+
assertNoWindowsPathAlias(params.source, "filesystem", "source path uses a Windows filesystem namespace alias");
|
|
911
|
+
({ opened: source, identity: sourceIdentity } = await openVerifiedLocalFile(params.source, {
|
|
912
|
+
hardlinks: params.sourceHardlinks,
|
|
913
|
+
}));
|
|
914
|
+
}
|
|
915
|
+
else {
|
|
916
|
+
source = await params.source.root.open(params.source.relativePath, params.sourceHardlinks === undefined ? undefined : { hardlinks: params.sourceHardlinks });
|
|
917
|
+
try {
|
|
918
|
+
sourceIdentity = await inspectFileIdentity(() => fsSync.fstatSync(source.handle.fd, { bigint: true }));
|
|
919
|
+
}
|
|
920
|
+
catch (error) {
|
|
921
|
+
await source.handle.close().catch(() => undefined);
|
|
922
|
+
throw error;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
770
925
|
if (params.maxBytes !== undefined && source.stat.size > params.maxBytes) {
|
|
771
926
|
await source.handle.close().catch(() => { });
|
|
772
927
|
throw new FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${source.stat.size})`);
|
|
773
928
|
}
|
|
774
929
|
try {
|
|
930
|
+
const sourceAdmission = params.admitSource?.(sourceIdentity, source.realPath);
|
|
931
|
+
const mode = sourceAdmission?.mode ?? params.mode;
|
|
775
932
|
await serializePathWrite(rootWriteQueueKey(root, params.relativePath), async () => {
|
|
776
|
-
const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode, params.denyMutations);
|
|
933
|
+
const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, mode ?? (params.preserveSourceMode ? Number(sourceIdentity.mode & 4095n) : undefined), params.denyMutations, params.overwrite !== false, params.mutationSymlinks);
|
|
777
934
|
await serializePathWrite(pinned.targetPath, async () => {
|
|
778
935
|
await assertCopySourceCurrent(source, sourceIdentity);
|
|
779
|
-
|
|
936
|
+
const verifySource = async () => {
|
|
937
|
+
params.signal?.throwIfAborted();
|
|
938
|
+
try {
|
|
939
|
+
sourceAdmission?.verify();
|
|
940
|
+
}
|
|
941
|
+
catch (error) {
|
|
942
|
+
throw new MutationAuthorityError(error);
|
|
943
|
+
}
|
|
944
|
+
if (typeof params.source !== "string") {
|
|
945
|
+
await params.source.root.stat(".");
|
|
946
|
+
}
|
|
947
|
+
await assertCopySourceCurrent(source, sourceIdentity);
|
|
948
|
+
};
|
|
949
|
+
const observer = createCopyPublicationObserver(pinned.targetPath, params.onDestinationPublished);
|
|
780
950
|
try {
|
|
781
|
-
|
|
951
|
+
await runPinnedWriteHelper({
|
|
782
952
|
rootPath: pinned.rootReal,
|
|
783
953
|
relativeParentPath: pinned.relativeParentPath,
|
|
784
954
|
basename: pinned.basename,
|
|
785
955
|
mkdir: params.mkdir !== false,
|
|
786
956
|
mode: pinned.mode,
|
|
787
|
-
overwrite:
|
|
957
|
+
overwrite: params.overwrite !== false,
|
|
958
|
+
rejectFinalSymlink: params.mutationSymlinks !== undefined,
|
|
788
959
|
maxBytes: params.maxBytes,
|
|
789
|
-
|
|
960
|
+
sync: params.durable !== false,
|
|
961
|
+
assertBeforeMutation: params.signal || params.assertBeforeMutation ? () => {
|
|
962
|
+
if (params.signal?.aborted)
|
|
963
|
+
throw new MutationAuthorityError(params.signal.reason);
|
|
964
|
+
params.assertBeforeMutation?.();
|
|
965
|
+
} : undefined,
|
|
966
|
+
verifyPublished: params.verifyPublished,
|
|
967
|
+
onPublished: observer.onPublished,
|
|
968
|
+
input: { kind: "file", handle: source.handle, size: source.stat.size, clone, signal: params.signal, verifySource },
|
|
790
969
|
rootIdentity: root.rootIdentity,
|
|
970
|
+
mutationAdmission: pinned.mutationAdmission,
|
|
791
971
|
});
|
|
792
972
|
}
|
|
793
973
|
catch (error) {
|
|
974
|
+
observer.rethrowObserverFailure(error);
|
|
975
|
+
if (params.signal?.aborted && error === params.signal.reason)
|
|
976
|
+
throw error;
|
|
977
|
+
if (isAlreadyExistsError(error)) {
|
|
978
|
+
throw new FsSafeError("already-exists", "copy destination already exists", { cause: error });
|
|
979
|
+
}
|
|
794
980
|
throw normalizePinnedWriteError(error);
|
|
795
981
|
}
|
|
796
|
-
|
|
797
|
-
await assertCopySourcePathCurrent(source, sourceIdentity);
|
|
798
|
-
}
|
|
799
|
-
catch (error) {
|
|
800
|
-
await removePathIfIdentityUnchanged(pinned.targetPath, identity).catch(() => undefined);
|
|
801
|
-
throw error;
|
|
802
|
-
}
|
|
982
|
+
await verifySource();
|
|
803
983
|
});
|
|
804
984
|
});
|
|
805
985
|
}
|
|
@@ -807,87 +987,12 @@ async function copyFileInRoot(root, params) {
|
|
|
807
987
|
await source.handle.close().catch(() => { });
|
|
808
988
|
}
|
|
809
989
|
}
|
|
810
|
-
async function assertCopySourceCurrent(source, identity) {
|
|
811
|
-
await inspectFileIdentity(() => fsSync.fstatSync(source.handle.fd, { bigint: true }), identity);
|
|
812
|
-
await assertCopySourcePathCurrent(source, identity);
|
|
813
|
-
}
|
|
814
|
-
async function assertCopySourcePathCurrent(source, identity) {
|
|
815
|
-
await inspectFileIdentity(async () => {
|
|
816
|
-
const current = fsSync.lstatSync(source.realPath, { bigint: true });
|
|
817
|
-
if (current.isSymbolicLink() || !current.isFile()) {
|
|
818
|
-
throw new FsSafeError("path-mismatch", "copy source path changed");
|
|
819
|
-
}
|
|
820
|
-
return current;
|
|
821
|
-
}, identity);
|
|
822
|
-
}
|
|
823
|
-
async function removePathIfIdentityUnchanged(targetPath, identity) {
|
|
824
|
-
const parentGuard = await createAsyncDirectoryGuard(path.dirname(targetPath));
|
|
825
|
-
const current = fsSync.lstatSync(targetPath);
|
|
826
|
-
if (current.isSymbolicLink() || !sameFileIdentityForCleanup(current, identity)) {
|
|
827
|
-
return;
|
|
828
|
-
}
|
|
829
|
-
await withAsyncDirectoryGuards([parentGuard], async () => {
|
|
830
|
-
await fs.rm(targetPath);
|
|
831
|
-
});
|
|
832
|
-
}
|
|
833
|
-
async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode, denyMutations, overwrite = true) {
|
|
834
|
-
const { rootReal, rootWithSep, resolved } = await resolveGuardedWritePathInRoot(root, {
|
|
835
|
-
relativePath,
|
|
836
|
-
denyMutations,
|
|
837
|
-
});
|
|
838
|
-
// resolvePathInRoot already enforces isPathInside, so any actual escape
|
|
839
|
-
// is rejected upstream.
|
|
840
|
-
const relativeResolved = path.relative(rootReal, resolved);
|
|
841
|
-
if (path.isAbsolute(relativeResolved)) {
|
|
842
|
-
throw outsideWorkspaceError();
|
|
843
|
-
}
|
|
844
|
-
const relativePosix = relativeResolved
|
|
845
|
-
? relativeResolved.split(path.sep).join(path.posix.sep)
|
|
846
|
-
: "";
|
|
847
|
-
const basename = path.posix.basename(relativePosix);
|
|
848
|
-
if (!basename || basename === "." || basename === "/") {
|
|
849
|
-
throw new FsSafeError("invalid-path", "invalid target path");
|
|
850
|
-
}
|
|
851
|
-
// Exclusive publication cannot inherit an existing file's mode. Keep type
|
|
852
|
-
// and alias checks, but never open a competing owner's record just to reject it.
|
|
853
|
-
if (!overwrite) {
|
|
854
|
-
try {
|
|
855
|
-
const existing = fsSync.statSync(resolved);
|
|
856
|
-
if (!existing.isFile())
|
|
857
|
-
throw new FsSafeError("not-file", "not a file");
|
|
858
|
-
if (existing.nlink > 1)
|
|
859
|
-
throw hardlinkedPathNotAllowedError();
|
|
860
|
-
throw new FsSafeError("already-exists", "file already exists");
|
|
861
|
-
}
|
|
862
|
-
catch (error) {
|
|
863
|
-
if (!isNotFoundPathError(error))
|
|
864
|
-
throw error;
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
const mode = overwrite
|
|
868
|
-
? await inheritWriteTargetMode({ targetPath: resolved, rootWithSep, requestedMode })
|
|
869
|
-
: requestedMode ?? 0o600;
|
|
870
|
-
return {
|
|
871
|
-
rootReal,
|
|
872
|
-
targetPath: resolved,
|
|
873
|
-
relativeParentPath: path.posix.dirname(relativePosix) === "." ? "" : path.posix.dirname(relativePosix),
|
|
874
|
-
basename,
|
|
875
|
-
mode,
|
|
876
|
-
};
|
|
877
|
-
}
|
|
878
990
|
async function resolvePinnedPathInRoot(root, params) {
|
|
879
|
-
return await resolvePinnedOperationPathInRoot(root, {
|
|
880
|
-
allowRoot: params.allowRoot,
|
|
881
|
-
denyMutations: params.denyMutations,
|
|
882
|
-
protectDenyMutationAncestors: params.remove === true,
|
|
883
|
-
relativePath: params.relativePath,
|
|
884
|
-
policy: params.remove ? PATH_ALIAS_POLICIES.unlinkTarget : PATH_ALIAS_POLICIES.strict,
|
|
885
|
-
});
|
|
886
|
-
}
|
|
887
|
-
async function resolvePinnedOperationPathInRoot(root, params) {
|
|
888
991
|
const resolved = await resolvePinnedRootPathInRoot(root, {
|
|
889
992
|
relativePath: params.relativePath,
|
|
890
|
-
policy: params.
|
|
993
|
+
policy: params.remove ? PATH_ALIAS_POLICIES.unlinkTarget : PATH_ALIAS_POLICIES.strict,
|
|
994
|
+
mutationSymlinks: params.mutationSymlinks,
|
|
995
|
+
removalReceipts: params.removalReceipts,
|
|
891
996
|
});
|
|
892
997
|
const relativeResolved = path.relative(resolved.rootReal, resolved.canonicalPath);
|
|
893
998
|
if ((relativeResolved === "" || relativeResolved === ".") && params.allowRoot === true) {
|
|
@@ -902,31 +1007,42 @@ async function resolvePinnedOperationPathInRoot(root, params) {
|
|
|
902
1007
|
throw outsideWorkspaceError();
|
|
903
1008
|
}
|
|
904
1009
|
const relativePosix = relativeResolved.split(path.sep).join(path.posix.sep);
|
|
905
|
-
|
|
1010
|
+
const admittedCanonicalPath = admitPathInsideRoot({
|
|
1011
|
+
rootPath: resolved.rootReal,
|
|
1012
|
+
candidatePath: resolved.canonicalPath,
|
|
1013
|
+
rootIdentity: root.rootIdentity,
|
|
1014
|
+
});
|
|
1015
|
+
if (!admittedCanonicalPath) {
|
|
906
1016
|
throw outsideWorkspaceError();
|
|
907
1017
|
}
|
|
1018
|
+
resolved.canonicalPath = admittedCanonicalPath.path;
|
|
908
1019
|
await assertMutationNotDenied(resolved.canonicalPath, params.denyMutations, {
|
|
909
|
-
protectAncestors: params.
|
|
1020
|
+
protectAncestors: params.remove === true,
|
|
910
1021
|
});
|
|
911
1022
|
return { rootReal: resolved.rootReal, resolved: resolved.canonicalPath, relativePosix };
|
|
912
1023
|
}
|
|
913
1024
|
async function resolvePinnedRootPathInRoot(root, params) {
|
|
914
|
-
await assertRootIdentityCurrent(root);
|
|
1025
|
+
await assertRootIdentityCurrent(root, params.removalReceipts?.observeRoot);
|
|
915
1026
|
const rootReal = root.rootReal;
|
|
916
1027
|
let resolved;
|
|
917
1028
|
try {
|
|
918
1029
|
const expandedPath = await expandRelativePathWithHome(params.relativePath);
|
|
919
|
-
|
|
1030
|
+
const resolution = {
|
|
920
1031
|
absolutePath: path.isAbsolute(expandedPath)
|
|
921
1032
|
? expandedPath
|
|
922
1033
|
: `${ensureTrailingSep(rootReal)}${expandedPath}`,
|
|
923
1034
|
rootPath: rootReal,
|
|
924
1035
|
rootCanonicalPath: rootReal,
|
|
1036
|
+
rootIdentity: root.rootIdentity,
|
|
925
1037
|
boundaryLabel: "root",
|
|
926
1038
|
policy: params.policy,
|
|
927
|
-
|
|
1039
|
+
...mutationSymlinkResolution(params.mutationSymlinks),
|
|
1040
|
+
};
|
|
1041
|
+
resolved = await (params.removalReceipts ? resolveRootPathForRemoval(resolution, params.removalReceipts) : resolveRootPath(resolution));
|
|
928
1042
|
}
|
|
929
1043
|
catch (err) {
|
|
1044
|
+
if (err instanceof FsSafeError && err.code === "symlink")
|
|
1045
|
+
throw err;
|
|
930
1046
|
throw new FsSafeError("path-alias", "path alias escape blocked", { cause: err });
|
|
931
1047
|
}
|
|
932
1048
|
const rootWithSep = ensureTrailingSep(resolved.rootCanonicalPath);
|
|
@@ -936,109 +1052,49 @@ async function resolvePinnedRootPathInRoot(root, params) {
|
|
|
936
1052
|
canonicalPath: resolved.canonicalPath,
|
|
937
1053
|
};
|
|
938
1054
|
}
|
|
939
|
-
async function prepareRemoveGuard(targetPath) {
|
|
940
|
-
try {
|
|
941
|
-
const guard = await createAsyncDirectoryGuard(path.dirname(targetPath));
|
|
942
|
-
await getFsSafeTestHooks()?.beforeRootFallbackMutation?.("remove", targetPath);
|
|
943
|
-
await assertAsyncDirectoryGuard(guard);
|
|
944
|
-
return guard;
|
|
945
|
-
}
|
|
946
|
-
catch (error) {
|
|
947
|
-
throw normalizeRemoveGuardError(error);
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
async function removePathFallback(resolved) {
|
|
951
|
-
const guard = await prepareRemoveGuard(resolved.resolved);
|
|
952
|
-
try {
|
|
953
|
-
await (fsSync.lstatSync(resolved.resolved).isDirectory() ? fs.rmdir(resolved.resolved) : fs.rm(resolved.resolved));
|
|
954
|
-
}
|
|
955
|
-
catch (error) {
|
|
956
|
-
throw normalizeRemovePathError(error);
|
|
957
|
-
}
|
|
958
|
-
await assertAsyncDirectoryGuard(guard).catch(() => undefined);
|
|
959
|
-
}
|
|
960
|
-
async function mkdirPathFallback(resolved) {
|
|
961
|
-
await mkdirPathComponentsWithGuards({
|
|
962
|
-
rootReal: resolved.rootReal, targetPath: resolved.resolved,
|
|
963
|
-
beforeComponent: async (componentPath) => await getFsSafeTestHooks()?.beforeRootFallbackMutation?.("mkdir", componentPath),
|
|
964
|
-
});
|
|
965
|
-
}
|
|
966
1055
|
async function statPathFallback(root, relativePath) {
|
|
967
|
-
const
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
await
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
if (isNotFoundPathError(error)) {
|
|
975
|
-
throw fileNotFoundError(error instanceof Error ? error : undefined);
|
|
976
|
-
}
|
|
977
|
-
throw error;
|
|
978
|
-
}
|
|
1056
|
+
const initialObservationHook = getFsSafeTestHooks()?.beforeRootStatInitialObservation;
|
|
1057
|
+
const observed = initialObservationHook
|
|
1058
|
+
? undefined
|
|
1059
|
+
: await resolvePinnedObservedPathInRoot(root, relativePath, "stat");
|
|
1060
|
+
const resolved = observed ??
|
|
1061
|
+
await resolvePinnedPathInRoot(root, { relativePath, allowRoot: true });
|
|
1062
|
+
return await statResolvedPathInRoot(root, resolved.resolved, resolved.receipt);
|
|
979
1063
|
}
|
|
980
1064
|
async function listPathFallback(root, relativePath, withFileTypes) {
|
|
981
|
-
const
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
if (!withFileTypes) {
|
|
986
|
-
await assertRootIdentityCurrent(root);
|
|
987
|
-
return sortedNames;
|
|
988
|
-
}
|
|
989
|
-
const entries = [];
|
|
990
|
-
for (const name of sortedNames) {
|
|
991
|
-
entries.push({
|
|
992
|
-
name,
|
|
993
|
-
...pathStatFromStats(fsSync.lstatSync(path.join(resolved.resolved, name))),
|
|
994
|
-
});
|
|
995
|
-
}
|
|
996
|
-
await assertRootIdentityCurrent(root);
|
|
997
|
-
return entries;
|
|
998
|
-
}
|
|
999
|
-
catch (error) {
|
|
1000
|
-
if (isNotFoundPathError(error)) {
|
|
1001
|
-
throw new FsSafeError("not-found", "directory not found", {
|
|
1002
|
-
cause: error instanceof Error ? error : undefined,
|
|
1003
|
-
});
|
|
1004
|
-
}
|
|
1005
|
-
throw error;
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
async function assertMoveMutationAllowed(root, params) {
|
|
1009
|
-
// Keep this preflight separate from the pinned resolutions in movePathFallback:
|
|
1010
|
-
// mutation denials must take precedence over source alias or identity failures.
|
|
1011
|
-
const source = await resolvePathInRoot(root, params.fromRelative, {
|
|
1012
|
-
aliasErrorCode: "path-alias",
|
|
1013
|
-
allowFinalSymlink: true,
|
|
1014
|
-
});
|
|
1015
|
-
await assertMutationNotDenied(source.resolved, params.denyMutations, { protectAncestors: true });
|
|
1016
|
-
const target = await resolvePathInRoot(root, params.toRelative, {
|
|
1017
|
-
aliasErrorCode: "path-alias",
|
|
1018
|
-
allowFinalSymlink: true,
|
|
1019
|
-
});
|
|
1020
|
-
await assertMutationNotDenied(target.resolved, params.denyMutations, { protectAncestors: true });
|
|
1065
|
+
const observed = await resolvePinnedObservedPathInRoot(root, relativePath, "directory");
|
|
1066
|
+
const resolved = observed ??
|
|
1067
|
+
await resolvePinnedPathInRoot(root, { relativePath, allowRoot: true });
|
|
1068
|
+
return await listDirectoryPath(root, resolved.resolved, withFileTypes, resolved.receipt);
|
|
1021
1069
|
}
|
|
1022
1070
|
async function movePathFallback(root, params) {
|
|
1071
|
+
const originalRoutes = params.overwrite && params.assertBeforeMutation
|
|
1072
|
+
? await Promise.all([params.fromRelative, params.toRelative].map(expandRelativePathWithHome)) : undefined;
|
|
1023
1073
|
const source = await resolvePathInRoot(root, params.fromRelative, {
|
|
1024
1074
|
aliasErrorCode: "path-alias",
|
|
1025
1075
|
allowFinalSymlink: true,
|
|
1076
|
+
...mutationSymlinkResolution(params.mutationSymlinks),
|
|
1026
1077
|
});
|
|
1027
1078
|
await assertMutationNotDenied(source.resolved, params.denyMutations, { protectAncestors: true });
|
|
1028
|
-
await resolvePinnedRootPathInRoot(root, {
|
|
1079
|
+
const pinnedSource = await resolvePinnedRootPathInRoot(root, {
|
|
1029
1080
|
relativePath: params.fromRelative,
|
|
1030
1081
|
policy: PATH_ALIAS_POLICIES.strict,
|
|
1082
|
+
mutationSymlinks: params.mutationSymlinks,
|
|
1031
1083
|
});
|
|
1084
|
+
let pinnedTarget;
|
|
1032
1085
|
const target = await resolveGuardedWritePathInRoot(root, {
|
|
1033
1086
|
relativePath: params.toRelative,
|
|
1034
1087
|
denyMutations: params.denyMutations,
|
|
1088
|
+
mutationSymlinks: params.mutationSymlinks,
|
|
1035
1089
|
allowFinalSymlink: true,
|
|
1036
1090
|
protectDeniedAncestors: true,
|
|
1037
1091
|
shouldAssertNoPathAlias: async (resolvedTarget) => {
|
|
1038
|
-
await resolvePinnedRootPathInRoot(root, {
|
|
1092
|
+
pinnedTarget = await resolvePinnedRootPathInRoot(root, {
|
|
1039
1093
|
relativePath: params.toRelative,
|
|
1040
1094
|
policy: PATH_ALIAS_POLICIES.unlinkTarget,
|
|
1041
1095
|
});
|
|
1096
|
+
if (!params.overwrite)
|
|
1097
|
+
return true;
|
|
1042
1098
|
let targetStat;
|
|
1043
1099
|
try {
|
|
1044
1100
|
targetStat = fsSync.lstatSync(resolvedTarget.resolved);
|
|
@@ -1049,9 +1105,14 @@ async function movePathFallback(root, params) {
|
|
|
1049
1105
|
targetStat?.isSymbolicLink() === true);
|
|
1050
1106
|
},
|
|
1051
1107
|
});
|
|
1052
|
-
let
|
|
1108
|
+
let sourceIdentity;
|
|
1053
1109
|
try {
|
|
1054
|
-
|
|
1110
|
+
if (params.overwrite && params.assertBeforeMutation) {
|
|
1111
|
+
sourceIdentity = inspectFileIdentitySync(() => admitMoveSourceStat(fsSync.lstatSync(source.resolved, { bigint: true }), true));
|
|
1112
|
+
}
|
|
1113
|
+
else {
|
|
1114
|
+
admitMoveSourceStat(fsSync.lstatSync(source.resolved), params.overwrite);
|
|
1115
|
+
}
|
|
1055
1116
|
}
|
|
1056
1117
|
catch (error) {
|
|
1057
1118
|
if (isNotFoundPathError(error)) {
|
|
@@ -1059,35 +1120,53 @@ async function movePathFallback(root, params) {
|
|
|
1059
1120
|
}
|
|
1060
1121
|
throw error;
|
|
1061
1122
|
}
|
|
1062
|
-
if (
|
|
1063
|
-
throw new FsSafeError("
|
|
1064
|
-
}
|
|
1065
|
-
if (sourceStat.isFile() && sourceStat.nlink > 1) {
|
|
1066
|
-
throw hardlinkedPathNotAllowedError();
|
|
1067
|
-
}
|
|
1068
|
-
if (!params.overwrite && sourceStat.isDirectory()) {
|
|
1069
|
-
throw new FsSafeError("invalid-path", "directory moves require overwrite: true");
|
|
1123
|
+
if (!pinnedTarget) {
|
|
1124
|
+
throw new FsSafeError("path-mismatch", "destination admission was not completed");
|
|
1070
1125
|
}
|
|
1071
1126
|
if (!params.overwrite) {
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
}
|
|
1080
|
-
if (!isNotFoundPathError(error)) {
|
|
1081
|
-
throw error;
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1127
|
+
await movePathNoReplaceNative(root, params, {
|
|
1128
|
+
sourcePath: source.resolved,
|
|
1129
|
+
sourceParentPath: path.dirname(pinnedSource.canonicalPath),
|
|
1130
|
+
targetPath: target.resolved,
|
|
1131
|
+
targetParentPath: path.dirname(pinnedTarget.canonicalPath),
|
|
1132
|
+
});
|
|
1133
|
+
return;
|
|
1084
1134
|
}
|
|
1085
|
-
const
|
|
1086
|
-
const
|
|
1135
|
+
const guardOptions = { bigint: sourceIdentity !== undefined };
|
|
1136
|
+
const sourceParentGuard = await createAsyncDirectoryGuard(path.dirname(source.resolved), guardOptions);
|
|
1137
|
+
const targetParentGuard = await createNearestExistingDirectoryGuard(target.rootReal, path.dirname(target.resolved), guardOptions);
|
|
1087
1138
|
await getFsSafeTestHooks()?.beforeRootFallbackMutation?.("move", target.resolved);
|
|
1088
1139
|
await assertAsyncDirectoryGuard(sourceParentGuard);
|
|
1089
1140
|
await assertAsyncDirectoryGuard(targetParentGuard);
|
|
1090
1141
|
try {
|
|
1142
|
+
assertFinalSymlinkRejected(source.resolved, params.mutationSymlinks !== undefined);
|
|
1143
|
+
assertFinalSymlinkRejected(target.resolved, params.mutationSymlinks !== undefined);
|
|
1144
|
+
params.assertBeforeMutation?.();
|
|
1145
|
+
if (sourceIdentity) {
|
|
1146
|
+
assertRootIdentityCurrentSync(root);
|
|
1147
|
+
assertSyncDirectoryGuard(sourceParentGuard);
|
|
1148
|
+
assertSyncDirectoryGuard(targetParentGuard);
|
|
1149
|
+
for (const [route, selected, expected, policy] of [
|
|
1150
|
+
[originalRoutes[0], source.resolved, pinnedSource.canonicalPath, PATH_ALIAS_POLICIES.strict],
|
|
1151
|
+
[originalRoutes[1], target.resolved, pinnedTarget.canonicalPath, PATH_ALIAS_POLICIES.unlinkTarget],
|
|
1152
|
+
]) {
|
|
1153
|
+
for (const absolutePath of new Set([path.isAbsolute(route) ? route : `${root.rootWithSep}${route}`, selected])) {
|
|
1154
|
+
try {
|
|
1155
|
+
const current = resolveRootPathSync({
|
|
1156
|
+
absolutePath, rootPath: root.rootReal, rootCanonicalPath: root.rootReal,
|
|
1157
|
+
rootIdentity: root.rootIdentity, boundaryLabel: "root", policy,
|
|
1158
|
+
...mutationSymlinkResolution(params.mutationSymlinks),
|
|
1159
|
+
});
|
|
1160
|
+
if (current.canonicalPath !== expected)
|
|
1161
|
+
throw new FsSafeError("path-mismatch", "move route changed during authorization");
|
|
1162
|
+
}
|
|
1163
|
+
catch (error) {
|
|
1164
|
+
throw normalizePinnedPathError(error);
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
inspectFileIdentitySync(() => admitMoveSourceStat(fsSync.lstatSync(source.resolved, { bigint: true }), true), sourceIdentity);
|
|
1169
|
+
}
|
|
1091
1170
|
await fs.rename(source.resolved, target.resolved);
|
|
1092
1171
|
}
|
|
1093
1172
|
catch (error) {
|
|
@@ -1095,109 +1174,237 @@ async function movePathFallback(root, params) {
|
|
|
1095
1174
|
throw fileNotFoundError(error instanceof Error ? error : undefined);
|
|
1096
1175
|
}
|
|
1097
1176
|
if (hasNodeErrorCode(error, "EEXIST")) {
|
|
1098
|
-
throw new FsSafeError("already-exists", "destination exists",
|
|
1099
|
-
cause: error instanceof Error ? error : undefined,
|
|
1100
|
-
});
|
|
1177
|
+
throw new FsSafeError("already-exists", "destination exists", errorCauseOptions(error));
|
|
1101
1178
|
}
|
|
1102
1179
|
throw error;
|
|
1103
1180
|
}
|
|
1104
|
-
|
|
1181
|
+
try {
|
|
1182
|
+
await assertAsyncDirectoryGuard(sourceParentGuard);
|
|
1183
|
+
await assertAsyncDirectoryGuard(targetParentGuard);
|
|
1184
|
+
}
|
|
1185
|
+
catch (error) {
|
|
1186
|
+
throw normalizePinnedPathError(error);
|
|
1187
|
+
}
|
|
1105
1188
|
}
|
|
1106
1189
|
async function writeFileFallback(root, params) {
|
|
1190
|
+
if (params.renameIdentity !== "verify-content-with-lock")
|
|
1191
|
+
return await writeFileFallbackUnlocked(root, params);
|
|
1192
|
+
const policy = snapshotPinnedMutationPolicy(params.denyMutations, params.mutationSymlinks);
|
|
1193
|
+
if (policy)
|
|
1194
|
+
params = { ...params, ...policy };
|
|
1195
|
+
const { rootReal, resolved } = await resolveGuardedWritePathInRoot(root, {
|
|
1196
|
+
relativePath: params.relativePath,
|
|
1197
|
+
denyMutations: params.denyMutations,
|
|
1198
|
+
mutationSymlinks: params.mutationSymlinks,
|
|
1199
|
+
});
|
|
1200
|
+
await withRootFallbackCompatibilityLock({
|
|
1201
|
+
rootPath: rootReal, rootIdentity: root.rootIdentity, targetPath: resolved, assertBeforeMutation: params.assertBeforeMutation,
|
|
1202
|
+
}, async ({ targetPath, ...binding }) => await writeFileFallbackUnlocked(root, { ...params, ...binding }, targetPath));
|
|
1203
|
+
}
|
|
1204
|
+
async function writeFileFallbackUnlocked(root, params, expectedWritePath) {
|
|
1107
1205
|
if (params.overwrite === false) {
|
|
1108
|
-
await writeMissingFileFallback(root, params);
|
|
1206
|
+
await writeMissingFileFallback(root, params, expectedWritePath);
|
|
1109
1207
|
return;
|
|
1110
1208
|
}
|
|
1111
|
-
const
|
|
1209
|
+
const admissionParams = {
|
|
1112
1210
|
relativePath: params.relativePath,
|
|
1113
1211
|
mkdir: params.mkdir,
|
|
1114
|
-
mode: params.mode,
|
|
1115
1212
|
denyMutations: params.denyMutations,
|
|
1213
|
+
assertBeforeMutation: params.assertBeforeMutation,
|
|
1214
|
+
mutationSymlinks: params.mutationSymlinks,
|
|
1116
1215
|
truncateExisting: false,
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
const
|
|
1120
|
-
|
|
1121
|
-
const
|
|
1216
|
+
expectedWritePath,
|
|
1217
|
+
};
|
|
1218
|
+
const admission = await openWritableFileInRoot(root, admissionParams, { createIfMissing: false });
|
|
1219
|
+
const existing = "missing" in admission ? undefined : admission;
|
|
1220
|
+
const target = existing?.opened;
|
|
1221
|
+
const retainedSelection = existing?.writeSelection;
|
|
1222
|
+
const missingSelection = "missing" in admission ? admission.writeSelection : undefined;
|
|
1223
|
+
const policyEnabled = params.denyMutations !== undefined || params.mutationSymlinks !== undefined;
|
|
1224
|
+
const destinationPath = "missing" in admission ? admission.targetPath
|
|
1225
|
+
: retainedSelection?.selectedPath ?? admission.opened.realPath;
|
|
1226
|
+
let mode = params.mode ?? (target ? target.stat.mode & 0o777 : undefined);
|
|
1227
|
+
if (policyEnabled && !retainedSelection && !missingSelection) {
|
|
1228
|
+
await target?.handle.close().catch(() => undefined);
|
|
1229
|
+
throw new FsSafeError("path-mismatch", "write admission state was not retained");
|
|
1230
|
+
}
|
|
1231
|
+
const destinationGuard = "missing" in admission ? admission.parentGuard : retainedSelection?.parentGuard ??
|
|
1232
|
+
await createAsyncDirectoryGuard(path.dirname(destinationPath), { bigint: true }).catch(async (error) => {
|
|
1233
|
+
await target?.handle.close().catch(() => undefined);
|
|
1234
|
+
throw error;
|
|
1235
|
+
});
|
|
1122
1236
|
let tempPath = null;
|
|
1123
1237
|
let unregisterTempPath = null;
|
|
1124
1238
|
let writtenHandle;
|
|
1239
|
+
let writtenIdentity;
|
|
1240
|
+
let lateTargetHandle;
|
|
1125
1241
|
try {
|
|
1126
1242
|
tempPath = buildAtomicWriteTempPath(destinationPath);
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1243
|
+
if (retainedSelection) {
|
|
1244
|
+
await refreshRetainedRootWriteAdmission(root, retainedSelection, true, target?.handle.fd);
|
|
1245
|
+
}
|
|
1246
|
+
else if (missingSelection) {
|
|
1247
|
+
await refreshRootWritePathSelection(missingSelection);
|
|
1248
|
+
}
|
|
1249
|
+
params.assertBeforeMutation?.();
|
|
1250
|
+
if (retainedSelection) {
|
|
1251
|
+
assertRootWriteSelectionSync(root, retainedSelection, true, target?.handle.fd);
|
|
1252
|
+
}
|
|
1253
|
+
else if (missingSelection) {
|
|
1254
|
+
assertRootWritePathSelectionSync(root, missingSelection);
|
|
1255
|
+
}
|
|
1256
|
+
assertRootIdentityCurrentSync(root);
|
|
1257
|
+
assertSyncDirectoryGuard(destinationGuard);
|
|
1258
|
+
writtenHandle = await fs.open(tempPath, OPEN_WRITE_CREATE_FLAGS, 0o600);
|
|
1259
|
+
writtenIdentity = fsSync.fstatSync(writtenHandle.fd, { bigint: true });
|
|
1260
|
+
// Preserve the creation mask when no existing destination supplies a mode.
|
|
1261
|
+
mode ??= Number(writtenIdentity.mode & 511n);
|
|
1262
|
+
unregisterTempPath = registerTempPathForExit(tempPath, { identity: writtenIdentity, singleLinkFile: true });
|
|
1263
|
+
await writeAllToFile(writtenHandle, params.data, {
|
|
1264
|
+
encoding: params.encoding, assertBeforeMutation: params.assertBeforeMutation,
|
|
1133
1265
|
});
|
|
1134
|
-
|
|
1135
|
-
|
|
1266
|
+
if (params.durable !== false)
|
|
1267
|
+
await writtenHandle.sync();
|
|
1136
1268
|
const commitTempPath = tempPath;
|
|
1269
|
+
const commitHandle = writtenHandle;
|
|
1270
|
+
const commitIdentity = writtenIdentity;
|
|
1137
1271
|
await withAsyncDirectoryGuards([destinationGuard], async () => {
|
|
1272
|
+
await verifyAtomicWriteResult({
|
|
1273
|
+
root, targetPath: commitTempPath, fd: commitHandle.fd,
|
|
1274
|
+
expectedIdentity: commitIdentity, parentGuard: destinationGuard,
|
|
1275
|
+
});
|
|
1276
|
+
assertRootIdentityCurrentSync(root);
|
|
1277
|
+
assertSyncDirectoryGuard(destinationGuard);
|
|
1278
|
+
let publicationIdentity = inspectFallbackReplacementDestination(destinationPath);
|
|
1279
|
+
// A raced file needs its own access admission, not the old handle's rights.
|
|
1280
|
+
if (publicationIdentity && (!existing || !sameFileIdentity(publicationIdentity, existing.identity))) {
|
|
1281
|
+
const admitted = await openWritableFileInRoot(root, {
|
|
1282
|
+
...admissionParams, mkdir: false, expectedWritePath: destinationPath,
|
|
1283
|
+
}, { createIfMissing: false });
|
|
1284
|
+
lateTargetHandle = "missing" in admitted ? undefined : admitted.opened.handle;
|
|
1285
|
+
publicationIdentity = "missing" in admitted ? undefined : admitted.identity;
|
|
1286
|
+
await lateTargetHandle?.close();
|
|
1287
|
+
}
|
|
1288
|
+
// Windows cannot replace a destination while its old handle remains open.
|
|
1289
|
+
await target?.handle.close();
|
|
1290
|
+
if (retainedSelection) {
|
|
1291
|
+
await refreshRetainedRootWriteAdmission(root, retainedSelection, true);
|
|
1292
|
+
}
|
|
1293
|
+
else if (missingSelection) {
|
|
1294
|
+
await refreshRootWritePathSelection(missingSelection);
|
|
1295
|
+
}
|
|
1296
|
+
assertFinalSymlinkRejected(destinationPath, params.mutationSymlinks !== undefined);
|
|
1297
|
+
params.assertBeforeMutation?.();
|
|
1298
|
+
if (retainedSelection) {
|
|
1299
|
+
assertRootWriteSelectionSync(root, retainedSelection, true);
|
|
1300
|
+
}
|
|
1301
|
+
else if (missingSelection) {
|
|
1302
|
+
assertRootWritePathSelectionSync(root, missingSelection);
|
|
1303
|
+
}
|
|
1304
|
+
assertRootIdentityCurrentSync(root);
|
|
1305
|
+
assertSyncDirectoryGuard(destinationGuard);
|
|
1306
|
+
const current = inspectFallbackReplacementDestination(destinationPath);
|
|
1307
|
+
if (publicationIdentity ? !current || !sameFileIdentity(current, publicationIdentity) : current) {
|
|
1308
|
+
throw new FsSafeError("path-mismatch", "write destination changed before publication");
|
|
1309
|
+
}
|
|
1138
1310
|
await fs.rename(commitTempPath, destinationPath);
|
|
1139
1311
|
tempPath = null;
|
|
1140
1312
|
});
|
|
1141
1313
|
unregisterTempPath();
|
|
1142
1314
|
unregisterTempPath = null;
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
});
|
|
1151
|
-
}
|
|
1152
|
-
catch (err) {
|
|
1153
|
-
emitWriteBoundaryWarning(`post-write verification failed: ${String(err)}`);
|
|
1154
|
-
throw err;
|
|
1155
|
-
}
|
|
1315
|
+
await finishRootFallbackWrite({
|
|
1316
|
+
root, targetPath: destinationPath, handle: writtenHandle, identity: writtenIdentity,
|
|
1317
|
+
parentGuard: destinationGuard, mode, options: params,
|
|
1318
|
+
// Read/write access is needed to sync the accepted destination on Windows.
|
|
1319
|
+
openForCompatibility: () => openVerifiedLocalFile(destinationPath, { hardlinks: "reject", readWrite: true }),
|
|
1320
|
+
onVerificationFailure: err => emitWriteBoundaryWarning(`post-write verification failed: ${String(err)}`),
|
|
1321
|
+
});
|
|
1156
1322
|
}
|
|
1157
1323
|
finally {
|
|
1158
|
-
await
|
|
1159
|
-
|
|
1160
|
-
|
|
1324
|
+
await target?.handle.close().catch(() => undefined);
|
|
1325
|
+
await lateTargetHandle?.close().catch(() => undefined);
|
|
1326
|
+
if (tempPath && writtenHandle) {
|
|
1327
|
+
await cleanupPinnedFilePath({
|
|
1328
|
+
pathname: tempPath, handle: writtenHandle, identity: writtenIdentity, parentGuard: destinationGuard,
|
|
1329
|
+
});
|
|
1161
1330
|
}
|
|
1331
|
+
await writtenHandle?.close().catch(() => undefined);
|
|
1162
1332
|
unregisterTempPath?.();
|
|
1163
1333
|
}
|
|
1164
1334
|
}
|
|
1165
|
-
|
|
1166
|
-
|
|
1335
|
+
function inspectFallbackReplacementDestination(targetPath) {
|
|
1336
|
+
let current;
|
|
1337
|
+
try {
|
|
1338
|
+
current = inspectFileIdentitySync(() => fsSync.lstatSync(targetPath, { bigint: true }));
|
|
1339
|
+
}
|
|
1340
|
+
catch (error) {
|
|
1341
|
+
if (isNotFoundPathError(error))
|
|
1342
|
+
return;
|
|
1343
|
+
throw error;
|
|
1344
|
+
}
|
|
1345
|
+
if (current.isSymbolicLink() || !current.isFile()) {
|
|
1346
|
+
throw new FsSafeError("path-mismatch", "write destination changed before publication");
|
|
1347
|
+
}
|
|
1348
|
+
if (current.nlink > 1n)
|
|
1349
|
+
throw hardlinkedPathNotAllowedError();
|
|
1350
|
+
return current;
|
|
1351
|
+
}
|
|
1352
|
+
async function writeMissingFileFallback(root, params, expectedWritePath) {
|
|
1353
|
+
const guardedTarget = params.denyMutations === undefined && params.mutationSymlinks === undefined
|
|
1354
|
+
? undefined
|
|
1355
|
+
: await resolveGuardedWriteTargetInRoot(root, {
|
|
1356
|
+
relativePath: params.relativePath,
|
|
1357
|
+
denyMutations: params.denyMutations,
|
|
1358
|
+
mutationSymlinks: params.mutationSymlinks,
|
|
1359
|
+
});
|
|
1360
|
+
const { resolved } = guardedTarget?.resolvedPath ?? await resolveGuardedWritePathInRoot(root, {
|
|
1167
1361
|
relativePath: params.relativePath,
|
|
1168
|
-
denyMutations: params.denyMutations,
|
|
1169
1362
|
});
|
|
1170
|
-
const
|
|
1171
|
-
|
|
1172
|
-
:
|
|
1173
|
-
|
|
1363
|
+
const prepared = guardedTarget ? await prepareSharedRootWriteTarget(root, {
|
|
1364
|
+
relativePath: params.relativePath, guardedTarget, mkdir: params.mkdir,
|
|
1365
|
+
assertBeforeMutation: params.assertBeforeMutation,
|
|
1366
|
+
}) : undefined;
|
|
1367
|
+
const mutationAdmission = prepared?.mutationAdmission;
|
|
1368
|
+
const preparedParent = prepared?.preparedParent;
|
|
1369
|
+
const targetPath = prepared?.targetPath ?? (params.mkdir === false ? resolved :
|
|
1370
|
+
await prepareRootWriteTarget(root, resolved, params.assertBeforeMutation));
|
|
1371
|
+
assertRootFallbackWritePath(expectedWritePath, targetPath);
|
|
1372
|
+
const pathSelection = guardedTarget
|
|
1373
|
+
? await prepareGuardedRootWritePathSelection(guardedTarget, targetPath, targetPath, preparedParent)
|
|
1374
|
+
: undefined;
|
|
1375
|
+
const parentGuard = pathSelection?.parentGuard ??
|
|
1376
|
+
await createAsyncDirectoryGuard(path.dirname(targetPath), { bigint: true });
|
|
1174
1377
|
let created = false;
|
|
1378
|
+
let completed = false;
|
|
1175
1379
|
let createdIdentity;
|
|
1176
1380
|
let writtenHandle;
|
|
1177
1381
|
let verifyingPublication = false;
|
|
1178
1382
|
try {
|
|
1179
1383
|
const { handle, writtenStat } = await withAsyncDirectoryGuards([parentGuard], async () => {
|
|
1384
|
+
assertFinalSymlinkRejected(targetPath, params.mutationSymlinks !== undefined);
|
|
1385
|
+
params.assertBeforeMutation?.();
|
|
1386
|
+
if (mutationAdmission)
|
|
1387
|
+
assertSyncDirectoryGuard(parentGuard);
|
|
1180
1388
|
const handle = await fs.open(targetPath, OPEN_WRITE_CREATE_FLAGS, params.mode ?? 0o600).catch((error) => recordExclusiveCreateFailure(error, targetPath));
|
|
1389
|
+
writtenHandle = handle;
|
|
1181
1390
|
created = true;
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
await handle.
|
|
1195
|
-
|
|
1196
|
-
}
|
|
1391
|
+
const writtenStat = fsSync.fstatSync(handle.fd, { bigint: true });
|
|
1392
|
+
createdIdentity = writtenStat;
|
|
1393
|
+
await writeAllToFile(handle, params.data, {
|
|
1394
|
+
encoding: params.encoding,
|
|
1395
|
+
assertBeforeMutation: () => {
|
|
1396
|
+
assertFinalSymlinkRejected(targetPath, params.mutationSymlinks !== undefined);
|
|
1397
|
+
params.assertBeforeMutation?.();
|
|
1398
|
+
if (mutationAdmission)
|
|
1399
|
+
assertSyncDirectoryGuard(parentGuard);
|
|
1400
|
+
},
|
|
1401
|
+
});
|
|
1402
|
+
if (params.durable !== false)
|
|
1403
|
+
await handle.sync();
|
|
1404
|
+
return { handle, writtenStat };
|
|
1197
1405
|
}, {
|
|
1198
|
-
onPostGuardFailure:
|
|
1406
|
+
onPostGuardFailure: () => {
|
|
1199
1407
|
created = false; // Parent is untrusted now; skip outer path cleanup by name.
|
|
1200
|
-
await handle.close().catch(() => undefined);
|
|
1201
1408
|
},
|
|
1202
1409
|
});
|
|
1203
1410
|
writtenHandle = handle;
|
|
@@ -1210,21 +1417,27 @@ async function writeMissingFileFallback(root, params) {
|
|
|
1210
1417
|
fd: handle.fd,
|
|
1211
1418
|
parentGuard,
|
|
1212
1419
|
});
|
|
1420
|
+
if (params.durable !== false)
|
|
1421
|
+
await syncDirectoryBestEffort(path.dirname(targetPath));
|
|
1422
|
+
completed = true;
|
|
1213
1423
|
}
|
|
1214
1424
|
catch (err) {
|
|
1215
1425
|
if (verifyingPublication)
|
|
1216
1426
|
throw err;
|
|
1217
1427
|
if (hasNodeErrorCode(err, "EEXIST")) {
|
|
1218
|
-
throw new FsSafeError("already-exists", "file already exists",
|
|
1219
|
-
cause: err instanceof Error ? err : undefined,
|
|
1220
|
-
});
|
|
1428
|
+
throw new FsSafeError("already-exists", "file already exists", errorCauseOptions(err));
|
|
1221
1429
|
}
|
|
1222
1430
|
throw err;
|
|
1223
1431
|
}
|
|
1224
1432
|
finally {
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1433
|
+
if (created && writtenHandle) {
|
|
1434
|
+
await cleanupPinnedFilePath({
|
|
1435
|
+
pathname: targetPath, handle: writtenHandle, identity: createdIdentity, parentGuard,
|
|
1436
|
+
});
|
|
1228
1437
|
}
|
|
1438
|
+
if (completed)
|
|
1439
|
+
await writtenHandle?.close();
|
|
1440
|
+
else
|
|
1441
|
+
await writtenHandle?.close().catch(() => undefined);
|
|
1229
1442
|
}
|
|
1230
1443
|
}
|