@xanots/sdk 0.0.1 → 0.0.3-beta.0

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.
Files changed (59) hide show
  1. package/README.md +10 -1
  2. package/dist/.build-fingerprint +1 -0
  3. package/dist/{agent-file-refresh-7XCACU34.js → agent-file-refresh-J3KY54E5.js} +3 -2
  4. package/dist/bin.js +8 -8
  5. package/dist/chunk-4HKZH6YK.js +307 -0
  6. package/dist/{chunk-3DUAGYGP.js → chunk-55VHDNW5.js} +2 -2
  7. package/dist/{chunk-EMCAWMHC.js → chunk-5L4X5LS6.js} +16 -2
  8. package/dist/{chunk-LH6Z6KFV.js → chunk-5XZ744TS.js} +1 -1
  9. package/dist/chunk-6DHJVLYP.js +2044 -0
  10. package/dist/{chunk-TRU5OHQ5.js → chunk-CBL57QBQ.js} +53 -31
  11. package/dist/{chunk-5YTBTF25.js → chunk-EWFHDJY5.js} +2 -2
  12. package/dist/{chunk-MZUI3JNX.js → chunk-F6JCFRKO.js} +2 -2
  13. package/dist/{chunk-IZW6MK3U.js → chunk-FY6LXRR6.js} +2 -2
  14. package/dist/{chunk-NOO35BQ2.js → chunk-HKAX756N.js} +3 -3
  15. package/dist/{chunk-RVB7ITKN.js → chunk-LU7TRWMC.js} +2 -2
  16. package/dist/{chunk-33ND6LKO.js → chunk-MWLNBSTY.js} +2 -2
  17. package/dist/{chunk-26CNBZE2.js → chunk-P3TTMWUP.js} +13 -4
  18. package/dist/{chunk-YYRDLFSJ.js → chunk-QO4I5OYF.js} +40 -2
  19. package/dist/{chunk-YDZYMZBE.js → chunk-TQUO2OXY.js} +4 -4
  20. package/dist/{chunk-FJ6ZS5KB.js → chunk-U3G2UW65.js} +177 -60
  21. package/dist/{chunk-YGPIY3WT.js → chunk-VVXPK6SE.js} +64 -22
  22. package/dist/{chunk-VKFQJEMW.js → chunk-WRYT2PAX.js} +14 -371
  23. package/dist/{chunk-WKP4D5MO.js → chunk-YZ4GU6F5.js} +283 -252
  24. package/dist/cli.d.ts +22 -0
  25. package/dist/cli.js +8 -8
  26. package/dist/{codegen-command-OOKK6AZK.js → codegen-command-EXLKZ2ZI.js} +19 -17
  27. package/dist/codegen.js +2 -2
  28. package/dist/{completion-TIPPZN7H.js → completion-2PVZK6YX.js} +2 -2
  29. package/dist/{deploy-command-4EQ7XX5G.js → deploy-command-SXX6RJWM.js} +16 -16
  30. package/dist/{env-target-IFJ5QDHC.js → env-target-3EGIPR4D.js} +2 -2
  31. package/dist/{ephemeral-command-3X3I4ULC.js → ephemeral-command-OGOYP7D6.js} +15 -15
  32. package/dist/index.d.ts +106 -84
  33. package/dist/index.js +6 -6
  34. package/dist/{init-command-R6H7ZXW5.js → init-command-6DGXEVZD.js} +13 -11
  35. package/dist/internal.d.ts +2 -2
  36. package/dist/internal.js +29 -11
  37. package/dist/{live-diff-Y3AKETHE.js → live-diff-RXSJCVJ7.js} +2 -2
  38. package/dist/{lock-commands-XTR2YKLY.js → lock-commands-R22J54XV.js} +11 -11
  39. package/dist/{loop-OM3P2Z6O.js → loop-SAWAOUFO.js} +2 -2
  40. package/dist/{marketplace-command-RATXTKXN.js → marketplace-command-XJIWL4YP.js} +6 -6
  41. package/dist/meta-client-OW5WKWW7.js +1 -1
  42. package/dist/node.d.ts +2 -2
  43. package/dist/node.js +14 -14
  44. package/dist/{release-command-VV5UVZKL.js → release-command-6PLMLGDK.js} +20 -20
  45. package/dist/sandbox-export-command-QCJY4GMV.js +1 -1
  46. package/dist/scaffold.d.ts +1896 -0
  47. package/dist/scaffold.js +101 -0
  48. package/dist/{store-BQ97nKIF.d.ts → store-g45zwB33.d.ts} +91 -75
  49. package/dist/{test-command-TSPBQHBM.js → test-command-LLPXKT35.js} +4 -4
  50. package/dist/{validate-command-4ERHJSCO.js → validate-command-WAT3ZJT3.js} +11 -11
  51. package/dist/{workspace-command-OF23DPNI.js → workspace-command-JKMI7RZ4.js} +20 -18
  52. package/dist/workspace-export-AJMGN3CQ.js +1 -1
  53. package/llms/statements-calls.md +4 -4
  54. package/llms/statements-catalog.md +20 -20
  55. package/llms/statements-data.md +1 -1
  56. package/llms-full.txt +26 -26
  57. package/llms.txt +1 -1
  58. package/manifest.json +197 -84
  59. package/package.json +10 -1
@@ -13,7 +13,7 @@
13
13
  - `s.foreach_remove` [special]
14
14
  - `s.foreach` [special]
15
15
  - `s.group` [special]
16
- - `s.lambda({ as?: string; code?: value; timeout?: value })`
16
+ - `s.lambda({ as?: string; code: value; timeout?: value })`
17
17
  - `s.precondition({ expr?: comparison; error_type?: "standard" | "notfound" | "toomanyrequests" | "accessdenied" | "unauthorized" | "badrequest" | "inputerror"; error?: value; payload?: value })`
18
18
  - `s.return` [special]
19
19
  - `s.switch` [special]
@@ -35,9 +35,9 @@
35
35
  ### ai
36
36
 
37
37
  - `s.ai.agent.run` [special]
