@poe-platform/safe-bash 0.1.551 → 0.1.553

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.
@@ -27220,6 +27220,7 @@ function parse12(context2, limits) {
27220
27220
  }
27221
27221
  let archive;
27222
27222
  let recursive = false;
27223
+ let quiet = false;
27223
27224
  let literal = false;
27224
27225
  let firstOperand = -1;
27225
27226
  const operands = [];
@@ -27229,8 +27230,11 @@ function parse12(context2, limits) {
27229
27230
  if (archive === void 0) throw new ZipFailure(16, "Invalid command arguments", "can't use -- before archive name");
27230
27231
  literal = true;
27231
27232
  } else if (!literal && argument2.startsWith("-") && argument2 !== "-") {
27232
- if (argument2.length > 1 && [...argument2.slice(1)].every((flag) => flag === "r")) recursive = true;
27233
- else throw new ZipFailure(16, "Invalid command arguments", `unsupported option: ${argument2}`);
27233
+ for (const flag of argument2.slice(1)) {
27234
+ if (flag === "r") recursive = true;
27235
+ else if (flag === "q") quiet = true;
27236
+ else throw new ZipFailure(16, "Invalid command arguments", `unsupported option: ${argument2}`);
27237
+ }
27234
27238
  } else if (archive === void 0) archive = argument2;
27235
27239
  else {
27236
27240
  if (operands.length >= limits.maxMembers) fail("operand limit exceeded");
@@ -27238,11 +27242,11 @@ function parse12(context2, limits) {
27238
27242
  operands.push(argument2);
27239
27243
  }
27240
27244
  }
27241
- if (archive === void 0) throw new ZipFailure(16, "Invalid command arguments", "expected zip [-r] ARCHIVE FILES...");
27245
+ if (archive === void 0) throw new ZipFailure(16, "Invalid command arguments", "expected zip [-r] [-q] ARCHIVE FILES...");
27242
27246
  if (archive === "-" || operands.includes("-")) throw new ZipFailure(16, "Invalid command arguments", "standard input/output archives are unsupported");
27243
27247
  if (!archive.slice(archive.lastIndexOf("/") + 1).includes(".")) archive += ".zip";
27244
27248
  checkPath(archive, limits);
27245
- return { archive, recursive, operands, firstOperand };
27249
+ return { archive, recursive, quiet, operands, firstOperand };
27246
27250
  }
