@xano/xanoscript-language-server 12.11.0 → 12.13.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/README.md CHANGED
@@ -62,7 +62,7 @@ The parser supports the following XanoScript constructs:
62
62
  | `realtime_server` | Realtime v2 server definitions (the container that owns channels) |
63
63
  | `channel` | Realtime v2 channel definitions (path templates) |
64
64
  | `message` | Realtime v2 channel message handlers |
65
- | `channel_trigger` | Realtime v2 channel lifecycle triggers (join/leave) |
65
+ | `channel_trigger` | Realtime v2 channel triggers (join/leave lifecycle, deliver per-recipient) |
66
66
  | `realtime_server_trigger` | Realtime v2 connection lifecycle triggers (connect/disconnect) |
67
67
  | `tool` | Tool definitions |
68
68
  | `workspace` | Workspace definitions |
package/lexer/realtime.js CHANGED
@@ -13,12 +13,23 @@ export const GetSessionToken = createTokenByName("get_session", {
13
13
  categories: [Identifier],
14
14
  });
15
15
 
16
- export const RealtimeStatementTokens = [RealtimeToken, GetSessionToken];
16
+ // publish
17
+ export const PublishToken = createTokenByName("publish", {
18
+ longer_alt: Identifier,
19
+ categories: [Identifier],
20
+ });
21
+
22
+ export const RealtimeStatementTokens = [
23
+ RealtimeToken,
24
+ GetSessionToken,
25
+ PublishToken,
26
+ ];
17
27
 
18
28
  export function mapTokenToType(token) {
19
29
  switch (token) {
20
30
  case RealtimeToken.name:
21
31
  case GetSessionToken.name:
32
+ case PublishToken.name:
22
33
  return "function";
23
34
  default:
24
35
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xano/xanoscript-language-server",
3
- "version": "12.11.0",
3
+ "version": "12.13.0",
4
4
  "description": "Language Server Protocol implementation for XanoScript",
5
5
  "type": "module",
6
6
  "main": "server.js",
@@ -4,7 +4,6 @@ import {
4
4
  DeliveryToken,
5
5
  PublishToken,
6
6
  RateLimitToken,
7
- ServerToken,
8
7
  } from "../lexer/channel.js";
9
8
  import { ChannelToken } from "../lexer/columns.js";
10
9
  import { EqualToken, LCurly, RCurly } from "../lexer/control.js";
@@ -46,12 +45,7 @@ export function channelDeclaration($) {
46
45
  GATE: () => !hasServer,
47
46
  ALT: () => {
48
47
  hasServer = true;
49
- const subParent = $.CONSUME(ServerToken); // "server"
50
- $.CONSUME(EqualToken); // "="
51
- const result = $.CONSUME2(StringLiteral); // "server_name"
52
- if (result.image === `""`) {
53
- $.addMissingError(subParent, "server cannot be empty");
54
- }
48
+ $.SUBRULE($.realtimeServerClause);
55
49
  },
56
50
  },
57
51
  {
@@ -178,7 +172,7 @@ export function channelDeclaration($) {
178
172
  });
179
173
 
180
174
  if (!hasServer) {
181
- $.addMissingError(parent, "{} is missing a server clause");
175
+ $.addMissingError(parent, "{} is missing a realtime_server clause");
182
176
  }
183
177
 
184
178
  $.MANY1(() => $.CONSUME1(NewlineToken)); // optional new line
@@ -1,4 +1,3 @@
1
- import { ServerToken } from "../lexer/channel.js";
2
1
  import { ChannelTriggerToken } from "../lexer/channel_trigger.js";
3
2
  import { EqualToken, LCurly, RCurly } from "../lexer/control.js";
4
3
  import { StringLiteral } from "../lexer/literal.js";
@@ -50,6 +49,7 @@ export function channelTriggerDeclaration($) {
50
49
  {
51
50
  "join?": "[boolean]",
52
51
  "leave?": "[boolean]",
52
+ "deliver?": "[boolean]",
53
53
  },
54
54
  ],
55
55
  });
@@ -68,12 +68,7 @@ export function channelTriggerDeclaration($) {
68
68
  GATE: () => !hasServer,
69
69
  ALT: () => {
70
70
  hasServer = true;
71
- const subParent = $.CONSUME(ServerToken); // "server"
72
- $.CONSUME3(EqualToken); // "="
73
- const result = $.CONSUME2(StringLiteral); // "server_name"
74
- if (result.image === `""`) {
75
- $.addMissingError(subParent, "server cannot be empty");
76
- }
71
+ $.SUBRULE($.realtimeServerClause);
77
72
  },
78
73
  },
