pathes
Build self-hosted HTTP Toolkit / build (linux-x64, ubuntu-latest, true) (push) Canceled after 0s
Build self-hosted HTTP Toolkit / build (macos-arm64, macos-latest, true) (push) Canceled after 0s
Build self-hosted HTTP Toolkit / build (windows-x64, windows-latest, false) (push) Canceled after 0s
Build self-hosted HTTP Toolkit / release (push) Canceled after 0s

This commit is contained in:
2026-08-15 01:59:20 +05:00
commit aeb59e8eda
16 changed files with 862 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
/*
* Single-file binary entry point (compiled with `bun build --compile`).
*
* Not part of upstream. Copied to the server submodule root by scripts/apply.sh.
* The built UI is embedded into the binary as `ui.tar.gz` (created by
* scripts/build.sh) and extracted to a temp dir on first run.
*
* Usage: httptoolkit [--port 8080] [--server-port 45457] [--mockttp-port 45456] [--no-open]
*/
// Bun global is present at runtime in the compiled binary:
declare const Bun: { file(path: string): { arrayBuffer(): Promise<ArrayBuffer> } };
import * as os from 'os';
import * as path from 'path';
import * as fs from 'fs';
import * as fsp from 'fs/promises';
import { x as extractTar } from 'tar';
import { startHtkApp } from './src/htk-app';
import { SERVER_VERSION } from './src/constants';
// Embedded UI bundle. Resolves to a path Bun can read from the compiled binary:
import uiArchive from './ui.tar.gz' with { type: 'file' };
function printHelp() {
console.log(`HTTP Toolkit (self-hosted single binary) v${SERVER_VERSION}
Usage: httptoolkit [options]
Options:
-p, --port <port> Port to serve the web UI on (default: 8080)
--server-port <port> HTK management API port (default: 45457)
--mockttp-port <port> Mockttp admin port (default: 45456)
--no-open Don't open a browser automatically
-h, --help Show this help
`);
}
function parseArgs(argv: string[]) {
const opts = { port: 8080, serverPort: 45457, mockttpPort: 45456, open: true };
for (let i = 0; i < argv.length; i++) {
const a = argv[i];
const eq = a.indexOf('=');
const inlineVal = eq !== -1 ? a.slice(eq + 1) : undefined;
const key = eq !== -1 ? a.slice(0, eq) : a;
const val = () => inlineVal ?? argv[++i];
switch (key) {
case '-p': case '--port': opts.port = parseInt(val(), 10); break;
case '--server-port': opts.serverPort = parseInt(val(), 10); break;
case '--mockttp-port': opts.mockttpPort = parseInt(val(), 10); break;
case '--no-open': opts.open = false; break;
case '-h': case '--help': printHelp(); process.exit(0);
default:
console.error(`Unknown option: ${a}`);
printHelp();
process.exit(1);
}
}
if (!Number.isInteger(opts.port) || opts.port <= 0 || opts.port > 65535) {
console.error(`Invalid --port value`); process.exit(1);
}
return opts;
}
async function extractUi(): Promise<string> {
const dir = path.join(os.tmpdir(), `httptoolkit-ui-${SERVER_VERSION}`);
const marker = path.join(dir, '.extracted');
if (fs.existsSync(marker)) return dir; // already extracted for this version
await fsp.rm(dir, { recursive: true, force: true });
await fsp.mkdir(dir, { recursive: true });
const bytes = new Uint8Array(await Bun.file(uiArchive).arrayBuffer());
const tmpArchive = path.join(dir, 'ui.tar.gz');
await fsp.writeFile(tmpArchive, bytes);
await extractTar({ file: tmpArchive, cwd: dir });
await fsp.unlink(tmpArchive).catch(() => {});
await fsp.writeFile(marker, '');
return dir;
}
async function main() {
const opts = parseArgs(process.argv.slice(2));
const uiDir = await extractUi();
await startHtkApp({ ...opts, uiDir });
}
main().catch((e) => {
console.error('Failed to start HTTP Toolkit:', e);
process.exit(1);
});