38
- - `s.ai.external.mcp.server_details({ as?: string; url?: value; bearer_token?: value; connection_type?: "sse" | "stream" })`
39
- - `s.ai.external.mcp.tool.list({ as?: string; url?: value; bearer_token?: value; connection_type?: "sse" | "stream" })`
40
- - `s.ai.external.mcp.tool.run({ as?: string; url?: value; bearer_token?: value; connection_type?: "sse" | "stream"; tool?: value; args?: value })`
38
+ - `s.ai.external.mcp.server_details({ as?: string; url: value; bearer_token?: value; connection_type?: "sse" | "stream" })`
39
+ - `s.ai.external.mcp.tool.list({ as?: string; url: value; bearer_token?: value; connection_type?: "sse" | "stream" })`
40
+ - `s.ai.external.mcp.tool.run({ as?: string; url: value; bearer_token?: value; connection_type?: "sse" | "stream"; tool: value; args?: value })`
41
41
 
42
42
  ### api
43
43
 
@@ -68,9 +68,9 @@
68
68
  ### cloud
69
69
 
70
70
  - `s.cloud.algolia.request({ as?: string; application_id: value; api_key: value; url: value; method?: "POST" | "GET" | "DELETE" | "PUT"; payload: value })` [output]
71
- - `s.cloud.aws.opensearch.document({ as?: string; auth_type?: "IAM" | "master"; key_id?: value; access_key?: value; region?: value; base_url: value; method?: "GET" | "POST" | "PUT" | "DELETE"; index?: value; doc_id?: value; doc?: value })`
72
- - `s.cloud.aws.opensearch.query({ as?: string; auth_type?: "IAM" | "master"; key_id?: value; access_key?: value; region?: value; base_url?: value; index?: value; payload?: value; size?: value; from?: value; included_fields?: value; return_type?: "search" | "count"; expression?: value; sort?: value })`
73
- - `s.cloud.aws.opensearch.request({ as?: string; auth_type?: "IAM" | "master"; key_id?: value; access_key?: value; region?: value; method?: "GET" | "POST" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "PATCH"; url?: value; query?: value })`
71
+ - `s.cloud.aws.opensearch.document({ as?: string; auth_type?: "IAM" | "master"; key_id: value; access_key: value; region: value; base_url: value; method?: "GET" | "POST" | "PUT" | "DELETE"; index: value; doc_id: value; doc: value })`
72
+ - `s.cloud.aws.opensearch.query({ as?: string; auth_type?: "IAM" | "master"; key_id: value; access_key: value; region: value; base_url: value; index: value; payload: value; size?: value; from?: value; included_fields?: value; return_type?: "search" | "count"; expression?: value; sort?: value })`
73
+ - `s.cloud.aws.opensearch.request({ as?: string; auth_type?: "IAM" | "master"; key_id: value; access_key: value; region: value; method?: "GET" | "POST" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "PATCH"; url: value; query: value })`
74
74
  - `s.cloud.aws.s3.delete_file({ as?: string; bucket: value; region: value; key: value; secret: value; file_key: value })`
75
75
  - `s.cloud.aws.s3.get_file_info({ as?: string; bucket: value; region: value; key: value; secret: value; file_key: value })`
76
76
  - `s.cloud.aws.s3.list_directory({ as?: string; bucket: value; region: value; key: value; secret: value; prefix?: value; next_page_token?: value })`
@@ -84,8 +84,8 @@
84
84
  - `s.cloud.azure.storage.sign_url({ as?: string; account_name: value; account_key: value; container_name: value; path: value; ttl?: value })`
85
85
  - `s.cloud.azure.storage.upload_file({ as?: string; account_name: value; account_key: value; container_name: value; filePath: value; file: value; metadata?: value })`
86
86
  - `s.cloud.elasticsearch.document({ as?: string; auth_type?: "Basic" | "Bearer" | "API Key"; key_id: value; access_key: value; base_url: value; index: value; method?: "GET" | "POST" | "PUT" | "DELETE"; doc_id: value; doc: value })`
87
- - `s.cloud.elasticsearch.query({ as?: string; auth_type?: "Basic" | "Bearer" | "API Key"; key_id?: value; access_key?: value; base_url?: value; index?: value; payload?: value; size?: value; from?: value; included_fields?: value; return_type?: "search" | "count"; expression?: value; sort?: value })`
88
- - `s.cloud.elasticsearch.request({ as?: string; auth_type?: "Basic" | "Bearer" | "API Key"; key_id?: value; access_key?: value; method?: "POST" | "GET" | "PUT" | "DELETE" | "PATCH"; url?: value; payload?: value })`
87
+ - `s.cloud.elasticsearch.query({ as?: string; auth_type?: "Basic" | "Bearer" | "API Key"; key_id: value; access_key: value; base_url: value; index: value; payload: value; size?: value; from?: value; included_fields?: value; return_type?: "search" | "count"; expression?: value; sort?: value })`
88
+ - `s.cloud.elasticsearch.request({ as?: string; auth_type?: "Basic" | "Bearer" | "API Key"; key_id: value; access_key: value; method?: "POST" | "GET" | "PUT" | "DELETE" | "PATCH"; url: value; payload: value })`
89
89
  - `s.cloud.google.storage.delete_file({ as?: string; service_account: value; bucket: value; filePath: value })`
90
90
  - `s.cloud.google.storage.get_file_info({ as?: string; service_account: value; bucket: value; filePath: value })`
91
91
  - `s.cloud.google.storage.list_directory({ as?: string; service_account: value; bucket: value; path: value })`
@@ -99,9 +99,9 @@
99
99
  ### datadog
100
100
 
101
101
  - `s.datadog.log_bulk({ entries: value; connection?: value })`
102
- - `s.datadog.log({ message?: value; status?: "debug" | "info" | "notice" | "warn" | "error" | "critical" | "alert" | "emergency"; attributes?: value; service?: value; source?: value; env?: value; hostname?: value; tags?: value; timestamp?: value; connection?: value })`
102
+ - `s.datadog.log({ message: value; status?: "debug" | "info" | "notice" | "warn" | "error" | "critical" | "alert" | "emergency"; attributes?: value; service?: value; source?: value; env?: value; hostname?: value; tags?: value; timestamp?: value; connection?: value })`
103
103
  - `s.datadog.metric_bulk({ entries: value; connection?: value })`
