@poe-platform/safe-bash 0.1.501 → 0.1.503
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/commands/apply-patch/apply.d.ts.map +1 -1
- package/dist/safe-bash/commands/apply-patch/apply.js +5 -2
- package/dist/safe-bash/commands/apply-patch/apply.js.map +1 -1
- package/dist/safe-bash/commands/archive/extract.d.ts.map +1 -1
- package/dist/safe-bash/commands/archive/extract.js +5 -2
- package/dist/safe-bash/commands/archive/extract.js.map +1 -1
- package/dist/safe-bash/commands/archive/internal.d.ts.map +1 -1
- package/dist/safe-bash/commands/archive/internal.js +6 -2
- package/dist/safe-bash/commands/archive/internal.js.map +1 -1
- package/dist/safe-bash/commands/bytes/compression/files.d.ts.map +1 -1
- package/dist/safe-bash/commands/bytes/compression/files.js +10 -6
- package/dist/safe-bash/commands/bytes/compression/files.js.map +1 -1
- package/dist/safe-bash/commands/diff-patch/diff.d.ts.map +1 -1
- package/dist/safe-bash/commands/diff-patch/diff.js +4 -3
- package/dist/safe-bash/commands/diff-patch/diff.js.map +1 -1
- package/dist/safe-bash/commands/diff-patch/shared.d.ts.map +1 -1
- package/dist/safe-bash/commands/diff-patch/shared.js +5 -3
- package/dist/safe-bash/commands/diff-patch/shared.js.map +1 -1
- package/dist/safe-bash/commands/du/du.d.ts.map +1 -1
- package/dist/safe-bash/commands/du/du.js +6 -6
- package/dist/safe-bash/commands/du/du.js.map +1 -1
- package/dist/safe-bash/commands/file/index.d.ts.map +1 -1
- package/dist/safe-bash/commands/file/index.js +9 -3
- package/dist/safe-bash/commands/file/index.js.map +1 -1
- package/dist/safe-bash/commands/filesystem-requirements.d.ts.map +1 -1
- package/dist/safe-bash/commands/filesystem-requirements.js +1 -0
- package/dist/safe-bash/commands/filesystem-requirements.js.map +1 -1
- package/dist/safe-bash/commands/filesystem.d.ts.map +1 -1
- package/dist/safe-bash/commands/filesystem.js +54 -10
- package/dist/safe-bash/commands/filesystem.js.map +1 -1
- package/dist/safe-bash/commands/find.js +1 -1
- package/dist/safe-bash/commands/find.js.map +1 -1
- package/dist/safe-bash/commands/html-to-markdown/input.d.ts.map +1 -1
- package/dist/safe-bash/commands/html-to-markdown/input.js +12 -18
- package/dist/safe-bash/commands/html-to-markdown/input.js.map +1 -1
- package/dist/safe-bash/commands/internal.d.ts +1 -1
- package/dist/safe-bash/commands/internal.d.ts.map +1 -1
- package/dist/safe-bash/commands/internal.js +3 -2
- package/dist/safe-bash/commands/internal.js.map +1 -1
- package/dist/safe-bash/commands/metadata/internal.d.ts +2 -2
- package/dist/safe-bash/commands/metadata/internal.d.ts.map +1 -1
- package/dist/safe-bash/commands/metadata/internal.js +1 -1
- package/dist/safe-bash/commands/metadata/internal.js.map +1 -1
- package/dist/safe-bash/commands/metadata/mktemp.d.ts.map +1 -1
- package/dist/safe-bash/commands/metadata/mktemp.js +5 -2
- package/dist/safe-bash/commands/metadata/mktemp.js.map +1 -1
- package/dist/safe-bash/commands/metadata/stat.js +1 -1
- package/dist/safe-bash/commands/metadata/stat.js.map +1 -1
- package/dist/safe-bash/commands/move.d.ts.map +1 -1
- package/dist/safe-bash/commands/move.js +3 -2
- package/dist/safe-bash/commands/move.js.map +1 -1
- package/dist/safe-bash/commands/network/body.d.ts.map +1 -1
- package/dist/safe-bash/commands/network/body.js +3 -1
- package/dist/safe-bash/commands/network/body.js.map +1 -1
- package/dist/safe-bash/commands/predicates.d.ts.map +1 -1
- package/dist/safe-bash/commands/predicates.js +8 -2
- package/dist/safe-bash/commands/predicates.js.map +1 -1
- package/dist/safe-bash/commands/safejs/index.d.ts.map +1 -1
- package/dist/safe-bash/commands/safejs/index.js +2 -1
- package/dist/safe-bash/commands/safejs/index.js.map +1 -1
- package/dist/safe-bash/commands/split/io.d.ts.map +1 -1
- package/dist/safe-bash/commands/split/io.js +2 -1
- package/dist/safe-bash/commands/split/io.js.map +1 -1
- package/dist/safe-bash/commands/split/split.d.ts.map +1 -1
- package/dist/safe-bash/commands/split/split.js +2 -1
- package/dist/safe-bash/commands/split/split.js.map +1 -1
- package/dist/safe-bash/commands/stream-format/shared.d.ts.map +1 -1
- package/dist/safe-bash/commands/stream-format/shared.js +7 -4
- package/dist/safe-bash/commands/stream-format/shared.js.map +1 -1
- package/dist/safe-bash/commands/stream-inspection/shared.d.ts.map +1 -1
- package/dist/safe-bash/commands/stream-inspection/shared.js +7 -4
- package/dist/safe-bash/commands/stream-inspection/shared.js.map +1 -1
- package/dist/safe-bash/commands/streams.d.ts.map +1 -1
- package/dist/safe-bash/commands/streams.js +4 -2
- package/dist/safe-bash/commands/streams.js.map +1 -1
- package/dist/safe-bash/commands/structured/jq.d.ts.map +1 -1
- package/dist/safe-bash/commands/structured/jq.js +15 -5
- package/dist/safe-bash/commands/structured/jq.js.map +1 -1
- package/dist/safe-bash/commands/table-text/internal.d.ts.map +1 -1
- package/dist/safe-bash/commands/table-text/internal.js +5 -4
- package/dist/safe-bash/commands/table-text/internal.js.map +1 -1
- package/dist/safe-bash/commands/text-programs/awk-runtime.d.ts.map +1 -1
- package/dist/safe-bash/commands/text-programs/awk-runtime.js +10 -4
- package/dist/safe-bash/commands/text-programs/awk-runtime.js.map +1 -1
- package/dist/safe-bash/commands/text.d.ts.map +1 -1
- package/dist/safe-bash/commands/text.js +3 -2
- package/dist/safe-bash/commands/text.js.map +1 -1
- package/dist/safe-bash/commands/time-env/date.d.ts.map +1 -1
- package/dist/safe-bash/commands/time-env/date.js +3 -2
- package/dist/safe-bash/commands/time-env/date.js.map +1 -1
- package/dist/safe-bash/commands/tree/tree.d.ts.map +1 -1
- package/dist/safe-bash/commands/tree/tree.js +2 -1
- package/dist/safe-bash/commands/tree/tree.js.map +1 -1
- package/dist/safe-bash/contracts/filesystem.d.ts +1 -1
- package/dist/safe-bash/contracts/filesystem.d.ts.map +1 -1
- package/dist/safe-bash/core.browser.js +259 -119
- package/dist/safe-bash/core.browser.js.map +4 -4
- package/dist/safe-bash/shell/conditional.d.ts.map +1 -1
- package/dist/safe-bash/shell/conditional.js +10 -6
- package/dist/safe-bash/shell/conditional.js.map +1 -1
- package/dist/safe-bash/shell/input.d.ts +1 -1
- package/dist/safe-bash/shell/input.d.ts.map +1 -1
- package/dist/safe-bash/shell/input.js +7 -3
- package/dist/safe-bash/shell/input.js.map +1 -1
- package/dist/safe-bash/shell/runtime.d.ts +2 -1
- package/dist/safe-bash/shell/runtime.d.ts.map +1 -1
- package/dist/safe-bash/shell/runtime.js +37 -28
- package/dist/safe-bash/shell/runtime.js.map +1 -1
- package/dist/safe-bash/shell/shell.d.ts.map +1 -1
- package/dist/safe-bash/shell/shell.js +3 -1
- package/dist/safe-bash/shell/shell.js.map +1 -1
- package/package.json +2 -2
|
@@ -4962,7 +4962,8 @@ async function* input(context2, name2 = "-") {
|
|
|
4962
4962
|
} else {
|
|
4963
4963
|
await assertInputRequirements(context2, [name2]);
|
|
4964
4964
|
const path = pathOf(context2, name2);
|
|
4965
|
-
|
|
4965
|
+
const capabilities = await context2.fs.capabilitiesFor?.(path, { signal: context2.signal }) ?? context2.fs.capabilities;
|
|
4966
|
+
if (context2.fs.readStream && capabilities.streamingRead !== false) {
|
|
4966
4967
|
let emitted = false;
|
|
4967
4968
|
let reading = true;
|
|
4968
4969
|
try {
|
|
@@ -4978,7 +4979,7 @@ async function* input(context2, name2 = "-") {
|
|
|
4978
4979
|
if (!reading || emitted || !(error instanceof FsError) || error.code !== "ENOTSUP") throw error;
|
|
4979
4980
|
}
|
|
4980
4981
|
}
|
|
4981
|
-
if (
|
|
4982
|
+
if (capabilities.read === false) throw new FsError("ENOTSUP", { syscall: "readFile", path });
|
|
4982
4983
|
yield* readBytes2({
|
|
4983
4984
|
async *[Symbol.asyncIterator]() {
|
|
4984
4985
|
const bytes3 = await context2.fs.readFile(path, { signal: context2.signal, maxBytes: bufferLimit });
|
|
@@ -5381,6 +5382,7 @@ var filesystemCommandRequirements = {
|
|
|
5381
5382
|
],
|
|
5382
5383
|
mv: [
|
|
5383
5384
|
{ id: "rename", description: "Rename files or directories", capabilities: ["stat", "rename"], mutates: true },
|
|
5385
|
+
{ id: "no-replace", description: "Atomically preserve an existing destination (-n)", capabilities: ["stat", "rename", "atomicRenameNoReplace"], mutates: true },
|
|
5384
5386
|
{ id: "cross-source", description: "Remove file sources after an existing cross-device transfer", capabilities: ["stat", "remove"], mutates: true },
|
|
5385
5387
|
{ id: "cross-directory-source", description: "Traverse and remove cross-device source directories", capabilities: ["stat", "readdir", "removeDirectory"], mutates: true },
|
|
5386
5388
|
{ id: "cross-link-source", description: "Inspect and remove cross-device source links", capabilities: ["stat", "readlink", "remove"], mutates: true },
|
|
@@ -5559,8 +5561,9 @@ async function moveAcrossDevices(context2, source2, target, noClobber, budget) {
|
|
|
5559
5561
|
for (const entry of [...plan].reverse()) {
|
|
5560
5562
|
context2.signal.throwIfAborted();
|
|
5561
5563
|
if (entry.stat.type !== "symlink") {
|
|
5562
|
-
|
|
5563
|
-
if (
|
|
5564
|
+
const capabilities = await context2.fs.capabilitiesFor?.(entry.target, { signal: context2.signal }) ?? context2.fs.capabilities;
|
|
5565
|
+
if (capabilities.permissions === true && context2.fs.chmod) await context2.fs.chmod(entry.target, entry.stat.mode & 4095, { signal: context2.signal });
|
|
5566
|
+
if (capabilities.timestamps === true && context2.fs.utimes) {
|
|
5564
5567
|
try {
|
|
5565
5568
|
await context2.fs.utimes(entry.target, entry.stat.atimeMs, entry.stat.mtimeMs, { signal: context2.signal });
|
|
5566
5569
|
} catch (error) {
|
|
@@ -5627,6 +5630,23 @@ async function maybeStat(context2, path, follow = true) {
|
|
|
5627
5630
|
throw error;
|
|
5628
5631
|
}
|
|
5629
5632
|
}
|
|
5633
|
+
async function admitNoReplaceRename(context2, target) {
|
|
5634
|
+
let candidate = target;
|
|
5635
|
+
while (true) {
|
|
5636
|
+
try {
|
|
5637
|
+
const capabilities = await context2.fs.capabilitiesFor?.(candidate, { signal: context2.signal }) ?? context2.fs.capabilities;
|
|
5638
|
+
context2.signal.throwIfAborted();
|
|
5639
|
+
if (capabilities.atomicRenameNoReplace !== true) {
|
|
5640
|
+
throw new FsError("ENOTSUP", { syscall: "mv", path: target, message: "atomic no-replace rename is unavailable" });
|
|
5641
|
+
}
|
|
5642
|
+
return;
|
|
5643
|
+
} catch (error) {
|
|
5644
|
+
context2.signal.throwIfAborted();
|
|
5645
|
+
if (codeOf(error) !== "ENOENT" || candidate === "/") throw error;
|
|
5646
|
+
candidate = dirname(candidate);
|
|
5647
|
+
}
|
|
5648
|
+
}
|
|
5649
|
+
}
|
|
5630
5650
|
async function canonicalMissing(context2, path, mode = "copy") {
|
|
5631
5651
|
if (mode !== "copy") {
|
|
5632
5652
|
context2.signal.throwIfAborted();
|
|
@@ -5668,6 +5688,8 @@ function needCapability(context2, capability) {
|
|
|
5668
5688
|
if (!context2.fs[capability]) throw new FsError("ENOTSUP", { syscall: capability });
|
|
5669
5689
|
}
|
|
5670
5690
|
async function admitEmptyDirectory(context2, path, readDirectory) {
|
|
5691
|
+
const stat = await maybeStat(context2, path, false);
|
|
5692
|
+
if (stat && stat.type !== "directory") throw new FsError("ENOTDIR", { syscall: "rmdir", path });
|
|
5671
5693
|
try {
|
|
5672
5694
|
await admitFilesystemModes(context2, "rmdir", ["directory"], [path]);
|
|
5673
5695
|
} catch (error) {
|
|
@@ -5746,14 +5768,15 @@ async function copy(context2, source2, target, flags3, readDirectory, top = true
|
|
|
5746
5768
|
}
|
|
5747
5769
|
if (!preflight) await context2.fs.symlink(linkTarget, target, { signal: context2.signal });
|
|
5748
5770
|
} else {
|
|
5749
|
-
|
|
5771
|
+
const replace = flags3.has("f") && targetStat !== void 0 && targetStat.type !== "character";
|
|
5772
|
+
await admitFilesystemModes(context2, "cp", ["file", ...replace ? ["replace", "exclusive"] : []], [target]);
|
|
5750
5773
|
if (targetStat?.type === "directory") throw new FsError("EISDIR", { path: target });
|
|
5751
5774
|
if (preflight) return;
|
|
5752
5775
|
try {
|
|
5753
5776
|
await context2.fs.copyFile(source2, target, { signal: context2.signal });
|
|
5754
5777
|
} catch (error) {
|
|
5755
5778
|
context2.signal.throwIfAborted();
|
|
5756
|
-
if (!
|
|
5779
|
+
if (!replace || codeOf(error) !== "EACCES") throw error;
|
|
5757
5780
|
const existing2 = await maybeStat(context2, target, false);
|
|
5758
5781
|
if (existing2) {
|
|
5759
5782
|
const sourceEntry = await context2.fs.lstat(source2, { signal: context2.signal });
|
|
@@ -5772,7 +5795,7 @@ async function copy(context2, source2, target, flags3, readDirectory, top = true
|
|
|
5772
5795
|
`);
|
|
5773
5796
|
}
|
|
5774
5797
|
function modeText(stat) {
|
|
5775
|
-
let text3 = stat.type === "directory" ? "d" : stat.type === "symlink" ? "l" : "-";
|
|
5798
|
+
let text3 = stat.type === "directory" ? "d" : stat.type === "symlink" ? "l" : stat.type === "character" ? "c" : "-";
|
|
5776
5799
|
for (const shift of [6, 3, 0]) {
|
|
5777
5800
|
const mode = stat.mode >> shift;
|
|
5778
5801
|
text3 += (mode & 4 ? "r" : "-") + (mode & 2 ? "w" : "-") + (mode & 1 ? "x" : "-");
|
|
@@ -5790,17 +5813,23 @@ function filesystemCommands(maxDirectoryEntries) {
|
|
|
5790
5813
|
requireOperands(parsed.operands);
|
|
5791
5814
|
const mode = value(parsed, "m");
|
|
5792
5815
|
if (mode !== void 0 && !/^[0-7]{1,4}$/u.test(mode)) throw new UsageError(`invalid mode '${mode}' (octal required)`);
|
|
5793
|
-
|
|
5794
|
-
context2,
|
|
5795
|
-
"
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5816
|
+
const createDirectory = async (operand, preflight) => {
|
|
5817
|
+
const path = pathOf(context2, operand);
|
|
5818
|
+
const recursive = parsed.flags.has("p");
|
|
5819
|
+
const stat = await maybeStat(context2, path, recursive);
|
|
5820
|
+
if (stat) {
|
|
5821
|
+
if (recursive && stat.type === "directory") return;
|
|
5822
|
+
throw new FsError("EEXIST", { syscall: "mkdir", path });
|
|
5823
|
+
}
|
|
5824
|
+
await admitFilesystemModes(context2, "mkdir", [recursive ? "parents" : "directory"], [path]);
|
|
5825
|
+
if (!preflight) {
|
|
5826
|
+
await context2.fs.mkdir(path, { recursive, ...mode === void 0 ? {} : { mode: parseInt(mode, 8) }, signal: context2.signal });
|
|
5827
|
+
if (parsed.flags.has("v")) await output(context2, `mkdir: created directory '${escapeText(operand, "display")}'
|
|
5802
5828
|
`);
|
|
5803
|
-
|
|
5829
|
+
}
|
|
5830
|
+
};
|
|
5831
|
+
await preflightOperands(context2, parsed.operands, (operand) => createDirectory(operand, true));
|
|
5832
|
+
return eachOperand(context2, parsed.operands, (operand) => createDirectory(operand, false));
|
|
5804
5833
|
}),
|
|
5805
5834
|
define("touch", async (context2) => {
|
|
5806
5835
|
const parsed = options2(context2.args, "camr:", { "no-create": "c", reference: "r" });
|
|
@@ -5868,15 +5897,21 @@ function filesystemCommands(maxDirectoryEntries) {
|
|
|
5868
5897
|
const target = destination2.directory ? joinPath(destination2.target, basename(source2)) : destination2.target;
|
|
5869
5898
|
if (parsed.flags.has("n") && await maybeStat(context2, target, false)) return;
|
|
5870
5899
|
await admitFilesystemModes(context2, "mv", ["rename"], [source2, target]);
|
|
5900
|
+
if (parsed.flags.has("n")) await admitNoReplaceRename(context2, target);
|
|
5871
5901
|
});
|
|
5872
5902
|
return eachOperand(context2, destination2.sources, async (operand) => {
|
|
5873
5903
|
const source2 = pathOf(context2, operand);
|
|
5874
5904
|
const target = destination2.directory ? joinPath(destination2.target, basename(source2)) : destination2.target;
|
|
5875
5905
|
if (parsed.flags.has("n") && await maybeStat(context2, target, false)) return;
|
|
5906
|
+
if (parsed.flags.has("n")) await admitNoReplaceRename(context2, target);
|
|
5876
5907
|
try {
|
|
5877
|
-
await context2.fs.rename(source2, target, { signal: context2.signal });
|
|
5908
|
+
await context2.fs.rename(source2, target, { signal: context2.signal, ...parsed.flags.has("n") ? { noReplace: true } : {} });
|
|
5878
5909
|
} catch (error) {
|
|
5879
5910
|
context2.signal.throwIfAborted();
|
|
5911
|
+
if (parsed.flags.has("n")) {
|
|
5912
|
+
if (codeOf(error) === "EEXIST") return;
|
|
5913
|
+
throw error;
|
|
5914
|
+
}
|
|
5880
5915
|
if (codeOf(error) !== "EXDEV") throw error;
|
|
5881
5916
|
if (!await moveAcrossDevices(context2, source2, target, parsed.flags.has("n"), budget)) {
|
|
5882
5917
|
if (!parsed.flags.has("n")) throw new FsError("EINVAL", { path: source2, dest: target, message: "source and destination are the same file" });
|
|
@@ -7170,8 +7205,15 @@ function streamCommands(maxTeeTargets = 64, maxTailFollowHandles = 64) {
|
|
|
7170
7205
|
try {
|
|
7171
7206
|
for (const operand of parsed.operands) {
|
|
7172
7207
|
try {
|
|
7173
|
-
|
|
7174
|
-
|
|
7208
|
+
const path = pathOf(context2, operand);
|
|
7209
|
+
const capabilities = await context2.fs.capabilitiesFor?.(path, { signal: context2.signal }) ?? context2.fs.capabilities;
|
|
7210
|
+
assertCommandRequirements(
|
|
7211
|
+
context2,
|
|
7212
|
+
teeRequirements,
|
|
7213
|
+
[parsed.flags.has("a") ? "append" : "overwrite"],
|
|
7214
|
+
context2.fs.capabilities.readOnly === true ? { ...capabilities, readOnly: true } : capabilities
|
|
7215
|
+
);
|
|
7216
|
+
targets.add(await openFileOutput(context2, path, parsed.flags.has("a") ? "a" : "w"));
|
|
7175
7217
|
} catch (error) {
|
|
7176
7218
|
context2.signal.throwIfAborted();
|
|
7177
7219
|
await diagnostic(context2, error);
|
|
@@ -7526,9 +7568,10 @@ async function emitRecords(context2, records4, destination2) {
|
|
|
7526
7568
|
return;
|
|
7527
7569
|
}
|
|
7528
7570
|
await admitTextOutput(context2, destination2);
|
|
7529
|
-
|
|
7571
|
+
const capabilities = await context2.fs.capabilitiesFor?.(pathOf(context2, destination2), { signal: context2.signal }) ?? context2.fs.capabilities;
|
|
7572
|
+
if (context2.fs.writeStream && capabilities.streamingWrite !== false) await context2.fs.writeStream(pathOf(context2, destination2), records4, { signal: context2.signal });
|
|
7530
7573
|
else {
|
|
7531
|
-
if (
|
|
7574
|
+
if (capabilities.write === false) throw new FsError("ENOTSUP", { syscall: "writeFile", path: pathOf(context2, destination2) });
|
|
7532
7575
|
let size = 0;
|
|
7533
7576
|
const chunks = [];
|
|
7534
7577
|
for await (const bytes3 of records4) {
|
|
@@ -7901,7 +7944,7 @@ function predicateCommands() {
|
|
|
7901
7944
|
if (!args.length) return { exitCode: 1 };
|
|
7902
7945
|
if (args.length === 1) return { exitCode: args[0] ? 0 : 1 };
|
|
7903
7946
|
if (args.length === 2 && args[0] === "!") return { exitCode: args[1] ? 1 : 0 };
|
|
7904
|
-
const unary2 = /* @__PURE__ */ new Set(["-n", "-z", "-e", "-a", "-f", "-d", "-L", "-h", "-s", "-r", "-w", "-x"]);
|
|
7947
|
+
const unary2 = /* @__PURE__ */ new Set(["-n", "-z", "-e", "-a", "-f", "-c", "-d", "-L", "-h", "-s", "-r", "-w", "-x"]);
|
|
7905
7948
|
const binary3 = /* @__PURE__ */ new Set(["=", "==", "!=", "<", ">", "-eq", "-ne", "-lt", "-le", "-gt", "-ge", "-nt", "-ot", "-ef"]);
|
|
7906
7949
|
let offset = 0;
|
|
7907
7950
|
const number4 = (text3) => {
|
|
@@ -7936,7 +7979,9 @@ function predicateCommands() {
|
|
|
7936
7979
|
const rightStat = await metadata(context2, right);
|
|
7937
7980
|
if (operator === "-nt") return leftStat !== void 0 && (!rightStat || leftStat.mtimeMs > rightStat.mtimeMs);
|
|
7938
7981
|
if (operator === "-ot") return rightStat !== void 0 && (!leftStat || leftStat.mtimeMs < rightStat.mtimeMs);
|
|
7939
|
-
|
|
7982
|
+
const identity2 = compareCopyIdentity(leftStat, rightStat);
|
|
7983
|
+
if (identity2 !== "unknown") return identity2 === "same";
|
|
7984
|
+
return leftStat?.ino !== void 0 && rightStat?.ino !== void 0 && leftStat.type === rightStat.type && leftStat.ino === rightStat.ino && leftStat.dev === rightStat.dev;
|
|
7940
7985
|
}
|
|
7941
7986
|
const leftNumber = number4(token);
|
|
7942
7987
|
const rightNumber = number4(right);
|
|
@@ -7974,6 +8019,7 @@ function predicateCommands() {
|
|
|
7974
8019
|
const stat = await metadata(context2, operand, token === "-L" || token === "-h");
|
|
7975
8020
|
if (!stat) return false;
|
|
7976
8021
|
if (token === "-f") return stat.type === "file";
|
|
8022
|
+
if (token === "-c") return stat.type === "character";
|
|
7977
8023
|
if (token === "-d") return stat.type === "directory";
|
|
7978
8024
|
if (token === "-L" || token === "-h") return stat.type === "symlink";
|
|
7979
8025
|
if (token === "-s") return stat.size > 0;
|
|
@@ -8924,7 +8970,7 @@ function findCommands(execute5, maxDirectoryEntries) {
|
|
|
8924
8970
|
};
|
|
8925
8971
|
}
|
|
8926
8972
|
if (token === "-type") {
|
|
8927
|
-
const types = { f: "file", d: "directory", l: "symlink" };
|
|
8973
|
+
const types = { f: "file", d: "directory", l: "symlink", c: "character" };
|
|
8928
8974
|
if (!types[operand]) throw new UsageError(`unsupported file type '${operand}'`);
|
|
8929
8975
|
return async (entry) => entry.stat.type === types[operand];
|
|
8930
8976
|
}
|
|
@@ -11711,8 +11757,14 @@ var AwkRuntime = class {
|
|
|
11711
11757
|
const useStdin = file === "-";
|
|
11712
11758
|
const source2 = (async function* () {
|
|
11713
11759
|
if (useStdin) yield* context2.stdin;
|
|
11714
|
-
else
|
|
11715
|
-
|
|
11760
|
+
else {
|
|
11761
|
+
budget.step();
|
|
11762
|
+
await budget.checkpoint();
|
|
11763
|
+
const capabilities = await context2.fs.capabilitiesFor?.(name2, { signal: context2.signal }) ?? context2.fs.capabilities;
|
|
11764
|
+
context2.signal.throwIfAborted();
|
|
11765
|
+
if (context2.fs.readStream && capabilities.streamingRead !== false) yield* context2.fs.readStream(name2, { signal: context2.signal });
|
|
11766
|
+
else yield await context2.fs.readFile(name2, { signal: context2.signal, maxBytes: budget.maxBufferBytes });
|
|
11767
|
+
}
|
|
11716
11768
|
})();
|
|
11717
11769
|
try {
|
|
11718
11770
|
reader = new Reader(source2, budget, this.retention);
|
|
@@ -14338,10 +14390,12 @@ function argumentsFor(args, budget) {
|
|
|
14338
14390
|
return options3;
|
|
14339
14391
|
}
|
|
14340
14392
|
async function readProgram2(context2, path, limits) {
|
|
14341
|
-
const absolute =
|
|
14393
|
+
const absolute = pathOf(context2, path);
|
|
14342
14394
|
const chunks = [];
|
|
14343
14395
|
let size = 0;
|
|
14344
|
-
|
|
14396
|
+
const capabilities = context2.fs.capabilitiesFor ? await interruptible(() => context2.fs.capabilitiesFor(absolute, { signal: context2.signal }), context2.signal) : context2.fs.capabilities;
|
|
14397
|
+
context2.signal.throwIfAborted();
|
|
14398
|
+
if (context2.fs.readStream && capabilities.streamingRead !== false) {
|
|
14345
14399
|
for await (const chunk of readBytes2(context2.fs.readStream(absolute, { signal: context2.signal }), context2.signal)) {
|
|
14346
14400
|
size += chunk.byteLength;
|
|
14347
14401
|
if (size > limits.maxSourceBytes) throw new JqLimitError("maxSourceBytes");
|
|
@@ -14368,9 +14422,12 @@ async function* inputSources(context2, options3, budget) {
|
|
|
14368
14422
|
usedStdin = true;
|
|
14369
14423
|
source2 = context2.stdin;
|
|
14370
14424
|
} else {
|
|
14371
|
-
const absolute =
|
|
14425
|
+
const absolute = pathOf(context2, file);
|
|
14372
14426
|
const remaining = budget.limits.maxInputBytes - budget.inputBytes;
|
|
14373
|
-
|
|
14427
|
+
await budget.tick();
|
|
14428
|
+
const capabilities = context2.fs.capabilitiesFor ? await interruptible(() => context2.fs.capabilitiesFor(absolute, { signal: context2.signal }), context2.signal) : context2.fs.capabilities;
|
|
14429
|
+
context2.signal.throwIfAborted();
|
|
14430
|
+
if (context2.fs.readStream && capabilities.streamingRead !== false) source2 = context2.fs.readStream(absolute, { signal: context2.signal });
|
|
14374
14431
|
else source2 = toByteSource(await interruptible(() => context2.fs.readFile(absolute, { signal: context2.signal, maxBytes: remaining }), context2.signal));
|
|
14375
14432
|
}
|
|
14376
14433
|
budget.inputLocation = { name: file === "-" ? "<stdin>" : file, line: 0, complete: false };
|
|
@@ -21010,10 +21067,11 @@ async function planOperands(context2, options3) {
|
|
|
21010
21067
|
continue;
|
|
21011
21068
|
}
|
|
21012
21069
|
if (!name2) throw new FsError("ENOENT", { path: name2 });
|
|
21013
|
-
|
|
21070
|
+
const source2 = pathOf(context2, name2);
|
|
21071
|
+
const sourceCapabilities = await context2.fs.capabilitiesFor?.(source2, { signal: context2.signal }) ?? context2.fs.capabilities;
|
|
21072
|
+
if (!context2.fs.readStream || sourceCapabilities.streamingRead === false) {
|
|
21014
21073
|
throw new FsError("ENOTSUP", { message: "named input requires VFS streaming reads; no readFile fallback" });
|
|
21015
21074
|
}
|
|
21016
|
-
const source2 = pathOf(context2, name2);
|
|
21017
21075
|
const sourceStat = await context2.fs.lstat(source2, { signal: context2.signal });
|
|
21018
21076
|
if (sourceStat.type !== "file") throw new FsError("EINVAL", { path: source2, message: "input must be a regular, non-symlink file" });
|
|
21019
21077
|
const realSource = await context2.fs.realpath(source2, { signal: context2.signal });
|
|
@@ -21024,20 +21082,22 @@ async function planOperands(context2, options3) {
|
|
|
21024
21082
|
if (context2.fs.capabilities.readOnly === true) {
|
|
21025
21083
|
throw new FsError("EROFS", { syscall: context2.command, path: realSource });
|
|
21026
21084
|
}
|
|
21027
|
-
if (!context2.fs.writeStream || context2.fs.capabilities.streamingWrite === false) {
|
|
21028
|
-
throw new FsError("ENOTSUP", { message: "file output requires VFS streaming writes (use -c for stdout)" });
|
|
21029
|
-
}
|
|
21030
21085
|
if (!options3.keep && !options3.force && (sourceStat.nlink ?? 1) > 1) {
|
|
21031
21086
|
throw new FsError("EINVAL", { path: source2, message: "input has multiple links (use -k or -f)" });
|
|
21032
21087
|
}
|
|
21033
21088
|
const destination2 = outputPath(realSource, options3);
|
|
21089
|
+
const capabilities = await context2.fs.capabilitiesFor?.(destination2, { signal: context2.signal }) ?? context2.fs.capabilities;
|
|
21090
|
+
if (capabilities.readOnly === true) throw new FsError("EROFS", { syscall: context2.command, path: destination2 });
|
|
21091
|
+
if (!context2.fs.writeStream || capabilities.streamingWrite === false) {
|
|
21092
|
+
throw new FsError("ENOTSUP", { message: "file output requires VFS streaming writes (use -c for stdout)" });
|
|
21093
|
+
}
|
|
21034
21094
|
const destinationStat = await existing(context2, destination2);
|
|
21035
21095
|
if (destinationStat) {
|
|
21036
21096
|
if (destinationStat.type !== "file" || sameIdentity(sourceStat, destinationStat) || realSource === await context2.fs.realpath(destination2, { signal: context2.signal })) {
|
|
21037
21097
|
throw new FsError("EINVAL", { path: destination2, message: "destination is not a distinct regular file" });
|
|
21038
21098
|
}
|
|
21039
21099
|
if (!options3.force) throw new FsError("EEXIST", { path: destination2 });
|
|
21040
|
-
if (
|
|
21100
|
+
if (capabilities.atomicRename !== true) {
|
|
21041
21101
|
throw new FsError("ENOTSUP", { path: destination2, message: "forced replacement requires VFS atomicRename" });
|
|
21042
21102
|
}
|
|
21043
21103
|
}
|
|
@@ -21370,7 +21430,8 @@ var Budget11 = class {
|
|
|
21370
21430
|
async read(path) {
|
|
21371
21431
|
this.context.signal.throwIfAborted();
|
|
21372
21432
|
const remaining = this.limits.maxInputBytes - this.inputBytes;
|
|
21373
|
-
const
|
|
21433
|
+
const capabilities = path === "-" ? void 0 : await host(this.context, async () => await this.context.fs.capabilitiesFor?.(path, { signal: this.context.signal }) ?? this.context.fs.capabilities);
|
|
21434
|
+
const bytes3 = path === "-" ? await collectBytes2(this.chunks(this.context.stdin), { signal: this.context.signal, maxBytes: remaining }) : this.context.fs.readStream && capabilities?.streamingRead !== false ? await collectBytes2(this.chunks(this.context.fs.readStream(path, { signal: this.context.signal })), { signal: this.context.signal, maxBytes: remaining }) : await host(this.context, () => this.context.fs.readFile(path, { signal: this.context.signal, maxBytes: remaining }));
|
|
21374
21435
|
this.inputBytes += bytes3.byteLength;
|
|
21375
21436
|
if (this.inputBytes > this.limits.maxInputBytes) throw new ToolError("input byte limit exceeded");
|
|
21376
21437
|
return this.text(bytes3);
|
|
@@ -21405,7 +21466,7 @@ async function host(context2, operation2) {
|
|
|
21405
21466
|
async function inspect(budget, path) {
|
|
21406
21467
|
const context2 = budget.context;
|
|
21407
21468
|
if (path.length > 4096) throw new ToolError("path length limit exceeded");
|
|
21408
|
-
const absolute =
|
|
21469
|
+
const absolute = pathOf(context2, path);
|
|
21409
21470
|
const parts2 = absolute.split("/").filter(Boolean);
|
|
21410
21471
|
if (absolute.length > 4096 || parts2.length > 256) throw new ToolError("path length/depth limit exceeded");
|
|
21411
21472
|
let current = "";
|
|
@@ -21794,7 +21855,7 @@ async function run(context2, budget) {
|
|
|
21794
21855
|
const names = /* @__PURE__ */ new Set();
|
|
21795
21856
|
for (const path of [leftStat ? left : void 0, rightStat ? right : void 0]) {
|
|
21796
21857
|
if (path === void 0) continue;
|
|
21797
|
-
const entries3 = await host(context2, () => context2.fs.readdir(
|
|
21858
|
+
const entries3 = await host(context2, () => context2.fs.readdir(pathOf(context2, path), { signal: context2.signal }));
|
|
21798
21859
|
for (const entry of entries3) {
|
|
21799
21860
|
budget.step();
|
|
21800
21861
|
if (!entry.name || entry.name === "." || entry.name === ".." || /[\/\\\0\r\n\t]/u.test(entry.name)) throw new ToolError("unsafe directory entry name");
|
|
@@ -21808,7 +21869,7 @@ async function run(context2, budget) {
|
|
|
21808
21869
|
const read = async (path, exists) => {
|
|
21809
21870
|
if (!exists) return "";
|
|
21810
21871
|
if (path === "-") return stdin ??= await budget.read("-");
|
|
21811
|
-
return budget.read(
|
|
21872
|
+
return budget.read(pathOf(context2, path));
|
|
21812
21873
|
};
|
|
21813
21874
|
const oldText = await read(left, !!leftStat);
|
|
21814
21875
|
const newText = await read(right, !!rightStat);
|
|
@@ -23070,7 +23131,7 @@ function metadataCommand(name2, handler) {
|
|
|
23070
23131
|
} };
|
|
23071
23132
|
}
|
|
23072
23133
|
function permissionString(mode, type2) {
|
|
23073
|
-
let text3 = type2 === "directory" ? "d" : type2 === "symlink" ? "l" : "-";
|
|
23134
|
+
let text3 = type2 === "directory" ? "d" : type2 === "symlink" ? "l" : type2 === "character" ? "c" : "-";
|
|
23074
23135
|
for (const [read, write2, execute5, special2, lower, upper] of [
|
|
23075
23136
|
[256, 128, 64, 2048, "s", "S"],
|
|
23076
23137
|
[32, 16, 8, 1024, "s", "S"],
|
|
@@ -23390,7 +23451,7 @@ async function render(context2, path, name2, stat, format2, escapes, limit) {
|
|
|
23390
23451
|
}
|
|
23391
23452
|
} else if (code === "%") text3 = "%";
|
|
23392
23453
|
else if (code === "A") text3 = permissionString(stat.mode, stat.type);
|
|
23393
|
-
else if (code === "F") text3 = stat.type === "directory" ? "directory" : stat.type === "symlink" ? "symbolic link" : stat.size === 0 ? "regular empty file" : "regular file";
|
|
23454
|
+
else if (code === "F") text3 = stat.type === "directory" ? "directory" : stat.type === "symlink" ? "symbolic link" : stat.type === "character" ? "character special file" : stat.size === 0 ? "regular empty file" : "regular file";
|
|
23394
23455
|
else if (["x", "y", "z", "w"].includes(code)) {
|
|
23395
23456
|
const value2 = times[code.toUpperCase()];
|
|
23396
23457
|
text3 = code === "w" && value2 === void 0 ? "-" : timestamp2(available(value2, code));
|
|
@@ -23515,7 +23576,6 @@ function createMktempCommand(configuration = {}) {
|
|
|
23515
23576
|
try {
|
|
23516
23577
|
if (!parsed.dryRun) {
|
|
23517
23578
|
if (context2.fs.capabilities.readOnly) throw new FsError("EROFS", { syscall: "mktemp" });
|
|
23518
|
-
if (context2.fs.capabilities.permissions !== true) throw new FsError("ENOTSUP", { syscall: "mktemp", message: "private temporary creation requires declared permission support" });
|
|
23519
23579
|
}
|
|
23520
23580
|
for (let attempt = 0; attempt < configured.limits.maxAttempts; attempt++) {
|
|
23521
23581
|
await budget.step();
|
|
@@ -23534,6 +23594,9 @@ function createMktempCommand(configuration = {}) {
|
|
|
23534
23594
|
if (codeOf(error) !== "ENOENT") throw error;
|
|
23535
23595
|
}
|
|
23536
23596
|
} else {
|
|
23597
|
+
const capabilities = await context2.fs.capabilitiesFor?.(path, { signal: context2.signal }) ?? context2.fs.capabilities;
|
|
23598
|
+
if (capabilities.readOnly === true) throw new FsError("EROFS", { syscall: "mktemp" });
|
|
23599
|
+
if (capabilities.permissions !== true) throw new FsError("ENOTSUP", { syscall: "mktemp", message: "private temporary creation requires declared permission support" });
|
|
23537
23600
|
try {
|
|
23538
23601
|
const mode = (parsed.directory ? 448 : 384) & ~configured.umask;
|
|
23539
23602
|
if (parsed.directory) await context2.fs.mkdir(path, { mode, recursive: false, signal: context2.signal });
|
|
@@ -23714,7 +23777,9 @@ async function* bounded(source2, maximum, signal, chunkSize2) {
|
|
|
23714
23777
|
}
|
|
23715
23778
|
async function* fileSource(context2, path, limits) {
|
|
23716
23779
|
context2.signal.throwIfAborted();
|
|
23717
|
-
|
|
23780
|
+
const capabilities = await operation(context2, () => context2.fs.capabilitiesFor?.(path, { signal: context2.signal }) ?? context2.fs.capabilities);
|
|
23781
|
+
context2.signal.throwIfAborted();
|
|
23782
|
+
if (context2.fs.readStream && capabilities.streamingRead !== false) {
|
|
23718
23783
|
yield* readBytes2(context2.fs.readStream(path, { signal: context2.signal, chunkSize: limits.chunkSize }), context2.signal);
|
|
23719
23784
|
} else {
|
|
23720
23785
|
const stat = await operation(context2, () => context2.fs.stat(path, { signal: context2.signal }));
|
|
@@ -23726,7 +23791,9 @@ async function* fileSource(context2, path, limits) {
|
|
|
23726
23791
|
}
|
|
23727
23792
|
async function publish2(context2, path, source2, mode = 384) {
|
|
23728
23793
|
const options3 = { signal: context2.signal, flag: "wx", mode };
|
|
23729
|
-
|
|
23794
|
+
const capabilities = await operation(context2, () => context2.fs.capabilitiesFor?.(path, { signal: context2.signal }) ?? context2.fs.capabilities);
|
|
23795
|
+
context2.signal.throwIfAborted();
|
|
23796
|
+
if (context2.fs.writeStream && capabilities.streamingWrite !== false) {
|
|
23730
23797
|
let finished = false;
|
|
23731
23798
|
const observed = (async function* () {
|
|
23732
23799
|
yield* readBytes2(source2, context2.signal);
|
|
@@ -24492,7 +24559,7 @@ async function readArchive(context2, source2, options3, budget) {
|
|
|
24492
24559
|
archivePath = await operation(context2, () => context2.fs.realpath(vfsPath(context2.cwd, options3.archive), { signal: context2.signal }));
|
|
24493
24560
|
archiveStat = await operation(context2, () => context2.fs.stat(archivePath, { signal: context2.signal }));
|
|
24494
24561
|
}
|
|
24495
|
-
if (options3.mode === "x") await checkRoot(context2,
|
|
24562
|
+
if (options3.mode === "x") await checkRoot(context2, options3.cwd);
|
|
24496
24563
|
try {
|
|
24497
24564
|
while (true) {
|
|
24498
24565
|
const block = await reader.exact(512);
|
|
@@ -24553,7 +24620,10 @@ async function readArchive(context2, source2, options3, budget) {
|
|
|
24553
24620
|
const operand = options3.operands[index];
|
|
24554
24621
|
const wanted = operand.name.replace(/^\/+/u, "").replace(/\/+$/u, "");
|
|
24555
24622
|
if (name2.replace(/\/+$/u, "") === wanted || name2.startsWith(`${wanted}/`)) {
|
|
24556
|
-
if (!selected)
|
|
24623
|
+
if (!selected) {
|
|
24624
|
+
if (options3.mode === "x") await checkRoot(context2, operand.cwd);
|
|
24625
|
+
root = resolvePath(operand.cwd);
|
|
24626
|
+
}
|
|
24557
24627
|
selected = true;
|
|
24558
24628
|
matched.add(index);
|
|
24559
24629
|
}
|
|
@@ -24864,10 +24934,11 @@ var Inputs = class {
|
|
|
24864
24934
|
let source2;
|
|
24865
24935
|
if (name2 === "-") source2 = this.context.stdin;
|
|
24866
24936
|
else {
|
|
24867
|
-
const path =
|
|
24937
|
+
const path = pathOf(this.context, name2);
|
|
24868
24938
|
const stat = await this.context.fs.stat(path, { signal: this.signal });
|
|
24869
24939
|
if (stat.type === "directory") throw new FsError("EISDIR", { path });
|
|
24870
|
-
|
|
24940
|
+
const capabilities = await this.context.fs.capabilitiesFor?.(path, { signal: this.signal }) ?? this.context.fs.capabilities;
|
|
24941
|
+
if (this.context.fs.readStream && capabilities.streamingRead !== false) source2 = this.context.fs.readStream(path, { signal: this.signal });
|
|
24871
24942
|
else {
|
|
24872
24943
|
const { context: context2, signal, budget } = this;
|
|
24873
24944
|
source2 = (async function* () {
|
|
@@ -25430,11 +25501,14 @@ var Session = class {
|
|
|
25430
25501
|
} };
|
|
25431
25502
|
} else {
|
|
25432
25503
|
if (!name2) throw new FsError("ENOENT", { path: name2 });
|
|
25433
|
-
const path =
|
|
25504
|
+
const path = pathOf(session.context, name2);
|
|
25434
25505
|
const stat = await session.context.fs.stat(path, { signal });
|
|
25435
25506
|
signal.throwIfAborted();
|
|
25436
25507
|
if (stat.type === "directory") throw new FsError("EISDIR", { path });
|
|
25437
|
-
|
|
25508
|
+
await session.step();
|
|
25509
|
+
const capabilities = await session.context.fs.capabilitiesFor?.(path, { signal }) ?? session.context.fs.capabilities;
|
|
25510
|
+
signal.throwIfAborted();
|
|
25511
|
+
if (session.context.fs.readStream && capabilities.streamingRead !== false) yield* session.context.fs.readStream(path, { signal });
|
|
25438
25512
|
else yield await session.context.fs.readFile(path, { signal, maxBytes: Math.min(session.limits.maxChunkBytes, session.limits.maxInputBytes - session.inputBytes) });
|
|
25439
25513
|
}
|
|
25440
25514
|
})();
|
|
@@ -25937,11 +26011,14 @@ var Session2 = class {
|
|
|
25937
26011
|
} };
|
|
25938
26012
|
} else {
|
|
25939
26013
|
if (!name2) throw new FsError("ENOENT", { path: name2 });
|
|
25940
|
-
const path =
|
|
26014
|
+
const path = pathOf(session.context, name2);
|
|
25941
26015
|
const stat = await session.context.fs.stat(path, { signal });
|
|
25942
26016
|
signal.throwIfAborted();
|
|
25943
26017
|
if (stat.type === "directory") throw new FsError("EISDIR", { path });
|
|
25944
|
-
|
|
26018
|
+
await session.step();
|
|
26019
|
+
const capabilities = await session.context.fs.capabilitiesFor?.(path, { signal }) ?? session.context.fs.capabilities;
|
|
26020
|
+
signal.throwIfAborted();
|
|
26021
|
+
if (session.context.fs.readStream && capabilities.streamingRead !== false) yield* session.context.fs.readStream(path, { signal });
|
|
25945
26022
|
else yield await session.context.fs.readFile(path, { signal, maxBytes: Math.min(session.limits.maxChunkBytes, session.limits.maxInputBytes - session.inputBytes) });
|
|
25946
26023
|
}
|
|
25947
26024
|
})();
|
|
@@ -26710,7 +26787,8 @@ var Cursor = class {
|
|
|
26710
26787
|
if (input3 === "-") yield* readBytes2(context2.stdin, signal);
|
|
26711
26788
|
else {
|
|
26712
26789
|
const path = pathOf(context2, input3);
|
|
26713
|
-
|
|
26790
|
+
const capabilities = await interruptible2(() => Promise.resolve(context2.fs.capabilitiesFor?.(path, { signal }) ?? context2.fs.capabilities), signal);
|
|
26791
|
+
if (context2.fs.readStream && capabilities.streamingRead !== false) {
|
|
26714
26792
|
yield* readBytes2(context2.fs.readStream(path, { signal, chunkSize: limits.maxChunkBytes }), signal);
|
|
26715
26793
|
} else {
|
|
26716
26794
|
const maxBytes = Math.min(limits.maxInputBytes, limits.maxBufferBytes);
|
|
@@ -26977,7 +27055,8 @@ async function run3(context2, limits) {
|
|
|
26977
27055
|
yield chunk;
|
|
26978
27056
|
}
|
|
26979
27057
|
})();
|
|
26980
|
-
|
|
27058
|
+
const capabilities = await interruptible2(() => Promise.resolve(context2.fs.capabilitiesFor?.(destination2.path, { signal }) ?? context2.fs.capabilities), signal);
|
|
27059
|
+
if (context2.fs.writeStream && capabilities.streamingWrite !== false) {
|
|
26981
27060
|
await interruptible2(() => context2.fs.writeStream(destination2.path, source2, { signal, flag: destination2.flag }), signal);
|
|
26982
27061
|
} else {
|
|
26983
27062
|
const bytes3 = await collectBytes2(source2, { signal, maxBytes: limits.maxBufferBytes });
|
|
@@ -27706,7 +27785,7 @@ function createDateCommand(configuration) {
|
|
|
27706
27785
|
if (parsed.reference !== void 0) {
|
|
27707
27786
|
try {
|
|
27708
27787
|
if (!parsed.reference) throw new FsError("ENOENT", { path: parsed.reference });
|
|
27709
|
-
const stat = await context2.fs.stat(
|
|
27788
|
+
const stat = await context2.fs.stat(pathOf(context2, parsed.reference), { signal: context2.signal });
|
|
27710
27789
|
context2.signal.throwIfAborted();
|
|
27711
27790
|
instant = millisecondsInstant(stat.mtimeMs);
|
|
27712
27791
|
} catch (error) {
|
|
@@ -28419,7 +28498,7 @@ var Walker2 = class {
|
|
|
28419
28498
|
this.budget.text(operand);
|
|
28420
28499
|
this.budget.entry();
|
|
28421
28500
|
if (this.args.json && index) await this.write(`,${this.newline()}`);
|
|
28422
|
-
const entry = await this.inspect(
|
|
28501
|
+
const entry = await this.inspect(pathOf(this.budget.context, operand), operand, operand);
|
|
28423
28502
|
await this.visit(entry, [], "", true, 0);
|
|
28424
28503
|
}
|
|
28425
28504
|
if (this.args.report) {
|
|
@@ -28849,10 +28928,11 @@ async function inspect2(context2, name2, follow, describe2, budget, stdinUsed) {
|
|
|
28849
28928
|
return result3;
|
|
28850
28929
|
}
|
|
28851
28930
|
if (!name2 || name2.includes("\0")) throw new FsError(name2 ? "EINVAL" : "ENOENT", { path: name2 });
|
|
28852
|
-
const path =
|
|
28931
|
+
const path = pathOf(context2, name2);
|
|
28853
28932
|
const fs = context2.fs;
|
|
28854
28933
|
const stat = await budget.host(() => follow ? fs.stat(path, { signal: budget.signal }) : fs.lstat(path, { signal: budget.signal }));
|
|
28855
28934
|
if (stat.type === "directory") return { description: "directory", mime: "inode/directory", encoding: "binary" };
|
|
28935
|
+
if (stat.type === "character") return { description: "character special", mime: "inode/chardevice", encoding: "binary" };
|
|
28856
28936
|
if (stat.type === "symlink") {
|
|
28857
28937
|
if (follow) throw new FsError("ENOTSUP", { path, message: "followed stat returned a symbolic link" });
|
|
28858
28938
|
const target = fs.readlink ? await budget.host(() => fs.readlink(path, { signal: budget.signal })) : void 0;
|
|
@@ -28861,7 +28941,8 @@ async function inspect2(context2, name2, follow, describe2, budget, stdinUsed) {
|
|
|
28861
28941
|
}
|
|
28862
28942
|
if (stat.type !== "file") throw new FsError("ENOTSUP", { path, message: "unsupported filesystem entry type" });
|
|
28863
28943
|
let sample;
|
|
28864
|
-
|
|
28944
|
+
const capabilities = fs.capabilitiesFor ? await budget.host(() => fs.capabilitiesFor(path, { signal: budget.signal })) : fs.capabilities;
|
|
28945
|
+
if (fs.readStream && capabilities.streamingRead !== false) {
|
|
28865
28946
|
const controller = new AbortController();
|
|
28866
28947
|
const signal = AbortSignal.any([budget.signal, controller.signal]);
|
|
28867
28948
|
try {
|
|
@@ -30226,25 +30307,17 @@ var Inputs2 = class {
|
|
|
30226
30307
|
if (name2 === "-") source2 = this.context.stdin;
|
|
30227
30308
|
else {
|
|
30228
30309
|
const context2 = this.context, budget = this.budget, path = pathOf(context2, name2);
|
|
30229
|
-
|
|
30230
|
-
|
|
30231
|
-
|
|
30232
|
-
|
|
30233
|
-
|
|
30234
|
-
|
|
30235
|
-
|
|
30236
|
-
|
|
30237
|
-
|
|
30238
|
-
|
|
30239
|
-
|
|
30240
|
-
},
|
|
30241
|
-
async return() {
|
|
30242
|
-
consumed = true;
|
|
30243
|
-
return { done: true, value: void 0 };
|
|
30244
|
-
}
|
|
30245
|
-
};
|
|
30246
|
-
} };
|
|
30247
|
-
}
|
|
30310
|
+
source2 = (async function* () {
|
|
30311
|
+
const capabilities = await context2.fs.capabilitiesFor?.(path, { signal: context2.signal }) ?? context2.fs.capabilities;
|
|
30312
|
+
context2.signal.throwIfAborted();
|
|
30313
|
+
if (context2.fs.readStream && capabilities.streamingRead !== false) {
|
|
30314
|
+
yield* readBytes2(context2.fs.readStream(path, { signal: context2.signal, chunkSize: 16384 }), context2.signal);
|
|
30315
|
+
} else {
|
|
30316
|
+
const value2 = await context2.fs.readFile(path, { signal: context2.signal, maxBytes: budget.limits.maxInputBytes - budget.input });
|
|
30317
|
+
context2.signal.throwIfAborted();
|
|
30318
|
+
yield value2;
|
|
30319
|
+
}
|
|
30320
|
+
})();
|
|
30248
30321
|
}
|
|
30249
30322
|
const cursor = new Cursor2(source2, this.context.signal);
|
|
30250
30323
|
this.cursors.push(cursor);
|
|
@@ -31249,7 +31322,7 @@ var Walker3 = class {
|
|
|
31249
31322
|
let stat;
|
|
31250
31323
|
try {
|
|
31251
31324
|
stat = await this.budget.fs(() => context2.fs.lstat(path, { signal: context2.signal }));
|
|
31252
|
-
if (!stat || !["file", "directory", "symlink"].includes(stat.type)) throw new PublicDiagnostic("invalid entry type");
|
|
31325
|
+
if (!stat || !["file", "directory", "symlink", "character"].includes(stat.type)) throw new PublicDiagnostic("invalid entry type");
|
|
31253
31326
|
} catch (error) {
|
|
31254
31327
|
await this.failure(error, display2);
|
|
31255
31328
|
return { bytes: 0, complete: false };
|
|
@@ -31281,10 +31354,9 @@ var Walker3 = class {
|
|
|
31281
31354
|
const { context: context2 } = this.budget;
|
|
31282
31355
|
this.budget.text(context2.cwd);
|
|
31283
31356
|
const paths = this.args.operands.map((operand) => {
|
|
31284
|
-
const path =
|
|
31285
|
-
|
|
31286
|
-
|
|
31287
|
-
return resolved;
|
|
31357
|
+
const path = pathOf(context2, operand === "" ? "." : operand);
|
|
31358
|
+
this.budget.text(path);
|
|
31359
|
+
return path;
|
|
31288
31360
|
});
|
|
31289
31361
|
for (let index = 0; index < paths.length; index++) {
|
|
31290
31362
|
const amount = await this.walk(paths[index], this.args.operands[index], 0);
|
|
@@ -33095,7 +33167,10 @@ var Invocation2 = class {
|
|
|
33095
33167
|
try {
|
|
33096
33168
|
await this.work.fs(target, () => this.context.fs.access(target, 2, { signal: this.context.signal }));
|
|
33097
33169
|
} catch (error) {
|
|
33098
|
-
if (error instanceof FileFailure2 && (error.error.code === "ENOTSUP" || error.error.code === "EOPNOTSUPP")
|
|
33170
|
+
if (error instanceof FileFailure2 && (error.error.code === "ENOTSUP" || error.error.code === "EOPNOTSUPP")) {
|
|
33171
|
+
const capabilities = await this.work.fs(target, async () => await this.context.fs.capabilitiesFor?.(target, { signal: this.context.signal }) ?? this.context.fs.capabilities);
|
|
33172
|
+
if (capabilities.permissions !== true) return;
|
|
33173
|
+
}
|
|
33099
33174
|
throw error;
|
|
33100
33175
|
}
|
|
33101
33176
|
}
|
|
@@ -33382,6 +33457,7 @@ init_platform();
|
|
|
33382
33457
|
|
|
33383
33458
|
// packages/safe-bash/src/shell/shell.ts
|
|
33384
33459
|
init_platform();
|
|
33460
|
+
import { createDeviceFileSystem } from "@poe-platform/safe-fs/core";
|
|
33385
33461
|
|
|
33386
33462
|
// packages/safe-bash/src/shell/env-warning.ts
|
|
33387
33463
|
init_platform();
|
|
@@ -33976,20 +34052,22 @@ async function unary(operator, value2, context2) {
|
|
|
33976
34052
|
return context2.present(value2);
|
|
33977
34053
|
}
|
|
33978
34054
|
if (operator === "-o") return context2.option(value2);
|
|
33979
|
-
if (!["-e", "-a", "-f", "-d", "-s", "-L", "-h", "-r", "-w", "-x"].includes(operator)) unsupported3(operator);
|
|
34055
|
+
if (!["-e", "-a", "-f", "-c", "-d", "-s", "-L", "-h", "-r", "-w", "-x"].includes(operator)) unsupported3(operator);
|
|
33980
34056
|
if (value2 === "") return false;
|
|
33981
34057
|
if (/^\/dev\/(?:fd(?:\/|$)|stdin$|stdout$|stderr$)/u.test(value2)) unsupported3("descriptor predicate");
|
|
33982
34058
|
const access = ["-r", "-w", "-x"].includes(operator);
|
|
33983
|
-
if (access && context2.fs.capabilities.permissions !== true) unsupported3("unobservable access permission");
|
|
33984
34059
|
try {
|
|
33985
34060
|
if (access) {
|
|
33986
|
-
await context2.fs.
|
|
34061
|
+
const capabilities = await context2.fs.capabilitiesFor?.(pathOf(context2, value2), { signal: context2.signal }) ?? context2.fs.capabilities;
|
|
34062
|
+
if (capabilities.permissions !== true) unsupported3("unobservable access permission");
|
|
34063
|
+
await context2.fs.access(pathOf(context2, value2), operator === "-r" ? 4 : operator === "-w" ? 2 : 1, { signal: context2.signal });
|
|
33987
34064
|
context2.signal.throwIfAborted();
|
|
33988
34065
|
return true;
|
|
33989
34066
|
}
|
|
33990
|
-
const metadata3 = await (operator === "-L" || operator === "-h" ? context2.fs.lstat(
|
|
34067
|
+
const metadata3 = await (operator === "-L" || operator === "-h" ? context2.fs.lstat(pathOf(context2, value2), { signal: context2.signal }) : context2.fs.stat(pathOf(context2, value2), { signal: context2.signal }));
|
|
33991
34068
|
context2.signal.throwIfAborted();
|
|
33992
34069
|
if (operator === "-f") return metadata3.type === "file";
|
|
34070
|
+
if (operator === "-c") return metadata3.type === "character";
|
|
33993
34071
|
if (operator === "-d") return metadata3.type === "directory";
|
|
33994
34072
|
if (operator === "-s") return metadata3.size > 0;
|
|
33995
34073
|
if (operator === "-L" || operator === "-h") return metadata3.type === "symlink";
|
|
@@ -38474,19 +38552,20 @@ var CdLookup = class {
|
|
|
38474
38552
|
const rawBytes = absolute ? targetBytes : component.startsWith("/") ? componentBytes + 1 + targetBytes : cwdBytes + 1 + (component ? componentBytes + 1 : 0) + targetBytes;
|
|
38475
38553
|
if (rawBytes > 65536) throw new PublicDiagnostic("cd: path exceeds 65536 UTF-8 bytes");
|
|
38476
38554
|
await this.charge(2 * rawBytes);
|
|
38477
|
-
const raw = absolute ? target :
|
|
38555
|
+
const raw = absolute ? target : pathOf({ cwd }, component ? `${component}/${target}` : target);
|
|
38478
38556
|
const path = resolvePath(cwd, raw);
|
|
38557
|
+
const operand = pathOf({ cwd }, raw);
|
|
38479
38558
|
await this.scan(path);
|
|
38480
38559
|
this.signal.throwIfAborted();
|
|
38481
38560
|
if (++this.probes > 4097) throw new PublicDiagnostic("cd: probe limit exceeded");
|
|
38482
38561
|
await this.charge(1);
|
|
38483
38562
|
this.signal.throwIfAborted();
|
|
38484
|
-
const stat = await fs.stat(
|
|
38563
|
+
const stat = await fs.stat(operand, { signal: this.signal });
|
|
38485
38564
|
this.signal.throwIfAborted();
|
|
38486
38565
|
if (stat.type !== "directory") throw new FsError("ENOTDIR", { path });
|
|
38487
38566
|
await this.charge(1);
|
|
38488
38567
|
this.signal.throwIfAborted();
|
|
38489
|
-
await fs.access(
|
|
38568
|
+
await fs.access(operand, ACCESS_MODES.X_OK, { signal: this.signal });
|
|
38490
38569
|
this.signal.throwIfAborted();
|
|
38491
38570
|
return path;
|
|
38492
38571
|
};
|
|
@@ -38841,7 +38920,7 @@ var InvocationCancellationOwner = class {
|
|
|
38841
38920
|
}
|
|
38842
38921
|
};
|
|
38843
38922
|
var Runtime = class _Runtime {
|
|
38844
|
-
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) {
|
|
38923
|
+
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) {
|
|
38845
38924
|
this.fs = fs;
|
|
38846
38925
|
this.commands = commands;
|
|
38847
38926
|
this.middleware = middleware;
|
|
@@ -38856,6 +38935,7 @@ var Runtime = class _Runtime {
|
|
|
38856
38935
|
this.cancellationDepth = cancellationDepth;
|
|
38857
38936
|
this.cancellationMaxDepth = cancellationMaxDepth;
|
|
38858
38937
|
this.outcomeFrame = outcomeFrame;
|
|
38938
|
+
this.inputProfile = inputProfile;
|
|
38859
38939
|
this.fs = scopeFileSystem(fs, () => budget.fileSystemOperation(), signal);
|
|
38860
38940
|
const checkpoint = () => budget.cpuCheckpoint();
|
|
38861
38941
|
registerYieldCheckpoint(signal, checkpoint);
|
|
@@ -38875,6 +38955,7 @@ var Runtime = class _Runtime {
|
|
|
38875
38955
|
cancellationDepth;
|
|
38876
38956
|
cancellationMaxDepth;
|
|
38877
38957
|
outcomeFrame;
|
|
38958
|
+
inputProfile;
|
|
38878
38959
|
async ereDiagnostic(io, detail) {
|
|
38879
38960
|
try {
|
|
38880
38961
|
await this.diagnostic(io, detail);
|
|
@@ -39073,7 +39154,8 @@ var Runtime = class _Runtime {
|
|
|
39073
39154
|
owner ?? this.cancellationOwner,
|
|
39074
39155
|
prepared.owned ? childDepth : this.cancellationDepth,
|
|
39075
39156
|
this.cancellationMaxDepth,
|
|
39076
|
-
frame
|
|
39157
|
+
frame,
|
|
39158
|
+
this.inputProfile
|
|
39077
39159
|
);
|
|
39078
39160
|
let captured;
|
|
39079
39161
|
const executeChild = () => execute5(runtime, scope);
|
|
@@ -39616,7 +39698,8 @@ var Runtime = class _Runtime {
|
|
|
39616
39698
|
owner,
|
|
39617
39699
|
childDepth,
|
|
39618
39700
|
this.cancellationMaxDepth,
|
|
39619
|
-
frame
|
|
39701
|
+
frame,
|
|
39702
|
+
this.inputProfile
|
|
39620
39703
|
);
|
|
39621
39704
|
const input3 = new ShellInput(incoming?.readable ?? io.stdin, this.budget, signal);
|
|
39622
39705
|
const pipeOutput = outgoing && { [outputFailure]: outgoing.abort, ownedOutput: outgoing.writable.ownedOutput, write: async (chunk) => {
|
|
@@ -40115,13 +40198,13 @@ var Runtime = class _Runtime {
|
|
|
40115
40198
|
}
|
|
40116
40199
|
}
|
|
40117
40200
|
} else {
|
|
40118
|
-
const path =
|
|
40201
|
+
const path = pathOf(state, target);
|
|
40119
40202
|
const options3 = { signal: this.signal };
|
|
40120
40203
|
if (redirect.operator === "<") {
|
|
40121
40204
|
await interruptible3(this.fs.access(path, 4, options3), this.signal);
|
|
40122
40205
|
const stat = await interruptible3(this.fs.stat(path, options3), this.signal);
|
|
40123
40206
|
if (stat.type === "directory" && !fileShortcut) throw new PublicDiagnostic(`${target}: Is a directory`);
|
|
40124
|
-
const source2 = stat.type === "directory" ? toByteSource("") : await fileInput(this.fs, path, this.budget.limits.maxInputBytes, this.signal);
|
|
40207
|
+
const source2 = stat.type === "directory" ? toByteSource("") : await fileInput(this.fs, path, this.budget.limits.maxInputBytes, this.signal, this.inputProfile);
|
|
40125
40208
|
const input3 = new ShellInput(source2, this.budget, this.signal);
|
|
40126
40209
|
inputs2.add(input3);
|
|
40127
40210
|
descriptors.set(redirect.descriptor, { input: input3, stdinIsDefault: false });
|
|
@@ -40129,24 +40212,25 @@ var Runtime = class _Runtime {
|
|
|
40129
40212
|
const append = redirect.operator === ">>";
|
|
40130
40213
|
const capabilities = await this.fs.capabilitiesFor?.(path, options3) ?? this.fs.capabilities;
|
|
40131
40214
|
const random = capabilities.randomAccessWrite === true;
|
|
40215
|
+
const key = resolvePath(state.cwd, path);
|
|
40132
40216
|
let file;
|
|
40133
|
-
await this.fileOperation(
|
|
40134
|
-
file = this.outputFiles.get(
|
|
40217
|
+
await this.fileOperation(key, async () => {
|
|
40218
|
+
file = this.outputFiles.get(key) ?? { data: void 0, references: 0 };
|
|
40135
40219
|
if (!random && file.references) throw new FsError("ENOTSUP", { path, message: "Conflicting sequential output descriptors" });
|
|
40136
40220
|
file.references++;
|
|
40137
|
-
this.outputFiles.set(
|
|
40221
|
+
this.outputFiles.set(key, file);
|
|
40138
40222
|
});
|
|
40139
40223
|
let closed = false;
|
|
40140
40224
|
let offset = 0;
|
|
40141
40225
|
const incremental = async () => {
|
|
40142
|
-
await this.fileOperation(
|
|
40226
|
+
await this.fileOperation(key, async () => {
|
|
40143
40227
|
if (append) await this.fs.appendFile(path, new Uint8Array(), options3);
|
|
40144
40228
|
else await this.fs.writeFile(path, new Uint8Array(), { ...options3, flag: "w" });
|
|
40145
40229
|
if (!append) file.data = new Uint8Array();
|
|
40146
40230
|
});
|
|
40147
40231
|
return { write: (chunk) => {
|
|
40148
40232
|
const copy2 = new Uint8Array(chunk);
|
|
40149
|
-
return this.fileOperation(
|
|
40233
|
+
return this.fileOperation(key, async () => {
|
|
40150
40234
|
if (closed) throw new Error("Output descriptor is closed");
|
|
40151
40235
|
const current = file.data;
|
|
40152
40236
|
let atEOF = false;
|
|
@@ -40178,7 +40262,7 @@ var Runtime = class _Runtime {
|
|
|
40178
40262
|
if (closed) return;
|
|
40179
40263
|
closed = true;
|
|
40180
40264
|
resumePathCache();
|
|
40181
|
-
if (--file.references === 0 && this.outputFiles.get(
|
|
40265
|
+
if (--file.references === 0 && this.outputFiles.get(key) === file) this.outputFiles.delete(key);
|
|
40182
40266
|
};
|
|
40183
40267
|
let target2;
|
|
40184
40268
|
let outputScope;
|
|
@@ -40422,7 +40506,8 @@ var Runtime = class _Runtime {
|
|
|
40422
40506
|
this.cancellationOwner,
|
|
40423
40507
|
this.cancellationDepth,
|
|
40424
40508
|
this.cancellationMaxDepth,
|
|
40425
|
-
this.outcomeFrame
|
|
40509
|
+
this.outcomeFrame,
|
|
40510
|
+
this.inputProfile
|
|
40426
40511
|
);
|
|
40427
40512
|
try {
|
|
40428
40513
|
return await runtime.dispatchScoped(name2, values, state, { ...io, [invocationScope]: scope }, assignments2, bypassFunctions);
|
|
@@ -40818,11 +40903,12 @@ ${functionDisplay(name2, state.functions.get(name2))}`;
|
|
|
40818
40903
|
let denied;
|
|
40819
40904
|
const matches3 = [];
|
|
40820
40905
|
for (const target of pathTargets(name2, state.variables.PATH, this.budget.limits, this.signal, (limit) => this.budget.fail(limit))) {
|
|
40821
|
-
const resolved =
|
|
40906
|
+
const resolved = pathOf(state, target);
|
|
40822
40907
|
try {
|
|
40823
40908
|
const options3 = { signal: this.signal };
|
|
40824
40909
|
if (!await interruptible3(this.budget.pathLookup.isFile(this.fs, resolved, this.signal), this.signal)) continue;
|
|
40825
|
-
|
|
40910
|
+
const capabilities = this.fs.capabilitiesFor ? await interruptible3(this.fs.capabilitiesFor(resolved, options3), this.signal) : this.fs.capabilities;
|
|
40911
|
+
if (capabilities.permissions !== true) throw new CommandFailure2(`${target}: execution permissions are not supported by this filesystem`, 126);
|
|
40826
40912
|
await interruptible3(this.fs.access(resolved, ACCESS_MODES.X_OK, options3), this.signal);
|
|
40827
40913
|
matches3.push(target);
|
|
40828
40914
|
if (!all) return matches3;
|
|
@@ -41037,7 +41123,8 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
41037
41123
|
this.cancellationOwner,
|
|
41038
41124
|
this.cancellationDepth,
|
|
41039
41125
|
this.cancellationMaxDepth,
|
|
41040
|
-
this.outcomeFrame
|
|
41126
|
+
this.outcomeFrame,
|
|
41127
|
+
this.inputProfile
|
|
41041
41128
|
);
|
|
41042
41129
|
let input3;
|
|
41043
41130
|
try {
|
|
@@ -41214,7 +41301,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
41214
41301
|
async scriptFile(context2, state, io, target, args, direct, errexit = false, loadedSource, braceexpand = true) {
|
|
41215
41302
|
if (target === "") throw new CommandFailure2(`${context2.command}: : No such file or directory`, 127);
|
|
41216
41303
|
if (state.depth >= this.budget.limits.maxSubstitutionDepth) this.budget.fail("maxSubstitutionDepth");
|
|
41217
|
-
const path =
|
|
41304
|
+
const path = pathOf(state, target);
|
|
41218
41305
|
let source2;
|
|
41219
41306
|
let environmentInterpreter = null;
|
|
41220
41307
|
let interpreterProfile;
|
|
@@ -41224,7 +41311,10 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
41224
41311
|
const options3 = { signal: this.signal };
|
|
41225
41312
|
const stat = await interruptible3(this.fs.stat(path, options3), this.signal);
|
|
41226
41313
|
if (stat.type !== "file") throw new CommandFailure2(`${target}: ${stat.type === "directory" ? "Is a directory" : "not a regular file"}`, 126);
|
|
41227
|
-
if (direct
|
|
41314
|
+
if (direct) {
|
|
41315
|
+
const capabilities = this.fs.capabilitiesFor ? await interruptible3(this.fs.capabilitiesFor(path, options3), this.signal) : this.fs.capabilities;
|
|
41316
|
+
if (capabilities.permissions !== true) throw new CommandFailure2(`${target}: execution permissions are not supported by this filesystem`, 126);
|
|
41317
|
+
}
|
|
41228
41318
|
await interruptible3(this.fs.access(path, ACCESS_MODES.R_OK | (direct ? ACCESS_MODES.X_OK : 0), options3), this.signal);
|
|
41229
41319
|
const maxBytes = this.budget.limits.maxSourceBytes - this.budget.sourceBytes;
|
|
41230
41320
|
if (stat.size > maxBytes) this.budget.fail("maxSourceBytes");
|
|
@@ -41362,7 +41452,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
41362
41452
|
if (filename && !filename.includes("/") && state.variables.PATH) {
|
|
41363
41453
|
let found = false;
|
|
41364
41454
|
for (const candidate of pathTargets(filename, state.variables.PATH, this.budget.limits, this.signal, (limit) => this.budget.fail(limit))) {
|
|
41365
|
-
const path2 =
|
|
41455
|
+
const path2 = pathOf(state, candidate);
|
|
41366
41456
|
try {
|
|
41367
41457
|
if (!await interruptible3(this.budget.pathLookup.isFile(this.fs, path2, this.signal), this.signal)) continue;
|
|
41368
41458
|
await interruptible3(this.fs.access(path2, ACCESS_MODES.R_OK, options3), this.signal);
|
|
@@ -41377,7 +41467,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
41377
41467
|
if (!found && state.profile === "sh") throw new CommandFailure2(`${context2.command}: ${filename}: file not found`, 1);
|
|
41378
41468
|
}
|
|
41379
41469
|
if (!filename) throw new CommandFailure2(": No such file or directory", 1);
|
|
41380
|
-
const path =
|
|
41470
|
+
const path = pathOf(state, target);
|
|
41381
41471
|
const stat = await interruptible3(this.fs.stat(path, options3), this.signal);
|
|
41382
41472
|
if (stat.type === "directory") throw new CommandFailure2(`${context2.command}: ${target}: is a directory`, 1);
|
|
41383
41473
|
if (stat.type !== "file") throw new CommandFailure2(`${target}: not a regular file`, 1);
|
|
@@ -43257,7 +43347,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
43257
43347
|
for (const candidate of candidates) {
|
|
43258
43348
|
let entries3;
|
|
43259
43349
|
try {
|
|
43260
|
-
const pending = this.fs.readdir(
|
|
43350
|
+
const pending = this.fs.readdir(pathOf(state, candidate || "."), { signal: this.signal });
|
|
43261
43351
|
entries3 = arrayStore(state) ? await interruptible3(pending, this.signal) : await pending;
|
|
43262
43352
|
} catch (error) {
|
|
43263
43353
|
if (["ENOENT", "ENOTDIR", "EACCES"].includes(errorCode(error) ?? "")) continue;
|
|
@@ -43278,7 +43368,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
43278
43368
|
const found = [];
|
|
43279
43369
|
for (const candidate of candidates) {
|
|
43280
43370
|
try {
|
|
43281
|
-
const pending = this.fs.stat(
|
|
43371
|
+
const pending = this.fs.stat(pathOf(state, candidate), { signal: this.signal });
|
|
43282
43372
|
const stat = arrayStore(state) ? await interruptible3(pending, this.signal) : await pending;
|
|
43283
43373
|
if (!value2.endsWith("/") || stat.type === "directory") found.push(candidate + (value2.endsWith("/") ? "/" : ""));
|
|
43284
43374
|
} catch (error) {
|
|
@@ -43290,7 +43380,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
43290
43380
|
};
|
|
43291
43381
|
|
|
43292
43382
|
// packages/safe-bash/src/shell/input.ts
|
|
43293
|
-
async function fileInput(fs, path, maxBytes, signal) {
|
|
43383
|
+
async function fileInput(fs, path, maxBytes, signal, inputProfile = fs) {
|
|
43294
43384
|
signal.throwIfAborted();
|
|
43295
43385
|
async function bufferedInput() {
|
|
43296
43386
|
signal.throwIfAborted();
|
|
@@ -43300,7 +43390,13 @@ async function fileInput(fs, path, maxBytes, signal) {
|
|
|
43300
43390
|
return toByteSource(bytes3);
|
|
43301
43391
|
}
|
|
43302
43392
|
const readStream = fs.readStream;
|
|
43303
|
-
|
|
43393
|
+
const capabilities = await interruptible3(Promise.resolve(fs.capabilitiesFor?.(path, { signal }) ?? fs.capabilities), signal);
|
|
43394
|
+
if (!readStream || capabilities.streamingRead === false) {
|
|
43395
|
+
if (!inputProfile.readStream || inputProfile.capabilities.streamingRead === false) return bufferedInput();
|
|
43396
|
+
return { async *[Symbol.asyncIterator]() {
|
|
43397
|
+
yield* await bufferedInput();
|
|
43398
|
+
} };
|
|
43399
|
+
}
|
|
43304
43400
|
let iterator;
|
|
43305
43401
|
try {
|
|
43306
43402
|
iterator = readStream.call(fs, path, { signal })[Symbol.asyncIterator]();
|
|
@@ -43894,8 +43990,9 @@ var Shell = class {
|
|
|
43894
43990
|
profile: "bash"
|
|
43895
43991
|
};
|
|
43896
43992
|
const admission = Runtime.rootCancellationAdmission(budget);
|
|
43993
|
+
const filesystem = options3.fs ?? this.#options.fs;
|
|
43897
43994
|
const runtime = new Runtime(
|
|
43898
|
-
|
|
43995
|
+
createDeviceFileSystem(filesystem),
|
|
43899
43996
|
this.commands,
|
|
43900
43997
|
[...this.#middleware],
|
|
43901
43998
|
budget,
|
|
@@ -43907,7 +44004,9 @@ var Shell = class {
|
|
|
43907
44004
|
cancellationState,
|
|
43908
44005
|
owner,
|
|
43909
44006
|
0,
|
|
43910
|
-
admission.maxDepth
|
|
44007
|
+
admission.maxDepth,
|
|
44008
|
+
void 0,
|
|
44009
|
+
filesystem
|
|
43911
44010
|
);
|
|
43912
44011
|
exitCode = 0;
|
|
43913
44012
|
while (true) {
|
|
@@ -44109,7 +44208,7 @@ init_platform();
|
|
|
44109
44208
|
// packages/safe-js/dist/browser/safe-fs.js
|
|
44110
44209
|
init_platform();
|
|
44111
44210
|
|
|
44112
|
-
// packages/safe-js/dist/browser/chunks/chunk-
|
|
44211
|
+
// packages/safe-js/dist/browser/chunks/chunk-QK4IEGRO.js
|
|
44113
44212
|
init_platform();
|
|
44114
44213
|
var platform = Object.freeze({
|
|
44115
44214
|
errno(_code) {
|
|
@@ -44767,6 +44866,7 @@ var MemoryFileSystem = class _MemoryFileSystem {
|
|
|
44767
44866
|
removeDirectory: true,
|
|
44768
44867
|
recursiveRemove: true,
|
|
44769
44868
|
rename: true,
|
|
44869
|
+
atomicRenameNoReplace: true,
|
|
44770
44870
|
copy: true,
|
|
44771
44871
|
exclusiveCopy: true,
|
|
44772
44872
|
readlink: true,
|
|
@@ -45191,6 +45291,7 @@ var MemoryFileSystem = class _MemoryFileSystem {
|
|
|
45191
45291
|
if (this.terminalDot(source2) || this.terminalDot(destination2)) this.fail("EINVAL", "rename", source2, destination2);
|
|
45192
45292
|
if (node === this.root || target.node === this.root) this.fail("EBUSY", "rename", source2, destination2);
|
|
45193
45293
|
if (destination2.endsWith("/") && node.type !== "directory") this.fail("ENOTDIR", "rename", source2, destination2);
|
|
45294
|
+
if (options3.noReplace && target.node) this.fail("EEXIST", "rename", source2, destination2);
|
|
45194
45295
|
if (target.node === node) return;
|
|
45195
45296
|
if (node.type === "directory" && target.path.startsWith(`${origin.path}/`)) this.fail("EINVAL", "rename", source2, destination2);
|
|
45196
45297
|
this.permission(origin.parent, 3, "rename", source2);
|
|
@@ -45477,6 +45578,39 @@ function stockDescriptorWrite(filesystem) {
|
|
|
45477
45578
|
}
|
|
45478
45579
|
return true;
|
|
45479
45580
|
}
|
|
45581
|
+
var deviceCapabilities = Object.freeze({
|
|
45582
|
+
readOnly: false,
|
|
45583
|
+
read: true,
|
|
45584
|
+
stat: true,
|
|
45585
|
+
realpath: true,
|
|
45586
|
+
access: true,
|
|
45587
|
+
readdir: false,
|
|
45588
|
+
write: true,
|
|
45589
|
+
append: true,
|
|
45590
|
+
exclusiveCreate: true,
|
|
45591
|
+
streamingRead: true,
|
|
45592
|
+
retainedRead: true,
|
|
45593
|
+
streamingWrite: true,
|
|
45594
|
+
streamingAppend: true,
|
|
45595
|
+
copy: true,
|
|
45596
|
+
exclusiveCopy: true,
|
|
45597
|
+
remove: false,
|
|
45598
|
+
removeDirectory: false,
|
|
45599
|
+
recursiveRemove: false,
|
|
45600
|
+
rename: false,
|
|
45601
|
+
mkdir: false,
|
|
45602
|
+
recursiveMkdir: false,
|
|
45603
|
+
symlinks: false,
|
|
45604
|
+
hardlinks: false,
|
|
45605
|
+
readlink: false,
|
|
45606
|
+
permissions: false,
|
|
45607
|
+
timestamps: false,
|
|
45608
|
+
truncate: false,
|
|
45609
|
+
randomAccessWrite: false,
|
|
45610
|
+
atomicRename: false,
|
|
45611
|
+
atomicRenameNoReplace: false,
|
|
45612
|
+
descriptorWriteStream: true
|
|
45613
|
+
});
|
|
45480
45614
|
var syntheticStat = Object.freeze({
|
|
45481
45615
|
type: "directory",
|
|
45482
45616
|
size: 0,
|
|
@@ -45849,6 +45983,7 @@ var WebDavFileSystem = class {
|
|
|
45849
45983
|
remove: true,
|
|
45850
45984
|
recursiveRemove: true,
|
|
45851
45985
|
rename: true,
|
|
45986
|
+
atomicRenameNoReplace: false,
|
|
45852
45987
|
copy: true,
|
|
45853
45988
|
exclusiveCopy: true,
|
|
45854
45989
|
readlink: false,
|
|
@@ -46787,6 +46922,10 @@ var WebDavFileSystem = class {
|
|
|
46787
46922
|
}
|
|
46788
46923
|
}
|
|
46789
46924
|
async rename(source2, destination2, options3 = {}) {
|
|
46925
|
+
if (options3.noReplace) {
|
|
46926
|
+
options3.signal?.throwIfAborted();
|
|
46927
|
+
fail32("ENOTSUP", "rename", source2, "atomic no-replace rename is unsupported");
|
|
46928
|
+
}
|
|
46790
46929
|
await this.transfer("MOVE", source2, destination2, options3);
|
|
46791
46930
|
}
|
|
46792
46931
|
async copyFile(source2, destination2, options3 = {}) {
|
|
@@ -47351,7 +47490,8 @@ function createSafeJsCommands(options3 = {}, dialect = {
|
|
|
47351
47490
|
let filename = parsed.file;
|
|
47352
47491
|
if (source2 === void 0) {
|
|
47353
47492
|
if (!fromStdin) filename = pathOf(context2, parsed.file);
|
|
47354
|
-
const
|
|
47493
|
+
const capabilities = fromStdin ? void 0 : await withSignal(signal, async () => await context2.fs.capabilitiesFor?.(filename, { signal }) ?? context2.fs.capabilities);
|
|
47494
|
+
const bytes3 = fromStdin ? context2.stdin : context2.fs.readStream && capabilities?.streamingRead !== false ? context2.fs.readStream(filename, { signal, chunkSize: 65536 }) : toByteSource(await withSignal(signal, () => context2.fs.readFile(filename, { signal, maxBytes: limits.maxSourceBytes })));
|
|
47355
47495
|
const reader = new GuestInput(bytes3, limits.maxSourceBytes, signal, fail4, "maxSourceBytes");
|
|
47356
47496
|
try {
|
|
47357
47497
|
source2 = await reader.readText();
|