@openclaw/fs-safe 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +91 -0
- package/README.md +8 -1
- package/dist/absolute-path.d.ts +0 -1
- package/dist/absolute-path.js +2 -8
- package/dist/advanced.d.ts +2 -1
- package/dist/advanced.js +2 -0
- package/dist/archive-crc32.d.ts +0 -1
- package/dist/archive-deadline.d.ts +0 -1
- package/dist/archive-deadline.js +22 -23
- package/dist/archive-durability.d.ts +0 -1
- package/dist/archive-entry.d.ts +0 -1
- package/dist/archive-errors.d.ts +0 -1
- package/dist/archive-gzip-tail.d.ts +0 -1
- package/dist/archive-input.d.ts +0 -1
- package/dist/archive-kind.d.ts +0 -1
- package/dist/archive-limits.d.ts +0 -1
- package/dist/archive-merge.d.ts +3 -4
- package/dist/archive-merge.js +17 -7
- package/dist/archive-native.d.ts +3 -14
- package/dist/archive-native.js +46 -70
- package/dist/archive-options.d.ts +9 -2
- package/dist/archive-parser-errors.d.ts +0 -1
- package/dist/archive-parser.wasm +0 -0
- package/dist/archive-plan.d.ts +10 -1
- package/dist/archive-plan.js +31 -21
- package/dist/archive-policy.d.ts +0 -1
- package/dist/archive-read.d.ts +0 -1
- package/dist/archive-staging.d.ts +0 -1
- package/dist/archive-tar-inspect.d.ts +0 -1
- package/dist/archive-tar-stream.d.ts +0 -1
- package/dist/archive-tar-wasm.d.ts +0 -1
- package/dist/archive-tar.d.ts +0 -1
- package/dist/archive-zip-admission.d.ts +0 -1
- package/dist/archive-zip-count.d.ts +0 -1
- package/dist/archive-zip-count.js +21 -1
- package/dist/archive-zip-directory.d.ts +0 -1
- package/dist/archive-zip-directory.js +23 -1
- package/dist/archive-zip-entry.d.ts +0 -1
- package/dist/archive-zip-integrity.d.ts +0 -1
- package/dist/archive-zip-loader.d.ts +2 -1
- package/dist/archive-zip-loader.js +7 -0
- package/dist/archive-zip-manifest.d.ts +0 -1
- package/dist/archive-zip-names.d.ts +0 -1
- package/dist/archive-zip-names.js +7 -2
- package/dist/archive-zip-preflight.d.ts +0 -1
- package/dist/archive.d.ts +0 -1
- package/dist/archive.js +93 -164
- package/dist/async-lock.d.ts +0 -1
- package/dist/atomic.d.ts +0 -1
- package/dist/bounded-read-stream.d.ts +0 -1
- package/dist/bounded-read.d.ts +0 -1
- package/dist/byte-budget.d.ts +0 -1
- package/dist/byte-view.d.ts +2 -0
- package/dist/byte-view.js +13 -0
- package/dist/clone-metadata.d.ts +0 -1
- package/dist/config.d.ts +0 -1
- package/dist/containment.d.ts +0 -1
- package/dist/copy-file-input.d.ts +0 -1
- package/dist/copy-policy.d.ts +0 -1
- package/dist/copy-publication.d.ts +0 -1
- package/dist/copy-tree-portable.d.ts +0 -1
- package/dist/copy-tree-portable.js +9 -6
- package/dist/copy.d.ts +0 -1
- package/dist/copy.js +5 -5
- package/dist/create-directory.d.ts +0 -2
- package/dist/create-directory.js +3 -22
- package/dist/create-file-async.d.ts +0 -1
- package/dist/create-file.d.ts +0 -1
- package/dist/create-file.js +3 -14
- package/dist/create-owned-file.d.ts +0 -1
- package/dist/create.d.ts +1 -2
- package/dist/create.js +1 -1
- package/dist/creation-darwin.d.ts +0 -2
- package/dist/creation-darwin.js +0 -9
- package/dist/creation-file-state.d.ts +0 -1
- package/dist/creation-path.d.ts +2 -1
- package/dist/creation-path.js +12 -0
- package/dist/creation-permissions.d.ts +0 -1
- package/dist/creation-permissions.js +28 -38
- package/dist/deny-mutations.d.ts +2 -3
- package/dist/deny-mutations.js +55 -35
- package/dist/device-path.d.ts +0 -1
- package/dist/directory-durability.d.ts +6 -7
- package/dist/directory-entry-path.d.ts +0 -1
- package/dist/directory-guard.d.ts +2 -7
- package/dist/directory-guard.js +25 -56
- package/dist/directory-mode-node.d.ts +0 -1
- package/dist/directory-mode-owner.d.ts +0 -1
- package/dist/directory-receipt.d.ts +2 -3
- package/dist/directory-receipt.js +15 -19
- package/dist/durability.d.ts +0 -1
- package/dist/effective-uid.d.ts +0 -1
- package/dist/error-detail.d.ts +0 -1
- package/dist/errors.d.ts +0 -1
- package/dist/file-cleanup.d.ts +1 -1
- package/dist/file-cleanup.js +7 -4
- package/dist/file-contents.d.ts +5 -0
- package/dist/file-contents.js +40 -0
- package/dist/file-handle-transfer.d.ts +0 -1
- package/dist/file-hash.d.ts +0 -1
- package/dist/file-hash.js +186 -70
- package/dist/file-identity.d.ts +0 -1
- package/dist/file-lock-sync-acquisition.d.ts +22 -0
- package/dist/file-lock-sync-acquisition.js +98 -0
- package/dist/file-lock-sync-admission.d.ts +0 -2
- package/dist/file-lock-sync-admission.js +9 -48
- package/dist/file-lock-sync-root-acquire.d.ts +0 -1
- package/dist/file-lock-sync-root-acquire.js +35 -98
- package/dist/file-lock-sync-root-arbitration.d.ts +0 -1
- package/dist/file-lock-sync-root-held.d.ts +1 -3
- package/dist/file-lock-sync-root-held.js +7 -5
- package/dist/file-lock-sync-root-io.d.ts +0 -1
- package/dist/file-lock-sync-root-mutation.d.ts +4 -5
- package/dist/file-lock-sync-root-mutation.js +7 -9
- package/dist/file-lock-sync-root-options.d.ts +0 -1
- package/dist/file-lock-sync-root-registration.d.ts +0 -1
- package/dist/file-lock-sync-root.d.ts +1 -2
- package/dist/file-lock-sync-root.js +14 -87
- package/dist/file-lock-sync-stale-admission.d.ts +2 -7
- package/dist/file-lock-sync-stale-admission.js +24 -23
- package/dist/file-lock-sync.d.ts +0 -1
- package/dist/file-lock-sync.js +46 -128
- package/dist/file-lock.d.ts +0 -1
- package/dist/file-observation.d.ts +0 -1
- package/dist/file-store-boundary.d.ts +0 -2
- package/dist/file-store-boundary.js +6 -26
- package/dist/file-store-copy-source.d.ts +1 -2
- package/dist/file-store-copy-source.js +1 -1
- package/dist/file-store-limit.d.ts +1 -2
- package/dist/file-store-limit.js +2 -3
- package/dist/file-store-path.d.ts +0 -1
- package/dist/file-store-prune.d.ts +0 -1
- package/dist/file-store-sync-directory.d.ts +0 -1
- package/dist/file-store-sync-directory.js +194 -231
- package/dist/file-store-sync-write.d.ts +0 -1
- package/dist/file-store-sync-write.js +16 -26
- package/dist/file-store.d.ts +0 -1
- package/dist/file-store.js +6 -7
- package/dist/file-sync.d.ts +0 -1
- package/dist/filename.d.ts +0 -1
- package/dist/filename.js +1 -7
- package/dist/fs.d.ts +0 -1
- package/dist/guarded-mkdir.d.ts +0 -1
- package/dist/guarded-mkdir.js +6 -27
- package/dist/guarded-mutation.d.ts +0 -7
- package/dist/guarded-mutation.js +6 -11
- package/dist/guest-dispatch-python.d.ts +0 -1
- package/dist/guest-dispatch-python.js +41 -90
- package/dist/guest-native-python.d.ts +0 -1
- package/dist/guest.d.ts +0 -1
- package/dist/home-dir.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/install-path.d.ts +0 -1
- package/dist/install-path.js +2 -5
- package/dist/json-document-store.d.ts +0 -1
- package/dist/json-durable-queue-directory.d.ts +13 -1
- package/dist/json-durable-queue-directory.js +134 -0
- package/dist/json-durable-queue-ownership.d.ts +0 -1
- package/dist/json-durable-queue-ownership.js +43 -66
- package/dist/json-durable-queue-read.d.ts +0 -1
- package/dist/json-durable-queue-read.js +6 -6
- package/dist/json-durable-queue.d.ts +0 -1
- package/dist/json-durable-queue.js +17 -139
- package/dist/json-store.d.ts +0 -1
- package/dist/json-stringify.d.ts +0 -1
- package/dist/json.d.ts +0 -1
- package/dist/json.js +38 -90
- package/dist/local-file-access.d.ts +0 -1
- package/dist/local-file-access.js +3 -10
- package/dist/local-file-descriptor.d.ts +0 -1
- package/dist/local-roots.d.ts +0 -1
- package/dist/local-roots.js +19 -21
- package/dist/lock-config.d.ts +0 -1
- package/dist/move-path-cleanup.d.ts +5 -20
- package/dist/move-path-cleanup.js +57 -21
- package/dist/move-path-stage.d.ts +0 -1
- package/dist/move-path.d.ts +0 -1
- package/dist/move-path.js +62 -39
- package/dist/mutation-authority.d.ts +0 -1
- package/dist/native-binding.d.ts +0 -1
- package/dist/native-config.d.ts +0 -1
- package/dist/native-directory-observation.d.ts +0 -1
- package/dist/native-fallback-warning.d.ts +0 -1
- package/dist/native-operations.d.ts +1 -5
- package/dist/native-operations.js +2 -6
- package/dist/native-parent-admission.d.ts +0 -1
- package/dist/native-pinned-write-windows.d.ts +0 -1
- package/dist/native-pinned-write.d.ts +0 -1
- package/dist/native-pinned-write.js +4 -10
- package/dist/native-policy-directory-observation.d.ts +0 -1
- package/dist/native-policy-parent-windows.d.ts +0 -1
- package/dist/native-rename-outcome.d.ts +0 -1
- package/dist/native-staged-file.d.ts +17 -4
- package/dist/native-staged-file.js +63 -68
- package/dist/native.d.ts +0 -1
- package/dist/native.js +2 -2
- package/dist/opened-file-failure.d.ts +0 -1
- package/dist/opened-realpath.d.ts +0 -1
- package/dist/opened-realpath.js +11 -2
- package/dist/output.d.ts +0 -1
- package/dist/overwrite-file-handle.d.ts +0 -1
- package/dist/owner-dacl.d.ts +0 -1
- package/dist/path-case.d.ts +0 -1
- package/dist/path-policy.d.ts +0 -1
- package/dist/path-prefix.d.ts +0 -1
- package/dist/path-scope-lexical.d.ts +0 -1
- package/dist/path-segment-route.d.ts +0 -1
- package/dist/path-suffix-aliases.d.ts +0 -1
- package/dist/path.d.ts +0 -1
- package/dist/path.js +2 -1
- package/dist/permission-exec.d.ts +0 -1
- package/dist/permission-exec.js +19 -25
- package/dist/permissions-public.d.ts +0 -1
- package/dist/permissions-windows.d.ts +2 -10
- package/dist/permissions-windows.js +10 -30
- package/dist/permissions.d.ts +0 -1
- package/dist/permissions.js +11 -33
- package/dist/pinned-mutation-admission.d.ts +0 -1
- package/dist/pinned-mutation-observation.d.ts +0 -1
- package/dist/pinned-mutation-shared-route.d.ts +0 -1
- package/dist/pinned-open.d.ts +1 -1
- package/dist/pinned-open.js +1 -1
- package/dist/pinned-operation.d.ts +0 -1
- package/dist/pinned-write-input.d.ts +0 -1
- package/dist/pinned-write-input.js +11 -1
- package/dist/pinned-write-mode.d.ts +3 -4
- package/dist/pinned-write-mode.js +15 -8
- package/dist/pinned-write-staged.d.ts +0 -1
- package/dist/pinned-write-staged.js +10 -11
- package/dist/pinned-write-types.d.ts +9 -21
- package/dist/pinned-write.d.ts +0 -1
- package/dist/pinned-write.js +17 -13
- package/dist/positional-read.d.ts +0 -1
- package/dist/private-directory.d.ts +0 -1
- package/dist/private-producer-handoff-sync.d.ts +0 -1
- package/dist/private-producer-handoff-sync.js +9 -51
- package/dist/private-producer-handoff.d.ts +20 -1
- package/dist/private-producer-handoff.js +69 -46
- package/dist/private-temp-workspace.d.ts +0 -1
- package/dist/private-temp-workspace.js +11 -36
- package/dist/publish-copy-stage.d.ts +0 -1
- package/dist/publish-file-failure.d.ts +0 -1
- package/dist/publish-file.d.ts +2 -3
- package/dist/publish-file.js +56 -96
- package/dist/read-open-flags.d.ts +0 -1
- package/dist/read-opened-file.d.ts +0 -1
- package/dist/realpath.d.ts +0 -1
- package/dist/recursive-mkdir-path.d.ts +0 -1
- package/dist/regular-file.d.ts +0 -1
- package/dist/regular-file.js +107 -178
- package/dist/replace-directory.d.ts +0 -1
- package/dist/replace-file-copy-fallback.d.ts +0 -1
- package/dist/replace-file-copy-fallback.js +42 -29
- package/dist/replace-file-copy-source.d.ts +0 -1
- package/dist/replace-file-copy-source.js +19 -23
- package/dist/replace-file-descriptor.d.ts +0 -1
- package/dist/replace-file-descriptor.js +16 -17
- package/dist/replace-file-mode.d.ts +0 -1
- package/dist/replace-file-rename-policy.d.ts +0 -1
- package/dist/replace-file-temp-owner.d.ts +12 -13
- package/dist/replace-file-temp-owner.js +72 -91
- package/dist/replace-file.d.ts +0 -1
- package/dist/replace-file.js +9 -13
- package/dist/retained-directory-replacement.d.ts +0 -1
- package/dist/root-boundary.d.ts +0 -1
- package/dist/root-context.d.ts +0 -1
- package/dist/root-create-input.d.ts +0 -1
- package/dist/root-directory-creation.d.ts +0 -1
- package/dist/root-directory-list.d.ts +0 -1
- package/dist/root-directory-list.js +20 -3
- package/dist/root-directory.d.ts +0 -1
- package/dist/root-entries.d.ts +0 -1
- package/dist/root-errors.d.ts +0 -1
- package/dist/root-file-final-admission.d.ts +1 -2
- package/dist/root-file-final-admission.js +5 -2
- package/dist/root-file.d.ts +0 -1
- package/dist/root-file.js +3 -2
- package/dist/root-impl.d.ts +2 -10
- package/dist/root-impl.js +164 -111
- package/dist/root-move-noreplace.d.ts +2 -1
- package/dist/root-move-noreplace.js +2 -2
- package/dist/root-move-preflight.d.ts +0 -1
- package/dist/root-observed-path.d.ts +0 -1
- package/dist/root-options.d.ts +0 -1
- package/dist/root-path-errors.d.ts +0 -1
- package/dist/root-path-existing.d.ts +3 -1
- package/dist/root-path-existing.js +39 -18
- package/dist/root-path-observation.d.ts +0 -1
- package/dist/root-path-stat.d.ts +0 -1
- package/dist/root-path.d.ts +0 -1
- package/dist/root-path.js +60 -188
- package/dist/root-paths-lexical.d.ts +0 -1
- package/dist/root-paths.d.ts +0 -1
- package/dist/root-read-admission.d.ts +0 -1
- package/dist/root-read-admission.js +31 -39
- package/dist/root-remove-identity.d.ts +0 -1
- package/dist/root-remove-receipt.d.ts +0 -1
- package/dist/root-remove.d.ts +0 -1
- package/dist/root-remove.js +15 -1
- package/dist/root-symlink-policy.d.ts +0 -1
- package/dist/root-walk.d.ts +0 -1
- package/dist/root-write-admission.d.ts +0 -1
- package/dist/root-write-compatibility.d.ts +0 -1
- package/dist/root-write-complete-parent.d.ts +0 -1
- package/dist/root-write-lock-binding.d.ts +0 -1
- package/dist/root-write-mode.d.ts +0 -1
- package/dist/root-write-publication.d.ts +0 -1
- package/dist/root-write-verification.d.ts +0 -1
- package/dist/root.d.ts +0 -1
- package/dist/safe-path-segment.d.ts +1 -2
- package/dist/safe-path-segment.js +2 -5
- package/dist/secret-file.d.ts +0 -1
- package/dist/secret-file.js +7 -17
- package/dist/secret-read-async.d.ts +0 -1
- package/dist/secret-read-async.js +5 -5
- package/dist/secret-read-policy.d.ts +0 -1
- package/dist/secret.d.ts +0 -1
- package/dist/secure-file-windows.d.ts +0 -6
- package/dist/secure-file-windows.js +13 -28
- package/dist/secure-file.d.ts +0 -1
- package/dist/secure-file.js +9 -9
- package/dist/secure-temp-dir.d.ts +0 -1
- package/dist/secure-temp-repair.d.ts +0 -1
- package/dist/sibling-staged-file.d.ts +0 -1
- package/dist/sibling-staged-file.js +32 -39
- package/dist/sibling-temp.d.ts +0 -1
- package/dist/sidecar-lock-acquire.d.ts +1 -2
- package/dist/sidecar-lock-acquire.js +35 -58
- package/dist/sidecar-lock-admission-context.d.ts +0 -1
- package/dist/sidecar-lock-admission-parser.d.ts +0 -1
- package/dist/sidecar-lock-admission.d.ts +1 -5
- package/dist/sidecar-lock-admission.js +1 -7
- package/dist/sidecar-lock-handle.d.ts +3 -1
- package/dist/sidecar-lock-handle.js +6 -0
- package/dist/sidecar-lock-policy.d.ts +3 -1
- package/dist/sidecar-lock-policy.js +16 -0
- package/dist/sidecar-lock-reclaim.d.ts +1 -2
- package/dist/sidecar-lock-reclaim.js +11 -8
- package/dist/sidecar-lock-registration.d.ts +13 -0
- package/dist/sidecar-lock-registration.js +47 -0
- package/dist/sidecar-lock-root.d.ts +0 -1
- package/dist/sidecar-lock-stale-admission.d.ts +0 -1
- package/dist/sidecar-lock-target.d.ts +0 -1
- package/dist/sidecar-lock-types.d.ts +0 -1
- package/dist/sidecar-lock.d.ts +0 -1
- package/dist/sidecar-lock.js +19 -88
- package/dist/staged-directory.d.ts +2 -3
- package/dist/staged-file-settlement.d.ts +0 -1
- package/dist/staged-file-types.d.ts +0 -1
- package/dist/standalone-publication-path.d.ts +0 -1
- package/dist/stat-observation.d.ts +0 -1
- package/dist/store.d.ts +0 -1
- package/dist/strict-file-identity.d.ts +1 -2
- package/dist/strict-file-identity.js +9 -9
- package/dist/string-coerce.d.ts +0 -1
- package/dist/suppressed-error.d.ts +0 -1
- package/dist/symlink-parents.d.ts +0 -1
- package/dist/symlink-parents.js +2 -27
- package/dist/temp-cleanup.d.ts +0 -1
- package/dist/temp-target.d.ts +0 -1
- package/dist/temp-target.js +7 -46
- package/dist/temp-workspace-admission.d.ts +0 -8
- package/dist/temp-workspace-admission.js +0 -4
- package/dist/temp-workspace-child-admission.d.ts +0 -4
- package/dist/temp-workspace-child-admission.js +0 -12
- package/dist/temp-workspace-descriptor.d.ts +0 -6
- package/dist/temp-workspace-descriptor.js +0 -2
- package/dist/temp-workspace-identity.d.ts +0 -1
- package/dist/temp-workspace-owner.d.ts +1 -1
- package/dist/temp-workspace-owner.js +49 -26
- package/dist/temp-workspace-permissions.d.ts +0 -1
- package/dist/temp-workspace-types.d.ts +0 -1
- package/dist/temp.d.ts +0 -1
- package/dist/test-hooks.d.ts +0 -1
- package/dist/text-atomic.d.ts +0 -1
- package/dist/timing.d.ts +0 -1
- package/dist/trash.d.ts +0 -1
- package/dist/types.d.ts +0 -1
- package/dist/unicode-path.d.ts +0 -1
- package/dist/unicode-path.js +3 -0
- package/dist/walk.d.ts +0 -1
- package/dist/walk.js +4 -2
- package/dist/windows-command.d.ts +0 -1
- package/dist/windows-owner.d.ts +0 -1
- package/dist/windows-owner.js +4 -1
- package/dist/windows-path-alias.d.ts +0 -1
- package/dist/windows-path-alias.js +7 -43
- package/dist/windows-path-syntax.d.ts +5 -0
- package/dist/windows-path-syntax.js +21 -0
- package/dist/windows-security-command.d.ts +0 -1
- package/dist/windows-security-facts.d.ts +0 -1
- package/dist/write-file-handle.d.ts +7 -1
- package/dist/write-file-handle.js +23 -0
- package/dist/write-open-flags.d.ts +0 -1
- package/dist/write-open-flags.js +1 -8
- package/dist/write-queue.d.ts +0 -1
- package/dist/write-queue.js +1 -4
- package/docs/advanced.md +68 -1
- package/docs/archive.md +41 -2
- package/docs/atomic.md +43 -5
- package/docs/contributing.md +4 -0
- package/docs/copy.md +2 -0
- package/docs/creation.md +8 -4
- package/docs/durability.md +35 -0
- package/docs/file-contents.md +68 -0
- package/docs/json.md +5 -4
- package/docs/local-roots.md +2 -0
- package/docs/mutation-policy-proof.md +11 -7
- package/docs/native.md +9 -8
- package/docs/path.md +4 -4
- package/docs/permissions.md +6 -0
- package/docs/public-api.md +5 -0
- package/docs/quickstart.md +1 -1
- package/docs/reading.md +2 -2
- package/docs/regular-file.md +3 -0
- package/docs/root.md +19 -0
- package/docs/secret-file.md +4 -0
- package/docs/sidecar-lock.md +9 -1
- package/docs/staged-file.md +4 -3
- package/docs/store.md +3 -1
- package/docs/temp.md +4 -1
- package/docs/types.md +18 -2
- package/docs/walk.md +7 -0
- package/docs/writing.md +18 -5
- package/package.json +8 -9
- package/dist/absolute-path.d.ts.map +0 -1
- package/dist/advanced.d.ts.map +0 -1
- package/dist/archive-crc32.d.ts.map +0 -1
- package/dist/archive-deadline.d.ts.map +0 -1
- package/dist/archive-durability.d.ts.map +0 -1
- package/dist/archive-entry.d.ts.map +0 -1
- package/dist/archive-errors.d.ts.map +0 -1
- package/dist/archive-gzip-tail.d.ts.map +0 -1
- package/dist/archive-input.d.ts.map +0 -1
- package/dist/archive-kind.d.ts.map +0 -1
- package/dist/archive-limits.d.ts.map +0 -1
- package/dist/archive-merge.d.ts.map +0 -1
- package/dist/archive-native.d.ts.map +0 -1
- package/dist/archive-options.d.ts.map +0 -1
- package/dist/archive-parser-errors.d.ts.map +0 -1
- package/dist/archive-plan.d.ts.map +0 -1
- package/dist/archive-policy.d.ts.map +0 -1
- package/dist/archive-read.d.ts.map +0 -1
- package/dist/archive-staging.d.ts.map +0 -1
- package/dist/archive-tar-inspect.d.ts.map +0 -1
- package/dist/archive-tar-stream.d.ts.map +0 -1
- package/dist/archive-tar-wasm.d.ts.map +0 -1
- package/dist/archive-tar.d.ts.map +0 -1
- package/dist/archive-zip-admission.d.ts.map +0 -1
- package/dist/archive-zip-count.d.ts.map +0 -1
- package/dist/archive-zip-directory.d.ts.map +0 -1
- package/dist/archive-zip-entry.d.ts.map +0 -1
- package/dist/archive-zip-integrity.d.ts.map +0 -1
- package/dist/archive-zip-loader.d.ts.map +0 -1
- package/dist/archive-zip-manifest.d.ts.map +0 -1
- package/dist/archive-zip-names.d.ts.map +0 -1
- package/dist/archive-zip-preflight.d.ts.map +0 -1
- package/dist/archive.d.ts.map +0 -1
- package/dist/async-lock.d.ts.map +0 -1
- package/dist/atomic.d.ts.map +0 -1
- package/dist/bounded-read-stream.d.ts.map +0 -1
- package/dist/bounded-read.d.ts.map +0 -1
- package/dist/byte-budget.d.ts.map +0 -1
- package/dist/clone-metadata.d.ts.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/containment.d.ts.map +0 -1
- package/dist/copy-file-input.d.ts.map +0 -1
- package/dist/copy-policy.d.ts.map +0 -1
- package/dist/copy-publication.d.ts.map +0 -1
- package/dist/copy-tree-portable.d.ts.map +0 -1
- package/dist/copy.d.ts.map +0 -1
- package/dist/create-directory.d.ts.map +0 -1
- package/dist/create-file-async.d.ts.map +0 -1
- package/dist/create-file.d.ts.map +0 -1
- package/dist/create-owned-file.d.ts.map +0 -1
- package/dist/create.d.ts.map +0 -1
- package/dist/creation-darwin.d.ts.map +0 -1
- package/dist/creation-file-state.d.ts.map +0 -1
- package/dist/creation-path.d.ts.map +0 -1
- package/dist/creation-permissions.d.ts.map +0 -1
- package/dist/deny-mutations.d.ts.map +0 -1
- package/dist/device-path.d.ts.map +0 -1
- package/dist/directory-durability.d.ts.map +0 -1
- package/dist/directory-entry-path.d.ts.map +0 -1
- package/dist/directory-guard.d.ts.map +0 -1
- package/dist/directory-mode-node.d.ts.map +0 -1
- package/dist/directory-mode-owner.d.ts.map +0 -1
- package/dist/directory-receipt.d.ts.map +0 -1
- package/dist/durability.d.ts.map +0 -1
- package/dist/effective-uid.d.ts.map +0 -1
- package/dist/error-detail.d.ts.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/file-cleanup.d.ts.map +0 -1
- package/dist/file-handle-transfer.d.ts.map +0 -1
- package/dist/file-hash.d.ts.map +0 -1
- package/dist/file-identity.d.ts.map +0 -1
- package/dist/file-lock-sync-admission.d.ts.map +0 -1
- package/dist/file-lock-sync-root-acquire.d.ts.map +0 -1
- package/dist/file-lock-sync-root-arbitration.d.ts.map +0 -1
- package/dist/file-lock-sync-root-held.d.ts.map +0 -1
- package/dist/file-lock-sync-root-io.d.ts.map +0 -1
- package/dist/file-lock-sync-root-mutation.d.ts.map +0 -1
- package/dist/file-lock-sync-root-options.d.ts.map +0 -1
- package/dist/file-lock-sync-root-registration.d.ts.map +0 -1
- package/dist/file-lock-sync-root.d.ts.map +0 -1
- package/dist/file-lock-sync-stale-admission.d.ts.map +0 -1
- package/dist/file-lock-sync.d.ts.map +0 -1
- package/dist/file-lock.d.ts.map +0 -1
- package/dist/file-observation.d.ts.map +0 -1
- package/dist/file-store-boundary.d.ts.map +0 -1
- package/dist/file-store-copy-source.d.ts.map +0 -1
- package/dist/file-store-limit.d.ts.map +0 -1
- package/dist/file-store-path.d.ts.map +0 -1
- package/dist/file-store-prune.d.ts.map +0 -1
- package/dist/file-store-sync-directory.d.ts.map +0 -1
- package/dist/file-store-sync-write.d.ts.map +0 -1
- package/dist/file-store.d.ts.map +0 -1
- package/dist/file-sync.d.ts.map +0 -1
- package/dist/filename.d.ts.map +0 -1
- package/dist/fs.d.ts.map +0 -1
- package/dist/guarded-mkdir.d.ts.map +0 -1
- package/dist/guarded-mutation.d.ts.map +0 -1
- package/dist/guest-dispatch-python.d.ts.map +0 -1
- package/dist/guest-native-python.d.ts.map +0 -1
- package/dist/guest.d.ts.map +0 -1
- package/dist/home-dir.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/install-path.d.ts.map +0 -1
- package/dist/json-document-store.d.ts.map +0 -1
- package/dist/json-durable-queue-directory.d.ts.map +0 -1
- package/dist/json-durable-queue-ownership.d.ts.map +0 -1
- package/dist/json-durable-queue-paths.d.ts +0 -11
- package/dist/json-durable-queue-paths.d.ts.map +0 -1
- package/dist/json-durable-queue-paths.js +0 -42
- package/dist/json-durable-queue-read.d.ts.map +0 -1
- package/dist/json-durable-queue.d.ts.map +0 -1
- package/dist/json-store.d.ts.map +0 -1
- package/dist/json-stringify.d.ts.map +0 -1
- package/dist/json.d.ts.map +0 -1
- package/dist/local-file-access.d.ts.map +0 -1
- package/dist/local-file-descriptor.d.ts.map +0 -1
- package/dist/local-roots.d.ts.map +0 -1
- package/dist/lock-config.d.ts.map +0 -1
- package/dist/move-path-cleanup.d.ts.map +0 -1
- package/dist/move-path-stage.d.ts.map +0 -1
- package/dist/move-path.d.ts.map +0 -1
- package/dist/mutation-authority.d.ts.map +0 -1
- package/dist/native-binding.d.ts.map +0 -1
- package/dist/native-config.d.ts.map +0 -1
- package/dist/native-directory-observation.d.ts.map +0 -1
- package/dist/native-fallback-warning.d.ts.map +0 -1
- package/dist/native-operations.d.ts.map +0 -1
- package/dist/native-parent-admission.d.ts.map +0 -1
- package/dist/native-pinned-write-windows.d.ts.map +0 -1
- package/dist/native-pinned-write.d.ts.map +0 -1
- package/dist/native-policy-directory-observation.d.ts.map +0 -1
- package/dist/native-policy-parent-windows.d.ts.map +0 -1
- package/dist/native-rename-outcome.d.ts.map +0 -1
- package/dist/native-staged-file.d.ts.map +0 -1
- package/dist/native.d.ts.map +0 -1
- package/dist/opened-file-failure.d.ts.map +0 -1
- package/dist/opened-realpath.d.ts.map +0 -1
- package/dist/output.d.ts.map +0 -1
- package/dist/overwrite-file-handle.d.ts.map +0 -1
- package/dist/owner-dacl.d.ts.map +0 -1
- package/dist/path-case.d.ts.map +0 -1
- package/dist/path-policy.d.ts.map +0 -1
- package/dist/path-prefix.d.ts.map +0 -1
- package/dist/path-scope-lexical.d.ts.map +0 -1
- package/dist/path-segment-route.d.ts.map +0 -1
- package/dist/path-suffix-aliases.d.ts.map +0 -1
- package/dist/path.d.ts.map +0 -1
- package/dist/permission-exec.d.ts.map +0 -1
- package/dist/permissions-public.d.ts.map +0 -1
- package/dist/permissions-windows.d.ts.map +0 -1
- package/dist/permissions.d.ts.map +0 -1
- package/dist/pinned-mutation-admission.d.ts.map +0 -1
- package/dist/pinned-mutation-observation.d.ts.map +0 -1
- package/dist/pinned-mutation-shared-route.d.ts.map +0 -1
- package/dist/pinned-open.d.ts.map +0 -1
- package/dist/pinned-operation.d.ts.map +0 -1
- package/dist/pinned-write-input.d.ts.map +0 -1
- package/dist/pinned-write-mode.d.ts.map +0 -1
- package/dist/pinned-write-staged.d.ts.map +0 -1
- package/dist/pinned-write-types.d.ts.map +0 -1
- package/dist/pinned-write.d.ts.map +0 -1
- package/dist/positional-read.d.ts.map +0 -1
- package/dist/private-directory.d.ts.map +0 -1
- package/dist/private-producer-handoff-sync.d.ts.map +0 -1
- package/dist/private-producer-handoff.d.ts.map +0 -1
- package/dist/private-temp-workspace.d.ts.map +0 -1
- package/dist/publish-copy-stage.d.ts.map +0 -1
- package/dist/publish-file-failure.d.ts.map +0 -1
- package/dist/publish-file.d.ts.map +0 -1
- package/dist/read-open-flags.d.ts.map +0 -1
- package/dist/read-opened-file.d.ts.map +0 -1
- package/dist/realpath.d.ts.map +0 -1
- package/dist/recursive-mkdir-path.d.ts.map +0 -1
- package/dist/regular-file.d.ts.map +0 -1
- package/dist/replace-directory.d.ts.map +0 -1
- package/dist/replace-file-copy-fallback.d.ts.map +0 -1
- package/dist/replace-file-copy-source.d.ts.map +0 -1
- package/dist/replace-file-descriptor.d.ts.map +0 -1
- package/dist/replace-file-mode.d.ts.map +0 -1
- package/dist/replace-file-rename-policy.d.ts.map +0 -1
- package/dist/replace-file-temp-owner.d.ts.map +0 -1
- package/dist/replace-file.d.ts.map +0 -1
- package/dist/retained-directory-replacement.d.ts.map +0 -1
- package/dist/root-boundary.d.ts.map +0 -1
- package/dist/root-context.d.ts.map +0 -1
- package/dist/root-create-input.d.ts.map +0 -1
- package/dist/root-directory-creation.d.ts.map +0 -1
- package/dist/root-directory-list.d.ts.map +0 -1
- package/dist/root-directory.d.ts.map +0 -1
- package/dist/root-entries.d.ts.map +0 -1
- package/dist/root-errors.d.ts.map +0 -1
- package/dist/root-file-final-admission.d.ts.map +0 -1
- package/dist/root-file.d.ts.map +0 -1
- package/dist/root-impl.d.ts.map +0 -1
- package/dist/root-move-noreplace.d.ts.map +0 -1
- package/dist/root-move-preflight.d.ts.map +0 -1
- package/dist/root-observed-path.d.ts.map +0 -1
- package/dist/root-options.d.ts.map +0 -1
- package/dist/root-path-errors.d.ts.map +0 -1
- package/dist/root-path-existing.d.ts.map +0 -1
- package/dist/root-path-observation.d.ts.map +0 -1
- package/dist/root-path-stat.d.ts.map +0 -1
- package/dist/root-path-symlink.d.ts +0 -7
- package/dist/root-path-symlink.d.ts.map +0 -1
- package/dist/root-path-symlink.js +0 -55
- package/dist/root-path.d.ts.map +0 -1
- package/dist/root-paths-lexical.d.ts.map +0 -1
- package/dist/root-paths.d.ts.map +0 -1
- package/dist/root-read-admission.d.ts.map +0 -1
- package/dist/root-remove-identity.d.ts.map +0 -1
- package/dist/root-remove-receipt.d.ts.map +0 -1
- package/dist/root-remove.d.ts.map +0 -1
- package/dist/root-symlink-policy.d.ts.map +0 -1
- package/dist/root-walk.d.ts.map +0 -1
- package/dist/root-write-admission.d.ts.map +0 -1
- package/dist/root-write-compatibility.d.ts.map +0 -1
- package/dist/root-write-complete-parent.d.ts.map +0 -1
- package/dist/root-write-lock-binding.d.ts.map +0 -1
- package/dist/root-write-mode.d.ts.map +0 -1
- package/dist/root-write-publication.d.ts.map +0 -1
- package/dist/root-write-verification.d.ts.map +0 -1
- package/dist/root.d.ts.map +0 -1
- package/dist/safe-path-segment.d.ts.map +0 -1
- package/dist/secret-file.d.ts.map +0 -1
- package/dist/secret-read-async.d.ts.map +0 -1
- package/dist/secret-read-policy.d.ts.map +0 -1
- package/dist/secret.d.ts.map +0 -1
- package/dist/secure-file-windows.d.ts.map +0 -1
- package/dist/secure-file.d.ts.map +0 -1
- package/dist/secure-temp-dir.d.ts.map +0 -1
- package/dist/secure-temp-repair.d.ts.map +0 -1
- package/dist/sibling-staged-file.d.ts.map +0 -1
- package/dist/sibling-temp.d.ts.map +0 -1
- package/dist/sidecar-lock-acquire.d.ts.map +0 -1
- package/dist/sidecar-lock-admission-context.d.ts.map +0 -1
- package/dist/sidecar-lock-admission-parser.d.ts.map +0 -1
- package/dist/sidecar-lock-admission.d.ts.map +0 -1
- package/dist/sidecar-lock-handle.d.ts.map +0 -1
- package/dist/sidecar-lock-policy.d.ts.map +0 -1
- package/dist/sidecar-lock-reclaim.d.ts.map +0 -1
- package/dist/sidecar-lock-root.d.ts.map +0 -1
- package/dist/sidecar-lock-stale-admission.d.ts.map +0 -1
- package/dist/sidecar-lock-target.d.ts.map +0 -1
- package/dist/sidecar-lock-types.d.ts.map +0 -1
- package/dist/sidecar-lock.d.ts.map +0 -1
- package/dist/staged-directory.d.ts.map +0 -1
- package/dist/staged-file-settlement.d.ts.map +0 -1
- package/dist/staged-file-types.d.ts.map +0 -1
- package/dist/standalone-publication-path.d.ts.map +0 -1
- package/dist/stat-observation.d.ts.map +0 -1
- package/dist/store.d.ts.map +0 -1
- package/dist/strict-file-identity.d.ts.map +0 -1
- package/dist/string-coerce.d.ts.map +0 -1
- package/dist/suppressed-error.d.ts.map +0 -1
- package/dist/symlink-parents.d.ts.map +0 -1
- package/dist/temp-cleanup.d.ts.map +0 -1
- package/dist/temp-target.d.ts.map +0 -1
- package/dist/temp-workspace-admission.d.ts.map +0 -1
- package/dist/temp-workspace-child-admission.d.ts.map +0 -1
- package/dist/temp-workspace-descriptor.d.ts.map +0 -1
- package/dist/temp-workspace-identity.d.ts.map +0 -1
- package/dist/temp-workspace-owner.d.ts.map +0 -1
- package/dist/temp-workspace-permissions.d.ts.map +0 -1
- package/dist/temp-workspace-types.d.ts.map +0 -1
- package/dist/temp.d.ts.map +0 -1
- package/dist/test-hooks.d.ts.map +0 -1
- package/dist/text-atomic.d.ts.map +0 -1
- package/dist/timing.d.ts.map +0 -1
- package/dist/trash.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/unicode-path.d.ts.map +0 -1
- package/dist/walk.d.ts.map +0 -1
- package/dist/windows-command.d.ts.map +0 -1
- package/dist/windows-owner.d.ts.map +0 -1
- package/dist/windows-path-alias.d.ts.map +0 -1
- package/dist/windows-security-command.d.ts.map +0 -1
- package/dist/windows-security-facts.d.ts.map +0 -1
- package/dist/write-file-handle.d.ts.map +0 -1
- package/dist/write-open-flags.d.ts.map +0 -1
- package/dist/write-queue.d.ts.map +0 -1
|
@@ -1,43 +1,9 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { FsSafeError } from "./errors.js";
|
|
3
|
-
|
|
4
|
-
const FORWARD_SLASH = 0x2f;
|
|
5
|
-
const BACKSLASH = 0x5c;
|
|
6
|
-
const DOT = 0x2e;
|
|
7
|
-
const QUESTION_MARK = 0x3f;
|
|
8
|
-
function isAsciiLetter(code) {
|
|
9
|
-
return (code >= 0x41 && code <= 0x5a) || (code >= 0x61 && code <= 0x7a);
|
|
10
|
-
}
|
|
11
|
-
function isSeparator(code) {
|
|
12
|
-
return code === FORWARD_SLASH || code === BACKSLASH;
|
|
13
|
-
}
|
|
14
|
-
function rootedDriveColonIndex(value) {
|
|
15
|
-
if (value.length >= 3 &&
|
|
16
|
-
isAsciiLetter(value.charCodeAt(0)) &&
|
|
17
|
-
value.charCodeAt(1) === COLON &&
|
|
18
|
-
isSeparator(value.charCodeAt(2))) {
|
|
19
|
-
return 1;
|
|
20
|
-
}
|
|
21
|
-
if (value.length >= 7 &&
|
|
22
|
-
isSeparator(value.charCodeAt(0)) &&
|
|
23
|
-
isSeparator(value.charCodeAt(1)) &&
|
|
24
|
-
(value.charCodeAt(2) === QUESTION_MARK || value.charCodeAt(2) === DOT) &&
|
|
25
|
-
isSeparator(value.charCodeAt(3)) &&
|
|
26
|
-
isAsciiLetter(value.charCodeAt(4)) &&
|
|
27
|
-
value.charCodeAt(5) === COLON &&
|
|
28
|
-
isSeparator(value.charCodeAt(6))) {
|
|
29
|
-
return 5;
|
|
30
|
-
}
|
|
31
|
-
return -1;
|
|
32
|
-
}
|
|
3
|
+
import { hasWindowsDrivePrefix, rootedWindowsDriveColonIndex, windowsNamespaceMarker, } from "./windows-path-syntax.js";
|
|
33
4
|
function isBareWindowsNamespaceDrive(value) {
|
|
34
|
-
return
|
|
35
|
-
|
|
36
|
-
isSeparator(value.charCodeAt(1)) &&
|
|
37
|
-
(value.charCodeAt(2) === QUESTION_MARK || value.charCodeAt(2) === DOT) &&
|
|
38
|
-
isSeparator(value.charCodeAt(3)) &&
|
|
39
|
-
isAsciiLetter(value.charCodeAt(4)) &&
|
|
40
|
-
value.charCodeAt(5) === COLON);
|
|
5
|
+
return value.length === 6 && windowsNamespaceMarker(value) !== undefined &&
|
|
6
|
+
hasWindowsDrivePrefix(value, 4);
|
|
41
7
|
}
|
|
42
8
|
/**
|
|
43
9
|
* Capture an ordinary Windows drive-relative path without normalizing its raw
|
|
@@ -47,9 +13,7 @@ function isBareWindowsNamespaceDrive(value) {
|
|
|
47
13
|
export function anchorWindowsDriveRelativePath(value) {
|
|
48
14
|
if (process.platform !== "win32" || path.isAbsolute(value))
|
|
49
15
|
return value;
|
|
50
|
-
if (value
|
|
51
|
-
!isAsciiLetter(value.charCodeAt(0)) ||
|
|
52
|
-
value.charCodeAt(1) !== COLON) {
|
|
16
|
+
if (!hasWindowsDrivePrefix(value)) {
|
|
53
17
|
return value;
|
|
54
18
|
}
|
|
55
19
|
const drive = value.slice(0, 2);
|
|
@@ -64,7 +28,7 @@ export function anchorWindowsDriveRelativePath(value) {
|
|
|
64
28
|
export function resolvePathPreservingWindowsRoot(value) {
|
|
65
29
|
if (value.length === 7 &&
|
|
66
30
|
process.platform === "win32" &&
|
|
67
|
-
|
|
31
|
+
rootedWindowsDriveColonIndex(value) === 5) {
|
|
68
32
|
return value.includes("/") ? value.replaceAll("/", "\\") : value;
|
|
69
33
|
}
|
|
70
34
|
const resolved = path.resolve(value);
|
|
@@ -110,7 +74,7 @@ export function resolvePathFromBasePreservingWindowsRoot(base, ...segments) {
|
|
|
110
74
|
*/
|
|
111
75
|
export function pathForWindowsFilesystem(value) {
|
|
112
76
|
if (process.platform !== "win32" ||
|
|
113
|
-
|
|
77
|
+
rootedWindowsDriveColonIndex(value) !== 5) {
|
|
114
78
|
return value;
|
|
115
79
|
}
|
|
116
80
|
if (value.length === 7) {
|
|
@@ -132,7 +96,7 @@ export function hasWindowsPathAlias(value, kind, platform = process.platform) {
|
|
|
132
96
|
return false;
|
|
133
97
|
if (kind === "relative")
|
|
134
98
|
return true;
|
|
135
|
-
return firstColon !==
|
|
99
|
+
return firstColon !== rootedWindowsDriveColonIndex(value) || value.indexOf(":", firstColon + 1) !== -1;
|
|
136
100
|
}
|
|
137
101
|
export function assertNoWindowsPathAliasForPlatform(value, kind, message, platform) {
|
|
138
102
|
if (hasWindowsPathAlias(value, kind, platform)) {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function isWindowsSeparator(value: string, offset: number): boolean;
|
|
2
|
+
export declare function hasWindowsDrivePrefix(value: string, offset?: number): boolean;
|
|
3
|
+
/** Classify a raw prefix without normalizing any path components. */
|
|
4
|
+
export declare function windowsNamespaceMarker(value: string): "." | "?" | undefined;
|
|
5
|
+
export declare function rootedWindowsDriveColonIndex(value: string): number;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function isWindowsSeparator(value, offset) {
|
|
2
|
+
const code = value.charCodeAt(offset);
|
|
3
|
+
return code === 0x2f || code === 0x5c;
|
|
4
|
+
}
|
|
5
|
+
export function hasWindowsDrivePrefix(value, offset = 0) {
|
|
6
|
+
const letter = value.charCodeAt(offset) | 0x20;
|
|
7
|
+
return letter >= 0x61 && letter <= 0x7a && value.charCodeAt(offset + 1) === 0x3a;
|
|
8
|
+
}
|
|
9
|
+
/** Classify a raw prefix without normalizing any path components. */
|
|
10
|
+
export function windowsNamespaceMarker(value) {
|
|
11
|
+
const marker = value[2];
|
|
12
|
+
return (marker === "." || marker === "?") &&
|
|
13
|
+
isWindowsSeparator(value, 0) && isWindowsSeparator(value, 1) &&
|
|
14
|
+
isWindowsSeparator(value, 3) ? marker : undefined;
|
|
15
|
+
}
|
|
16
|
+
export function rootedWindowsDriveColonIndex(value) {
|
|
17
|
+
const colon = hasWindowsDrivePrefix(value)
|
|
18
|
+
? 1
|
|
19
|
+
: windowsNamespaceMarker(value) !== undefined && hasWindowsDrivePrefix(value, 4) ? 5 : -1;
|
|
20
|
+
return colon >= 0 && isWindowsSeparator(value, colon + 1) ? colon : -1;
|
|
21
|
+
}
|
|
@@ -23,4 +23,3 @@ export declare function protectPrivateWindowsFileCommand(fd: number, targetPath:
|
|
|
23
23
|
}>;
|
|
24
24
|
export declare function verifyPrivateWindowsFileCommandSync(fd: number, targetPath: string, expectedFileIdentity: string, expectedParentIdentity: string, expectedLinks?: number): void;
|
|
25
25
|
export declare function verifyPrivateWindowsFileCommand(fd: number, targetPath: string, expectedFileIdentity: string, expectedParentIdentity: string, expectedLinks?: number): Promise<void>;
|
|
26
|
-
//# sourceMappingURL=windows-security-command.d.ts.map
|
|
@@ -3,4 +3,3 @@ import type { NativeWindowsSecurityFacts } from "./native-binding.js";
|
|
|
3
3
|
export declare function parseWindowsSecurityCommandFacts(value: unknown): NativeWindowsSecurityFacts;
|
|
4
4
|
/** Native and command observations share the same fail-closed admission policy. */
|
|
5
5
|
export declare function validateSecureWindowsSecurityFacts(value: unknown): NativeWindowsSecurityFacts;
|
|
6
|
-
//# sourceMappingURL=windows-security-facts.d.ts.map
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { FileHandle } from "node:fs/promises";
|
|
2
|
+
export type WriteFileWindowOptions = {
|
|
3
|
+
signal?: AbortSignal;
|
|
4
|
+
/** Synchronous authority check immediately before every write, including short-write retries. */
|
|
5
|
+
assertBeforeMutation?: () => void;
|
|
6
|
+
};
|
|
7
|
+
/** Write borrowed bytes completely; null advances the cursor, an explicit position preserves it. */
|
|
8
|
+
export declare function writeFileWindowFully(handle: FileHandle, bytes: Uint8Array, position: number | null, options?: WriteFileWindowOptions): Promise<void>;
|
|
2
9
|
export declare function writeAllToFile(target: FileHandle | number, data: string | Uint8Array, options?: {
|
|
3
10
|
encoding?: BufferEncoding;
|
|
4
11
|
position?: number;
|
|
5
12
|
assertBeforeMutation?: () => void;
|
|
6
13
|
}): Promise<void>;
|
|
7
|
-
//# sourceMappingURL=write-file-handle.d.ts.map
|
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
+
import { snapshotByteView } from "./byte-view.js";
|
|
2
3
|
import { FsSafeError } from "./errors.js";
|
|
4
|
+
import { assertSynchronousCallbackResult } from "./mutation-authority.js";
|
|
3
5
|
const WRITE_CHUNK_BYTES = 512 * 1024;
|
|
6
|
+
/** Write borrowed bytes completely; null advances the cursor, an explicit position preserves it. */
|
|
7
|
+
export async function writeFileWindowFully(handle, bytes, position, options = {}) {
|
|
8
|
+
const payload = snapshotByteView(bytes);
|
|
9
|
+
if (position !== null && (!Number.isSafeInteger(position) || position < 0 ||
|
|
10
|
+
!Number.isSafeInteger(position + payload.byteLength))) {
|
|
11
|
+
throw new RangeError("write position and window end must be non-negative safe integers");
|
|
12
|
+
}
|
|
13
|
+
const signal = options.signal;
|
|
14
|
+
const assertion = options.assertBeforeMutation;
|
|
15
|
+
signal?.throwIfAborted();
|
|
16
|
+
await writeAllToFile(handle, payload, {
|
|
17
|
+
position: position === null ? undefined : position,
|
|
18
|
+
assertBeforeMutation: () => {
|
|
19
|
+
signal?.throwIfAborted();
|
|
20
|
+
assertSynchronousCallbackResult(assertion === undefined ? undefined : Reflect.apply(assertion, options, []), "assertBeforeMutation");
|
|
21
|
+
signal?.throwIfAborted();
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
// A pending write must settle before cancellation releases the caller's buffer and handle.
|
|
25
|
+
signal?.throwIfAborted();
|
|
26
|
+
}
|
|
4
27
|
export async function writeAllToFile(target, data, options = {}) {
|
|
5
28
|
const buffer = typeof data === "string" ? Buffer.from(data, options.encoding ?? "utf8") : data;
|
|
6
29
|
let offset = 0;
|
|
@@ -2,4 +2,3 @@ import fsSync from "node:fs";
|
|
|
2
2
|
export declare function resolveNonblockingWriteFlag(constants?: Partial<Pick<typeof fsSync.constants, "O_NONBLOCK">>): number;
|
|
3
3
|
export declare function isNonRegularWriteOpenError(error: unknown, filePath: string, flags: number): Promise<boolean>;
|
|
4
4
|
export declare function isNonRegularWriteOpenErrorSync(error: unknown, filePath: string, flags: number): boolean;
|
|
5
|
-
//# sourceMappingURL=write-open-flags.d.ts.map
|
package/dist/write-open-flags.js
CHANGED
|
@@ -13,14 +13,7 @@ function isNonblockingWriteEnxio(error, flags) {
|
|
|
13
13
|
// A no-reader FIFO rejects a nonblocking write-only open before fstat is possible.
|
|
14
14
|
// Reclassify only a confirmed non-regular path; inconclusive races keep the errno.
|
|
15
15
|
export async function isNonRegularWriteOpenError(error, filePath, flags) {
|
|
16
|
-
|
|
17
|
-
return false;
|
|
18
|
-
try {
|
|
19
|
-
return !fsSync.lstatSync(filePath).isFile();
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
16
|
+
return isNonRegularWriteOpenErrorSync(error, filePath, flags);
|
|
24
17
|
}
|
|
25
18
|
export function isNonRegularWriteOpenErrorSync(error, filePath, flags) {
|
|
26
19
|
if (!isNonblockingWriteEnxio(error, flags))
|
package/dist/write-queue.d.ts
CHANGED
package/dist/write-queue.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
const writeQueues = new Map();
|
|
2
2
|
export async function serializePathWrite(key, run) {
|
|
3
3
|
const previous = writeQueues.get(key) ?? Promise.resolve();
|
|
4
|
-
const task = (
|
|
5
|
-
await previous.catch(() => undefined);
|
|
6
|
-
return await run();
|
|
7
|
-
})();
|
|
4
|
+
const task = previous.then(() => run());
|
|
8
5
|
const done = task.then(() => undefined, () => undefined);
|
|
9
6
|
writeQueues.set(key, done);
|
|
10
7
|
try {
|
package/docs/advanced.md
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
|
|
20
20
|
## What lives here
|
|
21
21
|
|
|
22
|
-
The exports group into a handful of themes.
|
|
22
|
+
The exports group into a handful of themes. Documented helpers link to their contract below or a dedicated page; everything else is reference-only and tracked here.
|
|
23
23
|
|
|
24
24
|
### Path scopes and root paths
|
|
25
25
|
|
|
@@ -71,7 +71,9 @@ Operational filesystem failures such as permissions or I/O errors are rethrown.
|
|
|
71
71
|
| `readFileDescriptorBounded`, `readFileDescriptorBoundedSync`, `readFileHandleBounded` | – | Incremental whole-file reads for already-open descriptors/handles. They consume at most `maxBytes + 1`, do not close the input, and throw `FsSafeError("too-large")` on overflow. |
|
|
72
72
|
| `createDirectory`, `createDirectorySync`, `createFileSync` | [Exclusive leaf creation](creation.md) | Create one exclusive entry under an existing trusted parent, optionally with private permissions; file creation returns an owned disposable descriptor. |
|
|
73
73
|
| `readFileWindowFully`, `readFileWindowFullySync`, `ReadFileWindowOptions` | [positional-read.md](positional-read.md) | Fill a caller-owned buffer at an explicit file position, completing short reads and returning the EOF count without moving or closing the descriptor. |
|
|
74
|
+
| `writeFileWindowFully`, `WriteFileWindowOptions` | [Borrowed-handle writes](#borrowed-handle-writes) | Write all supplied bytes at an explicit position or the current cursor, completing short writes with cancellation and per-write authority checks. |
|
|
74
75
|
| `copyFileHandle`, `copyFileDescriptorSync`, `CopyFileHandleOptions` | [copy.md](copy.md#borrowed-filehandle-transfers) | Copy caller-owned regular files through async handles or sync descriptors from position zero with byte limits and synchronous callbacks; preserves cursors and leaves publication and cleanup to the caller. |
|
|
76
|
+
| `sameFileContentsSync`, `SameFileContentsOptions` | [Exact file comparison](file-contents.md) | Compare borrowed regular-file descriptors byte for byte through EOF with bounded memory and an optional per-file byte limit, preserving both cursors and lifetimes. |
|
|
75
77
|
| `overwriteFileHandle`, `OverwriteFileHandleOptions` | [in-place-write.md](in-place-write.md) | Overwrite a borrowed read/write handle with prefix-only preparation and best-effort rollback; preserves its inode, cursor, and caller-owned lifetime. |
|
|
76
78
|
| `openRootFile`, `openRootFileSync`, `canUseRootFileOpen`, `matchRootFileOpenFailure`, related types | – | Low-level root-bounded open; rejects every symlink component by default, with `symlinks: "follow-parents-within-root"` for contained parent aliases or `"follow-within-root"` for final links too. |
|
|
77
79
|
| `appendRegularFile`, `appendRegularFileSync`, `readRegularFile`, `readRegularFileSync`, `statRegularFile`, `statRegularFileSync`, `resolveRegularFileAppendFlags`, `AppendRegularFileOptions`, `RegularFileStatResult` | [regular-file.md](regular-file.md) | Type-checked regular-file I/O. |
|
|
@@ -151,6 +153,71 @@ component is followed by another segment, both helpers throw
|
|
|
151
153
|
`FsSafeError("not-file")` before the platform can expose that state as POSIX
|
|
152
154
|
`ENOTDIR` or Windows `ENOENT`.
|
|
153
155
|
|
|
156
|
+
#### Borrowed-handle writes
|
|
157
|
+
|
|
158
|
+
Use `writeFileWindowFully()` when you already own a writable file handle and
|
|
159
|
+
need to complete a byte-window write, including positive short writes.
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
import { root } from "@openclaw/fs-safe";
|
|
163
|
+
import { writeFileWindowFully } from "@openclaw/fs-safe/advanced";
|
|
164
|
+
|
|
165
|
+
const workspace = await root("/srv/workspace");
|
|
166
|
+
await using opened = await workspace.openWritable("record.bin", { writeMode: "update" });
|
|
167
|
+
await writeFileWindowFully(opened.handle, Buffer.from([1, 2, 3]), 16);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
type WriteFileWindowOptions = {
|
|
172
|
+
signal?: AbortSignal;
|
|
173
|
+
assertBeforeMutation?: () => void;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
function writeFileWindowFully(
|
|
177
|
+
handle: import("node:fs/promises").FileHandle,
|
|
178
|
+
bytes: Uint8Array,
|
|
179
|
+
position: number | null,
|
|
180
|
+
options?: WriteFileWindowOptions,
|
|
181
|
+
): Promise<void>;
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
A numeric `position` writes at that offset without moving the handle's cursor.
|
|
185
|
+
It and the exclusive window end (`position + bytes.byteLength`) must be
|
|
186
|
+
non-negative safe integers; invalid ranges throw `RangeError` before mutation.
|
|
187
|
+
Bounds come from the intrinsic byte view, ignoring shadowed metadata properties.
|
|
188
|
+
Pass `null` to write at and advance the current cursor. Each syscall writes at
|
|
189
|
+
most 512 KiB. A write that makes no progress throws
|
|
190
|
+
`FsSafeError("helper-failed")`; filesystem errors propagate unchanged.
|
|
191
|
+
Empty input still validates the range and checks cancellation, but performs no
|
|
192
|
+
I/O and does not call `assertBeforeMutation`.
|
|
193
|
+
|
|
194
|
+
The caller must supply a writable regular-file handle, opened **without append
|
|
195
|
+
mode** for numeric positions. Some operating systems ignore positioned-write
|
|
196
|
+
offsets on append handles, and this helper does not inspect file type or open
|
|
197
|
+
flags. Opening, path admission, identity checks, and closing remain the caller's
|
|
198
|
+
responsibility. Keep the handle open and the borrowed bytes unchanged, attached,
|
|
199
|
+
and accessible until the promise settles; avoid concurrent I/O when it can change
|
|
200
|
+
the intended contents or shared cursor. The helper does not acquire a lock.
|
|
201
|
+
|
|
202
|
+
`assertBeforeMutation` runs synchronously immediately before every write,
|
|
203
|
+
including short-write retries. A thrown value propagates unchanged; a Promise or
|
|
204
|
+
thenable return rejects with `TypeError` before that write. The callback must not
|
|
205
|
+
modify the payload or handle. It does not run as a final completion check; the
|
|
206
|
+
caller owns any authority check before later publication or other mutations.
|
|
207
|
+
|
|
208
|
+
`signal` is checked at admission, before and after each authority callback, and
|
|
209
|
+
after each pending write settles. Cancellation waits for an in-flight write and
|
|
210
|
+
then rejects with the signal's reason without starting another syscall. If that
|
|
211
|
+
write fails, its filesystem error or zero-progress failure takes precedence over cancellation. Already
|
|
212
|
+
written bytes remain changed; there is no rollback or hidden write after the
|
|
213
|
+
promise settles.
|
|
214
|
+
|
|
215
|
+
The helper neither truncates an existing suffix nor changes permissions,
|
|
216
|
+
synchronizes, or closes the handle. Callers retain those responsibilities and
|
|
217
|
+
any wider transaction policy. For complete replacement with best-effort
|
|
218
|
+
rollback, use [`overwriteFileHandle()`](in-place-write.md); for root-bounded
|
|
219
|
+
atomic replacement, use [`Root.write()`](writing.md).
|
|
220
|
+
|
|
154
221
|
### Local roots and file URLs
|
|
155
222
|
|
|
156
223
|
| Export | Page | Notes |
|
package/docs/archive.md
CHANGED
|
@@ -11,6 +11,14 @@ These TAR routes work with all optional dependencies omitted and need no
|
|
|
11
11
|
runtime interpreter, download, install script, or consumer compiler toolchain.
|
|
12
12
|
ZIP fallback still requires optional `jszip`.
|
|
13
13
|
|
|
14
|
+
The shared TAR parser reuses the already-validated owned path for ordinary
|
|
15
|
+
members. Original header names and USTAR prefixes still undergo validation
|
|
16
|
+
even when PAX or GNU metadata supplies an override; effective override paths
|
|
17
|
+
retain their separate checks. Empty USTAR prefixes retain field decoding and
|
|
18
|
+
padding checks; path validation applies to nonempty prefixes. Joining an
|
|
19
|
+
admitted prefix and name with a separator preserves their checked components,
|
|
20
|
+
so the parser does not repeat the same component validation on the joined path.
|
|
21
|
+
|
|
14
22
|
`auto` prefers an available native binding; a native operation failure is
|
|
15
23
|
terminal and never retries through WASM. `require` rejects a missing binding
|
|
16
24
|
with `FsSafeError("helper-unavailable")`, including for zstd/bzip2 suffix
|
|
@@ -31,6 +39,7 @@ await extractArchive({
|
|
|
31
39
|
timeoutMs: 15_000, // hard budget; active destination mutation is joined
|
|
32
40
|
stripComponents: 0, // tar-style strip-leading-dirs
|
|
33
41
|
entryModes: "clamp", // default; use "preserve" for archive rwx bits
|
|
42
|
+
entryUmask: 0, // default; remove these bits from final modes
|
|
34
43
|
entryFilter: ({ path, kind, size }) => "extract",
|
|
35
44
|
onFiltered: "reject-archive", // default; opt into "skip-entry" explicitly
|
|
36
45
|
limits: {
|
|
@@ -50,7 +59,7 @@ await extractArchive({
|
|
|
50
59
|
type ExtractArchiveOptions = {
|
|
51
60
|
archivePath: string; // absolute path to the archive
|
|
52
61
|
destDir: string; // absolute destination directory; must already exist
|
|
53
|
-
timeoutMs: number; // positive
|
|
62
|
+
timeoutMs: number; // positive elapsed-time budget; <= 0/non-finite disables it
|
|
54
63
|
durable?: boolean; // false; opt into syncing published files and directories before completion
|
|
55
64
|
kind?: ArchiveKind; // "zip" | "tar" | "tar-zstd" | "tar-bzip2"
|
|
56
65
|
stripComponents?: number; // strip N leading dirs from entry paths
|
|
@@ -58,6 +67,7 @@ type ExtractArchiveOptions = {
|
|
|
58
67
|
limits?: ArchiveExtractLimits;
|
|
59
68
|
logger?: ArchiveLogger; // { info?, warn? }
|
|
60
69
|
entryModes?: "clamp" | "preserve";
|
|
70
|
+
entryUmask?: number; // integer 0..0o777; defaults to 0
|
|
61
71
|
entryFilter?: (entry: { path: string; kind: ArchiveEntryKind; size: number }) =>
|
|
62
72
|
"extract" | "skip";
|
|
63
73
|
onFiltered?: "reject-archive" | "skip-entry";
|
|
@@ -71,6 +81,12 @@ once, deepest first, and finally the destination directory. All work stays insid
|
|
|
71
81
|
the extraction deadline; active syncs are joined before rejection. File sync
|
|
72
82
|
failures use the same error surface as `Root.copyIn()`; directory I/O failures
|
|
73
83
|
also reject, with the existing platform limitations on directory flushing.
|
|
84
|
+
|
|
85
|
+
Deadline checks use a monotonic clock, including before queued mutations start
|
|
86
|
+
and before reporting success. Synchronous caller code can delay the timer, but
|
|
87
|
+
cannot permit the next operation after the budget expires. This does not
|
|
88
|
+
interrupt a callback halfway through execution or replace its own thrown error;
|
|
89
|
+
active destination mutations are still joined before timeout rejection.
|
|
74
90
|
Files whose final mode prevents reading, including `0o000` and write-only files,
|
|
75
91
|
sync once through the copy's retained descriptor during publication. Permissions
|
|
76
92
|
are never widened to reopen them. Directory modes are finalized after the file
|
|
@@ -103,6 +119,15 @@ including a mode containing only stripped special bits, stays zero under
|
|
|
103
119
|
directories; ZIP UNIX creator records with zero attributes are explicit zero,
|
|
104
120
|
while non-UNIX ZIP records use the absent-metadata defaults.
|
|
105
121
|
|
|
122
|
+
`entryUmask` removes permission bits after the selected mode policy: final modes
|
|
123
|
+
are the policy result `& ~entryUmask`. It applies to files, explicit directories,
|
|
124
|
+
and implicit parent directories, including existing destination directories.
|
|
125
|
+
The destination root and private staging modes are unchanged. The default `0`
|
|
126
|
+
preserves existing behavior; invalid masks reject before extraction begins.
|
|
127
|
+
fs-safe neither reads nor changes the process umask. Pass
|
|
128
|
+
`entryUmask: process.umask()` explicitly when that is the caller's policy.
|
|
129
|
+
Windows retains the POSIX-mode limitations described below.
|
|
130
|
+
|
|
106
131
|
TAR mode fields containing only NUL/ASCII-space padding use absent defaults.
|
|
107
132
|
Both backends recognize GNU binary modes, including signed values,
|
|
108
133
|
within JavaScript's safe-integer range before masking permission bits.
|
|
@@ -116,7 +141,7 @@ stay `0o600` and directories `0o700` until publication. Files receive their fina
|
|
|
116
141
|
mode through the guarded copy's owned writer descriptor. Directories are pinned
|
|
117
142
|
before descending and finalized after their children, including empty and
|
|
118
143
|
restrictive directories. Explicit accepted directory modes win regardless of
|
|
119
|
-
archive order; implicit parents receive `0o755`. Existing destination directories
|
|
144
|
+
archive order; implicit parents receive `0o755 & ~entryUmask`. Existing destination directories
|
|
120
145
|
also receive the requested final mode. They are never temporarily widened to
|
|
121
146
|
allow child writes; insufficient write/search access still rejects.
|
|
122
147
|
|
|
@@ -154,6 +179,13 @@ between native and JavaScript paths rather than reimplementing it in Rust.
|
|
|
154
179
|
|
|
155
180
|
ZIP extraction and bounded reads admit every physical central-directory record and its referenced local header before either decoder can normalize or collapse names. Raw names and valid Unicode Path names must pass traversal checks before stripping, filtering, or selecting a requested member; duplicate or colliding names reject with `entry-path`, even in unrelated or skipped members. Materially conflicting local/central or Unicode interpretations, malformed critical metadata, and ambiguous framing reject with `ArchiveFormatError`. Harmless internal separator and dot-component equivalence is allowed only after validation; every raw and Unicode interpretation must also agree on whether its name ends in `/` or `\`. Ordinary legacy filename decoding remains backend-selected. Native ZIP extraction groups nearby metadata reads into at most two 4 KiB read-ahead buffers per admission pass; larger records retain separately bounded reads. Buffered record views remain stable across eviction, and cached work periodically yields for deadline checks.
|
|
156
181
|
|
|
182
|
+
ZIP end-record admission searches the bounded comment window for signatures
|
|
183
|
+
while retaining complete comment-length and ambiguity checks. Dense signature
|
|
184
|
+
sequences fall back to the bounded byte scan.
|
|
185
|
+
The separate `readZipCentralDirectoryEntryCount(buffer)` hint uses bounded
|
|
186
|
+
reverse searches for comments and retains its latest-valid-record selection;
|
|
187
|
+
it does not replace strict archive admission.
|
|
188
|
+
|
|
157
189
|
ZIP admission establishes each entry's kind before callbacks: a high-word UNIX
|
|
158
190
|
symlink type takes precedence regardless of creator, followed by the DOS directory
|
|
159
191
|
bit, the exact UNIX directory type, or a terminal slash/backslash. Native manifests
|
|
@@ -185,6 +217,10 @@ decoded validation. Unicode Path admission is shared only when both the raw name
|
|
|
185
217
|
and the complete Unicode fields match; different fields still verify their own
|
|
186
218
|
CRC and interpretation. Shared backing memory is checked independently. Decoded
|
|
187
219
|
name validation is not reused across entries or archives.
|
|
220
|
+
UTF-8-flagged ASCII names in nonshared backing memory reuse their raw-path
|
|
221
|
+
validation, and an identical decoded spelling reuses its canonical key. Shared
|
|
222
|
+
name bytes still undergo independent decoding and validation; Unicode Path
|
|
223
|
+
fields retain their own CRC and interpretation checks.
|
|
188
224
|
|
|
189
225
|
`stripComponents` removes leading nonempty, non-`.` path components after
|
|
190
226
|
normalizing separators. For example, `./pkg/hello.txt` with
|
|
@@ -202,6 +238,9 @@ directory paths. For example, `./pkg//state\cache/value` is presented as
|
|
|
202
238
|
`pkg/state/cache/value`, even with `stripComponents: 1`. Case and Unicode
|
|
203
239
|
spelling are preserved. Local PAX `path`, GNU long-name, and supported ZIP
|
|
204
240
|
Unicode Path names use the same canonicalization.
|
|
241
|
+
Callbacks follow physical archive order, including ZIP names that look like
|
|
242
|
+
integer object keys. The public ZIP loader's `files` object retains ordinary
|
|
243
|
+
JavaScript object enumeration and mutation behavior.
|
|
205
244
|
|
|
206
245
|
Raw paths undergo traversal, absolute/drive-path, and NUL validation **before**
|
|
207
246
|
canonicalization; normalization cannot turn an unsafe path into an accepted
|
package/docs/atomic.md
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
|
|
17
17
|
Write `content` to a sibling temp file in the destination directory, apply the parent-directory and final file modes through verified descriptors, optionally `fsync` the file descriptor, optionally `fsync` the parent directory after rename, then atomically rename over the destination. No permission change follows a caller-supplied pathname.
|
|
18
18
|
|
|
19
|
-
On POSIX, the parent is opened with no-follow and directory-only flags, checked against its pre-open identity, and mode-adjusted through that descriptor. A replacement symlink is rejected rather than followed. If the directory cannot be opened for descriptor access, the operation fails closed instead of retrying by pathname. Windows does not enforce POSIX directory modes and Node cannot consistently open directory descriptors there, so `dirMode` is passed only to `mkdir`; no pathname `chmod` fallback is attempted.
|
|
19
|
+
On POSIX, the parent is opened with no-follow and directory-only flags, checked against its exact pre-open device/inode identity, and mode-adjusted through that descriptor. A replacement symlink is rejected rather than followed. If the directory cannot be opened for descriptor access, the operation fails closed instead of retrying by pathname. Windows does not enforce POSIX directory modes and Node cannot consistently open directory descriptors there, so `dirMode` is passed only to `mkdir`; no pathname `chmod` fallback is attempted.
|
|
20
20
|
|
|
21
21
|
Async replacements to the same destination are serialized inside the current process, so two overlapping `replaceFileAtomic()` calls do not interleave their temp-write/rename phases. Use a sidecar lock when multiple processes may write the same target.
|
|
22
22
|
|
|
@@ -92,10 +92,13 @@ await replaceFileAtomic({
|
|
|
92
92
|
|
|
93
93
|
If `beforeRename` throws, the rename is skipped and the owned temp file is removed — the destination is unchanged. Cleanup unlinks only the exact admitted single-link file; a substitute observed at the temp name is preserved and removed from cleanup authority. The same identity is rechecked before every rename retry, when entering copy fallback, and at the final name after rename. A post-rename verification failure reports the race without rolling back or deleting the published name.
|
|
94
94
|
|
|
95
|
-
JavaScript permits `beforeRename` callbacks to throw any value, including
|
|
95
|
+
JavaScript permits `beforeRename` callbacks and filesystem adapters to throw any value, including
|
|
96
96
|
`undefined`, `null`, `false`, signed zero, `0n`, an empty string, and `NaN`.
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
Atomic replacement preserves such operational failures when cleanup and close
|
|
98
|
+
succeed, including rename and post-rename verification failures. Rename retry
|
|
99
|
+
and copy-fallback classification reads the error code once without coercion;
|
|
100
|
+
missing or unreadable codes preserve the original failure. A rejected call has
|
|
101
|
+
no success receipt even if an adapter committed its rename before throwing. With
|
|
99
102
|
`throwOnCleanupError: true`, an additional owned-temp cleanup failure keeps the
|
|
100
103
|
existing cleanup wrapper whose `cause` is the original thrown value. A later
|
|
101
104
|
descriptor-close failure is reported in an `AggregateError`, in operation/cleanup
|
|
@@ -150,6 +153,28 @@ must not have aliases. The policy reads `nlink` from a pinned destination
|
|
|
150
153
|
descriptor, not pathname metadata, before rename and rechecks it in the copy
|
|
151
154
|
fallback.
|
|
152
155
|
|
|
156
|
+
The asynchronous helper closes a successfully admitted hardlink-check pin
|
|
157
|
+
best-effort, including synchronous adapter throws and rejected close promises.
|
|
158
|
+
The synchronous helper reports a close failure after successful admission.
|
|
159
|
+
|
|
160
|
+
Source and pinned destination admission compare exact bigint device/inode
|
|
161
|
+
observations, so distinct identities that round to the same JavaScript number
|
|
162
|
+
cannot authorize a copy. Unknown Windows identities get one bounded reinspection
|
|
163
|
+
of the same descriptor or path; incomplete or inconsistent observations fail
|
|
164
|
+
closed without reopening. Injected filesystem adapters must honor the
|
|
165
|
+
`{ bigint: true }` stat option. Source admission reuses that exact pair instead
|
|
166
|
+
of immediately repeating it with numeric metadata.
|
|
167
|
+
|
|
168
|
+
Copy-source close is best-effort. A failed pinned-destination admission also
|
|
169
|
+
preserves its selected failure when close fails. These cleanup rules include
|
|
170
|
+
synchronous throws and rejected promises from custom asynchronous adapters.
|
|
171
|
+
|
|
172
|
+
The best-effort parent-directory synchronization helper also ignores either form
|
|
173
|
+
of close failure. Parent-directory mode admission and its close remain fail-closed.
|
|
174
|
+
A compatibility-publication handle that was not adopted also receives one
|
|
175
|
+
best-effort close, preserving the selected verification or previous-handle close
|
|
176
|
+
failure. The retained owner's close failures remain reportable.
|
|
177
|
+
|
|
153
178
|
The default `copyFallbackRestore: "none"` preserves the existing fallback
|
|
154
179
|
contract: a failed copy can leave a partial destination. For state files where
|
|
155
180
|
preserving the old bytes is more important, choose `"restore-original"` and set
|
|
@@ -349,7 +374,10 @@ the preflight cap fails with `FsSafeError("too-large")`.
|
|
|
349
374
|
If another writer changes source entries during the fallback, the staged copy
|
|
350
375
|
throws `ESTALE` before commit when possible. If the destination has already
|
|
351
376
|
been committed, cleanup still preserves the changed source entries and throws
|
|
352
|
-
`ESTALE`.
|
|
377
|
+
`ESTALE`. Copied file and symlink manifests retain exact bigint identities and
|
|
378
|
+
nanosecond timestamps, so rounded file IDs cannot authorize copying or removal
|
|
379
|
+
of a different entry. Hardlink groups also use exact identities. Directory
|
|
380
|
+
manifests retain an exact bigint device/inode receipt from
|
|
353
381
|
copy admission. Each directory is rechecked after traversal, and the source root
|
|
354
382
|
is checked again before publication. Cleanup checks the same receipt before
|
|
355
383
|
removing children, then invokes mutation authority and rechecks the receipt and
|
|
@@ -366,6 +394,11 @@ unlink is verified through a remaining manifested alias and its exact resulting
|
|
|
366
394
|
identity becomes the next cleanup receipt. This accounts for the operation's
|
|
367
395
|
own link-count and ctime changes without suppressing unexpected external
|
|
368
396
|
mutations.
|
|
397
|
+
On Windows, opening a regular source may advance its ctime while all other
|
|
398
|
+
fingerprint fields match. That exception applies only to opening; post-copy
|
|
399
|
+
verification and cleanup retain their full fingerprint checks.
|
|
400
|
+
Copied aliases share each verified open-time update. Changes observed between
|
|
401
|
+
copies still reject instead of being mistaken for an owned open transition.
|
|
369
402
|
|
|
370
403
|
### Mutation authority and publication receipts
|
|
371
404
|
|
|
@@ -404,6 +437,11 @@ thenable, or any other value fails with a `TypeError`; rejected asynchronous
|
|
|
404
437
|
results are consumed. Perform asynchronous policy checks before calling the
|
|
405
438
|
helper and use the authority callback to recheck the current owner at each
|
|
406
439
|
mutation boundary. All callbacks are captured before the first await.
|
|
440
|
+
Copied source leaves are checked again immediately after authority returns and
|
|
441
|
+
before unlink is submitted. Supplying any of the three callbacks also
|
|
442
|
+
retains the original source-parent route and renews copied-directory ancestry
|
|
443
|
+
before cleanup. Substituted entries are preserved; pathname checks and unlink
|
|
444
|
+
remain a best-effort sequence, not atomic.
|
|
407
445
|
|
|
408
446
|
`onDestinationPublished` runs exactly once after a successful rename resolves,
|
|
409
447
|
before awaited post-rename directory checks or source cleanup. It receives a
|
package/docs/contributing.md
CHANGED
|
@@ -157,6 +157,10 @@ pnpm archive:producer-smoke ./consumer require
|
|
|
157
157
|
This uses a child bound to canonical cwd/device/inode running `/usr/bin/tar -czf - .`
|
|
158
158
|
with unchanged stdout, and npm tar, on synthetic Unicode/newline/long-name files,
|
|
159
159
|
then the installed package API for exact payload hashes and bounded reads.
|
|
160
|
+
The consumer must be separate from the source checkout; package resolution must
|
|
161
|
+
stay within its own `node_modules`, including pnpm's local `.pnpm` layout.
|
|
162
|
+
Workspace self-resolution, upward resolution, and external package links reject
|
|
163
|
+
before package imports or archive fixture creation.
|
|
160
164
|
It also rejects a valid PAX override attached to an invalid raw UTF-8 field.
|
|
161
165
|
The `require` command must resolve the freshly packed native binding; the
|
|
162
166
|
`off` command uses the installed WASM asset. No live user files are read.
|
package/docs/copy.md
CHANGED
|
@@ -178,6 +178,8 @@ These are low-level operations on caller-owned absolute paths, not Root-relative
|
|
|
178
178
|
|
|
179
179
|
An already aborted signal prevents dispatch. In-flight cancellation stops cancellable traversal and waits for admitted native writes to finish before rejecting. APFS and Btrfs bulk operations cannot be interrupted once dispatched. An aborted or failed call can therefore leave a destination, including a complete bulk clone. It remains caller-owned; after settlement, the caller decides whether to retain or remove it. Do not start cleanup by racing the cloning promise against an abort promise.
|
|
180
180
|
|
|
181
|
+
Tree copying preserves caller abort handlers and receives cancellation even when a caller handler stops event propagation, including native cloning and byte-copy fallbacks.
|
|
182
|
+
|
|
181
183
|
Completion is not a crash-durability guarantee. The API is suitable for reconstructible templates and checkouts; it does not sync every file or replace application-level publication and recovery rules.
|
|
182
184
|
|
|
183
185
|
A close-only rejection reports descriptor settlement, not whether bytes reached stable storage. The destination can already be complete when a close fails, just as other failed or cancelled calls can leave caller-owned output. Inspect or remove that output only after the copying promise settles and under the same source and destination authority assumptions.
|
package/docs/creation.md
CHANGED
|
@@ -42,12 +42,16 @@ POSIX creation requests `0700` for directories and `0600` for files by default;
|
|
|
42
42
|
the umask may restrict those permissions further. Existing directory privacy
|
|
43
43
|
checks never broaden permissions.
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
Private POSIX `Root.create()` and `createJson()` writes check the retained descriptor's actual owner and
|
|
46
46
|
permissions before writing payload bytes, after producer and authority callbacks,
|
|
47
|
-
and at publication
|
|
47
|
+
and at publication, including JavaScript fallback writes. Payload writes require
|
|
48
|
+
the temporary `0600` mode even when the requested final mode differs.
|
|
49
|
+
Private ownership, permissions and ACLs are checked before preparing that mode,
|
|
50
|
+
including after authority callbacks; valid restrictive initial modes remain supported.
|
|
51
|
+
A successful `chmod` is insufficient: filesystems that do not
|
|
48
52
|
enforce owner-only permissions reject before payload writes. The requested final
|
|
49
53
|
mode is verified too; a failure after publication preserves the completed file
|
|
50
|
-
and reports its published outcome.
|
|
54
|
+
and staged creation reports its published outcome.
|
|
51
55
|
|
|
52
56
|
On macOS (Darwin), private creation also requires an ACL-free result. The native
|
|
53
57
|
helper must provide `inspectDarwinAcl`; native `off`, a missing helper, or an
|
|
@@ -113,7 +117,7 @@ thenables reject before mutation. Parent and file identity checks are repeated
|
|
|
113
117
|
after the callback. Final permission checks, descriptor settlement and cleanup
|
|
114
118
|
retain the operation's cleanup ownership after publication.
|
|
115
119
|
|
|
116
|
-
Failure does not always mean the final path is absent.
|
|
120
|
+
Failure does not always mean the final path is absent. Staged private-file errors
|
|
117
121
|
after publication or ambiguous publication preserve the destination and carry
|
|
118
122
|
`details.publication.status` (`published` or `indeterminate`), the target path and
|
|
119
123
|
staging cleanup outcome. Cleanup and close failures retain the original error
|
package/docs/durability.md
CHANGED
|
@@ -89,6 +89,29 @@ or reconstructed numeric identity is accepted only when both components are
|
|
|
89
89
|
safe integers and, on Windows, nonzero. Rounded or unknown caller identities
|
|
90
90
|
fail with `path-mismatch` rather than authorizing a different directory.
|
|
91
91
|
|
|
92
|
+
Caller-supplied receipts may use `DirectoryReceipt<BigIntStats>` with the result
|
|
93
|
+
of `lstat(path, { bigint: true })`. `pinDirectory()`, `syncDirectory()`,
|
|
94
|
+
`syncDirectorySync()`, `publishFileExclusive()`'s `parentReceipt`, and
|
|
95
|
+
`stageFileInDirectory()` accept both numeric and bigint receipt inputs.
|
|
96
|
+
`DirectoryReceipt` without a type argument and all returned durability receipts
|
|
97
|
+
still expose numeric `Stats`, including working type predicates and Date
|
|
98
|
+
properties. Bigint metadata is projected from the supplied observation, retaining
|
|
99
|
+
fractional timestamps and the private exact device/inode identity.
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import { lstatSync, realpathSync, type BigIntStats } from "node:fs";
|
|
103
|
+
import { syncDirectorySync, type DirectoryReceipt } from "@openclaw/fs-safe/durability";
|
|
104
|
+
|
|
105
|
+
const directoryPath = "/srv/backups/sqlite";
|
|
106
|
+
const receipt: DirectoryReceipt<BigIntStats> = {
|
|
107
|
+
path: directoryPath,
|
|
108
|
+
realPath: realpathSync(directoryPath),
|
|
109
|
+
identity: lstatSync(directoryPath, { bigint: true }),
|
|
110
|
+
};
|
|
111
|
+
// Keep this receipt across the application's publication operation.
|
|
112
|
+
const outcome = syncDirectorySync(receipt);
|
|
113
|
+
```
|
|
114
|
+
|
|
92
115
|
Call `close()` in `finally`. Closing is idempotent; using a closed pin fails.
|
|
93
116
|
|
|
94
117
|
These checks intentionally reject a moved or replaced pathname. For one file's
|
|
@@ -276,6 +299,11 @@ pathname without reopening the file and repeat the symlink and file-type checks.
|
|
|
276
299
|
POSIX opens are nonblocking, so a raced FIFO or device is rejected after
|
|
277
300
|
descriptor inspection rather than waiting for a writer.
|
|
278
301
|
|
|
302
|
+
A pathname hash reports failure to close its owned descriptor after successful
|
|
303
|
+
hashing. If hashing, admission, or cancellation already failed, that original
|
|
304
|
+
failure remains primary even when close also fails. This also applies to
|
|
305
|
+
`sha256FileSync()`; borrowed handles and descriptors remain caller-owned.
|
|
306
|
+
|
|
279
307
|
When the optional binding is active, hashing runs as an async native task and
|
|
280
308
|
does not occupy the JavaScript event loop with digest updates. With native mode
|
|
281
309
|
`off`, or in `auto` when no binding loads, the fallback performs asynchronous
|
|
@@ -347,6 +375,13 @@ this receipt instead of inferring ownership from path existence. The original
|
|
|
347
375
|
failure remains available as `cause`. Failures before target creation retain
|
|
348
376
|
their existing error shape and do not claim a cleanup result.
|
|
349
377
|
|
|
378
|
+
Source and target identities are checked again after successful or unsupported
|
|
379
|
+
directory synchronization, while their descriptors remain owned. A late
|
|
380
|
+
verification failure retains its strategy's verification phase and is not a
|
|
381
|
+
directory-sync failure. Completed copied targets stay pinned during conditional
|
|
382
|
+
cleanup; substituted entries remain untouched. Returned numeric metadata comes
|
|
383
|
+
from the retained target descriptor and grants no continuing pathname authority.
|
|
384
|
+
|
|
350
385
|
### Directory-sync failure policy
|
|
351
386
|
|
|
352
387
|
`onSyncFailure` applies only after target creation and content/identity fencing
|