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.
Files changed (281) hide show
  1. package/.vscode/settings.json +0 -1
  2. package/README.md +141 -50
  3. package/biome.json +7 -0
  4. package/dist/SSHMimic/exec.d.ts.map +1 -1
  5. package/dist/SSHMimic/executor.d.ts.map +1 -1
  6. package/dist/SSHMimic/executor.js +32 -16
  7. package/dist/SSHMimic/index.d.ts.map +1 -1
  8. package/dist/SSHMimic/index.js +20 -6
  9. package/dist/VirtualFileSystem/binaryPack.d.ts.map +1 -1
  10. package/dist/VirtualFileSystem/binaryPack.js +29 -6
  11. package/dist/VirtualFileSystem/index.d.ts.map +1 -1
  12. package/dist/VirtualFileSystem/index.js +36 -13
  13. package/dist/VirtualPackageManager/index.d.ts.map +1 -1
  14. package/dist/VirtualPackageManager/index.js +192 -43
  15. package/dist/VirtualShell/index.d.ts +10 -4
  16. package/dist/VirtualShell/index.d.ts.map +1 -1
  17. package/dist/VirtualShell/index.js +18 -7
  18. package/dist/VirtualShell/shell.d.ts.map +1 -1
  19. package/dist/VirtualShell/shell.js +3 -1
  20. package/dist/VirtualShell/shellParser.d.ts.map +1 -1
  21. package/dist/VirtualUserManager/index.d.ts.map +1 -1
  22. package/dist/commands/adduser.d.ts +6 -0
  23. package/dist/commands/adduser.d.ts.map +1 -1
  24. package/dist/commands/adduser.js +6 -0
  25. package/dist/commands/alias.d.ts +5 -0
  26. package/dist/commands/alias.d.ts.map +1 -1
  27. package/dist/commands/alias.js +5 -0
  28. package/dist/commands/apt.d.ts +5 -0
  29. package/dist/commands/apt.d.ts.map +1 -1
  30. package/dist/commands/apt.js +32 -9
  31. package/dist/commands/awk.d.ts +11 -0
  32. package/dist/commands/awk.d.ts.map +1 -1
  33. package/dist/commands/awk.js +15 -2
  34. package/dist/commands/base64.d.ts +5 -0
  35. package/dist/commands/base64.d.ts.map +1 -1
  36. package/dist/commands/base64.js +9 -1
  37. package/dist/commands/cat.d.ts +5 -0
  38. package/dist/commands/cat.d.ts.map +1 -1
  39. package/dist/commands/cat.js +10 -2
  40. package/dist/commands/cd.d.ts +5 -0
  41. package/dist/commands/cd.d.ts.map +1 -1
  42. package/dist/commands/cd.js +5 -0
  43. package/dist/commands/chmod.d.ts +5 -0
  44. package/dist/commands/chmod.d.ts.map +1 -1
  45. package/dist/commands/chmod.js +5 -0
  46. package/dist/commands/cp.d.ts +5 -0
  47. package/dist/commands/cp.d.ts.map +1 -1
  48. package/dist/commands/cp.js +5 -0
  49. package/dist/commands/curl.d.ts +5 -0
  50. package/dist/commands/curl.d.ts.map +1 -1
  51. package/dist/commands/curl.js +34 -6
  52. package/dist/commands/cut.d.ts +5 -0
  53. package/dist/commands/cut.d.ts.map +1 -1
  54. package/dist/commands/cut.js +8 -1
  55. package/dist/commands/date.d.ts +5 -0
  56. package/dist/commands/date.d.ts.map +1 -1
  57. package/dist/commands/date.js +7 -1
  58. package/dist/commands/declare.d.ts +3 -0
  59. package/dist/commands/declare.d.ts.map +1 -0
  60. package/dist/commands/declare.js +39 -0
  61. package/dist/commands/diff.d.ts +5 -0
  62. package/dist/commands/diff.d.ts.map +1 -1
  63. package/dist/commands/diff.js +5 -0
  64. package/dist/commands/dpkg.d.ts +5 -0
  65. package/dist/commands/dpkg.d.ts.map +1 -1
  66. package/dist/commands/dpkg.js +24 -7
  67. package/dist/commands/du.d.ts.map +1 -1
  68. package/dist/commands/du.js +8 -2
  69. package/dist/commands/echo.d.ts +5 -0
  70. package/dist/commands/echo.d.ts.map +1 -1
  71. package/dist/commands/echo.js +13 -4
  72. package/dist/commands/env.d.ts +5 -0
  73. package/dist/commands/env.d.ts.map +1 -1
  74. package/dist/commands/env.js +11 -1
  75. package/dist/commands/exit.d.ts +5 -0
  76. package/dist/commands/exit.d.ts.map +1 -1
  77. package/dist/commands/exit.js +12 -2
  78. package/dist/commands/export.d.ts.map +1 -1
  79. package/dist/commands/export.js +3 -1
  80. package/dist/commands/find.d.ts +5 -0
  81. package/dist/commands/find.d.ts.map +1 -1
  82. package/dist/commands/find.js +5 -0
  83. package/dist/commands/free.d.ts +5 -0
  84. package/dist/commands/free.d.ts.map +1 -1
  85. package/dist/commands/free.js +5 -0
  86. package/dist/commands/grep.d.ts +5 -0
  87. package/dist/commands/grep.d.ts.map +1 -1
  88. package/dist/commands/grep.js +12 -2
  89. package/dist/commands/gzip.d.ts +5 -0
  90. package/dist/commands/gzip.d.ts.map +1 -1
  91. package/dist/commands/gzip.js +18 -2
  92. package/dist/commands/head.d.ts +5 -0
  93. package/dist/commands/head.d.ts.map +1 -1
  94. package/dist/commands/head.js +5 -0
  95. package/dist/commands/help.d.ts.map +1 -1
  96. package/dist/commands/help.js +98 -45
  97. package/dist/commands/history.d.ts +5 -0
  98. package/dist/commands/history.d.ts.map +1 -1
  99. package/dist/commands/history.js +5 -0
  100. package/dist/commands/hostname.d.ts +5 -0
  101. package/dist/commands/hostname.d.ts.map +1 -1
  102. package/dist/commands/hostname.js +5 -0
  103. package/dist/commands/id.d.ts.map +1 -1
  104. package/dist/commands/id.js +4 -1
  105. package/dist/commands/index.d.ts +2 -17
  106. package/dist/commands/index.d.ts.map +1 -1
  107. package/dist/commands/index.js +2 -340
  108. package/dist/commands/ls.d.ts.map +1 -1
  109. package/dist/commands/ls.js +3 -1
  110. package/dist/commands/lsb-release.d.ts.map +1 -1
  111. package/dist/commands/lsb-release.js +8 -2
  112. package/dist/commands/nano.js +1 -1
  113. package/dist/commands/neofetch.js +1 -1
  114. package/dist/commands/node.d.ts +9 -0
  115. package/dist/commands/node.d.ts.map +1 -0
  116. package/dist/commands/node.js +316 -0
  117. package/dist/commands/npm.d.ts +19 -0
  118. package/dist/commands/npm.d.ts.map +1 -0
  119. package/dist/commands/npm.js +109 -0
  120. package/dist/commands/ping.d.ts.map +1 -1
  121. package/dist/commands/ping.js +3 -1
  122. package/dist/commands/printf.d.ts +3 -0
  123. package/dist/commands/printf.d.ts.map +1 -0
  124. package/dist/commands/printf.js +113 -0
  125. package/dist/commands/ps.d.ts.map +1 -1
  126. package/dist/commands/ps.js +4 -1
  127. package/dist/commands/python.d.ts +30 -0
  128. package/dist/commands/python.d.ts.map +1 -0
  129. package/dist/commands/python.js +2058 -0
  130. package/dist/commands/read.d.ts +3 -0
  131. package/dist/commands/read.d.ts.map +1 -0
  132. package/dist/commands/read.js +34 -0
  133. package/dist/commands/registry.d.ts +8 -0
  134. package/dist/commands/registry.d.ts.map +1 -0
  135. package/dist/commands/registry.js +229 -0
  136. package/dist/commands/runtime.d.ts +6 -0
  137. package/dist/commands/runtime.d.ts.map +1 -0
  138. package/dist/commands/runtime.js +280 -0
  139. package/dist/commands/sed.d.ts.map +1 -1
  140. package/dist/commands/sed.js +11 -3
  141. package/dist/commands/set.d.ts.map +1 -1
  142. package/dist/commands/set.js +9 -3
  143. package/dist/commands/sh.d.ts.map +1 -1
  144. package/dist/commands/sh.js +57 -36
  145. package/dist/commands/shift.d.ts +5 -0
  146. package/dist/commands/shift.d.ts.map +1 -0
  147. package/dist/commands/shift.js +52 -0
  148. package/dist/commands/sleep.d.ts.map +1 -1
  149. package/dist/commands/sort.d.ts.map +1 -1
  150. package/dist/commands/sort.js +4 -2
  151. package/dist/commands/source.d.ts.map +1 -1
  152. package/dist/commands/source.js +5 -2
  153. package/dist/commands/sudo.js +1 -1
  154. package/dist/commands/tar.d.ts.map +1 -1
  155. package/dist/commands/tar.js +11 -3
  156. package/dist/commands/tee.d.ts.map +1 -1
  157. package/dist/commands/tee.js +8 -6
  158. package/dist/commands/test.d.ts.map +1 -1
  159. package/dist/commands/test.js +46 -24
  160. package/dist/commands/tr.d.ts.map +1 -1
  161. package/dist/commands/tr.js +3 -1
  162. package/dist/commands/true.d.ts +4 -0
  163. package/dist/commands/true.d.ts.map +1 -0
  164. package/dist/commands/true.js +14 -0
  165. package/dist/commands/type.d.ts.map +1 -1
  166. package/dist/commands/type.js +1 -1
  167. package/dist/commands/uname.d.ts.map +1 -1
  168. package/dist/commands/uname.js +4 -1
  169. package/dist/commands/uniq.d.ts.map +1 -1
  170. package/dist/commands/uptime.d.ts.map +1 -1
  171. package/dist/commands/uptime.js +4 -1
  172. package/dist/commands/wget.d.ts.map +1 -1
  173. package/dist/commands/wget.js +32 -7
  174. package/dist/commands/which.d.ts.map +1 -1
  175. package/dist/commands/xargs.d.ts.map +1 -1
  176. package/dist/commands/xargs.js +1 -1
  177. package/dist/index.d.ts +15 -14
  178. package/dist/index.d.ts.map +1 -1
  179. package/dist/index.js +9 -9
  180. package/dist/modules/linuxRootfs.d.ts +18 -1
  181. package/dist/modules/linuxRootfs.d.ts.map +1 -1
  182. package/dist/modules/linuxRootfs.js +160 -17
  183. package/dist/standalone-wo-sftp.d.ts +2 -0
  184. package/dist/standalone-wo-sftp.d.ts.map +1 -0
  185. package/dist/standalone-wo-sftp.js +30 -0
  186. package/dist/utils/expand.d.ts +50 -0
  187. package/dist/utils/expand.d.ts.map +1 -0
  188. package/dist/utils/expand.js +183 -0
  189. package/dist/utils/vfsDiff.d.ts +90 -0
  190. package/dist/utils/vfsDiff.d.ts.map +1 -0
  191. package/dist/utils/vfsDiff.js +177 -0
  192. package/package.json +2 -1
  193. package/src/SSHMimic/exec.ts +10 -1
  194. package/src/SSHMimic/executor.ts +104 -18
  195. package/src/SSHMimic/index.ts +49 -15
  196. package/src/VirtualFileSystem/binaryPack.ts +35 -8
  197. package/src/VirtualFileSystem/index.ts +78 -28
  198. package/src/VirtualPackageManager/index.ts +208 -49
  199. package/src/VirtualShell/index.ts +35 -7
  200. package/src/VirtualShell/shell.ts +23 -3
  201. package/src/VirtualShell/shellParser.ts +134 -36
  202. package/src/VirtualUserManager/index.ts +7 -2
  203. package/src/commands/adduser.ts +6 -0
  204. package/src/commands/alias.ts +5 -1
  205. package/src/commands/apt.ts +47 -17
  206. package/src/commands/awk.ts +20 -6
  207. package/src/commands/base64.ts +13 -2
  208. package/src/commands/cat.ts +13 -5
  209. package/src/commands/cd.ts +5 -0
  210. package/src/commands/chmod.ts +5 -0
  211. package/src/commands/cp.ts +5 -0
  212. package/src/commands/curl.ts +56 -12
  213. package/src/commands/cut.ts +8 -1
  214. package/src/commands/date.ts +7 -1
  215. package/src/commands/declare.ts +44 -0
  216. package/src/commands/diff.ts +17 -3
  217. package/src/commands/dpkg.ts +33 -11
  218. package/src/commands/du.ts +17 -5
  219. package/src/commands/echo.ts +22 -9
  220. package/src/commands/env.ts +11 -1
  221. package/src/commands/exit.ts +12 -2
  222. package/src/commands/export.ts +3 -1
  223. package/src/commands/find.ts +5 -0
  224. package/src/commands/free.ts +9 -2
  225. package/src/commands/grep.ts +12 -2
  226. package/src/commands/gzip.ts +28 -4
  227. package/src/commands/head.ts +5 -0
  228. package/src/commands/help.ts +121 -47
  229. package/src/commands/history.ts +7 -2
  230. package/src/commands/hostname.ts +5 -0
  231. package/src/commands/id.ts +4 -1
  232. package/src/commands/index.ts +9 -360
  233. package/src/commands/ls.ts +5 -3
  234. package/src/commands/lsb-release.ts +8 -2
  235. package/src/commands/nano.ts +1 -1
  236. package/src/commands/neofetch.ts +1 -1
  237. package/src/commands/node.ts +341 -0
  238. package/src/commands/npm.ts +132 -0
  239. package/src/commands/ping.ts +6 -2
  240. package/src/commands/printf.ts +112 -0
  241. package/src/commands/ps.ts +21 -9
  242. package/src/commands/python.ts +2229 -0
  243. package/src/commands/read.ts +41 -0
  244. package/src/commands/registry.ts +244 -0
  245. package/src/commands/runtime.ts +353 -0
  246. package/src/commands/sed.ts +27 -9
  247. package/src/commands/set.ts +9 -3
  248. package/src/commands/sh.ts +159 -55
  249. package/src/commands/shift.ts +53 -0
  250. package/src/commands/sleep.ts +2 -1
  251. package/src/commands/sort.ts +10 -6
  252. package/src/commands/source.ts +15 -3
  253. package/src/commands/sudo.ts +1 -1
  254. package/src/commands/tar.ts +28 -7
  255. package/src/commands/tee.ts +7 -1
  256. package/src/commands/test.ts +61 -26
  257. package/src/commands/tr.ts +3 -1
  258. package/src/commands/true.ts +17 -0
  259. package/src/commands/type.ts +6 -3
  260. package/src/commands/uname.ts +5 -1
  261. package/src/commands/uniq.ts +8 -2
  262. package/src/commands/uptime.ts +4 -1
  263. package/src/commands/wget.ts +51 -12
  264. package/src/commands/which.ts +5 -2
  265. package/src/commands/xargs.ts +11 -2
  266. package/src/index.ts +23 -24
  267. package/src/modules/linuxRootfs.ts +233 -30
  268. package/src/standalone-wo-sftp.ts +38 -0
  269. package/src/utils/expand.ts +238 -0
  270. package/src/utils/vfsDiff.ts +275 -0
  271. package/standalone-wo-sftp.js +507 -0
  272. package/standalone-wo-sftp.js.map +7 -0
  273. package/standalone.js +253 -191
  274. package/standalone.js.map +4 -4
  275. package/tests/bun-test-shim.ts +9 -1
  276. package/tests/command-helpers.test.ts +1 -5
  277. package/tests/new-features.test.ts +415 -5
  278. package/tests/parser-executor.test.ts +27 -27
  279. package/tests/sftp.test.ts +122 -42
  280. package/tests/users.test.ts +23 -5
  281. package/CHANGELOG.md +0 -150
