@openclaw/fs-safe 0.17.0 → 0.18.1
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 +53 -0
- package/dist/absolute-path.d.ts +0 -1
- package/dist/advanced.d.ts +2 -2
- package/dist/archive-crc32.d.ts +0 -1
- package/dist/archive-deadline.d.ts +0 -1
- package/dist/archive-durability.d.ts +1 -2
- 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-parser-errors.d.ts +0 -1
- package/dist/archive-parser.wasm +0 -0
- package/dist/archive-plan.d.ts +72 -2
- package/dist/archive-plan.js +86 -22
- package/dist/archive-read.d.ts +0 -1
- package/dist/archive-staging.d.ts +0 -1
- package/dist/archive-tar-stream.d.ts +0 -1
- package/dist/archive-tar-wasm.d.ts +1 -2
- 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 +1 -2
- package/dist/archive-zip-entry.d.ts +1 -2
- package/dist/archive-zip-entry.js +1 -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 +8 -6
- package/dist/archive.js +204 -168
- package/dist/async-lock.d.ts +0 -1
- package/dist/atomic.d.ts +3 -2
- 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 +1 -2
- 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-owned-file.d.ts +0 -1
- package/dist/create.d.ts +16 -3
- package/dist/create.js +388 -2
- package/dist/creation-boundary.d.ts +60 -0
- package/dist/creation-boundary.js +371 -0
- 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-node.js +12 -2
- package/dist/directory-mode-owner.d.ts +0 -1
- package/dist/directory-receipt.d.ts +0 -1
- package/dist/durability.d.ts +2 -2
- 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 +33 -103
- 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 +3 -3
- 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 +18 -27
- package/dist/file-lock-sync.d.ts +4 -22
- 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 +7 -2
- package/dist/file-store-boundary.js +64 -27
- 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 +18 -29
- package/dist/file-store.d.ts +0 -1
- package/dist/file-store.js +4 -10
- 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 +1 -2
- 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 +9 -7
- 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 +13 -9
- package/dist/json-durable-queue.d.ts +0 -1
- package/dist/json-durable-queue.js +8 -132
- package/dist/json-store.d.ts +0 -1
- package/dist/json-store.js +1 -2
- package/dist/json-stringify.d.ts +0 -1
- package/dist/json.d.ts +0 -1
- package/dist/json.js +7 -17
- 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/move-path.js +1 -2
- 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 -7
- package/dist/native-parent-admission.d.ts +0 -1
- package/dist/native-pinned-write-windows.d.ts +1 -2
- package/dist/native-pinned-write-windows.js +1 -1
- package/dist/native-pinned-write.d.ts +1 -2
- package/dist/native-pinned-write.js +7 -16
- package/dist/native-policy-directory-observation.d.ts +0 -1
- package/dist/native-policy-parent-windows.d.ts +1 -2
- package/dist/native-rename-outcome.d.ts +0 -1
- package/dist/native-staged-file.d.ts +17 -5
- package/dist/native-staged-file.js +56 -65
- 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 +1 -2
- 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 +7 -2
- package/dist/pinned-operation.d.ts +1 -2
- package/dist/pinned-operation.js +3 -16
- package/dist/pinned-write-input.d.ts +0 -1
- package/dist/pinned-write-mode.d.ts +0 -1
- package/dist/pinned-write-mode.js +1 -1
- package/dist/pinned-write-staged.d.ts +0 -1
- package/dist/pinned-write-staged.js +1 -2
- package/dist/pinned-write-types.d.ts +9 -21
- package/dist/pinned-write.d.ts +0 -2
- package/dist/pinned-write.js +3 -5
- package/dist/positional-read.d.ts +0 -1
- package/dist/private-directory.d.ts +0 -1
- package/dist/private-producer-handoff-sync.d.ts +2 -13
- package/dist/private-producer-handoff-sync.js +10 -52
- package/dist/private-producer-handoff.d.ts +23 -4
- package/dist/private-producer-handoff.js +69 -46
- package/dist/private-temp-workspace.d.ts +0 -1
- package/dist/private-temp-workspace.js +11 -37
- package/dist/publish-copy-stage.d.ts +1 -2
- package/dist/publish-file-failure.d.ts +0 -1
- package/dist/publish-file.d.ts +0 -2
- package/dist/publish-file.js +1 -2
- 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-directory.js +1 -2
- 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 +1 -3
- 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 +3 -4
- package/dist/replace-file.js +1 -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-context.js +3 -7
- package/dist/root-create-input.d.ts +1 -2
- package/dist/root-directory-creation.d.ts +1 -2
- package/dist/root-directory-creation.js +1 -1
- package/dist/root-directory-list.d.ts +0 -1
- package/dist/root-directory-list.js +3 -7
- package/dist/root-directory.d.ts +0 -1
- package/dist/root-entries.d.ts +0 -1
- package/dist/root-entries.js +2 -2
- package/dist/root-errors.d.ts +4 -1
- package/dist/root-errors.js +5 -3
- 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 -15
- package/dist/root-impl.js +136 -112
- package/dist/root-move-noreplace.d.ts +0 -1
- package/dist/root-move-noreplace.js +4 -10
- package/dist/root-move-preflight.d.ts +0 -1
- package/dist/root-observed-path.d.ts +0 -1
- package/dist/root-observed-path.js +2 -4
- package/dist/root-options.d.ts +1 -2
- package/dist/root-path-errors.d.ts +0 -1
- package/dist/root-path-existing.d.ts +3 -1
- package/dist/root-path-existing.js +38 -18
- package/dist/root-path-observation.d.ts +0 -1
- package/dist/root-path-stat.d.ts +0 -1
- package/dist/root-path-stat.js +2 -4
- 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-public-types.d.ts +11 -0
- 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-identity.js +2 -4
- package/dist/root-remove-receipt.d.ts +0 -1
- package/dist/root-remove.d.ts +0 -1
- package/dist/root-remove.js +2 -4
- package/dist/root-symlink-policy.d.ts +0 -1
- package/dist/root-walk.d.ts +0 -1
- package/dist/root-write-admission.d.ts +1 -2
- package/dist/root-write-admission.js +3 -7
- package/dist/root-write-compatibility.d.ts +0 -1
- package/dist/root-write-complete-parent.d.ts +0 -1
- package/dist/root-write-complete-parent.js +2 -3
- 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 +1 -2
- package/dist/root.d.ts +2 -7
- 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 -18
- 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/secure-temp-repair.js +5 -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 +37 -61
- 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 +4 -1
- package/dist/sidecar-lock-policy.js +23 -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-stale-admission.js +2 -6
- package/dist/sidecar-lock-target.d.ts +0 -1
- package/dist/sidecar-lock-types.d.ts +22 -17
- 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/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 +1 -7
- package/dist/temp-workspace-child-admission.d.ts +16 -6
- package/dist/temp-workspace-child-admission.js +71 -15
- package/dist/temp-workspace-descriptor.d.ts +1 -7
- package/dist/temp-workspace-descriptor.js +1 -4
- package/dist/temp-workspace-owner.d.ts +1 -1
- package/dist/temp-workspace-owner.js +45 -22
- 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/text-atomic.js +1 -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 +5 -2
- package/dist/windows-path-alias.d.ts +1 -1
- package/dist/windows-path-alias.js +12 -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/advanced.md +3 -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 +8 -0
- package/docs/sidecar-lock.md +4 -0
- package/docs/store.md +6 -0
- package/docs/temp.md +8 -1
- package/docs/writing.md +14 -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 +0 -22
- package/dist/archive-native.d.ts.map +0 -1
- package/dist/archive-native.js +0 -98
- package/dist/archive-options.d.ts +0 -25
- 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 +0 -22
- package/dist/archive-policy.d.ts.map +0 -1
- package/dist/archive-policy.js +0 -38
- 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 +0 -7
- package/dist/archive-tar-inspect.d.ts.map +0 -1
- package/dist/archive-tar-inspect.js +0 -62
- 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 +0 -19
- package/dist/archive-tar.d.ts.map +0 -1
- package/dist/archive-tar.js +0 -21
- 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 +0 -20
- package/dist/create-directory.d.ts.map +0 -1
- package/dist/create-directory.js +0 -130
- package/dist/create-file-async.d.ts +0 -7
- package/dist/create-file-async.d.ts.map +0 -1
- package/dist/create-file-async.js +0 -121
- package/dist/create-file.d.ts +0 -8
- package/dist/create-file.d.ts.map +0 -1
- package/dist/create-file.js +0 -190
- package/dist/create-owned-file.d.ts.map +0 -1
- package/dist/create.d.ts.map +0 -1
- package/dist/creation-darwin.d.ts +0 -6
- package/dist/creation-darwin.d.ts.map +0 -1
- package/dist/creation-darwin.js +0 -70
- package/dist/creation-file-state.d.ts +0 -19
- package/dist/creation-file-state.d.ts.map +0 -1
- package/dist/creation-file-state.js +0 -118
- package/dist/creation-path.d.ts +0 -21
- package/dist/creation-path.d.ts.map +0 -1
- package/dist/creation-path.js +0 -71
- package/dist/creation-permissions.d.ts +0 -19
- package/dist/creation-permissions.d.ts.map +0 -1
- package/dist/creation-permissions.js +0 -125
- 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 +0 -5
- package/dist/file-store-copy-source.d.ts.map +0 -1
- package/dist/file-store-copy-source.js +0 -31
- package/dist/file-store-limit.d.ts +0 -2
- package/dist/file-store-limit.d.ts.map +0 -1
- package/dist/file-store-limit.js +0 -8
- package/dist/file-store-path.d.ts +0 -3
- package/dist/file-store-path.d.ts.map +0 -1
- package/dist/file-store-path.js +0 -30
- 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 +0 -2
- package/dist/standalone-publication-path.d.ts.map +0 -1
- package/dist/standalone-publication-path.js +0 -6
- 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 +0 -15
- package/dist/temp-workspace-identity.d.ts.map +0 -1
- package/dist/temp-workspace-identity.js +0 -41
- package/dist/temp-workspace-owner.d.ts.map +0 -1
- package/dist/temp-workspace-permissions.d.ts +0 -4
- package/dist/temp-workspace-permissions.d.ts.map +0 -1
- package/dist/temp-workspace-permissions.js +0 -32
- package/dist/temp-workspace-types.d.ts.map +0 -1
- package/dist/temp.d.ts.map +0 -1
- package/dist/test-hooks.d.ts.map +0 -1
- package/dist/text-atomic.d.ts.map +0 -1
- package/dist/timing.d.ts.map +0 -1
- package/dist/trash.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/unicode-path.d.ts.map +0 -1
- package/dist/walk.d.ts.map +0 -1
- package/dist/windows-command.d.ts.map +0 -1
- package/dist/windows-owner.d.ts.map +0 -1
- package/dist/windows-path-alias.d.ts.map +0 -1
- package/dist/windows-security-command.d.ts.map +0 -1
- package/dist/windows-security-facts.d.ts.map +0 -1
- package/dist/write-file-handle.d.ts.map +0 -1
- package/dist/write-open-flags.d.ts.map +0 -1
- package/dist/write-queue.d.ts.map +0 -1
- /package/dist/{archive-options.js → root-public-types.js} +0 -0
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import { defaultSyncShouldReclaim
|
|
2
|
+
import { defaultSyncShouldReclaim } from "./file-lock-sync-admission.js";
|
|
3
3
|
import { parseSidecarLockSnapshot, readSidecarLockRawSnapshotSync, removeSidecarLockIfUnchangedSync, } from "./sidecar-lock-reclaim.js";
|
|
4
4
|
import { assertSynchronousCallbackResult } from "./mutation-authority.js";
|
|
5
|
+
import { sidecarLockStale } from "./sidecar-lock-policy.js";
|
|
5
6
|
/** Handle one exclusive-create conflict without surrendering canonical admission. */
|
|
6
|
-
export function handleSyncStaleAdmission(params) {
|
|
7
|
+
export function handleSyncStaleAdmission(acquisition, params) {
|
|
7
8
|
const holderChanged = {};
|
|
8
9
|
const assertUnheld = () => {
|
|
9
|
-
|
|
10
|
-
throw syncLockTimeout(params.lockPath, params.normalizedTargetPath);
|
|
11
|
-
}
|
|
10
|
+
acquisition.assert();
|
|
12
11
|
if (params.currentHeld())
|
|
13
12
|
throw holderChanged;
|
|
14
13
|
};
|
|
15
14
|
const retryHolderChange = (error) => {
|
|
16
15
|
if (error !== holderChanged)
|
|
17
16
|
return false;
|
|
18
|
-
|
|
17
|
+
acquisition.waitForRetry();
|
|
19
18
|
return true;
|
|
20
19
|
};
|
|
21
20
|
let rawSnapshot;
|
|
22
21
|
let lockFileOpenDenied = false;
|
|
23
22
|
try {
|
|
24
|
-
rawSnapshot = readSidecarLockRawSnapshotSync(
|
|
23
|
+
rawSnapshot = readSidecarLockRawSnapshotSync(acquisition.lockPath, {
|
|
25
24
|
rejectNonFile: true,
|
|
26
25
|
onOpenFailure: (error) => {
|
|
27
26
|
lockFileOpenDenied = true;
|
|
@@ -41,7 +40,7 @@ export function handleSyncStaleAdmission(params) {
|
|
|
41
40
|
return;
|
|
42
41
|
throw boundaryError;
|
|
43
42
|
}
|
|
44
|
-
if (lockFileOpenDenied &&
|
|
43
|
+
if (lockFileOpenDenied && acquisition.retryDenial(error))
|
|
45
44
|
return;
|
|
46
45
|
throw error;
|
|
47
46
|
}
|
|
@@ -93,7 +92,7 @@ export function handleSyncStaleAdmission(params) {
|
|
|
93
92
|
throw error;
|
|
94
93
|
}
|
|
95
94
|
if (!snapshot) {
|
|
96
|
-
|
|
95
|
+
acquisition.waitForRetry();
|
|
97
96
|
return;
|
|
98
97
|
}
|
|
99
98
|
const nowMs = Date.now();
|
|
@@ -103,8 +102,8 @@ export function handleSyncStaleAdmission(params) {
|
|
|
103
102
|
try {
|
|
104
103
|
reclaim = stale.shouldReclaim
|
|
105
104
|
? Reflect.apply(stale.shouldReclaim, params.options, [{
|
|
106
|
-
lockPath:
|
|
107
|
-
normalizedTargetPath:
|
|
105
|
+
lockPath: acquisition.lockPath,
|
|
106
|
+
normalizedTargetPath: acquisition.normalizedTargetPath,
|
|
108
107
|
payload: snapshot.payload,
|
|
109
108
|
staleMs: params.staleMs,
|
|
110
109
|
nowMs,
|
|
@@ -123,7 +122,7 @@ export function handleSyncStaleAdmission(params) {
|
|
|
123
122
|
throw error;
|
|
124
123
|
}
|
|
125
124
|
if (!reclaim) {
|
|
126
|
-
|
|
125
|
+
acquisition.waitForRetry();
|
|
127
126
|
return;
|
|
128
127
|
}
|
|
129
128
|
if (params.staleRecovery === "remove-if-unchanged" &&
|
|
@@ -134,8 +133,8 @@ export function handleSyncStaleAdmission(params) {
|
|
|
134
133
|
assertUnheld();
|
|
135
134
|
try {
|
|
136
135
|
approved = Reflect.apply(stale.shouldRemove, params.options, [{
|
|
137
|
-
lockPath:
|
|
138
|
-
normalizedTargetPath:
|
|
136
|
+
lockPath: acquisition.lockPath,
|
|
137
|
+
normalizedTargetPath: acquisition.normalizedTargetPath,
|
|
139
138
|
raw: snapshot.raw,
|
|
140
139
|
payload: snapshot.payload,
|
|
141
140
|
}]);
|
|
@@ -151,11 +150,7 @@ export function handleSyncStaleAdmission(params) {
|
|
|
151
150
|
throw error;
|
|
152
151
|
}
|
|
153
152
|
if (!approved) {
|
|
154
|
-
throw
|
|
155
|
-
code: "file_lock_stale",
|
|
156
|
-
lockPath: params.lockPath,
|
|
157
|
-
normalizedTargetPath: params.normalizedTargetPath,
|
|
158
|
-
});
|
|
153
|
+
throw sidecarLockStale(acquisition.lockPath, acquisition.normalizedTargetPath);
|
|
159
154
|
}
|
|
160
155
|
try {
|
|
161
156
|
fs.mkdirSync(params.reclaimGuardPath);
|
|
@@ -170,7 +165,7 @@ export function handleSyncStaleAdmission(params) {
|
|
|
170
165
|
throw boundaryError;
|
|
171
166
|
}
|
|
172
167
|
if (error.code === "EEXIST") {
|
|
173
|
-
|
|
168
|
+
acquisition.waitForRetry();
|
|
174
169
|
return;
|
|
175
170
|
}
|
|
176
171
|
throw error;
|
|
@@ -178,7 +173,7 @@ export function handleSyncStaleAdmission(params) {
|
|
|
178
173
|
let holderInterrupted = false;
|
|
179
174
|
try {
|
|
180
175
|
assertUnheld();
|
|
181
|
-
if (removeSidecarLockIfUnchangedSync(
|
|
176
|
+
if (removeSidecarLockIfUnchangedSync(acquisition.lockPath, snapshot, assertUnheld))
|
|
182
177
|
return;
|
|
183
178
|
}
|
|
184
179
|
catch (error) {
|
|
@@ -196,13 +191,9 @@ export function handleSyncStaleAdmission(params) {
|
|
|
196
191
|
}
|
|
197
192
|
}
|
|
198
193
|
if (holderInterrupted) {
|
|
199
|
-
|
|
194
|
+
acquisition.waitForRetry();
|
|
200
195
|
return;
|
|
201
196
|
}
|
|
202
197
|
}
|
|
203
|
-
throw
|
|
204
|
-
code: "file_lock_stale",
|
|
205
|
-
lockPath: params.lockPath,
|
|
206
|
-
normalizedTargetPath: params.normalizedTargetPath,
|
|
207
|
-
});
|
|
198
|
+
throw sidecarLockStale(acquisition.lockPath, acquisition.normalizedTargetPath);
|
|
208
199
|
}
|
package/dist/file-lock-sync.d.ts
CHANGED
|
@@ -1,28 +1,11 @@
|
|
|
1
|
-
import type { Root } from "./root-impl.js";
|
|
2
1
|
import { type SidecarLockStaleSnapshot } from "./sidecar-lock-reclaim.js";
|
|
3
|
-
import type {
|
|
4
|
-
export type FileLockSyncAcquireOptions<TPayload extends Record<string, unknown>> = {
|
|
5
|
-
lockPath?: string;
|
|
2
|
+
import type { SidecarLockCommonAcquireOptions, SidecarLockOptionFields, SidecarLockReclaimParams } from "./sidecar-lock-types.js";
|
|
3
|
+
export type FileLockSyncAcquireOptions<TPayload extends Record<string, unknown>> = SidecarLockOptionFields<SidecarLockCommonAcquireOptions & {
|
|
6
4
|
staleMs?: number;
|
|
7
|
-
timeoutMs?: number;
|
|
8
|
-
retry?: SidecarLockRetryOptions;
|
|
9
|
-
staleRecovery?: SidecarLockStaleRecovery;
|
|
10
|
-
reentrantOwner?: string;
|
|
11
5
|
payload: () => TPayload;
|
|
12
|
-
shouldReclaim?: (params:
|
|
13
|
-
lockPath: string;
|
|
14
|
-
normalizedTargetPath: string;
|
|
15
|
-
payload: unknown;
|
|
16
|
-
staleMs: number;
|
|
17
|
-
nowMs: number;
|
|
18
|
-
heldByThisProcess: false;
|
|
19
|
-
}) => boolean;
|
|
6
|
+
shouldReclaim?: (params: SidecarLockReclaimParams<false>) => boolean;
|
|
20
7
|
shouldRemoveStaleLock?: (snapshot: SidecarLockStaleSnapshot) => boolean;
|
|
21
|
-
|
|
22
|
-
lockRoot?: Root;
|
|
23
|
-
onCompromised?: (info: SidecarLockCompromisedInfo) => void;
|
|
24
|
-
compromiseCheckIntervalMs?: number;
|
|
25
|
-
};
|
|
8
|
+
}>;
|
|
26
9
|
export type FileLockSyncHandle = {
|
|
27
10
|
lockPath: string;
|
|
28
11
|
normalizedTargetPath: string;
|
|
@@ -32,4 +15,3 @@ export type FileLockSyncHandle = {
|
|
|
32
15
|
};
|
|
33
16
|
export declare function acquireFileLockSync<TPayload extends Record<string, unknown>>(targetPath: string, options: FileLockSyncAcquireOptions<TPayload>): FileLockSyncHandle;
|
|
34
17
|
export declare function withFileLockSync<T, TPayload extends Record<string, unknown>>(targetPath: string, options: FileLockSyncAcquireOptions<TPayload>, fn: () => T): T;
|
|
35
|
-
//# sourceMappingURL=file-lock-sync.d.ts.map
|
package/dist/file-lock-sync.js
CHANGED
|
@@ -3,14 +3,14 @@ import { acquireFileLockSyncWithRoot } from "./file-lock-sync-root-acquire.js";
|
|
|
3
3
|
import { withSyncHeldLockHandle } from "./file-lock-sync-root-held.js";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { readSidecarLockRawSnapshotSync, readSidecarLockSnapshotSync, removeSidecarLockIfUnchangedSync, serializeSidecarLockPayload, sidecarLockSnapshotMatches, } from "./sidecar-lock-reclaim.js";
|
|
6
|
-
import {
|
|
6
|
+
import { sidecarLockTimeout, isTransientLockFileDenial, validateSidecarLockStaleMs, validateSidecarLockCompromiseCheckIntervalMs, validateSidecarLockRetryOptions, validateSidecarLockTimeoutMs, } from "./sidecar-lock-policy.js";
|
|
7
7
|
import { getFsSafeLockConfig } from "./lock-config.js";
|
|
8
|
-
import {
|
|
8
|
+
import { SyncLockAcquisition } from "./file-lock-sync-acquisition.js";
|
|
9
9
|
import { assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
10
10
|
import { realpathSync } from "./realpath.js";
|
|
11
11
|
import { recursiveMkdirPath } from "./recursive-mkdir-path.js";
|
|
12
12
|
import { createSuppressedError } from "./suppressed-error.js";
|
|
13
|
-
import { ensureSyncLockExitCleanupRegistered, getSyncHeldLocks, foreignSyncHeldLock, getSyncLockAdmissions, syncReclaimGuardExists,
|
|
13
|
+
import { ensureSyncLockExitCleanupRegistered, getSyncHeldLocks, foreignSyncHeldLock, getSyncLockAdmissions, syncReclaimGuardExists, } from "./file-lock-sync-admission.js";
|
|
14
14
|
import { handleSyncStaleAdmission, } from "./file-lock-sync-stale-admission.js";
|
|
15
15
|
function releaseAllSyncHeldLocks() {
|
|
16
16
|
const heldLocks = getSyncHeldLocks();
|
|
@@ -135,15 +135,7 @@ export function acquireFileLockSync(targetPath, options) {
|
|
|
135
135
|
initiallyHeld.refCount += 1;
|
|
136
136
|
return createSyncHeldLockHandle(initiallyHeld);
|
|
137
137
|
}
|
|
138
|
-
const
|
|
139
|
-
const admissionToken = {};
|
|
140
|
-
let ownsAdmission = false;
|
|
141
|
-
const hasAdmissionToken = () => admissions.get(normalizedTargetPath) === admissionToken;
|
|
142
|
-
const releaseAdmission = () => {
|
|
143
|
-
if (ownsAdmission && hasAdmissionToken())
|
|
144
|
-
admissions.delete(normalizedTargetPath);
|
|
145
|
-
ownsAdmission = false;
|
|
146
|
-
};
|
|
138
|
+
const acquisition = new SyncLockAcquisition(lockPath, normalizedTargetPath, retry, timeoutMs);
|
|
147
139
|
let payloadCallback;
|
|
148
140
|
let onCompromised = undefined;
|
|
149
141
|
let onCompromisedObserved = false;
|
|
@@ -152,54 +144,10 @@ export function acquireFileLockSync(targetPath, options) {
|
|
|
152
144
|
let staleRecovery = undefined;
|
|
153
145
|
let staleRecoveryObserved = false;
|
|
154
146
|
const staleOptions = {};
|
|
155
|
-
const startedAt = Date.now();
|
|
156
|
-
let attempt = 0;
|
|
157
|
-
let transientDenials = 0;
|
|
158
147
|
const reclaimGuardPath = `${lockPath}.reclaim`;
|
|
159
|
-
const waitForRetry = () => {
|
|
160
|
-
releaseAdmission();
|
|
161
|
-
const elapsed = Date.now() - startedAt;
|
|
162
|
-
const timedOut = timeoutMs !== undefined && elapsed >= timeoutMs;
|
|
163
|
-
if (timedOut || (retry.retries !== undefined && attempt >= retry.retries)) {
|
|
164
|
-
throw syncLockTimeout(lockPath, normalizedTargetPath);
|
|
165
|
-
}
|
|
166
|
-
const remaining = timeoutMs === undefined || timeoutMs === Number.POSITIVE_INFINITY
|
|
167
|
-
? Number.POSITIVE_INFINITY
|
|
168
|
-
: Math.max(0, timeoutMs - elapsed);
|
|
169
|
-
sleepSync(Math.min(computeSidecarLockDelayMs(retry, attempt), remaining));
|
|
170
|
-
attempt += 1;
|
|
171
|
-
};
|
|
172
|
-
const retryLockFileDenial = (error) => {
|
|
173
|
-
if (!isTransientLockFileDenial(error, lockPath) ||
|
|
174
|
-
++transientDenials > maxTransientLockDenials)
|
|
175
|
-
return false;
|
|
176
|
-
try {
|
|
177
|
-
waitForRetry();
|
|
178
|
-
}
|
|
179
|
-
catch (waitError) {
|
|
180
|
-
// Preserve the filesystem diagnosis when the caller's budget runs out.
|
|
181
|
-
if (waitError.code === "file_lock_timeout")
|
|
182
|
-
throw error;
|
|
183
|
-
throw waitError;
|
|
184
|
-
}
|
|
185
|
-
return true;
|
|
186
|
-
};
|
|
187
|
-
const assertAdmissionToken = () => {
|
|
188
|
-
if (!hasAdmissionToken())
|
|
189
|
-
throw syncLockTimeout(lockPath, normalizedTargetPath);
|
|
190
|
-
};
|
|
191
|
-
const runAdmissionBoundary = (callback) => {
|
|
192
|
-
assertAdmissionToken();
|
|
193
|
-
try {
|
|
194
|
-
return callback();
|
|
195
|
-
}
|
|
196
|
-
finally {
|
|
197
|
-
assertAdmissionToken();
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
148
|
try {
|
|
201
149
|
while (true) {
|
|
202
|
-
if (!
|
|
150
|
+
if (!acquisition.owns) {
|
|
203
151
|
const held = heldLocks.get(normalizedTargetPath);
|
|
204
152
|
if (held && !foreignSyncHeldLock("raw", normalizedTargetPath) &&
|
|
205
153
|
requestedReentrantOwner !== undefined &&
|
|
@@ -208,12 +156,7 @@ export function acquireFileLockSync(targetPath, options) {
|
|
|
208
156
|
held.refCount += 1;
|
|
209
157
|
return createSyncHeldLockHandle(held);
|
|
210
158
|
}
|
|
211
|
-
|
|
212
|
-
// The owner can only finish after this synchronous callback unwinds.
|
|
213
|
-
throw syncLockTimeout(lockPath, normalizedTargetPath);
|
|
214
|
-
}
|
|
215
|
-
admissions.set(normalizedTargetPath, admissionToken);
|
|
216
|
-
ownsAdmission = true;
|
|
159
|
+
acquisition.reserve();
|
|
217
160
|
}
|
|
218
161
|
const attemptHeld = currentTargetHolder();
|
|
219
162
|
const holderWasReplaced = () => {
|
|
@@ -221,60 +164,60 @@ export function acquireFileLockSync(targetPath, options) {
|
|
|
221
164
|
return current !== undefined && current !== attemptHeld;
|
|
222
165
|
};
|
|
223
166
|
if (!staleRecoveryObserved) {
|
|
224
|
-
staleRecovery =
|
|
167
|
+
staleRecovery = acquisition.run(() => options.staleRecovery ?? defaults.staleRecovery);
|
|
225
168
|
staleRecoveryObserved = true;
|
|
226
169
|
if (holderWasReplaced()) {
|
|
227
|
-
waitForRetry();
|
|
170
|
+
acquisition.waitForRetry();
|
|
228
171
|
continue;
|
|
229
172
|
}
|
|
230
173
|
}
|
|
231
174
|
const reclaimGuardExists = syncReclaimGuardExists(reclaimGuardPath);
|
|
232
|
-
if (!
|
|
233
|
-
throw
|
|
175
|
+
if (!acquisition.hasToken())
|
|
176
|
+
throw sidecarLockTimeout(lockPath, normalizedTargetPath);
|
|
234
177
|
if (holderWasReplaced()) {
|
|
235
|
-
waitForRetry();
|
|
178
|
+
acquisition.waitForRetry();
|
|
236
179
|
continue;
|
|
237
180
|
}
|
|
238
181
|
if (reclaimGuardExists) {
|
|
239
|
-
waitForRetry();
|
|
182
|
+
acquisition.waitForRetry();
|
|
240
183
|
continue;
|
|
241
184
|
}
|
|
242
185
|
let fd;
|
|
243
186
|
let createdHeld;
|
|
244
187
|
let createdSnapshot;
|
|
245
188
|
if (!payloadCallback)
|
|
246
|
-
payloadCallback =
|
|
189
|
+
payloadCallback = acquisition.run(() => options.payload);
|
|
247
190
|
if (holderWasReplaced()) {
|
|
248
|
-
waitForRetry();
|
|
191
|
+
acquisition.waitForRetry();
|
|
249
192
|
continue;
|
|
250
193
|
}
|
|
251
|
-
const payload =
|
|
194
|
+
const payload = acquisition.run(() => Reflect.apply(payloadCallback, options, []));
|
|
252
195
|
if (holderWasReplaced()) {
|
|
253
|
-
waitForRetry();
|
|
196
|
+
acquisition.waitForRetry();
|
|
254
197
|
continue;
|
|
255
198
|
}
|
|
256
|
-
const { raw, ownershipToken } =
|
|
199
|
+
const { raw, ownershipToken } = acquisition.run(() => serializeSidecarLockPayload(payload));
|
|
257
200
|
if (holderWasReplaced()) {
|
|
258
|
-
waitForRetry();
|
|
201
|
+
acquisition.waitForRetry();
|
|
259
202
|
continue;
|
|
260
203
|
}
|
|
261
204
|
if (currentTargetHolder() !== undefined) {
|
|
262
|
-
waitForRetry();
|
|
205
|
+
acquisition.waitForRetry();
|
|
263
206
|
continue;
|
|
264
207
|
}
|
|
265
208
|
if (!onCompromisedObserved) {
|
|
266
|
-
onCompromised =
|
|
209
|
+
onCompromised = acquisition.run(() => options.onCompromised);
|
|
267
210
|
onCompromisedObserved = true;
|
|
268
211
|
if (currentTargetHolder() !== undefined) {
|
|
269
|
-
waitForRetry();
|
|
212
|
+
acquisition.waitForRetry();
|
|
270
213
|
continue;
|
|
271
214
|
}
|
|
272
215
|
}
|
|
273
216
|
if (!parsePayloadObserved) {
|
|
274
|
-
parsePayload =
|
|
217
|
+
parsePayload = acquisition.run(() => options.parsePayload);
|
|
275
218
|
parsePayloadObserved = true;
|
|
276
219
|
if (currentTargetHolder() !== undefined) {
|
|
277
|
-
waitForRetry();
|
|
220
|
+
acquisition.waitForRetry();
|
|
278
221
|
continue;
|
|
279
222
|
}
|
|
280
223
|
}
|
|
@@ -311,34 +254,17 @@ export function acquireFileLockSync(targetPath, options) {
|
|
|
311
254
|
};
|
|
312
255
|
const candidateHeld = createdHeld;
|
|
313
256
|
ensureSyncLockExitCleanupRegistered(releaseAllSyncHeldLocks, lockPath, normalizedTargetPath);
|
|
314
|
-
if (!
|
|
315
|
-
throw
|
|
257
|
+
if (!acquisition.hasToken() || currentTargetHolder() !== undefined) {
|
|
258
|
+
throw sidecarLockTimeout(lockPath, normalizedTargetPath);
|
|
316
259
|
}
|
|
317
260
|
const returnedHandle = createSyncHeldLockHandle(candidateHeld);
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
candidateHeld.timer = setInterval(() => {
|
|
321
|
-
let stillHeld;
|
|
322
|
-
try {
|
|
323
|
-
stillHeld = returnedHandle.verifyStillHeld();
|
|
324
|
-
}
|
|
325
|
-
catch {
|
|
326
|
-
stillHeld = false;
|
|
327
|
-
}
|
|
328
|
-
if (!stillHeld && candidateHeld.timer) {
|
|
329
|
-
clearInterval(candidateHeld.timer);
|
|
330
|
-
candidateHeld.timer = undefined;
|
|
331
|
-
Reflect.apply(compromisedCallback, options, [{ lockPath, normalizedTargetPath }]);
|
|
332
|
-
}
|
|
333
|
-
}, compromiseCheckIntervalMs);
|
|
334
|
-
candidateHeld.timer.unref();
|
|
335
|
-
}
|
|
336
|
-
if (!hasAdmissionToken() ||
|
|
261
|
+
acquisition.monitor(candidateHeld, returnedHandle, onCompromised, compromiseCheckIntervalMs, options);
|
|
262
|
+
if (!acquisition.hasToken() ||
|
|
337
263
|
currentTargetHolder() !== undefined) {
|
|
338
|
-
throw
|
|
264
|
+
throw sidecarLockTimeout(lockPath, normalizedTargetPath);
|
|
339
265
|
}
|
|
340
266
|
heldLocks.set(normalizedTargetPath, candidateHeld);
|
|
341
|
-
|
|
267
|
+
acquisition.release();
|
|
342
268
|
fd = undefined;
|
|
343
269
|
return returnedHandle;
|
|
344
270
|
}
|
|
@@ -374,44 +300,39 @@ export function acquireFileLockSync(targetPath, options) {
|
|
|
374
300
|
}
|
|
375
301
|
}
|
|
376
302
|
if (lockFileCreateDenied) {
|
|
377
|
-
if (!
|
|
378
|
-
throw
|
|
303
|
+
if (!acquisition.hasToken())
|
|
304
|
+
throw sidecarLockTimeout(lockPath, normalizedTargetPath);
|
|
379
305
|
if (currentTargetHolder() !== undefined) {
|
|
380
|
-
waitForRetry();
|
|
306
|
+
acquisition.waitForRetry();
|
|
381
307
|
continue;
|
|
382
308
|
}
|
|
383
|
-
if (
|
|
309
|
+
if (acquisition.retryDenial(error))
|
|
384
310
|
continue;
|
|
385
311
|
throw error;
|
|
386
312
|
}
|
|
387
313
|
if (!exclusiveCreateConflict)
|
|
388
314
|
throw error;
|
|
389
|
-
if (!
|
|
390
|
-
throw
|
|
315
|
+
if (!acquisition.hasToken())
|
|
316
|
+
throw sidecarLockTimeout(lockPath, normalizedTargetPath);
|
|
391
317
|
if (currentTargetHolder() !== undefined) {
|
|
392
|
-
waitForRetry();
|
|
318
|
+
acquisition.waitForRetry();
|
|
393
319
|
continue;
|
|
394
320
|
}
|
|
395
|
-
handleSyncStaleAdmission({
|
|
396
|
-
hasToken: hasAdmissionToken,
|
|
321
|
+
handleSyncStaleAdmission(acquisition, {
|
|
397
322
|
currentHeld: currentTargetHolder,
|
|
398
|
-
lockPath,
|
|
399
|
-
normalizedTargetPath,
|
|
400
323
|
options,
|
|
401
324
|
parsePayload,
|
|
402
325
|
reclaimGuardPath,
|
|
403
|
-
retryLockFileDenial,
|
|
404
326
|
staleMs,
|
|
405
327
|
staleOptions,
|
|
406
328
|
staleRecovery,
|
|
407
|
-
waitForRetry,
|
|
408
329
|
});
|
|
409
330
|
continue;
|
|
410
331
|
}
|
|
411
332
|
}
|
|
412
333
|
}
|
|
413
334
|
finally {
|
|
414
|
-
|
|
335
|
+
acquisition.release();
|
|
415
336
|
}
|
|
416
337
|
}
|
|
417
338
|
export function withFileLockSync(targetPath, options, fn) {
|
package/dist/file-lock.d.ts
CHANGED
|
@@ -21,4 +21,3 @@ export declare function withFileLock<T, TPayload extends Record<string, unknown>
|
|
|
21
21
|
export declare function createFileLockManager(key: string): FileLockManager;
|
|
22
22
|
export declare function drainFileLockManagerForTest(targetPath: string, managerKey?: string): Promise<void>;
|
|
23
23
|
export declare function resetFileLockManagerForTest(targetPath: string, managerKey?: string): void;
|
|
24
|
-
//# sourceMappingURL=file-lock.d.ts.map
|
|
@@ -18,7 +18,6 @@ export declare function writeStreamToTempSource(params: {
|
|
|
18
18
|
path: string;
|
|
19
19
|
cleanup: () => Promise<void>;
|
|
20
20
|
}>;
|
|
21
|
-
export declare function assertSyncDirectoryGuard(guard: SyncParentGuard): void;
|
|
22
21
|
export declare function ensureParentSync(params: {
|
|
23
22
|
rootDir: string;
|
|
24
23
|
filePath: string;
|
|
@@ -30,4 +29,10 @@ export declare function ensureStoreDirectorySync(params: {
|
|
|
30
29
|
mode: number;
|
|
31
30
|
messagePrefix: "private store" | "store";
|
|
32
31
|
}): SyncParentGuard;
|
|
33
|
-
|
|
32
|
+
export declare function assertRelativePath(relativePath: string): string;
|
|
33
|
+
export declare function resolveStorePath(rootDir: string, relativePath: string): string;
|
|
34
|
+
export declare function assertFileStoreMaxBytes(size: number, limit: number | undefined): void;
|
|
35
|
+
export declare function readFileStoreCopySource(params: {
|
|
36
|
+
sourcePath: string;
|
|
37
|
+
maxBytes: number;
|
|
38
|
+
}): Promise<Buffer>;
|
|
@@ -2,25 +2,22 @@ import syncFs from "node:fs";
|
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { createByteLimitTransform } from "./bounded-read-stream.js";
|
|
5
|
-
import { normalizeMaxBytes } from "./byte-budget.js";
|
|
6
5
|
import { pipeline } from "node:stream/promises";
|
|
7
6
|
import { FsSafeError } from "./errors.js";
|
|
8
7
|
import { assertSyncStoreDirectoryReceipt, ensureSyncStoreDirectory, } from "./file-store-sync-directory.js";
|
|
9
|
-
import { isPathInside } from "./path.js";
|
|
8
|
+
import { isPathInside, splitSafeRelativePath } from "./path.js";
|
|
10
9
|
import { resolveOpenedFileRealPathForHandle, root } from "./root.js";
|
|
11
10
|
import { ensureTrailingSep } from "./root-context.js";
|
|
12
11
|
import { RootHandle } from "./root-impl.js";
|
|
13
12
|
import { prepareSecretFileWrite } from "./secret-file.js";
|
|
14
13
|
import { resolveSecureTempRoot } from "./secure-temp-dir.js";
|
|
15
14
|
import { recursiveMkdirPath } from "./recursive-mkdir-path.js";
|
|
15
|
+
import { readRegularFile } from "./regular-file.js";
|
|
16
|
+
import { errorCauseOptions } from "./root-errors.js";
|
|
16
17
|
import { assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
17
|
-
function parentRelativePath(relativePath) {
|
|
18
|
-
const parent = path.posix.dirname(relativePath);
|
|
19
|
-
return parent === "." ? "" : parent;
|
|
20
|
-
}
|
|
21
18
|
export async function ensureParentInRoot(scopedRoot, relativePath, mode) {
|
|
22
|
-
const parent =
|
|
23
|
-
if (
|
|
19
|
+
const parent = path.posix.dirname(relativePath);
|
|
20
|
+
if (parent === ".") {
|
|
24
21
|
return;
|
|
25
22
|
}
|
|
26
23
|
await scopedRoot.mkdir(parent);
|
|
@@ -28,10 +25,9 @@ export async function ensureParentInRoot(scopedRoot, relativePath, mode) {
|
|
|
28
25
|
}
|
|
29
26
|
export async function openWritableStoreRoot(params) {
|
|
30
27
|
assertNoWindowsPathAlias(params.rootDir, "filesystem", "store root uses a Windows filesystem namespace alias");
|
|
31
|
-
const maxBytes = normalizeMaxBytes(params.maxBytes);
|
|
32
28
|
await fs.mkdir(recursiveMkdirPath(params.rootDir), { recursive: true, mode: params.dirMode });
|
|
33
29
|
await fs.chmod(params.rootDir, params.dirMode).catch(() => undefined);
|
|
34
|
-
return await root(params.rootDir, { hardlinks: "reject", maxBytes });
|
|
30
|
+
return await root(params.rootDir, { hardlinks: "reject", maxBytes: params.maxBytes });
|
|
35
31
|
}
|
|
36
32
|
export async function openPrivateStoreLockRoot(params) {
|
|
37
33
|
const { parentGuard } = await prepareSecretFileWrite(params);
|
|
@@ -66,15 +62,8 @@ async function chmodDirectoryInRootBestEffort(scopedRoot, relativePath, mode) {
|
|
|
66
62
|
await handle.close().catch(() => undefined);
|
|
67
63
|
}
|
|
68
64
|
}
|
|
69
|
-
function createMaxBytesTransform(maxBytes) {
|
|
70
|
-
const limit = normalizeMaxBytes(maxBytes);
|
|
71
|
-
if (limit === undefined) {
|
|
72
|
-
return undefined;
|
|
73
|
-
}
|
|
74
|
-
return createByteLimitTransform(limit, () => new FsSafeError("too-large", `file exceeds maximum size of ${limit} bytes`));
|
|
75
|
-
}
|
|
76
65
|
export async function writeStreamToTempSource(params) {
|
|
77
|
-
const maxBytes =
|
|
66
|
+
const maxBytes = params.maxBytes;
|
|
78
67
|
const tempRoot = resolveSecureTempRoot({
|
|
79
68
|
fallbackPrefix: "fs-safe-file-store",
|
|
80
69
|
unsafeFallbackLabel: "file store temp dir",
|
|
@@ -90,7 +79,7 @@ export async function writeStreamToTempSource(params) {
|
|
|
90
79
|
writable.once("close", () => {
|
|
91
80
|
handleClosedByStream = true;
|
|
92
81
|
});
|
|
93
|
-
const limiter =
|
|
82
|
+
const limiter = maxBytes === undefined ? undefined : createByteLimitTransform(maxBytes, () => new FsSafeError("too-large", `file exceeds maximum size of ${maxBytes} bytes`));
|
|
94
83
|
if (limiter) {
|
|
95
84
|
await pipeline(params.stream, limiter, writable);
|
|
96
85
|
}
|
|
@@ -116,13 +105,6 @@ export async function writeStreamToTempSource(params) {
|
|
|
116
105
|
throw err;
|
|
117
106
|
}
|
|
118
107
|
}
|
|
119
|
-
export function assertSyncDirectoryGuard(guard) {
|
|
120
|
-
assertSyncStoreDirectoryReceipt({
|
|
121
|
-
dir: guard.dir,
|
|
122
|
-
realPath: guard.realPath,
|
|
123
|
-
exactStat: guard.exactStat,
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
108
|
export function ensureParentSync(params) {
|
|
127
109
|
assertNoWindowsPathAlias(params.rootDir, "filesystem", "store root uses a Windows filesystem namespace alias");
|
|
128
110
|
assertNoWindowsPathAlias(params.filePath, "filesystem", "store path uses a Windows filesystem namespace alias");
|
|
@@ -135,6 +117,61 @@ export function ensureParentSync(params) {
|
|
|
135
117
|
}
|
|
136
118
|
export function ensureStoreDirectorySync(params) {
|
|
137
119
|
const guard = ensureSyncStoreDirectory(params);
|
|
138
|
-
|
|
120
|
+
assertSyncStoreDirectoryReceipt(guard);
|
|
139
121
|
return guard;
|
|
140
122
|
}
|
|
123
|
+
export function assertRelativePath(relativePath) {
|
|
124
|
+
const raw = relativePath.trim();
|
|
125
|
+
if (!raw || raw !== relativePath) {
|
|
126
|
+
throw new FsSafeError("invalid-path", "store key must be non-empty and unpadded");
|
|
127
|
+
}
|
|
128
|
+
const segments = splitSafeRelativePath(raw);
|
|
129
|
+
if (segments.length === 0 ||
|
|
130
|
+
segments.join("/") !== raw ||
|
|
131
|
+
raw.normalize("NFC") !== raw ||
|
|
132
|
+
segments.some((segment) => /[ .]$/u.test(segment))) {
|
|
133
|
+
throw new FsSafeError("invalid-path", "store key must use one canonical relative spelling");
|
|
134
|
+
}
|
|
135
|
+
return raw;
|
|
136
|
+
}
|
|
137
|
+
export function resolveStorePath(rootDir, relativePath) {
|
|
138
|
+
const key = assertRelativePath(relativePath);
|
|
139
|
+
// FileStore constructors snapshot an absolute root before this helper runs.
|
|
140
|
+
// Do not re-resolve it: Node drops the trailing separator from an exact
|
|
141
|
+
// Windows namespace drive root such as `\\?\C:\`.
|
|
142
|
+
const root = path.isAbsolute(rootDir) ? rootDir : path.resolve(rootDir);
|
|
143
|
+
// The immutable key already passed segment validation; keep the containment check.
|
|
144
|
+
const target = path.resolve(root, key);
|
|
145
|
+
if (!isPathInside(root, target)) {
|
|
146
|
+
throw new FsSafeError("outside-workspace", "relative path escapes root");
|
|
147
|
+
}
|
|
148
|
+
return target;
|
|
149
|
+
}
|
|
150
|
+
// Store operation boundaries admit the primitive limit before reaching this helper.
|
|
151
|
+
export function assertFileStoreMaxBytes(size, limit) {
|
|
152
|
+
if (limit !== undefined && size > limit) {
|
|
153
|
+
throw new FsSafeError("too-large", `file exceeds maximum size of ${limit} bytes`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
export async function readFileStoreCopySource(params) {
|
|
157
|
+
assertNoWindowsPathAlias(params.sourcePath, "filesystem", "source path uses a Windows filesystem namespace alias");
|
|
158
|
+
const sourceStat = syncFs.lstatSync(params.sourcePath);
|
|
159
|
+
if (sourceStat.isSymbolicLink() || !sourceStat.isFile()) {
|
|
160
|
+
throw new FsSafeError("not-file", "source path is not a file");
|
|
161
|
+
}
|
|
162
|
+
assertFileStoreMaxBytes(sourceStat.size, params.maxBytes);
|
|
163
|
+
try {
|
|
164
|
+
return (await readRegularFile({ filePath: params.sourcePath, maxBytes: params.maxBytes }))
|
|
165
|
+
.buffer;
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
169
|
+
if (message.includes("regular file") || message.includes("not a regular file")) {
|
|
170
|
+
throw new FsSafeError("not-file", "source path is not a file", errorCauseOptions(error));
|
|
171
|
+
}
|
|
172
|
+
if (message.includes(`exceeds ${params.maxBytes} bytes`)) {
|
|
173
|
+
throw new FsSafeError("too-large", `file exceeds maximum size of ${params.maxBytes} bytes`, errorCauseOptions(error));
|
|
174
|
+
}
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
}
|