MCPcopy
hub / github.com/simstudioai/sim / fireTableTrigger

Function fireTableTrigger

apps/sim/lib/table/trigger.ts:49–163  ·  view source on GitHub ↗
(
  tableId: string,
  tableName: string,
  eventType: EventType,
  rows: TableRow[],
  oldRows: Map<string, RowData> | null,
  schema: TableSchema,
  requestId: string
)

Source from the content-addressed store, hash-verified

47 * @param oldRows - Map of row ID to previous data. Pass null for inserts.
48 */
49export async function fireTableTrigger(
50 tableId: string,
51 tableName: string,
52 eventType: EventType,
53 rows: TableRow[],
54 oldRows: Map<string, RowData> | null,
55 schema: TableSchema,
56 requestId: string
57): Promise<void> {
58 try {
59 // Lazy: the webhook utils/processor pull in the executor + blocks stack.
60 // Eager imports would force every `lib/table/service` consumer (e.g. the
61 // dispatcher) to pay that cold-start even when no trigger fires.
62 const { fetchActiveWebhooks } = await import('@/lib/webhooks/polling/utils')
63 const webhooks = await fetchActiveWebhooks('table')
64 if (webhooks.length === 0) return
65
66 const headers = schema.columns.map((c) => c.name)
67 // The webhook payload is name-keyed (the workflow author references columns
68 // by name); stored row data is id-keyed, so translate on the way out.
69 const nameById = buildNameById(schema)
70
71 // Filter to webhooks watching this table with a matching event type
72 const matching = webhooks.filter((entry) => {
73 const config = entry.webhook.providerConfig as WebhookConfig | null
74 // Canonical key `tableId` first; `tableSelector`/`manualTableId` are a transitional
75 // basic-first fallback for configs deployed before the canonical key was written.
76 const configTableId = readCanonicalTriggerValue(
77 config?.tableId,
78 config?.tableSelector,
79 config?.manualTableId
80 )
81 if (configTableId !== tableId) return false
82
83 const configEventType = config?.eventType ?? 'insert'
84 return configEventType === eventType
85 })
86
87 if (matching.length === 0) return
88
89 const { processPolledWebhookEvent } = await import('@/lib/webhooks/processor')
90
91 logger.info(
92 `[${requestId}] Firing ${matching.length} trigger(s) for ${rows.length} ${eventType} event(s) in table ${tableId}`
93 )
94
95 for (const { webhook: webhookData, workflow: workflowData } of matching) {
96 const config = webhookData.providerConfig as WebhookConfig | null
97 const watchColumns = parseWatchColumns(config?.watchColumns)
98 const includeHeaders = config?.includeHeaders !== false
99
100 for (const row of rows) {
101 const previousIdData = oldRows?.get(row.id) ?? null
102 // Translate id-keyed stored data → name-keyed for the external payload.
103 const rawRow = rowDataIdToName(row.data, nameById)
104 const previousRow = previousIdData ? rowDataIdToName(previousIdData, nameById) : null
105 const changedColumns = previousIdData
106 ? detectChangedColumns(previousIdData, row.data)

Callers 6

insertRowFunction · 0.90
dispatchAfterBatchInsertFunction · 0.90
upsertRowFunction · 0.90
updateRowFunction · 0.90
updateRowsByFilterFunction · 0.90
batchUpdateRowsFunction · 0.90

Calls 12

buildNameByIdFunction · 0.90
rowDataIdToNameFunction · 0.90
getColumnIdFunction · 0.90
generateShortIdFunction · 0.90
fetchActiveWebhooksFunction · 0.85
parseWatchColumnsFunction · 0.85
detectChangedColumnsFunction · 0.85
infoMethod · 0.80
errorMethod · 0.80
getMethod · 0.65

Tested by

no test coverage detected