@xano/xanoscript-language-server 11.6.3 → 11.6.5
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/control.js +9 -0
- package/package.json +1 -1
- package/parser/function_parser.js +7 -1
- package/parser/function_parser.spec.js +13 -0
- package/parser/functions/varFn.spec.js +14 -0
- package/parser/generic/expressionFn.js +2 -0
- package/parser/query_parser.js +6 -1
- package/parser/query_parser.spec.js +13 -0
- package/parser/run_parser.js +1 -1
- package/parser/run_parser.spec.js +1 -1
package/lexer/control.js
CHANGED
|
@@ -302,6 +302,13 @@ export const PipeToken = createUniqToken({
|
|
|
302
302
|
label: "|",
|
|
303
303
|
});
|
|
304
304
|
|
|
305
|
+
// ..
|
|
306
|
+
export const DoubleDotToken = createUniqToken({
|
|
307
|
+
name: "DoubleDotToken",
|
|
308
|
+
pattern: /\.\./,
|
|
309
|
+
label: "..",
|
|
310
|
+
});
|
|
311
|
+
|
|
305
312
|
// ,
|
|
306
313
|
export const CommaToken = createUniqToken({
|
|
307
314
|
name: "CommaToken",
|
|
@@ -471,6 +478,7 @@ export const JsonSearchToken = createUniqToken({
|
|
|
471
478
|
});
|
|
472
479
|
|
|
473
480
|
export const ControlTokens = [
|
|
481
|
+
DoubleDotToken,
|
|
474
482
|
JsonNotBetweenToken,
|
|
475
483
|
JsonNotContainsToken,
|
|
476
484
|
JsonNotILikeToken,
|
|
@@ -626,6 +634,7 @@ export function mapTokenToType(token) {
|
|
|
626
634
|
case Question.name:
|
|
627
635
|
case ColonToken.name:
|
|
628
636
|
case PipeToken.name:
|
|
637
|
+
case DoubleDotToken.name:
|
|
629
638
|
case CommaToken.name:
|
|
630
639
|
return "punctuation";
|
|
631
640
|
default:
|
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@ import { LCurly, RCurly } from "../lexer/control.js";
|
|
|
3
3
|
import { FunctionToken } from "../lexer/function.js";
|
|
4
4
|
import { StringLiteral } from "../lexer/literal.js";
|
|
5
5
|
import { Identifier, NewlineToken } from "../lexer/tokens.js";
|
|
6
|
+
import { getVarName } from "./generic/utils.js";
|
|
6
7
|
|
|
7
8
|
export function functionDeclaration($) {
|
|
8
9
|
return () => {
|
|
@@ -22,10 +23,15 @@ export function functionDeclaration($) {
|
|
|
22
23
|
// Allow leading comments and newlines before the function declaration
|
|
23
24
|
$.SUBRULE($.optionalCommentBlockFn);
|
|
24
25
|
const parent = $.CONSUME(FunctionToken);
|
|
25
|
-
$.OR([
|
|
26
|
+
const nameToken = $.OR([
|
|
26
27
|
{ ALT: () => $.CONSUME(Identifier) },
|
|
27
28
|
{ ALT: () => $.CONSUME(StringLiteral) },
|
|
28
29
|
]);
|
|
30
|
+
|
|
31
|
+
if (nameToken?.image && getVarName(nameToken).startsWith("/")) {
|
|
32
|
+
$.addInvalidValueError(nameToken, "function name must not start with '/'");
|
|
33
|
+
}
|
|
34
|
+
|
|
29
35
|
$.CONSUME(LCurly); // "{"
|
|
30
36
|
$.MANY(() => {
|
|
31
37
|
$.AT_LEAST_ONE(() => $.CONSUME(NewlineToken)); // at least one new line
|
|
@@ -16,6 +16,19 @@ describe("function_parser", () => {
|
|
|
16
16
|
expect(parser.errors).to.be.empty;
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
+
it("should raise an error when a function name starts with /", () => {
|
|
20
|
+
const parser = xanoscriptParser(`function "/foo" {
|
|
21
|
+
input {
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
stack {
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
response = null
|
|
28
|
+
}`);
|
|
29
|
+
expect(parser.errors).to.not.be.empty;
|
|
30
|
+
});
|
|
31
|
+
|
|
19
32
|
it("should parse a function with a test", () => {
|
|
20
33
|
const parser = xanoscriptParser(`function foo {
|
|
21
34
|
input {
|
|
@@ -76,6 +76,20 @@ describe("varFn", () => {
|
|
|
76
76
|
expect(parser.errors).to.be.empty;
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
+
it("varFn allows range expressions", () => {
|
|
80
|
+
const parser = parse(`var $numbers {
|
|
81
|
+
value = (1..100)
|
|
82
|
+
}`);
|
|
83
|
+
expect(parser.errors).to.be.empty;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("varFn allows range expressions with variables", () => {
|
|
87
|
+
const parser = parse(`var $numbers {
|
|
88
|
+
value = ($var.start..$end_var)
|
|
89
|
+
}`);
|
|
90
|
+
expect(parser.errors).to.be.empty;
|
|
91
|
+
});
|
|
92
|
+
|
|
79
93
|
it("varFn accepts a system env variable", () => {
|
|
80
94
|
const parser = parse(`var $user {
|
|
81
95
|
value = $env.$remote_ip
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
AndTestToken,
|
|
4
4
|
ColonToken,
|
|
5
5
|
Divide,
|
|
6
|
+
DoubleDotToken,
|
|
6
7
|
GreaterThan,
|
|
7
8
|
GreaterThanOrEq,
|
|
8
9
|
IsEqual,
|
|
@@ -263,6 +264,7 @@ export function expressionTestFn($) {
|
|
|
263
264
|
{ ALT: () => $.CONSUME(Multiply) }, // "*"
|
|
264
265
|
{ ALT: () => $.CONSUME(Divide) }, // "/"
|
|
265
266
|
{ ALT: () => $.CONSUME(Modulus) }, // "%"
|
|
267
|
+
{ ALT: () => $.CONSUME(DoubleDotToken) }, // ".."
|
|
266
268
|
{ ALT: () => $.CONSUME(NullishCoalescingToken) }, // "??"
|
|
267
269
|
{ ALT: () => $.CONSUME(AndTestToken) }, // "&&"
|
|
268
270
|
{ ALT: () => $.CONSUME(OrTestToken) }, // "||"
|
package/parser/query_parser.js
CHANGED
|
@@ -37,10 +37,15 @@ export function queryDeclaration($) {
|
|
|
37
37
|
$.SUBRULE($.optionalCommentBlockFn);
|
|
38
38
|
|
|
39
39
|
const parent = $.CONSUME(QueryToken);
|
|
40
|
-
$.OR([
|
|
40
|
+
const nameToken = $.OR([
|
|
41
41
|
{ ALT: () => $.CONSUME(StringLiteral) }, // "foo/bar"
|
|
42
42
|
{ ALT: () => $.CONSUME(Identifier) }, // foo
|
|
43
43
|
]);
|
|
44
|
+
|
|
45
|
+
if (nameToken?.image && getVarName(nameToken).startsWith("/")) {
|
|
46
|
+
$.addInvalidValueError(nameToken, "query name must not start with '/'");
|
|
47
|
+
}
|
|
48
|
+
|
|
44
49
|
$.CONSUME(VerbToken);
|
|
45
50
|
$.CONSUME(EqualToken);
|
|
46
51
|
$.OR1([
|
|
@@ -16,6 +16,19 @@ describe("query_parser", () => {
|
|
|
16
16
|
expect(parser.errors).to.be.empty;
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
+
it("should raise an error when a query starts with /", () => {
|
|
20
|
+
const parser = xanoscriptParser(`query "/foo" verb=GET {
|
|
21
|
+
input {
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
stack {
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
response = null
|
|
28
|
+
}`);
|
|
29
|
+
expect(parser.errors).to.not.be.empty;
|
|
30
|
+
});
|
|
31
|
+
|
|
19
32
|
it("should accept an api_group", () => {
|
|
20
33
|
const parser = xanoscriptParser(`query foo verb=GET {
|
|
21
34
|
api_group = "Authentication";
|
package/parser/run_parser.js
CHANGED
|
@@ -5,7 +5,7 @@ import { xanoscriptParser } from "./parser.js";
|
|
|
5
5
|
describe("run", () => {
|
|
6
6
|
it("should parse a basic run.job", () => {
|
|
7
7
|
const parser = xanoscriptParser(`run.job "Average of values" {
|
|
8
|
-
main = {name: "avg_value"
|
|
8
|
+
main = {name: "avg_value"}
|
|
9
9
|
}`);
|
|
10
10
|
expect(parser.errors).to.be.empty;
|
|
11
11
|
});
|