Files
oh-my-pi/packages/stats/scripts/generate-client-bundle.ts
T
can1357 52719d1a7c refactor: restructured monorepo TypeScript config and build tasks for unified setup
- Migrated all package tsconfig files to extend tsconfig.workspace.json for unified TypeScript configuration across monorepo.
- Consolidated build and check scripts across 10+ packages to use biome for linting/formatting with separate type checking via tsgo.
- Renamed build scripts from build:native and build:binary to build for simplified command naming across packages/natives and packages/coding-agent.
- Refactored CI workflow to invoke bun tasks instead of inline shell scripts, reducing workflow complexity by 40+ lines.
- Removed sync-exports.ts and repro-stuck.ts scripts; deleted path aliases from tsconfig.base.json in favor of workspace-based configuration.
- Updated turbo.json with new task definitions (check:types, lint, fmt, fix) and removed build:native/embed:native tasks.
2026-04-08 17:05:20 +02:00

80 lines
2.4 KiB
TypeScript

#!/usr/bin/env bun
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import { $ } from "bun";
const GENERATED_FILE = path.join("src", "embedded-client.generated.txt");
const DIST_CLIENT_DIR = path.join("dist", "client");
const GENERATE_FLAG = "--generate";
const RESET_FLAG = "--reset";
function placeholderContent(): string {
return `/**
* Embedded stats dashboard bundle for compiled binaries.
*
* This file is generated by \`bun --cwd=packages/stats scripts/generate-client-bundle.ts --generate\` during
* binary builds. The checked-in value is intentionally empty.
*/
export const EMBEDDED_CLIENT_ARCHIVE_TAR_GZ_BASE64 = "";
`;
}
async function collectFiles(dir: string): Promise<string[]> {
const entries = await fs.readdir(dir, { withFileTypes: true });
const files: string[] = [];
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
files.push(...(await collectFiles(fullPath)));
} else if (entry.isFile()) {
files.push(fullPath);
}
}
files.sort((a, b) => a.localeCompare(b));
return files;
}
async function buildArchiveBase64(dir: string): Promise<string> {
const files = await collectFiles(dir);
const entries: Record<string, Uint8Array> = {};
for (const filePath of files) {
const relativePath = path.relative(dir, filePath).split(path.sep).join("/");
entries[relativePath] = await fs.readFile(filePath);
}
const tempArchivePath = path.join(
os.tmpdir(),
`omp-stats-client-${Bun.hash(Date.now().toString() + Math.random().toString(16)).toString(16)}.tar.gz`,
);
try {
await Bun.Archive.write(tempArchivePath, entries, { compress: "gzip" });
const archiveBytes = await Bun.file(tempArchivePath).bytes();
return Buffer.from(archiveBytes).toString("base64");
} finally {
await fs.rm(tempArchivePath, { force: true });
}
}
async function main(): Promise<void> {
if (process.argv.includes(RESET_FLAG)) {
await Bun.write(GENERATED_FILE, placeholderContent());
console.log(`Reset ${GENERATED_FILE}`);
return;
}
if (!process.argv.includes(GENERATE_FLAG)) {
console.log(`Skipping ${GENERATED_FILE}; pass ${GENERATE_FLAG} to build the embedded bundle`);
return;
}
await $`bun run build`;
const archiveBase64 = await buildArchiveBase64(DIST_CLIENT_DIR);
await Bun.write(GENERATED_FILE, archiveBase64);
console.log(`Generated ${GENERATED_FILE}`);
}
await main();