@xano/developer-mcp 1.0.26 → 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/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.d.ts +0 -52
- package/dist/api_docs/index.js +0 -111
- package/dist/api_docs/topics/agent.d.ts +0 -2
- package/dist/api_docs/topics/agent.js +0 -142
- package/dist/api_docs/topics/api.d.ts +0 -2
- 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.d.ts +0 -2
- 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.d.ts +0 -2
- 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.d.ts +0 -2
- 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
|
@@ -8,17 +8,17 @@ Complete reference for XanoScript database operations.
|
|
|
8
8
|
|
|
9
9
|
## Quick Reference
|
|
10
10
|
|
|
11
|
-
| Operation
|
|
12
|
-
|
|
13
|
-
| `db.query`
|
|
14
|
-
| `db.get`
|
|
15
|
-
| `db.has`
|
|
16
|
-
| `db.add`
|
|
17
|
-
| `db.edit`
|
|
18
|
-
| `db.patch`
|
|
19
|
-
| `db.add_or_edit` | Upsert record
|
|
20
|
-
| `db.del`
|
|
21
|
-
| `db.truncate`
|
|
11
|
+
| Operation | Purpose | Returns |
|
|
12
|
+
| ---------------- | ----------------------------- | ------------------------ |
|
|
13
|
+
| `db.query` | Query multiple records | List/single/count/exists |
|
|
14
|
+
| `db.get` | Get single record by field | Record or null |
|
|
15
|
+
| `db.has` | Check if record exists | Boolean |
|
|
16
|
+
| `db.add` | Insert new record | Created record |
|
|
17
|
+
| `db.edit` | Update record (inline data) | Updated record |
|
|
18
|
+
| `db.patch` | Update record (variable data) | Updated record |
|
|
19
|
+
| `db.add_or_edit` | Upsert record | Record |
|
|
20
|
+
| `db.del` | Delete record | None |
|
|
21
|
+
| `db.truncate` | Delete all records | None |
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
@@ -27,6 +27,7 @@ Complete reference for XanoScript database operations.
|
|
|
27
27
|
Query multiple records with filters, sorting, and pagination.
|
|
28
28
|
|
|
29
29
|
### Basic Query
|
|
30
|
+
|
|
30
31
|
```xs
|
|
31
32
|
db.query "product" {
|
|
32
33
|
where = $db.product.is_active == true
|
|
@@ -34,6 +35,7 @@ db.query "product" {
|
|
|
34
35
|
```
|
|
35
36
|
|
|
36
37
|
### Where Operators
|
|
38
|
+
|
|
37
39
|
```xs
|
|
38
40
|
// Comparison
|
|
39
41
|
$db.product.price == 100
|
|
@@ -62,13 +64,14 @@ $db.product.category == "electronics" || $db.product.featured == true
|
|
|
62
64
|
```
|
|
63
65
|
|
|
64
66
|
### Return Types
|
|
67
|
+
|
|
65
68
|
```xs
|
|
66
|
-
//
|
|
69
|
+
// returns an array of products (default)
|
|
67
70
|
db.query "product" {
|
|
68
71
|
return = { type: "list" }
|
|
69
72
|
} as $products
|
|
70
73
|
|
|
71
|
-
//
|
|
74
|
+
// Returns a paginated list of products
|
|
72
75
|
db.query "product" {
|
|
73
76
|
return = {
|
|
74
77
|
type: "list",
|
|
@@ -76,19 +79,19 @@ db.query "product" {
|
|
|
76
79
|
}
|
|
77
80
|
} as $products
|
|
78
81
|
|
|
79
|
-
//
|
|
82
|
+
// Returns a single record
|
|
80
83
|
db.query "product" {
|
|
81
84
|
where = $db.product.sku == $input.sku
|
|
82
85
|
return = { type: "single" }
|
|
83
86
|
} as $product
|
|
84
87
|
|
|
85
|
-
//
|
|
88
|
+
// Returns a count (number)
|
|
86
89
|
db.query "product" {
|
|
87
90
|
where = $db.product.is_active == true
|
|
88
91
|
return = { type: "count" }
|
|
89
92
|
} as $count
|
|
90
93
|
|
|
91
|
-
//
|
|
94
|
+
// Returns a boolean indicating existence
|
|
92
95
|
db.query "product" {
|
|
93
96
|
where = $db.product.email == $input.email
|
|
94
97
|
return = { type: "exists" }
|
|
@@ -96,6 +99,7 @@ db.query "product" {
|
|
|
96
99
|
```
|
|
97
100
|
|
|
98
101
|
### Sorting
|
|
102
|
+
|
|
99
103
|
```xs
|
|
100
104
|
db.query "product" {
|
|
101
105
|
sort = { created_at: "desc" } // Descending
|
|
@@ -105,6 +109,7 @@ db.query "product" {
|
|
|
105
109
|
```
|
|
106
110
|
|
|
107
111
|
### Joins
|
|
112
|
+
|
|
108
113
|
```xs
|
|
109
114
|
db.query "comment" {
|
|
110
115
|
join = {
|
|
@@ -114,11 +119,15 @@ db.query "comment" {
|
|
|
114
119
|
where: $db.comment.post_id == $db.post.id
|
|
115
120
|
}
|
|
116
121
|
}
|
|
122
|
+
eval = {
|
|
123
|
+
post_title: $db.post.title
|
|
124
|
+
}
|
|
117
125
|
where = $db.post.author_id == $auth.id
|
|
118
126
|
} as $comments
|
|
119
127
|
```
|
|
120
128
|
|
|
121
129
|
### Eval (Computed Fields)
|
|
130
|
+
|
|
122
131
|
```xs
|
|
123
132
|
db.query "order" {
|
|
124
133
|
join = {
|
|
@@ -132,6 +141,7 @@ db.query "order" {
|
|
|
132
141
|
```
|
|
133
142
|
|
|
134
143
|
### Addons (Related Data)
|
|
144
|
+
|
|
135
145
|
```xs
|
|
136
146
|
db.query "post" {
|
|
137
147
|
where = $db.post.author_id == $auth.id
|
|
@@ -141,6 +151,30 @@ db.query "post" {
|
|
|
141
151
|
} as $posts
|
|
142
152
|
```
|
|
143
153
|
|
|
154
|
+
### Vector Search (Similarity)
|
|
155
|
+
|
|
156
|
+
Search by vector similarity using embeddings. Requires a `vector` column with a `vector` index on the table (see [tables.md](tables.md)).
|
|
157
|
+
|
|
158
|
+
```xs
|
|
159
|
+
// Embeddings from an LLM engine
|
|
160
|
+
var $embeddings {
|
|
161
|
+
value = [0.345, 0.1553, ...]
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
db.query agent_message {
|
|
165
|
+
sort = {distance: "asc"}
|
|
166
|
+
eval = {
|
|
167
|
+
distance: $db.agent_message.embeddings|cosine_distance:$embeddings
|
|
168
|
+
}
|
|
169
|
+
return = {
|
|
170
|
+
type : "list"
|
|
171
|
+
paging: {page: 1, per_page: 5, metadata: false}
|
|
172
|
+
}
|
|
173
|
+
} as $search_results
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The `cosine_distance` filter computes the distance between the row's vector and the provided embeddings. Sort by `distance` ascending (smallest distance = most similar) — this ordering is required to leverage the PostgreSQL vector index.
|
|
177
|
+
|
|
144
178
|
---
|
|
145
179
|
|
|
146
180
|
## db.get
|
|
@@ -338,6 +372,7 @@ db.transaction {
|
|
|
338
372
|
Filters for use in `where` clauses:
|
|
339
373
|
|
|
340
374
|
### String/Text
|
|
375
|
+
|
|
341
376
|
```xs
|
|
342
377
|
$db.name|to_lower // Case conversion
|
|
343
378
|
$db.name|concat:" " // Concatenation
|
|
@@ -345,6 +380,7 @@ $db.text|substr:0:100 // Substring
|
|
|
345
380
|
```
|
|
346
381
|
|
|
347
382
|
### Numeric
|
|
383
|
+
|
|
348
384
|
```xs
|
|
349
385
|
$db.price|round:2
|
|
350
386
|
$db.price|floor
|
|
@@ -354,6 +390,7 @@ $db.price|mul:1.1
|
|
|
354
390
|
```
|
|
355
391
|
|
|
356
392
|
### Timestamp
|
|
393
|
+
|
|
357
394
|
```xs
|
|
358
395
|
$db.created_at|timestamp_year
|
|
359
396
|
$db.created_at|timestamp_month
|
|
@@ -362,18 +399,21 @@ $db.created_at|timestamp_subtract_hours:24
|
|
|
362
399
|
```
|
|
363
400
|
|
|
364
401
|
### Geographic
|
|
402
|
+
|
|
365
403
|
```xs
|
|
366
404
|
$db.location|distance:$input.point // Distance in meters
|
|
367
405
|
$db.location|within:$input.point:1000 // Within radius
|
|
368
406
|
```
|
|
369
407
|
|
|
370
408
|
### Vector (AI/ML)
|
|
409
|
+
|
|
371
410
|
```xs
|
|
372
|
-
$db.embedding|
|
|
411
|
+
$db.embedding|cosine_distance:$input.vector
|
|
373
412
|
$db.embedding|l2_distance_euclidean:$input.vector
|
|
374
413
|
```
|
|
375
414
|
|
|
376
415
|
### Full-Text Search
|
|
416
|
+
|
|
377
417
|
```xs
|
|
378
418
|
$db.content|search_rank:$input.query
|
|
379
419
|
```
|
|
@@ -19,7 +19,9 @@ function "<name>" {
|
|
|
19
19
|
}
|
|
20
20
|
response = $result
|
|
21
21
|
}
|
|
22
|
+
```
|
|
22
23
|
|
|
24
|
+
```xs
|
|
23
25
|
// Function with no inputs - IMPORTANT: braces must be on separate lines
|
|
24
26
|
function "<name>" {
|
|
25
27
|
description = "..."
|
|
@@ -31,6 +33,7 @@ function "<name>" {
|
|
|
31
33
|
```
|
|
32
34
|
|
|
33
35
|
### Calling Functions
|
|
36
|
+
|
|
34
37
|
```xs
|
|
35
38
|
function.run "<name>" {
|
|
36
39
|
input = { key: value }
|
|
@@ -55,7 +58,9 @@ function "calculate_total" {
|
|
|
55
58
|
```
|
|
56
59
|
|
|
57
60
|
### With Subfolders
|
|
61
|
+
|
|
58
62
|
Functions can be organized in subfolders:
|
|
63
|
+
|
|
59
64
|
```
|
|
60
65
|
functions/
|
|
61
66
|
├── math/
|
|
@@ -82,31 +87,25 @@ input {
|
|
|
82
87
|
}
|
|
83
88
|
```
|
|
84
89
|
|
|
85
|
-
### Empty Input Blocks
|
|
90
|
+
### Empty and Single-Input Blocks
|
|
86
91
|
|
|
87
|
-
|
|
92
|
+
Empty input blocks and single-input blocks can be written as one-liners. However, when there are two or more inputs, each must be on its own line.
|
|
88
93
|
|
|
89
94
|
```xs
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
description = "Returns all users"
|
|
93
|
-
input {
|
|
94
|
-
}
|
|
95
|
-
stack {
|
|
96
|
-
db.query "user" {} as $users
|
|
97
|
-
}
|
|
98
|
-
response = $users
|
|
99
|
-
}
|
|
95
|
+
// OK - empty input as one-liner
|
|
96
|
+
input {}
|
|
100
97
|
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
response = $users
|
|
98
|
+
// OK - single input as one-liner
|
|
99
|
+
input { email email_input? filters=trim|lower }
|
|
100
|
+
|
|
101
|
+
// OK - multiple inputs on separate lines
|
|
102
|
+
input {
|
|
103
|
+
email email_input? filters=trim|lower
|
|
104
|
+
text name
|
|
109
105
|
}
|
|
106
|
+
|
|
107
|
+
// WRONG - multiple inputs on one line will cause parsing errors
|
|
108
|
+
input { email email_input? filters=trim|lower text name }
|
|
110
109
|
```
|
|
111
110
|
|
|
112
111
|
---
|
|
@@ -116,6 +115,7 @@ function "get_all_users" {
|
|
|
116
115
|
Contains the function logic using control flow, variables, and operations.
|
|
117
116
|
|
|
118
117
|
### Variables
|
|
118
|
+
|
|
119
119
|
```xs
|
|
120
120
|
stack {
|
|
121
121
|
var $counter { value = 0 }
|
|
@@ -127,6 +127,7 @@ stack {
|
|
|
127
127
|
```
|
|
128
128
|
|
|
129
129
|
### Conditionals
|
|
130
|
+
|
|
130
131
|
```xs
|
|
131
132
|
stack {
|
|
132
133
|
conditional {
|
|
@@ -144,6 +145,7 @@ stack {
|
|
|
144
145
|
```
|
|
145
146
|
|
|
146
147
|
### Loops
|
|
148
|
+
|
|
147
149
|
```xs
|
|
148
150
|
stack {
|
|
149
151
|
// For loop (count-based)
|
|
@@ -170,6 +172,7 @@ stack {
|
|
|
170
172
|
```
|
|
171
173
|
|
|
172
174
|
### Switch
|
|
175
|
+
|
|
173
176
|
```xs
|
|
174
177
|
stack {
|
|
175
178
|
switch ($input.status) {
|
|
@@ -208,6 +211,7 @@ response = null // No return value
|
|
|
208
211
|
## Calling Functions
|
|
209
212
|
|
|
210
213
|
### Basic Call
|
|
214
|
+
|
|
211
215
|
```xs
|
|
212
216
|
function.run "calculate_total" {
|
|
213
217
|
input = { quantity: 5, price: 10.50 }
|
|
@@ -215,6 +219,7 @@ function.run "calculate_total" {
|
|
|
215
219
|
```
|
|
216
220
|
|
|
217
221
|
### With Variables
|
|
222
|
+
|
|
218
223
|
```xs
|
|
219
224
|
function.run "process_order" {
|
|
220
225
|
input = {
|
|
@@ -226,6 +231,7 @@ function.run "process_order" {
|
|
|
226
231
|
```
|
|
227
232
|
|
|
228
233
|
### Nested Calls
|
|
234
|
+
|
|
229
235
|
```xs
|
|
230
236
|
stack {
|
|
231
237
|
function.run "validate_user" {
|
|
@@ -245,6 +251,7 @@ stack {
|
|
|
245
251
|
## Complete Examples
|
|
246
252
|
|
|
247
253
|
### Utility Function
|
|
254
|
+
|
|
248
255
|
```xs
|
|
249
256
|
function "utils/format_currency" {
|
|
250
257
|
description = "Format number as currency string"
|
|
@@ -265,6 +272,7 @@ function "utils/format_currency" {
|
|
|
265
272
|
```
|
|
266
273
|
|
|
267
274
|
### Data Processing
|
|
275
|
+
|
|
268
276
|
```xs
|
|
269
277
|
function "process_order" {
|
|
270
278
|
input {
|
|
@@ -305,6 +313,7 @@ function "process_order" {
|
|
|
305
313
|
```
|
|
306
314
|
|
|
307
315
|
### Validation Function
|
|
316
|
+
|
|
308
317
|
```xs
|
|
309
318
|
function "validate_email_unique" {
|
|
310
319
|
input {
|
|
@@ -346,65 +355,28 @@ stack {
|
|
|
346
355
|
}
|
|
347
356
|
```
|
|
348
357
|
|
|
349
|
-
### group (
|
|
358
|
+
### group (Organizational Block)
|
|
350
359
|
|
|
351
|
-
|
|
360
|
+
Group related statements together for readability. The `group` block is purely organizational — it does **not** create parallel execution or a new scope.
|
|
352
361
|
|
|
353
362
|
```xs
|
|
354
363
|
stack {
|
|
364
|
+
// Use group to visually organize related initialization
|
|
355
365
|
group {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
api.request {
|
|
362
|
-
url = "https://api.example.com/products"
|
|
363
|
-
method = "GET"
|
|
364
|
-
} as $products
|
|
365
|
-
|
|
366
|
-
api.request {
|
|
367
|
-
url = "https://api.example.com/orders"
|
|
368
|
-
method = "GET"
|
|
369
|
-
} as $orders
|
|
370
|
-
}
|
|
366
|
+
stack {
|
|
367
|
+
var $total {
|
|
368
|
+
value = 0
|
|
369
|
+
}
|
|
371
370
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
users: $users.response.result,
|
|
376
|
-
products: $products.response.result,
|
|
377
|
-
orders: $orders.response.result
|
|
371
|
+
var $count {
|
|
372
|
+
value = 0
|
|
373
|
+
}
|
|
378
374
|
}
|
|
379
375
|
}
|
|
380
|
-
}
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
### Parallel Database Queries
|
|
384
|
-
|
|
385
|
-
```xs
|
|
386
|
-
stack {
|
|
387
|
-
group {
|
|
388
|
-
db.query "user" {
|
|
389
|
-
where = $db.user.is_active == true
|
|
390
|
-
return = { type: "count" }
|
|
391
|
-
} as $active_users
|
|
392
|
-
|
|
393
|
-
db.query "order" {
|
|
394
|
-
where = $db.order.created_at >= $input.start_date
|
|
395
|
-
return = { type: "count" }
|
|
396
|
-
} as $order_count
|
|
397
|
-
|
|
398
|
-
db.query "product" {
|
|
399
|
-
where = $db.product.stock == 0
|
|
400
|
-
return = { type: "count" }
|
|
401
|
-
} as $out_of_stock
|
|
402
|
-
}
|
|
403
376
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
out_of_stock: $out_of_stock
|
|
377
|
+
// Variables from the group are accessible here
|
|
378
|
+
var $average {
|
|
379
|
+
value = $total / $count
|
|
408
380
|
}
|
|
409
381
|
}
|
|
410
382
|
```
|
|
@@ -512,5 +484,5 @@ foreach ($items) {
|
|
|
512
484
|
3. **Organize in folders** - Group related functions: `utils/`, `auth/`, `orders/`
|
|
513
485
|
4. **Return early** - Use return for guard clauses
|
|
514
486
|
5. **Keep stacks shallow** - Avoid deeply nested conditionals
|
|
515
|
-
6. **Use group for
|
|
487
|
+
6. **Use group for organization** - Visually group related statements for readability
|
|
516
488
|
7. **Use remove sparingly** - Consider filtering arrays instead
|
|
@@ -12,7 +12,7 @@ Best practices for building fast, efficient XanoScript applications.
|
|
|
12
12
|
|------|----------------|
|
|
13
13
|
| Database | Indexes, query optimization, pagination |
|
|
14
14
|
| Caching | Redis, response caching |
|
|
15
|
-
| Loops | Bulk operations,
|
|
15
|
+
| Loops | Bulk operations, efficient iteration |
|
|
16
16
|
| Filters | Efficient data transformations |
|
|
17
17
|
|
|
18
18
|
---
|
|
@@ -212,34 +212,25 @@ conditional {
|
|
|
212
212
|
|
|
213
213
|
---
|
|
214
214
|
|
|
215
|
-
##
|
|
215
|
+
## Organizing with Group
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
The `group` statement is an organizational block for visually grouping related statements. It does **not** create parallel execution or a new scope — variables declared inside a group are accessible outside it.
|
|
218
218
|
|
|
219
219
|
```xs
|
|
220
|
-
//
|
|
220
|
+
// Use group to organize related variable initialization
|
|
221
221
|
group {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
222
|
+
stack {
|
|
223
|
+
var $total {
|
|
224
|
+
value = 0
|
|
225
|
+
}
|
|
226
226
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
products: $product_count
|
|
227
|
+
var $count {
|
|
228
|
+
value = 0
|
|
229
|
+
}
|
|
230
|
+
}
|
|
232
231
|
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
### Parallel API Calls
|
|
236
232
|
|
|
237
|
-
|
|
238
|
-
group {
|
|
239
|
-
api.request { url = "https://api1.example.com/data" } as $data1
|
|
240
|
-
api.request { url = "https://api2.example.com/data" } as $data2
|
|
241
|
-
api.request { url = "https://api3.example.com/data" } as $data3
|
|
242
|
-
}
|
|
233
|
+
// $total and $count are accessible here
|
|
243
234
|
```
|
|
244
235
|
|
|
245
236
|
---
|
|
@@ -401,7 +392,7 @@ conditional {
|
|
|
401
392
|
4. **Avoid N+1 queries** - Use joins or batch fetching
|
|
402
393
|
5. **Use bulk operations** - For batch inserts/updates
|
|
403
394
|
6. **Cache expensive operations** - Redis with appropriate TTL
|
|
404
|
-
7. **
|
|
395
|
+
7. **Use group for organization** - Group related statements for readability
|
|
405
396
|
8. **Filter early** - In database, not application code
|
|
406
397
|
9. **Stream large responses** - Don't load into memory
|
|
407
398
|
10. **Monitor performance** - Log slow operations
|
|
@@ -23,9 +23,11 @@ table "<name>" {
|
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
### Field Types
|
|
26
|
+
|
|
26
27
|
`int`, `text`, `email`, `password`, `decimal`, `bool`, `timestamp`, `date`, `uuid`, `vector`, `json`, `image`, `video`, `audio`, `attachment`, `enum`
|
|
27
28
|
|
|
28
29
|
### Index Types
|
|
30
|
+
|
|
29
31
|
`primary`, `btree`, `btree|unique`, `gin`
|
|
30
32
|
|
|
31
33
|
---
|
|
@@ -58,6 +60,7 @@ table "user" {
|
|
|
58
60
|
## Schema Fields
|
|
59
61
|
|
|
60
62
|
### Basic Fields
|
|
63
|
+
|
|
61
64
|
```xs
|
|
62
65
|
schema {
|
|
63
66
|
int id
|
|
@@ -70,6 +73,7 @@ schema {
|
|
|
70
73
|
```
|
|
71
74
|
|
|
72
75
|
### Optional & Defaults
|
|
76
|
+
|
|
73
77
|
```xs
|
|
74
78
|
schema {
|
|
75
79
|
text nickname? // Optional, no default
|
|
@@ -80,6 +84,7 @@ schema {
|
|
|
80
84
|
```
|
|
81
85
|
|
|
82
86
|
### With Filters
|
|
87
|
+
|
|
83
88
|
```xs
|
|
84
89
|
schema {
|
|
85
90
|
text name filters=trim
|
|
@@ -90,6 +95,7 @@ schema {
|
|
|
90
95
|
```
|
|
91
96
|
|
|
92
97
|
### With Metadata
|
|
98
|
+
|
|
93
99
|
```xs
|
|
94
100
|
schema {
|
|
95
101
|
text ssn {
|
|
@@ -104,6 +110,7 @@ schema {
|
|
|
104
110
|
```
|
|
105
111
|
|
|
106
112
|
### Foreign Keys
|
|
113
|
+
|
|
107
114
|
```xs
|
|
108
115
|
schema {
|
|
109
116
|
int user_id {
|
|
@@ -117,6 +124,7 @@ schema {
|
|
|
117
124
|
```
|
|
118
125
|
|
|
119
126
|
### Enum Fields
|
|
127
|
+
|
|
120
128
|
```xs
|
|
121
129
|
schema {
|
|
122
130
|
enum status {
|
|
@@ -129,6 +137,7 @@ schema {
|
|
|
129
137
|
```
|
|
130
138
|
|
|
131
139
|
### JSON Fields
|
|
140
|
+
|
|
132
141
|
```xs
|
|
133
142
|
schema {
|
|
134
143
|
json metadata
|
|
@@ -137,17 +146,24 @@ schema {
|
|
|
137
146
|
```
|
|
138
147
|
|
|
139
148
|
### Vector Fields
|
|
149
|
+
|
|
140
150
|
```xs
|
|
141
151
|
schema {
|
|
142
|
-
vector embedding //
|
|
152
|
+
vector embedding // Required vector field
|
|
153
|
+
vector? embeddings? { // Optional vector field with explicit size
|
|
154
|
+
size = 768
|
|
155
|
+
}
|
|
143
156
|
}
|
|
144
157
|
```
|
|
145
158
|
|
|
159
|
+
The `size` parameter specifies the vector dimensions (must match your embedding model's output). Pair with a vector index for similarity search (see [Vector Index](#vector-index) below).
|
|
160
|
+
|
|
146
161
|
---
|
|
147
162
|
|
|
148
163
|
## Indexes
|
|
149
164
|
|
|
150
165
|
### Primary Key
|
|
166
|
+
|
|
151
167
|
```xs
|
|
152
168
|
index = [
|
|
153
169
|
{type: "primary", field: [{name: "id"}]}
|
|
@@ -155,6 +171,7 @@ index = [
|
|
|
155
171
|
```
|
|
156
172
|
|
|
157
173
|
### B-tree Index
|
|
174
|
+
|
|
158
175
|
```xs
|
|
159
176
|
index = [
|
|
160
177
|
{type: "btree", field: [{name: "email", op: "asc"}]}
|
|
@@ -163,6 +180,7 @@ index = [
|
|
|
163
180
|
```
|
|
164
181
|
|
|
165
182
|
### Unique Index
|
|
183
|
+
|
|
166
184
|
```xs
|
|
167
185
|
index = [
|
|
168
186
|
{type: "btree|unique", field: [{name: "email"}]}
|
|
@@ -171,6 +189,7 @@ index = [
|
|
|
171
189
|
```
|
|
172
190
|
|
|
173
191
|
### Composite Index
|
|
192
|
+
|
|
174
193
|
```xs
|
|
175
194
|
index = [
|
|
176
195
|
{type: "btree", field: [{name: "user_id"}, {name: "created_at", op: "desc"}]}
|
|
@@ -178,6 +197,7 @@ index = [
|
|
|
178
197
|
```
|
|
179
198
|
|
|
180
199
|
### GIN Index (for JSON/arrays)
|
|
200
|
+
|
|
181
201
|
```xs
|
|
182
202
|
index = [
|
|
183
203
|
{type: "gin", field: [{name: "tags", op: "jsonb_path_op"}]}
|
|
@@ -185,11 +205,35 @@ index = [
|
|
|
185
205
|
]
|
|
186
206
|
```
|
|
187
207
|
|
|
208
|
+
### Full-Text Search Index
|
|
209
|
+
|
|
210
|
+
```xs
|
|
211
|
+
index = [
|
|
212
|
+
{
|
|
213
|
+
name : "search_content"
|
|
214
|
+
lang : "english"
|
|
215
|
+
type : "search"
|
|
216
|
+
field: [{name: "searchable_content", op: "A"}]
|
|
217
|
+
}
|
|
218
|
+
]
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Vector Index
|
|
222
|
+
|
|
223
|
+
```xs
|
|
224
|
+
index = [
|
|
225
|
+
{type: "vector", field: [{name: "embeddings", op: "vector_cosine_ops"}]}
|
|
226
|
+
]
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Required for vector similarity searches via `cosine_distance` in `db.query`. PostgreSQL vector indexes only support ascending scans, so queries must sort by distance `asc` to use the index. Sorting `desc` will bypass the index and trigger a full table scan. See [database.md](database.md) for query usage.
|
|
230
|
+
|
|
188
231
|
---
|
|
189
232
|
|
|
190
233
|
## Complete Examples
|
|
191
234
|
|
|
192
235
|
### User Table (with auth)
|
|
236
|
+
|
|
193
237
|
```xs
|
|
194
238
|
table "user" {
|
|
195
239
|
auth = true
|
|
@@ -212,6 +256,7 @@ table "user" {
|
|
|
212
256
|
```
|
|
213
257
|
|
|
214
258
|
### Product Table
|
|
259
|
+
|
|
215
260
|
```xs
|
|
216
261
|
table "product" {
|
|
217
262
|
auth = false
|
|
@@ -235,6 +280,7 @@ table "product" {
|
|
|
235
280
|
```
|
|
236
281
|
|
|
237
282
|
### Order with Foreign Keys
|
|
283
|
+
|
|
238
284
|
```xs
|
|
239
285
|
table "order" {
|
|
240
286
|
auth = false
|
|
@@ -74,23 +74,25 @@ input {
|
|
|
74
74
|
}
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
### Empty Input Blocks
|
|
77
|
+
### Empty and Single-Input Blocks
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
Empty input blocks and single-input blocks can be written as one-liners. When there are two or more inputs, each must be on its own line.
|
|
80
80
|
|
|
81
81
|
```xs
|
|
82
|
-
//
|
|
82
|
+
// OK - empty input
|
|
83
83
|
tool "get_system_status" {
|
|
84
84
|
description = "Get current system status"
|
|
85
85
|
instructions = "Use this to check if the system is healthy"
|
|
86
|
-
input {
|
|
87
|
-
}
|
|
86
|
+
input {}
|
|
88
87
|
stack { ... }
|
|
89
88
|
response = $status
|
|
90
89
|
}
|
|
91
90
|
|
|
92
|
-
//
|
|
93
|
-
input {}
|
|
91
|
+
// OK - single input as one-liner
|
|
92
|
+
input { text query filters=trim }
|
|
93
|
+
|
|
94
|
+
// WRONG - multiple inputs on one line will cause parsing errors
|
|
95
|
+
input { text query filters=trim int limit }
|
|
94
96
|
```
|
|
95
97
|
|
|
96
98
|
---
|