@poe-platform/safe-bash 0.1.744 → 0.1.746
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/dist/image-ast/browser/sharp.d.ts +1 -1
- package/dist/image-ast/index.js +133 -35
- package/dist/image-ast/sharp.d.ts +1 -1
- package/dist/safe-bash/chunks/{chunk-2CO4WCMK.js → chunk-3ZNXN3XO.js} +434 -245
- package/dist/safe-bash/chunks/{chunk-2F7Q532M.js → chunk-4GK4FAT6.js} +3 -3
- package/dist/safe-bash/chunks/{chunk-WCNFCN2G.js → chunk-BS6QFRNX.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-IZZ7KX4E.js → chunk-JCXAGOEK.js} +40 -3
- package/dist/safe-bash/chunks/{chunk-WN7FYUWU.js → chunk-MC2KZY3D.js} +26 -13
- package/dist/safe-bash/chunks/{chunk-I3DOFJSJ.js → chunk-MUWJPSGN.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-7RP6WOWK.js → chunk-OF2PDE3W.js} +2 -2
- package/dist/safe-bash/chunks/{pdf-renderer-3TVUXNBT.js → pdf-renderer-4APIM7F7.js} +2 -2
- package/dist/safe-bash/chunks/{src-5VZS2ZKB.js → src-T2WAWJXF.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-DRCPJVZF.js → chunk-44N2IRVP.js} +17 -5
- package/dist/safe-bash/command-chunks/{chunk-LYKC7WJB.js → chunk-6742OVAC.js} +37 -3
- package/dist/safe-bash/command-chunks/{chunk-BMBXSLVX.js → chunk-6QU5OLPJ.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-YHANNN7I.js → chunk-S3BO2NJT.js} +7 -0
- package/dist/safe-bash/commands/basic.d.ts +2 -0
- package/dist/safe-bash/commands/basic.js +236 -9
- package/dist/safe-bash/commands/pr/index.browser.js +1 -1
- package/dist/safe-bash/commands/streams.js +9 -56
- package/dist/safe-bash/commands/table-text/index.js +5 -1
- package/dist/safe-bash/commands/text.js +13 -2
- package/dist/safe-bash/commands/time-env/shared.js +2 -2
- package/dist/safe-bash/commands/time-env/sleep.js +6 -4
- package/dist/safe-bash/commands/timeout/index.d.ts +7 -0
- package/dist/safe-bash/commands/timeout/index.js +52 -32
- package/dist/safe-bash/commands/timeout/scheduler.js +7 -6
- package/dist/safe-bash/core.browser.js +3475 -883
- package/dist/safe-bash/opt-in/commands/shuf/random.js +2 -3
- package/dist/safe-bash/opt-in/shell/extensions/read/index.js +1 -2
- package/dist/safe-bash/opt-in/shell/extensions/trap/index.d.ts +1 -2
- package/dist/safe-bash/opt-in/shell/extensions/trap/index.js +1 -8
- package/dist/safe-bash/playwright/adapter.d.ts +2 -0
- package/dist/safe-bash/playwright/capability-events.d.ts +7 -0
- package/dist/safe-bash/playwright/capability-events.js +11 -3
- package/dist/safe-bash/playwright/controller.d.ts +14 -0
- package/dist/safe-bash/playwright/controller.js +36 -8
- package/dist/safe-bash/playwright/index.d.ts +1 -0
- package/dist/safe-bash/playwright/index.js +1 -0
- package/dist/safe-bash/playwright/private-target-transport.d.ts +1 -0
- package/dist/safe-bash/playwright/private-target-transport.js +21 -21
- package/dist/safe-bash/shell/runtime.d.ts +34 -2
- package/dist/safe-bash/shell/runtime.js +4107 -947
- package/dist/safe-bash/shell/sync-jq-expression.d.ts +6 -0
- package/dist/safe-bash/shell/sync-jq-expression.js +46 -0
- package/dist/safe-bash-command-cal/index.js +32 -12
- package/dist/safe-bash-command-hostname/index.js +22 -7
- package/dist/safe-bash-command-id/index.js +28 -9
- package/dist/safe-bash-command-pandoc/command.js +1 -1
- package/dist/safe-bash-command-pandoc/index.js +1 -1
- package/dist/safe-bash-command-ssconvert/command.d.ts +2 -2
- package/dist/safe-bash-command-ssconvert/contracts.d.ts +4 -0
- package/dist/safe-bash-command-ssconvert/engine.d.ts +2 -2
- package/dist/safe-bash-command-ssconvert/index.js +421 -237
- package/dist/safe-bash-command-whoami/index.js +26 -12
- package/dist/safe-bash-command-wkhtmltopdf/index.js +24 -11
- package/dist/safe-bash-command-wkhtmltopdf/limits.d.ts +1 -1
- package/dist/safe-bash-command-wkhtmltopdf/resources.d.ts +1 -1
- package/dist/safe-bash-query-engine/index.js +3 -3
- package/dist/safe-bash-query-engine/interpreter.js +1 -1
- package/dist/safe-bash-query-engine/parser.js +1 -1
- package/dist/safe-bash-query-engine/query-core.js +3 -3
- package/dist/safe-playwright-cloudflare/browser-private-transport.js +8 -13
- package/dist/safe-playwright-cloudflare/browser-storage-control.js +13 -4
- package/dist/safe-playwright-cloudflare/browser-trace-archive.js +1 -1
- package/package.json +18 -14
- package/dist/image-ast/streams/node.d.ts +0 -10
- package/dist/image-ast/streams/node.js +0 -5
- package/dist/image-ast/streams/web.js +0 -94
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { getCommandArguments, writeBytes } from "../../contracts/index.js";
|
|
1
|
+
import { FsError, getCommandArguments, writeBytes } from "../../contracts/index.js";
|
|
2
|
+
import { shellValueByteLength } from "../../contracts/value.js";
|
|
2
3
|
import { parseDuration } from "./duration.js";
|
|
3
4
|
import { parseSignal } from "./signal.js";
|
|
4
5
|
import { createDeadline, defaultSchedulerBinding } from "./scheduler.js";
|
|
@@ -25,6 +26,14 @@ function optionsObject(value) {
|
|
|
25
26
|
}
|
|
26
27
|
function settings(value, includeReplace) {
|
|
27
28
|
const options = optionsObject(value);
|
|
29
|
+
const configuredLimits = optionsObject(options?.limits);
|
|
30
|
+
const limits = {
|
|
31
|
+
maxArguments: Infinity, maxArgumentBytes: Infinity, maxOutputBytes: Infinity, ...configuredLimits,
|
|
32
|
+
};
|
|
33
|
+
for (const [name, limit] of Object.entries(limits)) {
|
|
34
|
+
if (limit !== Infinity && (!Number.isSafeInteger(limit) || limit < 1))
|
|
35
|
+
throw new RangeError(`Invalid timeout limit: ${name}`);
|
|
36
|
+
}
|
|
28
37
|
const killAfterPolicy = options?.killAfterPolicy;
|
|
29
38
|
if (killAfterPolicy !== undefined && typeof killAfterPolicy !== "function")
|
|
30
39
|
throw new TypeError("Timeout killAfterPolicy must be a function");
|
|
@@ -54,8 +63,8 @@ function settings(value, includeReplace) {
|
|
|
54
63
|
const maximum = options?.maxTimerMilliseconds;
|
|
55
64
|
if (maximum !== undefined && typeof maximum !== "number")
|
|
56
65
|
throw new TypeError("Timeout maxTimerMilliseconds must be a number");
|
|
57
|
-
if (maximum !== undefined && (!Number.isInteger(maximum) || maximum < 1 || maximum > 2147483647)) {
|
|
58
|
-
throw new RangeError("Timeout maxTimerMilliseconds must be an integer from 1 through 2147483647");
|
|
66
|
+
if (maximum !== undefined && maximum !== Infinity && (!Number.isInteger(maximum) || maximum < 1 || maximum > 2147483647)) {
|
|
67
|
+
throw new RangeError("Timeout maxTimerMilliseconds must be an integer from 1 through 2147483647 or Infinity");
|
|
59
68
|
}
|
|
60
69
|
let replace = false;
|
|
61
70
|
if (includeReplace) {
|
|
@@ -64,9 +73,11 @@ function settings(value, includeReplace) {
|
|
|
64
73
|
throw new TypeError("Timeout replace must be a boolean");
|
|
65
74
|
replace = configured ?? false;
|
|
66
75
|
}
|
|
67
|
-
return { invoke, killAfterPolicy: killAfterPolicy, scheduler: binding, maxTimerMilliseconds: maximum ?? 2147483647, replace };
|
|
76
|
+
return { limits, invoke, killAfterPolicy: killAfterPolicy, scheduler: binding, maxTimerMilliseconds: maximum ?? 2147483647, replace };
|
|
68
77
|
}
|
|
69
|
-
async function status(context, bytes, exitCode, stdout = false) {
|
|
78
|
+
async function status(configuration, context, bytes, exitCode, stdout = false) {
|
|
79
|
+
if (bytes.length > configuration.limits.maxOutputBytes)
|
|
80
|
+
throw new FsError("EFBIG", { message: "timeout output limit exceeded" });
|
|
70
81
|
await writeBytes(stdout ? context.stdout : context.stderr, bytes, context.signal);
|
|
71
82
|
return { exitCode };
|
|
72
83
|
}
|
|
@@ -82,7 +93,18 @@ function definition(configuration) {
|
|
|
82
93
|
name: "timeout",
|
|
83
94
|
description: "Run a virtual command with a cooperative time limit",
|
|
84
95
|
async execute(context) {
|
|
96
|
+
context.signal.throwIfAborted();
|
|
85
97
|
const originalArgs = context.args;
|
|
98
|
+
if (originalArgs.length > configuration.limits.maxArguments)
|
|
99
|
+
throw new FsError("EFBIG", { message: "timeout argument count limit exceeded" });
|
|
100
|
+
const suppliedValues = "argumentValues" in context ? context.argumentValues : undefined;
|
|
101
|
+
const ownedArguments = suppliedValues === undefined ? undefined : getCommandArguments(context);
|
|
102
|
+
let argumentBytes = 0;
|
|
103
|
+
for (const argument of ownedArguments?.values ?? originalArgs) {
|
|
104
|
+
argumentBytes += shellValueByteLength(argument);
|
|
105
|
+
if (argumentBytes > configuration.limits.maxArgumentBytes)
|
|
106
|
+
throw new FsError("EFBIG", { message: "timeout argument limit exceeded" });
|
|
107
|
+
}
|
|
86
108
|
let offset = 0;
|
|
87
109
|
let preserveStatus = false;
|
|
88
110
|
let verbose = false;
|
|
@@ -96,9 +118,9 @@ function definition(configuration) {
|
|
|
96
118
|
break;
|
|
97
119
|
}
|
|
98
120
|
if (token === "--help")
|
|
99
|
-
return status(context, records.help, 0, true);
|
|
121
|
+
return status(configuration, context, records.help, 0, true);
|
|
100
122
|
if (token === "--version")
|
|
101
|
-
return status(context, records.version, 0, true);
|
|
123
|
+
return status(configuration, context, records.version, 0, true);
|
|
102
124
|
if (token === "-" || !token.startsWith("-"))
|
|
103
125
|
break;
|
|
104
126
|
if (token === "--verbose") {
|
|
@@ -119,12 +141,12 @@ function definition(configuration) {
|
|
|
119
141
|
if (token === "--kill-after" || token.startsWith("--kill-after=")) {
|
|
120
142
|
const duration = token === "--kill-after" ? originalArgs[++offset] : token.slice(13);
|
|
121
143
|
if (duration === undefined)
|
|
122
|
-
return status(context, records.missingDuration, 125);
|
|
144
|
+
return status(configuration, context, records.missingDuration, 125);
|
|
123
145
|
const killAfter = parseDuration(duration);
|
|
124
146
|
if (killAfter.kind === "invalid")
|
|
125
|
-
return status(context, records.invalidDuration, 125);
|
|
147
|
+
return status(configuration, context, records.invalidDuration, 125);
|
|
126
148
|
if (killAfter.kind === "overflow")
|
|
127
|
-
return status(context, records.durationOverflow, 125);
|
|
149
|
+
return status(configuration, context, records.durationOverflow, 125);
|
|
128
150
|
killAfterMilliseconds = killAfter.milliseconds;
|
|
129
151
|
offset++;
|
|
130
152
|
continue;
|
|
@@ -132,10 +154,10 @@ function definition(configuration) {
|
|
|
132
154
|
if (token === "--signal" || token.startsWith("--signal=")) {
|
|
133
155
|
const signalToken = token === "--signal" ? originalArgs[++offset] : token.slice(9);
|
|
134
156
|
if (signalToken === undefined)
|
|
135
|
-
return status(context, records.invalidSignal, 125);
|
|
157
|
+
return status(configuration, context, records.invalidSignal, 125);
|
|
136
158
|
const parsedSignal = parseSignal(signalToken);
|
|
137
159
|
if (parsedSignal === undefined)
|
|
138
|
-
return status(context, records.invalidSignal, 125);
|
|
160
|
+
return status(configuration, context, records.invalidSignal, 125);
|
|
139
161
|
signalNumber = parsedSignal;
|
|
140
162
|
offset++;
|
|
141
163
|
continue;
|
|
@@ -162,46 +184,44 @@ function definition(configuration) {
|
|
|
162
184
|
if (flag === "k") {
|
|
163
185
|
const duration = token.slice(position + 1) || originalArgs[++offset];
|
|
164
186
|
if (duration === undefined)
|
|
165
|
-
return status(context, records.missingDuration, 125);
|
|
187
|
+
return status(configuration, context, records.missingDuration, 125);
|
|
166
188
|
const killAfter = parseDuration(duration);
|
|
167
189
|
if (killAfter.kind === "invalid")
|
|
168
|
-
return status(context, records.invalidDuration, 125);
|
|
190
|
+
return status(configuration, context, records.invalidDuration, 125);
|
|
169
191
|
if (killAfter.kind === "overflow")
|
|
170
|
-
return status(context, records.durationOverflow, 125);
|
|
192
|
+
return status(configuration, context, records.durationOverflow, 125);
|
|
171
193
|
killAfterMilliseconds = killAfter.milliseconds;
|
|
172
194
|
break;
|
|
173
195
|
}
|
|
174
196
|
if (flag === "s") {
|
|
175
197
|
const signalToken = token.slice(position + 1) || originalArgs[++offset];
|
|
176
198
|
if (signalToken === undefined)
|
|
177
|
-
return status(context, records.invalidSignal, 125);
|
|
199
|
+
return status(configuration, context, records.invalidSignal, 125);
|
|
178
200
|
const parsedSignal = parseSignal(signalToken);
|
|
179
201
|
if (parsedSignal === undefined)
|
|
180
|
-
return status(context, records.invalidSignal, 125);
|
|
202
|
+
return status(configuration, context, records.invalidSignal, 125);
|
|
181
203
|
signalNumber = parsedSignal;
|
|
182
204
|
break;
|
|
183
205
|
}
|
|
184
|
-
return status(context, records.invalidOption, 125);
|
|
206
|
+
return status(configuration, context, records.invalidOption, 125);
|
|
185
207
|
}
|
|
186
208
|
offset++;
|
|
187
209
|
continue;
|
|
188
210
|
}
|
|
189
|
-
return status(context, records.invalidOption, 125);
|
|
211
|
+
return status(configuration, context, records.invalidOption, 125);
|
|
190
212
|
}
|
|
191
213
|
const durationToken = originalArgs[offset];
|
|
192
214
|
if (durationToken === undefined)
|
|
193
|
-
return status(context, records.missingDuration, 125);
|
|
215
|
+
return status(configuration, context, records.missingDuration, 125);
|
|
194
216
|
const parsed = parseDuration(durationToken);
|
|
195
217
|
if (parsed.kind === "invalid")
|
|
196
|
-
return status(context, records.invalidDuration, 125);
|
|
218
|
+
return status(configuration, context, records.invalidDuration, 125);
|
|
197
219
|
if (parsed.kind === "overflow")
|
|
198
|
-
return status(context, records.durationOverflow, 125);
|
|
220
|
+
return status(configuration, context, records.durationOverflow, 125);
|
|
199
221
|
const command = originalArgs[offset + 1];
|
|
200
222
|
if (command === undefined)
|
|
201
|
-
return status(context, records.missingCommand, 125);
|
|
202
|
-
const
|
|
203
|
-
const argumentValues = suppliedValues === undefined ? undefined
|
|
204
|
-
: getCommandArguments({ args: originalArgs, argumentValues: suppliedValues }).slice(offset + 2);
|
|
223
|
+
return status(configuration, context, records.missingCommand, 125);
|
|
224
|
+
const argumentValues = ownedArguments?.slice(offset + 2);
|
|
205
225
|
const args = argumentValues?.args ?? Object.freeze(originalArgs.slice(offset + 2));
|
|
206
226
|
const streams = {
|
|
207
227
|
...(argumentValues === undefined ? {} : { argumentValues }),
|
|
@@ -214,7 +234,7 @@ function definition(configuration) {
|
|
|
214
234
|
if (killAfterMilliseconds !== undefined && killAfterMilliseconds !== 0 && parsed.milliseconds !== 0 && parsed.milliseconds !== Infinity) {
|
|
215
235
|
context.signal.throwIfAborted();
|
|
216
236
|
if (typeof killAfterPolicy !== "function")
|
|
217
|
-
return status(context, records.escalationUnavailable, 125);
|
|
237
|
+
return status(configuration, context, records.escalationUnavailable, 125);
|
|
218
238
|
let result;
|
|
219
239
|
try {
|
|
220
240
|
result = await killAfterPolicy(context, command, args, { signal: context.signal, ...streams }, Object.freeze({
|
|
@@ -233,7 +253,7 @@ function definition(configuration) {
|
|
|
233
253
|
const selected = childInvoker(context, configuration.invoke);
|
|
234
254
|
if (parsed.milliseconds === 0 || parsed.milliseconds === Infinity) {
|
|
235
255
|
if (selected === undefined)
|
|
236
|
-
return status(context, records.invokeUnavailable, 125);
|
|
256
|
+
return status(configuration, context, records.invokeUnavailable, 125);
|
|
237
257
|
context.signal.throwIfAborted();
|
|
238
258
|
let result;
|
|
239
259
|
try {
|
|
@@ -247,7 +267,7 @@ function definition(configuration) {
|
|
|
247
267
|
return result;
|
|
248
268
|
}
|
|
249
269
|
if (selected === undefined)
|
|
250
|
-
return status(context, records.invokeUnavailable, 125);
|
|
270
|
+
return status(configuration, context, records.invokeUnavailable, 125);
|
|
251
271
|
context.signal.throwIfAborted();
|
|
252
272
|
const deadline = createDeadline(configuration.scheduler, parsed.milliseconds, configuration.maxTimerMilliseconds, signalNumber !== 0);
|
|
253
273
|
context.registerCleanup?.(deadline.retire);
|
|
@@ -267,7 +287,7 @@ function definition(configuration) {
|
|
|
267
287
|
context.signal.throwIfAborted();
|
|
268
288
|
if (retirementFailed)
|
|
269
289
|
throw retirementFailure;
|
|
270
|
-
return status(context, records.timerSetupFailed, 125);
|
|
290
|
+
return status(configuration, context, records.timerSetupFailed, 125);
|
|
271
291
|
}
|
|
272
292
|
let returned = false;
|
|
273
293
|
let result;
|
|
@@ -294,12 +314,12 @@ function definition(configuration) {
|
|
|
294
314
|
if (retirementFailed)
|
|
295
315
|
throw retirementFailure;
|
|
296
316
|
if (verbose && deadline.expired) {
|
|
297
|
-
await
|
|
317
|
+
await status(configuration, context, encoder.encode(`timeout: cooperative deadline expired for command ‘${command}’\n`), 0);
|
|
298
318
|
}
|
|
299
319
|
if (!returned && invocationFailure === deadline.deadlineReason)
|
|
300
320
|
return { exitCode: signalNumber === 9 || preserveStatus ? 128 + signalNumber : 124 };
|
|
301
321
|
if (deadline.signal.aborted && deadline.signal.reason === deadline.timerFailureReason)
|
|
302
|
-
return status(context, records.timerSetupFailed, 125);
|
|
322
|
+
return status(configuration, context, records.timerSetupFailed, 125);
|
|
303
323
|
if (deadline.expired && (!preserveStatus || signalNumber === 9))
|
|
304
324
|
return { exitCode: signalNumber === 9 ? 137 : 124 };
|
|
305
325
|
return result;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export const defaultSchedulerBinding = Object.freeze({
|
|
2
2
|
receiver: globalThis,
|
|
3
|
-
now: globalThis.performance.now
|
|
4
|
-
setTimeout: globalThis.setTimeout
|
|
5
|
-
clearTimeout: globalThis.clearTimeout
|
|
3
|
+
now: () => globalThis.performance.now(),
|
|
4
|
+
setTimeout: (callback, milliseconds) => globalThis.setTimeout(callback, milliseconds),
|
|
5
|
+
clearTimeout: (handle) => globalThis.clearTimeout(handle),
|
|
6
6
|
});
|
|
7
7
|
function clock(binding, previous) {
|
|
8
8
|
const sample = Reflect.apply(binding.now, binding.receiver, []);
|
|
@@ -20,6 +20,7 @@ export function createDeadline(binding, duration, maximumChunk, cancel = true) {
|
|
|
20
20
|
let expired = false;
|
|
21
21
|
let remaining = duration;
|
|
22
22
|
let previous = 0;
|
|
23
|
+
let step = 0;
|
|
23
24
|
let handle;
|
|
24
25
|
let handleLive = false;
|
|
25
26
|
let cleanupFailed = false;
|
|
@@ -50,8 +51,8 @@ export function createDeadline(binding, duration, maximumChunk, cancel = true) {
|
|
|
50
51
|
controller.abort(timerFailureReason);
|
|
51
52
|
};
|
|
52
53
|
const arm = () => {
|
|
53
|
-
|
|
54
|
-
handle = Reflect.apply(binding.setTimeout, binding.receiver, [wake,
|
|
54
|
+
step = Math.min(2147483647, maximumChunk, Math.max(1, Math.ceil(remaining)));
|
|
55
|
+
handle = Reflect.apply(binding.setTimeout, binding.receiver, [wake, step]);
|
|
55
56
|
handleLive = true;
|
|
56
57
|
};
|
|
57
58
|
const wake = () => {
|
|
@@ -65,7 +66,7 @@ export function createDeadline(binding, duration, maximumChunk, cancel = true) {
|
|
|
65
66
|
failTimer();
|
|
66
67
|
return;
|
|
67
68
|
}
|
|
68
|
-
remaining -= sample - previous;
|
|
69
|
+
remaining -= Math.max(step, sample - previous);
|
|
69
70
|
previous = sample;
|
|
70
71
|
if (remaining <= 0) {
|
|
71
72
|
admissionOpen = false;
|