104
- - `s.datadog.metric({ metric?: value; value: value; type?: "count" | "gauge" | "rate" | "histogram" | "distribution"; tags?: value; service?: value; source?: value; env?: value; hostname?: value; timestamp?: value; connection?: value })`
104
+ - `s.datadog.metric({ metric: value; value: value; type?: "count" | "gauge" | "rate" | "histogram" | "distribution"; tags?: value; service?: value; source?: value; env?: value; hostname?: value; timestamp?: value; connection?: value })`
105
105
 
106
106
  ### db
107
107
 
@@ -215,7 +215,7 @@ Assertions. **Put them in a `workflowTest({...})` stack** — assert on what a `
215
215
 
216
216
  ### security
217
217
 
218
- - `s.security.check_password({ as?: string; text_password?: value; hash_password?: value })` [output] → as: boolean (true when the plaintext matches the stored hash. ⚠ input.password double-hashes — pass input.text() plaintext)
218
+ - `s.security.check_password({ as?: string; text_password: value; hash_password: value })` [output] → as: boolean (true when the plaintext matches the stored hash. ⚠ input.password double-hashes — pass input.text() plaintext)
219
219
  - `s.security.create_auth_token` [special]
220
220
  - `s.security.create_curve_key({ as?: string; curve?: "P-256" | "P-384" | "P-521"; format?: "object" | "base64" })`
221
221
  - `s.security.create_guid` [special]
@@ -223,12 +223,12 @@ Assertions. **Put them in a `workflowTest({...})` stack** — assert on what a `
223
223
  - `s.security.create_rsa_key({ as?: string; bits?: value; format?: "object" | "base64" })`
224
224
  - `s.security.create_secret_key({ as?: string; bits?: value; format?: "object" | "base64" })`
225
225
  - `s.security.create_uuid({ as?: string })`
226
- - `s.security.decrypt({ as?: string; data?: value; algorithm?: "aes-128-cbc" | "aes-192-cbc" | "aes-256-cbc" | "aes-128-gcm" | "aes-192-gcm" | "aes-256-gcm"; key?: value; iv?: value })`
227
- - `s.security.encrypt({ as?: string; data?: value; algorithm?: "aes-128-cbc" | "aes-192-cbc" | "aes-256-cbc" | "aes-128-gcm" | "aes-192-gcm" | "aes-256-gcm"; key?: value; iv?: value })`
228
- - `s.security.jwe_decode({ as?: string; token?: value; key?: value; check_claims?: value; key_algorithm?: "A128KW" | "A192KW" | "A256KW" | "A128GCMKW" | "A192GCMKW" | "A256GCMKW" | "ECDH-ES+A128KW" | "ECDH-ES+A192KW" | "ECDH-ES+A256KW"; content_algorithm?: "A128GCM" | "A192GCM" | "A256GCM" | "A128CBC-HS256" | "A192CBC-HS384" | "A256CBC-HS512"; timeDrift?: value })`
229
- - `s.security.jwe_encode({ as?: string; headers?: value; claims?: value; key?: value; key_algorithm?: "A128KW" | "A192KW" | "A256KW" | "A128GCMKW" | "A192GCMKW" | "A256GCMKW" | "ECDH-ES+A128KW" | "ECDH-ES+A192KW" | "ECDH-ES+A256KW"; content_algorithm?: "A128GCM" | "A192GCM" | "A256GCM" | "A128CBC-HS256" | "A192CBC-HS384" | "A256CBC-HS512"; ttl?: value })`
230
- - `s.security.jws_decode({ as?: string; token?: value; key?: value; check_claims?: value; signature_algorithm?: "PS256" | "PS384" | "PS512" | "RS256" | "RS384" | "RS512" | "HS256" | "HS384" | "HS512" | "ES256" | "ES384" | "ES512"; timeDrift?: value })`
231
- - `s.security.jws_encode({ as?: string; headers?: value; claims?: value; key?: value; signature_algorithm?: "PS256" | "PS384" | "PS512" | "RS256" | "RS384" | "RS512" | "HS256" | "HS384" | "HS512" | "ES256" | "ES384" | "ES512"; ttl?: value })`
226
+ - `s.security.decrypt({ as?: string; data: value; algorithm?: "aes-128-cbc" | "aes-192-cbc" | "aes-256-cbc" | "aes-128-gcm" | "aes-192-gcm" | "aes-256-gcm"; key: value; iv: value })`
227
+ - `s.security.encrypt({ as?: string; data: value; algorithm?: "aes-128-cbc" | "aes-192-cbc" | "aes-256-cbc" | "aes-128-gcm" | "aes-192-gcm" | "aes-256-gcm"; key: value; iv: value })`
228
+ - `s.security.jwe_decode({ as?: string; token: value; key: value; check_claims?: value; key_algorithm?: "A128KW" | "A192KW" | "A256KW" | "A128GCMKW" | "A192GCMKW" | "A256GCMKW" | "ECDH-ES+A128KW" | "ECDH-ES+A192KW" | "ECDH-ES+A256KW"; content_algorithm?: "A128GCM" | "A192GCM" | "A256GCM" | "A128CBC-HS256" | "A192CBC-HS384" | "A256CBC-HS512"; timeDrift?: value })`
229
+ - `s.security.jwe_encode({ as?: string; headers?: value; claims?: value; key: value; key_algorithm?: "A128KW" | "A192KW" | "A256KW" | "A128GCMKW" | "A192GCMKW" | "A256GCMKW" | "ECDH-ES+A128KW" | "ECDH-ES+A192KW" | "ECDH-ES+A256KW"; content_algorithm?: "A128GCM" | "A192GCM" | "A256GCM" | "A128CBC-HS256" | "A192CBC-HS384" | "A256CBC-HS512"; ttl?: value })`
230
+ - `s.security.jws_decode({ as?: string; token: value; key: value; check_claims?: value; signature_algorithm?: "PS256" | "PS384" | "PS512" | "RS256" | "RS384" | "RS512" | "HS256" | "HS384" | "HS512" | "ES256" | "ES384" | "ES512"; timeDrift?: value })`
231
+ - `s.security.jws_encode({ as?: string; headers?: value; claims?: value; key: value; signature_algorithm?: "PS256" | "PS384" | "PS512" | "RS256" | "RS384" | "RS512" | "HS256" | "HS384" | "HS512" | "ES256" | "ES384" | "ES512"; ttl?: value })`
232
232
  - `s.security.random_bytes({ as?: string; length?: value })`
