@xano/developer-mcp 1.0.53 → 1.0.56
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/xanoscript_docs.d.ts +7 -0
- package/dist/tools/xanoscript_docs.js +11 -3
- package/dist/xanoscript.d.ts +1 -0
- package/dist/xanoscript.js +30 -14
- package/dist/xanoscript.test.js +49 -6
- package/dist/xanoscript_docs/README.md +7 -7
- package/dist/xanoscript_docs/cheatsheet.md +4 -1
- package/dist/xanoscript_docs/database.md +2 -2
- package/dist/xanoscript_docs/docs_index.json +60 -53
- package/dist/xanoscript_docs/essentials.md +665 -0
- package/dist/xanoscript_docs/functions.md +1 -1
- package/dist/xanoscript_docs/middleware.md +5 -18
- package/dist/xanoscript_docs/quickstart.md +15 -6
- package/dist/xanoscript_docs/security.md +18 -43
- package/dist/xanoscript_docs/syntax/array-filters.md +238 -0
- package/dist/xanoscript_docs/syntax/functions.md +136 -0
- package/dist/xanoscript_docs/syntax/string-filters.md +188 -0
- package/dist/xanoscript_docs/syntax.md +92 -900
- package/dist/xanoscript_docs/triggers.md +1 -1
- package/dist/xanoscript_docs/types.md +1 -1
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ applyTo: "**/*.xs"
|
|
|
4
4
|
|
|
5
5
|
# Syntax Reference
|
|
6
6
|
|
|
7
|
-
Complete reference for XanoScript expressions, operators, and filters.
|
|
7
|
+
Complete reference for XanoScript expressions, operators, and core filters. For extended filter references, see the syntax sub-topics.
|
|
8
8
|
|
|
9
9
|
> **TL;DR:** XanoScript uses `|` for filters (`$text|trim`), `~` for string concat, and standard operators (`==`, `!=`, `&&`, `||`). Filters are chainable. Error handling uses `precondition`, `try_catch`, and `throw`.
|
|
10
10
|
|
|
@@ -15,22 +15,20 @@ Complete reference for XanoScript expressions, operators, and filters.
|
|
|
15
15
|
| [Operators](#quick-reference) | Comparison, logical, math, null-safe |
|
|
16
16
|
| [Conditional Blocks](#conditional-blocks) | `conditional`, `if`/`elseif`/`else` |
|
|
17
17
|
| [Expressions](#expressions) | Backtick syntax, comparisons |
|
|
18
|
-
| [Math Filters](#math-filters) | `add`, `subtract`, `round`, `abs`, `ceil`, `floor` |
|
|
19
|
-
| [String Filters](#string-filters) | `trim`, `to_lower`, `to_upper`, `substr`, `split`, `replace` |
|
|
20
|
-
| [Array Filters](#array-filters) | `first`, `last`, `count`, `map`, `filter`, `reduce` |
|
|
21
|
-
| [Array Functions](#array-functions) | `array.push`, `array.pop`, `array.map`, `array.filter`, `array.group_by` |
|
|
22
|
-
| [Text Functions](#text-functions) | `text.contains`, `text.starts_with`, `text.trim`, `text.append`, `text.prepend` |
|
|
23
|
-
| [Math Functions](#math-functions) | `math.add`, `math.sub`, `math.mul`, `math.div`, `math.bitwise.*` |
|
|
24
|
-
| [Object Functions](#object-functions) | `object.keys`, `object.values`, `object.entries` |
|
|
25
18
|
| [Object Filters](#object-filters) | `get`, `set`, `has`, `keys`, `values` |
|
|
26
19
|
| [Type Filters](#type-filters) | `to_int`, `to_text`, `to_bool`, `json_encode` |
|
|
27
20
|
| [Date/Time Filters](#datetime-filters) | `to_timestamp`, `format_timestamp` |
|
|
28
|
-
| [Encoding Filters](#encoding-filters) | `url_encode`, `base64_encode`, `json_encode` |
|
|
29
|
-
| [Security Filters](#security-filters) | `md5`, `sha256`, `encrypt`, `jws_encode` |
|
|
30
21
|
| [DB Query Filters](#db-query-filters) | `contains`, `includes`, `between`, `within` |
|
|
31
22
|
| [Error Handling](#error-handling) | `precondition`, `try_catch`, `throw` |
|
|
32
23
|
| [System Variables](#system-variables) | `$env.*`, `$auth.*`, request context |
|
|
33
24
|
|
|
25
|
+
### Extended Filter Sub-Topics
|
|
26
|
+
|
|
27
|
+
For detailed references on specific filter categories, use:
|
|
28
|
+
- `xanoscript_docs({ topic: "syntax/string-filters" })` — String filters, regex, encoding, security filters, text functions
|
|
29
|
+
- `xanoscript_docs({ topic: "syntax/array-filters" })` — Array filters, functional operations, array functions
|
|
30
|
+
- `xanoscript_docs({ topic: "syntax/functions" })` — Math filters/functions, object functions, bitwise operations
|
|
31
|
+
|
|
34
32
|
## CRITICAL: Filters Are Type-Specific
|
|
35
33
|
|
|
36
34
|
> **Filters only work on the correct input type.** String filters and array filters are NOT interchangeable. Using the wrong filter type will produce errors or incorrect results.
|
|
@@ -50,14 +48,14 @@ Complete reference for XanoScript expressions, operators, and filters.
|
|
|
50
48
|
|
|
51
49
|
```
|
|
52
50
|
Working with...
|
|
53
|
-
├── Strings? → USE STRING FILTERS ONLY
|
|
51
|
+
├── Strings? → USE STRING FILTERS ONLY
|
|
54
52
|
│ ├── Clean whitespace? → trim, ltrim, rtrim
|
|
55
53
|
│ ├── Change case? → to_lower, to_upper, capitalize
|
|
56
54
|
│ ├── Extract part? → substr (NOT slice)
|
|
57
55
|
│ ├── Split to array? → split
|
|
58
56
|
│ ├── Find/replace? → replace, contains
|
|
59
57
|
│ └── Get length? → strlen (NOT count)
|
|
60
|
-
├── Arrays? → USE ARRAY FILTERS ONLY
|
|
58
|
+
├── Arrays? → USE ARRAY FILTERS ONLY
|
|
61
59
|
│ ├── Get element? → first, last, get
|
|
62
60
|
│ ├── Count items? → count (NOT strlen)
|
|
63
61
|
│ ├── Transform all? → map (filter) or array.map (statement)
|
|
@@ -66,7 +64,7 @@ Working with...
|
|
|
66
64
|
│ ├── Combine? → reduce
|
|
67
65
|
│ ├── Reverse? → reverse (NOT available on strings)
|
|
68
66
|
│ ├── Sort? → sort
|
|
69
|
-
│ └── Statement-level ops? → See
|
|
67
|
+
│ └── Statement-level ops? → See syntax/array-filters topic
|
|
70
68
|
├── Objects?
|
|
71
69
|
│ ├── Get value? → get
|
|
72
70
|
│ ├── Set value? → set
|
|
@@ -87,6 +85,8 @@ Working with...
|
|
|
87
85
|
|
|
88
86
|
### Variable Access Prefixes
|
|
89
87
|
|
|
88
|
+
> **Full reference:** See `xanoscript_docs({ topic: "essentials" })` for detailed variable access rules, reserved variables, and type names.
|
|
89
|
+
|
|
90
90
|
| Prefix | Applies to | Shorthand? |
|
|
91
91
|
|--------|-----------|------------|
|
|
92
92
|
| `$input.field` | Input parameters | No — prefix always required |
|
|
@@ -95,29 +95,18 @@ Working with...
|
|
|
95
95
|
| `$env.NAME` | Environment variables | No |
|
|
96
96
|
| `$db.table.field` | DB field refs (queries) | No |
|
|
97
97
|
|
|
98
|
-
```xs
|
|
99
|
-
// ❌ Wrong — input fields are NOT accessible as bare variables
|
|
100
|
-
var $name { value = $name } // undefined; inputs live on $input
|
|
101
|
-
|
|
102
|
-
// ✅ Correct — always use $input for input fields
|
|
103
|
-
var $name { value = $input.name }
|
|
104
|
-
|
|
105
|
-
// ✅ Both are valid for stack variables
|
|
106
|
-
var $total { value = 0 }
|
|
107
|
-
$var.total // explicit
|
|
108
|
-
$total // shorthand — same thing
|
|
109
|
-
```
|
|
110
|
-
|
|
111
98
|
### Operators
|
|
99
|
+
|
|
112
100
|
| Category | Operators |
|
|
113
101
|
|----------|-----------|
|
|
114
102
|
| Comparison | `==`, `!=`, `>`, `<`, `>=`, `<=` |
|
|
115
|
-
| Logical | `&&`,
|
|
103
|
+
| Logical | `&&`, `\|\|`, `!` |
|
|
116
104
|
| Math | `+`, `-`, `*`, `/`, `%` |
|
|
117
105
|
| String | `~` (concat) |
|
|
118
106
|
| Null-safe | `==?`, `!=?`, `>=?`, `<=?` (ignore if null) |
|
|
119
107
|
|
|
120
108
|
### Common Filters
|
|
109
|
+
|
|
121
110
|
| Filter | Type | Purpose | Example |
|
|
122
111
|
|--------|------|---------|---------|
|
|
123
112
|
| `trim` | STRING | Remove whitespace | `$s\|trim` |
|
|
@@ -153,8 +142,6 @@ var $message {
|
|
|
153
142
|
|
|
154
143
|
```xs
|
|
155
144
|
// ✅ Correct — evaluate filter first, then apply operator
|
|
156
|
-
|
|
157
|
-
// ✅ Correct
|
|
158
145
|
if (($arr|count) == 0) { ... }
|
|
159
146
|
|
|
160
147
|
// ✅ Correct — wrap each filtered expression for concatenation
|
|
@@ -179,10 +166,10 @@ Use `conditional` blocks for if/elseif/else logic:
|
|
|
179
166
|
|
|
180
167
|
```xs
|
|
181
168
|
conditional {
|
|
182
|
-
if (
|
|
169
|
+
if ($status == "success") {
|
|
183
170
|
var $message { value = "All good!" }
|
|
184
171
|
}
|
|
185
|
-
elseif (
|
|
172
|
+
elseif ($status == "pending") {
|
|
186
173
|
var $message { value = "Please wait..." }
|
|
187
174
|
}
|
|
188
175
|
else {
|
|
@@ -195,16 +182,14 @@ conditional {
|
|
|
195
182
|
|
|
196
183
|
### Conditional with Variable Updates
|
|
197
184
|
|
|
198
|
-
Use conditional blocks to update a variable based on conditions:
|
|
199
|
-
|
|
200
185
|
```xs
|
|
201
186
|
var $tier_limit { value = 100 }
|
|
202
187
|
|
|
203
188
|
conditional {
|
|
204
|
-
if ($auth.tier == "premium") {
|
|
189
|
+
if ($auth.tier == "premium") {
|
|
205
190
|
var.update $tier_limit { value = 1000 }
|
|
206
191
|
}
|
|
207
|
-
elseif ($auth.tier == "pro") {
|
|
192
|
+
elseif ($auth.tier == "pro") {
|
|
208
193
|
var.update $tier_limit { value = 500 }
|
|
209
194
|
}
|
|
210
195
|
}
|
|
@@ -214,14 +199,16 @@ conditional {
|
|
|
214
199
|
|
|
215
200
|
## Expressions
|
|
216
201
|
|
|
217
|
-
|
|
202
|
+
Backticks enter **expression mode** — use them only when you need inline evaluation of a complex expression, not for regular conditionals or variable assignments.
|
|
218
203
|
|
|
219
204
|
```xs
|
|
205
|
+
// ✅ Regular conditionals — no backticks needed
|
|
220
206
|
conditional {
|
|
221
|
-
if (
|
|
207
|
+
if ($input.age >= 18) { ... }
|
|
222
208
|
}
|
|
223
209
|
|
|
224
|
-
|
|
210
|
+
// ✅ Variable assignment — no backticks needed
|
|
211
|
+
var $total { value = $input.qty * $input.price }
|
|
225
212
|
```
|
|
226
213
|
|
|
227
214
|
### Comparison
|
|
@@ -250,568 +237,6 @@ $db.post.date >=? $input.start_date
|
|
|
250
237
|
|
|
251
238
|
---
|
|
252
239
|
|
|
253
|
-
## Math Filters
|
|
254
|
-
|
|
255
|
-
| Filter | Example | Result |
|
|
256
|
-
|--------|---------|--------|
|
|
257
|
-
| `add` | `10\|add:5` | `15` |
|
|
258
|
-
| `subtract` | `10\|subtract:3` | `7` |
|
|
259
|
-
| `multiply` | `10\|multiply:2` | `20` |
|
|
260
|
-
| `divide` | `10\|divide:2` | `5` |
|
|
261
|
-
| `modulus` | `10\|modulus:3` | `1` |
|
|
262
|
-
| `floor` | `2.7\|floor` | `2` |
|
|
263
|
-
| `ceil` | `2.3\|ceil` | `3` |
|
|
264
|
-
| `round` | `2.567\|round:2` | `2.57` |
|
|
265
|
-
| `abs` | `-5\|abs` | `5` |
|
|
266
|
-
| `sqrt` | `9\|sqrt` | `3` |
|
|
267
|
-
| `pow` | `2\|pow:3` | `8` |
|
|
268
|
-
| `min` | `5\|min:3` | `3` |
|
|
269
|
-
| `max` | `5\|max:10` | `10` |
|
|
270
|
-
|
|
271
|
-
### Array Math
|
|
272
|
-
```xs
|
|
273
|
-
[1,2,3,4]|sum // 10
|
|
274
|
-
[1,2,3,4]|avg // 2.5
|
|
275
|
-
[1,2,3,4]|product // 24
|
|
276
|
-
[5,2,8,1]|array_min // 1
|
|
277
|
-
[5,2,8,1]|array_max // 8
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
### Trigonometry
|
|
281
|
-
`sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `deg2rad`, `rad2deg`
|
|
282
|
-
|
|
283
|
-
---
|
|
284
|
-
|
|
285
|
-
## String Filters
|
|
286
|
-
|
|
287
|
-
> **These filters operate on STRING values only.** Do not use array filters (`count`, `reverse`, `first`, `last`, `slice`) on strings. Use `strlen` for string length, `substr` for substrings.
|
|
288
|
-
|
|
289
|
-
| Filter | Example | Result |
|
|
290
|
-
|--------|---------|--------|
|
|
291
|
-
| `trim` | `" hi "\|trim` | `"hi"` |
|
|
292
|
-
| `ltrim` / `rtrim` | `" hi"\|ltrim` | `"hi"` |
|
|
293
|
-
| `to_lower` | `"Hi"\|to_lower` | `"hi"` |
|
|
294
|
-
| `to_upper` | `"Hi"\|to_upper` | `"HI"` |
|
|
295
|
-
| `capitalize` | `"hi there"\|capitalize` | `"Hi There"` |
|
|
296
|
-
| `strlen` | `"hello"\|strlen` | `5` |
|
|
297
|
-
| `substr` | `"hello"\|substr:1:3` | `"ell"` |
|
|
298
|
-
| `split` | `"a,b,c"\|split:","` | `["a","b","c"]` |
|
|
299
|
-
| `replace` | `"hello"\|replace:"l":"x"` | `"hexxo"` |
|
|
300
|
-
| `contains` | `"hello"\|contains:"ell"` | `true` |
|
|
301
|
-
| `starts_with` | `"hello"\|starts_with:"he"` | `true` |
|
|
302
|
-
| `ends_with` | `"hello"\|ends_with:"lo"` | `true` |
|
|
303
|
-
| `concat` | `"a"\|concat:"b":"-"` | `"a-b"` |
|
|
304
|
-
|
|
305
|
-
### Case-Insensitive Variants
|
|
306
|
-
`icontains`, `istarts_with`, `iends_with`, `iindex`
|
|
307
|
-
|
|
308
|
-
### Regex
|
|
309
|
-
```xs
|
|
310
|
-
"/pattern/"|regex_matches:"subject" // Boolean match
|
|
311
|
-
"/(\w+)/"|regex_get_first_match:"test" // First match
|
|
312
|
-
"/\w+/"|regex_get_all_matches:"a b c" // All matches
|
|
313
|
-
"/\s+/"|regex_replace:"-":"a b" // Replace: "a-b"
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
## Array Filters
|
|
319
|
-
|
|
320
|
-
> **These filters operate on ARRAY values only.** Do not use string filters (`strlen`, `substr`, `split`, `replace`) on arrays. Use `count` for array length, `slice` for sub-arrays, `join` to convert to string.
|
|
321
|
-
|
|
322
|
-
| Filter | Example | Result |
|
|
323
|
-
|--------|---------|--------|
|
|
324
|
-
| `first` | `[1,2,3]\|first` | `1` |
|
|
325
|
-
| `last` | `[1,2,3]\|last` | `3` |
|
|
326
|
-
| `count` | `[1,2,3]\|count` | `3` |
|
|
327
|
-
| `reverse` | `[1,2,3]\|reverse` | `[3,2,1]` |
|
|
328
|
-
| `unique` | `[1,1,2]\|unique` | `[1,2]` |
|
|
329
|
-
| `flatten` | `[[1,2],[3]]\|flatten` | `[1,2,3]` |
|
|
330
|
-
| `shuffle` | `[1,2,3]\|shuffle` | Random order |
|
|
331
|
-
| `slice` | `[1,2,3,4]\|slice:1:2` | `[2,3]` — offset 1, length 2 |
|
|
332
|
-
| `push` | `[1,2]\|push:3` | `[1,2,3]` |
|
|
333
|
-
| `pop` | `[1,2,3]\|pop` | `3` |
|
|
334
|
-
| `shift` | `[1,2,3]\|shift` | `1` |
|
|
335
|
-
| `unshift` | `[1,2]\|unshift:0` | `[0,1,2]` |
|
|
336
|
-
| `merge` | `[1,2]\|merge:[3,4]` | `[1,2,3,4]` |
|
|
337
|
-
| `diff` | `[1,2,3]\|diff:[2]` | `[1,3]` |
|
|
338
|
-
| `intersect` | `[1,2,3]\|intersect:[2,3,4]` | `[2,3]` |
|
|
339
|
-
| `join` | `["a","b"]\|join:","` | `"a,b"` |
|
|
340
|
-
| `range` | `\|range:1:5` | `[1,2,3,4,5]` |
|
|
341
|
-
| `..` | `(1..5)` | `[1,2,3,4,5]` |
|
|
342
|
-
|
|
343
|
-
### Range Operator
|
|
344
|
-
|
|
345
|
-
Generate numeric ranges with the `..` operator:
|
|
346
|
-
|
|
347
|
-
```xs
|
|
348
|
-
(1..5) // [1,2,3,4,5]
|
|
349
|
-
(0..10) // [0,1,2,3,4,5,6,7,8,9,10]
|
|
350
|
-
($start..$end) // Dynamic range with variables
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### Functional Operations
|
|
354
|
-
```xs
|
|
355
|
-
// Map - transform each element
|
|
356
|
-
[{v:1},{v:2}]|map:$$.v*2 // [2,4]
|
|
357
|
-
|
|
358
|
-
// Filter - keep matching elements
|
|
359
|
-
[1,2,3,4]|filter:$$%2==0 // [2,4]
|
|
360
|
-
|
|
361
|
-
// Find - first matching element
|
|
362
|
-
[{id:1},{id:2}]|find:$$.id==2 // {id:2}
|
|
363
|
-
|
|
364
|
-
// FindIndex - index of first match
|
|
365
|
-
[{id:1},{id:2}]|findIndex:$$.id==2 // 1
|
|
366
|
-
|
|
367
|
-
// Some - any element matches?
|
|
368
|
-
[1,2,3]|some:$$>2 // true
|
|
369
|
-
|
|
370
|
-
// Every - all elements match?
|
|
371
|
-
[2,4,6]|every:$$%2==0 // true
|
|
372
|
-
|
|
373
|
-
// Reduce - accumulate to single value
|
|
374
|
-
[1,2,3,4]|reduce:$$+$result:0 // 10
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
### Array Element Access: `|get` vs `|slice`
|
|
378
|
-
|
|
379
|
-
> **`|get:N`** returns a **single element** by zero-based index.
|
|
380
|
-
> **`|slice:offset:length`** returns a **sub-array**, skipping `offset` elements and returning the next `length` elements.
|
|
381
|
-
|
|
382
|
-
| Method | Use For | Example | Result |
|
|
383
|
-
|--------|---------|---------|--------|
|
|
384
|
-
| `\|get:N` | Single element by index (0-based) | `[10,20,30]\|get:0` | `10` |
|
|
385
|
-
| `\|slice:offset:length` | Sub-array — skip N, take M | `[10,20,30,40]\|slice:1:2` | `[20,30]` |
|
|
386
|
-
| `\|first` | First element | `[10,20,30]\|first` | `10` |
|
|
387
|
-
| `\|last` | Last element | `[10,20,30]\|last` | `30` |
|
|
388
|
-
|
|
389
|
-
```xs
|
|
390
|
-
// Single element by index
|
|
391
|
-
var $third { value = $items|get:2 } // 0-based: 3rd element
|
|
392
|
-
|
|
393
|
-
// Sub-array: skip first 10, return the next 5
|
|
394
|
-
var $page { value = $items|slice:10:5 }
|
|
395
|
-
|
|
396
|
-
// ⚠️ slice:offset:length — NOT slice:start:end
|
|
397
|
-
// $arr|slice:2:3 → skip 2, return 3 elements (indices 2, 3, 4)
|
|
398
|
-
// NOT "from index 2 to index 3"
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
### Grouping & Indexing
|
|
402
|
-
```xs
|
|
403
|
-
// Group by property
|
|
404
|
-
[{g:"a",v:1},{g:"b",v:2},{g:"a",v:3}]|index_by:g
|
|
405
|
-
// {"a":[{g:"a",v:1},{g:"a",v:3}],"b":[{g:"b",v:2}]}
|
|
406
|
-
|
|
407
|
-
// Sort
|
|
408
|
-
[{n:"z"},{n:"a"}]|sort:n:text:false // Ascending by n
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
---
|
|
412
|
-
|
|
413
|
-
## Array Functions
|
|
414
|
-
|
|
415
|
-
Statement-level functions for manipulating arrays within stacks. Unlike filters (e.g., `$arr|push:3`), these are standalone operations.
|
|
416
|
-
|
|
417
|
-
> **Syntax note:** Functions that use a `{ by = ... }` or `{ value = ... }` block wrap the array in parentheses — e.g., `array.map ($arr) { ... }`. Functions that use an `if (...)` condition take a bare variable — e.g., `array.filter $arr if (...) as $result`.
|
|
418
|
-
|
|
419
|
-
### array.push
|
|
420
|
-
|
|
421
|
-
Appends a new element to the end of an array.
|
|
422
|
-
|
|
423
|
-
```xs
|
|
424
|
-
array.push $shopping_cart {
|
|
425
|
-
value = "oranges"
|
|
426
|
-
}
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
### array.unshift
|
|
430
|
-
|
|
431
|
-
Inserts a new element at the beginning of an array, shifting existing elements to higher indexes.
|
|
432
|
-
|
|
433
|
-
```xs
|
|
434
|
-
array.unshift $priority_tasks {
|
|
435
|
-
value = "urgent meeting"
|
|
436
|
-
}
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
### array.pop
|
|
440
|
-
|
|
441
|
-
Removes and returns the last element of an array. The removed element is stored in the `as` variable.
|
|
442
|
-
|
|
443
|
-
```xs
|
|
444
|
-
array.pop $completed_tasks as $last_finished_task
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
### array.shift
|
|
448
|
-
|
|
449
|
-
Removes and returns the first element of an array. The removed element is stored in the `as` variable.
|
|
450
|
-
|
|
451
|
-
```xs
|
|
452
|
-
array.shift $waiting_list as $next_customer
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
### array.merge
|
|
456
|
-
|
|
457
|
-
Combines another array or a single value into the target array, appending all elements from the provided `value`.
|
|
458
|
-
|
|
459
|
-
```xs
|
|
460
|
-
array.merge $active_users {
|
|
461
|
-
value = $new_users
|
|
462
|
-
}
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
### array.find
|
|
466
|
-
|
|
467
|
-
Searches an array and returns the first element that meets the specified condition. Returns `null` if no match.
|
|
468
|
-
|
|
469
|
-
```xs
|
|
470
|
-
array.find $customer_ages if ($this > 18) as $first_adult_age
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
### array.find_index
|
|
474
|
-
|
|
475
|
-
Returns the index of the first element that satisfies the condition. Returns `-1` if no match.
|
|
476
|
-
|
|
477
|
-
```xs
|
|
478
|
-
array.find_index $sale_prices if ($this < 20) as $first_discount_index
|
|
479
|
-
```
|
|
480
|
-
|
|
481
|
-
### array.has
|
|
482
|
-
|
|
483
|
-
Checks if at least one element meets the condition. Returns `true` or `false`.
|
|
484
|
-
|
|
485
|
-
```xs
|
|
486
|
-
array.has $team_roles if ($this == "manager") as $has_manager
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
### array.every
|
|
490
|
-
|
|
491
|
-
Tests whether every element satisfies the condition. Returns `true` if all pass, `false` otherwise.
|
|
492
|
-
|
|
493
|
-
```xs
|
|
494
|
-
array.every $exam_scores if ($this >= 70) as $all_passed
|
|
495
|
-
```
|
|
496
|
-
|
|
497
|
-
### array.filter
|
|
498
|
-
|
|
499
|
-
Creates a new array containing only the elements that meet the condition.
|
|
500
|
-
|
|
501
|
-
```xs
|
|
502
|
-
array.filter $temperatures if ($this > 32) as $above_freezing
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
### array.filter_count
|
|
506
|
-
|
|
507
|
-
Counts how many elements satisfy the condition.
|
|
508
|
-
|
|
509
|
-
```xs
|
|
510
|
-
array.filter_count $survey_responses if ($this == "yes") as $yes_count
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
### array.map
|
|
514
|
-
|
|
515
|
-
Transforms each element in an array based on a specified mapping. The `by` parameter defines the transformation.
|
|
516
|
-
|
|
517
|
-
```xs
|
|
518
|
-
array.map ($json) {
|
|
519
|
-
by = $this.email
|
|
520
|
-
} as $emails
|
|
521
|
-
|
|
522
|
-
array.map ($json) {
|
|
523
|
-
by = {name: $this.name, gender: $this.gender}
|
|
524
|
-
} as $people
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
### array.partition
|
|
528
|
-
|
|
529
|
-
Divides an array into two groups based on a condition. Returns an object with `true` and `false` keys.
|
|
530
|
-
|
|
531
|
-
```xs
|
|
532
|
-
array.partition ($json) if ($this.gender == "male") as $is_male
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
### array.group_by
|
|
536
|
-
|
|
537
|
-
Groups elements based on a specified key or expression. Returns an object where each key is a group.
|
|
538
|
-
|
|
539
|
-
```xs
|
|
540
|
-
array.group_by ($users) {
|
|
541
|
-
by = $this.gender
|
|
542
|
-
} as $user_by_gender
|
|
543
|
-
```
|
|
544
|
-
|
|
545
|
-
### array.union
|
|
546
|
-
|
|
547
|
-
Combines two arrays ensuring all elements are unique based on the `by` key.
|
|
548
|
-
|
|
549
|
-
```xs
|
|
550
|
-
array.union ([1,3,5,7,9]) {
|
|
551
|
-
value = [2,4,6,8]
|
|
552
|
-
by = $this
|
|
553
|
-
} as $union
|
|
554
|
-
// Result: [1,2,3,4,5,6,7,8,9]
|
|
555
|
-
```
|
|
556
|
-
|
|
557
|
-
### array.difference
|
|
558
|
-
|
|
559
|
-
Returns elements present in the first array but not in the second, based on the `by` key.
|
|
560
|
-
|
|
561
|
-
```xs
|
|
562
|
-
array.difference ([1,2,3,4,5,6,7,8,9]) {
|
|
563
|
-
value = [2,4,6,8]
|
|
564
|
-
by = $this
|
|
565
|
-
} as $difference
|
|
566
|
-
// Result: [1,3,5,7,9]
|
|
567
|
-
```
|
|
568
|
-
|
|
569
|
-
### array.intersection
|
|
570
|
-
|
|
571
|
-
Returns elements present in both arrays, based on the `by` key.
|
|
572
|
-
|
|
573
|
-
```xs
|
|
574
|
-
array.intersection ([1,2,3,4,5,6,7,8,9]) {
|
|
575
|
-
value = [2,4,6,8]
|
|
576
|
-
by = $this
|
|
577
|
-
} as $intersection
|
|
578
|
-
// Result: [2,4,6,8]
|
|
579
|
-
```
|
|
580
|
-
|
|
581
|
-
---
|
|
582
|
-
|
|
583
|
-
## Text Functions
|
|
584
|
-
|
|
585
|
-
Statement-level functions for text manipulation within stacks. These operate directly on variables — checking conditions (returning `true`/`false` via `as`) or mutating the variable in place.
|
|
586
|
-
|
|
587
|
-
> **Syntax note:** Functions that check a condition (e.g., `text.contains`, `text.starts_with`) store the result in an `as` variable. Functions that modify text (e.g., `text.trim`, `text.append`) mutate the variable directly and do not return a value.
|
|
588
|
-
|
|
589
|
-
### text.contains
|
|
590
|
-
|
|
591
|
-
Checks if a text string contains the specified value. Returns `true` if found, `false` otherwise.
|
|
592
|
-
|
|
593
|
-
```xs
|
|
594
|
-
text.contains $log_entry {
|
|
595
|
-
value = "error"
|
|
596
|
-
} as $has_error
|
|
597
|
-
```
|
|
598
|
-
|
|
599
|
-
### text.icontains
|
|
600
|
-
|
|
601
|
-
Performs a case-insensitive check to see if a text string contains the specified value.
|
|
602
|
-
|
|
603
|
-
```xs
|
|
604
|
-
text.icontains $description {
|
|
605
|
-
value = "error"
|
|
606
|
-
} as $has_error
|
|
607
|
-
```
|
|
608
|
-
|
|
609
|
-
### text.starts_with
|
|
610
|
-
|
|
611
|
-
Checks if a text string begins with the specified value.
|
|
612
|
-
|
|
613
|
-
```xs
|
|
614
|
-
text.starts_with $message {
|
|
615
|
-
value = "Hello"
|
|
616
|
-
} as $starts_with_hello
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
### text.istarts_with
|
|
620
|
-
|
|
621
|
-
Performs a case-insensitive check to see if a text string starts with the specified value.
|
|
622
|
-
|
|
623
|
-
```xs
|
|
624
|
-
text.istarts_with $title {
|
|
625
|
-
value = "intro"
|
|
626
|
-
} as $starts_with_intro
|
|
627
|
-
```
|
|
628
|
-
|
|
629
|
-
### text.ends_with
|
|
630
|
-
|
|
631
|
-
Checks if a text string ends with the specified value.
|
|
632
|
-
|
|
633
|
-
```xs
|
|
634
|
-
text.ends_with $url {
|
|
635
|
-
value = ".com"
|
|
636
|
-
} as $is_com_domain
|
|
637
|
-
```
|
|
638
|
-
|
|
639
|
-
### text.iends_with
|
|
640
|
-
|
|
641
|
-
Performs a case-insensitive check to see if a text string ends with the specified value.
|
|
642
|
-
|
|
643
|
-
```xs
|
|
644
|
-
text.iends_with $filename {
|
|
645
|
-
value = "pdf"
|
|
646
|
-
} as $ends_with_pdf
|
|
647
|
-
```
|
|
648
|
-
|
|
649
|
-
### text.trim
|
|
650
|
-
|
|
651
|
-
Removes characters (default is whitespace, or as specified by `value`) from both the beginning and end of a text string. Mutates the variable directly.
|
|
652
|
-
|
|
653
|
-
```xs
|
|
654
|
-
text.trim $user_input {
|
|
655
|
-
value = " "
|
|
656
|
-
}
|
|
657
|
-
```
|
|
658
|
-
|
|
659
|
-
### text.ltrim
|
|
660
|
-
|
|
661
|
-
Removes leading characters (default is whitespace, or as specified by `value`) from a text string. Mutates the variable directly.
|
|
662
|
-
|
|
663
|
-
```xs
|
|
664
|
-
text.ltrim $user_input {
|
|
665
|
-
value = " "
|
|
666
|
-
}
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
### text.rtrim
|
|
670
|
-
|
|
671
|
-
Removes trailing characters (default is whitespace, or as specified by `value`) from a text string. Mutates the variable directly.
|
|
672
|
-
|
|
673
|
-
```xs
|
|
674
|
-
text.rtrim $user_input {
|
|
675
|
-
value = " "
|
|
676
|
-
}
|
|
677
|
-
```
|
|
678
|
-
|
|
679
|
-
### text.append
|
|
680
|
-
|
|
681
|
-
Adds the specified value to the end of a text string. Mutates the variable directly.
|
|
682
|
-
|
|
683
|
-
```xs
|
|
684
|
-
text.append $greeting {
|
|
685
|
-
value = ", welcome!"
|
|
686
|
-
}
|
|
687
|
-
```
|
|
688
|
-
|
|
689
|
-
### text.prepend
|
|
690
|
-
|
|
691
|
-
Adds the specified value to the beginning of a text string. Mutates the variable directly.
|
|
692
|
-
|
|
693
|
-
```xs
|
|
694
|
-
text.prepend $message {
|
|
695
|
-
value = "Alert: "
|
|
696
|
-
}
|
|
697
|
-
```
|
|
698
|
-
|
|
699
|
-
---
|
|
700
|
-
|
|
701
|
-
## Math Functions
|
|
702
|
-
|
|
703
|
-
Statement-level functions for arithmetic and bitwise operations within stacks. These mutate the target variable directly and do not return a value.
|
|
704
|
-
|
|
705
|
-
> **Note:** These are different from math filters (e.g., `$x|add:5`) and math domain functions (e.g., `math.add(5, 3)`). Statement-level math functions modify the variable in place.
|
|
706
|
-
|
|
707
|
-
### math.add
|
|
708
|
-
|
|
709
|
-
Adds the specified value to the variable.
|
|
710
|
-
|
|
711
|
-
```xs
|
|
712
|
-
math.add $cart_total {
|
|
713
|
-
value = $item_price
|
|
714
|
-
}
|
|
715
|
-
```
|
|
716
|
-
|
|
717
|
-
### math.sub
|
|
718
|
-
|
|
719
|
-
Subtracts the specified value from the variable.
|
|
720
|
-
|
|
721
|
-
```xs
|
|
722
|
-
math.sub $total_cost {
|
|
723
|
-
value = $discount_amount
|
|
724
|
-
}
|
|
725
|
-
```
|
|
726
|
-
|
|
727
|
-
### math.mul
|
|
728
|
-
|
|
729
|
-
Multiplies the variable by the specified value.
|
|
730
|
-
|
|
731
|
-
```xs
|
|
732
|
-
math.mul $base_price {
|
|
733
|
-
value = $tax_rate
|
|
734
|
-
}
|
|
735
|
-
```
|
|
736
|
-
|
|
737
|
-
### math.div
|
|
738
|
-
|
|
739
|
-
Divides the variable by the specified value.
|
|
740
|
-
|
|
741
|
-
```xs
|
|
742
|
-
math.div $total_time {
|
|
743
|
-
value = $num_tasks
|
|
744
|
-
}
|
|
745
|
-
```
|
|
746
|
-
|
|
747
|
-
### math.bitwise.and
|
|
748
|
-
|
|
749
|
-
Performs a bitwise AND operation on the variable.
|
|
750
|
-
|
|
751
|
-
```xs
|
|
752
|
-
math.bitwise.and $status_flags {
|
|
753
|
-
value = $check_bit
|
|
754
|
-
}
|
|
755
|
-
```
|
|
756
|
-
|
|
757
|
-
### math.bitwise.or
|
|
758
|
-
|
|
759
|
-
Performs a bitwise OR operation on the variable.
|
|
760
|
-
|
|
761
|
-
```xs
|
|
762
|
-
math.bitwise.or $permissions {
|
|
763
|
-
value = $new_permission
|
|
764
|
-
}
|
|
765
|
-
```
|
|
766
|
-
|
|
767
|
-
### math.bitwise.xor
|
|
768
|
-
|
|
769
|
-
Performs a bitwise XOR operation on the variable.
|
|
770
|
-
|
|
771
|
-
```xs
|
|
772
|
-
math.bitwise.xor $flags {
|
|
773
|
-
value = $toggle_bit
|
|
774
|
-
}
|
|
775
|
-
```
|
|
776
|
-
|
|
777
|
-
---
|
|
778
|
-
|
|
779
|
-
## Object Functions
|
|
780
|
-
|
|
781
|
-
Statement-level functions for extracting object properties within stacks. These return results via the `as` variable.
|
|
782
|
-
|
|
783
|
-
### object.keys
|
|
784
|
-
|
|
785
|
-
Retrieves the property keys of an object as an array.
|
|
786
|
-
|
|
787
|
-
```xs
|
|
788
|
-
object.keys {
|
|
789
|
-
value = $user_data
|
|
790
|
-
} as $user_data_keys
|
|
791
|
-
```
|
|
792
|
-
|
|
793
|
-
### object.values
|
|
794
|
-
|
|
795
|
-
Extracts the values of an object's properties into an array.
|
|
796
|
-
|
|
797
|
-
```xs
|
|
798
|
-
object.values {
|
|
799
|
-
value = $product_info
|
|
800
|
-
} as $product_values
|
|
801
|
-
```
|
|
802
|
-
|
|
803
|
-
### object.entries
|
|
804
|
-
|
|
805
|
-
Returns an array of key-value pairs from an object.
|
|
806
|
-
|
|
807
|
-
```xs
|
|
808
|
-
object.entries {
|
|
809
|
-
value = $settings
|
|
810
|
-
} as $settings_pairs
|
|
811
|
-
```
|
|
812
|
-
|
|
813
|
-
---
|
|
814
|
-
|
|
815
240
|
## Object Filters
|
|
816
241
|
|
|
817
242
|
| Filter | Example | Result |
|
|
@@ -858,6 +283,22 @@ null|first_notnull:0 // 0
|
|
|
858
283
|
""|first_notempty:"default" // "default"
|
|
859
284
|
```
|
|
860
285
|
|
|
286
|
+
### Nullish Coalescing
|
|
287
|
+
|
|
288
|
+
Return right operand when left is null (not just falsy):
|
|
289
|
+
|
|
290
|
+
```xs
|
|
291
|
+
$value ?? "default" // Returns "default" only if $value is null
|
|
292
|
+
$value || "default" // Returns "default" if $value is null, 0, "", or false
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
```xs
|
|
296
|
+
// Difference example
|
|
297
|
+
var $count { value = 0 }
|
|
298
|
+
$count ?? 10 // Returns 0 (not null)
|
|
299
|
+
$count || 10 // Returns 10 (0 is falsy)
|
|
300
|
+
```
|
|
301
|
+
|
|
861
302
|
---
|
|
862
303
|
|
|
863
304
|
## Date/Time Filters
|
|
@@ -884,40 +325,6 @@ $ts|timestamp_day_of_week // Day (0=Sunday)
|
|
|
884
325
|
|
|
885
326
|
---
|
|
886
327
|
|
|
887
|
-
## Encoding Filters
|
|
888
|
-
|
|
889
|
-
| Filter | Example |
|
|
890
|
-
|--------|---------|
|
|
891
|
-
| `json_encode` | `{a:1}\|json_encode` |
|
|
892
|
-
| `json_decode` | `'{"a":1}'\|json_decode` |
|
|
893
|
-
| `base64_encode` | `"hello"\|base64_encode` |
|
|
894
|
-
| `base64_decode` | `"aGVsbG8="\|base64_decode` |
|
|
895
|
-
| `url_encode` | `"a b"\|url_encode` |
|
|
896
|
-
| `url_decode` | `"a%20b"\|url_decode` |
|
|
897
|
-
| `xml_decode` | `"<a>1</a>"\|xml_decode` |
|
|
898
|
-
| `yaml_encode` / `yaml_decode` | YAML conversion |
|
|
899
|
-
| `hex2bin` / `bin2hex` | Hex conversion |
|
|
900
|
-
|
|
901
|
-
---
|
|
902
|
-
|
|
903
|
-
## Security Filters
|
|
904
|
-
|
|
905
|
-
> **Full reference:** For security best practices, see `xanoscript_docs({ topic: "security" })`.
|
|
906
|
-
|
|
907
|
-
| Filter | Example |
|
|
908
|
-
|--------|---------|
|
|
909
|
-
| `md5` | `"text"\|md5` |
|
|
910
|
-
| `sha1` / `sha256` / `sha512` | Hash functions |
|
|
911
|
-
| `hmac_sha256` | `"msg"\|hmac_sha256:"key"` |
|
|
912
|
-
| `encrypt` | `"data"\|encrypt:"aes-256-cbc":"key":"iv"` |
|
|
913
|
-
| `decrypt` | `$enc\|decrypt:"aes-256-cbc":"key":"iv"` |
|
|
914
|
-
| `jws_encode` / `jws_decode` | JWT signing |
|
|
915
|
-
| `jwe_encode` / `jwe_decode` | JWT encryption |
|
|
916
|
-
| `secureid_encode` / `secureid_decode` | ID obfuscation |
|
|
917
|
-
| `uuid` | `\|uuid` |
|
|
918
|
-
|
|
919
|
-
---
|
|
920
|
-
|
|
921
328
|
## DB Query Filters
|
|
922
329
|
|
|
923
330
|
> **Full reference:** For complete database operations, see `xanoscript_docs({ topic: "database" })`.
|
|
@@ -936,10 +343,56 @@ Used in `db.query` where clauses:
|
|
|
936
343
|
| `cosine_similarity` | `$db.vector\|cosine_similarity:$vec` | Vector similarity |
|
|
937
344
|
| `l2_distance_euclidean` | `$db.vector\|l2_distance_euclidean:$vec` | Vector distance |
|
|
938
345
|
|
|
346
|
+
### Database Filter Operators
|
|
347
|
+
|
|
348
|
+
Additional operators for `db.query` where clauses:
|
|
349
|
+
|
|
350
|
+
| Operator | Description | Example |
|
|
351
|
+
|----------|-------------|---------|
|
|
352
|
+
| `@>` | JSON contains | `$db.meta @> {"type": "featured"}` |
|
|
353
|
+
| `~` | Regex match | `$db.name ~ "^test"` |
|
|
354
|
+
| `!~` | Regex not match | `$db.name !~ "^draft"` |
|
|
355
|
+
| `not in` | Not in list | `$db.status not in ["deleted", "hidden"]` |
|
|
356
|
+
| `not between` | Not in range | `$db.price not between 0:10` |
|
|
357
|
+
| `not contains` | Array not contains | `$db.tags not contains "spam"` |
|
|
358
|
+
| `not includes` | String not includes | `$db.title not includes "test"` |
|
|
359
|
+
| `not overlaps` | Arrays don't overlap | `$db.tags not overlaps ["hidden", "draft"]` |
|
|
360
|
+
| `not ilike` | Case-insensitive not like | `$db.name not ilike "%test%"` |
|
|
361
|
+
|
|
362
|
+
```xs
|
|
363
|
+
db.query "product" {
|
|
364
|
+
where = $db.product.status not in ["deleted", "archived"]
|
|
365
|
+
&& $db.product.metadata @> {"featured": true}
|
|
366
|
+
&& $db.product.sku ~ "^SKU-[0-9]+"
|
|
367
|
+
} as $products
|
|
368
|
+
```
|
|
369
|
+
|
|
939
370
|
### Timestamp Arithmetic (DB)
|
|
371
|
+
|
|
940
372
|
```xs
|
|
941
373
|
$db.created_at|timestamp_add_days:7
|
|
942
374
|
$db.created_at|timestamp_subtract_hours:24
|
|
375
|
+
$db.created_at|timestamp_year // Extract year
|
|
376
|
+
$db.created_at|timestamp_month // Extract month (1-12)
|
|
377
|
+
$db.created_at|timestamp_week // Extract week number
|
|
378
|
+
$db.created_at|timestamp_day_of_month // Day of month (1-31)
|
|
379
|
+
$db.created_at|timestamp_day_of_week // Day of week (0-6)
|
|
380
|
+
$db.created_at|timestamp_day_of_year // Day of year (1-366)
|
|
381
|
+
$db.created_at|timestamp_hour // Hour (0-23)
|
|
382
|
+
$db.created_at|timestamp_minute // Minute (0-59)
|
|
383
|
+
$db.created_at|timestamp_epoch_seconds // Seconds since epoch
|
|
384
|
+
$db.created_at|timestamp_epoch_ms // Milliseconds since epoch
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Vector Operations (AI/ML)
|
|
388
|
+
|
|
389
|
+
> **Full reference:** For AI agents and embeddings, see `xanoscript_docs({ topic: "agents" })`.
|
|
390
|
+
|
|
391
|
+
```xs
|
|
392
|
+
$db.embedding|l1_distance_manhattan:$input.vector // L1/Manhattan distance
|
|
393
|
+
$db.embedding|negative_inner_product:$input.vector // Negative inner product
|
|
394
|
+
$db.embedding|inner_product:$input.vector // Inner product
|
|
395
|
+
$db.boundary|covers:$input.point // Polygon covers point
|
|
943
396
|
```
|
|
944
397
|
|
|
945
398
|
---
|
|
@@ -948,7 +401,7 @@ $db.created_at|timestamp_subtract_hours:24
|
|
|
948
401
|
|
|
949
402
|
### Preconditions
|
|
950
403
|
|
|
951
|
-
Validate conditions and throw typed errors:
|
|
404
|
+
Validate conditions and throw typed errors. See `xanoscript_docs({ topic: "essentials" })` for the error types reference table.
|
|
952
405
|
|
|
953
406
|
```xs
|
|
954
407
|
precondition ($input.amount > 0) {
|
|
@@ -967,15 +420,6 @@ precondition ($user.id == $auth.id) {
|
|
|
967
420
|
}
|
|
968
421
|
```
|
|
969
422
|
|
|
970
|
-
### Error Types
|
|
971
|
-
|
|
972
|
-
| Type | HTTP Status | Use Case |
|
|
973
|
-
|------|-------------|----------|
|
|
974
|
-
| `inputerror` | 400 Bad Request | Invalid input data |
|
|
975
|
-
| `accessdenied` | 403 Forbidden | Authorization failure |
|
|
976
|
-
| `notfound` | 404 Not Found | Resource doesn't exist |
|
|
977
|
-
| `standard` | 500 Internal Server Error | General errors |
|
|
978
|
-
|
|
979
423
|
### Throwing Errors
|
|
980
424
|
|
|
981
425
|
```xs
|
|
@@ -1054,259 +498,6 @@ var $current_branch { value = $env.$branch }
|
|
|
1054
498
|
var $api_key { value = $env.MY_API_KEY }
|
|
1055
499
|
```
|
|
1056
500
|
|
|
1057
|
-
### $env Limitations
|
|
1058
|
-
|
|
1059
|
-
> **Important:** `$env` variables cannot be used in `run.job` or `run.service` input blocks. Input values must be constants.
|
|
1060
|
-
|
|
1061
|
-
```xs
|
|
1062
|
-
// ❌ Invalid - $env not allowed in run.job input
|
|
1063
|
-
run.job "my_job" {
|
|
1064
|
-
input {
|
|
1065
|
-
text api_key = $env.API_KEY // Error!
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
// ✅ Valid - access $env inside the stack instead
|
|
1070
|
-
run.job "my_job" {
|
|
1071
|
-
input {
|
|
1072
|
-
text api_key // No default value
|
|
1073
|
-
}
|
|
1074
|
-
stack {
|
|
1075
|
-
var $key { value = $env.API_KEY }
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
```
|
|
1079
|
-
|
|
1080
|
-
---
|
|
1081
|
-
|
|
1082
|
-
## Additional Operators
|
|
1083
|
-
|
|
1084
|
-
### Nullish Coalescing
|
|
1085
|
-
|
|
1086
|
-
Return right operand when left is null (not just falsy):
|
|
1087
|
-
|
|
1088
|
-
```xs
|
|
1089
|
-
$value ?? "default" // Returns "default" only if $value is null
|
|
1090
|
-
$value || "default" // Returns "default" if $value is null, 0, "", or false
|
|
1091
|
-
```
|
|
1092
|
-
|
|
1093
|
-
```xs
|
|
1094
|
-
// Difference example
|
|
1095
|
-
var $count { value = 0 }
|
|
1096
|
-
$count ?? 10 // Returns 0 (not null)
|
|
1097
|
-
$count || 10 // Returns 10 (0 is falsy)
|
|
1098
|
-
```
|
|
1099
|
-
|
|
1100
|
-
### Database Filter Operators
|
|
1101
|
-
|
|
1102
|
-
Additional operators for `db.query` where clauses:
|
|
1103
|
-
|
|
1104
|
-
| Operator | Description | Example |
|
|
1105
|
-
|----------|-------------|---------|
|
|
1106
|
-
| `@>` | JSON contains | `$db.meta @> {"type": "featured"}` |
|
|
1107
|
-
| `~` | Regex match | `$db.name ~ "^test"` |
|
|
1108
|
-
| `!~` | Regex not match | `$db.name !~ "^draft"` |
|
|
1109
|
-
| `not in` | Not in list | `$db.status not in ["deleted", "hidden"]` |
|
|
1110
|
-
| `not between` | Not in range | `$db.price not between 0:10` |
|
|
1111
|
-
| `not contains` | Array not contains | `$db.tags not contains "spam"` |
|
|
1112
|
-
| `not includes` | String not includes | `$db.title not includes "test"` |
|
|
1113
|
-
| `not overlaps` | Arrays don't overlap | `$db.tags not overlaps ["hidden", "draft"]` |
|
|
1114
|
-
| `not ilike` | Case-insensitive not like | `$db.name not ilike "%test%"` |
|
|
1115
|
-
|
|
1116
|
-
```xs
|
|
1117
|
-
db.query "product" {
|
|
1118
|
-
where = $db.product.status not in ["deleted", "archived"]
|
|
1119
|
-
&& $db.product.metadata @> {"featured": true}
|
|
1120
|
-
&& $db.product.sku ~ "^SKU-[0-9]+"
|
|
1121
|
-
} as $products
|
|
1122
|
-
```
|
|
1123
|
-
|
|
1124
|
-
---
|
|
1125
|
-
|
|
1126
|
-
## Additional Filters
|
|
1127
|
-
|
|
1128
|
-
### Text Domain Functions
|
|
1129
|
-
|
|
1130
|
-
Functional equivalents for string operations:
|
|
1131
|
-
|
|
1132
|
-
```xs
|
|
1133
|
-
text.contains("hello world", "world") // true
|
|
1134
|
-
text.starts_with("hello", "he") // true
|
|
1135
|
-
text.ends_with("hello", "lo") // true
|
|
1136
|
-
text.icontains("Hello World", "WORLD") // true (case-insensitive)
|
|
1137
|
-
text.istarts_with("Hello", "HE") // true
|
|
1138
|
-
text.iends_with("Hello", "LO") // true
|
|
1139
|
-
```
|
|
1140
|
-
|
|
1141
|
-
### Object Domain Functions
|
|
1142
|
-
|
|
1143
|
-
Functional equivalents for object operations:
|
|
1144
|
-
|
|
1145
|
-
```xs
|
|
1146
|
-
object.keys({a: 1, b: 2}) // ["a", "b"]
|
|
1147
|
-
object.values({a: 1, b: 2}) // [1, 2]
|
|
1148
|
-
object.entries({a: 1, b: 2}) // [{key: "a", value: 1}, {key: "b", value: 2}]
|
|
1149
|
-
```
|
|
1150
|
-
|
|
1151
|
-
### Math Domain Functions
|
|
1152
|
-
|
|
1153
|
-
Functional equivalents for math operations:
|
|
1154
|
-
|
|
1155
|
-
```xs
|
|
1156
|
-
math.add(5, 3) // 8
|
|
1157
|
-
math.sub(10, 4) // 6
|
|
1158
|
-
math.mul(3, 4) // 12
|
|
1159
|
-
math.div(20, 5) // 4
|
|
1160
|
-
math.mod(10, 3) // 1
|
|
1161
|
-
```
|
|
1162
|
-
|
|
1163
|
-
### Bitwise Operations
|
|
1164
|
-
|
|
1165
|
-
```xs
|
|
1166
|
-
// As filters
|
|
1167
|
-
5|bitwise_and:3 // 1
|
|
1168
|
-
5|bitwise_or:3 // 7
|
|
1169
|
-
5|bitwise_xor:3 // 6
|
|
1170
|
-
5|bitwise_not // -6
|
|
1171
|
-
|
|
1172
|
-
// As functions
|
|
1173
|
-
math.bitwise.and(5, 3) // 1
|
|
1174
|
-
math.bitwise.or(5, 3) // 7
|
|
1175
|
-
math.bitwise.xor(5, 3) // 6
|
|
1176
|
-
```
|
|
1177
|
-
|
|
1178
|
-
### Logical NOT Filter
|
|
1179
|
-
|
|
1180
|
-
```xs
|
|
1181
|
-
true|not // false
|
|
1182
|
-
false|not // true
|
|
1183
|
-
$condition|not // Inverts boolean
|
|
1184
|
-
```
|
|
1185
|
-
|
|
1186
|
-
### Array Filtering
|
|
1187
|
-
|
|
1188
|
-
| Filter | Description | Example |
|
|
1189
|
-
|--------|-------------|---------|
|
|
1190
|
-
| `filter_empty` | Remove empty values | `$arr\|filter_empty` |
|
|
1191
|
-
| `filter_empty_text` | Remove empty strings | `$arr\|filter_empty_text` |
|
|
1192
|
-
| `filter_empty_array` | Remove empty arrays | `$arr\|filter_empty_array` |
|
|
1193
|
-
| `filter_empty_object` | Remove empty objects | `$arr\|filter_empty_object` |
|
|
1194
|
-
| `filter_null` | Remove null values | `$arr\|filter_null` |
|
|
1195
|
-
| `filter_zero` | Remove zero values | `$arr\|filter_zero` |
|
|
1196
|
-
| `filter_false` | Remove false values | `$arr\|filter_false` |
|
|
1197
|
-
|
|
1198
|
-
```xs
|
|
1199
|
-
[1, null, "", 0, "text", false]|filter_empty // [1, "text"]
|
|
1200
|
-
["a", "", "b", ""]|filter_empty_text // ["a", "b"]
|
|
1201
|
-
```
|
|
1202
|
-
|
|
1203
|
-
### Array Fill Operations
|
|
1204
|
-
|
|
1205
|
-
```xs
|
|
1206
|
-
|fill:5:"x" // ["x", "x", "x", "x", "x"]
|
|
1207
|
-
["a", "b"]|fill_keys:{"a": 1, "b": 2} // {a: 1, b: 2}
|
|
1208
|
-
```
|
|
1209
|
-
|
|
1210
|
-
### Deep Merge & Comparison
|
|
1211
|
-
|
|
1212
|
-
```xs
|
|
1213
|
-
{a: {b: 1}}|merge_recursive:{a: {c: 2}} // {a: {b: 1, c: 2}}
|
|
1214
|
-
[1, 2, 3]|diff_assoc:[2] // Associative diff
|
|
1215
|
-
[1, 2, 3]|intersect_assoc:[2, 3, 4] // Associative intersect
|
|
1216
|
-
```
|
|
1217
|
-
|
|
1218
|
-
### Encoding Filters
|
|
1219
|
-
|
|
1220
|
-
| Filter | Description | Example |
|
|
1221
|
-
|--------|-------------|---------|
|
|
1222
|
-
| `list_encodings` | List available encodings | `\|list_encodings` |
|
|
1223
|
-
| `detect_encoding` | Detect string encoding | `$text\|detect_encoding` |
|
|
1224
|
-
| `to_utf8` | Convert to UTF-8 | `$text\|to_utf8` |
|
|
1225
|
-
| `from_utf8` | Convert from UTF-8 | `$text\|from_utf8:"ISO-8859-1"` |
|
|
1226
|
-
| `convert_encoding` | Convert encodings | `$text\|convert_encoding:"UTF-8":"ISO-8859-1"` |
|
|
1227
|
-
|
|
1228
|
-
```xs
|
|
1229
|
-
// CSV parsing (alternative to csv_decode)
|
|
1230
|
-
$csv_text|csv_parse // Parse CSV string
|
|
1231
|
-
$data|csv_create // Create CSV string
|
|
1232
|
-
|
|
1233
|
-
// Query string
|
|
1234
|
-
"a=1&b=2"|querystring_parse // {a: "1", b: "2"}
|
|
1235
|
-
```
|
|
1236
|
-
|
|
1237
|
-
### String Escape Filters
|
|
1238
|
-
|
|
1239
|
-
| Filter | Description |
|
|
1240
|
-
|--------|-------------|
|
|
1241
|
-
| `addslashes` | Escape quotes and backslashes |
|
|
1242
|
-
| `escape` | HTML escape |
|
|
1243
|
-
| `text_escape` | Escape for text output |
|
|
1244
|
-
| `text_unescape` | Unescape text |
|
|
1245
|
-
| `regex_quote` | Escape regex special characters |
|
|
1246
|
-
|
|
1247
|
-
```xs
|
|
1248
|
-
"Hello \"World\""|addslashes // "Hello \\\"World\\\""
|
|
1249
|
-
"<script>"|escape // "<script>"
|
|
1250
|
-
"^test$"|regex_quote // "\^test\$"
|
|
1251
|
-
```
|
|
1252
|
-
|
|
1253
|
-
### Trigonometry Examples
|
|
1254
|
-
|
|
1255
|
-
```xs
|
|
1256
|
-
// Radians and degrees
|
|
1257
|
-
90|deg2rad // 1.5707963...
|
|
1258
|
-
1.5707963|rad2deg // 90
|
|
1259
|
-
|
|
1260
|
-
// Trig functions (input in radians)
|
|
1261
|
-
0|sin // 0
|
|
1262
|
-
0|cos // 1
|
|
1263
|
-
0.785398|tan // ~1 (45 degrees)
|
|
1264
|
-
|
|
1265
|
-
// Inverse trig
|
|
1266
|
-
0|asin // 0
|
|
1267
|
-
1|acos // 0
|
|
1268
|
-
1|atan // 0.785398...
|
|
1269
|
-
|
|
1270
|
-
// Hyperbolic
|
|
1271
|
-
0|sinh // 0
|
|
1272
|
-
0|cosh // 1
|
|
1273
|
-
0|tanh // 0
|
|
1274
|
-
```
|
|
1275
|
-
|
|
1276
|
-
### DB Query Timestamp Filters
|
|
1277
|
-
|
|
1278
|
-
Extended timestamp operations for database queries:
|
|
1279
|
-
|
|
1280
|
-
```xs
|
|
1281
|
-
$db.created_at|timestamp_year // Extract year
|
|
1282
|
-
$db.created_at|timestamp_month // Extract month (1-12)
|
|
1283
|
-
$db.created_at|timestamp_week // Extract week number
|
|
1284
|
-
$db.created_at|timestamp_day_of_month // Day of month (1-31)
|
|
1285
|
-
$db.created_at|timestamp_day_of_week // Day of week (0-6)
|
|
1286
|
-
$db.created_at|timestamp_day_of_year // Day of year (1-366)
|
|
1287
|
-
$db.created_at|timestamp_hour // Hour (0-23)
|
|
1288
|
-
$db.created_at|timestamp_minute // Minute (0-59)
|
|
1289
|
-
|
|
1290
|
-
// Epoch variants
|
|
1291
|
-
$db.created_at|timestamp_epoch_seconds // Seconds since epoch
|
|
1292
|
-
$db.created_at|timestamp_epoch_ms // Milliseconds since epoch
|
|
1293
|
-
```
|
|
1294
|
-
|
|
1295
|
-
### Vector Operations (AI/ML)
|
|
1296
|
-
|
|
1297
|
-
> **Full reference:** For AI agents and embeddings, see `xanoscript_docs({ topic: "agents" })`.
|
|
1298
|
-
|
|
1299
|
-
Additional vector similarity functions:
|
|
1300
|
-
|
|
1301
|
-
```xs
|
|
1302
|
-
$db.embedding|l1_distance_manhattan:$input.vector // L1/Manhattan distance
|
|
1303
|
-
$db.embedding|negative_inner_product:$input.vector // Negative inner product
|
|
1304
|
-
$db.embedding|inner_product:$input.vector // Inner product
|
|
1305
|
-
|
|
1306
|
-
// Geo covers (for polygon containment)
|
|
1307
|
-
$db.boundary|covers:$input.point // Polygon covers point
|
|
1308
|
-
```
|
|
1309
|
-
|
|
1310
501
|
---
|
|
1311
502
|
|
|
1312
503
|
## Related Topics
|
|
@@ -1315,8 +506,9 @@ Explore more with `xanoscript_docs({ topic: "<topic>" })`:
|
|
|
1315
506
|
|
|
1316
507
|
| Topic | Description |
|
|
1317
508
|
|-------|-------------|
|
|
1318
|
-
| `
|
|
509
|
+
| `essentials` | Common patterns, mistakes to avoid, error types, type names |
|
|
510
|
+
| `syntax/string-filters` | String filters, regex, encoding, security filters, text functions |
|
|
511
|
+
| `syntax/array-filters` | Array filters, functional operations, array functions |
|
|
512
|
+
| `syntax/functions` | Math filters/functions, object functions, bitwise |
|
|
1319
513
|
| `types` | Data types, input validation, schema definitions |
|
|
1320
514
|
| `database` | All db.* operations with query examples |
|
|
1321
|
-
| `functions` | Reusable function stacks, async patterns |
|
|
1322
|
-
| `security` | Security best practices and authentication |
|