@xano/developer-mcp 1.0.7 → 1.0.9
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 +28 -0
- package/dist/index.js +42 -1
- package/dist/templates/xanoscript-index.js +7 -0
- package/package.json +1 -1
- package/xanoscript_docs/README.md +38 -5
- package/xanoscript_docs/addons.md +285 -0
- package/xanoscript_docs/agents.md +84 -0
- package/xanoscript_docs/database.md +160 -0
- package/xanoscript_docs/debugging.md +342 -0
- package/xanoscript_docs/functions.md +172 -0
- package/xanoscript_docs/integrations.md +376 -7
- package/xanoscript_docs/performance.md +407 -0
- package/xanoscript_docs/realtime.md +382 -0
- package/xanoscript_docs/schema.md +292 -0
- package/xanoscript_docs/security.md +550 -0
- package/xanoscript_docs/streaming.md +318 -0
- package/xanoscript_docs/syntax.md +267 -0
- package/xanoscript_docs/triggers.md +354 -52
- package/xanoscript_docs/types.md +66 -21
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "functions/**/*.xs, apis/**/*.xs"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Streaming Operations
|
|
6
|
+
|
|
7
|
+
Stream data from files, requests, and to API responses.
|
|
8
|
+
|
|
9
|
+
## Quick Reference
|
|
10
|
+
|
|
11
|
+
| Operation | Purpose | Input |
|
|
12
|
+
|-----------|---------|-------|
|
|
13
|
+
| `stream.from_csv` | Parse CSV stream | File or string |
|
|
14
|
+
| `stream.from_jsonl` | Parse JSONL stream | File or string |
|
|
15
|
+
| `stream.from_request` | Stream HTTP request body | Request |
|
|
16
|
+
| `api.stream` | Stream response to client | Data |
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## stream.from_csv
|
|
21
|
+
|
|
22
|
+
Parse CSV data as a stream, processing rows one at a time without loading entire file into memory.
|
|
23
|
+
|
|
24
|
+
```xs
|
|
25
|
+
stream.from_csv {
|
|
26
|
+
value = $input.csv_file
|
|
27
|
+
headers = true
|
|
28
|
+
delimiter = ","
|
|
29
|
+
enclosure = "\""
|
|
30
|
+
} as $row {
|
|
31
|
+
// Process each row
|
|
32
|
+
db.add "import_record" {
|
|
33
|
+
data = {
|
|
34
|
+
name: $row.name,
|
|
35
|
+
email: $row.email,
|
|
36
|
+
created_at: now
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Parameters
|
|
43
|
+
|
|
44
|
+
| Parameter | Type | Default | Description |
|
|
45
|
+
|-----------|------|---------|-------------|
|
|
46
|
+
| `value` | file/text | required | CSV file or string |
|
|
47
|
+
| `headers` | bool | `true` | First row contains headers |
|
|
48
|
+
| `delimiter` | text | `,` | Field delimiter |
|
|
49
|
+
| `enclosure` | text | `"` | Field enclosure character |
|
|
50
|
+
| `escape` | text | `\` | Escape character |
|
|
51
|
+
|
|
52
|
+
### With Custom Headers
|
|
53
|
+
|
|
54
|
+
```xs
|
|
55
|
+
stream.from_csv {
|
|
56
|
+
value = $input.file
|
|
57
|
+
headers = false
|
|
58
|
+
} as $row {
|
|
59
|
+
// Access by index: $row.0, $row.1, etc.
|
|
60
|
+
var $name { value = $row.0 }
|
|
61
|
+
var $email { value = $row.1 }
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## stream.from_jsonl
|
|
68
|
+
|
|
69
|
+
Parse JSON Lines (newline-delimited JSON) as a stream.
|
|
70
|
+
|
|
71
|
+
```xs
|
|
72
|
+
stream.from_jsonl {
|
|
73
|
+
value = $input.jsonl_file
|
|
74
|
+
} as $record {
|
|
75
|
+
// Each $record is a parsed JSON object
|
|
76
|
+
db.add "event" {
|
|
77
|
+
data = {
|
|
78
|
+
event_type: $record.type,
|
|
79
|
+
payload: $record.data,
|
|
80
|
+
timestamp: $record.ts
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Parameters
|
|
87
|
+
|
|
88
|
+
| Parameter | Type | Default | Description |
|
|
89
|
+
|-----------|------|---------|-------------|
|
|
90
|
+
| `value` | file/text | required | JSONL file or string |
|
|
91
|
+
|
|
92
|
+
### Example JSONL Format
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
{"type":"click","data":{"page":"/home"},"ts":1699900000}
|
|
96
|
+
{"type":"view","data":{"page":"/products"},"ts":1699900001}
|
|
97
|
+
{"type":"click","data":{"page":"/checkout"},"ts":1699900002}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## stream.from_request
|
|
103
|
+
|
|
104
|
+
Stream the incoming HTTP request body for large uploads.
|
|
105
|
+
|
|
106
|
+
```xs
|
|
107
|
+
stream.from_request {
|
|
108
|
+
format = "jsonl"
|
|
109
|
+
} as $record {
|
|
110
|
+
// Process streamed data
|
|
111
|
+
db.add "log" { data = $record }
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Parameters
|
|
116
|
+
|
|
117
|
+
| Parameter | Type | Options | Description |
|
|
118
|
+
|-----------|------|---------|-------------|
|
|
119
|
+
| `format` | text | `jsonl`, `csv`, `raw` | Body format |
|
|
120
|
+
| `headers` | bool | `true` (csv) | CSV has headers |
|
|
121
|
+
| `delimiter` | text | `,` (csv) | CSV delimiter |
|
|
122
|
+
|
|
123
|
+
### Raw Chunks
|
|
124
|
+
|
|
125
|
+
```xs
|
|
126
|
+
stream.from_request {
|
|
127
|
+
format = "raw"
|
|
128
|
+
chunk_size = 8192
|
|
129
|
+
} as $chunk {
|
|
130
|
+
// Process raw bytes
|
|
131
|
+
storage.append_file {
|
|
132
|
+
pathname = "uploads/large_file.bin"
|
|
133
|
+
data = $chunk
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## api.stream
|
|
141
|
+
|
|
142
|
+
Stream response data to the client. Useful for large datasets, real-time feeds, or server-sent events.
|
|
143
|
+
|
|
144
|
+
### Streaming JSONL Response
|
|
145
|
+
|
|
146
|
+
```xs
|
|
147
|
+
query "export_logs" {
|
|
148
|
+
input {
|
|
149
|
+
timestamp start_date
|
|
150
|
+
timestamp end_date
|
|
151
|
+
}
|
|
152
|
+
stack {
|
|
153
|
+
db.query "log" {
|
|
154
|
+
where = $db.log.created_at >= $input.start_date && $db.log.created_at <= $input.end_date
|
|
155
|
+
return = { type: "stream" }
|
|
156
|
+
} as $logs
|
|
157
|
+
|
|
158
|
+
api.stream {
|
|
159
|
+
format = "jsonl"
|
|
160
|
+
value = $logs
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Streaming CSV Response
|
|
167
|
+
|
|
168
|
+
```xs
|
|
169
|
+
query "export_users_csv" {
|
|
170
|
+
stack {
|
|
171
|
+
db.query "user" {
|
|
172
|
+
return = { type: "stream" }
|
|
173
|
+
} as $users
|
|
174
|
+
|
|
175
|
+
api.stream {
|
|
176
|
+
format = "csv"
|
|
177
|
+
value = $users
|
|
178
|
+
headers = ["id", "name", "email", "created_at"]
|
|
179
|
+
filename = "users_export.csv"
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Server-Sent Events (SSE)
|
|
186
|
+
|
|
187
|
+
```xs
|
|
188
|
+
query "live_updates" {
|
|
189
|
+
stack {
|
|
190
|
+
api.stream {
|
|
191
|
+
format = "sse"
|
|
192
|
+
} as $stream
|
|
193
|
+
|
|
194
|
+
// Send events to client
|
|
195
|
+
$stream.send { event = "connected", data = { status: "ok" } }
|
|
196
|
+
|
|
197
|
+
foreach ($updates) {
|
|
198
|
+
each as $update {
|
|
199
|
+
$stream.send { event = "update", data = $update }
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
$stream.close
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Parameters
|
|
209
|
+
|
|
210
|
+
| Parameter | Type | Options | Description |
|
|
211
|
+
|-----------|------|---------|-------------|
|
|
212
|
+
| `format` | text | `jsonl`, `csv`, `sse`, `raw` | Stream format |
|
|
213
|
+
| `value` | stream | optional | Data source for jsonl/csv |
|
|
214
|
+
| `headers` | text[] | optional | CSV column headers |
|
|
215
|
+
| `filename` | text | optional | Suggested download filename |
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Streaming Patterns
|
|
220
|
+
|
|
221
|
+
### Large File Import
|
|
222
|
+
|
|
223
|
+
```xs
|
|
224
|
+
function "import_large_csv" {
|
|
225
|
+
input {
|
|
226
|
+
file csv_file
|
|
227
|
+
}
|
|
228
|
+
stack {
|
|
229
|
+
var $processed { value = 0 }
|
|
230
|
+
var $errors { value = [] }
|
|
231
|
+
|
|
232
|
+
stream.from_csv {
|
|
233
|
+
value = $input.csv_file
|
|
234
|
+
headers = true
|
|
235
|
+
} as $row {
|
|
236
|
+
try_catch {
|
|
237
|
+
try {
|
|
238
|
+
db.add "record" {
|
|
239
|
+
data = {
|
|
240
|
+
name: $row.name|trim,
|
|
241
|
+
email: $row.email|trim|lower,
|
|
242
|
+
created_at: now
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
math.add $processed { value = 1 }
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
var.update $errors {
|
|
249
|
+
value = $errors|push:{ row: $processed, error: $error.message }
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
response = { processed: $processed, errors: $errors }
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### ETL Pipeline
|
|
260
|
+
|
|
261
|
+
```xs
|
|
262
|
+
function "etl_events" {
|
|
263
|
+
input {
|
|
264
|
+
file events_file
|
|
265
|
+
}
|
|
266
|
+
stack {
|
|
267
|
+
stream.from_jsonl {
|
|
268
|
+
value = $input.events_file
|
|
269
|
+
} as $event {
|
|
270
|
+
// Transform
|
|
271
|
+
var $transformed {
|
|
272
|
+
value = {
|
|
273
|
+
event_type: $event.type|to_lower,
|
|
274
|
+
user_id: $event.user_id|to_int,
|
|
275
|
+
metadata: $event.data|json_encode,
|
|
276
|
+
occurred_at: $event.timestamp|to_timestamp
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Load
|
|
281
|
+
db.add "processed_event" {
|
|
282
|
+
data = $transformed
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
response = { status: "complete" }
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Chunked Export
|
|
291
|
+
|
|
292
|
+
```xs
|
|
293
|
+
query "stream_large_dataset" {
|
|
294
|
+
stack {
|
|
295
|
+
// Stream query results directly to response
|
|
296
|
+
db.query "analytics" {
|
|
297
|
+
where = $db.analytics.created_at >= $input.since
|
|
298
|
+
sort = { created_at: "asc" }
|
|
299
|
+
return = { type: "stream", chunk_size: 1000 }
|
|
300
|
+
} as $data
|
|
301
|
+
|
|
302
|
+
api.stream {
|
|
303
|
+
format = "jsonl"
|
|
304
|
+
value = $data
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Best Practices
|
|
313
|
+
|
|
314
|
+
1. **Use streaming for large files** - Prevents memory exhaustion
|
|
315
|
+
2. **Process in batches** - Commit database operations periodically
|
|
316
|
+
3. **Handle errors gracefully** - Log failures without stopping stream
|
|
317
|
+
4. **Set appropriate chunk sizes** - Balance memory and performance
|
|
318
|
+
5. **Use JSONL for structured data** - Easier to parse than multi-line JSON
|
|
@@ -382,3 +382,270 @@ conditional {
|
|
|
382
382
|
}
|
|
383
383
|
}
|
|
384
384
|
```
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## System Variables
|
|
389
|
+
|
|
390
|
+
Built-in variables available in the execution context.
|
|
391
|
+
|
|
392
|
+
### Request Context
|
|
393
|
+
|
|
394
|
+
| Variable | Description |
|
|
395
|
+
|----------|-------------|
|
|
396
|
+
| `$remote_ip` | Client IP address |
|
|
397
|
+
| `$remote_port` | Client port number |
|
|
398
|
+
| `$remote_host` | Remote hostname |
|
|
399
|
+
| `$request_method` | HTTP method (GET, POST, etc.) |
|
|
400
|
+
| `$request_uri` | Full request URI |
|
|
401
|
+
| `$request_querystring` | Query string portion |
|
|
402
|
+
| `$http_headers` | Request headers object |
|
|
403
|
+
| `$request_auth_token` | Authorization token (if present) |
|
|
404
|
+
|
|
405
|
+
### System Context
|
|
406
|
+
|
|
407
|
+
| Variable | Description |
|
|
408
|
+
|----------|-------------|
|
|
409
|
+
| `$datasource` | Current data source name |
|
|
410
|
+
| `$branch` | Current branch name |
|
|
411
|
+
| `$tenant` | Tenant ID (multi-tenant apps) |
|
|
412
|
+
| `$api_baseurl` | API base URL |
|
|
413
|
+
| `$webflow` | Webflow context (if applicable) |
|
|
414
|
+
|
|
415
|
+
### Access via $env
|
|
416
|
+
|
|
417
|
+
```xs
|
|
418
|
+
// Request variables accessed through $env
|
|
419
|
+
var $client_ip { value = $env.$remote_ip }
|
|
420
|
+
var $method { value = $env.$request_method }
|
|
421
|
+
var $headers { value = $env.$http_headers }
|
|
422
|
+
var $current_branch { value = $env.$branch }
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
## Additional Operators
|
|
428
|
+
|
|
429
|
+
### Nullish Coalescing
|
|
430
|
+
|
|
431
|
+
Return right operand when left is null (not just falsy):
|
|
432
|
+
|
|
433
|
+
```xs
|
|
434
|
+
$value ?? "default" // Returns "default" only if $value is null
|
|
435
|
+
$value || "default" // Returns "default" if $value is null, 0, "", or false
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
```xs
|
|
439
|
+
// Difference example
|
|
440
|
+
var $count { value = 0 }
|
|
441
|
+
$count ?? 10 // Returns 0 (not null)
|
|
442
|
+
$count || 10 // Returns 10 (0 is falsy)
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Database Filter Operators
|
|
446
|
+
|
|
447
|
+
Additional operators for `db.query` where clauses:
|
|
448
|
+
|
|
449
|
+
| Operator | Description | Example |
|
|
450
|
+
|----------|-------------|---------|
|
|
451
|
+
| `@>` | JSON contains | `$db.meta @> {"type": "featured"}` |
|
|
452
|
+
| `~` | Regex match | `$db.name ~ "^test"` |
|
|
453
|
+
| `!~` | Regex not match | `$db.name !~ "^draft"` |
|
|
454
|
+
| `not in` | Not in list | `$db.status not in ["deleted", "hidden"]` |
|
|
455
|
+
| `not between` | Not in range | `$db.price not between 0:10` |
|
|
456
|
+
| `not contains` | Array not contains | `$db.tags not contains "spam"` |
|
|
457
|
+
| `not includes` | String not includes | `$db.title not includes "test"` |
|
|
458
|
+
| `not overlaps` | Arrays don't overlap | `$db.tags not overlaps ["hidden", "draft"]` |
|
|
459
|
+
| `not ilike` | Case-insensitive not like | `$db.name not ilike "%test%"` |
|
|
460
|
+
|
|
461
|
+
```xs
|
|
462
|
+
db.query "product" {
|
|
463
|
+
where = $db.product.status not in ["deleted", "archived"]
|
|
464
|
+
&& $db.product.metadata @> {"featured": true}
|
|
465
|
+
&& $db.product.sku ~ "^SKU-[0-9]+"
|
|
466
|
+
} as $products
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
## Additional Filters
|
|
472
|
+
|
|
473
|
+
### Text Domain Functions
|
|
474
|
+
|
|
475
|
+
Functional equivalents for string operations:
|
|
476
|
+
|
|
477
|
+
```xs
|
|
478
|
+
text.contains("hello world", "world") // true
|
|
479
|
+
text.starts_with("hello", "he") // true
|
|
480
|
+
text.ends_with("hello", "lo") // true
|
|
481
|
+
text.icontains("Hello World", "WORLD") // true (case-insensitive)
|
|
482
|
+
text.istarts_with("Hello", "HE") // true
|
|
483
|
+
text.iends_with("Hello", "LO") // true
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### Object Domain Functions
|
|
487
|
+
|
|
488
|
+
Functional equivalents for object operations:
|
|
489
|
+
|
|
490
|
+
```xs
|
|
491
|
+
object.keys({a: 1, b: 2}) // ["a", "b"]
|
|
492
|
+
object.values({a: 1, b: 2}) // [1, 2]
|
|
493
|
+
object.entries({a: 1, b: 2}) // [{key: "a", value: 1}, {key: "b", value: 2}]
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Math Domain Functions
|
|
497
|
+
|
|
498
|
+
Functional equivalents for math operations:
|
|
499
|
+
|
|
500
|
+
```xs
|
|
501
|
+
math.add(5, 3) // 8
|
|
502
|
+
math.sub(10, 4) // 6
|
|
503
|
+
math.mul(3, 4) // 12
|
|
504
|
+
math.div(20, 5) // 4
|
|
505
|
+
math.mod(10, 3) // 1
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### Bitwise Operations
|
|
509
|
+
|
|
510
|
+
```xs
|
|
511
|
+
// As filters
|
|
512
|
+
5|bitwise_and:3 // 1
|
|
513
|
+
5|bitwise_or:3 // 7
|
|
514
|
+
5|bitwise_xor:3 // 6
|
|
515
|
+
5|bitwise_not // -6
|
|
516
|
+
|
|
517
|
+
// As functions
|
|
518
|
+
math.bitwise.and(5, 3) // 1
|
|
519
|
+
math.bitwise.or(5, 3) // 7
|
|
520
|
+
math.bitwise.xor(5, 3) // 6
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Logical NOT Filter
|
|
524
|
+
|
|
525
|
+
```xs
|
|
526
|
+
true|not // false
|
|
527
|
+
false|not // true
|
|
528
|
+
$condition|not // Inverts boolean
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### Array Filtering
|
|
532
|
+
|
|
533
|
+
| Filter | Description | Example |
|
|
534
|
+
|--------|-------------|---------|
|
|
535
|
+
| `filter_empty` | Remove empty values | `$arr\|filter_empty` |
|
|
536
|
+
| `filter_empty_text` | Remove empty strings | `$arr\|filter_empty_text` |
|
|
537
|
+
| `filter_empty_array` | Remove empty arrays | `$arr\|filter_empty_array` |
|
|
538
|
+
| `filter_empty_object` | Remove empty objects | `$arr\|filter_empty_object` |
|
|
539
|
+
| `filter_null` | Remove null values | `$arr\|filter_null` |
|
|
540
|
+
| `filter_zero` | Remove zero values | `$arr\|filter_zero` |
|
|
541
|
+
| `filter_false` | Remove false values | `$arr\|filter_false` |
|
|
542
|
+
|
|
543
|
+
```xs
|
|
544
|
+
[1, null, "", 0, "text", false]|filter_empty // [1, "text"]
|
|
545
|
+
["a", "", "b", ""]|filter_empty_text // ["a", "b"]
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### Array Fill Operations
|
|
549
|
+
|
|
550
|
+
```xs
|
|
551
|
+
|fill:5:"x" // ["x", "x", "x", "x", "x"]
|
|
552
|
+
["a", "b"]|fill_keys:{"a": 1, "b": 2} // {a: 1, b: 2}
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
### Deep Merge & Comparison
|
|
556
|
+
|
|
557
|
+
```xs
|
|
558
|
+
{a: {b: 1}}|merge_recursive:{a: {c: 2}} // {a: {b: 1, c: 2}}
|
|
559
|
+
[1, 2, 3]|diff_assoc:[2] // Associative diff
|
|
560
|
+
[1, 2, 3]|intersect_assoc:[2, 3, 4] // Associative intersect
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### Encoding Filters
|
|
564
|
+
|
|
565
|
+
| Filter | Description | Example |
|
|
566
|
+
|--------|-------------|---------|
|
|
567
|
+
| `list_encodings` | List available encodings | `\|list_encodings` |
|
|
568
|
+
| `detect_encoding` | Detect string encoding | `$text\|detect_encoding` |
|
|
569
|
+
| `to_utf8` | Convert to UTF-8 | `$text\|to_utf8` |
|
|
570
|
+
| `from_utf8` | Convert from UTF-8 | `$text\|from_utf8:"ISO-8859-1"` |
|
|
571
|
+
| `convert_encoding` | Convert encodings | `$text\|convert_encoding:"UTF-8":"ISO-8859-1"` |
|
|
572
|
+
|
|
573
|
+
```xs
|
|
574
|
+
// CSV parsing (alternative to csv_decode)
|
|
575
|
+
$csv_text|csv_parse // Parse CSV string
|
|
576
|
+
$data|csv_create // Create CSV string
|
|
577
|
+
|
|
578
|
+
// Query string
|
|
579
|
+
"a=1&b=2"|querystring_parse // {a: "1", b: "2"}
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
### String Escape Filters
|
|
583
|
+
|
|
584
|
+
| Filter | Description |
|
|
585
|
+
|--------|-------------|
|
|
586
|
+
| `addslashes` | Escape quotes and backslashes |
|
|
587
|
+
| `escape` | HTML escape |
|
|
588
|
+
| `text_escape` | Escape for text output |
|
|
589
|
+
| `text_unescape` | Unescape text |
|
|
590
|
+
| `regex_quote` | Escape regex special characters |
|
|
591
|
+
|
|
592
|
+
```xs
|
|
593
|
+
"Hello \"World\""|addslashes // "Hello \\\"World\\\""
|
|
594
|
+
"<script>"|escape // "<script>"
|
|
595
|
+
"^test$"|regex_quote // "\^test\$"
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
### Trigonometry Examples
|
|
599
|
+
|
|
600
|
+
```xs
|
|
601
|
+
// Radians and degrees
|
|
602
|
+
90|deg2rad // 1.5707963...
|
|
603
|
+
1.5707963|rad2deg // 90
|
|
604
|
+
|
|
605
|
+
// Trig functions (input in radians)
|
|
606
|
+
0|sin // 0
|
|
607
|
+
0|cos // 1
|
|
608
|
+
0.785398|tan // ~1 (45 degrees)
|
|
609
|
+
|
|
610
|
+
// Inverse trig
|
|
611
|
+
0|asin // 0
|
|
612
|
+
1|acos // 0
|
|
613
|
+
1|atan // 0.785398...
|
|
614
|
+
|
|
615
|
+
// Hyperbolic
|
|
616
|
+
0|sinh // 0
|
|
617
|
+
0|cosh // 1
|
|
618
|
+
0|tanh // 0
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
### DB Query Timestamp Filters
|
|
622
|
+
|
|
623
|
+
Extended timestamp operations for database queries:
|
|
624
|
+
|
|
625
|
+
```xs
|
|
626
|
+
$db.created_at|timestamp_year // Extract year
|
|
627
|
+
$db.created_at|timestamp_month // Extract month (1-12)
|
|
628
|
+
$db.created_at|timestamp_week // Extract week number
|
|
629
|
+
$db.created_at|timestamp_day_of_month // Day of month (1-31)
|
|
630
|
+
$db.created_at|timestamp_day_of_week // Day of week (0-6)
|
|
631
|
+
$db.created_at|timestamp_day_of_year // Day of year (1-366)
|
|
632
|
+
$db.created_at|timestamp_hour // Hour (0-23)
|
|
633
|
+
$db.created_at|timestamp_minute // Minute (0-59)
|
|
634
|
+
|
|
635
|
+
// Epoch variants
|
|
636
|
+
$db.created_at|timestamp_epoch_seconds // Seconds since epoch
|
|
637
|
+
$db.created_at|timestamp_epoch_ms // Milliseconds since epoch
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
### Vector Operations (AI/ML)
|
|
641
|
+
|
|
642
|
+
Additional vector similarity functions:
|
|
643
|
+
|
|
644
|
+
```xs
|
|
645
|
+
$db.embedding|l1_distance_manhattan:$input.vector // L1/Manhattan distance
|
|
646
|
+
$db.embedding|negative_inner_product:$input.vector // Negative inner product
|
|
647
|
+
$db.embedding|inner_product:$input.vector // Inner product
|
|
648
|
+
|
|
649
|
+
// Geo covers (for polygon containment)
|
|
650
|
+
$db.boundary|covers:$input.point // Polygon covers point
|
|
651
|
+
```
|