@openclaw/fs-safe 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +91 -0
- package/README.md +8 -1
- package/dist/absolute-path.d.ts +0 -1
- package/dist/absolute-path.js +2 -8
- package/dist/advanced.d.ts +2 -1
- package/dist/advanced.js +2 -0
- package/dist/archive-crc32.d.ts +0 -1
- package/dist/archive-deadline.d.ts +0 -1
- package/dist/archive-deadline.js +22 -23
- package/dist/archive-durability.d.ts +0 -1
- package/dist/archive-entry.d.ts +0 -1
- package/dist/archive-errors.d.ts +0 -1
- package/dist/archive-gzip-tail.d.ts +0 -1
- package/dist/archive-input.d.ts +0 -1
- package/dist/archive-kind.d.ts +0 -1
- package/dist/archive-limits.d.ts +0 -1
- package/dist/archive-merge.d.ts +3 -4
- package/dist/archive-merge.js +17 -7
- package/dist/archive-native.d.ts +3 -14
- package/dist/archive-native.js +46 -70
- package/dist/archive-options.d.ts +9 -2
- package/dist/archive-parser-errors.d.ts +0 -1
- package/dist/archive-parser.wasm +0 -0
- package/dist/archive-plan.d.ts +10 -1
- package/dist/archive-plan.js +31 -21
- package/dist/archive-policy.d.ts +0 -1
- package/dist/archive-read.d.ts +0 -1
- package/dist/archive-staging.d.ts +0 -1
- package/dist/archive-tar-inspect.d.ts +0 -1
- package/dist/archive-tar-stream.d.ts +0 -1
- package/dist/archive-tar-wasm.d.ts +0 -1
- package/dist/archive-tar.d.ts +0 -1
- package/dist/archive-zip-admission.d.ts +0 -1
- package/dist/archive-zip-count.d.ts +0 -1
- package/dist/archive-zip-count.js +21 -1
- package/dist/archive-zip-directory.d.ts +0 -1
- package/dist/archive-zip-directory.js +23 -1
- package/dist/archive-zip-entry.d.ts +0 -1
- package/dist/archive-zip-integrity.d.ts +0 -1
- package/dist/archive-zip-loader.d.ts +2 -1
- package/dist/archive-zip-loader.js +7 -0
- package/dist/archive-zip-manifest.d.ts +0 -1
- package/dist/archive-zip-names.d.ts +0 -1
- package/dist/archive-zip-names.js +7 -2
- package/dist/archive-zip-preflight.d.ts +0 -1
- package/dist/archive.d.ts +0 -1
- package/dist/archive.js +93 -164
- package/dist/async-lock.d.ts +0 -1
- package/dist/atomic.d.ts +0 -1
- package/dist/bounded-read-stream.d.ts +0 -1
- package/dist/bounded-read.d.ts +0 -1
- package/dist/byte-budget.d.ts +0 -1
- package/dist/byte-view.d.ts +2 -0
- package/dist/byte-view.js +13 -0
- package/dist/clone-metadata.d.ts +0 -1
- package/dist/config.d.ts +0 -1
- package/dist/containment.d.ts +0 -1
- package/dist/copy-file-input.d.ts +0 -1
- package/dist/copy-policy.d.ts +0 -1
- package/dist/copy-publication.d.ts +0 -1
- package/dist/copy-tree-portable.d.ts +0 -1
- package/dist/copy-tree-portable.js +9 -6
- package/dist/copy.d.ts +0 -1
- package/dist/copy.js +5 -5
- package/dist/create-directory.d.ts +0 -2
- package/dist/create-directory.js +3 -22
- package/dist/create-file-async.d.ts +0 -1
- package/dist/create-file.d.ts +0 -1
- package/dist/create-file.js +3 -14
- package/dist/create-owned-file.d.ts +0 -1
- package/dist/create.d.ts +1 -2
- package/dist/create.js +1 -1
- package/dist/creation-darwin.d.ts +0 -2
- package/dist/creation-darwin.js +0 -9
- package/dist/creation-file-state.d.ts +0 -1
- package/dist/creation-path.d.ts +2 -1
- package/dist/creation-path.js +12 -0
- package/dist/creation-permissions.d.ts +0 -1
- package/dist/creation-permissions.js +28 -38
- package/dist/deny-mutations.d.ts +2 -3
- package/dist/deny-mutations.js +55 -35
- package/dist/device-path.d.ts +0 -1
- package/dist/directory-durability.d.ts +6 -7
- package/dist/directory-entry-path.d.ts +0 -1
- package/dist/directory-guard.d.ts +2 -7
- package/dist/directory-guard.js +25 -56
- package/dist/directory-mode-node.d.ts +0 -1
- package/dist/directory-mode-owner.d.ts +0 -1
- package/dist/directory-receipt.d.ts +2 -3
- package/dist/directory-receipt.js +15 -19
- package/dist/durability.d.ts +0 -1
- package/dist/effective-uid.d.ts +0 -1
- package/dist/error-detail.d.ts +0 -1
- package/dist/errors.d.ts +0 -1
- package/dist/file-cleanup.d.ts +1 -1
- package/dist/file-cleanup.js +7 -4
- package/dist/file-contents.d.ts +5 -0
- package/dist/file-contents.js +40 -0
- package/dist/file-handle-transfer.d.ts +0 -1
- package/dist/file-hash.d.ts +0 -1
- package/dist/file-hash.js +186 -70
- package/dist/file-identity.d.ts +0 -1
- package/dist/file-lock-sync-acquisition.d.ts +22 -0
- package/dist/file-lock-sync-acquisition.js +98 -0
- package/dist/file-lock-sync-admission.d.ts +0 -2
- package/dist/file-lock-sync-admission.js +9 -48
- package/dist/file-lock-sync-root-acquire.d.ts +0 -1
- package/dist/file-lock-sync-root-acquire.js +35 -98
- package/dist/file-lock-sync-root-arbitration.d.ts +0 -1
- package/dist/file-lock-sync-root-held.d.ts +1 -3
- package/dist/file-lock-sync-root-held.js +7 -5
- package/dist/file-lock-sync-root-io.d.ts +0 -1
- package/dist/file-lock-sync-root-mutation.d.ts +4 -5
- package/dist/file-lock-sync-root-mutation.js +7 -9
- package/dist/file-lock-sync-root-options.d.ts +0 -1
- package/dist/file-lock-sync-root-registration.d.ts +0 -1
- package/dist/file-lock-sync-root.d.ts +1 -2
- package/dist/file-lock-sync-root.js +14 -87
- package/dist/file-lock-sync-stale-admission.d.ts +2 -7
- package/dist/file-lock-sync-stale-admission.js +24 -23
- package/dist/file-lock-sync.d.ts +0 -1
- package/dist/file-lock-sync.js +46 -128
- package/dist/file-lock.d.ts +0 -1
- package/dist/file-observation.d.ts +0 -1
- package/dist/file-store-boundary.d.ts +0 -2
- package/dist/file-store-boundary.js +6 -26
- package/dist/file-store-copy-source.d.ts +1 -2
- package/dist/file-store-copy-source.js +1 -1
- package/dist/file-store-limit.d.ts +1 -2
- package/dist/file-store-limit.js +2 -3
- package/dist/file-store-path.d.ts +0 -1
- package/dist/file-store-prune.d.ts +0 -1
- package/dist/file-store-sync-directory.d.ts +0 -1
- package/dist/file-store-sync-directory.js +194 -231
- package/dist/file-store-sync-write.d.ts +0 -1
- package/dist/file-store-sync-write.js +16 -26
- package/dist/file-store.d.ts +0 -1
- package/dist/file-store.js +6 -7
- package/dist/file-sync.d.ts +0 -1
- package/dist/filename.d.ts +0 -1
- package/dist/filename.js +1 -7
- package/dist/fs.d.ts +0 -1
- package/dist/guarded-mkdir.d.ts +0 -1
- package/dist/guarded-mkdir.js +6 -27
- package/dist/guarded-mutation.d.ts +0 -7
- package/dist/guarded-mutation.js +6 -11
- package/dist/guest-dispatch-python.d.ts +0 -1
- package/dist/guest-dispatch-python.js +41 -90
- package/dist/guest-native-python.d.ts +0 -1
- package/dist/guest.d.ts +0 -1
- package/dist/home-dir.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/install-path.d.ts +0 -1
- package/dist/install-path.js +2 -5
- package/dist/json-document-store.d.ts +0 -1
- package/dist/json-durable-queue-directory.d.ts +13 -1
- package/dist/json-durable-queue-directory.js +134 -0
- package/dist/json-durable-queue-ownership.d.ts +0 -1
- package/dist/json-durable-queue-ownership.js +43 -66
- package/dist/json-durable-queue-read.d.ts +0 -1
- package/dist/json-durable-queue-read.js +6 -6
- package/dist/json-durable-queue.d.ts +0 -1
- package/dist/json-durable-queue.js +17 -139
- package/dist/json-store.d.ts +0 -1
- package/dist/json-stringify.d.ts +0 -1
- package/dist/json.d.ts +0 -1
- package/dist/json.js +38 -90
- package/dist/local-file-access.d.ts +0 -1
- package/dist/local-file-access.js +3 -10
- package/dist/local-file-descriptor.d.ts +0 -1
- package/dist/local-roots.d.ts +0 -1
- package/dist/local-roots.js +19 -21
- package/dist/lock-config.d.ts +0 -1
- package/dist/move-path-cleanup.d.ts +5 -20
- package/dist/move-path-cleanup.js +57 -21
- package/dist/move-path-stage.d.ts +0 -1
- package/dist/move-path.d.ts +0 -1
- package/dist/move-path.js +62 -39
- package/dist/mutation-authority.d.ts +0 -1
- package/dist/native-binding.d.ts +0 -1
- package/dist/native-config.d.ts +0 -1
- package/dist/native-directory-observation.d.ts +0 -1
- package/dist/native-fallback-warning.d.ts +0 -1
- package/dist/native-operations.d.ts +1 -5
- package/dist/native-operations.js +2 -6
- package/dist/native-parent-admission.d.ts +0 -1
- package/dist/native-pinned-write-windows.d.ts +0 -1
- package/dist/native-pinned-write.d.ts +0 -1
- package/dist/native-pinned-write.js +4 -10
- package/dist/native-policy-directory-observation.d.ts +0 -1
- package/dist/native-policy-parent-windows.d.ts +0 -1
- package/dist/native-rename-outcome.d.ts +0 -1
- package/dist/native-staged-file.d.ts +17 -4
- package/dist/native-staged-file.js +63 -68
- package/dist/native.d.ts +0 -1
- package/dist/native.js +2 -2
- package/dist/opened-file-failure.d.ts +0 -1
- package/dist/opened-realpath.d.ts +0 -1
- package/dist/opened-realpath.js +11 -2
- package/dist/output.d.ts +0 -1
- package/dist/overwrite-file-handle.d.ts +0 -1
- package/dist/owner-dacl.d.ts +0 -1
- package/dist/path-case.d.ts +0 -1
- package/dist/path-policy.d.ts +0 -1
- package/dist/path-prefix.d.ts +0 -1
- package/dist/path-scope-lexical.d.ts +0 -1
- package/dist/path-segment-route.d.ts +0 -1
- package/dist/path-suffix-aliases.d.ts +0 -1
- package/dist/path.d.ts +0 -1
- package/dist/path.js +2 -1
- package/dist/permission-exec.d.ts +0 -1
- package/dist/permission-exec.js +19 -25
- package/dist/permissions-public.d.ts +0 -1
- package/dist/permissions-windows.d.ts +2 -10
- package/dist/permissions-windows.js +10 -30
- package/dist/permissions.d.ts +0 -1
- package/dist/permissions.js +11 -33
- package/dist/pinned-mutation-admission.d.ts +0 -1
- package/dist/pinned-mutation-observation.d.ts +0 -1
- package/dist/pinned-mutation-shared-route.d.ts +0 -1
- package/dist/pinned-open.d.ts +1 -1
- package/dist/pinned-open.js +1 -1
- package/dist/pinned-operation.d.ts +0 -1
- package/dist/pinned-write-input.d.ts +0 -1
- package/dist/pinned-write-input.js +11 -1
- package/dist/pinned-write-mode.d.ts +3 -4
- package/dist/pinned-write-mode.js +15 -8
- package/dist/pinned-write-staged.d.ts +0 -1
- package/dist/pinned-write-staged.js +10 -11
- package/dist/pinned-write-types.d.ts +9 -21
- package/dist/pinned-write.d.ts +0 -1
- package/dist/pinned-write.js +17 -13
- package/dist/positional-read.d.ts +0 -1
- package/dist/private-directory.d.ts +0 -1
- package/dist/private-producer-handoff-sync.d.ts +0 -1
- package/dist/private-producer-handoff-sync.js +9 -51
- package/dist/private-producer-handoff.d.ts +20 -1
- package/dist/private-producer-handoff.js +69 -46
- package/dist/private-temp-workspace.d.ts +0 -1
- package/dist/private-temp-workspace.js +11 -36
- package/dist/publish-copy-stage.d.ts +0 -1
- package/dist/publish-file-failure.d.ts +0 -1
- package/dist/publish-file.d.ts +2 -3
- package/dist/publish-file.js +56 -96
- package/dist/read-open-flags.d.ts +0 -1
- package/dist/read-opened-file.d.ts +0 -1
- package/dist/realpath.d.ts +0 -1
- package/dist/recursive-mkdir-path.d.ts +0 -1
- package/dist/regular-file.d.ts +0 -1
- package/dist/regular-file.js +107 -178
- package/dist/replace-directory.d.ts +0 -1
- package/dist/replace-file-copy-fallback.d.ts +0 -1
- package/dist/replace-file-copy-fallback.js +42 -29
- package/dist/replace-file-copy-source.d.ts +0 -1
- package/dist/replace-file-copy-source.js +19 -23
- package/dist/replace-file-descriptor.d.ts +0 -1
- package/dist/replace-file-descriptor.js +16 -17
- package/dist/replace-file-mode.d.ts +0 -1
- package/dist/replace-file-rename-policy.d.ts +0 -1
- package/dist/replace-file-temp-owner.d.ts +12 -13
- package/dist/replace-file-temp-owner.js +72 -91
- package/dist/replace-file.d.ts +0 -1
- package/dist/replace-file.js +9 -13
- package/dist/retained-directory-replacement.d.ts +0 -1
- package/dist/root-boundary.d.ts +0 -1
- package/dist/root-context.d.ts +0 -1
- package/dist/root-create-input.d.ts +0 -1
- package/dist/root-directory-creation.d.ts +0 -1
- package/dist/root-directory-list.d.ts +0 -1
- package/dist/root-directory-list.js +20 -3
- package/dist/root-directory.d.ts +0 -1
- package/dist/root-entries.d.ts +0 -1
- package/dist/root-errors.d.ts +0 -1
- package/dist/root-file-final-admission.d.ts +1 -2
- package/dist/root-file-final-admission.js +5 -2
- package/dist/root-file.d.ts +0 -1
- package/dist/root-file.js +3 -2
- package/dist/root-impl.d.ts +2 -10
- package/dist/root-impl.js +164 -111
- package/dist/root-move-noreplace.d.ts +2 -1
- package/dist/root-move-noreplace.js +2 -2
- package/dist/root-move-preflight.d.ts +0 -1
- package/dist/root-observed-path.d.ts +0 -1
- package/dist/root-options.d.ts +0 -1
- package/dist/root-path-errors.d.ts +0 -1
- package/dist/root-path-existing.d.ts +3 -1
- package/dist/root-path-existing.js +39 -18
- package/dist/root-path-observation.d.ts +0 -1
- package/dist/root-path-stat.d.ts +0 -1
- package/dist/root-path.d.ts +0 -1
- package/dist/root-path.js +60 -188
- package/dist/root-paths-lexical.d.ts +0 -1
- package/dist/root-paths.d.ts +0 -1
- package/dist/root-read-admission.d.ts +0 -1
- package/dist/root-read-admission.js +31 -39
- package/dist/root-remove-identity.d.ts +0 -1
- package/dist/root-remove-receipt.d.ts +0 -1
- package/dist/root-remove.d.ts +0 -1
- package/dist/root-remove.js +15 -1
- package/dist/root-symlink-policy.d.ts +0 -1
- package/dist/root-walk.d.ts +0 -1
- package/dist/root-write-admission.d.ts +0 -1
- package/dist/root-write-compatibility.d.ts +0 -1
- package/dist/root-write-complete-parent.d.ts +0 -1
- package/dist/root-write-lock-binding.d.ts +0 -1
- package/dist/root-write-mode.d.ts +0 -1
- package/dist/root-write-publication.d.ts +0 -1
- package/dist/root-write-verification.d.ts +0 -1
- package/dist/root.d.ts +0 -1
- package/dist/safe-path-segment.d.ts +1 -2
- package/dist/safe-path-segment.js +2 -5
- package/dist/secret-file.d.ts +0 -1
- package/dist/secret-file.js +7 -17
- package/dist/secret-read-async.d.ts +0 -1
- package/dist/secret-read-async.js +5 -5
- package/dist/secret-read-policy.d.ts +0 -1
- package/dist/secret.d.ts +0 -1
- package/dist/secure-file-windows.d.ts +0 -6
- package/dist/secure-file-windows.js +13 -28
- package/dist/secure-file.d.ts +0 -1
- package/dist/secure-file.js +9 -9
- package/dist/secure-temp-dir.d.ts +0 -1
- package/dist/secure-temp-repair.d.ts +0 -1
- package/dist/sibling-staged-file.d.ts +0 -1
- package/dist/sibling-staged-file.js +32 -39
- package/dist/sibling-temp.d.ts +0 -1
- package/dist/sidecar-lock-acquire.d.ts +1 -2
- package/dist/sidecar-lock-acquire.js +35 -58
- package/dist/sidecar-lock-admission-context.d.ts +0 -1
- package/dist/sidecar-lock-admission-parser.d.ts +0 -1
- package/dist/sidecar-lock-admission.d.ts +1 -5
- package/dist/sidecar-lock-admission.js +1 -7
- package/dist/sidecar-lock-handle.d.ts +3 -1
- package/dist/sidecar-lock-handle.js +6 -0
- package/dist/sidecar-lock-policy.d.ts +3 -1
- package/dist/sidecar-lock-policy.js +16 -0
- package/dist/sidecar-lock-reclaim.d.ts +1 -2
- package/dist/sidecar-lock-reclaim.js +11 -8
- package/dist/sidecar-lock-registration.d.ts +13 -0
- package/dist/sidecar-lock-registration.js +47 -0
- package/dist/sidecar-lock-root.d.ts +0 -1
- package/dist/sidecar-lock-stale-admission.d.ts +0 -1
- package/dist/sidecar-lock-target.d.ts +0 -1
- package/dist/sidecar-lock-types.d.ts +0 -1
- package/dist/sidecar-lock.d.ts +0 -1
- package/dist/sidecar-lock.js +19 -88
- package/dist/staged-directory.d.ts +2 -3
- package/dist/staged-file-settlement.d.ts +0 -1
- package/dist/staged-file-types.d.ts +0 -1
- package/dist/standalone-publication-path.d.ts +0 -1
- package/dist/stat-observation.d.ts +0 -1
- package/dist/store.d.ts +0 -1
- package/dist/strict-file-identity.d.ts +1 -2
- package/dist/strict-file-identity.js +9 -9
- package/dist/string-coerce.d.ts +0 -1
- package/dist/suppressed-error.d.ts +0 -1
- package/dist/symlink-parents.d.ts +0 -1
- package/dist/symlink-parents.js +2 -27
- package/dist/temp-cleanup.d.ts +0 -1
- package/dist/temp-target.d.ts +0 -1
- package/dist/temp-target.js +7 -46
- package/dist/temp-workspace-admission.d.ts +0 -8
- package/dist/temp-workspace-admission.js +0 -4
- package/dist/temp-workspace-child-admission.d.ts +0 -4
- package/dist/temp-workspace-child-admission.js +0 -12
- package/dist/temp-workspace-descriptor.d.ts +0 -6
- package/dist/temp-workspace-descriptor.js +0 -2
- package/dist/temp-workspace-identity.d.ts +0 -1
- package/dist/temp-workspace-owner.d.ts +1 -1
- package/dist/temp-workspace-owner.js +49 -26
- package/dist/temp-workspace-permissions.d.ts +0 -1
- package/dist/temp-workspace-types.d.ts +0 -1
- package/dist/temp.d.ts +0 -1
- package/dist/test-hooks.d.ts +0 -1
- package/dist/text-atomic.d.ts +0 -1
- package/dist/timing.d.ts +0 -1
- package/dist/trash.d.ts +0 -1
- package/dist/types.d.ts +0 -1
- package/dist/unicode-path.d.ts +0 -1
- package/dist/unicode-path.js +3 -0
- package/dist/walk.d.ts +0 -1
- package/dist/walk.js +4 -2
- package/dist/windows-command.d.ts +0 -1
- package/dist/windows-owner.d.ts +0 -1
- package/dist/windows-owner.js +4 -1
- package/dist/windows-path-alias.d.ts +0 -1
- package/dist/windows-path-alias.js +7 -43
- package/dist/windows-path-syntax.d.ts +5 -0
- package/dist/windows-path-syntax.js +21 -0
- package/dist/windows-security-command.d.ts +0 -1
- package/dist/windows-security-facts.d.ts +0 -1
- package/dist/write-file-handle.d.ts +7 -1
- package/dist/write-file-handle.js +23 -0
- package/dist/write-open-flags.d.ts +0 -1
- package/dist/write-open-flags.js +1 -8
- package/dist/write-queue.d.ts +0 -1
- package/dist/write-queue.js +1 -4
- package/docs/advanced.md +68 -1
- package/docs/archive.md +41 -2
- package/docs/atomic.md +43 -5
- package/docs/contributing.md +4 -0
- package/docs/copy.md +2 -0
- package/docs/creation.md +8 -4
- package/docs/durability.md +35 -0
- package/docs/file-contents.md +68 -0
- package/docs/json.md +5 -4
- package/docs/local-roots.md +2 -0
- package/docs/mutation-policy-proof.md +11 -7
- package/docs/native.md +9 -8
- package/docs/path.md +4 -4
- package/docs/permissions.md +6 -0
- package/docs/public-api.md +5 -0
- package/docs/quickstart.md +1 -1
- package/docs/reading.md +2 -2
- package/docs/regular-file.md +3 -0
- package/docs/root.md +19 -0
- package/docs/secret-file.md +4 -0
- package/docs/sidecar-lock.md +9 -1
- package/docs/staged-file.md +4 -3
- package/docs/store.md +3 -1
- package/docs/temp.md +4 -1
- package/docs/types.md +18 -2
- package/docs/walk.md +7 -0
- package/docs/writing.md +18 -5
- package/package.json +8 -9
- package/dist/absolute-path.d.ts.map +0 -1
- package/dist/advanced.d.ts.map +0 -1
- package/dist/archive-crc32.d.ts.map +0 -1
- package/dist/archive-deadline.d.ts.map +0 -1
- package/dist/archive-durability.d.ts.map +0 -1
- package/dist/archive-entry.d.ts.map +0 -1
- package/dist/archive-errors.d.ts.map +0 -1
- package/dist/archive-gzip-tail.d.ts.map +0 -1
- package/dist/archive-input.d.ts.map +0 -1
- package/dist/archive-kind.d.ts.map +0 -1
- package/dist/archive-limits.d.ts.map +0 -1
- package/dist/archive-merge.d.ts.map +0 -1
- package/dist/archive-native.d.ts.map +0 -1
- package/dist/archive-options.d.ts.map +0 -1
- package/dist/archive-parser-errors.d.ts.map +0 -1
- package/dist/archive-plan.d.ts.map +0 -1
- package/dist/archive-policy.d.ts.map +0 -1
- package/dist/archive-read.d.ts.map +0 -1
- package/dist/archive-staging.d.ts.map +0 -1
- package/dist/archive-tar-inspect.d.ts.map +0 -1
- package/dist/archive-tar-stream.d.ts.map +0 -1
- package/dist/archive-tar-wasm.d.ts.map +0 -1
- package/dist/archive-tar.d.ts.map +0 -1
- package/dist/archive-zip-admission.d.ts.map +0 -1
- package/dist/archive-zip-count.d.ts.map +0 -1
- package/dist/archive-zip-directory.d.ts.map +0 -1
- package/dist/archive-zip-entry.d.ts.map +0 -1
- package/dist/archive-zip-integrity.d.ts.map +0 -1
- package/dist/archive-zip-loader.d.ts.map +0 -1
- package/dist/archive-zip-manifest.d.ts.map +0 -1
- package/dist/archive-zip-names.d.ts.map +0 -1
- package/dist/archive-zip-preflight.d.ts.map +0 -1
- package/dist/archive.d.ts.map +0 -1
- package/dist/async-lock.d.ts.map +0 -1
- package/dist/atomic.d.ts.map +0 -1
- package/dist/bounded-read-stream.d.ts.map +0 -1
- package/dist/bounded-read.d.ts.map +0 -1
- package/dist/byte-budget.d.ts.map +0 -1
- package/dist/clone-metadata.d.ts.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/containment.d.ts.map +0 -1
- package/dist/copy-file-input.d.ts.map +0 -1
- package/dist/copy-policy.d.ts.map +0 -1
- package/dist/copy-publication.d.ts.map +0 -1
- package/dist/copy-tree-portable.d.ts.map +0 -1
- package/dist/copy.d.ts.map +0 -1
- package/dist/create-directory.d.ts.map +0 -1
- package/dist/create-file-async.d.ts.map +0 -1
- package/dist/create-file.d.ts.map +0 -1
- package/dist/create-owned-file.d.ts.map +0 -1
- package/dist/create.d.ts.map +0 -1
- package/dist/creation-darwin.d.ts.map +0 -1
- package/dist/creation-file-state.d.ts.map +0 -1
- package/dist/creation-path.d.ts.map +0 -1
- package/dist/creation-permissions.d.ts.map +0 -1
- package/dist/deny-mutations.d.ts.map +0 -1
- package/dist/device-path.d.ts.map +0 -1
- package/dist/directory-durability.d.ts.map +0 -1
- package/dist/directory-entry-path.d.ts.map +0 -1
- package/dist/directory-guard.d.ts.map +0 -1
- package/dist/directory-mode-node.d.ts.map +0 -1
- package/dist/directory-mode-owner.d.ts.map +0 -1
- package/dist/directory-receipt.d.ts.map +0 -1
- package/dist/durability.d.ts.map +0 -1
- package/dist/effective-uid.d.ts.map +0 -1
- package/dist/error-detail.d.ts.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/file-cleanup.d.ts.map +0 -1
- package/dist/file-handle-transfer.d.ts.map +0 -1
- package/dist/file-hash.d.ts.map +0 -1
- package/dist/file-identity.d.ts.map +0 -1
- package/dist/file-lock-sync-admission.d.ts.map +0 -1
- package/dist/file-lock-sync-root-acquire.d.ts.map +0 -1
- package/dist/file-lock-sync-root-arbitration.d.ts.map +0 -1
- package/dist/file-lock-sync-root-held.d.ts.map +0 -1
- package/dist/file-lock-sync-root-io.d.ts.map +0 -1
- package/dist/file-lock-sync-root-mutation.d.ts.map +0 -1
- package/dist/file-lock-sync-root-options.d.ts.map +0 -1
- package/dist/file-lock-sync-root-registration.d.ts.map +0 -1
- package/dist/file-lock-sync-root.d.ts.map +0 -1
- package/dist/file-lock-sync-stale-admission.d.ts.map +0 -1
- package/dist/file-lock-sync.d.ts.map +0 -1
- package/dist/file-lock.d.ts.map +0 -1
- package/dist/file-observation.d.ts.map +0 -1
- package/dist/file-store-boundary.d.ts.map +0 -1
- package/dist/file-store-copy-source.d.ts.map +0 -1
- package/dist/file-store-limit.d.ts.map +0 -1
- package/dist/file-store-path.d.ts.map +0 -1
- package/dist/file-store-prune.d.ts.map +0 -1
- package/dist/file-store-sync-directory.d.ts.map +0 -1
- package/dist/file-store-sync-write.d.ts.map +0 -1
- package/dist/file-store.d.ts.map +0 -1
- package/dist/file-sync.d.ts.map +0 -1
- package/dist/filename.d.ts.map +0 -1
- package/dist/fs.d.ts.map +0 -1
- package/dist/guarded-mkdir.d.ts.map +0 -1
- package/dist/guarded-mutation.d.ts.map +0 -1
- package/dist/guest-dispatch-python.d.ts.map +0 -1
- package/dist/guest-native-python.d.ts.map +0 -1
- package/dist/guest.d.ts.map +0 -1
- package/dist/home-dir.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/install-path.d.ts.map +0 -1
- package/dist/json-document-store.d.ts.map +0 -1
- package/dist/json-durable-queue-directory.d.ts.map +0 -1
- package/dist/json-durable-queue-ownership.d.ts.map +0 -1
- package/dist/json-durable-queue-paths.d.ts +0 -11
- package/dist/json-durable-queue-paths.d.ts.map +0 -1
- package/dist/json-durable-queue-paths.js +0 -42
- package/dist/json-durable-queue-read.d.ts.map +0 -1
- package/dist/json-durable-queue.d.ts.map +0 -1
- package/dist/json-store.d.ts.map +0 -1
- package/dist/json-stringify.d.ts.map +0 -1
- package/dist/json.d.ts.map +0 -1
- package/dist/local-file-access.d.ts.map +0 -1
- package/dist/local-file-descriptor.d.ts.map +0 -1
- package/dist/local-roots.d.ts.map +0 -1
- package/dist/lock-config.d.ts.map +0 -1
- package/dist/move-path-cleanup.d.ts.map +0 -1
- package/dist/move-path-stage.d.ts.map +0 -1
- package/dist/move-path.d.ts.map +0 -1
- package/dist/mutation-authority.d.ts.map +0 -1
- package/dist/native-binding.d.ts.map +0 -1
- package/dist/native-config.d.ts.map +0 -1
- package/dist/native-directory-observation.d.ts.map +0 -1
- package/dist/native-fallback-warning.d.ts.map +0 -1
- package/dist/native-operations.d.ts.map +0 -1
- package/dist/native-parent-admission.d.ts.map +0 -1
- package/dist/native-pinned-write-windows.d.ts.map +0 -1
- package/dist/native-pinned-write.d.ts.map +0 -1
- package/dist/native-policy-directory-observation.d.ts.map +0 -1
- package/dist/native-policy-parent-windows.d.ts.map +0 -1
- package/dist/native-rename-outcome.d.ts.map +0 -1
- package/dist/native-staged-file.d.ts.map +0 -1
- package/dist/native.d.ts.map +0 -1
- package/dist/opened-file-failure.d.ts.map +0 -1
- package/dist/opened-realpath.d.ts.map +0 -1
- package/dist/output.d.ts.map +0 -1
- package/dist/overwrite-file-handle.d.ts.map +0 -1
- package/dist/owner-dacl.d.ts.map +0 -1
- package/dist/path-case.d.ts.map +0 -1
- package/dist/path-policy.d.ts.map +0 -1
- package/dist/path-prefix.d.ts.map +0 -1
- package/dist/path-scope-lexical.d.ts.map +0 -1
- package/dist/path-segment-route.d.ts.map +0 -1
- package/dist/path-suffix-aliases.d.ts.map +0 -1
- package/dist/path.d.ts.map +0 -1
- package/dist/permission-exec.d.ts.map +0 -1
- package/dist/permissions-public.d.ts.map +0 -1
- package/dist/permissions-windows.d.ts.map +0 -1
- package/dist/permissions.d.ts.map +0 -1
- package/dist/pinned-mutation-admission.d.ts.map +0 -1
- package/dist/pinned-mutation-observation.d.ts.map +0 -1
- package/dist/pinned-mutation-shared-route.d.ts.map +0 -1
- package/dist/pinned-open.d.ts.map +0 -1
- package/dist/pinned-operation.d.ts.map +0 -1
- package/dist/pinned-write-input.d.ts.map +0 -1
- package/dist/pinned-write-mode.d.ts.map +0 -1
- package/dist/pinned-write-staged.d.ts.map +0 -1
- package/dist/pinned-write-types.d.ts.map +0 -1
- package/dist/pinned-write.d.ts.map +0 -1
- package/dist/positional-read.d.ts.map +0 -1
- package/dist/private-directory.d.ts.map +0 -1
- package/dist/private-producer-handoff-sync.d.ts.map +0 -1
- package/dist/private-producer-handoff.d.ts.map +0 -1
- package/dist/private-temp-workspace.d.ts.map +0 -1
- package/dist/publish-copy-stage.d.ts.map +0 -1
- package/dist/publish-file-failure.d.ts.map +0 -1
- package/dist/publish-file.d.ts.map +0 -1
- package/dist/read-open-flags.d.ts.map +0 -1
- package/dist/read-opened-file.d.ts.map +0 -1
- package/dist/realpath.d.ts.map +0 -1
- package/dist/recursive-mkdir-path.d.ts.map +0 -1
- package/dist/regular-file.d.ts.map +0 -1
- package/dist/replace-directory.d.ts.map +0 -1
- package/dist/replace-file-copy-fallback.d.ts.map +0 -1
- package/dist/replace-file-copy-source.d.ts.map +0 -1
- package/dist/replace-file-descriptor.d.ts.map +0 -1
- package/dist/replace-file-mode.d.ts.map +0 -1
- package/dist/replace-file-rename-policy.d.ts.map +0 -1
- package/dist/replace-file-temp-owner.d.ts.map +0 -1
- package/dist/replace-file.d.ts.map +0 -1
- package/dist/retained-directory-replacement.d.ts.map +0 -1
- package/dist/root-boundary.d.ts.map +0 -1
- package/dist/root-context.d.ts.map +0 -1
- package/dist/root-create-input.d.ts.map +0 -1
- package/dist/root-directory-creation.d.ts.map +0 -1
- package/dist/root-directory-list.d.ts.map +0 -1
- package/dist/root-directory.d.ts.map +0 -1
- package/dist/root-entries.d.ts.map +0 -1
- package/dist/root-errors.d.ts.map +0 -1
- package/dist/root-file-final-admission.d.ts.map +0 -1
- package/dist/root-file.d.ts.map +0 -1
- package/dist/root-impl.d.ts.map +0 -1
- package/dist/root-move-noreplace.d.ts.map +0 -1
- package/dist/root-move-preflight.d.ts.map +0 -1
- package/dist/root-observed-path.d.ts.map +0 -1
- package/dist/root-options.d.ts.map +0 -1
- package/dist/root-path-errors.d.ts.map +0 -1
- package/dist/root-path-existing.d.ts.map +0 -1
- package/dist/root-path-observation.d.ts.map +0 -1
- package/dist/root-path-stat.d.ts.map +0 -1
- package/dist/root-path-symlink.d.ts +0 -7
- package/dist/root-path-symlink.d.ts.map +0 -1
- package/dist/root-path-symlink.js +0 -55
- package/dist/root-path.d.ts.map +0 -1
- package/dist/root-paths-lexical.d.ts.map +0 -1
- package/dist/root-paths.d.ts.map +0 -1
- package/dist/root-read-admission.d.ts.map +0 -1
- package/dist/root-remove-identity.d.ts.map +0 -1
- package/dist/root-remove-receipt.d.ts.map +0 -1
- package/dist/root-remove.d.ts.map +0 -1
- package/dist/root-symlink-policy.d.ts.map +0 -1
- package/dist/root-walk.d.ts.map +0 -1
- package/dist/root-write-admission.d.ts.map +0 -1
- package/dist/root-write-compatibility.d.ts.map +0 -1
- package/dist/root-write-complete-parent.d.ts.map +0 -1
- package/dist/root-write-lock-binding.d.ts.map +0 -1
- package/dist/root-write-mode.d.ts.map +0 -1
- package/dist/root-write-publication.d.ts.map +0 -1
- package/dist/root-write-verification.d.ts.map +0 -1
- package/dist/root.d.ts.map +0 -1
- package/dist/safe-path-segment.d.ts.map +0 -1
- package/dist/secret-file.d.ts.map +0 -1
- package/dist/secret-read-async.d.ts.map +0 -1
- package/dist/secret-read-policy.d.ts.map +0 -1
- package/dist/secret.d.ts.map +0 -1
- package/dist/secure-file-windows.d.ts.map +0 -1
- package/dist/secure-file.d.ts.map +0 -1
- package/dist/secure-temp-dir.d.ts.map +0 -1
- package/dist/secure-temp-repair.d.ts.map +0 -1
- package/dist/sibling-staged-file.d.ts.map +0 -1
- package/dist/sibling-temp.d.ts.map +0 -1
- package/dist/sidecar-lock-acquire.d.ts.map +0 -1
- package/dist/sidecar-lock-admission-context.d.ts.map +0 -1
- package/dist/sidecar-lock-admission-parser.d.ts.map +0 -1
- package/dist/sidecar-lock-admission.d.ts.map +0 -1
- package/dist/sidecar-lock-handle.d.ts.map +0 -1
- package/dist/sidecar-lock-policy.d.ts.map +0 -1
- package/dist/sidecar-lock-reclaim.d.ts.map +0 -1
- package/dist/sidecar-lock-root.d.ts.map +0 -1
- package/dist/sidecar-lock-stale-admission.d.ts.map +0 -1
- package/dist/sidecar-lock-target.d.ts.map +0 -1
- package/dist/sidecar-lock-types.d.ts.map +0 -1
- package/dist/sidecar-lock.d.ts.map +0 -1
- package/dist/staged-directory.d.ts.map +0 -1
- package/dist/staged-file-settlement.d.ts.map +0 -1
- package/dist/staged-file-types.d.ts.map +0 -1
- package/dist/standalone-publication-path.d.ts.map +0 -1
- package/dist/stat-observation.d.ts.map +0 -1
- package/dist/store.d.ts.map +0 -1
- package/dist/strict-file-identity.d.ts.map +0 -1
- package/dist/string-coerce.d.ts.map +0 -1
- package/dist/suppressed-error.d.ts.map +0 -1
- package/dist/symlink-parents.d.ts.map +0 -1
- package/dist/temp-cleanup.d.ts.map +0 -1
- package/dist/temp-target.d.ts.map +0 -1
- package/dist/temp-workspace-admission.d.ts.map +0 -1
- package/dist/temp-workspace-child-admission.d.ts.map +0 -1
- package/dist/temp-workspace-descriptor.d.ts.map +0 -1
- package/dist/temp-workspace-identity.d.ts.map +0 -1
- package/dist/temp-workspace-owner.d.ts.map +0 -1
- package/dist/temp-workspace-permissions.d.ts.map +0 -1
- package/dist/temp-workspace-types.d.ts.map +0 -1
- package/dist/temp.d.ts.map +0 -1
- package/dist/test-hooks.d.ts.map +0 -1
- package/dist/text-atomic.d.ts.map +0 -1
- package/dist/timing.d.ts.map +0 -1
- package/dist/trash.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/unicode-path.d.ts.map +0 -1
- package/dist/walk.d.ts.map +0 -1
- package/dist/windows-command.d.ts.map +0 -1
- package/dist/windows-owner.d.ts.map +0 -1
- package/dist/windows-path-alias.d.ts.map +0 -1
- package/dist/windows-security-command.d.ts.map +0 -1
- package/dist/windows-security-facts.d.ts.map +0 -1
- package/dist/write-file-handle.d.ts.map +0 -1
- package/dist/write-open-flags.d.ts.map +0 -1
- package/dist/write-queue.d.ts.map +0 -1
package/dist/root-file.d.ts
CHANGED
package/dist/root-file.js
CHANGED
|
@@ -70,14 +70,15 @@ export function matchRootFileOpenFailure(failure, handlers) {
|
|
|
70
70
|
return handlers.fallback(failure);
|
|
71
71
|
}
|
|
72
72
|
function openRootFileResolved(params) {
|
|
73
|
+
const rejectHardlinks = params.rejectHardlinks ?? true;
|
|
73
74
|
const opened = openPinnedFileSync({
|
|
74
75
|
filePath: params.absolutePath,
|
|
75
76
|
resolvedPath: params.resolvedPath,
|
|
76
|
-
rejectHardlinks
|
|
77
|
+
rejectHardlinks,
|
|
77
78
|
maxBytes: params.maxBytes,
|
|
78
79
|
allowedType: params.allowedType,
|
|
79
80
|
ioFs: params.ioFs,
|
|
80
|
-
finalAdmission: createRootFileFinalAdmission(params.ioFs, params.rootObservation, params.boundaryLabel),
|
|
81
|
+
finalAdmission: createRootFileFinalAdmission(params.ioFs, params.rootObservation, params.boundaryLabel, rejectHardlinks),
|
|
81
82
|
});
|
|
82
83
|
if (!opened.ok) {
|
|
83
84
|
return opened;
|
package/dist/root-impl.d.ts
CHANGED
|
@@ -62,14 +62,12 @@ export interface Root {
|
|
|
62
62
|
walk(relativePath: string, options: RootWalkOptions): AsyncIterableIterator<RootWalkEntry>;
|
|
63
63
|
}
|
|
64
64
|
export declare class RootHandle implements Root {
|
|
65
|
-
private readonly
|
|
66
|
-
private readonly rootIdentity;
|
|
65
|
+
private readonly context;
|
|
67
66
|
readonly rootDir: string;
|
|
68
67
|
readonly rootReal: string;
|
|
69
68
|
readonly rootWithSep: string;
|
|
70
69
|
readonly defaults: RootDefaults;
|
|
71
70
|
constructor(context: RootContext, defaults?: RootDefaults);
|
|
72
|
-
private get context();
|
|
73
71
|
private mutationOptions;
|
|
74
72
|
resolve(relativePath: string): Promise<string>;
|
|
75
73
|
open(relativePath: string, options?: RootOpenOptions): Promise<OpenResult>;
|
|
@@ -119,12 +117,6 @@ export declare function readLocalFileSafely(params: {
|
|
|
119
117
|
export declare function openLocalFileSafely(params: {
|
|
120
118
|
filePath: string;
|
|
121
119
|
}): Promise<OpenResult>;
|
|
122
|
-
export type WritableOpenResult = {
|
|
123
|
-
handle: FileHandle;
|
|
124
|
-
containment: ContainmentGuarantee;
|
|
120
|
+
export type WritableOpenResult = OpenResult & {
|
|
125
121
|
createdForWrite: boolean;
|
|
126
|
-
realPath: string;
|
|
127
|
-
stat: Stats;
|
|
128
|
-
[Symbol.asyncDispose](): Promise<void>;
|
|
129
122
|
};
|
|
130
|
-
//# sourceMappingURL=root-impl.d.ts.map
|
package/dist/root-impl.js
CHANGED
|
@@ -73,18 +73,19 @@ import { PATH_ALIAS_POLICIES } from "./path-policy.js";
|
|
|
73
73
|
import { assertNoNulPathInput, hasNodeErrorCode, isNotFoundPathError, isSymlinkOpenError, } from "./path.js";
|
|
74
74
|
import { readOpenedFileSafely } from "./read-opened-file.js";
|
|
75
75
|
import { cleanupPinnedFilePath } from "./file-cleanup.js";
|
|
76
|
+
import { sameFileIdentity } from "./file-identity.js";
|
|
76
77
|
import { removePathIfIdentityUnchanged } from "./replace-file-temp-owner.js";
|
|
77
78
|
import { realpathSync } from "./realpath.js";
|
|
78
79
|
import { mkdirPathFallback, prepareRootWriteTarget, tryMkdirAtExactParent } from "./root-directory-creation.js";
|
|
79
80
|
import { isNonRegularWriteOpenError, resolveNonblockingWriteFlag } from "./write-open-flags.js";
|
|
80
|
-
import { resolveRootPath, resolveRootPathForRemoval } from "./root-path.js";
|
|
81
|
+
import { resolveRootPath, resolveRootPathSync, resolveRootPathForRemoval } from "./root-path.js";
|
|
81
82
|
import { RemovalPathReceipts } from "./root-remove-receipt.js";
|
|
82
83
|
import { admitPathInsideRoot } from "./root-boundary.js";
|
|
83
84
|
import { listDirectoryPath, openRootDirectoryListing } from "./root-directory-list.js";
|
|
84
85
|
import { statResolvedPathInRoot } from "./root-path-stat.js";
|
|
85
86
|
import { entriesInRoot } from "./root-entries.js";
|
|
86
87
|
import { assertMoveMutationAllowed } from "./root-move-preflight.js";
|
|
87
|
-
import { assertRootIdentityCurrent, assertValidRootDestinationPath, assertValidRootRelativePath, ensureTrailingSep, expandRelativePathWithHome, resolvePathInRoot, resolveRootContext, rootRelativeReadPath, } from "./root-context.js";
|
|
88
|
+
import { assertRootIdentityCurrent, assertRootIdentityCurrentSync, assertValidRootDestinationPath, assertValidRootRelativePath, ensureTrailingSep, expandRelativePathWithHome, resolvePathInRoot, resolveRootContext, rootRelativeReadPath, } from "./root-context.js";
|
|
88
89
|
import { fileNotFoundError, hardlinkedPathNotAllowedError, isAlreadyExistsError, normalizePinnedPathError, normalizePinnedWriteError, outsideWorkspaceError, } from "./root-errors.js";
|
|
89
90
|
import { getFsSafeTestHooks } from "./test-hooks.js";
|
|
90
91
|
import { stringifyJsonDocument } from "./json-stringify.js";
|
|
@@ -99,7 +100,7 @@ import { finishRootFallbackWrite } from "./root-write-publication.js";
|
|
|
99
100
|
import { withRootFallbackCompatibilityLock } from "./root-write-compatibility.js";
|
|
100
101
|
import { assertRootFallbackWritePath } from "./root-write-lock-binding.js";
|
|
101
102
|
import { inspectFileIdentity, inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
102
|
-
import { movePathNoReplaceNative } from "./root-move-noreplace.js";
|
|
103
|
+
import { admitMoveSourceStat, movePathNoReplaceNative } from "./root-move-noreplace.js";
|
|
103
104
|
import { admitRootReadHandle, inspectOpenedPathIdentitySync } from "./root-read-admission.js";
|
|
104
105
|
import { createCopyPublicationObserver, onCopyPublication, onCopySourceAdmission } from "./copy-publication.js";
|
|
105
106
|
import { writeAllToFile } from "./write-file-handle.js";
|
|
@@ -186,30 +187,19 @@ async function openVerifiedLocalFile(filePath, options) {
|
|
|
186
187
|
}
|
|
187
188
|
}
|
|
188
189
|
export class RootHandle {
|
|
189
|
-
|
|
190
|
-
rootIdentity;
|
|
190
|
+
context;
|
|
191
191
|
rootDir;
|
|
192
192
|
rootReal;
|
|
193
193
|
rootWithSep;
|
|
194
194
|
defaults;
|
|
195
195
|
constructor(context, defaults = {}) {
|
|
196
|
-
this.
|
|
197
|
-
this.rootIdentity = context.rootIdentity;
|
|
196
|
+
this.context = context;
|
|
198
197
|
this.rootDir = context.rootDir;
|
|
199
198
|
this.rootReal = context.rootReal;
|
|
200
199
|
this.rootWithSep = context.rootWithSep;
|
|
201
200
|
this.defaults = defaults;
|
|
202
201
|
registerFileLockSyncRootAdapter(this, context, defaults);
|
|
203
202
|
}
|
|
204
|
-
get context() {
|
|
205
|
-
return {
|
|
206
|
-
rootDir: this.rootDir,
|
|
207
|
-
rootGuard: this.rootGuard,
|
|
208
|
-
rootIdentity: this.rootIdentity,
|
|
209
|
-
rootReal: this.rootReal,
|
|
210
|
-
rootWithSep: this.rootWithSep,
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
203
|
mutationOptions(options) {
|
|
214
204
|
return {
|
|
215
205
|
...options,
|
|
@@ -224,9 +214,9 @@ export class RootHandle {
|
|
|
224
214
|
}
|
|
225
215
|
async open(relativePath, options = {}) {
|
|
226
216
|
return await openFileInRoot(this.context, {
|
|
227
|
-
relativePath,
|
|
228
217
|
...readDefaults(this.defaults),
|
|
229
218
|
...options,
|
|
219
|
+
relativePath,
|
|
230
220
|
});
|
|
231
221
|
}
|
|
232
222
|
async read(relativePath, options = {}) {
|
|
@@ -246,9 +236,11 @@ export class RootHandle {
|
|
|
246
236
|
return JSON.parse(await this.readText(relativePath, options));
|
|
247
237
|
}
|
|
248
238
|
async readAbsolute(filePath, options = {}) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
239
|
+
const context = this.context;
|
|
240
|
+
const readOptions = mergeReadOptions(this.defaults, options);
|
|
241
|
+
return await readFileInRoot(context, {
|
|
242
|
+
relativePath: rootRelativeReadPath(context, filePath),
|
|
243
|
+
...readOptions,
|
|
252
244
|
});
|
|
253
245
|
}
|
|
254
246
|
reader(options = {}) {
|
|
@@ -260,10 +252,11 @@ export class RootHandle {
|
|
|
260
252
|
assertValidRootDestinationPath(relativePath);
|
|
261
253
|
const writeMode = options.writeMode ?? "replace";
|
|
262
254
|
const target = await openWritableFileInRoot(this.context, {
|
|
263
|
-
relativePath,
|
|
264
255
|
mkdir: this.defaults.mkdir,
|
|
265
256
|
mode: this.defaults.mode,
|
|
266
257
|
...this.mutationOptions(options),
|
|
258
|
+
relativePath,
|
|
259
|
+
expectedWritePath: undefined,
|
|
267
260
|
append: writeMode === "append",
|
|
268
261
|
truncateExisting: writeMode === "replace",
|
|
269
262
|
}).catch(rethrowMutationAuthorityError);
|
|
@@ -272,11 +265,11 @@ export class RootHandle {
|
|
|
272
265
|
async append(relativePath, data, options = {}) {
|
|
273
266
|
assertValidRootDestinationPath(relativePath);
|
|
274
267
|
await appendFileInRoot(this.context, {
|
|
275
|
-
relativePath,
|
|
276
|
-
data,
|
|
277
268
|
mkdir: this.defaults.mkdir,
|
|
278
269
|
mode: this.defaults.mode,
|
|
279
270
|
...this.mutationOptions(options),
|
|
271
|
+
relativePath,
|
|
272
|
+
data,
|
|
280
273
|
durable: options.durable ?? this.defaults.durable ?? true,
|
|
281
274
|
}).catch(rethrowMutationAuthorityError);
|
|
282
275
|
}
|
|
@@ -285,33 +278,34 @@ export class RootHandle {
|
|
|
285
278
|
validateRemoveOptions(options);
|
|
286
279
|
options.signal?.throwIfAborted();
|
|
287
280
|
await removePathInRoot(this.context, {
|
|
288
|
-
relativePath,
|
|
289
281
|
...this.mutationOptions(options),
|
|
282
|
+
relativePath,
|
|
290
283
|
}).catch(rethrowMutationAuthorityError);
|
|
291
284
|
}
|
|
292
285
|
async mkdir(relativePath, options = {}) {
|
|
293
286
|
assertValidRootDestinationPath(relativePath);
|
|
294
287
|
await mkdirPathInRoot(this.context, {
|
|
295
|
-
relativePath,
|
|
296
288
|
...this.mutationOptions(options),
|
|
289
|
+
relativePath,
|
|
290
|
+
allowRoot: false,
|
|
297
291
|
}).catch(rethrowMutationAuthorityError);
|
|
298
292
|
}
|
|
299
293
|
async ensureRoot(options = {}) {
|
|
300
294
|
await mkdirPathInRoot(this.context, {
|
|
295
|
+
...this.mutationOptions(options),
|
|
301
296
|
relativePath: "",
|
|
302
297
|
allowRoot: true,
|
|
303
|
-
...this.mutationOptions(options),
|
|
304
298
|
}).catch(rethrowMutationAuthorityError);
|
|
305
299
|
}
|
|
306
300
|
async write(relativePath, data, options = {}) {
|
|
307
301
|
assertValidRootDestinationPath(relativePath);
|
|
308
302
|
await writeFileInRoot(this.context, {
|
|
309
|
-
relativePath,
|
|
310
|
-
data,
|
|
311
303
|
mkdir: this.defaults.mkdir,
|
|
312
304
|
mode: this.defaults.mode,
|
|
313
305
|
renameIdentity: this.defaults.renameIdentity,
|
|
314
306
|
...this.mutationOptions(options),
|
|
307
|
+
relativePath,
|
|
308
|
+
data,
|
|
315
309
|
durable: options.durable ?? this.defaults.durable ?? true,
|
|
316
310
|
}).catch(rethrowMutationAuthorityError);
|
|
317
311
|
}
|
|
@@ -319,11 +313,11 @@ export class RootHandle {
|
|
|
319
313
|
assertValidRootDestinationPath(relativePath);
|
|
320
314
|
const durable = options.durable ?? this.defaults.durable ?? true;
|
|
321
315
|
await writeFileInRoot(this.context, {
|
|
322
|
-
relativePath,
|
|
323
|
-
data,
|
|
324
316
|
mkdir: this.defaults.mkdir,
|
|
325
317
|
mode: this.defaults.mode,
|
|
326
318
|
...this.mutationOptions(createInputOptions(data, options, this.defaults.maxBytes)),
|
|
319
|
+
relativePath,
|
|
320
|
+
data,
|
|
327
321
|
durable: durable !== false,
|
|
328
322
|
strictFileSync: durable === "file",
|
|
329
323
|
overwrite: false,
|
|
@@ -343,12 +337,13 @@ export class RootHandle {
|
|
|
343
337
|
options.signal?.throwIfAborted();
|
|
344
338
|
assertValidRootDestinationPath(relativePath);
|
|
345
339
|
const { maxBytes, ...copyOptions } = this.mutationOptions(options);
|
|
340
|
+
const copySource = typeof source === "string" ? source : { root: source.root, relativePath: source.relativePath };
|
|
346
341
|
await copyFileInRoot(this.context, {
|
|
347
|
-
source: typeof source === "string" ? source : { root: source.root, relativePath: source.relativePath },
|
|
348
|
-
relativePath,
|
|
349
342
|
maxBytes: normalizeMaxBytes(maxBytes, { defaultValue: this.defaults.maxBytes }),
|
|
350
343
|
mkdir: this.defaults.mkdir,
|
|
351
344
|
...copyOptions,
|
|
345
|
+
source: copySource,
|
|
346
|
+
relativePath,
|
|
352
347
|
mode: options.mode ?? this.defaults.mode,
|
|
353
348
|
durable: options.durable ?? this.defaults.durable ?? true,
|
|
354
349
|
verifyPublished: options[onCopyPublication],
|
|
@@ -409,7 +404,7 @@ export class RootHandle {
|
|
|
409
404
|
walk(relativePath, options) {
|
|
410
405
|
assertValidRootRelativePath(relativePath);
|
|
411
406
|
return walkRoot({
|
|
412
|
-
rootReal: this.rootReal,
|
|
407
|
+
rootReal: this.context.rootReal,
|
|
413
408
|
stat: relative => this.stat(relative),
|
|
414
409
|
list: async (relative, listingOptions) => {
|
|
415
410
|
validatePinnedOperationPayload({ relativePath: relative });
|
|
@@ -468,15 +463,6 @@ async function readFileInRoot(root, params) {
|
|
|
468
463
|
await opened.handle.close().catch(() => { });
|
|
469
464
|
}
|
|
470
465
|
}
|
|
471
|
-
async function readPathInRoot(root, params) {
|
|
472
|
-
const relativePath = rootRelativeReadPath(root, params.filePath);
|
|
473
|
-
return await readFileInRoot(root, {
|
|
474
|
-
relativePath,
|
|
475
|
-
hardlinks: params.hardlinks,
|
|
476
|
-
maxBytes: params.maxBytes,
|
|
477
|
-
symlinks: params.symlinks,
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
466
|
export async function readLocalFileSafely(params) {
|
|
481
467
|
const maxBytes = normalizeMaxBytes(params.maxBytes);
|
|
482
468
|
const opened = await openLocalFileSafely({ filePath: params.filePath });
|
|
@@ -502,7 +488,7 @@ function buildAtomicWriteTempPath(targetPath) {
|
|
|
502
488
|
function rootWriteQueueKey(root, relativePath) {
|
|
503
489
|
return `${root.rootReal}\0${relativePath}`;
|
|
504
490
|
}
|
|
505
|
-
async function openWritableFileInRoot(root, params) {
|
|
491
|
+
async function openWritableFileInRoot(root, params, options) {
|
|
506
492
|
const guardedTarget = params.denyMutations === undefined && params.mutationSymlinks === undefined
|
|
507
493
|
? undefined
|
|
508
494
|
: await resolveGuardedWriteTargetInRoot(root, {
|
|
@@ -566,6 +552,17 @@ async function openWritableFileInRoot(root, params) {
|
|
|
566
552
|
if (!isNotFoundPathError(err)) {
|
|
567
553
|
throw err;
|
|
568
554
|
}
|
|
555
|
+
if (options?.createIfMissing === false) {
|
|
556
|
+
const parentGuard = writePathSelection?.parentGuard ??
|
|
557
|
+
await createAsyncDirectoryGuard(path.dirname(ioPath), { bigint: true });
|
|
558
|
+
assertRootIdentityCurrentSync(root);
|
|
559
|
+
if (!admitPathInsideRoot({
|
|
560
|
+
rootPath: root.rootReal, candidatePath: parentGuard.realPath, rootIdentity: root.rootIdentity,
|
|
561
|
+
}))
|
|
562
|
+
throw outsideWorkspaceError();
|
|
563
|
+
assertSyncDirectoryGuard(parentGuard);
|
|
564
|
+
return { missing: true, targetPath: ioPath, parentGuard, writeSelection: writePathSelection };
|
|
565
|
+
}
|
|
569
566
|
if (writePathSelection)
|
|
570
567
|
await refreshRootWritePathSelection(writePathSelection);
|
|
571
568
|
params.assertBeforeMutation?.();
|
|
@@ -723,8 +720,9 @@ async function appendFileInRoot(root, params) {
|
|
|
723
720
|
if (params.prependNewlineIfNeeded === true &&
|
|
724
721
|
!target.createdForWrite &&
|
|
725
722
|
target.stat.size > 0 &&
|
|
723
|
+
params.data.length > 0 &&
|
|
726
724
|
((typeof params.data === "string" && !params.data.startsWith("\n")) ||
|
|
727
|
-
(Buffer.isBuffer(params.data) && params.data
|
|
725
|
+
(Buffer.isBuffer(params.data) && params.data[0] !== 0x0a))) {
|
|
728
726
|
const newline = Buffer.from("\n", typeof params.data === "string" ? params.encoding : "utf8");
|
|
729
727
|
const tail = Buffer.alloc(newline.length);
|
|
730
728
|
const { bytesRead } = await target.handle.read(tail, 0, tail.length, Math.max(0, target.stat.size - tail.length));
|
|
@@ -789,16 +787,11 @@ async function mkdirPathInRoot(root, params) {
|
|
|
789
787
|
const policy = params.denyMutations === undefined && params.mutationSymlinks === undefined
|
|
790
788
|
? undefined
|
|
791
789
|
: snapshotPinnedMutationPolicy(params.denyMutations, params.mutationSymlinks);
|
|
790
|
+
const resolution = { relativePath: params.relativePath, allowRoot: params.allowRoot, ...policy };
|
|
792
791
|
const resolveCurrent = policy
|
|
793
|
-
? async () => await resolvePinnedPathInRoot(root,
|
|
794
|
-
...params,
|
|
795
|
-
denyMutations: policy.denyMutations,
|
|
796
|
-
mutationSymlinks: policy.mutationSymlinks,
|
|
797
|
-
})
|
|
792
|
+
? async () => await resolvePinnedPathInRoot(root, resolution)
|
|
798
793
|
: undefined;
|
|
799
|
-
const resolved =
|
|
800
|
-
? await resolveCurrent()
|
|
801
|
-
: await resolvePinnedPathInRoot(root, params);
|
|
794
|
+
const resolved = await resolvePinnedPathInRoot(root, resolution);
|
|
802
795
|
const prepared = policy && resolved.relativePosix !== ""
|
|
803
796
|
? await preparePinnedWriteMutationAdmission({
|
|
804
797
|
rootReal: resolved.rootReal,
|
|
@@ -994,20 +987,9 @@ async function copyFileInRoot(root, params) {
|
|
|
994
987
|
}
|
|
995
988
|
}
|
|
996
989
|
async function resolvePinnedPathInRoot(root, params) {
|
|
997
|
-
return await resolvePinnedOperationPathInRoot(root, {
|
|
998
|
-
allowRoot: params.allowRoot,
|
|
999
|
-
denyMutations: params.denyMutations,
|
|
1000
|
-
mutationSymlinks: params.mutationSymlinks,
|
|
1001
|
-
protectDenyMutationAncestors: params.remove === true,
|
|
1002
|
-
relativePath: params.relativePath,
|
|
1003
|
-
policy: params.remove ? PATH_ALIAS_POLICIES.unlinkTarget : PATH_ALIAS_POLICIES.strict,
|
|
1004
|
-
removalReceipts: params.removalReceipts,
|
|
1005
|
-
});
|
|
1006
|
-
}
|
|
1007
|
-
async function resolvePinnedOperationPathInRoot(root, params) {
|
|
1008
990
|
const resolved = await resolvePinnedRootPathInRoot(root, {
|
|
1009
991
|
relativePath: params.relativePath,
|
|
1010
|
-
policy: params.
|
|
992
|
+
policy: params.remove ? PATH_ALIAS_POLICIES.unlinkTarget : PATH_ALIAS_POLICIES.strict,
|
|
1011
993
|
mutationSymlinks: params.mutationSymlinks,
|
|
1012
994
|
removalReceipts: params.removalReceipts,
|
|
1013
995
|
});
|
|
@@ -1034,7 +1016,7 @@ async function resolvePinnedOperationPathInRoot(root, params) {
|
|
|
1034
1016
|
}
|
|
1035
1017
|
resolved.canonicalPath = admittedCanonicalPath.path;
|
|
1036
1018
|
await assertMutationNotDenied(resolved.canonicalPath, params.denyMutations, {
|
|
1037
|
-
protectAncestors: params.
|
|
1019
|
+
protectAncestors: params.remove === true,
|
|
1038
1020
|
});
|
|
1039
1021
|
return { rootReal: resolved.rootReal, resolved: resolved.canonicalPath, relativePosix };
|
|
1040
1022
|
}
|
|
@@ -1085,6 +1067,8 @@ async function listPathFallback(root, relativePath, withFileTypes) {
|
|
|
1085
1067
|
return await listDirectoryPath(root, resolved.resolved, withFileTypes, resolved.receipt);
|
|
1086
1068
|
}
|
|
1087
1069
|
async function movePathFallback(root, params) {
|
|
1070
|
+
const originalRoutes = params.overwrite && params.assertBeforeMutation
|
|
1071
|
+
? await Promise.all([params.fromRelative, params.toRelative].map(expandRelativePathWithHome)) : undefined;
|
|
1088
1072
|
const source = await resolvePathInRoot(root, params.fromRelative, {
|
|
1089
1073
|
aliasErrorCode: "path-alias",
|
|
1090
1074
|
allowFinalSymlink: true,
|
|
@@ -1120,9 +1104,14 @@ async function movePathFallback(root, params) {
|
|
|
1120
1104
|
targetStat?.isSymbolicLink() === true);
|
|
1121
1105
|
},
|
|
1122
1106
|
});
|
|
1123
|
-
let
|
|
1107
|
+
let sourceIdentity;
|
|
1124
1108
|
try {
|
|
1125
|
-
|
|
1109
|
+
if (params.overwrite && params.assertBeforeMutation) {
|
|
1110
|
+
sourceIdentity = inspectFileIdentitySync(() => admitMoveSourceStat(fsSync.lstatSync(source.resolved, { bigint: true }), true));
|
|
1111
|
+
}
|
|
1112
|
+
else {
|
|
1113
|
+
admitMoveSourceStat(fsSync.lstatSync(source.resolved), params.overwrite);
|
|
1114
|
+
}
|
|
1126
1115
|
}
|
|
1127
1116
|
catch (error) {
|
|
1128
1117
|
if (isNotFoundPathError(error)) {
|
|
@@ -1130,19 +1119,10 @@ async function movePathFallback(root, params) {
|
|
|
1130
1119
|
}
|
|
1131
1120
|
throw error;
|
|
1132
1121
|
}
|
|
1133
|
-
if (
|
|
1134
|
-
throw new FsSafeError("
|
|
1135
|
-
}
|
|
1136
|
-
if (sourceStat.isFile() && sourceStat.nlink > 1) {
|
|
1137
|
-
throw hardlinkedPathNotAllowedError();
|
|
1138
|
-
}
|
|
1139
|
-
if (!params.overwrite && sourceStat.isDirectory()) {
|
|
1140
|
-
throw new FsSafeError("invalid-path", "directory moves require overwrite: true");
|
|
1122
|
+
if (!pinnedTarget) {
|
|
1123
|
+
throw new FsSafeError("path-mismatch", "destination admission was not completed");
|
|
1141
1124
|
}
|
|
1142
1125
|
if (!params.overwrite) {
|
|
1143
|
-
if (!pinnedTarget) {
|
|
1144
|
-
throw new FsSafeError("path-mismatch", "destination admission was not completed");
|
|
1145
|
-
}
|
|
1146
1126
|
await movePathNoReplaceNative(root, params, {
|
|
1147
1127
|
sourcePath: source.resolved,
|
|
1148
1128
|
sourceParentPath: path.dirname(pinnedSource.canonicalPath),
|
|
@@ -1151,8 +1131,9 @@ async function movePathFallback(root, params) {
|
|
|
1151
1131
|
});
|
|
1152
1132
|
return;
|
|
1153
1133
|
}
|
|
1154
|
-
const
|
|
1155
|
-
const
|
|
1134
|
+
const guardOptions = { bigint: sourceIdentity !== undefined };
|
|
1135
|
+
const sourceParentGuard = await createAsyncDirectoryGuard(path.dirname(source.resolved), guardOptions);
|
|
1136
|
+
const targetParentGuard = await createNearestExistingDirectoryGuard(target.rootReal, path.dirname(target.resolved), guardOptions);
|
|
1156
1137
|
await getFsSafeTestHooks()?.beforeRootFallbackMutation?.("move", target.resolved);
|
|
1157
1138
|
await assertAsyncDirectoryGuard(sourceParentGuard);
|
|
1158
1139
|
await assertAsyncDirectoryGuard(targetParentGuard);
|
|
@@ -1160,6 +1141,31 @@ async function movePathFallback(root, params) {
|
|
|
1160
1141
|
assertFinalSymlinkRejected(source.resolved, params.mutationSymlinks !== undefined);
|
|
1161
1142
|
assertFinalSymlinkRejected(target.resolved, params.mutationSymlinks !== undefined);
|
|
1162
1143
|
params.assertBeforeMutation?.();
|
|
1144
|
+
if (sourceIdentity) {
|
|
1145
|
+
assertRootIdentityCurrentSync(root);
|
|
1146
|
+
assertSyncDirectoryGuard(sourceParentGuard);
|
|
1147
|
+
assertSyncDirectoryGuard(targetParentGuard);
|
|
1148
|
+
for (const [route, selected, expected, policy] of [
|
|
1149
|
+
[originalRoutes[0], source.resolved, pinnedSource.canonicalPath, PATH_ALIAS_POLICIES.strict],
|
|
1150
|
+
[originalRoutes[1], target.resolved, pinnedTarget.canonicalPath, PATH_ALIAS_POLICIES.unlinkTarget],
|
|
1151
|
+
]) {
|
|
1152
|
+
for (const absolutePath of new Set([path.isAbsolute(route) ? route : `${root.rootWithSep}${route}`, selected])) {
|
|
1153
|
+
try {
|
|
1154
|
+
const current = resolveRootPathSync({
|
|
1155
|
+
absolutePath, rootPath: root.rootReal, rootCanonicalPath: root.rootReal,
|
|
1156
|
+
rootIdentity: root.rootIdentity, boundaryLabel: "root", policy,
|
|
1157
|
+
...mutationSymlinkResolution(params.mutationSymlinks),
|
|
1158
|
+
});
|
|
1159
|
+
if (current.canonicalPath !== expected)
|
|
1160
|
+
throw new FsSafeError("path-mismatch", "move route changed during authorization");
|
|
1161
|
+
}
|
|
1162
|
+
catch (error) {
|
|
1163
|
+
throw normalizePinnedPathError(error);
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
inspectFileIdentitySync(() => admitMoveSourceStat(fsSync.lstatSync(source.resolved, { bigint: true }), true), sourceIdentity);
|
|
1168
|
+
}
|
|
1163
1169
|
await fs.rename(source.resolved, target.resolved);
|
|
1164
1170
|
}
|
|
1165
1171
|
catch (error) {
|
|
@@ -1197,48 +1203,59 @@ async function writeFileFallbackUnlocked(root, params, expectedWritePath) {
|
|
|
1197
1203
|
await writeMissingFileFallback(root, params, expectedWritePath);
|
|
1198
1204
|
return;
|
|
1199
1205
|
}
|
|
1200
|
-
const
|
|
1206
|
+
const admissionParams = {
|
|
1201
1207
|
relativePath: params.relativePath,
|
|
1202
1208
|
mkdir: params.mkdir,
|
|
1203
|
-
// Private, writable placeholder: Windows cannot rename over a read-only file.
|
|
1204
|
-
mode: 0o600,
|
|
1205
1209
|
denyMutations: params.denyMutations,
|
|
1206
1210
|
assertBeforeMutation: params.assertBeforeMutation,
|
|
1207
1211
|
mutationSymlinks: params.mutationSymlinks,
|
|
1208
1212
|
truncateExisting: false,
|
|
1209
1213
|
expectedWritePath,
|
|
1210
|
-
}
|
|
1214
|
+
};
|
|
1215
|
+
const admission = await openWritableFileInRoot(root, admissionParams, { createIfMissing: false });
|
|
1216
|
+
const existing = "missing" in admission ? undefined : admission;
|
|
1217
|
+
const target = existing?.opened;
|
|
1218
|
+
const retainedSelection = existing?.writeSelection;
|
|
1219
|
+
const missingSelection = "missing" in admission ? admission.writeSelection : undefined;
|
|
1211
1220
|
const policyEnabled = params.denyMutations !== undefined || params.mutationSymlinks !== undefined;
|
|
1212
|
-
const destinationPath =
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1221
|
+
const destinationPath = "missing" in admission ? admission.targetPath
|
|
1222
|
+
: retainedSelection?.selectedPath ?? admission.opened.realPath;
|
|
1223
|
+
let mode = params.mode ?? (target ? target.stat.mode & 0o777 : undefined);
|
|
1224
|
+
if (policyEnabled && !retainedSelection && !missingSelection) {
|
|
1225
|
+
await target?.handle.close().catch(() => undefined);
|
|
1216
1226
|
throw new FsSafeError("path-mismatch", "write admission state was not retained");
|
|
1217
1227
|
}
|
|
1218
|
-
const destinationGuard = retainedSelection?.parentGuard ??
|
|
1228
|
+
const destinationGuard = "missing" in admission ? admission.parentGuard : retainedSelection?.parentGuard ??
|
|
1219
1229
|
await createAsyncDirectoryGuard(path.dirname(destinationPath), { bigint: true }).catch(async (error) => {
|
|
1220
|
-
await target
|
|
1230
|
+
await target?.handle.close().catch(() => undefined);
|
|
1221
1231
|
throw error;
|
|
1222
1232
|
});
|
|
1223
1233
|
let tempPath = null;
|
|
1224
1234
|
let unregisterTempPath = null;
|
|
1225
1235
|
let writtenHandle;
|
|
1226
1236
|
let writtenIdentity;
|
|
1227
|
-
let
|
|
1228
|
-
let published = false;
|
|
1237
|
+
let lateTargetHandle;
|
|
1229
1238
|
try {
|
|
1230
|
-
if (target.createdForWrite)
|
|
1231
|
-
placeholderIdentity = targetIdentity;
|
|
1232
1239
|
tempPath = buildAtomicWriteTempPath(destinationPath);
|
|
1233
1240
|
if (retainedSelection) {
|
|
1234
|
-
await refreshRetainedRootWriteAdmission(root, retainedSelection, true, target
|
|
1241
|
+
await refreshRetainedRootWriteAdmission(root, retainedSelection, true, target?.handle.fd);
|
|
1242
|
+
}
|
|
1243
|
+
else if (missingSelection) {
|
|
1244
|
+
await refreshRootWritePathSelection(missingSelection);
|
|
1235
1245
|
}
|
|
1236
1246
|
params.assertBeforeMutation?.();
|
|
1237
1247
|
if (retainedSelection) {
|
|
1238
|
-
assertRootWriteSelectionSync(root, retainedSelection, true, target
|
|
1248
|
+
assertRootWriteSelectionSync(root, retainedSelection, true, target?.handle.fd);
|
|
1249
|
+
}
|
|
1250
|
+
else if (missingSelection) {
|
|
1251
|
+
assertRootWritePathSelectionSync(root, missingSelection);
|
|
1239
1252
|
}
|
|
1253
|
+
assertRootIdentityCurrentSync(root);
|
|
1254
|
+
assertSyncDirectoryGuard(destinationGuard);
|
|
1240
1255
|
writtenHandle = await fs.open(tempPath, OPEN_WRITE_CREATE_FLAGS, 0o600);
|
|
1241
1256
|
writtenIdentity = fsSync.fstatSync(writtenHandle.fd, { bigint: true });
|
|
1257
|
+
// Preserve the creation mask when no existing destination supplies a mode.
|
|
1258
|
+
mode ??= Number(writtenIdentity.mode & 511n);
|
|
1242
1259
|
unregisterTempPath = registerTempPathForExit(tempPath, { identity: writtenIdentity, singleLinkFile: true });
|
|
1243
1260
|
await writeAllToFile(writtenHandle, params.data, {
|
|
1244
1261
|
encoding: params.encoding, assertBeforeMutation: params.assertBeforeMutation,
|
|
@@ -1253,24 +1270,42 @@ async function writeFileFallbackUnlocked(root, params, expectedWritePath) {
|
|
|
1253
1270
|
root, targetPath: commitTempPath, fd: commitHandle.fd,
|
|
1254
1271
|
expectedIdentity: commitIdentity, parentGuard: destinationGuard,
|
|
1255
1272
|
});
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1273
|
+
assertRootIdentityCurrentSync(root);
|
|
1274
|
+
assertSyncDirectoryGuard(destinationGuard);
|
|
1275
|
+
let publicationIdentity = inspectFallbackReplacementDestination(destinationPath);
|
|
1276
|
+
// A raced file needs its own access admission, not the old handle's rights.
|
|
1277
|
+
if (publicationIdentity && (!existing || !sameFileIdentity(publicationIdentity, existing.identity))) {
|
|
1278
|
+
const admitted = await openWritableFileInRoot(root, {
|
|
1279
|
+
...admissionParams, mkdir: false, expectedWritePath: destinationPath,
|
|
1280
|
+
}, { createIfMissing: false });
|
|
1281
|
+
lateTargetHandle = "missing" in admitted ? undefined : admitted.opened.handle;
|
|
1282
|
+
publicationIdentity = "missing" in admitted ? undefined : admitted.identity;
|
|
1283
|
+
await lateTargetHandle?.close();
|
|
1260
1284
|
}
|
|
1261
1285
|
// Windows cannot replace a destination while its old handle remains open.
|
|
1262
|
-
await target
|
|
1286
|
+
await target?.handle.close();
|
|
1263
1287
|
if (retainedSelection) {
|
|
1264
|
-
await refreshRetainedRootWriteAdmission(root, retainedSelection,
|
|
1288
|
+
await refreshRetainedRootWriteAdmission(root, retainedSelection, true);
|
|
1289
|
+
}
|
|
1290
|
+
else if (missingSelection) {
|
|
1291
|
+
await refreshRootWritePathSelection(missingSelection);
|
|
1265
1292
|
}
|
|
1266
1293
|
assertFinalSymlinkRejected(destinationPath, params.mutationSymlinks !== undefined);
|
|
1267
1294
|
params.assertBeforeMutation?.();
|
|
1268
1295
|
if (retainedSelection) {
|
|
1269
|
-
assertRootWriteSelectionSync(root, retainedSelection,
|
|
1296
|
+
assertRootWriteSelectionSync(root, retainedSelection, true);
|
|
1297
|
+
}
|
|
1298
|
+
else if (missingSelection) {
|
|
1299
|
+
assertRootWritePathSelectionSync(root, missingSelection);
|
|
1300
|
+
}
|
|
1301
|
+
assertRootIdentityCurrentSync(root);
|
|
1302
|
+
assertSyncDirectoryGuard(destinationGuard);
|
|
1303
|
+
const current = inspectFallbackReplacementDestination(destinationPath);
|
|
1304
|
+
if (publicationIdentity ? !current || !sameFileIdentity(current, publicationIdentity) : current) {
|
|
1305
|
+
throw new FsSafeError("path-mismatch", "write destination changed before publication");
|
|
1270
1306
|
}
|
|
1271
1307
|
await fs.rename(commitTempPath, destinationPath);
|
|
1272
1308
|
tempPath = null;
|
|
1273
|
-
published = true;
|
|
1274
1309
|
});
|
|
1275
1310
|
unregisterTempPath();
|
|
1276
1311
|
unregisterTempPath = null;
|
|
@@ -1283,12 +1318,8 @@ async function writeFileFallbackUnlocked(root, params, expectedWritePath) {
|
|
|
1283
1318
|
});
|
|
1284
1319
|
}
|
|
1285
1320
|
finally {
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
pathname: destinationPath, handle: target.handle, identity: placeholderIdentity, parentGuard: destinationGuard,
|
|
1289
|
-
});
|
|
1290
|
-
}
|
|
1291
|
-
await target.handle.close().catch(() => undefined);
|
|
1321
|
+
await target?.handle.close().catch(() => undefined);
|
|
1322
|
+
await lateTargetHandle?.close().catch(() => undefined);
|
|
1292
1323
|
if (tempPath && writtenHandle) {
|
|
1293
1324
|
await cleanupPinnedFilePath({
|
|
1294
1325
|
pathname: tempPath, handle: writtenHandle, identity: writtenIdentity, parentGuard: destinationGuard,
|
|
@@ -1298,6 +1329,23 @@ async function writeFileFallbackUnlocked(root, params, expectedWritePath) {
|
|
|
1298
1329
|
unregisterTempPath?.();
|
|
1299
1330
|
}
|
|
1300
1331
|
}
|
|
1332
|
+
function inspectFallbackReplacementDestination(targetPath) {
|
|
1333
|
+
let current;
|
|
1334
|
+
try {
|
|
1335
|
+
current = inspectFileIdentitySync(() => fsSync.lstatSync(targetPath, { bigint: true }));
|
|
1336
|
+
}
|
|
1337
|
+
catch (error) {
|
|
1338
|
+
if (isNotFoundPathError(error))
|
|
1339
|
+
return;
|
|
1340
|
+
throw error;
|
|
1341
|
+
}
|
|
1342
|
+
if (current.isSymbolicLink() || !current.isFile()) {
|
|
1343
|
+
throw new FsSafeError("path-mismatch", "write destination changed before publication");
|
|
1344
|
+
}
|
|
1345
|
+
if (current.nlink > 1n)
|
|
1346
|
+
throw hardlinkedPathNotAllowedError();
|
|
1347
|
+
return current;
|
|
1348
|
+
}
|
|
1301
1349
|
async function writeMissingFileFallback(root, params, expectedWritePath) {
|
|
1302
1350
|
const guardedTarget = params.denyMutations === undefined && params.mutationSymlinks === undefined
|
|
1303
1351
|
? undefined
|
|
@@ -1324,6 +1372,7 @@ async function writeMissingFileFallback(root, params, expectedWritePath) {
|
|
|
1324
1372
|
const parentGuard = pathSelection?.parentGuard ??
|
|
1325
1373
|
await createAsyncDirectoryGuard(path.dirname(targetPath), { bigint: true });
|
|
1326
1374
|
let created = false;
|
|
1375
|
+
let completed = false;
|
|
1327
1376
|
let createdIdentity;
|
|
1328
1377
|
let writtenHandle;
|
|
1329
1378
|
let verifyingPublication = false;
|
|
@@ -1367,6 +1416,7 @@ async function writeMissingFileFallback(root, params, expectedWritePath) {
|
|
|
1367
1416
|
});
|
|
1368
1417
|
if (params.durable !== false)
|
|
1369
1418
|
await syncDirectoryBestEffort(path.dirname(targetPath));
|
|
1419
|
+
completed = true;
|
|
1370
1420
|
}
|
|
1371
1421
|
catch (err) {
|
|
1372
1422
|
if (verifyingPublication)
|
|
@@ -1384,6 +1434,9 @@ async function writeMissingFileFallback(root, params, expectedWritePath) {
|
|
|
1384
1434
|
pathname: targetPath, handle: writtenHandle, identity: createdIdentity, parentGuard,
|
|
1385
1435
|
});
|
|
1386
1436
|
}
|
|
1387
|
-
|
|
1437
|
+
if (completed)
|
|
1438
|
+
await writtenHandle?.close();
|
|
1439
|
+
else
|
|
1440
|
+
await writtenHandle?.close().catch(() => undefined);
|
|
1388
1441
|
}
|
|
1389
1442
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { type BigIntStats, type Stats } from "node:fs";
|
|
1
2
|
import { type DenyMutationPolicy } from "./deny-mutations.js";
|
|
2
3
|
import { type RootContext } from "./root-context.js";
|
|
3
4
|
import { type MutationSymlinkPolicy } from "./root-symlink-policy.js";
|
|
5
|
+
export declare function admitMoveSourceStat<T extends Stats | BigIntStats>(stat: T, overwrite?: boolean): T;
|
|
4
6
|
export declare function movePathNoReplaceNative(root: RootContext, params: {
|
|
5
7
|
assertBeforeMutation?: () => void;
|
|
6
8
|
denyMutations?: DenyMutationPolicy;
|
|
@@ -11,4 +13,3 @@ export declare function movePathNoReplaceNative(root: RootContext, params: {
|
|
|
11
13
|
targetPath: string;
|
|
12
14
|
targetParentPath: string;
|
|
13
15
|
}): Promise<void>;
|
|
14
|
-
//# sourceMappingURL=root-move-noreplace.d.ts.map
|
|
@@ -58,14 +58,14 @@ function normalizeRenameNoReplaceError(error) {
|
|
|
58
58
|
}
|
|
59
59
|
return normalizeMoveError(error);
|
|
60
60
|
}
|
|
61
|
-
function admitMoveSourceStat(stat) {
|
|
61
|
+
export function admitMoveSourceStat(stat, overwrite = false) {
|
|
62
62
|
if (stat.isSymbolicLink()) {
|
|
63
63
|
throw new FsSafeError("symlink", "symlink not allowed");
|
|
64
64
|
}
|
|
65
65
|
if (stat.isFile() && stat.nlink > 1) {
|
|
66
66
|
throw hardlinkedPathNotAllowedError();
|
|
67
67
|
}
|
|
68
|
-
if (stat.isDirectory()) {
|
|
68
|
+
if (!overwrite && stat.isDirectory()) {
|
|
69
69
|
throw new FsSafeError("invalid-path", "directory moves require overwrite: true");
|
|
70
70
|
}
|
|
71
71
|
return stat;
|