typescript-virtual-container 1.4.2 → 1.4.3

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 (48) hide show
  1. package/README.md +72 -35
  2. package/builds/self-standalone.js +160 -160
  3. package/builds/self-standalone.js.map +4 -4
  4. package/builds/standalone-wo-sftp.js +18 -18
  5. package/builds/standalone-wo-sftp.js.map +3 -3
  6. package/builds/standalone.js +46 -46
  7. package/builds/standalone.js.map +3 -3
  8. package/dist/VirtualFileSystem/index.d.ts +47 -0
  9. package/dist/VirtualFileSystem/index.d.ts.map +1 -1
  10. package/dist/VirtualFileSystem/index.js +159 -0
  11. package/dist/VirtualShell/index.d.ts +29 -0
  12. package/dist/VirtualShell/index.d.ts.map +1 -1
  13. package/dist/VirtualShell/index.js +29 -0
  14. package/dist/VirtualShell/shellParser.js +28 -1
  15. package/dist/commands/export.d.ts.map +1 -1
  16. package/dist/commands/export.js +5 -3
  17. package/dist/commands/registry.d.ts.map +1 -1
  18. package/dist/commands/registry.js +2 -0
  19. package/dist/commands/runtime.d.ts.map +1 -1
  20. package/dist/commands/runtime.js +28 -3
  21. package/dist/commands/seq.d.ts +4 -0
  22. package/dist/commands/seq.d.ts.map +1 -0
  23. package/dist/commands/seq.js +50 -0
  24. package/dist/commands/sh.d.ts +0 -6
  25. package/dist/commands/sh.d.ts.map +1 -1
  26. package/dist/commands/sh.js +153 -10
  27. package/dist/types/pipeline.d.ts +6 -0
  28. package/dist/types/pipeline.d.ts.map +1 -1
  29. package/dist/types/vfs.d.ts +15 -0
  30. package/dist/types/vfs.d.ts.map +1 -1
  31. package/dist/utils/expand.d.ts +9 -0
  32. package/dist/utils/expand.d.ts.map +1 -1
  33. package/dist/utils/expand.js +84 -2
  34. package/dist/utils/tokenize.d.ts.map +1 -1
  35. package/dist/utils/tokenize.js +40 -0
  36. package/package.json +1 -1
  37. package/src/VirtualFileSystem/index.ts +164 -1
  38. package/src/VirtualShell/index.ts +36 -0
  39. package/src/VirtualShell/shellParser.ts +26 -1
  40. package/src/commands/export.ts +5 -3
  41. package/src/commands/registry.ts +2 -0
  42. package/src/commands/runtime.ts +30 -3
  43. package/src/commands/seq.ts +43 -0
  44. package/src/commands/sh.ts +144 -19
  45. package/src/types/pipeline.ts +6 -0
  46. package/src/types/vfs.ts +17 -0
  47. package/src/utils/expand.ts +75 -2
  48. package/src/utils/tokenize.ts +20 -0
