@kubb/cli
Version:
Command-line interface for Kubb, enabling easy generation of TypeScript, React-Query, Zod, and other code from OpenAPI specifications.
144 lines (130 loc) • 4.54 kB
text/typescript
import { spawn } from 'node:child_process'
import path from 'node:path'
import * as process from 'node:process'
import { fileURLToPath } from 'node:url'
import { styleText } from 'node:util'
import * as clack from '@clack/prompts'
import type { ArgsDef } from 'citty'
import { defineCommand } from 'citty'
const args = {
config: {
type: 'string',
description: 'Path to the Kubb config',
alias: 'c',
},
port: {
type: 'string',
description: 'Port for the server. If not specified, an available port is automatically selected.',
alias: 'p',
},
host: {
type: 'string',
description: 'Host for the server',
default: 'localhost',
},
'no-cache': {
type: 'boolean',
description: 'Disable session caching',
default: false,
},
'allow-write': {
type: 'boolean',
description: 'Allow writing generated files to the filesystem. When not set, no files are written and the config patch is not persisted.',
default: false,
},
'allow-all': {
type: 'boolean',
description: 'Grant all permissions (implies --allow-write).',
default: false,
},
} as const satisfies ArgsDef
type StartServerProps = {
port: number
host: string
configPath: string
noCache: boolean
allowWrite: boolean
allowAll: boolean
}
async function startServer({ port, host, configPath, noCache, allowWrite, allowAll }: StartServerProps): Promise<void> {
try {
// Load .env file into process.env using Node.js built-in (v20.12.0+)
try {
process.loadEnvFile()
} catch {
// .env file may not exist; ignore
}
// Resolve the @kubb/agent package path
const agentPkgUrl = import.meta.resolve('@kubb/agent/package.json')
const agentPkgPath = fileURLToPath(agentPkgUrl)
const agentDir = path.dirname(agentPkgPath)
const serverPath = path.join(agentDir, '.output', 'server', 'index.mjs')
// nitro env
const PORT = process.env.PORT || (port === 0 ? '3000' : String(port))
const HOST = process.env.HOST || host || '0.0.0.0'
// kubb env
const KUBB_AGENT_ROOT = process.env.KUBB_AGENT_ROOT || process.cwd()
const KUBB_AGENT_CONFIG = process.env.KUBB_AGENT_CONFIG || configPath || 'kubb.config.ts'
const KUBB_AGENT_NO_CACHE = noCache ? 'true' : 'false'
const KUBB_AGENT_ALLOW_WRITE = allowAll || allowWrite ? 'true' : (process.env.KUBB_AGENT_ALLOW_WRITE ?? 'false')
const KUBB_AGENT_ALLOW_ALL = allowAll ? 'true' : (process.env.KUBB_AGENT_ALLOW_ALL ?? 'false')
const KUBB_AGENT_TOKEN = process.env.KUBB_AGENT_TOKEN
const KUBB_AGENT_RETRY_TIMEOUT = process.env.KUBB_AGENT_RETRY_TIMEOUT || '30000'
const KUBB_STUDIO_URL = process.env.KUBB_STUDIO_URL || 'https://studio.kubb.dev'
// Set environment variables
const env = {
PORT,
HOST,
KUBB_AGENT_ROOT,
KUBB_AGENT_CONFIG,
KUBB_AGENT_NO_CACHE,
KUBB_AGENT_ALLOW_WRITE,
KUBB_AGENT_ALLOW_ALL,
KUBB_AGENT_TOKEN,
KUBB_AGENT_RETRY_TIMEOUT,
KUBB_STUDIO_URL,
}
clack.log.step(styleText('cyan', 'Starting agent server...'))
clack.log.info(styleText('dim', `Config: ${KUBB_AGENT_CONFIG}`))
clack.log.info(styleText('dim', `Host: ${HOST}`))
clack.log.info(styleText('dim', `Port: ${PORT}`))
if (noCache) {
clack.log.info(styleText('dim', 'Session caching: disabled'))
}
if (!KUBB_AGENT_ALLOW_WRITE && !KUBB_AGENT_ALLOW_ALL) {
clack.log.warn(styleText('yellow', 'Filesystem writes disabled. Use --allow-write or --allow-all to enable.'))
}
spawn('node', [serverPath], {
env: { ...process.env, ...env },
stdio: 'inherit',
cwd: process.cwd(),
})
} catch (error) {
console.error('Failed to start agent server:', error)
process.exit(1)
}
}
const command = defineCommand({
meta: {
name: 'start',
description: 'Start the Agent server',
},
args,
async run(commandContext) {
const { args } = commandContext
try {
const configPath = path.resolve(process.cwd(), args.config || 'kubb.config.ts')
const port = args.port ? Number.parseInt(args.port, 10) : 0
const host = args.host
const noCache = args['no-cache']
const allowWrite = args['allow-write']
const allowAll = args['allow-all']
await startServer({ port, host, configPath, noCache, allowWrite, allowAll })
} catch (error) {
clack.log.error(styleText('red', 'Failed to start agent server'))
console.error(error)
process.exit(1)
}
},
})
export default command