@poe-platform/safe-bash 0.1.625 → 0.1.626

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.
@@ -26639,6 +26639,7 @@ var longOptions = {
26639
26639
  filesync: "FS",
26640
26640
  "archive-comment": "z",
26641
26641
  "entry-comments": "c",
26642
+ "latest-time": "o",
26642
26643
  delete: "d",
26643
26644
  include: "i",
26644
26645
  exclude: "x",
@@ -26693,7 +26694,6 @@ var reservedOptions = [
26693
26694
  "log-info",
26694
26695
  "license",
26695
26696
  "move",
26696
- "latest-time",
26697
26697
  "paths",
26698
26698
  "password",
26699
26699
  "regex",
@@ -26729,6 +26729,19 @@ function normalizeZipOption(argument2) {
26729
26729
  }
26730
26730
 
26731
26731
  // packages/safe-bash/src/commands/archive/zip/dates.ts
26732
+ async function zipLatestTime(entries2, signal) {
26733
+ signal.throwIfAborted();
26734
+ let latest;
26735
+ for (let index = 0; index < entries2.length; index++) {
26736
+ if (index % 128 === 0) await yieldTurn(signal);
26737
+ const entry = entries2[index];
26738
+ if (entry.directory) continue;
26739
+ const rounded2 = new Date(Math.ceil(Math.floor(entry.modified.getTime() / 1e3) / 2) * 2e3);
26740
+ const timestamp3 = rounded2.getFullYear() < 1980 ? new Date(1980, 0, 1).getTime() : new Date(rounded2.getFullYear(), rounded2.getMonth(), rounded2.getDate(), rounded2.getHours(), rounded2.getMinutes(), rounded2.getSeconds()).getTime();
26741
+ if (latest === void 0 || timestamp3 > latest) latest = timestamp3;
26742
+ }
26743
+ return latest;
26744
+ }
26732
26745
  function integer4(input3, start, width) {
26733
26746
  let offset = start;
26734
26747
  while (" \r\n\v\f".includes(input3[offset] ?? "\0")) offset++;
@@ -27670,7 +27683,8 @@ async function publishZip(scope, prepared) {
27670
27683
  staging = await fs.createStagedFile(path, "archive.zip", { type: "file", data: prepared.bytes }, {
27671
27684
  signal,
27672
27685
  parent: prepared.parentStat,
27673
- ...prepared.existing ? { mode: prepared.existing.mode & 4095 } : {}
27686
+ ...prepared.existing ? { mode: prepared.existing.mode & 4095 } : {},
27687
+ ...prepared.mtimeMs === void 0 ? {} : { mtimeMs: prepared.mtimeMs, atimeMs: prepared.mtimeMs }
27674
27688
  });
27675
27689
  });
27676
27690
  break;
@@ -27680,6 +27694,7 @@ async function publishZip(scope, prepared) {
27680
27694
  }
27681
27695
  }
27682
27696
  if (!staging) fail("ZIP temporary directory attempt limit exceeded");
27697
+ if (prepared.mtimeMs !== void 0 && (staging.file.stat.mtimeMs !== prepared.mtimeMs || staging.file.stat.atimeMs !== prepared.mtimeMs)) fail("ZIP staging did not retain archive modification time");
27683
27698
  const parent = await scope.operation(() => fs.realpath(prepared.parentName, { signal }));
27684
27699
  if (parent !== prepared.parent) fail("archive parent changed before publication");
27685
27700
  await scope.operation(() => fs.publishStagedFile(staging, prepared.output, {
@@ -27939,6 +27954,7 @@ async function parse12(scope, limits) {
27939
27954
  let filesync = false;
27940
27955
  let archiveComment = false;
27941
27956
  let entryComments = false;
27957
+ let latestTime = false;
27942
27958
  let fromDate;
27943
27959
  let beforeDate;
27944
27960
  let descriptors = false;
@@ -27994,6 +28010,7 @@ async function parse12(scope, limits) {
27994
28010
  } else if (flag === "q") quiet = true;
27995
28011
  else if (flag === "z") archiveComment = true;
27996
28012
  else if (flag === "c") entryComments = true;
28013
+ else if (flag === "o") latestTime = true;
27997
28014
  else if (flag === "j") junkPaths = true;
27998
28015
  else if (flag === "X") {
27999
28016
  metadata3 = argument2[offset + 1] === "-" ? "all" : "strip";
@@ -28112,7 +28129,7 @@ async function parse12(scope, limits) {
28112
28129
  }
28113
28130
  if (recursivePatterns && !names.length && !operands.length) throw new ZipFailure(16, "Invalid command arguments", "nothing to select from");
28114
28131
  if (filesync && action !== "add") throw new ZipFailure(16, "Invalid command arguments", "can't use -d, -f, -u, -U, or -g with filesync -FS\n");
28115
- return { args, action, archive, output: output2, recursive, recursivePatterns, noWild, stopAtDirectories, quiet, junkPaths, omitDirectories, storeLinks, test, mustMatch, filesync, archiveComment, entryComments, fromDate, beforeDate, descriptors, zip64, metadata: metadata3, includes, excludes, level, method, suffixes, operands: [...names, ...operands], firstOperand };
28132
+ return { args, action, archive, output: output2, recursive, recursivePatterns, noWild, stopAtDirectories, quiet, junkPaths, omitDirectories, storeLinks, test, mustMatch, filesync, archiveComment, entryComments, latestTime, fromDate, beforeDate, descriptors, zip64, metadata: metadata3, includes, excludes, level, method, suffixes, operands: [...names, ...operands], firstOperand };
28116
28133
  }
28117
28134
  function memberName(path, limits) {
28118
28135
  if (path.startsWith("//") && !path.startsWith("///")) fail("UNC source paths are unsupported");
@@ -28192,11 +28209,13 @@ async function prepare(scope, parsed, budget) {
28192
28209
  if (parsed.archive === "-" && parsed.test && !parsed.quiet) await budget.output(" zip warning: can't use -T on stdout, -T ignored\n");
28193
28210
  if (existing2 && (existing2.type !== "file" || !hasIdentity(existing2) || existing2.nlink !== 1)) fail("updating archive requires a regular, single-link file with known backing identity; archive aliases are unsupported");
28194
28211
  let archive = { entries: [], comment: new Uint8Array() };
28212
+ let originalBytes;
28195
28213
  if (existing2 && input3) {
28196
28214
  if (!Number.isSafeInteger(existing2.size) || existing2.size < 0 || existing2.size > limits.maxArchiveBytes) fail("archive byte limit exceeded");
28197
28215
  const bytes4 = await collectBytes(scope.input(input3), { maxBytes: limits.maxArchiveBytes, signal: context2.signal });
28198
28216
  if (bytes4.length !== existing2.size) fail("archive changed while reading");
28199
28217
  archive = await readZipArchive(bytes4, limits, context2.signal);
28218
+ if (parsed.latestTime) originalBytes = bytes4;
28200
28219
  const current = await scope.stat(input3);
28201
28220
  if (!current || !unchanged4(existing2, current)) fail("archive changed while reading");
28202
28221
  }
@@ -28399,11 +28418,17 @@ async function prepare(scope, parsed, budget) {
28399
28418
  for (const entry of archive.entries) if (!synchronized.has(entry.name)) deleted.add(entry.name);
28400
28419
  if (!selected.size && !deleted.size) {
28401
28420
  if (!parsed.quiet) await budget.output("Archive is current\n");
28402
- return { kind: "current" };
28421
+ if (!parsed.latestTime) return { kind: "current", exitCode: 0 };
28403
28422
  }
28404
28423
  }
28405
- if (!selected.size && !((editComment || editEntries) && archive.entries.length) && (parsed.action === "freshen" || parsed.action === "update" && (existing2 || !parsed.includes.length))) return void 0;
28406
- if (!selected.size && !deleted.size && !((editComment || editEntries) && archive.entries.length) && (parsed.action === "delete" || parsed.action === "copy" || parsed.recursivePatterns || parsed.fromDate !== void 0 || parsed.beforeDate !== void 0 || !parsed.includes.length)) {
28424
+ const changed = selected.size > 0 || deleted.size > 0;
28425
+ let exitCode = 0;
28426
+ if (!selected.size && !((editComment || editEntries) && archive.entries.length) && (parsed.action === "freshen" || parsed.action === "update" && (existing2 || !parsed.includes.length))) {
28427
+ if (!parsed.latestTime || !archive.entries.length) return void 0;
28428
+ exitCode = 12;
28429
+ }
28430
+ if (parsed.latestTime && !changed && !archive.entries.length && parsed.archive !== "-") throw new ZipFailure(13, "Missing or empty zip file", parsed.archive);
28431
+ if (!selected.size && !deleted.size && !((editComment || editEntries || parsed.latestTime) && archive.entries.length) && (parsed.action === "delete" || parsed.action === "copy" || parsed.recursivePatterns || parsed.fromDate !== void 0 || parsed.beforeDate !== void 0 || !parsed.includes.length)) {
28407
28432
  const detail = parsed.action !== "delete" && parsed.recursive && parsed.firstOperand >= 0 ? `try: zip ${parsed.args.slice(0, parsed.firstOperand).join(" ")} . -i ${parsed.args.slice(parsed.firstOperand).join(" ")}` : parsed.archive;
28408
28433
  throw new ZipFailure(12, "Nothing to do!", detail);
28409
28434
  }
@@ -28480,7 +28505,16 @@ async function prepare(scope, parsed, budget) {
28480
28505
  if (editComment) comment2 = await readZipComment(commentInput, limits, context2.signal);
28481
28506
  }
28482
28507
  if (!publication) return { kind: "stream", archive: { entries: entries2, comment: comment2 }, progress };
28483
- const bytes3 = await writeZipArchive({ entries: entries2, comment: comment2 }, limits, context2.signal, false, parsed.zip64 === true);
28508
+ if (parsed.latestTime) {
28509
+ const mtimeMs = await zipLatestTime(entries2, context2.signal);
28510
+ if (mtimeMs === void 0) queue(entries2.length ? " zip warning: zip file has only directories, can't make it as old as latest entry\n" : " zip warning: zip file is empty, can't make it as old as latest entry\n");
28511
+ else publication = { ...publication, mtimeMs };
28512
+ if (mtimeMs === void 0 && !changed && originalBytes && !editComment && !editEntries) {
28513
+ for (const message3 of progress) await budget.output(message3);
28514
+ return { kind: "current", exitCode };
28515
+ }
28516
+ }
28517
+ const bytes3 = parsed.latestTime && originalBytes && !changed && !editComment && !editEntries ? originalBytes : await writeZipArchive({ entries: entries2, comment: comment2 }, limits, context2.signal, false, parsed.zip64 === true);
28484
28518
  if (parsed.test && parsed.archive !== "-") {
28485
28519
  for (const message3 of progress) await budget.output(message3);
28486
28520
  progress.length = 0;
@@ -28506,7 +28540,7 @@ async function prepare(scope, parsed, budget) {
28506
28540
  `);
28507
28541
  }
28508
28542
  }
28509
- return { kind: "file", publication, bytes: bytes3, progress };
28543
+ return { kind: "file", publication, bytes: bytes3, progress, exitCode };
28510
28544
  }
28511
28545
  function createZipCommand(options2 = {}) {
28512
28546
  const limits = settings2(options2);
@@ -28520,7 +28554,7 @@ function createZipCommand(options2 = {}) {
28520
28554
  if (parsed.archive === "-") budget = new Budget14({ ...context2, stdout: context2.stderr }, limits);
28521
28555
  const prepared = await prepare(scope, parsed, budget);
28522
28556
  if (!prepared) return { exitCode: 12 };
28523
- if (prepared.kind === "current") return { exitCode: 0 };
28557
+ if (prepared.kind === "current") return { exitCode: prepared.exitCode };
28524
28558
  if (prepared.kind === "file") {
28525
28559
  const publication = prepared.publication;
28526
28560
  if (!publication) fail("ZIP missing file publication");
@@ -28537,7 +28571,7 @@ function createZipCommand(options2 = {}) {
28537
28571
  await output2.close();
28538
28572
  }
28539
28573
  }
28540
- return { exitCode: 0 };
28574
+ return { exitCode: prepared.kind === "file" ? prepared.exitCode : 0 };
28541
28575
  } catch (error) {
28542
28576
  original.signal.throwIfAborted();
28543
28577
  context2.signal.throwIfAborted();