@camstack/system 1.2.380 → 1.2.382

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.
Files changed (117) hide show
  1. package/dist/addon-runner.js +4 -2
  2. package/dist/addon-runner.mjs +4 -2
  3. package/dist/addon-utils.js +1 -1
  4. package/dist/addon-utils.mjs +1 -1
  5. package/dist/auth/admin-token-manager.d.ts +75 -0
  6. package/dist/auth/api-key-manager.d.ts +1 -14
  7. package/dist/auth/auth-audit-log.d.ts +59 -0
  8. package/dist/auth/auth-manager.d.ts +28 -16
  9. package/dist/auth/cidr.d.ts +22 -0
  10. package/dist/auth/login-session-manager.d.ts +158 -0
  11. package/dist/auth/user-management-internal.d.ts +69 -0
  12. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  13. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  14. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  15. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  16. package/dist/builtins/alerts/alerts.addon.js +1 -1
  17. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  18. package/dist/builtins/autotrack/index.js +1 -1
  19. package/dist/builtins/autotrack/index.mjs +1 -1
  20. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +14 -0
  21. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +291 -3631
  22. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +284 -3617
  23. package/dist/builtins/backup-orchestrator/encryption-key-store.d.ts +36 -0
  24. package/dist/builtins/backup-orchestrator/manifest-store.d.ts +19 -1
  25. package/dist/builtins/backup-orchestrator/restore-archive.d.ts +24 -0
  26. package/dist/builtins/calendars/calendars.addon.js +1 -1
  27. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  28. package/dist/builtins/camera-grid/index.js +1 -1
  29. package/dist/builtins/camera-grid/index.mjs +1 -1
  30. package/dist/builtins/composer/composer.addon.js +2 -2
  31. package/dist/builtins/composer/composer.addon.mjs +2 -2
  32. package/dist/builtins/console-logging/index.js +1 -1
  33. package/dist/builtins/console-logging/index.mjs +1 -1
  34. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  35. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  36. package/dist/builtins/device-manager/device-aggregation.d.ts +12 -0
  37. package/dist/builtins/device-manager/device-form-secrets.d.ts +25 -0
  38. package/dist/builtins/device-manager/device-manager.addon.d.ts +2 -0
  39. package/dist/builtins/device-manager/device-manager.addon.js +165 -26
  40. package/dist/builtins/device-manager/device-manager.addon.mjs +165 -26
  41. package/dist/builtins/hub-forwarder/index.js +1 -1
  42. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  43. package/dist/builtins/keychain/index.js +1108 -733
  44. package/dist/builtins/keychain/index.mjs +1108 -733
  45. package/dist/builtins/keychain/keychain-reset-trigger.d.ts +25 -0
  46. package/dist/builtins/keychain/keychain-service.d.ts +36 -3
  47. package/dist/builtins/keychain/keychain-store.d.ts +24 -1
  48. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  49. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  50. package/dist/builtins/local-auth/local-auth.addon.d.ts +16 -0
  51. package/dist/builtins/local-auth/local-auth.addon.js +1021 -118
  52. package/dist/builtins/local-auth/local-auth.addon.mjs +1034 -141
  53. package/dist/builtins/local-network/local-network.addon.js +3 -3
  54. package/dist/builtins/local-network/local-network.addon.mjs +3 -3
  55. package/dist/builtins/loki-logging/index.js +97 -29
  56. package/dist/builtins/loki-logging/index.mjs +97 -29
  57. package/dist/builtins/loki-logging/loki-logging.addon.d.ts +7 -23
  58. package/dist/builtins/loki-logging/retire-enabled-flag.d.ts +23 -0
  59. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  60. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  61. package/dist/builtins/platform-probe/index.js +1 -1
  62. package/dist/builtins/platform-probe/index.mjs +1 -1
  63. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  64. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  65. package/dist/builtins/snapshot/index.js +1 -1
  66. package/dist/builtins/snapshot/index.mjs +1 -1
  67. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  68. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  69. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  70. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  71. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +2 -2
  72. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +2 -2
  73. package/dist/builtins/system-backup/backup-encryption.d.ts +57 -0
  74. package/dist/builtins/system-backup/system-backup.service.d.ts +16 -1
  75. package/dist/builtins/system-config/cluster-secret-keeper.d.ts +7 -0
  76. package/dist/builtins/system-config/system-config.addon.d.ts +13 -3
  77. package/dist/builtins/system-config/system-config.addon.js +324 -38
  78. package/dist/builtins/system-config/system-config.addon.mjs +312 -39
  79. package/dist/builtins/winston-logging/index.js +1 -1
  80. package/dist/builtins/winston-logging/index.mjs +1 -1
  81. package/dist/{child-cap-dispatch-CZeRUgYF.js → child-cap-dispatch-BrMdKHfp.js} +6 -3
  82. package/dist/{child-cap-dispatch-CpjohToR.mjs → child-cap-dispatch-WsYPNvnK.mjs} +10 -7
  83. package/dist/{cluster-secret-Dg0OOOSr.js → cluster-secret-BEPLh3LL.js} +1 -1
  84. package/dist/{cluster-secret-BDue-uJj.mjs → cluster-secret-DhPdZ0VA.mjs} +1 -1
  85. package/dist/{composition-sources-CHvLMrFI.js → composition-sources-C6ZynCZ2.js} +1 -1
  86. package/dist/{composition-sources-DT_uJwI3.mjs → composition-sources-XqRX51db.mjs} +1 -1
  87. package/dist/{dist-B9oFw2jh.mjs → dist-CP5TTjwd.mjs} +1713 -157
  88. package/dist/{dist-Cc6KOdY-.js → dist-tnAO12ak.js} +1754 -156
  89. package/dist/{event-loop-stall-monitor-mk6WGxir.js → event-loop-stall-monitor-9kR0sAPS.js} +15 -15
  90. package/dist/{event-loop-stall-monitor-anUH2IE1.mjs → event-loop-stall-monitor-WkssIXjq.mjs} +15 -15
  91. package/dist/{hub-cap-forward-CH6_VWVO.mjs → hub-cap-forward-CDiN1p98.mjs} +18 -2
  92. package/dist/{hub-cap-forward-COCmYaup.js → hub-cap-forward-W8oEm4ME.js} +23 -1
  93. package/dist/index.d.ts +16 -1
  94. package/dist/index.js +3341 -79
  95. package/dist/index.mjs +3567 -354
  96. package/dist/{jwt-signing-key-Qhde8r82.mjs → jwt-signing-key-CAbozwvF.mjs} +1 -1
  97. package/dist/{jwt-signing-key-C2rE3wH6.js → jwt-signing-key-Dgf8sIXY.js} +1 -1
  98. package/dist/kernel/index.d.ts +12 -0
  99. package/dist/kernel/moleculer/broker-factory.d.ts +8 -1
  100. package/dist/kernel/moleculer/child-addon-call-dispatch.d.ts +1 -0
  101. package/dist/kernel/moleculer/hub-service.d.ts +9 -0
  102. package/dist/kernel/moleculer/mesh-access-middleware.d.ts +28 -0
  103. package/dist/kernel/moleculer/mesh-auth-mode.d.ts +64 -0
  104. package/dist/kernel/moleculer/mesh-authenticator.d.ts +71 -0
  105. package/dist/kernel/moleculer/mesh-auto-enforce.d.ts +26 -0
  106. package/dist/kernel/moleculer/mesh-join-client.d.ts +51 -0
  107. package/dist/kernel/moleculer/mesh-join-proof.d.ts +39 -0
  108. package/dist/kernel/system-settings-policy.d.ts +4 -3
  109. package/dist/kernel/transport/hub-cap-forward.d.ts +14 -3
  110. package/dist/kernel/transport/index.d.ts +1 -1
  111. package/dist/restore-archive-BV39nY46.mjs +4045 -0
  112. package/dist/restore-archive-CbvrfPuB.js +4139 -0
  113. package/dist/{retired-settings-keys-YOOKLA3v.js → retired-settings-keys-4bHpL-0m.js} +1 -1
  114. package/dist/{retired-settings-keys-DlZ3VV6x.mjs → retired-settings-keys-CzpIkwS-.mjs} +1 -1
  115. package/dist/{tls-CJHogwTl.mjs → tls-4cRH24Id.mjs} +3 -3
  116. package/package.json +1 -1
  117. package/dist/{tls-CCMX7MjX.js → tls-CljF057D.js} +1 -1
@@ -0,0 +1,4045 @@
1
+ import { g as DATABASE_SNAPSHOT_SUFFIX } from "./dist-CP5TTjwd.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 * as zlib from "node:zlib";
11
+ import { EventEmitter } from "node:events";
12
+ import As, { Transform } from "node:stream";
13
+ import { StringDecoder } from "node:string_decoder";
14
+ import I from "fs";
15
+ import qs, { dirname as dirname$1, parse } from "path";
16
+ import * as Ms from "zlib";
17
+ import Jr from "zlib";
18
+ import Pi from "assert";
19
+ import $r, { EventEmitter as EventEmitter$1 } from "events";
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 };