import { ORPCError } from "@orpc/client" import * as z from "zod" import { retryableActionError, terminalActionError, type ActionRuntime, } from "../../../automation/actions" import type { ResolvedIntegrationAccount } from "../../../automation/integrations" import { getRuntimeAutomateClient, getRuntimeAutomateClientForApiKey, } from "../../../automation/runtime-management" const AUTOMATE_SECRET_SCHEMA = z.object({ apiKey: z.string().min(1) }) export const AUTOMATE_RUNTIME_CREDENTIAL = Symbol("automate-runtime") /** * Creates an authenticated Automate.ax management client. * * Runtime provenance is sent with integration actions so lifecycle triggers can * exclude the automation that caused an event. * * @param account - Runtime identity or a resolved Automate.ax organization * account. * @param runtime - Action provenance and runtime-authenticated client. * @throws If the action builder supplies an unknown default account sentinel. */ export function getAutomateApi( account: ResolvedIntegrationAccount<"automate"> | symbol, runtime: ActionRuntime, ) { if (typeof account === "symbol") { if (account !== AUTOMATE_RUNTIME_CREDENTIAL) { throw new Error("Unknown Automate.ax account default") } return getRuntimeAutomateClient(runtime) } const { apiKey } = AUTOMATE_SECRET_SCHEMA.parse(account.secret) return getRuntimeAutomateClientForApiKey(runtime, apiKey) } /** * Executes one management request with action-aware failure classification. * * @param request - Deferred Automate.ax management request. */ export async function callAutomateApi(request: () => Promise) { try { return await request() } catch (error) { if (error instanceof ORPCError) { if ( error.status === 408 || error.status === 429 || error.status === 499 || error.status >= 500 ) { throw retryableActionError(error) } throw terminalActionError(error) } throw error } }