@xano/xanoscript-language-server 12.16.0 → 12.16.2

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.
@@ -11,10 +11,14 @@ export const RealtimeServerTriggerToken = createTokenByName(
11
11
  );
12
12
 
13
13
  // "realtime_server" (parent-reference keyword used by realtimeServerClause).
14
- // longer_alt points at the trigger token so `realtime_server_trigger` wins
15
- // over the shorter `realtime_server` prefix.
14
+ // longer_alt lists the trigger token so `realtime_server_trigger` wins over the
15
+ // shorter `realtime_server` prefix, AND Identifier so a name that merely EXTENDS
16
+ // the keyword (e.g. `realtime_server_0`, the default scaffold name) tokenizes as
17
+ // one identifier instead of keyword + leftover `_0` (DEV-7582). longer_alt is not
18
+ // transitive, so Identifier must be listed here directly — matching the
19
+ // [ServerDetailsToken, Identifier] precedent in channel.js.
16
20
  export const RealtimeServerToken = createTokenByName("realtime_server", {
17
- longer_alt: RealtimeServerTriggerToken,
21
+ longer_alt: [RealtimeServerTriggerToken, Identifier],
18
22
  categories: [Identifier], // could also be an identifier
19
23
  });
20
24
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xano/xanoscript-language-server",
3
- "version": "12.16.0",
3
+ "version": "12.16.2",
4
4
  "description": "Language Server Protocol implementation for XanoScript",
5
5
  "type": "module",
6
6
  "main": "server.js",
@@ -1,8 +1,22 @@
1
1
  import { EqualToken } from "../../lexer/control.js";
2
+ import { IntegerLiteral } from "../../lexer/literal.js";
2
3
  import { HistoryToken } from "../../lexer/tokens.js";
3
4
 
4
5
  /**
5
6
  * Parses the history clause.
7
+ *
8
+ * `history` mirrors the backend serializer (cloud-client
9
+ * helper/script/transform via `Transform::onSchemaRequestHistory`): the value is
10
+ * `false` (disabled), `"inherit"` (hand-authored sentinel), `"all"` (unbounded),
11
+ * or ANY non-negative integer message limit — not a fixed set of magic numbers.
12
+ * It is split across two OR branches because `schemaParseEnumFn` refuses an enum
13
+ * that mixes constants (`false`/`"inherit"`/`"all"`) with a generic numeric type:
14
+ * an integer literal is consumed directly, every other value by the sentinel
15
+ * enum (which keeps emitting the existing "must be one of …" error). The limit
16
+ * is an integer message count, so a float is intentionally NOT accepted.
17
+ * `IGNORE_AMBIGUITIES` steers an integer literal to the number branch, since both
18
+ * branches can begin with one.
19
+ *
6
20
  * @param {import('../base_parser.js').XanoBaseParser} $
7
21
  */
8
22
  export function historyClause($) {
@@ -10,8 +24,19 @@ export function historyClause($) {
10
24
  $.sectionStack.push("historyClause");
11
25
  const parent = $.CONSUME(HistoryToken); // "history"
12
26
  $.CONSUME(EqualToken); // "="
13
- $.SUBRULE($.schemaParseEnumFn, {
14
- ARGS: [parent, [false, "inherit", 0, 10, 100, 1000, 10000, "all"]],
27
+ $.OR({
28
+ IGNORE_AMBIGUITIES: true,
29
+ DEF: [
30
+ // any non-negative integer message limit (e.g. 50, 100, 250)
31
+ { ALT: () => $.CONSUME(IntegerLiteral) },
32
+ // the non-numeric sentinels: false | "inherit" | "all"
33
+ {
34
+ ALT: () =>
35
+ $.SUBRULE($.schemaParseEnumFn, {
36
+ ARGS: [parent, [false, "inherit", "all"]],
37
+ }),
38
+ },
39
+ ],
15
40
  });
16
41
 
17
42
  $.sectionStack.pop();
@@ -10,6 +10,8 @@ export function messageDeclaration($) {
10
10
  let hasChannel = false;
11
11
  let hasDeliverTo = false;
12
12
  let hasDescription = false;
13
+ let hasDocs = false;
14
+ let hasActive = false;
13
15
  let hasGuid = false;
14
16
  let hasHistory = false;
15
17
  let hasInput = false;
@@ -79,6 +81,24 @@ export function messageDeclaration($) {
79
81
  $.SUBRULE($.descriptionFieldAttribute);
80
82
  },
81
83
  },
84
+ {
85
+ // backend Message.php `encode()` emits `docs = "..."` for a
86
+ // documented message; round-tripped by `decode()`. See DEV-7620.
87
+ GATE: () => !hasDocs,
88
+ ALT: () => {
89
+ hasDocs = true;
90
+ $.SUBRULE($.docsFieldAttribute);
91
+ },
92
+ },
93
+ {
94
+ // backend Message.php `encode()` emits `active = false` for a
95
+ // disabled message; mirrors the sibling `channel` declaration.
96
+ GATE: () => !hasActive,
97
+ ALT: () => {
98
+ hasActive = true;
99
+ $.SUBRULE($.activeFieldAttribute);
100
+ },
101
+ },
82
102
  {
83
103
  GATE: () => !hasGuid,
84
104
  ALT: () => {
@@ -147,26 +167,12 @@ export function messageDeclaration($) {
147
167
  );
148
168
  }
149
169
 
150
- if (!hasInput) {
151
- $.addMissingError(
152
- parent,
153
- `{} ${nameToken.image} is missing an input clause`,
154
- );
155
- }
156
-
157
- if (!hasStack) {
158
- $.addMissingError(
159
- parent,
160
- `{} ${nameToken.image} is missing a stack clause`,
161
- );
162
- }
163
-
164
- if (!hasResponse) {
165
- $.addMissingError(
166
- parent,
167
- `{} ${nameToken.image} is missing a response clause`,
168
- );
169
- }
170
+ // input/stack/response are OPTIONAL on a message: a realtime v2 message is
171
+ // created config-only (its Stack is generated server-side after save), so a
172
+ // scaffold carrying only realtime_server/channel/deliver_to/description/history
173
+ // must be diagnostic-clean. Mirrors channel_parser.js (requires realtime_server
174
+ // only). When present, these clauses are still fully parsed + validated by the
175
+ // OR2 alternatives above.
170
176
 
171
177
  $.MANY1(() => $.CONSUME1(NewlineToken)); // optional new line
172
178
  $.CONSUME(RCurly); // "}"
@@ -32,7 +32,11 @@ export function realtimeChannelDeclaration($) {
32
32
  "settings?": {
33
33
  anonymous_clients: "[boolean]",
34
34
  nested_channels: "[boolean]",
35
- message_history: [0, 25, 50, 100, 250, 1000],
35
+ // The CLI pull emits `message_history: history ?? 0` (an arbitrary
36
+ // integer — see cloud-client RealtimeChannel.php `onSettings`), so
37
+ // accept any numeric value rather than a fixed enum. Kept typed
38
+ // ("[number]") so a non-numeric value still surfaces a diagnostic.
39
+ message_history: "[number]",
36
40
  auth_channel: "[boolean]",
37
41
  presence: "[boolean]",
38
42
  },