@openclaw/fs-safe 0.17.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 +43 -0
- package/dist/absolute-path.d.ts +0 -1
- package/dist/advanced.d.ts +0 -1
- package/dist/archive-crc32.d.ts +0 -1
- package/dist/archive-deadline.d.ts +0 -1
- 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 +2 -4
- package/dist/archive-merge.js +14 -4
- package/dist/archive-native.d.ts +3 -15
- package/dist/archive-native.js +46 -71
- package/dist/archive-options.d.ts +7 -2
- package/dist/archive-parser-errors.d.ts +0 -1
- 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-directory.d.ts +0 -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 +0 -1
- package/dist/archive-zip-manifest.d.ts +0 -1
- package/dist/archive-zip-names.d.ts +0 -1
- package/dist/archive-zip-preflight.d.ts +0 -1
- package/dist/archive.d.ts +0 -1
- package/dist/archive.js +87 -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 +0 -1
- 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 -1
- 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 +0 -1
- 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 +0 -1
- 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 +0 -1
- package/dist/file-contents.d.ts +0 -1
- package/dist/file-handle-transfer.d.ts +0 -1
- package/dist/file-hash.d.ts +0 -1
- package/dist/file-hash.js +170 -66
- 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 +32 -98
- package/dist/file-lock-sync-root-arbitration.d.ts +0 -1
- package/dist/file-lock-sync-root-held.d.ts +0 -1
- 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 +21 -23
- package/dist/file-lock-sync.d.ts +0 -1
- package/dist/file-lock-sync.js +38 -117
- 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 +3 -4
- 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-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/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 +42 -61
- 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 +7 -130
- 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 +6 -15
- 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/lock-config.d.ts +0 -1
- package/dist/move-path-cleanup.d.ts +0 -1
- package/dist/move-path-stage.d.ts +0 -1
- package/dist/move-path.d.ts +0 -1
- 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 +15 -3
- package/dist/native-staged-file.js +55 -63
- package/dist/native.d.ts +0 -1
- package/dist/opened-file-failure.d.ts +0 -1
- package/dist/opened-realpath.d.ts +0 -1
- 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/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 +8 -16
- 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-mode.d.ts +0 -1
- package/dist/pinned-write-staged.d.ts +0 -1
- package/dist/pinned-write-types.d.ts +9 -21
- package/dist/pinned-write.d.ts +0 -1
- 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 +0 -1
- 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 +77 -139
- 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 +14 -3
- package/dist/replace-file-copy-source.d.ts +0 -1
- package/dist/replace-file-copy-source.js +6 -1
- package/dist/replace-file-descriptor.d.ts +0 -1
- package/dist/replace-file-descriptor.js +6 -1
- 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 +66 -85
- package/dist/replace-file.d.ts +0 -1
- 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.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 +0 -1
- package/dist/root-file.d.ts +0 -1
- package/dist/root-impl.d.ts +2 -10
- package/dist/root-impl.js +114 -91
- package/dist/root-move-noreplace.d.ts +0 -1
- 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 -44
- 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-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 +31 -52
- 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 +0 -1
- package/dist/sidecar-lock-policy.d.ts +3 -1
- package/dist/sidecar-lock-policy.js +16 -0
- package/dist/sidecar-lock-reclaim.d.ts +0 -1
- 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 +16 -83
- package/dist/staged-directory.d.ts +0 -1
- 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 +0 -1
- 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/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 +45 -22
- 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/walk.d.ts +0 -1
- 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 +0 -1
- package/dist/write-open-flags.d.ts +0 -1
- package/dist/write-queue.d.ts +0 -1
- package/docs/atomic.md +14 -0
- package/docs/copy.md +2 -0
- package/docs/mutation-policy-proof.md +6 -4
- package/docs/permissions.md +6 -0
- package/docs/root.md +10 -0
- package/docs/secret-file.md +4 -0
- package/docs/writing.md +9 -3
- 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/byte-view.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-contents.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 -20
- 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
|
@@ -5,11 +5,11 @@ import { assertNoUnsafeDeviceReadPath } from "./device-path.js";
|
|
|
5
5
|
import { FsSafeError } from "./errors.js";
|
|
6
6
|
import { resolveReadOpenFlags } from "./read-open-flags.js";
|
|
7
7
|
import { realpathSync } from "./realpath.js";
|
|
8
|
-
import {
|
|
8
|
+
import { inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
9
9
|
import { prepareSecretRead, secretPathErrorCode, secretReadError, trimSecretFileContent, } from "./secret-read-policy.js";
|
|
10
10
|
import { assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
11
11
|
export async function readSecretFile(filePath, label, options = {}) {
|
|
12
|
-
const { resolvedPath, maxBytes,
|
|
12
|
+
const { resolvedPath, maxBytes, rejectHardlinks, previewStat, inspectInput } = prepareSecretRead(filePath, label, options);
|
|
13
13
|
let handle;
|
|
14
14
|
let raw;
|
|
15
15
|
try {
|
|
@@ -18,20 +18,20 @@ export async function readSecretFile(filePath, label, options = {}) {
|
|
|
18
18
|
assertNoUnsafeDeviceReadPath(realPath);
|
|
19
19
|
handle = await fs.open(realPath, resolveReadOpenFlags());
|
|
20
20
|
const openedHandle = handle;
|
|
21
|
-
const openedStat =
|
|
21
|
+
const openedStat = inspectFileIdentitySync(() => {
|
|
22
22
|
const stat = fsSync.fstatSync(openedHandle.fd, { bigint: true });
|
|
23
23
|
if (!stat.isFile() || (rejectHardlinks && stat.nlink > 1n)) {
|
|
24
24
|
throw new FsSafeError("path-mismatch", "security validation failed");
|
|
25
25
|
}
|
|
26
26
|
return stat;
|
|
27
27
|
}, previewStat);
|
|
28
|
-
|
|
28
|
+
inspectFileIdentitySync(() => {
|
|
29
29
|
const stat = fsSync.lstatSync(realPath, { bigint: true });
|
|
30
30
|
if (!stat.isFile())
|
|
31
31
|
throw new FsSafeError("path-mismatch", "security validation failed");
|
|
32
32
|
return stat;
|
|
33
33
|
}, openedStat);
|
|
34
|
-
|
|
34
|
+
inspectFileIdentitySync(() => inspectInput("secret path became a symlink"), openedStat);
|
|
35
35
|
raw = (await readFileHandleBounded(handle, maxBytes)).toString("utf8");
|
|
36
36
|
}
|
|
37
37
|
catch (error) {
|
package/dist/secret.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { createSecretFileAtomic, PRIVATE_SECRET_DIR_MODE, PRIVATE_SECRET_FILE_MODE, readSecretFileSync, tryReadSecretFileSync, writeSecretFileAtomic, } from "./secret-file.js";
|
|
2
2
|
export { DEFAULT_SECRET_FILE_MAX_BYTES, type SecretFileReadOptions } from "./secret-read-policy.js";
|
|
3
3
|
export { readSecretFile, tryReadSecretFile } from "./secret-read-async.js";
|
|
4
|
-
//# sourceMappingURL=secret.d.ts.map
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import type { BigIntStats, Stats } from "node:fs";
|
|
2
2
|
import type { PermissionCheck } from "./permissions.js";
|
|
3
3
|
type ExactIdentity = Pick<BigIntStats, "dev" | "ino">;
|
|
4
|
-
export declare function inspectSecureWindowsDescriptor(params: {
|
|
5
|
-
fd: number;
|
|
6
|
-
identity: ExactIdentity;
|
|
7
|
-
stat: Stats;
|
|
8
|
-
}): PermissionCheck;
|
|
9
4
|
/** Both mechanisms inspect the same borrowed handle; the caller owns its lifetime. */
|
|
10
5
|
export declare function inspectSecureWindowsFile(params: {
|
|
11
6
|
fd: number;
|
|
@@ -13,4 +8,3 @@ export declare function inspectSecureWindowsFile(params: {
|
|
|
13
8
|
stat: Stats;
|
|
14
9
|
}): Promise<PermissionCheck>;
|
|
15
10
|
export {};
|
|
16
|
-
//# sourceMappingURL=secure-file-windows.d.ts.map
|
|
@@ -29,27 +29,6 @@ function parseIdentity(value) {
|
|
|
29
29
|
ino: BigInt(`0x${match[2]}`),
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
export function inspectSecureWindowsDescriptor(params) {
|
|
33
|
-
let native;
|
|
34
|
-
try {
|
|
35
|
-
native = getNativeBinding();
|
|
36
|
-
}
|
|
37
|
-
catch (cause) {
|
|
38
|
-
permissionUnverified("Windows descriptor ACL verification requires the matching native helper", cause);
|
|
39
|
-
}
|
|
40
|
-
const inspect = native?.inspectWindowsSecureFileHandle;
|
|
41
|
-
if (typeof inspect !== "function") {
|
|
42
|
-
permissionUnverified("Windows descriptor ACL verification requires an up-to-date native helper");
|
|
43
|
-
}
|
|
44
|
-
let result;
|
|
45
|
-
try {
|
|
46
|
-
result = inspect.call(native, params.fd);
|
|
47
|
-
}
|
|
48
|
-
catch (cause) {
|
|
49
|
-
permissionUnverified("Windows descriptor ACL verification failed", cause);
|
|
50
|
-
}
|
|
51
|
-
return inspectDescriptorResult(params, result, "native");
|
|
52
|
-
}
|
|
53
32
|
function inspectDescriptorResult(params, result, mechanism) {
|
|
54
33
|
if (!isRecord(result))
|
|
55
34
|
permissionUnverified("Windows descriptor ACL facts were malformed");
|
|
@@ -85,19 +64,25 @@ export async function inspectSecureWindowsFile(params) {
|
|
|
85
64
|
catch (cause) {
|
|
86
65
|
permissionUnverified("Windows descriptor ACL verification requires the matching native helper", cause);
|
|
87
66
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (getFsSafeNativeConfig().mode === "require") {
|
|
67
|
+
const inspect = native?.inspectWindowsSecureFileHandle;
|
|
68
|
+
const nativeAvailable = typeof inspect === "function";
|
|
69
|
+
if (!nativeAvailable && getFsSafeNativeConfig().mode === "require") {
|
|
92
70
|
permissionUnverified("Windows descriptor ACL verification requires an up-to-date native helper");
|
|
93
71
|
}
|
|
94
|
-
|
|
72
|
+
if (!nativeAvailable) {
|
|
73
|
+
warnNativeFallback("windows-secure-file", "Windows descriptor ACL inspection uses a slower built-in system command.");
|
|
74
|
+
}
|
|
95
75
|
let result;
|
|
96
76
|
try {
|
|
97
|
-
|
|
77
|
+
if (nativeAvailable) {
|
|
78
|
+
result = inspect.call(native, params.fd);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
result = await inspectWindowsDescriptorCommand(params.fd);
|
|
82
|
+
}
|
|
98
83
|
}
|
|
99
84
|
catch (cause) {
|
|
100
85
|
permissionUnverified("Windows descriptor ACL verification failed", cause);
|
|
101
86
|
}
|
|
102
|
-
return inspectDescriptorResult(params, result, "system-command");
|
|
87
|
+
return inspectDescriptorResult(params, result, nativeAvailable ? "native" : "system-command");
|
|
103
88
|
}
|
package/dist/secure-file.d.ts
CHANGED
package/dist/secure-file.js
CHANGED
|
@@ -12,7 +12,7 @@ import { formatPermissionErrorDetail } from "./permission-exec.js";
|
|
|
12
12
|
import { resolveReadOpenFlags } from "./read-open-flags.js";
|
|
13
13
|
import { realpathSync } from "./realpath.js";
|
|
14
14
|
import { inspectPathPermissions, isGroupReadable, isGroupWritable, isWorldReadable, isWorldWritable, modeBits, } from "./permissions.js";
|
|
15
|
-
import {
|
|
15
|
+
import { inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
16
16
|
import { inspectSecureWindowsFile } from "./secure-file-windows.js";
|
|
17
17
|
import { scheduleTimeout } from "./timing.js";
|
|
18
18
|
import { anchorWindowsDriveRelativePath, assertNoWindowsPathAlias, resolvePathPreservingWindowsRoot, } from "./windows-path-alias.js";
|
|
@@ -139,9 +139,9 @@ async function openSecureHandle(options, maxBytes) {
|
|
|
139
139
|
if (!openedStat.isFile()) {
|
|
140
140
|
throw new FsSafeError("not-file", `${label(options)} must be a file: ${options.filePath}`);
|
|
141
141
|
}
|
|
142
|
-
const openedIdentity =
|
|
142
|
+
const openedIdentity = inspectFileIdentitySync(() => fsSync.fstatSync(handle.fd, { bigint: true }));
|
|
143
143
|
assertNotHardlinked(options, openedIdentity);
|
|
144
|
-
|
|
144
|
+
inspectFileIdentitySync(() => {
|
|
145
145
|
const pathStat = options.trust?.allowSymlink
|
|
146
146
|
? fsSync.statSync(options.filePath, { bigint: true })
|
|
147
147
|
: fsSync.lstatSync(options.filePath, { bigint: true });
|
|
@@ -153,7 +153,7 @@ async function openSecureHandle(options, maxBytes) {
|
|
|
153
153
|
}, openedIdentity);
|
|
154
154
|
const realPath = realpathSync.native(options.filePath);
|
|
155
155
|
assertNoWindowsPathAlias(realPath, "filesystem", `${label(options)} resolved path uses a Windows filesystem namespace alias`);
|
|
156
|
-
|
|
156
|
+
inspectFileIdentitySync(() => {
|
|
157
157
|
const realPathStat = fsSync.statSync(realPath, { bigint: true });
|
|
158
158
|
assertNotHardlinked(options, realPathStat);
|
|
159
159
|
return realPathStat;
|
|
@@ -168,11 +168,11 @@ async function openSecureHandle(options, maxBytes) {
|
|
|
168
168
|
throw err;
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
|
-
|
|
171
|
+
function assertTrustedDirs(options, realPath) {
|
|
172
172
|
if (!options.trust?.trustedDirs || options.trust.trustedDirs.length === 0) {
|
|
173
173
|
return;
|
|
174
174
|
}
|
|
175
|
-
const trusted =
|
|
175
|
+
const trusted = options.trust.trustedDirs.map((dir) => {
|
|
176
176
|
let realPath;
|
|
177
177
|
try {
|
|
178
178
|
realPath = realpathSync.native(dir);
|
|
@@ -182,7 +182,7 @@ async function assertTrustedDirs(options, realPath) {
|
|
|
182
182
|
}
|
|
183
183
|
assertNoWindowsPathAlias(realPath, "filesystem", "trusted directory uses a Windows filesystem namespace alias");
|
|
184
184
|
return realPath;
|
|
185
|
-
})
|
|
185
|
+
});
|
|
186
186
|
if (!trusted.some((dir) => isPathInside(dir, realPath))) {
|
|
187
187
|
throw new FsSafeError("outside-workspace", `${label(options)} is outside trustedDirs: ${realPath}`);
|
|
188
188
|
}
|
|
@@ -281,10 +281,10 @@ export async function readSecureFile(options) {
|
|
|
281
281
|
assertNoWindowsPathAlias(options.filePath, "filesystem", `${label(options)} path uses a Windows filesystem namespace alias`);
|
|
282
282
|
const opened = await openSecureHandle(options, maxBytes);
|
|
283
283
|
try {
|
|
284
|
-
|
|
284
|
+
assertTrustedDirs(options, opened.realPath);
|
|
285
285
|
const permissions = await assertSecurePermissions(options, opened.pathStat, opened.realPath, opened.identity, opened.handle.fd);
|
|
286
286
|
const buffer = await readHandleWithTimeout(opened.handle, options.io?.timeoutMs, maxBytes);
|
|
287
|
-
const finalIdentity =
|
|
287
|
+
const finalIdentity = inspectFileIdentitySync(() => fsSync.fstatSync(opened.handle.fd, { bigint: true }), opened.identity);
|
|
288
288
|
if (!finalIdentity.isFile()) {
|
|
289
289
|
throw new FsSafeError("not-file", `${label(options)} must remain a file: ${options.filePath}`);
|
|
290
290
|
}
|
|
@@ -32,4 +32,3 @@ export declare function secureTempDirectoryReceipt(stat: ExactDirectoryStat, uid
|
|
|
32
32
|
/** No pathname chmod, search-only descriptors, procfs, or reopening fallback. */
|
|
33
33
|
export declare function repairSecureTempDirectory(candidate: string, expected: SecureTempDirectoryReceipt, uid: number, adapter: SecureTempRepairAdapter, access: () => void, repaired: () => void, finalize?: boolean): void;
|
|
34
34
|
export {};
|
|
35
|
-
//# sourceMappingURL=secure-temp-repair.d.ts.map
|
|
@@ -2,7 +2,7 @@ import { syncFileBestEffort } from "./file-sync.js";
|
|
|
2
2
|
import fsSync, {} from "node:fs";
|
|
3
3
|
import fs, {} from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
import {
|
|
5
|
+
import { assertDirectoryIdentitySync, createAsyncDirectoryGuard, } from "./directory-guard.js";
|
|
6
6
|
import { syncDirectoryBestEffort } from "./directory-durability.js";
|
|
7
7
|
import { isWindowsReservedDeviceName } from "./device-path.js";
|
|
8
8
|
import { FsSafeError } from "./errors.js";
|
|
@@ -10,7 +10,7 @@ import { getNativeBinding } from "./native.js";
|
|
|
10
10
|
import { handoffPrivateProducerFile, } from "./private-producer-handoff.js";
|
|
11
11
|
import { resolveReadOpenFlags } from "./read-open-flags.js";
|
|
12
12
|
import { rootFromDirectoryGuard } from "./root-impl.js";
|
|
13
|
-
import {
|
|
13
|
+
import { inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
14
14
|
import { registerTempPathForExit } from "./temp-cleanup.js";
|
|
15
15
|
import { createOwnedTempFile } from "./temp-target.js";
|
|
16
16
|
import { serializePathWrite } from "./write-queue.js";
|
|
@@ -52,8 +52,8 @@ function assertRegularFile(stat) {
|
|
|
52
52
|
throw new FsSafeError("hardlink", "sibling temp must have exactly one link");
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
|
|
56
|
-
return
|
|
55
|
+
function inspectStage(inspect, expected) {
|
|
56
|
+
return inspectFileIdentitySync(() => {
|
|
57
57
|
const stat = inspect();
|
|
58
58
|
assertRegularFile(stat);
|
|
59
59
|
return stat;
|
|
@@ -67,12 +67,7 @@ function aggregateErrors(errors, message) {
|
|
|
67
67
|
// Own the workspace before the producer can leave partial output. The finished
|
|
68
68
|
// file still enters the ordinary sibling admission and publication lifecycle.
|
|
69
69
|
async function writeIsolatedProducer(params) {
|
|
70
|
-
const tempPath = params
|
|
71
|
-
const write = params.write;
|
|
72
|
-
const writeReceiver = params.writeReceiver;
|
|
73
|
-
const parentGuard = params.parentGuard;
|
|
74
|
-
const assertParent = params.assertParent;
|
|
75
|
-
const syncTempFile = params.syncTempFile;
|
|
70
|
+
const { tempPath, write, writeReceiver, parentGuard, assertParent, syncTempFile } = params;
|
|
76
71
|
assertParent();
|
|
77
72
|
const targetRoot = rootFromDirectoryGuard(parentGuard);
|
|
78
73
|
// Select the handoff before invoking the producer. Missing required native
|
|
@@ -150,7 +145,9 @@ export async function writeCallbackSibling(params) {
|
|
|
150
145
|
const syncTempFile = params.syncTempFile;
|
|
151
146
|
const syncParentDir = params.syncParentDir;
|
|
152
147
|
const guard = await createAsyncDirectoryGuard(parent, { bigint: true });
|
|
153
|
-
const assertParent = () =>
|
|
148
|
+
const assertParent = () => assertDirectoryIdentitySync(parent, {
|
|
149
|
+
dev: guard.stat.dev, ino: guard.stat.ino, realPath: guard.realPath,
|
|
150
|
+
});
|
|
154
151
|
let handle;
|
|
155
152
|
let identity;
|
|
156
153
|
let unregister;
|
|
@@ -158,10 +155,10 @@ export async function writeCallbackSibling(params) {
|
|
|
158
155
|
let renamed = false;
|
|
159
156
|
let failure;
|
|
160
157
|
const inspectPath = (pathname, expected) => inspectStage(() => fsSync.lstatSync(pathname, { bigint: true }), expected);
|
|
161
|
-
const assertCurrent =
|
|
162
|
-
|
|
163
|
-
const opened =
|
|
164
|
-
const current =
|
|
158
|
+
const assertCurrent = (pathname) => {
|
|
159
|
+
assertParent();
|
|
160
|
+
const opened = inspectStage(() => fsSync.fstatSync(handle.fd, { bigint: true }), identity);
|
|
161
|
+
const current = inspectPath(pathname, opened);
|
|
165
162
|
if (maxBytes !== undefined &&
|
|
166
163
|
(opened.size > maxBytes || current.size > maxBytes)) {
|
|
167
164
|
throw new FsSafeError("too-large", `sibling temp exceeds maxBytes (${maxBytes})`);
|
|
@@ -176,11 +173,7 @@ export async function writeCallbackSibling(params) {
|
|
|
176
173
|
writeReceiver: params,
|
|
177
174
|
parentGuard: guard,
|
|
178
175
|
syncTempFile: syncTempFile,
|
|
179
|
-
assertParent
|
|
180
|
-
dev: guard.stat.dev,
|
|
181
|
-
ino: guard.stat.ino,
|
|
182
|
-
realPath: guard.realPath,
|
|
183
|
-
}),
|
|
176
|
+
assertParent,
|
|
184
177
|
});
|
|
185
178
|
result = isolated.result;
|
|
186
179
|
cleanupWorkspace = isolated.cleanupWorkspace;
|
|
@@ -193,13 +186,10 @@ export async function writeCallbackSibling(params) {
|
|
|
193
186
|
else {
|
|
194
187
|
result = await Reflect.apply(write, params, [tempPath]);
|
|
195
188
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
else {
|
|
202
|
-
const before = await inspectPath(tempPath);
|
|
189
|
+
assertParent();
|
|
190
|
+
let expected = identity;
|
|
191
|
+
if (!handle) {
|
|
192
|
+
expected = inspectPath(tempPath);
|
|
203
193
|
try {
|
|
204
194
|
// No create/truncate flags; O_NONBLOCK also bounds a FIFO swap during open.
|
|
205
195
|
const access = syncTempFile ? fsSync.constants.O_RDWR : fsSync.constants.O_RDONLY;
|
|
@@ -211,12 +201,14 @@ export async function writeCallbackSibling(params) {
|
|
|
211
201
|
}
|
|
212
202
|
throw error;
|
|
213
203
|
}
|
|
214
|
-
|
|
215
|
-
|
|
204
|
+
}
|
|
205
|
+
const opened = inspectStage(() => fsSync.fstatSync(handle.fd, { bigint: true }), expected);
|
|
206
|
+
inspectPath(tempPath, opened);
|
|
207
|
+
if (!identity) {
|
|
216
208
|
identity = opened;
|
|
217
209
|
unregister = registerTempPathForExit(tempPath, { identity, singleLinkFile: true });
|
|
218
210
|
}
|
|
219
|
-
|
|
211
|
+
assertParent();
|
|
220
212
|
if (cleanupWorkspace) {
|
|
221
213
|
const cleanup = cleanupWorkspace;
|
|
222
214
|
cleanupWorkspace = undefined;
|
|
@@ -233,7 +225,7 @@ export async function writeCallbackSibling(params) {
|
|
|
233
225
|
throw new FsSafeError("invalid-path", "final path must differ from the sibling temp path");
|
|
234
226
|
}
|
|
235
227
|
await serializePathWrite(filePath, async () => {
|
|
236
|
-
|
|
228
|
+
assertCurrent(tempPath);
|
|
237
229
|
if (mode !== undefined) {
|
|
238
230
|
try {
|
|
239
231
|
await handle.chmod(mode);
|
|
@@ -242,20 +234,21 @@ export async function writeCallbackSibling(params) {
|
|
|
242
234
|
if (!ignoreModeError)
|
|
243
235
|
throw error;
|
|
244
236
|
}
|
|
237
|
+
assertCurrent(tempPath);
|
|
245
238
|
}
|
|
246
239
|
if (syncTempFile) {
|
|
247
|
-
await assertCurrent(tempPath);
|
|
248
240
|
await syncFileBestEffort(handle);
|
|
241
|
+
assertCurrent(tempPath);
|
|
249
242
|
}
|
|
250
|
-
await assertCurrent(tempPath);
|
|
251
243
|
await fs.rename(tempPath, filePath);
|
|
252
244
|
// A later verification failure never authorizes rollback of the final name.
|
|
253
245
|
renamed = true;
|
|
254
246
|
unregister();
|
|
255
|
-
|
|
256
|
-
if (syncParentDir)
|
|
247
|
+
assertCurrent(filePath);
|
|
248
|
+
if (syncParentDir) {
|
|
257
249
|
await syncDirectoryBestEffort(parent);
|
|
258
|
-
|
|
250
|
+
assertCurrent(filePath);
|
|
251
|
+
}
|
|
259
252
|
});
|
|
260
253
|
return { filePath, result };
|
|
261
254
|
}
|
|
@@ -276,9 +269,9 @@ export async function writeCallbackSibling(params) {
|
|
|
276
269
|
try {
|
|
277
270
|
if (!renamed && identity) {
|
|
278
271
|
try {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
272
|
+
assertParent();
|
|
273
|
+
inspectStage(() => fsSync.fstatSync(handle.fd, { bigint: true }), identity);
|
|
274
|
+
inspectPath(tempPath, identity);
|
|
282
275
|
await fs.unlink(tempPath);
|
|
283
276
|
unregister?.();
|
|
284
277
|
}
|
package/dist/sibling-temp.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { SidecarLockAcquireOptions, SidecarLockHandle } from "./sidecar-lock-types.js";
|
|
2
|
-
import {
|
|
2
|
+
import type { SidecarLockAcquisitionContext } from "./sidecar-lock-admission.js";
|
|
3
3
|
export type { HeldSidecarLock } from "./sidecar-lock-admission.js";
|
|
4
4
|
export declare function acquireSidecarLock<TPayload extends Record<string, unknown>>(options: SidecarLockAcquireOptions<TPayload>, context: SidecarLockAcquisitionContext): Promise<SidecarLockHandle>;
|
|
5
|
-
//# sourceMappingURL=sidecar-lock-acquire.d.ts.map
|
|
@@ -5,12 +5,11 @@ import { fileObservation } from "./file-observation.js";
|
|
|
5
5
|
import { readFileHandleBounded } from "./bounded-read.js";
|
|
6
6
|
import { openSidecarRoot } from "./sidecar-lock-root.js";
|
|
7
7
|
import { createNativeExclusiveFile } from "./native-operations.js";
|
|
8
|
-
import {
|
|
8
|
+
import { sidecarLockRetryDelay, sidecarLockTimeout, isTransientLockFileDenial, maxTransientLockDenials, validateSidecarLockStaleMs, validateSidecarLockRetryOptions, validateSidecarLockCompromiseCheckIntervalMs, validateSidecarLockTimeoutMs, } from "./sidecar-lock-policy.js";
|
|
9
9
|
import { relativeSidecarLockPath, removeSidecarLockIfUnchanged, serializeSidecarLockPayload, sidecarReclaimGuardExists, } from "./sidecar-lock-reclaim.js";
|
|
10
10
|
import { awaitSidecarAdmissionBoundary, conditionalSidecarLockParser, observeHeldSidecarParser, observeSidecarLockParser, runSidecarAdmissionBoundary, } from "./sidecar-lock-admission-parser.js";
|
|
11
11
|
import { handleStaleSidecarAdmission, } from "./sidecar-lock-stale-admission.js";
|
|
12
12
|
import { ancestryHasSidecarAdmission, captureSidecarAdmissionAncestry, createSidecarAdmissionController, } from "./sidecar-lock-admission-context.js";
|
|
13
|
-
import { sidecarLockTimeout } from "./sidecar-lock-admission.js";
|
|
14
13
|
import { resolveSidecarLockPaths } from "./sidecar-lock-target.js";
|
|
15
14
|
import { createSuppressedError } from "./suppressed-error.js";
|
|
16
15
|
import { sleep } from "./timing.js";
|
|
@@ -34,11 +33,25 @@ export async function acquireSidecarLock(options, context) {
|
|
|
34
33
|
const requestedReentrantOwner = options.reentrantOwner;
|
|
35
34
|
const { lockPath, normalizedTargetPath } = await resolveSidecarLockPaths(targetPath, explicitLockPath, lockRoot);
|
|
36
35
|
const activeDescendant = ancestryHasSidecarAdmission(admissionAncestry, context.admissions, normalizedTargetPath);
|
|
37
|
-
|
|
38
|
-
if (held &&
|
|
36
|
+
const isReentrant = (candidate) => !!candidate &&
|
|
39
37
|
requestedReentrantOwner !== undefined &&
|
|
40
|
-
|
|
41
|
-
requestedReentrantOwner ===
|
|
38
|
+
candidate.reentrantOwner !== undefined &&
|
|
39
|
+
requestedReentrantOwner === candidate.reentrantOwner;
|
|
40
|
+
const reuseHeldLock = (candidate) => {
|
|
41
|
+
const lifecycle = context.ensureExitCleanupRegistered();
|
|
42
|
+
context.assertRetainOnExitSupported(retainOnExit);
|
|
43
|
+
if (context.held.get(normalizedTargetPath) !== candidate || candidate.releasePromise)
|
|
44
|
+
return undefined;
|
|
45
|
+
candidate.refCount = (candidate.refCount ?? 1) + 1;
|
|
46
|
+
// Any same-owner request upgrades exit retention; later requests never revoke it.
|
|
47
|
+
if (retainOnExit === true)
|
|
48
|
+
candidate.retainOnExit = true;
|
|
49
|
+
const returnedHandle = context.handleForHeldLock(normalizedTargetPath, candidate);
|
|
50
|
+
context.armExitCleanup(lifecycle);
|
|
51
|
+
return returnedHandle;
|
|
52
|
+
};
|
|
53
|
+
let held = context.held.get(normalizedTargetPath);
|
|
54
|
+
if (isReentrant(held)) {
|
|
42
55
|
// Join a final release before deciding whether this completed owner remains.
|
|
43
56
|
// Successful cleanup requires a fresh acquisition; failed cleanup can retry.
|
|
44
57
|
if (held.releasePromise) {
|
|
@@ -47,23 +60,10 @@ export async function acquireSidecarLock(options, context) {
|
|
|
47
60
|
await held.releasePromise.catch(() => undefined);
|
|
48
61
|
held = context.held.get(normalizedTargetPath);
|
|
49
62
|
}
|
|
50
|
-
if (held
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const lifecycle = context.ensureExitCleanupRegistered();
|
|
55
|
-
context.assertRetainOnExitSupported(retainOnExit);
|
|
56
|
-
if (context.held.get(normalizedTargetPath) === held && !held.releasePromise) {
|
|
57
|
-
held.refCount = (held.refCount ?? 1) + 1;
|
|
58
|
-
// Retention is monotonic: any same-owner request to keep the sidecar on
|
|
59
|
-
// exit upgrades the held lock; a later default acquisition never revokes it.
|
|
60
|
-
if (retainOnExit === true) {
|
|
61
|
-
held.retainOnExit = true;
|
|
62
|
-
}
|
|
63
|
-
const returnedHandle = context.handleForHeldLock(normalizedTargetPath, held);
|
|
64
|
-
context.armExitCleanup(lifecycle);
|
|
65
|
-
return returnedHandle;
|
|
66
|
-
}
|
|
63
|
+
if (isReentrant(held)) {
|
|
64
|
+
const reused = reuseHeldLock(held);
|
|
65
|
+
if (reused)
|
|
66
|
+
return reused;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
if (activeDescendant)
|
|
@@ -90,17 +90,9 @@ export async function acquireSidecarLock(options, context) {
|
|
|
90
90
|
const withinDenialBudget = () => ++transientDenials <= maxTransientLockDenials;
|
|
91
91
|
const waitForRetry = async () => {
|
|
92
92
|
admission.release();
|
|
93
|
-
const
|
|
94
|
-
if (
|
|
95
|
-
timeoutMs !== Number.POSITIVE_INFINITY &&
|
|
96
|
-
elapsed >= timeoutMs) ||
|
|
97
|
-
(retry.retries !== undefined && attempt >= retry.retries)) {
|
|
93
|
+
const delay = sidecarLockRetryDelay(retry, timeoutMs === Number.POSITIVE_INFINITY ? undefined : timeoutMs, Date.now() - startedAt, attempt);
|
|
94
|
+
if (delay === undefined)
|
|
98
95
|
throw sidecarLockTimeout(lockPath, normalizedTargetPath);
|
|
99
|
-
}
|
|
100
|
-
const remaining = timeoutMs === undefined || timeoutMs === Number.POSITIVE_INFINITY
|
|
101
|
-
? Number.POSITIVE_INFINITY
|
|
102
|
-
: Math.max(0, timeoutMs - elapsed);
|
|
103
|
-
const delay = Math.min(computeSidecarLockDelayMs(retry, attempt), remaining);
|
|
104
96
|
attempt += 1;
|
|
105
97
|
await sleep(delay);
|
|
106
98
|
};
|
|
@@ -123,29 +115,16 @@ export async function acquireSidecarLock(options, context) {
|
|
|
123
115
|
while (true) {
|
|
124
116
|
if (!admission.owns) {
|
|
125
117
|
held = context.held.get(normalizedTargetPath);
|
|
126
|
-
if (held
|
|
127
|
-
requestedReentrantOwner !== undefined &&
|
|
128
|
-
held.reentrantOwner !== undefined &&
|
|
129
|
-
requestedReentrantOwner === held.reentrantOwner) {
|
|
118
|
+
if (isReentrant(held)) {
|
|
130
119
|
if (held.releasePromise) {
|
|
131
120
|
await held.releasePromise.catch(() => undefined);
|
|
132
121
|
held = context.held.get(normalizedTargetPath);
|
|
133
122
|
}
|
|
134
|
-
if (held
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
context.assertRetainOnExitSupported(retainOnExit);
|
|
140
|
-
if (context.held.get(normalizedTargetPath) !== held || held.releasePromise) {
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
held.refCount = (held.refCount ?? 1) + 1;
|
|
144
|
-
if (retainOnExit === true)
|
|
145
|
-
held.retainOnExit = true;
|
|
146
|
-
const returnedHandle = context.handleForHeldLock(normalizedTargetPath, held);
|
|
147
|
-
context.armExitCleanup(lifecycle);
|
|
148
|
-
return returnedHandle;
|
|
123
|
+
if (isReentrant(held)) {
|
|
124
|
+
const reused = reuseHeldLock(held);
|
|
125
|
+
if (reused)
|
|
126
|
+
return reused;
|
|
127
|
+
continue;
|
|
149
128
|
}
|
|
150
129
|
}
|
|
151
130
|
if (context.admissions.has(normalizedTargetPath)) {
|
|
@@ -2,11 +2,10 @@ import type { NativeFileHandle } from "./native-operations.js";
|
|
|
2
2
|
import type { Root } from "./root-impl.js";
|
|
3
3
|
import type { SidecarLockSnapshot } from "./sidecar-lock-reclaim.js";
|
|
4
4
|
import type { SidecarLockHandle } from "./sidecar-lock-types.js";
|
|
5
|
-
type SidecarFileHandle = Pick<NativeFileHandle, "fd" | "close" | "stat" | "writeFile">;
|
|
6
5
|
export type HeldSidecarLock = {
|
|
7
6
|
refCount: number;
|
|
8
7
|
reentrantOwner?: string;
|
|
9
|
-
handle:
|
|
8
|
+
handle: NativeFileHandle;
|
|
10
9
|
lockPath: string;
|
|
11
10
|
snapshot: SidecarLockSnapshot;
|
|
12
11
|
acquiredAt: number;
|
|
@@ -30,6 +29,3 @@ export type SidecarLockAcquisitionContext = {
|
|
|
30
29
|
assertRetainOnExitSupported(retainOnExit: boolean | undefined): void;
|
|
31
30
|
handleForHeldLock(normalizedTargetPath: string, held: HeldSidecarLock): SidecarLockHandle;
|
|
32
31
|
};
|
|
33
|
-
export declare function sidecarLockTimeout(lockPath: string, normalizedTargetPath: string): Error;
|
|
34
|
-
export {};
|
|
35
|
-
//# sourceMappingURL=sidecar-lock-admission.d.ts.map
|
|
@@ -4,6 +4,9 @@ export declare function validateSidecarLockTimeoutMs(timeoutMs: number | undefin
|
|
|
4
4
|
export declare function validateSidecarLockStaleMs(staleMs: number | undefined): void;
|
|
5
5
|
export declare function validateSidecarLockCompromiseCheckIntervalMs(intervalMs: number | undefined): void;
|
|
6
6
|
export declare function computeSidecarLockDelayMs(retry: SidecarLockRetryOptions, attempt: number): number;
|
|
7
|
+
export declare function sidecarLockTimeout(lockPath: string, normalizedTargetPath: string): Error;
|
|
8
|
+
/** Undefined means the deadline or retry count is exhausted. */
|
|
9
|
+
export declare function sidecarLockRetryDelay(retry: SidecarLockRetryOptions, timeoutMs: number | undefined, elapsed: number, attempt: number): number | undefined;
|
|
7
10
|
export declare const maxTransientLockDenials = 8;
|
|
8
11
|
export declare function isTransientLockFileDenial(error: unknown, lockPath: string): boolean;
|
|
9
12
|
export declare function sidecarLockPayloadCreatedAtMs(payload: unknown): number | null;
|
|
@@ -13,4 +16,3 @@ export declare function defaultSidecarLockShouldReclaim(params: {
|
|
|
13
16
|
staleMs: number;
|
|
14
17
|
nowMs: number;
|
|
15
18
|
}): Promise<boolean>;
|
|
16
|
-
//# sourceMappingURL=sidecar-lock-policy.d.ts.map
|
|
@@ -55,6 +55,22 @@ export function computeSidecarLockDelayMs(retry, attempt) {
|
|
|
55
55
|
const jitter = retry.randomize ? 1 + Math.random() : 1;
|
|
56
56
|
return Math.min(maxTimeout, Math.round(base * jitter));
|
|
57
57
|
}
|
|
58
|
+
export function sidecarLockTimeout(lockPath, normalizedTargetPath) {
|
|
59
|
+
return Object.assign(new Error(`file lock timeout for ${normalizedTargetPath}`), {
|
|
60
|
+
code: "file_lock_timeout",
|
|
61
|
+
lockPath,
|
|
62
|
+
normalizedTargetPath,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/** Undefined means the deadline or retry count is exhausted. */
|
|
66
|
+
export function sidecarLockRetryDelay(retry, timeoutMs, elapsed, attempt) {
|
|
67
|
+
if ((timeoutMs !== undefined && elapsed >= timeoutMs) ||
|
|
68
|
+
(retry.retries !== undefined && attempt >= retry.retries))
|
|
69
|
+
return undefined;
|
|
70
|
+
const remaining = timeoutMs === undefined || timeoutMs === Number.POSITIVE_INFINITY
|
|
71
|
+
? Number.POSITIVE_INFINITY : Math.max(0, timeoutMs - elapsed);
|
|
72
|
+
return Math.min(computeSidecarLockDelayMs(retry, attempt), remaining);
|
|
73
|
+
}
|
|
58
74
|
// Windows denies access to a lock file while a just-unlinked directory entry
|
|
59
75
|
// is still being torn down, so a contended acquire sees EPERM on a name that is
|
|
60
76
|
// already gone -- both when creating it exclusively and when reading the
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type CleanupRegistration = {
|
|
2
|
+
event: "exit" | "beforeExit";
|
|
3
|
+
registered: symbol;
|
|
4
|
+
registering: symbol;
|
|
5
|
+
handler: symbol;
|
|
6
|
+
retainAware?: symbol;
|
|
7
|
+
reentryError(): Error;
|
|
8
|
+
};
|
|
9
|
+
/** Preserve the legacy, first-registration-wins protocol across package copies. */
|
|
10
|
+
export declare function ensureSidecarLockCleanupRegistered<T extends true | {
|
|
11
|
+
armed: boolean;
|
|
12
|
+
}>(keys: CleanupRegistration, cleanup: () => void, marker: T): T;
|
|
13
|
+
export {};
|