@poe-platform/safe-bash 0.1.843 → 0.1.844

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.
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  createFfprobeCommand
3
- } from "../safe-bash/command-chunks/chunk-MJB4WWYP.js";
3
+ } from "../safe-bash/command-chunks/chunk-3SWIXYXT.js";
4
4
  import "../safe-bash/command-chunks/chunk-MGBHGZEX.js";
5
- import "../safe-bash/command-chunks/chunk-SBBMNLD6.js";
5
+ import "../safe-bash/command-chunks/chunk-LORSYIAF.js";
6
6
  import "../safe-bash/command-chunks/chunk-65DS4IOB.js";
7
7
 
8
8
  // packages/safe-bash-command-ffprobe/src/index.ts
@@ -11,9 +11,9 @@ import {
11
11
  loadManifestResources,
12
12
  resolvePath,
13
13
  rethrowRuntimeError
14
- } from "../safe-bash/command-chunks/chunk-MJB4WWYP.js";
14
+ } from "../safe-bash/command-chunks/chunk-3SWIXYXT.js";
15
15
  import "../safe-bash/command-chunks/chunk-MGBHGZEX.js";
16
- import "../safe-bash/command-chunks/chunk-SBBMNLD6.js";
16
+ import "../safe-bash/command-chunks/chunk-LORSYIAF.js";
17
17
  import "../safe-bash/command-chunks/chunk-65DS4IOB.js";
18
18
  export {
19
19
  createFfprobeCommand,
@@ -1273,10 +1273,10 @@ function* combinePixelSteps(size, lengths) {
1273
1273
  for (let offset = 3; offset < length; offset += 4) data[offset] = 255;
1274
1274
  continue;
1275
1275
  }
1276
- const count = Math.max(0, Math.min(length, lengths[image] - position));
1276
+ const count = Math.max(0, Math.min(length, (lengths[image] ?? 0) - position));
1277
1277
  if (!count) continue;
1278
1278
  const source = yield { kind: "read", image, position, length: count };
1279
- for (let offset = 0; offset < count; offset += 4) data[offset + image] = source[offset];
1279
+ for (let offset = 0; offset < count; offset += 4) data[offset + image] = Math.round(0.212656 * source[offset] + 0.715158 * source[offset + 1] + 0.072186 * source[offset + 2]);
1280
1280
  }
1281
1281
  yield { kind: "write", position, data };
1282
1282
  }
