@openclaw/fs-safe 0.10.0 → 0.12.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 +114 -0
- package/LICENSE +1 -0
- package/README.md +39 -6
- package/dist/absolute-path.d.ts.map +1 -1
- package/dist/absolute-path.js +3 -2
- package/dist/advanced.d.ts +5 -1
- package/dist/advanced.d.ts.map +1 -1
- package/dist/advanced.js +5 -1
- package/dist/archive-durability.d.ts +6 -6
- package/dist/archive-durability.d.ts.map +1 -1
- package/dist/archive-durability.js +1 -1
- package/dist/archive-entry.d.ts.map +1 -1
- package/dist/archive-entry.js +8 -8
- package/dist/archive-gzip-tail.d.ts +1 -0
- package/dist/archive-gzip-tail.d.ts.map +1 -1
- package/dist/archive-gzip-tail.js +16 -9
- package/dist/archive-input.d.ts.map +1 -1
- package/dist/archive-input.js +4 -2
- package/dist/archive-merge.d.ts +5 -1
- package/dist/archive-merge.d.ts.map +1 -1
- package/dist/archive-merge.js +15 -12
- package/dist/archive-native.js +4 -4
- package/dist/archive-parser.wasm +0 -0
- package/dist/archive-read.d.ts.map +1 -1
- package/dist/archive-read.js +54 -42
- package/dist/archive-staging.d.ts +6 -3
- package/dist/archive-staging.d.ts.map +1 -1
- package/dist/archive-staging.js +42 -22
- package/dist/archive-tar-stream.d.ts.map +1 -1
- package/dist/archive-tar-stream.js +7 -6
- package/dist/archive-tar-wasm.d.ts.map +1 -1
- package/dist/archive-tar-wasm.js +16 -13
- package/dist/archive-zip-admission.d.ts +1 -1
- package/dist/archive-zip-admission.d.ts.map +1 -1
- package/dist/archive-zip-admission.js +48 -12
- package/dist/archive-zip-loader.d.ts +6 -0
- package/dist/archive-zip-loader.d.ts.map +1 -0
- package/dist/archive-zip-loader.js +38 -0
- package/dist/archive-zip-names.d.ts.map +1 -1
- package/dist/archive-zip-names.js +26 -9
- package/dist/archive-zip-preflight.d.ts +2 -3
- package/dist/archive-zip-preflight.d.ts.map +1 -1
- package/dist/archive-zip-preflight.js +2 -34
- package/dist/archive.d.ts.map +1 -1
- package/dist/archive.js +12 -10
- package/dist/bounded-read.d.ts +5 -0
- package/dist/bounded-read.d.ts.map +1 -1
- package/dist/bounded-read.js +18 -11
- package/dist/copy-file-input.d.ts +0 -1
- package/dist/copy-file-input.d.ts.map +1 -1
- package/dist/copy-file-input.js +4 -26
- package/dist/copy-tree-portable.d.ts.map +1 -1
- package/dist/copy-tree-portable.js +57 -26
- package/dist/copy.d.ts +1 -1
- package/dist/copy.d.ts.map +1 -1
- package/dist/copy.js +3 -1
- package/dist/device-path.d.ts.map +1 -1
- package/dist/device-path.js +5 -3
- package/dist/directory-durability.d.ts.map +1 -1
- package/dist/directory-durability.js +5 -4
- package/dist/directory-guard.d.ts +11 -1
- package/dist/directory-guard.d.ts.map +1 -1
- package/dist/directory-guard.js +53 -11
- package/dist/durability.d.ts +1 -1
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +1 -1
- package/dist/file-handle-transfer.d.ts +14 -0
- package/dist/file-handle-transfer.d.ts.map +1 -0
- package/dist/file-handle-transfer.js +64 -0
- package/dist/file-hash.d.ts +3 -0
- package/dist/file-hash.d.ts.map +1 -1
- package/dist/file-hash.js +99 -32
- package/dist/file-lock-sync.d.ts.map +1 -1
- package/dist/file-lock-sync.js +8 -4
- package/dist/file-store-boundary.d.ts.map +1 -1
- package/dist/file-store-boundary.js +7 -5
- package/dist/file-store-path.d.ts +3 -0
- package/dist/file-store-path.d.ts.map +1 -0
- package/dist/file-store-path.js +27 -0
- package/dist/file-store-prune.d.ts.map +1 -1
- package/dist/file-store-prune.js +15 -5
- package/dist/file-store-sync-write.d.ts.map +1 -1
- package/dist/file-store-sync-write.js +56 -44
- package/dist/file-store.d.ts.map +1 -1
- package/dist/file-store.js +2 -18
- package/dist/filename.d.ts +1 -0
- package/dist/filename.d.ts.map +1 -1
- package/dist/filename.js +32 -14
- package/dist/guarded-mkdir.d.ts +2 -0
- package/dist/guarded-mkdir.d.ts.map +1 -1
- package/dist/guarded-mkdir.js +52 -16
- package/dist/guest-dispatch-python.d.ts +2 -0
- package/dist/guest-dispatch-python.d.ts.map +1 -0
- package/dist/guest-dispatch-python.js +117 -0
- package/dist/guest-native-python.d.ts +4 -0
- package/dist/guest-native-python.d.ts.map +1 -0
- package/dist/guest-native-python.js +135 -0
- package/dist/guest.d.ts +9 -0
- package/dist/guest.d.ts.map +1 -0
- package/dist/guest.js +421 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/install-path.d.ts +6 -0
- package/dist/install-path.d.ts.map +1 -1
- package/dist/install-path.js +16 -2
- package/dist/json-durable-queue-directory.js +3 -3
- package/dist/json-durable-queue-ownership.d.ts +2 -0
- package/dist/json-durable-queue-ownership.d.ts.map +1 -1
- package/dist/json-durable-queue-ownership.js +47 -3
- package/dist/json-durable-queue-read.d.ts +6 -0
- package/dist/json-durable-queue-read.d.ts.map +1 -0
- package/dist/json-durable-queue-read.js +59 -0
- package/dist/json-durable-queue.d.ts +1 -1
- package/dist/json-durable-queue.d.ts.map +1 -1
- package/dist/json-durable-queue.js +43 -84
- package/dist/json.d.ts.map +1 -1
- package/dist/json.js +2 -1
- package/dist/local-roots.d.ts.map +1 -1
- package/dist/local-roots.js +2 -1
- package/dist/move-path-stage.d.ts.map +1 -1
- package/dist/move-path-stage.js +2 -1
- package/dist/move-path.d.ts.map +1 -1
- package/dist/move-path.js +4 -3
- package/dist/mutation-authority.d.ts +1 -0
- package/dist/mutation-authority.d.ts.map +1 -1
- package/dist/mutation-authority.js +4 -4
- package/dist/native-binding.d.ts +14 -2
- package/dist/native-binding.d.ts.map +1 -1
- package/dist/native-pinned-write-windows.d.ts.map +1 -1
- package/dist/native-pinned-write-windows.js +3 -2
- package/dist/native-pinned-write.d.ts.map +1 -1
- package/dist/native-pinned-write.js +2 -1
- package/dist/opened-realpath.d.ts.map +1 -1
- package/dist/opened-realpath.js +5 -4
- package/dist/output.d.ts +2 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +2 -0
- package/dist/overwrite-file-handle.d.ts +8 -0
- package/dist/overwrite-file-handle.d.ts.map +1 -0
- package/dist/overwrite-file-handle.js +42 -0
- package/dist/path-case.d.ts +7 -0
- package/dist/path-case.d.ts.map +1 -0
- package/dist/path-case.js +136 -0
- package/dist/path-scope-lexical.d.ts +14 -0
- package/dist/path-scope-lexical.d.ts.map +1 -0
- package/dist/path-scope-lexical.js +27 -0
- package/dist/path.d.ts.map +1 -1
- package/dist/path.js +22 -3
- package/dist/permissions-windows.d.ts +1 -1
- package/dist/permissions-windows.d.ts.map +1 -1
- package/dist/permissions-windows.js +48 -6
- package/dist/pinned-open.d.ts.map +1 -1
- package/dist/pinned-open.js +3 -1
- package/dist/pinned-write.d.ts +2 -2
- package/dist/pinned-write.d.ts.map +1 -1
- package/dist/pinned-write.js +3 -1
- package/dist/private-temp-workspace.d.ts.map +1 -1
- package/dist/private-temp-workspace.js +6 -4
- package/dist/realpath.d.ts +4 -0
- package/dist/realpath.d.ts.map +1 -0
- package/dist/realpath.js +43 -0
- package/dist/recursive-mkdir-path.d.ts +3 -0
- package/dist/recursive-mkdir-path.d.ts.map +1 -0
- package/dist/recursive-mkdir-path.js +8 -0
- package/dist/replace-directory.d.ts.map +1 -1
- package/dist/replace-directory.js +2 -1
- package/dist/replace-file-copy-fallback.d.ts.map +1 -1
- package/dist/replace-file-copy-fallback.js +23 -31
- package/dist/replace-file-copy-source.d.ts.map +1 -1
- package/dist/replace-file-copy-source.js +7 -12
- package/dist/replace-file-mode.d.ts +3 -0
- package/dist/replace-file-mode.d.ts.map +1 -0
- package/dist/replace-file-mode.js +10 -0
- package/dist/replace-file.d.ts +1 -0
- package/dist/replace-file.d.ts.map +1 -1
- package/dist/replace-file.js +14 -8
- package/dist/root-boundary.d.ts +25 -0
- package/dist/root-boundary.d.ts.map +1 -0
- package/dist/root-boundary.js +177 -0
- package/dist/root-context.d.ts.map +1 -1
- package/dist/root-context.js +40 -13
- package/dist/root-create-input.d.ts +10 -0
- package/dist/root-create-input.d.ts.map +1 -0
- package/dist/root-create-input.js +80 -0
- package/dist/root-directory-list.d.ts +3 -1
- package/dist/root-directory-list.d.ts.map +1 -1
- package/dist/root-directory-list.js +31 -5
- package/dist/root-entries.d.ts +11 -0
- package/dist/root-entries.d.ts.map +1 -0
- package/dist/root-entries.js +61 -0
- package/dist/root-errors.d.ts +5 -5
- package/dist/root-errors.d.ts.map +1 -1
- package/dist/root-errors.js +13 -12
- package/dist/root-impl.d.ts +13 -3
- package/dist/root-impl.d.ts.map +1 -1
- package/dist/root-impl.js +93 -70
- package/dist/root-move-preflight.d.ts +8 -0
- package/dist/root-move-preflight.d.ts.map +1 -0
- package/dist/root-move-preflight.js +16 -0
- package/dist/root-options.d.ts +12 -1
- package/dist/root-options.d.ts.map +1 -1
- package/dist/root-path-existing.d.ts +2 -0
- package/dist/root-path-existing.d.ts.map +1 -1
- package/dist/root-path-existing.js +14 -5
- package/dist/root-path-symlink.d.ts.map +1 -1
- package/dist/root-path-symlink.js +3 -2
- package/dist/root-path.d.ts +2 -0
- package/dist/root-path.d.ts.map +1 -1
- package/dist/root-path.js +54 -26
- package/dist/root-paths.d.ts +2 -6
- package/dist/root-paths.d.ts.map +1 -1
- package/dist/root-paths.js +24 -32
- package/dist/root-remove.d.ts +5 -0
- package/dist/root-remove.d.ts.map +1 -0
- package/dist/root-remove.js +286 -0
- package/dist/root-symlink-policy.d.ts +2 -1
- package/dist/root-symlink-policy.d.ts.map +1 -1
- package/dist/root-symlink-policy.js +2 -2
- package/dist/root-walk.d.ts.map +1 -1
- package/dist/root-walk.js +2 -1
- package/dist/root-write-mode.d.ts +2 -0
- package/dist/root-write-mode.d.ts.map +1 -1
- package/dist/root-write-mode.js +21 -7
- package/dist/root-write-verification.d.ts.map +1 -1
- package/dist/root-write-verification.js +12 -3
- package/dist/root.d.ts +2 -1
- package/dist/root.d.ts.map +1 -1
- package/dist/safe-path-segment.d.ts.map +1 -1
- package/dist/safe-path-segment.js +3 -1
- package/dist/secret-file.d.ts.map +1 -1
- package/dist/secret-file.js +2 -1
- package/dist/secret-read-async.d.ts.map +1 -1
- package/dist/secret-read-async.js +2 -1
- package/dist/secure-file-windows.d.ts +10 -0
- package/dist/secure-file-windows.d.ts.map +1 -0
- package/dist/secure-file-windows.js +186 -0
- package/dist/secure-file.d.ts.map +1 -1
- package/dist/secure-file.js +27 -7
- package/dist/secure-temp-dir.d.ts.map +1 -1
- package/dist/secure-temp-dir.js +2 -1
- package/dist/sibling-staged-file.d.ts +2 -0
- package/dist/sibling-staged-file.d.ts.map +1 -1
- package/dist/sibling-staged-file.js +49 -8
- package/dist/sibling-temp.d.ts +2 -0
- package/dist/sibling-temp.d.ts.map +1 -1
- package/dist/sibling-temp.js +8 -5
- package/dist/sidecar-lock-acquire.d.ts.map +1 -1
- package/dist/sidecar-lock-acquire.js +16 -5
- package/dist/sidecar-lock-policy.d.ts +2 -0
- package/dist/sidecar-lock-policy.d.ts.map +1 -1
- package/dist/sidecar-lock-policy.js +17 -0
- package/dist/sidecar-lock.d.ts.map +1 -1
- package/dist/sidecar-lock.js +2 -3
- package/dist/staged-directory.d.ts.map +1 -1
- package/dist/staged-directory.js +4 -3
- package/dist/temp-target.d.ts +14 -12
- package/dist/temp-target.d.ts.map +1 -1
- package/dist/temp-target.js +15 -7
- package/dist/trash.d.ts.map +1 -1
- package/dist/trash.js +7 -5
- package/dist/unicode-path.d.ts +3 -0
- package/dist/unicode-path.d.ts.map +1 -0
- package/dist/unicode-path.js +13 -0
- package/dist/walk.d.ts.map +1 -1
- package/dist/walk.js +14 -12
- package/dist/write-file-handle.d.ts +1 -0
- package/dist/write-file-handle.d.ts.map +1 -1
- package/dist/write-file-handle.js +3 -2
- package/docs/advanced.md +7 -1
- package/docs/archive.md +31 -5
- package/docs/atomic.md +17 -1
- package/docs/config.md +1 -0
- package/docs/contributing.md +33 -2
- package/docs/copy.md +75 -6
- package/docs/directory-identity.md +85 -0
- package/docs/durability.md +40 -3
- package/docs/entries.md +109 -0
- package/docs/errors.md +3 -3
- package/docs/file-store.md +21 -0
- package/docs/filename.md +9 -2
- package/docs/guest.md +146 -0
- package/docs/in-place-write.md +81 -0
- package/docs/index.md +2 -0
- package/docs/install-path.md +59 -13
- package/docs/install.md +34 -0
- package/docs/native-helper.md +14 -5
- package/docs/native.md +18 -2
- package/docs/output.md +32 -6
- package/docs/path-case.md +64 -0
- package/docs/path-scope.md +1 -1
- package/docs/path.md +1 -1
- package/docs/permissions.md +37 -3
- package/docs/public-api.md +36 -2
- package/docs/root.md +33 -3
- package/docs/secure-file.md +17 -14
- package/docs/security-model.md +1 -1
- package/docs/sidecar-lock.md +12 -3
- package/docs/store.md +22 -1
- package/docs/temp.md +39 -6
- package/docs/types.md +1 -1
- package/docs/writing.md +153 -3
- package/package.json +14 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-binding.d.ts","sourceRoot":"","sources":["../src/native-binding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAuB,SAAQ,kBAAkB;CAAG;AAErE,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,GAAG,iBAAiB,GAAG,MAAM,CAAC;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,eAAe,GAAG,aAAa,CAAC;CAC9C;AAED,MAAM,WAAW,4BAA4B;IAC3C,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,+BAA+B;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QACL,GAAG,EAAE,MAAM,CAAC;QACZ,aAAa,EAAE,OAAO,CAAC;QACvB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,kBAAkB,EAAE,OAAO,CAAC;QAC5B,WAAW,EAAE,OAAO,CAAC;QACrB,SAAS,EAAE,OAAO,CAAC;QACnB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,YAAY,EAAE,OAAO,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,IAAI,EAAE,+BAA+B,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,aAAa;IAC5B,
|
|
1
|
+
{"version":3,"file":"native-binding.d.ts","sourceRoot":"","sources":["../src/native-binding.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-pinned-write-windows.d.ts","sourceRoot":"","sources":["../src/native-pinned-write-windows.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAM3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAI3D,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,KAAK,CAAC,EAC3C,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,KAAK,CAAC,GAC3C,OAAO,CAET;AAWD,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,sBAAsB,GAClC,OAAO,CAAC,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"native-pinned-write-windows.d.ts","sourceRoot":"","sources":["../src/native-pinned-write-windows.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAM3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAI3D,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,KAAK,CAAC,EAC3C,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,KAAK,CAAC,GAC3C,OAAO,CAET;AAWD,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,sBAAsB,GAClC,OAAO,CAAC,gBAAgB,CAAC,CA0F3B"}
|
|
@@ -69,8 +69,9 @@ export async function runPinnedWriteWindows(binding, params, root, parentFd, par
|
|
|
69
69
|
catch (error) {
|
|
70
70
|
closeWriteFd(targetFd);
|
|
71
71
|
targetFd = undefined;
|
|
72
|
-
//
|
|
73
|
-
if (params.input.kind
|
|
72
|
+
// Staged copies and streamed creates preserve publication for caller recovery.
|
|
73
|
+
if (params.input.kind === "buffer" ||
|
|
74
|
+
(params.input.kind === "stream" && !params.input.stageBeforePublish)) {
|
|
74
75
|
removeNativeCreatedFileIfStillPinned({
|
|
75
76
|
parentPath,
|
|
76
77
|
parentFd,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-pinned-write.d.ts","sourceRoot":"","sources":["../src/native-pinned-write.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"native-pinned-write.d.ts","sourceRoot":"","sources":["../src/native-pinned-write.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAK3D,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA2FvH"}
|
|
@@ -59,6 +59,7 @@ import { runPinnedWriteWindows, sameNativeIdentity } from "./native-pinned-write
|
|
|
59
59
|
import { assertNativeStaging, writeNativeStage } from "./native-staged-file.js";
|
|
60
60
|
import { describeStagedDirectory, exactIdentityMatches } from "./staged-directory.js";
|
|
61
61
|
import { inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
62
|
+
import { realpathSync } from "./realpath.js";
|
|
62
63
|
export async function runPinnedWriteNative(binding, params) {
|
|
63
64
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
64
65
|
try {
|
|
@@ -104,7 +105,7 @@ export async function runPinnedWriteNative(binding, params) {
|
|
|
104
105
|
binding.mkdirBeneath(root.fd, params.relativeParentPath, 0o777);
|
|
105
106
|
}
|
|
106
107
|
parentFd = binding.openBeneath(root.fd, params.relativeParentPath, directoryFlags).fd;
|
|
107
|
-
const parentPath =
|
|
108
|
+
const parentPath = realpathSync.native(params.relativeParentPath
|
|
108
109
|
? path.join(params.rootPath, ...params.relativeParentPath.split("/"))
|
|
109
110
|
: params.rootPath);
|
|
110
111
|
const directory = windows ? undefined : describeStagedDirectory(parentFd, parentPath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opened-realpath.d.ts","sourceRoot":"","sources":["../src/opened-realpath.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,OAAO,EAAoB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"opened-realpath.d.ts","sourceRoot":"","sources":["../src/opened-realpath.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,OAAO,EAAoB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAI7E,wBAAsB,kCAAkC,CACtD,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,MAAM,EACV,UAAU,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACxC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC,CAAC;AACpD,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,gBAAgB,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,GAAG,WAAW,CAAA;CAAE,CAAC,CAAC"}
|
package/dist/opened-realpath.js
CHANGED
|
@@ -4,6 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
import { openedPathResolutionError } from "./opened-file-failure.js";
|
|
5
5
|
import { sameFileIdentity } from "./file-identity.js";
|
|
6
6
|
import { isNotFoundPathError } from "./path.js";
|
|
7
|
+
import { realpathSync } from "./realpath.js";
|
|
7
8
|
export async function resolveOpenedFileRealPathForHandle(handle, ioPath) {
|
|
8
9
|
const handleStat = fsSync.fstatSync(handle.fd);
|
|
9
10
|
return (await resolveOpenedFileRealPathForFd(handle.fd, handleStat, ioPath)).realPath;
|
|
@@ -16,7 +17,7 @@ export async function resolveOpenedFileRealPathForFd(fd, handleStat, ioPath) {
|
|
|
16
17
|
: [];
|
|
17
18
|
for (const fdPath of fdCandidates) {
|
|
18
19
|
try {
|
|
19
|
-
const fdRealPath =
|
|
20
|
+
const fdRealPath = realpathSync.native(fdPath);
|
|
20
21
|
const fdRealStat = statOptions ? fsSync.statSync(fdRealPath, statOptions) : fsSync.statSync(fdRealPath);
|
|
21
22
|
if (sameFileIdentity(handleStat, fdRealStat)) {
|
|
22
23
|
return { realPath: fdRealPath, stat: fdRealStat };
|
|
@@ -27,7 +28,7 @@ export async function resolveOpenedFileRealPathForFd(fd, handleStat, ioPath) {
|
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
try {
|
|
30
|
-
const ioRealPath =
|
|
31
|
+
const ioRealPath = realpathSync.native(ioPath);
|
|
31
32
|
const ioRealStat = statOptions ? fsSync.statSync(ioRealPath, statOptions) : fsSync.statSync(ioRealPath);
|
|
32
33
|
if (sameFileIdentity(handleStat, ioRealStat)) {
|
|
33
34
|
return { realPath: ioRealPath, stat: ioRealStat };
|
|
@@ -53,7 +54,7 @@ export async function resolveOpenedFileRealPathForFd(fd, handleStat, ioPath) {
|
|
|
53
54
|
async function resolveOpenedFileRealPathFromParent(handleStat, ioPath, statOptions) {
|
|
54
55
|
let parentReal;
|
|
55
56
|
try {
|
|
56
|
-
parentReal =
|
|
57
|
+
parentReal = realpathSync.native(path.dirname(ioPath));
|
|
57
58
|
}
|
|
58
59
|
catch (err) {
|
|
59
60
|
if (isNotFoundPathError(err)) {
|
|
@@ -76,7 +77,7 @@ async function resolveOpenedFileRealPathFromParent(handleStat, ioPath, statOptio
|
|
|
76
77
|
try {
|
|
77
78
|
const candidateStat = statOptions ? fsSync.lstatSync(candidatePath, statOptions) : fsSync.lstatSync(candidatePath);
|
|
78
79
|
if (candidateStat.isFile() && sameFileIdentity(handleStat, candidateStat)) {
|
|
79
|
-
const realPath =
|
|
80
|
+
const realPath = realpathSync.native(candidatePath);
|
|
80
81
|
const stat = statOptions ? fsSync.statSync(realPath, statOptions) : fsSync.statSync(realPath);
|
|
81
82
|
if (sameFileIdentity(handleStat, stat))
|
|
82
83
|
return { realPath, stat };
|
package/dist/output.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export type ExternalFileWriteOptions<T = void> = {
|
|
|
5
5
|
maxBytes?: number;
|
|
6
6
|
mode?: number;
|
|
7
7
|
staging?: "workspace" | "sibling";
|
|
8
|
+
/** Isolate sibling producers; workspace staging is already private. */
|
|
9
|
+
producerIsolation?: "private-directory";
|
|
8
10
|
fallbackFileName?: string;
|
|
9
11
|
};
|
|
10
12
|
export type ExternalFileWriteResult<T = void> = {
|
package/dist/output.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,wBAAwB,CAAC,CAAC,GAAG,IAAI,IAAI;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,uBAAuB,CAAC,CAAC,GAAG,IAAI,IAAI;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,CAAC,CAAC;CACX,CAAC;AAyDF,wBAAsB,2BAA2B,CAAC,CAAC,GAAG,IAAI,EACxD,OAAO,EAAE,wBAAwB,CAAC,CAAC,CAAC,GACnC,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,wBAAwB,CAAC,CAAC,GAAG,IAAI,IAAI;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAClC,uEAAuE;IACvE,iBAAiB,CAAC,EAAE,mBAAmB,CAAC;IACxC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,uBAAuB,CAAC,CAAC,GAAG,IAAI,IAAI;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,CAAC,CAAC;CACX,CAAC;AAyDF,wBAAsB,2BAA2B,CAAC,CAAC,GAAG,IAAI,EACxD,OAAO,EAAE,wBAAwB,CAAC,CAAC,CAAC,GACnC,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAiDrC"}
|
package/dist/output.js
CHANGED
|
@@ -74,6 +74,7 @@ export async function writeExternalFileWithinRoot(options) {
|
|
|
74
74
|
const result = await writeExternalFileViaSibling({
|
|
75
75
|
finalPath: siblingFinalPath,
|
|
76
76
|
write: options.write,
|
|
77
|
+
producerIsolation: options.producerIsolation,
|
|
77
78
|
fallbackFileName: options.fallbackFileName,
|
|
78
79
|
maxBytes,
|
|
79
80
|
mode: options.mode,
|
|
@@ -113,6 +114,7 @@ async function writeExternalFileViaSibling(params) {
|
|
|
113
114
|
const { result } = await writeCallbackSibling({
|
|
114
115
|
tempPath: buildSiblingTempPath(finalPath, params.fallbackFileName),
|
|
115
116
|
write: params.write,
|
|
117
|
+
producerIsolation: params.producerIsolation,
|
|
116
118
|
resolveFinalPath: () => finalPath,
|
|
117
119
|
mode: params.mode,
|
|
118
120
|
maxBytes: params.maxBytes,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FileHandle } from "node:fs/promises";
|
|
2
|
+
export type OverwriteFileHandleOptions = {
|
|
3
|
+
/** Admit the whole write once, after rollback preparation and before any mutation. */
|
|
4
|
+
beforeWrite?: () => void;
|
|
5
|
+
};
|
|
6
|
+
/** Overwrite a borrowed, non-append read/write handle with best-effort failure rollback. */
|
|
7
|
+
export declare function overwriteFileHandle(handle: FileHandle, data: Uint8Array, options?: OverwriteFileHandleOptions): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=overwrite-file-handle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overwrite-file-handle.d.ts","sourceRoot":"","sources":["../src/overwrite-file-handle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAMnD,MAAM,MAAM,0BAA0B,GAAG;IACvC,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B,CAAC;AAEF,4FAA4F;AAC5F,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,IAAI,CAAC,CAoCf"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { FsSafeError } from "./errors.js";
|
|
2
|
+
import { assertSynchronousCallbackResult } from "./mutation-authority.js";
|
|
3
|
+
import { readFileWindowFully } from "./positional-read.js";
|
|
4
|
+
import { writeAllToFile } from "./write-file-handle.js";
|
|
5
|
+
/** Overwrite a borrowed, non-append read/write handle with best-effort failure rollback. */
|
|
6
|
+
export async function overwriteFileHandle(handle, data, options = {}) {
|
|
7
|
+
const payload = data.subarray(0, data.byteLength);
|
|
8
|
+
const payloadBytes = payload.byteLength;
|
|
9
|
+
const stat = await handle.stat();
|
|
10
|
+
if (!stat.isFile()) {
|
|
11
|
+
throw new FsSafeError("not-file", "overwrite handle must be a regular file");
|
|
12
|
+
}
|
|
13
|
+
const originalSize = stat.size;
|
|
14
|
+
if (!Number.isSafeInteger(originalSize) || originalSize < 0) {
|
|
15
|
+
throw new RangeError("file size must be a non-negative safe integer");
|
|
16
|
+
}
|
|
17
|
+
const prefixBytes = Math.min(payloadBytes, originalSize);
|
|
18
|
+
const originalPrefix = Buffer.allocUnsafe(prefixBytes);
|
|
19
|
+
if (await readFileWindowFully(handle, originalPrefix, 0) !== prefixBytes) {
|
|
20
|
+
throw new FsSafeError("read-failed", "file ended before overwrite rollback preparation completed");
|
|
21
|
+
}
|
|
22
|
+
assertSynchronousCallbackResult(options.beforeWrite?.(), "beforeWrite");
|
|
23
|
+
let prefixStarted = false;
|
|
24
|
+
try {
|
|
25
|
+
// Leave existing bytes intact until any additional storage has been written.
|
|
26
|
+
if (payloadBytes > originalSize) {
|
|
27
|
+
await writeAllToFile(handle, payload.subarray(originalSize), { position: originalSize });
|
|
28
|
+
}
|
|
29
|
+
prefixStarted = true;
|
|
30
|
+
await writeAllToFile(handle, payload.subarray(0, prefixBytes), { position: 0 });
|
|
31
|
+
if (payloadBytes < originalSize) {
|
|
32
|
+
await handle.truncate(payloadBytes);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (prefixStarted) {
|
|
37
|
+
await writeAllToFile(handle, originalPrefix, { position: 0 }).catch(() => undefined);
|
|
38
|
+
}
|
|
39
|
+
await handle.truncate(originalSize).catch(() => undefined);
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type ProbePathCaseOptions = {
|
|
2
|
+
/** Allow an exclusively created empty probe when existing entries provide no answer. Defaults to true. */
|
|
3
|
+
allowTemporaryProbe?: boolean;
|
|
4
|
+
};
|
|
5
|
+
/** Observe local ASCII case behavior; unknown observations never imply an operating-system default. */
|
|
6
|
+
export declare function probePathCaseInsensitiveSync(targetPath: string, options?: ProbePathCaseOptions): boolean | undefined;
|
|
7
|
+
//# sourceMappingURL=path-case.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-case.d.ts","sourceRoot":"","sources":["../src/path-case.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,oBAAoB,GAAG;IACjC,0GAA0G;IAC1G,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC;AAmFF,uGAAuG;AACvG,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,oBAAyB,GACjC,OAAO,GAAG,SAAS,CAqCrB"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import fs, {} from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { assertDirectoryIdentitySync, inspectDirectoryIdentitySync } from "./directory-guard.js";
|
|
5
|
+
import { sameFileIdentityForCleanup } from "./file-identity.js";
|
|
6
|
+
import { isNotFoundPathError } from "./path.js";
|
|
7
|
+
import { realpathSync } from "./realpath.js";
|
|
8
|
+
import { writeTempFileSync } from "./replace-file-descriptor.js";
|
|
9
|
+
import { SyncAtomicTempOwner } from "./replace-file-temp-owner.js";
|
|
10
|
+
import { inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
11
|
+
function swapAsciiCase(value) {
|
|
12
|
+
return value.replace(/[A-Za-z]/g, character => {
|
|
13
|
+
const lower = character.toLowerCase();
|
|
14
|
+
return character === lower ? character.toUpperCase() : lower;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function probeEntry(directory, name, names) {
|
|
18
|
+
const alternate = swapAsciiCase(name);
|
|
19
|
+
if (alternate === name)
|
|
20
|
+
return undefined;
|
|
21
|
+
const bothListed = names.has(name) && names.has(alternate);
|
|
22
|
+
const originalPath = path.join(directory, name);
|
|
23
|
+
let original;
|
|
24
|
+
let observed;
|
|
25
|
+
try {
|
|
26
|
+
original = inspectFileIdentitySync(() => fs.lstatSync(originalPath, { bigint: true }));
|
|
27
|
+
try {
|
|
28
|
+
const other = inspectFileIdentitySync(() => fs.lstatSync(path.join(directory, alternate), { bigint: true }));
|
|
29
|
+
const sameIdentity = sameFileIdentityForCleanup(original, other);
|
|
30
|
+
if (sameIdentity || bothListed) {
|
|
31
|
+
// Matching inodes can belong to newly linked case-distinct names.
|
|
32
|
+
const currentNames = new Set(fs.readdirSync(directory));
|
|
33
|
+
const bothCurrent = currentNames.has(name) && currentNames.has(alternate);
|
|
34
|
+
if (bothListed && !bothCurrent)
|
|
35
|
+
return undefined;
|
|
36
|
+
observed = sameIdentity && !bothCurrent;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
observed = false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (bothListed || !isNotFoundPathError(error))
|
|
44
|
+
return undefined;
|
|
45
|
+
observed = false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
// Disappearance during lookup is not evidence that case variants are distinct.
|
|
52
|
+
inspectFileIdentitySync(() => fs.lstatSync(originalPath, { bigint: true }), original);
|
|
53
|
+
return observed;
|
|
54
|
+
}
|
|
55
|
+
function probeTemporaryEntry(directory) {
|
|
56
|
+
const name = `.fs-safe-case-probe-${randomUUID()}`;
|
|
57
|
+
const owner = new SyncAtomicTempOwner(path.join(directory, name));
|
|
58
|
+
try {
|
|
59
|
+
owner.start();
|
|
60
|
+
owner.adopt(writeTempFileSync({
|
|
61
|
+
fsModule: fs,
|
|
62
|
+
tempPath: owner.pathname,
|
|
63
|
+
content: "",
|
|
64
|
+
mode: 0o600,
|
|
65
|
+
sync: false,
|
|
66
|
+
onIdentity: owner.onIdentity,
|
|
67
|
+
}));
|
|
68
|
+
owner.assertCurrent(fs);
|
|
69
|
+
const observed = probeEntry(directory, name, new Set(fs.readdirSync(directory)));
|
|
70
|
+
owner.assertCurrent(fs);
|
|
71
|
+
return observed;
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
// Failed cleanup invalidates the observation; the existing owner retains its exit retry.
|
|
75
|
+
owner.finish({ fsModule: fs, throwOnCleanupError: true });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function probeDirectory(directory, allowTemporaryProbe, preferredName) {
|
|
79
|
+
const canonical = realpathSync.native(directory);
|
|
80
|
+
const identity = inspectDirectoryIdentitySync(canonical);
|
|
81
|
+
const names = new Set(fs.readdirSync(canonical));
|
|
82
|
+
let observed = preferredName === undefined ? undefined : probeEntry(canonical, preferredName, names);
|
|
83
|
+
for (const name of names) {
|
|
84
|
+
if (observed !== undefined)
|
|
85
|
+
break;
|
|
86
|
+
observed = probeEntry(canonical, name, names);
|
|
87
|
+
}
|
|
88
|
+
if (observed === undefined && allowTemporaryProbe)
|
|
89
|
+
observed = probeTemporaryEntry(canonical);
|
|
90
|
+
assertDirectoryIdentitySync(canonical, identity);
|
|
91
|
+
return realpathSync.native(directory) === canonical ? observed : undefined;
|
|
92
|
+
}
|
|
93
|
+
/** Observe local ASCII case behavior; unknown observations never imply an operating-system default. */
|
|
94
|
+
export function probePathCaseInsensitiveSync(targetPath, options = {}) {
|
|
95
|
+
const resolved = path.resolve(targetPath);
|
|
96
|
+
const allowTemporaryProbe = options.allowTemporaryProbe !== false;
|
|
97
|
+
let targetExists = true;
|
|
98
|
+
try {
|
|
99
|
+
fs.lstatSync(resolved);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (!isNotFoundPathError(error))
|
|
103
|
+
return undefined;
|
|
104
|
+
targetExists = false;
|
|
105
|
+
}
|
|
106
|
+
if (targetExists) {
|
|
107
|
+
try {
|
|
108
|
+
return probeDirectory(path.dirname(resolved), allowTemporaryProbe, path.basename(resolved));
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
let directory = path.dirname(resolved);
|
|
115
|
+
for (;;) {
|
|
116
|
+
let exists = false;
|
|
117
|
+
try {
|
|
118
|
+
exists = fs.statSync(directory).isDirectory();
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// A missing or unreadable component can still have a readable existing ancestor.
|
|
122
|
+
}
|
|
123
|
+
if (exists) {
|
|
124
|
+
try {
|
|
125
|
+
return probeDirectory(directory, allowTemporaryProbe);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const parent = path.dirname(directory);
|
|
132
|
+
if (parent === directory)
|
|
133
|
+
return undefined;
|
|
134
|
+
directory = parent;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type ResolvePathWithinRootParams = {
|
|
2
|
+
rootDir: string;
|
|
3
|
+
requestedPath: string;
|
|
4
|
+
scopeLabel: string;
|
|
5
|
+
defaultFileName?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function resolvePathWithinNormalizedRoot(params: ResolvePathWithinRootParams, root: string): {
|
|
8
|
+
ok: true;
|
|
9
|
+
path: string;
|
|
10
|
+
} | {
|
|
11
|
+
ok: false;
|
|
12
|
+
error: string;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=path-scope-lexical.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-scope-lexical.d.ts","sourceRoot":"","sources":["../src/path-scope-lexical.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAUF,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,2BAA2B,EACnC,IAAI,EAAE,MAAM,GACX;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAiB3D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { isPathInside, isPathRelativeEscape } from "./path.js";
|
|
3
|
+
function pathStaysWithinRoot(rootDir, candidatePath) {
|
|
4
|
+
if (process.platform !== "win32") {
|
|
5
|
+
return candidatePath !== rootDir && isPathInside(rootDir, candidatePath);
|
|
6
|
+
}
|
|
7
|
+
const relative = path.relative(rootDir, candidatePath);
|
|
8
|
+
return Boolean(relative) && !isPathRelativeEscape(relative);
|
|
9
|
+
}
|
|
10
|
+
export function resolvePathWithinNormalizedRoot(params, root) {
|
|
11
|
+
const raw = params.requestedPath.trim();
|
|
12
|
+
if (!raw) {
|
|
13
|
+
if (!params.defaultFileName) {
|
|
14
|
+
return { ok: false, error: "path is required" };
|
|
15
|
+
}
|
|
16
|
+
const defaultPath = path.resolve(root, params.defaultFileName);
|
|
17
|
+
if (!pathStaysWithinRoot(root, defaultPath)) {
|
|
18
|
+
return { ok: false, error: `Invalid path: must stay within ${params.scopeLabel}` };
|
|
19
|
+
}
|
|
20
|
+
return { ok: true, path: defaultPath };
|
|
21
|
+
}
|
|
22
|
+
const resolved = path.resolve(root, raw);
|
|
23
|
+
if (!pathStaysWithinRoot(root, resolved)) {
|
|
24
|
+
return { ok: false, error: `Invalid path: must stay within ${params.scopeLabel}` };
|
|
25
|
+
}
|
|
26
|
+
return { ok: true, path: resolved };
|
|
27
|
+
}
|
package/dist/path.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAOzB,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,GAChC,MAAM,kBAAkB,CAAC;AAM1B,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWvE;AAWD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,cAAc,CAI1E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,SAA6B,GAAG,IAAI,CAIjG;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE3D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE1D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CA0ClE;AAED,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAElE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAExE;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAa/F;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAChE,OAAO,CAUT;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,EAAE,CAAC,KAAK,GAAG,IAAI,CAMhE;AAED,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BpE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAOrF"}
|
package/dist/path.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { FsSafeError } from "./errors.js";
|
|
4
|
+
import { realpathSync } from "./realpath.js";
|
|
4
5
|
import { isDriveRelativePath } from "./safe-path-segment.js";
|
|
5
6
|
export { assertNoUnsafeDeviceReadPath, isUnsafeDeviceReadPath, matchUnsafeDeviceReadPath, } from "./device-path.js";
|
|
6
7
|
const NOT_FOUND_CODES = new Set(["ENOENT", "ENOTDIR"]);
|
|
@@ -18,6 +19,14 @@ export function normalizeWindowsPathForComparison(input) {
|
|
|
18
19
|
// whitespace is part of the path and must not be trimmed away.
|
|
19
20
|
return normalized.replaceAll("/", "\\").toLowerCase();
|
|
20
21
|
}
|
|
22
|
+
function resolveWindowsPathForComparison(input) {
|
|
23
|
+
const resolved = path.win32.resolve(input);
|
|
24
|
+
// Ordinary drive paths are already normalized by resolve. Namespace paths
|
|
25
|
+
// retain Node's additional normalization rules before comparison.
|
|
26
|
+
return resolved[1] === ":" && path.win32.isAbsolute(resolved)
|
|
27
|
+
? resolved.toLowerCase()
|
|
28
|
+
: normalizeWindowsPathForComparison(resolved);
|
|
29
|
+
}
|
|
21
30
|
export function isNodeError(value) {
|
|
22
31
|
return Boolean(value && typeof value === "object" && "code" in value);
|
|
23
32
|
}
|
|
@@ -37,8 +46,18 @@ export function isSymlinkOpenError(value) {
|
|
|
37
46
|
}
|
|
38
47
|
export function isPathInside(root, target) {
|
|
39
48
|
if (process.platform === "win32") {
|
|
40
|
-
const rootForCompare =
|
|
41
|
-
const targetForCompare =
|
|
49
|
+
const rootForCompare = resolveWindowsPathForComparison(root);
|
|
50
|
+
const targetForCompare = resolveWindowsPathForComparison(target);
|
|
51
|
+
// Resolved drive paths already have canonical separators and case. A full
|
|
52
|
+
// segment prefix needs no second resolution through path.relative.
|
|
53
|
+
// Colon-bearing components keep Node's relative-path interpretation.
|
|
54
|
+
if (rootForCompare[1] === ":" && path.win32.isAbsolute(rootForCompare) &&
|
|
55
|
+
!targetForCompare.includes(":", 2) &&
|
|
56
|
+
(targetForCompare === rootForCompare ||
|
|
57
|
+
(targetForCompare.startsWith(rootForCompare) &&
|
|
58
|
+
(rootForCompare.endsWith("\\") || targetForCompare[rootForCompare.length] === "\\")))) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
42
61
|
const relative = path.win32.relative(rootForCompare, targetForCompare);
|
|
43
62
|
const firstSegment = relative.split(path.win32.sep)[0];
|
|
44
63
|
return (relative === "" || (firstSegment !== ".." && !path.win32.isAbsolute(relative)));
|
|
@@ -76,7 +95,7 @@ export function safeRealpathSync(targetPath, cache) {
|
|
|
76
95
|
return cached;
|
|
77
96
|
}
|
|
78
97
|
try {
|
|
79
|
-
const resolved =
|
|
98
|
+
const resolved = realpathSync(targetPath);
|
|
80
99
|
cache?.set(targetPath, resolved);
|
|
81
100
|
cache?.set(resolved, resolved);
|
|
82
101
|
return resolved;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type PermissionCommandFailure } from "./permission-exec.js";
|
|
2
|
-
import type
|
|
2
|
+
import { type PermissionCheck, type PermissionCheckOptions, type SafeStatResult } from "./permissions.js";
|
|
3
3
|
export type PermissionExec = (command: string, args: string[]) => Promise<{
|
|
4
4
|
stdout: string;
|
|
5
5
|
stderr: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions-windows.d.ts","sourceRoot":"","sources":["../src/permissions-windows.ts"],"names":[],"mappings":"AAEA,OAAO,EAA4B,KAAK,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"permissions-windows.d.ts","sourceRoot":"","sources":["../src/permissions-windows.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import os from "node:os";
|
|
2
2
|
import { getNativeBinding } from "./native.js";
|
|
3
3
|
import { executePermissionCommand } from "./permission-exec.js";
|
|
4
|
+
import { safeStat } from "./permissions.js";
|
|
4
5
|
import { normalizeLowercaseStringOrEmpty } from "./string-coerce.js";
|
|
5
6
|
import { resolveWindowsSystemCommand } from "./windows-command.js";
|
|
6
7
|
import { inspectWindowsOwner } from "./windows-owner.js";
|
|
@@ -126,8 +127,18 @@ export function resolveWindowsUserPrincipal(env, userInfo = defaultWindowsUserIn
|
|
|
126
127
|
const domain = env?.USERDOMAIN?.trim();
|
|
127
128
|
return domain ? `${domain}\\${username}` : username;
|
|
128
129
|
}
|
|
130
|
+
function buildTrustedSidPrincipals(env) {
|
|
131
|
+
const trusted = new Set();
|
|
132
|
+
const userSid = normalizeSid(env?.USERSID ?? "");
|
|
133
|
+
if (userSid && SID_RE.test(userSid) && !WORLD_SIDS.has(userSid))
|
|
134
|
+
trusted.add(userSid);
|
|
135
|
+
return trusted;
|
|
136
|
+
}
|
|
129
137
|
function buildTrustedPrincipals(env) {
|
|
130
|
-
const trusted = new Set(
|
|
138
|
+
const trusted = new Set([
|
|
139
|
+
...TRUSTED_BASE,
|
|
140
|
+
...buildTrustedSidPrincipals(env),
|
|
141
|
+
]);
|
|
131
142
|
const principal = resolveWindowsUserPrincipal(env);
|
|
132
143
|
if (principal) {
|
|
133
144
|
trusted.add(normalize(principal));
|
|
@@ -135,9 +146,6 @@ function buildTrustedPrincipals(env) {
|
|
|
135
146
|
if (userOnly)
|
|
136
147
|
trusted.add(normalize(userOnly));
|
|
137
148
|
}
|
|
138
|
-
const userSid = normalizeSid(env?.USERSID ?? "");
|
|
139
|
-
if (userSid && SID_RE.test(userSid) && !WORLD_SIDS.has(userSid))
|
|
140
|
-
trusted.add(userSid);
|
|
141
149
|
return trusted;
|
|
142
150
|
}
|
|
143
151
|
function classifyPrincipal(principal, trustedPrincipals) {
|
|
@@ -209,7 +217,11 @@ export function parseIcaclsOutput(output, targetPath) {
|
|
|
209
217
|
return entries;
|
|
210
218
|
}
|
|
211
219
|
export function summarizeWindowsAcl(entries, env) {
|
|
212
|
-
|
|
220
|
+
// Canonical SID entries cannot match account names. Classify them directly
|
|
221
|
+
// so structured descriptor facts do not depend on a separate user lookup.
|
|
222
|
+
const trustedPrincipals = entries.every((entry) => SID_RE.test(normalize(entry.sid ?? entry.principal)))
|
|
223
|
+
? buildTrustedSidPrincipals(env)
|
|
224
|
+
: buildTrustedPrincipals(env);
|
|
213
225
|
const trusted = [];
|
|
214
226
|
const untrustedWorld = [];
|
|
215
227
|
const untrustedGroup = [];
|
|
@@ -258,7 +270,37 @@ export async function inspectWindowsAcl(targetPath, opts) {
|
|
|
258
270
|
const error = new Error("Windows ACL principal SID translation failed");
|
|
259
271
|
return summarizeWindowsOwnerAcl({ error: String(error), errorCause: error });
|
|
260
272
|
}
|
|
261
|
-
|
|
273
|
+
let owner;
|
|
274
|
+
if (process.platform === "win32" && opts?.env === undefined && opts?.exec === undefined) {
|
|
275
|
+
try {
|
|
276
|
+
const native = getNativeBinding();
|
|
277
|
+
const stat = native && await safeStat(targetPath);
|
|
278
|
+
// Keep the named-query behavior for leaf links; the native reader follows them.
|
|
279
|
+
const facts = stat?.ok && !stat.isSymlink ? native?.readOwnerAndDacl(targetPath) : undefined;
|
|
280
|
+
if (facts && !facts.fallbackRequired && facts.isLocal && facts.aceListComplete && facts.unsupportedAceTypes.length === 0 &&
|
|
281
|
+
facts.aces.every(ace => ace.flags.inherited && ace.mask !== 0)) {
|
|
282
|
+
// .NET normalizes explicit ACEs, but retains nonzero inherited ACEs in
|
|
283
|
+
// their original order without merging them. Other forms keep its query.
|
|
284
|
+
// Adapt descriptor facts only: the public summary owns its SID and rights
|
|
285
|
+
// classification, which differs from the native secure-read policy.
|
|
286
|
+
owner = {
|
|
287
|
+
daclPresent: facts.daclPresent,
|
|
288
|
+
currentUserSid: facts.currentUserSid,
|
|
289
|
+
aces: facts.aces.map(ace => ({
|
|
290
|
+
sid: ace.sid,
|
|
291
|
+
mask: ace.mask,
|
|
292
|
+
deny: ace.aceType === "deny",
|
|
293
|
+
inheritOnly: ace.flags.inheritOnly,
|
|
294
|
+
})),
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
// Preserve this inspector's structured fallback and command diagnostics
|
|
300
|
+
// when the optional helper or native descriptor query is unavailable.
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
owner ??= await inspectWindowsOwner({ targetPath, env: opts?.env, exec: opts?.exec ?? defaultPermissionExec });
|
|
262
304
|
return summarizeWindowsOwnerAcl({
|
|
263
305
|
...owner,
|
|
264
306
|
currentUserSid: normalizeSid(opts?.currentUserSid ?? "") || owner.currentUserSid,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pinned-open.d.ts","sourceRoot":"","sources":["../src/pinned-open.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"pinned-open.d.ts","sourceRoot":"","sources":["../src/pinned-open.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAOzB,MAAM,MAAM,2BAA2B,GAAG,MAAM,GAAG,YAAY,GAAG,IAAI,CAAC;AAEvE,MAAM,MAAM,oBAAoB,GAC5B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAA;CAAE,GACtD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,2BAA2B,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAExE,MAAM,MAAM,yBAAyB,GAAG,MAAM,GAAG,WAAW,CAAC;AAE7D,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,OAAO,EAAE,EACT,WAAW,GAAG,WAAW,GAAG,cAAc,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW,CACpF,CAAC;AAQF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,yBAAyB,CAAC;IACxC,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB,GAAG,oBAAoB,CAqDvB"}
|
package/dist/pinned-open.js
CHANGED
|
@@ -3,6 +3,7 @@ import { isUnsafeDeviceReadPath } from "./device-path.js";
|
|
|
3
3
|
import { FsSafeError } from "./errors.js";
|
|
4
4
|
import { inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
5
5
|
import { resolveReadOpenFlags } from "./read-open-flags.js";
|
|
6
|
+
import { realpathSync } from "./realpath.js";
|
|
6
7
|
function isExpectedPathError(error) {
|
|
7
8
|
const code = typeof error === "object" && error !== null && "code" in error ? String(error.code) : "";
|
|
8
9
|
return code === "ENOENT" || code === "ENOTDIR" || code === "ELOOP";
|
|
@@ -22,7 +23,8 @@ export function openPinnedFileSync(params) {
|
|
|
22
23
|
return { ok: false, reason: "validation" };
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
|
-
const realPath = params.resolvedPath ??
|
|
26
|
+
const realPath = params.resolvedPath ??
|
|
27
|
+
(ioFs === fs ? realpathSync(params.filePath) : ioFs.realpathSync(params.filePath));
|
|
26
28
|
if (isUnsafeDeviceReadPath(realPath)) {
|
|
27
29
|
return { ok: false, reason: "validation" };
|
|
28
30
|
}
|
package/dist/pinned-write.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Readable } from "node:stream";
|
|
2
1
|
import { type AnyAsyncDirectoryGuard } from "./directory-guard.js";
|
|
3
2
|
import type { FileIdentityStat } from "./file-identity.js";
|
|
4
3
|
import { type CopyFileInput } from "./copy-file-input.js";
|
|
@@ -8,7 +7,8 @@ export type PinnedWriteInput = {
|
|
|
8
7
|
encoding?: BufferEncoding;
|
|
9
8
|
} | {
|
|
10
9
|
kind: "stream";
|
|
11
|
-
stream:
|
|
10
|
+
stream: AsyncIterable<Uint8Array | string>;
|
|
11
|
+
stageBeforePublish?: boolean;
|
|
12
12
|
} | CopyFileInput;
|
|
13
13
|
export type RenameIdentityPolicy = "strict" | "verify-content-with-lock";
|
|
14
14
|
export type PublishedWriteIdentity = Readonly<{
|