UNPKG

@proofkit/fmodata

Version:

FileMaker OData API client

121 lines (107 loc) 4.07 kB
import { Command } from "commander"; import { FMTable } from "../../orm/table"; import type { ConnectionOptions } from "../utils/connection"; import { buildConnection } from "../utils/connection"; import { handleCliError } from "../utils/errors"; import { printResult } from "../utils/output"; const WEBHOOK_ID_RE = /^\d+$/; function parseWebhookId(id: string): number { if (!WEBHOOK_ID_RE.test(id)) { throw new Error(`Invalid webhook ID: "${id}" — must be a positive integer`); } return Number(id); } export function makeWebhookCommand(): Command { const webhook = new Command("webhook").description("FileMaker webhook operations"); webhook .command("list") .description("List all webhooks") .action(async (_opts, cmd) => { const globalOpts = cmd.parent?.parent?.opts() as ConnectionOptions & { pretty: boolean }; try { const { db } = buildConnection(globalOpts); const result = await db.webhook.list(); printResult(result, { pretty: globalOpts.pretty ?? false }); } catch (err) { handleCliError(err); } }); webhook .command("get <id>") .description("Get a webhook by ID") .action(async (id: string, _opts, cmd) => { const globalOpts = cmd.parent?.parent?.opts() as ConnectionOptions & { pretty: boolean }; try { const parsedId = parseWebhookId(id); const { db } = buildConnection(globalOpts); const result = await db.webhook.get(parsedId); printResult(result, { pretty: globalOpts.pretty ?? false }); } catch (err) { handleCliError(err); } }); webhook .command("add") .description("Add a new webhook") .requiredOption("--table <name>", "Table to monitor") .requiredOption("--url <url>", "Webhook URL to call") .option("--select <fields>", "Comma-separated field names to include") .option( "--header <kv>", "Header in key=value format (repeatable)", (val, acc: string[]) => { acc.push(val); return acc; }, [], ) .action(async (opts, cmd) => { const globalOpts = cmd.parent?.parent?.opts() as ConnectionOptions & { pretty: boolean }; try { const { db } = buildConnection(globalOpts); // Parse headers const headers: Record<string, string> = {}; for (const h of opts.header as string[]) { const eqIdx = h.indexOf("="); if (eqIdx === -1) { throw new Error(`Invalid header format (expected key=value): ${h}`); } headers[h.slice(0, eqIdx)] = h.slice(eqIdx + 1); } // Build a minimal FMTable-like proxy for the tableName // webhook.add() only reads the name via Symbol, so this is safe at runtime const tableProxy = { [FMTable.Symbol.Name]: opts.table, } as unknown as import("../../orm/table").FMTable<Record<string, never>, string>; const webhookPayload: import("../../client/webhook-builder").Webhook<typeof tableProxy> = { webhook: opts.url as string, tableName: tableProxy, }; if (Object.keys(headers).length > 0) { webhookPayload.headers = headers; } if (opts.select) { webhookPayload.select = opts.select as string; } const result = await db.webhook.add(webhookPayload); printResult(result, { pretty: globalOpts.pretty ?? false }); } catch (err) { handleCliError(err); } }); webhook .command("remove <id>") .description("Remove a webhook by ID") .action(async (id: string, _opts, cmd) => { const globalOpts = cmd.parent?.parent?.opts() as ConnectionOptions & { pretty: boolean }; try { const parsedId = parseWebhookId(id); const { db } = buildConnection(globalOpts); await db.webhook.remove(parsedId); printResult({ removed: true, id: parsedId }, { pretty: globalOpts.pretty ?? false }); } catch (err) { handleCliError(err); } }); return webhook; }