@xano/developer-mcp 1.0.33 → 1.0.35
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/tools/index.d.ts +2 -15
- package/dist/tools/index.js +2 -2
- package/dist/tools/validate_xanoscript.d.ts +84 -9
- package/dist/tools/validate_xanoscript.js +345 -31
- package/dist/xanoscript.js +5 -0
- package/dist/xanoscript.test.js +4 -2
- package/dist/xanoscript_docs/README.md +81 -7
- package/dist/xanoscript_docs/database.md +14 -0
- package/dist/xanoscript_docs/functions.md +14 -0
- package/dist/xanoscript_docs/integrations.md +75 -5
- package/dist/xanoscript_docs/quickstart.md +653 -0
- package/dist/xanoscript_docs/syntax.md +104 -1
- package/dist/xanoscript_docs/types.md +14 -0
- package/package.json +1 -1
|
@@ -0,0 +1,653 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**/*.xs"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Quickstart & Common Patterns
|
|
6
|
+
|
|
7
|
+
Essential patterns for XanoScript development. Use this as a quick reference for frequently-used code patterns.
|
|
8
|
+
|
|
9
|
+
## Quick Reference
|
|
10
|
+
|
|
11
|
+
### Reserved Variable Names
|
|
12
|
+
|
|
13
|
+
These variable names are reserved and cannot be used:
|
|
14
|
+
|
|
15
|
+
| Variable | Description |
|
|
16
|
+
|----------|-------------|
|
|
17
|
+
| `$response` | API/function response (auto-populated) |
|
|
18
|
+
| `$output` | Output value |
|
|
19
|
+
| `$input` | Input parameters from request/function call |
|
|
20
|
+
| `$auth` | Authenticated user context |
|
|
21
|
+
| `$env` | Environment variables and request context |
|
|
22
|
+
| `$db` | Database table reference for queries |
|
|
23
|
+
| `$this` | Current context reference |
|
|
24
|
+
| `$result` | Used in reduce operations |
|
|
25
|
+
|
|
26
|
+
```xs
|
|
27
|
+
// ❌ Wrong - using reserved variable name
|
|
28
|
+
var $response { value = "test" } // Error: $response is reserved
|
|
29
|
+
|
|
30
|
+
// ✅ Correct - use a different name
|
|
31
|
+
var $api_response { value = "test" }
|
|
32
|
+
var $my_result { value = "test" }
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Type Names (Common Aliases)
|
|
36
|
+
|
|
37
|
+
XanoScript uses specific type names. Common aliases from other languages won't work.
|
|
38
|
+
|
|
39
|
+
> **Full reference:** For complete type details and validation, see `xanoscript_docs({ topic: "types" })`.
|
|
40
|
+
|
|
41
|
+
| ❌ Wrong | ✅ Correct | Description |
|
|
42
|
+
|----------|------------|-------------|
|
|
43
|
+
| `boolean` | `bool` | Boolean true/false |
|
|
44
|
+
| `integer` | `int` | 32-bit integer |
|
|
45
|
+
| `string` | `text` | UTF-8 string |
|
|
46
|
+
| `number` | `decimal` | Floating-point number |
|
|
47
|
+
| `float` | `decimal` | Floating-point number |
|
|
48
|
+
| `array` | `type[]` | Array (e.g., `text[]`, `int[]`) |
|
|
49
|
+
| `list` | `type[]` | Array (e.g., `text[]`, `int[]`) |
|
|
50
|
+
|
|
51
|
+
```xs
|
|
52
|
+
// ❌ Wrong - invalid type names
|
|
53
|
+
input {
|
|
54
|
+
boolean is_active // Error: use "bool"
|
|
55
|
+
integer count // Error: use "int"
|
|
56
|
+
string name // Error: use "text"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ✅ Correct - proper XanoScript types
|
|
60
|
+
input {
|
|
61
|
+
bool is_active
|
|
62
|
+
int count
|
|
63
|
+
text name
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Variable Declaration
|
|
68
|
+
```xs
|
|
69
|
+
var $name { value = "initial value" }
|
|
70
|
+
var $count { value = 0 }
|
|
71
|
+
var $data { value = { key: "value" } }
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Conditional Logic
|
|
75
|
+
```xs
|
|
76
|
+
conditional {
|
|
77
|
+
if (`$status == "active"`) {
|
|
78
|
+
var $result { value = "Active user" }
|
|
79
|
+
}
|
|
80
|
+
elseif (`$status == "pending"`) {
|
|
81
|
+
var $result { value = "Pending approval" }
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
var $result { value = "Unknown status" }
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### API Request with Error Handling
|
|
90
|
+
```xs
|
|
91
|
+
api.request {
|
|
92
|
+
url = "https://api.example.com/data"
|
|
93
|
+
method = "POST"
|
|
94
|
+
params = $payload // Note: "params" is used for request body, NOT "body"
|
|
95
|
+
headers = ["Content-Type: application/json", "Authorization: Bearer " ~ $env.API_KEY]
|
|
96
|
+
} as $api_result
|
|
97
|
+
|
|
98
|
+
precondition ($api_result.response.status == 200) {
|
|
99
|
+
error_type = "standard"
|
|
100
|
+
error = "API request failed"
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
var $data { value = $api_result.response.result }
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### api.request Response Structure
|
|
107
|
+
The response object contains:
|
|
108
|
+
```xs
|
|
109
|
+
$result.response.status // HTTP status code (200, 404, 500, etc.)
|
|
110
|
+
$result.response.result // Parsed response body (JSON decoded)
|
|
111
|
+
$result.response.headers // Response headers object
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### While Loop
|
|
115
|
+
```xs
|
|
116
|
+
stack {
|
|
117
|
+
var $counter { value = 0 }
|
|
118
|
+
while ($counter < 10) {
|
|
119
|
+
each {
|
|
120
|
+
var.update $counter { value = $counter + 1 }
|
|
121
|
+
debug.log { value = "Iteration: " ~ ($counter|to_text) }
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### String Concatenation
|
|
128
|
+
```xs
|
|
129
|
+
var $greeting { value = "Hello, " ~ $input.name ~ "!" }
|
|
130
|
+
|
|
131
|
+
// With filters (use parentheses)
|
|
132
|
+
var $message { value = "Status: " ~ ($status|to_text) ~ " - " ~ ($data|json_encode) }
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Input Block Syntax
|
|
136
|
+
|
|
137
|
+
> **Full reference:** For complete input types and validation options, see `xanoscript_docs({ topic: "types" })`.
|
|
138
|
+
|
|
139
|
+
```xs
|
|
140
|
+
input {
|
|
141
|
+
// Required input
|
|
142
|
+
text name
|
|
143
|
+
|
|
144
|
+
// Optional input (can be omitted)
|
|
145
|
+
text nickname?
|
|
146
|
+
|
|
147
|
+
// Optional with default value
|
|
148
|
+
text role?="user"
|
|
149
|
+
|
|
150
|
+
// With filters applied
|
|
151
|
+
email contact filters=trim|lower
|
|
152
|
+
|
|
153
|
+
// Optional with default AND filters
|
|
154
|
+
text search?="" filters=trim
|
|
155
|
+
|
|
156
|
+
// Array type
|
|
157
|
+
text[] tags filters=trim
|
|
158
|
+
|
|
159
|
+
// Nested object with schema
|
|
160
|
+
object address {
|
|
161
|
+
schema {
|
|
162
|
+
text street
|
|
163
|
+
text city
|
|
164
|
+
text country?="US"
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Error Types Reference
|
|
171
|
+
|
|
172
|
+
> **Full reference:** For try-catch, throw, and preconditions, see `xanoscript_docs({ topic: "syntax" })`.
|
|
173
|
+
|
|
174
|
+
| Type | HTTP Status | Use Case |
|
|
175
|
+
|------|-------------|----------|
|
|
176
|
+
| `inputerror` | 400 Bad Request | Invalid input data |
|
|
177
|
+
| `accessdenied` | 403 Forbidden | Authorization failure |
|
|
178
|
+
| `notfound` | 404 Not Found | Resource doesn't exist |
|
|
179
|
+
| `standard` | 500 Internal Server Error | General errors |
|
|
180
|
+
|
|
181
|
+
### Quick Filter Reference
|
|
182
|
+
|
|
183
|
+
> **Full reference:** For the complete list of filters with examples, see `xanoscript_docs({ topic: "syntax" })`.
|
|
184
|
+
|
|
185
|
+
**String Filters:**
|
|
186
|
+
```xs
|
|
187
|
+
$s|trim // Remove whitespace
|
|
188
|
+
$s|to_lower // Lowercase
|
|
189
|
+
$s|to_upper // Uppercase
|
|
190
|
+
$s|substr:1:3 // Substring from index 1, length 3
|
|
191
|
+
$s|split:"," // Split by delimiter → array
|
|
192
|
+
$s|replace:"old":"new" // Replace text
|
|
193
|
+
$s|contains:"text" // Check if contains → bool
|
|
194
|
+
$s|strlen // String length
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Array Filters:**
|
|
198
|
+
```xs
|
|
199
|
+
$arr|first // First element
|
|
200
|
+
$arr|last // Last element
|
|
201
|
+
$arr|count // Array length
|
|
202
|
+
$arr|push:$item // Add to end
|
|
203
|
+
$arr|pop // Remove & return last
|
|
204
|
+
$arr|join:"," // Join to string
|
|
205
|
+
$arr|map:$$.name // Transform elements
|
|
206
|
+
$arr|filter:$$.active // Filter elements
|
|
207
|
+
$arr|find:$$.id == 5 // Find first match
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Object Filters:**
|
|
211
|
+
```xs
|
|
212
|
+
$obj|get:"key" // Get property value
|
|
213
|
+
$obj|get:"key":"default" // With default if missing
|
|
214
|
+
$obj|set:"key":"value" // Set property
|
|
215
|
+
$obj|has:"key" // Check if key exists → bool
|
|
216
|
+
$obj|keys // Get all keys → array
|
|
217
|
+
$obj|values // Get all values → array
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Type Conversion:**
|
|
221
|
+
```xs
|
|
222
|
+
$val|to_text // Convert to string
|
|
223
|
+
$val|to_int // Convert to integer
|
|
224
|
+
$val|to_decimal // Convert to decimal
|
|
225
|
+
$val|to_bool // Convert to boolean
|
|
226
|
+
$val|json_encode // Object → JSON string
|
|
227
|
+
$str|json_decode // JSON string → object
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Null Handling:**
|
|
231
|
+
```xs
|
|
232
|
+
$val|first_notnull:"default" // Default if null
|
|
233
|
+
$val|first_notempty:"default" // Default if empty
|
|
234
|
+
$val ?? "default" // Nullish coalescing (same as first_notnull)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Encoding:**
|
|
238
|
+
```xs
|
|
239
|
+
$s|url_encode // URL encode
|
|
240
|
+
$s|url_decode // URL decode
|
|
241
|
+
$s|base64_encode // Base64 encode
|
|
242
|
+
$s|base64_decode // Base64 decode
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Common Patterns
|
|
248
|
+
|
|
249
|
+
### 1. Input Validation
|
|
250
|
+
|
|
251
|
+
```xs
|
|
252
|
+
// Required field check
|
|
253
|
+
precondition ($input.email != null && $input.email != "") {
|
|
254
|
+
error_type = "inputerror"
|
|
255
|
+
error = "Email is required"
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Format validation
|
|
259
|
+
precondition ($input.email|contains:"@") {
|
|
260
|
+
error_type = "inputerror"
|
|
261
|
+
error = "Invalid email format"
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### 2. Database CRUD
|
|
266
|
+
|
|
267
|
+
> **Full reference:** For all db.* operations including transactions, see `xanoscript_docs({ topic: "database" })`.
|
|
268
|
+
|
|
269
|
+
```xs
|
|
270
|
+
// Create
|
|
271
|
+
db.add "user" {
|
|
272
|
+
data = { name: $input.name, email: $input.email }
|
|
273
|
+
} as $new_user
|
|
274
|
+
|
|
275
|
+
// Read one
|
|
276
|
+
db.get "user" {
|
|
277
|
+
where = $db.user.id == $input.id
|
|
278
|
+
} as $user
|
|
279
|
+
|
|
280
|
+
// Read many
|
|
281
|
+
db.query "user" {
|
|
282
|
+
where = $db.user.is_active == true
|
|
283
|
+
order = [{ field: created_at, direction: desc }]
|
|
284
|
+
paging = { limit: 10, offset: 0 }
|
|
285
|
+
} as $users
|
|
286
|
+
|
|
287
|
+
// Update
|
|
288
|
+
db.edit "user" {
|
|
289
|
+
where = $db.user.id == $input.id
|
|
290
|
+
data = { name: $input.name }
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Delete
|
|
294
|
+
db.delete "user" {
|
|
295
|
+
where = $db.user.id == $input.id
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### 3. Optional Field Handling
|
|
300
|
+
|
|
301
|
+
```xs
|
|
302
|
+
// Build object with optional fields
|
|
303
|
+
var $data { value = { required_field: $input.required } }
|
|
304
|
+
|
|
305
|
+
conditional {
|
|
306
|
+
if ($input.optional_field != null) {
|
|
307
|
+
var.update $data { value = $data|set:"optional_field":$input.optional_field }
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Or use set_ifnotnull
|
|
312
|
+
var $data {
|
|
313
|
+
value = { required: $input.required }|set_ifnotnull:"optional":$input.optional
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### 4. Loop Through Array
|
|
318
|
+
|
|
319
|
+
```xs
|
|
320
|
+
// Using each
|
|
321
|
+
each ($items as $item) {
|
|
322
|
+
debug.log { value = $item.name }
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Using map filter
|
|
326
|
+
var $names { value = $items|map:$$.name }
|
|
327
|
+
|
|
328
|
+
// Using filter
|
|
329
|
+
var $active_items { value = $items|filter:$$.is_active == true }
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### 5. Error Handling with Try-Catch
|
|
333
|
+
|
|
334
|
+
> **Full reference:** For all error handling patterns, see `xanoscript_docs({ topic: "syntax" })`.
|
|
335
|
+
|
|
336
|
+
```xs
|
|
337
|
+
try_catch {
|
|
338
|
+
try {
|
|
339
|
+
api.request {
|
|
340
|
+
url = "https://api.example.com/risky"
|
|
341
|
+
method = "GET"
|
|
342
|
+
} as $result
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
debug.log { value = "Request failed, using fallback" }
|
|
346
|
+
var $result { value = { response: { result: null } } }
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### 6. Authentication Check
|
|
352
|
+
|
|
353
|
+
> **Full reference:** For security best practices, see `xanoscript_docs({ topic: "security" })`.
|
|
354
|
+
|
|
355
|
+
```xs
|
|
356
|
+
// Require authenticated user
|
|
357
|
+
precondition ($auth.id != null) {
|
|
358
|
+
error_type = "accessdenied"
|
|
359
|
+
error = "Authentication required"
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Check user owns resource
|
|
363
|
+
db.get "post" {
|
|
364
|
+
where = $db.post.id == $input.post_id
|
|
365
|
+
} as $post
|
|
366
|
+
|
|
367
|
+
precondition ($post.user_id == $auth.id) {
|
|
368
|
+
error_type = "accessdenied"
|
|
369
|
+
error = "You can only edit your own posts"
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### 7. Pagination
|
|
374
|
+
|
|
375
|
+
```xs
|
|
376
|
+
var $page { value = $input.page ?? 1 }
|
|
377
|
+
var $limit { value = $input.limit ?? 20 }
|
|
378
|
+
var $offset { value = ($page - 1) * $limit }
|
|
379
|
+
|
|
380
|
+
db.query "item" {
|
|
381
|
+
where = $db.item.is_active == true
|
|
382
|
+
order = [{ field: created_at, direction: desc }]
|
|
383
|
+
paging = { limit: $limit, offset: $offset }
|
|
384
|
+
count = true
|
|
385
|
+
} as $result
|
|
386
|
+
|
|
387
|
+
response = {
|
|
388
|
+
items: $result.items,
|
|
389
|
+
total: $result.count,
|
|
390
|
+
page: $page,
|
|
391
|
+
pages: ($result.count / $limit)|ceil
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### 8. Building Complex Objects
|
|
396
|
+
|
|
397
|
+
```xs
|
|
398
|
+
// Step by step
|
|
399
|
+
var $response { value = {} }
|
|
400
|
+
var.update $response { value = $response|set:"user":$user }
|
|
401
|
+
var.update $response { value = $response|set:"posts":$posts }
|
|
402
|
+
var.update $response { value = $response|set:"stats":{ count: $posts|count } }
|
|
403
|
+
|
|
404
|
+
// Or all at once
|
|
405
|
+
var $response {
|
|
406
|
+
value = {
|
|
407
|
+
user: $user,
|
|
408
|
+
posts: $posts,
|
|
409
|
+
stats: { count: $posts|count }
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### 9. Date/Time Operations
|
|
415
|
+
|
|
416
|
+
> **Full reference:** For all date/time filters, see `xanoscript_docs({ topic: "syntax" })`.
|
|
417
|
+
|
|
418
|
+
```xs
|
|
419
|
+
// Current timestamp
|
|
420
|
+
var $now { value = now }
|
|
421
|
+
|
|
422
|
+
// Format for display
|
|
423
|
+
var $formatted { value = now|format_timestamp:"Y-m-d H:i:s":"UTC" }
|
|
424
|
+
|
|
425
|
+
// Relative time
|
|
426
|
+
var $yesterday { value = now|transform_timestamp:"-1 day" }
|
|
427
|
+
var $next_week { value = now|transform_timestamp:"+7 days" }
|
|
428
|
+
|
|
429
|
+
// Compare dates
|
|
430
|
+
db.query "event" {
|
|
431
|
+
where = $db.event.start_date >= now
|
|
432
|
+
} as $upcoming_events
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### 10. JSON API Response
|
|
436
|
+
|
|
437
|
+
> **Full reference:** For external API patterns, see `xanoscript_docs({ topic: "integrations" })`.
|
|
438
|
+
|
|
439
|
+
```xs
|
|
440
|
+
api.request {
|
|
441
|
+
url = "https://api.openai.com/v1/chat/completions"
|
|
442
|
+
method = "POST"
|
|
443
|
+
params = {
|
|
444
|
+
model: "gpt-4",
|
|
445
|
+
messages: [{ role: "user", content: $input.prompt }]
|
|
446
|
+
}
|
|
447
|
+
headers = [
|
|
448
|
+
"Content-Type: application/json",
|
|
449
|
+
"Authorization: Bearer " ~ $env.OPENAI_API_KEY
|
|
450
|
+
]
|
|
451
|
+
} as $api_result
|
|
452
|
+
|
|
453
|
+
conditional {
|
|
454
|
+
if ($api_result.response.status == 200) {
|
|
455
|
+
var $answer { value = $api_result.response.result.choices|first|get:"message"|get:"content" }
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
throw {
|
|
459
|
+
name = "APIError",
|
|
460
|
+
value = "OpenAI API error: " ~ ($api_result.response.status|to_text)
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
## Common Mistakes
|
|
469
|
+
|
|
470
|
+
### 1. Using `else if` instead of `elseif`
|
|
471
|
+
```xs
|
|
472
|
+
// ❌ Wrong
|
|
473
|
+
conditional {
|
|
474
|
+
if (...) { }
|
|
475
|
+
else if (...) { } // Parse error!
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// ✅ Correct
|
|
479
|
+
conditional {
|
|
480
|
+
if (...) { }
|
|
481
|
+
elseif (...) { }
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### 2. Missing parentheses in filter concatenation
|
|
486
|
+
```xs
|
|
487
|
+
// ❌ Wrong - parse error
|
|
488
|
+
var $msg { value = $status|to_text ~ " - " ~ $data|json_encode }
|
|
489
|
+
|
|
490
|
+
// ✅ Correct - wrap filtered expressions in parentheses
|
|
491
|
+
var $msg { value = ($status|to_text) ~ " - " ~ ($data|json_encode) }
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### 3. Missing parentheses in filter comparisons
|
|
495
|
+
```xs
|
|
496
|
+
// ❌ Wrong - parse error
|
|
497
|
+
if ($array|count > 0) { }
|
|
498
|
+
|
|
499
|
+
// ✅ Correct - wrap filter expression in parentheses
|
|
500
|
+
if (($array|count) > 0) { }
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### 4. Using `body` instead of `params` for api.request
|
|
504
|
+
```xs
|
|
505
|
+
// ❌ Wrong - "body" is not valid
|
|
506
|
+
api.request {
|
|
507
|
+
url = "..."
|
|
508
|
+
method = "POST"
|
|
509
|
+
body = $payload
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// ✅ Correct - use "params" for request body
|
|
513
|
+
api.request {
|
|
514
|
+
url = "..."
|
|
515
|
+
method = "POST"
|
|
516
|
+
params = $payload
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
### 5. Using `default` filter (doesn't exist)
|
|
521
|
+
```xs
|
|
522
|
+
// ❌ Wrong - no "default" filter exists
|
|
523
|
+
var $value { value = $input.optional|default:"fallback" }
|
|
524
|
+
|
|
525
|
+
// ✅ Correct - use first_notnull or ?? operator
|
|
526
|
+
var $value { value = $input.optional|first_notnull:"fallback" }
|
|
527
|
+
// or
|
|
528
|
+
var $value { value = $input.optional ?? "fallback" }
|
|
529
|
+
|
|
530
|
+
// For object key access with default, use get with 3rd parameter
|
|
531
|
+
var $val { value = $obj|get:"key":"default_value" }
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### 6. Using reserved variable names
|
|
535
|
+
```xs
|
|
536
|
+
// ❌ Wrong - $response is reserved
|
|
537
|
+
var $response { value = "test" }
|
|
538
|
+
|
|
539
|
+
// ✅ Correct - use a different name
|
|
540
|
+
var $api_response { value = "test" }
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
### 7. Wrong type names
|
|
544
|
+
```xs
|
|
545
|
+
// ❌ Wrong - invalid type names
|
|
546
|
+
input {
|
|
547
|
+
boolean active // Use "bool"
|
|
548
|
+
integer count // Use "int"
|
|
549
|
+
string name // Use "text"
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// ✅ Correct
|
|
553
|
+
input {
|
|
554
|
+
bool active
|
|
555
|
+
int count
|
|
556
|
+
text name
|
|
557
|
+
}
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### 8. Object literal syntax (using = instead of :)
|
|
561
|
+
```xs
|
|
562
|
+
// ❌ Wrong - object literals use : not =
|
|
563
|
+
var $data { value = { customer = $id } }
|
|
564
|
+
|
|
565
|
+
// ✅ Correct - use : for object properties
|
|
566
|
+
var $data { value = { customer: $id } }
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
### 9. Throw block with commas
|
|
570
|
+
```xs
|
|
571
|
+
// ❌ Wrong - throw blocks don't use commas
|
|
572
|
+
throw {
|
|
573
|
+
name = "Error",
|
|
574
|
+
value = "message"
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// ✅ Correct - no commas between properties
|
|
578
|
+
throw {
|
|
579
|
+
name = "Error"
|
|
580
|
+
value = "message"
|
|
581
|
+
}
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### 10. Using $env in run.job input blocks
|
|
585
|
+
```xs
|
|
586
|
+
// ❌ Wrong - $env not allowed in input blocks
|
|
587
|
+
run.job "my_job" {
|
|
588
|
+
input {
|
|
589
|
+
text api_key = $env.API_KEY
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// ✅ Correct - access $env in the stack instead
|
|
594
|
+
run.job "my_job" {
|
|
595
|
+
stack {
|
|
596
|
+
var $api_key { value = $env.API_KEY }
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### 11. Using `object` type without schema
|
|
602
|
+
```xs
|
|
603
|
+
// ❌ Wrong - object requires a schema
|
|
604
|
+
input {
|
|
605
|
+
object data // Error: needs schema
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// ✅ Correct - use json for arbitrary data
|
|
609
|
+
input {
|
|
610
|
+
json data // Accepts any JSON
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// ✅ Or define a schema for object
|
|
614
|
+
input {
|
|
615
|
+
object data {
|
|
616
|
+
schema {
|
|
617
|
+
text name
|
|
618
|
+
int id
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
### 12. While loop outside of stack block
|
|
625
|
+
```xs
|
|
626
|
+
// ❌ Wrong - while must be inside stack
|
|
627
|
+
while (true) {
|
|
628
|
+
each { ... }
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
// ✅ Correct - wrap in stack block
|
|
632
|
+
stack {
|
|
633
|
+
while (true) {
|
|
634
|
+
each { ... }
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
---
|
|
640
|
+
|
|
641
|
+
## Related Topics
|
|
642
|
+
|
|
643
|
+
Explore more with `xanoscript_docs({ topic: "<topic>" })`:
|
|
644
|
+
|
|
645
|
+
| Topic | Description |
|
|
646
|
+
|-------|-------------|
|
|
647
|
+
| `syntax` | Complete filter reference, operators, system variables |
|
|
648
|
+
| `types` | Data types, input validation, schema definitions |
|
|
649
|
+
| `database` | All db.* operations: query, get, add, edit, delete |
|
|
650
|
+
| `functions` | Reusable function stacks, async patterns, loops |
|
|
651
|
+
| `apis` | HTTP endpoints, authentication, CRUD patterns |
|
|
652
|
+
| `security` | Security best practices and authentication |
|
|
653
|
+
| `integrations` | External API patterns (OpenAI, Stripe, etc.) |
|