233
233
  - `s.security.random_number({ as?: string; min?: value; max?: value })`
234
234
 
@@ -277,7 +277,7 @@ Assertions. **Put them in a `workflowTest({...})` stack** — assert on what a `
277
277
 
278
278
  ### util
279
279
 
280
- - `s.util.geo_distance({ as?: string; latitude_1?: value; longitude_1?: value; latitude_2?: value; longitude_2?: value })` → as: number (great-circle distance in METRES (a decimal) — divide by 1000 for km. Identical points return 0)
280
+ - `s.util.geo_distance({ as?: string; latitude_1: value; longitude_1: value; latitude_2: value; longitude_2: value })` → as: number (great-circle distance in METRES (a decimal) — divide by 1000 for km. Identical points return 0)
281
281
  - `s.util.get_all_input({ as?: string })`
282
282
  - `s.util.get_env({ as?: string })`
283
283
  - `s.util.get_input` [special]
@@ -285,7 +285,7 @@ Assertions. **Put them in a `workflowTest({...})` stack** — assert on what a `
285
285
  - `s.util.get_vars({ as?: string })`
286
286
  - `s.util.ip_lookup({ as?: string; value: value })` → as: IpLookupResult | null (NESTED, not flat: { continent: {code,name}, country: {code,name}, region: {code,name}, city: {name}, postal: {code}, location: {latitude, longitude, tz, radius} }. Coordinates are ref("geo.location.latitude"/".longitude"), place names ref("geo.city.name"/"geo.region.name"/"geo.country.name"); radius is KILOMETRES. ⚠ Every leaf is nullable and region/city/postal commonly ARE null for a routable public address — that is a normal hit, not a failed lookup. `city` is an OBJECT, so a bare ref("geo.city") into a text column fails on the object and { safe: true } does NOT help; drill to city.name with a fallback. The whole var is null for an unresolvable address)
287
287
  - `s.util.post_process` [special]
288
- - `s.util.send_email({ as?: string; service_provider?: "resend" | "xano"; api_key?: value; subject?: value; message?: value; to?: value; bcc?: value; cc?: value; from?: value; reply_to?: value; scheduled_at?: value })`
288
+ - `s.util.send_email({ as?: string; api_key?: value; service_provider?: "resend" | "xano"; subject?: value; message?: value; to?: value; bcc?: value; cc?: value; from?: value; reply_to?: value; scheduled_at?: value })`
289
289
  - `s.util.set_header({ value: value; duplicates?: "replace" | "append" })`
290
290
  - `s.util.sleep({ value: value })`
291
291
  - `s.util.template_engine({ as?: string; value: value })`
@@ -5,7 +5,7 @@
5
5
  Array blocks (an `if`/`transform` is applied per item):
6
6
 
7
7
  - `s.array.map({ source, as?, transform? })` — `transform` is either a per-item `Value` expression (each item maps to that value) or a **record of values** (each item maps to an object with those keys), or a list of `{ key, value }` pairs, for a key computed per item or two rows sharing one. Use `ref("$this")` for the item and `ref("$index")` for its position. These are THIS statement's own bindings, in a value expression — not the JavaScript lambda contract (see **Lambda bodies**), which binds a different set per surface and is written with `lam.fn`.
8
- - `s.array.union({ source, with?, as?, transform? })` — set-union two arrays.
8
+ - `s.array.union({ source, with, as?, transform? })` — set-union two arrays. `with` is REQUIRED; omitted → `Unable to locate input: `.
9
9
 
10
10
  DB reads/writes (`table` is a def handle or name; `fieldName` defaults to the
11
11
  primary key `id`):
package/llms-full.txt CHANGED
@@ -1,4 +1,4 @@
1
- # xanots v0.0.1
1
+ # xanots v0.0.3-beta.0
2
2
 
3
3
  > TypeScript SDK that compiles a typed Xano workspace into the importable packageExport JSON bundle.
4
4
 
