typescript-virtual-container 1.2.9 → 1.3.1
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/.vscode/settings.json +0 -1
- package/README.md +141 -50
- package/biome.json +7 -0
- package/dist/SSHMimic/exec.d.ts.map +1 -1
- package/dist/SSHMimic/executor.d.ts.map +1 -1
- package/dist/SSHMimic/executor.js +32 -16
- package/dist/SSHMimic/index.d.ts.map +1 -1
- package/dist/SSHMimic/index.js +20 -6
- package/dist/VirtualFileSystem/binaryPack.d.ts.map +1 -1
- package/dist/VirtualFileSystem/binaryPack.js +29 -6
- package/dist/VirtualFileSystem/index.d.ts.map +1 -1
- package/dist/VirtualFileSystem/index.js +36 -13
- package/dist/VirtualPackageManager/index.d.ts.map +1 -1
- package/dist/VirtualPackageManager/index.js +192 -43
- package/dist/VirtualShell/index.d.ts +10 -4
- package/dist/VirtualShell/index.d.ts.map +1 -1
- package/dist/VirtualShell/index.js +18 -7
- package/dist/VirtualShell/shell.d.ts.map +1 -1
- package/dist/VirtualShell/shell.js +3 -1
- package/dist/VirtualShell/shellParser.d.ts.map +1 -1
- package/dist/VirtualUserManager/index.d.ts.map +1 -1
- package/dist/commands/adduser.d.ts +6 -0
- package/dist/commands/adduser.d.ts.map +1 -1
- package/dist/commands/adduser.js +6 -0
- package/dist/commands/alias.d.ts +5 -0
- package/dist/commands/alias.d.ts.map +1 -1
- package/dist/commands/alias.js +5 -0
- package/dist/commands/apt.d.ts +5 -0
- package/dist/commands/apt.d.ts.map +1 -1
- package/dist/commands/apt.js +32 -9
- package/dist/commands/awk.d.ts +11 -0
- package/dist/commands/awk.d.ts.map +1 -1
- package/dist/commands/awk.js +15 -2
- package/dist/commands/base64.d.ts +5 -0
- package/dist/commands/base64.d.ts.map +1 -1
- package/dist/commands/base64.js +9 -1
- package/dist/commands/cat.d.ts +5 -0
- package/dist/commands/cat.d.ts.map +1 -1
- package/dist/commands/cat.js +10 -2
- package/dist/commands/cd.d.ts +5 -0
- package/dist/commands/cd.d.ts.map +1 -1
- package/dist/commands/cd.js +5 -0
- package/dist/commands/chmod.d.ts +5 -0
- package/dist/commands/chmod.d.ts.map +1 -1
- package/dist/commands/chmod.js +5 -0
- package/dist/commands/cp.d.ts +5 -0
- package/dist/commands/cp.d.ts.map +1 -1
- package/dist/commands/cp.js +5 -0
- package/dist/commands/curl.d.ts +5 -0
- package/dist/commands/curl.d.ts.map +1 -1
- package/dist/commands/curl.js +34 -6
- package/dist/commands/cut.d.ts +5 -0
- package/dist/commands/cut.d.ts.map +1 -1
- package/dist/commands/cut.js +8 -1
- package/dist/commands/date.d.ts +5 -0
- package/dist/commands/date.d.ts.map +1 -1
- package/dist/commands/date.js +7 -1
- package/dist/commands/declare.d.ts +3 -0
- package/dist/commands/declare.d.ts.map +1 -0
- package/dist/commands/declare.js +39 -0
- package/dist/commands/diff.d.ts +5 -0
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +5 -0
- package/dist/commands/dpkg.d.ts +5 -0
- package/dist/commands/dpkg.d.ts.map +1 -1
- package/dist/commands/dpkg.js +24 -7
- package/dist/commands/du.d.ts.map +1 -1
- package/dist/commands/du.js +8 -2
- package/dist/commands/echo.d.ts +5 -0
- package/dist/commands/echo.d.ts.map +1 -1
- package/dist/commands/echo.js +13 -4
- package/dist/commands/env.d.ts +5 -0
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +11 -1
- package/dist/commands/exit.d.ts +5 -0
- package/dist/commands/exit.d.ts.map +1 -1
- package/dist/commands/exit.js +12 -2
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +3 -1
- package/dist/commands/find.d.ts +5 -0
- package/dist/commands/find.d.ts.map +1 -1
- package/dist/commands/find.js +5 -0
- package/dist/commands/free.d.ts +5 -0
- package/dist/commands/free.d.ts.map +1 -1
- package/dist/commands/free.js +5 -0
- package/dist/commands/grep.d.ts +5 -0
- package/dist/commands/grep.d.ts.map +1 -1
- package/dist/commands/grep.js +12 -2
- package/dist/commands/gzip.d.ts +5 -0
- package/dist/commands/gzip.d.ts.map +1 -1
- package/dist/commands/gzip.js +18 -2
- package/dist/commands/head.d.ts +5 -0
- package/dist/commands/head.d.ts.map +1 -1
- package/dist/commands/head.js +5 -0
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +98 -45
- package/dist/commands/history.d.ts +5 -0
- package/dist/commands/history.d.ts.map +1 -1
- package/dist/commands/history.js +5 -0
- package/dist/commands/hostname.d.ts +5 -0
- package/dist/commands/hostname.d.ts.map +1 -1
- package/dist/commands/hostname.js +5 -0
- package/dist/commands/id.d.ts.map +1 -1
- package/dist/commands/id.js +4 -1
- package/dist/commands/index.d.ts +2 -17
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -340
- package/dist/commands/ls.d.ts.map +1 -1
- package/dist/commands/ls.js +3 -1
- package/dist/commands/lsb-release.d.ts.map +1 -1
- package/dist/commands/lsb-release.js +8 -2
- package/dist/commands/nano.js +1 -1
- package/dist/commands/neofetch.js +1 -1
- package/dist/commands/node.d.ts +9 -0
- package/dist/commands/node.d.ts.map +1 -0
- package/dist/commands/node.js +316 -0
- package/dist/commands/npm.d.ts +19 -0
- package/dist/commands/npm.d.ts.map +1 -0
- package/dist/commands/npm.js +109 -0
- package/dist/commands/ping.d.ts.map +1 -1
- package/dist/commands/ping.js +3 -1
- package/dist/commands/printf.d.ts +3 -0
- package/dist/commands/printf.d.ts.map +1 -0
- package/dist/commands/printf.js +113 -0
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +4 -1
- package/dist/commands/python.d.ts +30 -0
- package/dist/commands/python.d.ts.map +1 -0
- package/dist/commands/python.js +2058 -0
- package/dist/commands/read.d.ts +3 -0
- package/dist/commands/read.d.ts.map +1 -0
- package/dist/commands/read.js +34 -0
- package/dist/commands/registry.d.ts +8 -0
- package/dist/commands/registry.d.ts.map +1 -0
- package/dist/commands/registry.js +229 -0
- package/dist/commands/runtime.d.ts +6 -0
- package/dist/commands/runtime.d.ts.map +1 -0
- package/dist/commands/runtime.js +280 -0
- package/dist/commands/sed.d.ts.map +1 -1
- package/dist/commands/sed.js +11 -3
- package/dist/commands/set.d.ts.map +1 -1
- package/dist/commands/set.js +9 -3
- package/dist/commands/sh.d.ts.map +1 -1
- package/dist/commands/sh.js +57 -36
- package/dist/commands/shift.d.ts +5 -0
- package/dist/commands/shift.d.ts.map +1 -0
- package/dist/commands/shift.js +52 -0
- package/dist/commands/sleep.d.ts.map +1 -1
- package/dist/commands/sort.d.ts.map +1 -1
- package/dist/commands/sort.js +4 -2
- package/dist/commands/source.d.ts.map +1 -1
- package/dist/commands/source.js +5 -2
- package/dist/commands/sudo.js +1 -1
- package/dist/commands/tar.d.ts.map +1 -1
- package/dist/commands/tar.js +11 -3
- package/dist/commands/tee.d.ts.map +1 -1
- package/dist/commands/tee.js +8 -6
- package/dist/commands/test.d.ts.map +1 -1
- package/dist/commands/test.js +46 -24
- package/dist/commands/tr.d.ts.map +1 -1
- package/dist/commands/tr.js +3 -1
- package/dist/commands/true.d.ts +4 -0
- package/dist/commands/true.d.ts.map +1 -0
- package/dist/commands/true.js +14 -0
- package/dist/commands/type.d.ts.map +1 -1
- package/dist/commands/type.js +1 -1
- package/dist/commands/uname.d.ts.map +1 -1
- package/dist/commands/uname.js +4 -1
- package/dist/commands/uniq.d.ts.map +1 -1
- package/dist/commands/uptime.d.ts.map +1 -1
- package/dist/commands/uptime.js +4 -1
- package/dist/commands/wget.d.ts.map +1 -1
- package/dist/commands/wget.js +32 -7
- package/dist/commands/which.d.ts.map +1 -1
- package/dist/commands/xargs.d.ts.map +1 -1
- package/dist/commands/xargs.js +1 -1
- package/dist/index.d.ts +15 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -9
- package/dist/modules/linuxRootfs.d.ts +18 -1
- package/dist/modules/linuxRootfs.d.ts.map +1 -1
- package/dist/modules/linuxRootfs.js +160 -17
- package/dist/standalone-wo-sftp.d.ts +2 -0
- package/dist/standalone-wo-sftp.d.ts.map +1 -0
- package/dist/standalone-wo-sftp.js +30 -0
- package/dist/utils/expand.d.ts +50 -0
- package/dist/utils/expand.d.ts.map +1 -0
- package/dist/utils/expand.js +183 -0
- package/dist/utils/vfsDiff.d.ts +90 -0
- package/dist/utils/vfsDiff.d.ts.map +1 -0
- package/dist/utils/vfsDiff.js +177 -0
- package/package.json +2 -1
- package/src/SSHMimic/exec.ts +10 -1
- package/src/SSHMimic/executor.ts +104 -18
- package/src/SSHMimic/index.ts +49 -15
- package/src/VirtualFileSystem/binaryPack.ts +35 -8
- package/src/VirtualFileSystem/index.ts +78 -28
- package/src/VirtualPackageManager/index.ts +208 -49
- package/src/VirtualShell/index.ts +35 -7
- package/src/VirtualShell/shell.ts +23 -3
- package/src/VirtualShell/shellParser.ts +134 -36
- package/src/VirtualUserManager/index.ts +7 -2
- package/src/commands/adduser.ts +6 -0
- package/src/commands/alias.ts +5 -1
- package/src/commands/apt.ts +47 -17
- package/src/commands/awk.ts +20 -6
- package/src/commands/base64.ts +13 -2
- package/src/commands/cat.ts +13 -5
- package/src/commands/cd.ts +5 -0
- package/src/commands/chmod.ts +5 -0
- package/src/commands/cp.ts +5 -0
- package/src/commands/curl.ts +56 -12
- package/src/commands/cut.ts +8 -1
- package/src/commands/date.ts +7 -1
- package/src/commands/declare.ts +44 -0
- package/src/commands/diff.ts +17 -3
- package/src/commands/dpkg.ts +33 -11
- package/src/commands/du.ts +17 -5
- package/src/commands/echo.ts +22 -9
- package/src/commands/env.ts +11 -1
- package/src/commands/exit.ts +12 -2
- package/src/commands/export.ts +3 -1
- package/src/commands/find.ts +5 -0
- package/src/commands/free.ts +9 -2
- package/src/commands/grep.ts +12 -2
- package/src/commands/gzip.ts +28 -4
- package/src/commands/head.ts +5 -0
- package/src/commands/help.ts +121 -47
- package/src/commands/history.ts +7 -2
- package/src/commands/hostname.ts +5 -0
- package/src/commands/id.ts +4 -1
- package/src/commands/index.ts +9 -360
- package/src/commands/ls.ts +5 -3
- package/src/commands/lsb-release.ts +8 -2
- package/src/commands/nano.ts +1 -1
- package/src/commands/neofetch.ts +1 -1
- package/src/commands/node.ts +341 -0
- package/src/commands/npm.ts +132 -0
- package/src/commands/ping.ts +6 -2
- package/src/commands/printf.ts +112 -0
- package/src/commands/ps.ts +21 -9
- package/src/commands/python.ts +2229 -0
- package/src/commands/read.ts +41 -0
- package/src/commands/registry.ts +244 -0
- package/src/commands/runtime.ts +353 -0
- package/src/commands/sed.ts +27 -9
- package/src/commands/set.ts +9 -3
- package/src/commands/sh.ts +159 -55
- package/src/commands/shift.ts +53 -0
- package/src/commands/sleep.ts +2 -1
- package/src/commands/sort.ts +10 -6
- package/src/commands/source.ts +15 -3
- package/src/commands/sudo.ts +1 -1
- package/src/commands/tar.ts +28 -7
- package/src/commands/tee.ts +7 -1
- package/src/commands/test.ts +61 -26
- package/src/commands/tr.ts +3 -1
- package/src/commands/true.ts +17 -0
- package/src/commands/type.ts +6 -3
- package/src/commands/uname.ts +5 -1
- package/src/commands/uniq.ts +8 -2
- package/src/commands/uptime.ts +4 -1
- package/src/commands/wget.ts +51 -12
- package/src/commands/which.ts +5 -2
- package/src/commands/xargs.ts +11 -2
- package/src/index.ts +23 -24
- package/src/modules/linuxRootfs.ts +233 -30
- package/src/standalone-wo-sftp.ts +38 -0
- package/src/utils/expand.ts +238 -0
- package/src/utils/vfsDiff.ts +275 -0
- package/standalone-wo-sftp.js +507 -0
- package/standalone-wo-sftp.js.map +7 -0
- package/standalone.js +253 -191
- package/standalone.js.map +4 -4
- package/tests/bun-test-shim.ts +9 -1
- package/tests/command-helpers.test.ts +1 -5
- package/tests/new-features.test.ts +415 -5
- package/tests/parser-executor.test.ts +27 -27
- package/tests/sftp.test.ts +122 -42
- package/tests/users.test.ts +23 -5
- package/CHANGELOG.md +0 -150
package/dist/commands/sh.js
CHANGED
|
@@ -1,32 +1,13 @@
|
|
|
1
|
+
import { expandAsync } from "../utils/expand";
|
|
1
2
|
import { ifFlag } from "./command-helpers";
|
|
2
3
|
import { resolvePath } from "./helpers";
|
|
3
|
-
import { runCommand } from "./
|
|
4
|
-
/** Expand $VAR and ${VAR:-default} in a line using the current env (sync, no $(cmd)) */
|
|
5
|
-
function expandVarsSync(line, env, lastExit) {
|
|
6
|
-
return line
|
|
7
|
-
.replace(/\$\?/g, String(lastExit))
|
|
8
|
-
.replace(/\$\{([^}:]+):-([^}]*)\}/g, (_, n, d) => env[n] ?? d)
|
|
9
|
-
.replace(/\$\{([^}]+)\}/g, (_, n) => env[n] ?? "")
|
|
10
|
-
.replace(/\$([A-Za-z_][A-Za-z0-9_]*)/g, (_, n) => env[n] ?? "")
|
|
11
|
-
.replace(/^~(\/|$)/, `${env.HOME ?? "/home/user"}$1`);
|
|
12
|
-
}
|
|
4
|
+
import { runCommand } from "./runtime";
|
|
13
5
|
/**
|
|
14
|
-
* Expand
|
|
15
|
-
*
|
|
6
|
+
* Expand all shell forms including $(cmd) substitution.
|
|
7
|
+
* Delegates to centralised expandAsync (single-quote-aware, depth-tracked).
|
|
16
8
|
*/
|
|
17
9
|
async function expandVars(line, env, lastExit, ctx) {
|
|
18
|
-
|
|
19
|
-
if (line.includes("$(")) {
|
|
20
|
-
const subRe = /\$\(([^)]+)\)/g;
|
|
21
|
-
const matches = [...line.matchAll(subRe)];
|
|
22
|
-
for (const m of matches) {
|
|
23
|
-
const sub = m[1]?.trim() ?? "";
|
|
24
|
-
const subResult = await runCommand(sub, ctx.authUser, ctx.hostname, ctx.mode, ctx.cwd, ctx.shell, undefined, ctx.env);
|
|
25
|
-
const subOut = (subResult.stdout ?? "").replace(/\n$/, "");
|
|
26
|
-
line = line.replace(m[0], subOut);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return expandVarsSync(line, env, lastExit);
|
|
10
|
+
return expandAsync(line, env, lastExit, (sub) => runCommand(sub, ctx.authUser, ctx.hostname, ctx.mode, ctx.cwd, ctx.shell, undefined, ctx.env).then((r) => r.stdout ?? ""));
|
|
30
11
|
}
|
|
31
12
|
/** Very small shell interpreter: supports if/elif/else/fi, for/do/done, while/do/done */
|
|
32
13
|
function parseBlocks(lines) {
|
|
@@ -39,7 +20,10 @@ function parseBlocks(lines) {
|
|
|
39
20
|
continue;
|
|
40
21
|
}
|
|
41
22
|
if (line.startsWith("if ") || line === "if") {
|
|
42
|
-
const cond = line
|
|
23
|
+
const cond = line
|
|
24
|
+
.replace(/^if\s+/, "")
|
|
25
|
+
.replace(/;\s*then\s*$/, "")
|
|
26
|
+
.trim();
|
|
43
27
|
const thenLines = [];
|
|
44
28
|
const elifBlocks = [];
|
|
45
29
|
const elseLines = [];
|
|
@@ -50,7 +34,10 @@ function parseBlocks(lines) {
|
|
|
50
34
|
const l = lines[i].trim();
|
|
51
35
|
if (l.startsWith("elif ")) {
|
|
52
36
|
section = "elif";
|
|
53
|
-
elifCond = l
|
|
37
|
+
elifCond = l
|
|
38
|
+
.replace(/^elif\s+/, "")
|
|
39
|
+
.replace(/;\s*then\s*$/, "")
|
|
40
|
+
.trim();
|
|
54
41
|
elifBlocks.push({ cond: elifCond, body: [] });
|
|
55
42
|
}
|
|
56
43
|
else if (l === "else") {
|
|
@@ -66,8 +53,13 @@ function parseBlocks(lines) {
|
|
|
66
53
|
}
|
|
67
54
|
i++;
|
|
68
55
|
}
|
|
69
|
-
|
|
70
|
-
|
|
56
|
+
blocks.push({
|
|
57
|
+
type: "if",
|
|
58
|
+
cond,
|
|
59
|
+
then_: thenLines,
|
|
60
|
+
elif: elifBlocks,
|
|
61
|
+
else_: elseLines,
|
|
62
|
+
});
|
|
71
63
|
}
|
|
72
64
|
else if (line.startsWith("for ")) {
|
|
73
65
|
const m = line.match(/^for\s+(\w+)\s+in\s+(.+?)(?:\s*;\s*do)?$/);
|
|
@@ -87,7 +79,10 @@ function parseBlocks(lines) {
|
|
|
87
79
|
}
|
|
88
80
|
}
|
|
89
81
|
else if (line.startsWith("while ")) {
|
|
90
|
-
const cond = line
|
|
82
|
+
const cond = line
|
|
83
|
+
.replace(/^while\s+/, "")
|
|
84
|
+
.replace(/;\s*do\s*$/, "")
|
|
85
|
+
.trim();
|
|
91
86
|
const body = [];
|
|
92
87
|
i++;
|
|
93
88
|
while (i < lines.length && lines[i]?.trim() !== "done") {
|
|
@@ -119,7 +114,7 @@ async function evalCondition(cond, ctx) {
|
|
|
119
114
|
if (flag === "f")
|
|
120
115
|
return ctx.shell.vfs.exists(p) && ctx.shell.vfs.stat(p).type === "file";
|
|
121
116
|
if (flag === "d")
|
|
122
|
-
return ctx.shell.vfs.exists(p) && ctx.shell.vfs.stat(p).type === "directory";
|
|
117
|
+
return (ctx.shell.vfs.exists(p) && ctx.shell.vfs.stat(p).type === "directory");
|
|
123
118
|
if (flag === "e")
|
|
124
119
|
return ctx.shell.vfs.exists(p);
|
|
125
120
|
if (flag === "z")
|
|
@@ -165,6 +160,20 @@ async function runBlocks(blocks, ctx) {
|
|
|
165
160
|
for (const block of blocks) {
|
|
166
161
|
if (block.type === "cmd") {
|
|
167
162
|
const expanded = await expandVars(block.line, ctx.env.vars, ctx.env.lastExitCode, ctx);
|
|
163
|
+
// Bare VAR=val assignment(s) — handle before dispatching to runCommand
|
|
164
|
+
const assignRe = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)/;
|
|
165
|
+
const tokens = expanded.trim().split(/\s+/);
|
|
166
|
+
if (tokens.length > 0 && assignRe.test(tokens[0])) {
|
|
167
|
+
const allAssign = tokens.every((t) => assignRe.test(t));
|
|
168
|
+
if (allAssign) {
|
|
169
|
+
for (const tok of tokens) {
|
|
170
|
+
const m = tok.match(assignRe);
|
|
171
|
+
ctx.env.vars[m[1]] = m[2];
|
|
172
|
+
}
|
|
173
|
+
ctx.env.lastExitCode = 0;
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
168
177
|
const r = await runCommand(expanded, ctx.authUser, ctx.hostname, ctx.mode, ctx.cwd, ctx.shell, undefined, ctx.env);
|
|
169
178
|
ctx.env.lastExitCode = r.exitCode ?? 0;
|
|
170
179
|
if (r.stdout)
|
|
@@ -176,7 +185,7 @@ async function runBlocks(blocks, ctx) {
|
|
|
176
185
|
else if (block.type === "if") {
|
|
177
186
|
let ran = false;
|
|
178
187
|
if (await evalCondition(block.cond, ctx)) {
|
|
179
|
-
const sub = await runBlocks(parseBlocks(block.
|
|
188
|
+
const sub = await runBlocks(parseBlocks(block.then_), ctx);
|
|
180
189
|
if (sub.stdout)
|
|
181
190
|
output += `${sub.stdout}\n`;
|
|
182
191
|
ran = true;
|
|
@@ -212,7 +221,7 @@ async function runBlocks(blocks, ctx) {
|
|
|
212
221
|
}
|
|
213
222
|
else if (block.type === "while") {
|
|
214
223
|
let iterations = 0;
|
|
215
|
-
while (iterations < 1000 && await evalCondition(block.cond, ctx)) {
|
|
224
|
+
while (iterations < 1000 && (await evalCondition(block.cond, ctx))) {
|
|
216
225
|
const sub = await runBlocks(parseBlocks(block.body), ctx);
|
|
217
226
|
if (sub.stdout)
|
|
218
227
|
output += `${sub.stdout}\n`;
|
|
@@ -237,7 +246,10 @@ export const shCommand = {
|
|
|
237
246
|
const script = args[args.indexOf("-c") + 1] ?? "";
|
|
238
247
|
if (!script)
|
|
239
248
|
return { stderr: "sh: -c requires a script", exitCode: 1 };
|
|
240
|
-
const lines = script
|
|
249
|
+
const lines = script
|
|
250
|
+
.split(/[;\n]/)
|
|
251
|
+
.map((l) => l.trim())
|
|
252
|
+
.filter((l) => l && !l.startsWith("#"));
|
|
241
253
|
const blocks = parseBlocks(lines);
|
|
242
254
|
return runBlocks(blocks, ctx);
|
|
243
255
|
}
|
|
@@ -246,12 +258,21 @@ export const shCommand = {
|
|
|
246
258
|
if (fileArg) {
|
|
247
259
|
const p = resolvePath(cwd, fileArg);
|
|
248
260
|
if (!shell.vfs.exists(p))
|
|
249
|
-
return {
|
|
261
|
+
return {
|
|
262
|
+
stderr: `sh: ${fileArg}: No such file or directory`,
|
|
263
|
+
exitCode: 1,
|
|
264
|
+
};
|
|
250
265
|
const content = shell.vfs.readFile(p);
|
|
251
|
-
const lines = content
|
|
266
|
+
const lines = content
|
|
267
|
+
.split("\n")
|
|
268
|
+
.map((l) => l.trim())
|
|
269
|
+
.filter((l) => l && !l.startsWith("#"));
|
|
252
270
|
const blocks = parseBlocks(lines);
|
|
253
271
|
return runBlocks(blocks, ctx);
|
|
254
272
|
}
|
|
255
|
-
return {
|
|
273
|
+
return {
|
|
274
|
+
stderr: "sh: invalid usage. Use: sh -c 'cmd' or sh <file>",
|
|
275
|
+
exitCode: 1,
|
|
276
|
+
};
|
|
256
277
|
},
|
|
257
278
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shift.d.ts","sourceRoot":"","sources":["../../src/commands/shift.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,YAAY,EAAE,WAoB1B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,WAezB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,WAW3B,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export const shiftCommand = {
|
|
2
|
+
name: "shift",
|
|
3
|
+
description: "Shift positional parameters",
|
|
4
|
+
category: "shell",
|
|
5
|
+
params: ["[n]"],
|
|
6
|
+
// shift is meaningful only inside sh scripts where positional params exist.
|
|
7
|
+
// In the current impl, positional params ($1 $2 …) aren't tracked in env by default.
|
|
8
|
+
// We store them under env.vars.__argv and shift there if present.
|
|
9
|
+
run: ({ args, env }) => {
|
|
10
|
+
if (!env)
|
|
11
|
+
return { exitCode: 0 };
|
|
12
|
+
const n = parseInt(args[0] ?? "1", 10) || 1;
|
|
13
|
+
const argv = env.vars.__argv?.split("\x00").filter(Boolean) ?? [];
|
|
14
|
+
env.vars.__argv = argv.slice(n).join("\x00");
|
|
15
|
+
// Update $1 $2 … in env
|
|
16
|
+
const shifted = argv.slice(n);
|
|
17
|
+
for (let i = 1; i <= 9; i++) {
|
|
18
|
+
env.vars[String(i)] = shifted[i - 1] ?? "";
|
|
19
|
+
}
|
|
20
|
+
return { exitCode: 0 };
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
export const trapCommand = {
|
|
24
|
+
name: "trap",
|
|
25
|
+
description: "Trap signals and events",
|
|
26
|
+
category: "shell",
|
|
27
|
+
params: ["[action] [signal...]"],
|
|
28
|
+
// Store trap handlers in env for EXIT signal support
|
|
29
|
+
run: ({ args, env }) => {
|
|
30
|
+
if (!env || args.length === 0)
|
|
31
|
+
return { exitCode: 0 };
|
|
32
|
+
const action = args[0] ?? "";
|
|
33
|
+
const signals = args.slice(1);
|
|
34
|
+
for (const sig of signals) {
|
|
35
|
+
env.vars[`__trap_${sig.toUpperCase()}`] = action;
|
|
36
|
+
}
|
|
37
|
+
return { exitCode: 0 };
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
export const returnCommand = {
|
|
41
|
+
name: "return",
|
|
42
|
+
description: "Return from a shell function",
|
|
43
|
+
category: "shell",
|
|
44
|
+
params: ["[n]"],
|
|
45
|
+
run: ({ args, env }) => {
|
|
46
|
+
const code = parseInt(args[0] ?? "0", 10);
|
|
47
|
+
if (env)
|
|
48
|
+
env.lastExitCode = code;
|
|
49
|
+
// Signal the caller via exitCode; function return is handled by runBlocks
|
|
50
|
+
return { exitCode: code };
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sleep.d.ts","sourceRoot":"","sources":["../../src/commands/sleep.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"sleep.d.ts","sourceRoot":"","sources":["../../src/commands/sleep.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,YAAY,EAAE,WAY1B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sort.d.ts","sourceRoot":"","sources":["../../src/commands/sort.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"sort.d.ts","sourceRoot":"","sources":["../../src/commands/sort.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,WAAW,EAAE,WAoCzB,CAAC"}
|
package/dist/commands/sort.js
CHANGED
|
@@ -12,7 +12,8 @@ export const sortCommand = {
|
|
|
12
12
|
const files = args.filter((a) => !a.startsWith("-"));
|
|
13
13
|
const getContent = () => {
|
|
14
14
|
if (files.length > 0) {
|
|
15
|
-
return files
|
|
15
|
+
return files
|
|
16
|
+
.map((f) => {
|
|
16
17
|
try {
|
|
17
18
|
assertPathAccess(authUser, resolvePath(cwd, f), "sort");
|
|
18
19
|
return shell.vfs.readFile(resolvePath(cwd, f));
|
|
@@ -20,7 +21,8 @@ export const sortCommand = {
|
|
|
20
21
|
catch {
|
|
21
22
|
return "";
|
|
22
23
|
}
|
|
23
|
-
})
|
|
24
|
+
})
|
|
25
|
+
.join("\n");
|
|
24
26
|
}
|
|
25
27
|
return stdin ?? "";
|
|
26
28
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/commands/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/commands/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,aAAa,EAAE,WA0C3B,CAAC"}
|
package/dist/commands/source.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolvePath } from "./helpers";
|
|
2
|
-
import { runCommand } from "
|
|
2
|
+
import { runCommand } from "./runtime";
|
|
3
3
|
export const sourceCommand = {
|
|
4
4
|
name: "source",
|
|
5
5
|
aliases: ["."],
|
|
@@ -13,7 +13,10 @@ export const sourceCommand = {
|
|
|
13
13
|
}
|
|
14
14
|
const filePath = resolvePath(cwd, fileArg);
|
|
15
15
|
if (!shell.vfs.exists(filePath)) {
|
|
16
|
-
return {
|
|
16
|
+
return {
|
|
17
|
+
stderr: `source: ${fileArg}: No such file or directory`,
|
|
18
|
+
exitCode: 1,
|
|
19
|
+
};
|
|
17
20
|
}
|
|
18
21
|
const content = shell.vfs.readFile(filePath);
|
|
19
22
|
let lastExitCode = 0;
|
package/dist/commands/sudo.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tar.d.ts","sourceRoot":"","sources":["../../src/commands/tar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"tar.d.ts","sourceRoot":"","sources":["../../src/commands/tar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,UAAU,EAAE,WA0ExB,CAAC"}
|
package/dist/commands/tar.js
CHANGED
|
@@ -10,7 +10,9 @@ export const tarCommand = {
|
|
|
10
10
|
const extract = ifFlag(args, ["-x"]);
|
|
11
11
|
const list = ifFlag(args, ["-t"]);
|
|
12
12
|
const fFlag = args.findIndex((a) => a.includes("f"));
|
|
13
|
-
const archiveName = fFlag !== -1
|
|
13
|
+
const archiveName = fFlag !== -1
|
|
14
|
+
? args[fFlag + 1]
|
|
15
|
+
: args.find((a) => a.endsWith(".tar") || a.endsWith(".tar.gz") || a.endsWith(".tgz"));
|
|
14
16
|
if (!archiveName)
|
|
15
17
|
return { stderr: "tar: no archive specified", exitCode: 1 };
|
|
16
18
|
const archivePath = resolvePath(cwd, archiveName);
|
|
@@ -38,7 +40,10 @@ export const tarCommand = {
|
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
catch {
|
|
41
|
-
return {
|
|
43
|
+
return {
|
|
44
|
+
stderr: `tar: ${f}: No such file or directory`,
|
|
45
|
+
exitCode: 1,
|
|
46
|
+
};
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
49
|
shell.writeFileAsUser(authUser, archivePath, JSON.stringify(entries));
|
|
@@ -50,7 +55,10 @@ export const tarCommand = {
|
|
|
50
55
|
entries = JSON.parse(shell.vfs.readFile(archivePath));
|
|
51
56
|
}
|
|
52
57
|
catch {
|
|
53
|
-
return {
|
|
58
|
+
return {
|
|
59
|
+
stderr: `tar: ${archiveName}: cannot open archive`,
|
|
60
|
+
exitCode: 1,
|
|
61
|
+
};
|
|
54
62
|
}
|
|
55
63
|
if (list)
|
|
56
64
|
return { stdout: Object.keys(entries).join("\n"), exitCode: 0 };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tee.d.ts","sourceRoot":"","sources":["../../src/commands/tee.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"tee.d.ts","sourceRoot":"","sources":["../../src/commands/tee.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,UAAU,EAAE,WA0BxB,CAAC"}
|
package/dist/commands/tee.js
CHANGED
|
@@ -12,12 +12,14 @@ export const teeCommand = {
|
|
|
12
12
|
for (const f of files) {
|
|
13
13
|
const p = resolvePath(cwd, f);
|
|
14
14
|
if (append) {
|
|
15
|
-
const existing = (() => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
const existing = (() => {
|
|
16
|
+
try {
|
|
17
|
+
return shell.vfs.readFile(p);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
22
|
+
})();
|
|
21
23
|
shell.writeFileAsUser(authUser, p, existing + input);
|
|
22
24
|
}
|
|
23
25
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAwHrD,eAAO,MAAM,WAAW,EAAE,WAczB,CAAC"}
|
package/dist/commands/test.js
CHANGED
|
@@ -22,13 +22,13 @@ function evalTest(tokens, shell, cwd) {
|
|
|
22
22
|
// Boolean -a / -o (simple left-right, no precedence)
|
|
23
23
|
const andIdx = tokens.indexOf("-a");
|
|
24
24
|
if (andIdx !== -1) {
|
|
25
|
-
return evalTest(tokens.slice(0, andIdx), shell, cwd) &&
|
|
26
|
-
evalTest(tokens.slice(andIdx + 1), shell, cwd);
|
|
25
|
+
return (evalTest(tokens.slice(0, andIdx), shell, cwd) &&
|
|
26
|
+
evalTest(tokens.slice(andIdx + 1), shell, cwd));
|
|
27
27
|
}
|
|
28
28
|
const orIdx = tokens.indexOf("-o");
|
|
29
29
|
if (orIdx !== -1) {
|
|
30
|
-
return evalTest(tokens.slice(0, orIdx), shell, cwd) ||
|
|
31
|
-
evalTest(tokens.slice(orIdx + 1), shell, cwd);
|
|
30
|
+
return (evalTest(tokens.slice(0, orIdx), shell, cwd) ||
|
|
31
|
+
evalTest(tokens.slice(orIdx + 1), shell, cwd));
|
|
32
32
|
}
|
|
33
33
|
// Unary file tests
|
|
34
34
|
if (tokens.length === 2) {
|
|
@@ -36,16 +36,28 @@ function evalTest(tokens, shell, cwd) {
|
|
|
36
36
|
const resolvePath = (p) => p.startsWith("/") ? p : `${cwd}/${p}`.replace(/\/+/g, "/");
|
|
37
37
|
const path = resolvePath(operand);
|
|
38
38
|
switch (flag) {
|
|
39
|
-
case "-e":
|
|
40
|
-
|
|
41
|
-
case "-
|
|
42
|
-
|
|
43
|
-
case "-
|
|
44
|
-
|
|
45
|
-
case "-
|
|
46
|
-
|
|
47
|
-
case "-
|
|
48
|
-
|
|
39
|
+
case "-e":
|
|
40
|
+
return shell.vfs.exists(path);
|
|
41
|
+
case "-f":
|
|
42
|
+
return shell.vfs.exists(path) && shell.vfs.stat(path).type === "file";
|
|
43
|
+
case "-d":
|
|
44
|
+
return (shell.vfs.exists(path) && shell.vfs.stat(path).type === "directory");
|
|
45
|
+
case "-r":
|
|
46
|
+
return shell.vfs.exists(path); // all readable in virtual env
|
|
47
|
+
case "-w":
|
|
48
|
+
return shell.vfs.exists(path);
|
|
49
|
+
case "-x":
|
|
50
|
+
return shell.vfs.exists(path) && !!(shell.vfs.stat(path).mode & 0o111);
|
|
51
|
+
case "-s":
|
|
52
|
+
return (shell.vfs.exists(path) &&
|
|
53
|
+
shell.vfs.stat(path).type === "file" &&
|
|
54
|
+
shell.vfs.stat(path).size > 0);
|
|
55
|
+
case "-z":
|
|
56
|
+
return operand.length === 0;
|
|
57
|
+
case "-n":
|
|
58
|
+
return operand.length > 0;
|
|
59
|
+
case "-L":
|
|
60
|
+
return shell.vfs.isSymlink(path);
|
|
49
61
|
}
|
|
50
62
|
}
|
|
51
63
|
// Binary comparisons
|
|
@@ -56,17 +68,27 @@ function evalTest(tokens, shell, cwd) {
|
|
|
56
68
|
switch (op) {
|
|
57
69
|
// String
|
|
58
70
|
case "=":
|
|
59
|
-
case "==":
|
|
60
|
-
|
|
61
|
-
case "
|
|
62
|
-
|
|
71
|
+
case "==":
|
|
72
|
+
return left === right;
|
|
73
|
+
case "!=":
|
|
74
|
+
return left !== right;
|
|
75
|
+
case "<":
|
|
76
|
+
return left < right;
|
|
77
|
+
case ">":
|
|
78
|
+
return left > right;
|
|
63
79
|
// Numeric
|
|
64
|
-
case "-eq":
|
|
65
|
-
|
|
66
|
-
case "-
|
|
67
|
-
|
|
68
|
-
case "-
|
|
69
|
-
|
|
80
|
+
case "-eq":
|
|
81
|
+
return leftN === rightN;
|
|
82
|
+
case "-ne":
|
|
83
|
+
return leftN !== rightN;
|
|
84
|
+
case "-lt":
|
|
85
|
+
return leftN < rightN;
|
|
86
|
+
case "-le":
|
|
87
|
+
return leftN <= rightN;
|
|
88
|
+
case "-gt":
|
|
89
|
+
return leftN > rightN;
|
|
90
|
+
case "-ge":
|
|
91
|
+
return leftN >= rightN;
|
|
70
92
|
}
|
|
71
93
|
}
|
|
72
94
|
// Single string (truthy if non-empty)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tr.d.ts","sourceRoot":"","sources":["../../src/commands/tr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"tr.d.ts","sourceRoot":"","sources":["../../src/commands/tr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,SAAS,EAAE,WAsBvB,CAAC"}
|
package/dist/commands/tr.js
CHANGED
|
@@ -16,7 +16,9 @@ export const trCommand = {
|
|
|
16
16
|
}
|
|
17
17
|
else if (set2) {
|
|
18
18
|
for (let i = 0; i < set1.length; i++) {
|
|
19
|
-
input = input
|
|
19
|
+
input = input
|
|
20
|
+
.split(set1[i])
|
|
21
|
+
.join(set2[i] ?? set2[set2.length - 1] ?? "");
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
return { stdout: input, exitCode: 0 };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"true.d.ts","sourceRoot":"","sources":["../../src/commands/true.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,WAAW,EAAE,WAMzB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,WAM1B,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const trueCommand = {
|
|
2
|
+
name: "true",
|
|
3
|
+
description: "Return success exit code",
|
|
4
|
+
category: "shell",
|
|
5
|
+
params: [],
|
|
6
|
+
run: () => ({ exitCode: 0 }),
|
|
7
|
+
};
|
|
8
|
+
export const falseCommand = {
|
|
9
|
+
name: "false",
|
|
10
|
+
description: "Return failure exit code",
|
|
11
|
+
category: "shell",
|
|
12
|
+
params: [],
|
|
13
|
+
run: () => ({ exitCode: 1 }),
|
|
14
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../src/commands/type.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../src/commands/type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,WAAW,EAAE,WAuCzB,CAAC"}
|
package/dist/commands/type.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uname.d.ts","sourceRoot":"","sources":["../../src/commands/uname.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"uname.d.ts","sourceRoot":"","sources":["../../src/commands/uname.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,YAAY,EAAE,WAoB1B,CAAC"}
|
package/dist/commands/uname.js
CHANGED
|
@@ -11,7 +11,10 @@ export const unameCommand = {
|
|
|
11
11
|
const machine = shell.properties?.arch ?? "x86_64";
|
|
12
12
|
const hostname = shell.hostname;
|
|
13
13
|
if (all)
|
|
14
|
-
return {
|
|
14
|
+
return {
|
|
15
|
+
stdout: `${sysname} ${hostname} ${release} #1 SMP ${machine} GNU/Linux`,
|
|
16
|
+
exitCode: 0,
|
|
17
|
+
};
|
|
15
18
|
if (ifFlag(args, ["-r"]))
|
|
16
19
|
return { stdout: release, exitCode: 0 };
|
|
17
20
|
if (ifFlag(args, ["-m"]))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uniq.d.ts","sourceRoot":"","sources":["../../src/commands/uniq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"uniq.d.ts","sourceRoot":"","sources":["../../src/commands/uniq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,WAAW,EAAE,WA8BzB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uptime.d.ts","sourceRoot":"","sources":["../../src/commands/uptime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"uptime.d.ts","sourceRoot":"","sources":["../../src/commands/uptime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,aAAa,EAAE,WA6C3B,CAAC"}
|
package/dist/commands/uptime.js
CHANGED
|
@@ -13,7 +13,10 @@ export const uptimeCommand = {
|
|
|
13
13
|
const mins = Math.floor((uptimeSec % 3600) / 60);
|
|
14
14
|
if (since) {
|
|
15
15
|
return {
|
|
16
|
-
stdout: new Date(shell.startTime)
|
|
16
|
+
stdout: new Date(shell.startTime)
|
|
17
|
+
.toISOString()
|
|
18
|
+
.slice(0, 19)
|
|
19
|
+
.replace("T", " "),
|
|
17
20
|
exitCode: 0,
|
|
18
21
|
};
|
|
19
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wget.d.ts","sourceRoot":"","sources":["../../src/commands/wget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"wget.d.ts","sourceRoot":"","sources":["../../src/commands/wget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,WAAW,EAAE,WA+HzB,CAAC"}
|
package/dist/commands/wget.js
CHANGED
|
@@ -7,7 +7,16 @@ export const wgetCommand = {
|
|
|
7
7
|
params: ["[options] <url>"],
|
|
8
8
|
run: async ({ authUser, cwd, args, shell }) => {
|
|
9
9
|
const { flagsWithValues, positionals } = parseArgs(args, {
|
|
10
|
-
flagsWithValue: [
|
|
10
|
+
flagsWithValue: [
|
|
11
|
+
"-O",
|
|
12
|
+
"--output-document",
|
|
13
|
+
"-o",
|
|
14
|
+
"--output-file",
|
|
15
|
+
"-P",
|
|
16
|
+
"--directory-prefix",
|
|
17
|
+
"--tries",
|
|
18
|
+
"--timeout",
|
|
19
|
+
],
|
|
11
20
|
});
|
|
12
21
|
if (ifFlag(args, ["-h", "--help"])) {
|
|
13
22
|
return {
|
|
@@ -25,13 +34,23 @@ export const wgetCommand = {
|
|
|
25
34
|
};
|
|
26
35
|
}
|
|
27
36
|
if (ifFlag(args, ["-V", "--version"])) {
|
|
28
|
-
return {
|
|
37
|
+
return {
|
|
38
|
+
stdout: "GNU Wget 1.21.3 (virtual) built on Fortune GNU/Linux.",
|
|
39
|
+
exitCode: 0,
|
|
40
|
+
};
|
|
29
41
|
}
|
|
30
42
|
const url = positionals[0];
|
|
31
43
|
if (!url)
|
|
32
|
-
return {
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
return {
|
|
45
|
+
stderr: "wget: missing URL\nUsage: wget [OPTION]... [URL]...",
|
|
46
|
+
exitCode: 1,
|
|
47
|
+
};
|
|
48
|
+
const outputArg = flagsWithValues.get("-O") ??
|
|
49
|
+
flagsWithValues.get("--output-document") ??
|
|
50
|
+
null;
|
|
51
|
+
const dirPrefix = flagsWithValues.get("-P") ??
|
|
52
|
+
flagsWithValues.get("--directory-prefix") ??
|
|
53
|
+
null;
|
|
35
54
|
const quiet = ifFlag(args, ["-q", "--quiet"]);
|
|
36
55
|
// Derive target filename
|
|
37
56
|
const filename = outputArg === "-" ? null : (outputArg ?? stripUrlFilename(url));
|
|
@@ -48,7 +67,9 @@ export const wgetCommand = {
|
|
|
48
67
|
}
|
|
49
68
|
let response;
|
|
50
69
|
try {
|
|
51
|
-
response = await fetch(url, {
|
|
70
|
+
response = await fetch(url, {
|
|
71
|
+
headers: { "User-Agent": "Wget/1.21.3 (Fortune GNU/Linux)" },
|
|
72
|
+
});
|
|
52
73
|
}
|
|
53
74
|
catch (err) {
|
|
54
75
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -73,7 +94,11 @@ export const wgetCommand = {
|
|
|
73
94
|
}
|
|
74
95
|
// Output to stdout (pipe) or file
|
|
75
96
|
if (outputArg === "-") {
|
|
76
|
-
return {
|
|
97
|
+
return {
|
|
98
|
+
stdout: body,
|
|
99
|
+
stderr: stderrLines.join("\n") || undefined,
|
|
100
|
+
exitCode: 0,
|
|
101
|
+
};
|
|
77
102
|
}
|
|
78
103
|
if (targetPath) {
|
|
79
104
|
shell.writeFileAsUser(authUser, targetPath, body);
|