@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
|
@@ -2,9 +2,8 @@ import { syncFileBestEffort, syncFileBestEffortSync } from "./file-sync.js";
|
|
|
2
2
|
import syncFs, {} from "node:fs";
|
|
3
3
|
import fs, {} from "node:fs/promises";
|
|
4
4
|
import { FsSafeError } from "./errors.js";
|
|
5
|
-
import { sameFileIdentity } from "./file-identity.js";
|
|
6
5
|
import { inspectFileIdentity, inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
7
|
-
import {
|
|
6
|
+
import { ownDirectoryMode } from "./directory-mode-owner.js";
|
|
8
7
|
export async function syncDirectoryBestEffort(fsModule, dirPath) {
|
|
9
8
|
let handle;
|
|
10
9
|
try {
|
|
@@ -15,7 +14,12 @@ export async function syncDirectoryBestEffort(fsModule, dirPath) {
|
|
|
15
14
|
// Best-effort on platforms/filesystems that do not support directory fsync.
|
|
16
15
|
}
|
|
17
16
|
finally {
|
|
18
|
-
|
|
17
|
+
try {
|
|
18
|
+
await handle?.close();
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// Best-effort close also covers synchronous adapter throws.
|
|
22
|
+
}
|
|
19
23
|
}
|
|
20
24
|
}
|
|
21
25
|
export function syncDirectoryBestEffortSync(fsModule, dirPath) {
|
|
@@ -48,12 +52,7 @@ function assertDirectory(identity, dirPath) {
|
|
|
48
52
|
if (identity.isSymbolicLink() || !identity.isDirectory()) {
|
|
49
53
|
throw new FsSafeError("not-file", `Atomic replace parent must be a real directory: ${dirPath}`);
|
|
50
54
|
}
|
|
51
|
-
|
|
52
|
-
function assertSameDirectory(expected, opened, dirPath) {
|
|
53
|
-
assertDirectory(opened, dirPath);
|
|
54
|
-
if (!sameFileIdentity(expected, opened)) {
|
|
55
|
-
throw new FsSafeError("path-mismatch", `Atomic replace parent changed before its mode could be applied: ${dirPath}`);
|
|
56
|
-
}
|
|
55
|
+
return identity;
|
|
57
56
|
}
|
|
58
57
|
export async function pinDirectoryForMode(params) {
|
|
59
58
|
// Node does not enforce POSIX directory modes on Windows, and its directory
|
|
@@ -63,15 +62,16 @@ export async function pinDirectoryForMode(params) {
|
|
|
63
62
|
return;
|
|
64
63
|
}
|
|
65
64
|
const expected = params.fsModule === fs
|
|
66
|
-
? syncFs.lstatSync(params.dirPath
|
|
67
|
-
|
|
65
|
+
? inspectFileIdentitySync(() => assertDirectory(syncFs.lstatSync(params.dirPath, { bigint: true }), params.dirPath))
|
|
66
|
+
: await inspectFileIdentity(async () => assertDirectory(await params.fsModule.lstat(params.dirPath, { bigint: true }), params.dirPath));
|
|
68
67
|
const handle = await params.fsModule.open(params.dirPath, directoryOpenFlags());
|
|
69
68
|
try {
|
|
70
69
|
const owner = ownDirectoryMode({
|
|
71
70
|
async inspect() {
|
|
72
|
-
const opened = params.fsModule === fs
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
const opened = params.fsModule === fs
|
|
72
|
+
? inspectFileIdentitySync(() => assertDirectory(syncFs.fstatSync(handle.fd, { bigint: true }), params.dirPath), expected)
|
|
73
|
+
: await inspectFileIdentity(async () => assertDirectory(await handle.stat({ bigint: true }), params.dirPath), expected);
|
|
74
|
+
return Number(opened.mode & 4095n);
|
|
75
75
|
},
|
|
76
76
|
chmod: (mode) => handle.chmod(mode),
|
|
77
77
|
close: () => handle.close(),
|
|
@@ -98,11 +98,10 @@ export function applyDirectoryModeSync(params) {
|
|
|
98
98
|
if (process.platform === "win32") {
|
|
99
99
|
return;
|
|
100
100
|
}
|
|
101
|
-
const expected = params.fsModule.lstatSync(params.dirPath);
|
|
102
|
-
assertDirectory(expected, params.dirPath);
|
|
101
|
+
const expected = inspectFileIdentitySync(() => assertDirectory(params.fsModule.lstatSync(params.dirPath, { bigint: true }), params.dirPath));
|
|
103
102
|
const fd = params.fsModule.openSync(params.dirPath, directoryOpenFlags());
|
|
104
103
|
try {
|
|
105
|
-
|
|
104
|
+
inspectFileIdentitySync(() => assertDirectory(params.fsModule.fstatSync(fd, { bigint: true }), params.dirPath), expected);
|
|
106
105
|
// chmod ignores file-type bits; mask so raw stat modes are tolerated.
|
|
107
106
|
params.fchmodSync?.(fd, params.mode & 0o7777);
|
|
108
107
|
}
|
|
@@ -4,4 +4,3 @@ export declare function validateRenameIdentity(policy: RenameIdentityPolicy | un
|
|
|
4
4
|
export declare function atomicExpectedContentHash(policy: RenameIdentityPolicy | undefined, content: string | Uint8Array): string | undefined;
|
|
5
5
|
export declare function withAtomicRenameIdentityLock<T>(filePath: string, fn: () => Promise<T>): Promise<T>;
|
|
6
6
|
export declare function withAtomicRenameIdentityLockSync<T>(filePath: string, fn: () => T): T;
|
|
7
|
-
//# sourceMappingURL=replace-file-rename-policy.d.ts.map
|
|
@@ -1,45 +1,45 @@
|
|
|
1
1
|
import syncFs, { type BigIntStats } from "node:fs";
|
|
2
2
|
import fs, { type FileHandle } from "node:fs/promises";
|
|
3
|
+
import { type TempPathRegistration } from "./temp-cleanup.js";
|
|
3
4
|
type AsyncOwnerFileSystem = Pick<typeof fs, "lstat" | "open" | "unlink">;
|
|
4
5
|
type SyncOwnerFileSystem = Pick<typeof syncFs, "closeSync" | "fstatSync" | "lstatSync" | "openSync" | "readFileSync" | "unlinkSync">;
|
|
5
6
|
export type AtomicTempFailure = Readonly<{
|
|
6
7
|
error: unknown;
|
|
7
8
|
}>;
|
|
8
9
|
export declare function removePathIfIdentityUnchanged(targetPath: string, identity: Pick<BigIntStats, "dev" | "ino">): Promise<void>;
|
|
9
|
-
|
|
10
|
-
#private;
|
|
10
|
+
declare class AtomicTempOwner<Resource> {
|
|
11
11
|
readonly pathname: string;
|
|
12
|
+
protected resource: Resource | undefined;
|
|
13
|
+
protected recordedIdentity: BigIntStats | undefined;
|
|
14
|
+
protected exists: boolean;
|
|
15
|
+
protected unregister: TempPathRegistration;
|
|
12
16
|
constructor(pathname: string);
|
|
13
17
|
start(): void;
|
|
14
18
|
readonly onIdentity: (identity: BigIntStats) => void;
|
|
19
|
+
get identity(): BigIntStats;
|
|
20
|
+
markRenamed(): void;
|
|
21
|
+
protected takeResource(): Resource | undefined;
|
|
22
|
+
}
|
|
23
|
+
export declare class AsyncAtomicTempOwner extends AtomicTempOwner<FileHandle> {
|
|
15
24
|
adopt(temp: {
|
|
16
25
|
handle: FileHandle;
|
|
17
26
|
identity: BigIntStats;
|
|
18
27
|
}): void;
|
|
19
|
-
get identity(): BigIntStats;
|
|
20
28
|
assertCurrent(fsModule: AsyncOwnerFileSystem, pathname?: string): Promise<void>;
|
|
21
29
|
assertPublished(fsModule: AsyncOwnerFileSystem, pathname: string, expectedHash?: string): Promise<void>;
|
|
22
|
-
markRenamed(): void;
|
|
23
30
|
finish(params: {
|
|
24
31
|
fsModule: AsyncOwnerFileSystem;
|
|
25
32
|
originalFailure?: AtomicTempFailure;
|
|
26
33
|
throwOnCleanupError: boolean;
|
|
27
34
|
}): Promise<void>;
|
|
28
35
|
}
|
|
29
|
-
export declare class SyncAtomicTempOwner {
|
|
30
|
-
#private;
|
|
31
|
-
readonly pathname: string;
|
|
32
|
-
constructor(pathname: string);
|
|
33
|
-
start(): void;
|
|
34
|
-
readonly onIdentity: (identity: BigIntStats) => void;
|
|
36
|
+
export declare class SyncAtomicTempOwner extends AtomicTempOwner<number> {
|
|
35
37
|
adopt(temp: {
|
|
36
38
|
fd: number;
|
|
37
39
|
identity: BigIntStats;
|
|
38
40
|
}): void;
|
|
39
|
-
get identity(): BigIntStats;
|
|
40
41
|
assertCurrent(fsModule: SyncOwnerFileSystem, pathname?: string): void;
|
|
41
42
|
assertPublished(fsModule: SyncOwnerFileSystem, pathname: string, expectedHash?: string): void;
|
|
42
|
-
markRenamed(): void;
|
|
43
43
|
finish(params: {
|
|
44
44
|
fsModule: SyncOwnerFileSystem;
|
|
45
45
|
originalFailure?: AtomicTempFailure;
|
|
@@ -47,4 +47,3 @@ export declare class SyncAtomicTempOwner {
|
|
|
47
47
|
}): void;
|
|
48
48
|
}
|
|
49
49
|
export {};
|
|
50
|
-
//# sourceMappingURL=replace-file-temp-owner.d.ts.map
|
|
@@ -57,6 +57,15 @@ function cleanupFailure(originalFailure, cleanupError) {
|
|
|
57
57
|
}
|
|
58
58
|
return isErrorValue(cleanupError) ? cleanupError : new Error(describeFailure(cleanupError));
|
|
59
59
|
}
|
|
60
|
+
function closeFailure(closeError, params, cleanupFailure) {
|
|
61
|
+
return {
|
|
62
|
+
error: cleanupFailure
|
|
63
|
+
? new AggregateError([cleanupFailure.error, closeError], "Atomic temp cleanup and close failed")
|
|
64
|
+
: params.originalFailure
|
|
65
|
+
? new AggregateError([params.originalFailure.error, closeError], "Atomic file replace and close failed")
|
|
66
|
+
: closeError,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
60
69
|
async function cleanupOwnedPath(params) {
|
|
61
70
|
try {
|
|
62
71
|
await removeOwnedPath(params);
|
|
@@ -92,36 +101,48 @@ function cleanupOwnedPathSync(params) {
|
|
|
92
101
|
return false;
|
|
93
102
|
}
|
|
94
103
|
}
|
|
95
|
-
|
|
104
|
+
class AtomicTempOwner {
|
|
96
105
|
pathname;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
106
|
+
resource;
|
|
107
|
+
recordedIdentity;
|
|
108
|
+
exists = false;
|
|
109
|
+
unregister;
|
|
101
110
|
constructor(pathname) {
|
|
102
111
|
this.pathname = pathname;
|
|
103
|
-
this
|
|
112
|
+
this.unregister = registerTempPathForExit(pathname, { singleLinkFile: true });
|
|
104
113
|
}
|
|
105
114
|
start() {
|
|
106
|
-
this
|
|
115
|
+
this.exists = true;
|
|
107
116
|
}
|
|
108
117
|
onIdentity = (identity) => {
|
|
109
|
-
this
|
|
110
|
-
this
|
|
118
|
+
this.recordedIdentity = identity;
|
|
119
|
+
this.unregister.setIdentity(identity);
|
|
111
120
|
};
|
|
112
|
-
adopt(temp) {
|
|
113
|
-
this.#handle = temp.handle;
|
|
114
|
-
this.onIdentity(temp.identity);
|
|
115
|
-
}
|
|
116
121
|
get identity() {
|
|
117
|
-
if (!this
|
|
122
|
+
if (!this.recordedIdentity)
|
|
118
123
|
throw new Error("Atomic temp owner has no identity");
|
|
119
|
-
return this
|
|
124
|
+
return this.recordedIdentity;
|
|
125
|
+
}
|
|
126
|
+
markRenamed() {
|
|
127
|
+
this.exists = false;
|
|
128
|
+
this.unregister();
|
|
129
|
+
}
|
|
130
|
+
takeResource() {
|
|
131
|
+
// A throwing close may already have released the descriptor for reuse.
|
|
132
|
+
const resource = this.resource;
|
|
133
|
+
this.resource = undefined;
|
|
134
|
+
return resource;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export class AsyncAtomicTempOwner extends AtomicTempOwner {
|
|
138
|
+
adopt(temp) {
|
|
139
|
+
this.resource = temp.handle;
|
|
140
|
+
this.onIdentity(temp.identity);
|
|
120
141
|
}
|
|
121
142
|
async assertCurrent(fsModule, pathname = this.pathname) {
|
|
122
143
|
const opened = await inspectFileIdentity(async () => {
|
|
123
|
-
const stat = fsModule === fs ? syncFs.fstatSync(this
|
|
124
|
-
: await this
|
|
144
|
+
const stat = fsModule === fs ? syncFs.fstatSync(this.resource.fd, { bigint: true })
|
|
145
|
+
: await this.resource.stat({ bigint: true });
|
|
125
146
|
assertOwnedFile(stat, pathname, false);
|
|
126
147
|
return stat;
|
|
127
148
|
}, this.identity);
|
|
@@ -134,7 +155,7 @@ export class AsyncAtomicTempOwner {
|
|
|
134
155
|
}, opened);
|
|
135
156
|
}
|
|
136
157
|
catch (error) {
|
|
137
|
-
if (error
|
|
158
|
+
if (hasErrorCode(error, "ENOENT")) {
|
|
138
159
|
throw missingOwnedFile(pathname, error);
|
|
139
160
|
}
|
|
140
161
|
throw error;
|
|
@@ -146,7 +167,7 @@ export class AsyncAtomicTempOwner {
|
|
|
146
167
|
return;
|
|
147
168
|
}
|
|
148
169
|
catch (error) {
|
|
149
|
-
if (!(error instanceof FsSafeError) || error
|
|
170
|
+
if (!(error instanceof FsSafeError) || !hasErrorCode(error, "path-mismatch") || !expectedHash) {
|
|
150
171
|
throw error;
|
|
151
172
|
}
|
|
152
173
|
}
|
|
@@ -156,7 +177,7 @@ export class AsyncAtomicTempOwner {
|
|
|
156
177
|
published = await fsModule.open(pathname, PUBLISHED_READ_FLAGS);
|
|
157
178
|
}
|
|
158
179
|
catch (error) {
|
|
159
|
-
if (error
|
|
180
|
+
if (hasErrorCode(error, "ELOOP")) {
|
|
160
181
|
throw new FsSafeError("symlink", `Atomic replace published file became a symlink: ${pathname}`, {
|
|
161
182
|
cause: error,
|
|
162
183
|
});
|
|
@@ -178,30 +199,30 @@ export class AsyncAtomicTempOwner {
|
|
|
178
199
|
if (sha256Hex(await published.readFile()) !== expectedHash) {
|
|
179
200
|
throw new FsSafeError("path-mismatch", `Atomic replace published content changed: ${pathname}`);
|
|
180
201
|
}
|
|
181
|
-
const previousHandle = this
|
|
182
|
-
this.#handle = undefined;
|
|
202
|
+
const previousHandle = this.takeResource();
|
|
183
203
|
await previousHandle?.close();
|
|
184
|
-
this
|
|
185
|
-
this
|
|
204
|
+
this.resource = published;
|
|
205
|
+
this.recordedIdentity = identity;
|
|
186
206
|
published = undefined;
|
|
187
207
|
}
|
|
188
208
|
finally {
|
|
189
|
-
|
|
209
|
+
try {
|
|
210
|
+
await published?.close();
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
// Preserve the selected verification or previous-handle close failure.
|
|
214
|
+
}
|
|
190
215
|
}
|
|
191
216
|
}
|
|
192
|
-
markRenamed() {
|
|
193
|
-
this.#exists = false;
|
|
194
|
-
this.#unregister();
|
|
195
|
-
}
|
|
196
217
|
async finish(params) {
|
|
197
218
|
let deferredFailure;
|
|
198
|
-
let cleanupComplete = !this
|
|
199
|
-
if (this
|
|
219
|
+
let cleanupComplete = !this.exists;
|
|
220
|
+
if (this.exists) {
|
|
200
221
|
try {
|
|
201
222
|
cleanupComplete = await cleanupOwnedPath({
|
|
202
223
|
fsModule: params.fsModule,
|
|
203
224
|
pathname: this.pathname,
|
|
204
|
-
identity: this
|
|
225
|
+
identity: this.recordedIdentity,
|
|
205
226
|
originalFailure: params.originalFailure,
|
|
206
227
|
throwOnCleanupError: params.throwOnCleanupError,
|
|
207
228
|
});
|
|
@@ -211,54 +232,26 @@ export class AsyncAtomicTempOwner {
|
|
|
211
232
|
}
|
|
212
233
|
}
|
|
213
234
|
if (cleanupComplete)
|
|
214
|
-
this
|
|
215
|
-
const handle = this
|
|
216
|
-
this.#handle = undefined;
|
|
235
|
+
this.unregister();
|
|
236
|
+
const handle = this.takeResource();
|
|
217
237
|
try {
|
|
218
238
|
await handle?.close();
|
|
219
239
|
}
|
|
220
240
|
catch (closeError) {
|
|
221
|
-
deferredFailure =
|
|
222
|
-
error: deferredFailure
|
|
223
|
-
? new AggregateError([deferredFailure.error, closeError], "Atomic temp cleanup and close failed")
|
|
224
|
-
: params.originalFailure
|
|
225
|
-
? new AggregateError([params.originalFailure.error, closeError], "Atomic file replace and close failed")
|
|
226
|
-
: closeError,
|
|
227
|
-
};
|
|
241
|
+
deferredFailure = closeFailure(closeError, params, deferredFailure);
|
|
228
242
|
}
|
|
229
243
|
if (deferredFailure)
|
|
230
244
|
throw deferredFailure.error;
|
|
231
245
|
}
|
|
232
246
|
}
|
|
233
|
-
export class SyncAtomicTempOwner {
|
|
234
|
-
pathname;
|
|
235
|
-
#fd;
|
|
236
|
-
#identity;
|
|
237
|
-
#exists = false;
|
|
238
|
-
#unregister;
|
|
239
|
-
constructor(pathname) {
|
|
240
|
-
this.pathname = pathname;
|
|
241
|
-
this.#unregister = registerTempPathForExit(pathname, { singleLinkFile: true });
|
|
242
|
-
}
|
|
243
|
-
start() {
|
|
244
|
-
this.#exists = true;
|
|
245
|
-
}
|
|
246
|
-
onIdentity = (identity) => {
|
|
247
|
-
this.#identity = identity;
|
|
248
|
-
this.#unregister.setIdentity(identity);
|
|
249
|
-
};
|
|
247
|
+
export class SyncAtomicTempOwner extends AtomicTempOwner {
|
|
250
248
|
adopt(temp) {
|
|
251
|
-
this
|
|
249
|
+
this.resource = temp.fd;
|
|
252
250
|
this.onIdentity(temp.identity);
|
|
253
251
|
}
|
|
254
|
-
get identity() {
|
|
255
|
-
if (!this.#identity)
|
|
256
|
-
throw new Error("Atomic temp owner has no identity");
|
|
257
|
-
return this.#identity;
|
|
258
|
-
}
|
|
259
252
|
assertCurrent(fsModule, pathname = this.pathname) {
|
|
260
253
|
const opened = inspectFileIdentitySync(() => {
|
|
261
|
-
const stat = fsModule.fstatSync(this
|
|
254
|
+
const stat = fsModule.fstatSync(this.resource, { bigint: true });
|
|
262
255
|
assertOwnedFile(stat, pathname, false);
|
|
263
256
|
return stat;
|
|
264
257
|
}, this.identity);
|
|
@@ -270,7 +263,7 @@ export class SyncAtomicTempOwner {
|
|
|
270
263
|
}, opened);
|
|
271
264
|
}
|
|
272
265
|
catch (error) {
|
|
273
|
-
if (error
|
|
266
|
+
if (hasErrorCode(error, "ENOENT")) {
|
|
274
267
|
throw missingOwnedFile(pathname, error);
|
|
275
268
|
}
|
|
276
269
|
throw error;
|
|
@@ -282,7 +275,7 @@ export class SyncAtomicTempOwner {
|
|
|
282
275
|
return;
|
|
283
276
|
}
|
|
284
277
|
catch (error) {
|
|
285
|
-
if (!(error instanceof FsSafeError) || error
|
|
278
|
+
if (!(error instanceof FsSafeError) || !hasErrorCode(error, "path-mismatch") || !expectedHash) {
|
|
286
279
|
throw error;
|
|
287
280
|
}
|
|
288
281
|
}
|
|
@@ -292,7 +285,7 @@ export class SyncAtomicTempOwner {
|
|
|
292
285
|
publishedFd = fsModule.openSync(pathname, PUBLISHED_READ_FLAGS);
|
|
293
286
|
}
|
|
294
287
|
catch (error) {
|
|
295
|
-
if (error
|
|
288
|
+
if (hasErrorCode(error, "ELOOP")) {
|
|
296
289
|
throw new FsSafeError("symlink", `Atomic replace published file became a symlink: ${pathname}`, {
|
|
297
290
|
cause: error,
|
|
298
291
|
});
|
|
@@ -312,11 +305,10 @@ export class SyncAtomicTempOwner {
|
|
|
312
305
|
if (sha256Hex(fsModule.readFileSync(publishedFd)) !== expectedHash) {
|
|
313
306
|
throw new FsSafeError("path-mismatch", `Atomic replace published content changed: ${pathname}`);
|
|
314
307
|
}
|
|
315
|
-
const previousFd = this
|
|
316
|
-
this.#fd = undefined;
|
|
308
|
+
const previousFd = this.takeResource();
|
|
317
309
|
fsModule.closeSync(previousFd);
|
|
318
|
-
this
|
|
319
|
-
this
|
|
310
|
+
this.resource = publishedFd;
|
|
311
|
+
this.recordedIdentity = identity;
|
|
320
312
|
publishedFd = undefined;
|
|
321
313
|
}
|
|
322
314
|
finally {
|
|
@@ -330,19 +322,15 @@ export class SyncAtomicTempOwner {
|
|
|
330
322
|
}
|
|
331
323
|
}
|
|
332
324
|
}
|
|
333
|
-
markRenamed() {
|
|
334
|
-
this.#exists = false;
|
|
335
|
-
this.#unregister();
|
|
336
|
-
}
|
|
337
325
|
finish(params) {
|
|
338
326
|
let deferredFailure;
|
|
339
|
-
let cleanupComplete = !this
|
|
340
|
-
if (this
|
|
327
|
+
let cleanupComplete = !this.exists;
|
|
328
|
+
if (this.exists) {
|
|
341
329
|
try {
|
|
342
330
|
cleanupComplete = cleanupOwnedPathSync({
|
|
343
331
|
fsModule: params.fsModule,
|
|
344
332
|
pathname: this.pathname,
|
|
345
|
-
identity: this
|
|
333
|
+
identity: this.recordedIdentity,
|
|
346
334
|
originalFailure: params.originalFailure,
|
|
347
335
|
throwOnCleanupError: params.throwOnCleanupError,
|
|
348
336
|
});
|
|
@@ -352,21 +340,14 @@ export class SyncAtomicTempOwner {
|
|
|
352
340
|
}
|
|
353
341
|
}
|
|
354
342
|
if (cleanupComplete)
|
|
355
|
-
this
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
this.#fd = undefined;
|
|
343
|
+
this.unregister();
|
|
344
|
+
const fd = this.takeResource();
|
|
345
|
+
if (fd !== undefined) {
|
|
359
346
|
try {
|
|
360
347
|
params.fsModule.closeSync(fd);
|
|
361
348
|
}
|
|
362
349
|
catch (closeError) {
|
|
363
|
-
deferredFailure =
|
|
364
|
-
error: deferredFailure
|
|
365
|
-
? new AggregateError([deferredFailure.error, closeError], "Atomic temp cleanup and close failed")
|
|
366
|
-
: params.originalFailure
|
|
367
|
-
? new AggregateError([params.originalFailure.error, closeError], "Atomic file replace and close failed")
|
|
368
|
-
: closeError,
|
|
369
|
-
};
|
|
350
|
+
deferredFailure = closeFailure(closeError, params, deferredFailure);
|
|
370
351
|
}
|
|
371
352
|
}
|
|
372
353
|
if (deferredFailure)
|
package/dist/replace-file.d.ts
CHANGED
|
@@ -56,4 +56,3 @@ export type ReplaceFileAtomicResult = {
|
|
|
56
56
|
export declare function replaceFileAtomic(options: ReplaceFileAtomicOptions): Promise<ReplaceFileAtomicResult>;
|
|
57
57
|
export declare function replaceFileAtomicWithDirectorySync(options: ReplaceFileAtomicOptions, syncParent?: (directoryPath: string) => Promise<unknown>): Promise<ReplaceFileAtomicResult>;
|
|
58
58
|
export declare function replaceFileAtomicSync(options: ReplaceFileAtomicSyncOptions): ReplaceFileAtomicResult;
|
|
59
|
-
//# sourceMappingURL=replace-file.d.ts.map
|
package/dist/replace-file.js
CHANGED
|
@@ -12,13 +12,7 @@ import { assertSafePathPrefix } from "./safe-path-segment.js";
|
|
|
12
12
|
import { admitStandalonePublicationPath } from "./standalone-publication-path.js";
|
|
13
13
|
import { sleep, sleepSync } from "./timing.js";
|
|
14
14
|
import { serializePathWrite } from "./write-queue.js";
|
|
15
|
-
|
|
16
|
-
return error.code === "EBUSY";
|
|
17
|
-
}
|
|
18
|
-
function isPermissionRenameError(error) {
|
|
19
|
-
const code = error.code;
|
|
20
|
-
return code === "EPERM" || code === "EEXIST";
|
|
21
|
-
}
|
|
15
|
+
import { hasErrorCode, readErrorCode } from "./file-cleanup.js";
|
|
22
16
|
async function renameWithRetry(params) {
|
|
23
17
|
for (let attempt = 0; attempt <= params.maxRetries; attempt++) {
|
|
24
18
|
if (attempt > 0)
|
|
@@ -28,11 +22,12 @@ async function renameWithRetry(params) {
|
|
|
28
22
|
return { method: "rename" };
|
|
29
23
|
}
|
|
30
24
|
catch (error) {
|
|
31
|
-
|
|
25
|
+
const code = readErrorCode(error);
|
|
26
|
+
if (code === "EBUSY" && attempt < params.maxRetries) {
|
|
32
27
|
await sleep(params.baseDelayMs * 2 ** attempt);
|
|
33
28
|
continue;
|
|
34
29
|
}
|
|
35
|
-
if (params.copyFallbackOnPermissionError &&
|
|
30
|
+
if (params.copyFallbackOnPermissionError && (code === "EPERM" || code === "EEXIST")) {
|
|
36
31
|
await copyFallbackReplace({
|
|
37
32
|
fsModule: params.fsModule,
|
|
38
33
|
src: params.src,
|
|
@@ -59,11 +54,12 @@ function renameWithRetrySync(params) {
|
|
|
59
54
|
return { method: "rename" };
|
|
60
55
|
}
|
|
61
56
|
catch (error) {
|
|
62
|
-
|
|
57
|
+
const code = readErrorCode(error);
|
|
58
|
+
if (code === "EBUSY" && attempt < params.maxRetries) {
|
|
63
59
|
sleepSync(params.baseDelayMs * 2 ** attempt);
|
|
64
60
|
continue;
|
|
65
61
|
}
|
|
66
|
-
if (params.copyFallbackOnPermissionError &&
|
|
62
|
+
if (params.copyFallbackOnPermissionError && (code === "EPERM" || code === "EEXIST")) {
|
|
67
63
|
copyFallbackReplaceSync({
|
|
68
64
|
fsModule: params.fsModule,
|
|
69
65
|
src: params.src,
|
|
@@ -114,7 +110,7 @@ async function resolveMode(options, filePath) {
|
|
|
114
110
|
stat = fsModule === fs ? syncFs.lstatSync(filePath) : await fsModule.lstat(filePath);
|
|
115
111
|
}
|
|
116
112
|
catch (error) {
|
|
117
|
-
if (error
|
|
113
|
+
if (hasErrorCode(error, "ENOENT")) {
|
|
118
114
|
return defaultMode;
|
|
119
115
|
}
|
|
120
116
|
throw error;
|
|
@@ -132,7 +128,7 @@ function resolveModeSync(options, filePath) {
|
|
|
132
128
|
stat = fsModule.lstatSync(filePath);
|
|
133
129
|
}
|
|
134
130
|
catch (error) {
|
|
135
|
-
if (error
|
|
131
|
+
if (!hasErrorCode(error, "ENOENT")) {
|
|
136
132
|
throw error;
|
|
137
133
|
}
|
|
138
134
|
}
|
package/dist/root-boundary.d.ts
CHANGED
package/dist/root-context.d.ts
CHANGED
|
@@ -14,4 +14,3 @@ export declare function rethrowCreateInputError(error: unknown): never;
|
|
|
14
14
|
export declare function createInputOptions(data: RootWriteParams["data"], options: RootCreateOptions & RootCreateStreamOptions, defaultMaxBytes?: number): RootCreateOptions & RootCreateStreamOptions;
|
|
15
15
|
export declare function rootWriteInput(params: RootWriteParams): PinnedWriteInput;
|
|
16
16
|
export {};
|
|
17
|
-
//# sourceMappingURL=root-create-input.d.ts.map
|
|
@@ -10,4 +10,3 @@ export declare function mkdirPathFallback(root: RootContext, resolved: {
|
|
|
10
10
|
rootReal: string;
|
|
11
11
|
resolved: string;
|
|
12
12
|
}, assertBeforeMutation?: () => void, rejectSymlinks?: boolean, mutationAdmission?: PinnedWriteMutationAdmission, privateMode?: boolean): Promise<void>;
|
|
13
|
-
//# sourceMappingURL=root-directory-creation.d.ts.map
|
|
@@ -36,4 +36,3 @@ export type RootDirectoryListingOptions = {
|
|
|
36
36
|
admitEntry(): boolean;
|
|
37
37
|
};
|
|
38
38
|
export declare function openRootDirectoryListing(root: RootContext, directory: string, options: RootDirectoryListingOptions): Promise<RootDirectoryListing>;
|
|
39
|
-
//# sourceMappingURL=root-directory-list.d.ts.map
|
|
@@ -2,7 +2,7 @@ import fsSync from "node:fs";
|
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { setImmediate as yieldToEventLoop } from "node:timers/promises";
|
|
5
|
-
import { assertAsyncDirectoryGuard, assertDirectoryObservationGuardSync, assertDirectoryObservationSync, createAsyncDirectoryGuard, } from "./directory-guard.js";
|
|
5
|
+
import { assertAsyncDirectoryGuard, assertDirectoryObservationGuardSync, assertDirectoryObservationSync, createAsyncDirectoryGuard, extendDirectoryObservationGuard, } from "./directory-guard.js";
|
|
6
6
|
import { FsSafeError } from "./errors.js";
|
|
7
7
|
import { inspectNativeDirectoryObservation, isNativeDirectoryObservationGuard, } from "./native-directory-observation.js";
|
|
8
8
|
import { isNotFoundPathError } from "./path.js";
|
|
@@ -73,7 +73,18 @@ export async function assertRootDirectoryObservationGuard(root, guard) {
|
|
|
73
73
|
}
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
|
-
|
|
76
|
+
if ("identity" in guard && typeof root.rootIdentity.dev === "bigint" &&
|
|
77
|
+
typeof root.rootIdentity.ino === "bigint") {
|
|
78
|
+
try {
|
|
79
|
+
assertDirectoryObservationSync(root.rootReal, root.rootIdentity);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
throw rootPathChangedError(error instanceof Error ? error : undefined);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
await assertRootIdentityCurrent(root);
|
|
87
|
+
}
|
|
77
88
|
try {
|
|
78
89
|
if ("identity" in guard)
|
|
79
90
|
assertDirectoryObservationGuardSync(guard);
|
|
@@ -215,9 +226,15 @@ async function listGuardedDirectoryPath(root, guard, withFileTypes, receipt) {
|
|
|
215
226
|
return entries;
|
|
216
227
|
}
|
|
217
228
|
export async function openRootDirectoryListing(root, directory, options) {
|
|
218
|
-
const
|
|
229
|
+
const admitted = await createRootDirectoryObservationGuard(root, directory).catch((error) => {
|
|
219
230
|
throw normalizeDirectoryError(error);
|
|
220
231
|
});
|
|
232
|
+
// Retain exact admission identities; metadata rechecks can use numeric Stats
|
|
233
|
+
// only when every identity component is losslessly representable.
|
|
234
|
+
const guard = extendDirectoryObservationGuard({
|
|
235
|
+
stat: admitted.stat,
|
|
236
|
+
identity: { dev: admitted.stat.dev, ino: admitted.stat.ino },
|
|
237
|
+
}, admitted.dir, admitted.realPath);
|
|
221
238
|
const assertCurrent = async () => {
|
|
222
239
|
options.signal?.throwIfAborted();
|
|
223
240
|
await assertRootDirectoryObservationGuard(root, guard);
|
package/dist/root-directory.d.ts
CHANGED
package/dist/root-entries.d.ts
CHANGED
package/dist/root-errors.d.ts
CHANGED
|
@@ -10,4 +10,3 @@ export declare function normalizePinnedPathError(error: unknown, details?: FsSaf
|
|
|
10
10
|
export declare function normalizeRemoveGuardError(error: unknown, details?: FsSafeErrorDetails): Error;
|
|
11
11
|
export declare function normalizeRemovePathError(error: unknown, details?: FsSafeErrorDetails): Error;
|
|
12
12
|
export declare function throwFsSafeReadError(error: unknown, label: string): never;
|
|
13
|
-
//# sourceMappingURL=root-errors.d.ts.map
|
|
@@ -16,6 +16,5 @@ export type CanonicalRootObservation = {
|
|
|
16
16
|
export declare function observeCanonicalRoot(ioFs: RootFileAdmissionFs, rootPath: string): CanonicalRootObservation;
|
|
17
17
|
export declare function createRootFileFinalAdmission(ioFs: RootFileAdmissionFs, root: Extract<CanonicalRootObservation, {
|
|
18
18
|
ok: true;
|
|
19
|
-
}>, boundaryLabel: string): PinnedOpenSyncFinalAdmission;
|
|
19
|
+
}>, boundaryLabel: string, rejectHardlinks?: boolean): PinnedOpenSyncFinalAdmission;
|
|
20
20
|
export {};
|
|
21
|
-
//# sourceMappingURL=root-file-final-admission.d.ts.map
|
|
@@ -2,6 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import { FsSafeError } from "./errors.js";
|
|
3
3
|
import { realpathSync } from "./realpath.js";
|
|
4
4
|
import { admitPathInsideRoot } from "./root-boundary.js";
|
|
5
|
+
import { hardlinkedPathNotAllowedError } from "./root-errors.js";
|
|
5
6
|
import { inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
6
7
|
import { assertNoWindowsPathAlias, pathForWindowsFilesystem } from "./windows-path-alias.js";
|
|
7
8
|
function rootIdentityMismatch(cause) {
|
|
@@ -51,7 +52,7 @@ export function observeCanonicalRoot(ioFs, rootPath) {
|
|
|
51
52
|
function resolveConsumedPath(ioFs, filePath) {
|
|
52
53
|
return ioFs === fs ? realpathSync.native(filePath) : ioFs.realpathSync(filePath);
|
|
53
54
|
}
|
|
54
|
-
export function createRootFileFinalAdmission(ioFs, root, boundaryLabel) {
|
|
55
|
+
export function createRootFileFinalAdmission(ioFs, root, boundaryLabel, rejectHardlinks = true) {
|
|
55
56
|
const inspectRoot = (candidateRootPath, expected) => {
|
|
56
57
|
inspectCanonicalRoot(ioFs, candidateRootPath, expected);
|
|
57
58
|
};
|
|
@@ -69,7 +70,9 @@ export function createRootFileFinalAdmission(ioFs, root, boundaryLabel) {
|
|
|
69
70
|
throw new FsSafeError("outside-workspace", `resolved path escapes ${boundaryLabel}`);
|
|
70
71
|
}
|
|
71
72
|
try {
|
|
72
|
-
inspectFileIdentitySync(() => ioFs.lstatSync(admitted.path, { bigint: true }), descriptorIdentity);
|
|
73
|
+
const current = inspectFileIdentitySync(() => ioFs.lstatSync(admitted.path, { bigint: true }), descriptorIdentity);
|
|
74
|
+
if (rejectHardlinks && current.isFile() && current.nlink > 1n)
|
|
75
|
+
throw hardlinkedPathNotAllowedError();
|
|
73
76
|
}
|
|
74
77
|
catch (error) {
|
|
75
78
|
if (isExpectedPathError(error)) {
|