@@ -761,7 +761,7 @@ errorTrigger}({ name, guid?, description?, active?, tags?, ... })`.
761
761
  Array blocks (an `if`/`transform` is applied per item):
762
762
 
763
763
  - `s.array.map({ source, as?, transform? })` — `transform` is either a per-item `Value` expression (each item maps to that value) or a **record of values** (each item maps to an object with those keys), or a list of `{ key, value }` pairs, for a key computed per item or two rows sharing one. Use `ref("$this")` for the item and `ref("$index")` for its position. These are THIS statement's own bindings, in a value expression — not the JavaScript lambda contract (see **Lambda bodies**), which binds a different set per surface and is written with `lam.fn`.
764
- - `s.array.union({ source, with?, as?, transform? })` — set-union two arrays.
764
+ - `s.array.union({ source, with, as?, transform? })` — set-union two arrays. `with` is REQUIRED; omitted → `Unable to locate input: `.
765
765
 
766
766
  DB reads/writes (`table` is a def handle or name; `fieldName` defaults to the
767
767
  primary key `id`):
@@ -873,12 +873,12 @@ Auth & calls:
873
873
  - `s.function.run({ fn, input?, as?, runtime? })` / `s.function.call({ fn, input?, as? })` — run another function; `input` is keyed by the target's input names.
874
874
  - `runtime?` runs it in the BACKGROUND: `{ mode: "async-shared" }` or `{ mode: "async-dedicated", cpu?, memory?, timeout?, maxRetry? }` (resources read at dedicated only). An async call DOES NOT return the result — it dispatches and continues, so `as` binds nothing; collect with `s.await({ ids })`. Omit for a normal call. Same block on `s.ai.agent.run`.
875
875
  - `s.api.call({ api, input?, headers?, auth?, as? })` — invoke an endpoint. `headers` REPLACES the request headers the callee sees and takes the same shapes as `s.api.request`'s — a `{ "Name": value }` record (values may be tagged), a `string[]` of `"Name: value"` lines, or one `Value`. `auth` is `{ token, ignoreExpiration? }`: `token` must be a BARE STRING — a tagged `Value` deploys clean and then fails the run with `Param: token - Text filter requires an integer, float, string or boolean value`, since the engine stores that slot as plain text and never evaluates it. Neither slot authenticates the call today; see `llms/tests.md` for what a workflow-test run actually sees. WORKFLOW-TEST ONLY (see Gotchas in `llms.txt`) — elsewhere it deploys clean and 500s the first real request.
876
- - `s.api.request({ url?, method?, params?, headers?, timeout?, follow_location?, verify_host?, verify_peer?, ca_certificate?, certificate?, certificate_pass?, private_key?, private_key_pass?, description?, output?, as? })` — external HTTP request (`mvp:api_request`). Ergonomic types, each also accepting a dynamic `Value`: `method` suggests the 7 verbs (GET/POST/PUT/DELETE/HEAD/OPTIONS/PATCH), `params` a plain JSON object **or** a FLAT record whose values are tagged `Value`s (`{ count: ref("count") }`, each lifted via a `set` filter — the same record-of-values shape `response: { key: value }` takes); a tagged value NESTED inside an object or array THROWS at encode, so wrap a structured body in `obj({...})`, which encodes any depth as one `const:expr2` (→ query string for GET/HEAD/OPTIONS, body otherwise), `headers` a `{ "Name": value }` record whose values may be tagged (`{ "x-api-key": env("KEY") }`, each pair joined to a `"Name: value"` line) **or** a `string[]` of full header lines — prefer a header over a `?key=` query param for a credential — a URL travels into access logs, proxies and `Referer`. ⚠ Neither spelling is envelope-safe: the `as` envelope's `request` half mirrors `url`, `params` AND `headers`, so never return it raw from a credentialed request — read `response.result`. A NAME outside the header-token charset is refused, and a LITERAL value carrying a newline is refused; a value may hold `:` and spaces (`Bearer a: b` is a valid value). A TAGGED value cannot be checked at build time, so strip CRLF from caller-controlled input before this slot. Literal pairs lead the emitted array and computed ones follow, so the wire order is not the record's key order, `timeout` a `number` in seconds (1–86400), and `follow_location`/`verify_host`/`verify_peer` booleans. `description` (Settings tab) and `output` filters (Output tab) ride the envelope. SSL cert interdependencies (certificate↔private_key, ca_certificate→verify_peer) are checked at build time when statically provable, else by the engine at runtime. The `as` result is typed as the `{request, response}` envelope (`response.status: number`, `response.result: unknown`), so `InferResponse` resolves a `ref` to it. Same typed result on `webflow.request` and `microservice.request`.
877
- - `s.stream.from_request({ url?, method?, …tls, as? })` — streaming external HTTP request (`mvp:streaming_api_request`); same typed field surface as `s.api.request` (no description/output envelope).
878
- - `s.webflow.request({ path?, method?, …tls, as? })` — Webflow API request (`mvp:connect_webflow_api_request`); like `s.api.request` but addressed by `path` (host is engine-supplied).
876
+ - `s.api.request({ url, method?, params?, headers?, timeout?, follow_location?, verify_host?, verify_peer?, ca_certificate?, certificate?, certificate_pass?, private_key?, private_key_pass?, description?, output?, as? })` — external HTTP request (`mvp:api_request`). Ergonomic types, each also accepting a dynamic `Value`: `method` suggests the 7 verbs (GET/POST/PUT/DELETE/HEAD/OPTIONS/PATCH), `params` a plain JSON object **or** a FLAT record whose values are tagged `Value`s (`{ count: ref("count") }`, each lifted via a `set` filter — the same record-of-values shape `response: { key: value }` takes); a tagged value NESTED inside an object or array THROWS at encode, so wrap a structured body in `obj({...})`, which encodes any depth as one `const:expr2` (→ query string for GET/HEAD/OPTIONS, body otherwise), `headers` a `{ "Name": value }` record whose values may be tagged (`{ "x-api-key": env("KEY") }`, each pair joined to a `"Name: value"` line) **or** a `string[]` of full header lines — prefer a header over a `?key=` query param for a credential — a URL travels into access logs, proxies and `Referer`. ⚠ Neither spelling is envelope-safe: the `as` envelope's `request` half mirrors `url`, `params` AND `headers`, so never return it raw from a credentialed request — read `response.result`. A NAME outside the header-token charset is refused, and a LITERAL value carrying a newline is refused; a value may hold `:` and spaces (`Bearer a: b` is a valid value). A TAGGED value cannot be checked at build time, so strip CRLF from caller-controlled input before this slot. Literal pairs lead the emitted array and computed ones follow, so the wire order is not the record's key order, `timeout` a `number` in seconds (1–86400), and `follow_location`/`verify_host`/`verify_peer` booleans. `description` (Settings tab) and `output` filters (Output tab) ride the envelope. SSL cert interdependencies (certificate↔private_key, ca_certificate→verify_peer) are checked at build time when statically provable, else by the engine at runtime. The `as` result is typed as the `{request, response}` envelope (`response.status: number`, `response.result: unknown`), so `InferResponse` resolves a `ref` to it. Same typed result on `webflow.request` and `microservice.request`.
877
+ - `s.stream.from_request({ url, method?, …tls, as? })` — streaming external HTTP request (`mvp:streaming_api_request`); same typed field surface as `s.api.request` (no description/output envelope). `url` is REQUIRED — it shares `api.request`'s engine declaration, which has no default.
878
+ - `s.webflow.request({ path, method?, …tls, as? })` — Webflow API request (`mvp:connect_webflow_api_request`); like `s.api.request` but addressed by `path` (host is engine-supplied), and `path` is REQUIRED — the engine rejects an empty one. No `headers`: the engine builds its own from the workspace's Webflow connection and ignores an authored value.
879
879
  - `s.task.call` / `s.tool.call` / `s.trigger.call` / `s.middleware.call` / `s.addon.call` — same `{ <target>, input?, as? }` shape against the named kind. `s.task.call` and `s.trigger.call` are WORKFLOW-TEST ONLY (see Gotchas in `llms.txt`); `s.tool.call`, `s.middleware.call` and `s.addon.call` run from any stack.
880
880
  - `s.action.call({ action, package?, input?, as? })` / `s.action.package.call(…)` — invoke a marketplace action; `package` is its slug.
881
- - `s.cloud.job({ image?, command?, args?, secret?, template?, await?, as? })` — launch a containerized job. ⚠ `await` is SECONDS (default 60), not a boolean.
881
+ - `s.cloud.job({ image, command, args?, secret?, template?, await?, as? })` — launch a containerized job. `image`/`command` are REQUIRED; omitted → `Missing param`. ⚠ `await` is SECONDS (default 60), not a boolean.
882
882
  - `s.cloud.job.status({ id, as? })` · `s.cloud.job.await({ ids, timeout, as? })` — poll one job, or block on several (`ids` a list `Value`, `timeout` in seconds; both required).
883
883
 
884
884
  Microservices (the `microservice()` def and the statement that calls it):
@@ -1376,7 +1376,7 @@ var VALUES ride inline in `xano/workspace.ts`, so treat a pulled tree as secret-
1376
1376
  - `s.foreach_remove` [special]
1377
1377
  - `s.foreach` [special]
1378
1378
  - `s.group` [special]
1379
- - `s.lambda({ as?: string; code?: value; timeout?: value })`
1379
+ - `s.lambda({ as?: string; code: value; timeout?: value })`
1380
1380
  - `s.precondition({ expr?: comparison; error_type?: "standard" | "notfound" | "toomanyrequests" | "accessdenied" | "unauthorized" | "badrequest" | "inputerror"; error?: value; payload?: value })`
1381
1381
  - `s.return` [special]
1382
1382
  - `s.switch` [special]
@@ -1398,9 +1398,9 @@ var VALUES ride inline in `xano/workspace.ts`, so treat a pulled tree as secret-
1398
1398
  ### ai
1399
1399
 
1400
1400
  - `s.ai.agent.run` [special]
1401
- - `s.ai.external.mcp.server_details({ as?: string; url?: value; bearer_token?: value; connection_type?: "sse" | "stream" })`
1402
- - `s.ai.external.mcp.tool.list({ as?: string; url?: value; bearer_token?: value; connection_type?: "sse" | "stream" })`
1403
- - `s.ai.external.mcp.tool.run({ as?: string; url?: value; bearer_token?: value; connection_type?: "sse" | "stream"; tool?: value; args?: value })`
1401
+ - `s.ai.external.mcp.server_details({ as?: string; url: value; bearer_token?: value; connection_type?: "sse" | "stream" })`
1402
+ - `s.ai.external.mcp.tool.list({ as?: string; url: value; bearer_token?: value; connection_type?: "sse" | "stream" })`
1403
+ - `s.ai.external.mcp.tool.run({ as?: string; url: value; bearer_token?: value; connection_type?: "sse" | "stream"; tool: value; args?: value })`
1404
1404
 
1405
1405
  ### api
1406
1406
 
@@ -1431,9 +1431,9 @@ var VALUES ride inline in `xano/workspace.ts`, so treat a pulled tree as secret-
1431
1431
  ### cloud
1432
1432
 
1433
1433
  - `s.cloud.algolia.request({ as?: string; application_id: value; api_key: value; url: value; method?: "POST" | "GET" | "DELETE" | "PUT"; payload: value })` [output]
1434
- - `s.cloud.aws.opensearch.document({ as?: string; auth_type?: "IAM" | "master"; key_id?: value; access_key?: value; region?: value; base_url: value; method?: "GET" | "POST" | "PUT" | "DELETE"; index?: value; doc_id?: value; doc?: value })`
1435
- - `s.cloud.aws.opensearch.query({ as?: string; auth_type?: "IAM" | "master"; key_id?: value; access_key?: value; region?: value; base_url?: value; index?: value; payload?: value; size?: value; from?: value; included_fields?: value; return_type?: "search" | "count"; expression?: value; sort?: value })`
1436
- - `s.cloud.aws.opensearch.request({ as?: string; auth_type?: "IAM" | "master"; key_id?: value; access_key?: value; region?: value; method?: "GET" | "POST" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "PATCH"; url?: value; query?: value })`
1434
+ - `s.cloud.aws.opensearch.document({ as?: string; auth_type?: "IAM" | "master"; key_id: value; access_key: value; region: value; base_url: value; method?: "GET" | "POST" | "PUT" | "DELETE"; index: value; doc_id: value; doc: value })`
1435
+ - `s.cloud.aws.opensearch.query({ as?: string; auth_type?: "IAM" | "master"; key_id: value; access_key: value; region: value; base_url: value; index: value; payload: value; size?: value; from?: value; included_fields?: value; return_type?: "search" | "count"; expression?: value; sort?: value })`
1436
+ - `s.cloud.aws.opensearch.request({ as?: string; auth_type?: "IAM" | "master"; key_id: value; access_key: value; region: value; method?: "GET" | "POST" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "PATCH"; url: value; query: value })`
1437
1437
  - `s.cloud.aws.s3.delete_file({ as?: string; bucket: value; region: value; key: value; secret: value; file_key: value })`
1438
1438
  - `s.cloud.aws.s3.get_file_info({ as?: string; bucket: value; region: value; key: value; secret: value; file_key: value })`
1439
1439
  - `s.cloud.aws.s3.list_directory({ as?: string; bucket: value; region: value; key: value; secret: value; prefix?: value; next_page_token?: value })`
@@ -1447,8 +1447,8 @@ var VALUES ride inline in `xano/workspace.ts`, so treat a pulled tree as secret-
1447
1447
  - `s.cloud.azure.storage.sign_url({ as?: string; account_name: value; account_key: value; container_name: value; path: value; ttl?: value })`
1448
1448
  - `s.cloud.azure.storage.upload_file({ as?: string; account_name: value; account_key: value; container_name: value; filePath: value; file: value; metadata?: value })`
1449
1449
  - `s.cloud.elasticsearch.document({ as?: string; auth_type?: "Basic" | "Bearer" | "API Key"; key_id: value; access_key: value; base_url: value; index: value; method?: "GET" | "POST" | "PUT" | "DELETE"; doc_id: value; doc: value })`
1450
- - `s.cloud.elasticsearch.query({ as?: string; auth_type?: "Basic" | "Bearer" | "API Key"; key_id?: value; access_key?: value; base_url?: value; index?: value; payload?: value; size?: value; from?: value; included_fields?: value; return_type?: "search" | "count"; expression?: value; sort?: value })`
1451
- - `s.cloud.elasticsearch.request({ as?: string; auth_type?: "Basic" | "Bearer" | "API Key"; key_id?: value; access_key?: value; method?: "POST" | "GET" | "PUT" | "DELETE" | "PATCH"; url?: value; payload?: value })`
1450
+ - `s.cloud.elasticsearch.query({ as?: string; auth_type?: "Basic" | "Bearer" | "API Key"; key_id: value; access_key: value; base_url: value; index: value; payload: value; size?: value; from?: value; included_fields?: value; return_type?: "search" | "count"; expression?: value; sort?: value })`
1451
+ - `s.cloud.elasticsearch.request({ as?: string; auth_type?: "Basic" | "Bearer" | "API Key"; key_id: value; access_key: value; method?: "POST" | "GET" | "PUT" | "DELETE" | "PATCH"; url: value; payload: value })`
1452
1452
  - `s.cloud.google.storage.delete_file({ as?: string; service_account: value; bucket: value; filePath: value })`
1453
1453
  - `s.cloud.google.storage.get_file_info({ as?: string; service_account: value; bucket: value; filePath: value })`
1454
1454
  - `s.cloud.google.storage.list_directory({ as?: string; service_account: value; bucket: value; path: value })`
@@ -1462,9 +1462,9 @@ var VALUES ride inline in `xano/workspace.ts`, so treat a pulled tree as secret-
1462
1462
  ### datadog
1463
1463
 
1464
1464
  - `s.datadog.log_bulk({ entries: value; connection?: value })`
1465
- - `s.datadog.log({ message?: value; status?: "debug" | "info" | "notice" | "warn" | "error" | "critical" | "alert" | "emergency"; attributes?: value; service?: value; source?: value; env?: value; hostname?: value; tags?: value; timestamp?: value; connection?: value })`
1465
+ - `s.datadog.log({ message: value; status?: "debug" | "info" | "notice" | "warn" | "error" | "critical" | "alert" | "emergency"; attributes?: value; service?: value; source?: value; env?: value; hostname?: value; tags?: value; timestamp?: value; connection?: value })`
1466
1466
  - `s.datadog.metric_bulk({ entries: value; connection?: value })`
1467
- - `s.datadog.metric({ metric?: value; value: value; type?: "count" | "gauge" | "rate" | "histogram" | "distribution"; tags?: value; service?: value; source?: value; env?: value; hostname?: value; timestamp?: value; connection?: value })`
1467
+ - `s.datadog.metric({ metric: value; value: value; type?: "count" | "gauge" | "rate" | "histogram" | "distribution"; tags?: value; service?: value; source?: value; env?: value; hostname?: value; timestamp?: value; connection?: value })`
1468
1468
 
1469
1469
  ### db
1470
1470
 
@@ -1578,7 +1578,7 @@ Assertions. **Put them in a `workflowTest({...})` stack** — assert on what a `
1578
1578
 
