ograph/packages/cli/src/commands/reactions.ts

162 lines
5.1 KiB
TypeScript

// 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 <name>', 'Projection def name')
create.option('--params <json>', 'Params JSON')
create.option('--action <type>', 'Action type: webhook (default), emit_event, or handler', 'webhook')
create.option('--webhook <url>', 'Webhook URL (required when --action webhook)')
create.option('--emit-type <event_type>', 'Event type to emit (required when --action emit_event)')
create.option('--emit-template <jsonata>', 'JSONata template for emitted event payload')
create.option('--handler-code <code>', 'Handler code (required when --action handler)')
create.option('--handler-timeout <ms>', '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<string, unknown> = {}
if (opts.params) {
try {
params = JSON.parse(opts.params) as Record<string, unknown>
} 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 <url> is required when --action webhook')
process.exit(1)
return
}
if (action === 'emit_event' && !opts.emitType) {
fail('--emit-type <event_type> is required when --action emit_event')
process.exit(1)
return
}
if (action === 'handler' && !opts.handlerCode) {
fail('--handler-code <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('<id>', '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
}