@xano/developer-mcp 1.0.25 → 1.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -0
- package/dist/cli_docs/format.d.ts +12 -0
- package/dist/cli_docs/format.js +98 -0
- package/dist/{api_docs → cli_docs}/index.d.ts +6 -11
- package/dist/cli_docs/index.js +86 -0
- package/dist/cli_docs/topics/function.js +114 -0
- package/dist/cli_docs/topics/integration.d.ts +2 -0
- package/dist/cli_docs/topics/integration.js +157 -0
- package/dist/{api_docs/topics/agent.d.ts → cli_docs/topics/profile.d.ts} +1 -1
- package/dist/cli_docs/topics/profile.js +153 -0
- package/dist/{api_docs/topics/api.d.ts → cli_docs/topics/run.d.ts} +1 -1
- package/dist/cli_docs/topics/run.js +248 -0
- package/dist/cli_docs/topics/start.js +111 -0
- package/dist/cli_docs/topics/static_host.d.ts +2 -0
- package/dist/cli_docs/topics/static_host.js +77 -0
- package/dist/cli_docs/topics/workspace.js +119 -0
- package/dist/cli_docs/types.d.ts +44 -0
- package/dist/cli_docs/types.js +4 -0
- package/dist/index.js +42 -0
- package/dist/xanoscript_docs/README.md +78 -64
- package/dist/xanoscript_docs/apis.md +81 -27
- package/dist/xanoscript_docs/branch.md +13 -13
- package/dist/xanoscript_docs/database.md +57 -17
- package/dist/xanoscript_docs/functions.md +43 -71
- package/dist/xanoscript_docs/performance.md +14 -23
- package/dist/xanoscript_docs/tables.md +47 -1
- package/dist/xanoscript_docs/tools.md +9 -7
- package/dist/xanoscript_docs/types.md +12 -10
- package/package.json +1 -1
- package/dist/api_docs/format.d.ts +0 -5
- package/dist/api_docs/format.js +0 -171
- package/dist/api_docs/index.js +0 -111
- package/dist/api_docs/topics/agent.js +0 -142
- package/dist/api_docs/topics/api.js +0 -176
- package/dist/api_docs/topics/apigroup.d.ts +0 -2
- package/dist/api_docs/topics/apigroup.js +0 -124
- package/dist/api_docs/topics/authentication.d.ts +0 -2
- package/dist/api_docs/topics/authentication.js +0 -61
- package/dist/api_docs/topics/branch.d.ts +0 -2
- package/dist/api_docs/topics/branch.js +0 -73
- package/dist/api_docs/topics/file.d.ts +0 -2
- package/dist/api_docs/topics/file.js +0 -70
- package/dist/api_docs/topics/function.js +0 -164
- package/dist/api_docs/topics/history.d.ts +0 -2
- package/dist/api_docs/topics/history.js +0 -149
- package/dist/api_docs/topics/mcp_server.d.ts +0 -2
- package/dist/api_docs/topics/mcp_server.js +0 -139
- package/dist/api_docs/topics/middleware.d.ts +0 -2
- package/dist/api_docs/topics/middleware.js +0 -156
- package/dist/api_docs/topics/realtime.d.ts +0 -2
- package/dist/api_docs/topics/realtime.js +0 -112
- package/dist/api_docs/topics/start.js +0 -107
- package/dist/api_docs/topics/table.d.ts +0 -2
- package/dist/api_docs/topics/table.js +0 -195
- package/dist/api_docs/topics/task.d.ts +0 -2
- package/dist/api_docs/topics/task.js +0 -165
- package/dist/api_docs/topics/tool.d.ts +0 -2
- package/dist/api_docs/topics/tool.js +0 -150
- package/dist/api_docs/topics/workflows.d.ts +0 -2
- package/dist/api_docs/topics/workflows.js +0 -131
- package/dist/api_docs/topics/workspace.js +0 -153
- package/dist/api_docs/types.d.ts +0 -79
- package/dist/api_docs/types.js +0 -4
- package/dist/templates/init-workspace.d.ts +0 -10
- package/dist/templates/init-workspace.js +0 -278
- package/dist/templates/xanoscript-index.d.ts +0 -11
- package/dist/templates/xanoscript-index.js +0 -72
- package/dist/xanoscript_docs/ephemeral.md +0 -330
- package/dist/xanoscript_docs_auto/README.md +0 -119
- package/dist/xanoscript_docs_auto/agents.md +0 -446
- package/dist/xanoscript_docs_auto/apis.md +0 -517
- package/dist/xanoscript_docs_auto/control-flow.md +0 -543
- package/dist/xanoscript_docs_auto/database.md +0 -551
- package/dist/xanoscript_docs_auto/debugging.md +0 -527
- package/dist/xanoscript_docs_auto/filters.md +0 -464
- package/dist/xanoscript_docs_auto/functions.md +0 -431
- package/dist/xanoscript_docs_auto/integrations.md +0 -657
- package/dist/xanoscript_docs_auto/mcp-servers.md +0 -408
- package/dist/xanoscript_docs_auto/operators.md +0 -368
- package/dist/xanoscript_docs_auto/syntax.md +0 -287
- package/dist/xanoscript_docs_auto/tables.md +0 -447
- package/dist/xanoscript_docs_auto/tasks.md +0 -479
- package/dist/xanoscript_docs_auto/testing.md +0 -574
- package/dist/xanoscript_docs_auto/tools.md +0 -485
- package/dist/xanoscript_docs_auto/triggers.md +0 -595
- package/dist/xanoscript_docs_auto/types.md +0 -323
- package/dist/xanoscript_docs_auto/variables.md +0 -462
- package/dist/xanoscript_docs_auto/version.json +0 -5
- /package/dist/{api_docs → cli_docs}/topics/function.d.ts +0 -0
- /package/dist/{api_docs → cli_docs}/topics/start.d.ts +0 -0
- /package/dist/{api_docs → cli_docs}/topics/workspace.d.ts +0 -0
|
@@ -1,595 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
applyTo: "triggers/**/*.xs"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Triggers
|
|
6
|
-
|
|
7
|
-
Event-driven handlers for database, realtime, workspace, agent, and MCP events.
|
|
8
|
-
|
|
9
|
-
## Quick Reference
|
|
10
|
-
|
|
11
|
-
| Trigger Type | Purpose |
|
|
12
|
-
|--------------|---------|
|
|
13
|
-
| `table_trigger` | Database table events (insert, update, delete) |
|
|
14
|
-
| `realtime_trigger` | Real-time channel events |
|
|
15
|
-
| `workspace_trigger` | Workspace-level events |
|
|
16
|
-
| `agent_trigger` | AI agent events |
|
|
17
|
-
| `mcp_server_trigger` | MCP server events |
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Table Triggers
|
|
22
|
-
|
|
23
|
-
React to database table changes:
|
|
24
|
-
|
|
25
|
-
### On Insert
|
|
26
|
-
|
|
27
|
-
```xs
|
|
28
|
-
table_trigger "user_created" {
|
|
29
|
-
table = user
|
|
30
|
-
event = insert
|
|
31
|
-
|
|
32
|
-
stack {
|
|
33
|
-
// Send welcome email
|
|
34
|
-
util.send_email {
|
|
35
|
-
to = $trigger.new.email
|
|
36
|
-
subject = "Welcome!"
|
|
37
|
-
body = "Thank you for signing up, " ~ $trigger.new.name ~ "!"
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Create initial preferences
|
|
41
|
-
db.add user_preference {
|
|
42
|
-
data = {
|
|
43
|
-
user_id: $trigger.new.id,
|
|
44
|
-
theme: "light",
|
|
45
|
-
notifications: true
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### On Update
|
|
53
|
-
|
|
54
|
-
```xs
|
|
55
|
-
table_trigger "order_status_changed" {
|
|
56
|
-
table = order
|
|
57
|
-
event = update
|
|
58
|
-
|
|
59
|
-
stack {
|
|
60
|
-
// Check if status changed
|
|
61
|
-
conditional {
|
|
62
|
-
if ($trigger.old.status != $trigger.new.status) {
|
|
63
|
-
// Log status change
|
|
64
|
-
db.add order_history {
|
|
65
|
-
data = {
|
|
66
|
-
order_id: $trigger.new.id,
|
|
67
|
-
old_status: $trigger.old.status,
|
|
68
|
-
new_status: $trigger.new.status,
|
|
69
|
-
changed_at: now
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Notify customer
|
|
74
|
-
conditional {
|
|
75
|
-
if ($trigger.new.status == "shipped") {
|
|
76
|
-
util.send_email {
|
|
77
|
-
to = $trigger.new.customer_email
|
|
78
|
-
subject = "Your order has shipped!"
|
|
79
|
-
body = "Order #" ~ $trigger.new.order_number ~ " is on its way."
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### On Delete
|
|
90
|
-
|
|
91
|
-
```xs
|
|
92
|
-
table_trigger "user_deleted" {
|
|
93
|
-
table = user
|
|
94
|
-
event = delete
|
|
95
|
-
|
|
96
|
-
stack {
|
|
97
|
-
// Clean up related data
|
|
98
|
-
db.bulk.delete session {
|
|
99
|
-
where = $db.session.user_id == $trigger.old.id
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
db.bulk.delete user_preference {
|
|
103
|
-
where = $db.user_preference.user_id == $trigger.old.id
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Log deletion
|
|
107
|
-
db.add audit_log {
|
|
108
|
-
data = {
|
|
109
|
-
action: "user_deleted",
|
|
110
|
-
user_id: $trigger.old.id,
|
|
111
|
-
user_email: $trigger.old.email,
|
|
112
|
-
deleted_at: now
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
## Trigger Context
|
|
122
|
-
|
|
123
|
-
### $trigger.new
|
|
124
|
-
|
|
125
|
-
New record data (available on insert and update):
|
|
126
|
-
|
|
127
|
-
```xs
|
|
128
|
-
$trigger.new.id
|
|
129
|
-
$trigger.new.name
|
|
130
|
-
$trigger.new.email
|
|
131
|
-
$trigger.new.created_at
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### $trigger.old
|
|
135
|
-
|
|
136
|
-
Previous record data (available on update and delete):
|
|
137
|
-
|
|
138
|
-
```xs
|
|
139
|
-
$trigger.old.id
|
|
140
|
-
$trigger.old.status
|
|
141
|
-
$trigger.old.updated_at
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### Comparing Old and New
|
|
145
|
-
|
|
146
|
-
```xs
|
|
147
|
-
table_trigger "price_changed" {
|
|
148
|
-
table = product
|
|
149
|
-
event = update
|
|
150
|
-
|
|
151
|
-
stack {
|
|
152
|
-
conditional {
|
|
153
|
-
if ($trigger.old.price != $trigger.new.price) {
|
|
154
|
-
// Price changed - log it
|
|
155
|
-
db.add price_history {
|
|
156
|
-
data = {
|
|
157
|
-
product_id: $trigger.new.id,
|
|
158
|
-
old_price: $trigger.old.price,
|
|
159
|
-
new_price: $trigger.new.price,
|
|
160
|
-
changed_at: now
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
## Multiple Events
|
|
172
|
-
|
|
173
|
-
Handle multiple events in one trigger:
|
|
174
|
-
|
|
175
|
-
```xs
|
|
176
|
-
table_trigger "product_audit" {
|
|
177
|
-
table = product
|
|
178
|
-
event = [insert, update, delete]
|
|
179
|
-
|
|
180
|
-
stack {
|
|
181
|
-
var $action {
|
|
182
|
-
value = $trigger.event // "insert", "update", or "delete"
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
db.add audit_log {
|
|
186
|
-
data = {
|
|
187
|
-
table_name: "product",
|
|
188
|
-
action: $action,
|
|
189
|
-
record_id: ($trigger.new ?? $trigger.old).id,
|
|
190
|
-
old_data: $trigger.old|json_encode,
|
|
191
|
-
new_data: $trigger.new|json_encode,
|
|
192
|
-
created_at: now
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
---
|
|
200
|
-
|
|
201
|
-
## Realtime Triggers
|
|
202
|
-
|
|
203
|
-
Handle real-time channel events:
|
|
204
|
-
|
|
205
|
-
```xs
|
|
206
|
-
realtime_trigger "chat_message" {
|
|
207
|
-
channel = "chat:*"
|
|
208
|
-
event = message
|
|
209
|
-
|
|
210
|
-
stack {
|
|
211
|
-
// Store message
|
|
212
|
-
db.add chat_message {
|
|
213
|
-
data = {
|
|
214
|
-
channel: $trigger.channel,
|
|
215
|
-
user_id: $trigger.user_id,
|
|
216
|
-
message: $trigger.data.message,
|
|
217
|
-
created_at: now
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Broadcast to other users
|
|
222
|
-
api.realtime_event {
|
|
223
|
-
channel = $trigger.channel
|
|
224
|
-
event = "new_message"
|
|
225
|
-
data = {
|
|
226
|
-
user_id: $trigger.user_id,
|
|
227
|
-
message: $trigger.data.message,
|
|
228
|
-
timestamp: now
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
### Channel Patterns
|
|
236
|
-
|
|
237
|
-
```xs
|
|
238
|
-
// Exact channel match
|
|
239
|
-
channel = "notifications"
|
|
240
|
-
|
|
241
|
-
// Wildcard pattern
|
|
242
|
-
channel = "chat:*" // Matches chat:room1, chat:room2, etc.
|
|
243
|
-
channel = "user:*:updates" // Matches user:123:updates
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
---
|
|
247
|
-
|
|
248
|
-
## Workspace Triggers
|
|
249
|
-
|
|
250
|
-
Handle workspace-level events:
|
|
251
|
-
|
|
252
|
-
```xs
|
|
253
|
-
workspace_trigger "on_error" {
|
|
254
|
-
event = error
|
|
255
|
-
|
|
256
|
-
stack {
|
|
257
|
-
// Log errors
|
|
258
|
-
db.add error_log {
|
|
259
|
-
data = {
|
|
260
|
-
error_type: $trigger.error.type,
|
|
261
|
-
error_message: $trigger.error.message,
|
|
262
|
-
stack_trace: $trigger.error.stack,
|
|
263
|
-
request_path: $trigger.request.path,
|
|
264
|
-
user_id: $trigger.auth.id,
|
|
265
|
-
created_at: now
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// Alert on critical errors
|
|
270
|
-
conditional {
|
|
271
|
-
if ($trigger.error.code >= 500) {
|
|
272
|
-
util.send_email {
|
|
273
|
-
to = $env.ADMIN_EMAIL
|
|
274
|
-
subject = "Critical Error Alert"
|
|
275
|
-
body = $trigger.error.message
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
### Workspace Events
|
|
284
|
-
|
|
285
|
-
| Event | Description |
|
|
286
|
-
|-------|-------------|
|
|
287
|
-
| `error` | Runtime error occurred |
|
|
288
|
-
| `request` | API request received |
|
|
289
|
-
| `response` | API response sent |
|
|
290
|
-
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
## Agent Triggers
|
|
294
|
-
|
|
295
|
-
Handle AI agent events:
|
|
296
|
-
|
|
297
|
-
```xs
|
|
298
|
-
agent_trigger "on_completion" {
|
|
299
|
-
agent = "customer_support"
|
|
300
|
-
event = completion
|
|
301
|
-
|
|
302
|
-
stack {
|
|
303
|
-
// Log agent response
|
|
304
|
-
db.add agent_log {
|
|
305
|
-
data = {
|
|
306
|
-
agent: $trigger.agent,
|
|
307
|
-
conversation_id: $trigger.conversation_id,
|
|
308
|
-
input: $trigger.input,
|
|
309
|
-
output: $trigger.output,
|
|
310
|
-
tokens_used: $trigger.usage.total_tokens,
|
|
311
|
-
created_at: now
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
### Agent Events
|
|
319
|
-
|
|
320
|
-
| Event | Description |
|
|
321
|
-
|-------|-------------|
|
|
322
|
-
| `completion` | Agent completed response |
|
|
323
|
-
| `tool_call` | Agent called a tool |
|
|
324
|
-
| `error` | Agent encountered error |
|
|
325
|
-
|
|
326
|
-
### Tool Call Trigger
|
|
327
|
-
|
|
328
|
-
```xs
|
|
329
|
-
agent_trigger "log_tool_usage" {
|
|
330
|
-
agent = "*" // All agents
|
|
331
|
-
event = tool_call
|
|
332
|
-
|
|
333
|
-
stack {
|
|
334
|
-
db.add tool_usage {
|
|
335
|
-
data = {
|
|
336
|
-
agent: $trigger.agent,
|
|
337
|
-
tool_name: $trigger.tool.name,
|
|
338
|
-
tool_input: $trigger.tool.input|json_encode,
|
|
339
|
-
tool_output: $trigger.tool.output|json_encode,
|
|
340
|
-
created_at: now
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
---
|
|
348
|
-
|
|
349
|
-
## MCP Server Triggers
|
|
350
|
-
|
|
351
|
-
Handle MCP (Model Context Protocol) server events:
|
|
352
|
-
|
|
353
|
-
```xs
|
|
354
|
-
mcp_server_trigger "tool_invoked" {
|
|
355
|
-
server = "my_mcp_server"
|
|
356
|
-
event = tool_call
|
|
357
|
-
|
|
358
|
-
stack {
|
|
359
|
-
db.add mcp_log {
|
|
360
|
-
data = {
|
|
361
|
-
server: $trigger.server,
|
|
362
|
-
tool: $trigger.tool,
|
|
363
|
-
input: $trigger.input|json_encode,
|
|
364
|
-
created_at: now
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
---
|
|
372
|
-
|
|
373
|
-
## Common Patterns
|
|
374
|
-
|
|
375
|
-
### Audit Trail
|
|
376
|
-
|
|
377
|
-
```xs
|
|
378
|
-
table_trigger "audit_all_changes" {
|
|
379
|
-
table = [user, product, order]
|
|
380
|
-
event = [insert, update, delete]
|
|
381
|
-
|
|
382
|
-
stack {
|
|
383
|
-
db.add audit_trail {
|
|
384
|
-
data = {
|
|
385
|
-
table_name: $trigger.table,
|
|
386
|
-
record_id: ($trigger.new ?? $trigger.old).id,
|
|
387
|
-
action: $trigger.event,
|
|
388
|
-
user_id: $auth.id,
|
|
389
|
-
old_data: $trigger.old,
|
|
390
|
-
new_data: $trigger.new,
|
|
391
|
-
ip_address: $env.$remote_ip,
|
|
392
|
-
created_at: now
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
### Cache Invalidation
|
|
400
|
-
|
|
401
|
-
```xs
|
|
402
|
-
table_trigger "invalidate_cache" {
|
|
403
|
-
table = product
|
|
404
|
-
event = [update, delete]
|
|
405
|
-
|
|
406
|
-
stack {
|
|
407
|
-
// Clear product cache
|
|
408
|
-
redis.del {
|
|
409
|
-
key = "product:" ~ ($trigger.new ?? $trigger.old).id
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// Clear category cache
|
|
413
|
-
redis.del {
|
|
414
|
-
key = "category:" ~ ($trigger.new ?? $trigger.old).category_id
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// Clear listing cache
|
|
418
|
-
redis.del {
|
|
419
|
-
key = "products:list"
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
### Cascading Updates
|
|
426
|
-
|
|
427
|
-
```xs
|
|
428
|
-
table_trigger "update_order_totals" {
|
|
429
|
-
table = order_item
|
|
430
|
-
event = [insert, update, delete]
|
|
431
|
-
|
|
432
|
-
stack {
|
|
433
|
-
var $order_id {
|
|
434
|
-
value = ($trigger.new ?? $trigger.old).order_id
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// Recalculate order total
|
|
438
|
-
db.query order_item {
|
|
439
|
-
where = $db.order_item.order_id == $order_id
|
|
440
|
-
} as $items
|
|
441
|
-
|
|
442
|
-
var $new_total {
|
|
443
|
-
value = $items|map:$$.total|sum
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
db.patch order {
|
|
447
|
-
field_name = "id"
|
|
448
|
-
field_value = $order_id
|
|
449
|
-
data = {
|
|
450
|
-
total: $new_total,
|
|
451
|
-
updated_at: now
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
### Notifications
|
|
459
|
-
|
|
460
|
-
```xs
|
|
461
|
-
table_trigger "notify_on_mention" {
|
|
462
|
-
table = comment
|
|
463
|
-
event = insert
|
|
464
|
-
|
|
465
|
-
stack {
|
|
466
|
-
// Extract mentioned users
|
|
467
|
-
var $mentions {
|
|
468
|
-
value = $trigger.new.content|regex_get_all_matches:"@(\w+)"
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
foreach ($mentions) {
|
|
472
|
-
each as $username {
|
|
473
|
-
db.get user {
|
|
474
|
-
field_name = "username"
|
|
475
|
-
field_value = $username
|
|
476
|
-
} as $user
|
|
477
|
-
|
|
478
|
-
conditional {
|
|
479
|
-
if ($user != null) {
|
|
480
|
-
db.add notification {
|
|
481
|
-
data = {
|
|
482
|
-
user_id: $user.id,
|
|
483
|
-
type: "mention",
|
|
484
|
-
message: "You were mentioned in a comment",
|
|
485
|
-
reference_id: $trigger.new.id,
|
|
486
|
-
created_at: now
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
```
|
|
496
|
-
|
|
497
|
-
---
|
|
498
|
-
|
|
499
|
-
## Error Handling
|
|
500
|
-
|
|
501
|
-
```xs
|
|
502
|
-
table_trigger "safe_trigger" {
|
|
503
|
-
table = order
|
|
504
|
-
event = insert
|
|
505
|
-
|
|
506
|
-
stack {
|
|
507
|
-
try_catch {
|
|
508
|
-
try {
|
|
509
|
-
// Send notification
|
|
510
|
-
util.send_email {
|
|
511
|
-
to = $trigger.new.customer_email
|
|
512
|
-
subject = "Order Confirmation"
|
|
513
|
-
body = "Your order has been received."
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
catch {
|
|
517
|
-
// Log error but don't fail the trigger
|
|
518
|
-
db.add trigger_error {
|
|
519
|
-
data = {
|
|
520
|
-
trigger: "safe_trigger",
|
|
521
|
-
error: $error.message,
|
|
522
|
-
record_id: $trigger.new.id,
|
|
523
|
-
created_at: now
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
---
|
|
533
|
-
|
|
534
|
-
## Best Practices
|
|
535
|
-
|
|
536
|
-
### Keep Triggers Fast
|
|
537
|
-
|
|
538
|
-
Triggers run synchronously. For heavy processing:
|
|
539
|
-
|
|
540
|
-
```xs
|
|
541
|
-
table_trigger "queue_processing" {
|
|
542
|
-
table = order
|
|
543
|
-
event = insert
|
|
544
|
-
|
|
545
|
-
stack {
|
|
546
|
-
// Add to queue instead of processing inline
|
|
547
|
-
redis.push {
|
|
548
|
-
key = "queue:order_processing"
|
|
549
|
-
value = $trigger.new.id|to_text
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
### Avoid Infinite Loops
|
|
556
|
-
|
|
557
|
-
Be careful with triggers that update the same table:
|
|
558
|
-
|
|
559
|
-
```xs
|
|
560
|
-
table_trigger "safe_update" {
|
|
561
|
-
table = order
|
|
562
|
-
event = update
|
|
563
|
-
|
|
564
|
-
stack {
|
|
565
|
-
// Only act on specific field changes
|
|
566
|
-
conditional {
|
|
567
|
-
if ($trigger.old.status != $trigger.new.status) {
|
|
568
|
-
// This is safe - we're checking the specific change
|
|
569
|
-
// Don't update status here or you'll create a loop
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
```
|
|
575
|
-
|
|
576
|
-
### Use Conditions
|
|
577
|
-
|
|
578
|
-
Filter when triggers fire:
|
|
579
|
-
|
|
580
|
-
```xs
|
|
581
|
-
table_trigger "notify_high_value" {
|
|
582
|
-
table = order
|
|
583
|
-
event = insert
|
|
584
|
-
condition = $trigger.new.total > 1000
|
|
585
|
-
|
|
586
|
-
stack {
|
|
587
|
-
// Only runs for orders over $1000
|
|
588
|
-
util.send_email {
|
|
589
|
-
to = $env.SALES_EMAIL
|
|
590
|
-
subject = "High-value order received!"
|
|
591
|
-
body = "Order #" ~ $trigger.new.order_number ~ " for $" ~ $trigger.new.total
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
```
|