@@ -6,7 +6,11 @@ import type { ShellModule } from "../types/commands";
6
6
  * string =, !=, numeric -eq -ne -lt -le -gt -ge,
7
7
  * ! (negate), -a (and), -o (or).
8
8
  */
9
- function evalTest(tokens: string[], shell: import("../VirtualShell").VirtualShell, cwd: string): boolean {
9
+ function evalTest(
10
+ tokens: string[],
11
+ shell: import("../VirtualShell").VirtualShell,
12
+ cwd: string,
13
+ ): boolean {
10
14
  // When called via [ command, ] is the last arg — strip it
11
15
  // When called via test command, no brackets present
12
16
  if (tokens[tokens.length - 1] === "]") {
@@ -25,32 +29,53 @@ function evalTest(tokens: string[], shell: import("../VirtualShell").VirtualShel
25
29
  // Boolean -a / -o (simple left-right, no precedence)
26
30
  const andIdx = tokens.indexOf("-a");
27
31
  if (andIdx !== -1) {
28
- return evalTest(tokens.slice(0, andIdx), shell, cwd) &&
29
- evalTest(tokens.slice(andIdx + 1), shell, cwd);
32
+ return (
33
+ evalTest(tokens.slice(0, andIdx), shell, cwd) &&
34
+ evalTest(tokens.slice(andIdx + 1), shell, cwd)
35
+ );
30
36
  }
31
37
  const orIdx = tokens.indexOf("-o");
32
38
  if (orIdx !== -1) {
33
- return evalTest(tokens.slice(0, orIdx), shell, cwd) ||
34
- evalTest(tokens.slice(orIdx + 1), shell, cwd);
39
+ return (
40
+ evalTest(tokens.slice(0, orIdx), shell, cwd) ||
41
+ evalTest(tokens.slice(orIdx + 1), shell, cwd)
42
+ );
35
43
  }
36
44
 
37
45
  // Unary file tests
38
46
  if (tokens.length === 2) {
39
47
  const [flag, operand = ""] = tokens;
40
- const resolvePath = (p: string) => p.startsWith("/") ? p : `${cwd}/${p}`.replace(/\/+/g, "/");
48
+ const resolvePath = (p: string) =>
49
+ p.startsWith("/") ? p : `${cwd}/${p}`.replace(/\/+/g, "/");
41
50
  const path = resolvePath(operand);
42
51
 
43
52
  switch (flag) {
44
- case "-e": return shell.vfs.exists(path);
45
- case "-f": return shell.vfs.exists(path) && shell.vfs.stat(path).type === "file";
46
- case "-d": return shell.vfs.exists(path) && shell.vfs.stat(path).type === "directory";
47
- case "-r": return shell.vfs.exists(path); // all readable in virtual env
48
- case "-w": return shell.vfs.exists(path);
49
- case "-x": return shell.vfs.exists(path) && !!(shell.vfs.stat(path).mode & 0o111);
50
- case "-s": return shell.vfs.exists(path) && shell.vfs.stat(path).type === "file" && (shell.vfs.stat(path) as import("../types/vfs").VfsFileNode).size > 0;
51
- case "-z": return operand.length === 0;
52
- case "-n": return operand.length > 0;
53
- case "-L": return shell.vfs.isSymlink(path);
53
+ case "-e":
54
+ return shell.vfs.exists(path);
55
+ case "-f":
56
+ return shell.vfs.exists(path) && shell.vfs.stat(path).type === "file";
57
+ case "-d":
58
+ return (
59
+ shell.vfs.exists(path) && shell.vfs.stat(path).type === "directory"
60
+ );
61
+ case "-r":
62
+ return shell.vfs.exists(path); // all readable in virtual env
63
+ case "-w":
64
+ return shell.vfs.exists(path);
65
+ case "-x":
66
+ return shell.vfs.exists(path) && !!(shell.vfs.stat(path).mode & 0o111);
67
+ case "-s":
68
+ return (
69
+ shell.vfs.exists(path) &&
70
+ shell.vfs.stat(path).type === "file" &&
71
+ (shell.vfs.stat(path) as import("../types/vfs").VfsFileNode).size > 0
72
+ );
73
+ case "-z":
74
+ return operand.length === 0;
75
+ case "-n":
76
+ return operand.length > 0;
77
+ case "-L":
78
+ return shell.vfs.isSymlink(path);
54
79
  }
55
80
  }
56
81
 
@@ -63,17 +88,27 @@ function evalTest(tokens: string[], shell: import("../VirtualShell").VirtualShel
63
88
  switch (op) {
64
89
  // String
65
90
  case "=":
66
- case "==": return left === right;
67
- case "!=": return left !== right;
68
- case "<": return left < right;
69
- case ">": return left > right;
91
+ case "==":
92
+ return left === right;
93
+ case "!=":
94
+ return left !== right;
95
+ case "<":
96
+ return left < right;
97
+ case ">":
98
+ return left > right;
70
99
  // Numeric
71
- case "-eq": return leftN === rightN;
72
- case "-ne": return leftN !== rightN;
73
- case "-lt": return leftN < rightN;
74
- case "-le": return leftN <= rightN;
75
- case "-gt": return leftN > rightN;
76
- case "-ge": return leftN >= rightN;
100
+ case "-eq":
101
+ return leftN === rightN;
102
+ case "-ne":
103
+ return leftN !== rightN;
104
+ case "-lt":
105
+ return leftN < rightN;
106
+ case "-le":
107
+ return leftN <= rightN;
108
+ case "-gt":
109
+ return leftN > rightN;
110
+ case "-ge":
111
+ return leftN >= rightN;
77
112
  }
78
113
  }
79
114
 
@@ -16,7 +16,9 @@ export const trCommand: ShellModule = {
16
16
  for (const c of set1) input = input.split(c).join("");
17
17
  } else if (set2) {
18
18
  for (let i = 0; i < set1.length; i++) {
19
- input = input.split(set1[i]!).join(set2[i] ?? set2[set2.length - 1] ?? "");
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,17 @@
1
+ import type { ShellModule } from "../types/commands";
2
+
3
+ export const trueCommand: ShellModule = {
4
+ name: "true",
5
+ description: "Return success exit code",
6
+ category: "shell",
7
+ params: [],
8
+ run: () => ({ exitCode: 0 }),
9
+ };
10
+
11
+ export const falseCommand: ShellModule = {
12
+ name: "false",
13
+ description: "Return failure exit code",
14
+ category: "shell",
15
+ params: [],
16
+ run: () => ({ exitCode: 1 }),
17
+ };
@@ -1,5 +1,5 @@
1
- import { resolveModule } from ".";
2
1
  import type { ShellModule } from "../types/commands";
2
+ import { resolveModule } from "./registry";
3
3
 
4
4
  export const typeCommand: ShellModule = {
5
5
  name: "type",
@@ -7,9 +7,12 @@ export const typeCommand: ShellModule = {
7
7
  category: "shell",
8
8
  params: ["<command...>"],
9
9
  run: ({ args, shell, env }) => {
10
- if (args.length === 0) return { stderr: "type: missing argument", exitCode: 1 };
10
+ if (args.length === 0)
11
+ return { stderr: "type: missing argument", exitCode: 1 };
11
12
 
12
- const pathDirs = (env?.vars?.PATH ?? "/usr/local/bin:/usr/bin:/bin").split(":");
13
+ const pathDirs = (env?.vars?.PATH ?? "/usr/local/bin:/usr/bin:/bin").split(
14
+ ":",
15
+ );
13
16
  const lines: string[] = [];
14
17
  let exitCode = 0;
15
18
 
@@ -12,7 +12,11 @@ export const unameCommand: ShellModule = {
12
12
  const release = shell.properties?.kernel ?? "5.15.0";
13
13
  const machine = shell.properties?.arch ?? "x86_64";
14
14
  const hostname = shell.hostname;
15
- if (all) return { stdout: `${sysname} ${hostname} ${release} #1 SMP ${machine} GNU/Linux`, exitCode: 0 };
15
+ if (all)
16
+ return {
17
+ stdout: `${sysname} ${hostname} ${release} #1 SMP ${machine} GNU/Linux`,
18
+ exitCode: 0,
19
+ };
16
20
  if (ifFlag(args, ["-r"])) return { stdout: release, exitCode: 0 };
17
21
  if (ifFlag(args, ["-m"])) return { stdout: machine, exitCode: 0 };
18
22
  return { stdout: sysname, exitCode: 0 };
@@ -18,8 +18,14 @@ export const uniqCommand: ShellModule = {
18
18
  while (j < lines.length && lines[j] === lines[i]) j++;
19
19
  const n = j - i;
20
20
  const line = lines[i]!;
21
- if (dupOnly && n === 1) { i = j; continue; }
22
- if (uniqOnly && n > 1) { i = j; continue; }
21
+ if (dupOnly && n === 1) {
22
+ i = j;
23
+ continue;
24
+ }
25
+ if (uniqOnly && n > 1) {
26
+ i = j;
27
+ continue;
28
+ }
23
29
  out.push(count ? `${String(n).padStart(4)} ${line}` : line);
24
30
  i = j;
25
31
  }
@@ -17,7 +17,10 @@ export const uptimeCommand: ShellModule = {
17
17
 
18
18
  if (since) {
19
19
  return {
20
- stdout: new Date(shell.startTime).toISOString().slice(0, 19).replace("T", " "),
20
+ stdout: new Date(shell.startTime)
21
+ .toISOString()
22
+ .slice(0, 19)
23
+ .replace("T", " "),
21
24
  exitCode: 0,
22
25
  };
23
26
  }
@@ -9,7 +9,16 @@ export const wgetCommand: ShellModule = {
9
9
  params: ["[options] <url>"],
10
10
  run: async ({ authUser, cwd, args, shell }) => {
11
11
  const { flagsWithValues, positionals } = parseArgs(args, {
12
- flagsWithValue: ["-O", "--output-document", "-o", "--output-file", "-P", "--directory-prefix", "--tries", "--timeout"],
12
+ flagsWithValue: [
13
+ "-O",
14
+ "--output-document",
15
+ "-o",
16
+ "--output-file",
17
+ "-P",
18
+ "--directory-prefix",
19
+ "--tries",
20
+ "--timeout",
21
+ ],
13
22
  });
14
23
 
15
24
  if (ifFlag(args, ["-h", "--help"])) {
@@ -29,18 +38,32 @@ export const wgetCommand: ShellModule = {
29
38
  }
30
39
 
31
40
  if (ifFlag(args, ["-V", "--version"])) {
32
- return { stdout: "GNU Wget 1.21.3 (virtual) built on Fortune GNU/Linux.", exitCode: 0 };
41
+ return {
42
+ stdout: "GNU Wget 1.21.3 (virtual) built on Fortune GNU/Linux.",
43
+ exitCode: 0,
44
+ };
33
45
  }
34
46
 
35
47
  const url = positionals[0];
36
- if (!url) return { stderr: "wget: missing URL\nUsage: wget [OPTION]... [URL]...", exitCode: 1 };
48
+ if (!url)
49
+ return {
50
+ stderr: "wget: missing URL\nUsage: wget [OPTION]... [URL]...",
51
+ exitCode: 1,
52
+ };
37
53
 
38
- const outputArg = flagsWithValues.get("-O") ?? flagsWithValues.get("--output-document") ?? null;
39
- const dirPrefix = flagsWithValues.get("-P") ?? flagsWithValues.get("--directory-prefix") ?? null;
54
+ const outputArg =
55
+ flagsWithValues.get("-O") ??
56
+ flagsWithValues.get("--output-document") ??
57
+ null;
58
+ const dirPrefix =
59
+ flagsWithValues.get("-P") ??
60
+ flagsWithValues.get("--directory-prefix") ??
61
+ null;
40
62
  const quiet = ifFlag(args, ["-q", "--quiet"]);
41
63
 
42
64
  // Derive target filename
43
- const filename = outputArg === "-" ? null : (outputArg ?? stripUrlFilename(url));
65
+ const filename =
66
+ outputArg === "-" ? null : (outputArg ?? stripUrlFilename(url));
44
67
  const targetPath = filename
45
68
  ? resolvePath(cwd, dirPrefix ? `${dirPrefix}/${filename}` : filename)
46
69
  : null;
@@ -56,7 +79,9 @@ export const wgetCommand: ShellModule = {
56
79
 
57
80
  let response: Response;
58
81
  try {
59
- response = await fetch(url, { headers: { "User-Agent": "Wget/1.21.3 (Fortune GNU/Linux)" } });
82
+ response = await fetch(url, {
83
+ headers: { "User-Agent": "Wget/1.21.3 (Fortune GNU/Linux)" },
84
+ });
60
85
  } catch (err) {
61
86
  const msg = err instanceof Error ? err.message : String(err);
62
87
  stderrLines.push(`wget: unable to resolve host: ${msg}`);
@@ -69,22 +94,36 @@ export const wgetCommand: ShellModule = {
69
94
  }
70
95
 
71
96
  let body: string;
72
- try { body = await response.text(); } catch { return { stderr: "wget: failed to read response", exitCode: 1 }; }
97
+ try {
98
+ body = await response.text();
99
+ } catch {
100
+ return { stderr: "wget: failed to read response", exitCode: 1 };
101
+ }
73
102
 
74
103
  if (!quiet) {
75
- const ct = response.headers.get("content-type") ?? "application/octet-stream";
76
- stderrLines.push(`HTTP request sent, awaiting response... ${response.status} ${response.statusText}`);
104
+ const ct =
105
+ response.headers.get("content-type") ?? "application/octet-stream";
106
+ stderrLines.push(
107
+ `HTTP request sent, awaiting response... ${response.status} ${response.statusText}`,
108
+ );
77
109
  stderrLines.push(`Length: ${body.length} [${ct}]`);
78
110
  }
79
111
 
80
112
  // Output to stdout (pipe) or file
81
113
  if (outputArg === "-") {
82
- return { stdout: body, stderr: stderrLines.join("\n") || undefined, exitCode: 0 };
114
+ return {
115
+ stdout: body,
116
+ stderr: stderrLines.join("\n") || undefined,
117
+ exitCode: 0,
118
+ };
83
119
  }
84
120
 
85
121
  if (targetPath) {
86
122
  shell.writeFileAsUser(authUser, targetPath, body);
87
- if (!quiet) stderrLines.push(`Saving to: '${targetPath}'\n${targetPath} 100%[==================>] ${body.length} B`);
123
+ if (!quiet)
124
+ stderrLines.push(
125
+ `Saving to: '${targetPath}'\n${targetPath} 100%[==================>] ${body.length} B`,
126
+ );
88
127
  return { stderr: stderrLines.join("\n") || undefined, exitCode: 0 };
89
128
  }
90
129
 
@@ -6,9 +6,12 @@ export const whichCommand: ShellModule = {
6
6
  category: "shell",
7
7
  params: ["<command...>"],
8
8
  run: ({ args, shell, env }) => {
9
- if (args.length === 0) return { stderr: "which: missing argument", exitCode: 1 };
9
+ if (args.length === 0)
10
+ return { stderr: "which: missing argument", exitCode: 1 };
10
11
 
11
- const pathDirs = (env?.vars?.PATH ?? "/usr/local/bin:/usr/bin:/bin").split(":");
12
+ const pathDirs = (env?.vars?.PATH ?? "/usr/local/bin:/usr/bin:/bin").split(
13
+ ":",
14
+ );
12
15
  const lines: string[] = [];
13
16
  let anyMissing = false;
14
17
 
@@ -1,5 +1,5 @@
1
1
  import type { ShellModule } from "../types/commands";
2
- import { runCommand } from "./index";
2
+ import { runCommand } from "./runtime";
3
3
 
4
4
  export const xargsCommand: ShellModule = {
5
5
  name: "xargs",
@@ -12,6 +12,15 @@ export const xargsCommand: ShellModule = {
12
12
  const items = (stdin ?? "").trim().split(/\s+/).filter(Boolean);
13
13
  if (items.length === 0) return { exitCode: 0 };
14
14
  const fullCmd = [baseCmd, ...extraArgs, ...items].join(" ");
15
- return runCommand(fullCmd, authUser, hostname, mode, cwd, shell, undefined, env);
15
+ return runCommand(
16
+ fullCmd,
17
+ authUser,
18
+ hostname,
19
+ mode,
20
+ cwd,
21
+ shell,
22
+ undefined,
23
+ env,
24
+ );
16
25
  },
17
26
  };
package/src/index.ts CHANGED
@@ -1,14 +1,14 @@
1
- import { HoneyPot } from "./Honeypot/index";
2
- import { SshClient } from "./SSHClient/index";
3
- import { SftpMimic, SshMimic } from "./SSHMimic/index";
4
- import VirtualFileSystem from "./VirtualFileSystem/index";
5
- import { VirtualShell } from "./VirtualShell/index";
6
- import { VirtualUserManager } from "./VirtualUserManager/index";
7
- import { VirtualPackageManager } from "./VirtualPackageManager/index";
1
+ export { HoneyPot } from "./Honeypot/index";
2
+ export { SshClient } from "./SSHClient/index";
3
+ export { SftpMimic as VirtualSftpServer, SshMimic as VirtualSshServer } from "./SSHMimic/index";
4
+ export { default as VirtualFileSystem } from "./VirtualFileSystem/index";
5
+ export { VirtualPackageManager } from "./VirtualPackageManager/index";
6
+ export { VirtualShell } from "./VirtualShell/index";
7
+ export { VirtualUserManager } from "./VirtualUserManager/index";
8
8
 
9
9
  export type {
10
10
  AuditLogEntry,
11
- HoneyPotStats,
11
+ HoneyPotStats
12
12
  } from "./Honeypot/index";
13
13
  export type {
14
14
  CommandContext,
@@ -18,9 +18,8 @@ export type {
18
18
  NanoEditorSession,
19
19
  ShellEnv,
20
20
  ShellModule,
21
- SudoChallenge,
21
+ SudoChallenge
22
22
  } from "./types/commands";
23
- export type { ShellProperties } from "./VirtualShell/index";
24
23
  export type { ExecStream, ShellStream } from "./types/streams";
25
24
  export type {
26
25
  RemoveOptions,
@@ -34,29 +33,29 @@ export type {
34
33
  VfsSnapshotDirectoryNode,
35
34
  VfsSnapshotFileNode,
36
35
  VfsSnapshotNode,
37
- WriteFileOptions,
36
+ WriteFileOptions
38
37
  } from "./types/vfs";
39
38
  export type { VfsOptions, VfsPersistenceMode } from "./VirtualFileSystem/index";
39
+ export type { ShellProperties } from "./VirtualShell/index";
40
40
 
41
41
  export type {
42
- PackageDefinition,
43
- PackageFile,
44
- InstalledPackage,
42
+ InstalledPackage, PackageDefinition,
43
+ PackageFile
45
44
  } from "./VirtualPackageManager/index";
46
45
 
47
46
  export {
48
- HoneyPot,
49
- SshClient,
50
- VirtualFileSystem,
51
- SftpMimic as VirtualSftpServer,
52
- VirtualShell,
53
- SshMimic as VirtualSshServer,
54
- VirtualUserManager,
55
- VirtualPackageManager,
56
- };
47
+ assertDiff, diffSnapshots,
48
+ formatDiff
49
+ } from "./utils/vfsDiff";
50
+ export type {
51
+ VfsDiff,
52
+ VfsDiffEntry,
53
+ VfsDiffModified
54
+ } from "./utils/vfsDiff";
57
55
 
58
56
  export {
59
57
  getArg,
60
58
  getFlag,
61
- ifFlag,
59
+ ifFlag
62
60
  } from "./commands/command-helpers";
61
+