@poe-platform/safe-bash 0.1.527 → 0.1.528
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/dist/safe-bash/core.browser.js +332 -21
- package/dist/safe-bash/core.browser.js.map +4 -4
- package/dist/safe-bash/shell/arrays/bindings.d.ts +4 -1
- package/dist/safe-bash/shell/arrays/bindings.d.ts.map +1 -1
- package/dist/safe-bash/shell/arrays/bindings.js +44 -1
- package/dist/safe-bash/shell/arrays/bindings.js.map +1 -1
- package/dist/safe-bash/shell/input.d.ts +4 -0
- package/dist/safe-bash/shell/input.d.ts.map +1 -1
- package/dist/safe-bash/shell/input.js +53 -0
- package/dist/safe-bash/shell/input.js.map +1 -1
- package/dist/safe-bash/shell/mapfile.d.ts +29 -0
- package/dist/safe-bash/shell/mapfile.d.ts.map +1 -0
- package/dist/safe-bash/shell/mapfile.js +134 -0
- package/dist/safe-bash/shell/mapfile.js.map +1 -0
- package/dist/safe-bash/shell/runtime.d.ts +3 -2
- package/dist/safe-bash/shell/runtime.d.ts.map +1 -1
- package/dist/safe-bash/shell/runtime.js +173 -22
- package/dist/safe-bash/shell/runtime.js.map +1 -1
- package/package.json +2 -2
|
@@ -40879,14 +40879,16 @@ var controlNames = /* @__PURE__ */ new Set([
|
|
|
40879
40879
|
"LC_CTYPE"
|
|
40880
40880
|
]);
|
|
40881
40881
|
var OwnedText = class {
|
|
40882
|
-
constructor(value2, bytes3, admission) {
|
|
40882
|
+
constructor(value2, bytes3, admission, rawValue) {
|
|
40883
40883
|
this.value = value2;
|
|
40884
40884
|
this.bytes = bytes3;
|
|
40885
40885
|
this.admission = admission;
|
|
40886
|
+
this.rawValue = rawValue;
|
|
40886
40887
|
}
|
|
40887
40888
|
value;
|
|
40888
40889
|
bytes;
|
|
40889
40890
|
admission;
|
|
40891
|
+
rawValue;
|
|
40890
40892
|
references = 1;
|
|
40891
40893
|
retain() {
|
|
40892
40894
|
if (this.references === Number.MAX_SAFE_INTEGER) throw new ArrayFailure("reference capacity is not representable");
|
|
@@ -40912,6 +40914,38 @@ async function textToken(owner, value2, signal) {
|
|
|
40912
40914
|
const admission = owner.reserve({ payload: bytes3, metadata: 32, work: 4 });
|
|
40913
40915
|
return new OwnedText(value2, bytes3, admission);
|
|
40914
40916
|
}
|
|
40917
|
+
async function valueToken(owner, value2, signal) {
|
|
40918
|
+
if (typeof value2 === "string") return textToken(owner, value2, signal);
|
|
40919
|
+
const bytes3 = shellValueByteLength(value2);
|
|
40920
|
+
const temporary = owner.reserve({ payload: bytes3 * 3, metadata: 64, work: 4 });
|
|
40921
|
+
try {
|
|
40922
|
+
const input3 = shellValueBytes(value2);
|
|
40923
|
+
const decoder2 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
40924
|
+
let text3 = "";
|
|
40925
|
+
for (let offset = 0; offset < bytes3; offset += 1024) {
|
|
40926
|
+
const end = Math.min(bytes3, offset + 1024);
|
|
40927
|
+
owner.reserve({ work: end - offset }).release();
|
|
40928
|
+
await owner.ledger.checkpoint(signal, end - offset);
|
|
40929
|
+
if (text3 !== void 0) try {
|
|
40930
|
+
text3 += decoder2.decode(input3.subarray(offset, end), { stream: end < bytes3 });
|
|
40931
|
+
} catch (error) {
|
|
40932
|
+
if (!(error instanceof TypeError) || "code" in error && error.code !== "ERR_ENCODING_INVALID_ENCODED_DATA") throw error;
|
|
40933
|
+
text3 = void 0;
|
|
40934
|
+
}
|
|
40935
|
+
}
|
|
40936
|
+
if (text3 !== void 0) return await textToken(owner, text3, signal);
|
|
40937
|
+
const admission = owner.reserve({ payload: bytes3 * 4, metadata: 128, work: 4 });
|
|
40938
|
+
try {
|
|
40939
|
+
const raw = shellValueFromBytes(input3);
|
|
40940
|
+
return new OwnedText(shellValueText(raw), bytes3, admission, raw);
|
|
40941
|
+
} catch (error) {
|
|
40942
|
+
admission.release();
|
|
40943
|
+
throw error;
|
|
40944
|
+
}
|
|
40945
|
+
} finally {
|
|
40946
|
+
temporary.release();
|
|
40947
|
+
}
|
|
40948
|
+
}
|
|
40915
40949
|
var IndexedBinding = class _IndexedBinding {
|
|
40916
40950
|
constructor(owner) {
|
|
40917
40951
|
this.owner = owner;
|
|
@@ -41148,6 +41182,116 @@ var BindingStore = class _BindingStore {
|
|
|
41148
41182
|
}
|
|
41149
41183
|
};
|
|
41150
41184
|
|
|
41185
|
+
// packages/safe-bash/src/shell/mapfile.ts
|
|
41186
|
+
init_platform();
|
|
41187
|
+
var MapfileUsageError = class extends Error {
|
|
41188
|
+
constructor(message3, status2) {
|
|
41189
|
+
super(message3);
|
|
41190
|
+
this.status = status2;
|
|
41191
|
+
}
|
|
41192
|
+
status;
|
|
41193
|
+
};
|
|
41194
|
+
async function mapfileOptions(context2, work, allocation) {
|
|
41195
|
+
const options3 = { name: "MAPFILE", strip: false, delimiter: 10, count: 0, skip: 0, origin: 0, preserve: false, callback: void 0, quantum: 5e3 };
|
|
41196
|
+
const args = getCommandArguments(context2);
|
|
41197
|
+
let cursor = 0;
|
|
41198
|
+
const numeric4 = async (text3, maximum) => {
|
|
41199
|
+
let value2 = 0;
|
|
41200
|
+
let index = 0;
|
|
41201
|
+
const whitespace2 = (code) => code === 32 || code >= 9 && code <= 13;
|
|
41202
|
+
while (index < text3.length && whitespace2(text3.charCodeAt(index))) {
|
|
41203
|
+
const pending = stringCheckpoint(work);
|
|
41204
|
+
if (pending) await pending;
|
|
41205
|
+
index++;
|
|
41206
|
+
}
|
|
41207
|
+
const negative = text3[index] === "-";
|
|
41208
|
+
if (negative || text3[index] === "+") index++;
|
|
41209
|
+
let digits = 0;
|
|
41210
|
+
for (; index < text3.length; index++) {
|
|
41211
|
+
const pending = stringCheckpoint(work);
|
|
41212
|
+
if (pending) await pending;
|
|
41213
|
+
const digit3 = text3.charCodeAt(index) - 48;
|
|
41214
|
+
if (digit3 < 0 || digit3 > 9) break;
|
|
41215
|
+
if (value2 > Math.floor((maximum - digit3) / 10)) throw new MapfileUsageError(`${text3}: invalid number`, 1);
|
|
41216
|
+
value2 = value2 * 10 + digit3;
|
|
41217
|
+
digits++;
|
|
41218
|
+
}
|
|
41219
|
+
for (; index < text3.length; index++) {
|
|
41220
|
+
const pending = stringCheckpoint(work);
|
|
41221
|
+
if (pending) await pending;
|
|
41222
|
+
if (!whitespace2(text3.charCodeAt(index))) throw new MapfileUsageError(`${text3}: invalid number`, 1);
|
|
41223
|
+
}
|
|
41224
|
+
if (!digits || negative && value2 !== 0) throw new MapfileUsageError(`${text3}: invalid number`, 1);
|
|
41225
|
+
return value2;
|
|
41226
|
+
};
|
|
41227
|
+
while (cursor < context2.args.length) {
|
|
41228
|
+
const option = context2.args[cursor];
|
|
41229
|
+
if (option === "--") {
|
|
41230
|
+
cursor++;
|
|
41231
|
+
break;
|
|
41232
|
+
}
|
|
41233
|
+
if (!option.startsWith("-") || option === "-") break;
|
|
41234
|
+
cursor++;
|
|
41235
|
+
for (let index = 1; index < option.length; index++) {
|
|
41236
|
+
const pending = stringCheckpoint(work);
|
|
41237
|
+
if (pending) await pending;
|
|
41238
|
+
const flag = option[index];
|
|
41239
|
+
if (flag === "t") {
|
|
41240
|
+
options3.strip = true;
|
|
41241
|
+
continue;
|
|
41242
|
+
}
|
|
41243
|
+
if (!"dnsOCc".includes(flag)) throw new MapfileUsageError(`-${flag}: invalid option`, 2);
|
|
41244
|
+
const attached = index + 1 < option.length;
|
|
41245
|
+
const operandIndex = attached ? cursor - 1 : cursor++;
|
|
41246
|
+
const operand = attached ? option.slice(index + 1) : context2.args[operandIndex];
|
|
41247
|
+
if (operand === void 0) throw new MapfileUsageError(`-${flag}: option requires an argument`, 2);
|
|
41248
|
+
if (flag === "d") {
|
|
41249
|
+
const bytes3 = shellValueBytes(args.values[operandIndex], allocation);
|
|
41250
|
+
options3.delimiter = bytes3[attached ? index + 1 : 0] ?? 0;
|
|
41251
|
+
} else if (flag === "C") options3.callback = operand;
|
|
41252
|
+
else {
|
|
41253
|
+
const value2 = await numeric4(operand, flag === "O" ? 2147483647 : Number.MAX_SAFE_INTEGER);
|
|
41254
|
+
if (flag === "c") {
|
|
41255
|
+
if (!value2) throw new MapfileUsageError("0: invalid callback quantum", 1);
|
|
41256
|
+
options3.quantum = value2;
|
|
41257
|
+
} else if (flag === "n") options3.count = value2;
|
|
41258
|
+
else if (flag === "s") options3.skip = value2;
|
|
41259
|
+
else {
|
|
41260
|
+
options3.origin = value2;
|
|
41261
|
+
options3.preserve = true;
|
|
41262
|
+
}
|
|
41263
|
+
}
|
|
41264
|
+
break;
|
|
41265
|
+
}
|
|
41266
|
+
}
|
|
41267
|
+
options3.name = context2.args[cursor] ?? "MAPFILE";
|
|
41268
|
+
if (!/^[a-zA-Z_][a-zA-Z_0-9]*$/u.test(options3.name)) throw new MapfileUsageError(`${options3.name}: invalid identifier`, 1);
|
|
41269
|
+
return options3;
|
|
41270
|
+
}
|
|
41271
|
+
async function collectMapfile(options3, input3, hooks) {
|
|
41272
|
+
let skipped = 0;
|
|
41273
|
+
let written = 0;
|
|
41274
|
+
while (!options3.count || written < options3.count) {
|
|
41275
|
+
hooks.loop();
|
|
41276
|
+
const allocation = hooks.allocation();
|
|
41277
|
+
try {
|
|
41278
|
+
const record4 = await input3.mapfileRecord(options3.delimiter, options3.strip, allocation);
|
|
41279
|
+
if (!record4.present) break;
|
|
41280
|
+
if (skipped < options3.skip) {
|
|
41281
|
+
skipped++;
|
|
41282
|
+
continue;
|
|
41283
|
+
}
|
|
41284
|
+
const index = options3.origin + written;
|
|
41285
|
+
if (index > 2147483647) throw new MapfileUsageError("array index exceeds 2147483647", 1);
|
|
41286
|
+
if (options3.callback !== void 0 && (written + 1) % options3.quantum === 0) await hooks.callback(options3.callback, index, record4.value);
|
|
41287
|
+
await hooks.write(index, record4.value);
|
|
41288
|
+
written++;
|
|
41289
|
+
} finally {
|
|
41290
|
+
allocation.close();
|
|
41291
|
+
}
|
|
41292
|
+
}
|
|
41293
|
+
}
|
|
41294
|
+
|
|
41151
41295
|
// packages/safe-bash/src/shell/arrays/state.ts
|
|
41152
41296
|
init_platform();
|
|
41153
41297
|
var sessions = /* @__PURE__ */ new WeakMap();
|
|
@@ -41909,6 +42053,8 @@ var shellBuiltinNames = /* @__PURE__ */ new Set([
|
|
|
41909
42053
|
"local",
|
|
41910
42054
|
"unset",
|
|
41911
42055
|
"read",
|
|
42056
|
+
"mapfile",
|
|
42057
|
+
"readarray",
|
|
41912
42058
|
"exit",
|
|
41913
42059
|
"return",
|
|
41914
42060
|
"break",
|
|
@@ -42907,6 +43053,7 @@ var InvocationCancellationOwner = class {
|
|
|
42907
43053
|
this.#failures.push(...result2.failures);
|
|
42908
43054
|
}
|
|
42909
43055
|
};
|
|
43056
|
+
var mapfileCallbackStates = /* @__PURE__ */ new WeakSet();
|
|
42910
43057
|
var Runtime = class _Runtime {
|
|
42911
43058
|
constructor(fs, commands, middleware, budget, signal = budget.signal, fileWrites = /* @__PURE__ */ new Map(), outputFiles = /* @__PURE__ */ new Map(), commandSignal = signal, cancellation, cancellationState, cancellationOwner, cancellationDepth, cancellationMaxDepth, outcomeFrame = void 0, inputProfile = fs) {
|
|
42912
43059
|
this.fs = fs;
|
|
@@ -43257,7 +43404,7 @@ var Runtime = class _Runtime {
|
|
|
43257
43404
|
this.writeVariable(state, name2, value2, origin);
|
|
43258
43405
|
return;
|
|
43259
43406
|
}
|
|
43260
|
-
await this.arrayZero(state, name2, async () =>
|
|
43407
|
+
await this.arrayZero(state, name2, async () => value2);
|
|
43261
43408
|
}
|
|
43262
43409
|
async prepareVariable(state, name2, saved, scalarLegacy = false) {
|
|
43263
43410
|
const store = requireArrays(state);
|
|
@@ -43414,6 +43561,7 @@ var Runtime = class _Runtime {
|
|
|
43414
43561
|
const store = requireArrays(state);
|
|
43415
43562
|
const operation2 = ArrayOwner.create(store.owner.ledger, store.owner);
|
|
43416
43563
|
const holding = store.owner.hold();
|
|
43564
|
+
const valueAllocation = this.budget.values.scope();
|
|
43417
43565
|
let staged;
|
|
43418
43566
|
try {
|
|
43419
43567
|
const watch = await store.watch(name2, operation2, this.signal);
|
|
@@ -43430,8 +43578,9 @@ var Runtime = class _Runtime {
|
|
|
43430
43578
|
const current = store.get(name2);
|
|
43431
43579
|
if (!current) throw new ArrayFailure("stale binding");
|
|
43432
43580
|
staged = await current.copy(this.signal);
|
|
43433
|
-
const
|
|
43434
|
-
const
|
|
43581
|
+
const previous = current.values.get(0)?.text.rawValue ?? current.get(0) ?? "";
|
|
43582
|
+
const value2 = !append ? expanded : typeof previous === "string" && typeof expanded === "string" ? await this.arrayJoin(operation2, [previous, expanded], "") : concatShellValues([previous, expanded], valueAllocation);
|
|
43583
|
+
const token = await valueToken(staged.owner, value2, this.signal);
|
|
43435
43584
|
try {
|
|
43436
43585
|
staged.insert(0, token);
|
|
43437
43586
|
} catch (error) {
|
|
@@ -43459,6 +43608,7 @@ var Runtime = class _Runtime {
|
|
|
43459
43608
|
await staged?.release();
|
|
43460
43609
|
await operation2.close();
|
|
43461
43610
|
} finally {
|
|
43611
|
+
valueAllocation.close();
|
|
43462
43612
|
holding.release();
|
|
43463
43613
|
}
|
|
43464
43614
|
}
|
|
@@ -43522,7 +43672,7 @@ var Runtime = class _Runtime {
|
|
|
43522
43672
|
const preserve = assignment.kind === "element" || assignment.append;
|
|
43523
43673
|
staged = preserve && current ? await current.copy(this.signal) : IndexedBinding.create(store.owner);
|
|
43524
43674
|
if (preserve && !current && state.variables[name2] !== void 0) {
|
|
43525
|
-
const token = await
|
|
43675
|
+
const token = await valueToken(staged.owner, stateMonitor(state)?.values.get(name2, state.variables[name2]) ?? state.variables[name2], this.signal);
|
|
43526
43676
|
try {
|
|
43527
43677
|
staged.insert(0, token);
|
|
43528
43678
|
} catch (error) {
|
|
@@ -43534,7 +43684,7 @@ var Runtime = class _Runtime {
|
|
|
43534
43684
|
let cursor = assignment.append && assignment.kind === "compound" ? initialMaximum + 1 : 0;
|
|
43535
43685
|
const insert = async (index, value2) => {
|
|
43536
43686
|
if (index > 2147483647) throw new ArrayFailure("index outside 0..2147483647");
|
|
43537
|
-
const token = await
|
|
43687
|
+
const token = await valueToken(staged.owner, value2, this.signal);
|
|
43538
43688
|
try {
|
|
43539
43689
|
staged.insert(index, token);
|
|
43540
43690
|
} catch (error) {
|
|
@@ -43543,11 +43693,12 @@ var Runtime = class _Runtime {
|
|
|
43543
43693
|
}
|
|
43544
43694
|
writes++;
|
|
43545
43695
|
};
|
|
43696
|
+
const join = async (values) => values.every((value2) => typeof value2 === "string") ? this.arrayJoin(operation2, values, "") : concatShellValues(values, io[valueScope]);
|
|
43546
43697
|
if (assignment.kind === "element") {
|
|
43547
43698
|
const index = numericIndex(assignment.index);
|
|
43548
|
-
const fields3 = await this.
|
|
43549
|
-
let value2 = await
|
|
43550
|
-
if (assignment.append) value2 = await
|
|
43699
|
+
const fields3 = await this.valueWord(assignment.value, state, io, false);
|
|
43700
|
+
let value2 = await join(fields3);
|
|
43701
|
+
if (assignment.append) value2 = await join([staged.values.get(index)?.text.rawValue ?? staged.get(index) ?? "", value2]);
|
|
43551
43702
|
await insert(index, value2);
|
|
43552
43703
|
} else for (const entry of assignment.entries) {
|
|
43553
43704
|
const original = compoundEntryWords.get(entry);
|
|
@@ -43558,16 +43709,16 @@ var Runtime = class _Runtime {
|
|
|
43558
43709
|
expandedEntry = true;
|
|
43559
43710
|
const values = await this.valueWord(expanded, state, io, true, false, false, false, void 0, false);
|
|
43560
43711
|
for (const value2 of values) {
|
|
43561
|
-
await insert(cursor,
|
|
43712
|
+
await insert(cursor, value2);
|
|
43562
43713
|
cursor++;
|
|
43563
43714
|
}
|
|
43564
43715
|
}
|
|
43565
43716
|
if (expandedEntry) continue;
|
|
43566
43717
|
}
|
|
43567
|
-
const fields3 = await this.
|
|
43718
|
+
const fields3 = await this.valueWord(entry.value, state, io, entry.index === void 0);
|
|
43568
43719
|
if (entry.index) {
|
|
43569
43720
|
const index = numericIndex(entry.index);
|
|
43570
|
-
await insert(index, await
|
|
43721
|
+
await insert(index, await join(fields3));
|
|
43571
43722
|
cursor = index + 1;
|
|
43572
43723
|
} else for (const value2 of fields3) {
|
|
43573
43724
|
await insert(cursor, value2);
|
|
@@ -44458,8 +44609,8 @@ var Runtime = class _Runtime {
|
|
|
44458
44609
|
throw new ArrayFailure("indexed binding cannot be a command prefix");
|
|
44459
44610
|
}
|
|
44460
44611
|
await this.arrayZero(state, assignment.name, async () => {
|
|
44461
|
-
const fields3 = await this.
|
|
44462
|
-
return this.arrayJoin(requireArrays(state).owner, fields3, "");
|
|
44612
|
+
const fields3 = await this.valueWord(assignment.value, state, io, false);
|
|
44613
|
+
return fields3.every((value3) => typeof value3 === "string") ? this.arrayJoin(requireArrays(state).owner, fields3, "") : concatShellValues(fields3, io[valueScope]);
|
|
44463
44614
|
}, assignment.append);
|
|
44464
44615
|
continue;
|
|
44465
44616
|
}
|
|
@@ -44778,6 +44929,8 @@ var Runtime = class _Runtime {
|
|
|
44778
44929
|
functionRestoration?.close();
|
|
44779
44930
|
throw error;
|
|
44780
44931
|
}
|
|
44932
|
+
const callerLoopDepth = state.loopDepth;
|
|
44933
|
+
if (mapfileCallbackStates.has(state)) state.loopDepth = 0;
|
|
44781
44934
|
try {
|
|
44782
44935
|
return { exitCode: await this.command(body, state, { ...io, ...context3, scriptName: body.sourceName ?? io.scriptName ?? "shell" }) };
|
|
44783
44936
|
} catch (error) {
|
|
@@ -44791,6 +44944,7 @@ var Runtime = class _Runtime {
|
|
|
44791
44944
|
savedPositionals.close();
|
|
44792
44945
|
state.positionalSetVersion = positionalSetVersion;
|
|
44793
44946
|
state.functionDepth--;
|
|
44947
|
+
state.loopDepth = callerLoopDepth;
|
|
44794
44948
|
state.depth--;
|
|
44795
44949
|
state.locals.pop();
|
|
44796
44950
|
};
|
|
@@ -46262,12 +46416,119 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
46262
46416
|
allocation.close();
|
|
46263
46417
|
}
|
|
46264
46418
|
}
|
|
46419
|
+
async mapfileBuiltin(context2, state) {
|
|
46420
|
+
const allocation = this.budget.values.scope();
|
|
46421
|
+
const work = { remaining: this.budget.limits.maxExpansionBytes * 8, signal: this.signal, exhausted: () => this.budget.fail("maxExpansionBytes") };
|
|
46422
|
+
let pinned;
|
|
46423
|
+
let releaseHolding;
|
|
46424
|
+
try {
|
|
46425
|
+
const options3 = await mapfileOptions(context2, work, allocation);
|
|
46426
|
+
if (state.readonlyVariables?.has(options3.name)) throw new MapfileUsageError(`${options3.name}: readonly variable`, 1);
|
|
46427
|
+
if (controlNames.has(options3.name) || state.exported.has(options3.name)) throw new ArrayFailure("control or exported binding cannot be indexed");
|
|
46428
|
+
const store = requireArrays(state);
|
|
46429
|
+
const holding = store.owner.hold();
|
|
46430
|
+
releaseHolding = () => holding.release();
|
|
46431
|
+
if (!options3.preserve || !store.get(options3.name)) await this.arrayAssignment({ kind: "compound", name: options3.name, append: options3.preserve, entries: [] }, state, context2);
|
|
46432
|
+
const entry = store.bindings.get(options3.name);
|
|
46433
|
+
allocation.reserve(128 + import_buffer.Buffer.byteLength(options3.name) * 2, 0);
|
|
46434
|
+
pinned = entry.binding.retain();
|
|
46435
|
+
const input3 = context2.stdin instanceof ShellInput ? context2.stdin : new ShellInput(context2.stdin, this.budget, this.signal);
|
|
46436
|
+
let pendingFlow;
|
|
46437
|
+
await collectMapfile(options3, input3, {
|
|
46438
|
+
allocation: () => this.budget.values.scope(),
|
|
46439
|
+
loop: () => this.budget.loop(),
|
|
46440
|
+
write: async (index, value2) => {
|
|
46441
|
+
if (pinned !== entry.binding) {
|
|
46442
|
+
const previous = pinned;
|
|
46443
|
+
pinned = entry.binding.retain();
|
|
46444
|
+
await previous.release();
|
|
46445
|
+
}
|
|
46446
|
+
const operation2 = ArrayOwner.create(store.owner.ledger, store.owner);
|
|
46447
|
+
let staged;
|
|
46448
|
+
try {
|
|
46449
|
+
const current = pinned;
|
|
46450
|
+
const attached = store.bindings.get(options3.name) === entry;
|
|
46451
|
+
const watch = attached ? await store.watch(options3.name, operation2, this.signal) : void 0;
|
|
46452
|
+
const supersede = attached ? await stateMonitor(state).prepareTypedPublication(options3.name, operation2, this.signal) : void 0;
|
|
46453
|
+
if (attached) await this.prepareArrayObservers(state, operation2);
|
|
46454
|
+
const tickets = operation2.reserve({ generation: true, version: true, epoch: true, work: 8 });
|
|
46455
|
+
staged = current.references > (attached ? 2 : 1) ? await current.copy(this.signal) : current.retain();
|
|
46456
|
+
const token = await valueToken(staged.owner, value2, this.signal);
|
|
46457
|
+
try {
|
|
46458
|
+
this.signal.throwIfAborted();
|
|
46459
|
+
if (watch && !watch.valid()) throw new ArrayFailure("stale binding");
|
|
46460
|
+
staged.insert(index, token);
|
|
46461
|
+
} catch (error) {
|
|
46462
|
+
token.release();
|
|
46463
|
+
throw error;
|
|
46464
|
+
}
|
|
46465
|
+
if (attached) {
|
|
46466
|
+
let released;
|
|
46467
|
+
stateMonitor(state).publish(tickets, options3.name, () => {
|
|
46468
|
+
supersede();
|
|
46469
|
+
released = store.publish(options3.name, staged, tickets);
|
|
46470
|
+
});
|
|
46471
|
+
staged = void 0;
|
|
46472
|
+
await released;
|
|
46473
|
+
} else {
|
|
46474
|
+
const previous = pinned;
|
|
46475
|
+
pinned = staged;
|
|
46476
|
+
entry.binding = staged;
|
|
46477
|
+
staged = void 0;
|
|
46478
|
+
await previous.release();
|
|
46479
|
+
}
|
|
46480
|
+
} finally {
|
|
46481
|
+
try {
|
|
46482
|
+
await staged?.release();
|
|
46483
|
+
} finally {
|
|
46484
|
+
await operation2.close();
|
|
46485
|
+
}
|
|
46486
|
+
}
|
|
46487
|
+
},
|
|
46488
|
+
callback: async (source2, index, value2) => {
|
|
46489
|
+
if (pendingFlow) return;
|
|
46490
|
+
const callbackAllocation = this.budget.values.scope();
|
|
46491
|
+
const nested = mapfileCallbackStates.has(state);
|
|
46492
|
+
try {
|
|
46493
|
+
const quoted2 = shellValueText(await transformParameter(value2, "Q", { maximumBytes: this.budget.limits.maxExpansionBytes, byteLocale: byteLocale(state.variables), work, allocation: callbackAllocation }));
|
|
46494
|
+
if (import_buffer.Buffer.byteLength(source2) + import_buffer.Buffer.byteLength(quoted2) + String(index).length + 2 > this.budget.limits.maxExpansionBytes) this.budget.fail("maxExpansionBytes");
|
|
46495
|
+
mapfileCallbackStates.add(state);
|
|
46496
|
+
await this.evalBuiltin({ ...context2, args: [source2, String(index), quoted2] }, state, context2, false);
|
|
46497
|
+
} catch (error) {
|
|
46498
|
+
if (error instanceof Flow2 && (error.kind === "break" || error.kind === "continue")) pendingFlow = error;
|
|
46499
|
+
else throw error;
|
|
46500
|
+
} finally {
|
|
46501
|
+
if (!nested) mapfileCallbackStates.delete(state);
|
|
46502
|
+
callbackAllocation.close();
|
|
46503
|
+
}
|
|
46504
|
+
}
|
|
46505
|
+
});
|
|
46506
|
+
if (pendingFlow) throw pendingFlow;
|
|
46507
|
+
return 0;
|
|
46508
|
+
} catch (error) {
|
|
46509
|
+
this.signal.throwIfAborted();
|
|
46510
|
+
if (!(error instanceof MapfileUsageError)) throw error;
|
|
46511
|
+
await this.diagnostic(context2, `${context2.command}: ${error.message}`);
|
|
46512
|
+
return error.status;
|
|
46513
|
+
} finally {
|
|
46514
|
+
try {
|
|
46515
|
+
await pinned?.release();
|
|
46516
|
+
} finally {
|
|
46517
|
+
try {
|
|
46518
|
+
releaseHolding?.();
|
|
46519
|
+
} finally {
|
|
46520
|
+
allocation.close();
|
|
46521
|
+
}
|
|
46522
|
+
}
|
|
46523
|
+
}
|
|
46524
|
+
}
|
|
46265
46525
|
async builtin(context2, state, assignments2, diagnose, suppressSpecial = false) {
|
|
46266
46526
|
const { command: command7, args, stdout, stderr } = context2;
|
|
46267
46527
|
if (command7 === ":" || command7 === "true") return 0;
|
|
46268
46528
|
if (command7 === "false") return 1;
|
|
46269
46529
|
if (command7 === "shopt") return this.shoptBuiltin(context2, state);
|
|
46270
46530
|
if (command7 === "let") return this.letBuiltin(context2, state);
|
|
46531
|
+
if (command7 === "mapfile" || command7 === "readarray") return this.mapfileBuiltin(context2, state);
|
|
46271
46532
|
if (command7 === "getopts") return this.getoptsBuiltin(context2, state);
|
|
46272
46533
|
if (command7 === "pushd" || command7 === "dirs" || command7 === "popd") return this.directoryStackBuiltin(context2, state, diagnose);
|
|
46273
46534
|
if (command7 === "pwd") {
|
|
@@ -46823,7 +47084,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
46823
47084
|
if (part.kind === "variable" && part.transform) {
|
|
46824
47085
|
const selector2 = getArraySelector(part);
|
|
46825
47086
|
if (selector2?.kind === "members" || part.name === "@" || part.name === "*") {
|
|
46826
|
-
const members = selector2 ? await this.arrayMembers(part.name, state) : this.positionalValues(state);
|
|
47087
|
+
const members = selector2 ? await this.arrayMembers(part.name, state, io) : this.positionalValues(state);
|
|
46827
47088
|
const ifs = state.variables.IFS ?? " ";
|
|
46828
47089
|
const separator = ifs.length ? String.fromCodePoint(ifs.codePointAt(0)) : "";
|
|
46829
47090
|
const fragments = [];
|
|
@@ -46867,6 +47128,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
46867
47128
|
const token = index === void 0 || selector?.kind === "members" ? void 0 : binding?.values.get(index)?.text;
|
|
46868
47129
|
token?.retain();
|
|
46869
47130
|
try {
|
|
47131
|
+
if (token?.rawValue && part.kind === "variable" && !part.length && !part.operator && !part.substring) return shellValueFromBytes(shellValueBytes(token.rawValue, io[valueScope]), io[valueScope]);
|
|
46870
47132
|
const value2 = await this.partValue(part, state, io, hereString);
|
|
46871
47133
|
if (binding) await textToken(requireArrays(state).owner, shellValueText(value2), this.signal);
|
|
46872
47134
|
return value2;
|
|
@@ -46984,8 +47246,11 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
46984
47246
|
return part.length ? this.parameterLength(value3 ?? "") : value3 ?? "";
|
|
46985
47247
|
}
|
|
46986
47248
|
if (part.length) return String(binding?.values.size ?? (state.variables[part.name] === void 0 ? 0 : 1));
|
|
46987
|
-
const values = await this.arrayMembers(part.name, state);
|
|
46988
|
-
|
|
47249
|
+
const values = await this.arrayMembers(part.name, state, io);
|
|
47250
|
+
const separator = Array.from(state.variables.IFS ?? " ")[0] ?? "";
|
|
47251
|
+
if (values.every((value3) => typeof value3 === "string")) return this.arrayJoin(store.owner, values, separator);
|
|
47252
|
+
io[valueScope]?.reserve(values.length * 32 + 64, 0);
|
|
47253
|
+
return concatShellValues(values.flatMap((value3, index) => index ? [separator, value3] : [value3]), io[valueScope]);
|
|
46989
47254
|
}
|
|
46990
47255
|
let value2 = part.name === "?" ? String(state.status) : part.name === "-" ? `${state.errexit ? "e" : ""}${state.nounset ? "u" : ""}${state.braceexpand !== false ? "B" : ""}` : part.name === "#" ? String(state.positional.length) : part.name === "@" || part.name === "*" ? state.positional.join(hereString && (part.name === "@" || !part.quoted) ? " " : Array.from(state.variables.IFS ?? " ")[0] ?? "") : /^0+$/u.test(part.name) ? state.arg0 ?? "virtual-bash" : /^\d+$/u.test(part.name) ? state.positional[Number(part.name) - 1] : this.variable(state, part.name);
|
|
46991
47256
|
let retained = value2;
|
|
@@ -47394,7 +47659,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
47394
47659
|
emptyNameGroups.add(quoteGroup);
|
|
47395
47660
|
}
|
|
47396
47661
|
} else if (part.kind === "variable" && split4 && (selector?.kind === "members" && !part.length && (!part.quoted || selector.separator === "@") || part.transform && part.name === "@")) {
|
|
47397
|
-
const members = selector?.kind === "members" ? await this.arrayMembers(part.name, state) : this.positionalValues(state);
|
|
47662
|
+
const members = selector?.kind === "members" ? await this.arrayMembers(part.name, state, io) : this.positionalValues(state);
|
|
47398
47663
|
for (let position = 0; position < members.length; position++) {
|
|
47399
47664
|
if (position > 0) addField();
|
|
47400
47665
|
const original = members[position];
|
|
@@ -47536,7 +47801,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
47536
47801
|
for (const value2 of values) if (typeof value2 !== "string") allocation.hold(value2);
|
|
47537
47802
|
return createCommandArguments(values, allocation);
|
|
47538
47803
|
}
|
|
47539
|
-
async arrayMembers(name2, state) {
|
|
47804
|
+
async arrayMembers(name2, state, io) {
|
|
47540
47805
|
const store = requireArrays(state);
|
|
47541
47806
|
const holding = store.owner.hold();
|
|
47542
47807
|
try {
|
|
@@ -47555,8 +47820,9 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
47555
47820
|
const values = [];
|
|
47556
47821
|
for (const index of indices) {
|
|
47557
47822
|
store.owner.reserve({ metadata: 32, allocatedSlots: 1, work: 4 });
|
|
47558
|
-
const
|
|
47559
|
-
|
|
47823
|
+
const token = binding.values.get(index).text;
|
|
47824
|
+
const value2 = token.rawValue === void 0 ? token.value : shellValueFromBytes(shellValueBytes(token.rawValue, io[valueScope]), io[valueScope]);
|
|
47825
|
+
if (typeof value2 === "string") await textToken(store.owner, value2, this.signal);
|
|
47560
47826
|
values.push(value2);
|
|
47561
47827
|
await store.owner.ledger.checkpoint(this.signal);
|
|
47562
47828
|
}
|
|
@@ -48231,6 +48497,51 @@ var ShellInput = class _ShellInput {
|
|
|
48231
48497
|
}
|
|
48232
48498
|
});
|
|
48233
48499
|
}
|
|
48500
|
+
mapfileRecord(delimiter, strip, allocation) {
|
|
48501
|
+
return this.#cursor.consume(this.signal, async () => {
|
|
48502
|
+
this.#cursor.admitBoundedRead();
|
|
48503
|
+
allocation.reserve(64, 0);
|
|
48504
|
+
const parts = [];
|
|
48505
|
+
let length = 0;
|
|
48506
|
+
let truncated = false;
|
|
48507
|
+
let pulls = 0;
|
|
48508
|
+
while (true) {
|
|
48509
|
+
if (++pulls % 128 === 0) await yieldTurn(this.signal);
|
|
48510
|
+
const result2 = await this.#cursor.take(this.signal);
|
|
48511
|
+
if (result2.done) return { value: concatShellValues(parts, allocation), present: length > 0 };
|
|
48512
|
+
const chunk = result2.value;
|
|
48513
|
+
for (let offset = 0; offset < chunk.length; ) {
|
|
48514
|
+
await yieldTurn(this.signal);
|
|
48515
|
+
if (length >= this.budget.limits.maxOutputBytes) this.budget.fail("maxOutputBytes");
|
|
48516
|
+
const end = Math.min(offset + 1024, chunk.length, offset + this.budget.limits.maxOutputBytes - length);
|
|
48517
|
+
allocation.reserve(end - offset + 64, 0);
|
|
48518
|
+
const output2 = new Uint8Array(end - offset);
|
|
48519
|
+
let used = 0;
|
|
48520
|
+
let terminated = false;
|
|
48521
|
+
while (offset < end) {
|
|
48522
|
+
const byte = chunk[offset++];
|
|
48523
|
+
this.#cursor.position++;
|
|
48524
|
+
if (++length > this.budget.limits.maxOutputBytes) this.budget.fail("maxOutputBytes");
|
|
48525
|
+
if (byte === delimiter) {
|
|
48526
|
+
if (!strip && byte !== 0 && !truncated) output2[used++] = byte;
|
|
48527
|
+
terminated = true;
|
|
48528
|
+
break;
|
|
48529
|
+
}
|
|
48530
|
+
if (byte === 0) truncated = true;
|
|
48531
|
+
if (!truncated) output2[used++] = byte;
|
|
48532
|
+
}
|
|
48533
|
+
if (used) {
|
|
48534
|
+
allocation.reserve(32, 0);
|
|
48535
|
+
parts.push(shellValueFromBytes(output2.subarray(0, used), allocation));
|
|
48536
|
+
}
|
|
48537
|
+
if (terminated) {
|
|
48538
|
+
if (offset < chunk.length) this.#cursor.remainder = chunk.subarray(offset);
|
|
48539
|
+
return { value: concatShellValues(parts, allocation), present: true };
|
|
48540
|
+
}
|
|
48541
|
+
}
|
|
48542
|
+
}
|
|
48543
|
+
});
|
|
48544
|
+
}
|
|
48234
48545
|
async readBounded(raw, options3) {
|
|
48235
48546
|
const text3 = new ReadText();
|
|
48236
48547
|
let characters = 0;
|