// reactions commands import { Command } from 'commander' import { OGraphClient } from '../client.js' const c = { reset: '\x1b[0m', green: '\x1b[32m', cyan: '\x1b[36m', red: '\x1b[31m', bold: '\x1b[1m', } function fail(msg: string) { console.error(`${c.red}✗${c.reset} ${msg}`) } export function createReactionsCommand(): Command { const cmd = new Command('reactions') cmd.description('Manage reactions (projection triggers)') // create const create = new Command('create') create.description('Create a new reaction') create.requiredOption('--projection ', 'Projection def name') create.option('--params ', 'Params JSON') create.option('--action ', 'Action type: webhook (default), emit_event, or handler', 'webhook') create.option('--webhook ', 'Webhook URL (required when --action webhook)') create.option('--emit-type ', 'Event type to emit (required when --action emit_event)') create.option('--emit-template ', 'JSONata template for emitted event payload') create.option('--handler-code ', 'Handler code (required when --action handler)') create.option('--handler-timeout ', 'Handler timeout in ms (default 5000)', parseInt) create.option('--json', 'output raw JSON') create.action( async (opts: { projection: string params?: string action: string webhook?: string emitType?: string emitTemplate?: string handlerCode?: string handlerTimeout?: number json?: boolean }) => { const client = new OGraphClient() try { await client.init() let params: Record = {} if (opts.params) { try { params = JSON.parse(opts.params) as Record } catch { fail('Invalid JSON for --params') process.exit(1) return } } const action = opts.action as 'webhook' | 'emit_event' | 'handler' if (action !== 'webhook' && action !== 'emit_event' && action !== 'handler') { fail('--action must be "webhook", "emit_event", or "handler"') process.exit(1) return } if (action === 'webhook' && !opts.webhook) { fail('--webhook is required when --action webhook') process.exit(1) return } if (action === 'emit_event' && !opts.emitType) { fail('--emit-type is required when --action emit_event') process.exit(1) return } if (action === 'handler' && !opts.handlerCode) { fail('--handler-code is required when --action handler') process.exit(1) return } const reaction = await client.createReaction(opts.projection, params, { action, webhook_url: opts.webhook, emit_event_type: opts.emitType, emit_payload_template: opts.emitTemplate, handler_code: opts.handlerCode, handler_timeout_ms: opts.handlerTimeout, }) if (opts.json) { console.log(JSON.stringify(reaction, null, 2)) return } console.log( `${c.green}✓${c.reset} Created reaction: ${c.cyan}${reaction.id}${c.reset} (action: ${reaction.action})`, ) } catch (err) { fail(String(err instanceof Error ? err.message : err)) process.exit(1) } }, ) // list const list = new Command('list') list.description('List all reactions') list.option('--json', 'output raw JSON') list.action(async (opts: { json?: boolean }) => { const client = new OGraphClient() try { await client.init() const reactions = await client.listReactions() if (opts.json) { console.log(JSON.stringify(reactions, null, 2)) return } if (reactions.length === 0) { console.log('No reactions found.') return } console.log(`${c.bold}Reactions${c.reset}`) for (const r of reactions) { const target = r.action === 'emit_event' ? `emit:${r.emit_event_type}` : r.action === 'handler' ? 'handler' : (r.webhook_url ?? '') console.log(` ${c.cyan}${r.id}${c.reset} [${r.action}] ${target}`) } } catch (err) { fail(String(err instanceof Error ? err.message : err)) process.exit(1) } }) // delete const del = new Command('delete') del.description('Delete a reaction') del.argument('', 'Reaction ID') del.option('--json', 'output raw JSON') del.action(async (id: string, opts: { json?: boolean }) => { const client = new OGraphClient() try { await client.init() const result = await client.deleteReaction(parseInt(id, 10)) if (opts.json) { console.log(JSON.stringify(result, null, 2)) return } console.log(`${c.green}✓${c.reset} Deleted reaction: ${id}`) } catch (err) { fail(String(err instanceof Error ? err.message : err)) process.exit(1) } }) cmd.addCommand(create) cmd.addCommand(list) cmd.addCommand(del) return cmd }