@xano/xanoscript-language-server 12.23.0 → 12.25.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.
package/lexer/tokens.js CHANGED
@@ -134,7 +134,6 @@ import {
134
134
  RealtimeTriggerTokens,
135
135
  } from "./realtime_trigger.js";
136
136
  import { mapTokenToType as mapRedisTokenToType, RedisTokens } from "./redis.js";
137
- import { mapTokenToType as mapRunTokenToType, RunTokens } from "./run.js";
138
137
  import {
139
138
  mapTokenToType as mapSecurityTokenToType,
140
139
  SecurityTokens,
@@ -295,7 +294,7 @@ export const HistoryToken = createTokenByName("history", {
295
294
  categories: [Identifier], // could also be an identifier
296
295
  });
297
296
 
298
- // `mesh0 = {logging, statements}` on objects and containers.
297
+ // `mesh0 = {logging}` on objects and containers.
299
298
  export const Mesh0Token = createTokenByName("mesh0", {
300
299
  longer_alt: Identifier,
301
300
  categories: [Identifier], // could also be an identifier
@@ -469,7 +468,6 @@ export const allTokens = uniq([
469
468
  ...DbTokens,
470
469
  ...RedisTokens,
471
470
  ...TextTokens,
472
- ...RunTokens,
473
471
  ...ObjectTokens,
474
472
  ...StreamTokens,
475
473
  ...DatadogTokens,
@@ -536,7 +534,6 @@ const tokenMappers = [
536
534
  mapRealtimeServerTriggerTokenToType,
537
535
  mapRealtimeTriggerTokenToType,
538
536
  mapRedisTokenToType,
539
- mapRunTokenToType,
540
537
  mapSecurityTokenToType,
541
538
  mapStorageTokenToType,
542
539
  mapStreamTokenToType,
@@ -333,62 +333,6 @@ An `error_trigger` file defines the workspace's error-notification handler, fire
333
333
 
334
334
  Use an `error_trigger` to wire workspace-wide alerting on top of the error-logs system without subscribing per object or per event source.
335
335
 
336
- # run.job
337
-
338
- ```xs
339
- run.job "Gemini -> Image Understanding" {
340
- main = {
341
- name: "Gemini -> Image Understanding"
342
- input: {
343
- model: "gemini-1.5-flash"
344
- prompt: "Describe what is happening in this image."
345
- image: "(attach image file)"
346
- }
347
- }
348
- env = ["gemini_api_key"]
349
- }
350
- ```
351
-
352
- A `run.job` file defines a job configuration for execution in the Xano Job Runner. It includes:
353
-
354
- - A name (e.g., `"Gemini -> Image Understanding"`) to identify the job,
355
- - A required `main` attribute specifying the function to execute:
356
- - `name`: The name of the function to call,
357
- - `input`: Optional input parameters to pass to the function,
358
- - An optional `env` array listing environment variable names required by the job.
359
-
360
- Jobs are used to run functions as standalone processes, typically for long-running or resource-intensive operations.
361
-
362
- # run.service
363
-
364
- ```xs
365
- run.service "email proxy" {
366
- pre = {
367
- name: "email_proxy_init"
368
- input: {
369
- config: "default"
370
- }
371
- }
372
- env = ["email_proxy_api_key"]
373
- }
374
- ```
375
-
376
- A `run.service` file defines a service configuration for the Xano Job Runner. It includes:
377
-
378
- - A name (e.g., `"email proxy"`) to identify the service,
379
- - An optional `pre` attribute specifying an initialization function to run before the service starts:
380
- - `name`: The name of the initialization function,
381
- - `input`: Optional input parameters for the initialization,
382
- - An optional `env` array listing environment variable names required by the service.
383
-
384
- Services can also be defined in minimal form without a body:
385
-
386
- ```xs
387
- run.service "email proxy"
388
- ```
389
-
390
- Services are ideal for long-running background processes like proxies, webhooks listeners, or daemon-style operations.
391
-
392
336
  # action.call
393
337
 
394
338
  ```xs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xano/xanoscript-language-server",
3
- "version": "12.23.0",
3
+ "version": "12.25.0",
4
4
  "description": "Language Server Protocol implementation for XanoScript, the language of Xano backends",
5
5
  "keywords": [
6
6
  "xano",
@@ -182,6 +182,7 @@ export function agentDeclaration($) {
182
182
  "include_thoughts",
183
183
  ],
184
184
  };
185
+ validFieldsPerSource["xano-ai"] = validFieldsPerSource["xano-free"];
185
186
 
186
187
  const captured = {};
187
188
  $.SUBRULE($.schemaParseObjectFn, {
@@ -193,6 +194,7 @@ export function agentDeclaration($) {
193
194
  "azure-openai",
194
195
  "google-genai",
195
196
  "openai",
197
+ "xano-ai",
196
198
  "xano-free",
197
199
  ],
198
200
  max_steps: "[number]",
@@ -57,7 +57,7 @@ export function branchDeclaration($) {
57
57
  "prompt?": historyValues,
58
58
  "resource?": historyValues,
59
59
  },
60
- // Strict whitelist of run types, each `{logging, statements}`.
60
+ // Strict whitelist of run types, each `{logging}`.
61
61
  // The platform writes only the types that differ from the
62
62
  // default, and no block at all when none do.
63
63
  "mesh0?": {
@@ -2,26 +2,25 @@ import { EqualToken } from "../../lexer/control.js";
2
2
  import { Mesh0Token } from "../../lexer/tokens.js";
3
3
 
4
4
  /**
5
- * The value set of one mesh0 setting, `{logging, statements}`, shared by the
5
+ * The value set of one mesh0 setting, `{logging}`, shared by the
6
6
  * object/container `mesh0 = {...}` clause and each run type of a branch
7
7
  * document's `mesh0` block (`branch_parser.js`).
8
8
  *
9
9
  * Mirrors the platform's mesh0 settings: `logging` is the trace detail
10
- * (`"inherit"` defers to the next level), `statements` the per-run statement
11
- * span cap. Unlimited is written `"all"`, as `history` writes it; the platform
12
- * stores it as `-1`. Both keys are optional, and a missing one inherits.
10
+ * (`"inherit"` defers to the next level) and is required. The per-run
11
+ * statement span cap is not a mesh0 key; the platform takes it from the
12
+ * request-history `history` setting, so a `statements` key is invalid.
13
13
  */
14
14
  export const MESH0_SETTING_SCHEMA = {
15
- "logging?": ["inherit", "minimal", "light", "full"],
16
- "statements?": [100, 1000, 10000, "all"],
15
+ logging: ["inherit", "minimal", "light", "full"],
17
16
  };
18
17
 
19
18
  /**
20
- * Parses the `mesh0 = {logging: "light", statements: 1000}` setting of an
21
- * object (query, function, task, tool, middleware, trigger, prompt, resource)
22
- * or a container (api_group, mcp_server, channel, realtime_server). It sits
23
- * beside `history`. A container presents the same two keys; the platform maps
24
- * them to its type-prefixed fields (`query_logging`, `tool_statements`, ...).
19
+ * Parses the `mesh0 = {logging: "light"}` setting of an object (query,
20
+ * function, task, tool, middleware, trigger, prompt, resource) or a container
21
+ * (api_group, mcp_server, channel, realtime_server). It sits beside
22
+ * `history`. A container presents the same key; the platform maps it to its
23
+ * type-prefixed field (`query_logging`, `tool_logging`, ...).
25
24
  *
26
25
  * @param {import('../base_parser.js').XanoBaseParser} $
27
26
  */
@@ -31,19 +30,8 @@ export function mesh0Clause($) {
31
30
  const parent = $.CONSUME(Mesh0Token); // "mesh0"
32
31
  $.CONSUME(EqualToken); // "="
33
32
 
34
- const captured = {};
35
33
  $.SUBRULE($.schemaParseObjectFn, {
36
- ARGS: [parent, MESH0_SETTING_SCHEMA, captured],
37
- });
38
-
39
- // Both keys are optional, but an empty setting says nothing.
40
- $.ACTION(() => {
41
- if (Object.keys(captured).length === 0) {
42
- $.addMissingError(
43
- parent,
44
- "{} requires at least one of: logging, statements",
45
- );
46
- }
34
+ ARGS: [parent, MESH0_SETTING_SCHEMA],
47
35
  });
48
36
 
49
37
  $.sectionStack.pop();
package/parser/parser.js CHANGED
@@ -110,7 +110,11 @@ export function xanoscriptParser(text, scheme, preTokenized = null) {
110
110
  parser.realtimeChannelDeclaration();
111
111
  return parser;
112
112
  case "run":
113
- parser.runDeclaration();
113
+ // run.job and run.service were removed from XanoScript with Xano Run. The platform refuses
114
+ // a document that still opens with one with this message, so report it here too, rather
115
+ // than the function parser's errors.
116
+ if (reportRemovedKeyword(lexResult.tokens)) return parser;
117
+ parser.functionDeclaration();
114
118
  return parser;
115
119
  case "table_trigger":
116
120
  parser.tableTriggerDeclaration();
@@ -137,6 +141,44 @@ export function xanoscriptParser(text, scheme, preTokenized = null) {
137
141
  }
138
142
  }
139
143
 
144
+ /** The top-level keywords XanoScript removed, with the platform's message for each. */
145
+ export const REMOVED_KEYWORDS = ["run.job", "run.service"];
146
+
147
+ /**
148
+ * The platform's error for a removed keyword, quoted as PHP's escapeshellarg quotes it.
149
+ * @param {string} keyword
150
+ */
151
+ export function removedKeywordMessage(keyword) {
152
+ return `'${keyword}' is no longer supported: Xano Run was removed from XanoScript. Remove this document.`;
153
+ }
154
+
155
+ /**
156
+ * Reports a document whose declaration opens with a removed keyword (`run.job foo {`), on the
157
+ * keyword. Returns whether it did.
158
+ * @param {import('chevrotain').IToken[]} tokens
159
+ */
160
+ function reportRemovedKeyword(tokens) {
161
+ const words = tokens.filter((t) => !/^\s*$/.test(t.image) && !t.image.startsWith("//"));
162
+ const [first, dot, second] = words;
163
+ if (!first || !dot || !second || dot.image !== ".") return false;
164
+ if (dot.startOffset !== first.endOffset + 1 || second.startOffset !== dot.endOffset + 1) return false;
165
+ const keyword = `${first.image}.${second.image}`;
166
+ if (!REMOVED_KEYWORDS.includes(keyword)) return false;
167
+ parser.addInvalidValueError(
168
+ {
169
+ image: keyword,
170
+ startOffset: first.startOffset,
171
+ endOffset: second.endOffset,
172
+ startLine: first.startLine,
173
+ startColumn: first.startColumn,
174
+ endLine: second.endLine,
175
+ endColumn: second.endColumn,
176
+ },
177
+ removedKeywordMessage(keyword),
178
+ );
179
+ return true;
180
+ }
181
+
140
182
  const SEPARATOR_IN_STRING =
141
183
  'A line that is only "---" separates documents in a multidoc push (xano workspace push, release push), even inside a string. Indent it to keep it in the text.';
142
184
 
@@ -1,7 +1,7 @@
1
1
  // Generated by scripts/gen-policy-catalogue.mjs from the platform's policy check catalogue
2
2
  // (`xano policy catalogue -o json`). Do not edit by hand: regenerate it.
3
3
  export default {
4
- "generated_at": "2026-10-13",
4
+ "generated_at": "2026-10-29",
5
5
  "items": [
6
6
  {
7
7
  "id": "db.output_fields_forbidden",
@@ -2504,6 +2504,7 @@ export default {
2504
2504
  "litellm",
2505
2505
  "openai",
2506
2506
  "openrouter",
2507
+ "xano-ai",
2507
2508
  "xano-free"
2508
2509
  ]
2509
2510
  }
@@ -43,11 +43,6 @@ import { realtimeChannelDeclaration } from "./realtime_channel_parser.js";
43
43
  import { realtimeServerDeclaration } from "./realtime_server_parser.js";
44
44
  import { realtimeServerTriggerDeclaration } from "./realtime_server_trigger_parser.js";
45
45
  import { realtimeTriggerDeclaration } from "./realtime_trigger_parser.js";
46
- import {
47
- runDeclaration,
48
- runJobClause,
49
- runServiceClause,
50
- } from "./run_parser.js";
51
46
  import { tableDeclaration } from "./table_parser.js";
52
47
  import { tableTriggerDeclaration } from "./table_trigger_parser.js";
53
48
  import { taskDeclaration } from "./task_parser.js";
@@ -158,9 +153,6 @@ export const register = ($) => {
158
153
  "realtimeChannelDeclaration",
159
154
  realtimeChannelDeclaration($)
160
155
  );
161
- $.runDeclaration = $.RULE("runDeclaration", runDeclaration($));
162
- $.runJobClause = $.RULE("runJobClause", runJobClause($));
163
- $.runServiceClause = $.RULE("runServiceClause", runServiceClause($));
164
156
  $.tableTriggerDeclaration = $.RULE(
165
157
  "tableTriggerDeclaration",
166
158
  tableTriggerDeclaration($)
package/lexer/run.js DELETED
@@ -1,37 +0,0 @@
1
- import { Identifier } from "./identifier.js";
2
- import { createTokenByName } from "./utils.js";
3
-
4
- // "run"
5
- export const RunToken = createTokenByName("run", {
6
- longer_alt: Identifier,
7
- categories: [Identifier],
8
- });
9
-
10
- // "job"
11
- export const JobToken = createTokenByName("job", {
12
- longer_alt: Identifier,
13
- categories: [Identifier],
14
- });
15
-
16
- // "service"
17
- export const ServiceToken = createTokenByName("service", {
18
- longer_alt: Identifier,
19
- categories: [Identifier],
20
- });
21
-
22
- export const RunTokens = [RunToken, JobToken, ServiceToken];
23
-
24
- /**
25
- * Maps a token name to a type
26
- * @param {string} token the token name
27
- */
28
- export function mapTokenToType(token) {
29
- switch (token) {
30
- case RunToken.name:
31
- case JobToken.name:
32
- case ServiceToken.name:
33
- return "keyword";
34
- default:
35
- return null;
36
- }
37
- }
@@ -1,72 +0,0 @@
1
- import { StringLiteral } from "../lexer/literal.js";
2
- import { JobToken, RunToken, ServiceToken } from "../lexer/run.js";
3
- import { DotToken, Identifier, NewlineToken } from "../lexer/tokens.js";
4
-
5
- export function runDeclaration($) {
6
- return () => {
7
- $.sectionStack.push("runDeclaration");
8
- // Allow leading comments and newlines before the run declaration
9
- $.SUBRULE($.optionalCommentBlockFn);
10
-
11
- $.CONSUME(RunToken); // "run"
12
- $.CONSUME(DotToken); // "."
13
-
14
- $.OR([
15
- { ALT: () => $.SUBRULE($.runJobClause) },
16
- { ALT: () => $.SUBRULE($.runServiceClause) },
17
- ]);
18
-
19
- $.MANY2(() => $.CONSUME2(NewlineToken)); // optional trailing newlines
20
- $.sectionStack.pop();
21
- };
22
- }
23
-
24
- export function runJobClause($) {
25
- return () => {
26
- const parent = $.CONSUME(JobToken); // "job"
27
-
28
- const nameToken = $.OR([
29
- { ALT: () => $.CONSUME(StringLiteral) },
30
- { ALT: () => $.CONSUME(Identifier) },
31
- ]);
32
- $.validateDeclarationName(nameToken, "job");
33
-
34
- $.SUBRULE($.schemaParseAttributeFn, {
35
- ARGS: [
36
- parent,
37
- {
38
- main: {
39
- name: "[string]",
40
- "input?": { "[string]?": "[constant]" },
41
- },
42
- "env?": ["[string]"],
43
- },
44
- ],
45
- });
46
- };
47
- }
48
-
49
- export function runServiceClause($) {
50
- return () => {
51
- const parent = $.CONSUME(ServiceToken); // "service"
52
-
53
- const nameToken = $.OR([
54
- { ALT: () => $.CONSUME(StringLiteral) },
55
- { ALT: () => $.CONSUME(Identifier) },
56
- ]);
57
- $.validateDeclarationName(nameToken, "service");
58
-
59
- $.SUBRULE($.schemaParseAttributeFn, {
60
- ARGS: [
61
- parent,
62
- {
63
- "pre?": {
64
- name: "[string]",
65
- input: { "[string]?": "[constant]" },
66
- },
67
- "env?": ["[string]"],
68
- },
69
- ],
70
- });
71
- };
72
- }