import { resolve } from 'node:path'; import { ReferenceCompiler } from '../src/lib/server/reference/index'; import { fixtureSources } from '../src/lib/server/reference/sources'; import { productionSources } from '../src/lib/server/reference/production'; import type { BuildProfile } from '../src/lib/server/reference/types'; const HELP = `Reference data compiler (fixture/offline only when explicitly selected) Usage: bun workers/reference.ts --fixture [--directory DIR] bun workers/reference.ts --production [--archive-dir DIR] [--directory DIR] bun workers/reference.ts --check [--fixture|--production] [--directory DIR] bun workers/reference.ts --rollback [--directory DIR] Options: --fixture Use the checked-in, tiny fixture adapters (never downloads). --production Download and compile the pinned public production archives. --archive-dir Archive staging/cache directory (default: data/reference-live). --offline Parse archives already present in --archive-dir; no network. --check Check configured source metadata only; never downloads archives. --rollback Atomically switch ACTIVE to PREVIOUS. --directory Reference directory (default: REFERENCE_DIR or data/reference). --help Show this help. Production imports stream downloads and archive members with bounded limits. --check never downloads archives. `; function valueAfter(args: string[], flag: string): string | undefined { const index = args.indexOf(flag); return index >= 0 ? args[index + 1] : undefined; } export function validateArguments(args: string[]): void { const flags = new Set(['--fixture', '--production', '--offline', '--check', '--rollback']); for (let i = 0; i < args.length; i++) { if (args[i] === '--directory' || args[i] === '--archive-dir') { if (!args[i + 1] || args[i + 1].startsWith('-')) throw new Error('A reference directory option is missing its value'); i++; } else if (!flags.has(args[i])) throw new Error('Unknown reference compiler option'); } if (args.includes('--fixture') && args.includes('--production')) throw new Error('Choose either --fixture or --production, not both'); if (args.includes('--check') && args.includes('--rollback')) throw new Error('Choose either --check or --rollback, not both'); if (args.includes('--offline') && args.includes('--fixture')) throw new Error('--offline is for production archives; fixtures are always offline'); } async function main(args: string[]): Promise { if (!args.length || args.includes('--help') || args.includes('-h')) { console.log(HELP); return; } try { validateArguments(args); } catch (error) { console.error(error instanceof Error ? error.message : 'Invalid reference compiler options'); process.exitCode = 2; return; } const fixture = args.includes('--fixture'); const production = args.includes('--production'); // REFERENCE_DIR is the shared application artifact mount. REFERENCE_LIVE_DIR // controls archive storage only and must never redirect published artifacts. const directory = resolve(valueAfter(args, '--directory') ?? process.env.REFERENCE_DIR ?? (production ? 'data/reference-live' : 'data/reference')); const profile: BuildProfile = fixture ? 'fixture' : 'production'; const archiveDir = resolve(valueAfter(args, '--archive-dir') ?? process.env.REFERENCE_LIVE_DIR ?? 'data/reference-live'); const compiler = new ReferenceCompiler({ directory, profile, sources: fixture ? fixtureSources() : (production || args.includes('--check')) ? productionSources({ archiveDir, offline: args.includes('--offline') }) : {} }); if (args.includes('--check')) { if (fixture) { const results = await compiler.checkSources(); console.log(JSON.stringify({ directory, profile, archiveFetch: false, results }, null, 2)); if (results.some((result) => result.error)) process.exitCode = 1; } else { const results = await compiler.checkSources(); console.log(JSON.stringify({ directory, profile, archiveFetch: false, results }, null, 2)); if (results.some((result) => result.error)) process.exitCode = 1; } return; } if (args.includes('--rollback')) { try { console.log(JSON.stringify(await compiler.rollback(), null, 2)); } catch (error) { process.exitCode = 1; console.error(error instanceof Error ? error.message : String(error)); } return; } if (fixture || production) { const result = await compiler.compile(); console.log(JSON.stringify(result, null, 2)); if (result.status === 'failed') process.exitCode = 1; return; } console.error('No build mode selected. Use --fixture, --check, --rollback, or --help.'); process.exitCode = 2; } if (import.meta.main) await main(process.argv.slice(2));