1579
1579
  ### security
1580
1580
 
1581
- - `s.security.check_password({ as?: string; text_password?: value; hash_password?: value })` [output] → as: boolean (true when the plaintext matches the stored hash. ⚠ input.password double-hashes — pass input.text() plaintext)
1581
+ - `s.security.check_password({ as?: string; text_password: value; hash_password: value })` [output] → as: boolean (true when the plaintext matches the stored hash. ⚠ input.password double-hashes — pass input.text() plaintext)
1582
1582
  - `s.security.create_auth_token` [special]
1583
1583
  - `s.security.create_curve_key({ as?: string; curve?: "P-256" | "P-384" | "P-521"; format?: "object" | "base64" })`
1584
1584
  - `s.security.create_guid` [special]
@@ -1586,12 +1586,12 @@ Assertions. **Put them in a `workflowTest({...})` stack** — assert on what a `
1586
1586
  - `s.security.create_rsa_key({ as?: string; bits?: value; format?: "object" | "base64" })`
1587
1587
  - `s.security.create_secret_key({ as?: string; bits?: value; format?: "object" | "base64" })`
1588
1588
  - `s.security.create_uuid({ as?: string })`
1589
- - `s.security.decrypt({ as?: string; data?: value; algorithm?: "aes-128-cbc" | "aes-192-cbc" | "aes-256-cbc" | "aes-128-gcm" | "aes-192-gcm" | "aes-256-gcm"; key?: value; iv?: value })`
1590
- - `s.security.encrypt({ as?: string; data?: value; algorithm?: "aes-128-cbc" | "aes-192-cbc" | "aes-256-cbc" | "aes-128-gcm" | "aes-192-gcm" | "aes-256-gcm"; key?: value; iv?: value })`
1591
- - `s.security.jwe_decode({ as?: string; token?: value; key?: value; check_claims?: value; key_algorithm?: "A128KW" | "A192KW" | "A256KW" | "A128GCMKW" | "A192GCMKW" | "A256GCMKW" | "ECDH-ES+A128KW" | "ECDH-ES+A192KW" | "ECDH-ES+A256KW"; content_algorithm?: "A128GCM" | "A192GCM" | "A256GCM" | "A128CBC-HS256" | "A192CBC-HS384" | "A256CBC-HS512"; timeDrift?: value })`
1592
- - `s.security.jwe_encode({ as?: string; headers?: value; claims?: value; key?: value; key_algorithm?: "A128KW" | "A192KW" | "A256KW" | "A128GCMKW" | "A192GCMKW" | "A256GCMKW" | "ECDH-ES+A128KW" | "ECDH-ES+A192KW" | "ECDH-ES+A256KW"; content_algorithm?: "A128GCM" | "A192GCM" | "A256GCM" | "A128CBC-HS256" | "A192CBC-HS384" | "A256CBC-HS512"; ttl?: value })`
1593
- - `s.security.jws_decode({ as?: string; token?: value; key?: value; check_claims?: value; signature_algorithm?: "PS256" | "PS384" | "PS512" | "RS256" | "RS384" | "RS512" | "HS256" | "HS384" | "HS512" | "ES256" | "ES384" | "ES512"; timeDrift?: value })`
1594
- - `s.security.jws_encode({ as?: string; headers?: value; claims?: value; key?: value; signature_algorithm?: "PS256" | "PS384" | "PS512" | "RS256" | "RS384" | "RS512" | "HS256" | "HS384" | "HS512" | "ES256" | "ES384" | "ES512"; ttl?: value })`
1589
+ - `s.security.decrypt({ as?: string; data: value; algorithm?: "aes-128-cbc" | "aes-192-cbc" | "aes-256-cbc" | "aes-128-gcm" | "aes-192-gcm" | "aes-256-gcm"; key: value; iv: value })`
1590
+ - `s.security.encrypt({ as?: string; data: value; algorithm?: "aes-128-cbc" | "aes-192-cbc" | "aes-256-cbc" | "aes-128-gcm" | "aes-192-gcm" | "aes-256-gcm"; key: value; iv: value })`
1591
+ - `s.security.jwe_decode({ as?: string; token: value; key: value; check_claims?: value; key_algorithm?: "A128KW" | "A192KW" | "A256KW" | "A128GCMKW" | "A192GCMKW" | "A256GCMKW" | "ECDH-ES+A128KW" | "ECDH-ES+A192KW" | "ECDH-ES+A256KW"; content_algorithm?: "A128GCM" | "A192GCM" | "A256GCM" | "A128CBC-HS256" | "A192CBC-HS384" | "A256CBC-HS512"; timeDrift?: value })`
1592
+ - `s.security.jwe_encode({ as?: string; headers?: value; claims?: value; key: value; key_algorithm?: "A128KW" | "A192KW" | "A256KW" | "A128GCMKW" | "A192GCMKW" | "A256GCMKW" | "ECDH-ES+A128KW" | "ECDH-ES+A192KW" | "ECDH-ES+A256KW"; content_algorithm?: "A128GCM" | "A192GCM" | "A256GCM" | "A128CBC-HS256" | "A192CBC-HS384" | "A256CBC-HS512"; ttl?: value })`
1593
+ - `s.security.jws_decode({ as?: string; token: value; key: value; check_claims?: value; signature_algorithm?: "PS256" | "PS384" | "PS512" | "RS256" | "RS384" | "RS512" | "HS256" | "HS384" | "HS512" | "ES256" | "ES384" | "ES512"; timeDrift?: value })`
1594
+ - `s.security.jws_encode({ as?: string; headers?: value; claims?: value; key: value; signature_algorithm?: "PS256" | "PS384" | "PS512" | "RS256" | "RS384" | "RS512" | "HS256" | "HS384" | "HS512" | "ES256" | "ES384" | "ES512"; ttl?: value })`
1595
1595
  - `s.security.random_bytes({ as?: string; length?: value })`
1596
1596
  - `s.security.random_number({ as?: string; min?: value; max?: value })`
1597
1597
 
@@ -1640,7 +1640,7 @@ Assertions. **Put them in a `workflowTest({...})` stack** — assert on what a `
1640
1640
 
