typescript-virtual-container 1.5.5 → 1.5.6
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 +106 -32
- package/dist/.tsbuildinfo +1 -1
- package/dist/commands/awk.d.ts +6 -11
- package/dist/commands/awk.js +462 -109
- package/dist/commands/bzip2.d.ts +11 -0
- package/dist/commands/bzip2.js +91 -0
- package/dist/commands/find.d.ts +2 -2
- package/dist/commands/find.js +212 -37
- package/dist/commands/lsof.d.ts +6 -0
- package/dist/commands/lsof.js +30 -0
- package/dist/commands/perl.d.ts +6 -0
- package/dist/commands/perl.js +76 -0
- package/dist/commands/registry.js +13 -0
- package/dist/commands/sed.d.ts +2 -2
- package/dist/commands/sed.js +216 -34
- package/dist/commands/sh.js +42 -0
- package/dist/commands/strace.d.ts +6 -0
- package/dist/commands/strace.js +26 -0
- package/dist/commands/tar.d.ts +2 -1
- package/dist/commands/tar.js +138 -52
- package/dist/commands/zip.d.ts +11 -0
- package/dist/commands/zip.js +232 -0
- package/dist/modules/linuxRootfs.js +1 -1
- package/dist/utils/expand.js +64 -0
- package/package.json +5 -4
- package/dist/self-standalone.d.ts +0 -1
- package/dist/self-standalone.js +0 -444
- package/dist/standalone-wo-sftp.d.ts +0 -1
- package/dist/standalone-wo-sftp.js +0 -30
- package/dist/standalone.d.ts +0 -1
- package/dist/standalone.js +0 -61
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { deflateSync, inflateSync } from "fflate";
|
|
2
|
+
import { resolvePath } from "./helpers";
|
|
3
|
+
// ── CRC32 ─────────────────────────────────────────────────────────────────────
|
|
4
|
+
const CRC_TABLE = (() => {
|
|
5
|
+
const t = new Uint32Array(256);
|
|
6
|
+
for (let i = 0; i < 256; i++) {
|
|
7
|
+
let c = i;
|
|
8
|
+
for (let j = 0; j < 8; j++)
|
|
9
|
+
c = c & 1 ? (0xedb88320 ^ (c >>> 1)) : (c >>> 1);
|
|
10
|
+
t[i] = c;
|
|
11
|
+
}
|
|
12
|
+
return t;
|
|
13
|
+
})();
|
|
14
|
+
function crc32(buf) {
|
|
15
|
+
let crc = 0xffffffff;
|
|
16
|
+
for (let i = 0; i < buf.length; i++)
|
|
17
|
+
crc = (CRC_TABLE[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8)) >>> 0;
|
|
18
|
+
return (crc ^ 0xffffffff) >>> 0;
|
|
19
|
+
}
|
|
20
|
+
// ── DOS date/time from JS Date ────────────────────────────────────────────────
|
|
21
|
+
function dosDateTime() {
|
|
22
|
+
const d = new Date();
|
|
23
|
+
const date = ((d.getFullYear() - 1980) << 9) | ((d.getMonth() + 1) << 5) | d.getDate();
|
|
24
|
+
const time = (d.getHours() << 11) | (d.getMinutes() << 5) | Math.floor(d.getSeconds() / 2);
|
|
25
|
+
return [time, date];
|
|
26
|
+
}
|
|
27
|
+
// ── ZIP builder ───────────────────────────────────────────────────────────────
|
|
28
|
+
function buildZip(entries) {
|
|
29
|
+
const parts = [];
|
|
30
|
+
const cdParts = [];
|
|
31
|
+
let offset = 0;
|
|
32
|
+
const [modTime, modDate] = dosDateTime();
|
|
33
|
+
for (const { name, content } of entries) {
|
|
34
|
+
const nameBuf = Buffer.from(name, "utf8");
|
|
35
|
+
const compressed = Buffer.from(deflateSync(content, { level: 6 }));
|
|
36
|
+
const useDeflate = compressed.length < content.length;
|
|
37
|
+
const stored = useDeflate ? compressed : content;
|
|
38
|
+
const crc = crc32(content);
|
|
39
|
+
const method = useDeflate ? 8 : 0;
|
|
40
|
+
// Local file header
|
|
41
|
+
const lfh = Buffer.alloc(30 + nameBuf.length);
|
|
42
|
+
lfh.writeUInt32LE(0x04034b50, 0);
|
|
43
|
+
lfh.writeUInt16LE(20, 4);
|
|
44
|
+
lfh.writeUInt16LE(0x0800, 6); // UTF-8 flag
|
|
45
|
+
lfh.writeUInt16LE(method, 8);
|
|
46
|
+
lfh.writeUInt16LE(modTime, 10);
|
|
47
|
+
lfh.writeUInt16LE(modDate, 12);
|
|
48
|
+
lfh.writeUInt32LE(crc, 14);
|
|
49
|
+
lfh.writeUInt32LE(stored.length, 18);
|
|
50
|
+
lfh.writeUInt32LE(content.length, 22);
|
|
51
|
+
lfh.writeUInt16LE(nameBuf.length, 26);
|
|
52
|
+
lfh.writeUInt16LE(0, 28);
|
|
53
|
+
nameBuf.copy(lfh, 30);
|
|
54
|
+
// Central directory entry
|
|
55
|
+
const cd = Buffer.alloc(46 + nameBuf.length);
|
|
56
|
+
cd.writeUInt32LE(0x02014b50, 0);
|
|
57
|
+
cd.writeUInt16LE(20, 4);
|
|
58
|
+
cd.writeUInt16LE(20, 6);
|
|
59
|
+
cd.writeUInt16LE(0x0800, 8);
|
|
60
|
+
cd.writeUInt16LE(method, 10);
|
|
61
|
+
cd.writeUInt16LE(modTime, 12);
|
|
62
|
+
cd.writeUInt16LE(modDate, 14);
|
|
63
|
+
cd.writeUInt32LE(crc, 16);
|
|
64
|
+
cd.writeUInt32LE(stored.length, 20);
|
|
65
|
+
cd.writeUInt32LE(content.length, 24);
|
|
66
|
+
cd.writeUInt16LE(nameBuf.length, 28);
|
|
67
|
+
cd.writeUInt16LE(0, 30); // extra
|
|
68
|
+
cd.writeUInt16LE(0, 32); // comment
|
|
69
|
+
cd.writeUInt16LE(0, 34); // disk start
|
|
70
|
+
cd.writeUInt16LE(0, 36); // int attr
|
|
71
|
+
cd.writeUInt32LE(0x81a40000, 38); // ext attr: -rw-r--r--
|
|
72
|
+
cd.writeUInt32LE(offset, 42);
|
|
73
|
+
nameBuf.copy(cd, 46);
|
|
74
|
+
parts.push(lfh, stored);
|
|
75
|
+
cdParts.push(cd);
|
|
76
|
+
offset += lfh.length + stored.length;
|
|
77
|
+
}
|
|
78
|
+
const cdBuf = Buffer.concat(cdParts);
|
|
79
|
+
const eocd = Buffer.alloc(22);
|
|
80
|
+
eocd.writeUInt32LE(0x06054b50, 0);
|
|
81
|
+
eocd.writeUInt16LE(0, 4);
|
|
82
|
+
eocd.writeUInt16LE(0, 6);
|
|
83
|
+
eocd.writeUInt16LE(entries.length, 8);
|
|
84
|
+
eocd.writeUInt16LE(entries.length, 10);
|
|
85
|
+
eocd.writeUInt32LE(cdBuf.length, 12);
|
|
86
|
+
eocd.writeUInt32LE(offset, 16);
|
|
87
|
+
eocd.writeUInt16LE(0, 20);
|
|
88
|
+
return Buffer.concat([...parts, cdBuf, eocd]);
|
|
89
|
+
}
|
|
90
|
+
// ── ZIP parser ────────────────────────────────────────────────────────────────
|
|
91
|
+
function parseZip(raw) {
|
|
92
|
+
const files = [];
|
|
93
|
+
let off = 0;
|
|
94
|
+
while (off + 4 <= raw.length) {
|
|
95
|
+
const sig = raw.readUInt32LE(off);
|
|
96
|
+
if (sig === 0x02014b50 || sig === 0x06054b50)
|
|
97
|
+
break; // central dir / EOCD
|
|
98
|
+
if (sig !== 0x04034b50) {
|
|
99
|
+
off++;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const method = raw.readUInt16LE(off + 8);
|
|
103
|
+
const compSize = raw.readUInt32LE(off + 18);
|
|
104
|
+
const uncompSize = raw.readUInt32LE(off + 22);
|
|
105
|
+
const nameLen = raw.readUInt16LE(off + 26);
|
|
106
|
+
const extraLen = raw.readUInt16LE(off + 28);
|
|
107
|
+
const name = raw.subarray(off + 30, off + 30 + nameLen).toString("utf8");
|
|
108
|
+
const dataOff = off + 30 + nameLen + extraLen;
|
|
109
|
+
const compData = raw.subarray(dataOff, dataOff + compSize);
|
|
110
|
+
let content;
|
|
111
|
+
if (method === 8) {
|
|
112
|
+
try {
|
|
113
|
+
content = Buffer.from(inflateSync(compData));
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
content = compData;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
content = compData;
|
|
121
|
+
}
|
|
122
|
+
if (name && !name.endsWith("/")) {
|
|
123
|
+
// Validate size
|
|
124
|
+
if (content.length === uncompSize || method !== 0)
|
|
125
|
+
files.push({ name, content });
|
|
126
|
+
else
|
|
127
|
+
files.push({ name, content });
|
|
128
|
+
}
|
|
129
|
+
off = dataOff + compSize;
|
|
130
|
+
}
|
|
131
|
+
return files;
|
|
132
|
+
}
|
|
133
|
+
// ── Commands ──────────────────────────────────────────────────────────────────
|
|
134
|
+
/**
|
|
135
|
+
* Create ZIP archives using real PKZIP format with DEFLATE compression.
|
|
136
|
+
* @category archive
|
|
137
|
+
*/
|
|
138
|
+
export const zipCommand = {
|
|
139
|
+
name: "zip",
|
|
140
|
+
description: "Package and compress files",
|
|
141
|
+
category: "archive",
|
|
142
|
+
params: ["[-r] <archive.zip> <file...>"],
|
|
143
|
+
run: ({ shell, cwd, args }) => {
|
|
144
|
+
const recursive = args.includes("-r") || args.includes("-R");
|
|
145
|
+
const files = args.filter((a) => !a.startsWith("-"));
|
|
146
|
+
const archiveArg = files[0];
|
|
147
|
+
const sources = files.slice(1);
|
|
148
|
+
if (!archiveArg)
|
|
149
|
+
return { stderr: "zip: no archive specified", exitCode: 1 };
|
|
150
|
+
if (sources.length === 0)
|
|
151
|
+
return { stderr: "zip: nothing to do!", exitCode: 12 };
|
|
152
|
+
const archivePath = resolvePath(cwd, archiveArg.endsWith(".zip") ? archiveArg : `${archiveArg}.zip`);
|
|
153
|
+
const entries = [];
|
|
154
|
+
const verboseLines = [];
|
|
155
|
+
for (const src of sources) {
|
|
156
|
+
const p = resolvePath(cwd, src);
|
|
157
|
+
if (!shell.vfs.exists(p))
|
|
158
|
+
return { stderr: `zip warning: name not matched: ${src}`, exitCode: 12 };
|
|
159
|
+
const st = shell.vfs.stat(p);
|
|
160
|
+
if (st.type === "file") {
|
|
161
|
+
const content = shell.vfs.readFileRaw(p);
|
|
162
|
+
entries.push({ name: src, content });
|
|
163
|
+
verboseLines.push(` adding: ${src} (deflated)`);
|
|
164
|
+
}
|
|
165
|
+
else if (recursive) {
|
|
166
|
+
const walk = (dir, prefix) => {
|
|
167
|
+
for (const e of shell.vfs.list(dir)) {
|
|
168
|
+
const full = `${dir}/${e}`, rel = `${prefix}/${e}`;
|
|
169
|
+
const s = shell.vfs.stat(full);
|
|
170
|
+
if (s.type === "directory")
|
|
171
|
+
walk(full, rel);
|
|
172
|
+
else {
|
|
173
|
+
const content = shell.vfs.readFileRaw(full);
|
|
174
|
+
entries.push({ name: rel, content });
|
|
175
|
+
verboseLines.push(` adding: ${rel} (deflated)`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
walk(p, src);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (entries.length === 0)
|
|
183
|
+
return { stderr: "zip: nothing to do!", exitCode: 12 };
|
|
184
|
+
const zipBuf = buildZip(entries);
|
|
185
|
+
shell.vfs.writeFile(archivePath, zipBuf);
|
|
186
|
+
return { stdout: verboseLines.join("\n"), exitCode: 0 };
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Extract ZIP archives (real PKZIP DEFLATE format).
|
|
191
|
+
* @category archive
|
|
192
|
+
*/
|
|
193
|
+
export const unzipCommand = {
|
|
194
|
+
name: "unzip",
|
|
195
|
+
description: "Extract compressed files from ZIP archives",
|
|
196
|
+
category: "archive",
|
|
197
|
+
params: ["[-l] [-o] <archive.zip> [-d <dir>]"],
|
|
198
|
+
run: ({ shell, cwd, args }) => {
|
|
199
|
+
const listOnly = args.includes("-l");
|
|
200
|
+
const dIdx = args.indexOf("-d");
|
|
201
|
+
const destDir = dIdx !== -1 ? args[dIdx + 1] : undefined;
|
|
202
|
+
const archive = args.find((a) => !a.startsWith("-") && a !== destDir);
|
|
203
|
+
if (!archive)
|
|
204
|
+
return { stderr: "unzip: missing archive operand", exitCode: 1 };
|
|
205
|
+
const archivePath = resolvePath(cwd, archive);
|
|
206
|
+
if (!shell.vfs.exists(archivePath))
|
|
207
|
+
return { stderr: `unzip: cannot find or open ${archive}`, exitCode: 9 };
|
|
208
|
+
const raw = shell.vfs.readFileRaw(archivePath);
|
|
209
|
+
let files;
|
|
210
|
+
try {
|
|
211
|
+
files = parseZip(raw);
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
return { stderr: `unzip: ${archive}: not a valid ZIP file`, exitCode: 1 };
|
|
215
|
+
}
|
|
216
|
+
const dest = destDir ? resolvePath(cwd, destDir) : cwd;
|
|
217
|
+
if (listOnly) {
|
|
218
|
+
const header = `Archive: ${archive}\n Length Date Time Name\n--------- ---------- ----- ----`;
|
|
219
|
+
const rows = files.map((f) => ` ${String(f.content.length).padStart(8)} 2024-01-01 00:00 ${f.name}`);
|
|
220
|
+
const total = files.reduce((s, f) => s + f.content.length, 0);
|
|
221
|
+
const footer = `--------- -------\n ${String(total).padStart(8)} ${files.length} file${files.length !== 1 ? "s" : ""}`;
|
|
222
|
+
return { stdout: `${header}\n${rows.join("\n")}\n${footer}`, exitCode: 0 };
|
|
223
|
+
}
|
|
224
|
+
const out = [`Archive: ${archive}`];
|
|
225
|
+
for (const { name, content } of files) {
|
|
226
|
+
const destPath = `${dest}/${name}`;
|
|
227
|
+
shell.vfs.writeFile(destPath, content);
|
|
228
|
+
out.push(` inflating: ${destPath}`);
|
|
229
|
+
}
|
|
230
|
+
return { stdout: out.join("\n"), exitCode: 0 };
|
|
231
|
+
},
|
|
232
|
+
};
|
|
@@ -1281,7 +1281,7 @@ Installed-Size: 6800
|
|
|
1281
1281
|
Maintainer: Fortune Package Team <dpkg@fortune.local>
|
|
1282
1282
|
Architecture: amd64
|
|
1283
1283
|
Version: 1.22.6nyx1
|
|
1284
|
-
Depends: libc6 (>= 2.17), libzstd1 (>= 1.5.
|
|
1284
|
+
Depends: libc6 (>= 2.17), libzstd1 (>= 1.5.6)
|
|
1285
1285
|
Description: Fortune package management system
|
|
1286
1286
|
This package provides the low-level infrastructure for handling the
|
|
1287
1287
|
installation and removal of Fortune software packages.
|
package/dist/utils/expand.js
CHANGED
|
@@ -377,6 +377,19 @@ export function expandSync(input, env, lastExit = 0, home) {
|
|
|
377
377
|
s = s.replace(/\$LINENO\b/g, "1");
|
|
378
378
|
// $(( arithmetic )) — must come before ${ and $VAR to avoid conflicts
|
|
379
379
|
s = expandArithmeticChunks(s, env);
|
|
380
|
+
// ${arr[@]} and ${arr[*]} — all array elements
|
|
381
|
+
s = s.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)[@*]\}/g, (_, name) => env[name] ?? "");
|
|
382
|
+
// ${arr[N]} — single array element
|
|
383
|
+
s = s.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\[(\d+)\]\}/g, (_, name, idx) => env[`${name}[${idx}]`] ?? "");
|
|
384
|
+
// ${#arr[@]} — array length
|
|
385
|
+
s = s.replace(/\$\{#([A-Za-z_][A-Za-z0-9_]*)[@*]\}/g, (_, name) => {
|
|
386
|
+
let count = 0;
|
|
387
|
+
for (const k of Object.keys(env)) {
|
|
388
|
+
if (k.startsWith(`${name}[`))
|
|
389
|
+
count++;
|
|
390
|
+
}
|
|
391
|
+
return String(count);
|
|
392
|
+
});
|
|
380
393
|
// ${#VAR} — string length
|
|
381
394
|
s = s.replace(/\$\{#([A-Za-z_][A-Za-z0-9_]*)\}/g, (_, name) => String((env[name] ?? "").length));
|
|
382
395
|
// ${VAR:-default}
|
|
@@ -389,6 +402,57 @@ export function expandSync(input, env, lastExit = 0, home) {
|
|
|
389
402
|
});
|
|
390
403
|
// ${VAR:+alternate}
|
|
391
404
|
s = s.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*):\+([^}]*)\}/g, (_, name, alt) => env[name] !== undefined && env[name] !== "" ? alt : "");
|
|
405
|
+
// ${VAR:offset:len} and ${VAR:offset}
|
|
406
|
+
s = s.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*):(-?\d+)(?::(\d+))?\}/g, (_, name, offset, len) => {
|
|
407
|
+
const val = env[name] ?? "";
|
|
408
|
+
const off = parseInt(offset, 10);
|
|
409
|
+
const start = off < 0 ? Math.max(0, val.length + off) : Math.min(off, val.length);
|
|
410
|
+
return len !== undefined ? val.slice(start, start + parseInt(len, 10)) : val.slice(start);
|
|
411
|
+
});
|
|
412
|
+
// ${VAR//pattern/replace} — replace all
|
|
413
|
+
s = s.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\/\/([^/}]*)\/([^}]*)\}/g, (_, name, pat, rep) => {
|
|
414
|
+
const val = env[name] ?? "";
|
|
415
|
+
try {
|
|
416
|
+
return val.replace(new RegExp(pat.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, "."), "g"), rep);
|
|
417
|
+
}
|
|
418
|
+
catch {
|
|
419
|
+
return val;
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
// ${VAR/pattern/replace} — replace first
|
|
423
|
+
s = s.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\/([^/}]*)\/([^}]*)\}/g, (_, name, pat, rep) => {
|
|
424
|
+
const val = env[name] ?? "";
|
|
425
|
+
try {
|
|
426
|
+
return val.replace(new RegExp(pat.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".")), rep);
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
return val;
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
// ${VAR##pattern} — strip longest prefix
|
|
433
|
+
s = s.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)##([^}]+)\}/g, (_, name, pat) => {
|
|
434
|
+
const val = env[name] ?? "";
|
|
435
|
+
const re = new RegExp(`^${pat.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".")}`);
|
|
436
|
+
return val.replace(re, "");
|
|
437
|
+
});
|
|
438
|
+
// ${VAR#pattern} — strip shortest prefix
|
|
439
|
+
s = s.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)#([^}]+)\}/g, (_, name, pat) => {
|
|
440
|
+
const val = env[name] ?? "";
|
|
441
|
+
const re = new RegExp(`^${pat.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/]*").replace(/\?/g, ".")}`);
|
|
442
|
+
return val.replace(re, "");
|
|
443
|
+
});
|
|
444
|
+
// ${VAR%%pattern} — strip longest suffix
|
|
445
|
+
s = s.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)%%([^}]+)\}/g, (_, name, pat) => {
|
|
446
|
+
const val = env[name] ?? "";
|
|
447
|
+
const re = new RegExp(`${pat.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".")}$`);
|
|
448
|
+
return val.replace(re, "");
|
|
449
|
+
});
|
|
450
|
+
// ${VAR%pattern} — strip shortest suffix
|
|
451
|
+
s = s.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)%([^}]+)\}/g, (_, name, pat) => {
|
|
452
|
+
const val = env[name] ?? "";
|
|
453
|
+
const re = new RegExp(`${pat.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/]*").replace(/\?/g, ".")}$`);
|
|
454
|
+
return val.replace(re, "");
|
|
455
|
+
});
|
|
392
456
|
// ${VAR}
|
|
393
457
|
s = s.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (_, name) => env[name] ?? "");
|
|
394
458
|
// $VAR and positional params $1 $2 ...
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"version": "1.5.
|
|
7
|
+
"version": "1.5.6",
|
|
8
8
|
"files": [
|
|
9
9
|
"dist/",
|
|
10
10
|
"README.md",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"lint:write": "bunx --bun @biomejs/biome lint --write ./src",
|
|
33
33
|
"test": "bun run test-salve",
|
|
34
34
|
"test-battery": "bun test tests/",
|
|
35
|
-
"test-salve": "for f in tests/*.test.ts; do echo \"\\n
|
|
35
|
+
"test-salve": "for f in tests/*.test.ts; do echo \"\\n🧪 Testing $f...\"; bun test \"$f\" --timeout 10000; sleep 0.25; done",
|
|
36
36
|
"build": "tsc --project tsconfig.json",
|
|
37
37
|
"deploy:npm": "bun publish --access public",
|
|
38
38
|
"bench": "rm -rf .benchmark-shells/ && bun benchmark-virtualshell.ts",
|
|
@@ -46,13 +46,13 @@
|
|
|
46
46
|
"self-standalone-build": "node scripts/build-all.mjs",
|
|
47
47
|
"standalone-build": "bunx esbuild src/standalone.ts --bundle --platform=node --target=node18 --outfile=builds/standalone.cjs --tree-shaking=true --minify --banner:js='#!/usr/bin/env node'",
|
|
48
48
|
"build-all": "node scripts/build-all.mjs",
|
|
49
|
-
"publish-doc": "bunx typedoc && bun build-all && bunx gh-pages -d docs && git add docs && git commit -m 'docs: update documentation' && git push",
|
|
49
|
+
"publish-doc": "bunx typedoc && bun build-all && cd examples && node build && cd .. && bunx gh-pages -d docs && git add docs && git commit -m 'docs: update documentation' && git push",
|
|
50
50
|
"generate-manuals": "node scripts/generate-manuals-bundle.mjs"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@biomejs/biome": "^2.4.15",
|
|
54
54
|
"@types/bun": "^1.3.14",
|
|
55
|
-
"@types/node": "^25.
|
|
55
|
+
"@types/node": "^25.8.0",
|
|
56
56
|
"@types/ssh2": "^1.15.5",
|
|
57
57
|
"esbuild": "^0.28.0",
|
|
58
58
|
"gh-pages": "^6.3.0",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"typescript": "^5"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
+
"fflate": "^0.8.2",
|
|
66
67
|
"ssh2": "^1.17.0"
|
|
67
68
|
}
|
|
68
69
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|