/** * lib/spec-arg.ts — shared `--spec` / `--spec-file` resolution. * * Every CLI accepts its JSON spec inline (`--spec ''`); the frontend * specs routinely exceed what a shell can carry as ONE argument — a pagespec * with its `i18nKeys` in four locales blows past the Git Bash argv limit * (well below Windows' 32 KB CreateProcess ceiling), making generation * impossible without a spawn-based workaround. `--spec-file ` reads the * same JSON from disk instead. Six backend CLIs carried this pattern * individually; this helper is the shared implementation the frontend CLIs * adopt (parseArgs is `strict: true` everywhere, so an unknown `--spec-file` * used to be a HARD parse error, not a soft ignore). */ import { readFileSync } from 'node:fs' export type SpecArgResult = { raw: string } | { error: string } /** Resolve the raw spec JSON: `--spec-file` wins, then `--spec`. */ export function readSpecArg(values: { spec?: string; 'spec-file'?: string }): SpecArgResult { const file = values['spec-file'] if (file) { try { return { raw: readFileSync(file, 'utf-8') } } catch (err) { return { error: `Failed to read --spec-file ${file}: ${err instanceof Error ? err.message : String(err)}` } } } if (values.spec) return { raw: values.spec } return { error: 'Either --spec or --spec-file is required' } }