import { airtableTriggerDefinitions } from "./airtable" import { apifyTriggerDefinitions } from "./apify" import { anthropicTriggerDefinitions } from "./anthropic" import { axiomTriggerDefinitions } from "./axiom" import { automateTriggerDefinitions } from "./automate" import { asanaTriggerDefinitions } from "./asana" import { brevoTriggerDefinitions } from "./brevo" import { calcomTriggerDefinitions } from "./calcom" import { convexTriggerDefinitions } from "./convex" import { discordTriggerDefinitions } from "./discord" import { elevenLabsTriggerDefinitions } from "./elevenlabs" import { closeTriggerDefinitions } from "./close" import { cloudflareTriggerDefinitions } from "./cloudflare" import { clickUpTriggerDefinitions } from "./clickup" import { calendlyTriggerDefinitions } from "./calendly" import { coreTriggerDefinitions } from "./core" import { githubTriggerDefinitions } from "./github" import { googleTriggerDefinitions } from "./google" import { googleAdsTriggerDefinitions } from "./google-ads" import { hubspotTriggerDefinitions } from "./hubspot" import { kitTriggerDefinitions } from "./kit" import { linearTriggerDefinitions } from "./linear" import { millionVerifierTriggerDefinitions } from "./millionverifier" import { microsoftTriggerDefinitions } from "./microsoft" import { metaAdsTriggerDefinitions } from "./meta-ads" import { notionTriggerDefinitions } from "./notion" import { redditTriggerDefinitions } from "./reddit" import { resendTriggerDefinitions } from "./resend" import { slackTriggerDefinitions } from "./slack" import { squareTriggerDefinitions } from "./square" import { stripeTriggerDefinitions } from "./stripe" import { trelloTriggerDefinitions } from "./trello" import { tallyTriggerDefinitions } from "./tally" import { vercelTriggerDefinitions } from "./vercel" import { webflowTriggerDefinitions } from "./webflow" import { whatsappTriggerDefinitions } from "./whatsapp" import { sentenceCase } from "./name" import { getIntegrationService } from "../catalog" import type { TriggerDefinition, TriggerPresentation, TriggerPresentationContext, TriggerScopePresentation, } from "../types" export { getDashboardRunEndpoint, getDashboardRunEndpointKey, getHttpTriggerEndpoint, getHttpTriggerEndpointKey, getMailhookAddress, getMailhookAddressKey, PLATFORM_EMAIL_DOMAIN, DASHBOARD_RUN_CONFIG_SCHEMA, type DashboardRunConfig, type DashboardRunEndpointOptions, type HttpTriggerEndpointOptions, type HttpTriggerScope, type MailhookAddressOptions, type MailhookScope, } from "./core" /** Plain shared definitions for every public trigger type. */ export const triggerDefinitions = { ...anthropicTriggerDefinitions, ...apifyTriggerDefinitions, ...airtableTriggerDefinitions, ...axiomTriggerDefinitions, ...automateTriggerDefinitions, ...asanaTriggerDefinitions, ...brevoTriggerDefinitions, ...calcomTriggerDefinitions, ...convexTriggerDefinitions, ...discordTriggerDefinitions, ...elevenLabsTriggerDefinitions, ...closeTriggerDefinitions, ...cloudflareTriggerDefinitions, ...clickUpTriggerDefinitions, ...calendlyTriggerDefinitions, ...coreTriggerDefinitions, ...githubTriggerDefinitions, ...googleTriggerDefinitions, ...googleAdsTriggerDefinitions, ...hubspotTriggerDefinitions, ...kitTriggerDefinitions, ...linearTriggerDefinitions, ...millionVerifierTriggerDefinitions, ...microsoftTriggerDefinitions, ...metaAdsTriggerDefinitions, ...notionTriggerDefinitions, ...redditTriggerDefinitions, ...resendTriggerDefinitions, ...slackTriggerDefinitions, ...squareTriggerDefinitions, ...stripeTriggerDefinitions, ...trelloTriggerDefinitions, ...tallyTriggerDefinitions, ...vercelTriggerDefinitions, ...webflowTriggerDefinitions, ...whatsappTriggerDefinitions, } as const satisfies Record /** Trigger definitions with inferred display names materialized. */ export const triggerCatalog = Object.values(triggerDefinitions).map( (definition) => ({ ...definition, name: ("name" in definition ? definition.name : undefined) ?? inferTriggerName(definition), }), ) export type TriggerType = (typeof triggerCatalog)[number]["type"] /** * Looks up one known trigger by its stable event type. * * @param type - Stable public event type. */ export function getTriggerDefinition( type: string, ): (TriggerDefinition & { name: string }) | undefined { return triggerCatalog.find((trigger) => trigger.type === type) } /** * Resolves the display name for a stable event type. * * Known trigger types use their catalog name. Unknown types fall back to the * same sentence-case convention used by catalog definitions. * * @param type - Stable event type to name. */ export function getTriggerName(type: string) { return getTriggerDefinition(type)?.name ?? sentenceCase(type) } /** * Describes one configured trigger using its shared client-safe definition. * * @param context - Trigger identity, configuration, and public application * origin. */ export function getTriggerPresentation( context: TriggerPresentationContext & { eventType: string }, ): TriggerPresentation { const definition = getTriggerDefinition(context.eventType) const primary = definition?.getPrimary?.(context) ?? (definition?.account && context.accountLabel ? { value: context.accountLabel } : undefined) return { details: definition?.getDetails?.(context) ?? [], name: definition?.name ?? getTriggerName(context.eventType), ...(primary ? { primary } : {}), type: context.eventType, } } /** * Returns whether a trigger should be shown outside its enclosing scopes. * * @param scopePath - The trigger's enclosing scope path. * @param scopes - The automation's planned scope presentation. */ export function isTriggerVisible( scopePath: readonly number[], scopes: readonly TriggerScopePresentation[], ) { return !scopes.some( (scope) => scope.presentation !== "expanded" && scope.path.length <= scopePath.length && scope.path.every((segment, index) => scopePath[index] === segment), ) } /** * Infers presentation copy from a trigger's stable event type. * * @param definition - Trigger definition to name. */ function inferTriggerName(definition: TriggerDefinition) { const [namespace = definition.type] = definition.type.split(".") const inferredName = sentenceCase(definition.type) const service = definition.account?.serviceId.toLowerCase() === namespace.toLowerCase() ? getIntegrationService(definition.account.serviceId) : undefined return service ? inferredName.replace(sentenceCase(namespace), service.name) : inferredName }