79
74
  {
@@ -136,7 +131,7 @@ export function channelTriggerDeclaration($) {
136
131
  });
137
132
 
138
133
  if (!hasServer) {
139
- $.addMissingError(parent, "{} is missing a server clause");
134
+ $.addMissingError(parent, "{} is missing a realtime_server clause");
140
135
  }
141
136
 
142
137
  if (!hasChannel) {
@@ -0,0 +1,39 @@
1
+ import { PublishToken } from "../../../lexer/realtime.js";
2
+
3
+ // realtime.publish {
4
+ // realtime_server = "main"
5
+ // channel = "rooms/42"
6
+ // message = "chat" // optional — becomes the delivered frame's `type`
7
+ // data = $payload
8
+ // auth_table = "user" // optional — asserted identity (attribution only)
9
+ // auth_id = $auth.id // optional
10
+ // }
11
+ //
12
+ // Injects a server-authored event onto a realtime v2 channel (cloud-client
13
+ // mvp:realtime_publish). `realtime_server` + `channel` + `data` are required;
14
+ // `message`/`auth_table`/`auth_id` are optional. Flat attrs (the PHP transform
15
+ // maps auth_table/auth_id into the nested context.auth.{dbo_id,row_id} shape).
16
+ // Unlike realtime.get_session it has NO `as $var` binding.
17
+
18
+ /**
19
+ * @param {import('../../base_parser.js').XanoBaseParser} $
20
+ */
21
+ export function realtimePublishFn($) {
22
+ const requiredAttrs = ["realtime_server", "channel", "data"];
23
+ const optionalAttrs = [
24
+ "message",
25
+ "auth_table",
26
+ "auth_id",
27
+ "description",
28
+ "disabled",
29
+ ];
30
+
31
+ return () => {
32
+ $.sectionStack.push("realtimePublishFn");
33
+ const fnToken = $.CONSUME(PublishToken); // "publish"
34
+ $.SUBRULE($.functionAttrReq, {
35
+ ARGS: [fnToken, requiredAttrs, optionalAttrs],
36
+ });
37
+ $.sectionStack.pop();
38
+ };
39
+ }
@@ -1,4 +1,5 @@
1
1
  import { realtimeGetSessionFn } from "./realtimeGetSessionFn.js";
2
+ import { realtimePublishFn } from "./realtimePublishFn.js";
2
3
 
3
4
  /**
4
5
  * Registers all the parsers in this folder
@@ -9,4 +10,5 @@ export const register = ($) => {
9
10
  "realtimeGetSessionFn",
10
11
  realtimeGetSessionFn($),
11
12
  );
13
+ $.realtimePublishFn = $.RULE("realtimePublishFn", realtimePublishFn($));
12
14
  };
@@ -12,6 +12,7 @@ export function realtimeFn($) {
12
12
  $.CONSUME(DotToken); // "."
13
13
  $.OR([
14
14
  { ALT: () => $.SUBRULE($.realtimeGetSessionFn) }, // "realtime.get_session"
15
+ { ALT: () => $.SUBRULE($.realtimePublishFn) }, // "realtime.publish"
15
16
  ]);
16
17
  $.sectionStack.pop();
17
18
  };
@@ -1,4 +1,3 @@
1
- import { ServerToken } from "../lexer/channel.js";
2
1
  import { EqualToken, LCurly, RCurly } from "../lexer/control.js";
3
2
  import { StringLiteral } from "../lexer/literal.js";
4
3
  import { DeliverToToken, MessageToken } from "../lexer/message.js";
@@ -48,12 +47,7 @@ export function messageDeclaration($) {
48
47
  GATE: () => !hasServer,
49
48
  ALT: () => {
50
49
  hasServer = true;
51
- const subParent = $.CONSUME(ServerToken); // "server"
52
- $.CONSUME3(EqualToken); // "="
53
- const result = $.CONSUME3(StringLiteral); // "server_name"
54
- if (result.image === `""`) {
55
- $.addMissingError(subParent, "server cannot be empty");
56
- }
50
+ $.SUBRULE($.realtimeServerClause);
57
51
  },
58
52
  },
59
53
  {
@@ -142,7 +136,7 @@ export function messageDeclaration($) {
142
136
  if (!hasServer) {
143
137
  $.addMissingError(
144
138
  parent,
145
- `{} ${nameToken.image} is missing a server clause`,
139
+ `{} ${nameToken.image} is missing a realtime_server clause`,
146
140
  );
147
141
  }
148
142