@xano/xanoscript-language-server 11.5.0 → 11.6.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.
@@ -1,45 +0,0 @@
1
- import { CommaToken, LSquare, RSquare } from "../../lexer/control.js";
2
- import { StringLiteral } from "../../lexer/literal.js";
3
- import { NewlineToken } from "../../lexer/tokens.js";
4
-
5
- /**
6
- * Dynamicly raises error for missing and required attributes
7
- * @param {import('../base_parser.js').XanoBaseParser} $
8
- */
9
- export function arrayOfStringLiterals($) {
10
- return () => {
11
- $.CONSUME(LSquare); // "["
12
- $.OPTION(() => {
13
- $.OR([
14
- // multi line, each value on a new line
15
- // [
16
- // value
17
- // value2
18
- // ]
19
- {
20
- ALT: () => {
21
- $.CONSUME(NewlineToken);
22
- $.AT_LEAST_ONE(() => {
23
- $.CONSUME(StringLiteral);
24
- $.OPTION1(() => $.CONSUME(CommaToken)); // optional comma
25
- $.AT_LEAST_ONE1(() => $.CONSUME3(NewlineToken));
26
- });
27
- },
28
- },
29
- // one line, comma separated [ value, value2 ]
30
- {
31
- ALT: () => {
32
- $.AT_LEAST_ONE_SEP({
33
- SEP: CommaToken,
34
- DEF: () => {
35
- $.CONSUME1(StringLiteral);
36
- },
37
- });
38
- $.MANY(() => $.CONSUME2(NewlineToken));
39
- },
40
- },
41
- ]);
42
- });
43
- $.CONSUME(RSquare); // "]"
44
- };
45
- }
@@ -1,56 +0,0 @@
1
- import { expect } from "chai";
2
- import { describe, it } from "mocha";
3
- import { lexDocument } from "../../lexer/lexer.js";
4
- import { parser } from "../test_parser.js";
5
-
6
- function parse(inputText) {
7
- parser.reset();
8
- const lexResult = lexDocument(inputText);
9
- parser.input = lexResult.tokens;
10
- parser.arrayOfStringLiterals();
11
- return parser;
12
- }
13
-
14
- describe("arrayOfStringLiterals", () => {
15
- it("arrayOfStringLiterals accepts a single string ", () => {
16
- const parser = parse(`[ "true" ]`);
17
- expect(parser.errors).to.be.empty;
18
- });
19
-
20
- it("arrayOfStringLiterals can be empty ", () => {
21
- const parser = parse(`[]`);
22
- expect(parser.errors).to.be.empty;
23
- });
24
-
25
- it("arrayOfStringLiterals can be multilines without trailing commas", () => {
26
- const parser = parse(`[
27
- "foo"
28
- "bar"
29
- ]`);
30
- expect(parser.errors).to.be.empty;
31
- });
32
-
33
- it("arrayOfStringLiterals can be multilines with trailing commas ", () => {
34
- const parser = parse(`[
35
- "foo",
36
- "bar"
37
- ]`);
38
- expect(parser.errors).to.be.empty;
39
- });
40
-
41
- it("arrayOfStringLiterals can be compact ", () => {
42
- const parser = parse(`["foo","bar"]`);
43
- expect(parser.errors).to.be.empty;
44
- });
45
-
46
- it("arrayOfStringLiterals cannot contain a non string ", () => {
47
- let parser = parse(`[4]`);
48
- expect(parser.errors).to.not.be.empty;
49
-
50
- parser = parse(`[true]`);
51
- expect(parser.errors).to.not.be.empty;
52
-
53
- parser = parse(`["test", 4]`);
54
- expect(parser.errors).to.not.be.empty;
55
- });
56
- });
@@ -1,243 +0,0 @@
1
- import { MismatchedTokenException } from "chevrotain";
2
- import { ColonToken, CommaToken, LCurly, RCurly } from "../../lexer/control.js";
3
- import { StringLiteral } from "../../lexer/literal.js";
4
- import { MultiLineStringToken } from "../../lexer/multiline.js";
5
- import { Identifier, NewlineToken } from "../../lexer/tokens.js";
6
- import { getVarName } from "./utils.js";
7
-
8
- const DEFAULT_OPTIONS = {
9
- allowDuplicates: [],
10
- allowQueryExpression: false,
11
- recursive: [],
12
- recursiveArray: [],
13
- allowVariables: true,
14
- types: {},
15
- };
16
-
17
- /**
18
- * Dynamicly raises error for missing and required attributes
19
- * @param {import('../base_parser.js').XanoBaseParser} $
20
- */
21
- export function objectAttrReq($) {
22
- /**
23
- * @param {import('chevrotain').IToken} parent
24
- * @param {string[]} required the required attributes
25
- * @param {string[]} optional the optional attributes
26
- * @param {Object} options additional options
27
- * @param {string[]} options.allowDuplicates attributes that are allowed to be duplicated
28
- * @param {string[]} options.allowQueryExpression attributes that are allowed to be duplicated
29
- * @param {string[]} options.recursive the same rules applies to sub-objects deeper in the tree
30
- * @param {string[]} options.recursiveArray the same rules applies to sub-arrays deeper in the tree
31
- * @param {boolean} options.allowVariables whether to allow variables as values
32
- * @param {Object} options.types a map of attribute names to their expected types (string, number, boolean)
33
- * if the type is not specified, any value is allowed
34
- **/
35
- return (parent, required, optional, options = {}) => {
36
- // setup basic defaults
37
- required = required || [];
38
- optional = optional || [];
39
-
40
- options = {
41
- ...DEFAULT_OPTIONS,
42
- ...options,
43
- };
44
-
45
- const definedAttributes = [];
46
- const allowedAttributes = [...required, ...optional];
47
- let identifier;
48
-
49
- $.CONSUME(LCurly); // "{"
50
- $.OPTION(() => {
51
- $.OR([
52
- {
53
- // one line, comma separated { key: value, key2: value2 }
54
- ALT: () => {
55
- $.AT_LEAST_ONE_SEP({
56
- SEP: CommaToken,
57
- DEF: () => {
58
- identifier = $.OR1([
59
- { ALT: () => $.CONSUME(Identifier) }, // key
60
- { ALT: () => $.CONSUME(StringLiteral) }, // "value"
61
- ]);
62
- definedAttributes.push(identifier);
63
- const varName = getVarName(identifier);
64
- $.CONSUME(ColonToken);
65
- if (options.recursive.includes(varName)) {
66
- $.SUBRULE($.objectAttrReq, {
67
- ARGS: [identifier, required, optional, options],
68
- });
69
- } else if (options.recursiveArray.includes(varName)) {
70
- $.SUBRULE($.arrayOfObjectAttrReq, {
71
- ARGS: [identifier, required, optional, options],
72
- });
73
- } else {
74
- const varType = options.types[varName];
75
- if (typeof varType === "function") {
76
- varType.call(null, $, identifier); // custom function handler
77
- } else if (Array.isArray(varType)) {
78
- // Treat array as enum - value must be one of the array elements
79
- const stringToken = $.CONSUME3(StringLiteral);
80
- const providedValue = getVarName(stringToken);
81
-
82
- // Check if the provided value is in the allowed array
83
- if (!varType.includes(providedValue)) {
84
- $.addMissingError(
85
- stringToken,
86
- `Invalid value "${providedValue}". Must be one of: ${varType
87
- .map((v) => `"${v}"`)
88
- .join(", ")}`
89
- );
90
- }
91
- } else {
92
- $.OR4([
93
- {
94
- GATE: () => varType === "boolean",
95
- ALT: () => $.SUBRULE($.booleanValue), // boolean
96
- },
97
- {
98
- GATE: () => varType === "number",
99
- ALT: () => $.SUBRULE($.numberValue), // number
100
- },
101
- {
102
- GATE: () => varType === "string",
103
- ALT: () => $.CONSUME3(StringLiteral), // "..."
104
- },
105
- {
106
- GATE: () => varType === "object",
107
- ALT: () =>
108
- $.SUBRULE1($.objectWithAttributes, {
109
- ARGS: [options],
110
- }),
111
- },
112
- {
113
- GATE: () => !varType,
114
- ALT: () =>
115
- $.SUBRULE($.expressionFn, {
116
- ARGS: [identifier, options],
117
- }), // anything goes
118
- },
119
- ]);
120
- }
121
- }
122
- },
123
- });
124
- },
125
- },
126
- {
127
- // multi line, each key value pair on a new line
128
- // {
129
- // key: value
130
- // key2: value2
131
- // }
132
- ALT: () => {
133
- $.CONSUME(NewlineToken);
134
- $.AT_LEAST_ONE(() => {
135
- const identifier = $.OR2([
136
- { ALT: () => $.CONSUME2(Identifier) }, // key
137
- { ALT: () => $.CONSUME2(StringLiteral) }, // "other key"
138
- ]);
139
- definedAttributes.push(identifier);
140
- $.CONSUME1(ColonToken);
141
- const varName = getVarName(identifier);
142
- if (options.recursive.includes(varName)) {
143
- $.SUBRULE($.objectAttrReq, {
144
- ARGS: [identifier, required, optional, options],
145
- });
146
- } else if (options.recursiveArray.includes(varName)) {
147
- $.SUBRULE($.arrayOfObjectAttrReq, {
148
- ARGS: [identifier, required, optional, options],
149
- });
150
- } else {
151
- const varType = options.types[varName];
152
- if (typeof varType === "function") {
153
- varType.call(null, $, identifier); // custom function handler
154
- } else if (Array.isArray(varType)) {
155
- // Treat array as enum - value must be one of the array elements
156
- const stringToken = $.CONSUME3(StringLiteral);
157
- const providedValue = getVarName(stringToken);
158
-
159
- // Check if the provided value is in the allowed array
160
- if (!varType.includes(providedValue)) {
161
- $.SAVE_ERROR(
162
- new MismatchedTokenException(
163
- `Invalid value "${providedValue}". Must be one of: ${varType
164
- .map((v) => `"${v}"`)
165
- .join(", ")}`,
166
- stringToken,
167
- stringToken
168
- )
169
- );
170
- }
171
- } else {
172
- $.OR3([
173
- {
174
- GATE: () => varType === "boolean",
175
- ALT: () => $.SUBRULE1($.booleanValue), // boolean
176
- },
177
- {
178
- GATE: () => varType === "number",
179
- ALT: () => $.SUBRULE1($.numberValue), // number
180
- },
181
- {
182
- GATE: () => varType === "string",
183
- ALT: () =>
184
- $.OR5([
185
- { ALT: () => $.CONSUME1(StringLiteral) }, // "..."
186
- { ALT: () => $.CONSUME(MultiLineStringToken) },
187
- ]),
188
- },
189
- {
190
- GATE: () => varType === "object",
191
- ALT: () =>
192
- $.SUBRULE($.objectWithAttributes, { ARGS: [options] }),
193
- },
194
- {
195
- GATE: () => !varType,
196
- ALT: () =>
197
- $.SUBRULE1($.expressionFn, {
198
- ARGS: [identifier, options],
199
- }), // anything goes
200
- },
201
- ]);
202
- }
203
- }
204
- $.OPTION1(() => $.CONSUME(CommaToken)); // ","
205
- $.AT_LEAST_ONE1(() => $.CONSUME1(NewlineToken));
206
- });
207
- },
208
- },
209
- ]);
210
- });
211
- $.CONSUME(RCurly); // "}"
212
-
213
- // detects duplicate attributes
214
- const duplicateAttributes = definedAttributes.filter(
215
- (token, index) =>
216
- !options.allowDuplicates.includes(getVarName(token)) &&
217
- definedAttributes.findIndex(
218
- (t) => getVarName(t) === getVarName(token)
219
- ) !== index
220
- );
221
-
222
- for (const token of duplicateAttributes) {
223
- $.addDuplicateAttributeError(token);
224
- }
225
-
226
- // report any illegal attributes
227
- const illegalAttributes = definedAttributes.filter(
228
- (token) => !allowedAttributes.includes(getVarName(token))
229
- );
230
- for (const token of illegalAttributes) {
231
- $.addIllegalAttributeError(token);
232
- }
233
-
234
- // report any missing attributes
235
- const definedAttrNames = definedAttributes.map(getVarName);
236
- const missingAttributes = required.filter(
237
- (reqAttrName) => !definedAttrNames.includes(reqAttrName)
238
- );
239
- if (missingAttributes.length > 0) {
240
- $.addMissingAttributeError(parent, missingAttributes);
241
- }
242
- };
243
- }