27247
27251
  function memberName(path, limits) {
27248
27252
  if (path.startsWith("//") && !path.startsWith("///")) fail("UNC source paths are unsupported");
@@ -27299,14 +27303,14 @@ async function prepare(scope, parsed, budget) {
27299
27303
  } catch (error) {
27300
27304
  context2.signal.throwIfAborted();
27301
27305
  if (typeof error !== "object" || error === null || !("code" in error) || error.code !== "ENOENT") throw error;
27302
- if (!old.has(name2)) await budget.output(` zip warning: name not matched: ${source2}
27306
+ if (!parsed.quiet && !old.has(name2)) await budget.output(` zip warning: name not matched: ${source2}
27303
27307
  `);
27304
27308
  return;
27305
27309
  }
27306
27310
  checkPath(canonical, limits);
27307
27311
  if (canonical === output2 || existing2 && sameIdentity2(existing2, stat)) return;
27308
27312
  if (stat.type !== "file" && stat.type !== "directory") {
27309
- await budget.output(` zip warning: ignoring special file: ${source2}
27313
+ if (!parsed.quiet) await budget.output(` zip warning: ignoring special file: ${source2}
27310
27314
  `);
27311
27315
  return;
27312
27316
  }
@@ -27317,7 +27321,7 @@ async function prepare(scope, parsed, budget) {
27317
27321
  checkPath(name2, limits);
27318
27322
  const previous = selected.get(name2);
27319
27323
  if (previous && previous.source !== source2) {
27320
- await budget.output(` zip warning: first full name: ${previous.source}
27324
+ if (!parsed.quiet) await budget.output(` zip warning: first full name: ${previous.source}
27321
27325
  second full name: ${source2}
27322
27326
  name in zip file repeated: ${name2}
27323
27327
  `);
@@ -27364,6 +27368,7 @@ async function prepare(scope, parsed, budget) {
27364
27368
  const progress = [];
27365
27369
  let progressBytes = 0;
27366
27370
  const append = (entry, update) => {
27371
+ if (parsed.quiet) return;
27367
27372
  const percentage = entry.size ? Math.trunc((Math.trunc(200 * (entry.size - entry.data.length) / entry.size) + 1) / 2) : 0;
27368
27373
  const message3 = `${update ? "updating:" : " adding:"} ${entry.name} (${entry.method === 8 ? `deflated ${percentage}%` : "stored 0%"})
27369
27374
  `;
@@ -27451,6 +27456,7 @@ function parseArguments(context2, limits) {
27451
27456
  for (const value2 of argumentsValue.values) text2(shellValueBytes(value2));
27452
27457
  }
27453
27458
  let list = false;
27459
+ let pipe = false;
27454
27460
  let overwrite = false;
27455
27461
  let destination2;
27456
27462
  let archive;
@@ -27466,6 +27472,7 @@ function parseArguments(context2, limits) {
27466
27472
  for (let offset = 1; offset < argument2.length; offset++) {
27467
27473
  const flag = argument2[offset];
27468
27474
  if (flag === "l") list = true;
27475
+ else if (flag === "p") pipe = true;
27469
27476
  else if (flag === "o") overwrite = true;
27470
27477
  else if (flag === "d") {
27471
27478
  if (destination2 !== void 0) fail("-d may only be specified once");
@@ -27478,9 +27485,9 @@ function parseArguments(context2, limits) {
27478
27485
  } else if (archive === void 0) archive = argument2;
27479
27486
  else patterns2.push(argument2);
27480
27487
  }
27481
- if (archive === void 0) fail("usage: unzip [-l] [-o] [-d DIR] ARCHIVE [FILES...]");
27488
+ if (archive === void 0) fail("usage: unzip [-l] [-p] [-o] [-d DIR] ARCHIVE [FILES...]");
27482
27489
  checkPath(archive, limits);
27483
- return { list, overwrite, destination: destination2, archive, patterns: patterns2 };
27490
+ return { list: list && !pipe, pipe, overwrite, destination: destination2, archive, patterns: patterns2 };
27484
27491
  }
27485
27492
  function tokenize2(pattern) {
27486
27493
  const characters = Array.from(pattern);
@@ -27532,7 +27539,7 @@ var Selection = class {
27532
27539
  step() {
27533
27540
  if (++this.work > this.limits.maxPatternSteps) fail("pattern work limit exceeded");
27534
27541
  }
27535
- async matches(name2) {
27542
+ async matches(name2, firstMatchOnly = false) {
27536
27543
  if (!this.patterns.length) return true;
27537
27544
  const characters = Array.from(name2);
27538
27545
  let selected = false;
@@ -27564,6 +27571,7 @@ var Selection = class {
27564
27571
  }
27565
27572
  if (states[characters.length]) {
27566
27573
  this.matched.add(pattern);
27574
+ if (firstMatchOnly) return true;
27567
27575
  selected = true;
27568
27576
  }
27569
27577
  }
@@ -27898,16 +27906,17 @@ async function comment(bytes3, budget) {
27898
27906
  }
27899
27907
  function createUnzipCommand(options2 = {}) {
27900
27908
  const limits = settings2(options2);
27901
- return { name: "unzip", description: "List and safely extract ZIP archives in the virtual filesystem", async execute(original) {
27909
+ return { name: "unzip", description: "List, stream or safely extract ZIP archives in the virtual filesystem", async execute(original) {
27902
27910
  original.signal.throwIfAborted();
27903
27911
  const controller = new AbortController();
27904
27912
  const context2 = { ...original, signal: AbortSignal.any([original.signal, controller.signal]) };
27905
27913
  const extraction = new Extraction(context2, limits);
27914
+ let output2;
27906
27915
  let answers;
27907
27916
  let closing;
27908
27917
  const close = () => closing ??= (async () => {
27909
27918
  controller.abort(new Error("unzip command closed"));
27910
- await extraction.close();
27919
+ await Promise.all([extraction.close(), output2?.close()]);
27911
27920
  await answers?.close().catch(() => {
27912
27921
  });
27913
27922
  })();
@@ -27915,6 +27924,8 @@ function createUnzipCommand(options2 = {}) {
27915
27924
  const budget = new Budget14(context2, limits);
27916
27925
  try {
27917
27926
  const parsed = parseArguments(context2, limits);
27927
+ if (parsed.pipe) output2 = createOutputOperation(context2, context2.stdout);
27928
+ if (parsed.pipe && parsed.destination !== void 0) await budget.output("caution: not extracting; -d ignored\n", true);
27918
27929
  const selection = new Selection(parsed.patterns, limits, context2.signal);
27919
27930
  let archive = parsed.archive;
27920
27931
  let archiveStat;
@@ -27928,7 +27939,7 @@ function createUnzipCommand(options2 = {}) {
27928
27939
  }
27929
27940
  }
27930
27941
  if (!archiveStat) {
27931
- await budget.output(`unzip: cannot find or open ${archive}, ${archive}.zip or ${archive}.ZIP.
27942
+ if (!parsed.pipe) await budget.output(`unzip: cannot find or open ${archive}, ${archive}.zip or ${archive}.ZIP.
27932
27943
  `, true);
27933
27944
  return { exitCode: 9 };
27934
27945
  }
@@ -27936,10 +27947,10 @@ function createUnzipCommand(options2 = {}) {
27936
27947
  archiveStat = await extraction.operation(() => context2.fs.stat(archivePath, { signal: context2.signal }));
27937
27948
  if (archiveStat.type !== "file") fail("input archive is not a regular file");
27938
27949
  const bytes3 = await collectBytes(bounded(extraction.input(archivePath), limits.maxArchiveBytes, context2.signal, limits.chunkSize), { signal: context2.signal, maxBytes: limits.maxArchiveBytes });
27939
- await budget.output(`Archive: ${filtered(archive)}
27950
+ if (!parsed.pipe) await budget.output(`Archive: ${filtered(archive)}
27940
27951
  `);
27941
27952
  const zip = await readZipArchive(bytes3, limits, context2.signal);
27942
- await comment(zip.comment, budget);
27953
+ if (!parsed.pipe) await comment(zip.comment, budget);
27943
27954
  if (!zip.entries.length) {
27944
27955
  await budget.output(`warning [${filtered(archive)}]: zipfile is empty
27945
27956
  `, true);
@@ -27947,21 +27958,35 @@ function createUnzipCommand(options2 = {}) {
27947
27958
  }
27948
27959
  if (parsed.list) await budget.output(" Length Date Time Name\n--------- ---------- ----- ----\n");
27949
27960
  const rootRaw = parsed.destination === void 0 ? context2.cwd : vfsPath(context2.cwd, parsed.destination);
27950
- const root = parsed.list ? resolvePath(rootRaw) : await extraction.directory(rootRaw, true);
27951
- answers = new Answers(extraction.source(context2.stdin), limits, context2.signal);
27961
+ const root = parsed.list || parsed.pipe ? resolvePath(rootRaw) : await extraction.directory(rootRaw, true);
27962
+ if (!parsed.list && !parsed.pipe) answers = new Answers(extraction.source(context2.stdin), limits, context2.signal);
27952
27963
  let overwrite = parsed.overwrite ? "all" : "ask";
27953
27964
  let exitCode = 0;
27954
27965
  let selected = 0;
27955
27966
  let total = 0;
27956
27967
  let actualTotal = 0;
27968
+ const payload = async function* (entry) {
27969
+ let actual = 0;
27970
+ const signal = output2?.signal ?? context2.signal;
27971
+ for await (const chunk of readBytes(decodeZipEntry(entry, limits, signal), signal)) {
27972
+ if (chunk.length > limits.maxEntryBytes - actual || chunk.length > limits.maxTotalBytes - actualTotal) fail("actual decompressed byte limit exceeded");
27973
+ actual += chunk.length;
27974
+ actualTotal += chunk.length;
27975
+ yield chunk;
27976
+ }
27977
+ };
27957
27978
  const links = [];
27958
27979
  const directories = [];
27959
27980
  for (const entry of zip.entries) {
27960
27981
  await budget.member(entry.size);
27961
27982
  checkPath(entry.name, limits);
27962
- if (!await selection.matches(entry.name)) continue;
27983
+ if (!await selection.matches(entry.name, parsed.pipe)) continue;
27963
27984
  selected++;
27964
27985
  total += entry.size;
27986
+ if (parsed.pipe) {
27987
+ for await (const chunk of payload(entry)) await output2.output.write(chunk);
27988
+ continue;
27989
+ }
27965
27990
  if (parsed.list) {
27966
27991
  await budget.output(`${String(entry.size).padStart(9)} ${date(entry)} ${filtered(entry.name)}
27967
27992
  `);
@@ -27976,7 +28001,7 @@ function createUnzipCommand(options2 = {}) {
27976
28001
  await extraction.parents(root, path, true);
27977
28002
  if (entry.directory) {
27978
28003
  if (entry.size) fail("directory has nonempty payload");
27979
- for await (const chunk of readBytes(decodeZipEntry(entry, limits, context2.signal), context2.signal)) {
28004
+ for await (const chunk of payload(entry)) {
27980
28005
  await writeFileOutput(context2, chunk, async () => {
27981
28006
  if (chunk.length) fail("directory has nonempty payload");
27982
28007
  });
@@ -28046,10 +28071,8 @@ function createUnzipCommand(options2 = {}) {
28046
28071
  if (skip) continue;
28047
28072
  const chunks = [];
28048
28073
  let actual = 0;
28049
- for await (const chunk of readBytes(decodeZipEntry(entry, limits, context2.signal), context2.signal)) {
28050
- if (chunk.length > limits.maxEntryBytes - actual || chunk.length > limits.maxTotalBytes - actualTotal) fail("actual decompressed byte limit exceeded");
28074
+ for await (const chunk of payload(entry)) {
28051
28075
  actual += chunk.length;
28052
- actualTotal += chunk.length;
28053
28076
  await writeFileOutput(context2, chunk, async (bytes4) => {
28054
28077
  chunks.push(Uint8Array.from(bytes4));
28055
28078
  });