@camstack/system 1.2.381 → 1.2.383
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/dist/addon-runner.js +4 -2
- package/dist/addon-runner.mjs +4 -2
- package/dist/addon-utils.js +1 -1
- package/dist/addon-utils.mjs +1 -1
- package/dist/auth/admin-token-manager.d.ts +75 -0
- package/dist/auth/api-key-manager.d.ts +1 -14
- package/dist/auth/auth-audit-log.d.ts +59 -0
- package/dist/auth/auth-manager.d.ts +28 -16
- package/dist/auth/cidr.d.ts +22 -0
- package/dist/auth/login-session-manager.d.ts +158 -0
- package/dist/auth/user-management-internal.d.ts +69 -0
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +14 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +291 -3631
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +284 -3617
- package/dist/builtins/backup-orchestrator/encryption-key-store.d.ts +36 -0
- package/dist/builtins/backup-orchestrator/manifest-store.d.ts +19 -1
- package/dist/builtins/backup-orchestrator/restore-archive.d.ts +24 -0
- package/dist/builtins/calendars/calendars.addon.js +1 -1
- package/dist/builtins/calendars/calendars.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +1110 -735
- package/dist/builtins/keychain/index.mjs +1109 -734
- package/dist/builtins/keychain/keychain-reset-trigger.d.ts +25 -0
- package/dist/builtins/keychain/keychain-service.d.ts +36 -3
- package/dist/builtins/keychain/keychain-store.d.ts +24 -1
- package/dist/builtins/keychain/system-held-secrets.d.ts +2 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.d.ts +16 -0
- package/dist/builtins/local-auth/local-auth.addon.js +1028 -294
- package/dist/builtins/local-auth/local-auth.addon.mjs +1035 -299
- package/dist/builtins/local-network/local-network.addon.js +3 -3
- package/dist/builtins/local-network/local-network.addon.mjs +3 -3
- package/dist/builtins/loki-logging/index.js +97 -29
- package/dist/builtins/loki-logging/index.mjs +97 -29
- package/dist/builtins/loki-logging/loki-logging.addon.d.ts +7 -23
- package/dist/builtins/loki-logging/retire-enabled-flag.d.ts +23 -0
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +2 -2
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +2 -2
- package/dist/builtins/system-backup/backup-encryption.d.ts +57 -0
- package/dist/builtins/system-backup/system-backup.service.d.ts +16 -1
- package/dist/builtins/system-config/cluster-secret-keeper.d.ts +7 -0
- package/dist/builtins/system-config/index.d.ts +1 -0
- package/dist/builtins/system-config/index.js +2 -0
- package/dist/builtins/system-config/index.mjs +2 -2
- package/dist/builtins/system-config/mesh-actions.d.ts +19 -0
- package/dist/builtins/system-config/system-config.addon.d.ts +47 -4
- package/dist/builtins/system-config/system-config.addon.js +87858 -43
- package/dist/builtins/system-config/system-config.addon.mjs +87813 -39
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{child-cap-dispatch-hf-Gce_4.js → child-cap-dispatch-BD8fhJ1b.js} +7 -4
- package/dist/{child-cap-dispatch-BTe4eKep.mjs → child-cap-dispatch-C68N2a6Y.mjs} +11 -8
- package/dist/{composition-sources-4SmsP0O4.js → composition-sources-ChpT_Yw4.js} +1 -1
- package/dist/{composition-sources-CgOQVIwa.mjs → composition-sources-DM7Ft_tp.mjs} +1 -1
- package/dist/{cluster-secret-BUiG8DCo.js → constants-CDpry1_T.js} +82 -1
- package/dist/{cluster-secret-DgJTZ4qY.mjs → constants-e3mCa1jG.mjs} +23 -2
- package/dist/{dist-BugrtARh.js → dist-CUNGH0fs.js} +1755 -157
- package/dist/{dist-BC0GnGeg.mjs → dist-osl3bkF0.mjs} +1732 -158
- package/dist/{event-loop-stall-monitor-GgpnfAC0.mjs → event-loop-stall-monitor-BeeWMnyT.mjs} +15 -15
- package/dist/{event-loop-stall-monitor-CnQ-K6Gn.js → event-loop-stall-monitor-Dk28EF8B.js} +15 -15
- package/dist/{hub-cap-forward-CH6_VWVO.mjs → hub-cap-forward-CDiN1p98.mjs} +18 -2
- package/dist/{hub-cap-forward-COCmYaup.js → hub-cap-forward-W8oEm4ME.js} +23 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +1023 -83525
- package/dist/index.mjs +1218 -83794
- package/dist/{jwt-signing-key-CsuVKA1W.mjs → jwt-signing-key-MQLxLfgF.mjs} +1 -1
- package/dist/{jwt-signing-key-CjoZcol8.js → jwt-signing-key-WI6z7JBo.js} +1 -1
- package/dist/kernel/index.d.ts +17 -1
- package/dist/kernel/moleculer/agent-mesh-authenticator.d.ts +41 -0
- package/dist/kernel/moleculer/broker-factory.d.ts +25 -2
- package/dist/kernel/moleculer/child-addon-call-dispatch.d.ts +1 -0
- package/dist/kernel/moleculer/hub-service.d.ts +9 -0
- package/dist/kernel/moleculer/mesh-access-middleware.d.ts +33 -0
- package/dist/kernel/moleculer/mesh-auth-mode.d.ts +64 -0
- package/dist/kernel/moleculer/mesh-authenticator.d.ts +71 -0
- package/dist/kernel/moleculer/mesh-auto-enforce.d.ts +26 -0
- package/dist/kernel/moleculer/mesh-join-client.d.ts +51 -0
- package/dist/kernel/moleculer/mesh-join-proof.d.ts +39 -0
- package/dist/kernel/moleculer/mesh-mtls/constants.d.ts +20 -0
- package/dist/kernel/moleculer/mesh-mtls/index.d.ts +9 -0
- package/dist/kernel/moleculer/mesh-mtls/mesh-ca-keeper.d.ts +55 -0
- package/dist/kernel/moleculer/mesh-mtls/mesh-ca.d.ts +45 -0
- package/dist/kernel/moleculer/mesh-mtls/mesh-crl.d.ts +16 -0
- package/dist/kernel/moleculer/mesh-mtls/mesh-enroll.d.ts +27 -0
- package/dist/kernel/moleculer/mesh-mtls/mesh-join-token.d.ts +55 -0
- package/dist/kernel/moleculer/mesh-mtls/mesh-tls-enabler.d.ts +5 -0
- package/dist/kernel/moleculer/mesh-mtls/tls-tcp-transporter.d.ts +92 -0
- package/dist/kernel/system-settings-policy.d.ts +4 -3
- package/dist/kernel/transport/hub-cap-forward.d.ts +14 -3
- package/dist/kernel/transport/index.d.ts +1 -1
- package/dist/ms-DlIWNkkk.mjs +160 -0
- package/dist/ms-t68_FaqE.js +171 -0
- package/dist/restore-archive-C5f9yX90.js +4139 -0
- package/dist/restore-archive-CZRtI1k9.mjs +4045 -0
- package/dist/{retired-settings-keys-MCVhxPkJ.mjs → retired-settings-keys-LuDd4y3M.mjs} +1 -1
- package/dist/{retired-settings-keys-DCuetwOt.js → retired-settings-keys-WLrbzdPR.js} +1 -1
- package/dist/tls-BWpwU-d5.js +1160 -0
- package/dist/tls-C2NT-Orr.mjs +949 -0
- package/dist/{tls-CCMX7MjX.js → x509.es-BhTzcFhZ.js} +65 -1108
- package/dist/{tls-CJHogwTl.mjs → x509.es-Xf3K_brW.mjs} +40 -950
- package/package.json +3 -2
|
@@ -0,0 +1,4045 @@
|
|
|
1
|
+
import { g as DATABASE_SNAPSHOT_SUFFIX } from "./dist-osl3bkF0.mjs";
|
|
2
|
+
import { createCipheriv, createDecipheriv, createHash, createPrivateKey, createPublicKey, diffieHellman, generateKeyPairSync, hkdfSync, randomBytes } from "node:crypto";
|
|
3
|
+
import { Buffer as Buffer$1 } from "buffer";
|
|
4
|
+
import * as fsp from "node:fs/promises";
|
|
5
|
+
import jn from "node:fs/promises";
|
|
6
|
+
import * as path$1 from "node:path";
|
|
7
|
+
import path, { basename, join, posix, win32 } from "node:path";
|
|
8
|
+
import * as fs$1 from "node:fs";
|
|
9
|
+
import Kt from "node:fs";
|
|
10
|
+
import { EventEmitter } from "node:events";
|
|
11
|
+
import As, { Transform } from "node:stream";
|
|
12
|
+
import { StringDecoder } from "node:string_decoder";
|
|
13
|
+
import I from "fs";
|
|
14
|
+
import qs, { dirname as dirname$1, parse } from "path";
|
|
15
|
+
import * as Ms from "zlib";
|
|
16
|
+
import Jr from "zlib";
|
|
17
|
+
import Pi from "assert";
|
|
18
|
+
import $r, { EventEmitter as EventEmitter$1 } from "events";
|
|
19
|
+
import * as zlib from "node:zlib";
|
|
20
|
+
import { pipeline } from "node:stream/promises";
|
|
21
|
+
import no from "node:assert";
|
|
22
|
+
//#region src/builtins/system-backup/backup-encryption.ts
|
|
23
|
+
/**
|
|
24
|
+
* Backup archive encryption — public key, streaming, chunked AEAD (D-backup
|
|
25
|
+
* encryption, operator decision 2026-10-09).
|
|
26
|
+
*
|
|
27
|
+
* ## Why a public-key scheme
|
|
28
|
+
*
|
|
29
|
+
* Scheduled backups run with nobody present, so the hub must be able to
|
|
30
|
+
* ENCRYPT on its own. With a symmetric key the hub would also hold what
|
|
31
|
+
* DECRYPTS every archive it ever shipped — in its database, in the nightly
|
|
32
|
+
* appdata tar, in any copy of the data volume — and the archives on SMB / S3
|
|
33
|
+
* would be exactly as safe as the hub. Here the hub keeps only the PUBLIC key:
|
|
34
|
+
* an attacker with the hub, its database or its volume backup still cannot
|
|
35
|
+
* open an archive that already left. The operator keeps the secret key (shown
|
|
36
|
+
* once at setup) and gives it back at restore time. It is independent of the
|
|
37
|
+
* keychain master key, so a restore onto a fresh hub needs nothing from the
|
|
38
|
+
* old one, and a keychain reset does not strand the backups.
|
|
39
|
+
*
|
|
40
|
+
* ## Format `x25519-hkdf-aes256gcm-stream-v1` (age's STREAM construction, AES-GCM)
|
|
41
|
+
*
|
|
42
|
+
* header (69 bytes)
|
|
43
|
+
* magic "CSBKENC1" (8) | version 1 (1) | chunk size u32 BE (4)
|
|
44
|
+
* | recipient key id (8) | ephemeral X25519 public key (32) | salt (16)
|
|
45
|
+
* chunks
|
|
46
|
+
* AES-256-GCM(payloadKey, nonce, plaintext[≤ chunk]) ‖ tag(16)
|
|
47
|
+
*
|
|
48
|
+
* `payloadKey = HKDF-SHA256(X25519(ephemeral, recipient), salt,
|
|
49
|
+
* "camstack-backup-v1" ‖ header)` — the whole header is bound into the key,
|
|
50
|
+
* so a changed byte in it fails the first chunk. The nonce is an 11-byte
|
|
51
|
+
* big-endian chunk counter plus a final-chunk flag: a reordered, dropped or
|
|
52
|
+
* appended chunk fails authentication, and an archive cut at a chunk boundary
|
|
53
|
+
* is refused because its last chunk is not marked final. Every archive has a
|
|
54
|
+
* final chunk (empty when the plaintext is a multiple of the chunk size).
|
|
55
|
+
*
|
|
56
|
+
* Memory is one chunk (64 KiB by default) per stream, whatever the archive
|
|
57
|
+
* size. `scripts/ops/backup-decrypt.mjs` implements the same format with
|
|
58
|
+
* nothing but Node, for a restore without a hub.
|
|
59
|
+
*/
|
|
60
|
+
var BACKUP_ENCRYPTION_SCHEME = "x25519-hkdf-aes256gcm-stream-v1";
|
|
61
|
+
var ENCRYPTED_BACKUP_SUFFIX = ".csbk";
|
|
62
|
+
var MAGIC = Buffer.from("CSBKENC1", "ascii");
|
|
63
|
+
var VERSION = 1;
|
|
64
|
+
var KEY_ID_BYTES = 8;
|
|
65
|
+
var SALT_BYTES = 16;
|
|
66
|
+
var TAG_BYTES = 16;
|
|
67
|
+
var INFO_LABEL = Buffer.from("camstack-backup-v1", "ascii");
|
|
68
|
+
var BACKUP_ENCRYPTION_HEADER_BYTES = MAGIC.length + 1 + 4 + KEY_ID_BYTES + 32 + SALT_BYTES;
|
|
69
|
+
var MAX_CHUNK_BYTES = 16 * 1024 * 1024;
|
|
70
|
+
var SECRET_PREFIX = "camstack-backup-secret-v1:";
|
|
71
|
+
var PUBLIC_PREFIX = "camstack-backup-public-v1:";
|
|
72
|
+
var CHECKSUM_BYTES = 4;
|
|
73
|
+
var PKCS8_PREFIX = Buffer.from("302e020100300506032b656e04220420", "hex");
|
|
74
|
+
var SPKI_PREFIX = Buffer.from("302a300506032b656e032100", "hex");
|
|
75
|
+
/** A key string that is not a backup key, or was mistyped. */
|
|
76
|
+
var BackupKeyFormatError = class extends Error {
|
|
77
|
+
constructor(message) {
|
|
78
|
+
super(message);
|
|
79
|
+
this.name = "BackupKeyFormatError";
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
/** The archive was encrypted to another backup key. */
|
|
83
|
+
var BackupKeyMismatchError = class extends Error {
|
|
84
|
+
archiveKeyId;
|
|
85
|
+
givenKeyId;
|
|
86
|
+
constructor(archiveKeyId, givenKeyId) {
|
|
87
|
+
super(`this backup was encrypted to backup key ${archiveKeyId}; the key given is ${givenKeyId}. Use the key that was current when the backup was made.`);
|
|
88
|
+
this.archiveKeyId = archiveKeyId;
|
|
89
|
+
this.givenKeyId = givenKeyId;
|
|
90
|
+
this.name = "BackupKeyMismatchError";
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
/** The archive is damaged, truncated or tampered with. */
|
|
94
|
+
var BackupDecryptError = class extends Error {
|
|
95
|
+
constructor(message) {
|
|
96
|
+
super(`encrypted backup is unreadable: ${message}`);
|
|
97
|
+
this.name = "BackupDecryptError";
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
function checksum(prefix, raw) {
|
|
101
|
+
return createHash("sha256").update(prefix).update(raw).digest().subarray(0, CHECKSUM_BYTES);
|
|
102
|
+
}
|
|
103
|
+
function encodeKey(prefix, raw) {
|
|
104
|
+
return `${prefix}${Buffer.concat([raw, checksum(prefix, raw)]).toString("base64url")}`;
|
|
105
|
+
}
|
|
106
|
+
function decodeKey(prefix, text, what) {
|
|
107
|
+
const trimmed = text.trim();
|
|
108
|
+
if (!trimmed.startsWith(prefix)) throw new BackupKeyFormatError(`not a backup ${what} key (it must start with "${prefix}")`);
|
|
109
|
+
const bytes = Buffer.from(trimmed.slice(prefix.length), "base64url");
|
|
110
|
+
if (bytes.length !== 36) throw new BackupKeyFormatError(`the backup ${what} key has the wrong length — copy it again`);
|
|
111
|
+
const raw = bytes.subarray(0, 32);
|
|
112
|
+
if (!checksum(prefix, raw).equals(bytes.subarray(32))) throw new BackupKeyFormatError(`the backup ${what} key does not check out — it was mistyped`);
|
|
113
|
+
return Buffer.from(raw);
|
|
114
|
+
}
|
|
115
|
+
function keyIdBytes(publicRaw) {
|
|
116
|
+
return createHash("sha256").update(publicRaw).digest().subarray(0, KEY_ID_BYTES);
|
|
117
|
+
}
|
|
118
|
+
function privateKeyObject(raw) {
|
|
119
|
+
return createPrivateKey({
|
|
120
|
+
key: Buffer.concat([PKCS8_PREFIX, raw]),
|
|
121
|
+
format: "der",
|
|
122
|
+
type: "pkcs8"
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function publicKeyObject(raw) {
|
|
126
|
+
return createPublicKey({
|
|
127
|
+
key: Buffer.concat([SPKI_PREFIX, raw]),
|
|
128
|
+
format: "der",
|
|
129
|
+
type: "spki"
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
function rawPublic(key) {
|
|
133
|
+
return key.export({
|
|
134
|
+
format: "der",
|
|
135
|
+
type: "spki"
|
|
136
|
+
}).subarray(SPKI_PREFIX.length);
|
|
137
|
+
}
|
|
138
|
+
function rawPrivate(key) {
|
|
139
|
+
return key.export({
|
|
140
|
+
format: "der",
|
|
141
|
+
type: "pkcs8"
|
|
142
|
+
}).subarray(PKCS8_PREFIX.length);
|
|
143
|
+
}
|
|
144
|
+
function generateBackupKeyPair() {
|
|
145
|
+
const { privateKey, publicKey } = generateKeyPairSync("x25519");
|
|
146
|
+
const pub = rawPublic(publicKey);
|
|
147
|
+
return {
|
|
148
|
+
secretKey: encodeKey(SECRET_PREFIX, rawPrivate(privateKey)),
|
|
149
|
+
publicKey: encodeKey(PUBLIC_PREFIX, pub),
|
|
150
|
+
keyId: keyIdBytes(pub).toString("hex")
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function parseBackupPublicKey(text) {
|
|
154
|
+
const raw = decodeKey(PUBLIC_PREFIX, text, "public");
|
|
155
|
+
return {
|
|
156
|
+
raw,
|
|
157
|
+
keyId: keyIdBytes(raw).toString("hex")
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function parseBackupSecretKey(text) {
|
|
161
|
+
const key = privateKeyObject(decodeKey(SECRET_PREFIX, text, "secret"));
|
|
162
|
+
const publicRaw = rawPublic(createPublicKey(key));
|
|
163
|
+
return {
|
|
164
|
+
key,
|
|
165
|
+
publicRaw,
|
|
166
|
+
keyId: keyIdBytes(publicRaw).toString("hex")
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function payloadKey(shared, salt, header) {
|
|
170
|
+
return Buffer.from(hkdfSync("sha256", shared, salt, Buffer.concat([INFO_LABEL, header]), 32));
|
|
171
|
+
}
|
|
172
|
+
function nonceFor(counter, final) {
|
|
173
|
+
const nonce = Buffer.alloc(12);
|
|
174
|
+
nonce.writeBigUInt64BE(counter, 3);
|
|
175
|
+
nonce[11] = final ? 1 : 0;
|
|
176
|
+
return nonce;
|
|
177
|
+
}
|
|
178
|
+
function seal(key, counter, final, plaintext) {
|
|
179
|
+
const cipher = createCipheriv("aes-256-gcm", key, nonceFor(counter, final));
|
|
180
|
+
const body = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
181
|
+
return Buffer.concat([body, cipher.getAuthTag()]);
|
|
182
|
+
}
|
|
183
|
+
function open(key, counter, final, sealed) {
|
|
184
|
+
if (sealed.length < TAG_BYTES) return null;
|
|
185
|
+
const decipher = createDecipheriv("aes-256-gcm", key, nonceFor(counter, final));
|
|
186
|
+
decipher.setAuthTag(sealed.subarray(sealed.length - TAG_BYTES));
|
|
187
|
+
try {
|
|
188
|
+
return Buffer.concat([decipher.update(sealed.subarray(0, sealed.length - TAG_BYTES)), decipher.final()]);
|
|
189
|
+
} catch {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/** A growing byte queue that takes exact slices without re-concatenating everything. */
|
|
194
|
+
var ByteQueue = class {
|
|
195
|
+
parts = [];
|
|
196
|
+
length = 0;
|
|
197
|
+
push(buf) {
|
|
198
|
+
if (buf.length === 0) return;
|
|
199
|
+
this.parts.push(buf);
|
|
200
|
+
this.length += buf.length;
|
|
201
|
+
}
|
|
202
|
+
take(n) {
|
|
203
|
+
const out = Buffer.allocUnsafe(n);
|
|
204
|
+
let filled = 0;
|
|
205
|
+
while (filled < n) {
|
|
206
|
+
const head = this.parts[0];
|
|
207
|
+
if (head === void 0) throw new Error("ByteQueue underflow");
|
|
208
|
+
const need = n - filled;
|
|
209
|
+
if (head.length <= need) {
|
|
210
|
+
head.copy(out, filled);
|
|
211
|
+
filled += head.length;
|
|
212
|
+
this.parts.shift();
|
|
213
|
+
} else {
|
|
214
|
+
head.copy(out, filled, 0, need);
|
|
215
|
+
this.parts[0] = head.subarray(need);
|
|
216
|
+
filled += need;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
this.length -= n;
|
|
220
|
+
return out;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
function toBuffer(chunk) {
|
|
224
|
+
if (Buffer.isBuffer(chunk)) return chunk;
|
|
225
|
+
if (chunk instanceof Uint8Array) return Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
226
|
+
if (typeof chunk === "string") return Buffer.from(chunk);
|
|
227
|
+
throw new TypeError("backup encryption: a stream chunk must be bytes");
|
|
228
|
+
}
|
|
229
|
+
/** Encrypt a byte stream to the holder of `publicKey`'s secret key. */
|
|
230
|
+
function createBackupEncryptStream(publicKey, opts) {
|
|
231
|
+
const recipient = parseBackupPublicKey(publicKey);
|
|
232
|
+
const chunkBytes = opts?.chunkBytes ?? 65536;
|
|
233
|
+
if (!Number.isInteger(chunkBytes) || chunkBytes < 1 || chunkBytes > MAX_CHUNK_BYTES) throw new RangeError(`backup encryption: chunk size ${chunkBytes} is out of range`);
|
|
234
|
+
const ephemeral = generateKeyPairSync("x25519");
|
|
235
|
+
const salt = randomBytes(SALT_BYTES);
|
|
236
|
+
const sizeField = Buffer.alloc(4);
|
|
237
|
+
sizeField.writeUInt32BE(chunkBytes);
|
|
238
|
+
const header = Buffer.concat([
|
|
239
|
+
MAGIC,
|
|
240
|
+
Buffer.from([VERSION]),
|
|
241
|
+
sizeField,
|
|
242
|
+
keyIdBytes(recipient.raw),
|
|
243
|
+
rawPublic(ephemeral.publicKey),
|
|
244
|
+
salt
|
|
245
|
+
]);
|
|
246
|
+
const key = payloadKey(diffieHellman({
|
|
247
|
+
privateKey: ephemeral.privateKey,
|
|
248
|
+
publicKey: publicKeyObject(recipient.raw)
|
|
249
|
+
}), salt, header);
|
|
250
|
+
const queue = new ByteQueue();
|
|
251
|
+
let counter = 0n;
|
|
252
|
+
let headerSent = false;
|
|
253
|
+
const sendHeader = (stream) => {
|
|
254
|
+
if (headerSent) return;
|
|
255
|
+
headerSent = true;
|
|
256
|
+
stream.push(header);
|
|
257
|
+
};
|
|
258
|
+
return new Transform({
|
|
259
|
+
transform(chunk, _enc, callback) {
|
|
260
|
+
try {
|
|
261
|
+
sendHeader(this);
|
|
262
|
+
queue.push(toBuffer(chunk));
|
|
263
|
+
while (queue.length > chunkBytes) {
|
|
264
|
+
this.push(seal(key, counter, false, queue.take(chunkBytes)));
|
|
265
|
+
counter += 1n;
|
|
266
|
+
}
|
|
267
|
+
callback();
|
|
268
|
+
} catch (err) {
|
|
269
|
+
callback(err instanceof Error ? err : new Error(String(err)));
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
flush(callback) {
|
|
273
|
+
try {
|
|
274
|
+
sendHeader(this);
|
|
275
|
+
this.push(seal(key, counter, true, queue.take(queue.length)));
|
|
276
|
+
callback();
|
|
277
|
+
} catch (err) {
|
|
278
|
+
callback(err instanceof Error ? err : new Error(String(err)));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
function parseHeader(header) {
|
|
284
|
+
if (header.length < BACKUP_ENCRYPTION_HEADER_BYTES) return null;
|
|
285
|
+
if (!header.subarray(0, MAGIC.length).equals(MAGIC)) return null;
|
|
286
|
+
let at = MAGIC.length;
|
|
287
|
+
const version = header[at];
|
|
288
|
+
at += 1;
|
|
289
|
+
if (version !== VERSION) throw new BackupDecryptError(`format version ${String(version)} is not supported`);
|
|
290
|
+
const chunkBytes = header.readUInt32BE(at);
|
|
291
|
+
at += 4;
|
|
292
|
+
if (chunkBytes < 1 || chunkBytes > MAX_CHUNK_BYTES) throw new BackupDecryptError("the header names an impossible chunk size");
|
|
293
|
+
const keyId = header.subarray(at, at + KEY_ID_BYTES).toString("hex");
|
|
294
|
+
at += KEY_ID_BYTES;
|
|
295
|
+
const ephemeral = Buffer.from(header.subarray(at, at + 32));
|
|
296
|
+
at += 32;
|
|
297
|
+
return {
|
|
298
|
+
chunkBytes,
|
|
299
|
+
keyId,
|
|
300
|
+
ephemeral,
|
|
301
|
+
salt: Buffer.from(header.subarray(at, at + SALT_BYTES))
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
/** Decrypt a stream produced by {@link createBackupEncryptStream}. */
|
|
305
|
+
function createBackupDecryptStream(secretKey) {
|
|
306
|
+
const recipient = parseBackupSecretKey(secretKey);
|
|
307
|
+
const queue = new ByteQueue();
|
|
308
|
+
let key = null;
|
|
309
|
+
let sealedChunk = 0;
|
|
310
|
+
let counter = 0n;
|
|
311
|
+
const openHeader = () => {
|
|
312
|
+
const header = queue.take(BACKUP_ENCRYPTION_HEADER_BYTES);
|
|
313
|
+
const parsed = parseHeader(header);
|
|
314
|
+
if (parsed === null) throw new BackupDecryptError("this is not an encrypted CamStack backup");
|
|
315
|
+
if (parsed.keyId !== recipient.keyId) throw new BackupKeyMismatchError(parsed.keyId, recipient.keyId);
|
|
316
|
+
key = payloadKey(diffieHellman({
|
|
317
|
+
privateKey: recipient.key,
|
|
318
|
+
publicKey: publicKeyObject(parsed.ephemeral)
|
|
319
|
+
}), parsed.salt, header);
|
|
320
|
+
sealedChunk = parsed.chunkBytes + TAG_BYTES;
|
|
321
|
+
};
|
|
322
|
+
const openChunk = (stream, sealed, final) => {
|
|
323
|
+
if (key === null) throw new BackupDecryptError("no header");
|
|
324
|
+
const plain = open(key, counter, final, sealed);
|
|
325
|
+
if (plain === null) throw new BackupDecryptError(final ? `the last chunk (${counter}) failed authentication — the archive is truncated, damaged or tampered with` : `chunk ${counter} failed authentication — the archive is damaged or tampered with`);
|
|
326
|
+
counter += 1n;
|
|
327
|
+
if (plain.length > 0) stream.push(plain);
|
|
328
|
+
};
|
|
329
|
+
return new Transform({
|
|
330
|
+
transform(chunk, _enc, callback) {
|
|
331
|
+
try {
|
|
332
|
+
queue.push(toBuffer(chunk));
|
|
333
|
+
if (key === null) {
|
|
334
|
+
if (queue.length < BACKUP_ENCRYPTION_HEADER_BYTES) return callback();
|
|
335
|
+
openHeader();
|
|
336
|
+
}
|
|
337
|
+
while (queue.length > sealedChunk) openChunk(this, queue.take(sealedChunk), false);
|
|
338
|
+
callback();
|
|
339
|
+
} catch (err) {
|
|
340
|
+
callback(err instanceof Error ? err : new Error(String(err)));
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
flush(callback) {
|
|
344
|
+
try {
|
|
345
|
+
if (key === null) {
|
|
346
|
+
if (queue.length < BACKUP_ENCRYPTION_HEADER_BYTES) throw new BackupDecryptError("the archive ends before its header does");
|
|
347
|
+
openHeader();
|
|
348
|
+
}
|
|
349
|
+
if (queue.length < TAG_BYTES) throw new BackupDecryptError("the archive ends without its final chunk — it is truncated");
|
|
350
|
+
openChunk(this, queue.take(queue.length), true);
|
|
351
|
+
callback();
|
|
352
|
+
} catch (err) {
|
|
353
|
+
callback(err instanceof Error ? err : new Error(String(err)));
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
/** The key id an encrypted archive names, or `null` for a plain (pre-encryption) archive. */
|
|
359
|
+
async function readBackupEncryptionHeader(file) {
|
|
360
|
+
const handle = await fsp.open(file, "r");
|
|
361
|
+
try {
|
|
362
|
+
const header = Buffer.alloc(BACKUP_ENCRYPTION_HEADER_BYTES);
|
|
363
|
+
const { bytesRead } = await handle.read(header, 0, header.length, 0);
|
|
364
|
+
if (bytesRead < MAGIC.length || !header.subarray(0, MAGIC.length).equals(MAGIC)) return null;
|
|
365
|
+
const parsed = parseHeader(header.subarray(0, bytesRead));
|
|
366
|
+
if (parsed === null) throw new BackupDecryptError("the header is cut short");
|
|
367
|
+
return { keyId: parsed.keyId };
|
|
368
|
+
} finally {
|
|
369
|
+
await handle.close();
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* File → file. A failure of any kind removes the partial output: a restore
|
|
374
|
+
* must never find half a tar where the archive should be.
|
|
375
|
+
*/
|
|
376
|
+
async function decryptBackupFile(input, output, secretKey) {
|
|
377
|
+
const decrypt = createBackupDecryptStream(secretKey);
|
|
378
|
+
try {
|
|
379
|
+
await pipeline(fs$1.createReadStream(input), decrypt, fs$1.createWriteStream(output, { mode: 384 }));
|
|
380
|
+
} catch (err) {
|
|
381
|
+
await fsp.rm(output, { force: true }).catch(() => void 0);
|
|
382
|
+
throw err;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
//#endregion
|
|
386
|
+
//#region node_modules/tar/dist/esm/index.min.js
|
|
387
|
+
var Mr = Object.defineProperty;
|
|
388
|
+
var Br = (s, t) => {
|
|
389
|
+
for (var e in t) Mr(s, e, {
|
|
390
|
+
get: t[e],
|
|
391
|
+
enumerable: !0
|
|
392
|
+
});
|
|
393
|
+
};
|
|
394
|
+
var xs = typeof process == "object" && process ? process : {
|
|
395
|
+
stdout: null,
|
|
396
|
+
stderr: null
|
|
397
|
+
}, zr = (s) => !!s && typeof s == "object" && (s instanceof A || s instanceof As || Ur(s) || Hr(s)), Ur = (s) => !!s && typeof s == "object" && s instanceof EventEmitter && typeof s.pipe == "function" && s.pipe !== As.Writable.prototype.pipe, Hr = (s) => !!s && typeof s == "object" && s instanceof EventEmitter && typeof s.write == "function" && typeof s.end == "function", q = Symbol("EOF"), Q = Symbol("maybeEmitEnd"), rt = Symbol("emittedEnd"), Le = Symbol("emittingEnd"), qt = Symbol("emittedError"), Ne = Symbol("closed"), Ls = Symbol("read"), De = Symbol("flush"), Ns = Symbol("flushChunk"), z = Symbol("encoding"), Mt = Symbol("decoder"), g = Symbol("flowing"), Qt = Symbol("paused"), Bt = Symbol("resume"), b = Symbol("buffer"), D = Symbol("pipes"), _ = Symbol("bufferLength"), gi = Symbol("bufferPush"), Ae = Symbol("bufferShift"), L = Symbol("objectMode"), w = Symbol("destroyed"), bi = Symbol("error"), _i = Symbol("emitData"), Ds = Symbol("emitEnd"), Oi = Symbol("emitEnd2"), Z = Symbol("async"), Ti = Symbol("abort"), Ie = Symbol("aborted"), Jt = Symbol("signal"), Rt = Symbol("dataListeners"), F = Symbol("discarded"), jt = (s) => Promise.resolve().then(s), Wr = (s) => s(), Gr = (s) => s === "end" || s === "finish" || s === "prefinish", Zr = (s) => s instanceof ArrayBuffer || !!s && typeof s == "object" && s.constructor && s.constructor.name === "ArrayBuffer" && s.byteLength >= 0, Yr = (s) => !Buffer.isBuffer(s) && ArrayBuffer.isView(s), Fe = class {
|
|
398
|
+
src;
|
|
399
|
+
dest;
|
|
400
|
+
opts;
|
|
401
|
+
ondrain;
|
|
402
|
+
constructor(t, e, i) {
|
|
403
|
+
this.src = t, this.dest = e, this.opts = i, this.ondrain = () => t[Bt](), this.dest.on("drain", this.ondrain);
|
|
404
|
+
}
|
|
405
|
+
unpipe() {
|
|
406
|
+
this.dest.removeListener("drain", this.ondrain);
|
|
407
|
+
}
|
|
408
|
+
proxyErrors(t) {}
|
|
409
|
+
end() {
|
|
410
|
+
this.unpipe(), this.opts.end && this.dest.end();
|
|
411
|
+
}
|
|
412
|
+
}, xi = class extends Fe {
|
|
413
|
+
unpipe() {
|
|
414
|
+
this.src.removeListener("error", this.proxyErrors), super.unpipe();
|
|
415
|
+
}
|
|
416
|
+
constructor(t, e, i) {
|
|
417
|
+
super(t, e, i), this.proxyErrors = (r) => this.dest.emit("error", r), t.on("error", this.proxyErrors);
|
|
418
|
+
}
|
|
419
|
+
}, Kr = (s) => !!s.objectMode, Vr = (s) => !s.objectMode && !!s.encoding && s.encoding !== "buffer", A = class extends EventEmitter {
|
|
420
|
+
[g] = !1;
|
|
421
|
+
[Qt] = !1;
|
|
422
|
+
[D] = [];
|
|
423
|
+
[b] = [];
|
|
424
|
+
[L];
|
|
425
|
+
[z];
|
|
426
|
+
[Z];
|
|
427
|
+
[Mt];
|
|
428
|
+
[q] = !1;
|
|
429
|
+
[rt] = !1;
|
|
430
|
+
[Le] = !1;
|
|
431
|
+
[Ne] = !1;
|
|
432
|
+
[qt] = null;
|
|
433
|
+
[_] = 0;
|
|
434
|
+
[w] = !1;
|
|
435
|
+
[Jt];
|
|
436
|
+
[Ie] = !1;
|
|
437
|
+
[Rt] = 0;
|
|
438
|
+
[F] = !1;
|
|
439
|
+
writable = !0;
|
|
440
|
+
readable = !0;
|
|
441
|
+
constructor(...t) {
|
|
442
|
+
let e = t[0] || {};
|
|
443
|
+
if (super(), e.objectMode && typeof e.encoding == "string") throw new TypeError("Encoding and objectMode may not be used together");
|
|
444
|
+
Kr(e) ? (this[L] = !0, this[z] = null) : Vr(e) ? (this[z] = e.encoding, this[L] = !1) : (this[L] = !1, this[z] = null), this[Z] = !!e.async, this[Mt] = this[z] ? new StringDecoder(this[z]) : null, e && e.debugExposeBuffer === !0 && Object.defineProperty(this, "buffer", { get: () => this[b] }), e && e.debugExposePipes === !0 && Object.defineProperty(this, "pipes", { get: () => this[D] });
|
|
445
|
+
let { signal: i } = e;
|
|
446
|
+
i && (this[Jt] = i, i.aborted ? this[Ti]() : i.addEventListener("abort", () => this[Ti]()));
|
|
447
|
+
}
|
|
448
|
+
get bufferLength() {
|
|
449
|
+
return this[_];
|
|
450
|
+
}
|
|
451
|
+
get encoding() {
|
|
452
|
+
return this[z];
|
|
453
|
+
}
|
|
454
|
+
set encoding(t) {
|
|
455
|
+
throw new Error("Encoding must be set at instantiation time");
|
|
456
|
+
}
|
|
457
|
+
setEncoding(t) {
|
|
458
|
+
throw new Error("Encoding must be set at instantiation time");
|
|
459
|
+
}
|
|
460
|
+
get objectMode() {
|
|
461
|
+
return this[L];
|
|
462
|
+
}
|
|
463
|
+
set objectMode(t) {
|
|
464
|
+
throw new Error("objectMode must be set at instantiation time");
|
|
465
|
+
}
|
|
466
|
+
get async() {
|
|
467
|
+
return this[Z];
|
|
468
|
+
}
|
|
469
|
+
set async(t) {
|
|
470
|
+
this[Z] = this[Z] || !!t;
|
|
471
|
+
}
|
|
472
|
+
[Ti]() {
|
|
473
|
+
this[Ie] = !0, this.emit("abort", this[Jt]?.reason), this.destroy(this[Jt]?.reason);
|
|
474
|
+
}
|
|
475
|
+
get aborted() {
|
|
476
|
+
return this[Ie];
|
|
477
|
+
}
|
|
478
|
+
set aborted(t) {}
|
|
479
|
+
write(t, e, i) {
|
|
480
|
+
if (this[Ie]) return !1;
|
|
481
|
+
if (this[q]) throw new Error("write after end");
|
|
482
|
+
if (this[w]) return this.emit("error", Object.assign(/* @__PURE__ */ new Error("Cannot call write after a stream was destroyed"), { code: "ERR_STREAM_DESTROYED" })), !0;
|
|
483
|
+
typeof e == "function" && (i = e, e = "utf8"), e || (e = "utf8");
|
|
484
|
+
let r = this[Z] ? jt : Wr;
|
|
485
|
+
if (!this[L] && !Buffer.isBuffer(t)) {
|
|
486
|
+
if (Yr(t)) t = Buffer.from(t.buffer, t.byteOffset, t.byteLength);
|
|
487
|
+
else if (Zr(t)) t = Buffer.from(t);
|
|
488
|
+
else if (typeof t != "string") throw new Error("Non-contiguous data written to non-objectMode stream");
|
|
489
|
+
}
|
|
490
|
+
return this[L] ? (this[g] && this[_] !== 0 && this[De](!0), this[g] ? this.emit("data", t) : this[gi](t), this[_] !== 0 && this.emit("readable"), i && r(i), this[g]) : t.length ? (typeof t == "string" && !(e === this[z] && !this[Mt]?.lastNeed) && (t = Buffer.from(t, e)), Buffer.isBuffer(t) && this[z] && (t = this[Mt].write(t)), this[g] && this[_] !== 0 && this[De](!0), this[g] ? this.emit("data", t) : this[gi](t), this[_] !== 0 && this.emit("readable"), i && r(i), this[g]) : (this[_] !== 0 && this.emit("readable"), i && r(i), this[g]);
|
|
491
|
+
}
|
|
492
|
+
read(t) {
|
|
493
|
+
if (this[w]) return null;
|
|
494
|
+
if (this[F] = !1, this[_] === 0 || t === 0 || t && t > this[_]) return this[Q](), null;
|
|
495
|
+
this[L] && (t = null), this[b].length > 1 && !this[L] && (this[b] = [this[z] ? this[b].join("") : Buffer.concat(this[b], this[_])]);
|
|
496
|
+
let e = this[Ls](t || null, this[b][0]);
|
|
497
|
+
return this[Q](), e;
|
|
498
|
+
}
|
|
499
|
+
[Ls](t, e) {
|
|
500
|
+
if (this[L]) this[Ae]();
|
|
501
|
+
else {
|
|
502
|
+
let i = e;
|
|
503
|
+
t === i.length || t === null ? this[Ae]() : typeof i == "string" ? (this[b][0] = i.slice(t), e = i.slice(0, t), this[_] -= t) : (this[b][0] = i.subarray(t), e = i.subarray(0, t), this[_] -= t);
|
|
504
|
+
}
|
|
505
|
+
return this.emit("data", e), !this[b].length && !this[q] && this.emit("drain"), e;
|
|
506
|
+
}
|
|
507
|
+
end(t, e, i) {
|
|
508
|
+
return typeof t == "function" && (i = t, t = void 0), typeof e == "function" && (i = e, e = "utf8"), t !== void 0 && this.write(t, e), i && this.once("end", i), this[q] = !0, this.writable = !1, (this[g] || !this[Qt]) && this[Q](), this;
|
|
509
|
+
}
|
|
510
|
+
[Bt]() {
|
|
511
|
+
this[w] || (!this[Rt] && !this[D].length && (this[F] = !0), this[Qt] = !1, this[g] = !0, this.emit("resume"), this[b].length ? this[De]() : this[q] ? this[Q]() : this.emit("drain"));
|
|
512
|
+
}
|
|
513
|
+
resume() {
|
|
514
|
+
return this[Bt]();
|
|
515
|
+
}
|
|
516
|
+
pause() {
|
|
517
|
+
this[g] = !1, this[Qt] = !0, this[F] = !1;
|
|
518
|
+
}
|
|
519
|
+
get destroyed() {
|
|
520
|
+
return this[w];
|
|
521
|
+
}
|
|
522
|
+
get flowing() {
|
|
523
|
+
return this[g];
|
|
524
|
+
}
|
|
525
|
+
get paused() {
|
|
526
|
+
return this[Qt];
|
|
527
|
+
}
|
|
528
|
+
[gi](t) {
|
|
529
|
+
this[L] ? this[_] += 1 : this[_] += t.length, this[b].push(t);
|
|
530
|
+
}
|
|
531
|
+
[Ae]() {
|
|
532
|
+
return this[L] ? this[_] -= 1 : this[_] -= this[b][0].length, this[b].shift();
|
|
533
|
+
}
|
|
534
|
+
[De](t = !1) {
|
|
535
|
+
do ;
|
|
536
|
+
while (this[Ns](this[Ae]()) && this[b].length);
|
|
537
|
+
!t && !this[b].length && !this[q] && this.emit("drain");
|
|
538
|
+
}
|
|
539
|
+
[Ns](t) {
|
|
540
|
+
return this.emit("data", t), this[g];
|
|
541
|
+
}
|
|
542
|
+
pipe(t, e) {
|
|
543
|
+
if (this[w]) return t;
|
|
544
|
+
this[F] = !1;
|
|
545
|
+
let i = this[rt];
|
|
546
|
+
return e = e || {}, t === xs.stdout || t === xs.stderr ? e.end = !1 : e.end = e.end !== !1, e.proxyErrors = !!e.proxyErrors, i ? e.end && t.end() : (this[D].push(e.proxyErrors ? new xi(this, t, e) : new Fe(this, t, e)), this[Z] ? jt(() => this[Bt]()) : this[Bt]()), t;
|
|
547
|
+
}
|
|
548
|
+
unpipe(t) {
|
|
549
|
+
let e = this[D].find((i) => i.dest === t);
|
|
550
|
+
e && (this[D].length === 1 ? (this[g] && this[Rt] === 0 && (this[g] = !1), this[D] = []) : this[D].splice(this[D].indexOf(e), 1), e.unpipe());
|
|
551
|
+
}
|
|
552
|
+
addListener(t, e) {
|
|
553
|
+
return this.on(t, e);
|
|
554
|
+
}
|
|
555
|
+
on(t, e) {
|
|
556
|
+
let i = super.on(t, e);
|
|
557
|
+
if (t === "data") this[F] = !1, this[Rt]++, !this[D].length && !this[g] && this[Bt]();
|
|
558
|
+
else if (t === "readable" && this[_] !== 0) super.emit("readable");
|
|
559
|
+
else if (Gr(t) && this[rt]) super.emit(t), this.removeAllListeners(t);
|
|
560
|
+
else if (t === "error" && this[qt]) {
|
|
561
|
+
let r = e;
|
|
562
|
+
this[Z] ? jt(() => r.call(this, this[qt])) : r.call(this, this[qt]);
|
|
563
|
+
}
|
|
564
|
+
return i;
|
|
565
|
+
}
|
|
566
|
+
removeListener(t, e) {
|
|
567
|
+
return this.off(t, e);
|
|
568
|
+
}
|
|
569
|
+
off(t, e) {
|
|
570
|
+
let i = super.off(t, e);
|
|
571
|
+
return t === "data" && (this[Rt] = this.listeners("data").length, this[Rt] === 0 && !this[F] && !this[D].length && (this[g] = !1)), i;
|
|
572
|
+
}
|
|
573
|
+
removeAllListeners(t) {
|
|
574
|
+
let e = super.removeAllListeners(t);
|
|
575
|
+
return (t === "data" || t === void 0) && (this[Rt] = 0, !this[F] && !this[D].length && (this[g] = !1)), e;
|
|
576
|
+
}
|
|
577
|
+
get emittedEnd() {
|
|
578
|
+
return this[rt];
|
|
579
|
+
}
|
|
580
|
+
[Q]() {
|
|
581
|
+
!this[Le] && !this[rt] && !this[w] && this[b].length === 0 && this[q] && (this[Le] = !0, this.emit("end"), this.emit("prefinish"), this.emit("finish"), this[Ne] && this.emit("close"), this[Le] = !1);
|
|
582
|
+
}
|
|
583
|
+
emit(t, ...e) {
|
|
584
|
+
let i = e[0];
|
|
585
|
+
if (t !== "error" && t !== "close" && t !== w && this[w]) return !1;
|
|
586
|
+
if (t === "data") return !this[L] && !i ? !1 : this[Z] ? (jt(() => this[_i](i)), !0) : this[_i](i);
|
|
587
|
+
if (t === "end") return this[Ds]();
|
|
588
|
+
if (t === "close") {
|
|
589
|
+
if (this[Ne] = !0, !this[rt] && !this[w]) return !1;
|
|
590
|
+
let n = super.emit("close");
|
|
591
|
+
return this.removeAllListeners("close"), n;
|
|
592
|
+
} else if (t === "error") {
|
|
593
|
+
this[qt] = i, super.emit(bi, i);
|
|
594
|
+
let n = !this[Jt] || this.listeners("error").length ? super.emit("error", i) : !1;
|
|
595
|
+
return this[Q](), n;
|
|
596
|
+
} else if (t === "resume") {
|
|
597
|
+
let n = super.emit("resume");
|
|
598
|
+
return this[Q](), n;
|
|
599
|
+
} else if (t === "finish" || t === "prefinish") {
|
|
600
|
+
let n = super.emit(t);
|
|
601
|
+
return this.removeAllListeners(t), n;
|
|
602
|
+
}
|
|
603
|
+
let r = super.emit(t, ...e);
|
|
604
|
+
return this[Q](), r;
|
|
605
|
+
}
|
|
606
|
+
[_i](t) {
|
|
607
|
+
for (let i of this[D]) i.dest.write(t) === !1 && this.pause();
|
|
608
|
+
let e = this[F] ? !1 : super.emit("data", t);
|
|
609
|
+
return this[Q](), e;
|
|
610
|
+
}
|
|
611
|
+
[Ds]() {
|
|
612
|
+
return this[rt] ? !1 : (this[rt] = !0, this.readable = !1, this[Z] ? (jt(() => this[Oi]()), !0) : this[Oi]());
|
|
613
|
+
}
|
|
614
|
+
[Oi]() {
|
|
615
|
+
if (this[Mt]) {
|
|
616
|
+
let e = this[Mt].end();
|
|
617
|
+
if (e) {
|
|
618
|
+
for (let i of this[D]) i.dest.write(e);
|
|
619
|
+
this[F] || super.emit("data", e);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
for (let e of this[D]) e.end();
|
|
623
|
+
let t = super.emit("end");
|
|
624
|
+
return this.removeAllListeners("end"), t;
|
|
625
|
+
}
|
|
626
|
+
async collect() {
|
|
627
|
+
let t = Object.assign([], { dataLength: 0 });
|
|
628
|
+
this[L] || (t.dataLength = 0);
|
|
629
|
+
let e = this.promise();
|
|
630
|
+
return this.on("data", (i) => {
|
|
631
|
+
t.push(i), this[L] || (t.dataLength += i.length);
|
|
632
|
+
}), await e, t;
|
|
633
|
+
}
|
|
634
|
+
async concat() {
|
|
635
|
+
if (this[L]) throw new Error("cannot concat in objectMode");
|
|
636
|
+
let t = await this.collect();
|
|
637
|
+
return this[z] ? t.join("") : Buffer.concat(t, t.dataLength);
|
|
638
|
+
}
|
|
639
|
+
async promise() {
|
|
640
|
+
return new Promise((t, e) => {
|
|
641
|
+
this.on(w, () => e(/* @__PURE__ */ new Error("stream destroyed"))), this.on("error", (i) => e(i)), this.on("end", () => t());
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
[Symbol.asyncIterator]() {
|
|
645
|
+
this[F] = !1;
|
|
646
|
+
let t = !1, e = async () => (this.pause(), t = !0, {
|
|
647
|
+
value: void 0,
|
|
648
|
+
done: !0
|
|
649
|
+
});
|
|
650
|
+
return {
|
|
651
|
+
next: () => {
|
|
652
|
+
if (t) return e();
|
|
653
|
+
let r = this.read();
|
|
654
|
+
if (r !== null) return Promise.resolve({
|
|
655
|
+
done: !1,
|
|
656
|
+
value: r
|
|
657
|
+
});
|
|
658
|
+
if (this[q]) return e();
|
|
659
|
+
let n, o, a = (d) => {
|
|
660
|
+
this.off("data", h), this.off("end", l), this.off(w, c), e(), o(d);
|
|
661
|
+
}, h = (d) => {
|
|
662
|
+
this.off("error", a), this.off("end", l), this.off(w, c), this.pause(), n({
|
|
663
|
+
value: d,
|
|
664
|
+
done: !!this[q]
|
|
665
|
+
});
|
|
666
|
+
}, l = () => {
|
|
667
|
+
this.off("error", a), this.off("data", h), this.off(w, c), e(), n({
|
|
668
|
+
done: !0,
|
|
669
|
+
value: void 0
|
|
670
|
+
});
|
|
671
|
+
}, c = () => a(/* @__PURE__ */ new Error("stream destroyed"));
|
|
672
|
+
return new Promise((d, S) => {
|
|
673
|
+
o = S, n = d, this.once(w, c), this.once("error", a), this.once("end", l), this.once("data", h);
|
|
674
|
+
});
|
|
675
|
+
},
|
|
676
|
+
throw: e,
|
|
677
|
+
return: e,
|
|
678
|
+
[Symbol.asyncIterator]() {
|
|
679
|
+
return this;
|
|
680
|
+
},
|
|
681
|
+
[Symbol.asyncDispose]: async () => {}
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
[Symbol.iterator]() {
|
|
685
|
+
this[F] = !1;
|
|
686
|
+
let t = !1, e = () => (this.pause(), this.off(bi, e), this.off(w, e), this.off("end", e), t = !0, {
|
|
687
|
+
done: !0,
|
|
688
|
+
value: void 0
|
|
689
|
+
}), i = () => {
|
|
690
|
+
if (t) return e();
|
|
691
|
+
let r = this.read();
|
|
692
|
+
return r === null ? e() : {
|
|
693
|
+
done: !1,
|
|
694
|
+
value: r
|
|
695
|
+
};
|
|
696
|
+
};
|
|
697
|
+
return this.once("end", e), this.once(bi, e), this.once(w, e), {
|
|
698
|
+
next: i,
|
|
699
|
+
throw: e,
|
|
700
|
+
return: e,
|
|
701
|
+
[Symbol.iterator]() {
|
|
702
|
+
return this;
|
|
703
|
+
},
|
|
704
|
+
[Symbol.dispose]: () => {}
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
destroy(t) {
|
|
708
|
+
if (this[w]) return t ? this.emit("error", t) : this.emit(w), this;
|
|
709
|
+
this[w] = !0, this[F] = !0, this[b].length = 0, this[_] = 0;
|
|
710
|
+
let e = this;
|
|
711
|
+
return typeof e.close == "function" && !this[Ne] && e.close(), t ? this.emit("error", t) : this.emit(w), this;
|
|
712
|
+
}
|
|
713
|
+
static get isStream() {
|
|
714
|
+
return zr;
|
|
715
|
+
}
|
|
716
|
+
};
|
|
717
|
+
var Xr = I.writev, ot = Symbol("_autoClose"), H = Symbol("_close"), te = Symbol("_ended"), m = Symbol("_fd"), Ni = Symbol("_finished"), j = Symbol("_flags"), Di = Symbol("_flush"), Ci = Symbol("_handleChunk"), ki = Symbol("_makeBuf"), ie = Symbol("_mode"), Ce = Symbol("_needDrain"), Ut = Symbol("_onerror"), Ht = Symbol("_onopen"), Ai = Symbol("_onread"), Pt = Symbol("_onwrite"), ht = Symbol("_open"), U = Symbol("_path"), nt = Symbol("_pos"), Y = Symbol("_queue"), zt = Symbol("_read"), Ii = Symbol("_readSize"), J = Symbol("_reading"), ee = Symbol("_remain"), Fi = Symbol("_size"), ke = Symbol("_write"), gt = Symbol("_writing"), ve = Symbol("_defaultFlag"), bt = Symbol("_errored"), _t = class extends A {
|
|
718
|
+
[bt] = !1;
|
|
719
|
+
[m];
|
|
720
|
+
[U];
|
|
721
|
+
[Ii];
|
|
722
|
+
[J] = !1;
|
|
723
|
+
[Fi];
|
|
724
|
+
[ee];
|
|
725
|
+
[ot];
|
|
726
|
+
constructor(t, e) {
|
|
727
|
+
if (e = e || {}, super(e), this.readable = !0, this.writable = !1, typeof t != "string") throw new TypeError("path must be a string");
|
|
728
|
+
this[bt] = !1, this[m] = typeof e.fd == "number" ? e.fd : void 0, this[U] = t, this[Ii] = e.readSize || 16 * 1024 * 1024, this[J] = !1, this[Fi] = typeof e.size == "number" ? e.size : Infinity, this[ee] = this[Fi], this[ot] = typeof e.autoClose == "boolean" ? e.autoClose : !0, typeof this[m] == "number" ? this[zt]() : this[ht]();
|
|
729
|
+
}
|
|
730
|
+
get fd() {
|
|
731
|
+
return this[m];
|
|
732
|
+
}
|
|
733
|
+
get path() {
|
|
734
|
+
return this[U];
|
|
735
|
+
}
|
|
736
|
+
write() {
|
|
737
|
+
throw new TypeError("this is a readable stream");
|
|
738
|
+
}
|
|
739
|
+
end() {
|
|
740
|
+
throw new TypeError("this is a readable stream");
|
|
741
|
+
}
|
|
742
|
+
[ht]() {
|
|
743
|
+
I.open(this[U], "r", (t, e) => this[Ht](t, e));
|
|
744
|
+
}
|
|
745
|
+
[Ht](t, e) {
|
|
746
|
+
t ? this[Ut](t) : (this[m] = e, this.emit("open", e), this[zt]());
|
|
747
|
+
}
|
|
748
|
+
[ki]() {
|
|
749
|
+
return Buffer.allocUnsafe(Math.min(this[Ii], this[ee]));
|
|
750
|
+
}
|
|
751
|
+
[zt]() {
|
|
752
|
+
if (!this[J]) {
|
|
753
|
+
this[J] = !0;
|
|
754
|
+
let t = this[ki]();
|
|
755
|
+
if (t.length === 0) return process.nextTick(() => this[Ai](null, 0, t));
|
|
756
|
+
I.read(this[m], t, 0, t.length, null, (e, i, r) => this[Ai](e, i, r));
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
[Ai](t, e, i) {
|
|
760
|
+
this[J] = !1, t ? this[Ut](t) : this[Ci](e, i) && this[zt]();
|
|
761
|
+
}
|
|
762
|
+
[H]() {
|
|
763
|
+
if (this[ot] && typeof this[m] == "number") {
|
|
764
|
+
let t = this[m];
|
|
765
|
+
this[m] = void 0, I.close(t, (e) => e ? this.emit("error", e) : this.emit("close"));
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
[Ut](t) {
|
|
769
|
+
this[J] = !0, this[H](), this.emit("error", t);
|
|
770
|
+
}
|
|
771
|
+
[Ci](t, e) {
|
|
772
|
+
let i = !1;
|
|
773
|
+
return this[ee] -= t, t > 0 && (i = super.write(t < e.length ? e.subarray(0, t) : e)), (t === 0 || this[ee] <= 0) && (i = !1, this[H](), super.end()), i;
|
|
774
|
+
}
|
|
775
|
+
emit(t, ...e) {
|
|
776
|
+
switch (t) {
|
|
777
|
+
case "prefinish":
|
|
778
|
+
case "finish": return !1;
|
|
779
|
+
case "drain": return typeof this[m] == "number" && this[zt](), !1;
|
|
780
|
+
case "error": return this[bt] ? !1 : (this[bt] = !0, super.emit(t, ...e));
|
|
781
|
+
default: return super.emit(t, ...e);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
}, Me = class extends _t {
|
|
785
|
+
[ht]() {
|
|
786
|
+
let t = !0;
|
|
787
|
+
try {
|
|
788
|
+
this[Ht](null, I.openSync(this[U], "r")), t = !1;
|
|
789
|
+
} finally {
|
|
790
|
+
t && this[H]();
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
[zt]() {
|
|
794
|
+
let t = !0;
|
|
795
|
+
try {
|
|
796
|
+
if (!this[J]) {
|
|
797
|
+
this[J] = !0;
|
|
798
|
+
do {
|
|
799
|
+
let e = this[ki](), i = e.length === 0 ? 0 : I.readSync(this[m], e, 0, e.length, null);
|
|
800
|
+
if (!this[Ci](i, e)) break;
|
|
801
|
+
} while (!0);
|
|
802
|
+
this[J] = !1;
|
|
803
|
+
}
|
|
804
|
+
t = !1;
|
|
805
|
+
} finally {
|
|
806
|
+
t && this[H]();
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
[H]() {
|
|
810
|
+
if (this[ot] && typeof this[m] == "number") {
|
|
811
|
+
let t = this[m];
|
|
812
|
+
this[m] = void 0, I.closeSync(t), this.emit("close");
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}, tt = class extends $r {
|
|
816
|
+
readable = !1;
|
|
817
|
+
writable = !0;
|
|
818
|
+
[bt] = !1;
|
|
819
|
+
[gt] = !1;
|
|
820
|
+
[te] = !1;
|
|
821
|
+
[Y] = [];
|
|
822
|
+
[Ce] = !1;
|
|
823
|
+
[U];
|
|
824
|
+
[ie];
|
|
825
|
+
[ot];
|
|
826
|
+
[m];
|
|
827
|
+
[ve];
|
|
828
|
+
[j];
|
|
829
|
+
[Ni] = !1;
|
|
830
|
+
[nt];
|
|
831
|
+
constructor(t, e) {
|
|
832
|
+
e = e || {}, super(e), this[U] = t, this[m] = typeof e.fd == "number" ? e.fd : void 0, this[ie] = e.mode === void 0 ? 438 : e.mode, this[nt] = typeof e.start == "number" ? e.start : void 0, this[ot] = typeof e.autoClose == "boolean" ? e.autoClose : !0;
|
|
833
|
+
let i = this[nt] !== void 0 ? "r+" : "w";
|
|
834
|
+
this[ve] = e.flags === void 0, this[j] = e.flags === void 0 ? i : e.flags, this[m] === void 0 && this[ht]();
|
|
835
|
+
}
|
|
836
|
+
emit(t, ...e) {
|
|
837
|
+
if (t === "error") {
|
|
838
|
+
if (this[bt]) return !1;
|
|
839
|
+
this[bt] = !0;
|
|
840
|
+
}
|
|
841
|
+
return super.emit(t, ...e);
|
|
842
|
+
}
|
|
843
|
+
get fd() {
|
|
844
|
+
return this[m];
|
|
845
|
+
}
|
|
846
|
+
get path() {
|
|
847
|
+
return this[U];
|
|
848
|
+
}
|
|
849
|
+
[Ut](t) {
|
|
850
|
+
this[H](), this[gt] = !0, this.emit("error", t);
|
|
851
|
+
}
|
|
852
|
+
[ht]() {
|
|
853
|
+
I.open(this[U], this[j], this[ie], (t, e) => this[Ht](t, e));
|
|
854
|
+
}
|
|
855
|
+
[Ht](t, e) {
|
|
856
|
+
this[ve] && this[j] === "r+" && t && t.code === "ENOENT" ? (this[j] = "w", this[ht]()) : t ? this[Ut](t) : (this[m] = e, this.emit("open", e), this[gt] || this[Di]());
|
|
857
|
+
}
|
|
858
|
+
end(t, e) {
|
|
859
|
+
return t && this.write(t, e), this[te] = !0, !this[gt] && !this[Y].length && typeof this[m] == "number" && this[Pt](null, 0), this;
|
|
860
|
+
}
|
|
861
|
+
write(t, e) {
|
|
862
|
+
return typeof t == "string" && (t = Buffer.from(t, e)), this[te] ? (this.emit("error", /* @__PURE__ */ new Error("write() after end()")), !1) : this[m] === void 0 || this[gt] || this[Y].length ? (this[Y].push(t), this[Ce] = !0, !1) : (this[gt] = !0, this[ke](t), !0);
|
|
863
|
+
}
|
|
864
|
+
[ke](t) {
|
|
865
|
+
I.write(this[m], t, 0, t.length, this[nt], (e, i) => this[Pt](e, i));
|
|
866
|
+
}
|
|
867
|
+
[Pt](t, e) {
|
|
868
|
+
t ? this[Ut](t) : (this[nt] !== void 0 && typeof e == "number" && (this[nt] += e), this[Y].length ? this[Di]() : (this[gt] = !1, this[te] && !this[Ni] ? (this[Ni] = !0, this[H](), this.emit("finish")) : this[Ce] && (this[Ce] = !1, this.emit("drain"))));
|
|
869
|
+
}
|
|
870
|
+
[Di]() {
|
|
871
|
+
if (this[Y].length === 0) this[te] && this[Pt](null, 0);
|
|
872
|
+
else if (this[Y].length === 1) this[ke](this[Y].pop());
|
|
873
|
+
else {
|
|
874
|
+
let t = this[Y];
|
|
875
|
+
this[Y] = [], Xr(this[m], t, this[nt], (e, i) => this[Pt](e, i));
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
[H]() {
|
|
879
|
+
if (this[ot] && typeof this[m] == "number") {
|
|
880
|
+
let t = this[m];
|
|
881
|
+
this[m] = void 0, I.close(t, (e) => e ? this.emit("error", e) : this.emit("close"));
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}, Wt = class extends tt {
|
|
885
|
+
[ht]() {
|
|
886
|
+
let t;
|
|
887
|
+
if (this[ve] && this[j] === "r+") try {
|
|
888
|
+
t = I.openSync(this[U], this[j], this[ie]);
|
|
889
|
+
} catch (e) {
|
|
890
|
+
if (e?.code === "ENOENT") return this[j] = "w", this[ht]();
|
|
891
|
+
throw e;
|
|
892
|
+
}
|
|
893
|
+
else t = I.openSync(this[U], this[j], this[ie]);
|
|
894
|
+
this[Ht](null, t);
|
|
895
|
+
}
|
|
896
|
+
[H]() {
|
|
897
|
+
if (this[ot] && typeof this[m] == "number") {
|
|
898
|
+
let t = this[m];
|
|
899
|
+
this[m] = void 0, I.closeSync(t), this.emit("close");
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
[ke](t) {
|
|
903
|
+
let e = !0;
|
|
904
|
+
try {
|
|
905
|
+
this[Pt](null, I.writeSync(this[m], t, 0, t.length, this[nt])), e = !1;
|
|
906
|
+
} finally {
|
|
907
|
+
if (e) try {
|
|
908
|
+
this[H]();
|
|
909
|
+
} catch {}
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
};
|
|
913
|
+
var qr = new Map([
|
|
914
|
+
["C", "cwd"],
|
|
915
|
+
["f", "file"],
|
|
916
|
+
["z", "gzip"],
|
|
917
|
+
["P", "preservePaths"],
|
|
918
|
+
["U", "unlink"],
|
|
919
|
+
["strip-components", "strip"],
|
|
920
|
+
["stripComponents", "strip"],
|
|
921
|
+
["keep-newer", "newer"],
|
|
922
|
+
["keepNewer", "newer"],
|
|
923
|
+
["keep-newer-files", "newer"],
|
|
924
|
+
["keepNewerFiles", "newer"],
|
|
925
|
+
["k", "keep"],
|
|
926
|
+
["keep-existing", "keep"],
|
|
927
|
+
["keepExisting", "keep"],
|
|
928
|
+
["m", "noMtime"],
|
|
929
|
+
["no-mtime", "noMtime"],
|
|
930
|
+
["p", "preserveOwner"],
|
|
931
|
+
["L", "follow"],
|
|
932
|
+
["h", "follow"],
|
|
933
|
+
["onentry", "onReadEntry"]
|
|
934
|
+
]), Is = (s) => !!s.sync && !!s.file, Fs = (s) => !s.sync && !!s.file, Cs = (s) => !!s.sync && !s.file, ks = (s) => !s.sync && !s.file;
|
|
935
|
+
var vs = (s) => !!s.file;
|
|
936
|
+
var Qr = (s) => {
|
|
937
|
+
return qr.get(s) || s;
|
|
938
|
+
}, se = (s = {}) => {
|
|
939
|
+
if (!s) return {};
|
|
940
|
+
let t = {};
|
|
941
|
+
for (let [e, i] of Object.entries(s)) {
|
|
942
|
+
let r = Qr(e);
|
|
943
|
+
t[r] = i;
|
|
944
|
+
}
|
|
945
|
+
return t.chmod === void 0 && t.noChmod === !1 && (t.chmod = !0), delete t.noChmod, t;
|
|
946
|
+
};
|
|
947
|
+
var K = (s, t, e, i, r) => Object.assign((n = [], o, a) => {
|
|
948
|
+
Array.isArray(n) && (o = n, n = {}), typeof o == "function" && (a = o, o = void 0), o = o ? Array.from(o) : [];
|
|
949
|
+
let h = se(n);
|
|
950
|
+
if (r?.(h, o), Is(h)) {
|
|
951
|
+
if (typeof a == "function") throw new TypeError("callback not supported for sync tar functions");
|
|
952
|
+
return s(h, o);
|
|
953
|
+
} else if (Fs(h)) {
|
|
954
|
+
let l = t(h, o);
|
|
955
|
+
return a ? l.then(() => a(), a) : l;
|
|
956
|
+
} else if (Cs(h)) {
|
|
957
|
+
if (typeof a == "function") throw new TypeError("callback not supported for sync tar functions");
|
|
958
|
+
return e(h, o);
|
|
959
|
+
} else if (ks(h)) {
|
|
960
|
+
if (typeof a == "function") throw new TypeError("callback only supported with file option");
|
|
961
|
+
return i(h, o);
|
|
962
|
+
}
|
|
963
|
+
throw new Error("impossible options??");
|
|
964
|
+
}, {
|
|
965
|
+
syncFile: s,
|
|
966
|
+
asyncFile: t,
|
|
967
|
+
syncNoFile: e,
|
|
968
|
+
asyncNoFile: i,
|
|
969
|
+
validate: r
|
|
970
|
+
});
|
|
971
|
+
var jr = Jr.constants || { ZLIB_VERNUM: 4736 }, M = Object.freeze(Object.assign(Object.create(null), {
|
|
972
|
+
Z_NO_FLUSH: 0,
|
|
973
|
+
Z_PARTIAL_FLUSH: 1,
|
|
974
|
+
Z_SYNC_FLUSH: 2,
|
|
975
|
+
Z_FULL_FLUSH: 3,
|
|
976
|
+
Z_FINISH: 4,
|
|
977
|
+
Z_BLOCK: 5,
|
|
978
|
+
Z_OK: 0,
|
|
979
|
+
Z_STREAM_END: 1,
|
|
980
|
+
Z_NEED_DICT: 2,
|
|
981
|
+
Z_ERRNO: -1,
|
|
982
|
+
Z_STREAM_ERROR: -2,
|
|
983
|
+
Z_DATA_ERROR: -3,
|
|
984
|
+
Z_MEM_ERROR: -4,
|
|
985
|
+
Z_BUF_ERROR: -5,
|
|
986
|
+
Z_VERSION_ERROR: -6,
|
|
987
|
+
Z_NO_COMPRESSION: 0,
|
|
988
|
+
Z_BEST_SPEED: 1,
|
|
989
|
+
Z_BEST_COMPRESSION: 9,
|
|
990
|
+
Z_DEFAULT_COMPRESSION: -1,
|
|
991
|
+
Z_FILTERED: 1,
|
|
992
|
+
Z_HUFFMAN_ONLY: 2,
|
|
993
|
+
Z_RLE: 3,
|
|
994
|
+
Z_FIXED: 4,
|
|
995
|
+
Z_DEFAULT_STRATEGY: 0,
|
|
996
|
+
DEFLATE: 1,
|
|
997
|
+
INFLATE: 2,
|
|
998
|
+
GZIP: 3,
|
|
999
|
+
GUNZIP: 4,
|
|
1000
|
+
DEFLATERAW: 5,
|
|
1001
|
+
INFLATERAW: 6,
|
|
1002
|
+
UNZIP: 7,
|
|
1003
|
+
BROTLI_DECODE: 8,
|
|
1004
|
+
BROTLI_ENCODE: 9,
|
|
1005
|
+
Z_MIN_WINDOWBITS: 8,
|
|
1006
|
+
Z_MAX_WINDOWBITS: 15,
|
|
1007
|
+
Z_DEFAULT_WINDOWBITS: 15,
|
|
1008
|
+
Z_MIN_CHUNK: 64,
|
|
1009
|
+
Z_MAX_CHUNK: Infinity,
|
|
1010
|
+
Z_DEFAULT_CHUNK: 16384,
|
|
1011
|
+
Z_MIN_MEMLEVEL: 1,
|
|
1012
|
+
Z_MAX_MEMLEVEL: 9,
|
|
1013
|
+
Z_DEFAULT_MEMLEVEL: 8,
|
|
1014
|
+
Z_MIN_LEVEL: -1,
|
|
1015
|
+
Z_MAX_LEVEL: 9,
|
|
1016
|
+
Z_DEFAULT_LEVEL: -1,
|
|
1017
|
+
BROTLI_OPERATION_PROCESS: 0,
|
|
1018
|
+
BROTLI_OPERATION_FLUSH: 1,
|
|
1019
|
+
BROTLI_OPERATION_FINISH: 2,
|
|
1020
|
+
BROTLI_OPERATION_EMIT_METADATA: 3,
|
|
1021
|
+
BROTLI_MODE_GENERIC: 0,
|
|
1022
|
+
BROTLI_MODE_TEXT: 1,
|
|
1023
|
+
BROTLI_MODE_FONT: 2,
|
|
1024
|
+
BROTLI_DEFAULT_MODE: 0,
|
|
1025
|
+
BROTLI_MIN_QUALITY: 0,
|
|
1026
|
+
BROTLI_MAX_QUALITY: 11,
|
|
1027
|
+
BROTLI_DEFAULT_QUALITY: 11,
|
|
1028
|
+
BROTLI_MIN_WINDOW_BITS: 10,
|
|
1029
|
+
BROTLI_MAX_WINDOW_BITS: 24,
|
|
1030
|
+
BROTLI_LARGE_MAX_WINDOW_BITS: 30,
|
|
1031
|
+
BROTLI_DEFAULT_WINDOW: 22,
|
|
1032
|
+
BROTLI_MIN_INPUT_BLOCK_BITS: 16,
|
|
1033
|
+
BROTLI_MAX_INPUT_BLOCK_BITS: 24,
|
|
1034
|
+
BROTLI_PARAM_MODE: 0,
|
|
1035
|
+
BROTLI_PARAM_QUALITY: 1,
|
|
1036
|
+
BROTLI_PARAM_LGWIN: 2,
|
|
1037
|
+
BROTLI_PARAM_LGBLOCK: 3,
|
|
1038
|
+
BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING: 4,
|
|
1039
|
+
BROTLI_PARAM_SIZE_HINT: 5,
|
|
1040
|
+
BROTLI_PARAM_LARGE_WINDOW: 6,
|
|
1041
|
+
BROTLI_PARAM_NPOSTFIX: 7,
|
|
1042
|
+
BROTLI_PARAM_NDIRECT: 8,
|
|
1043
|
+
BROTLI_DECODER_RESULT_ERROR: 0,
|
|
1044
|
+
BROTLI_DECODER_RESULT_SUCCESS: 1,
|
|
1045
|
+
BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT: 2,
|
|
1046
|
+
BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT: 3,
|
|
1047
|
+
BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION: 0,
|
|
1048
|
+
BROTLI_DECODER_PARAM_LARGE_WINDOW: 1,
|
|
1049
|
+
BROTLI_DECODER_NO_ERROR: 0,
|
|
1050
|
+
BROTLI_DECODER_SUCCESS: 1,
|
|
1051
|
+
BROTLI_DECODER_NEEDS_MORE_INPUT: 2,
|
|
1052
|
+
BROTLI_DECODER_NEEDS_MORE_OUTPUT: 3,
|
|
1053
|
+
BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE: -1,
|
|
1054
|
+
BROTLI_DECODER_ERROR_FORMAT_RESERVED: -2,
|
|
1055
|
+
BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE: -3,
|
|
1056
|
+
BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET: -4,
|
|
1057
|
+
BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME: -5,
|
|
1058
|
+
BROTLI_DECODER_ERROR_FORMAT_CL_SPACE: -6,
|
|
1059
|
+
BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE: -7,
|
|
1060
|
+
BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT: -8,
|
|
1061
|
+
BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1: -9,
|
|
1062
|
+
BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2: -10,
|
|
1063
|
+
BROTLI_DECODER_ERROR_FORMAT_TRANSFORM: -11,
|
|
1064
|
+
BROTLI_DECODER_ERROR_FORMAT_DICTIONARY: -12,
|
|
1065
|
+
BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS: -13,
|
|
1066
|
+
BROTLI_DECODER_ERROR_FORMAT_PADDING_1: -14,
|
|
1067
|
+
BROTLI_DECODER_ERROR_FORMAT_PADDING_2: -15,
|
|
1068
|
+
BROTLI_DECODER_ERROR_FORMAT_DISTANCE: -16,
|
|
1069
|
+
BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET: -19,
|
|
1070
|
+
BROTLI_DECODER_ERROR_INVALID_ARGUMENTS: -20,
|
|
1071
|
+
BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES: -21,
|
|
1072
|
+
BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS: -22,
|
|
1073
|
+
BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP: -25,
|
|
1074
|
+
BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1: -26,
|
|
1075
|
+
BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2: -27,
|
|
1076
|
+
BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES: -30,
|
|
1077
|
+
BROTLI_DECODER_ERROR_UNREACHABLE: -31
|
|
1078
|
+
}, jr));
|
|
1079
|
+
var tn = Buffer$1.concat, Bs = Object.getOwnPropertyDescriptor(Buffer$1, "concat"), en = (s) => s, Mi = Bs?.writable === !0 || Bs?.set !== void 0 ? (s) => {
|
|
1080
|
+
Buffer$1.concat = s ? en : tn;
|
|
1081
|
+
} : (s) => {}, Tt = Symbol("_superWrite"), Gt = class extends Error {
|
|
1082
|
+
code;
|
|
1083
|
+
errno;
|
|
1084
|
+
constructor(t, e) {
|
|
1085
|
+
super("zlib: " + t.message, { cause: t }), this.code = t.code, this.errno = t.errno, this.code || (this.code = "ZLIB_ERROR"), this.message = "zlib: " + t.message, Error.captureStackTrace(this, e ?? this.constructor);
|
|
1086
|
+
}
|
|
1087
|
+
get name() {
|
|
1088
|
+
return "ZlibError";
|
|
1089
|
+
}
|
|
1090
|
+
}, Bi = Symbol("flushFlag"), re = class extends A {
|
|
1091
|
+
#t = !1;
|
|
1092
|
+
#i = !1;
|
|
1093
|
+
#s;
|
|
1094
|
+
#n;
|
|
1095
|
+
#r;
|
|
1096
|
+
#e;
|
|
1097
|
+
#o;
|
|
1098
|
+
get sawError() {
|
|
1099
|
+
return this.#t;
|
|
1100
|
+
}
|
|
1101
|
+
get handle() {
|
|
1102
|
+
return this.#e;
|
|
1103
|
+
}
|
|
1104
|
+
get flushFlag() {
|
|
1105
|
+
return this.#s;
|
|
1106
|
+
}
|
|
1107
|
+
constructor(t, e) {
|
|
1108
|
+
if (!t || typeof t != "object") throw new TypeError("invalid options for ZlibBase constructor");
|
|
1109
|
+
if (super(t), this.#s = t.flush ?? 0, this.#n = t.finishFlush ?? 0, this.#r = t.fullFlushFlag ?? 0, typeof Ms[e] != "function") throw new TypeError("Compression method not supported: " + e);
|
|
1110
|
+
try {
|
|
1111
|
+
this.#e = new Ms[e](t);
|
|
1112
|
+
} catch (i) {
|
|
1113
|
+
throw new Gt(i, this.constructor);
|
|
1114
|
+
}
|
|
1115
|
+
this.#o = (i) => {
|
|
1116
|
+
this.#t || (this.#t = !0, this.close(), this.emit("error", i));
|
|
1117
|
+
}, this.#e?.on("error", (i) => this.#o(new Gt(i))), this.once("end", () => this.close);
|
|
1118
|
+
}
|
|
1119
|
+
close() {
|
|
1120
|
+
this.#e && (this.#e.close(), this.#e = void 0, this.emit("close"));
|
|
1121
|
+
}
|
|
1122
|
+
reset() {
|
|
1123
|
+
if (!this.#t) return Pi(this.#e, "zlib binding closed"), this.#e.reset?.();
|
|
1124
|
+
}
|
|
1125
|
+
flush(t) {
|
|
1126
|
+
this.ended || (typeof t != "number" && (t = this.#r), this.write(Object.assign(Buffer$1.alloc(0), { [Bi]: t })));
|
|
1127
|
+
}
|
|
1128
|
+
end(t, e, i) {
|
|
1129
|
+
return typeof t == "function" && (i = t, e = void 0, t = void 0), typeof e == "function" && (i = e, e = void 0), t && (e ? this.write(t, e) : this.write(t)), this.flush(this.#n), this.#i = !0, super.end(i);
|
|
1130
|
+
}
|
|
1131
|
+
get ended() {
|
|
1132
|
+
return this.#i;
|
|
1133
|
+
}
|
|
1134
|
+
[Tt](t) {
|
|
1135
|
+
return super.write(t);
|
|
1136
|
+
}
|
|
1137
|
+
write(t, e, i) {
|
|
1138
|
+
if (typeof e == "function" && (i = e, e = "utf8"), typeof t == "string" && (t = Buffer$1.from(t, e)), this.#t) return;
|
|
1139
|
+
Pi(this.#e, "zlib binding closed");
|
|
1140
|
+
let r = this.#e._handle, n = r.close;
|
|
1141
|
+
r.close = () => {};
|
|
1142
|
+
let o = this.#e.close;
|
|
1143
|
+
this.#e.close = () => {}, Mi(!0);
|
|
1144
|
+
let a;
|
|
1145
|
+
try {
|
|
1146
|
+
let l = typeof t[Bi] == "number" ? t[Bi] : this.#s;
|
|
1147
|
+
a = this.#e._processChunk(t, l), Mi(!1);
|
|
1148
|
+
} catch (l) {
|
|
1149
|
+
Mi(!1), this.#o(new Gt(l, this.write));
|
|
1150
|
+
} finally {
|
|
1151
|
+
this.#e && (this.#e._handle = r, r.close = n, this.#e.close = o, this.#e.removeAllListeners("error"));
|
|
1152
|
+
}
|
|
1153
|
+
this.#e && this.#e.on("error", (l) => this.#o(new Gt(l, this.write)));
|
|
1154
|
+
let h;
|
|
1155
|
+
if (a) if (Array.isArray(a) && a.length > 0) {
|
|
1156
|
+
let l = a[0];
|
|
1157
|
+
h = this[Tt](Buffer$1.from(l));
|
|
1158
|
+
for (let c = 1; c < a.length; c++) h = this[Tt](a[c]);
|
|
1159
|
+
} else h = this[Tt](Buffer$1.from(a));
|
|
1160
|
+
return i && i(), h;
|
|
1161
|
+
}
|
|
1162
|
+
}, Be = class extends re {
|
|
1163
|
+
#t;
|
|
1164
|
+
#i;
|
|
1165
|
+
constructor(t, e) {
|
|
1166
|
+
t = t || {}, t.flush = t.flush || M.Z_NO_FLUSH, t.finishFlush = t.finishFlush || M.Z_FINISH, t.fullFlushFlag = M.Z_FULL_FLUSH, super(t, e), this.#t = t.level, this.#i = t.strategy;
|
|
1167
|
+
}
|
|
1168
|
+
params(t, e) {
|
|
1169
|
+
if (!this.sawError) {
|
|
1170
|
+
if (!this.handle) throw new Error("cannot switch params when binding is closed");
|
|
1171
|
+
if (!this.handle.params) throw new Error("not supported in this implementation");
|
|
1172
|
+
if (this.#t !== t || this.#i !== e) {
|
|
1173
|
+
this.flush(M.Z_SYNC_FLUSH), Pi(this.handle, "zlib binding closed");
|
|
1174
|
+
let i = this.handle.flush;
|
|
1175
|
+
this.handle.flush = (r, n) => {
|
|
1176
|
+
typeof r == "function" && (n = r, r = this.flushFlag), this.flush(r), n?.();
|
|
1177
|
+
};
|
|
1178
|
+
try {
|
|
1179
|
+
this.handle.params(t, e);
|
|
1180
|
+
} finally {
|
|
1181
|
+
this.handle.flush = i;
|
|
1182
|
+
}
|
|
1183
|
+
this.handle && (this.#t = t, this.#i = e);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
};
|
|
1188
|
+
var Pe = class extends Be {
|
|
1189
|
+
#t;
|
|
1190
|
+
constructor(t) {
|
|
1191
|
+
super(t, "Gzip"), this.#t = t && !!t.portable;
|
|
1192
|
+
}
|
|
1193
|
+
[Tt](t) {
|
|
1194
|
+
return this.#t ? (this.#t = !1, t[9] = 255, super[Tt](t)) : super[Tt](t);
|
|
1195
|
+
}
|
|
1196
|
+
};
|
|
1197
|
+
var ze = class extends Be {
|
|
1198
|
+
constructor(t) {
|
|
1199
|
+
super(t, "Unzip");
|
|
1200
|
+
}
|
|
1201
|
+
}, Ue = class extends re {
|
|
1202
|
+
constructor(t, e) {
|
|
1203
|
+
t = t || {}, t.flush = t.flush || M.BROTLI_OPERATION_PROCESS, t.finishFlush = t.finishFlush || M.BROTLI_OPERATION_FINISH, t.fullFlushFlag = M.BROTLI_OPERATION_FLUSH, super(t, e);
|
|
1204
|
+
}
|
|
1205
|
+
}, He = class extends Ue {
|
|
1206
|
+
constructor(t) {
|
|
1207
|
+
super(t, "BrotliCompress");
|
|
1208
|
+
}
|
|
1209
|
+
}, We = class extends Ue {
|
|
1210
|
+
constructor(t) {
|
|
1211
|
+
super(t, "BrotliDecompress");
|
|
1212
|
+
}
|
|
1213
|
+
}, Ge = class extends re {
|
|
1214
|
+
constructor(t, e) {
|
|
1215
|
+
t = t || {}, t.flush = t.flush || M.ZSTD_e_continue, t.finishFlush = t.finishFlush || M.ZSTD_e_end, t.fullFlushFlag = M.ZSTD_e_flush, super(t, e);
|
|
1216
|
+
}
|
|
1217
|
+
}, Ze = class extends Ge {
|
|
1218
|
+
constructor(t) {
|
|
1219
|
+
super(t, "ZstdCompress");
|
|
1220
|
+
}
|
|
1221
|
+
}, Ye = class extends Ge {
|
|
1222
|
+
constructor(t) {
|
|
1223
|
+
super(t, "ZstdDecompress");
|
|
1224
|
+
}
|
|
1225
|
+
};
|
|
1226
|
+
var Ps = (s, t) => {
|
|
1227
|
+
if (Number.isSafeInteger(s)) s < 0 ? nn(s, t) : rn(s, t);
|
|
1228
|
+
else throw Error("cannot encode number outside of javascript safe integer range");
|
|
1229
|
+
return t;
|
|
1230
|
+
}, rn = (s, t) => {
|
|
1231
|
+
t[0] = 128;
|
|
1232
|
+
for (var e = t.length; e > 1; e--) t[e - 1] = s & 255, s = Math.floor(s / 256);
|
|
1233
|
+
}, nn = (s, t) => {
|
|
1234
|
+
t[0] = 255;
|
|
1235
|
+
var e = !1;
|
|
1236
|
+
s = s * -1;
|
|
1237
|
+
for (var i = t.length; i > 1; i--) {
|
|
1238
|
+
var r = s & 255;
|
|
1239
|
+
s = Math.floor(s / 256), e ? t[i - 1] = Us(r) : r === 0 ? t[i - 1] = 0 : (e = !0, t[i - 1] = Hs(r));
|
|
1240
|
+
}
|
|
1241
|
+
}, zs = (s) => {
|
|
1242
|
+
let t = s[0], e = t === 128 ? hn(s.subarray(1, s.length)) : t === 255 ? on(s) : null;
|
|
1243
|
+
if (e === null) throw Error("invalid base256 encoding");
|
|
1244
|
+
if (!Number.isSafeInteger(e)) throw Error("parsed number outside of javascript safe integer range");
|
|
1245
|
+
return e;
|
|
1246
|
+
}, on = (s) => {
|
|
1247
|
+
for (var t = s.length, e = 0, i = !1, r = t - 1; r > -1; r--) {
|
|
1248
|
+
var n = Number(s[r]), o;
|
|
1249
|
+
i ? o = Us(n) : n === 0 ? o = n : (i = !0, o = Hs(n)), o !== 0 && (e -= o * Math.pow(256, t - r - 1));
|
|
1250
|
+
}
|
|
1251
|
+
return e;
|
|
1252
|
+
}, hn = (s) => {
|
|
1253
|
+
for (var t = s.length, e = 0, i = t - 1; i > -1; i--) {
|
|
1254
|
+
var r = Number(s[i]);
|
|
1255
|
+
r !== 0 && (e += r * Math.pow(256, t - i - 1));
|
|
1256
|
+
}
|
|
1257
|
+
return e;
|
|
1258
|
+
}, Us = (s) => (255 ^ s) & 255, Hs = (s) => (255 ^ s) + 1 & 255;
|
|
1259
|
+
Br({}, {
|
|
1260
|
+
code: () => Ke,
|
|
1261
|
+
isCode: () => ne,
|
|
1262
|
+
isName: () => ln,
|
|
1263
|
+
name: () => oe,
|
|
1264
|
+
normalFsTypes: () => zi
|
|
1265
|
+
});
|
|
1266
|
+
var ne = (s) => oe.has(s), ln = (s) => Ke.has(s), zi = new Set([
|
|
1267
|
+
"0",
|
|
1268
|
+
"",
|
|
1269
|
+
"1",
|
|
1270
|
+
"2",
|
|
1271
|
+
"3",
|
|
1272
|
+
"4",
|
|
1273
|
+
"5",
|
|
1274
|
+
"6",
|
|
1275
|
+
"7",
|
|
1276
|
+
"D"
|
|
1277
|
+
]), oe = new Map([
|
|
1278
|
+
["0", "File"],
|
|
1279
|
+
["", "OldFile"],
|
|
1280
|
+
["1", "Link"],
|
|
1281
|
+
["2", "SymbolicLink"],
|
|
1282
|
+
["3", "CharacterDevice"],
|
|
1283
|
+
["4", "BlockDevice"],
|
|
1284
|
+
["5", "Directory"],
|
|
1285
|
+
["6", "FIFO"],
|
|
1286
|
+
["7", "ContiguousFile"],
|
|
1287
|
+
["g", "GlobalExtendedHeader"],
|
|
1288
|
+
["x", "ExtendedHeader"],
|
|
1289
|
+
["A", "SolarisACL"],
|
|
1290
|
+
["D", "GNUDumpDir"],
|
|
1291
|
+
["I", "Inode"],
|
|
1292
|
+
["K", "NextFileHasLongLinkpath"],
|
|
1293
|
+
["L", "NextFileHasLongPath"],
|
|
1294
|
+
["M", "ContinuationFile"],
|
|
1295
|
+
["N", "OldGnuLongPath"],
|
|
1296
|
+
["S", "SparseFile"],
|
|
1297
|
+
["V", "TapeVolumeHeader"],
|
|
1298
|
+
["X", "OldExtendedHeader"]
|
|
1299
|
+
]), Ke = new Map(Array.from(oe).map((s) => [s[1], s[0]]));
|
|
1300
|
+
var C = class {
|
|
1301
|
+
cksumValid = !1;
|
|
1302
|
+
needPax = !1;
|
|
1303
|
+
nullBlock = !1;
|
|
1304
|
+
block;
|
|
1305
|
+
path;
|
|
1306
|
+
mode;
|
|
1307
|
+
uid;
|
|
1308
|
+
gid;
|
|
1309
|
+
size;
|
|
1310
|
+
cksum;
|
|
1311
|
+
#t = "Unsupported";
|
|
1312
|
+
linkpath;
|
|
1313
|
+
uname;
|
|
1314
|
+
gname;
|
|
1315
|
+
devmaj = 0;
|
|
1316
|
+
devmin = 0;
|
|
1317
|
+
atime;
|
|
1318
|
+
ctime;
|
|
1319
|
+
mtime;
|
|
1320
|
+
charset;
|
|
1321
|
+
comment;
|
|
1322
|
+
constructor(t, e = 0, i, r) {
|
|
1323
|
+
Buffer.isBuffer(t) ? this.decode(t, e || 0, i, r) : t && this.#i(t);
|
|
1324
|
+
}
|
|
1325
|
+
decode(t, e, i, r) {
|
|
1326
|
+
if (e || (e = 0), !t || !(t.length >= e + 512)) throw new Error("need 512 bytes for header");
|
|
1327
|
+
let n = xt(t, e + 156, 1), o = zi.has(n), a = o ? i : void 0, h = o ? r : void 0;
|
|
1328
|
+
if (this.path = a?.path ?? xt(t, e, 100), this.mode = a?.mode ?? h?.mode ?? at(t, e + 100, 8), this.uid = a?.uid ?? h?.uid ?? at(t, e + 108, 8), this.gid = a?.gid ?? h?.gid ?? at(t, e + 116, 8), this.size = a?.size ?? h?.size ?? at(t, e + 124, 12), this.mtime = a?.mtime ?? h?.mtime ?? Hi(t, e + 136, 12), this.cksum = at(t, e + 148, 12), h && this.#i(h, !0), a && this.#i(a), ne(n) && (this.#t = n || "0"), this.#t === "0" && this.path.slice(-1) === "/" && (this.#t = "5"), this.#t === "5" && (this.size = 0), this.linkpath = xt(t, e + 157, 100), t.subarray(e + 257, e + 265).toString() === "ustar\x0000") if (this.uname = a?.uname ?? h?.uname ?? xt(t, e + 265, 32), this.gname = a?.gname ?? h?.gname ?? xt(t, e + 297, 32), this.devmaj = a?.devmaj ?? h?.devmaj ?? at(t, e + 329, 8) ?? 0, this.devmin = a?.devmin ?? h?.devmin ?? at(t, e + 337, 8) ?? 0, t[e + 475] !== 0) {
|
|
1329
|
+
let c = xt(t, e + 345, 155);
|
|
1330
|
+
this.path = c + "/" + this.path;
|
|
1331
|
+
} else {
|
|
1332
|
+
let c = xt(t, e + 345, 130);
|
|
1333
|
+
c && (this.path = c + "/" + this.path), this.atime = i?.atime ?? r?.atime ?? Hi(t, e + 476, 12), this.ctime = i?.ctime ?? r?.ctime ?? Hi(t, e + 488, 12);
|
|
1334
|
+
}
|
|
1335
|
+
let l = 256;
|
|
1336
|
+
for (let c = e; c < e + 148; c++) l += t[c];
|
|
1337
|
+
for (let c = e + 156; c < e + 512; c++) l += t[c];
|
|
1338
|
+
this.cksumValid = l === this.cksum, this.cksum === void 0 && l === 256 && (this.nullBlock = !0);
|
|
1339
|
+
}
|
|
1340
|
+
#i(t, e = !1) {
|
|
1341
|
+
Object.assign(this, Object.fromEntries(Object.entries(t).filter(([i, r]) => !(r == null || i === "path" && e || i === "linkpath" && e || i === "global"))));
|
|
1342
|
+
}
|
|
1343
|
+
encode(t, e = 0) {
|
|
1344
|
+
if (t || (t = this.block = Buffer.alloc(512)), this.#t === "Unsupported" && (this.#t = "0"), !(t.length >= e + 512)) throw new Error("need 512 bytes for header");
|
|
1345
|
+
let i = this.ctime || this.atime ? 130 : 155, r = cn(this.path || "", i), n = r[0], o = r[1];
|
|
1346
|
+
this.needPax = !!r[2], this.needPax = Lt(t, e, 100, n) || this.needPax, this.needPax = lt(t, e + 100, 8, this.mode) || this.needPax, this.needPax = lt(t, e + 108, 8, this.uid) || this.needPax, this.needPax = lt(t, e + 116, 8, this.gid) || this.needPax, this.needPax = lt(t, e + 124, 12, this.size) || this.needPax, this.needPax = Wi(t, e + 136, 12, this.mtime) || this.needPax, t[e + 156] = Number(this.#t.codePointAt(0)), this.needPax = Lt(t, e + 157, 100, this.linkpath) || this.needPax, t.write("ustar\x0000", e + 257, 8), this.needPax = Lt(t, e + 265, 32, this.uname) || this.needPax, this.needPax = Lt(t, e + 297, 32, this.gname) || this.needPax, this.needPax = lt(t, e + 329, 8, this.devmaj) || this.needPax, this.needPax = lt(t, e + 337, 8, this.devmin) || this.needPax, this.needPax = Lt(t, e + 345, i, o) || this.needPax, t[e + 475] !== 0 ? this.needPax = Lt(t, e + 345, 155, o) || this.needPax : (this.needPax = Lt(t, e + 345, 130, o) || this.needPax, this.needPax = Wi(t, e + 476, 12, this.atime) || this.needPax, this.needPax = Wi(t, e + 488, 12, this.ctime) || this.needPax);
|
|
1347
|
+
let a = 256;
|
|
1348
|
+
for (let h = e; h < e + 148; h++) a += t[h];
|
|
1349
|
+
for (let h = e + 156; h < e + 512; h++) a += t[h];
|
|
1350
|
+
return this.cksum = a, lt(t, e + 148, 8, this.cksum), this.cksumValid = !0, this.needPax;
|
|
1351
|
+
}
|
|
1352
|
+
get type() {
|
|
1353
|
+
return this.#t === "Unsupported" ? this.#t : oe.get(this.#t);
|
|
1354
|
+
}
|
|
1355
|
+
get typeKey() {
|
|
1356
|
+
return this.#t;
|
|
1357
|
+
}
|
|
1358
|
+
set type(t) {
|
|
1359
|
+
let e = String(Ke.get(t));
|
|
1360
|
+
if (ne(e) || e === "Unsupported") this.#t = e;
|
|
1361
|
+
else if (ne(t)) this.#t = t;
|
|
1362
|
+
else throw new TypeError("invalid entry type: " + t);
|
|
1363
|
+
}
|
|
1364
|
+
}, cn = (s, t) => {
|
|
1365
|
+
let i = s, r = "", n, o = posix.parse(s).root || ".";
|
|
1366
|
+
if (Buffer.byteLength(i) < 100) n = [
|
|
1367
|
+
i,
|
|
1368
|
+
r,
|
|
1369
|
+
!1
|
|
1370
|
+
];
|
|
1371
|
+
else {
|
|
1372
|
+
r = posix.dirname(i), i = posix.basename(i);
|
|
1373
|
+
do
|
|
1374
|
+
Buffer.byteLength(i) <= 100 && Buffer.byteLength(r) <= t ? n = [
|
|
1375
|
+
i,
|
|
1376
|
+
r,
|
|
1377
|
+
!1
|
|
1378
|
+
] : Buffer.byteLength(i) > 100 && Buffer.byteLength(r) <= t ? n = [
|
|
1379
|
+
i.slice(0, 99),
|
|
1380
|
+
r,
|
|
1381
|
+
!0
|
|
1382
|
+
] : (i = posix.join(posix.basename(r), i), r = posix.dirname(r));
|
|
1383
|
+
while (r !== o && n === void 0);
|
|
1384
|
+
n || (n = [
|
|
1385
|
+
s.slice(0, 99),
|
|
1386
|
+
"",
|
|
1387
|
+
!0
|
|
1388
|
+
]);
|
|
1389
|
+
}
|
|
1390
|
+
return n;
|
|
1391
|
+
}, xt = (s, t, e) => s.subarray(t, t + e).toString("utf8").replace(/\0.*/, ""), Hi = (s, t, e) => fn(at(s, t, e)), fn = (s) => s === void 0 ? void 0 : /* @__PURE__ */ new Date(s * 1e3), at = (s, t, e) => Number(s[t]) & 128 ? zs(s.subarray(t, t + e)) : un(s, t, e), dn = (s) => isNaN(s) ? void 0 : s, un = (s, t, e) => dn(parseInt(s.subarray(t, t + e).toString("utf8").replace(/\0.*$/, "").trim(), 8)), mn = {
|
|
1392
|
+
12: 8589934591,
|
|
1393
|
+
8: 2097151
|
|
1394
|
+
}, lt = (s, t, e, i) => i === void 0 ? !1 : i > mn[e] || i < 0 ? (Ps(i, s.subarray(t, t + e)), !0) : (pn(s, t, e, i), !1), pn = (s, t, e, i) => s.write(En(i, e), t, e, "ascii"), En = (s, t) => wn(Math.floor(s).toString(8), t), wn = (s, t) => (s.length === t - 1 ? s : new Array(t - s.length - 1).join("0") + s + " ") + "\0", Wi = (s, t, e, i) => i === void 0 ? !1 : lt(s, t, e, i.getTime() / 1e3), Sn = new Array(156).join("\0"), Lt = (s, t, e, i) => i === void 0 ? !1 : (s.write(i + Sn, t, e, "utf8"), i.length !== Buffer.byteLength(i) || i.length > e);
|
|
1395
|
+
var ct = class s {
|
|
1396
|
+
atime;
|
|
1397
|
+
mtime;
|
|
1398
|
+
ctime;
|
|
1399
|
+
charset;
|
|
1400
|
+
comment;
|
|
1401
|
+
gid;
|
|
1402
|
+
uid;
|
|
1403
|
+
gname;
|
|
1404
|
+
uname;
|
|
1405
|
+
linkpath;
|
|
1406
|
+
dev;
|
|
1407
|
+
ino;
|
|
1408
|
+
nlink;
|
|
1409
|
+
path;
|
|
1410
|
+
size;
|
|
1411
|
+
mode;
|
|
1412
|
+
global;
|
|
1413
|
+
constructor(t, e = !1) {
|
|
1414
|
+
this.atime = t.atime, this.charset = t.charset, this.comment = t.comment, this.ctime = t.ctime, this.dev = t.dev, this.gid = t.gid, this.global = e, this.gname = t.gname, this.ino = t.ino, this.linkpath = t.linkpath, this.mtime = t.mtime, this.nlink = t.nlink, this.path = t.path, this.size = t.size, this.uid = t.uid, this.uname = t.uname;
|
|
1415
|
+
}
|
|
1416
|
+
encode() {
|
|
1417
|
+
let t = this.encodeBody();
|
|
1418
|
+
if (t === "") return Buffer.allocUnsafe(0);
|
|
1419
|
+
let e = Buffer.byteLength(t), i = 512 * Math.ceil(1 + e / 512), r = Buffer.allocUnsafe(i);
|
|
1420
|
+
for (let n = 0; n < 512; n++) r[n] = 0;
|
|
1421
|
+
new C({
|
|
1422
|
+
path: ("PaxHeader/" + basename(this.path ?? "")).slice(0, 99),
|
|
1423
|
+
mode: this.mode || 420,
|
|
1424
|
+
uid: this.uid,
|
|
1425
|
+
gid: this.gid,
|
|
1426
|
+
size: e,
|
|
1427
|
+
mtime: this.mtime,
|
|
1428
|
+
type: this.global ? "GlobalExtendedHeader" : "ExtendedHeader",
|
|
1429
|
+
linkpath: "",
|
|
1430
|
+
uname: this.uname || "",
|
|
1431
|
+
gname: this.gname || "",
|
|
1432
|
+
devmaj: 0,
|
|
1433
|
+
devmin: 0,
|
|
1434
|
+
atime: this.atime,
|
|
1435
|
+
ctime: this.ctime
|
|
1436
|
+
}).encode(r), r.write(t, 512, e, "utf8");
|
|
1437
|
+
for (let n = e + 512; n < r.length; n++) r[n] = 0;
|
|
1438
|
+
return r;
|
|
1439
|
+
}
|
|
1440
|
+
encodeBody() {
|
|
1441
|
+
return this.encodeField("path") + this.encodeField("ctime") + this.encodeField("atime") + this.encodeField("dev") + this.encodeField("ino") + this.encodeField("nlink") + this.encodeField("charset") + this.encodeField("comment") + this.encodeField("gid") + this.encodeField("gname") + this.encodeField("linkpath") + this.encodeField("mtime") + this.encodeField("size") + this.encodeField("uid") + this.encodeField("uname");
|
|
1442
|
+
}
|
|
1443
|
+
encodeField(t) {
|
|
1444
|
+
if (this[t] === void 0) return "";
|
|
1445
|
+
let e = this[t], i = e instanceof Date ? e.getTime() / 1e3 : e, r = " " + (t === "dev" || t === "ino" || t === "nlink" ? "SCHILY." : "") + t + "=" + i + `
|
|
1446
|
+
`, n = Buffer.byteLength(r), o = Math.floor(Math.log(n) / Math.log(10)) + 1;
|
|
1447
|
+
return n + o >= Math.pow(10, o) && (o += 1), o + n + r;
|
|
1448
|
+
}
|
|
1449
|
+
static parse(t, e, i = !1) {
|
|
1450
|
+
return new s(Rn(gn(t), e), i);
|
|
1451
|
+
}
|
|
1452
|
+
}, Rn = (s, t) => t ? Object.assign({}, t, s) : s, gn = (s) => s.replace(/\n$/, "").split(`
|
|
1453
|
+
`).reduce(bn, Object.create(null)), bn = (s, t) => {
|
|
1454
|
+
let e = parseInt(t, 10);
|
|
1455
|
+
if (e !== Buffer.byteLength(t) + 1) return s;
|
|
1456
|
+
t = t.slice((e + " ").length);
|
|
1457
|
+
let i = t.split("="), r = i.shift();
|
|
1458
|
+
if (!r) return s;
|
|
1459
|
+
let n = r.replace(/^SCHILY\.(dev|ino|nlink)/, "$1"), o = i.join("=");
|
|
1460
|
+
return s[n] = /^([A-Z]+\.)?([mac]|birth|creation)time$/.test(n) ? /* @__PURE__ */ new Date(Number(o) * 1e3) : /^[0-9]+$/.test(o) ? +o : o, s;
|
|
1461
|
+
};
|
|
1462
|
+
var f = (process.env.TESTING_TAR_FAKE_PLATFORM || process.platform) !== "win32" ? (s) => s : (s) => s && s.replaceAll(/\\/g, "/");
|
|
1463
|
+
var Ve = class extends A {
|
|
1464
|
+
extended;
|
|
1465
|
+
globalExtended;
|
|
1466
|
+
header;
|
|
1467
|
+
startBlockSize;
|
|
1468
|
+
blockRemain;
|
|
1469
|
+
remain;
|
|
1470
|
+
type;
|
|
1471
|
+
meta = !1;
|
|
1472
|
+
ignore = !1;
|
|
1473
|
+
path;
|
|
1474
|
+
mode;
|
|
1475
|
+
uid;
|
|
1476
|
+
gid;
|
|
1477
|
+
uname;
|
|
1478
|
+
gname;
|
|
1479
|
+
size = 0;
|
|
1480
|
+
mtime;
|
|
1481
|
+
atime;
|
|
1482
|
+
ctime;
|
|
1483
|
+
linkpath;
|
|
1484
|
+
dev;
|
|
1485
|
+
ino;
|
|
1486
|
+
nlink;
|
|
1487
|
+
invalid = !1;
|
|
1488
|
+
absolute;
|
|
1489
|
+
unsupported = !1;
|
|
1490
|
+
constructor(t, e, i) {
|
|
1491
|
+
switch (super({}), this.pause(), this.extended = e, this.globalExtended = i, this.header = t, this.remain = t.size ?? 0, this.startBlockSize = 512 * Math.ceil(this.remain / 512), this.blockRemain = this.startBlockSize, this.type = t.type, this.type) {
|
|
1492
|
+
case "File":
|
|
1493
|
+
case "OldFile":
|
|
1494
|
+
case "Link":
|
|
1495
|
+
case "SymbolicLink":
|
|
1496
|
+
case "CharacterDevice":
|
|
1497
|
+
case "BlockDevice":
|
|
1498
|
+
case "Directory":
|
|
1499
|
+
case "FIFO":
|
|
1500
|
+
case "ContiguousFile":
|
|
1501
|
+
case "GNUDumpDir": break;
|
|
1502
|
+
case "NextFileHasLongLinkpath":
|
|
1503
|
+
case "NextFileHasLongPath":
|
|
1504
|
+
case "OldGnuLongPath":
|
|
1505
|
+
case "GlobalExtendedHeader":
|
|
1506
|
+
case "ExtendedHeader":
|
|
1507
|
+
case "OldExtendedHeader":
|
|
1508
|
+
this.meta = !0;
|
|
1509
|
+
break;
|
|
1510
|
+
default: this.ignore = !0;
|
|
1511
|
+
}
|
|
1512
|
+
if (!t.path) throw new Error("no path provided for tar.ReadEntry");
|
|
1513
|
+
this.path = f(t.path), this.mode = t.mode, this.mode && (this.mode = this.mode & 4095), this.uid = t.uid, this.gid = t.gid, this.uname = t.uname, this.gname = t.gname, this.size = this.remain, this.mtime = t.mtime, this.atime = t.atime, this.ctime = t.ctime, this.linkpath = t.linkpath ? f(t.linkpath) : void 0, this.uname = t.uname, this.gname = t.gname, e && this.#t(e), i && this.#t(i, !0);
|
|
1514
|
+
}
|
|
1515
|
+
write(t) {
|
|
1516
|
+
let e = t.length;
|
|
1517
|
+
if (e > this.blockRemain) throw new Error("writing more to entry than is appropriate");
|
|
1518
|
+
let i = this.remain, r = this.blockRemain;
|
|
1519
|
+
return this.remain = Math.max(0, i - e), this.blockRemain = Math.max(0, r - e), this.ignore ? !0 : i >= e ? super.write(t) : super.write(t.subarray(0, i));
|
|
1520
|
+
}
|
|
1521
|
+
#t(t, e = !1) {
|
|
1522
|
+
t.path && (t.path = f(t.path)), t.linkpath && (t.linkpath = f(t.linkpath)), Object.assign(this, Object.fromEntries(Object.entries(t).filter(([i, r]) => !(r == null || i === "path" && e))));
|
|
1523
|
+
}
|
|
1524
|
+
};
|
|
1525
|
+
var Nt = (s, t, e, i = {}) => {
|
|
1526
|
+
s.file && (i.file = s.file), s.cwd && (i.cwd = s.cwd), i.code = e instanceof Error && e.code || t, i.tarCode = t, !s.strict && i.recoverable !== !1 ? (e instanceof Error && (i = Object.assign(e, i), e = e.message), s.emit("warn", t, e, i)) : e instanceof Error ? s.emit("error", Object.assign(e, i)) : s.emit("error", Object.assign(/* @__PURE__ */ new Error(`${t}: ${e}`), i));
|
|
1527
|
+
};
|
|
1528
|
+
var Tn = 1024 * 1024, Vi = Buffer.from([31, 139]), $i = Buffer.from([
|
|
1529
|
+
40,
|
|
1530
|
+
181,
|
|
1531
|
+
47,
|
|
1532
|
+
253
|
|
1533
|
+
]), xn = Math.max(Vi.length, $i.length), B = Symbol("state"), Dt = Symbol("writeEntry"), et = Symbol("readEntry"), Gi = Symbol("nextEntry"), Ws = Symbol("processEntry"), V = Symbol("extendedHeader"), he = Symbol("globalExtendedHeader"), ft = Symbol("meta"), Gs = Symbol("emitMeta"), p = Symbol("buffer"), it = Symbol("queue"), dt = Symbol("ended"), Zi = Symbol("emittedEnd"), At = Symbol("emit"), y = Symbol("unzip"), $e = Symbol("consumeChunk"), Xe = Symbol("consumeChunkSub"), Yi = Symbol("consumeBody"), Zs = Symbol("consumeMeta"), Ys = Symbol("consumeHeader"), ae = Symbol("consuming"), Ki = Symbol("bufferConcat"), qe = Symbol("maybeEnd"), Yt = Symbol("writing"), ut = Symbol("aborted"), Qe = Symbol("onDone"), It = Symbol("sawValidEntry"), Je = Symbol("sawNullBlock"), je = Symbol("sawEOF"), Ks = Symbol("closeStream"), Ln = () => !0, st = class extends EventEmitter$1 {
|
|
1534
|
+
file;
|
|
1535
|
+
strict;
|
|
1536
|
+
maxMetaEntrySize;
|
|
1537
|
+
filter;
|
|
1538
|
+
brotli;
|
|
1539
|
+
zstd;
|
|
1540
|
+
writable = !0;
|
|
1541
|
+
readable = !1;
|
|
1542
|
+
[it] = [];
|
|
1543
|
+
[p];
|
|
1544
|
+
[et];
|
|
1545
|
+
[Dt];
|
|
1546
|
+
[B] = "begin";
|
|
1547
|
+
[ft] = "";
|
|
1548
|
+
[V];
|
|
1549
|
+
[he];
|
|
1550
|
+
[dt] = !1;
|
|
1551
|
+
[y];
|
|
1552
|
+
[ut] = !1;
|
|
1553
|
+
[It];
|
|
1554
|
+
[Je] = !1;
|
|
1555
|
+
[je] = !1;
|
|
1556
|
+
[Yt] = !1;
|
|
1557
|
+
[ae] = !1;
|
|
1558
|
+
[Zi] = !1;
|
|
1559
|
+
constructor(t = {}) {
|
|
1560
|
+
super(), this.file = t.file || "", this.on(Qe, () => {
|
|
1561
|
+
(this[B] === "begin" || this[It] === !1) && this.warn("TAR_BAD_ARCHIVE", "Unrecognized archive format");
|
|
1562
|
+
}), t.ondone ? this.on(Qe, t.ondone) : this.on(Qe, () => {
|
|
1563
|
+
this.emit("prefinish"), this.emit("finish"), this.emit("end");
|
|
1564
|
+
}), this.strict = !!t.strict, this.maxMetaEntrySize = t.maxMetaEntrySize || Tn, this.filter = typeof t.filter == "function" ? t.filter : Ln;
|
|
1565
|
+
let e = t.file && (t.file.endsWith(".tar.br") || t.file.endsWith(".tbr"));
|
|
1566
|
+
this.brotli = !(t.gzip || t.zstd) && t.brotli !== void 0 ? t.brotli : e ? void 0 : !1;
|
|
1567
|
+
let i = t.file && (t.file.endsWith(".tar.zst") || t.file.endsWith(".tzst"));
|
|
1568
|
+
this.zstd = !(t.gzip || t.brotli) && t.zstd !== void 0 ? t.zstd : i ? !0 : void 0, this.on("end", () => this[Ks]()), typeof t.onwarn == "function" && this.on("warn", t.onwarn), typeof t.onReadEntry == "function" && this.on("entry", t.onReadEntry);
|
|
1569
|
+
}
|
|
1570
|
+
warn(t, e, i = {}) {
|
|
1571
|
+
Nt(this, t, e, i);
|
|
1572
|
+
}
|
|
1573
|
+
[Ys](t, e) {
|
|
1574
|
+
this[It] === void 0 && (this[It] = !1);
|
|
1575
|
+
let i;
|
|
1576
|
+
try {
|
|
1577
|
+
i = new C(t, e, this[V], this[he]);
|
|
1578
|
+
} catch (r) {
|
|
1579
|
+
return this.warn("TAR_ENTRY_INVALID", r);
|
|
1580
|
+
}
|
|
1581
|
+
if (i.nullBlock) this[Je] ? (this[je] = !0, this[B] === "begin" && (this[B] = "header"), this[At]("eof")) : (this[Je] = !0, this[At]("nullBlock"));
|
|
1582
|
+
else if (this[Je] = !1, !i.cksumValid) this.warn("TAR_ENTRY_INVALID", "checksum failure", { header: i });
|
|
1583
|
+
else if (!i.path) this.warn("TAR_ENTRY_INVALID", "path is required", { header: i });
|
|
1584
|
+
else {
|
|
1585
|
+
let r = i.type;
|
|
1586
|
+
if (/^(Symbolic)?Link$/.test(r) && !i.linkpath) this.warn("TAR_ENTRY_INVALID", "linkpath required", { header: i });
|
|
1587
|
+
else if (!/^(Symbolic)?Link$/.test(r) && !/^(Global)?ExtendedHeader$/.test(r) && i.linkpath) this.warn("TAR_ENTRY_INVALID", "linkpath forbidden", { header: i });
|
|
1588
|
+
else {
|
|
1589
|
+
let n = this[Dt] = new Ve(i, this[V], this[he]);
|
|
1590
|
+
if (!this[It]) if (n.remain) {
|
|
1591
|
+
let o = () => {
|
|
1592
|
+
n.invalid || (this[It] = !0);
|
|
1593
|
+
};
|
|
1594
|
+
n.on("end", o);
|
|
1595
|
+
} else this[It] = !0;
|
|
1596
|
+
n.meta ? n.size > this.maxMetaEntrySize ? (n.ignore = !0, this[At]("ignoredEntry", n), this[B] = "ignore", n.resume()) : n.size > 0 && (this[ft] = "", n.on("data", (o) => this[ft] += o), this[B] = "meta") : (this[V] = void 0, n.ignore = n.ignore || !this.filter(n.path, n), n.ignore ? (this[At]("ignoredEntry", n), this[B] = n.remain ? "ignore" : "header", n.resume()) : (n.remain ? this[B] = "body" : (this[B] = "header", n.end()), this[et] ? this[it].push(n) : (this[it].push(n), this[Gi]())));
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
[Ks]() {
|
|
1601
|
+
queueMicrotask(() => this.emit("close"));
|
|
1602
|
+
}
|
|
1603
|
+
[Ws](t) {
|
|
1604
|
+
let e = !0;
|
|
1605
|
+
if (!t) this[et] = void 0, e = !1;
|
|
1606
|
+
else if (Array.isArray(t)) {
|
|
1607
|
+
let [i, ...r] = t;
|
|
1608
|
+
this.emit(i, ...r);
|
|
1609
|
+
} else this[et] = t, this.emit("entry", t), t.emittedEnd || (t.on("end", () => this[Gi]()), e = !1);
|
|
1610
|
+
return e;
|
|
1611
|
+
}
|
|
1612
|
+
[Gi]() {
|
|
1613
|
+
do ;
|
|
1614
|
+
while (this[Ws](this[it].shift()));
|
|
1615
|
+
if (this[it].length === 0) {
|
|
1616
|
+
let t = this[et];
|
|
1617
|
+
!t || t.flowing || t.size === t.remain ? this[Yt] || this.emit("drain") : t.once("drain", () => this.emit("drain"));
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
[Yi](t, e) {
|
|
1621
|
+
let i = this[Dt];
|
|
1622
|
+
if (!i) throw new Error("attempt to consume body without entry??");
|
|
1623
|
+
let r = i.blockRemain ?? 0, n = r >= t.length && e === 0 ? t : t.subarray(e, e + r);
|
|
1624
|
+
return i.write(n), i.blockRemain || (this[B] = "header", this[Dt] = void 0, i.end()), n.length;
|
|
1625
|
+
}
|
|
1626
|
+
[Zs](t, e) {
|
|
1627
|
+
let i = this[Dt], r = this[Yi](t, e);
|
|
1628
|
+
return !this[Dt] && i && this[Gs](i), r;
|
|
1629
|
+
}
|
|
1630
|
+
[At](t, e, i) {
|
|
1631
|
+
this[it].length === 0 && !this[et] ? this.emit(t, e, i) : this[it].push([
|
|
1632
|
+
t,
|
|
1633
|
+
e,
|
|
1634
|
+
i
|
|
1635
|
+
]);
|
|
1636
|
+
}
|
|
1637
|
+
[Gs](t) {
|
|
1638
|
+
switch (this[At]("meta", this[ft]), t.type) {
|
|
1639
|
+
case "ExtendedHeader":
|
|
1640
|
+
case "OldExtendedHeader":
|
|
1641
|
+
this[V] = ct.parse(this[ft], this[V], !1);
|
|
1642
|
+
break;
|
|
1643
|
+
case "GlobalExtendedHeader":
|
|
1644
|
+
this[he] = ct.parse(this[ft], this[he], !0);
|
|
1645
|
+
break;
|
|
1646
|
+
case "NextFileHasLongPath":
|
|
1647
|
+
case "OldGnuLongPath": {
|
|
1648
|
+
let e = this[V] ?? Object.create(null);
|
|
1649
|
+
this[V] = e, e.path = this[ft].replace(/\0.*/, "");
|
|
1650
|
+
break;
|
|
1651
|
+
}
|
|
1652
|
+
case "NextFileHasLongLinkpath": {
|
|
1653
|
+
let e = this[V] || Object.create(null);
|
|
1654
|
+
this[V] = e, e.linkpath = this[ft].replace(/\0.*/, "");
|
|
1655
|
+
break;
|
|
1656
|
+
}
|
|
1657
|
+
default: throw new Error("unknown meta: " + t.type);
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
abort(t) {
|
|
1661
|
+
this[ut] = !0, this.emit("abort", t), this.warn("TAR_ABORT", t, { recoverable: !1 });
|
|
1662
|
+
}
|
|
1663
|
+
write(t, e, i) {
|
|
1664
|
+
if (typeof e == "function" && (i = e, e = void 0), typeof t == "string" && (t = Buffer.from(t, typeof e == "string" ? e : "utf8")), this[ut]) return i?.(), !1;
|
|
1665
|
+
if ((this[y] === void 0 || this.brotli === void 0 && this[y] === !1) && t) {
|
|
1666
|
+
if (this[p] && (t = Buffer.concat([this[p], t]), this[p] = void 0), t.length < xn) return this[p] = t, i?.(), !0;
|
|
1667
|
+
for (let h = 0; this[y] === void 0 && h < Vi.length; h++) t[h] !== Vi[h] && (this[y] = !1);
|
|
1668
|
+
let o = !1;
|
|
1669
|
+
if (this[y] === !1 && this.zstd !== !1) {
|
|
1670
|
+
o = !0;
|
|
1671
|
+
for (let h = 0; h < $i.length; h++) if (t[h] !== $i[h]) {
|
|
1672
|
+
o = !1;
|
|
1673
|
+
break;
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
let a = this.brotli === void 0 && !o;
|
|
1677
|
+
if (this[y] === !1 && a) if (t.length < 512) if (this[dt]) this.brotli = !0;
|
|
1678
|
+
else return this[p] = t, i?.(), !0;
|
|
1679
|
+
else try {
|
|
1680
|
+
new C(t.subarray(0, 512)), this.brotli = !1;
|
|
1681
|
+
} catch {
|
|
1682
|
+
this.brotli = !0;
|
|
1683
|
+
}
|
|
1684
|
+
if (this[y] === void 0 || this[y] === !1 && (this.brotli || o)) {
|
|
1685
|
+
let h = this[dt];
|
|
1686
|
+
this[dt] = !1, this[y] = this[y] === void 0 ? new ze({}) : o ? new Ye({}) : new We({}), this[y].on("data", (c) => this[$e](c)), this[y].on("error", (c) => this.abort(c)), this[y].on("end", () => {
|
|
1687
|
+
this[dt] = !0, this[$e]();
|
|
1688
|
+
}), this[Yt] = !0;
|
|
1689
|
+
let l = !!this[y][h ? "end" : "write"](t);
|
|
1690
|
+
return this[Yt] = !1, i?.(), l;
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
this[Yt] = !0, this[y] ? this[y].write(t) : this[$e](t), this[Yt] = !1;
|
|
1694
|
+
let n = this[it].length > 0 ? !1 : this[et] ? this[et].flowing : !0;
|
|
1695
|
+
return !n && this[it].length === 0 && this[et]?.once("drain", () => this.emit("drain")), i?.(), n;
|
|
1696
|
+
}
|
|
1697
|
+
[Ki](t) {
|
|
1698
|
+
t && !this[ut] && (this[p] = this[p] ? Buffer.concat([this[p], t]) : t);
|
|
1699
|
+
}
|
|
1700
|
+
[qe]() {
|
|
1701
|
+
if (this[dt] && !this[Zi] && !this[ut] && !this[ae]) {
|
|
1702
|
+
this[Zi] = !0;
|
|
1703
|
+
let t = this[Dt];
|
|
1704
|
+
if (t && t.blockRemain) {
|
|
1705
|
+
let e = this[p] ? this[p].length : 0;
|
|
1706
|
+
this.warn("TAR_BAD_ARCHIVE", `Truncated input (needed ${t.blockRemain} more bytes, only ${e} available)`, { entry: t }), this[p] && t.write(this[p]), t.end();
|
|
1707
|
+
}
|
|
1708
|
+
this[At](Qe);
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
[$e](t) {
|
|
1712
|
+
if (this[ae] && t) this[Ki](t);
|
|
1713
|
+
else if (!t && !this[p]) this[qe]();
|
|
1714
|
+
else if (t) {
|
|
1715
|
+
if (this[ae] = !0, this[p]) {
|
|
1716
|
+
this[Ki](t);
|
|
1717
|
+
let e = this[p];
|
|
1718
|
+
this[p] = void 0, this[Xe](e);
|
|
1719
|
+
} else this[Xe](t);
|
|
1720
|
+
for (; this[p] && this[p]?.length >= 512 && !this[ut] && !this[je];) {
|
|
1721
|
+
let e = this[p];
|
|
1722
|
+
this[p] = void 0, this[Xe](e);
|
|
1723
|
+
}
|
|
1724
|
+
this[ae] = !1;
|
|
1725
|
+
}
|
|
1726
|
+
(!this[p] || this[dt]) && this[qe]();
|
|
1727
|
+
}
|
|
1728
|
+
[Xe](t) {
|
|
1729
|
+
let e = 0, i = t.length;
|
|
1730
|
+
for (; e + 512 <= i && !this[ut] && !this[je];) switch (this[B]) {
|
|
1731
|
+
case "begin":
|
|
1732
|
+
case "header":
|
|
1733
|
+
this[Ys](t, e), e += 512;
|
|
1734
|
+
break;
|
|
1735
|
+
case "ignore":
|
|
1736
|
+
case "body":
|
|
1737
|
+
e += this[Yi](t, e);
|
|
1738
|
+
break;
|
|
1739
|
+
case "meta":
|
|
1740
|
+
e += this[Zs](t, e);
|
|
1741
|
+
break;
|
|
1742
|
+
default: throw new Error("invalid state: " + this[B]);
|
|
1743
|
+
}
|
|
1744
|
+
e < i && (this[p] = this[p] ? Buffer.concat([t.subarray(e), this[p]]) : t.subarray(e));
|
|
1745
|
+
}
|
|
1746
|
+
end(t, e, i) {
|
|
1747
|
+
return typeof t == "function" && (i = t, e = void 0, t = void 0), typeof e == "function" && (i = e, e = void 0), typeof t == "string" && (t = Buffer.from(t, e)), i && this.once("finish", i), this[ut] || (this[y] ? (t && this[y].write(t), this[y].end()) : (this[dt] = !0, (this.brotli === void 0 || this.zstd === void 0) && (t = t || Buffer.alloc(0)), t && this.write(t), this[qe]())), this;
|
|
1748
|
+
}
|
|
1749
|
+
};
|
|
1750
|
+
var mt = (s) => {
|
|
1751
|
+
let t = s.length - 1, e = -1;
|
|
1752
|
+
for (; t > -1 && s.charAt(t) === "/";) e = t, t--;
|
|
1753
|
+
return e === -1 ? s : s.slice(0, e);
|
|
1754
|
+
};
|
|
1755
|
+
var An = (s) => {
|
|
1756
|
+
let t = s.onReadEntry;
|
|
1757
|
+
s.onReadEntry = t ? (e) => {
|
|
1758
|
+
t(e), e.resume();
|
|
1759
|
+
} : (e) => e.resume();
|
|
1760
|
+
}, Xi = (s, t) => {
|
|
1761
|
+
let e = new Map(t.map((n) => [mt(n), !0])), i = s.filter, r = (n, o = "") => {
|
|
1762
|
+
let a = o || parse(n).root || ".", h;
|
|
1763
|
+
if (n === a) h = !1;
|
|
1764
|
+
else {
|
|
1765
|
+
let l = e.get(n);
|
|
1766
|
+
h = l !== void 0 ? l : r(dirname$1(n), a);
|
|
1767
|
+
}
|
|
1768
|
+
return e.set(n, h), h;
|
|
1769
|
+
};
|
|
1770
|
+
s.filter = i ? (n, o) => i(n, o) && r(mt(n)) : (n) => r(mt(n));
|
|
1771
|
+
}, In = (s) => {
|
|
1772
|
+
let t = new st(s), e = s.file, i;
|
|
1773
|
+
try {
|
|
1774
|
+
i = Kt.openSync(e, "r");
|
|
1775
|
+
let r = Kt.fstatSync(i), n = s.maxReadSize || 16 * 1024 * 1024;
|
|
1776
|
+
if (r.size < n) {
|
|
1777
|
+
let o = Buffer.allocUnsafe(r.size), a = Kt.readSync(i, o, 0, r.size, 0);
|
|
1778
|
+
t.end(a === o.byteLength ? o : o.subarray(0, a));
|
|
1779
|
+
} else {
|
|
1780
|
+
let o = 0, a = Buffer.allocUnsafe(n);
|
|
1781
|
+
for (; o < r.size;) {
|
|
1782
|
+
let h = Kt.readSync(i, a, 0, n, o);
|
|
1783
|
+
if (h === 0) break;
|
|
1784
|
+
o += h, t.write(a.subarray(0, h));
|
|
1785
|
+
}
|
|
1786
|
+
t.end();
|
|
1787
|
+
}
|
|
1788
|
+
} finally {
|
|
1789
|
+
if (typeof i == "number") try {
|
|
1790
|
+
Kt.closeSync(i);
|
|
1791
|
+
} catch {}
|
|
1792
|
+
}
|
|
1793
|
+
}, Fn = (s, t) => {
|
|
1794
|
+
let e = new st(s), i = s.maxReadSize || 16 * 1024 * 1024, r = s.file;
|
|
1795
|
+
return new Promise((o, a) => {
|
|
1796
|
+
e.on("error", a), e.on("end", o), Kt.stat(r, (h, l) => {
|
|
1797
|
+
if (h) a(h);
|
|
1798
|
+
else {
|
|
1799
|
+
let c = new _t(r, {
|
|
1800
|
+
readSize: i,
|
|
1801
|
+
size: l.size
|
|
1802
|
+
});
|
|
1803
|
+
c.on("error", a), c.pipe(e);
|
|
1804
|
+
}
|
|
1805
|
+
});
|
|
1806
|
+
});
|
|
1807
|
+
}, Ft = K(In, Fn, (s) => new st(s), (s) => new st(s), (s, t) => {
|
|
1808
|
+
t?.length && Xi(s, t), s.noResume || An(s);
|
|
1809
|
+
});
|
|
1810
|
+
var qi = (s, t, e) => (s &= 4095, e && (s = (s | 384) & -19), t && (s & 256 && (s |= 64), s & 32 && (s |= 8), s & 4 && (s |= 1)), s);
|
|
1811
|
+
var { isAbsolute: kn, parse: Vs } = win32, le = (s) => {
|
|
1812
|
+
let t = "", e = Vs(s);
|
|
1813
|
+
for (; kn(s) || e.root;) {
|
|
1814
|
+
let i = s.charAt(0) === "/" && s.slice(0, 4) !== "//?/" ? "/" : e.root;
|
|
1815
|
+
s = s.slice(i.length), t += i, e = Vs(s);
|
|
1816
|
+
}
|
|
1817
|
+
return [t, s];
|
|
1818
|
+
};
|
|
1819
|
+
var ti = [
|
|
1820
|
+
"|",
|
|
1821
|
+
"<",
|
|
1822
|
+
">",
|
|
1823
|
+
"?",
|
|
1824
|
+
":"
|
|
1825
|
+
], Qi = ti.map((s) => String.fromCodePoint(61440 + Number(s.codePointAt(0)))), vn = new Map(ti.map((s, t) => [s, Qi[t]])), Mn = new Map(Qi.map((s, t) => [s, ti[t]])), Ji = (s) => ti.reduce((t, e) => t.split(e).join(vn.get(e)), s), $s = (s) => Qi.reduce((t, e) => t.split(e).join(Mn.get(e)), s);
|
|
1826
|
+
var er = (s, t) => t ? (s = f(s).replace(/^\.(\/|$)/, ""), mt(t) + "/" + s) : f(s), Bn = 16 * 1024 * 1024, Qs = Symbol("process"), Js = Symbol("file"), js = Symbol("directory"), ts = Symbol("symlink"), tr = Symbol("hardlink"), ce = Symbol("header"), ei = Symbol("read"), es = Symbol("lstat"), ii = Symbol("onlstat"), is = Symbol("onread"), ss = Symbol("onreadlink"), rs = Symbol("openfile"), ns = Symbol("onopenfile"), pt = Symbol("close"), si = Symbol("mode"), os = Symbol("awaitDrain"), ji = Symbol("ondrain"), X = Symbol("prefix"), fe = class extends A {
|
|
1827
|
+
path;
|
|
1828
|
+
portable;
|
|
1829
|
+
myuid = process.getuid && process.getuid() || 0;
|
|
1830
|
+
myuser = process.env.USER || "";
|
|
1831
|
+
maxReadSize;
|
|
1832
|
+
linkCache;
|
|
1833
|
+
statCache;
|
|
1834
|
+
preservePaths;
|
|
1835
|
+
cwd;
|
|
1836
|
+
strict;
|
|
1837
|
+
mtime;
|
|
1838
|
+
noPax;
|
|
1839
|
+
noMtime;
|
|
1840
|
+
prefix;
|
|
1841
|
+
fd;
|
|
1842
|
+
blockLen = 0;
|
|
1843
|
+
blockRemain = 0;
|
|
1844
|
+
buf;
|
|
1845
|
+
pos = 0;
|
|
1846
|
+
remain = 0;
|
|
1847
|
+
length = 0;
|
|
1848
|
+
offset = 0;
|
|
1849
|
+
win32;
|
|
1850
|
+
absolute;
|
|
1851
|
+
header;
|
|
1852
|
+
type;
|
|
1853
|
+
linkpath;
|
|
1854
|
+
stat;
|
|
1855
|
+
onWriteEntry;
|
|
1856
|
+
#t = !1;
|
|
1857
|
+
constructor(t, e = {}) {
|
|
1858
|
+
let i = se(e);
|
|
1859
|
+
super(), this.path = f(t), this.portable = !!i.portable, this.maxReadSize = i.maxReadSize || Bn, this.linkCache = i.linkCache || /* @__PURE__ */ new Map(), this.statCache = i.statCache || /* @__PURE__ */ new Map(), this.preservePaths = !!i.preservePaths, this.cwd = f(i.cwd || process.cwd()), this.strict = !!i.strict, this.noPax = !!i.noPax, this.noMtime = !!i.noMtime, this.mtime = i.mtime, this.prefix = i.prefix ? f(i.prefix) : void 0, this.onWriteEntry = i.onWriteEntry, typeof i.onwarn == "function" && this.on("warn", i.onwarn);
|
|
1860
|
+
let r = !1;
|
|
1861
|
+
if (!this.preservePaths) {
|
|
1862
|
+
let [o, a] = le(this.path);
|
|
1863
|
+
o && typeof a == "string" && (this.path = a, r = o);
|
|
1864
|
+
}
|
|
1865
|
+
this.win32 = !!i.win32 || process.platform === "win32", this.win32 && (this.path = $s(this.path.replaceAll(/\\/g, "/")), t = t.replaceAll(/\\/g, "/")), this.absolute = f(i.absolute || qs.resolve(this.cwd, t)), this.path === "" && (this.path = "./"), r && this.warn("TAR_ENTRY_INFO", `stripping ${r} from absolute path`, {
|
|
1866
|
+
entry: this,
|
|
1867
|
+
path: r + this.path
|
|
1868
|
+
});
|
|
1869
|
+
let n = this.statCache.get(this.absolute);
|
|
1870
|
+
n ? this[ii](n) : this[es]();
|
|
1871
|
+
}
|
|
1872
|
+
warn(t, e, i = {}) {
|
|
1873
|
+
return Nt(this, t, e, i);
|
|
1874
|
+
}
|
|
1875
|
+
emit(t, ...e) {
|
|
1876
|
+
return t === "error" && (this.#t = !0), super.emit(t, ...e);
|
|
1877
|
+
}
|
|
1878
|
+
[es]() {
|
|
1879
|
+
I.lstat(this.absolute, (t, e) => {
|
|
1880
|
+
if (t) return this.emit("error", t);
|
|
1881
|
+
this[ii](e);
|
|
1882
|
+
});
|
|
1883
|
+
}
|
|
1884
|
+
[ii](t) {
|
|
1885
|
+
this.statCache.set(this.absolute, t), this.stat = t, t.isFile() || (t.size = 0), this.type = Pn(t), this.emit("stat", t), this[Qs]();
|
|
1886
|
+
}
|
|
1887
|
+
[Qs]() {
|
|
1888
|
+
switch (this.type) {
|
|
1889
|
+
case "File": return this[Js]();
|
|
1890
|
+
case "Directory": return this[js]();
|
|
1891
|
+
case "SymbolicLink": return this[ts]();
|
|
1892
|
+
default: return this.end();
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
[si](t) {
|
|
1896
|
+
return qi(t, this.type === "Directory", this.portable);
|
|
1897
|
+
}
|
|
1898
|
+
[X](t) {
|
|
1899
|
+
return er(t, this.prefix);
|
|
1900
|
+
}
|
|
1901
|
+
[ce]() {
|
|
1902
|
+
if (!this.stat) throw new Error("cannot write header before stat");
|
|
1903
|
+
this.type === "Directory" && this.portable && (this.noMtime = !0), this.onWriteEntry?.(this), this.header = new C({
|
|
1904
|
+
path: this[X](this.path),
|
|
1905
|
+
linkpath: this.type === "Link" && this.linkpath !== void 0 ? this[X](this.linkpath) : this.linkpath,
|
|
1906
|
+
mode: this[si](this.stat.mode),
|
|
1907
|
+
uid: this.portable ? void 0 : this.stat.uid,
|
|
1908
|
+
gid: this.portable ? void 0 : this.stat.gid,
|
|
1909
|
+
size: this.stat.size,
|
|
1910
|
+
mtime: this.noMtime ? void 0 : this.mtime || this.stat.mtime,
|
|
1911
|
+
type: this.type === "Unsupported" ? void 0 : this.type,
|
|
1912
|
+
uname: this.portable ? void 0 : this.stat.uid === this.myuid ? this.myuser : "",
|
|
1913
|
+
atime: this.portable ? void 0 : this.stat.atime,
|
|
1914
|
+
ctime: this.portable ? void 0 : this.stat.ctime
|
|
1915
|
+
}), this.header.encode() && !this.noPax && super.write(new ct({
|
|
1916
|
+
atime: this.portable ? void 0 : this.header.atime,
|
|
1917
|
+
ctime: this.portable ? void 0 : this.header.ctime,
|
|
1918
|
+
gid: this.portable ? void 0 : this.header.gid,
|
|
1919
|
+
mtime: this.noMtime ? void 0 : this.mtime || this.header.mtime,
|
|
1920
|
+
path: this[X](this.path),
|
|
1921
|
+
linkpath: this.type === "Link" && this.linkpath !== void 0 ? this[X](this.linkpath) : this.linkpath,
|
|
1922
|
+
size: this.header.size,
|
|
1923
|
+
uid: this.portable ? void 0 : this.header.uid,
|
|
1924
|
+
uname: this.portable ? void 0 : this.header.uname,
|
|
1925
|
+
dev: this.portable ? void 0 : this.stat.dev,
|
|
1926
|
+
ino: this.portable ? void 0 : this.stat.ino,
|
|
1927
|
+
nlink: this.portable ? void 0 : this.stat.nlink
|
|
1928
|
+
}).encode());
|
|
1929
|
+
let t = this.header?.block;
|
|
1930
|
+
if (!t) throw new Error("failed to encode header");
|
|
1931
|
+
super.write(t);
|
|
1932
|
+
}
|
|
1933
|
+
[js]() {
|
|
1934
|
+
if (!this.stat) throw new Error("cannot create directory entry without stat");
|
|
1935
|
+
this.path.slice(-1) !== "/" && (this.path += "/"), this.stat.size = 0, this[ce](), this.end();
|
|
1936
|
+
}
|
|
1937
|
+
[ts]() {
|
|
1938
|
+
I.readlink(this.absolute, (t, e) => {
|
|
1939
|
+
if (t) return this.emit("error", t);
|
|
1940
|
+
this[ss](e);
|
|
1941
|
+
});
|
|
1942
|
+
}
|
|
1943
|
+
[ss](t) {
|
|
1944
|
+
this.linkpath = f(t), this[ce](), this.end();
|
|
1945
|
+
}
|
|
1946
|
+
[tr](t) {
|
|
1947
|
+
if (!this.stat) throw new Error("cannot create link entry without stat");
|
|
1948
|
+
this.type = "Link", this.linkpath = f(qs.relative(this.cwd, t)), this.stat.size = 0, this[ce](), this.end();
|
|
1949
|
+
}
|
|
1950
|
+
[Js]() {
|
|
1951
|
+
if (!this.stat) throw new Error("cannot create file entry without stat");
|
|
1952
|
+
if (this.stat.nlink > 1) {
|
|
1953
|
+
let t = `${this.stat.dev}:${this.stat.ino}`, e = this.linkCache.get(t);
|
|
1954
|
+
if (e?.indexOf(this.cwd) === 0) return this[tr](e);
|
|
1955
|
+
this.linkCache.set(t, this.absolute);
|
|
1956
|
+
}
|
|
1957
|
+
if (this[ce](), this.stat.size === 0) return this.end();
|
|
1958
|
+
this[rs]();
|
|
1959
|
+
}
|
|
1960
|
+
[rs]() {
|
|
1961
|
+
I.open(this.absolute, "r", (t, e) => {
|
|
1962
|
+
if (t) return this.emit("error", t);
|
|
1963
|
+
this[ns](e);
|
|
1964
|
+
});
|
|
1965
|
+
}
|
|
1966
|
+
[ns](t) {
|
|
1967
|
+
if (this.fd = t, this.#t) return this[pt]();
|
|
1968
|
+
if (!this.stat) throw new Error("should stat before calling onopenfile");
|
|
1969
|
+
this.blockLen = 512 * Math.ceil(this.stat.size / 512), this.blockRemain = this.blockLen;
|
|
1970
|
+
let e = Math.min(this.blockLen, this.maxReadSize);
|
|
1971
|
+
this.buf = Buffer.allocUnsafe(e), this.offset = 0, this.pos = 0, this.remain = this.stat.size, this.length = this.buf.length, this[ei]();
|
|
1972
|
+
}
|
|
1973
|
+
[ei]() {
|
|
1974
|
+
let { fd: t, buf: e, offset: i, length: r, pos: n } = this;
|
|
1975
|
+
if (t === void 0 || e === void 0) throw new Error("cannot read file without first opening");
|
|
1976
|
+
I.read(t, e, i, r, n, (o, a) => {
|
|
1977
|
+
if (o) return this[pt](() => this.emit("error", o));
|
|
1978
|
+
this[is](a);
|
|
1979
|
+
});
|
|
1980
|
+
}
|
|
1981
|
+
[pt](t = () => {}) {
|
|
1982
|
+
this.fd !== void 0 && I.close(this.fd, t);
|
|
1983
|
+
}
|
|
1984
|
+
[is](t) {
|
|
1985
|
+
if (t <= 0 && this.remain > 0) {
|
|
1986
|
+
let r = Object.assign(/* @__PURE__ */ new Error("encountered unexpected EOF"), {
|
|
1987
|
+
path: this.absolute,
|
|
1988
|
+
syscall: "read",
|
|
1989
|
+
code: "EOF"
|
|
1990
|
+
});
|
|
1991
|
+
return this[pt](() => this.emit("error", r));
|
|
1992
|
+
}
|
|
1993
|
+
if (t > this.remain) {
|
|
1994
|
+
let r = Object.assign(/* @__PURE__ */ new Error("did not encounter expected EOF"), {
|
|
1995
|
+
path: this.absolute,
|
|
1996
|
+
syscall: "read",
|
|
1997
|
+
code: "EOF"
|
|
1998
|
+
});
|
|
1999
|
+
return this[pt](() => this.emit("error", r));
|
|
2000
|
+
}
|
|
2001
|
+
if (!this.buf) throw new Error("should have created buffer prior to reading");
|
|
2002
|
+
if (t === this.remain) for (let r = t; r < this.length && t < this.blockRemain; r++) this.buf[r + this.offset] = 0, t++, this.remain++;
|
|
2003
|
+
let e = this.offset === 0 && t === this.buf.length ? this.buf : this.buf.subarray(this.offset, this.offset + t);
|
|
2004
|
+
this.write(e) ? this[ji]() : this[os](() => this[ji]());
|
|
2005
|
+
}
|
|
2006
|
+
[os](t) {
|
|
2007
|
+
this.once("drain", t);
|
|
2008
|
+
}
|
|
2009
|
+
write(t, e, i) {
|
|
2010
|
+
if (typeof e == "function" && (i = e, e = void 0), typeof t == "string" && (t = Buffer.from(t, typeof e == "string" ? e : "utf8")), this.blockRemain < t.length) {
|
|
2011
|
+
let r = Object.assign(/* @__PURE__ */ new Error("writing more data than expected"), { path: this.absolute });
|
|
2012
|
+
return this.emit("error", r);
|
|
2013
|
+
}
|
|
2014
|
+
return this.remain -= t.length, this.blockRemain -= t.length, this.pos += t.length, this.offset += t.length, super.write(t, null, i);
|
|
2015
|
+
}
|
|
2016
|
+
[ji]() {
|
|
2017
|
+
if (!this.remain) return this.blockRemain && super.write(Buffer.alloc(this.blockRemain)), this[pt]((t) => t ? this.emit("error", t) : this.end());
|
|
2018
|
+
if (!this.buf) throw new Error("buffer lost somehow in ONDRAIN");
|
|
2019
|
+
this.offset >= this.length && (this.buf = Buffer.allocUnsafe(Math.min(this.blockRemain, this.buf.length)), this.offset = 0), this.length = this.buf.length - this.offset, this[ei]();
|
|
2020
|
+
}
|
|
2021
|
+
}, ri = class extends fe {
|
|
2022
|
+
sync = !0;
|
|
2023
|
+
[es]() {
|
|
2024
|
+
this[ii](I.lstatSync(this.absolute));
|
|
2025
|
+
}
|
|
2026
|
+
[ts]() {
|
|
2027
|
+
this[ss](I.readlinkSync(this.absolute));
|
|
2028
|
+
}
|
|
2029
|
+
[rs]() {
|
|
2030
|
+
this[ns](I.openSync(this.absolute, "r"));
|
|
2031
|
+
}
|
|
2032
|
+
[ei]() {
|
|
2033
|
+
let t = !0;
|
|
2034
|
+
try {
|
|
2035
|
+
let { fd: e, buf: i, offset: r, length: n, pos: o } = this;
|
|
2036
|
+
if (e === void 0 || i === void 0) throw new Error("fd and buf must be set in READ method");
|
|
2037
|
+
let a = I.readSync(e, i, r, n, o);
|
|
2038
|
+
this[is](a), t = !1;
|
|
2039
|
+
} finally {
|
|
2040
|
+
if (t) try {
|
|
2041
|
+
this[pt](() => {});
|
|
2042
|
+
} catch {}
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
[os](t) {
|
|
2046
|
+
t();
|
|
2047
|
+
}
|
|
2048
|
+
[pt](t = () => {}) {
|
|
2049
|
+
this.fd !== void 0 && I.closeSync(this.fd), t();
|
|
2050
|
+
}
|
|
2051
|
+
}, ni = class extends A {
|
|
2052
|
+
blockLen = 0;
|
|
2053
|
+
blockRemain = 0;
|
|
2054
|
+
buf = 0;
|
|
2055
|
+
pos = 0;
|
|
2056
|
+
remain = 0;
|
|
2057
|
+
length = 0;
|
|
2058
|
+
preservePaths;
|
|
2059
|
+
portable;
|
|
2060
|
+
strict;
|
|
2061
|
+
noPax;
|
|
2062
|
+
noMtime;
|
|
2063
|
+
readEntry;
|
|
2064
|
+
type;
|
|
2065
|
+
prefix;
|
|
2066
|
+
path;
|
|
2067
|
+
mode;
|
|
2068
|
+
uid;
|
|
2069
|
+
gid;
|
|
2070
|
+
uname;
|
|
2071
|
+
gname;
|
|
2072
|
+
header;
|
|
2073
|
+
mtime;
|
|
2074
|
+
atime;
|
|
2075
|
+
ctime;
|
|
2076
|
+
linkpath;
|
|
2077
|
+
size;
|
|
2078
|
+
onWriteEntry;
|
|
2079
|
+
warn(t, e, i = {}) {
|
|
2080
|
+
return Nt(this, t, e, i);
|
|
2081
|
+
}
|
|
2082
|
+
constructor(t, e = {}) {
|
|
2083
|
+
let i = se(e);
|
|
2084
|
+
super(), this.preservePaths = !!i.preservePaths, this.portable = !!i.portable, this.strict = !!i.strict, this.noPax = !!i.noPax, this.noMtime = !!i.noMtime, this.onWriteEntry = i.onWriteEntry, this.readEntry = t;
|
|
2085
|
+
let { type: r } = t;
|
|
2086
|
+
if (r === "Unsupported") throw new Error("writing entry that should be ignored");
|
|
2087
|
+
this.type = r, this.type === "Directory" && this.portable && (this.noMtime = !0), this.prefix = i.prefix, this.path = f(t.path), this.mode = t.mode !== void 0 ? this[si](t.mode) : void 0, this.uid = this.portable ? void 0 : t.uid, this.gid = this.portable ? void 0 : t.gid, this.uname = this.portable ? void 0 : t.uname, this.gname = this.portable ? void 0 : t.gname, this.size = t.size, this.mtime = this.noMtime ? void 0 : i.mtime || t.mtime, this.atime = this.portable ? void 0 : t.atime, this.ctime = this.portable ? void 0 : t.ctime, this.linkpath = t.linkpath !== void 0 ? f(t.linkpath) : void 0, typeof i.onwarn == "function" && this.on("warn", i.onwarn);
|
|
2088
|
+
let n = !1;
|
|
2089
|
+
if (!this.preservePaths) {
|
|
2090
|
+
let [a, h] = le(this.path);
|
|
2091
|
+
a && typeof h == "string" && (this.path = h, n = a);
|
|
2092
|
+
}
|
|
2093
|
+
this.remain = t.size, this.blockRemain = t.startBlockSize, this.onWriteEntry?.(this), this.header = new C({
|
|
2094
|
+
path: this[X](this.path),
|
|
2095
|
+
linkpath: this.type === "Link" && this.linkpath !== void 0 ? this[X](this.linkpath) : this.linkpath,
|
|
2096
|
+
mode: this.mode,
|
|
2097
|
+
uid: this.portable ? void 0 : this.uid,
|
|
2098
|
+
gid: this.portable ? void 0 : this.gid,
|
|
2099
|
+
size: this.size,
|
|
2100
|
+
mtime: this.noMtime ? void 0 : this.mtime,
|
|
2101
|
+
type: this.type,
|
|
2102
|
+
uname: this.portable ? void 0 : this.uname,
|
|
2103
|
+
atime: this.portable ? void 0 : this.atime,
|
|
2104
|
+
ctime: this.portable ? void 0 : this.ctime
|
|
2105
|
+
}), n && this.warn("TAR_ENTRY_INFO", `stripping ${n} from absolute path`, {
|
|
2106
|
+
entry: this,
|
|
2107
|
+
path: n + this.path
|
|
2108
|
+
}), this.header.encode() && !this.noPax && super.write(new ct({
|
|
2109
|
+
atime: this.portable ? void 0 : this.atime,
|
|
2110
|
+
ctime: this.portable ? void 0 : this.ctime,
|
|
2111
|
+
gid: this.portable ? void 0 : this.gid,
|
|
2112
|
+
mtime: this.noMtime ? void 0 : this.mtime,
|
|
2113
|
+
path: this[X](this.path),
|
|
2114
|
+
linkpath: this.type === "Link" && this.linkpath !== void 0 ? this[X](this.linkpath) : this.linkpath,
|
|
2115
|
+
size: this.size,
|
|
2116
|
+
uid: this.portable ? void 0 : this.uid,
|
|
2117
|
+
uname: this.portable ? void 0 : this.uname,
|
|
2118
|
+
dev: this.portable ? void 0 : this.readEntry.dev,
|
|
2119
|
+
ino: this.portable ? void 0 : this.readEntry.ino,
|
|
2120
|
+
nlink: this.portable ? void 0 : this.readEntry.nlink
|
|
2121
|
+
}).encode());
|
|
2122
|
+
let o = this.header?.block;
|
|
2123
|
+
if (!o) throw new Error("failed to encode header");
|
|
2124
|
+
super.write(o), t.pipe(this);
|
|
2125
|
+
}
|
|
2126
|
+
[X](t) {
|
|
2127
|
+
return er(t, this.prefix);
|
|
2128
|
+
}
|
|
2129
|
+
[si](t) {
|
|
2130
|
+
return qi(t, this.type === "Directory", this.portable);
|
|
2131
|
+
}
|
|
2132
|
+
write(t, e, i) {
|
|
2133
|
+
typeof e == "function" && (i = e, e = void 0), typeof t == "string" && (t = Buffer.from(t, typeof e == "string" ? e : "utf8"));
|
|
2134
|
+
let r = t.length;
|
|
2135
|
+
if (r > this.blockRemain) throw new Error("writing more to entry than is appropriate");
|
|
2136
|
+
return this.blockRemain -= r, super.write(t, i);
|
|
2137
|
+
}
|
|
2138
|
+
end(t, e, i) {
|
|
2139
|
+
return this.blockRemain && super.write(Buffer.alloc(this.blockRemain)), typeof t == "function" && (i = t, e = void 0, t = void 0), typeof e == "function" && (i = e, e = void 0), typeof t == "string" && (t = Buffer.from(t, e ?? "utf8")), i && this.once("finish", i), t ? super.end(t, i) : super.end(i), this;
|
|
2140
|
+
}
|
|
2141
|
+
}, Pn = (s) => s.isFile() ? "File" : s.isDirectory() ? "Directory" : s.isSymbolicLink() ? "SymbolicLink" : "Unsupported";
|
|
2142
|
+
var oi = class s {
|
|
2143
|
+
tail;
|
|
2144
|
+
head;
|
|
2145
|
+
length = 0;
|
|
2146
|
+
static create(t = []) {
|
|
2147
|
+
return new s(t);
|
|
2148
|
+
}
|
|
2149
|
+
constructor(t = []) {
|
|
2150
|
+
for (let e of t) this.push(e);
|
|
2151
|
+
}
|
|
2152
|
+
*[Symbol.iterator]() {
|
|
2153
|
+
for (let t = this.head; t; t = t.next) yield t.value;
|
|
2154
|
+
}
|
|
2155
|
+
removeNode(t) {
|
|
2156
|
+
if (t.list !== this) throw new Error("removing node which does not belong to this list");
|
|
2157
|
+
let e = t.next, i = t.prev;
|
|
2158
|
+
return e && (e.prev = i), i && (i.next = e), t === this.head && (this.head = e), t === this.tail && (this.tail = i), this.length--, t.next = void 0, t.prev = void 0, t.list = void 0, e;
|
|
2159
|
+
}
|
|
2160
|
+
unshiftNode(t) {
|
|
2161
|
+
if (t === this.head) return;
|
|
2162
|
+
t.list && t.list.removeNode(t);
|
|
2163
|
+
let e = this.head;
|
|
2164
|
+
t.list = this, t.next = e, e && (e.prev = t), this.head = t, this.tail || (this.tail = t), this.length++;
|
|
2165
|
+
}
|
|
2166
|
+
pushNode(t) {
|
|
2167
|
+
if (t === this.tail) return;
|
|
2168
|
+
t.list && t.list.removeNode(t);
|
|
2169
|
+
let e = this.tail;
|
|
2170
|
+
t.list = this, t.prev = e, e && (e.next = t), this.tail = t, this.head || (this.head = t), this.length++;
|
|
2171
|
+
}
|
|
2172
|
+
push(...t) {
|
|
2173
|
+
for (let e = 0, i = t.length; e < i; e++) Un(this, t[e]);
|
|
2174
|
+
return this.length;
|
|
2175
|
+
}
|
|
2176
|
+
unshift(...t) {
|
|
2177
|
+
for (var e = 0, i = t.length; e < i; e++) Hn(this, t[e]);
|
|
2178
|
+
return this.length;
|
|
2179
|
+
}
|
|
2180
|
+
pop() {
|
|
2181
|
+
if (!this.tail) return;
|
|
2182
|
+
let t = this.tail.value, e = this.tail;
|
|
2183
|
+
return this.tail = this.tail.prev, this.tail ? this.tail.next = void 0 : this.head = void 0, e.list = void 0, this.length--, t;
|
|
2184
|
+
}
|
|
2185
|
+
shift() {
|
|
2186
|
+
if (!this.head) return;
|
|
2187
|
+
let t = this.head.value, e = this.head;
|
|
2188
|
+
return this.head = this.head.next, this.head ? this.head.prev = void 0 : this.tail = void 0, e.list = void 0, this.length--, t;
|
|
2189
|
+
}
|
|
2190
|
+
forEach(t, e) {
|
|
2191
|
+
e = e || this;
|
|
2192
|
+
for (let i = this.head, r = 0; i; r++) t.call(e, i.value, r, this), i = i.next;
|
|
2193
|
+
}
|
|
2194
|
+
forEachReverse(t, e) {
|
|
2195
|
+
e = e || this;
|
|
2196
|
+
for (let i = this.tail, r = this.length - 1; i; r--) t.call(e, i.value, r, this), i = i.prev;
|
|
2197
|
+
}
|
|
2198
|
+
get(t) {
|
|
2199
|
+
let e = 0, i = this.head;
|
|
2200
|
+
for (; i && e < t; e++) i = i.next;
|
|
2201
|
+
if (e === t && i) return i.value;
|
|
2202
|
+
}
|
|
2203
|
+
getReverse(t) {
|
|
2204
|
+
let e = 0, i = this.tail;
|
|
2205
|
+
for (; i && e < t; e++) i = i.prev;
|
|
2206
|
+
if (e === t && i) return i.value;
|
|
2207
|
+
}
|
|
2208
|
+
map(t, e) {
|
|
2209
|
+
e = e || this;
|
|
2210
|
+
let i = new s();
|
|
2211
|
+
for (let r = this.head; r;) i.push(t.call(e, r.value, this)), r = r.next;
|
|
2212
|
+
return i;
|
|
2213
|
+
}
|
|
2214
|
+
mapReverse(t, e) {
|
|
2215
|
+
e = e || this;
|
|
2216
|
+
var i = new s();
|
|
2217
|
+
for (let r = this.tail; r;) i.push(t.call(e, r.value, this)), r = r.prev;
|
|
2218
|
+
return i;
|
|
2219
|
+
}
|
|
2220
|
+
reduce(t, e) {
|
|
2221
|
+
let i, r = this.head;
|
|
2222
|
+
if (arguments.length > 1) i = e;
|
|
2223
|
+
else if (this.head) r = this.head.next, i = this.head.value;
|
|
2224
|
+
else throw new TypeError("Reduce of empty list with no initial value");
|
|
2225
|
+
for (var n = 0; r; n++) i = t(i, r.value, n), r = r.next;
|
|
2226
|
+
return i;
|
|
2227
|
+
}
|
|
2228
|
+
reduceReverse(t, e) {
|
|
2229
|
+
let i, r = this.tail;
|
|
2230
|
+
if (arguments.length > 1) i = e;
|
|
2231
|
+
else if (this.tail) r = this.tail.prev, i = this.tail.value;
|
|
2232
|
+
else throw new TypeError("Reduce of empty list with no initial value");
|
|
2233
|
+
for (let n = this.length - 1; r; n--) i = t(i, r.value, n), r = r.prev;
|
|
2234
|
+
return i;
|
|
2235
|
+
}
|
|
2236
|
+
toArray() {
|
|
2237
|
+
let t = new Array(this.length);
|
|
2238
|
+
for (let e = 0, i = this.head; i; e++) t[e] = i.value, i = i.next;
|
|
2239
|
+
return t;
|
|
2240
|
+
}
|
|
2241
|
+
toArrayReverse() {
|
|
2242
|
+
let t = new Array(this.length);
|
|
2243
|
+
for (let e = 0, i = this.tail; i; e++) t[e] = i.value, i = i.prev;
|
|
2244
|
+
return t;
|
|
2245
|
+
}
|
|
2246
|
+
slice(t = 0, e = this.length) {
|
|
2247
|
+
e < 0 && (e += this.length), t < 0 && (t += this.length);
|
|
2248
|
+
let i = new s();
|
|
2249
|
+
if (e < t || e < 0) return i;
|
|
2250
|
+
t < 0 && (t = 0), e > this.length && (e = this.length);
|
|
2251
|
+
let r = this.head, n = 0;
|
|
2252
|
+
for (n = 0; r && n < t; n++) r = r.next;
|
|
2253
|
+
for (; r && n < e; n++, r = r.next) i.push(r.value);
|
|
2254
|
+
return i;
|
|
2255
|
+
}
|
|
2256
|
+
sliceReverse(t = 0, e = this.length) {
|
|
2257
|
+
e < 0 && (e += this.length), t < 0 && (t += this.length);
|
|
2258
|
+
let i = new s();
|
|
2259
|
+
if (e < t || e < 0) return i;
|
|
2260
|
+
t < 0 && (t = 0), e > this.length && (e = this.length);
|
|
2261
|
+
let r = this.length, n = this.tail;
|
|
2262
|
+
for (; n && r > e; r--) n = n.prev;
|
|
2263
|
+
for (; n && r > t; r--, n = n.prev) i.push(n.value);
|
|
2264
|
+
return i;
|
|
2265
|
+
}
|
|
2266
|
+
splice(t, e = 0, ...i) {
|
|
2267
|
+
t > this.length && (t = this.length - 1), t < 0 && (t = this.length + t);
|
|
2268
|
+
let r = this.head;
|
|
2269
|
+
for (let o = 0; r && o < t; o++) r = r.next;
|
|
2270
|
+
let n = [];
|
|
2271
|
+
for (let o = 0; r && o < e; o++) n.push(r.value), r = this.removeNode(r);
|
|
2272
|
+
r ? r !== this.tail && (r = r.prev) : r = this.tail;
|
|
2273
|
+
for (let o of i) r = zn(this, r, o);
|
|
2274
|
+
return n;
|
|
2275
|
+
}
|
|
2276
|
+
reverse() {
|
|
2277
|
+
let t = this.head, e = this.tail;
|
|
2278
|
+
for (let i = t; i; i = i.prev) {
|
|
2279
|
+
let r = i.prev;
|
|
2280
|
+
i.prev = i.next, i.next = r;
|
|
2281
|
+
}
|
|
2282
|
+
return this.head = e, this.tail = t, this;
|
|
2283
|
+
}
|
|
2284
|
+
};
|
|
2285
|
+
function zn(s, t, e) {
|
|
2286
|
+
let n = new de(e, t, t ? t.next : s.head, s);
|
|
2287
|
+
return n.next === void 0 && (s.tail = n), n.prev === void 0 && (s.head = n), s.length++, n;
|
|
2288
|
+
}
|
|
2289
|
+
function Un(s, t) {
|
|
2290
|
+
s.tail = new de(t, s.tail, void 0, s), s.head || (s.head = s.tail), s.length++;
|
|
2291
|
+
}
|
|
2292
|
+
function Hn(s, t) {
|
|
2293
|
+
s.head = new de(t, void 0, s.head, s), s.tail || (s.tail = s.head), s.length++;
|
|
2294
|
+
}
|
|
2295
|
+
var de = class {
|
|
2296
|
+
list;
|
|
2297
|
+
next;
|
|
2298
|
+
prev;
|
|
2299
|
+
value;
|
|
2300
|
+
constructor(t, e, i, r) {
|
|
2301
|
+
this.list = r, this.value = t, e ? (e.next = this, this.prev = e) : this.prev = void 0, i ? (i.prev = this, this.next = i) : this.next = void 0;
|
|
2302
|
+
}
|
|
2303
|
+
};
|
|
2304
|
+
var mi = class {
|
|
2305
|
+
path;
|
|
2306
|
+
absolute;
|
|
2307
|
+
entry;
|
|
2308
|
+
stat;
|
|
2309
|
+
readdir;
|
|
2310
|
+
pending = !1;
|
|
2311
|
+
pendingLink = !1;
|
|
2312
|
+
ignore = !1;
|
|
2313
|
+
piped = !1;
|
|
2314
|
+
constructor(t, e) {
|
|
2315
|
+
this.path = t || "./", this.absolute = e;
|
|
2316
|
+
}
|
|
2317
|
+
}, ir = Buffer.alloc(1024), ai = Symbol("onStat"), ue = Symbol("ended"), W = Symbol("queue"), me = Symbol("pendingLinks"), Et = Symbol("current"), Ct = Symbol("process"), pe = Symbol("processing"), hi = Symbol("processJob"), G = Symbol("jobs"), hs = Symbol("jobDone"), li = Symbol("addFSEntry"), sr = Symbol("addTarEntry"), cs = Symbol("stat"), fs = Symbol("readdir"), ci = Symbol("onreaddir"), fi = Symbol("pipe"), rr = Symbol("entry"), as = Symbol("entryOpt"), di = Symbol("writeEntryClass"), or = Symbol("write"), ls = Symbol("ondrain"), wt = class extends A {
|
|
2318
|
+
sync = !1;
|
|
2319
|
+
opt;
|
|
2320
|
+
cwd;
|
|
2321
|
+
maxReadSize;
|
|
2322
|
+
preservePaths;
|
|
2323
|
+
strict;
|
|
2324
|
+
noPax;
|
|
2325
|
+
prefix;
|
|
2326
|
+
linkCache;
|
|
2327
|
+
statCache;
|
|
2328
|
+
file;
|
|
2329
|
+
portable;
|
|
2330
|
+
zip;
|
|
2331
|
+
readdirCache;
|
|
2332
|
+
noDirRecurse;
|
|
2333
|
+
follow;
|
|
2334
|
+
noMtime;
|
|
2335
|
+
mtime;
|
|
2336
|
+
filter;
|
|
2337
|
+
jobs;
|
|
2338
|
+
[di];
|
|
2339
|
+
onWriteEntry;
|
|
2340
|
+
[W];
|
|
2341
|
+
[me] = /* @__PURE__ */ new Map();
|
|
2342
|
+
[G] = 0;
|
|
2343
|
+
[pe] = !1;
|
|
2344
|
+
[ue] = !1;
|
|
2345
|
+
constructor(t = {}) {
|
|
2346
|
+
if (super(), this.opt = t, this.file = t.file || "", this.cwd = t.cwd || process.cwd(), this.maxReadSize = t.maxReadSize, this.preservePaths = !!t.preservePaths, this.strict = !!t.strict, this.noPax = !!t.noPax, this.prefix = f(t.prefix || ""), this.linkCache = t.linkCache || /* @__PURE__ */ new Map(), this.statCache = t.statCache || /* @__PURE__ */ new Map(), this.readdirCache = t.readdirCache || /* @__PURE__ */ new Map(), this.onWriteEntry = t.onWriteEntry, this[di] = fe, typeof t.onwarn == "function" && this.on("warn", t.onwarn), this.portable = !!t.portable, t.gzip || t.brotli || t.zstd) {
|
|
2347
|
+
if ((t.gzip ? 1 : 0) + (t.brotli ? 1 : 0) + (t.zstd ? 1 : 0) > 1) throw new TypeError("gzip, brotli, zstd are mutually exclusive");
|
|
2348
|
+
if (t.gzip && (typeof t.gzip != "object" && (t.gzip = {}), this.portable && (t.gzip.portable = !0), this.zip = new Pe(t.gzip)), t.brotli && (typeof t.brotli != "object" && (t.brotli = {}), this.zip = new He(t.brotli)), t.zstd && (typeof t.zstd != "object" && (t.zstd = {}), this.zip = new Ze(t.zstd)), !this.zip) throw new Error("impossible");
|
|
2349
|
+
let e = this.zip;
|
|
2350
|
+
e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[ls]()), this.on("resume", () => e.resume());
|
|
2351
|
+
} else this.on("drain", this[ls]);
|
|
2352
|
+
this.noDirRecurse = !!t.noDirRecurse, this.follow = !!t.follow, this.noMtime = !!t.noMtime, t.mtime && (this.mtime = t.mtime), this.filter = typeof t.filter == "function" ? t.filter : () => !0, this[W] = new oi(), this[G] = 0, this.jobs = Number(t.jobs) || 4, this[pe] = !1, this[ue] = !1;
|
|
2353
|
+
}
|
|
2354
|
+
[or](t) {
|
|
2355
|
+
return super.write(t);
|
|
2356
|
+
}
|
|
2357
|
+
add(t) {
|
|
2358
|
+
return this.write(t), this;
|
|
2359
|
+
}
|
|
2360
|
+
end(t, e, i) {
|
|
2361
|
+
return typeof t == "function" && (i = t, t = void 0), typeof e == "function" && (i = e, e = void 0), t && this.add(t), this[ue] = !0, this[Ct](), i && i(), this;
|
|
2362
|
+
}
|
|
2363
|
+
write(t) {
|
|
2364
|
+
if (this[ue]) throw new Error("write after end");
|
|
2365
|
+
return typeof t == "string" ? this[li](t) : this[sr](t), this.flowing;
|
|
2366
|
+
}
|
|
2367
|
+
[sr](t) {
|
|
2368
|
+
let e = f(qs.resolve(this.cwd, t.path));
|
|
2369
|
+
if (!this.filter(t.path, t)) t.resume();
|
|
2370
|
+
else {
|
|
2371
|
+
let i = new mi(t.path, e);
|
|
2372
|
+
i.entry = new ni(t, this[as](i)), i.entry.on("end", () => this[hs](i)), this[G] += 1, this[W].push(i);
|
|
2373
|
+
}
|
|
2374
|
+
this[Ct]();
|
|
2375
|
+
}
|
|
2376
|
+
[li](t) {
|
|
2377
|
+
let e = f(qs.resolve(this.cwd, t));
|
|
2378
|
+
this[W].push(new mi(t, e)), this[Ct]();
|
|
2379
|
+
}
|
|
2380
|
+
[cs](t) {
|
|
2381
|
+
t.pending = !0, this[G] += 1;
|
|
2382
|
+
I[this.follow ? "stat" : "lstat"](t.absolute, (i, r) => {
|
|
2383
|
+
t.pending = !1, this[G] -= 1, i ? this.emit("error", i) : this[ai](t, r);
|
|
2384
|
+
});
|
|
2385
|
+
}
|
|
2386
|
+
[ai](t, e) {
|
|
2387
|
+
if (this.statCache.set(t.absolute, e), t.stat = e, !this.filter(t.path, e)) t.ignore = !0;
|
|
2388
|
+
else if (e.isFile() && e.nlink > 1 && !this.linkCache.get(`${e.dev}:${e.ino}`) && !this.sync) if (t === this[Et]) this[hi](t);
|
|
2389
|
+
else {
|
|
2390
|
+
let i = `${e.dev}:${e.ino}`, r = this[me].get(i);
|
|
2391
|
+
r ? r.push(t) : this[me].set(i, [t]), t.pendingLink = !0, t.pending = !0;
|
|
2392
|
+
}
|
|
2393
|
+
this[Ct]();
|
|
2394
|
+
}
|
|
2395
|
+
[fs](t) {
|
|
2396
|
+
t.pending = !0, this[G] += 1, I.readdir(t.absolute, (e, i) => {
|
|
2397
|
+
if (t.pending = !1, this[G] -= 1, e) return this.emit("error", e);
|
|
2398
|
+
this[ci](t, i);
|
|
2399
|
+
});
|
|
2400
|
+
}
|
|
2401
|
+
[ci](t, e) {
|
|
2402
|
+
this.readdirCache.set(t.absolute, e), t.readdir = e, this[Ct]();
|
|
2403
|
+
}
|
|
2404
|
+
[Ct]() {
|
|
2405
|
+
if (!this[pe]) {
|
|
2406
|
+
this[pe] = !0;
|
|
2407
|
+
for (let t = this[W].head; t && this[G] < this.jobs; t = t.next) if (this[hi](t.value), t.value.ignore) {
|
|
2408
|
+
let e = t.next;
|
|
2409
|
+
this[W].removeNode(t), t.next = e;
|
|
2410
|
+
}
|
|
2411
|
+
this[pe] = !1, this[ue] && this[W].length === 0 && this[G] === 0 && (this.zip ? this.zip.end(ir) : (super.write(ir), super.end()));
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
get [Et]() {
|
|
2415
|
+
return this[W] && this[W].head && this[W].head.value;
|
|
2416
|
+
}
|
|
2417
|
+
[hs](t) {
|
|
2418
|
+
this[W].shift(), this[G] -= 1;
|
|
2419
|
+
let { stat: e } = t;
|
|
2420
|
+
if (e && e.isFile() && e.nlink > 1) {
|
|
2421
|
+
let i = `${e.dev}:${e.ino}`, r = this[me].get(i);
|
|
2422
|
+
if (r) {
|
|
2423
|
+
this[me].delete(i);
|
|
2424
|
+
for (let n of r) n.pending = !1, this[hi](n);
|
|
2425
|
+
}
|
|
2426
|
+
}
|
|
2427
|
+
this[Ct]();
|
|
2428
|
+
}
|
|
2429
|
+
[hi](t) {
|
|
2430
|
+
if (t.pending && t.pendingLink && t === this[Et] && (t.pending = !1, t.pendingLink = !1), !t.pending) {
|
|
2431
|
+
if (t.entry) {
|
|
2432
|
+
t === this[Et] && !t.piped && this[fi](t);
|
|
2433
|
+
return;
|
|
2434
|
+
}
|
|
2435
|
+
if (!t.stat) {
|
|
2436
|
+
let e = this.statCache.get(t.absolute);
|
|
2437
|
+
e ? this[ai](t, e) : this[cs](t);
|
|
2438
|
+
}
|
|
2439
|
+
if (t.stat && !t.ignore) {
|
|
2440
|
+
if (!this.noDirRecurse && t.stat.isDirectory() && !t.readdir) {
|
|
2441
|
+
let e = this.readdirCache.get(t.absolute);
|
|
2442
|
+
if (e ? this[ci](t, e) : this[fs](t), !t.readdir) return;
|
|
2443
|
+
}
|
|
2444
|
+
if (t.entry = this[rr](t), !t.entry) {
|
|
2445
|
+
t.ignore = !0;
|
|
2446
|
+
return;
|
|
2447
|
+
}
|
|
2448
|
+
t === this[Et] && !t.piped && this[fi](t);
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
[as](t) {
|
|
2453
|
+
return {
|
|
2454
|
+
onwarn: (e, i, r) => this.warn(e, i, r),
|
|
2455
|
+
noPax: this.noPax,
|
|
2456
|
+
cwd: this.cwd,
|
|
2457
|
+
absolute: t.absolute,
|
|
2458
|
+
preservePaths: this.preservePaths,
|
|
2459
|
+
maxReadSize: this.maxReadSize,
|
|
2460
|
+
strict: this.strict,
|
|
2461
|
+
portable: this.portable,
|
|
2462
|
+
linkCache: this.linkCache,
|
|
2463
|
+
statCache: this.statCache,
|
|
2464
|
+
noMtime: this.noMtime,
|
|
2465
|
+
mtime: this.mtime,
|
|
2466
|
+
prefix: this.prefix,
|
|
2467
|
+
onWriteEntry: this.onWriteEntry
|
|
2468
|
+
};
|
|
2469
|
+
}
|
|
2470
|
+
[rr](t) {
|
|
2471
|
+
this[G] += 1;
|
|
2472
|
+
try {
|
|
2473
|
+
return new this[di](t.path, this[as](t)).on("end", () => this[hs](t)).on("error", (i) => this.emit("error", i));
|
|
2474
|
+
} catch (e) {
|
|
2475
|
+
this.emit("error", e);
|
|
2476
|
+
}
|
|
2477
|
+
}
|
|
2478
|
+
[ls]() {
|
|
2479
|
+
this[Et] && this[Et].entry && this[Et].entry.resume();
|
|
2480
|
+
}
|
|
2481
|
+
[fi](t) {
|
|
2482
|
+
t.piped = !0, t.readdir && t.readdir.forEach((r) => {
|
|
2483
|
+
let n = t.path, o = n === "./" ? "" : n.replace(/\/*$/, "/");
|
|
2484
|
+
this[li](o + r);
|
|
2485
|
+
});
|
|
2486
|
+
let e = t.entry, i = this.zip;
|
|
2487
|
+
if (!e) throw new Error("cannot pipe without source");
|
|
2488
|
+
i ? e.on("data", (r) => {
|
|
2489
|
+
i.write(r) || e.pause();
|
|
2490
|
+
}) : e.on("data", (r) => {
|
|
2491
|
+
super.write(r) || e.pause();
|
|
2492
|
+
});
|
|
2493
|
+
}
|
|
2494
|
+
pause() {
|
|
2495
|
+
return this.zip && this.zip.pause(), super.pause();
|
|
2496
|
+
}
|
|
2497
|
+
warn(t, e, i = {}) {
|
|
2498
|
+
Nt(this, t, e, i);
|
|
2499
|
+
}
|
|
2500
|
+
}, kt = class extends wt {
|
|
2501
|
+
sync = !0;
|
|
2502
|
+
constructor(t) {
|
|
2503
|
+
super(t), this[di] = ri;
|
|
2504
|
+
}
|
|
2505
|
+
pause() {}
|
|
2506
|
+
resume() {}
|
|
2507
|
+
[cs](t) {
|
|
2508
|
+
let e = this.follow ? "statSync" : "lstatSync";
|
|
2509
|
+
this[ai](t, I[e](t.absolute));
|
|
2510
|
+
}
|
|
2511
|
+
[fs](t) {
|
|
2512
|
+
this[ci](t, I.readdirSync(t.absolute));
|
|
2513
|
+
}
|
|
2514
|
+
[fi](t) {
|
|
2515
|
+
let e = t.entry, i = this.zip;
|
|
2516
|
+
if (t.readdir && t.readdir.forEach((r) => {
|
|
2517
|
+
let n = t.path, o = n === "./" ? "" : n.replace(/\/*$/, "/");
|
|
2518
|
+
this[li](o + r);
|
|
2519
|
+
}), !e) throw new Error("Cannot pipe without source");
|
|
2520
|
+
i ? e.on("data", (r) => {
|
|
2521
|
+
i.write(r);
|
|
2522
|
+
}) : e.on("data", (r) => {
|
|
2523
|
+
super[or](r);
|
|
2524
|
+
});
|
|
2525
|
+
}
|
|
2526
|
+
};
|
|
2527
|
+
var Wn = (s, t) => {
|
|
2528
|
+
let e = new kt(s), i = new Wt(s.file, { mode: s.mode || 438 });
|
|
2529
|
+
e.pipe(i), ar(e, t);
|
|
2530
|
+
}, Gn = (s, t) => {
|
|
2531
|
+
let e = new wt(s), i = new tt(s.file, { mode: s.mode || 438 });
|
|
2532
|
+
e.pipe(i);
|
|
2533
|
+
let r = new Promise((n, o) => {
|
|
2534
|
+
i.on("error", o), i.on("close", n), e.on("error", o);
|
|
2535
|
+
});
|
|
2536
|
+
return lr(e, t).catch((n) => e.emit("error", n)), r;
|
|
2537
|
+
}, ar = (s, t) => {
|
|
2538
|
+
t.forEach((e) => {
|
|
2539
|
+
e.charAt(0) === "@" ? Ft({
|
|
2540
|
+
file: path.resolve(s.cwd, e.slice(1)),
|
|
2541
|
+
sync: !0,
|
|
2542
|
+
noResume: !0,
|
|
2543
|
+
onReadEntry: (i) => s.add(i)
|
|
2544
|
+
}) : s.add(e);
|
|
2545
|
+
}), s.end();
|
|
2546
|
+
}, lr = async (s, t) => {
|
|
2547
|
+
for (let e of t) e.charAt(0) === "@" ? await Ft({
|
|
2548
|
+
file: path.resolve(String(s.cwd), e.slice(1)),
|
|
2549
|
+
noResume: !0,
|
|
2550
|
+
onReadEntry: (i) => {
|
|
2551
|
+
s.add(i);
|
|
2552
|
+
}
|
|
2553
|
+
}) : s.add(e);
|
|
2554
|
+
s.end();
|
|
2555
|
+
}, Zn = (s, t) => {
|
|
2556
|
+
let e = new kt(s);
|
|
2557
|
+
return ar(e, t), e;
|
|
2558
|
+
}, Yn = (s, t) => {
|
|
2559
|
+
let e = new wt(s);
|
|
2560
|
+
return lr(e, t).catch((i) => e.emit("error", i)), e;
|
|
2561
|
+
}, Kn = K(Wn, Gn, Zn, Yn, (s, t) => {
|
|
2562
|
+
if (!t?.length) throw new TypeError("no paths specified to add to archive");
|
|
2563
|
+
});
|
|
2564
|
+
var ur = (process.env.__FAKE_PLATFORM__ || process.platform) === "win32", { O_CREAT: mr, O_NOFOLLOW: cr, O_TRUNC: pr, O_WRONLY: Er } = I.constants, wr = Number(process.env.__FAKE_FS_O_FILENAME__) || I.constants.UV_FS_O_FILEMAP || 0, $n = ur && !!wr, Xn = 512 * 1024, qn = wr | pr | mr | Er, fr = !ur && typeof cr == "number" ? cr | pr | mr | Er : null, ds = fr !== null ? () => fr : $n ? (s) => s < Xn ? qn : "w" : () => "w";
|
|
2565
|
+
var us = (s, t, e) => {
|
|
2566
|
+
try {
|
|
2567
|
+
return Kt.lchownSync(s, t, e);
|
|
2568
|
+
} catch (i) {
|
|
2569
|
+
if (i?.code !== "ENOENT") throw i;
|
|
2570
|
+
}
|
|
2571
|
+
}, pi = (s, t, e, i) => {
|
|
2572
|
+
Kt.lchown(s, t, e, (r) => {
|
|
2573
|
+
i(r && r?.code !== "ENOENT" ? r : null);
|
|
2574
|
+
});
|
|
2575
|
+
}, Qn = (s, t, e, i, r) => {
|
|
2576
|
+
if (t.isDirectory()) ms(path.resolve(s, t.name), e, i, (n) => {
|
|
2577
|
+
if (n) return r(n);
|
|
2578
|
+
pi(path.resolve(s, t.name), e, i, r);
|
|
2579
|
+
});
|
|
2580
|
+
else pi(path.resolve(s, t.name), e, i, r);
|
|
2581
|
+
}, ms = (s, t, e, i) => {
|
|
2582
|
+
Kt.readdir(s, { withFileTypes: !0 }, (r, n) => {
|
|
2583
|
+
if (r) {
|
|
2584
|
+
if (r.code === "ENOENT") return i();
|
|
2585
|
+
if (r.code !== "ENOTDIR" && r.code !== "ENOTSUP") return i(r);
|
|
2586
|
+
}
|
|
2587
|
+
if (r || !n.length) return pi(s, t, e, i);
|
|
2588
|
+
let o = n.length, a = null, h = (l) => {
|
|
2589
|
+
if (!a) {
|
|
2590
|
+
if (l) return i(a = l);
|
|
2591
|
+
if (--o === 0) return pi(s, t, e, i);
|
|
2592
|
+
}
|
|
2593
|
+
};
|
|
2594
|
+
for (let l of n) Qn(s, l, t, e, h);
|
|
2595
|
+
});
|
|
2596
|
+
}, Jn = (s, t, e, i) => {
|
|
2597
|
+
t.isDirectory() && ps(path.resolve(s, t.name), e, i), us(path.resolve(s, t.name), e, i);
|
|
2598
|
+
}, ps = (s, t, e) => {
|
|
2599
|
+
let i;
|
|
2600
|
+
try {
|
|
2601
|
+
i = Kt.readdirSync(s, { withFileTypes: !0 });
|
|
2602
|
+
} catch (r) {
|
|
2603
|
+
let n = r;
|
|
2604
|
+
if (n?.code === "ENOENT") return;
|
|
2605
|
+
if (n?.code === "ENOTDIR" || n?.code === "ENOTSUP") return us(s, t, e);
|
|
2606
|
+
throw n;
|
|
2607
|
+
}
|
|
2608
|
+
for (let r of i) Jn(s, r, t, e);
|
|
2609
|
+
return us(s, t, e);
|
|
2610
|
+
};
|
|
2611
|
+
var we = class extends Error {
|
|
2612
|
+
path;
|
|
2613
|
+
code;
|
|
2614
|
+
syscall = "chdir";
|
|
2615
|
+
constructor(t, e) {
|
|
2616
|
+
super(`${e}: Cannot cd into '${t}'`), this.path = t, this.code = e;
|
|
2617
|
+
}
|
|
2618
|
+
get name() {
|
|
2619
|
+
return "CwdError";
|
|
2620
|
+
}
|
|
2621
|
+
};
|
|
2622
|
+
var St = class extends Error {
|
|
2623
|
+
path;
|
|
2624
|
+
symlink;
|
|
2625
|
+
syscall = "symlink";
|
|
2626
|
+
code = "TAR_SYMLINK_ERROR";
|
|
2627
|
+
constructor(t, e) {
|
|
2628
|
+
super("TAR_SYMLINK_ERROR: Cannot extract through symbolic link"), this.symlink = t, this.path = e;
|
|
2629
|
+
}
|
|
2630
|
+
get name() {
|
|
2631
|
+
return "SymlinkError";
|
|
2632
|
+
}
|
|
2633
|
+
};
|
|
2634
|
+
var to = (s, t) => {
|
|
2635
|
+
Kt.stat(s, (e, i) => {
|
|
2636
|
+
(e || !i.isDirectory()) && (e = new we(s, e?.code || "ENOTDIR")), t(e);
|
|
2637
|
+
});
|
|
2638
|
+
}, Sr = (s, t, e) => {
|
|
2639
|
+
s = f(s);
|
|
2640
|
+
let i = t.umask ?? 18, r = t.mode | 448, n = (r & i) !== 0, o = t.uid, a = t.gid, h = typeof o == "number" && typeof a == "number" && (o !== t.processUid || a !== t.processGid), l = t.preserve, c = t.unlink, d = f(t.cwd), S = (E, x) => {
|
|
2641
|
+
E ? e(E) : x && h ? ms(x, o, a, (xe) => S(xe)) : n ? Kt.chmod(s, r, e) : e();
|
|
2642
|
+
};
|
|
2643
|
+
if (s === d) return to(s, S);
|
|
2644
|
+
if (l) return jn.mkdir(s, {
|
|
2645
|
+
mode: r,
|
|
2646
|
+
recursive: !0
|
|
2647
|
+
}).then((E) => S(null, E ?? void 0), S);
|
|
2648
|
+
Es(d, f(path.relative(d, s)).split("/"), r, c, d, void 0, S);
|
|
2649
|
+
}, Es = (s, t, e, i, r, n, o) => {
|
|
2650
|
+
if (t.length === 0) return o(null, n);
|
|
2651
|
+
let a = t.shift(), h = f(path.resolve(s + "/" + a));
|
|
2652
|
+
Kt.mkdir(h, e, yr(h, t, e, i, r, n, o));
|
|
2653
|
+
}, yr = (s, t, e, i, r, n, o) => (a) => {
|
|
2654
|
+
a ? Kt.lstat(s, (h, l) => {
|
|
2655
|
+
if (h) h.path = h.path && f(h.path), o(h);
|
|
2656
|
+
else if (l.isDirectory()) Es(s, t, e, i, r, n, o);
|
|
2657
|
+
else if (i) Kt.unlink(s, (c) => {
|
|
2658
|
+
if (c) return o(c);
|
|
2659
|
+
Kt.mkdir(s, e, yr(s, t, e, i, r, n, o));
|
|
2660
|
+
});
|
|
2661
|
+
else {
|
|
2662
|
+
if (l.isSymbolicLink()) return o(new St(s, s + "/" + t.join("/")));
|
|
2663
|
+
o(a);
|
|
2664
|
+
}
|
|
2665
|
+
}) : (n = n || s, Es(s, t, e, i, r, n, o));
|
|
2666
|
+
}, eo = (s) => {
|
|
2667
|
+
let t = !1, e;
|
|
2668
|
+
try {
|
|
2669
|
+
t = Kt.statSync(s).isDirectory();
|
|
2670
|
+
} catch (i) {
|
|
2671
|
+
e = i?.code;
|
|
2672
|
+
} finally {
|
|
2673
|
+
if (!t) throw new we(s, e ?? "ENOTDIR");
|
|
2674
|
+
}
|
|
2675
|
+
}, Rr = (s, t) => {
|
|
2676
|
+
s = f(s);
|
|
2677
|
+
let e = t.umask ?? 18, i = t.mode | 448, r = (i & e) !== 0, n = t.uid, o = t.gid, a = typeof n == "number" && typeof o == "number" && (n !== t.processUid || o !== t.processGid), h = t.preserve, l = t.unlink, c = f(t.cwd), d = (E) => {
|
|
2678
|
+
E && a && ps(E, n, o), r && Kt.chmodSync(s, i);
|
|
2679
|
+
};
|
|
2680
|
+
if (s === c) return eo(c), d();
|
|
2681
|
+
if (h) return d(Kt.mkdirSync(s, {
|
|
2682
|
+
mode: i,
|
|
2683
|
+
recursive: !0
|
|
2684
|
+
}) ?? void 0);
|
|
2685
|
+
let T = f(path.relative(c, s)).split("/"), N;
|
|
2686
|
+
for (let E = T.shift(), x = c; E && (x += "/" + E); E = T.shift()) {
|
|
2687
|
+
x = f(path.resolve(x));
|
|
2688
|
+
try {
|
|
2689
|
+
Kt.mkdirSync(x, i), N = N || x;
|
|
2690
|
+
} catch {
|
|
2691
|
+
let xe = Kt.lstatSync(x);
|
|
2692
|
+
if (xe.isDirectory()) continue;
|
|
2693
|
+
if (l) {
|
|
2694
|
+
Kt.unlinkSync(x), Kt.mkdirSync(x, i), N = N || x;
|
|
2695
|
+
continue;
|
|
2696
|
+
} else if (xe.isSymbolicLink()) return new St(x, x + "/" + T.join("/"));
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
return d(N);
|
|
2700
|
+
};
|
|
2701
|
+
var ws = Object.create(null), gr = 1e4, Vt = /* @__PURE__ */ new Set(), br = (s) => {
|
|
2702
|
+
Vt.has(s) ? Vt.delete(s) : ws[s] = s.normalize("NFD").toLocaleLowerCase("en").toLocaleUpperCase("en"), Vt.add(s);
|
|
2703
|
+
let t = ws[s], e = Vt.size - gr;
|
|
2704
|
+
if (e > gr / 10) {
|
|
2705
|
+
for (let i of Vt) if (Vt.delete(i), delete ws[i], --e <= 0) break;
|
|
2706
|
+
}
|
|
2707
|
+
return t;
|
|
2708
|
+
};
|
|
2709
|
+
var so = (process.env.TESTING_TAR_FAKE_PLATFORM || process.platform) === "win32", ro = (s) => s.split("/").slice(0, -1).reduce((e, i) => {
|
|
2710
|
+
let r = e.at(-1);
|
|
2711
|
+
return r !== void 0 && (i = join(r, i)), e.push(i || "/"), e;
|
|
2712
|
+
}, []), Si = class {
|
|
2713
|
+
#t = /* @__PURE__ */ new Map();
|
|
2714
|
+
#i = /* @__PURE__ */ new Map();
|
|
2715
|
+
#s = /* @__PURE__ */ new Set();
|
|
2716
|
+
reserve(t, e) {
|
|
2717
|
+
t = so ? ["win32 parallelization disabled"] : t.map((r) => mt(join(br(r))));
|
|
2718
|
+
let i = new Set(t.map((r) => ro(r)).reduce((r, n) => r.concat(n)));
|
|
2719
|
+
this.#i.set(e, {
|
|
2720
|
+
dirs: i,
|
|
2721
|
+
paths: t
|
|
2722
|
+
});
|
|
2723
|
+
for (let r of t) {
|
|
2724
|
+
let n = this.#t.get(r);
|
|
2725
|
+
n ? n.push(e) : this.#t.set(r, [e]);
|
|
2726
|
+
}
|
|
2727
|
+
for (let r of i) {
|
|
2728
|
+
let n = this.#t.get(r);
|
|
2729
|
+
if (!n) this.#t.set(r, [new Set([e])]);
|
|
2730
|
+
else {
|
|
2731
|
+
let o = n.at(-1);
|
|
2732
|
+
o instanceof Set ? o.add(e) : n.push(new Set([e]));
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
return this.#r(e);
|
|
2736
|
+
}
|
|
2737
|
+
#n(t) {
|
|
2738
|
+
let e = this.#i.get(t);
|
|
2739
|
+
if (!e) throw new Error("function does not have any path reservations");
|
|
2740
|
+
return {
|
|
2741
|
+
paths: e.paths.map((i) => this.#t.get(i)),
|
|
2742
|
+
dirs: [...e.dirs].map((i) => this.#t.get(i))
|
|
2743
|
+
};
|
|
2744
|
+
}
|
|
2745
|
+
check(t) {
|
|
2746
|
+
let { paths: e, dirs: i } = this.#n(t);
|
|
2747
|
+
return e.every((r) => r && r[0] === t) && i.every((r) => r && r[0] instanceof Set && r[0].has(t));
|
|
2748
|
+
}
|
|
2749
|
+
#r(t) {
|
|
2750
|
+
return this.#s.has(t) || !this.check(t) ? !1 : (this.#s.add(t), t(() => this.#e(t)), !0);
|
|
2751
|
+
}
|
|
2752
|
+
#e(t) {
|
|
2753
|
+
if (!this.#s.has(t)) return !1;
|
|
2754
|
+
let e = this.#i.get(t);
|
|
2755
|
+
if (!e) throw new Error("invalid reservation");
|
|
2756
|
+
let { paths: i, dirs: r } = e, n = /* @__PURE__ */ new Set();
|
|
2757
|
+
for (let o of i) {
|
|
2758
|
+
let a = this.#t.get(o);
|
|
2759
|
+
if (!a || a?.[0] !== t) continue;
|
|
2760
|
+
let h = a[1];
|
|
2761
|
+
if (!h) {
|
|
2762
|
+
this.#t.delete(o);
|
|
2763
|
+
continue;
|
|
2764
|
+
}
|
|
2765
|
+
if (a.shift(), typeof h == "function") n.add(h);
|
|
2766
|
+
else for (let l of h) n.add(l);
|
|
2767
|
+
}
|
|
2768
|
+
for (let o of r) {
|
|
2769
|
+
let a = this.#t.get(o), h = a?.[0];
|
|
2770
|
+
if (!(!a || !(h instanceof Set))) if (h.size === 1 && a.length === 1) {
|
|
2771
|
+
this.#t.delete(o);
|
|
2772
|
+
continue;
|
|
2773
|
+
} else if (h.size === 1) {
|
|
2774
|
+
a.shift();
|
|
2775
|
+
let l = a[0];
|
|
2776
|
+
typeof l == "function" && n.add(l);
|
|
2777
|
+
} else h.delete(t);
|
|
2778
|
+
}
|
|
2779
|
+
return this.#s.delete(t), n.forEach((o) => this.#r(o)), !0;
|
|
2780
|
+
}
|
|
2781
|
+
};
|
|
2782
|
+
var Or = () => process.umask();
|
|
2783
|
+
var Tr = Symbol("onEntry"), gs = Symbol("checkFs"), xr = Symbol("checkFs2"), bs = Symbol("isReusable"), P = Symbol("makeFs"), _s = Symbol("file"), Os = Symbol("directory"), Ri = Symbol("link"), Lr = Symbol("symlink"), Nr = Symbol("hardlink"), ye = Symbol("ensureNoSymlink"), Dr = Symbol("unsupported"), Ar = Symbol("checkPath"), Ss = Symbol("stripAbsolutePath"), yt = Symbol("mkdir"), O = Symbol("onError"), yi = Symbol("pending"), Ir = Symbol("pend"), $t = Symbol("unpend"), ys = Symbol("ended"), Rs = Symbol("maybeClose"), Ts = Symbol("skip"), Re = Symbol("doChown"), ge = Symbol("uid"), be = Symbol("gid"), _e = Symbol("checkedCwd"), Oe = (process.env.TESTING_TAR_FAKE_PLATFORM || process.platform) === "win32", ho = 1024, ao = (s, t) => {
|
|
2784
|
+
if (!Oe) return Kt.unlink(s, t);
|
|
2785
|
+
let e = s + ".DELETE." + randomBytes(16).toString("hex");
|
|
2786
|
+
Kt.rename(s, e, (i) => {
|
|
2787
|
+
if (i) return t(i);
|
|
2788
|
+
Kt.unlink(e, t);
|
|
2789
|
+
});
|
|
2790
|
+
}, lo = (s) => {
|
|
2791
|
+
if (!Oe) return Kt.unlinkSync(s);
|
|
2792
|
+
let t = s + ".DELETE." + randomBytes(16).toString("hex");
|
|
2793
|
+
Kt.renameSync(s, t), Kt.unlinkSync(t);
|
|
2794
|
+
}, Fr = (s, t, e) => s !== void 0 && s === s >>> 0 ? s : t !== void 0 && t === t >>> 0 ? t : e, Xt = class extends st {
|
|
2795
|
+
[ys] = !1;
|
|
2796
|
+
[_e] = !1;
|
|
2797
|
+
[yi] = 0;
|
|
2798
|
+
reservations = new Si();
|
|
2799
|
+
transform;
|
|
2800
|
+
writable = !0;
|
|
2801
|
+
readable = !1;
|
|
2802
|
+
uid;
|
|
2803
|
+
gid;
|
|
2804
|
+
setOwner;
|
|
2805
|
+
preserveOwner;
|
|
2806
|
+
processGid;
|
|
2807
|
+
processUid;
|
|
2808
|
+
maxDepth;
|
|
2809
|
+
forceChown;
|
|
2810
|
+
win32;
|
|
2811
|
+
newer;
|
|
2812
|
+
keep;
|
|
2813
|
+
noMtime;
|
|
2814
|
+
preservePaths;
|
|
2815
|
+
unlink;
|
|
2816
|
+
cwd;
|
|
2817
|
+
strip;
|
|
2818
|
+
processUmask;
|
|
2819
|
+
umask;
|
|
2820
|
+
dmode;
|
|
2821
|
+
fmode;
|
|
2822
|
+
chmod;
|
|
2823
|
+
constructor(t = {}) {
|
|
2824
|
+
if (t.ondone = () => {
|
|
2825
|
+
this[ys] = !0, this[Rs]();
|
|
2826
|
+
}, super(t), this.transform = t.transform, this.chmod = !!t.chmod, typeof t.uid == "number" || typeof t.gid == "number") {
|
|
2827
|
+
if (typeof t.uid != "number" || typeof t.gid != "number") throw new TypeError("cannot set owner without number uid and gid");
|
|
2828
|
+
if (t.preserveOwner) throw new TypeError("cannot preserve owner in archive and also set owner explicitly");
|
|
2829
|
+
this.uid = t.uid, this.gid = t.gid, this.setOwner = !0;
|
|
2830
|
+
} else this.uid = void 0, this.gid = void 0, this.setOwner = !1;
|
|
2831
|
+
this.preserveOwner = t.preserveOwner === void 0 && typeof t.uid != "number" ? !!(process.getuid && process.getuid() === 0) : !!t.preserveOwner, this.processUid = (this.preserveOwner || this.setOwner) && process.getuid ? process.getuid() : void 0, this.processGid = (this.preserveOwner || this.setOwner) && process.getgid ? process.getgid() : void 0, this.maxDepth = typeof t.maxDepth == "number" ? t.maxDepth : ho, this.forceChown = t.forceChown === !0, this.win32 = !!t.win32 || Oe, this.newer = !!t.newer, this.keep = !!t.keep, this.noMtime = !!t.noMtime, this.preservePaths = !!t.preservePaths, this.unlink = !!t.unlink, this.cwd = f(path.resolve(t.cwd || process.cwd())), this.strip = Number(t.strip) || 0, this.processUmask = this.chmod ? typeof t.processUmask == "number" ? t.processUmask : Or() : 0, this.umask = typeof t.umask == "number" ? t.umask : this.processUmask, this.dmode = t.dmode || 511 & ~this.umask, this.fmode = t.fmode || 438 & ~this.umask, this.on("entry", (e) => this[Tr](e));
|
|
2832
|
+
}
|
|
2833
|
+
warn(t, e, i = {}) {
|
|
2834
|
+
return (t === "TAR_BAD_ARCHIVE" || t === "TAR_ABORT") && (i.recoverable = !1), super.warn(t, e, i);
|
|
2835
|
+
}
|
|
2836
|
+
[Rs]() {
|
|
2837
|
+
this[ys] && this[yi] === 0 && (this.emit("prefinish"), this.emit("finish"), this.emit("end"));
|
|
2838
|
+
}
|
|
2839
|
+
[Ss](t, e) {
|
|
2840
|
+
let i = t[e], { type: r } = t;
|
|
2841
|
+
if (!i || this.preservePaths) return !0;
|
|
2842
|
+
let [n, o] = le(i), a = o.replaceAll(/\\/g, "/").split("/");
|
|
2843
|
+
if (a.includes("..") || Oe && /^[a-z]:\.\.$/i.test(a[0] ?? "")) {
|
|
2844
|
+
if (e === "path" || r === "Link") return this.warn("TAR_ENTRY_ERROR", `${e} contains '..'`, {
|
|
2845
|
+
entry: t,
|
|
2846
|
+
[e]: i
|
|
2847
|
+
}), !1;
|
|
2848
|
+
let h = path.posix.dirname(t.path), l = path.posix.normalize(path.posix.join(h, a.join("/")));
|
|
2849
|
+
if (l.startsWith("../") || l === "..") return this.warn("TAR_ENTRY_ERROR", `${e} escapes extraction directory`, {
|
|
2850
|
+
entry: t,
|
|
2851
|
+
[e]: i
|
|
2852
|
+
}), !1;
|
|
2853
|
+
}
|
|
2854
|
+
return n && (t[e] = String(o), this.warn("TAR_ENTRY_INFO", `stripping ${n} from absolute ${e}`, {
|
|
2855
|
+
entry: t,
|
|
2856
|
+
[e]: i
|
|
2857
|
+
})), !0;
|
|
2858
|
+
}
|
|
2859
|
+
[Ar](t) {
|
|
2860
|
+
let e = f(t.path), i = e.split("/");
|
|
2861
|
+
if (this.strip) {
|
|
2862
|
+
if (i.length < this.strip) return !1;
|
|
2863
|
+
if (t.type === "Link") {
|
|
2864
|
+
let r = f(String(t.linkpath)).split("/");
|
|
2865
|
+
if (r.length >= this.strip) t.linkpath = r.slice(this.strip).join("/");
|
|
2866
|
+
else return !1;
|
|
2867
|
+
}
|
|
2868
|
+
i.splice(0, this.strip), t.path = i.join("/");
|
|
2869
|
+
}
|
|
2870
|
+
if (isFinite(this.maxDepth) && i.length > this.maxDepth) return this.warn("TAR_ENTRY_ERROR", "path excessively deep", {
|
|
2871
|
+
entry: t,
|
|
2872
|
+
path: e,
|
|
2873
|
+
depth: i.length,
|
|
2874
|
+
maxDepth: this.maxDepth
|
|
2875
|
+
}), !1;
|
|
2876
|
+
if (!this[Ss](t, "path") || !this[Ss](t, "linkpath")) return !1;
|
|
2877
|
+
if (t.absolute = path.isAbsolute(t.path) ? f(path.resolve(t.path)) : f(path.resolve(this.cwd, t.path)), !this.preservePaths && typeof t.absolute == "string" && t.absolute.indexOf(this.cwd + "/") !== 0 && t.absolute !== this.cwd) return this.warn("TAR_ENTRY_ERROR", "path escaped extraction target", {
|
|
2878
|
+
entry: t,
|
|
2879
|
+
path: f(t.path),
|
|
2880
|
+
resolvedPath: t.absolute,
|
|
2881
|
+
cwd: this.cwd
|
|
2882
|
+
}), !1;
|
|
2883
|
+
if (t.absolute === this.cwd && t.type !== "Directory" && t.type !== "GNUDumpDir") return !1;
|
|
2884
|
+
if (this.win32) {
|
|
2885
|
+
let { root: r } = path.win32.parse(String(t.absolute));
|
|
2886
|
+
t.absolute = r + Ji(String(t.absolute).slice(r.length));
|
|
2887
|
+
let { root: n } = path.win32.parse(t.path);
|
|
2888
|
+
t.path = n + Ji(t.path.slice(n.length));
|
|
2889
|
+
}
|
|
2890
|
+
return !0;
|
|
2891
|
+
}
|
|
2892
|
+
[Tr](t) {
|
|
2893
|
+
if (!this[Ar](t)) return t.resume();
|
|
2894
|
+
switch (no.equal(typeof t.absolute, "string"), t.type) {
|
|
2895
|
+
case "Directory":
|
|
2896
|
+
case "GNUDumpDir": t.mode && (t.mode = t.mode | 448);
|
|
2897
|
+
case "File":
|
|
2898
|
+
case "OldFile":
|
|
2899
|
+
case "ContiguousFile":
|
|
2900
|
+
case "Link":
|
|
2901
|
+
case "SymbolicLink": return this[gs](t);
|
|
2902
|
+
default: return this[Dr](t);
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
[O](t, e) {
|
|
2906
|
+
t.name === "CwdError" ? this.emit("error", t) : (this.warn("TAR_ENTRY_ERROR", t, { entry: e }), this[$t](), e.resume());
|
|
2907
|
+
}
|
|
2908
|
+
[yt](t, e, i) {
|
|
2909
|
+
Sr(f(t), {
|
|
2910
|
+
uid: this.uid,
|
|
2911
|
+
gid: this.gid,
|
|
2912
|
+
processUid: this.processUid,
|
|
2913
|
+
processGid: this.processGid,
|
|
2914
|
+
umask: this.processUmask,
|
|
2915
|
+
preserve: this.preservePaths,
|
|
2916
|
+
unlink: this.unlink,
|
|
2917
|
+
cwd: this.cwd,
|
|
2918
|
+
mode: e
|
|
2919
|
+
}, i);
|
|
2920
|
+
}
|
|
2921
|
+
[Re](t) {
|
|
2922
|
+
return this.forceChown || this.preserveOwner && (typeof t.uid == "number" && t.uid !== this.processUid || typeof t.gid == "number" && t.gid !== this.processGid) || typeof this.uid == "number" && this.uid !== this.processUid || typeof this.gid == "number" && this.gid !== this.processGid;
|
|
2923
|
+
}
|
|
2924
|
+
[ge](t) {
|
|
2925
|
+
return Fr(this.uid, t.uid, this.processUid);
|
|
2926
|
+
}
|
|
2927
|
+
[be](t) {
|
|
2928
|
+
return Fr(this.gid, t.gid, this.processGid);
|
|
2929
|
+
}
|
|
2930
|
+
[_s](t, e) {
|
|
2931
|
+
let i = typeof t.mode == "number" ? t.mode & 4095 : this.fmode, r = new tt(String(t.absolute), {
|
|
2932
|
+
flags: ds(t.size),
|
|
2933
|
+
mode: i,
|
|
2934
|
+
autoClose: !1
|
|
2935
|
+
});
|
|
2936
|
+
r.on("error", (h) => {
|
|
2937
|
+
r.fd && Kt.close(r.fd, () => {}), r.write = () => !0, this[O](h, t), e();
|
|
2938
|
+
});
|
|
2939
|
+
let n = 1, o = (h) => {
|
|
2940
|
+
if (h) {
|
|
2941
|
+
r.fd && Kt.close(r.fd, () => {}), this[O](h, t), e();
|
|
2942
|
+
return;
|
|
2943
|
+
}
|
|
2944
|
+
--n === 0 && r.fd !== void 0 && Kt.close(r.fd, (l) => {
|
|
2945
|
+
l ? this[O](l, t) : this[$t](), e();
|
|
2946
|
+
});
|
|
2947
|
+
};
|
|
2948
|
+
r.on("finish", () => {
|
|
2949
|
+
let h = String(t.absolute), l = r.fd;
|
|
2950
|
+
if (typeof l == "number" && t.mtime && !this.noMtime) {
|
|
2951
|
+
n++;
|
|
2952
|
+
let c = t.atime || /* @__PURE__ */ new Date(), d = t.mtime;
|
|
2953
|
+
Kt.futimes(l, c, d, (S) => S ? Kt.utimes(h, c, d, (T) => o(T && S)) : o());
|
|
2954
|
+
}
|
|
2955
|
+
if (typeof l == "number" && this[Re](t)) {
|
|
2956
|
+
n++;
|
|
2957
|
+
let c = this[ge](t), d = this[be](t);
|
|
2958
|
+
typeof c == "number" && typeof d == "number" && Kt.fchown(l, c, d, (S) => S ? Kt.chown(h, c, d, (T) => o(T && S)) : o());
|
|
2959
|
+
}
|
|
2960
|
+
o();
|
|
2961
|
+
});
|
|
2962
|
+
let a = this.transform && this.transform(t) || t;
|
|
2963
|
+
a !== t && (a.on("error", (h) => {
|
|
2964
|
+
this[O](h, t), e();
|
|
2965
|
+
}), t.pipe(a)), a.pipe(r);
|
|
2966
|
+
}
|
|
2967
|
+
[Os](t, e) {
|
|
2968
|
+
let i = typeof t.mode == "number" ? t.mode & 4095 : this.dmode;
|
|
2969
|
+
this[yt](String(t.absolute), i, (r) => {
|
|
2970
|
+
if (r) {
|
|
2971
|
+
this[O](r, t), e();
|
|
2972
|
+
return;
|
|
2973
|
+
}
|
|
2974
|
+
let n = 1, o = () => {
|
|
2975
|
+
--n === 0 && (e(), this[$t](), t.resume());
|
|
2976
|
+
};
|
|
2977
|
+
t.mtime && !this.noMtime && (n++, Kt.utimes(String(t.absolute), t.atime || /* @__PURE__ */ new Date(), t.mtime, o)), this[Re](t) && (n++, Kt.chown(String(t.absolute), Number(this[ge](t)), Number(this[be](t)), o)), o();
|
|
2978
|
+
});
|
|
2979
|
+
}
|
|
2980
|
+
[Dr](t) {
|
|
2981
|
+
t.unsupported = !0, this.warn("TAR_ENTRY_UNSUPPORTED", `unsupported entry type: ${t.type}`, { entry: t }), t.resume();
|
|
2982
|
+
}
|
|
2983
|
+
[Lr](t, e) {
|
|
2984
|
+
let i = f(path.relative(this.cwd, path.resolve(path.dirname(String(t.absolute)), String(t.linkpath)))).split("/");
|
|
2985
|
+
this[ye](t, this.cwd, i, () => this[Ri](t, String(t.linkpath), "symlink", e), (r) => {
|
|
2986
|
+
this[O](r, t), e();
|
|
2987
|
+
});
|
|
2988
|
+
}
|
|
2989
|
+
[Nr](t, e) {
|
|
2990
|
+
let i = f(path.resolve(this.cwd, String(t.linkpath))), r = f(String(t.linkpath)).split("/");
|
|
2991
|
+
this[ye](t, this.cwd, r, () => this[Ri](t, i, "link", e), (n) => {
|
|
2992
|
+
this[O](n, t), e();
|
|
2993
|
+
});
|
|
2994
|
+
}
|
|
2995
|
+
[ye](t, e, i, r, n) {
|
|
2996
|
+
let o = i.shift();
|
|
2997
|
+
if (this.preservePaths || o === void 0) return r();
|
|
2998
|
+
let a = path.resolve(e, o);
|
|
2999
|
+
Kt.lstat(a, (h, l) => {
|
|
3000
|
+
if (h) return r();
|
|
3001
|
+
if (l?.isSymbolicLink()) return n(new St(a, path.resolve(a, i.join("/"))));
|
|
3002
|
+
this[ye](t, a, i, r, n);
|
|
3003
|
+
});
|
|
3004
|
+
}
|
|
3005
|
+
[Ir]() {
|
|
3006
|
+
this[yi]++;
|
|
3007
|
+
}
|
|
3008
|
+
[$t]() {
|
|
3009
|
+
this[yi]--, this[Rs]();
|
|
3010
|
+
}
|
|
3011
|
+
[Ts](t) {
|
|
3012
|
+
this[$t](), t.resume();
|
|
3013
|
+
}
|
|
3014
|
+
[bs](t, e) {
|
|
3015
|
+
return t.type === "File" && !this.unlink && e.isFile() && e.nlink <= 1 && !Oe;
|
|
3016
|
+
}
|
|
3017
|
+
[gs](t) {
|
|
3018
|
+
this[Ir]();
|
|
3019
|
+
let e = [t.path];
|
|
3020
|
+
t.linkpath && e.push(t.linkpath), this.reservations.reserve(e, (i) => this[xr](t, i));
|
|
3021
|
+
}
|
|
3022
|
+
[xr](t, e) {
|
|
3023
|
+
let i = (a) => {
|
|
3024
|
+
e(a);
|
|
3025
|
+
}, r = () => {
|
|
3026
|
+
this[yt](this.cwd, this.dmode, (a) => {
|
|
3027
|
+
if (a) {
|
|
3028
|
+
this[O](a, t), i();
|
|
3029
|
+
return;
|
|
3030
|
+
}
|
|
3031
|
+
this[_e] = !0, n();
|
|
3032
|
+
});
|
|
3033
|
+
}, n = () => {
|
|
3034
|
+
if (t.absolute !== this.cwd) {
|
|
3035
|
+
let a = f(path.dirname(String(t.absolute)));
|
|
3036
|
+
if (a !== this.cwd) return this[yt](a, this.dmode, (h) => {
|
|
3037
|
+
if (h) {
|
|
3038
|
+
this[O](h, t), i();
|
|
3039
|
+
return;
|
|
3040
|
+
}
|
|
3041
|
+
o();
|
|
3042
|
+
});
|
|
3043
|
+
}
|
|
3044
|
+
o();
|
|
3045
|
+
}, o = () => {
|
|
3046
|
+
Kt.lstat(String(t.absolute), (a, h) => {
|
|
3047
|
+
if (h && (this.keep || this.newer && h.mtime > (t.mtime ?? h.mtime))) {
|
|
3048
|
+
this[Ts](t), i();
|
|
3049
|
+
return;
|
|
3050
|
+
}
|
|
3051
|
+
if (a || this[bs](t, h)) return this[P](null, t, i);
|
|
3052
|
+
if (h.isDirectory()) {
|
|
3053
|
+
if (t.type === "Directory") {
|
|
3054
|
+
let l = this.chmod && t.mode && (h.mode & 4095) !== t.mode, c = (d) => this[P](d ?? null, t, i);
|
|
3055
|
+
return l ? Kt.chmod(String(t.absolute), Number(t.mode), c) : c();
|
|
3056
|
+
}
|
|
3057
|
+
if (t.absolute !== this.cwd) return Kt.rmdir(String(t.absolute), (l) => this[P](l ?? null, t, i));
|
|
3058
|
+
}
|
|
3059
|
+
if (t.absolute === this.cwd) return this[P](null, t, i);
|
|
3060
|
+
ao(String(t.absolute), (l) => this[P](l ?? null, t, i));
|
|
3061
|
+
});
|
|
3062
|
+
};
|
|
3063
|
+
this[_e] ? n() : r();
|
|
3064
|
+
}
|
|
3065
|
+
[P](t, e, i) {
|
|
3066
|
+
if (t) {
|
|
3067
|
+
this[O](t, e), i();
|
|
3068
|
+
return;
|
|
3069
|
+
}
|
|
3070
|
+
switch (e.type) {
|
|
3071
|
+
case "File":
|
|
3072
|
+
case "OldFile":
|
|
3073
|
+
case "ContiguousFile": return this[_s](e, i);
|
|
3074
|
+
case "Link": return this[Nr](e, i);
|
|
3075
|
+
case "SymbolicLink": return this[Lr](e, i);
|
|
3076
|
+
case "Directory":
|
|
3077
|
+
case "GNUDumpDir": return this[Os](e, i);
|
|
3078
|
+
}
|
|
3079
|
+
}
|
|
3080
|
+
[Ri](t, e, i, r) {
|
|
3081
|
+
Kt[i](e, String(t.absolute), (n) => {
|
|
3082
|
+
n ? this[O](n, t) : (this[$t](), t.resume()), r();
|
|
3083
|
+
});
|
|
3084
|
+
}
|
|
3085
|
+
}, Se = (s) => {
|
|
3086
|
+
try {
|
|
3087
|
+
return [null, s()];
|
|
3088
|
+
} catch (t) {
|
|
3089
|
+
return [t, null];
|
|
3090
|
+
}
|
|
3091
|
+
}, Te = class extends Xt {
|
|
3092
|
+
sync = !0;
|
|
3093
|
+
[P](t, e) {
|
|
3094
|
+
return super[P](t, e, () => {});
|
|
3095
|
+
}
|
|
3096
|
+
[gs](t) {
|
|
3097
|
+
if (!this[_e]) {
|
|
3098
|
+
let n = this[yt](this.cwd, this.dmode);
|
|
3099
|
+
if (n) return this[O](n, t);
|
|
3100
|
+
this[_e] = !0;
|
|
3101
|
+
}
|
|
3102
|
+
if (t.absolute !== this.cwd) {
|
|
3103
|
+
let n = f(path.dirname(String(t.absolute)));
|
|
3104
|
+
if (n !== this.cwd) {
|
|
3105
|
+
let o = this[yt](n, this.dmode);
|
|
3106
|
+
if (o) return this[O](o, t);
|
|
3107
|
+
}
|
|
3108
|
+
}
|
|
3109
|
+
let [e, i] = Se(() => Kt.lstatSync(String(t.absolute)));
|
|
3110
|
+
if (i && (this.keep || this.newer && i.mtime > (t.mtime ?? i.mtime))) return this[Ts](t);
|
|
3111
|
+
if (e || this[bs](t, i)) return this[P](null, t);
|
|
3112
|
+
if (i.isDirectory()) {
|
|
3113
|
+
if (t.type === "Directory") {
|
|
3114
|
+
let [a] = this.chmod && t.mode && (i.mode & 4095) !== t.mode ? Se(() => {
|
|
3115
|
+
Kt.chmodSync(String(t.absolute), Number(t.mode));
|
|
3116
|
+
}) : [];
|
|
3117
|
+
return this[P](a, t);
|
|
3118
|
+
}
|
|
3119
|
+
let [n] = Se(() => Kt.rmdirSync(String(t.absolute)));
|
|
3120
|
+
this[P](n, t);
|
|
3121
|
+
}
|
|
3122
|
+
let [r] = t.absolute === this.cwd ? [] : Se(() => lo(String(t.absolute)));
|
|
3123
|
+
this[P](r, t);
|
|
3124
|
+
}
|
|
3125
|
+
[_s](t, e) {
|
|
3126
|
+
let i = typeof t.mode == "number" ? t.mode & 4095 : this.fmode, r = (a) => {
|
|
3127
|
+
let h;
|
|
3128
|
+
try {
|
|
3129
|
+
Kt.closeSync(n);
|
|
3130
|
+
} catch (l) {
|
|
3131
|
+
h = l;
|
|
3132
|
+
}
|
|
3133
|
+
(a || h) && this[O](a || h, t), e();
|
|
3134
|
+
}, n;
|
|
3135
|
+
try {
|
|
3136
|
+
n = Kt.openSync(String(t.absolute), ds(t.size), i);
|
|
3137
|
+
} catch (a) {
|
|
3138
|
+
return r(a);
|
|
3139
|
+
}
|
|
3140
|
+
let o = this.transform && this.transform(t) || t;
|
|
3141
|
+
o !== t && (o.on("error", (a) => this[O](a, t)), t.pipe(o)), o.on("data", (a) => {
|
|
3142
|
+
try {
|
|
3143
|
+
Kt.writeSync(n, a, 0, a.length);
|
|
3144
|
+
} catch (h) {
|
|
3145
|
+
r(h);
|
|
3146
|
+
}
|
|
3147
|
+
}), o.on("end", () => {
|
|
3148
|
+
let a = null;
|
|
3149
|
+
if (t.mtime && !this.noMtime) {
|
|
3150
|
+
let h = t.atime || /* @__PURE__ */ new Date(), l = t.mtime;
|
|
3151
|
+
try {
|
|
3152
|
+
Kt.futimesSync(n, h, l);
|
|
3153
|
+
} catch (c) {
|
|
3154
|
+
try {
|
|
3155
|
+
Kt.utimesSync(String(t.absolute), h, l);
|
|
3156
|
+
} catch {
|
|
3157
|
+
a = c;
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
}
|
|
3161
|
+
if (this[Re](t)) {
|
|
3162
|
+
let h = this[ge](t), l = this[be](t);
|
|
3163
|
+
try {
|
|
3164
|
+
Kt.fchownSync(n, Number(h), Number(l));
|
|
3165
|
+
} catch (c) {
|
|
3166
|
+
try {
|
|
3167
|
+
Kt.chownSync(String(t.absolute), Number(h), Number(l));
|
|
3168
|
+
} catch {
|
|
3169
|
+
a = a || c;
|
|
3170
|
+
}
|
|
3171
|
+
}
|
|
3172
|
+
}
|
|
3173
|
+
r(a);
|
|
3174
|
+
});
|
|
3175
|
+
}
|
|
3176
|
+
[Os](t, e) {
|
|
3177
|
+
let i = typeof t.mode == "number" ? t.mode & 4095 : this.dmode, r = this[yt](String(t.absolute), i);
|
|
3178
|
+
if (r) {
|
|
3179
|
+
this[O](r, t), e();
|
|
3180
|
+
return;
|
|
3181
|
+
}
|
|
3182
|
+
if (t.mtime && !this.noMtime) try {
|
|
3183
|
+
Kt.utimesSync(String(t.absolute), t.atime || /* @__PURE__ */ new Date(), t.mtime);
|
|
3184
|
+
} catch {}
|
|
3185
|
+
if (this[Re](t)) try {
|
|
3186
|
+
Kt.chownSync(String(t.absolute), Number(this[ge](t)), Number(this[be](t)));
|
|
3187
|
+
} catch {}
|
|
3188
|
+
e(), t.resume();
|
|
3189
|
+
}
|
|
3190
|
+
[yt](t, e) {
|
|
3191
|
+
try {
|
|
3192
|
+
return Rr(f(t), {
|
|
3193
|
+
uid: this.uid,
|
|
3194
|
+
gid: this.gid,
|
|
3195
|
+
processUid: this.processUid,
|
|
3196
|
+
processGid: this.processGid,
|
|
3197
|
+
umask: this.processUmask,
|
|
3198
|
+
preserve: this.preservePaths,
|
|
3199
|
+
unlink: this.unlink,
|
|
3200
|
+
cwd: this.cwd,
|
|
3201
|
+
mode: e
|
|
3202
|
+
});
|
|
3203
|
+
} catch (i) {
|
|
3204
|
+
return i;
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
[ye](t, e, i, r, n) {
|
|
3208
|
+
if (this.preservePaths || i.length === 0) return r();
|
|
3209
|
+
let o = e;
|
|
3210
|
+
for (let a of i) {
|
|
3211
|
+
o = path.resolve(o, a);
|
|
3212
|
+
let [h, l] = Se(() => Kt.lstatSync(o));
|
|
3213
|
+
if (h) return r();
|
|
3214
|
+
if (l.isSymbolicLink()) return n(new St(o, path.resolve(e, i.join("/"))));
|
|
3215
|
+
}
|
|
3216
|
+
r();
|
|
3217
|
+
}
|
|
3218
|
+
[Ri](t, e, i, r) {
|
|
3219
|
+
let n = `${i}Sync`;
|
|
3220
|
+
try {
|
|
3221
|
+
Kt[n](e, String(t.absolute)), r(), t.resume();
|
|
3222
|
+
} catch (o) {
|
|
3223
|
+
return this[O](o, t);
|
|
3224
|
+
}
|
|
3225
|
+
}
|
|
3226
|
+
}, co = (s) => {
|
|
3227
|
+
let t = new Te(s), e = s.file, i = Kt.statSync(e);
|
|
3228
|
+
new Me(e, {
|
|
3229
|
+
readSize: s.maxReadSize || 16 * 1024 * 1024,
|
|
3230
|
+
size: i.size
|
|
3231
|
+
}).pipe(t);
|
|
3232
|
+
}, fo = (s, t) => {
|
|
3233
|
+
let e = new Xt(s), i = s.maxReadSize || 16 * 1024 * 1024, r = s.file;
|
|
3234
|
+
return new Promise((o, a) => {
|
|
3235
|
+
e.on("error", a), e.on("close", o), Kt.stat(r, (h, l) => {
|
|
3236
|
+
if (h) a(h);
|
|
3237
|
+
else {
|
|
3238
|
+
let c = new _t(r, {
|
|
3239
|
+
readSize: i,
|
|
3240
|
+
size: l.size
|
|
3241
|
+
});
|
|
3242
|
+
c.on("error", a), c.pipe(e);
|
|
3243
|
+
}
|
|
3244
|
+
});
|
|
3245
|
+
});
|
|
3246
|
+
};
|
|
3247
|
+
K(co, fo, (s) => new Te(s), (s) => new Xt(s), (s, t) => {
|
|
3248
|
+
t?.length && Xi(s, t);
|
|
3249
|
+
});
|
|
3250
|
+
var mo = (s, t) => {
|
|
3251
|
+
let e = new kt(s), i = !0, r, n;
|
|
3252
|
+
try {
|
|
3253
|
+
try {
|
|
3254
|
+
r = Kt.openSync(s.file, "r+");
|
|
3255
|
+
} catch (h) {
|
|
3256
|
+
if (h?.code === "ENOENT") r = Kt.openSync(s.file, "w+");
|
|
3257
|
+
else throw h;
|
|
3258
|
+
}
|
|
3259
|
+
let o = Kt.fstatSync(r), a = Buffer.alloc(512);
|
|
3260
|
+
t: for (n = 0; n < o.size; n += 512) {
|
|
3261
|
+
for (let c = 0, d = 0; c < 512; c += d) {
|
|
3262
|
+
if (d = Kt.readSync(r, a, c, a.length - c, n + c), n === 0 && a[0] === 31 && a[1] === 139) throw new Error("cannot append to compressed archives");
|
|
3263
|
+
if (!d) break t;
|
|
3264
|
+
}
|
|
3265
|
+
let h = new C(a);
|
|
3266
|
+
if (!h.cksumValid) break;
|
|
3267
|
+
let l = 512 * Math.ceil((h.size || 0) / 512);
|
|
3268
|
+
if (n + l + 512 > o.size) break;
|
|
3269
|
+
n += l, s.mtimeCache && h.mtime && s.mtimeCache.set(String(h.path), h.mtime);
|
|
3270
|
+
}
|
|
3271
|
+
i = !1, po(s, e, n, r, t);
|
|
3272
|
+
} finally {
|
|
3273
|
+
if (i) try {
|
|
3274
|
+
Kt.closeSync(r);
|
|
3275
|
+
} catch {}
|
|
3276
|
+
}
|
|
3277
|
+
}, po = (s, t, e, i, r) => {
|
|
3278
|
+
let n = new Wt(s.file, {
|
|
3279
|
+
fd: i,
|
|
3280
|
+
start: e
|
|
3281
|
+
});
|
|
3282
|
+
t.pipe(n), wo(t, r);
|
|
3283
|
+
}, Eo = (s, t) => {
|
|
3284
|
+
t = Array.from(t);
|
|
3285
|
+
let e = new wt(s), i = (n, o, a) => {
|
|
3286
|
+
let h = (T, N) => {
|
|
3287
|
+
T ? Kt.close(n, (E) => a(T)) : a(null, N);
|
|
3288
|
+
}, l = 0;
|
|
3289
|
+
if (o === 0) return h(null, 0);
|
|
3290
|
+
let c = 0, d = Buffer.alloc(512), S = (T, N) => {
|
|
3291
|
+
if (T || N === void 0) return h(T);
|
|
3292
|
+
if (c += N, c < 512 && N) return Kt.read(n, d, c, d.length - c, l + c, S);
|
|
3293
|
+
if (l === 0 && d[0] === 31 && d[1] === 139) return h(/* @__PURE__ */ new Error("cannot append to compressed archives"));
|
|
3294
|
+
if (c < 512) return h(null, l);
|
|
3295
|
+
let E = new C(d);
|
|
3296
|
+
if (!E.cksumValid) return h(null, l);
|
|
3297
|
+
let x = 512 * Math.ceil((E.size ?? 0) / 512);
|
|
3298
|
+
if (l + x + 512 > o || (l += x + 512, l >= o)) return h(null, l);
|
|
3299
|
+
s.mtimeCache && E.mtime && s.mtimeCache.set(String(E.path), E.mtime), c = 0, Kt.read(n, d, 0, 512, l, S);
|
|
3300
|
+
};
|
|
3301
|
+
Kt.read(n, d, 0, 512, l, S);
|
|
3302
|
+
};
|
|
3303
|
+
return new Promise((n, o) => {
|
|
3304
|
+
e.on("error", o);
|
|
3305
|
+
let a = "r+", h = (l, c) => {
|
|
3306
|
+
if (l && l.code === "ENOENT" && a === "r+") return a = "w+", Kt.open(s.file, a, h);
|
|
3307
|
+
if (l || !c) return o(l);
|
|
3308
|
+
Kt.fstat(c, (d, S) => {
|
|
3309
|
+
if (d) return Kt.close(c, () => o(d));
|
|
3310
|
+
i(c, S.size, (T, N) => {
|
|
3311
|
+
if (T) return o(T);
|
|
3312
|
+
let E = new tt(s.file, {
|
|
3313
|
+
fd: c,
|
|
3314
|
+
start: N
|
|
3315
|
+
});
|
|
3316
|
+
e.pipe(E), E.on("error", o), E.on("close", n), So(e, t);
|
|
3317
|
+
});
|
|
3318
|
+
});
|
|
3319
|
+
};
|
|
3320
|
+
Kt.open(s.file, a, h);
|
|
3321
|
+
});
|
|
3322
|
+
}, wo = (s, t) => {
|
|
3323
|
+
t.forEach((e) => {
|
|
3324
|
+
e.charAt(0) === "@" ? Ft({
|
|
3325
|
+
file: path.resolve(s.cwd, e.slice(1)),
|
|
3326
|
+
sync: !0,
|
|
3327
|
+
noResume: !0,
|
|
3328
|
+
onReadEntry: (i) => s.add(i)
|
|
3329
|
+
}) : s.add(e);
|
|
3330
|
+
}), s.end();
|
|
3331
|
+
}, So = async (s, t) => {
|
|
3332
|
+
for (let e of t) e.charAt(0) === "@" ? await Ft({
|
|
3333
|
+
file: path.resolve(String(s.cwd), e.slice(1)),
|
|
3334
|
+
noResume: !0,
|
|
3335
|
+
onReadEntry: (i) => s.add(i)
|
|
3336
|
+
}) : s.add(e);
|
|
3337
|
+
s.end();
|
|
3338
|
+
}, vt = K(mo, Eo, () => {
|
|
3339
|
+
throw new TypeError("file is required");
|
|
3340
|
+
}, () => {
|
|
3341
|
+
throw new TypeError("file is required");
|
|
3342
|
+
}, (s, t) => {
|
|
3343
|
+
if (!vs(s)) throw new TypeError("file is required");
|
|
3344
|
+
if (s.gzip || s.brotli || s.zstd || s.file.endsWith(".br") || s.file.endsWith(".tbr")) throw new TypeError("cannot append to compressed archives");
|
|
3345
|
+
if (!t?.length) throw new TypeError("no paths specified to add/replace");
|
|
3346
|
+
});
|
|
3347
|
+
K(vt.syncFile, vt.asyncFile, vt.syncNoFile, vt.asyncNoFile, (s, t = []) => {
|
|
3348
|
+
vt.validate?.(s, t), Ro(s);
|
|
3349
|
+
});
|
|
3350
|
+
var Ro = (s) => {
|
|
3351
|
+
let t = s.filter;
|
|
3352
|
+
s.mtimeCache || (s.mtimeCache = /* @__PURE__ */ new Map()), s.filter = t ? (e, i) => t(e, i) && !((s.mtimeCache?.get(e) ?? i.mtime ?? 0) > (i.mtime ?? 0)) : (e, i) => !((s.mtimeCache?.get(e) ?? i.mtime ?? 0) > (i.mtime ?? 0));
|
|
3353
|
+
};
|
|
3354
|
+
//#endregion
|
|
3355
|
+
//#region src/builtins/system-backup/system-backup.service.ts
|
|
3356
|
+
/**
|
|
3357
|
+
* Thrown when an archive build (or a backup run driving one) is
|
|
3358
|
+
* stopped via its `AbortSignal`. Callers use `instanceof` to tell a
|
|
3359
|
+
* deliberate operator cancel from a real failure — a cancelled run is
|
|
3360
|
+
* an outcome, not an error to alert on. (D342)
|
|
3361
|
+
*/
|
|
3362
|
+
var BackupCancelledError = class extends Error {
|
|
3363
|
+
constructor(message = "backup run cancelled") {
|
|
3364
|
+
super(message);
|
|
3365
|
+
this.name = "BackupCancelledError";
|
|
3366
|
+
}
|
|
3367
|
+
};
|
|
3368
|
+
/**
|
|
3369
|
+
* Thrown when an archive would carry a live database and its owner could not
|
|
3370
|
+
* produce a verified snapshot of it (D693). Nothing was built: a run that
|
|
3371
|
+
* "succeeded" without the database — or with a torn copy of it — would push
|
|
3372
|
+
* the oldest good archive out of every destination's retention.
|
|
3373
|
+
*/
|
|
3374
|
+
var BackupSnapshotRefusedError = class extends Error {
|
|
3375
|
+
constructor(reason) {
|
|
3376
|
+
super(`settings database snapshot failed — no archive built, nothing uploaded, retention untouched: ${reason}`);
|
|
3377
|
+
this.name = "BackupSnapshotRefusedError";
|
|
3378
|
+
}
|
|
3379
|
+
};
|
|
3380
|
+
/**
|
|
3381
|
+
* Settle with `pending`, or reject with {@link BackupCancelledError} as soon as
|
|
3382
|
+
* `signal` fires. A pending call abandoned by the cancel still settles later:
|
|
3383
|
+
* `onAbandoned` runs then, to clean up what it produced.
|
|
3384
|
+
*/
|
|
3385
|
+
function raceAbort(pending, signal, onAbandoned) {
|
|
3386
|
+
if (signal === void 0) return pending;
|
|
3387
|
+
return new Promise((resolve, reject) => {
|
|
3388
|
+
let abandoned = false;
|
|
3389
|
+
const onAbort = () => {
|
|
3390
|
+
abandoned = true;
|
|
3391
|
+
reject(new BackupCancelledError());
|
|
3392
|
+
};
|
|
3393
|
+
if (signal.aborted) onAbort();
|
|
3394
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
3395
|
+
pending.then((value) => {
|
|
3396
|
+
signal.removeEventListener("abort", onAbort);
|
|
3397
|
+
if (abandoned) onAbandoned();
|
|
3398
|
+
else resolve(value);
|
|
3399
|
+
}, (err) => {
|
|
3400
|
+
signal.removeEventListener("abort", onAbort);
|
|
3401
|
+
if (abandoned) onAbandoned();
|
|
3402
|
+
else reject(err);
|
|
3403
|
+
});
|
|
3404
|
+
});
|
|
3405
|
+
}
|
|
3406
|
+
/** Throw `BackupCancelledError` when the signal has fired. */
|
|
3407
|
+
function throwIfCancelled(signal) {
|
|
3408
|
+
if (signal?.aborted) throw new BackupCancelledError();
|
|
3409
|
+
}
|
|
3410
|
+
/**
|
|
3411
|
+
* Default set of paths considered part of a "system backup". Includes
|
|
3412
|
+
* everything that isn't pure backend code — config, sqlite, addons
|
|
3413
|
+
* (runtime overlay), addons-data (per-addon private dir), TLS certs,
|
|
3414
|
+
* auto-update marker.
|
|
3415
|
+
*
|
|
3416
|
+
* Anything not listed is excluded by omission — recordings/, media/,
|
|
3417
|
+
* models/, logs/, cache/ (too large or fully recreatable). Note this
|
|
3418
|
+
* covers only TOP-LEVEL trees: bulk nested INSIDE a listed location
|
|
3419
|
+
* is excluded via `DEFAULT_BACKUP_EXCLUDES` + the node_modules rule
|
|
3420
|
+
* below, enforced in the walk and the tar filter alike.
|
|
3421
|
+
*/
|
|
3422
|
+
var DEFAULT_BACKUP_LOCATIONS = [
|
|
3423
|
+
"config.yaml",
|
|
3424
|
+
"addons",
|
|
3425
|
+
"addons-data",
|
|
3426
|
+
"tls",
|
|
3427
|
+
"auto-update.json"
|
|
3428
|
+
];
|
|
3429
|
+
/**
|
|
3430
|
+
* Subtrees never captured by a system backup even though they live
|
|
3431
|
+
* under a `DEFAULT_BACKUP_LOCATIONS` entry. Paths are dataDir-relative
|
|
3432
|
+
* prefixes. Two lessons from the live hub (2026-09-04, D-record
|
|
3433
|
+
* "backup excludes"):
|
|
3434
|
+
*
|
|
3435
|
+
* - `addons-data/backup-orchestrator/staging` — the orchestrator's
|
|
3436
|
+
* LEGACY staging dir (now `<dataDir>/backup-staging`, outside every
|
|
3437
|
+
* location). Before Jul 28 every archive nested all previous
|
|
3438
|
+
* archives (175M → 503M → 4.5G); leaked files from that era must
|
|
3439
|
+
* never be re-swept into new backups.
|
|
3440
|
+
* - `addons-data/recorder/exports` — operator-exported clips (8.4 GB
|
|
3441
|
+
* on the hub). Media, not system state; a restore has no use for it.
|
|
3442
|
+
*/
|
|
3443
|
+
var DEFAULT_BACKUP_EXCLUDES = ["addons-data/backup-orchestrator/staging", "addons-data/recorder/exports"];
|
|
3444
|
+
/**
|
|
3445
|
+
* Directory name excluded wherever it appears in the tree.
|
|
3446
|
+
* `AddonInstaller` materialises runtime deps under
|
|
3447
|
+
* `addons/@camstack/<addon>/node_modules` (~196 MB on the hub); only
|
|
3448
|
+
* built `dist` + package.json + assets are restore-worthy — deps are
|
|
3449
|
+
* reinstalled from npm on demand. node_modules is NEVER archived.
|
|
3450
|
+
*/
|
|
3451
|
+
var EXCLUDED_DIR_NAME = "node_modules";
|
|
3452
|
+
/**
|
|
3453
|
+
* True when a dataDir-relative path must be omitted from archives,
|
|
3454
|
+
* manifests and location stats. Accepts tar-style paths (`./` prefix,
|
|
3455
|
+
* trailing `/`) and backslash separators.
|
|
3456
|
+
*/
|
|
3457
|
+
function isExcludedFromBackup(relPath) {
|
|
3458
|
+
const norm = normalizeArchivePath(relPath);
|
|
3459
|
+
if (norm.length === 0) return false;
|
|
3460
|
+
const segments = norm.split("/");
|
|
3461
|
+
if (segments.includes(EXCLUDED_DIR_NAME)) return true;
|
|
3462
|
+
if (segments.some((seg) => seg.endsWith(".backup-snapshot-partial"))) return true;
|
|
3463
|
+
if (norm.endsWith(".backup-snapshot")) return true;
|
|
3464
|
+
return DEFAULT_BACKUP_EXCLUDES.some((prefix) => norm === prefix || norm.startsWith(`${prefix}/`));
|
|
3465
|
+
}
|
|
3466
|
+
/** `./a/b/` and `a\\b` → `a/b`: the one spelling every archive-path comparison uses. */
|
|
3467
|
+
function normalizeArchivePath(relPath) {
|
|
3468
|
+
return relPath.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+$/, "");
|
|
3469
|
+
}
|
|
3470
|
+
/** The files SQLite keeps beside a database. A live one is never archived. */
|
|
3471
|
+
var SQLITE_SIDECAR_SUFFIXES = [
|
|
3472
|
+
"-wal",
|
|
3473
|
+
"-shm",
|
|
3474
|
+
"-journal"
|
|
3475
|
+
];
|
|
3476
|
+
var SQLITE_DATABASE_SUFFIXES = [
|
|
3477
|
+
".db",
|
|
3478
|
+
".sqlite",
|
|
3479
|
+
".sqlite3"
|
|
3480
|
+
];
|
|
3481
|
+
/**
|
|
3482
|
+
* The database a `-wal` / `-shm` / `-journal` belongs to, or null for any other
|
|
3483
|
+
* path. The base must name a database (`.db` / `.sqlite` / `.sqlite3`): a
|
|
3484
|
+
* `build-journal` is not a sidecar, and must not stop every backup as a "live
|
|
3485
|
+
* database" that does not exist.
|
|
3486
|
+
*/
|
|
3487
|
+
function databaseOfSidecar(relPath) {
|
|
3488
|
+
for (const suffix of SQLITE_SIDECAR_SUFFIXES) {
|
|
3489
|
+
if (!relPath.endsWith(suffix)) continue;
|
|
3490
|
+
const db = relPath.slice(0, -suffix.length);
|
|
3491
|
+
return SQLITE_DATABASE_SUFFIXES.some((dbSuffix) => db.endsWith(dbSuffix)) ? db : null;
|
|
3492
|
+
}
|
|
3493
|
+
return null;
|
|
3494
|
+
}
|
|
3495
|
+
/** A SQLite database file, or a sidecar of one. */
|
|
3496
|
+
function isSqlitePath(relPath) {
|
|
3497
|
+
const db = databaseOfSidecar(relPath) ?? relPath;
|
|
3498
|
+
return SQLITE_DATABASE_SUFFIXES.some((suffix) => db.endsWith(suffix));
|
|
3499
|
+
}
|
|
3500
|
+
/** Path of the manifest file embedded inside every archive. */
|
|
3501
|
+
var ARCHIVE_MANIFEST_NAME = ".camstack-backup-manifest.json";
|
|
3502
|
+
var DEFAULT_STAT_CACHE_TTL_MS = 6e4;
|
|
3503
|
+
/**
|
|
3504
|
+
* System-level archive primitives. Construct one per server boot;
|
|
3505
|
+
* methods are pure I/O.
|
|
3506
|
+
*/
|
|
3507
|
+
var SystemBackupService = class {
|
|
3508
|
+
dataDir;
|
|
3509
|
+
logger;
|
|
3510
|
+
statCacheTtlMs;
|
|
3511
|
+
statCache = /* @__PURE__ */ new Map();
|
|
3512
|
+
constructor(dataDir, logger, opts) {
|
|
3513
|
+
this.dataDir = dataDir;
|
|
3514
|
+
this.logger = logger;
|
|
3515
|
+
this.statCacheTtlMs = opts?.statCacheTtlMs ?? DEFAULT_STAT_CACHE_TTL_MS;
|
|
3516
|
+
}
|
|
3517
|
+
/**
|
|
3518
|
+
* Snapshot the current size + file count of each well-known
|
|
3519
|
+
* location. Used by the admin UI to render an opt-in checklist
|
|
3520
|
+
* before triggering a backup, and by `createArchive` to derive the
|
|
3521
|
+
* embedded manifest.
|
|
3522
|
+
*
|
|
3523
|
+
* The walk is async (yields to the event loop per directory) and
|
|
3524
|
+
* per-location results are cached + single-flighted: the service
|
|
3525
|
+
* runs in-process in the hub, and a synchronous walk of the 70k+
|
|
3526
|
+
* file `addons` location blocked the event loop long enough to kill
|
|
3527
|
+
* WS keepalives cluster-wide.
|
|
3528
|
+
*/
|
|
3529
|
+
statLocations(locations = DEFAULT_BACKUP_LOCATIONS) {
|
|
3530
|
+
return Promise.all(locations.map((loc) => this.statLocationCached(loc)));
|
|
3531
|
+
}
|
|
3532
|
+
statLocationCached(loc) {
|
|
3533
|
+
const now = Date.now();
|
|
3534
|
+
const hit = this.statCache.get(loc);
|
|
3535
|
+
if (hit && now - hit.at < this.statCacheTtlMs) return hit.value;
|
|
3536
|
+
const value = this.statLocation(loc);
|
|
3537
|
+
this.statCache.set(loc, {
|
|
3538
|
+
at: now,
|
|
3539
|
+
value
|
|
3540
|
+
});
|
|
3541
|
+
value.catch(() => this.statCache.delete(loc));
|
|
3542
|
+
return value;
|
|
3543
|
+
}
|
|
3544
|
+
async statLocation(loc) {
|
|
3545
|
+
const abs = path$1.isAbsolute(loc) ? loc : path$1.join(this.dataDir, loc);
|
|
3546
|
+
if (!fs$1.existsSync(abs)) return {
|
|
3547
|
+
name: loc,
|
|
3548
|
+
sizeBytes: 0,
|
|
3549
|
+
fileCount: 0,
|
|
3550
|
+
present: false
|
|
3551
|
+
};
|
|
3552
|
+
const walked = await walkAbs(abs, abs, this.exclusionPredicate());
|
|
3553
|
+
return {
|
|
3554
|
+
name: loc,
|
|
3555
|
+
sizeBytes: walked.reduce((acc, e) => acc + e.sizeBytes, 0),
|
|
3556
|
+
fileCount: walked.filter((e) => e.kind === "file").length,
|
|
3557
|
+
present: true
|
|
3558
|
+
};
|
|
3559
|
+
}
|
|
3560
|
+
/**
|
|
3561
|
+
* Create a tar.gz of the given locations. Uses the `tar` npm package
|
|
3562
|
+
* (used by npm itself) instead of shelling out — gives us:
|
|
3563
|
+
*
|
|
3564
|
+
* - Symlink dereference (`follow: true`) so dev mode's
|
|
3565
|
+
* `addons/<name> → packages/<name>` overlay archives content,
|
|
3566
|
+
* not just link stubs.
|
|
3567
|
+
* - Programmatic walk → we build a manifest of every entry while
|
|
3568
|
+
* copying so the archive can self-describe.
|
|
3569
|
+
*
|
|
3570
|
+
* Locations that don't exist are silently skipped. Throws if zero
|
|
3571
|
+
* locations would be included.
|
|
3572
|
+
*
|
|
3573
|
+
* Cancellation: `signal` aborts the build IN FLIGHT — the manifest
|
|
3574
|
+
* walk checks it per filesystem node and the tar phase runs through
|
|
3575
|
+
* `stream.pipeline(..., { signal })`, which destroys the pack and
|
|
3576
|
+
* the file sink immediately. On abort the half-written archive is
|
|
3577
|
+
* deleted here (never left for the caller to remember) and the call
|
|
3578
|
+
* rejects with {@link BackupCancelledError}. (D342)
|
|
3579
|
+
*
|
|
3580
|
+
* Progress: `onArchiveBytes` receives the cumulative compressed
|
|
3581
|
+
* bytes written to `archivePath` — the live "how large has staging
|
|
3582
|
+
* grown" counter `backup.listRuns` exposes.
|
|
3583
|
+
*/
|
|
3584
|
+
async createArchive(opts) {
|
|
3585
|
+
throwIfCancelled(opts.signal);
|
|
3586
|
+
const recipient = opts.encryptTo !== void 0 ? parseBackupPublicKey(opts.encryptTo) : null;
|
|
3587
|
+
const requested = opts.locations ?? DEFAULT_BACKUP_LOCATIONS;
|
|
3588
|
+
const present = [];
|
|
3589
|
+
for (const loc of requested) {
|
|
3590
|
+
const abs = path$1.isAbsolute(loc) ? loc : path$1.join(this.dataDir, loc);
|
|
3591
|
+
if (fs$1.existsSync(abs)) present.push(loc);
|
|
3592
|
+
else this.logger.debug("createArchive: skipping missing location", { meta: { location: loc } });
|
|
3593
|
+
}
|
|
3594
|
+
if (present.length === 0) throw new Error(`createArchive: no locations from {${requested.join(", ")}} exist under ${this.dataDir}`);
|
|
3595
|
+
fs$1.mkdirSync(path$1.dirname(opts.archivePath), { recursive: true });
|
|
3596
|
+
const walked = [];
|
|
3597
|
+
for (const loc of present) {
|
|
3598
|
+
throwIfCancelled(opts.signal);
|
|
3599
|
+
const abs = path$1.join(this.dataDir, loc);
|
|
3600
|
+
const stat = await fsp.stat(abs);
|
|
3601
|
+
if (stat.isDirectory()) for (const e of await walkAbs(abs, this.dataDir, this.exclusionPredicate(), opts.signal)) walked.push(e);
|
|
3602
|
+
else if (!isExcludedFromBackup(path$1.relative(this.dataDir, abs))) walked.push(toArchiveEntry(abs, this.dataDir, stat));
|
|
3603
|
+
}
|
|
3604
|
+
const walkedPaths = new Set(walked.map((e) => e.path));
|
|
3605
|
+
const owned = walked.some((e) => isSqlitePath(e.path)) ? await this.ownedDatabasesInScope(opts.owner, walkedPaths) : /* @__PURE__ */ new Set();
|
|
3606
|
+
const unowned = /* @__PURE__ */ new Set();
|
|
3607
|
+
for (const e of walked) {
|
|
3608
|
+
const db = databaseOfSidecar(e.path);
|
|
3609
|
+
if (db !== null && !owned.has(db)) unowned.add(db);
|
|
3610
|
+
}
|
|
3611
|
+
if (unowned.size > 0) {
|
|
3612
|
+
const databases = [...unowned].sort();
|
|
3613
|
+
this.logger.error("createArchive: a live SQLite database has no owner snapshot — no archive built", { meta: {
|
|
3614
|
+
databases,
|
|
3615
|
+
archivePath: opts.archivePath
|
|
3616
|
+
} });
|
|
3617
|
+
throw new BackupSnapshotRefusedError(`live SQLite database ${databases.join(", ")} has no owner that can snapshot it — a copy of its files would be torn; remove its stale -wal/-shm/-journal if nothing has it open, or leave its location out of the backup`);
|
|
3618
|
+
}
|
|
3619
|
+
const snapshot = owned.size > 0 && opts.owner ? await this.takeOwnerSnapshot(opts.owner, owned, opts.signal) : null;
|
|
3620
|
+
try {
|
|
3621
|
+
const liveFiles = /* @__PURE__ */ new Set();
|
|
3622
|
+
for (const db of owned) {
|
|
3623
|
+
liveFiles.add(db);
|
|
3624
|
+
for (const suffix of SQLITE_SIDECAR_SUFFIXES) liveFiles.add(db + suffix);
|
|
3625
|
+
}
|
|
3626
|
+
const entries = walked.filter((e) => !liveFiles.has(e.path));
|
|
3627
|
+
if (snapshot !== null) entries.push(snapshot.entry);
|
|
3628
|
+
const manifest = {
|
|
3629
|
+
archiveVersion: 1,
|
|
3630
|
+
createdAt: Date.now(),
|
|
3631
|
+
dataDir: this.dataDir,
|
|
3632
|
+
locations: present,
|
|
3633
|
+
entries,
|
|
3634
|
+
totalBytes: entries.reduce((acc, e) => acc + e.sizeBytes, 0),
|
|
3635
|
+
totalFiles: entries.filter((e) => e.kind === "file").length,
|
|
3636
|
+
...snapshot !== null ? { sqliteSnapshots: [snapshot.archived] } : {}
|
|
3637
|
+
};
|
|
3638
|
+
const carriedSnapshot = snapshot?.archived.snapshotPath ?? null;
|
|
3639
|
+
return await this.writeArchive({
|
|
3640
|
+
archivePath: opts.archivePath,
|
|
3641
|
+
present,
|
|
3642
|
+
manifest,
|
|
3643
|
+
excluded: (rel) => {
|
|
3644
|
+
if (rel === carriedSnapshot) return false;
|
|
3645
|
+
return liveFiles.has(rel) || isExcludedFromBackup(rel);
|
|
3646
|
+
},
|
|
3647
|
+
...opts.signal ? { signal: opts.signal } : {},
|
|
3648
|
+
...opts.onArchiveBytes ? { onArchiveBytes: opts.onArchiveBytes } : {},
|
|
3649
|
+
...opts.encryptTo !== void 0 ? { encryptTo: opts.encryptTo } : {}
|
|
3650
|
+
}).then((result) => recipient === null ? result : {
|
|
3651
|
+
...result,
|
|
3652
|
+
encryption: {
|
|
3653
|
+
scheme: BACKUP_ENCRYPTION_SCHEME,
|
|
3654
|
+
keyId: recipient.keyId
|
|
3655
|
+
}
|
|
3656
|
+
});
|
|
3657
|
+
} finally {
|
|
3658
|
+
if (snapshot !== null) await this.removeSnapshot(snapshot.absPath);
|
|
3659
|
+
}
|
|
3660
|
+
}
|
|
3661
|
+
/**
|
|
3662
|
+
* Tar `present` (filtered by `excluded`) plus the staged manifest into
|
|
3663
|
+
* `archivePath`.
|
|
3664
|
+
*/
|
|
3665
|
+
async writeArchive(opts) {
|
|
3666
|
+
const { present, manifest } = opts;
|
|
3667
|
+
const manifestStagePath = `${opts.archivePath}.${process.pid}.manifest.json`;
|
|
3668
|
+
fs$1.writeFileSync(manifestStagePath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
3669
|
+
this.logger.info("createArchive: tarring", { meta: {
|
|
3670
|
+
archivePath: opts.archivePath,
|
|
3671
|
+
locations: [...present],
|
|
3672
|
+
totalFiles: manifest.totalFiles,
|
|
3673
|
+
totalBytes: manifest.totalBytes
|
|
3674
|
+
} });
|
|
3675
|
+
try {
|
|
3676
|
+
const stagedInDataDir = path$1.join(this.dataDir, ARCHIVE_MANIFEST_NAME);
|
|
3677
|
+
fs$1.copyFileSync(manifestStagePath, stagedInDataDir);
|
|
3678
|
+
const stagingRel = path$1.relative(this.dataDir, path$1.dirname(opts.archivePath));
|
|
3679
|
+
const excludePrefix = stagingRel && !stagingRel.startsWith("..") && !path$1.isAbsolute(stagingRel) ? stagingRel : null;
|
|
3680
|
+
try {
|
|
3681
|
+
const pack = Kn({
|
|
3682
|
+
gzip: true,
|
|
3683
|
+
cwd: this.dataDir,
|
|
3684
|
+
follow: true,
|
|
3685
|
+
portable: true,
|
|
3686
|
+
filter: (entryPath) => {
|
|
3687
|
+
const norm = normalizeArchivePath(entryPath);
|
|
3688
|
+
if (opts.excluded(norm)) return false;
|
|
3689
|
+
if (!excludePrefix) return true;
|
|
3690
|
+
return norm !== excludePrefix && !norm.startsWith(`${excludePrefix}/`);
|
|
3691
|
+
}
|
|
3692
|
+
}, [ARCHIVE_MANIFEST_NAME, ...present]);
|
|
3693
|
+
const sink = fs$1.createWriteStream(opts.archivePath, { mode: 384 });
|
|
3694
|
+
try {
|
|
3695
|
+
const streamOpts = opts.signal ? { signal: opts.signal } : {};
|
|
3696
|
+
if (opts.encryptTo !== void 0) await pipeline(pack, createBackupEncryptStream(opts.encryptTo), byteCountingPassthrough(opts.onArchiveBytes), sink, streamOpts);
|
|
3697
|
+
else await pipeline(pack, byteCountingPassthrough(opts.onArchiveBytes), sink, streamOpts);
|
|
3698
|
+
} catch (err) {
|
|
3699
|
+
try {
|
|
3700
|
+
fs$1.rmSync(opts.archivePath, { force: true });
|
|
3701
|
+
} catch {}
|
|
3702
|
+
if (opts.signal?.aborted) throw new BackupCancelledError();
|
|
3703
|
+
throw err;
|
|
3704
|
+
}
|
|
3705
|
+
} finally {
|
|
3706
|
+
try {
|
|
3707
|
+
fs$1.rmSync(stagedInDataDir, { force: true });
|
|
3708
|
+
} catch {}
|
|
3709
|
+
}
|
|
3710
|
+
} finally {
|
|
3711
|
+
try {
|
|
3712
|
+
fs$1.rmSync(manifestStagePath, { force: true });
|
|
3713
|
+
} catch {}
|
|
3714
|
+
}
|
|
3715
|
+
const sizeBytes = fs$1.statSync(opts.archivePath).size;
|
|
3716
|
+
return {
|
|
3717
|
+
archivePath: opts.archivePath,
|
|
3718
|
+
includedLocations: [...present],
|
|
3719
|
+
sizeBytes,
|
|
3720
|
+
manifest
|
|
3721
|
+
};
|
|
3722
|
+
}
|
|
3723
|
+
/**
|
|
3724
|
+
* without extracting payload files. Streams the tar.gz, parses the
|
|
3725
|
+
* one entry we care about, then aborts.
|
|
3726
|
+
*/
|
|
3727
|
+
async readArchiveManifest(archivePath) {
|
|
3728
|
+
if (!fs$1.existsSync(archivePath)) throw new Error(`readArchiveManifest: ${archivePath} does not exist`);
|
|
3729
|
+
return new Promise((resolve, reject) => {
|
|
3730
|
+
const chunks = [];
|
|
3731
|
+
let found = false;
|
|
3732
|
+
let resolved = false;
|
|
3733
|
+
const parser = new st({ onentry: (entry) => {
|
|
3734
|
+
if (entry.path === ".camstack-backup-manifest.json" && !found) {
|
|
3735
|
+
found = true;
|
|
3736
|
+
entry.on("data", (chunk) => chunks.push(chunk));
|
|
3737
|
+
entry.on("end", () => {
|
|
3738
|
+
try {
|
|
3739
|
+
const json = Buffer.concat(chunks).toString("utf-8");
|
|
3740
|
+
const parsed = JSON.parse(json);
|
|
3741
|
+
resolved = true;
|
|
3742
|
+
resolve(parsed);
|
|
3743
|
+
} catch (err) {
|
|
3744
|
+
resolved = true;
|
|
3745
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
3746
|
+
}
|
|
3747
|
+
});
|
|
3748
|
+
} else entry.resume();
|
|
3749
|
+
} });
|
|
3750
|
+
parser.on("end", () => {
|
|
3751
|
+
if (!resolved) resolve(found ? null : null);
|
|
3752
|
+
});
|
|
3753
|
+
const gunzip = zlib.createGunzip();
|
|
3754
|
+
gunzip.on("error", (err) => {
|
|
3755
|
+
if (!resolved) {
|
|
3756
|
+
resolved = true;
|
|
3757
|
+
reject(err);
|
|
3758
|
+
}
|
|
3759
|
+
});
|
|
3760
|
+
const reader = fs$1.createReadStream(archivePath);
|
|
3761
|
+
reader.on("error", (err) => {
|
|
3762
|
+
if (!resolved) {
|
|
3763
|
+
resolved = true;
|
|
3764
|
+
reject(err);
|
|
3765
|
+
}
|
|
3766
|
+
});
|
|
3767
|
+
reader.pipe(gunzip).pipe(parser);
|
|
3768
|
+
});
|
|
3769
|
+
}
|
|
3770
|
+
/**
|
|
3771
|
+
* Schedule a restore for the next boot by writing a marker file.
|
|
3772
|
+
* `locations` (optional) carries through to the launcher's boot-time
|
|
3773
|
+
* restore (`server/backend/src/launcher.ts`, the only restore there is)
|
|
3774
|
+
* so the operator's "restore only X and Y" choice survives the process
|
|
3775
|
+
* restart.
|
|
3776
|
+
*/
|
|
3777
|
+
scheduleRestoreMarker(opts) {
|
|
3778
|
+
if (!fs$1.existsSync(opts.archivePath)) throw new Error(`scheduleRestoreMarker: ${opts.archivePath} missing`);
|
|
3779
|
+
const markerPath = this.getRestoreMarkerPath();
|
|
3780
|
+
const marker = {
|
|
3781
|
+
archivePath: opts.archivePath,
|
|
3782
|
+
requestedAt: Date.now(),
|
|
3783
|
+
source: opts.source,
|
|
3784
|
+
...opts.locations ? { locations: [...opts.locations] } : {}
|
|
3785
|
+
};
|
|
3786
|
+
fs$1.mkdirSync(path$1.dirname(markerPath), { recursive: true });
|
|
3787
|
+
fs$1.writeFileSync(markerPath, JSON.stringify(marker, null, 2), { mode: 384 });
|
|
3788
|
+
return markerPath;
|
|
3789
|
+
}
|
|
3790
|
+
/** Read the pending-restore marker if one is present. */
|
|
3791
|
+
readPendingMarker() {
|
|
3792
|
+
const markerPath = this.getRestoreMarkerPath();
|
|
3793
|
+
if (!fs$1.existsSync(markerPath)) return null;
|
|
3794
|
+
try {
|
|
3795
|
+
const raw = fs$1.readFileSync(markerPath, "utf-8");
|
|
3796
|
+
const parsed = JSON.parse(raw);
|
|
3797
|
+
if (typeof parsed === "object" && parsed != null && typeof parsed.archivePath === "string") return parsed;
|
|
3798
|
+
} catch (err) {
|
|
3799
|
+
this.logger.warn("readPendingMarker: malformed marker — ignoring", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
3800
|
+
}
|
|
3801
|
+
return null;
|
|
3802
|
+
}
|
|
3803
|
+
/** Drop the marker after a successful boot-time restore. */
|
|
3804
|
+
clearPendingMarker() {
|
|
3805
|
+
const markerPath = this.getRestoreMarkerPath();
|
|
3806
|
+
if (fs$1.existsSync(markerPath)) fs$1.rmSync(markerPath, { force: true });
|
|
3807
|
+
}
|
|
3808
|
+
/**
|
|
3809
|
+
* The databases the owner declares, archive-relative, that this walk found.
|
|
3810
|
+
* One outside this data root is not in scope. An owner that cannot answer
|
|
3811
|
+
* stops the archive: without the answer, nothing says which file is live.
|
|
3812
|
+
*/
|
|
3813
|
+
async ownedDatabasesInScope(owner, walked) {
|
|
3814
|
+
if (owner === void 0) return /* @__PURE__ */ new Set();
|
|
3815
|
+
let declared;
|
|
3816
|
+
try {
|
|
3817
|
+
declared = await owner.listDatabases();
|
|
3818
|
+
} catch (err) {
|
|
3819
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
3820
|
+
this.logger.error("createArchive: the database owner did not say what it owns — no archive built", { meta: { error: reason } });
|
|
3821
|
+
throw new BackupSnapshotRefusedError(`the database owner could not be asked: ${reason}`);
|
|
3822
|
+
}
|
|
3823
|
+
const inScope = /* @__PURE__ */ new Set();
|
|
3824
|
+
for (const abs of declared) {
|
|
3825
|
+
const rel = this.archiveRelative(abs);
|
|
3826
|
+
if (rel !== null && walked.has(rel)) inScope.add(rel);
|
|
3827
|
+
}
|
|
3828
|
+
return inScope;
|
|
3829
|
+
}
|
|
3830
|
+
/**
|
|
3831
|
+
* Ask the owner for its snapshot, and place it in this archive. The snapshot
|
|
3832
|
+
* must sit on THIS data root — the call is pinned to this node, so a path
|
|
3833
|
+
* elsewhere means it reached another host, and that file is not ours to
|
|
3834
|
+
* read — beside an owned database in scope, and it must cover EVERY owned
|
|
3835
|
+
* database in scope. Anything else is refused.
|
|
3836
|
+
*
|
|
3837
|
+
* Only ever DELETED here: `<owned db>.backup-snapshot` under this data root,
|
|
3838
|
+
* a name this process derives itself. A path the owner ANSWERS is never
|
|
3839
|
+
* deleted on its word — answering the live database as the snapshot would
|
|
3840
|
+
* otherwise delete the live database. A file at any other path is left to
|
|
3841
|
+
* the owner's own sweep.
|
|
3842
|
+
*
|
|
3843
|
+
* A cancel is honoured while the owner is still copying; the copy it may
|
|
3844
|
+
* finish afterwards is removed when that call settles.
|
|
3845
|
+
*/
|
|
3846
|
+
async takeOwnerSnapshot(owner, owned, signal) {
|
|
3847
|
+
const removeOwnedSnapshots = async () => {
|
|
3848
|
+
for (const db of owned) await this.removeSnapshot(path$1.join(this.dataDir, db + DATABASE_SNAPSHOT_SUFFIX));
|
|
3849
|
+
};
|
|
3850
|
+
let result;
|
|
3851
|
+
try {
|
|
3852
|
+
result = await raceAbort(owner.writeSnapshot(), signal, () => {
|
|
3853
|
+
this.logger.info("createArchive: run cancelled while the owner copied — its copy is removed when it lands", { meta: { databases: [...owned] } });
|
|
3854
|
+
return removeOwnedSnapshots();
|
|
3855
|
+
});
|
|
3856
|
+
} catch (err) {
|
|
3857
|
+
if (err instanceof BackupCancelledError) throw err;
|
|
3858
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
3859
|
+
this.logger.error("createArchive: the owner could not snapshot its live database — no archive built", { meta: {
|
|
3860
|
+
databases: [...owned],
|
|
3861
|
+
error: reason
|
|
3862
|
+
} });
|
|
3863
|
+
await removeOwnedSnapshots();
|
|
3864
|
+
throw new BackupSnapshotRefusedError(reason);
|
|
3865
|
+
}
|
|
3866
|
+
try {
|
|
3867
|
+
const livePath = this.archiveRelative(result.livePath);
|
|
3868
|
+
const snapshotPath = this.archiveRelative(result.snapshotPath);
|
|
3869
|
+
if (livePath === null || snapshotPath === null) {
|
|
3870
|
+
this.logger.warn("createArchive: the owner answered a snapshot outside this data root — not touched, left to its sweep", { meta: {
|
|
3871
|
+
snapshot: result.snapshotPath,
|
|
3872
|
+
dataDir: this.dataDir
|
|
3873
|
+
} });
|
|
3874
|
+
throw new BackupSnapshotRefusedError(`snapshot ${result.snapshotPath} is not under this archive's data root ${this.dataDir}`);
|
|
3875
|
+
}
|
|
3876
|
+
if (snapshotPath !== livePath + ".backup-snapshot") throw new BackupSnapshotRefusedError(`snapshot ${snapshotPath} does not sit beside the database ${livePath} it copies`);
|
|
3877
|
+
const uncovered = [...owned].filter((db) => db !== livePath);
|
|
3878
|
+
if (!owned.has(livePath) || uncovered.length > 0) throw new BackupSnapshotRefusedError(`snapshot copies ${livePath}, but the owned database(s) in this archive are ${[...owned].join(", ")}`);
|
|
3879
|
+
const absPath = path$1.join(this.dataDir, snapshotPath);
|
|
3880
|
+
const stat = await fsp.stat(absPath);
|
|
3881
|
+
this.logger.info("createArchive: carrying the owner snapshot in place of the live database", { meta: {
|
|
3882
|
+
database: livePath,
|
|
3883
|
+
snapshot: snapshotPath,
|
|
3884
|
+
sizeBytes: stat.size,
|
|
3885
|
+
tables: result.tables.length,
|
|
3886
|
+
copyMs: result.copyMs,
|
|
3887
|
+
verifyMs: result.verifyMs
|
|
3888
|
+
} });
|
|
3889
|
+
return {
|
|
3890
|
+
absPath,
|
|
3891
|
+
archived: {
|
|
3892
|
+
...result,
|
|
3893
|
+
livePath,
|
|
3894
|
+
snapshotPath
|
|
3895
|
+
},
|
|
3896
|
+
entry: toArchiveEntry(absPath, this.dataDir, stat)
|
|
3897
|
+
};
|
|
3898
|
+
} catch (err) {
|
|
3899
|
+
await removeOwnedSnapshots();
|
|
3900
|
+
throw err;
|
|
3901
|
+
}
|
|
3902
|
+
}
|
|
3903
|
+
async removeSnapshot(absPath) {
|
|
3904
|
+
try {
|
|
3905
|
+
await fsp.rm(absPath, { force: true });
|
|
3906
|
+
} catch (err) {
|
|
3907
|
+
this.logger.warn("createArchive: owner snapshot could not be removed", { meta: {
|
|
3908
|
+
snapshot: absPath,
|
|
3909
|
+
error: err instanceof Error ? err.message : String(err)
|
|
3910
|
+
} });
|
|
3911
|
+
}
|
|
3912
|
+
}
|
|
3913
|
+
/** `abs` relative to the data root, or null when it lies outside it. */
|
|
3914
|
+
archiveRelative(abs) {
|
|
3915
|
+
const rel = path$1.relative(path$1.resolve(this.dataDir), path$1.resolve(abs));
|
|
3916
|
+
if (rel.length === 0 || rel.startsWith("..") || path$1.isAbsolute(rel)) return null;
|
|
3917
|
+
return normalizeArchivePath(rel);
|
|
3918
|
+
}
|
|
3919
|
+
getRestoreMarkerPath() {
|
|
3920
|
+
return path$1.join(this.dataDir, ".pending-restore.json");
|
|
3921
|
+
}
|
|
3922
|
+
/**
|
|
3923
|
+
* Absolute-path form of {@link isExcludedFromBackup}, anchored on
|
|
3924
|
+
* this service's dataDir. Shared by the manifest walk and the location
|
|
3925
|
+
* stats so both agree with the tar filter about what a backup contains.
|
|
3926
|
+
*/
|
|
3927
|
+
exclusionPredicate() {
|
|
3928
|
+
return (abs) => isExcludedFromBackup(path$1.relative(this.dataDir, abs));
|
|
3929
|
+
}
|
|
3930
|
+
};
|
|
3931
|
+
/**
|
|
3932
|
+
* Recursively walk a directory and produce one `ArchiveEntry` per
|
|
3933
|
+
* filesystem node. `dataDir` is used to compute the archive-relative
|
|
3934
|
+
* path. Symlinks are dereferenced (matches the `follow: true` flag we
|
|
3935
|
+
* pass to tar.create).
|
|
3936
|
+
*/
|
|
3937
|
+
async function walkAbs(absRoot, dataDir, shouldSkip, signal) {
|
|
3938
|
+
const out = [];
|
|
3939
|
+
await walkRec(absRoot, dataDir, out, shouldSkip, signal);
|
|
3940
|
+
return out;
|
|
3941
|
+
}
|
|
3942
|
+
async function walkRec(abs, dataDir, out, shouldSkip, signal) {
|
|
3943
|
+
throwIfCancelled(signal);
|
|
3944
|
+
if (shouldSkip?.(abs)) return;
|
|
3945
|
+
let stat;
|
|
3946
|
+
try {
|
|
3947
|
+
stat = await fsp.stat(abs);
|
|
3948
|
+
} catch {
|
|
3949
|
+
return;
|
|
3950
|
+
}
|
|
3951
|
+
out.push(toArchiveEntry(abs, dataDir, stat));
|
|
3952
|
+
if (stat.isDirectory()) {
|
|
3953
|
+
let children;
|
|
3954
|
+
try {
|
|
3955
|
+
children = await fsp.readdir(abs);
|
|
3956
|
+
} catch {
|
|
3957
|
+
return;
|
|
3958
|
+
}
|
|
3959
|
+
for (const child of children) await walkRec(path$1.join(abs, child), dataDir, out, shouldSkip, signal);
|
|
3960
|
+
}
|
|
3961
|
+
}
|
|
3962
|
+
/**
|
|
3963
|
+
* Pass-through transform that reports the CUMULATIVE bytes flowed so
|
|
3964
|
+
* far. Sits between the tar pack and the file sink so the caller's
|
|
3965
|
+
* progress counter tracks the compressed archive as it grows on disk.
|
|
3966
|
+
*/
|
|
3967
|
+
function byteCountingPassthrough(onBytes) {
|
|
3968
|
+
let total = 0;
|
|
3969
|
+
return new Transform({ transform(chunk, _encoding, callback) {
|
|
3970
|
+
if (Buffer.isBuffer(chunk)) total += chunk.byteLength;
|
|
3971
|
+
onBytes?.(total);
|
|
3972
|
+
callback(null, chunk);
|
|
3973
|
+
} });
|
|
3974
|
+
}
|
|
3975
|
+
function toArchiveEntry(abs, dataDir, stat) {
|
|
3976
|
+
const rel = path$1.relative(dataDir, abs).replace(/\\/g, "/");
|
|
3977
|
+
const kind = stat.isDirectory() ? "dir" : stat.isSymbolicLink() ? "symlink" : "file";
|
|
3978
|
+
return {
|
|
3979
|
+
path: rel || path$1.basename(abs),
|
|
3980
|
+
kind,
|
|
3981
|
+
sizeBytes: kind === "file" ? stat.size : 0,
|
|
3982
|
+
mtime: stat.mtimeMs
|
|
3983
|
+
};
|
|
3984
|
+
}
|
|
3985
|
+
//#endregion
|
|
3986
|
+
//#region src/builtins/backup-orchestrator/restore-archive.ts
|
|
3987
|
+
/**
|
|
3988
|
+
* Turn a downloaded backup into the plain `.tar.gz` the boot-time restore
|
|
3989
|
+
* extracts (`server/backend/src/pending-restore.ts`, unchanged).
|
|
3990
|
+
*
|
|
3991
|
+
* An encrypted archive is decrypted HERE, before the restart, with the backup
|
|
3992
|
+
* secret key the operator typed into the restore dialog: the launcher runs
|
|
3993
|
+
* before any runner and has no way to ask for a key. The plaintext lands only
|
|
3994
|
+
* in the hub's private staging directory (0600), where the restore marker
|
|
3995
|
+
* points at it, and is swept with the rest of staging once consumed.
|
|
3996
|
+
*
|
|
3997
|
+
* A plain archive — every backup made before encryption, or with it off — is
|
|
3998
|
+
* used as it is: existing backups stay restorable.
|
|
3999
|
+
*/
|
|
4000
|
+
/** An encrypted backup was asked to restore without its key. */
|
|
4001
|
+
var BackupKeyRequiredError = class extends Error {
|
|
4002
|
+
keyId;
|
|
4003
|
+
constructor(keyId) {
|
|
4004
|
+
super(`this backup is encrypted to backup key ${keyId} — enter that key's secret to restore it`);
|
|
4005
|
+
this.keyId = keyId;
|
|
4006
|
+
this.name = "BackupKeyRequiredError";
|
|
4007
|
+
}
|
|
4008
|
+
};
|
|
4009
|
+
/**
|
|
4010
|
+
* Before downloading gigabytes: does the operator's key fit what the
|
|
4011
|
+
* destination's manifest says the archive needs? `archiveKeyId` undefined =
|
|
4012
|
+
* the manifest records no encryption (the header check after the download
|
|
4013
|
+
* remains the authority).
|
|
4014
|
+
*/
|
|
4015
|
+
function precheckRestoreKey(archiveKeyId, secretKey) {
|
|
4016
|
+
if (archiveKeyId === void 0) return;
|
|
4017
|
+
if (secretKey === void 0 || secretKey.trim().length === 0) throw new BackupKeyRequiredError(archiveKeyId);
|
|
4018
|
+
const given = parseBackupSecretKey(secretKey).keyId;
|
|
4019
|
+
if (given !== archiveKeyId) throw new BackupKeyMismatchError(archiveKeyId, given);
|
|
4020
|
+
}
|
|
4021
|
+
async function prepareRestoreArchive(input) {
|
|
4022
|
+
let header;
|
|
4023
|
+
try {
|
|
4024
|
+
header = await readBackupEncryptionHeader(input.downloaded);
|
|
4025
|
+
} catch (err) {
|
|
4026
|
+
await fsp.rm(input.downloaded, { force: true });
|
|
4027
|
+
throw err;
|
|
4028
|
+
}
|
|
4029
|
+
if (header === null) {
|
|
4030
|
+
await fsp.rename(input.downloaded, input.target);
|
|
4031
|
+
return { encrypted: false };
|
|
4032
|
+
}
|
|
4033
|
+
try {
|
|
4034
|
+
if (input.secretKey === void 0 || input.secretKey.trim().length === 0) throw new BackupKeyRequiredError(header.keyId);
|
|
4035
|
+
await decryptBackupFile(input.downloaded, input.target, input.secretKey);
|
|
4036
|
+
return {
|
|
4037
|
+
encrypted: true,
|
|
4038
|
+
keyId: header.keyId
|
|
4039
|
+
};
|
|
4040
|
+
} finally {
|
|
4041
|
+
await fsp.rm(input.downloaded, { force: true });
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
4044
|
+
//#endregion
|
|
4045
|
+
export { BackupSnapshotRefusedError as a, BackupKeyFormatError as c, generateBackupKeyPair as d, parseBackupPublicKey as f, BackupCancelledError as i, BackupKeyMismatchError as l, readBackupEncryptionHeader as m, precheckRestoreKey as n, SystemBackupService as o, parseBackupSecretKey as p, prepareRestoreArchive as r, BackupDecryptError as s, BackupKeyRequiredError as t, ENCRYPTED_BACKUP_SUFFIX as u };
|