162 lines
5.1 KiB
TypeScript
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
|
|
}
|