@witchcraft/expressit 0.3.0 → 0.4.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/dist/Lexer.js +14 -19
- package/dist/Parser.js +104 -115
- package/dist/ast/builders/array.js +7 -8
- package/dist/ast/builders/condition.js +1 -1
- package/dist/ast/builders/expression.js +4 -4
- package/dist/ast/builders/group.js +8 -9
- package/dist/ast/builders/token.js +1 -1
- package/dist/ast/builders/variable.js +5 -6
- package/dist/ast/createConditionNode.js +1 -2
- package/dist/ast/handlers.js +22 -25
- package/dist/examples/ParserWithSqlSupport.js +22 -30
- package/dist/examples/ShortcutContextParser.js +2 -5
- package/dist/internal/ExpressitError.js +7 -10
- package/dist/internal/checkParserOpts.js +10 -11
- package/dist/internal/escapeVariableOrPrefix.js +1 -1
- package/dist/internal/parseParserOptions.js +3 -4
- package/dist/package.json.js +1 -1
- package/dist/types/ast.js +1 -1
- package/dist/types/autocomplete.js +1 -1
- package/dist/types/errors.js +1 -1
- package/dist/utils/extractTokens.js +4 -5
- package/dist/utils/generateParentsMap.js +7 -8
- package/dist/utils/getCursorInfo.js +3 -3
- package/dist/utils/getOppositeDelimiter.js +1 -1
- package/dist/utils/getSurroundingErrors.js +2 -3
- package/dist/utils/isBracket.js +1 -1
- package/dist/utils/isDelimiter.js +1 -1
- package/dist/utils/isNode.js +1 -1
- package/dist/utils/isParen.js +1 -1
- package/dist/utils/isQuote.js +1 -1
- package/dist/utils/isToken.js +1 -1
- package/dist/utils/prettyAst.js +10 -11
- package/package.json +20 -33
- package/src/Lexer.ts +3 -3
- package/src/Parser.ts +7 -7
- package/src/ast/builders/token.ts +1 -1
- package/src/examples/ParserWithSqlSupport.ts +1 -1
- package/src/internal/ExpressitError.ts +3 -3
- package/src/internal/checkParserOpts.ts +2 -2
- package/src/internal/escapeVariableOrPrefix.ts +1 -1
- package/src/types/ast.ts +1 -1
- package/src/types/autocomplete.ts +1 -1
- package/src/types/errors.ts +1 -1
- package/src/utils/extractTokens.ts +1 -1
- package/src/utils/getCursorInfo.ts +2 -2
- package/src/utils/getOppositeDelimiter.ts +1 -1
- package/src/utils/prettyAst.ts +3 -3
package/dist/Lexer.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { enumFromArray } from "@alanscodelog/utils/enumFromArray.js";
|
|
5
|
-
import { isBlank } from "@alanscodelog/utils/isBlank.js";
|
|
6
|
-
import { pushIfNotIn } from "@alanscodelog/utils/pushIfNotIn.js";
|
|
1
|
+
import { enumFromArray } from "@alanscodelog/utils/enumFromArray";
|
|
2
|
+
import { isBlank } from "@alanscodelog/utils/isBlank";
|
|
3
|
+
import { pushIfNotIn } from "@alanscodelog/utils/pushIfNotIn";
|
|
7
4
|
import { checkParserOpts } from "./internal/checkParserOpts.js";
|
|
8
5
|
import { parseParserOptions } from "./internal/parseParserOptions.js";
|
|
9
6
|
const regexFlags = /^[a-zA-Z]+/;
|
|
@@ -104,12 +101,12 @@ function matchSymbol(symbols) {
|
|
|
104
101
|
};
|
|
105
102
|
}
|
|
106
103
|
class Lexer {
|
|
104
|
+
symbols;
|
|
105
|
+
$;
|
|
106
|
+
$categories;
|
|
107
|
+
branches;
|
|
108
|
+
opts;
|
|
107
109
|
constructor(opts = {}) {
|
|
108
|
-
__publicField(this, "symbols");
|
|
109
|
-
__publicField(this, "$");
|
|
110
|
-
__publicField(this, "$categories");
|
|
111
|
-
__publicField(this, "branches");
|
|
112
|
-
__publicField(this, "opts");
|
|
113
110
|
this.opts = parseParserOptions(opts);
|
|
114
111
|
checkParserOpts(this.opts);
|
|
115
112
|
this.symbols = this.calculateSymbolInfo();
|
|
@@ -119,7 +116,6 @@ class Lexer {
|
|
|
119
116
|
this.branches = this.createModeBranches();
|
|
120
117
|
}
|
|
121
118
|
calculateSymbolInfo() {
|
|
122
|
-
var _a;
|
|
123
119
|
const opts = this.opts;
|
|
124
120
|
const symOrs = opts.keywords.or.filter((_) => _.isSymbol).map((_) => _.value);
|
|
125
121
|
const symAnds = opts.keywords.and.filter((_) => _.isSymbol).map((_) => _.value);
|
|
@@ -146,7 +142,7 @@ class Lexer {
|
|
|
146
142
|
wordNots: wordNots.sort((a, b) => b.length - a.length),
|
|
147
143
|
all: syms.sort((a, b) => b.length - a.length)
|
|
148
144
|
};
|
|
149
|
-
const expandedSepAlsoCustom =
|
|
145
|
+
const expandedSepAlsoCustom = opts.customPropertyOperators?.includes(opts.expandedPropertySeparator) ?? false;
|
|
150
146
|
let customOpAlsoNegation = false;
|
|
151
147
|
if (symbols.symNots.length > 0) {
|
|
152
148
|
for (const op of opts.customPropertyOperators ?? []) {
|
|
@@ -162,7 +158,6 @@ class Lexer {
|
|
|
162
158
|
}
|
|
163
159
|
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
164
160
|
createTokens() {
|
|
165
|
-
var _a;
|
|
166
161
|
const opts = this.opts;
|
|
167
162
|
const symbols = this.symbols;
|
|
168
163
|
const $ = {
|
|
@@ -213,7 +208,7 @@ class Lexer {
|
|
|
213
208
|
prevEscaped = false;
|
|
214
209
|
}
|
|
215
210
|
} else {
|
|
216
|
-
prevEscaped
|
|
211
|
+
prevEscaped &&= false;
|
|
217
212
|
}
|
|
218
213
|
end++;
|
|
219
214
|
c = input[end];
|
|
@@ -231,7 +226,7 @@ class Lexer {
|
|
|
231
226
|
* Go back to main instead of searching for the quoted value
|
|
232
227
|
* Otherwise input like 'a'b'c' will trap us in a MAIN <=> NOT_SINGLE loop.
|
|
233
228
|
*/
|
|
234
|
-
|
|
229
|
+
previous?.type === $T.VALUE_NOT_SINGLE || previous?.type === $T.VALUE_UNQUOTED
|
|
235
230
|
) {
|
|
236
231
|
if (mode.startsWith(BRACKET_PREFIX)) return MODE.BRACKET_MAIN;
|
|
237
232
|
return MODE.MAIN;
|
|
@@ -251,7 +246,7 @@ class Lexer {
|
|
|
251
246
|
[$T.QUOTE_DOUBLE]: createTokenType($T.QUOTE_DOUBLE, {
|
|
252
247
|
push: (mode, tokens) => {
|
|
253
248
|
const previous = tokens[tokens.length - 2];
|
|
254
|
-
if (
|
|
249
|
+
if (previous?.type === $T.VALUE_NOT_DOUBLE || previous?.type === $T.VALUE_UNQUOTED) {
|
|
255
250
|
if (mode.startsWith(BRACKET_PREFIX)) return MODE.BRACKET_MAIN;
|
|
256
251
|
return MODE.MAIN;
|
|
257
252
|
}
|
|
@@ -270,7 +265,7 @@ class Lexer {
|
|
|
270
265
|
[$T.QUOTE_BACKTICK]: createTokenType($T.QUOTE_BACKTICK, {
|
|
271
266
|
push: (mode, tokens) => {
|
|
272
267
|
const previous = tokens[tokens.length - 2];
|
|
273
|
-
if (
|
|
268
|
+
if (previous?.type === $T.VALUE_NOT_BACKTICK || previous?.type === $T.VALUE_UNQUOTED) {
|
|
274
269
|
if (mode.startsWith(BRACKET_PREFIX)) return MODE.BRACKET_MAIN;
|
|
275
270
|
return MODE.MAIN;
|
|
276
271
|
}
|
|
@@ -372,7 +367,7 @@ class Lexer {
|
|
|
372
367
|
}
|
|
373
368
|
})
|
|
374
369
|
} : {},
|
|
375
|
-
...(
|
|
370
|
+
...(opts.customPropertyOperators?.length ?? 0) > 0 && !symbols.customOpAlsoNegation ? {
|
|
376
371
|
[$T.CUSTOM_PROP_OP]: createTokenType($T.CUSTOM_PROP_OP, {
|
|
377
372
|
matches: (_c, input, start) => {
|
|
378
373
|
for (const op of opts.customPropertyOperators ?? []) {
|
package/dist/Parser.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { isWhitespace } from "@alanscodelog/utils/isWhitespace.js";
|
|
8
|
-
import { setReadOnly } from "@alanscodelog/utils/setReadOnly.js";
|
|
9
|
-
import { unreachable } from "@alanscodelog/utils/unreachable.js";
|
|
1
|
+
import { get } from "@alanscodelog/utils/get";
|
|
2
|
+
import { insert } from "@alanscodelog/utils/insert";
|
|
3
|
+
import { isArray } from "@alanscodelog/utils/isArray";
|
|
4
|
+
import { isWhitespace } from "@alanscodelog/utils/isWhitespace";
|
|
5
|
+
import { setReadOnly } from "@alanscodelog/utils/setReadOnly";
|
|
6
|
+
import { unreachable } from "@alanscodelog/utils/unreachable";
|
|
10
7
|
import { pos } from "./ast/builders/pos.js";
|
|
11
8
|
import { createCondition } from "./ast/createNormalizedCondition.js";
|
|
12
9
|
import { createExpression } from "./ast/createNormalizedExpression.js";
|
|
@@ -59,34 +56,8 @@ const tokenRequiresWhitespace = (valid, whitespace, wordOps) => {
|
|
|
59
56
|
};
|
|
60
57
|
const tokenVariable = [TOKEN_TYPE.BACKTICK, TOKEN_TYPE.DOUBLEQUOTE, TOKEN_TYPE.SINGLEQUOTE, TOKEN_TYPE.VALUE, TOKEN_TYPE.REGEX];
|
|
61
58
|
class Parser {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
__publicField(this, "evaluationOptionsChecked", false);
|
|
65
|
-
__publicField(this, "validationOptionsChecked", false);
|
|
66
|
-
__publicField(this, "options");
|
|
67
|
-
__publicField(this, "lexer");
|
|
68
|
-
__publicField(this, "$");
|
|
69
|
-
__publicField(this, "$categories");
|
|
70
|
-
__publicField(this, "info");
|
|
71
|
-
__publicField(this, "state", {
|
|
72
|
-
rawInput: "",
|
|
73
|
-
lexedTokens: [],
|
|
74
|
-
index: 0,
|
|
75
|
-
shift: 0
|
|
76
|
-
});
|
|
77
|
-
__publicField(this, "subParserOne");
|
|
78
|
-
__publicField(this, "subParserTwo");
|
|
79
|
-
const opts = parseParserOptions(options ?? {});
|
|
80
|
-
checkParserOpts(opts);
|
|
81
|
-
this.options = opts;
|
|
82
|
-
this.lexer = new Lexer(opts);
|
|
83
|
-
this.$ = this.lexer.$;
|
|
84
|
-
this.$categories = this.lexer.$categories;
|
|
85
|
-
this.info = {
|
|
86
|
-
expandedSepAlsoCustom: this.lexer.symbols.expandedSepAlsoCustom,
|
|
87
|
-
customOpAlsoNegation: this.lexer.symbols.customOpAlsoNegation
|
|
88
|
-
};
|
|
89
|
-
}
|
|
59
|
+
// needed for evaluate and validate so they are only checked on demand
|
|
60
|
+
evaluationOptionsChecked = false;
|
|
90
61
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
91
62
|
_checkEvaluationOptions() {
|
|
92
63
|
if (!this.evaluationOptionsChecked) {
|
|
@@ -94,6 +65,7 @@ class Parser {
|
|
|
94
65
|
this.evaluationOptionsChecked = true;
|
|
95
66
|
}
|
|
96
67
|
}
|
|
68
|
+
validationOptionsChecked = false;
|
|
97
69
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
98
70
|
_checkValidationOptions() {
|
|
99
71
|
if (!this.validationOptionsChecked) {
|
|
@@ -101,6 +73,29 @@ class Parser {
|
|
|
101
73
|
this.validationOptionsChecked = true;
|
|
102
74
|
}
|
|
103
75
|
}
|
|
76
|
+
options;
|
|
77
|
+
lexer;
|
|
78
|
+
$;
|
|
79
|
+
$categories;
|
|
80
|
+
info;
|
|
81
|
+
constructor(options) {
|
|
82
|
+
const opts = parseParserOptions(options ?? {});
|
|
83
|
+
checkParserOpts(opts);
|
|
84
|
+
this.options = opts;
|
|
85
|
+
this.lexer = new Lexer(opts);
|
|
86
|
+
this.$ = this.lexer.$;
|
|
87
|
+
this.$categories = this.lexer.$categories;
|
|
88
|
+
this.info = {
|
|
89
|
+
expandedSepAlsoCustom: this.lexer.symbols.expandedSepAlsoCustom,
|
|
90
|
+
customOpAlsoNegation: this.lexer.symbols.customOpAlsoNegation
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
state = {
|
|
94
|
+
rawInput: "",
|
|
95
|
+
lexedTokens: [],
|
|
96
|
+
index: 0,
|
|
97
|
+
shift: 0
|
|
98
|
+
};
|
|
104
99
|
/**
|
|
105
100
|
* This is exposed mainly for debugging purposes. Use parse directly instead.
|
|
106
101
|
*/
|
|
@@ -149,6 +144,8 @@ class Parser {
|
|
|
149
144
|
};
|
|
150
145
|
return res;
|
|
151
146
|
}
|
|
147
|
+
subParserOne;
|
|
148
|
+
subParserTwo;
|
|
152
149
|
createSubParserIfNotExists(opts, which = "One") {
|
|
153
150
|
if (this[`subParser${which}`] === void 0) {
|
|
154
151
|
this[`subParser${which}`] = new Parser(opts);
|
|
@@ -162,8 +159,7 @@ class Parser {
|
|
|
162
159
|
};
|
|
163
160
|
}
|
|
164
161
|
getCategoryTokens(type) {
|
|
165
|
-
|
|
166
|
-
return (_a = this.$categories[type]) == null ? void 0 : _a.entries;
|
|
162
|
+
return this.$categories[type]?.entries;
|
|
167
163
|
}
|
|
168
164
|
getTokenType(type) {
|
|
169
165
|
return this.$[type];
|
|
@@ -178,9 +174,9 @@ class Parser {
|
|
|
178
174
|
if (token2 === void 0) return false;
|
|
179
175
|
if (token2.type === type) return true;
|
|
180
176
|
const tokenType = this.getTokenType(token2.type);
|
|
181
|
-
if (
|
|
177
|
+
if (tokenType?.type === type) return true;
|
|
182
178
|
const category = this.$categories[type];
|
|
183
|
-
if (
|
|
179
|
+
if (category?.entries[token2.type] !== void 0) {
|
|
184
180
|
return true;
|
|
185
181
|
}
|
|
186
182
|
return false;
|
|
@@ -208,8 +204,7 @@ class Parser {
|
|
|
208
204
|
return this.peek(1) === void 0;
|
|
209
205
|
}
|
|
210
206
|
consumeAny() {
|
|
211
|
-
|
|
212
|
-
return this.consume((_a = this.peek(1)) == null ? void 0 : _a.type);
|
|
207
|
+
return this.consume(this.peek(1)?.type);
|
|
213
208
|
}
|
|
214
209
|
consume(type) {
|
|
215
210
|
if (type === void 0) {
|
|
@@ -221,21 +216,21 @@ class Parser {
|
|
|
221
216
|
}
|
|
222
217
|
if (this.$categories[type] !== void 0) {
|
|
223
218
|
const categoryToken = this.$categories[type];
|
|
224
|
-
const tokenType = categoryToken
|
|
219
|
+
const tokenType = categoryToken?.entries[nextToken.type];
|
|
225
220
|
if (categoryToken && tokenType) {
|
|
226
221
|
this.state.index++;
|
|
227
222
|
return this.transformCategoryToken(nextToken, categoryToken);
|
|
228
223
|
} else {
|
|
229
|
-
|
|
224
|
+
unreachable();
|
|
230
225
|
}
|
|
231
226
|
} else {
|
|
232
227
|
const tokenType = this.getTokenType(type);
|
|
233
228
|
if (tokenType !== void 0) {
|
|
234
|
-
if (
|
|
229
|
+
if (nextToken?.type === tokenType.type) {
|
|
235
230
|
this.state.index++;
|
|
236
231
|
return nextToken;
|
|
237
232
|
} else {
|
|
238
|
-
throw new Error(`Expected token type ${tokenType.type}, got ${nextToken
|
|
233
|
+
throw new Error(`Expected token type ${tokenType.type}, got ${nextToken?.type}`);
|
|
239
234
|
}
|
|
240
235
|
}
|
|
241
236
|
}
|
|
@@ -257,11 +252,10 @@ class Parser {
|
|
|
257
252
|
}
|
|
258
253
|
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
259
254
|
ruleBool(type) {
|
|
260
|
-
var _a;
|
|
261
255
|
const OP_TYPE = type === "AND" ? $C.OPERATOR_AND : $C.OPERATOR_OR;
|
|
262
256
|
const pairs = [];
|
|
263
257
|
let next = this.peek(1);
|
|
264
|
-
while (pairs.length < 1 ||
|
|
258
|
+
while (pairs.length < 1 || pairs[pairs.length - 1]?.[1] !== void 0) {
|
|
265
259
|
const exp = type === "AND" ? this.ruleCondition() : this.ruleBool("AND");
|
|
266
260
|
next = this.peek(1);
|
|
267
261
|
const canAttemptErrorRecovery = type === "AND" ? ["error", "and"].includes(this.options.onMissingBooleanOperator) : this.options.onMissingBooleanOperator === "or";
|
|
@@ -329,12 +323,11 @@ class Parser {
|
|
|
329
323
|
return res;
|
|
330
324
|
}
|
|
331
325
|
ruleCondition() {
|
|
332
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
333
326
|
const not = this.ruleNot();
|
|
334
327
|
const property = this.ruleConditionProperty();
|
|
335
|
-
const propVal =
|
|
336
|
-
const propOpVal =
|
|
337
|
-
const isExpanded = (
|
|
328
|
+
const propVal = property?.prop?.value === void 0 ? void 0 : !property.prop.value.valid ? "" : property.prop.value.value;
|
|
329
|
+
const propOpVal = property?.rest?.propertyOperator === void 0 ? void 0 : !property.rest.propertyOperator?.valid ? "" : property.rest.propertyOperator?.value;
|
|
330
|
+
const isExpanded = (property?.rest?.sepL ?? property?.rest?.sepR) !== void 0;
|
|
338
331
|
const convertRegexValues = typeof this.options.regexValues === "function" && !this.options.regexValues(propVal, propOpVal, isExpanded);
|
|
339
332
|
const convertArrayValues = typeof this.options.arrayValues === "function" && !this.options.arrayValues(propVal, propOpVal, isExpanded);
|
|
340
333
|
let value = this.ruleConditionValue(property, { convertRegexValues, convertArrayValues });
|
|
@@ -346,15 +339,15 @@ class Parser {
|
|
|
346
339
|
group$1 = value;
|
|
347
340
|
value = void 0;
|
|
348
341
|
}
|
|
349
|
-
if (convertRegexValues && isNode(value) && value.type === AST_TYPE.VARIABLE &&
|
|
342
|
+
if (convertRegexValues && isNode(value) && value.type === AST_TYPE.VARIABLE && value.quote?.left.type === TOKEN_TYPE.REGEX) {
|
|
350
343
|
value = variable(void 0, void 0, token.value(
|
|
351
|
-
(
|
|
344
|
+
(value.quote?.left?.value ?? "") + (value.value.value ?? "") + (value.quote?.right?.value ?? ""),
|
|
352
345
|
pos(value)
|
|
353
346
|
), void 0);
|
|
354
347
|
}
|
|
355
348
|
if (group$1) {
|
|
356
349
|
if (property) {
|
|
357
|
-
return condition(not, property
|
|
350
|
+
return condition(not, property?.prop, property?.rest, group(void 0, void 0, ...group$1));
|
|
358
351
|
}
|
|
359
352
|
if (value) {
|
|
360
353
|
return group(void 0, condition(not, void 0, void 0, value), ...group$1);
|
|
@@ -362,14 +355,14 @@ class Parser {
|
|
|
362
355
|
return group(not, value, ...group$1);
|
|
363
356
|
}
|
|
364
357
|
if ([not, property, value].every((_) => _ === void 0)) return void 0;
|
|
365
|
-
return condition(not, property
|
|
358
|
+
return condition(not, property?.prop, property?.rest, value);
|
|
366
359
|
}
|
|
367
360
|
ruleConditionValue(property, { convertRegexValues = false, convertArrayValues = false } = {}) {
|
|
368
361
|
const next = this.peek(1);
|
|
369
362
|
const next2 = this.peek(2);
|
|
370
363
|
const next3 = this.peek(3);
|
|
371
364
|
const next4 = this.peek(4);
|
|
372
|
-
if (this.options.prefixableGroups && property === void 0 &&
|
|
365
|
+
if (this.options.prefixableGroups && property === void 0 && next?.type !== $T.PAREN_L && (this.isType(next, $C.VALUE) && (this.isType(next2, $T.PAREN_L) || this.isType(next2, $C.QUOTE_ANY) && this.isType(next3, $T.PAREN_L)) || this.isType(next, $C.QUOTE_ANY) && (this.isType(next2, $T.PAREN_L) || this.isType(next2, $C.VALUE) && (this.isType(next3, $T.PAREN_L) || // "a(
|
|
373
366
|
this.isType(next3, $C.QUOTE_ANY) && this.isType(next4, $T.PAREN_L))))) {
|
|
374
367
|
const res = this.ruleVariable({ unprefixed: true });
|
|
375
368
|
if (res) return res;
|
|
@@ -397,7 +390,7 @@ class Parser {
|
|
|
397
390
|
if (onlyValues && !this.nextIsEof()) {
|
|
398
391
|
while (!this.nextIsEof() && (!this.isType(this.peek(1), $T.PAREN_R) || parenLeftCount !== 0)) {
|
|
399
392
|
const token2 = this.consumeAny();
|
|
400
|
-
start
|
|
393
|
+
start ??= extractPosition(token2, this.state.shift).start;
|
|
401
394
|
if (token2.type === $T.PAREN_L) {
|
|
402
395
|
parenLeftCount++;
|
|
403
396
|
}
|
|
@@ -407,7 +400,7 @@ class Parser {
|
|
|
407
400
|
}
|
|
408
401
|
}
|
|
409
402
|
if (start !== void 0) {
|
|
410
|
-
end
|
|
403
|
+
end ??= extractPosition(this.peek(0), this.state.shift).end;
|
|
411
404
|
}
|
|
412
405
|
const parenR = this.isType(this.peek(1), $T.PAREN_R) ? this.ruleParenR() : void 0;
|
|
413
406
|
if (start !== void 0) {
|
|
@@ -447,7 +440,7 @@ class Parser {
|
|
|
447
440
|
return array(bracketL, values, bracketR);
|
|
448
441
|
}
|
|
449
442
|
const start = bracketL.start;
|
|
450
|
-
const end = bracketR
|
|
443
|
+
const end = bracketR?.end;
|
|
451
444
|
const subInput = this.state.rawInput.slice(start, end);
|
|
452
445
|
this.createSubParserIfNotExists({
|
|
453
446
|
...this.options,
|
|
@@ -509,12 +502,12 @@ class Parser {
|
|
|
509
502
|
const next3 = this.peek(3);
|
|
510
503
|
if (next && (this.isExactType(next, $T.QUOTE_DOUBLE) || this.isExactType(next, $T.QUOTE_SINGLE) || this.isExactType(next, $T.QUOTE_BACKTICK))) {
|
|
511
504
|
const quoteType = next.type;
|
|
512
|
-
if (
|
|
505
|
+
if (next2?.type === quoteType) {
|
|
513
506
|
const quoteL = this.ruleQuote(quoteType);
|
|
514
507
|
const quoteR = this.ruleQuote(quoteType);
|
|
515
508
|
return variable(void 0, quoteL, void 0, quoteR);
|
|
516
509
|
}
|
|
517
|
-
if (
|
|
510
|
+
if (next3?.type === next.type) {
|
|
518
511
|
const quoteL = this.ruleQuote(quoteType);
|
|
519
512
|
const value = this.isType(next2, $T.VALUE_UNQUOTED) ? this.ruleValueUnquoted({}) : this.ruleValueNot(quoteType);
|
|
520
513
|
const quoteR = this.ruleQuote(quoteType);
|
|
@@ -595,8 +588,8 @@ class Parser {
|
|
|
595
588
|
}
|
|
596
589
|
ruleQuote(type) {
|
|
597
590
|
const quote = this.peek(1);
|
|
598
|
-
if (type !==
|
|
599
|
-
throw new Error(`Expected quote type ${type}, got ${quote
|
|
591
|
+
if (type !== quote?.type) {
|
|
592
|
+
throw new Error(`Expected quote type ${type}, got ${quote?.type}`);
|
|
600
593
|
}
|
|
601
594
|
switch (type) {
|
|
602
595
|
case $T.QUOTE_SINGLE:
|
|
@@ -636,7 +629,7 @@ class Parser {
|
|
|
636
629
|
}
|
|
637
630
|
ruleParenL() {
|
|
638
631
|
const next = this.peek(1);
|
|
639
|
-
const value =
|
|
632
|
+
const value = next?.type === $T.PAREN_L ? this.consume($T.PAREN_L) : this.createErrorToken($T.PAREN_L);
|
|
640
633
|
const loc = extractPosition(value, this.state.shift);
|
|
641
634
|
return this.state.shift === 0 || loc.start > 0 ? delimiter.parenL(value.isError ? void 0 : value.value, loc) : void 0;
|
|
642
635
|
}
|
|
@@ -646,7 +639,7 @@ class Parser {
|
|
|
646
639
|
}
|
|
647
640
|
ruleBracketL() {
|
|
648
641
|
const next = this.peek(1);
|
|
649
|
-
const value =
|
|
642
|
+
const value = next?.type === $T.BRACKET_L ? this.consume($T.BRACKET_L) : this.createErrorToken($T.BRACKET_L);
|
|
650
643
|
const loc = extractPosition(value, this.state.shift);
|
|
651
644
|
return this.state.shift === 0 || loc.start > 0 ? delimiter.bracketL(value.isError ? void 0 : value.value, loc) : void 0;
|
|
652
645
|
}
|
|
@@ -704,14 +697,13 @@ class Parser {
|
|
|
704
697
|
return [{ suggestion, value: "/" }];
|
|
705
698
|
case SUGGESTION_TYPE.REGEX_FLAGS:
|
|
706
699
|
return regexFlags.map((value) => ({ suggestion, value })).filter((completion) => {
|
|
707
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
708
700
|
const { suggestion: suggestion2, value } = completion;
|
|
709
701
|
if (suggestion2.type !== SUGGESTION_TYPE.REGEX_FLAGS) {
|
|
710
702
|
return true;
|
|
711
703
|
}
|
|
712
704
|
const token2 = suggestion2.cursorInfo;
|
|
713
|
-
const flags = token2.at &&
|
|
714
|
-
if (
|
|
705
|
+
const flags = token2.at && getParent(token2.at, parentMap)?.quote?.flags === suggestion2.cursorInfo.at ? token2.at : token2.next && getParent(token2.next, parentMap)?.quote?.flags === suggestion2.cursorInfo.next ? token2.next : token2.prev && getParent(token2.prev, parentMap)?.quote?.flags === suggestion2.cursorInfo.prev ? token2.prev : void 0;
|
|
706
|
+
if (flags?.value?.includes(value)) {
|
|
715
707
|
return false;
|
|
716
708
|
}
|
|
717
709
|
return true;
|
|
@@ -802,14 +794,13 @@ class Parser {
|
|
|
802
794
|
* ```
|
|
803
795
|
*/
|
|
804
796
|
autosuggest(input, ast, index) {
|
|
805
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
|
|
806
797
|
const parentMap = generateParentsMap(ast);
|
|
807
798
|
const opts = this.options;
|
|
808
799
|
const tokens = extractTokens(ast);
|
|
809
800
|
const token2 = getCursorInfo(input, tokens, index);
|
|
810
801
|
const wordOps = [...opts.keywords.and, ...opts.keywords.or, ...opts.keywords.not].filter((op) => !op.isSymbol);
|
|
811
|
-
const canSuggestOpAfterPrev = token2.valid.prev && tokenVariable.includes(
|
|
812
|
-
const canSuggestOpBeforeNext = token2.valid.next && tokenVariable.includes(
|
|
802
|
+
const canSuggestOpAfterPrev = token2.valid.prev && tokenVariable.includes(token2.valid.prev?.type) && (token2.whitespace.prev || token2.valid.prev.type === TOKEN_TYPE.PARENR) && !token2.at && token2.valid.next === void 0;
|
|
803
|
+
const canSuggestOpBeforeNext = token2.valid.next && tokenVariable.includes(token2.valid.next?.type) && token2.whitespace.next && // no parenL allowed since check since there will already be prefix suggestions
|
|
813
804
|
!token2.at && token2.valid.prev === void 0;
|
|
814
805
|
const requiresWhitespacePrev = tokenRequiresWhitespace(token2.valid.prev, token2.whitespace.prev, wordOps);
|
|
815
806
|
const requiresWhitespaceNext = tokenRequiresWhitespace(token2.valid.next, token2.whitespace.next, wordOps);
|
|
@@ -900,8 +891,8 @@ class Parser {
|
|
|
900
891
|
break;
|
|
901
892
|
case TOKEN_TYPE.VALUE: {
|
|
902
893
|
const errorParent = getParent(error, parentMap);
|
|
903
|
-
const prefixedValue =
|
|
904
|
-
const isRegexValue =
|
|
894
|
+
const prefixedValue = errorParent?.type === AST_TYPE.VARIABLE ? getParent(error, parentMap)?.prefix?.value : false;
|
|
895
|
+
const isRegexValue = errorParent?.type === AST_TYPE.VARIABLE && (errorParent.quote?.left.type === TOKEN_TYPE.REGEX || errorParent.quote?.right.type === TOKEN_TYPE.REGEX);
|
|
905
896
|
if (!isRegexValue) {
|
|
906
897
|
if (!prefixedValue && opts.prefixableGroups) {
|
|
907
898
|
suggestions.push({
|
|
@@ -972,16 +963,16 @@ class Parser {
|
|
|
972
963
|
const nextCondition = getParent(nextVar, parentMap);
|
|
973
964
|
const atVar = getParent(token2.at, parentMap);
|
|
974
965
|
const atCondition = getParent(atVar, parentMap);
|
|
975
|
-
const isVarPrev = !token2.whitespace.prev &&
|
|
976
|
-
const isVarNext = !token2.whitespace.next &&
|
|
977
|
-
const isVarAt =
|
|
978
|
-
const isPropertyPrev =
|
|
979
|
-
const isPropertyNext =
|
|
980
|
-
const isPropertyAt =
|
|
981
|
-
const isPropertyOperatorPrev =
|
|
982
|
-
const isPropertyOperatorNext =
|
|
983
|
-
const isPropertyOperatorAt =
|
|
984
|
-
const noArrayValuesTarget =
|
|
966
|
+
const isVarPrev = !token2.whitespace.prev && token2.valid.prev?.type !== TOKEN_TYPE.REGEX && prevVar?.type === AST_TYPE.VARIABLE && (prevCondition?.type === AST_TYPE.CONDITION && prevCondition.value === prevVar && (prevVar.quote?.right === token2.valid.prev || prevVar.value === token2.valid.prev) || prevCondition?.type === AST_TYPE.ARRAY);
|
|
967
|
+
const isVarNext = !token2.whitespace.next && token2.valid.next?.type !== TOKEN_TYPE.REGEX && nextVar?.type === AST_TYPE.VARIABLE && (nextCondition?.type === AST_TYPE.CONDITION && nextCondition.value === nextVar && (nextVar.quote?.left === token2.valid.next || nextVar.value === token2.valid.next) || nextCondition?.type === AST_TYPE.ARRAY);
|
|
968
|
+
const isVarAt = atVar?.type === AST_TYPE.VARIABLE && atCondition?.type === AST_TYPE.CONDITION || prevVar?.type === AST_TYPE.VARIABLE && token2.valid.prev === prevVar?.quote?.left || nextVar?.type === AST_TYPE.VARIABLE && token2.valid.next === nextVar?.quote?.right;
|
|
969
|
+
const isPropertyPrev = prevCondition?.type === AST_TYPE.CONDITION && prevVar !== void 0 && prevVar === prevCondition?.property;
|
|
970
|
+
const isPropertyNext = nextCondition?.type === AST_TYPE.CONDITION && nextVar !== void 0 && nextVar === nextCondition?.property;
|
|
971
|
+
const isPropertyAt = atCondition?.type === AST_TYPE.CONDITION && atVar !== void 0 && atVar === atCondition?.property;
|
|
972
|
+
const isPropertyOperatorPrev = prevVar?.type === AST_TYPE.CONDITION && token2.valid.prev === prevVar?.propertyOperator;
|
|
973
|
+
const isPropertyOperatorNext = nextVar?.type === AST_TYPE.CONDITION && token2.valid.next === nextVar?.propertyOperator;
|
|
974
|
+
const isPropertyOperatorAt = atVar?.type === AST_TYPE.CONDITION && token2.at === atVar?.propertyOperator;
|
|
975
|
+
const noArrayValuesTarget = token2.valid.prev?.type === TOKEN_TYPE.BRACKETL && (token2.valid.next === void 0 || token2.valid.next?.type === TOKEN_TYPE.BRACKETR);
|
|
985
976
|
const target = isVarPrev ? token2.valid.prev : !noArrayValuesTarget && !isPropertyPrev && !isPropertyOperatorPrev && isVarNext ? token2.valid.next : isVarAt ? token2.at : void 0;
|
|
986
977
|
const propertyTarget = isPropertyPrev ? token2.valid.prev : !noArrayValuesTarget && !isVarPrev && !isPropertyOperatorPrev && isPropertyNext ? token2.valid.next : isPropertyAt ? token2.at : void 0;
|
|
987
978
|
const propOpTarget = isPropertyOperatorPrev ? token2.valid.prev : !noArrayValuesTarget && !isVarPrev && !isPropertyPrev && isPropertyOperatorNext ? token2.valid.next : isPropertyOperatorAt ? token2.at : void 0;
|
|
@@ -993,15 +984,15 @@ class Parser {
|
|
|
993
984
|
const condition2 = parentParent;
|
|
994
985
|
const isValue = condition2.propertyOperator !== void 0 && condition2.value === parent;
|
|
995
986
|
const maybeGroup = getParent(parentParent, parentMap);
|
|
996
|
-
const isPrefix =
|
|
987
|
+
const isPrefix = maybeGroup?.type === AST_TYPE.GROUP && maybeGroup.prefix === condition2;
|
|
997
988
|
const varStart = getCursorInfo(input, ast, parent.start);
|
|
998
989
|
const varEnd = getCursorInfo(input, ast, parent.end);
|
|
999
990
|
const targetRequiresWhitespacePrev = tokenRequiresWhitespace(varStart.valid.prev, varStart.whitespace.prev, wordOps);
|
|
1000
991
|
const targetRequiresWhitespaceNext = tokenRequiresWhitespace(varEnd.valid.next, varEnd.whitespace.next, wordOps);
|
|
1001
|
-
const prefixedValue = parent.type === AST_TYPE.VARIABLE ?
|
|
1002
|
-
const isSepPrev =
|
|
1003
|
-
const arrayValue =
|
|
1004
|
-
const isRegexFlag = target ===
|
|
992
|
+
const prefixedValue = parent.type === AST_TYPE.VARIABLE ? parent?.prefix?.value : false;
|
|
993
|
+
const isSepPrev = token2.prev?.type === TOKEN_TYPE.OP_EXPANDED_SEP;
|
|
994
|
+
const arrayValue = parentParent?.type === AST_TYPE.ARRAY;
|
|
995
|
+
const isRegexFlag = target === parent.quote?.flags;
|
|
1005
996
|
if (!isRegexFlag && !isSepPrev && !isValue && !arrayValue && !prefixedValue && opts.prefixableGroups) {
|
|
1006
997
|
suggestions.push({
|
|
1007
998
|
...baseSuggestion,
|
|
@@ -1058,9 +1049,9 @@ class Parser {
|
|
|
1058
1049
|
range: pos(propOpTarget)
|
|
1059
1050
|
});
|
|
1060
1051
|
}
|
|
1061
|
-
const canSuggestValue = token2.whitespace.next && (token2.whitespace.prev ||
|
|
1052
|
+
const canSuggestValue = token2.whitespace.next && (token2.whitespace.prev || token2.prev?.type === TOKEN_TYPE.BRACKETL || token2.prev?.type === TOKEN_TYPE.PARENL) || token2.whitespace.prev && (token2.whitespace.next || token2.next?.type === TOKEN_TYPE.BRACKETR || token2.next?.type === TOKEN_TYPE.PARENR);
|
|
1062
1053
|
if (canSuggestValue) {
|
|
1063
|
-
const inArrayNode = [nextCondition, prevCondition, nextVar, prevVar].find((_) =>
|
|
1054
|
+
const inArrayNode = [nextCondition, prevCondition, nextVar, prevVar].find((_) => _?.type === AST_TYPE.ARRAY) !== void 0;
|
|
1064
1055
|
const opsNotNeeded = ["and", "or"].includes(opts.onMissingBooleanOperator);
|
|
1065
1056
|
if (inArrayNode || opsNotNeeded) {
|
|
1066
1057
|
suggestions.push({
|
|
@@ -1086,8 +1077,8 @@ class Parser {
|
|
|
1086
1077
|
const tokenValidNextParent = getParent(token2.valid.next, parentMap);
|
|
1087
1078
|
const canSuggestRegexFlags = (
|
|
1088
1079
|
// has existing flags before/after
|
|
1089
|
-
token2.at && token2.at ===
|
|
1090
|
-
|
|
1080
|
+
token2.at && token2.at === tokenAtParent?.quote?.flags || token2.valid.prev && token2.valid.prev === tokenValidPrevParent?.quote?.flags || token2.valid.next && token2.valid.next === tokenValidNextParent?.quote?.flags || // no flags
|
|
1081
|
+
token2.valid.prev?.type === TOKEN_TYPE.REGEX && token2.valid.prev === tokenValidPrevParent.quote?.right
|
|
1091
1082
|
);
|
|
1092
1083
|
if (canSuggestRegexFlags) {
|
|
1093
1084
|
suggestions.push({
|
|
@@ -1264,7 +1255,6 @@ class Parser {
|
|
|
1264
1255
|
* Normalizes the ast by applying {@link GroupNode GroupNodes} and converting {@link ConditionNode ConditionNodes} to {@link NormalizedConditionNode NormalizedConditionNodes}.
|
|
1265
1256
|
*/
|
|
1266
1257
|
normalize(ast) {
|
|
1267
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
|
|
1268
1258
|
this._checkEvaluationOptions();
|
|
1269
1259
|
const opts = this.options;
|
|
1270
1260
|
if (!ast.valid) {
|
|
@@ -1276,8 +1266,8 @@ class Parser {
|
|
|
1276
1266
|
const self_ = this;
|
|
1277
1267
|
if (ast.type === AST_TYPE.CONDITION) {
|
|
1278
1268
|
if (!(ast.value.type === AST_TYPE.GROUP)) {
|
|
1279
|
-
const isValue = ast.value.type === AST_TYPE.ARRAY ||
|
|
1280
|
-
let name =
|
|
1269
|
+
const isValue = ast.value.type === AST_TYPE.ARRAY || ast.value?.quote?.left.type === TOKEN_TYPE.REGEX;
|
|
1270
|
+
let name = ast.property?.value?.value ? unescape(ast.property.value.value) : isValue ? void 0 : unescape(ast.value.value.value);
|
|
1281
1271
|
const isNested = operator2 !== void 0;
|
|
1282
1272
|
if (prefix !== void 0 && !isNested) {
|
|
1283
1273
|
name = name ? applyPrefix(prefix, name, opts.prefixApplier) : prefix;
|
|
@@ -1287,16 +1277,16 @@ class Parser {
|
|
|
1287
1277
|
value = name ?? true;
|
|
1288
1278
|
name = prefix;
|
|
1289
1279
|
} else {
|
|
1290
|
-
value = ast.value.type === AST_TYPE.ARRAY ? ast.value.values.map((val) => unescape(val.value.value)) :
|
|
1280
|
+
value = ast.value.type === AST_TYPE.ARRAY ? ast.value.values.map((val) => unescape(val.value.value)) : ast.value?.quote?.left.type === TOKEN_TYPE.REGEX ? ast.value.value?.value : ast.property && ast.value.type === AST_TYPE.VARIABLE ? unescape(ast.value.value.value) : true;
|
|
1291
1281
|
}
|
|
1292
1282
|
const propertyKeys = name ? opts.keyParser(name) : [];
|
|
1293
1283
|
const boolValue = applyBoolean(groupValue, ast.operator === void 0);
|
|
1294
1284
|
const valuePrefix = ast.value.type === AST_TYPE.VARIABLE && ast.value.prefix ? unescape(ast.value.prefix.value) : void 0;
|
|
1295
|
-
operator2
|
|
1296
|
-
const isRegex =
|
|
1297
|
-
const isQuoted =
|
|
1285
|
+
operator2 ??= ast.propertyOperator?.value;
|
|
1286
|
+
const isRegex = ast.value?.quote?.left.type === TOKEN_TYPE.REGEX;
|
|
1287
|
+
const isQuoted = ast.value?.quote !== void 0;
|
|
1298
1288
|
const isExpanded = ast.sep !== void 0;
|
|
1299
|
-
const regexFlags =
|
|
1289
|
+
const regexFlags = ast.value?.quote?.flags?.value;
|
|
1300
1290
|
const query = {
|
|
1301
1291
|
value,
|
|
1302
1292
|
operator: operator2,
|
|
@@ -1317,14 +1307,14 @@ class Parser {
|
|
|
1317
1307
|
name = applyPrefix(prefix, name, opts.prefixApplier);
|
|
1318
1308
|
}
|
|
1319
1309
|
const boolValue = applyBoolean(groupValue, ast.operator === void 0);
|
|
1320
|
-
const operator22 =
|
|
1310
|
+
const operator22 = ast.propertyOperator?.value;
|
|
1321
1311
|
return self_.normalize(ast.value, name, boolValue, operator22);
|
|
1322
1312
|
}
|
|
1323
1313
|
}
|
|
1324
1314
|
if (ast.type === AST_TYPE.GROUP) {
|
|
1325
|
-
const _prefix =
|
|
1315
|
+
const _prefix = ast.prefix?.type === AST_TYPE.CONDITION && ast.prefix?.value.type === AST_TYPE.VARIABLE ? unescape(ast.prefix.value.value.value) : void 0;
|
|
1326
1316
|
const isNotToken = _prefix === void 0;
|
|
1327
|
-
const _groupValue =
|
|
1317
|
+
const _groupValue = ast.prefix?.type === AST_TYPE.CONDITION ? ast.prefix.operator === void 0 : !(ast.prefix?.valid === true);
|
|
1328
1318
|
const applied = isNotToken ? prefix : applyPrefix(prefix, _prefix, opts.prefixApplier);
|
|
1329
1319
|
return self_.normalize(ast.expression, applied, applyBoolean(groupValue, _groupValue), operator2);
|
|
1330
1320
|
}
|
|
@@ -1343,7 +1333,6 @@ class Parser {
|
|
|
1343
1333
|
* The context does not need to be passed. If it's not passed, the function will not attempt to get the values (so it will not error) and the contextValue param of the valueValidator will be undefined.
|
|
1344
1334
|
*/
|
|
1345
1335
|
validate(ast, context) {
|
|
1346
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
1347
1336
|
const self = this;
|
|
1348
1337
|
self._checkValidationOptions();
|
|
1349
1338
|
const opts = self.options;
|
|
@@ -1358,7 +1347,7 @@ class Parser {
|
|
|
1358
1347
|
const self_ = this;
|
|
1359
1348
|
if (ast.type === AST_TYPE.CONDITION) {
|
|
1360
1349
|
if (!(ast.value.type === AST_TYPE.GROUP)) {
|
|
1361
|
-
const isValue = ast.value.type === AST_TYPE.ARRAY ||
|
|
1350
|
+
const isValue = ast.value.type === AST_TYPE.ARRAY || ast.value?.quote?.left.type === TOKEN_TYPE.REGEX;
|
|
1362
1351
|
const nameNode = ast.property ? ast.property : isValue ? void 0 : ast.value;
|
|
1363
1352
|
let name = nameNode ? unescape(nameNode.value.value) : void 0;
|
|
1364
1353
|
const isNested = operator2 !== void 0;
|
|
@@ -1373,17 +1362,17 @@ class Parser {
|
|
|
1373
1362
|
propertyNodes = [...prefixes];
|
|
1374
1363
|
} else {
|
|
1375
1364
|
propertyNodes = [...prefixes, ...nameNode ? [nameNode] : []];
|
|
1376
|
-
value = ast.value.type === AST_TYPE.ARRAY ? ast.value.values :
|
|
1365
|
+
value = ast.value.type === AST_TYPE.ARRAY ? ast.value.values : ast.value?.quote?.left.type === TOKEN_TYPE.REGEX ? ast.value : ast.property && ast.value.type === AST_TYPE.VARIABLE ? ast.value : true;
|
|
1377
1366
|
}
|
|
1378
1367
|
const propertyKeys = name ? opts.keyParser(name) : [];
|
|
1379
1368
|
const contextValue = context !== void 0 ? get(context, propertyKeys) : void 0;
|
|
1380
1369
|
const boolValue = applyBoolean(groupValue, ast.operator === void 0);
|
|
1381
1370
|
const valuePrefix = ast.value.type === AST_TYPE.VARIABLE && ast.value.prefix ? ast.value.prefix : void 0;
|
|
1382
|
-
operator2
|
|
1383
|
-
const isRegex =
|
|
1384
|
-
const isQuoted =
|
|
1371
|
+
operator2 ??= ast.propertyOperator;
|
|
1372
|
+
const isRegex = ast.value?.quote?.left.type === TOKEN_TYPE.REGEX;
|
|
1373
|
+
const isQuoted = ast.value?.quote !== void 0;
|
|
1385
1374
|
const isExpanded = ast.sep !== void 0;
|
|
1386
|
-
const regexFlags =
|
|
1375
|
+
const regexFlags = ast.value?.quote?.flags;
|
|
1387
1376
|
const query = {
|
|
1388
1377
|
value,
|
|
1389
1378
|
operator: operator2,
|
|
@@ -1416,10 +1405,10 @@ class Parser {
|
|
|
1416
1405
|
}
|
|
1417
1406
|
}
|
|
1418
1407
|
if (ast.type === AST_TYPE.GROUP) {
|
|
1419
|
-
const _prefix =
|
|
1408
|
+
const _prefix = ast.prefix?.type === AST_TYPE.CONDITION && ast.prefix.value.type === AST_TYPE.VARIABLE ? ast.prefix.value : void 0;
|
|
1420
1409
|
if (_prefix) prefixes.push(_prefix);
|
|
1421
|
-
const _groupValue =
|
|
1422
|
-
self_.validate(ast.expression, context, applyPrefix(prefix,
|
|
1410
|
+
const _groupValue = ast.prefix?.type === AST_TYPE.CONDITION ? ast.prefix.operator === void 0 : !(ast.prefix?.valid === true);
|
|
1411
|
+
self_.validate(ast.expression, context, applyPrefix(prefix, _prefix?.value.value ?? "", opts.prefixApplier), applyBoolean(groupValue, _groupValue), results, prefixes, operator2);
|
|
1423
1412
|
}
|
|
1424
1413
|
if (ast.type === AST_TYPE.EXPRESSION) {
|
|
1425
1414
|
self_.validate(ast.left, context, prefix, groupValue, results, [...prefixes], operator2);
|