UNPKG

api

Version:

Magical SDK generation from an OpenAPI definition 🪄

63 lines • 2.57 kB
import { spawn } from 'node:child_process'; /** * Commands that are handled by this package's own Commander program. Anything else is dispatched * to the Restless CLI. */ const CODEGEN_COMMANDS = new Set(['install', 'list', 'uninstall']); const HELP_AND_VERSION_FLAGS = new Set(['--help', '-h', '--version', '-V']); /** * Determine whether an invocation should be handled by our own Commander program (`codegen`) or * dispatched to the separately published Restless CLI. * * @param args CLI arguments — `process.argv` minus the Node binary and the script path. */ export function classifyInvocation(args) { for (const arg of args) { // A help or version flag ahead of any command (`api --help`, `api -V`) is ours. if (HELP_AND_VERSION_FLAGS.has(arg)) { return 'codegen'; } // The first non-flag argument is the command. if (!arg.startsWith('-')) { return CODEGEN_COMMANDS.has(arg) ? 'codegen' : 'restless'; } } // No command at all — Commander prints its usage. return 'codegen'; } /** * Re-run the invocation against the Restless CLI (published on npm as `@restlessai/cli`) in a * child process, forwarding its exit code and any termination signals. The Restless CLI is * intentionally **not** a dependency of this package: `npx -y` fetches (and caches) it on * demand, keeping the two fully decoupled. * * @param args CLI arguments — `process.argv` minus the Node binary and the script path. */ export function dispatchToRestlessCli(args) { const child = spawn('npx', ['-y', '@restlessai/cli@latest', ...args], { // `npx` is a `.cmd` shim on Windows and can't be spawned directly there. shell: process.platform === 'win32', stdio: 'inherit', }); const forwardSignal = (signal) => { child.kill(signal); }; // Handling these ourselves keeps the parent alive until the child has finished shutting down. process.on('SIGINT', forwardSignal); process.on('SIGTERM', forwardSignal); child.on('error', err => { process.stderr.write(`${err.message}\n`); process.exit(1); }); child.on('close', (code, signal) => { process.off('SIGINT', forwardSignal); process.off('SIGTERM', forwardSignal); if (signal) { // The child was killed by a signal — re-raise it so our own exit status reflects that. process.kill(process.pid, signal); return; } process.exit(code ?? 0); }); } //# sourceMappingURL=router.js.map