buninu 0.3.1 → 0.4.0
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/CHANGELOG.md +71 -0
- package/README.md +313 -37
- package/apps/cmdlist +6 -1
- package/apps/jsgotty/gotty.js +65 -76
- package/apps/jsgotty/package.json +6 -1
- package/apps/jsgotty/single-exe/README.md +358 -54
- package/apps/jsgotty/single-exe/assetsHelper.js +293 -12
- package/apps/jsgotty/single-exe/assetsLoader.mjs +1 -1
- package/apps/jsgotty/single-exe/assetsPacker.js +218 -0
- package/apps/jsgotty/single-exe/compiled.js +379 -19
- package/apps/jsgotty/single-exe/entry.mjs +16 -2
- package/apps/jsgotty/zmodem-node.js +14 -12
- package/apps/jsmdcui/CHANGELOG.md +56 -0
- package/apps/jsmdcui/package.json +12 -2
- package/apps/jsmdcui/single-exe/README.md +298 -375
- package/apps/jsmdcui/single-exe/assetsHelper.js +198 -18
- package/apps/jsmdcui/single-exe/assetsLoader.mjs +1 -1
- package/apps/jsmdcui/single-exe/assetsPacker.js +218 -0
- package/apps/jsmdcui/single-exe/compiled.js +291 -5
- package/apps/jsmdcui/single-exe/entry.mjs +7 -0
- package/apps/jsmdcui/src/index.js +11 -8
- package/apps/jsmdcui/tests/jmigt.js +16 -0
- package/bin/bunmsh.bat +3 -0
- package/bin/bunmsh.sh +5 -0
- package/bin/init.js +37 -2
- package/bin/install.js +541 -0
- package/package.json +3 -2
package/apps/jsgotty/gotty.js
CHANGED
|
@@ -97,25 +97,30 @@ const DEFAULTS = {
|
|
|
97
97
|
const compiledHelperPromise = import("./single-exe/compiled.js").catch(() => null);
|
|
98
98
|
const assetsHelperPromise = import("./single-exe/assetsHelper.js").catch(() => null);
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
let
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
100
|
+
// Assets are addressed by the package-relative keys package.json declares
|
|
101
|
+
// ("static/index.html", "README.md"). assetsHelper turns a key into bytes,
|
|
102
|
+
// wherever they live: the embedded store, the compiled binary's virtual
|
|
103
|
+
// filesystem, or a file on disk. Nothing here builds an absolute path.
|
|
104
|
+
let assets = null;
|
|
105
|
+
|
|
106
|
+
// Node runs this file without the ESM-only helper. Then there is nothing
|
|
107
|
+
// embedded either, so a key is just a path under the source checkout.
|
|
108
|
+
function assetText(key) {
|
|
109
|
+
return assets
|
|
110
|
+
? assets.readAssetTextSync(key)
|
|
111
|
+
: fs.readFileSync(path.join(__dirname, key), "utf8");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function assetFilePath(key) {
|
|
115
|
+
return assets ? assets.assetDiskPath(key) : path.join(__dirname, key);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// URL-relative path -> asset key, or null when it escapes `static/`.
|
|
119
|
+
// Normalizing against "/" is what makes "../../etc/passwd" unreachable.
|
|
120
|
+
function staticAssetKey(relativePath) {
|
|
121
|
+
const rel = path.posix.normalize(`/${String(relativePath ?? "")}`).slice(1);
|
|
122
|
+
if (!rel || rel === ".." || rel.startsWith("../")) return null;
|
|
123
|
+
return `static/${rel}`;
|
|
119
124
|
}
|
|
120
125
|
|
|
121
126
|
let cliBootstrapPromise = null;
|
|
@@ -247,8 +252,8 @@ Experimental:
|
|
|
247
252
|
--build-for <target> Build a Bun single-file executable for target`);
|
|
248
253
|
}
|
|
249
254
|
|
|
250
|
-
function printMarkdownFile(
|
|
251
|
-
const text =
|
|
255
|
+
function printMarkdownFile(key) {
|
|
256
|
+
const text = assetText(key);
|
|
252
257
|
const markdownAnsi =
|
|
253
258
|
typeof Bun !== "undefined" &&
|
|
254
259
|
Bun &&
|
|
@@ -259,10 +264,6 @@ function printMarkdownFile(filePath) {
|
|
|
259
264
|
console.log(markdownAnsi ? markdownAnsi(text, { hyperlinks: true }) : text);
|
|
260
265
|
}
|
|
261
266
|
|
|
262
|
-
function printWebHelp() {
|
|
263
|
-
printMarkdownFile(DEFAULT_HELP);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
267
|
function fatal(message, code = 1) {
|
|
267
268
|
console.error(message);
|
|
268
269
|
process.exit(code);
|
|
@@ -510,15 +511,15 @@ function parseArgs(argv) {
|
|
|
510
511
|
process.exit(0);
|
|
511
512
|
break;
|
|
512
513
|
case "--help-web":
|
|
513
|
-
|
|
514
|
+
printMarkdownFile("static/help.md");
|
|
514
515
|
process.exit(0);
|
|
515
516
|
break;
|
|
516
517
|
case "--readme":
|
|
517
|
-
printMarkdownFile(
|
|
518
|
+
printMarkdownFile("README.md");
|
|
518
519
|
process.exit(0);
|
|
519
520
|
break;
|
|
520
521
|
case "--readme-en":
|
|
521
|
-
printMarkdownFile(
|
|
522
|
+
printMarkdownFile("README.en.md");
|
|
522
523
|
process.exit(0);
|
|
523
524
|
break;
|
|
524
525
|
case "--address":
|
|
@@ -664,36 +665,6 @@ function previewBuffer(buffer, limit = 96) {
|
|
|
664
665
|
});
|
|
665
666
|
}
|
|
666
667
|
|
|
667
|
-
function readTextFile(filePath) {
|
|
668
|
-
const bundledText = helperReadInternalAssetText?.(internalAssetPathFor(filePath));
|
|
669
|
-
if (bundledText == null) {
|
|
670
|
-
return fs.readFileSync(filePath, "utf8");
|
|
671
|
-
}
|
|
672
|
-
return bundledText;
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
function internalAssetPathFor(filePath) {
|
|
676
|
-
if (!helperAssetPath) {
|
|
677
|
-
return filePath;
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
const normalizedPath = path.normalize(filePath);
|
|
681
|
-
const staticRelativePath = path.relative(STATIC_ROOT, normalizedPath);
|
|
682
|
-
if (staticRelativePath && !staticRelativePath.startsWith("..") && !path.isAbsolute(staticRelativePath)) {
|
|
683
|
-
return helperAssetPath("static", staticRelativePath);
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
if (normalizedPath === DEFAULT_README) {
|
|
687
|
-
return helperAssetPath("README.md");
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
if (normalizedPath === DEFAULT_README_EN) {
|
|
691
|
-
return helperAssetPath("README.en.md");
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
return filePath;
|
|
695
|
-
}
|
|
696
|
-
|
|
697
668
|
function contentType(filePath) {
|
|
698
669
|
const ext = path.extname(filePath).toLowerCase();
|
|
699
670
|
switch (ext) {
|
|
@@ -1357,10 +1328,26 @@ class NodePtyBackend {
|
|
|
1357
1328
|
constructor(options) {
|
|
1358
1329
|
let nodePty;
|
|
1359
1330
|
try {
|
|
1331
|
+
// Split so the bundler cannot resolve it. This branch is unreachable
|
|
1332
|
+
// in a compiled binary (Bun >= 1.3.14 always takes BunPtyBackend), so
|
|
1333
|
+
// a static require would only bake ~54 KB of dead JS into the exe —
|
|
1334
|
+
// and node-pty's own `.node` loading is dynamic anyway, so it would
|
|
1335
|
+
// still need the files on disk.
|
|
1360
1336
|
let preventSingleExe="./lib/"
|
|
1361
1337
|
nodePty = require(preventSingleExe+"node-pty");
|
|
1362
1338
|
} catch (error) {
|
|
1363
|
-
|
|
1339
|
+
const detail = error && error.message ? `: ${error.message}` : "";
|
|
1340
|
+
throw new Error(
|
|
1341
|
+
globalThis.Bun
|
|
1342
|
+
? "This build falls back to node-pty because Bun " + globalThis.Bun.version
|
|
1343
|
+
+ " is older than 1.3.14, which is where the built-in ConPTY backend landed. "
|
|
1344
|
+
+ "A compiled binary cannot load node-pty — it is deliberately left out of the "
|
|
1345
|
+
+ "bundle — so rebuild with Bun 1.3.14 or newer, or run from a source checkout "
|
|
1346
|
+
+ "with node-pty installed" + detail
|
|
1347
|
+
: "node-pty is required to run under Node on Windows, and it could not be loaded "
|
|
1348
|
+
+ "from ./lib/node-pty. Run with Bun 1.3.14 or newer to use the built-in ConPTY "
|
|
1349
|
+
+ "backend instead" + detail,
|
|
1350
|
+
);
|
|
1364
1351
|
}
|
|
1365
1352
|
|
|
1366
1353
|
const system32 = path.join(process.env.windir, 'System32');
|
|
@@ -2659,8 +2646,10 @@ function createServerRuntime(command, argv, options) {
|
|
|
2659
2646
|
);
|
|
2660
2647
|
const wsPath = `${basePath}ws`;
|
|
2661
2648
|
const originMatcher = options.wsOrigin ? new RegExp(options.wsOrigin) : null;
|
|
2662
|
-
const indexTemplate =
|
|
2663
|
-
|
|
2649
|
+
const indexTemplate = options.index
|
|
2650
|
+
? fs.readFileSync(expandHome(options.index), "utf8")
|
|
2651
|
+
: assetText("static/index.html");
|
|
2652
|
+
const manifestTemplate = assetText("static/manifest.json");
|
|
2664
2653
|
const activeSessions = new Set();
|
|
2665
2654
|
const reconnectRegistry = new Map();
|
|
2666
2655
|
let acceptedOnce = false;
|
|
@@ -2784,7 +2773,7 @@ function createServerRuntime(command, argv, options) {
|
|
|
2784
2773
|
}
|
|
2785
2774
|
|
|
2786
2775
|
if (relativePath === "help.md" || relativePath === "help") {
|
|
2787
|
-
const markdown =
|
|
2776
|
+
const markdown = assetText("static/help.md");
|
|
2788
2777
|
const markdownToHtml = global.Bun?.markdown?.html;
|
|
2789
2778
|
const renderHtml = relativePath === "help" && typeof markdownToHtml === "function";
|
|
2790
2779
|
const body = renderHtml
|
|
@@ -2865,18 +2854,18 @@ function createServerRuntime(command, argv, options) {
|
|
|
2865
2854
|
return;
|
|
2866
2855
|
}
|
|
2867
2856
|
|
|
2868
|
-
const
|
|
2869
|
-
if (!
|
|
2857
|
+
const assetKey = staticAssetKey(relativePath);
|
|
2858
|
+
if (!assetKey) {
|
|
2870
2859
|
res.writeHead(403);
|
|
2871
2860
|
res.end("Forbidden");
|
|
2872
2861
|
return;
|
|
2873
2862
|
}
|
|
2874
2863
|
|
|
2875
|
-
const bundledAsset =
|
|
2864
|
+
const bundledAsset = assets?.readInternalAssetBytes(assetKey);
|
|
2876
2865
|
if (bundledAsset != null) {
|
|
2877
2866
|
const body = bundledAsset instanceof Uint8Array ? bundledAsset : new Uint8Array(bundledAsset);
|
|
2878
2867
|
res.writeHead(200, {
|
|
2879
|
-
"Content-Type": contentType(
|
|
2868
|
+
"Content-Type": contentType(assetKey),
|
|
2880
2869
|
"Content-Length": body.length,
|
|
2881
2870
|
"Server": "GoTTY"
|
|
2882
2871
|
});
|
|
@@ -2884,7 +2873,8 @@ function createServerRuntime(command, argv, options) {
|
|
|
2884
2873
|
return;
|
|
2885
2874
|
}
|
|
2886
2875
|
|
|
2887
|
-
|
|
2876
|
+
const externalPath = assetFilePath(assetKey);
|
|
2877
|
+
fs.stat(externalPath, (error, stats) => {
|
|
2888
2878
|
if (error || !stats.isFile()) {
|
|
2889
2879
|
res.writeHead(404, { "Server": "GoTTY" });
|
|
2890
2880
|
res.end("Not Found");
|
|
@@ -2892,11 +2882,11 @@ function createServerRuntime(command, argv, options) {
|
|
|
2892
2882
|
}
|
|
2893
2883
|
|
|
2894
2884
|
res.writeHead(200, {
|
|
2895
|
-
"Content-Type": contentType(
|
|
2885
|
+
"Content-Type": contentType(assetKey),
|
|
2896
2886
|
"Content-Length": stats.size,
|
|
2897
2887
|
"Server": "GoTTY"
|
|
2898
2888
|
});
|
|
2899
|
-
fs.createReadStream(
|
|
2889
|
+
fs.createReadStream(externalPath).pipe(res);
|
|
2900
2890
|
});
|
|
2901
2891
|
};
|
|
2902
2892
|
|
|
@@ -3290,15 +3280,9 @@ function main() {
|
|
|
3290
3280
|
async function bootstrap() {
|
|
3291
3281
|
try {
|
|
3292
3282
|
const compiledHelper = await compiledHelperPromise;
|
|
3293
|
-
configureResourceRoot(compiledHelper);
|
|
3294
3283
|
await compiledHelper?.buildEarlyExit?.(process.argv,'jsgt');
|
|
3295
3284
|
|
|
3296
|
-
|
|
3297
|
-
if (assetsHelper) {
|
|
3298
|
-
helperAssetPath = assetsHelper.assetPath;
|
|
3299
|
-
helperReadInternalAssetText = assetsHelper.readInternalAssetText;
|
|
3300
|
-
helperReadInternalAssetBytes = assetsHelper.readInternalAssetBytes;
|
|
3301
|
-
}
|
|
3285
|
+
assets = await assetsHelperPromise;
|
|
3302
3286
|
await globalThis.assetsLoaderPromise;
|
|
3303
3287
|
} catch (error) {
|
|
3304
3288
|
console.error(String(error && error.stack ? error.stack : error));
|
|
@@ -3323,3 +3307,8 @@ if (require.main === module) {
|
|
|
3323
3307
|
process.exitCode = 1;
|
|
3324
3308
|
});
|
|
3325
3309
|
}
|
|
3310
|
+
|
|
3311
|
+
// The guard above is inlined to false once this file is bundled, because
|
|
3312
|
+
// the bundle entry point is single-exe/entry.mjs rather than this file.
|
|
3313
|
+
// Export the starter so that entry point can call it.
|
|
3314
|
+
module.exports.bootstrap = bootstrap;
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsgotty",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
4
4
|
"description": "Share your terminal as a web application: A JavaScript rewrite of GoTTY",
|
|
5
5
|
"bin": {
|
|
6
6
|
"jsgotty": "./gotty.js"
|
|
7
7
|
},
|
|
8
8
|
"type": "commonjs",
|
|
9
|
+
"assets": [
|
|
10
|
+
"static",
|
|
11
|
+
"README.md",
|
|
12
|
+
"README.en.md"
|
|
13
|
+
],
|
|
9
14
|
"dependencies": {
|
|
10
15
|
"node-addon-api": "^7.1.1",
|
|
11
16
|
"ws": "^8.18.3"
|