@poe-platform/safe-bash 0.1.801 → 0.1.803
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/image-ast/index.browser.js +16 -5
- package/dist/image-ast/index.js +16 -5
- package/dist/safe-bash/chunks/chunk-2LSAMQER.js +84 -0
- package/dist/safe-bash/chunks/chunk-3HQU4OJO.js +13 -0
- package/dist/safe-bash/chunks/chunk-4BSJLKNM.js +14 -0
- package/dist/safe-bash/chunks/chunk-4D4N7IU2.js +47 -0
- package/dist/safe-bash/chunks/chunk-55YJASTN.js +14 -0
- package/dist/safe-bash/chunks/{chunk-NZQXYWA3.js → chunk-5OHX7C2V.js} +0 -1
- package/dist/safe-bash/chunks/chunk-7ZBU7KYV.js +14 -0
- package/dist/safe-bash/chunks/{chunk-7VNF5BFF.js → chunk-B7PIL77G.js} +101 -415
- package/dist/safe-bash/chunks/chunk-DQP3VHSB.js +15 -0
- package/dist/safe-bash/chunks/{chunk-VQDD3G76.js → chunk-EEEWOYEG.js} +18 -18
- package/dist/safe-bash/chunks/chunk-FZE4HW6G.js +11 -0
- package/dist/safe-bash/chunks/{chunk-45PK3NWI.js → chunk-GDYNCWRV.js} +1 -1
- package/dist/safe-bash/chunks/chunk-GEG3BWGE.js +14 -0
- package/dist/safe-bash/chunks/chunk-HBCN24ZA.js +50 -0
- package/dist/safe-bash/chunks/chunk-HZ7BWKQ3.js +13 -0
- package/dist/safe-bash/chunks/{chunk-ICFDYV64.js → chunk-HZAMGT5I.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-FNDNHAGE.js → chunk-JMMEIDPF.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-IVRQ4BXL.js → chunk-PH63PLPZ.js} +7 -7
- package/dist/safe-bash/chunks/{chunk-SZH7EJLD.js → chunk-PNBBUWSM.js} +5529 -6547
- package/dist/safe-bash/chunks/chunk-QGUV42T5.js +44 -0
- package/dist/safe-bash/chunks/chunk-R3NAKOED.js +51 -0
- package/dist/safe-bash/chunks/chunk-RRR7AQ24.js +38 -0
- package/dist/safe-bash/chunks/{chunk-PQRAK7HU.js → chunk-RYFQ3LZG.js} +281 -476
- package/dist/safe-bash/chunks/chunk-VBTDHOWC.js +55 -0
- package/dist/safe-bash/chunks/{chunk-NR3EM4LS.js → chunk-VKNVHEX3.js} +1 -6
- package/dist/safe-bash/chunks/chunk-XAQMU6OY.js +14 -0
- package/dist/safe-bash/chunks/chunk-ZVD5IS4V.js +49 -0
- package/dist/safe-bash/command-chunks/{chunk-ORYGZYKW.js → chunk-4FEVBOL5.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-VXSLJH7G.js → chunk-6JSIFWYT.js} +26 -6
- package/dist/safe-bash/command-chunks/chunk-A7MU7762.js +200 -0
- package/dist/safe-bash/command-chunks/{chunk-KJIMDLBB.js → chunk-BXCXRYVU.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-F4TEEZTL.js → chunk-CQHP3I66.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-PEF7K3UQ.js → chunk-EARHPPPJ.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-QKFSRZGQ.js → chunk-GFC2NTDG.js} +2 -2
- package/dist/safe-bash/command-chunks/chunk-GIRNFXP3.js +466 -0
- package/dist/safe-bash/command-chunks/{chunk-EFANWIHL.js → chunk-GY3BWK7K.js} +1 -0
- package/dist/safe-bash/command-chunks/{chunk-FPVUD6TH.js → chunk-HDCNKOIX.js} +9 -7
- package/dist/safe-bash/command-chunks/{chunk-MQFIPHIQ.js → chunk-ILX2NOLF.js} +18 -15
- package/dist/safe-bash/command-chunks/{chunk-5E4WAO4O.js → chunk-JD5QNRNO.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-I237SNW5.js → chunk-LFJJQQND.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-W5DNF4JH.js → chunk-LOICUCHG.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-7U7EXOXX.js → chunk-NASVPT6F.js} +2 -1
- package/dist/safe-bash/command-chunks/{chunk-WBNZ4PRE.js → chunk-NGG2XL56.js} +7 -4
- package/dist/safe-bash/command-chunks/{chunk-GLOZX57Y.js → chunk-NKIELG7Y.js} +45 -115
- package/dist/safe-bash/command-chunks/{chunk-WPYIOKE3.js → chunk-PICVQ6B5.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-YOFC45RK.js → chunk-QVOS4YXL.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-VGG2DL5Q.js → chunk-TRR4MYWF.js} +4 -0
- package/dist/safe-bash/command-chunks/{chunk-2JRBIDAD.js → chunk-V4K2JDYU.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-CZ7EN3JG.js → chunk-VT6MJBEI.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-PCEFOYA3.js → chunk-WWIBP2ET.js} +41 -114
- package/dist/safe-bash/command-chunks/{chunk-F6OYH562.js → chunk-X54L3DBL.js} +4 -9
- package/dist/safe-bash/command-chunks/{chunk-TNOA7FCQ.js → chunk-YVNGTIJO.js} +1 -1
- package/dist/safe-bash/command-chunks/chunk-ZDN7MJE6.js +168 -0
- package/dist/safe-bash/commands/apply-patch/index.browser.js +14 -0
- package/dist/safe-bash/commands/archive/index.browser.js +36 -0
- package/dist/safe-bash/commands/bytes/compression/index.js +54 -51
- package/dist/safe-bash/commands/chmod/index.browser.js +14 -0
- package/dist/safe-bash/commands/chmod/index.d.ts +2 -0
- package/dist/safe-bash/commands/chmod/index.js +2 -0
- package/dist/safe-bash/commands/column/index.browser.js +12 -0
- package/dist/safe-bash/commands/du/index.browser.js +14 -0
- package/dist/safe-bash/commands/expr/index.browser.js +12 -0
- package/dist/safe-bash/commands/file/index.browser.js +14 -0
- package/dist/safe-bash/commands/filesystem.js +9 -2
- package/dist/safe-bash/commands/grep-aliases/index.browser.js +14 -0
- package/dist/safe-bash/commands/html-to-markdown/index.browser.js +16 -0
- package/dist/safe-bash/commands/metadata/chmod.d.ts +1 -7
- package/dist/safe-bash/commands/metadata/chmod.js +1 -204
- package/dist/safe-bash/commands/metadata/index.browser.js +17 -0
- package/dist/safe-bash/commands/metadata/internal.d.ts +1 -30
- package/dist/safe-bash/commands/metadata/internal.js +1 -76
- package/dist/safe-bash/commands/metadata/mktemp.d.ts +1 -3
- package/dist/safe-bash/commands/metadata/mktemp.js +1 -202
- package/dist/safe-bash/commands/metadata/stat.d.ts +1 -7
- package/dist/safe-bash/commands/metadata/stat.js +1 -530
- package/dist/safe-bash/commands/mktemp/index.browser.js +13 -0
- package/dist/safe-bash/commands/mktemp/index.d.ts +2 -0
- package/dist/safe-bash/commands/mktemp/index.js +2 -0
- package/dist/safe-bash/commands/network/index.browser.js +1 -1
- package/dist/safe-bash/commands/node/index.browser.js +4 -4
- package/dist/safe-bash/commands/portable-random.d.ts +1 -1
- package/dist/safe-bash/commands/portable-random.js +1 -12
- package/dist/safe-bash/commands/python/index.browser.js +8 -8
- package/dist/safe-bash/commands/regex-execution/public.browser.js +5 -3
- package/dist/safe-bash/commands/split/index.browser.js +14 -0
- package/dist/safe-bash/commands/stat/index.browser.js +13 -0
- package/dist/safe-bash/commands/stat/index.d.ts +2 -0
- package/dist/safe-bash/commands/stat/index.js +2 -0
- package/dist/safe-bash/commands/stream-format/index.browser.js +11 -0
- package/dist/safe-bash/commands/stream-inspection/index.browser.js +11 -0
- package/dist/safe-bash/commands/streams.js +5 -5
- package/dist/safe-bash/commands/table-text/index.browser.js +11 -0
- package/dist/safe-bash/commands/text.js +48 -143
- package/dist/safe-bash/commands/time-env/index.browser.js +15 -0
- package/dist/safe-bash/commands/tree/index.browser.js +14 -0
- package/dist/safe-bash/full-core.browser.js +256 -247
- package/dist/safe-bash/opt-in/commands/yq/native-work.js +1 -0
- package/dist/safe-bash/optional-host.browser.js +12 -12
- package/dist/safe-bash/plugins/index.browser.js +25 -11
- package/dist/safe-bash/registry-entry.browser.js +28 -14
- package/dist/safe-bash/search.browser.js +48 -0
- package/dist/safe-bash/shell/runtime.d.ts +3 -9
- package/dist/safe-bash/shell/runtime.js +63 -311
- package/dist/safe-bash/shell/shell.js +0 -23
- package/dist/safe-bash/shell/types.d.ts +2 -0
- package/dist/safe-bash/shell/worker-limits.js +1 -0
- package/dist/safe-bash/shell-entry.browser.js +19 -10
- package/dist/safe-bash/worker/host.js +1 -1
- package/dist/safe-bash-command-bc/index.js +12 -5
- package/dist/safe-bash-command-bzip2/index.js +4 -3
- package/dist/safe-bash-command-chmod/LICENSE +21 -0
- package/dist/safe-bash-command-chmod/command.d.ts +7 -0
- package/dist/safe-bash-command-chmod/command.js +11 -0
- package/dist/safe-bash-command-chmod/index.d.ts +6 -0
- package/dist/safe-bash-command-chmod/index.js +27 -0
- package/dist/safe-bash-command-exiftool/index.js +5 -5
- package/dist/safe-bash-command-find/find.js +1 -1
- package/dist/safe-bash-command-find/index.js +1 -1
- package/dist/safe-bash-command-fmt/index.js +9 -2
- package/dist/safe-bash-command-gzip/index.js +45 -42
- package/dist/safe-bash-command-imagemagick/index.js +3 -1
- package/dist/safe-bash-command-jq/index.js +1 -1
- package/dist/safe-bash-command-jq/jq.js +1 -1
- package/dist/safe-bash-command-less/index.js +12 -3
- package/dist/safe-bash-command-mktemp/LICENSE +21 -0
- package/dist/safe-bash-command-mktemp/command.d.ts +3 -0
- package/dist/safe-bash-command-mktemp/command.js +9 -0
- package/dist/safe-bash-command-mktemp/index.d.ts +6 -0
- package/dist/safe-bash-command-mktemp/index.js +25 -0
- package/dist/safe-bash-command-nl/index.js +1 -1
- package/dist/safe-bash-command-nl/nl.js +1 -1
- package/dist/safe-bash-command-od/index.js +6 -2
- package/dist/safe-bash-command-op/index.js +25 -6
- package/dist/safe-bash-command-rg/index.js +1 -1
- package/dist/safe-bash-command-rg/rg-command.d.ts +0 -1
- package/dist/safe-bash-command-rg/rg-command.js +3 -5
- package/dist/safe-bash-command-sed/index.js +1 -1
- package/dist/safe-bash-command-sed/sed.js +1 -1
- package/dist/safe-bash-command-sips/index.js +13 -5
- package/dist/safe-bash-command-sponge/index.js +10 -3
- package/dist/safe-bash-command-stat/LICENSE +21 -0
- package/dist/safe-bash-command-stat/command.d.ts +7 -0
- package/dist/safe-bash-command-stat/command.js +9 -0
- package/dist/safe-bash-command-stat/index.d.ts +6 -0
- package/dist/safe-bash-command-stat/index.js +25 -0
- package/dist/safe-bash-command-unexpand/index.js +1 -1
- package/dist/safe-bash-command-unexpand/unexpand.js +1 -1
- package/dist/safe-bash-command-unrtf/index.js +11 -1
- package/dist/safe-bash-command-xxd/index.js +6 -2
- package/dist/safe-bash-command-xz/command.d.ts +1 -1
- package/dist/safe-bash-command-xz/index.js +3 -2
- package/dist/safe-bash-command-yq/index.js +1 -0
- package/dist/safe-bash-command-yq/native-work.js +1 -0
- package/dist/safe-bash-command-yq/query.js +3 -0
- package/dist/safe-bash-compression-engine/bounded-codec.js +3 -3
- package/dist/safe-bash-compression-engine/codec-loader.js +2 -2
- package/dist/safe-bash-compression-engine/files.js +6 -6
- package/dist/safe-bash-compression-engine/index.js +5 -5
- package/dist/safe-bash-compression-engine/operand.js +6 -6
- package/dist/safe-bash-compression-engine/options.js +1 -1
- package/dist/safe-bash-compression-engine/stream.js +5 -5
- package/dist/safe-bash-compression-engine/zstd-decode.js +4 -4
- package/dist/safe-bash-contracts/escaping.js +2 -2
- package/dist/safe-bash-contracts/filesystem-output.js +2 -2
- package/dist/safe-bash-contracts/index.js +2 -2
- package/dist/safe-bash-contracts/io.d.ts +2 -0
- package/dist/safe-bash-contracts/io.js +1 -1
- package/dist/safe-bash-contracts/output.js +2 -2
- package/dist/safe-bash-io-engine/commands/search/requirements.js +1 -1
- package/dist/safe-bash-io-engine/commands/text-programs/shared.js +1 -1
- package/dist/safe-bash-mcp/index.browser.js +11 -1
- package/dist/safe-bash-mcp/index.js +38 -17
- package/dist/safe-bash-metadata-engine/LICENSE +21 -0
- package/dist/safe-bash-metadata-engine/index.d.ts +30 -0
- package/dist/safe-bash-metadata-engine/index.js +82 -0
- package/dist/safe-bash-metadata-engine/random.d.ts +1 -0
- package/dist/safe-bash-metadata-engine/random.js +21 -0
- package/dist/safe-bash-regex-engine/index.js +4 -4
- package/dist/safe-bash-regex-engine/text/budget.d.ts +0 -1
- package/dist/safe-bash-regex-engine/text/budget.js +1 -1
- package/dist/safe-bash-regex-engine/text/regex.js +4 -4
- package/dist/safe-bash-regex-engine/text/replacement-buffer.js +2 -2
- package/dist/safe-bash-regex-engine/text/rust-syntax.js +2 -2
- package/dist/safe-bash-search-engine/ergonomic-regex.js +2 -2
- package/dist/safe-bash-search-engine/glob.js +2 -2
- package/dist/safe-bash-search-engine/grep.js +2 -2
- package/dist/safe-bash-search-engine/matcher.js +2 -2
- package/dist/safe-bash-search-engine/options.d.ts +2 -0
- package/dist/safe-bash-search-engine/options.js +1 -1
- package/dist/safe-bash-search-engine/output.js +1 -1
- package/dist/safe-bash-search-engine/shared.js +2 -2
- package/dist/safe-bash-search-engine/walk.js +3 -3
- package/dist/safe-playwright-cloudflare/browser-snapshot-json.js +2 -2
- package/dist/safe-playwright-cloudflare/browser-snapshot-references.js +1 -1
- package/package.json +91 -10
|
@@ -1,205 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export { modeChange } from "../../../safe-bash-io-engine/commands/mode-change.js";
|
|
3
|
-
import { bindConditionalMutation } from "@poe-platform/safe-fs/core";
|
|
4
|
-
import { creationUmask } from "../../fs/creation-mask.js";
|
|
5
|
-
import { FsError } from "../../contracts/index.js";
|
|
6
|
-
import { codeOf, diagnostic, options, pathOf, requireOperands, syncCommandEvaluators, UsageError, value } from "../internal.js";
|
|
7
|
-
import { gnuInformationSync } from "../gnu-information.js";
|
|
8
|
-
import { MetadataBudget, metadataCommand, permissionString, settings } from "./internal.js";
|
|
9
|
-
export function createChmodCommand(configuration = {}) {
|
|
10
|
-
const configured = settings(configuration);
|
|
11
|
-
const configuredUmask = configuration.umask === undefined ? undefined : configured.umask;
|
|
12
|
-
return metadataCommand("chmod", async (context) => {
|
|
13
|
-
const budget = new MetadataBudget(context, configured.limits);
|
|
14
|
-
const modeOptions = [];
|
|
15
|
-
let ended = false, referenceValue = false;
|
|
16
|
-
const args = context.args.flatMap(argument => {
|
|
17
|
-
if (referenceValue) {
|
|
18
|
-
referenceValue = false;
|
|
19
|
-
return [argument];
|
|
20
|
-
}
|
|
21
|
-
if (argument === "--")
|
|
22
|
-
ended = true;
|
|
23
|
-
if (ended)
|
|
24
|
-
return [argument];
|
|
25
|
-
if (argument === "--reference")
|
|
26
|
-
referenceValue = true;
|
|
27
|
-
if (argument.startsWith("-") && argument.length > 1 && "rwxXstugo01234567".includes(argument[1])) {
|
|
28
|
-
modeOptions.push(argument);
|
|
29
|
-
return [];
|
|
30
|
-
}
|
|
31
|
-
return [argument];
|
|
32
|
-
});
|
|
33
|
-
const parsed = options(args, "Rvcf", { recursive: "R", verbose: "v", changes: "c", silent: "f", quiet: "f", reference: "reference:" });
|
|
34
|
-
const reference = value(parsed, "reference");
|
|
35
|
-
if (reference !== undefined && modeOptions.length)
|
|
36
|
-
throw new UsageError("cannot combine mode and --reference options");
|
|
37
|
-
requireOperands(parsed.operands, reference === undefined && !modeOptions.length ? 2 : 1);
|
|
38
|
-
const mode = modeOptions.length ? modeOptions.join(",") : reference === undefined ? parsed.operands.shift() : undefined;
|
|
39
|
-
const mask = configuredUmask ?? Reflect.get(context.fs, creationUmask);
|
|
40
|
-
const activeUmask = typeof mask === "number" ? mask : configured.umask;
|
|
41
|
-
const change = mode === undefined ? undefined : modeChange(mode, activeUmask);
|
|
42
|
-
const paths = parsed.operands;
|
|
43
|
-
if (context.fs.capabilities.readOnly)
|
|
44
|
-
throw new FsError("EROFS", { syscall: "chmod" });
|
|
45
|
-
if (!context.fs.chmod || context.fs.capabilities.permissions === false)
|
|
46
|
-
throw new FsError("ENOTSUP", { syscall: "chmod" });
|
|
47
|
-
const referenceMode = reference === undefined ? undefined : (await context.fs.stat(pathOf(context, reference), { signal: context.signal })).mode & 0o7777;
|
|
48
|
-
let exitCode = 0;
|
|
49
|
-
const visit = async (path, display, depth, top) => {
|
|
50
|
-
await budget.step(depth);
|
|
51
|
-
const link = await context.fs.lstat(path, { signal: context.signal });
|
|
52
|
-
if (link.type === "symlink" && !top)
|
|
53
|
-
return;
|
|
54
|
-
const target = link.type === "symlink" ? await context.fs.realpath(path, { signal: context.signal }) : path;
|
|
55
|
-
const stat = link.type === "symlink" ? await context.fs.stat(target, { signal: context.signal }) : link;
|
|
56
|
-
const mode = referenceMode ?? change(stat);
|
|
57
|
-
if (parsed.flags.has("R") && stat.type === "directory" && await context.fs.realpath(target, { signal: context.signal }) === "/")
|
|
58
|
-
throw new FsError("EBUSY", { syscall: "chmod", path, message: "refusing recursive mode changes at virtual root" });
|
|
59
|
-
const canonicalTarget = await context.fs.realpath(target, { signal: context.signal });
|
|
60
|
-
const apply = async () => {
|
|
61
|
-
context.signal.throwIfAborted();
|
|
62
|
-
const currentCanonical = await context.fs.realpath(target, { signal: context.signal });
|
|
63
|
-
if (currentCanonical !== canonicalTarget)
|
|
64
|
-
throw new FsError("EIO", { syscall: "chmod", path, message: "path changed during permission update" });
|
|
65
|
-
const fresh = await context.fs.lstat(canonicalTarget, { signal: context.signal });
|
|
66
|
-
if (fresh.type === "symlink" || fresh.type !== stat.type || stat.ino !== undefined && fresh.ino !== stat.ino || stat.dev !== undefined && fresh.dev !== stat.dev)
|
|
67
|
-
throw new FsError("EIO", { syscall: "chmod", path, message: "path changed during permission update" });
|
|
68
|
-
const capabilities = await context.fs.capabilitiesFor?.(canonicalTarget, { signal: context.signal, conditionalChmod: true }) ?? context.fs.capabilities;
|
|
69
|
-
context.signal.throwIfAborted();
|
|
70
|
-
if (capabilities.conditionalChmod !== true)
|
|
71
|
-
throw new FsError("ENOTSUP", { syscall: "chmod", path, message: "conditional permission updates are not supported" });
|
|
72
|
-
const parentPath = canonicalTarget.slice(0, canonicalTarget.lastIndexOf("/")) || "/";
|
|
73
|
-
const ancestorPaths = ["/"];
|
|
74
|
-
if (parentPath !== "/") {
|
|
75
|
-
let prefix = "";
|
|
76
|
-
for (const part of parentPath.split("/").filter(Boolean)) {
|
|
77
|
-
prefix += `/${part}`;
|
|
78
|
-
ancestorPaths.push(prefix);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
const ancestors = await Promise.all(ancestorPaths.map(async (entryPath) => ({
|
|
82
|
-
path: entryPath,
|
|
83
|
-
stat: await context.fs.lstat(entryPath, { signal: context.signal }),
|
|
84
|
-
})));
|
|
85
|
-
const parentStat = ancestors.at(-1).stat;
|
|
86
|
-
const mutation = { signal: context.signal, parent: parentStat, expected: fresh, ancestors };
|
|
87
|
-
await bindConditionalMutation(fresh.identityScope, { path: canonicalTarget, parent: parentStat, expected: fresh, ancestors }, () => context.fs.chmod(canonicalTarget, mode, mutation));
|
|
88
|
-
if (parsed.flags.has("v") || parsed.flags.has("c") && mode !== (stat.mode & 0o7777)) {
|
|
89
|
-
await budget.output(`mode of '${display}' ${mode === (stat.mode & 0o7777) ? "retained as" : "changed from " + (stat.mode & 0o7777).toString(8).padStart(4, "0") + " (" + permissionString(stat.mode, stat.type).slice(1) + ") to"} ${mode.toString(8).padStart(4, "0")} (${permissionString(mode, stat.type).slice(1)})\n`);
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
const deferred = stat.type === "directory" && parsed.flags.has("R") && (stat.mode & 0o777 & ~mode) !== 0;
|
|
93
|
-
if (!deferred)
|
|
94
|
-
await apply();
|
|
95
|
-
if (stat.type === "directory" && parsed.flags.has("R")) {
|
|
96
|
-
const entries = await context.fs.readdir(target, { signal: context.signal,
|
|
97
|
-
...(Number.isFinite(budget.remainingEntries) ? { maxEntries: budget.remainingEntries } : {}) });
|
|
98
|
-
if (entries.length > budget.remainingEntries)
|
|
99
|
-
throw new FsError("EFBIG", { message: "metadata traversal limit exceeded" });
|
|
100
|
-
for (const entry of entries) {
|
|
101
|
-
if (!entry.name || entry.name === "." || entry.name === ".." || entry.name.includes("/") || entry.name.includes("\0"))
|
|
102
|
-
throw new FsError("EIO", { message: "invalid directory entry" });
|
|
103
|
-
try {
|
|
104
|
-
await visit(`${target.replace(/\/$/u, "")}/${entry.name}`, `${display.replace(/\/$/u, "")}/${entry.name}`, depth + 1, false);
|
|
105
|
-
}
|
|
106
|
-
catch (error) {
|
|
107
|
-
context.signal.throwIfAborted();
|
|
108
|
-
if (codeOf(error) === "EFBIG")
|
|
109
|
-
throw error;
|
|
110
|
-
exitCode = 1;
|
|
111
|
-
if (!parsed.flags.has("f"))
|
|
112
|
-
await diagnostic(context, error);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
if (deferred)
|
|
117
|
-
await apply();
|
|
118
|
-
};
|
|
119
|
-
for (const operand of paths) {
|
|
120
|
-
try {
|
|
121
|
-
await visit(pathOf(context, operand), operand, 0, true);
|
|
122
|
-
}
|
|
123
|
-
catch (error) {
|
|
124
|
-
context.signal.throwIfAborted();
|
|
125
|
-
if (codeOf(error) === "EFBIG")
|
|
126
|
-
throw error;
|
|
127
|
-
exitCode = 1;
|
|
128
|
-
if (!parsed.flags.has("f"))
|
|
129
|
-
await diagnostic(context, error);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return { exitCode };
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
export function evalSyncChmod(opArgs, umask, chmodNodeSync) {
|
|
136
|
-
const gnuInfo = gnuInformationSync("chmod", opArgs);
|
|
137
|
-
if (gnuInfo !== undefined)
|
|
138
|
-
return gnuInfo;
|
|
139
|
-
if (!chmodNodeSync)
|
|
140
|
-
return undefined;
|
|
141
|
-
try {
|
|
142
|
-
const modeOptions = [];
|
|
143
|
-
let ended = false;
|
|
144
|
-
let referenceValue = false;
|
|
145
|
-
const args = [];
|
|
146
|
-
for (const argument of opArgs) {
|
|
147
|
-
if (referenceValue) {
|
|
148
|
-
referenceValue = false;
|
|
149
|
-
args.push(argument);
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
if (argument === "--") {
|
|
153
|
-
ended = true;
|
|
154
|
-
args.push(argument);
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
if (!ended && argument === "--reference") {
|
|
158
|
-
referenceValue = true;
|
|
159
|
-
args.push(argument);
|
|
160
|
-
continue;
|
|
161
|
-
}
|
|
162
|
-
if (!ended && argument.startsWith("-") && argument.length > 1 && "rwxXstugo01234567".includes(argument[1])) {
|
|
163
|
-
modeOptions.push(argument);
|
|
164
|
-
continue;
|
|
165
|
-
}
|
|
166
|
-
args.push(argument);
|
|
167
|
-
}
|
|
168
|
-
const parsed = options(args, "vcf", { verbose: "v", changes: "c", silent: "f", quiet: "f", reference: "reference:" });
|
|
169
|
-
const reference = value(parsed, "reference");
|
|
170
|
-
if (reference !== undefined && modeOptions.length)
|
|
171
|
-
return undefined;
|
|
172
|
-
const minOps = reference !== undefined || modeOptions.length ? 1 : 2;
|
|
173
|
-
if (parsed.operands.length < minOps)
|
|
174
|
-
return undefined;
|
|
175
|
-
let referenceMode;
|
|
176
|
-
if (reference !== undefined) {
|
|
177
|
-
if (!chmodNodeSync(reference, stat => { referenceMode = stat.mode & 0o7777; return stat.mode; }) || referenceMode === undefined) {
|
|
178
|
-
return undefined;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
const mode = modeOptions.length ? modeOptions.join(",") : reference === undefined ? parsed.operands.shift() : undefined;
|
|
182
|
-
const change = mode === undefined ? undefined : modeChange(mode, umask);
|
|
183
|
-
let out = "";
|
|
184
|
-
for (const op of parsed.operands) {
|
|
185
|
-
let line = "";
|
|
186
|
-
const ok = chmodNodeSync(op, stat => {
|
|
187
|
-
const oldMode = stat.mode & 0o7777;
|
|
188
|
-
const nextMode = (referenceMode ?? change(stat)) & 0o7777;
|
|
189
|
-
if (parsed.flags.has("v") || (parsed.flags.has("c") && nextMode !== oldMode)) {
|
|
190
|
-
line = `mode of '${op}' ${nextMode === oldMode ? "retained as" : "changed from " + oldMode.toString(8).padStart(4, "0") + " (" + permissionString(oldMode, stat.type).slice(1) + ") to"} ${nextMode.toString(8).padStart(4, "0")} (${permissionString(nextMode, stat.type).slice(1)})\n`;
|
|
191
|
-
}
|
|
192
|
-
return nextMode;
|
|
193
|
-
});
|
|
194
|
-
if (!ok)
|
|
195
|
-
return undefined;
|
|
196
|
-
out += line;
|
|
197
|
-
}
|
|
198
|
-
return out;
|
|
199
|
-
}
|
|
200
|
-
catch {
|
|
201
|
-
return undefined;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
syncCommandEvaluators.evalSyncChmod = evalSyncChmod;
|
|
1
|
+
export * from "../../../safe-bash-command-chmod/command.js";
|
|
205
2
|
//# sourceMappingURL=chmod.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createMetadataCommands,
|
|
3
|
+
evalSyncMktemp,
|
|
4
|
+
evalSyncStat,
|
|
5
|
+
evalSyncTruncate,
|
|
6
|
+
metadataCommands
|
|
7
|
+
} from "../../chunks/chunk-VBTDHOWC.js";
|
|
8
|
+
import "../../chunks/chunk-E7OYNDGL.js";
|
|
9
|
+
import "../../chunks/chunk-IWDICZVK.js";
|
|
10
|
+
import "../../chunks/chunk-B7TAL7S5.js";
|
|
11
|
+
export {
|
|
12
|
+
createMetadataCommands,
|
|
13
|
+
evalSyncMktemp,
|
|
14
|
+
evalSyncStat,
|
|
15
|
+
evalSyncTruncate,
|
|
16
|
+
metadataCommands
|
|
17
|
+
};
|
|
@@ -1,31 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export interface MetadataLimits {
|
|
3
|
-
readonly maxEntries: number;
|
|
4
|
-
readonly maxDepth: number;
|
|
5
|
-
readonly maxOutputBytes: number;
|
|
6
|
-
readonly maxArgumentBytes: number;
|
|
7
|
-
readonly maxAttempts: number;
|
|
8
|
-
readonly maxArguments?: number;
|
|
9
|
-
}
|
|
10
|
-
export interface MetadataCommandsOptions {
|
|
11
|
-
readonly replace?: boolean;
|
|
12
|
-
readonly umask?: number;
|
|
13
|
-
readonly limits?: Partial<MetadataLimits>;
|
|
14
|
-
}
|
|
15
|
-
export declare function settings(options?: MetadataCommandsOptions): {
|
|
16
|
-
limits: MetadataLimits;
|
|
17
|
-
umask: number;
|
|
18
|
-
};
|
|
19
|
-
export declare class MetadataBudget {
|
|
20
|
-
readonly context: CommandContext;
|
|
21
|
-
readonly limits: MetadataLimits;
|
|
22
|
-
private entries;
|
|
23
|
-
private outputBytes;
|
|
24
|
-
get remainingEntries(): number;
|
|
25
|
-
constructor(context: CommandContext, limits: MetadataLimits);
|
|
26
|
-
step(depth?: number): Promise<void>;
|
|
27
|
-
output(text: string | Uint8Array): Promise<void>;
|
|
28
|
-
}
|
|
29
|
-
export declare function metadataCommand(name: string, handler: CommandHandler): CommandDefinition;
|
|
30
|
-
export declare function permissionString(mode: number, type: FileType): string;
|
|
1
|
+
export * from "../../../safe-bash-metadata-engine/index.js";
|
|
31
2
|
//# sourceMappingURL=internal.d.ts.map
|
|
@@ -1,77 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { yieldTurn } from "../../contracts/yield.js";
|
|
3
|
-
import { FsError, writeBytes } from "../../contracts/index.js";
|
|
4
|
-
import { diagnostic } from "../internal.js";
|
|
5
|
-
import { gnuInformation } from "../gnu-information.js";
|
|
6
|
-
export function settings(options = {}) {
|
|
7
|
-
const limits = { maxEntries: Infinity, maxDepth: Infinity, maxOutputBytes: Infinity, maxArgumentBytes: Infinity, maxAttempts: Infinity, maxArguments: Infinity, ...options.limits };
|
|
8
|
-
for (const [key, value] of Object.entries(limits)) {
|
|
9
|
-
if (value !== Infinity && (!Number.isSafeInteger(value) || value < (key === "maxDepth" ? 0 : 1)))
|
|
10
|
-
throw new RangeError(`Invalid metadata limit: ${key}`);
|
|
11
|
-
}
|
|
12
|
-
const umask = options.umask ?? 0o022;
|
|
13
|
-
if (!Number.isInteger(umask) || umask < 0 || umask > 0o777)
|
|
14
|
-
throw new RangeError("Invalid metadata umask");
|
|
15
|
-
return { limits, umask };
|
|
16
|
-
}
|
|
17
|
-
export class MetadataBudget {
|
|
18
|
-
context;
|
|
19
|
-
limits;
|
|
20
|
-
entries = 0;
|
|
21
|
-
outputBytes = 0;
|
|
22
|
-
get remainingEntries() { return this.limits.maxEntries - this.entries; }
|
|
23
|
-
constructor(context, limits) {
|
|
24
|
-
this.context = context;
|
|
25
|
-
this.limits = limits;
|
|
26
|
-
if (context.args.reduce((size, argument) => size + byteLength(argument), 0) > limits.maxArgumentBytes)
|
|
27
|
-
throw new FsError("EFBIG", { message: "metadata argument limit exceeded" });
|
|
28
|
-
}
|
|
29
|
-
async step(depth = 0) {
|
|
30
|
-
this.context.signal.throwIfAborted();
|
|
31
|
-
if (++this.entries > this.limits.maxEntries || depth > this.limits.maxDepth)
|
|
32
|
-
throw new FsError("EFBIG", { message: "metadata traversal limit exceeded" });
|
|
33
|
-
if (this.entries % 128 === 0)
|
|
34
|
-
await yieldTurn();
|
|
35
|
-
this.context.signal.throwIfAborted();
|
|
36
|
-
}
|
|
37
|
-
async output(text) {
|
|
38
|
-
const bytes = typeof text === "string" ? new TextEncoder().encode(text) : text;
|
|
39
|
-
if (bytes.byteLength > this.limits.maxOutputBytes - this.outputBytes)
|
|
40
|
-
throw new FsError("EFBIG", { message: "metadata output limit exceeded" });
|
|
41
|
-
this.outputBytes += bytes.byteLength;
|
|
42
|
-
await writeBytes(this.context.stdout, bytes, this.context.signal);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
export function metadataCommand(name, handler) {
|
|
46
|
-
return { name, async execute(context) {
|
|
47
|
-
context.signal.throwIfAborted();
|
|
48
|
-
try {
|
|
49
|
-
const infoPromise = gnuInformation(name, context);
|
|
50
|
-
if (infoPromise) {
|
|
51
|
-
const info = await infoPromise;
|
|
52
|
-
if (info)
|
|
53
|
-
return info;
|
|
54
|
-
}
|
|
55
|
-
return await handler(context);
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
context.signal.throwIfAborted();
|
|
59
|
-
await diagnostic(context, error);
|
|
60
|
-
return { exitCode: 1 };
|
|
61
|
-
}
|
|
62
|
-
} };
|
|
63
|
-
}
|
|
64
|
-
export function permissionString(mode, type) {
|
|
65
|
-
let text = type === "directory" ? "d" : type === "symlink" ? "l" : type === "character" ? "c" : "-";
|
|
66
|
-
for (const [read, write, execute, special, lower, upper] of [
|
|
67
|
-
[0o400, 0o200, 0o100, 0o4000, "s", "S"],
|
|
68
|
-
[0o040, 0o020, 0o010, 0o2000, "s", "S"],
|
|
69
|
-
[0o004, 0o002, 0o001, 0o1000, "t", "T"],
|
|
70
|
-
]) {
|
|
71
|
-
text += mode & read ? "r" : "-";
|
|
72
|
-
text += mode & write ? "w" : "-";
|
|
73
|
-
text += mode & special ? (mode & execute ? lower : upper) : mode & execute ? "x" : "-";
|
|
74
|
-
}
|
|
75
|
-
return text;
|
|
76
|
-
}
|
|
1
|
+
export * from "../../../safe-bash-metadata-engine/index.js";
|
|
77
2
|
//# sourceMappingURL=internal.js.map
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export declare function evalSyncMktemp(opArgs: readonly string[], env: Readonly<Record<string, string>>, statTypeSync?: (filePath: string) => string | undefined, writeFileSync?: (filePath: string, bytes: Uint8Array) => boolean, mkdirSync?: (filePath: string) => boolean): string | undefined;
|
|
3
|
-
export declare function createMktempCommand(configuration?: MetadataCommandsOptions): import("../../../safe-bash-contracts/command.js").CommandDefinition;
|
|
1
|
+
export * from "../../../safe-bash-command-mktemp/command.js";
|
|
4
2
|
//# sourceMappingURL=mktemp.d.ts.map
|
|
@@ -1,203 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { creationUmask } from "../../fs/creation-mask.js";
|
|
3
|
-
import { randomInteger } from "../portable-random.js";
|
|
4
|
-
import { FsError, validatePath } from "../../contracts/index.js";
|
|
5
|
-
import { codeOf, diagnostic, pathOf, syncCommandEvaluators, UsageError } from "../internal.js";
|
|
6
|
-
import { gnuInformationSync } from "../gnu-information.js";
|
|
7
|
-
import { MetadataBudget, metadataCommand, settings } from "./internal.js";
|
|
8
|
-
function parse(args) {
|
|
9
|
-
let directory = false;
|
|
10
|
-
let dryRun = false;
|
|
11
|
-
let quiet = false;
|
|
12
|
-
let useTmpdir = false;
|
|
13
|
-
let deprecatedTmpdir = false;
|
|
14
|
-
let tmpdir;
|
|
15
|
-
let suffix;
|
|
16
|
-
let literal = false;
|
|
17
|
-
const operands = [];
|
|
18
|
-
for (let index = 0; index < args.length; index++) {
|
|
19
|
-
const argument = args[index];
|
|
20
|
-
if (literal || argument === "-" || !argument.startsWith("-"))
|
|
21
|
-
operands.push(argument);
|
|
22
|
-
else if (argument === "--")
|
|
23
|
-
literal = true;
|
|
24
|
-
else if (argument === "--directory")
|
|
25
|
-
directory = true;
|
|
26
|
-
else if (argument === "--dry-run")
|
|
27
|
-
dryRun = true;
|
|
28
|
-
else if (argument === "--quiet")
|
|
29
|
-
quiet = true;
|
|
30
|
-
else if (argument === "--tmpdir" || argument.startsWith("--tmpdir=")) {
|
|
31
|
-
useTmpdir = true;
|
|
32
|
-
tmpdir = argument.includes("=") ? argument.slice(argument.indexOf("=") + 1) : "";
|
|
33
|
-
}
|
|
34
|
-
else if (argument === "--suffix" || argument.startsWith("--suffix=")) {
|
|
35
|
-
suffix = argument.includes("=") ? argument.slice(argument.indexOf("=") + 1) : args[++index];
|
|
36
|
-
if (suffix === undefined)
|
|
37
|
-
throw new UsageError("--suffix requires an argument");
|
|
38
|
-
}
|
|
39
|
-
else if (!argument.startsWith("--")) {
|
|
40
|
-
for (let offset = 1; offset < argument.length; offset++) {
|
|
41
|
-
const option = argument[offset];
|
|
42
|
-
if (option === "d")
|
|
43
|
-
directory = true;
|
|
44
|
-
else if (option === "u")
|
|
45
|
-
dryRun = true;
|
|
46
|
-
else if (option === "q")
|
|
47
|
-
quiet = true;
|
|
48
|
-
else if (option === "t") {
|
|
49
|
-
useTmpdir = true;
|
|
50
|
-
deprecatedTmpdir = true;
|
|
51
|
-
}
|
|
52
|
-
else if (option === "p") {
|
|
53
|
-
tmpdir = argument.slice(offset + 1) || args[++index];
|
|
54
|
-
if (tmpdir === undefined)
|
|
55
|
-
throw new UsageError("-p requires an argument");
|
|
56
|
-
useTmpdir = true;
|
|
57
|
-
break;
|
|
58
|
-
}
|
|
59
|
-
else
|
|
60
|
-
throw new UsageError(`unrecognized option '${argument}'`);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
else
|
|
64
|
-
throw new UsageError(`unrecognized option '${argument}'`);
|
|
65
|
-
}
|
|
66
|
-
if (operands.length > 1)
|
|
67
|
-
throw new UsageError("too many templates");
|
|
68
|
-
const template = operands[0] ?? "tmp.XXXXXXXXXX";
|
|
69
|
-
if (operands.length === 0)
|
|
70
|
-
useTmpdir = true;
|
|
71
|
-
validatePath(template);
|
|
72
|
-
if (deprecatedTmpdir && template.includes("/"))
|
|
73
|
-
throw new UsageError("template contains directory separator");
|
|
74
|
-
validatePath(suffix ?? "");
|
|
75
|
-
if (suffix?.includes("/") || suffix !== undefined && !template.endsWith("X"))
|
|
76
|
-
throw new UsageError("suffix requires a template ending in X and cannot contain '/'");
|
|
77
|
-
const name = template.slice(template.lastIndexOf("/") + 1);
|
|
78
|
-
if (name.length + (suffix?.length ?? 0) > 255 || mktempEncoder.encode(name).byteLength + mktempEncoder.encode(suffix ?? "").byteLength > 255)
|
|
79
|
-
throw new FsError("ENAMETOOLONG", { path: template });
|
|
80
|
-
const end = name.lastIndexOf("X") + 1;
|
|
81
|
-
let start = end;
|
|
82
|
-
while (start > 0 && name[start - 1] === "X")
|
|
83
|
-
start--;
|
|
84
|
-
if (end - start < 3)
|
|
85
|
-
throw new UsageError("template must contain at least three consecutive X characters in its last component");
|
|
86
|
-
if (useTmpdir && template.startsWith("/"))
|
|
87
|
-
throw new UsageError("template must be relative with --tmpdir/-p");
|
|
88
|
-
const tail = suffix ?? name.slice(end);
|
|
89
|
-
return { directory, dryRun, quiet, useTmpdir, deprecatedTmpdir, tmpdir, template, prefix: template.slice(0, template.length - name.length + start), count: end - start, tail };
|
|
90
|
-
}
|
|
91
|
-
const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
92
|
-
function sampleTemplateChars(count) {
|
|
93
|
-
let out = "";
|
|
94
|
-
for (let index = 0; index < count; index++)
|
|
95
|
-
out += alphabet[randomInteger(alphabet.length)];
|
|
96
|
-
return out;
|
|
97
|
-
}
|
|
98
|
-
export function evalSyncMktemp(opArgs, env, statTypeSync, writeFileSync, mkdirSync) {
|
|
99
|
-
const gnuInfo = gnuInformationSync("mktemp", opArgs);
|
|
100
|
-
if (gnuInfo !== undefined)
|
|
101
|
-
return gnuInfo;
|
|
102
|
-
try {
|
|
103
|
-
const parsed = parse(opArgs);
|
|
104
|
-
const parent = (parsed.deprecatedTmpdir && env.TMPDIR) || parsed.tmpdir || env.TMPDIR || "/tmp";
|
|
105
|
-
validatePath(parent);
|
|
106
|
-
if (!statTypeSync)
|
|
107
|
-
return undefined;
|
|
108
|
-
if (parsed.useTmpdir && !parsed.dryRun && statTypeSync(parent || ".") !== "directory")
|
|
109
|
-
return undefined;
|
|
110
|
-
for (let attempt = 0; attempt < 32; attempt++) {
|
|
111
|
-
const random = sampleTemplateChars(parsed.count);
|
|
112
|
-
const generated = `${parsed.prefix}${random}${parsed.tail}`;
|
|
113
|
-
const display = parsed.useTmpdir ? `${parent.replace(/\/+$/u, "")}/${generated}` : generated;
|
|
114
|
-
const st = statTypeSync(display);
|
|
115
|
-
if (st !== "missing")
|
|
116
|
-
continue;
|
|
117
|
-
if (!parsed.dryRun) {
|
|
118
|
-
if (parsed.directory) {
|
|
119
|
-
if (!mkdirSync || !mkdirSync(display))
|
|
120
|
-
return undefined;
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
if (!writeFileSync || !writeFileSync(display, new Uint8Array(0)))
|
|
124
|
-
return undefined;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return `${display}\n`;
|
|
128
|
-
}
|
|
129
|
-
return undefined;
|
|
130
|
-
}
|
|
131
|
-
catch {
|
|
132
|
-
return undefined;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
syncCommandEvaluators.evalSyncMktemp = evalSyncMktemp;
|
|
136
|
-
export function createMktempCommand(configuration = {}) {
|
|
137
|
-
const configured = settings(configuration);
|
|
138
|
-
const configuredUmask = configuration.umask === undefined ? undefined : configured.umask;
|
|
139
|
-
return metadataCommand("mktemp", async (context) => {
|
|
140
|
-
const budget = new MetadataBudget(context, configured.limits);
|
|
141
|
-
const parsed = parse(context.args);
|
|
142
|
-
const parent = (parsed.deprecatedTmpdir && context.env.TMPDIR) || parsed.tmpdir || context.env.TMPDIR || "/tmp";
|
|
143
|
-
validatePath(parent);
|
|
144
|
-
try {
|
|
145
|
-
if (!parsed.dryRun) {
|
|
146
|
-
if (context.fs.capabilities.readOnly)
|
|
147
|
-
throw new FsError("EROFS", { syscall: "mktemp" });
|
|
148
|
-
}
|
|
149
|
-
for (let attempt = 0; attempt < configured.limits.maxAttempts; attempt++) {
|
|
150
|
-
await budget.step();
|
|
151
|
-
const random = sampleTemplateChars(parsed.count);
|
|
152
|
-
const generated = `${parsed.prefix}${random}${parsed.tail}`;
|
|
153
|
-
const display = parsed.useTmpdir ? `${parent.replace(/\/+$/u, "")}/${generated}` : generated;
|
|
154
|
-
const path = pathOf(context, display);
|
|
155
|
-
if (mktempEncoder.encode(display).byteLength + 1 > configured.limits.maxOutputBytes)
|
|
156
|
-
throw new FsError("EFBIG", { message: "temporary pathname output exceeds limit" });
|
|
157
|
-
if (parsed.dryRun) {
|
|
158
|
-
try {
|
|
159
|
-
await context.fs.lstat(path, { signal: context.signal });
|
|
160
|
-
continue;
|
|
161
|
-
}
|
|
162
|
-
catch (error) {
|
|
163
|
-
context.signal.throwIfAborted();
|
|
164
|
-
if (codeOf(error) !== "ENOENT")
|
|
165
|
-
throw error;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
const capabilities = await context.fs.capabilitiesFor?.(path, { signal: context.signal }) ?? context.fs.capabilities;
|
|
170
|
-
if (capabilities.readOnly === true)
|
|
171
|
-
throw new FsError("EROFS", { syscall: "mktemp" });
|
|
172
|
-
if (capabilities.permissions !== true)
|
|
173
|
-
throw new FsError("ENOTSUP", { syscall: "mktemp", message: "private temporary creation requires declared permission support" });
|
|
174
|
-
try {
|
|
175
|
-
const mask = configuredUmask ?? Reflect.get(context.fs, creationUmask);
|
|
176
|
-
const activeUmask = typeof mask === "number" ? mask : configured.umask;
|
|
177
|
-
const mode = (parsed.directory ? 0o700 : 0o600) & ~activeUmask;
|
|
178
|
-
if (parsed.directory)
|
|
179
|
-
await context.fs.mkdir(path, { mode, recursive: false, signal: context.signal });
|
|
180
|
-
else
|
|
181
|
-
await context.fs.writeFile(path, new Uint8Array(), { mode, flag: "wx", signal: context.signal });
|
|
182
|
-
}
|
|
183
|
-
catch (error) {
|
|
184
|
-
context.signal.throwIfAborted();
|
|
185
|
-
if (codeOf(error) !== "EEXIST")
|
|
186
|
-
throw error;
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
await budget.output(`${display}\n`);
|
|
191
|
-
return { exitCode: 0 };
|
|
192
|
-
}
|
|
193
|
-
throw new FsError("EEXIST", { syscall: "mktemp", message: "temporary name collision limit exceeded" });
|
|
194
|
-
}
|
|
195
|
-
catch (error) {
|
|
196
|
-
context.signal.throwIfAborted();
|
|
197
|
-
if (!parsed.quiet)
|
|
198
|
-
await diagnostic(context, error);
|
|
199
|
-
return { exitCode: 1 };
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
}
|
|
1
|
+
export * from "../../../safe-bash-command-mktemp/command.js";
|
|
203
2
|
//# sourceMappingURL=mktemp.js.map
|
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { type MetadataCommandsOptions } from "./internal.js";
|
|
3
|
-
export declare function createStatCommand(configuration?: MetadataCommandsOptions): import("../../../safe-bash-contracts/command.js").CommandDefinition;
|
|
4
|
-
export interface SyncStatInfo extends FileStat {
|
|
5
|
-
readonly target?: string;
|
|
6
|
-
}
|
|
7
|
-
export declare function evalSyncStat(args: readonly string[], cwd: string, quotingStyle: string | undefined, inspectStat: (absPath: string, follow: boolean) => SyncStatInfo | undefined): string | undefined;
|
|
1
|
+
export * from "../../../safe-bash-command-stat/command.js";
|
|
8
2
|
//# sourceMappingURL=stat.d.ts.map
|