@xano/developer-mcp 1.0.27 → 1.0.29
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 +1 -1
- package/dist/api_docs/format.d.ts +5 -0
- package/dist/api_docs/format.js +171 -0
- package/dist/api_docs/index.d.ts +52 -0
- package/dist/api_docs/index.js +111 -0
- package/dist/api_docs/topics/agent.d.ts +2 -0
- package/dist/api_docs/topics/agent.js +142 -0
- package/dist/api_docs/topics/api.d.ts +2 -0
- package/dist/api_docs/topics/api.js +176 -0
- package/dist/api_docs/topics/apigroup.d.ts +2 -0
- package/dist/api_docs/topics/apigroup.js +124 -0
- package/dist/api_docs/topics/authentication.d.ts +2 -0
- package/dist/api_docs/topics/authentication.js +61 -0
- package/dist/api_docs/topics/branch.d.ts +2 -0
- package/dist/api_docs/topics/branch.js +73 -0
- package/dist/api_docs/topics/file.d.ts +2 -0
- package/dist/api_docs/topics/file.js +70 -0
- package/dist/api_docs/topics/function.d.ts +2 -0
- package/dist/api_docs/topics/function.js +164 -0
- package/dist/api_docs/topics/history.d.ts +2 -0
- package/dist/api_docs/topics/history.js +149 -0
- package/dist/api_docs/topics/mcp_server.d.ts +2 -0
- package/dist/api_docs/topics/mcp_server.js +139 -0
- package/dist/api_docs/topics/middleware.d.ts +2 -0
- package/dist/api_docs/topics/middleware.js +156 -0
- package/dist/api_docs/topics/realtime.d.ts +2 -0
- package/dist/api_docs/topics/realtime.js +112 -0
- package/dist/api_docs/topics/start.d.ts +2 -0
- package/dist/api_docs/topics/start.js +107 -0
- package/dist/api_docs/topics/table.d.ts +2 -0
- package/dist/api_docs/topics/table.js +195 -0
- package/dist/api_docs/topics/task.d.ts +2 -0
- package/dist/api_docs/topics/task.js +165 -0
- package/dist/api_docs/topics/tool.d.ts +2 -0
- package/dist/api_docs/topics/tool.js +150 -0
- package/dist/api_docs/topics/workflows.d.ts +2 -0
- package/dist/api_docs/topics/workflows.js +131 -0
- package/dist/api_docs/topics/workspace.d.ts +2 -0
- package/dist/api_docs/topics/workspace.js +153 -0
- package/dist/api_docs/types.d.ts +79 -0
- package/dist/api_docs/types.js +4 -0
- package/dist/meta_api_docs/topics/branch.js +154 -18
- package/dist/meta_api_docs/topics/workspace.js +45 -2
- package/dist/templates/init-workspace.d.ts +10 -0
- package/dist/templates/init-workspace.js +278 -0
- package/dist/templates/xanoscript-index.d.ts +11 -0
- package/dist/templates/xanoscript-index.js +72 -0
- package/dist/xanoscript_docs/README.md +3 -13
- package/dist/xanoscript_docs/ephemeral.md +330 -0
- package/dist/xanoscript_docs/functions.md +0 -21
- package/dist/xanoscript_docs/integrations.md +0 -10
- package/dist/xanoscript_docs/performance.md +1 -10
- package/dist/xanoscript_docs/realtime.md +1 -48
- package/dist/xanoscript_docs/security.md +2 -0
- package/dist/xanoscript_docs/tools.md +2 -21
- package/dist/xanoscript_docs/triggers.md +2 -27
- package/dist/xanoscript_docs_auto/README.md +119 -0
- package/dist/xanoscript_docs_auto/agents.md +446 -0
- package/dist/xanoscript_docs_auto/apis.md +517 -0
- package/dist/xanoscript_docs_auto/control-flow.md +543 -0
- package/dist/xanoscript_docs_auto/database.md +551 -0
- package/dist/xanoscript_docs_auto/debugging.md +527 -0
- package/dist/xanoscript_docs_auto/filters.md +464 -0
- package/dist/xanoscript_docs_auto/functions.md +431 -0
- package/dist/xanoscript_docs_auto/integrations.md +657 -0
- package/dist/xanoscript_docs_auto/mcp-servers.md +408 -0
- package/dist/xanoscript_docs_auto/operators.md +368 -0
- package/dist/xanoscript_docs_auto/syntax.md +287 -0
- package/dist/xanoscript_docs_auto/tables.md +447 -0
- package/dist/xanoscript_docs_auto/tasks.md +479 -0
- package/dist/xanoscript_docs_auto/testing.md +574 -0
- package/dist/xanoscript_docs_auto/tools.md +485 -0
- package/dist/xanoscript_docs_auto/triggers.md +595 -0
- package/dist/xanoscript_docs_auto/types.md +323 -0
- package/dist/xanoscript_docs_auto/variables.md +462 -0
- package/dist/xanoscript_docs_auto/version.json +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "apis/**/*.xs"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# APIs (Queries)
|
|
6
|
+
|
|
7
|
+
HTTP API endpoint definitions with authentication, input validation, and response handling.
|
|
8
|
+
|
|
9
|
+
## Quick Reference
|
|
10
|
+
|
|
11
|
+
```xs
|
|
12
|
+
query "<name>" verb=GET {
|
|
13
|
+
input { ... }
|
|
14
|
+
stack { ... }
|
|
15
|
+
response = $data
|
|
16
|
+
security { ... }
|
|
17
|
+
cache { ... }
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### HTTP Verbs
|
|
22
|
+
| Verb | Purpose |
|
|
23
|
+
|------|---------|
|
|
24
|
+
| `GET` | Retrieve data |
|
|
25
|
+
| `POST` | Create resource |
|
|
26
|
+
| `PUT` | Full update |
|
|
27
|
+
| `PATCH` | Partial update |
|
|
28
|
+
| `DELETE` | Remove resource |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Basic Query Definition
|
|
33
|
+
|
|
34
|
+
### GET Endpoint
|
|
35
|
+
|
|
36
|
+
```xs
|
|
37
|
+
query "get_users" verb=GET {
|
|
38
|
+
input {
|
|
39
|
+
int? page default=1
|
|
40
|
+
int? per_page default=20
|
|
41
|
+
text? search
|
|
42
|
+
}
|
|
43
|
+
stack {
|
|
44
|
+
db.query user {
|
|
45
|
+
where = $db.user.name ilike? ("%" ~ $input.search ~ "%")
|
|
46
|
+
order_by = {field: "created_at", direction: "desc"}
|
|
47
|
+
return = {type: "list", paging: {per_page: $input.per_page, page: $input.page}}
|
|
48
|
+
} as $users
|
|
49
|
+
}
|
|
50
|
+
response = $users
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### POST Endpoint
|
|
55
|
+
|
|
56
|
+
```xs
|
|
57
|
+
query "create_user" verb=POST {
|
|
58
|
+
input {
|
|
59
|
+
text name filters=trim|min:1|max:100
|
|
60
|
+
email user_email filters=trim|lower
|
|
61
|
+
password pwd filters=min:8
|
|
62
|
+
}
|
|
63
|
+
stack {
|
|
64
|
+
// Check for duplicate email
|
|
65
|
+
db.has user {
|
|
66
|
+
where = $db.user.email == $input.user_email
|
|
67
|
+
} as $exists
|
|
68
|
+
|
|
69
|
+
precondition (!$exists) {
|
|
70
|
+
error_type = "inputerror"
|
|
71
|
+
error = "Email already registered"
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Create user
|
|
75
|
+
db.add user {
|
|
76
|
+
data = {
|
|
77
|
+
name: $input.name,
|
|
78
|
+
email: $input.user_email,
|
|
79
|
+
password: $input.pwd|password_hash,
|
|
80
|
+
created_at: now
|
|
81
|
+
}
|
|
82
|
+
} as $user
|
|
83
|
+
}
|
|
84
|
+
response = $user
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### PUT Endpoint
|
|
89
|
+
|
|
90
|
+
```xs
|
|
91
|
+
query "update_user" verb=PUT {
|
|
92
|
+
input {
|
|
93
|
+
int id
|
|
94
|
+
text name filters=trim|min:1|max:100
|
|
95
|
+
email user_email filters=trim|lower
|
|
96
|
+
}
|
|
97
|
+
stack {
|
|
98
|
+
db.edit user {
|
|
99
|
+
field_name = "id"
|
|
100
|
+
field_value = $input.id
|
|
101
|
+
data = {
|
|
102
|
+
name: $input.name,
|
|
103
|
+
email: $input.user_email,
|
|
104
|
+
updated_at: now
|
|
105
|
+
}
|
|
106
|
+
} as $user
|
|
107
|
+
}
|
|
108
|
+
response = $user
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### PATCH Endpoint
|
|
113
|
+
|
|
114
|
+
```xs
|
|
115
|
+
query "patch_user" verb=PATCH {
|
|
116
|
+
input {
|
|
117
|
+
int id
|
|
118
|
+
text? name filters=trim|min:1|max:100
|
|
119
|
+
email? user_email filters=trim|lower
|
|
120
|
+
}
|
|
121
|
+
stack {
|
|
122
|
+
var $updates { value = {} }
|
|
123
|
+
|
|
124
|
+
conditional {
|
|
125
|
+
if ($input.name != null) {
|
|
126
|
+
var.update $updates {
|
|
127
|
+
value = $updates|set:"name":$input.name
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
conditional {
|
|
133
|
+
if ($input.user_email != null) {
|
|
134
|
+
var.update $updates {
|
|
135
|
+
value = $updates|set:"email":$input.user_email
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
db.patch user {
|
|
141
|
+
field_name = "id"
|
|
142
|
+
field_value = $input.id
|
|
143
|
+
data = $updates|set:"updated_at":now
|
|
144
|
+
} as $user
|
|
145
|
+
}
|
|
146
|
+
response = $user
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### DELETE Endpoint
|
|
151
|
+
|
|
152
|
+
```xs
|
|
153
|
+
query "delete_user" verb=DELETE {
|
|
154
|
+
input {
|
|
155
|
+
int id
|
|
156
|
+
}
|
|
157
|
+
stack {
|
|
158
|
+
db.del user {
|
|
159
|
+
field_name = "id"
|
|
160
|
+
field_value = $input.id
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
response = {success: true}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Authentication
|
|
170
|
+
|
|
171
|
+
### Security Block
|
|
172
|
+
|
|
173
|
+
```xs
|
|
174
|
+
query "protected_endpoint" verb=GET {
|
|
175
|
+
security {
|
|
176
|
+
type = "auth"
|
|
177
|
+
// Requires authentication token
|
|
178
|
+
}
|
|
179
|
+
stack {
|
|
180
|
+
// $auth is available here
|
|
181
|
+
db.query order {
|
|
182
|
+
where = $db.order.user_id == $auth.id
|
|
183
|
+
} as $orders
|
|
184
|
+
}
|
|
185
|
+
response = $orders
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### No Authentication
|
|
190
|
+
|
|
191
|
+
```xs
|
|
192
|
+
query "public_endpoint" verb=GET {
|
|
193
|
+
security {
|
|
194
|
+
type = "none"
|
|
195
|
+
}
|
|
196
|
+
stack { ... }
|
|
197
|
+
response = $data
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Custom Authentication
|
|
202
|
+
|
|
203
|
+
```xs
|
|
204
|
+
query "custom_auth" verb=GET {
|
|
205
|
+
security {
|
|
206
|
+
type = "custom"
|
|
207
|
+
function = "verify_api_key"
|
|
208
|
+
}
|
|
209
|
+
stack { ... }
|
|
210
|
+
response = $data
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## GUID (URL Parameters)
|
|
217
|
+
|
|
218
|
+
Route parameters in the URL:
|
|
219
|
+
|
|
220
|
+
```xs
|
|
221
|
+
query "get_user" verb=GET {
|
|
222
|
+
security {
|
|
223
|
+
guid = "user_id" // URL: /user/{user_id}
|
|
224
|
+
}
|
|
225
|
+
input {
|
|
226
|
+
int user_id // Comes from GUID
|
|
227
|
+
}
|
|
228
|
+
stack {
|
|
229
|
+
db.get user {
|
|
230
|
+
field_name = "id"
|
|
231
|
+
field_value = $input.user_id
|
|
232
|
+
} as $user
|
|
233
|
+
|
|
234
|
+
precondition ($user != null) {
|
|
235
|
+
error_type = "notfound"
|
|
236
|
+
error = "User not found"
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
response = $user
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Multiple GUIDs
|
|
244
|
+
|
|
245
|
+
```xs
|
|
246
|
+
query "get_order_item" verb=GET {
|
|
247
|
+
security {
|
|
248
|
+
guid = "order_id,item_id" // URL: /order/{order_id}/item/{item_id}
|
|
249
|
+
}
|
|
250
|
+
input {
|
|
251
|
+
int order_id
|
|
252
|
+
int item_id
|
|
253
|
+
}
|
|
254
|
+
stack { ... }
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Caching
|
|
261
|
+
|
|
262
|
+
```xs
|
|
263
|
+
query "get_products" verb=GET {
|
|
264
|
+
cache {
|
|
265
|
+
ttl = 300 // 5 minutes in seconds
|
|
266
|
+
key = "products:" ~ $input.category
|
|
267
|
+
}
|
|
268
|
+
input {
|
|
269
|
+
text category
|
|
270
|
+
}
|
|
271
|
+
stack {
|
|
272
|
+
db.query product {
|
|
273
|
+
where = $db.product.category == $input.category
|
|
274
|
+
} as $products
|
|
275
|
+
}
|
|
276
|
+
response = $products
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Cache Invalidation
|
|
281
|
+
|
|
282
|
+
```xs
|
|
283
|
+
// In another endpoint that modifies products:
|
|
284
|
+
query "update_product" verb=PUT {
|
|
285
|
+
stack {
|
|
286
|
+
db.edit product { ... } as $product
|
|
287
|
+
|
|
288
|
+
// Clear cache
|
|
289
|
+
redis.del {
|
|
290
|
+
key = "products:" ~ $product.category
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Response Headers
|
|
299
|
+
|
|
300
|
+
```xs
|
|
301
|
+
query "download_file" verb=GET {
|
|
302
|
+
stack {
|
|
303
|
+
storage.read_file_resource {
|
|
304
|
+
path = $input.file_path
|
|
305
|
+
} as $content
|
|
306
|
+
|
|
307
|
+
util.set_header {
|
|
308
|
+
name = "Content-Disposition"
|
|
309
|
+
value = "attachment; filename=\"" ~ $input.filename ~ "\""
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
util.set_header {
|
|
313
|
+
name = "Content-Type"
|
|
314
|
+
value = "application/octet-stream"
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
response = $content
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## Input Validation
|
|
324
|
+
|
|
325
|
+
### Input Filters
|
|
326
|
+
|
|
327
|
+
```xs
|
|
328
|
+
input {
|
|
329
|
+
text name filters=trim|min:1|max:100
|
|
330
|
+
email email filters=trim|lower
|
|
331
|
+
password pwd filters=min:8|minAlpha:1|minDigit:1
|
|
332
|
+
text phone filters=pattern:^\+?[0-9]{10,15}$
|
|
333
|
+
int quantity filters=min:1|max:1000
|
|
334
|
+
decimal price filters=min:0
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Custom Validation
|
|
339
|
+
|
|
340
|
+
```xs
|
|
341
|
+
stack {
|
|
342
|
+
precondition ($input.end_date > $input.start_date) {
|
|
343
|
+
error_type = "inputerror"
|
|
344
|
+
error = "End date must be after start date"
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
precondition ($input.items|count > 0) {
|
|
348
|
+
error_type = "inputerror"
|
|
349
|
+
error = "At least one item is required"
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## API Groups
|
|
357
|
+
|
|
358
|
+
Organize related endpoints:
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
apis/
|
|
362
|
+
├── users/
|
|
363
|
+
│ ├── list.xs
|
|
364
|
+
│ ├── get.xs
|
|
365
|
+
│ ├── create.xs
|
|
366
|
+
│ ├── update.xs
|
|
367
|
+
│ └── delete.xs
|
|
368
|
+
├── products/
|
|
369
|
+
│ ├── list.xs
|
|
370
|
+
│ ├── get.xs
|
|
371
|
+
│ └── search.xs
|
|
372
|
+
└── orders/
|
|
373
|
+
├── create.xs
|
|
374
|
+
└── status.xs
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### API Group Configuration
|
|
378
|
+
|
|
379
|
+
```xs
|
|
380
|
+
api_group "users" {
|
|
381
|
+
base_path = "/users"
|
|
382
|
+
middleware = ["auth", "logging"]
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## Streaming Responses
|
|
389
|
+
|
|
390
|
+
```xs
|
|
391
|
+
query "stream_data" verb=GET {
|
|
392
|
+
stack {
|
|
393
|
+
api.stream {
|
|
394
|
+
content_type = "text/event-stream"
|
|
395
|
+
run {
|
|
396
|
+
foreach ($large_dataset) {
|
|
397
|
+
each as $item {
|
|
398
|
+
api.stream.write {
|
|
399
|
+
data = $item|json_encode ~ "\n"
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## File Uploads
|
|
412
|
+
|
|
413
|
+
```xs
|
|
414
|
+
query "upload_file" verb=POST {
|
|
415
|
+
input {
|
|
416
|
+
file document
|
|
417
|
+
text? description
|
|
418
|
+
}
|
|
419
|
+
stack {
|
|
420
|
+
storage.create_file_resource {
|
|
421
|
+
name = $input.document.name
|
|
422
|
+
content = $input.document
|
|
423
|
+
} as $stored_file
|
|
424
|
+
|
|
425
|
+
db.add document {
|
|
426
|
+
data = {
|
|
427
|
+
path: $stored_file.path,
|
|
428
|
+
name: $input.document.name,
|
|
429
|
+
size: $input.document.size,
|
|
430
|
+
mime: $input.document.mime,
|
|
431
|
+
description: $input.description,
|
|
432
|
+
uploaded_at: now
|
|
433
|
+
}
|
|
434
|
+
} as $record
|
|
435
|
+
}
|
|
436
|
+
response = $record
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## Common Patterns
|
|
443
|
+
|
|
444
|
+
### List with Filtering
|
|
445
|
+
|
|
446
|
+
```xs
|
|
447
|
+
query "list_products" verb=GET {
|
|
448
|
+
input {
|
|
449
|
+
int? page default=1
|
|
450
|
+
int? per_page default=20
|
|
451
|
+
text? category
|
|
452
|
+
decimal? min_price
|
|
453
|
+
decimal? max_price
|
|
454
|
+
text? sort default="created_at"
|
|
455
|
+
text? order default="desc"
|
|
456
|
+
}
|
|
457
|
+
stack {
|
|
458
|
+
db.query product {
|
|
459
|
+
where = $db.product.active == true
|
|
460
|
+
&& $db.product.category ==? $input.category
|
|
461
|
+
&& $db.product.price >=? $input.min_price
|
|
462
|
+
&& $db.product.price <=? $input.max_price
|
|
463
|
+
order_by = {field: $input.sort, direction: $input.order}
|
|
464
|
+
return = {type: "list", paging: {per_page: $input.per_page, page: $input.page}}
|
|
465
|
+
} as $products
|
|
466
|
+
}
|
|
467
|
+
response = $products
|
|
468
|
+
}
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### CRUD Resource
|
|
472
|
+
|
|
473
|
+
```xs
|
|
474
|
+
// GET /users - List
|
|
475
|
+
query "list" verb=GET { ... }
|
|
476
|
+
|
|
477
|
+
// GET /users/{id} - Get one
|
|
478
|
+
query "get" verb=GET {
|
|
479
|
+
security { guid = "id" }
|
|
480
|
+
...
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// POST /users - Create
|
|
484
|
+
query "create" verb=POST { ... }
|
|
485
|
+
|
|
486
|
+
// PUT /users/{id} - Update
|
|
487
|
+
query "update" verb=PUT {
|
|
488
|
+
security { guid = "id" }
|
|
489
|
+
...
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// DELETE /users/{id} - Delete
|
|
493
|
+
query "delete" verb=DELETE {
|
|
494
|
+
security { guid = "id" }
|
|
495
|
+
...
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### Search Endpoint
|
|
500
|
+
|
|
501
|
+
```xs
|
|
502
|
+
query "search" verb=GET {
|
|
503
|
+
input {
|
|
504
|
+
text q filters=trim|min:2
|
|
505
|
+
int? limit default=20
|
|
506
|
+
}
|
|
507
|
+
stack {
|
|
508
|
+
db.query product {
|
|
509
|
+
where = $db.product.name ilike ("%" ~ $input.q ~ "%")
|
|
510
|
+
|| $db.product.description search $input.q
|
|
511
|
+
order_by = {field: "name", direction: "asc"}
|
|
512
|
+
return = {type: "list", paging: {per_page: $input.limit}}
|
|
513
|
+
} as $results
|
|
514
|
+
}
|
|
515
|
+
response = $results
|
|
516
|
+
}
|
|
517
|
+
```
|