package/README.md CHANGED
@@ -24,6 +24,7 @@
24
24
  - [`VirtualSftpServer`](#virtualsftpserver)
25
25
  - [`VirtualShell`](#virtualshell)
26
26
  - [`VirtualFileSystem`](#virtualfilesystem)
27
+ - [Mount API](#mount-api)
27
28
  - [`VirtualUserManager`](#virtualusermanager)
28
29
  - [`VirtualPackageManager`](#virtualpackagemanager)
29
30
  - [Snapshot Diff Tooling](#snapshot-diff-tooling)
@@ -53,7 +54,7 @@
53
54
  | Mode | Entry point | Use case |
54
55
  |------|-------------|----------|
55
56
  | **SSH/SFTP server** | `VirtualSshServer` / `VirtualSftpServer` | Honeypots, remote testing, training environments |
56
- | **Web shell** | `builds/web.min.js` (browser bundle) | Embedded terminals, interactive tutorials, browser demos |
57
+ | **Web shell** | `builds/web.min.js` / `builds/web-full-api.min.js` (ESM) | Embedded terminals, interactive tutorials, browser demos |
57
58
  | **Standalone CLI** | `builds/self-standalone.js` (single file) | Local shell, one-liner demos, no install required |
58
59
 
59
60
  All three modes share the same core: a pure in-memory VFS, a real shell interpreter, a virtual package manager, and a typed programmatic API.
@@ -111,24 +112,22 @@ await ssh.start();
111
112
 
112
113
  ### Web shell (browser)
113
114
 
114
- Three browser bundles are available — pick the one that fits your deployment:
115
+ Two browser bundles are available:
115
116
 
116
- | Bundle | Format | Entry | Use case |
117
- |--------|--------|-------|----------|
118
- | `builds/web.min.js` | ESM | `createWebShell()` | Local dev, modern bundlers |
119
- | `builds/web-iife.min.js` | IIFE (`WebShellLib`) | `WebShellLib.createWebShell()` | Cloudflare, CDN, reverse proxies |
120
- | `builds/web-full-api.min.js` | ESM | `createVirtualShellShim()` | API surface close to `VirtualShell` |
117
+ | Bundle | Format | Entry point | Use case |
118
+ |--------|--------|-------------|----------|
119
+ | `builds/web.min.js` | ESM | `createWebShell()` | Embedded terminals, modern bundlers |
120
+ | `builds/web-full-api.min.js` | ESM | `createVirtualShellShim()` | Full `VirtualShell`-like API in the browser |
121
121
 
122
- All bundles persist the VFS in **IndexedDB** — state survives page reloads.
122
+ Both bundles persist the VFS in **IndexedDB** — state survives page reloads.
123
123
 
124
124
  ```bash
125
- bun run web-build # → builds/web.min.js + examples/web.min.js
126
- bun run web-build-iife # → builds/web-iife.min.js
127
- bun run web-full-build # builds/web-full-api.min.js
128
- bun run build-all # rebuild everything
125
+ bun run web-build # → builds/web.min.js + examples/web.min.js
126
+ bun run web-full-build # → builds/web-full-api.min.js
127
+ bun run build-all # rebuild everything
129
128
  ```
130
129
 
131
- **ESM (`web.min.js`)**
130
+ **`web.min.js`** — lightweight shell with IndexedDB VFS:
132
131
 
133
132
  ```html
134
133
  <script type="module">
@@ -144,19 +143,7 @@ bun run build-all # rebuild everything
144
143
  </script>
145
144
  ```
146
145
 
147
- **IIFE (`web-iife.min.js`)**no `type="module"` needed, works through Cloudflare:
148
-
149
- ```html
150
- <script src="./builds/web-iife.min.js"></script>
151
- <script>
152
- const shell = WebShellLib.createWebShell("web-vm");
153
- shell.ensureInitialized().then(() =>
154
- shell.executeCommandLine("whoami").then(r => console.log(r.stdout))
155
- );
156
- </script>
157
- ```
158
-
159
- **Full API shim (`web-full-api.min.js`)** — mirrors the `VirtualShell` programmatic API:
146
+ **`web-full-api.min.js`**mirrors the `VirtualShell` programmatic API:
160
147
 
161
148
  ```html
162
149
  <script type="module">
@@ -165,8 +152,7 @@ bun run build-all # rebuild everything
165
152
  const shell = createVirtualShellShim("web-vm");
166
153
  await shell.ensureInitialized();
167
154
  await shell.executeCommandLine("mkdir -p /app && echo hello > /app/file.txt");
168
- const vfs = shell.getVfs();
169
- console.log(vfs.readFile("/app/file.txt")); // hello
155
+ console.log(shell.getVfs().readFile("/app/file.txt")); // hello
170
156
  </script>
171
157
  ```
172
158
 
@@ -174,8 +160,7 @@ bun run build-all # rebuild everything
174
160
 
175
161
  ```bash
176
162
  bun run example-serve
177
- # Open http://localhost:8787/index.html (ESM)
178
- # or http://localhost:8787/index-cf.html (IIFE, Cloudflare-compatible)
163
+ # Open http://localhost:8787/index.html
179
164
  ```
180
165
 
181
166
  ### Programmatic API
@@ -327,6 +312,9 @@ interface ShellProperties {
327
312
  | `writeFileAsUser(authUser, path, content)` | Write with quota enforcement. |
328
313
  | `refreshProcFs(): void` | Refresh all `/proc/*` files (uptime, meminfo, cpuinfo, per-pid). |
329
314
  | `refreshProcSessions(): void` | Lightweight refresh of `/proc/<pid>` and `/proc/self` only. |
315
+ | `mount(vPath, hostPath, options?): void` | Mount a host directory into the VFS. See [Mount API](#mount-api). |
316
+ | `unmount(vPath): void` | Remove a host directory mount. |
317
+ | `getMounts()` | List all active mounts as `{ vPath, hostPath, readOnly }[]`. |
330
318
  | `syncPasswd(): void` | Sync `/etc/passwd`, `/etc/group`, `/etc/shadow` from user manager. |
331
319
  | `getVfs(): VirtualFileSystem \| null` | Access VFS instance. |
332
320
  | `getUsers(): VirtualUserManager \| null` | Access user manager. |
@@ -398,6 +386,40 @@ await vfs.flushMirror(); // save to disk
398
386
 
399
387
  **Events:** `file:write { path, size }`, `file:read { path, size }`, `dir:create { path, mode }`, `node:remove { path }`, `symlink:create { link, target }`, `snapshot:import`, `snapshot:restore { path }`, `mirror:flush { path? }`
400
388
 
389
+
390
+ #### Mount API
391
+
392
+ Mount a host directory inside the VM — all standard VFS operations (`readFile`, `writeFile`, `exists`, `stat`, `list`) are transparently delegated to the host filesystem.
393
+
394
+ > **Node.js only.** In browser environments `mount()` is a silent no-op — the `vPath` remains an empty in-memory directory.
395
+
396
+ ```typescript
397
+ // Read-only mount (default) — shell commands can read host files
398
+ shell.mount("/workspace", "./my-project");
399
+
400
+ // Read-write mount — shell commands can also write back to the host
401
+ shell.mount("/data", "./data", { readOnly: false });
402
+
403
+ // Unmount — delegation removed, vPath stays as an empty VFS directory
404
+ shell.unmount("/workspace");
405
+
406
+ // Introspect
407
+ shell.getMounts();
408
+ // → [{ vPath: "/workspace", hostPath: "/abs/path/my-project", readOnly: true }]
409
+ ```
410
+
411
+ Direct VFS usage:
412
+
413
+ ```typescript
414
+ shell.vfs.mount("/workspace", "./my-project");
415
+ shell.vfs.unmount("/workspace");
416
+ shell.vfs.getMounts();
417
+ ```
418
+
419
+ **Events:** `mount { vPath, hostPath, readOnly }`, `unmount { vPath }`
420
+
421
+ **Snapshot behaviour:** mounted files are **not** included in `toSnapshot()` — only the in-memory VFS tree is serialised. The mount configuration itself is also not persisted; restore it after each `fromSnapshot()` or `restoreMirror()`.
422
+
401
423
  #### VFSB Binary Format
402
424
 
403
425
  In `"fs"` mode, state is persisted as a compact binary file (`vfs-snapshot.vfsb`).
@@ -654,6 +676,17 @@ interface VirtualActiveSession {
654
676
  remoteAddress: string;
655
677
  startedAt: string; // ISO-8601
656
678
  }
679
+
680
+ /** Returned by adduser, passwd, deluser — triggers interactive password prompt in the terminal. */
681
+ interface PasswordChallenge {
682
+ preamble?: string; // Lines printed before the first prompt
683
+ prompt: string; // e.g. "New password: "
684
+ confirmPrompt?: string; // Second prompt for confirmation
685
+ confirmText?: string; // Destructive confirmation prompt (y/N)
686
+ action: "adduser" | "passwd" | "deluser" | "su";
687
+ targetUsername: string;
688
+ newUsername?: string; // adduser only
689
+ }
657
690
  ```
658
691
 
659
692
  ---
@@ -932,7 +965,7 @@ echo "Welcome back, root!"
932
965
  <details>
933
966
  <summary><strong>Built-in Commands (91)</strong></summary>
934
967
 
935
- Type `help` in the shell for a grouped, colorized listing. Type `help <command>` for detailed usage.
968
+ Type `help` in the shell for a grouped, colorized listing. Type `help <command>` for detailed usage. Type `man <command>` for full manual pages — all 91 commands are documented.
936
969
 
937
970
  ### Navigation
938
971
 
@@ -1440,13 +1473,17 @@ Open:
1440
1473
  - [x] Pure in-memory VFS · symlinks · binary snapshot format (VFSB, ~27% smaller than JSON+base64)
1441
1474
  - [x] Linux rootfs on boot — `/etc`, `/proc`, `/sys`, `/dev`, `/usr`, `/var`
1442
1475
  - [x] Virtual package manager — `apt`/`dpkg`, 25 packages, VFS file writes
1443
- - [x] 91 built-in commands across 9 categories
1444
- - [x] Real shell interpreter — `if`/`for`/`while`/`case`/functions, `$(cmd)`, `$((expr))`, `${#VAR}`, single-quote isolation
1476
+ - [x] 92 built-in commands across 9 categories (`seq` added)
1477
+ - [x] Real shell interpreter — `if`/`for`/`while`/`case`/functions, `$(cmd)`, `$((expr))`, `${#VAR}`, `{a,b,c}` brace expansion, `{1..N}` ranges, `2>/dev/null` stderr redirect, `2>&1`, `(( x++ ))`
1445
1478
  - [x] `curl`/`wget` as pure `fetch()` · VFS PATH resolution · `/sbin` root-only
1446
1479
  - [x] `/proc/self` and `/proc/<pid>` per-session entries
1447
1480
  - [x] Snapshot diff tooling — `diffSnapshots`, `formatDiff`, `assertDiff`
1448
1481
  - [x] `node`/`python3`/`npm`/`npx` — package-gated virtual REPL stubs
1449
- - [x] Web shell bundle (`web.min.js`) — fully browser-native with IndexedDB VFS
1450
- - [x] Self-standalone CLI (`self-standalone.js`) — single-file interactive shell, no install
1482
+ - [x] Web shell bundles (`web.min.js`, `web-full-api.min.js`) — fully browser-native with IndexedDB VFS
1483
+ - [x] Self-standalone CLI (`self-standalone.js`) — single-file interactive shell, per-user history, tab completion
1484
+ - [x] 120+ `man` pages — all built-in commands documented via `man <cmd>`
1485
+ - [x] Shared `tokenize.ts` — unified tokenizer for shell parser and runtime (eliminates duplication)
1486
+ - [x] `PasswordChallenge` type — generic interactive password flow for `adduser`, `passwd`, `deluser`
1487
+ - [x] `VirtualFileSystem.mount(vPath, hostPath, { readOnly })` — bind-mount host directories into the VM; read-only by default; browser-safe (silent no-op)
1451
1488
 
1452
1489
  </details>