import { getHubSpotApi as getHubSpotContractApi, HubSpotApiError, } from "@automate.ax/integration-contracts/hubspot" import type { IntegrationScopeRequirement } from "../../automation/integrations" import { parseRetryAfter, retryableActionError, terminalActionError, } from "../../automation/actions" export const HUBSPOT_ACCOUNT = "hubspot" /** * Builds OAuth and private-app alternatives for one HubSpot scope. * * @param requiredScope - Scope expression required by the callable. */ export function hubSpotAccountRequirement( requiredScope: IntegrationScopeRequirement, ) { return { connections: [ { connectionMethodId: "oauth", requiredScope }, { connectionMethodId: "private-app", requiredScope }, ], } as const } /** * Creates a HubSpot client whose failures carry action retry disposition. * * @param secret - Stored HubSpot account secret. */ export function getHubSpotApi( secret: unknown, ): ReturnType { const api = getHubSpotContractApi(secret) const request = api.request.bind(api) api.request = async (path, options) => { try { return await request(path, options) } catch (error) { if (error instanceof HubSpotApiError) { if (error.status === 429) { throw retryableActionError(error, { retryAt: parseRetryAfter(error.retryAfter), }) } if (error.status < 500) throw terminalActionError(error) } throw error } } return api } /** * Encodes one HubSpot path segment without changing its path shape. * * @param value - Raw path segment. */ export function hubSpotPathSegment(value: string) { return encodeURIComponent(value) }