import { getTallyApi as getTallyContractApi, TallyApiError, } from "@automate.ax/integration-contracts/tally" import * as z from "zod" import { retryableActionError, terminalActionError, } from "../../automation/actions" import type { ResolvedIntegrationAccount } from "../../automation/integrations" export const TALLY_ACCOUNT = "tally" export const TALLY_API_KEY_ACCOUNT = { connections: [{ connectionMethodId: "api-key" }], } as const export const TALLY_ID_SCHEMA = z.string().trim().min(1) export const TALLY_EMPTY_SCHEMA = z.object({}) /** * Resolves an action-aware Tally client. * * @param account Resolved Tally integration account. */ export function getTallyApi(account: ResolvedIntegrationAccount<"tally">) { const api = getTallyContractApi(account) const request = api.request.bind(api) const requestVoid = api.requestVoid.bind(api) api.request = async (path, options) => { try { return await request(path, options) } catch (error) { throw mapTallyError(error) } } api.requestVoid = async (path, options) => { try { return await requestVoid(path, options) } catch (error) { throw mapTallyError(error) } } return api } /** * Maps provider failures to Automate.ax retry outcomes. * * @param error Provider request failure. */ function mapTallyError(error: unknown) { if (!(error instanceof TallyApiError)) return error if (error.status === 429) { return retryableActionError(error, { retryAt: error.retryAfter === undefined ? undefined : new Date(Date.now() + error.retryAfter * 1_000), }) } return error.status < 500 ? terminalActionError(error) : error }