@openclaw/fs-safe 0.14.0 → 0.16.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 +88 -0
- package/README.md +38 -10
- package/dist/advanced.d.ts +2 -1
- package/dist/advanced.d.ts.map +1 -1
- package/dist/advanced.js +2 -1
- package/dist/archive-kind.d.ts +0 -1
- package/dist/archive-kind.d.ts.map +1 -1
- package/dist/archive-kind.js +5 -17
- package/dist/archive-merge.d.ts.map +1 -1
- package/dist/archive-merge.js +113 -46
- package/dist/archive-parser.wasm +0 -0
- package/dist/archive-read.d.ts.map +1 -1
- package/dist/archive-read.js +10 -11
- package/dist/archive-tar-stream.d.ts +3 -0
- package/dist/archive-tar-stream.d.ts.map +1 -1
- package/dist/archive-tar-stream.js +56 -37
- package/dist/archive-tar-wasm.d.ts +16 -4
- package/dist/archive-tar-wasm.d.ts.map +1 -1
- package/dist/archive-tar-wasm.js +134 -34
- package/dist/archive-zip-directory.d.ts +4 -0
- package/dist/archive-zip-directory.d.ts.map +1 -1
- package/dist/archive-zip-directory.js +2 -0
- package/dist/archive-zip-entry.d.ts +6 -2
- package/dist/archive-zip-entry.d.ts.map +1 -1
- package/dist/archive-zip-entry.js +23 -8
- package/dist/archive-zip-integrity.d.ts.map +1 -1
- package/dist/archive-zip-integrity.js +3 -4
- package/dist/archive-zip-loader.d.ts.map +1 -1
- package/dist/archive-zip-loader.js +107 -31
- package/dist/archive-zip-names.d.ts +1 -0
- package/dist/archive-zip-names.d.ts.map +1 -1
- package/dist/archive-zip-names.js +6 -0
- package/dist/archive.d.ts.map +1 -1
- package/dist/archive.js +11 -11
- package/dist/bounded-read-stream.d.ts +0 -1
- package/dist/bounded-read-stream.d.ts.map +1 -1
- package/dist/bounded-read-stream.js +0 -6
- package/dist/clone-metadata.d.ts +1 -0
- package/dist/clone-metadata.d.ts.map +1 -1
- package/dist/clone-metadata.js +6 -2
- package/dist/copy-publication.d.ts +6 -0
- package/dist/copy-publication.d.ts.map +1 -1
- package/dist/copy-publication.js +3 -0
- package/dist/copy-tree-portable.d.ts.map +1 -1
- package/dist/copy-tree-portable.js +44 -24
- package/dist/copy.d.ts.map +1 -1
- package/dist/copy.js +29 -11
- package/dist/create-directory.d.ts +20 -0
- package/dist/create-directory.d.ts.map +1 -0
- package/dist/create-directory.js +130 -0
- package/dist/create-file-async.d.ts +7 -0
- package/dist/create-file-async.d.ts.map +1 -0
- package/dist/create-file-async.js +121 -0
- package/dist/create-file.d.ts +8 -0
- package/dist/create-file.d.ts.map +1 -0
- package/dist/create-file.js +190 -0
- package/dist/create-owned-file.d.ts +8 -0
- package/dist/create-owned-file.d.ts.map +1 -0
- package/dist/create-owned-file.js +16 -0
- package/dist/create.d.ts +4 -0
- package/dist/create.d.ts.map +1 -0
- package/dist/create.js +2 -0
- package/dist/creation-darwin.d.ts +7 -0
- package/dist/creation-darwin.d.ts.map +1 -0
- package/dist/creation-darwin.js +79 -0
- package/dist/creation-file-state.d.ts +19 -0
- package/dist/creation-file-state.d.ts.map +1 -0
- package/dist/creation-file-state.js +118 -0
- package/dist/creation-path.d.ts +21 -0
- package/dist/creation-path.d.ts.map +1 -0
- package/dist/creation-path.js +71 -0
- package/dist/creation-permissions.d.ts +19 -0
- package/dist/creation-permissions.d.ts.map +1 -0
- package/dist/creation-permissions.js +125 -0
- package/dist/directory-durability.d.ts +1 -1
- package/dist/directory-durability.d.ts.map +1 -1
- package/dist/directory-durability.js +22 -80
- package/dist/directory-guard.d.ts +3 -0
- package/dist/directory-guard.d.ts.map +1 -1
- package/dist/directory-mode-node.d.ts +2 -0
- package/dist/directory-mode-node.d.ts.map +1 -1
- package/dist/directory-mode-node.js +8 -0
- package/dist/directory-mode-owner.js +5 -5
- package/dist/directory-receipt.d.ts +24 -0
- package/dist/directory-receipt.d.ts.map +1 -0
- package/dist/directory-receipt.js +127 -0
- package/dist/file-cleanup.d.ts +19 -0
- package/dist/file-cleanup.d.ts.map +1 -0
- package/dist/file-cleanup.js +78 -0
- package/dist/file-handle-transfer.d.ts +2 -0
- package/dist/file-handle-transfer.d.ts.map +1 -1
- package/dist/file-handle-transfer.js +57 -2
- package/dist/file-identity.d.ts.map +1 -1
- package/dist/file-identity.js +18 -4
- package/dist/file-lock-sync-admission.d.ts +19 -0
- package/dist/file-lock-sync-admission.d.ts.map +1 -0
- package/dist/file-lock-sync-admission.js +93 -0
- package/dist/file-lock-sync-root-acquire.d.ts +4 -0
- package/dist/file-lock-sync-root-acquire.d.ts.map +1 -0
- package/dist/file-lock-sync-root-acquire.js +370 -0
- package/dist/file-lock-sync-root-arbitration.d.ts +18 -0
- package/dist/file-lock-sync-root-arbitration.d.ts.map +1 -0
- package/dist/file-lock-sync-root-arbitration.js +66 -0
- package/dist/file-lock-sync-root-held.d.ts +34 -0
- package/dist/file-lock-sync-root-held.d.ts.map +1 -0
- package/dist/file-lock-sync-root-held.js +393 -0
- package/dist/file-lock-sync-root-io.d.ts +44 -0
- package/dist/file-lock-sync-root-io.d.ts.map +1 -0
- package/dist/file-lock-sync-root-io.js +209 -0
- package/dist/file-lock-sync-root-mutation.d.ts +17 -0
- package/dist/file-lock-sync-root-mutation.d.ts.map +1 -0
- package/dist/file-lock-sync-root-mutation.js +277 -0
- package/dist/file-lock-sync-root-options.d.ts +20 -0
- package/dist/file-lock-sync-root-options.d.ts.map +1 -0
- package/dist/file-lock-sync-root-options.js +58 -0
- package/dist/file-lock-sync-root-registration.d.ts +2 -0
- package/dist/file-lock-sync-root-registration.d.ts.map +1 -0
- package/dist/file-lock-sync-root-registration.js +90 -0
- package/dist/file-lock-sync-root.d.ts +36 -0
- package/dist/file-lock-sync-root.d.ts.map +1 -0
- package/dist/file-lock-sync-root.js +361 -0
- package/dist/file-lock-sync-stale-admission.d.ts +24 -0
- package/dist/file-lock-sync-stale-admission.d.ts.map +1 -0
- package/dist/file-lock-sync-stale-admission.js +205 -0
- package/dist/file-lock-sync.d.ts.map +1 -1
- package/dist/file-lock-sync.js +245 -205
- package/dist/file-observation.d.ts +1 -1
- package/dist/file-observation.d.ts.map +1 -1
- package/dist/file-store-boundary.d.ts +2 -6
- package/dist/file-store-boundary.d.ts.map +1 -1
- package/dist/file-store-boundary.js +3 -9
- package/dist/file-store-prune.d.ts.map +1 -1
- package/dist/file-store-prune.js +5 -1
- package/dist/file-store-sync-write.d.ts.map +1 -1
- package/dist/file-store-sync-write.js +5 -8
- package/dist/file-store.d.ts.map +1 -1
- package/dist/file-store.js +47 -12
- package/dist/guarded-mkdir.d.ts +1 -0
- package/dist/guarded-mkdir.d.ts.map +1 -1
- package/dist/guarded-mkdir.js +36 -7
- package/dist/json-document-store.d.ts.map +1 -1
- package/dist/json-document-store.js +22 -15
- package/dist/json-durable-queue-ownership.d.ts +0 -1
- package/dist/json-durable-queue-ownership.d.ts.map +1 -1
- package/dist/json-durable-queue-ownership.js +0 -6
- package/dist/move-path.js +1 -1
- package/dist/native-binding.d.ts +13 -1
- package/dist/native-binding.d.ts.map +1 -1
- package/dist/native-fallback-warning.d.ts +4 -0
- package/dist/native-fallback-warning.d.ts.map +1 -0
- package/dist/native-fallback-warning.js +11 -0
- package/dist/native-operations.d.ts +0 -2
- package/dist/native-operations.d.ts.map +1 -1
- package/dist/native-operations.js +0 -24
- package/dist/native-parent-admission.d.ts +5 -2
- package/dist/native-parent-admission.d.ts.map +1 -1
- package/dist/native-parent-admission.js +27 -7
- package/dist/native-pinned-write-windows.d.ts +1 -1
- package/dist/native-pinned-write-windows.d.ts.map +1 -1
- package/dist/native-pinned-write-windows.js +174 -29
- package/dist/native-pinned-write.d.ts.map +1 -1
- package/dist/native-pinned-write.js +26 -14
- package/dist/native-policy-parent-windows.d.ts +14 -0
- package/dist/native-policy-parent-windows.d.ts.map +1 -0
- package/dist/native-policy-parent-windows.js +209 -0
- package/dist/native-rename-outcome.d.ts +4 -0
- package/dist/native-rename-outcome.d.ts.map +1 -0
- package/dist/native-rename-outcome.js +8 -0
- package/dist/native-staged-file.d.ts +3 -2
- package/dist/native-staged-file.d.ts.map +1 -1
- package/dist/native-staged-file.js +121 -72
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +12 -8
- package/dist/owner-dacl.d.ts.map +1 -1
- package/dist/owner-dacl.js +10 -4
- package/dist/path-prefix.d.ts.map +1 -1
- package/dist/path-prefix.js +30 -8
- package/dist/path-suffix-aliases.d.ts +2 -0
- package/dist/path-suffix-aliases.d.ts.map +1 -1
- package/dist/path-suffix-aliases.js +25 -17
- package/dist/permission-exec.d.ts +2 -0
- package/dist/permission-exec.d.ts.map +1 -1
- package/dist/permission-exec.js +150 -21
- package/dist/permissions-windows.js +1 -1
- package/dist/pinned-mutation-admission.d.ts.map +1 -1
- package/dist/pinned-mutation-admission.js +10 -5
- package/dist/pinned-mutation-observation.d.ts +0 -1
- package/dist/pinned-mutation-observation.d.ts.map +1 -1
- package/dist/pinned-mutation-observation.js +0 -19
- package/dist/pinned-mutation-shared-route.d.ts +1 -0
- package/dist/pinned-mutation-shared-route.d.ts.map +1 -1
- package/dist/pinned-mutation-shared-route.js +1 -1
- package/dist/pinned-write-input.d.ts +4 -0
- package/dist/pinned-write-input.d.ts.map +1 -0
- package/dist/pinned-write-input.js +25 -0
- package/dist/pinned-write-mode.d.ts +5 -0
- package/dist/pinned-write-mode.d.ts.map +1 -0
- package/dist/pinned-write-mode.js +24 -0
- package/dist/pinned-write-staged.d.ts +6 -0
- package/dist/pinned-write-staged.d.ts.map +1 -0
- package/dist/pinned-write-staged.js +187 -0
- package/dist/pinned-write-types.d.ts +5 -0
- package/dist/pinned-write-types.d.ts.map +1 -1
- package/dist/pinned-write.d.ts.map +1 -1
- package/dist/pinned-write.js +35 -145
- package/dist/private-directory.d.ts.map +1 -1
- package/dist/private-directory.js +18 -4
- package/dist/private-producer-handoff-sync.d.ts +14 -0
- package/dist/private-producer-handoff-sync.d.ts.map +1 -0
- package/dist/private-producer-handoff-sync.js +114 -0
- package/dist/private-producer-handoff.d.ts +22 -4
- package/dist/private-producer-handoff.d.ts.map +1 -1
- package/dist/private-producer-handoff.js +140 -77
- package/dist/private-temp-workspace.d.ts.map +1 -1
- package/dist/private-temp-workspace.js +75 -121
- package/dist/publish-copy-stage.d.ts +2 -1
- package/dist/publish-copy-stage.d.ts.map +1 -1
- package/dist/publish-copy-stage.js +16 -7
- package/dist/publish-file.d.ts.map +1 -1
- package/dist/publish-file.js +2 -2
- package/dist/regular-file.d.ts.map +1 -1
- package/dist/regular-file.js +1 -15
- package/dist/replace-directory.d.ts.map +1 -1
- package/dist/replace-directory.js +256 -18
- package/dist/replace-file-copy-fallback.d.ts.map +1 -1
- package/dist/replace-file-copy-fallback.js +62 -70
- package/dist/replace-file-copy-source.d.ts.map +1 -1
- package/dist/replace-file-copy-source.js +10 -12
- package/dist/replace-file-temp-owner.d.ts +5 -9
- package/dist/replace-file-temp-owner.d.ts.map +1 -1
- package/dist/replace-file-temp-owner.js +56 -72
- package/dist/replace-file.js +6 -6
- package/dist/retained-directory-replacement.d.ts +26 -0
- package/dist/retained-directory-replacement.d.ts.map +1 -0
- package/dist/retained-directory-replacement.js +193 -0
- package/dist/root-boundary.d.ts +1 -0
- package/dist/root-boundary.d.ts.map +1 -1
- package/dist/root-boundary.js +4 -0
- package/dist/root-context.d.ts +0 -8
- package/dist/root-context.d.ts.map +1 -1
- package/dist/root-context.js +0 -3
- package/dist/root-create-input.d.ts +8 -1
- package/dist/root-create-input.d.ts.map +1 -1
- package/dist/root-create-input.js +17 -4
- package/dist/root-directory-creation.d.ts +3 -3
- package/dist/root-directory-creation.d.ts.map +1 -1
- package/dist/root-directory-creation.js +15 -3
- package/dist/root-directory-list.d.ts +1 -0
- package/dist/root-directory-list.d.ts.map +1 -1
- package/dist/root-directory-list.js +1 -0
- package/dist/root-impl.d.ts.map +1 -1
- package/dist/root-impl.js +46 -17
- package/dist/root-move-noreplace.d.ts.map +1 -1
- package/dist/root-move-noreplace.js +24 -15
- package/dist/root-options.d.ts +12 -4
- package/dist/root-options.d.ts.map +1 -1
- package/dist/root-path-errors.d.ts +1 -0
- package/dist/root-path-errors.d.ts.map +1 -1
- package/dist/root-path-errors.js +11 -2
- package/dist/root-path-existing.d.ts.map +1 -1
- package/dist/root-path-existing.js +11 -35
- package/dist/root-path-stat.d.ts.map +1 -1
- package/dist/root-path-stat.js +59 -7
- package/dist/root-path.js +1 -13
- package/dist/root-remove.d.ts +1 -0
- package/dist/root-remove.d.ts.map +1 -1
- package/dist/root-remove.js +4 -0
- package/dist/root-walk.d.ts +1 -1
- package/dist/root-walk.d.ts.map +1 -1
- package/dist/root-walk.js +17 -2
- package/dist/root-write-admission.d.ts +0 -2
- package/dist/root-write-admission.d.ts.map +1 -1
- package/dist/root-write-admission.js +1 -15
- package/dist/root-write-complete-parent.d.ts.map +1 -1
- package/dist/root-write-complete-parent.js +7 -23
- package/dist/root-write-publication.js +1 -1
- package/dist/root-write-verification.d.ts.map +1 -1
- package/dist/root-write-verification.js +29 -42
- package/dist/secret-file.d.ts.map +1 -1
- package/dist/secret-file.js +3 -24
- package/dist/secret-read-async.d.ts.map +1 -1
- package/dist/secret-read-async.js +3 -24
- package/dist/secret-read-policy.d.ts +6 -2
- package/dist/secret-read-policy.d.ts.map +1 -1
- package/dist/secret-read-policy.js +26 -2
- package/dist/secure-file-windows.d.ts +6 -0
- package/dist/secure-file-windows.d.ts.map +1 -1
- package/dist/secure-file-windows.js +34 -117
- package/dist/secure-file.js +2 -2
- package/dist/sibling-temp.d.ts.map +1 -1
- package/dist/sibling-temp.js +23 -12
- package/dist/sidecar-lock-acquire.d.ts +2 -28
- package/dist/sidecar-lock-acquire.d.ts.map +1 -1
- package/dist/sidecar-lock-acquire.js +288 -199
- package/dist/sidecar-lock-admission-context.d.ts +19 -0
- package/dist/sidecar-lock-admission-context.d.ts.map +1 -0
- package/dist/sidecar-lock-admission-context.js +60 -0
- package/dist/sidecar-lock-admission-parser.d.ts +43 -0
- package/dist/sidecar-lock-admission-parser.d.ts.map +1 -0
- package/dist/sidecar-lock-admission-parser.js +113 -0
- package/dist/sidecar-lock-admission.d.ts +35 -0
- package/dist/sidecar-lock-admission.d.ts.map +1 -0
- package/dist/sidecar-lock-admission.js +7 -0
- package/dist/sidecar-lock-reclaim.d.ts +9 -4
- package/dist/sidecar-lock-reclaim.d.ts.map +1 -1
- package/dist/sidecar-lock-reclaim.js +80 -25
- package/dist/sidecar-lock-root.d.ts.map +1 -1
- package/dist/sidecar-lock-root.js +2 -1
- package/dist/sidecar-lock-stale-admission.d.ts +39 -0
- package/dist/sidecar-lock-stale-admission.d.ts.map +1 -0
- package/dist/sidecar-lock-stale-admission.js +232 -0
- package/dist/sidecar-lock-target.d.ts +8 -0
- package/dist/sidecar-lock-target.d.ts.map +1 -0
- package/dist/sidecar-lock-target.js +55 -0
- package/dist/sidecar-lock.d.ts.map +1 -1
- package/dist/sidecar-lock.js +100 -16
- package/dist/staged-directory.d.ts.map +1 -1
- package/dist/staged-directory.js +6 -6
- package/dist/staged-file-settlement.d.ts +17 -0
- package/dist/staged-file-settlement.d.ts.map +1 -0
- package/dist/staged-file-settlement.js +57 -0
- package/dist/temp-workspace-descriptor.d.ts.map +1 -1
- package/dist/temp-workspace-descriptor.js +9 -27
- package/dist/temp-workspace-owner.d.ts.map +1 -1
- package/dist/temp-workspace-owner.js +8 -8
- package/dist/walk.d.ts +5 -1
- package/dist/walk.d.ts.map +1 -1
- package/dist/walk.js +19 -6
- package/dist/windows-owner.d.ts.map +1 -1
- package/dist/windows-owner.js +4 -3
- package/dist/windows-security-bridge.cs +336 -0
- package/dist/windows-security-bridge.ps1 +15 -0
- package/dist/windows-security-command.d.ts +26 -0
- package/dist/windows-security-command.d.ts.map +1 -0
- package/dist/windows-security-command.js +363 -0
- package/dist/windows-security-facts.d.ts +6 -0
- package/dist/windows-security-facts.d.ts.map +1 -0
- package/dist/windows-security-facts.js +108 -0
- package/docs/advanced.md +4 -2
- package/docs/archive.md +97 -46
- package/docs/atomic.md +85 -8
- package/docs/config.md +6 -2
- package/docs/contributing.md +44 -4
- package/docs/copy.md +37 -0
- package/docs/creation.md +128 -0
- package/docs/durability.md +24 -0
- package/docs/file-store.md +19 -0
- package/docs/install.md +31 -7
- package/docs/json-store.md +5 -0
- package/docs/migrating-to-0.5.md +15 -6
- package/docs/migrating-to-0.6.md +9 -4
- package/docs/native-helper.md +32 -12
- package/docs/native.md +38 -7
- package/docs/output.md +6 -0
- package/docs/path-prefix.md +10 -0
- package/docs/path-suffix-aliases.md +51 -6
- package/docs/permissions.md +50 -14
- package/docs/public-api.md +3 -2
- package/docs/root.md +56 -3
- package/docs/secret-file.md +11 -2
- package/docs/secure-file.md +9 -4
- package/docs/sidecar-lock.md +114 -8
- package/docs/staged-file.md +12 -3
- package/docs/temp.md +20 -3
- package/docs/walk.md +67 -1
- package/docs/writing.md +76 -6
- package/package.json +19 -16
- package/dist/darwin-acl.d.ts +0 -4
- package/dist/darwin-acl.d.ts.map +0 -1
- package/dist/darwin-acl.js +0 -24
package/dist/owner-dacl.js
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import { FsSafeError } from "./errors.js";
|
|
2
2
|
import { getNativeBinding } from "./native.js";
|
|
3
|
+
import { getFsSafeNativeConfig } from "./native-config.js";
|
|
4
|
+
import { warnNativeFallback } from "./native-fallback-warning.js";
|
|
3
5
|
import { assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
6
|
+
import { readWindowsSecurityFactsCommand } from "./windows-security-command.js";
|
|
4
7
|
export function readOwnerAndDacl(targetPath) {
|
|
5
8
|
if (process.platform !== "win32") {
|
|
6
9
|
return { status: "unsupported-platform", platform: process.platform };
|
|
7
10
|
}
|
|
8
11
|
assertNoWindowsPathAlias(targetPath, "filesystem", "owner and DACL path uses a Windows filesystem namespace alias");
|
|
9
12
|
const native = getNativeBinding();
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
const inspect = native?.readOwnerAndDacl;
|
|
14
|
+
if (typeof inspect !== "function") {
|
|
15
|
+
if (getFsSafeNativeConfig().mode === "require") {
|
|
16
|
+
throw new FsSafeError("helper-unavailable", "Windows owner and DACL facts require an up-to-date native helper");
|
|
17
|
+
}
|
|
18
|
+
warnNativeFallback("windows-owner-dacl", "Windows owner and DACL inspection uses a slower built-in system command.");
|
|
13
19
|
}
|
|
14
|
-
const facts =
|
|
20
|
+
const facts = typeof inspect === "function" ? inspect.call(native, targetPath) : readWindowsSecurityFactsCommand(targetPath);
|
|
15
21
|
return {
|
|
16
22
|
status: "supported",
|
|
17
23
|
ownerSid: facts.ownerSid,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path-prefix.d.ts","sourceRoot":"","sources":["../src/path-prefix.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;CAChD,CAAC;
|
|
1
|
+
{"version":3,"file":"path-prefix.d.ts","sourceRoot":"","sources":["../src/path-prefix.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;CAChD,CAAC;AAuBF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAuEvE"}
|
package/dist/path-prefix.js
CHANGED
|
@@ -19,15 +19,23 @@ function resolutionError(code, absolutePath) {
|
|
|
19
19
|
code, syscall: "resolvePathPrefix", path: absolutePath,
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
|
+
// Leave ample room for ordinary shallow paths to retain the legacy small-array
|
|
23
|
+
// path. At 32 components, repeated front removal can reindex at most 496 array
|
|
24
|
+
// positions per constructed queue; longer queues use a forward cursor instead.
|
|
25
|
+
const SHIFT_QUEUE_COMPONENT_LIMIT = 32;
|
|
22
26
|
export function resolvePathPrefixSync(input) {
|
|
23
27
|
assertNoNulPathInput(input);
|
|
24
28
|
const absolutePath = absolutePathWithRawSegments(input);
|
|
25
29
|
let resolved = rawRoot(absolutePath);
|
|
26
|
-
|
|
30
|
+
let remaining = absolutePath.slice(resolved.length).split(path.sep);
|
|
31
|
+
let shiftQueue = remaining.length <= SHIFT_QUEUE_COMPONENT_LIMIT;
|
|
32
|
+
let nextSegment = 0;
|
|
33
|
+
let remainingCount = remaining.length;
|
|
27
34
|
const visitedStates = new Set();
|
|
28
35
|
let symlinkHops = 0;
|
|
29
|
-
while (
|
|
30
|
-
const segment = remaining.shift();
|
|
36
|
+
while (remainingCount > 0) {
|
|
37
|
+
const segment = shiftQueue ? remaining.shift() : remaining[nextSegment++];
|
|
38
|
+
remainingCount--;
|
|
31
39
|
if (segment === "")
|
|
32
40
|
continue;
|
|
33
41
|
if (segment === "." || segment === "..") {
|
|
@@ -51,32 +59,46 @@ export function resolvePathPrefixSync(input) {
|
|
|
51
59
|
return {
|
|
52
60
|
absolutePath,
|
|
53
61
|
existingPath: realpathSync.native(pathForWindowsFilesystem(resolved)),
|
|
54
|
-
unresolvedSegments: [segment, ...remaining],
|
|
62
|
+
unresolvedSegments: shiftQueue ? [segment, ...remaining] : remaining.slice(nextSegment - 1),
|
|
55
63
|
};
|
|
56
64
|
}
|
|
57
65
|
if (!stat.isSymbolicLink()) {
|
|
58
|
-
if (!stat.isDirectory() &&
|
|
66
|
+
if (!stat.isDirectory() && remainingCount > 0)
|
|
59
67
|
throw resolutionError("ENOTDIR", absolutePath);
|
|
60
68
|
resolved = candidate;
|
|
61
69
|
continue;
|
|
62
70
|
}
|
|
63
|
-
const
|
|
71
|
+
const pendingSuffix = shiftQueue ? remaining : remaining.slice(nextSegment);
|
|
72
|
+
const state = JSON.stringify([String(stat.dev), String(stat.ino), candidate, pendingSuffix]);
|
|
64
73
|
if (symlinkHops >= 64 || visitedStates.has(state))
|
|
65
74
|
throw resolutionError("ELOOP", absolutePath);
|
|
66
75
|
visitedStates.add(state);
|
|
67
76
|
symlinkHops++;
|
|
68
77
|
const target = fs.readlinkSync(candidate);
|
|
69
78
|
const rawTarget = path.sep === "\\" ? target.replaceAll("/", "\\") : target;
|
|
79
|
+
let targetSegments;
|
|
70
80
|
if (path.isAbsolute(rawTarget)) {
|
|
71
81
|
const targetRoot = rawRoot(rawTarget);
|
|
72
82
|
// A rooted Windows link target uses the link's drive/share, not cwd's.
|
|
73
83
|
resolved = path.sep === "\\" && targetRoot === "\\" ? rawRoot(resolved) : targetRoot;
|
|
74
|
-
|
|
84
|
+
targetSegments = rawTarget.slice(targetRoot.length).split(path.sep);
|
|
75
85
|
}
|
|
76
86
|
else {
|
|
77
87
|
// A target's parent traversal applies after resolving its preceding links.
|
|
78
|
-
|
|
88
|
+
targetSegments = rawTarget.split(path.sep);
|
|
79
89
|
}
|
|
90
|
+
const expandedCount = targetSegments.length + pendingSuffix.length;
|
|
91
|
+
if (expandedCount <= SHIFT_QUEUE_COMPONENT_LIMIT) {
|
|
92
|
+
// The spread is bounded by the same fixed limit as subsequent shifts.
|
|
93
|
+
remaining = pendingSuffix;
|
|
94
|
+
remaining.unshift(...targetSegments);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
remaining = targetSegments.concat(pendingSuffix);
|
|
98
|
+
}
|
|
99
|
+
remainingCount = remaining.length;
|
|
100
|
+
shiftQueue = remainingCount <= SHIFT_QUEUE_COMPONENT_LIMIT;
|
|
101
|
+
nextSegment = 0;
|
|
80
102
|
}
|
|
81
103
|
return { absolutePath, existingPath: realpathSync.native(pathForWindowsFilesystem(resolved)), unresolvedSegments: [] };
|
|
82
104
|
}
|
|
@@ -2,6 +2,8 @@ export type ProbePathSuffixAliasesOptions = {
|
|
|
2
2
|
directory: string;
|
|
3
3
|
left: string;
|
|
4
4
|
right: string;
|
|
5
|
+
/** Maximum relative component count; defaults to 32. */
|
|
6
|
+
maxDepth?: number;
|
|
5
7
|
/** Synchronous caller policy for differing NFC pairs not equivalent under ASCII case folding. */
|
|
6
8
|
shouldProbeCaseVariants?: (leftNfc: string, rightNfc: string) => boolean;
|
|
7
9
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path-suffix-aliases.d.ts","sourceRoot":"","sources":["../src/path-suffix-aliases.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,iGAAiG;IACjG,uBAAuB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;CAC1E,CAAC;
|
|
1
|
+
{"version":3,"file":"path-suffix-aliases.d.ts","sourceRoot":"","sources":["../src/path-suffix-aliases.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iGAAiG;IACjG,uBAAuB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;CAC1E,CAAC;AAkVF,4FAA4F;AAC5F,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,6BAA6B,GAAG,OAAO,GAAG,SAAS,CAmDtG"}
|
|
@@ -15,6 +15,7 @@ const MAX_SUFFIX_DEPTH = 32;
|
|
|
15
15
|
const MAX_MKDIR_ATTEMPTS = 128;
|
|
16
16
|
const MAX_CREATED_DIRECTORIES = 64;
|
|
17
17
|
const MAX_FORWARD_OBSERVATIONS = 4_096;
|
|
18
|
+
const MAX_SCALED_FORWARD_OBSERVATIONS = 32_768;
|
|
18
19
|
const PROBE_NAME_LENGTH = 6;
|
|
19
20
|
const PROBE_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
20
21
|
const PROBE_FIRST_ALPHABET = "bdefghijkmoqrstuvwxyz";
|
|
@@ -25,7 +26,7 @@ function assertMutationPath(value) {
|
|
|
25
26
|
if (value.length > MAX_PATH_LENGTH)
|
|
26
27
|
unavailable();
|
|
27
28
|
}
|
|
28
|
-
function suffixSegments(value) {
|
|
29
|
+
function suffixSegments(value, maxDepth) {
|
|
29
30
|
if (typeof value !== "string")
|
|
30
31
|
throw new TypeError("suffix must be a string");
|
|
31
32
|
if (value.length > MAX_SUFFIX_LENGTH)
|
|
@@ -35,8 +36,8 @@ function suffixSegments(value) {
|
|
|
35
36
|
}
|
|
36
37
|
const windows = process.platform === "win32";
|
|
37
38
|
const segments = (windows ? value.replaceAll("/", "\\") : value).split(path.sep);
|
|
38
|
-
if (segments.length >
|
|
39
|
-
throw new RangeError(
|
|
39
|
+
if (segments.length > maxDepth)
|
|
40
|
+
throw new RangeError(`suffix exceeds ${maxDepth} components`);
|
|
40
41
|
if (segments.some(segment => !segment || segment === "." || segment === ".." ||
|
|
41
42
|
(windows && (segment.includes(":") || /^[ .]+$/u.test(segment) ||
|
|
42
43
|
isWindowsReservedDeviceName(segment))))) {
|
|
@@ -96,14 +97,8 @@ function createPrivateProbeName(nameLength) {
|
|
|
96
97
|
return name;
|
|
97
98
|
}
|
|
98
99
|
function* asciiCaseProbePairs(nameLength, forbidden) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const first = createPrivateProbeName(nameLength);
|
|
102
|
-
const second = `${first[0].toUpperCase()}${first.slice(1)}`;
|
|
103
|
-
if (!forbidden(first) && !forbidden(second)) {
|
|
104
|
-
count++;
|
|
105
|
-
yield [first, second];
|
|
106
|
-
}
|
|
100
|
+
for (const first of privateProbeNames(nameLength, forbidden)) {
|
|
101
|
+
yield [first, `${first[0].toUpperCase()}${first.slice(1)}`];
|
|
107
102
|
}
|
|
108
103
|
}
|
|
109
104
|
function* privateProbeNames(nameLength, forbidden) {
|
|
@@ -128,8 +123,16 @@ class ProbeDirectories {
|
|
|
128
123
|
observations = 0;
|
|
129
124
|
mkdirAttempts = 0;
|
|
130
125
|
creations = 0;
|
|
131
|
-
|
|
126
|
+
maxObservations;
|
|
127
|
+
maxMkdirAttempts;
|
|
128
|
+
maxCreations;
|
|
129
|
+
constructor(requestedDirectory, depth) {
|
|
132
130
|
this.requestedDirectory = requestedDirectory;
|
|
131
|
+
// The suffix-length limit bounds actual depth, so these products remain safe integers.
|
|
132
|
+
const scale = Math.max(1, depth / MAX_SUFFIX_DEPTH);
|
|
133
|
+
this.maxObservations = Math.min(MAX_SCALED_FORWARD_OBSERVATIONS, MAX_FORWARD_OBSERVATIONS * scale * scale);
|
|
134
|
+
this.maxMkdirAttempts = MAX_MKDIR_ATTEMPTS * scale;
|
|
135
|
+
this.maxCreations = MAX_CREATED_DIRECTORIES * scale;
|
|
133
136
|
this.observe(1);
|
|
134
137
|
const canonical = realpathSync.native(pathForWindowsFilesystem(requestedDirectory));
|
|
135
138
|
assertMutationPath(canonical);
|
|
@@ -138,7 +141,7 @@ class ProbeDirectories {
|
|
|
138
141
|
this.assert(this.root);
|
|
139
142
|
}
|
|
140
143
|
reserveObservations(units) {
|
|
141
|
-
if (this.
|
|
144
|
+
if (units > this.maxObservations - this.observations)
|
|
142
145
|
unavailable();
|
|
143
146
|
}
|
|
144
147
|
observe(units, cleanup = false) {
|
|
@@ -159,7 +162,7 @@ class ProbeDirectories {
|
|
|
159
162
|
}
|
|
160
163
|
}
|
|
161
164
|
create(parent, name) {
|
|
162
|
-
if (this.mkdirAttempts >=
|
|
165
|
+
if (this.mkdirAttempts >= this.maxMkdirAttempts || this.creations >= this.maxCreations)
|
|
163
166
|
unavailable();
|
|
164
167
|
const probePath = path.join(parent.path, name);
|
|
165
168
|
assertMutationPath(probePath);
|
|
@@ -337,11 +340,16 @@ export function probePathSuffixAliasesSync(options) {
|
|
|
337
340
|
const directory = resolvePathPreservingWindowsRoot(requestedDirectory);
|
|
338
341
|
if (directory.length > MAX_PATH_LENGTH)
|
|
339
342
|
throw new RangeError("resolved directory exceeds 32768 code units");
|
|
343
|
+
const requestedMaxDepth = options.maxDepth;
|
|
344
|
+
const maxDepth = requestedMaxDepth === undefined ? MAX_SUFFIX_DEPTH : requestedMaxDepth;
|
|
345
|
+
if (!Number.isSafeInteger(maxDepth) || maxDepth < 0) {
|
|
346
|
+
throw new RangeError("maxDepth must be a non-negative safe integer");
|
|
347
|
+
}
|
|
340
348
|
const leftInput = options.left;
|
|
341
349
|
const rightInput = options.right;
|
|
342
350
|
const predicate = options.shouldProbeCaseVariants;
|
|
343
|
-
const left = suffixSegments(leftInput);
|
|
344
|
-
const right = suffixSegments(rightInput);
|
|
351
|
+
const left = suffixSegments(leftInput, maxDepth);
|
|
352
|
+
const right = suffixSegments(rightInput, maxDepth);
|
|
345
353
|
if (left.length !== right.length)
|
|
346
354
|
throw new TypeError("suffixes must have the same component count");
|
|
347
355
|
if (predicate !== undefined && typeof predicate !== "function") {
|
|
@@ -370,7 +378,7 @@ export function probePathSuffixAliasesSync(options) {
|
|
|
370
378
|
let observed;
|
|
371
379
|
let cleaned = true;
|
|
372
380
|
try {
|
|
373
|
-
observed = observeSuffixes(() => owner ??= new ProbeDirectories(directory), left, right, shouldProbe);
|
|
381
|
+
observed = observeSuffixes(() => owner ??= new ProbeDirectories(directory, left.length), left, right, shouldProbe);
|
|
374
382
|
owner?.assert(owner.root);
|
|
375
383
|
}
|
|
376
384
|
catch {
|
|
@@ -8,6 +8,8 @@ export type PermissionCommandFailure = {
|
|
|
8
8
|
stderr: string;
|
|
9
9
|
};
|
|
10
10
|
export declare function formatPermissionErrorDetail(value: string): string;
|
|
11
|
+
/** Formats only caught permission-query failures without invoking user code. */
|
|
12
|
+
export declare function formatCaughtPermissionFailure(error: unknown): string;
|
|
11
13
|
export declare class PermissionCommandError extends Error implements PermissionCommandFailure {
|
|
12
14
|
readonly command: string;
|
|
13
15
|
readonly durationMs: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-exec.d.ts","sourceRoot":"","sources":["../src/permission-exec.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,kCAAkC,QAAS,CAAC;AAEzD,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjE;
|
|
1
|
+
{"version":3,"file":"permission-exec.d.ts","sourceRoot":"","sources":["../src/permission-exec.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,kCAAkC,QAAS,CAAC;AAEzD,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjE;AA4ED,gFAAgF;AAChF,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAqBpE;AA2CD,qBAAa,sBAAuB,SAAQ,KAAM,YAAW,wBAAwB;IACnF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,YACE,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,OAAO,EACd,SAAS,SAAqC,EAc/C;CACF;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,wBAAwB,GAAG,SAAS,CAgCtC;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,SAAqC,GAC7C,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAa7C"}
|
package/dist/permission-exec.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { execFile } from "node:child_process";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { promisify } from "node:util";
|
|
3
|
+
import { promisify, types as utilTypes } from "node:util";
|
|
4
4
|
import { formatErrorDetail } from "./error-detail.js";
|
|
5
5
|
const execFileAsync = promisify(execFile);
|
|
6
6
|
export const DEFAULT_PERMISSION_EXEC_TIMEOUT_MS = 30_000;
|
|
@@ -8,15 +8,127 @@ export function formatPermissionErrorDetail(value) {
|
|
|
8
8
|
const formatted = formatErrorDetail(value);
|
|
9
9
|
return formatted.length > 400 ? `${formatted.slice(0, 399)}…` : formatted;
|
|
10
10
|
}
|
|
11
|
+
const MISSING_DATA_PROPERTY = Object.freeze({ found: false });
|
|
12
|
+
const MAX_CAUGHT_FAILURE_PROTOTYPES = 4;
|
|
13
|
+
const primitiveString = String;
|
|
14
|
+
const isUint8Array = utilTypes.isUint8Array;
|
|
15
|
+
const Uint8ArrayIntrinsic = Uint8Array;
|
|
16
|
+
const typedArrayPrototype = Object.getPrototypeOf(Uint8ArrayIntrinsic.prototype);
|
|
17
|
+
const typedArrayBufferGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, "buffer").get;
|
|
18
|
+
const typedArrayByteOffsetGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, "byteOffset").get;
|
|
19
|
+
const typedArrayByteLengthGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, "byteLength").get;
|
|
20
|
+
const typedArraySet = Object.getOwnPropertyDescriptor(typedArrayPrototype, "set").value;
|
|
21
|
+
const textDecoderDecode = TextDecoder.prototype.decode;
|
|
22
|
+
const stderrDecoder = new TextDecoder("utf-8", {
|
|
23
|
+
fatal: false,
|
|
24
|
+
ignoreBOM: true,
|
|
25
|
+
});
|
|
26
|
+
const MAX_STDERR_BYTES = 1600;
|
|
27
|
+
function isInspectableCaughtObject(value) {
|
|
28
|
+
if ((typeof value !== "object" || value === null) && typeof value !== "function") {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
return !utilTypes.isProxy(value);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function dataProperty(value, name) {
|
|
39
|
+
if (!isInspectableCaughtObject(value))
|
|
40
|
+
return MISSING_DATA_PROPERTY;
|
|
41
|
+
let current = value;
|
|
42
|
+
for (let depth = 0; current !== null && depth < MAX_CAUGHT_FAILURE_PROTOTYPES; depth += 1) {
|
|
43
|
+
if (!isInspectableCaughtObject(current))
|
|
44
|
+
return MISSING_DATA_PROPERTY;
|
|
45
|
+
let descriptor;
|
|
46
|
+
try {
|
|
47
|
+
descriptor = Object.getOwnPropertyDescriptor(current, name);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return MISSING_DATA_PROPERTY;
|
|
51
|
+
}
|
|
52
|
+
if (descriptor) {
|
|
53
|
+
return Object.hasOwn(descriptor, "value")
|
|
54
|
+
? { found: true, value: descriptor.value }
|
|
55
|
+
: MISSING_DATA_PROPERTY;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
current = Object.getPrototypeOf(current);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return MISSING_DATA_PROPERTY;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return MISSING_DATA_PROPERTY;
|
|
65
|
+
}
|
|
66
|
+
function caughtPrimitiveDisplay(value) {
|
|
67
|
+
if (value !== null && (typeof value === "object" || typeof value === "function"))
|
|
68
|
+
return undefined;
|
|
69
|
+
return primitiveString(value);
|
|
70
|
+
}
|
|
71
|
+
/** Formats only caught permission-query failures without invoking user code. */
|
|
72
|
+
export function formatCaughtPermissionFailure(error) {
|
|
73
|
+
const primitive = caughtPrimitiveDisplay(error);
|
|
74
|
+
if (primitive !== undefined)
|
|
75
|
+
return formatBoundedCaughtDetail(primitive);
|
|
76
|
+
if (!isInspectableCaughtObject(error)) {
|
|
77
|
+
return "Uninspectable proxy failure";
|
|
78
|
+
}
|
|
79
|
+
const message = dataProperty(error, "message");
|
|
80
|
+
const name = dataProperty(error, "name");
|
|
81
|
+
const rawMessage = message.found && typeof message.value === "string"
|
|
82
|
+
? message.value : "";
|
|
83
|
+
const rawName = name.found && typeof name.value === "string"
|
|
84
|
+
? name.value : "";
|
|
85
|
+
const messageText = rawMessage.slice(0, 400);
|
|
86
|
+
const nameText = rawName.slice(0, 400);
|
|
87
|
+
const display = messageText
|
|
88
|
+
? (nameText ? `${nameText}: ${messageText}` : messageText)
|
|
89
|
+
: nameText || (typeof error === "function" ? "Unknown function failure" : "Unknown object failure");
|
|
90
|
+
return formatBoundedCaughtDetail(display, rawMessage.length > messageText.length || rawName.length > nameText.length);
|
|
91
|
+
}
|
|
92
|
+
function formatBoundedCaughtDetail(value, alreadyTruncated = false) {
|
|
93
|
+
const inputWasTruncated = alreadyTruncated || value.length > 400;
|
|
94
|
+
const formatted = formatPermissionErrorDetail(value.slice(0, 400));
|
|
95
|
+
if (!inputWasTruncated || formatted.endsWith("…"))
|
|
96
|
+
return formatted;
|
|
97
|
+
return `${formatted.slice(0, 399)}…`;
|
|
98
|
+
}
|
|
99
|
+
function safeStderr(value) {
|
|
100
|
+
if (typeof value === "string")
|
|
101
|
+
return formatBoundedCaughtDetail(value);
|
|
102
|
+
try {
|
|
103
|
+
if (!isUint8Array(value))
|
|
104
|
+
return "";
|
|
105
|
+
const backing = Reflect.apply(typedArrayBufferGetter, value, []);
|
|
106
|
+
const byteOffset = Reflect.apply(typedArrayByteOffsetGetter, value, []);
|
|
107
|
+
const byteLength = Reflect.apply(typedArrayByteLengthGetter, value, []);
|
|
108
|
+
const copiedByteLength = byteLength < MAX_STDERR_BYTES
|
|
109
|
+
? byteLength : MAX_STDERR_BYTES;
|
|
110
|
+
const source = new Uint8ArrayIntrinsic(backing, byteOffset, copiedByteLength);
|
|
111
|
+
const copy = new Uint8ArrayIntrinsic(copiedByteLength);
|
|
112
|
+
Reflect.apply(typedArraySet, copy, [source, 0]);
|
|
113
|
+
const decoded = Reflect.apply(textDecoderDecode, stderrDecoder, [copy]);
|
|
114
|
+
return formatBoundedCaughtDetail(decoded, byteLength > copiedByteLength);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return "";
|
|
118
|
+
}
|
|
119
|
+
}
|
|
11
120
|
function commandFailureFields(error) {
|
|
12
|
-
const
|
|
121
|
+
const killed = dataProperty(error, "killed");
|
|
122
|
+
const code = dataProperty(error, "code");
|
|
123
|
+
const signal = dataProperty(error, "signal");
|
|
124
|
+
const stderr = dataProperty(error, "stderr");
|
|
13
125
|
return {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
126
|
+
found: killed.found || code.found || signal.found || stderr.found,
|
|
127
|
+
timedOut: killed.found && killed.value === true &&
|
|
128
|
+
signal.found && signal.value === "SIGKILL",
|
|
129
|
+
exitCode: code.found && typeof code.value === "number" ? code.value : null,
|
|
130
|
+
signal: signal.found && typeof signal.value === "string" ? signal.value : null,
|
|
131
|
+
stderr: stderr.found ? safeStderr(stderr.value) : "",
|
|
20
132
|
};
|
|
21
133
|
}
|
|
22
134
|
export class PermissionCommandError extends Error {
|
|
@@ -41,21 +153,38 @@ export class PermissionCommandError extends Error {
|
|
|
41
153
|
}
|
|
42
154
|
}
|
|
43
155
|
export function getPermissionCommandFailure(error, command, durationMs) {
|
|
44
|
-
if (error
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
156
|
+
if (isInspectableCaughtObject(error) && utilTypes.isNativeError(error)) {
|
|
157
|
+
const name = dataProperty(error, "name");
|
|
158
|
+
if (name.found && name.value === "PermissionCommandError") {
|
|
159
|
+
const wrappedCommand = dataProperty(error, "command");
|
|
160
|
+
const wrappedDuration = dataProperty(error, "durationMs");
|
|
161
|
+
const wrappedTimedOut = dataProperty(error, "timedOut");
|
|
162
|
+
const wrappedExitCode = dataProperty(error, "exitCode");
|
|
163
|
+
const wrappedSignal = dataProperty(error, "signal");
|
|
164
|
+
const wrappedStderr = dataProperty(error, "stderr");
|
|
165
|
+
if (wrappedCommand.found && typeof wrappedCommand.value === "string" &&
|
|
166
|
+
wrappedDuration.found && typeof wrappedDuration.value === "number" &&
|
|
167
|
+
Number.isSafeInteger(wrappedDuration.value) && wrappedDuration.value >= 0 &&
|
|
168
|
+
wrappedTimedOut.found && typeof wrappedTimedOut.value === "boolean" &&
|
|
169
|
+
wrappedExitCode.found && (wrappedExitCode.value === null || typeof wrappedExitCode.value === "number") &&
|
|
170
|
+
wrappedSignal.found && (wrappedSignal.value === null || typeof wrappedSignal.value === "string") &&
|
|
171
|
+
wrappedStderr.found) {
|
|
172
|
+
return {
|
|
173
|
+
command: wrappedCommand.value,
|
|
174
|
+
durationMs: wrappedDuration.value,
|
|
175
|
+
timedOut: wrappedTimedOut.value,
|
|
176
|
+
exitCode: wrappedExitCode.value,
|
|
177
|
+
signal: wrappedSignal.value,
|
|
178
|
+
stderr: safeStderr(wrappedStderr.value),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
53
182
|
}
|
|
54
|
-
|
|
55
|
-
|
|
183
|
+
const fields = commandFailureFields(error);
|
|
184
|
+
if (!fields.found)
|
|
56
185
|
return undefined;
|
|
57
|
-
}
|
|
58
|
-
return { command, durationMs: Math.round(durationMs), ...
|
|
186
|
+
const { found: _found, ...detail } = fields;
|
|
187
|
+
return { command, durationMs: Math.round(durationMs), ...detail };
|
|
59
188
|
}
|
|
60
189
|
export async function executePermissionCommand(command, args, timeoutMs = DEFAULT_PERMISSION_EXEC_TIMEOUT_MS) {
|
|
61
190
|
const startedAt = performance.now();
|
|
@@ -96,7 +96,7 @@ export async function inspectWindowsPermissions(params) {
|
|
|
96
96
|
env: params.opts?.env,
|
|
97
97
|
exec: params.opts?.exec ?? defaultPermissionExec,
|
|
98
98
|
});
|
|
99
|
-
if (owner.error) {
|
|
99
|
+
if (owner.error !== undefined) {
|
|
100
100
|
const error = `Windows owner inspection failed: ${owner.error}`;
|
|
101
101
|
return { ...unverified, ownerError: owner.error, error, errorDetail: owner.errorDetail, errorCause: owner.errorCause };
|
|
102
102
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pinned-mutation-admission.d.ts","sourceRoot":"","sources":["../src/pinned-mutation-admission.ts"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGvF,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,KAAK,EAKV,4BAA4B,EAC7B,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAgCtE,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;CAC1C,CAAC,CAAC;AAEH,wBAAgB,4BAA4B,CAC1C,aAAa,EAAE,kBAAkB,GAAG,SAAS,EAC7C,gBAAgB,EAAE,qBAAqB,GAAG,SAAS,GAClD,4BAA4B,GAAG,SAAS,CAO1C;AAuJD,wBAAsB,mCAAmC,CAAC,MAAM,EAAE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yBAAyB,EAAE,MAAM,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACjD,cAAc,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD,GAAG,OAAO,CAAC;IACV,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,4BAA4B,CAAC;CAClD,CAAC,
|
|
1
|
+
{"version":3,"file":"pinned-mutation-admission.d.ts","sourceRoot":"","sources":["../src/pinned-mutation-admission.ts"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGvF,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,KAAK,EAKV,4BAA4B,EAC7B,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAgCtE,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;CAC1C,CAAC,CAAC;AAEH,wBAAgB,4BAA4B,CAC1C,aAAa,EAAE,kBAAkB,GAAG,SAAS,EAC7C,gBAAgB,EAAE,qBAAqB,GAAG,SAAS,GAClD,4BAA4B,GAAG,SAAS,CAO1C;AAuJD,wBAAsB,mCAAmC,CAAC,MAAM,EAAE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yBAAyB,EAAE,MAAM,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACjD,cAAc,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD,GAAG,OAAO,CAAC;IACV,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,4BAA4B,CAAC;CAClD,CAAC,CAgQD"}
|
|
@@ -165,6 +165,10 @@ export async function preparePinnedWriteMutationAdmission(params) {
|
|
|
165
165
|
selectedTarget: params.resolvedTargetPath,
|
|
166
166
|
policy,
|
|
167
167
|
});
|
|
168
|
+
const nativeRoute = sharedRoute ?? (process.platform === "win32" && params.originalPath?.includes("/")
|
|
169
|
+
? simpleSharedRoute({ rootReal: params.rootReal, rootIdentity: params.rootIdentity,
|
|
170
|
+
originalPath: params.originalPath.replaceAll("/", "\\"), selectedTarget: params.resolvedTargetPath, policy })
|
|
171
|
+
: undefined);
|
|
168
172
|
let pinnedSession;
|
|
169
173
|
let epoch;
|
|
170
174
|
let pending;
|
|
@@ -194,13 +198,13 @@ export async function preparePinnedWriteMutationAdmission(params) {
|
|
|
194
198
|
}
|
|
195
199
|
return current;
|
|
196
200
|
};
|
|
197
|
-
const
|
|
201
|
+
const createSharedParentWalk = (admittedRoute) => {
|
|
198
202
|
const session = Object.freeze({
|
|
199
203
|
kind: "shared",
|
|
200
|
-
route:
|
|
204
|
+
route: admittedRoute.route,
|
|
201
205
|
selectedTarget: params.resolvedTargetPath,
|
|
202
206
|
nativeMode: getFsSafeNativeConfig().mode,
|
|
203
|
-
rootIdentity:
|
|
207
|
+
rootIdentity: admittedRoute.rootIdentity,
|
|
204
208
|
authorizationToken: Object.freeze({}),
|
|
205
209
|
});
|
|
206
210
|
let disposed = false;
|
|
@@ -314,7 +318,7 @@ export async function preparePinnedWriteMutationAdmission(params) {
|
|
|
314
318
|
disable();
|
|
315
319
|
},
|
|
316
320
|
});
|
|
317
|
-
}
|
|
321
|
+
};
|
|
318
322
|
const mutationAdmission = Object.freeze({
|
|
319
323
|
rejectParentSymlinks: policy.mutationSymlinks === "reject",
|
|
320
324
|
beginParentWalk: route ? () => {
|
|
@@ -329,7 +333,8 @@ export async function preparePinnedWriteMutationAdmission(params) {
|
|
|
329
333
|
pending = undefined;
|
|
330
334
|
return route;
|
|
331
335
|
} : undefined,
|
|
332
|
-
beginSharedParentWalk,
|
|
336
|
+
beginSharedParentWalk: sharedRoute ? () => createSharedParentWalk(sharedRoute) : undefined,
|
|
337
|
+
beginNativeParentWalk: nativeRoute ? () => createSharedParentWalk(nativeRoute) : undefined,
|
|
333
338
|
tryAuthorizeAtParent(request, parent) {
|
|
334
339
|
pending = undefined;
|
|
335
340
|
const reusable = epoch;
|
|
@@ -30,7 +30,6 @@ export type MutationPathObservation = Readonly<{
|
|
|
30
30
|
export declare function missingMutationSegments(observation: MutationPathObservation): number;
|
|
31
31
|
export declare function nextMissingMutationPath(observation: MutationPathObservation): string | undefined;
|
|
32
32
|
export declare function checkedMutationDirectory(pathname: string, canonicalPath: string, stat: Pick<BigIntStats, "dev" | "ino" | "mode" | "nlink">, observeCurrent?: MutationDirectoryObserver): MutationDirectoryObservation;
|
|
33
|
-
export declare function mutationDirectoryObservationCurrent(observation: MutationDirectoryObservation): boolean;
|
|
34
33
|
export declare function mutationObservationUsesDirectory(observation: MutationPathObservation, directory: MutationDirectoryObservation): boolean;
|
|
35
34
|
export declare function observeMutationPath(pathname: string): MutationPathObservation | undefined;
|
|
36
35
|
export declare function mutationObservationCurrent(observation: MutationPathObservation): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pinned-mutation-observation.d.ts","sourceRoot":"","sources":["../src/pinned-mutation-observation.ts"],"names":[],"mappings":"AAAA,OAAW,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAM/C,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAEH,QAAA,MAAM,2BAA2B,eAAmD,CAAC;AAGrF,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,CAAC,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,MAAM,wBAAwB,GAAG,SAAS,CAAC;AAEnF,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,CAAC,2BAA2B,CAAC,EAAE,IAAI,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC,CAAC;AA6BH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,uBAAuB,GAAG,MAAM,CAEpF;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,uBAAuB,GAAG,MAAM,GAAG,SAAS,CAGhG;AAKD,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,EACzD,cAAc,CAAC,EAAE,yBAAyB,GACzC,4BAA4B,CAY9B;AAQD,wBAAgB,
|
|
1
|
+
{"version":3,"file":"pinned-mutation-observation.d.ts","sourceRoot":"","sources":["../src/pinned-mutation-observation.ts"],"names":[],"mappings":"AAAA,OAAW,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAM/C,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAEH,QAAA,MAAM,2BAA2B,eAAmD,CAAC;AAGrF,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,CAAC,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,MAAM,wBAAwB,GAAG,SAAS,CAAC;AAEnF,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,CAAC,2BAA2B,CAAC,EAAE,IAAI,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC,CAAC;AA6BH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,uBAAuB,GAAG,MAAM,CAEpF;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,uBAAuB,GAAG,MAAM,GAAG,SAAS,CAGhG;AAKD,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,EACzD,cAAc,CAAC,EAAE,yBAAyB,GACzC,4BAA4B,CAY9B;AAQD,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,uBAAuB,EACpC,SAAS,EAAE,4BAA4B,GACtC,OAAO,CAMT;AAGD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS,CA0BzF;AAED,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,uBAAuB,GAAG,OAAO,CAaxF;AAKD,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,SAAS,uBAAuB,EAAE,EAChD,WAAW,EAAE,SAAS,4BAA4B,EAAE,GACnD,OAAO,CAiET;AAID,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,uBAAuB,EACpC,MAAM,EAAE,4BAA4B,EACpC,KAAK,EAAE,4BAA4B,GAClC,uBAAuB,GAAG,SAAS,CAiBrC"}
|
|
@@ -54,25 +54,6 @@ function checkedDirectory(observation) {
|
|
|
54
54
|
path.isAbsolute(observation.path) && path.isAbsolute(observation.canonicalPath) &&
|
|
55
55
|
directoryMode(observation.identity.mode);
|
|
56
56
|
}
|
|
57
|
-
export function mutationDirectoryObservationCurrent(observation) {
|
|
58
|
-
if (!checkedDirectory(observation))
|
|
59
|
-
return false;
|
|
60
|
-
try {
|
|
61
|
-
const observed = directoryObservers.get(observation)?.();
|
|
62
|
-
if (observed) {
|
|
63
|
-
return directoryMode(observed.identity.mode) &&
|
|
64
|
-
sameIdentity(observation.identity, observed.identity) &&
|
|
65
|
-
observed.canonicalPath === observation.canonicalPath;
|
|
66
|
-
}
|
|
67
|
-
const stat = inspectFileIdentitySync(() => fs.lstatSync(observation.path, { bigint: true }));
|
|
68
|
-
return stat.isDirectory() && !stat.isSymbolicLink() &&
|
|
69
|
-
sameIdentity(observation.identity, stat) &&
|
|
70
|
-
realpathSync.native(observation.path) === observation.canonicalPath;
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
57
|
export function mutationObservationUsesDirectory(observation, directory) {
|
|
77
58
|
return checkedDirectory(directory) &&
|
|
78
59
|
observation.ancestor === directory.path &&
|
|
@@ -9,6 +9,7 @@ type SharedMutationPolicy = Readonly<{
|
|
|
9
9
|
denyMutations?: DenyMutationPolicy;
|
|
10
10
|
mutationSymlinks?: MutationSymlinkPolicy;
|
|
11
11
|
}>;
|
|
12
|
+
export declare function ordinaryWindowsSegments(relativePath: string): boolean;
|
|
12
13
|
export declare function ordinarySharedAbsoluteInsideRoot(rootReal: string, candidatePath: string, rootIdentity: ExactRootIdentity): boolean;
|
|
13
14
|
export declare function simpleSharedRoute(params: {
|
|
14
15
|
rootReal: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pinned-mutation-shared-route.d.ts","sourceRoot":"","sources":["../src/pinned-mutation-shared-route.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAG9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEtE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEvE,KAAK,oBAAoB,GAAG,QAAQ,CAAC;IACnC,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;CAC1C,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"pinned-mutation-shared-route.d.ts","sourceRoot":"","sources":["../src/pinned-mutation-shared-route.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAG9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEtE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEvE,KAAK,oBAAoB,GAAG,QAAQ,CAAC;IACnC,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;CAC1C,CAAC,CAAC;AAQH,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAMrE;AAiBD,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,iBAAiB,GAC9B,OAAO,CAeT;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,oBAAoB,CAAC;CAC9B,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,iBAAiB,CAAA;CAAE,GAAG,SAAS,CAqBjE"}
|
|
@@ -7,7 +7,7 @@ function windowsReservedDeviceSegment(segment) {
|
|
|
7
7
|
const stem = segment.slice(0, extension < 0 ? segment.length : extension).toUpperCase();
|
|
8
8
|
return WINDOWS_RESERVED_DEVICE_NAMES.has(stem);
|
|
9
9
|
}
|
|
10
|
-
function ordinaryWindowsSegments(relativePath) {
|
|
10
|
+
export function ordinaryWindowsSegments(relativePath) {
|
|
11
11
|
if (relativePath === "" || relativePath.includes("/") || relativePath.includes("\0"))
|
|
12
12
|
return false;
|
|
13
13
|
const segments = relativePath.split("\\");
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { FileHandle } from "node:fs/promises";
|
|
2
|
+
import type { PinnedWriteInput } from "./pinned-write-types.js";
|
|
3
|
+
export declare function writePinnedInput(target: FileHandle | number, input: PinnedWriteInput, maxBytes?: number, assertBeforeMutation?: () => void): Promise<void>;
|
|
4
|
+
//# sourceMappingURL=pinned-write-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pinned-write-input.d.ts","sourceRoot":"","sources":["../src/pinned-write-input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,UAAU,GAAG,MAAM,EAC3B,KAAK,EAAE,gBAAgB,EACvB,QAAQ,CAAC,EAAE,MAAM,EACjB,oBAAoB,CAAC,EAAE,MAAM,IAAI,GAChC,OAAO,CAAC,IAAI,CAAC,CAoBf"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { writeCopyFileToFd } from "./copy-file-input.js";
|
|
2
|
+
import { FsSafeError } from "./errors.js";
|
|
3
|
+
import { writeAllToFile } from "./write-file-handle.js";
|
|
4
|
+
export async function writePinnedInput(target, input, maxBytes, assertBeforeMutation) {
|
|
5
|
+
if (input.kind === "file") {
|
|
6
|
+
await writeCopyFileToFd(typeof target === "number" ? target : target.fd, input, maxBytes, assertBeforeMutation);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
let bytes = 0;
|
|
10
|
+
const write = async (data) => {
|
|
11
|
+
bytes += data.byteLength;
|
|
12
|
+
if (maxBytes !== undefined && bytes > maxBytes) {
|
|
13
|
+
throw new FsSafeError("too-large", `file exceeds limit of ${maxBytes} bytes (got at least ${bytes})`);
|
|
14
|
+
}
|
|
15
|
+
await writeAllToFile(target, data, { assertBeforeMutation });
|
|
16
|
+
};
|
|
17
|
+
if (input.kind === "buffer") {
|
|
18
|
+
await write(typeof input.data === "string" ? Buffer.from(input.data, input.encoding ?? "utf8") : input.data);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
for await (const chunk of input.stream) {
|
|
22
|
+
await write(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FileHandle } from "node:fs/promises";
|
|
2
|
+
export declare function assertPinnedWriteMode(fd: number, mode: number): void;
|
|
3
|
+
export declare function preparePinnedWriteMode(handle: FileHandle, createdMode: number, assertBeforeMutation?: () => void): Promise<(() => void) | undefined>;
|
|
4
|
+
export declare function pinnedWriteModeAssertion(fd: number, mode: number, assertBeforeMutation?: () => void): () => void;
|
|
5
|
+
//# sourceMappingURL=pinned-write-mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pinned-write-mode.d.ts","sourceRoot":"","sources":["../src/pinned-write-mode.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAKpE;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,MAAM,EACnB,oBAAoB,CAAC,EAAE,MAAM,IAAI,GAChC,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC,CAKnC;AAED,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,oBAAoB,CAAC,EAAE,MAAM,IAAI,GAChC,MAAM,IAAI,CAKZ"}
|