1641
1641
  ### util
1642
1642
 
1643
- - `s.util.geo_distance({ as?: string; latitude_1?: value; longitude_1?: value; latitude_2?: value; longitude_2?: value })` → as: number (great-circle distance in METRES (a decimal) — divide by 1000 for km. Identical points return 0)
1643
+ - `s.util.geo_distance({ as?: string; latitude_1: value; longitude_1: value; latitude_2: value; longitude_2: value })` → as: number (great-circle distance in METRES (a decimal) — divide by 1000 for km. Identical points return 0)
1644
1644
  - `s.util.get_all_input({ as?: string })`
1645
1645
  - `s.util.get_env({ as?: string })`
1646
1646
  - `s.util.get_input` [special]
@@ -1648,7 +1648,7 @@ Assertions. **Put them in a `workflowTest({...})` stack** — assert on what a `
1648
1648
  - `s.util.get_vars({ as?: string })`
1649
1649
  - `s.util.ip_lookup({ as?: string; value: value })` → as: IpLookupResult | null (NESTED, not flat: { continent: {code,name}, country: {code,name}, region: {code,name}, city: {name}, postal: {code}, location: {latitude, longitude, tz, radius} }. Coordinates are ref("geo.location.latitude"/".longitude"), place names ref("geo.city.name"/"geo.region.name"/"geo.country.name"); radius is KILOMETRES. ⚠ Every leaf is nullable and region/city/postal commonly ARE null for a routable public address — that is a normal hit, not a failed lookup. `city` is an OBJECT, so a bare ref("geo.city") into a text column fails on the object and { safe: true } does NOT help; drill to city.name with a fallback. The whole var is null for an unresolvable address)
1650
1650
  - `s.util.post_process` [special]
1651
- - `s.util.send_email({ as?: string; service_provider?: "resend" | "xano"; api_key?: value; subject?: value; message?: value; to?: value; bcc?: value; cc?: value; from?: value; reply_to?: value; scheduled_at?: value })`
1651
+ - `s.util.send_email({ as?: string; api_key?: value; service_provider?: "resend" | "xano"; subject?: value; message?: value; to?: value; bcc?: value; cc?: value; from?: value; reply_to?: value; scheduled_at?: value })`
1652
1652
  - `s.util.set_header({ value: value; duplicates?: "replace" | "append" })`
1653
1653
  - `s.util.sleep({ value: value })`
1654
1654
  - `s.util.template_engine({ as?: string; value: value })`
package/llms.txt CHANGED
@@ -1,4 +1,4 @@
1
- # xanots v0.0.1
1
+ # xanots v0.0.3-beta.0
2
2
 
3
3
  > TypeScript SDK that compiles a typed Xano workspace into the importable packageExport JSON bundle.
4
4