@@ -4840,8 +4840,8 @@ function* applyMagickSpliceSteps(img, geomStr, bg, gravity = "northwest", signal
4840
4840
  function* applyMagickChopSteps(img, geomStr, gravity = "northwest", signal) {
4841
4841
  let cooperativeWork = 0;
4842
4842
  const g = parseMagickGeometry(geomStr);
4843
- const cw = Math.max(0, Math.round(g.width ?? 0));
4844
- const ch = Math.max(0, Math.round(g.height ?? 0));
4843
+ const cw = Math.max(0, Math.round((g.width ?? 0) * (g.isPercent ? img.width / 100 : 1)));
4844
+ const ch = Math.max(0, Math.round((g.height ?? 0) * (g.isPercent ? img.height / 100 : 1)));
4845
4845
  const { x: x0, y: y0 } = gravityAdjustBox(img.width, img.height, cw, ch, g.x, g.y, gravity);
4846
4846
  if (x0 + cw < 0 || y0 + ch < 0 || x0 > img.width || y0 > img.height) {
4847
4847
  return img;
@@ -4879,6 +4879,7 @@ function* applyMagickChopSteps(img, geomStr, gravity = "northwest", signal) {
4879
4879
  }
4880
4880
  function parseMagickRollGeometry(raw) {
4881
4881
  const geometry = parseMagickGeometry(raw);
4882
+ if (geometry.isPercent) return { ...geometry, x: 0, y: 0 };
4882
4883
  if (geometry.hasOffset && geometry.width !== void 0 && !raw.toLowerCase().includes("x")) {
4883
4884
  throw new Error(`invalid argument for option '-roll': ${raw}`);
4884
4885
  }
@@ -7797,32 +7798,37 @@ function runIdentifyCliSync(argv, files, stdinBytes, signal) {
7797
7798
  }
7798
7799
  return next.value;
7799
7800
  }
7800
- function* parseMagickIndexSpec(spec, length) {
7801
+ function parseMagickIndices(spec, ranges = true) {
7802
+ if (!spec.trim() || spec.trimStart().startsWith(",")) throw new Error(`invalid argument ${spec}`);
7803
+ return spec.split(",").filter((part) => part.trim()).map((part) => {
7804
+ const value = part.trim();
7805
+ const separator = ranges ? value.indexOf("-", 1) : -1;
7806
+ const values = separator > 0 ? [value.slice(0, separator), value.slice(separator + 1)] : [value];
7807
+ return values.map((value2) => {
7808
+ const digits = value2.startsWith("-") ? value2.slice(1) : value2;
7809
+ if (!digits.length || !Array.from(digits).every((c) => c >= "0" && c <= "9") || !Number.isSafeInteger(Number(value2))) {
7810
+ throw new Error(`invalid argument ${spec}`);
7811
+ }
7812
+ return Number(value2);
7813
+ });
7814
+ });
7815
+ }
7816
+ function* parseMagickIndexSpec(spec, length, operation) {
7817
+ const parts = parseMagickIndices(spec);
7801
7818
  if (length <= 0) return;
7802
7819
  const resolve = (n) => n < 0 ? Math.max(0, length + n) : Math.min(Math.max(0, n), length - 1);
7803
- for (const part of spec.split(",")) {
7804
- const trimmed = part.trim();
7805
- if (!trimmed) continue;
7806
- const separator = trimmed.indexOf("-", 1);
7807
- const integer = (value) => {
7808
- const digits = value.startsWith("-") ? value.slice(1) : value;
7809
- return digits.length > 0 && Array.from(digits).every((c) => c >= "0" && c <= "9");
7810
- };
7811
- const rangeMatch = separator > 0 && integer(trimmed.slice(0, separator)) && integer(trimmed.slice(separator + 1)) ? [trimmed, trimmed.slice(0, separator), trimmed.slice(separator + 1)] : void 0;
7812
- if (rangeMatch) {
7813
- const s = resolve(parseInt(rangeMatch[1], 10));
7814
- const e = resolve(parseInt(rangeMatch[2], 10));
7815
- if (s <= e) {
7816
- for (let k = s; k <= e; k++) yield k;
7817
- } else {
7818
- for (let k = s; k >= e; k--) yield k;
7820
+ for (const [num, end] of parts) {
7821
+ if (end !== void 0) {
7822
+ const s = resolve(num), e = resolve(end), step = s <= e ? 1 : -1;
7823
+ if (operation === "delete" && s > e) continue;
7824
+ for (let k = s; ; k += step) {
7825
+ yield k;
7826
+ if (k === e) break;
7819
7827
  }
7820
7828
  } else {
7821
- const num = parseInt(trimmed, 10);
7822
- if (!Number.isNaN(num)) {
7823
- const idx = num < 0 ? length + num : num;
7824
- if (idx >= 0 && idx < length) yield idx;
7825
- }
7829
+ const idx = num < 0 ? length + num : num;
7830
+ if (idx >= 0 && idx < length) yield idx;
7831
+ else if (operation === "clone") throw new Error(`invalid image index ${num}`);
7826
7832
  }
7827
7833
  }
7828
7834
  }
@@ -8619,7 +8625,7 @@ function applyMagickReadSetting(tokens, state, start) {
8619
8625
  } else return void 0;
8620
8626
  return i;
8621
8627
  }
8622
- function* evaluatePipelineTokensSteps(tokens, files, state, parentStack = [], stdinBytes, signal, analysis = { text: "", warnings: "" }) {
8628
+ function* evaluatePipelineTokensSteps(tokens, files, state, parentStack, stdinBytes, signal, analysis = { text: "", warnings: "" }) {
8623
8629
  let cooperativeWork = 63;
8624
8630
  let stack = [];
8625
8631
  let operandsOnly = false;
@@ -9077,14 +9083,11 @@ function* evaluatePipelineTokensSteps(tokens, files, state, parentStack = [], st
9077
9083
  }
9078
9084
  stack = nextStack;
9079
9085
  } else if (t === "-combine") {
9080
- if (stack.length >= 3) {
9086
+ if (stack.length > 0) {
9081
9087
  const rIm = stack[0];
9082
- const gIm = stack[1] ?? rIm;
9083
- const bIm = stack[2] ?? rIm;
9084
- const aIm = stack[3];
9085
- const sources = [rIm, gIm, bIm, ...aIm ? [aIm] : []];
9088
+ const sources = stack.slice(0, 4);
9086
9089
  const result = yield* applyMagickRasterSteps(rIm, combinePixelSteps(rIm.width * rIm.height * 4, sources.map((image) => image.data.length)), signal, rIm, sources);
9087
- stack = [{ ...result, space: "srgb", channels: 4, hasAlpha: Boolean(aIm) }];
9090
+ stack = [{ ...result, space: "srgb", channels: 4, hasAlpha: sources.length === 4 }];
9088
9091
  }
9089
9092
  } else if (t === "-draw") {
9090
9093
  const drawSpec = tokens[++i] ?? "";
@@ -9115,9 +9118,10 @@ function* evaluatePipelineTokensSteps(tokens, files, state, parentStack = [], st
9115
9118
  return yield* applyMagickRasterSteps(im, annotatePixelSteps(im, offset, text, state), signal);
9116
9119
  });
9117
9120
  } else if (t === "+clone" || t === "-clone") {
9118
- const sourcePool = stack.length > 0 ? stack : parentStack;
9121
+ const sourcePool = parentStack ?? stack;
9122
+ if (sourcePool.length === 0) throw new Error(`UnableToCloneImage ${t}`);
9119
9123
  const spec = t === "+clone" ? "-1" : tokens[++i] ?? "-1";
9120
- for (const idx of parseMagickIndexSpec(spec, sourcePool.length)) {
9124
+ for (const idx of parseMagickIndexSpec(spec, sourcePool.length, "clone")) {
9121
9125
  if (++cooperativeWork % 65536 === 0)
9122
9126
  yield;
9123
9127
  const chosen = sourcePool[idx];
@@ -9125,27 +9129,23 @@ function* evaluatePipelineTokensSteps(tokens, files, state, parentStack = [], st
9125
9129
  stack.push({ ...chosen, data: new Uint8Array(chosen.data) });
9126
9130
  }
9127
9131
  } else if (t === "-duplicate" || t === "+duplicate") {
9132
+ if (stack.length === 0) throw new Error(`no images found for operation ${t}`);
9128
9133
  let count = 1;
9129
9134
  let idxSpec = "-1";
9130
9135
  if (t === "-duplicate") {
9131
- const nextTok = tokens[i + 1];
9132
- if (nextTok && /^\d+/.test(nextTok)) {
9133
- i++;
9134
- const commaIdx = nextTok.indexOf(",");
9135
- if (commaIdx >= 0) {
9136
- count = Math.max(0, parseInt(nextTok.slice(0, commaIdx), 10));
9137
- idxSpec = nextTok.slice(commaIdx + 1) || "-1";
9138
- } else {
9139
- count = Math.max(0, parseInt(nextTok, 10));
9140
- }
9141
- }
9142
- }
9143
- const sourcePool = stack.length > 0 ? stack : parentStack;
9136
+ const value = tokens[++i] ?? "", comma = value.indexOf(",");
9137
+ const countSpec = comma < 0 ? value : value.slice(0, comma);
9138
+ count = parseInt(countSpec, 10);
9139
+ if (!Number.isSafeInteger(count) || count < 0) throw new Error(`invalid argument ${value}`);
9140
+ idxSpec = comma < 0 ? "-1" : value.slice(comma + 1) || "-1";
9141
+ parseMagickIndices(idxSpec);
9142
+ }
9143
+ const sourcePool = stack;
9144
9144
  const sourceLength = sourcePool.length;
9145
9145
  for (let k = 0; k < count; k++) {
9146
9146
  if (++cooperativeWork % 65536 === 0)
9147
9147
  yield;
9148
- for (const idx of parseMagickIndexSpec(idxSpec, sourceLength)) {
9148
+ for (const idx of parseMagickIndexSpec(idxSpec, sourceLength, "clone")) {
9149
9149
  if (++cooperativeWork % 65536 === 0)
9150
9150
  yield;
9151
9151
  const chosen = sourcePool[idx];
@@ -9155,30 +9155,30 @@ function* evaluatePipelineTokensSteps(tokens, files, state, parentStack = [], st
9155
9155
  }
9156
9156
  } else if (t === "+insert" || t === "-insert") {
9157
9157
  const rawIdx = t === "+insert" ? 0 : Number(tokens[++i] ?? 0);
9158
+ const target = rawIdx < 0 ? stack.length - 1 + rawIdx : rawIdx;
9159
+ if (!Number.isInteger(target) || target < 0 || target >= stack.length || rawIdx < 0 && target === 0) throw new Error(`invalid image index ${t}`);
9158
9160
  if (stack.length > 1) {
9159
9161
  const last = stack.pop();
9160
- const target = rawIdx < 0 ? Math.max(0, stack.length + 1 + rawIdx) : Math.min(stack.length, Math.max(0, rawIdx));
9161
9162
  stack.splice(target, 0, last);
9162
9163
  }
9163
9164
  } else if (t === "+swap" || t === "-swap") {
9164
9165
  let i1 = stack.length - 2;
9165
9166
  let i2 = stack.length - 1;
9166
9167
  if (t === "-swap") {
9167
- const [s1, s2] = (tokens[++i] ?? "-2,-1").split(",").map((n) => Number(n));
9168
+ const [s1, s2] = parseMagickIndices(tokens[++i] ?? "-2,-1", false).flat();
9168
9169
  i1 = (s1 ?? -2) < 0 ? stack.length + (s1 ?? -2) : s1 ?? 0;
9169
9170
  i2 = (s2 ?? -1) < 0 ? stack.length + (s2 ?? -1) : s2 ?? 0;
9170
9171
  }
9171
- if (stack[i1] && stack[i2]) {
9172
- const tmp = stack[i1];
9173
- stack[i1] = stack[i2];
9174
- stack[i2] = tmp;
9175
- }
9172
+ if (i1 === i2 || !stack[i1] || !stack[i2]) throw new Error(`invalid image index ${t}`);
9173
+ const tmp = stack[i1];
9174
+ stack[i1] = stack[i2];
9175
+ stack[i2] = tmp;
9176
9176
  } else if (t === "+delete" || t === "-delete") {
9177
9177
  if (t === "+delete") {
9178
9178
  const popped = stack.pop();
9179
9179
  if (popped) detachRgbaBuffer(popped.data);
9180
9180
  } else {
9181
- const toDelete = new Set(parseMagickIndexSpec(tokens[++i] ?? "-1", stack.length));
9181
+ const toDelete = new Set(parseMagickIndexSpec(tokens[++i] ?? "-1", stack.length, "delete"));
9182
9182
  stack = stack.filter((im, idx) => {
9183
9183
  if (toDelete.has(idx)) {
9184
9184
  detachRgbaBuffer(im.data);
@@ -9335,7 +9335,7 @@ function* runConvertCliResultSteps(argv, files, stdinBytes, signal, analysis = {
9335
9335
  const pipelineTokens = argv.slice(0, -1);
9336
9336
  const state = createDefaultState();
9337
9337
  try {
9338
- const stack = yield* evaluatePipelineTokensSteps(pipelineTokens, files, state, [], stdinBytes, signal, analysis);
9338
+ const stack = yield* evaluatePipelineTokensSteps(pipelineTokens, files, state, void 0, stdinBytes, signal, analysis);
9339
9339
  if (stack.length === 0) {
9340
9340
  return {
9341
9341
  exitCode: 1,
@@ -9535,7 +9535,8 @@ async function transformStoredMagickCoordinates(image, backend, token, geometry,
9535
9535
  xs = [{ source: 0, target: 0, length: x }, { source: x, target: x + sw, length: w - x }];
9536
9536
  ys = [{ source: 0, target: 0, length: y }, { source: y, target: y + sh, length: h - y }];
9537
9537
  } else {
9538
- const cw = Math.max(0, Math.round(g.width ?? 0)), ch = Math.max(0, Math.round(g.height ?? 0));
9538
+ const cw = Math.max(0, Math.round((g.width ?? 0) * (g.isPercent ? w / 100 : 1)));
9539
+ const ch = Math.max(0, Math.round((g.height ?? 0) * (g.isPercent ? h / 100 : 1)));
9539
9540
  const { x, y } = gravityAdjustBox(w, h, cw, ch, g.x, g.y, state.gravity);
9540
9541
  if (x + cw < 0 || y + ch < 0 || x > w || y > h) return image;
9541
9542
  const x0 = Math.max(0, Math.min(w, x)), x1 = Math.max(x0, Math.min(w, x + cw));
@@ -9686,34 +9687,42 @@ async function tryConvertFilesResult(argv, input, stdinBytes, signal, analysis)
9686
9687
  if (!operandsOnly && ["+clone", "-clone", "+duplicate", "-duplicate", "+delete", "-delete", "+swap", "-swap", "-reverse", "+insert", "-insert"].includes(token)) {
9687
9688
  let spec = "-1", count = 1;
9688
9689
  if (["-clone", "-delete", "-swap", "-insert"].includes(token)) spec = tokens[++i] ?? (token === "-swap" ? "-2,-1" : token === "-insert" ? "0" : "-1");
9689
- if (token === "-duplicate" && tokens[i + 1]?.[0] && tokens[i + 1][0] >= "0" && tokens[i + 1][0] <= "9") {
9690
- const value = tokens[++i], comma = value.indexOf(",");
9691
- count = Math.max(0, parseInt(value, 10));
9690
+ if (token === "-duplicate") {
9691
+ const value = tokens[++i] ?? "", comma = value.indexOf(",");
9692
+ count = parseInt(value, 10);
9693
+ if (!Number.isSafeInteger(count) || count < 0) throw new Error(`invalid argument ${value}`);
9692
9694
  spec = comma < 0 ? "-1" : value.slice(comma + 1) || "-1";
9695
+ parseMagickIndices(spec);
9693
9696
  }
9694
9697
  stackStep(async (stack, _backend, parents) => {
9698
+ if (token.endsWith("duplicate") && stack.length === 0) throw new Error(`no images found for operation ${token}`);
9695
9699
  if (token.endsWith("clone") || token.endsWith("duplicate")) {
9696
- const source = stack.length ? stack : parents.at(-1) ?? stack, length = source.length;
9697
- for (let repeat = 0; repeat < count; repeat++) for (const index of parseMagickIndexSpec(spec, length)) {
9700
+ const source = token.endsWith("clone") ? parents.at(-1) ?? stack : stack;
9701
+ const length = source.length;
9702
+ if (token.endsWith("clone") && length === 0) throw new Error(`UnableToCloneImage ${token}`);
9703
+ for (let repeat = 0; repeat < count; repeat++) for (const index of parseMagickIndexSpec(spec, length, "clone")) {
9698
9704
  await yieldTurn11(signal);
9699
9705
  await stack.push(await source.get(index));
9700
9706
  }
9701
- } else if (token.endsWith("delete")) await stack.remove(parseMagickIndexSpec(spec, stack.length));
9707
+ } else if (token.endsWith("delete")) await stack.remove(parseMagickIndexSpec(spec, stack.length, "delete"));
9702
9708
  else if (token === "-reverse") {
9703
9709
  for (let n = 0; n < Math.floor(stack.length / 2); n++) {
9704
9710
  await yieldTurn11(signal);
9705
9711
  await stack.swap(n, stack.length - 1 - n);
9706
9712
  }
9707
9713
  } else if (token.endsWith("insert")) {
9708
- const raw = token === "+insert" ? 0 : Number(spec), target = raw < 0 ? Math.max(0, stack.length + raw) : Math.min(stack.length - 1, Math.max(0, raw));
9714
+ const raw = token === "+insert" ? 0 : Number(spec), target = raw < 0 ? stack.length - 1 + raw : raw;
9715
+ if (!Number.isInteger(target) || target < 0 || target >= stack.length || raw < 0 && target === 0) throw new Error(`invalid image index ${token}`);
9709
9716
  for (let n = stack.length - 1; n > target; n--) {
9710
9717
  await yieldTurn11(signal);
9711
9718
  await stack.swap(n, n - 1);
9712
9719
  }
9713
9720
  } else {
9714
- const values = (token === "+swap" ? "-2,-1" : spec).split(",").map(Number);
9721
+ const values = parseMagickIndices(token === "+swap" ? "-2,-1" : spec, false).flat();
9715
9722
  const a = values[0] ?? -2, b = values[1] ?? -1;
9716
- await stack.swap(a < 0 ? stack.length + a : a, b < 0 ? stack.length + b : b);
9723
+ const i1 = a < 0 ? stack.length + a : a, i2 = b < 0 ? stack.length + b : b;
9724
+ if (i1 === i2 || i1 < 0 || i2 < 0 || i1 >= stack.length || i2 >= stack.length) throw new Error(`invalid image index ${token}`);
9725
+ await stack.swap(i1, i2);
9717
9726
  }
9718
9727
  return stack;
9719
9728
  });
@@ -9743,7 +9752,7 @@ async function tryConvertFilesResult(argv, input, stdinBytes, signal, analysis)
9743
9752
  }
9744
9753
  return result;
9745
9754
  } else if (token === "-combine") {
9746
- if (stack.length < 3) return stack;
9755
+ if (stack.length === 0) return stack;
9747
9756
  const sources = [];
9748
9757
  for (let index = 0; index < Math.min(4, stack.length); index++) sources.push(await stack.get(index));
9749
9758
  const base = sources[0], result = await transformStoredMagickRaster(base, backend, combinePixelSteps(base.width * base.height * 4, sources.map((image) => image.width * image.height * 4)), signal, base, sources);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poe-platform/safe-bash",
3
- "version": "0.1.843",
3
+ "version": "0.1.844",
4
4
  "description": "Extensible virtual shell with pluggable filesystems and streaming commands",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1415,7 +1415,7 @@
1415
1415
  "access": "public"
1416
1416
  },
1417
1417
  "dependencies": {
1418
- "@poe-platform/safe-fs": "0.1.843",
1418
+ "@poe-platform/safe-fs": "0.1.844",
1419
1419
  "pdf-lib": "1.17.1",
1420
1420
  "@types/node": "^25.2.2",
1421
1421
  "@formatjs/intl-numberformat": "9.4.0",