@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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ArchiveKind } from "./archive-kind.js";
|
|
1
2
|
import type { TarMeterLimits } from "./archive-limits.js";
|
|
2
3
|
import { type AdmittedTarMember } from "./archive-tar-wasm.js";
|
|
3
4
|
/** Buffers are private immutable snapshots, just like the staged file route. */
|
|
@@ -11,6 +12,7 @@ type TarInput = {
|
|
|
11
12
|
export declare function inspectTar(params: TarInput & {
|
|
12
13
|
limits: TarMeterLimits;
|
|
13
14
|
signal?: AbortSignal;
|
|
15
|
+
kind?: Exclude<ArchiveKind, "zip">;
|
|
14
16
|
onMember?: (entry: AdmittedTarMember) => void;
|
|
15
17
|
}): Promise<void>;
|
|
16
18
|
/** Replay in physical order, retaining at most one decoded chunk. Every range
|
|
@@ -18,6 +20,7 @@ export declare function inspectTar(params: TarInput & {
|
|
|
18
20
|
export declare function replayTar<T extends AdmittedTarMember>(params: TarInput & {
|
|
19
21
|
limits: TarMeterLimits;
|
|
20
22
|
signal?: AbortSignal;
|
|
23
|
+
kind?: Exclude<ArchiveKind, "zip">;
|
|
21
24
|
members: readonly T[];
|
|
22
25
|
consume(member: T, payload: AsyncIterable<Buffer>): Promise<void>;
|
|
23
26
|
}): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive-tar-stream.d.ts","sourceRoot":"","sources":["../src/archive-tar-stream.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,
|
|
1
|
+
{"version":3,"file":"archive-tar-stream.d.ts","sourceRoot":"","sources":["../src/archive-tar-stream.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAmC,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGhG,gFAAgF;AAChF,KAAK,QAAQ,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AA0EhH,wBAAsB,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG;IAClD,MAAM,EAAE,cAAc,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACjF,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC/C,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhB;AAED;2DAC2D;AAC3D,wBAAsB,SAAS,CAAC,CAAC,SAAS,iBAAiB,EAAE,MAAM,EAAE,QAAQ,GAAG;IAC9E,MAAM,EAAE,cAAc,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACjF,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;IACtB,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BhB"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import { Readable, Writable } from "node:stream";
|
|
3
|
-
import { pipeline } from "node:stream/promises";
|
|
3
|
+
import { finished, pipeline } from "node:stream/promises";
|
|
4
4
|
import { createGunzip } from "node:zlib";
|
|
5
5
|
import { GzipInput, isGzipBuffer, validateGzipBufferTail, validateGzipContainerTail } from "./archive-gzip-tail.js";
|
|
6
6
|
import { ArchiveFormatError } from "./archive-errors.js";
|
|
7
|
-
import { TarParserStream } from "./archive-tar-wasm.js";
|
|
7
|
+
import { TarParserStream, TarWasmSession } from "./archive-tar-wasm.js";
|
|
8
8
|
import { readFileWindowFully } from "./positional-read.js";
|
|
9
9
|
function* bufferChunks(buffer) {
|
|
10
10
|
for (let offset = 0; offset < buffer.length; offset += 65536)
|
|
@@ -23,45 +23,64 @@ async function gzipFile(filePath) {
|
|
|
23
23
|
}
|
|
24
24
|
async function withTarStream(params, consume) {
|
|
25
25
|
const buffer = params.archiveBuffer;
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
? Readable.from(bufferChunks(buffer), { objectMode: false, highWaterMark: 65536 })
|
|
30
|
-
: fs.createReadStream(params.archivePath, { highWaterMark: 65536 });
|
|
31
|
-
// Match the WASM input window for both staged files and buffered reads.
|
|
32
|
-
const decoder = gzip ? createGunzip({ chunkSize: 65536 }) : undefined;
|
|
33
|
-
const gzipInput = decoder ? new GzipInput(decoder) : undefined;
|
|
34
|
-
const destroy = (error) => {
|
|
35
|
-
input.destroy(error);
|
|
36
|
-
gzipInput?.destroy(error);
|
|
37
|
-
decoder?.destroy(error);
|
|
38
|
-
parser.destroy(error);
|
|
39
|
-
};
|
|
40
|
-
const pumps = decoder && gzipInput
|
|
41
|
-
? [pipeline(decoder, parser, { signal: params.signal }), pipeline(input, gzipInput, { signal: params.signal })]
|
|
42
|
-
: [pipeline(input, parser, { signal: params.signal })];
|
|
43
|
-
// Either pump tears down both routes; join every pump even after the first failure.
|
|
44
|
-
const settled = Promise.all(pumps.map((pump) => pump.then(() => undefined, (cause) => {
|
|
45
|
-
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
46
|
-
destroy(error);
|
|
47
|
-
return error;
|
|
48
|
-
}))).then((errors) => errors.find((error) => error !== undefined));
|
|
26
|
+
const kind = params.kind ?? "tar";
|
|
27
|
+
const gzip = kind === "tar" && (buffer !== undefined ? isGzipBuffer(buffer) : await gzipFile(params.archivePath));
|
|
28
|
+
const session = new TarWasmSession(params.limits);
|
|
49
29
|
try {
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
30
|
+
const parser = new TarParserStream(params.limits, params.onMember, session);
|
|
31
|
+
const input = buffer !== undefined
|
|
32
|
+
? Readable.from(bufferChunks(buffer), { objectMode: false, highWaterMark: 65536 })
|
|
33
|
+
: fs.createReadStream(params.archivePath, { highWaterMark: 65536 });
|
|
34
|
+
// Match the WASM input window for both staged files and buffered reads.
|
|
35
|
+
const decoder = gzip ? createGunzip({ chunkSize: 65536 }) : undefined;
|
|
36
|
+
const gzipInput = decoder ? new GzipInput(decoder) : undefined;
|
|
37
|
+
const destroy = (error) => {
|
|
38
|
+
input.destroy(error);
|
|
39
|
+
gzipInput?.destroy(error);
|
|
40
|
+
decoder?.destroy(error);
|
|
41
|
+
parser.destroy(error);
|
|
42
|
+
};
|
|
43
|
+
// A pipeline with an async-generator stage can settle before its file's
|
|
44
|
+
// asynchronous close. Join the actual close events before freeing WASM.
|
|
45
|
+
const closed = Promise.all([input, parser, ...(decoder ? [decoder] : []), ...(gzipInput ? [gzipInput] : [])].map(stream => {
|
|
46
|
+
const closing = new Promise(resolve => { stream.once("close", resolve); });
|
|
47
|
+
return finished(stream, { cleanup: true }).then(() => undefined, (cause) => cause instanceof Error ? cause : new Error(String(cause))).then(async (error) => { await closing; return error; });
|
|
48
|
+
}));
|
|
49
|
+
const pumps = decoder && gzipInput
|
|
50
|
+
? [pipeline(decoder, parser, { signal: params.signal }), pipeline(input, gzipInput, { signal: params.signal })]
|
|
51
|
+
: kind !== "tar"
|
|
52
|
+
? [pipeline(input, (source) => session.decode(source, kind, params.signal), parser, { signal: params.signal })]
|
|
53
|
+
: [pipeline(input, parser, { signal: params.signal })];
|
|
54
|
+
// Either pump tears down both routes; join every pump even after the first failure.
|
|
55
|
+
const settled = Promise.all(pumps.map((pump) => pump.then(() => undefined, (cause) => {
|
|
56
|
+
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
57
|
+
destroy(error);
|
|
58
|
+
return error;
|
|
59
|
+
}))).then((errors) => errors.find((error) => error !== undefined));
|
|
60
|
+
try {
|
|
61
|
+
const result = await consume(parser);
|
|
62
|
+
const error = await settled;
|
|
63
|
+
if (error)
|
|
64
|
+
throw error;
|
|
65
|
+
const closeError = (await closed).find(error => error !== undefined);
|
|
66
|
+
if (closeError)
|
|
67
|
+
throw closeError;
|
|
68
|
+
if (gzipInput) {
|
|
69
|
+
if (buffer !== undefined)
|
|
70
|
+
await validateGzipBufferTail(buffer, gzipInput.tailOffset, params.signal);
|
|
71
|
+
else
|
|
72
|
+
await validateGzipContainerTail(params.archivePath, gzipInput.tailOffset, params.signal);
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
destroy();
|
|
78
|
+
await settled;
|
|
79
|
+
await closed;
|
|
59
80
|
}
|
|
60
|
-
return result;
|
|
61
81
|
}
|
|
62
82
|
finally {
|
|
63
|
-
|
|
64
|
-
await settled;
|
|
83
|
+
session.dispose();
|
|
65
84
|
}
|
|
66
85
|
}
|
|
67
86
|
export async function inspectTar(params) {
|
|
@@ -4,13 +4,25 @@ import type { TarEntryInfo } from "./archive-tar.js";
|
|
|
4
4
|
export type AdmittedTarMember = TarEntryInfo & {
|
|
5
5
|
offset: number;
|
|
6
6
|
};
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
/** One bounded memory domain owns both admission and decompression. Its owner
|
|
8
|
+
* must join the decoder and parser before disposing this shared instance. */
|
|
9
|
+
export declare class TarWasmSession {
|
|
10
10
|
private abi;
|
|
11
|
-
constructor(limits: TarMeterLimits
|
|
11
|
+
constructor(limits: TarMeterLimits);
|
|
12
12
|
private bytes;
|
|
13
13
|
private text;
|
|
14
|
+
parse(chunk: Buffer, onMember?: (entry: AdmittedTarMember) => void): void;
|
|
15
|
+
finish(): void;
|
|
16
|
+
private codecError;
|
|
17
|
+
decode(source: AsyncIterable<Buffer>, kind: "tar-zstd" | "tar-bzip2", signal?: AbortSignal): AsyncGenerator<Buffer>;
|
|
18
|
+
dispose(): void;
|
|
19
|
+
}
|
|
20
|
+
/** Backpressure-aware transport only; all TAR semantics live in the Rust core. */
|
|
21
|
+
export declare class TarParserStream extends Transform {
|
|
22
|
+
private readonly onMember?;
|
|
23
|
+
private readonly session;
|
|
24
|
+
private readonly ownsSession;
|
|
25
|
+
constructor(limits: TarMeterLimits, onMember?: ((entry: AdmittedTarMember) => void) | undefined, session?: TarWasmSession);
|
|
14
26
|
_transform(chunk: Buffer, _encoding: BufferEncoding, callback: TransformCallback): void;
|
|
15
27
|
_flush(callback: TransformCallback): void;
|
|
16
28
|
_destroy(error: Error | null, callback: (error: Error | null) => void): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive-tar-wasm.d.ts","sourceRoot":"","sources":["../src/archive-tar-wasm.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"archive-tar-wasm.d.ts","sourceRoot":"","sources":["../src/archive-tar-wasm.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAmDlE;6EAC6E;AAC7E,qBAAa,cAAc;IACzB,OAAO,CAAC,GAAG,CAAkB;IAC7B,YAAY,MAAM,EAAE,cAAc,EAMjC;IACD,OAAO,CAAC,KAAK;IAQb,OAAO,CAAC,IAAI;IAIZ,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAAG,IAAI,CAkBxE;IACD,MAAM,IAAI,IAAI,CAEb;IACD,OAAO,CAAC,UAAU;IAIX,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,GAAG,WAAW,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CA2DzH;IACD,OAAO,IAAI,IAAI,CAOd;CACF;AAED,kFAAkF;AAClF,qBAAa,eAAgB,SAAQ,SAAS;IAGR,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAF9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IACtC,YAAY,MAAM,EAAE,cAAc,EAAmB,QAAQ,CAAC,GAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,aAAA,EAAE,OAAO,CAAC,EAAE,cAAc,EAI3H;IACQ,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAG/F;IACQ,MAAM,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAGjD;IACQ,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAIpF;CACF"}
|
package/dist/archive-tar-wasm.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { classifyArchiveParserError } from "./archive-parser-errors.js";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { Transform } from "node:stream";
|
|
4
|
+
import { setImmediate } from "node:timers/promises";
|
|
4
5
|
import { ArchiveFormatError } from "./archive-errors.js";
|
|
5
6
|
// Node exposes WebAssembly without DOM globals; keep the private ABI types local.
|
|
6
7
|
const wasm = globalThis.WebAssembly;
|
|
@@ -24,17 +25,14 @@ function parserError(message) {
|
|
|
24
25
|
return mapped;
|
|
25
26
|
return new ArchiveFormatError(message.replace(/^archive-header-invalid:/, "invalid TAR header:"));
|
|
26
27
|
}
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
/** One bounded memory domain owns both admission and decompression. Its owner
|
|
29
|
+
* must join the decoder and parser before disposing this shared instance. */
|
|
30
|
+
export class TarWasmSession {
|
|
30
31
|
abi;
|
|
31
|
-
constructor(limits
|
|
32
|
-
super();
|
|
33
|
-
this.onMember = onMember;
|
|
32
|
+
constructor(limits) {
|
|
34
33
|
this.abi = instance();
|
|
35
34
|
if (this.abi.init(limits.maxEntries, limits.maxMetaEntryBytes, limits.maxDecodedBytes, limits.maxManifestBytes, Number(process.platform === "win32")) !== 0) {
|
|
36
|
-
this.
|
|
37
|
-
this.abi = undefined;
|
|
35
|
+
this.dispose();
|
|
38
36
|
throw new RangeError("invalid TAR parser limits");
|
|
39
37
|
}
|
|
40
38
|
}
|
|
@@ -50,28 +48,133 @@ export class TarParserStream extends Transform {
|
|
|
50
48
|
const abi = this.abi;
|
|
51
49
|
return utf8Decoder.decode(this.bytes(abi.text_ptr(), abi.text_len()));
|
|
52
50
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
this.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
51
|
+
parse(chunk, onMember) {
|
|
52
|
+
const abi = this.abi;
|
|
53
|
+
for (let offset = 0; offset < chunk.length; offset += 65536) {
|
|
54
|
+
const length = Math.min(65536, chunk.length - offset);
|
|
55
|
+
this.bytes(abi.input_ptr(), length).set(chunk.subarray(offset, offset + length));
|
|
56
|
+
// A member event can stop before the end of this already-copied inbox.
|
|
57
|
+
for (let consumed = 0; consumed < length;) {
|
|
58
|
+
const used = abi.push(consumed, length - consumed);
|
|
59
|
+
if (used < 0)
|
|
60
|
+
throw parserError(this.text());
|
|
61
|
+
if (used === 0 || used > length - consumed)
|
|
62
|
+
throw new ArchiveFormatError("TAR WASM made no progress");
|
|
63
|
+
consumed += used;
|
|
64
|
+
const type = abi.member_type();
|
|
65
|
+
if (type >= 0)
|
|
66
|
+
onMember?.({
|
|
67
|
+
path: this.text(), type: types.get(type) ?? "Unsupported", size: abi.member_size(),
|
|
68
|
+
mode: abi.member_mode(), offset: abi.member_offset(),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
finish() {
|
|
74
|
+
if (this.abi.finish() !== 0)
|
|
75
|
+
throw parserError(this.text());
|
|
76
|
+
}
|
|
77
|
+
codecError() {
|
|
78
|
+
const abi = this.abi;
|
|
79
|
+
return new ArchiveFormatError(utf8Decoder.decode(this.bytes(abi.codec_error_ptr(), abi.codec_error_len())));
|
|
80
|
+
}
|
|
81
|
+
async *decode(source, kind, signal) {
|
|
82
|
+
const abi = this.abi;
|
|
83
|
+
signal?.throwIfAborted();
|
|
84
|
+
if (abi.codec_init(kind === "tar-bzip2" ? 1 : 2) !== 0)
|
|
85
|
+
throw this.codecError();
|
|
86
|
+
let work = 0;
|
|
87
|
+
let calls = 0;
|
|
88
|
+
let unconsumedBoundary = false;
|
|
89
|
+
const step = (input) => {
|
|
90
|
+
signal?.throwIfAborted();
|
|
91
|
+
this.bytes(abi.codec_input_ptr(), input.length).set(input);
|
|
92
|
+
const result = abi.codec_push(input.length);
|
|
93
|
+
if (result < 0)
|
|
94
|
+
throw this.codecError();
|
|
95
|
+
const consumed = abi.codec_consumed(), produced = abi.codec_produced();
|
|
96
|
+
if (!Number.isInteger(consumed) || consumed < 0 || consumed > input.length ||
|
|
97
|
+
!Number.isInteger(produced) || produced < 0 || produced > 65536 ||
|
|
98
|
+
(result !== 0 && result !== 1) ||
|
|
99
|
+
(input.length > 0 && consumed === 0 && produced === 0 && (result !== 1 || unconsumedBoundary))) {
|
|
100
|
+
throw new ArchiveFormatError("compressed TAR WASM made no progress");
|
|
101
|
+
}
|
|
102
|
+
if (input.length > 0)
|
|
103
|
+
unconsumedBoundary = consumed === 0 && produced === 0;
|
|
104
|
+
work += consumed + produced;
|
|
105
|
+
calls++;
|
|
106
|
+
// The parser can grow this same memory, and the next codec call reuses it.
|
|
107
|
+
return { consumed, output: produced ? Buffer.from(this.bytes(abi.codec_output_ptr(), produced)) : undefined };
|
|
108
|
+
};
|
|
109
|
+
const empty = Buffer.alloc(0);
|
|
110
|
+
// Yield even for output-free skippable frames and arbitrarily small members.
|
|
111
|
+
const yieldIfNeeded = async () => {
|
|
112
|
+
if (work >= 256 * 1024 || calls >= 32) {
|
|
113
|
+
work = 0;
|
|
114
|
+
calls = 0;
|
|
115
|
+
await setImmediate(undefined, { signal });
|
|
116
|
+
}
|
|
117
|
+
signal?.throwIfAborted();
|
|
118
|
+
};
|
|
119
|
+
for await (const chunk of source) {
|
|
120
|
+
for (let offset = 0; offset < chunk.length;) {
|
|
121
|
+
const { consumed, output } = step(chunk.subarray(offset, offset + 65536));
|
|
122
|
+
offset += consumed;
|
|
123
|
+
if (output)
|
|
124
|
+
yield output;
|
|
125
|
+
await yieldIfNeeded();
|
|
126
|
+
// A full output window can leave more decoded bytes with no new input.
|
|
127
|
+
if (output) {
|
|
128
|
+
for (;;) {
|
|
129
|
+
const drained = step(empty);
|
|
130
|
+
if (drained.output)
|
|
131
|
+
yield drained.output;
|
|
132
|
+
await yieldIfNeeded();
|
|
133
|
+
if (!drained.output)
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
73
136
|
}
|
|
74
137
|
}
|
|
138
|
+
}
|
|
139
|
+
// Physical EOF, rather than a selected range or TAR EOF, ends the decoder.
|
|
140
|
+
for (;;) {
|
|
141
|
+
const drained = step(empty);
|
|
142
|
+
if (drained.output)
|
|
143
|
+
yield drained.output;
|
|
144
|
+
await yieldIfNeeded();
|
|
145
|
+
if (!drained.output)
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
if (abi.codec_finish() !== 0)
|
|
149
|
+
throw this.codecError();
|
|
150
|
+
}
|
|
151
|
+
dispose() {
|
|
152
|
+
const abi = this.abi;
|
|
153
|
+
this.abi = undefined;
|
|
154
|
+
if (abi) {
|
|
155
|
+
try {
|
|
156
|
+
abi.codec_dispose();
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
abi.dispose();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** Backpressure-aware transport only; all TAR semantics live in the Rust core. */
|
|
165
|
+
export class TarParserStream extends Transform {
|
|
166
|
+
onMember;
|
|
167
|
+
session;
|
|
168
|
+
ownsSession;
|
|
169
|
+
constructor(limits, onMember, session) {
|
|
170
|
+
super();
|
|
171
|
+
this.onMember = onMember;
|
|
172
|
+
this.session = session ?? new TarWasmSession(limits);
|
|
173
|
+
this.ownsSession = session === undefined;
|
|
174
|
+
}
|
|
175
|
+
_transform(chunk, _encoding, callback) {
|
|
176
|
+
try {
|
|
177
|
+
this.session.parse(chunk, this.onMember);
|
|
75
178
|
callback(null, chunk);
|
|
76
179
|
}
|
|
77
180
|
catch (error) {
|
|
@@ -80,8 +183,7 @@ export class TarParserStream extends Transform {
|
|
|
80
183
|
}
|
|
81
184
|
_flush(callback) {
|
|
82
185
|
try {
|
|
83
|
-
|
|
84
|
-
throw parserError(this.text());
|
|
186
|
+
this.session.finish();
|
|
85
187
|
callback();
|
|
86
188
|
}
|
|
87
189
|
catch (error) {
|
|
@@ -90,14 +192,12 @@ export class TarParserStream extends Transform {
|
|
|
90
192
|
}
|
|
91
193
|
_destroy(error, callback) {
|
|
92
194
|
try {
|
|
93
|
-
this.
|
|
195
|
+
if (this.ownsSession)
|
|
196
|
+
this.session.dispose();
|
|
94
197
|
}
|
|
95
198
|
catch (cause) {
|
|
96
199
|
error ??= cause instanceof Error ? cause : new Error(String(cause));
|
|
97
200
|
}
|
|
98
|
-
finally {
|
|
99
|
-
this.abi = undefined;
|
|
100
|
-
}
|
|
101
201
|
callback(error);
|
|
102
202
|
}
|
|
103
203
|
}
|
|
@@ -10,8 +10,12 @@ export type ZipDirectoryEntry = {
|
|
|
10
10
|
creatorSystem: number;
|
|
11
11
|
externalAttributes: number;
|
|
12
12
|
size: number;
|
|
13
|
+
compressedSize: number;
|
|
14
|
+
compressionMethod: number;
|
|
15
|
+
crc32: number;
|
|
13
16
|
path?: string;
|
|
14
17
|
portableKey: string;
|
|
18
|
+
portableDirectory: boolean;
|
|
15
19
|
kind: ArchiveEntryKind;
|
|
16
20
|
};
|
|
17
21
|
export declare function scanZipDirectory(size: number, limits: ResolvedArchiveExtractLimits, onEntry?: (entry: ZipDirectoryEntry) => void): ZipScan;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive-zip-directory.d.ts","sourceRoot":"","sources":["../src/archive-zip-directory.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,MAAM,OAAO,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AACzD,MAAM,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AACzD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,gBAAgB,CAAC;CACxB,CAAC;AA4IF,wBAAiB,gBAAgB,CAC/B,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,4BAA4B,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAC/F,OAAO,
|
|
1
|
+
{"version":3,"file":"archive-zip-directory.d.ts","sourceRoot":"","sources":["../src/archive-zip-directory.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,MAAM,OAAO,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AACzD,MAAM,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AACzD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,IAAI,EAAE,gBAAgB,CAAC;CACxB,CAAC;AA4IF,wBAAiB,gBAAgB,CAC/B,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,4BAA4B,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAC/F,OAAO,CAqET"}
|
|
@@ -224,6 +224,8 @@ export function* scanZipDirectory(size, limits, onEntry) {
|
|
|
224
224
|
onEntry?.({
|
|
225
225
|
index: count - 1, creatorSystem: central[5], externalAttributes: central.readUInt32LE(38),
|
|
226
226
|
size: values.uncompressed, path: admittedName.path, portableKey: admittedName.portableKey,
|
|
227
|
+
compressedSize: values.compressed, compressionMethod: central.readUInt16LE(10), crc32: crc,
|
|
228
|
+
portableDirectory: admittedName.portableDirectory,
|
|
227
229
|
kind: entryKind(central.readUInt32LE(38), admittedName.directory),
|
|
228
230
|
});
|
|
229
231
|
at = next;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { type ArchiveEntryModePolicy } from "./archive-policy.js";
|
|
1
|
+
import { type ArchiveEntryModePolicy, type ArchiveEntryKind } from "./archive-policy.js";
|
|
2
|
+
import type { ZipDirectoryEntry } from "./archive-zip-directory.js";
|
|
2
3
|
export type ZipEntry = {
|
|
3
4
|
name: string;
|
|
4
5
|
dir: boolean;
|
|
5
6
|
unixPermissions?: number | null;
|
|
7
|
+
dosPermissions?: number | null;
|
|
6
8
|
_data?: {
|
|
7
9
|
crc32?: number;
|
|
8
10
|
uncompressedSize?: number;
|
|
@@ -10,12 +12,14 @@ export type ZipEntry = {
|
|
|
10
12
|
nodeStream?: () => NodeJS.ReadableStream;
|
|
11
13
|
async: (type: "nodebuffer") => Promise<Buffer>;
|
|
12
14
|
};
|
|
15
|
+
/** Internal: register only after the complete decoder/admission association. */
|
|
16
|
+
export declare function registerAdmittedZipEntry(entry: ZipEntry, physical: ZipDirectoryEntry): void;
|
|
13
17
|
export declare function zipEntryIntegrityMetadata(entry: ZipEntry): {
|
|
14
18
|
crc32?: number;
|
|
15
19
|
uncompressedSize?: number;
|
|
16
20
|
} | undefined;
|
|
17
|
-
export declare function hasDeferredEmptyZipData(entry: ZipEntry): boolean;
|
|
18
21
|
export declare function isZipSymlinkEntry(entry: ZipEntry): boolean;
|
|
22
|
+
export declare function zipEntryKind(entry: ZipEntry): ArchiveEntryKind;
|
|
19
23
|
export declare function zipEntryMode(entry: ZipEntry, policy: ArchiveEntryModePolicy | undefined): number;
|
|
20
24
|
export declare function zipEntryDeclaredSize(entry: ZipEntry): number;
|
|
21
25
|
//# sourceMappingURL=archive-zip-entry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive-zip-entry.d.ts","sourceRoot":"","sources":["../src/archive-zip-entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,sBAAsB,
|
|
1
|
+
{"version":3,"file":"archive-zip-entry.d.ts","sourceRoot":"","sources":["../src/archive-zip-entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7E,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC,cAAc,CAAC;IACzC,KAAK,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAChD,CAAC;AAIF,gFAAgF;AAChF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAQ3F;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,QAAQ,GACd;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAI3D;AAKD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAE1D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,gBAAgB,CAM9D;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,QAAQ,EACf,MAAM,EAAE,sBAAsB,GAAG,SAAS,GACzC,MAAM,CAOR;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAE5D"}
|
|
@@ -1,27 +1,42 @@
|
|
|
1
1
|
import { resolveArchiveEntryMode, } from "./archive-policy.js";
|
|
2
|
+
const admittedMetadata = new WeakMap();
|
|
3
|
+
/** Internal: register only after the complete decoder/admission association. */
|
|
4
|
+
export function registerAdmittedZipEntry(entry, physical) {
|
|
5
|
+
const mode = physical.creatorSystem === 3 ? physical.externalAttributes >>> 16 : undefined;
|
|
6
|
+
admittedMetadata.set(entry, { kind: physical.kind, mode, size: physical.size });
|
|
7
|
+
entry.dir = physical.kind === "directory";
|
|
8
|
+
// Previously unsupported non-UNIX symlinks must also be recognizable to
|
|
9
|
+
// public preflight consumers using JSZip's conventional type inspection.
|
|
10
|
+
entry.unixPermissions = mode ?? (physical.kind === "symlink" ? 0o120000 : null);
|
|
11
|
+
entry.dosPermissions = physical.creatorSystem === 0 ? physical.externalAttributes & 0x3f : null;
|
|
12
|
+
}
|
|
2
13
|
export function zipEntryIntegrityMetadata(entry) {
|
|
3
14
|
const data = entry._data;
|
|
4
15
|
if (!data || "then" in data)
|
|
5
16
|
return undefined;
|
|
6
17
|
return data;
|
|
7
18
|
}
|
|
8
|
-
export function hasDeferredEmptyZipData(entry) {
|
|
9
|
-
const data = entry._data;
|
|
10
|
-
return Boolean(data && "then" in data);
|
|
11
|
-
}
|
|
12
19
|
const ZIP_UNIX_FILE_TYPE_MASK = 0o170000;
|
|
13
20
|
const ZIP_UNIX_SYMLINK_TYPE = 0o120000;
|
|
14
21
|
export function isZipSymlinkEntry(entry) {
|
|
15
|
-
return (
|
|
16
|
-
|
|
22
|
+
return zipEntryKind(entry) === "symlink";
|
|
23
|
+
}
|
|
24
|
+
export function zipEntryKind(entry) {
|
|
25
|
+
const metadata = admittedMetadata.get(entry);
|
|
26
|
+
if (metadata)
|
|
27
|
+
return metadata.kind;
|
|
28
|
+
return typeof entry.unixPermissions === "number" &&
|
|
29
|
+
(entry.unixPermissions & ZIP_UNIX_FILE_TYPE_MASK) === ZIP_UNIX_SYMLINK_TYPE
|
|
30
|
+
? "symlink" : entry.dir ? "directory" : "file";
|
|
17
31
|
}
|
|
18
32
|
export function zipEntryMode(entry, policy) {
|
|
33
|
+
const metadata = admittedMetadata.get(entry);
|
|
19
34
|
return resolveArchiveEntryMode({
|
|
20
35
|
kind: entry.dir ? "directory" : "file",
|
|
21
|
-
archivedMode: entry.unixPermissions,
|
|
36
|
+
archivedMode: metadata ? metadata.mode : entry.unixPermissions,
|
|
22
37
|
policy,
|
|
23
38
|
});
|
|
24
39
|
}
|
|
25
40
|
export function zipEntryDeclaredSize(entry) {
|
|
26
|
-
return Math.max(0, Math.floor(zipEntryIntegrityMetadata(entry)?.uncompressedSize ?? 0));
|
|
41
|
+
return admittedMetadata.get(entry)?.size ?? Math.max(0, Math.floor(zipEntryIntegrityMetadata(entry)?.uncompressedSize ?? 0));
|
|
27
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive-zip-integrity.d.ts","sourceRoot":"","sources":["../src/archive-zip-integrity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,
|
|
1
|
+
{"version":3,"file":"archive-zip-integrity.d.ts","sourceRoot":"","sources":["../src/archive-zip-integrity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAEL,KAAK,QAAQ,EACd,MAAM,wBAAwB,CAAC;AAIhC,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAQhE;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,CA+BtE"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Transform } from "node:stream";
|
|
2
2
|
import { ArchiveFormatError } from "./archive-errors.js";
|
|
3
|
-
import {
|
|
3
|
+
import { zipEntryIntegrityMetadata, } from "./archive-zip-entry.js";
|
|
4
4
|
import { updateCrc32 } from "./archive-crc32.js";
|
|
5
5
|
export function normalizeZipIntegrityError(error) {
|
|
6
6
|
if (error instanceof Error &&
|
|
@@ -11,9 +11,8 @@ export function normalizeZipIntegrityError(error) {
|
|
|
11
11
|
}
|
|
12
12
|
export function createZipIntegrityTransform(entry) {
|
|
13
13
|
const metadata = zipEntryIntegrityMetadata(entry);
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const expectedSize = deferredEmpty ? 0 : metadata?.uncompressedSize;
|
|
14
|
+
const expectedCrc32 = metadata?.crc32;
|
|
15
|
+
const expectedSize = metadata?.uncompressedSize;
|
|
17
16
|
if (typeof expectedCrc32 !== "number" ||
|
|
18
17
|
!Number.isInteger(expectedCrc32) ||
|
|
19
18
|
typeof expectedSize !== "number" ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive-zip-loader.d.ts","sourceRoot":"","sources":["../src/archive-zip-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAIpE,MAAM,MAAM,mBAAmB,GAAG;
|
|
1
|
+
{"version":3,"file":"archive-zip-loader.d.ts","sourceRoot":"","sources":["../src/archive-zip-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAIpE,MAAM,MAAM,mBAAmB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AA2BrE,kFAAkF;AAClF,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,GAAG,UAAU,EAC3B,QAAQ,EAAE,iBAAiB,EAAE,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAkF9B"}
|