@witchcraft/expressit 0.0.2 → 0.1.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.
Files changed (124) hide show
  1. package/README.md +6 -4
  2. package/dist/Lexer.d.ts +146 -0
  3. package/dist/Lexer.d.ts.map +1 -0
  4. package/dist/Lexer.js +960 -0
  5. package/dist/Parser.d.ts +140 -0
  6. package/dist/Parser.d.ts.map +1 -0
  7. package/dist/Parser.js +668 -0
  8. package/dist/ast/builders/token.js +1 -1
  9. package/dist/ast/handlers.d.ts +3 -3
  10. package/dist/ast/handlers.d.ts.map +1 -1
  11. package/dist/ast/index.d.ts.map +1 -1
  12. package/dist/examples/index.d.ts +2 -0
  13. package/dist/examples/index.d.ts.map +1 -0
  14. package/dist/examples/index.js +4 -0
  15. package/dist/examples/shortcutContextParser.d.ts +2 -1
  16. package/dist/examples/shortcutContextParser.d.ts.map +1 -1
  17. package/dist/examples/shortcutContextParser.js +9 -5
  18. package/dist/helpers/errors.d.ts.map +1 -1
  19. package/dist/helpers/errors.js +3 -1
  20. package/dist/helpers/index.d.ts.map +1 -1
  21. package/dist/helpers/parser/checkParserOpts.d.ts.map +1 -1
  22. package/dist/helpers/parser/checkParserOpts.js +3 -2
  23. package/dist/helpers/parser/extractPosition.d.ts +2 -6
  24. package/dist/helpers/parser/extractPosition.d.ts.map +1 -1
  25. package/dist/helpers/parser/extractPosition.js +3 -3
  26. package/dist/helpers/parser/getUnclosedRightParenCount.d.ts +2 -3
  27. package/dist/helpers/parser/getUnclosedRightParenCount.d.ts.map +1 -1
  28. package/dist/helpers/parser/getUnclosedRightParenCount.js +4 -4
  29. package/dist/index.d.ts +1 -2
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +3 -5
  32. package/dist/methods/autocomplete.d.ts.map +1 -1
  33. package/dist/methods/autocomplete.js +1 -1
  34. package/dist/methods/autoreplace.js +1 -1
  35. package/dist/methods/autosuggest.js +1 -1
  36. package/dist/methods/evaluate.d.ts.map +1 -1
  37. package/dist/methods/evaluate.js +3 -1
  38. package/dist/methods/getIndexes.d.ts.map +1 -1
  39. package/dist/methods/getIndexes.js +2 -1
  40. package/dist/methods/normalize.d.ts +0 -2
  41. package/dist/methods/normalize.d.ts.map +1 -1
  42. package/dist/methods/normalize.js +2 -3
  43. package/dist/methods/validate.d.ts.map +1 -1
  44. package/dist/methods/validate.js +3 -1
  45. package/dist/package.json.js +44 -37
  46. package/dist/types/ast.d.ts +2 -8
  47. package/dist/types/ast.d.ts.map +1 -1
  48. package/dist/types/errors.d.ts +5 -17
  49. package/dist/types/errors.d.ts.map +1 -1
  50. package/dist/types/errors.js +0 -1
  51. package/dist/types/parser.d.ts +6 -2
  52. package/dist/types/parser.d.ts.map +1 -1
  53. package/dist/utils/extractTokens.js +1 -1
  54. package/dist/utils/getCursorInfo.d.ts +2 -2
  55. package/dist/utils/getCursorInfo.d.ts.map +1 -1
  56. package/dist/utils/getCursorInfo.js +3 -2
  57. package/dist/utils/getOppositeDelimiter.d.ts.map +1 -1
  58. package/dist/utils/getOppositeDelimiter.js +1 -1
  59. package/dist/utils/prettyAst.d.ts.map +1 -1
  60. package/dist/utils/prettyAst.js +15 -9
  61. package/package.json +42 -37
  62. package/src/Lexer.ts +704 -0
  63. package/src/Parser.ts +972 -0
  64. package/src/ast/builders/array.ts +2 -2
  65. package/src/ast/builders/condition.ts +1 -1
  66. package/src/ast/builders/expression.ts +1 -1
  67. package/src/ast/builders/group.ts +1 -1
  68. package/src/ast/builders/index.ts +1 -1
  69. package/src/ast/builders/pos.ts +1 -1
  70. package/src/ast/builders/token.ts +2 -2
  71. package/src/ast/builders/type.ts +1 -1
  72. package/src/ast/builders/variable.ts +1 -1
  73. package/src/ast/classes/ConditionNode.ts +1 -1
  74. package/src/ast/classes/ErrorToken.ts +1 -1
  75. package/src/ast/classes/ValidToken.ts +2 -2
  76. package/src/ast/classes/index.ts +1 -1
  77. package/src/ast/handlers.ts +6 -6
  78. package/src/ast/index.ts +2 -2
  79. package/src/examples/index.ts +3 -0
  80. package/src/examples/shortcutContextParser.ts +11 -6
  81. package/src/helpers/errors.ts +5 -3
  82. package/src/helpers/general/defaultConditionNormalizer.ts +1 -1
  83. package/src/helpers/general/index.ts +1 -1
  84. package/src/helpers/index.ts +3 -2
  85. package/src/helpers/parser/checkParserOpts.ts +13 -12
  86. package/src/helpers/parser/extractPosition.ts +4 -8
  87. package/src/helpers/parser/getUnclosedRightParenCount.ts +6 -6
  88. package/src/helpers/parser/index.ts +1 -1
  89. package/src/helpers/parser/parseParserOptions.ts +1 -1
  90. package/src/index.ts +2 -2
  91. package/src/methods/autocomplete.ts +5 -5
  92. package/src/methods/autoreplace.ts +2 -2
  93. package/src/methods/autosuggest.ts +3 -3
  94. package/src/methods/evaluate.ts +4 -2
  95. package/src/methods/getIndexes.ts +2 -1
  96. package/src/methods/normalize.ts +3 -4
  97. package/src/methods/validate.ts +4 -2
  98. package/src/types/ast.ts +2 -9
  99. package/src/types/errors.ts +12 -22
  100. package/src/types/parser.ts +6 -4
  101. package/src/utils/extractTokens.ts +1 -1
  102. package/src/utils/getCursorInfo.ts +6 -4
  103. package/src/utils/getOppositeDelimiter.ts +5 -2
  104. package/src/utils/prettyAst.ts +5 -3
  105. package/dist/examples/advancedValueComparer.d.ts +0 -3
  106. package/dist/examples/advancedValueComparer.d.ts.map +0 -1
  107. package/dist/examples/advancedValueComparer.js +0 -28
  108. package/dist/grammar/ParserBase.d.ts +0 -51
  109. package/dist/grammar/ParserBase.d.ts.map +0 -1
  110. package/dist/grammar/ParserBase.js +0 -516
  111. package/dist/grammar/createTokens.d.ts +0 -56
  112. package/dist/grammar/createTokens.d.ts.map +0 -1
  113. package/dist/grammar/createTokens.js +0 -843
  114. package/dist/grammar/index.d.ts +0 -3
  115. package/dist/grammar/index.d.ts.map +0 -1
  116. package/dist/grammar/index.js +0 -6
  117. package/dist/parser.d.ts +0 -58
  118. package/dist/parser.d.ts.map +0 -1
  119. package/dist/parser.js +0 -136
  120. package/src/examples/advancedValueComparer.ts +0 -31
  121. package/src/grammar/ParserBase.ts +0 -715
  122. package/src/grammar/createTokens.ts +0 -512
  123. package/src/grammar/index.ts +0 -4
  124. package/src/parser.ts +0 -183
package/dist/Lexer.js ADDED
@@ -0,0 +1,960 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => {
4
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ return value;
6
+ };
7
+ import { isBlank } from "@alanscodelog/utils/isBlank";
8
+ import { pushIfNotIn } from "@alanscodelog/utils/pushIfNotIn";
9
+ import { checkParserOpts } from "./helpers/parser/checkParserOpts.js";
10
+ import { parseParserOptions } from "./helpers/parser/parseParserOptions.js";
11
+ const regexFlags = /^[a-zA-Z]+/;
12
+ const BRACKET_PREFIX = "BRACKET";
13
+ var $T = /* @__PURE__ */ (($T2) => {
14
+ $T2["_"] = "_";
15
+ $T2["VALUE_UNQUOTED"] = "VALUE_UNQUOTED";
16
+ $T2["VALUE_REGEX"] = "VALUE_REGEX";
17
+ $T2["VALUE_NOT_SINGLE"] = "VALUE_NOT_SINGLE";
18
+ $T2["VALUE_NOT_DOUBLE"] = "VALUE_NOT_DOUBLE";
19
+ $T2["VALUE_NOT_BACKTICK"] = "VALUE_NOT_BACKTICK";
20
+ $T2["SYM_OR"] = "SYM_OR";
21
+ $T2["SYM_AND"] = "SYM_AND";
22
+ $T2["SYM_NOT"] = "SYM_NOT";
23
+ $T2["WORD_OR"] = "WORD_OR";
24
+ $T2["WORD_AND"] = "WORD_AND";
25
+ $T2["WORD_NOT"] = "WORD_NOT";
26
+ $T2["REGEX_START"] = "REGEX_START";
27
+ $T2["REGEX_END"] = "REGEX_END";
28
+ $T2["EXP_PROP_OP"] = "EXP_PROP_OP";
29
+ $T2["CUSTOM_PROP_OP"] = "CUSTOM_PROP_OP";
30
+ $T2["PAREN_L"] = "PAREN_L";
31
+ $T2["PAREN_R"] = "PAREN_R";
32
+ $T2["BRACKET_L"] = "BRACKET_L";
33
+ $T2["BRACKET_R"] = "BRACKET_R";
34
+ $T2["QUOTE_SINGLE"] = "QUOTE_SINGLE";
35
+ $T2["QUOTE_DOUBLE"] = "QUOTE_DOUBLE";
36
+ $T2["QUOTE_BACKTICK"] = "QUOTE_BACKTICK";
37
+ return $T2;
38
+ })($T || {});
39
+ var $C = /* @__PURE__ */ (($C2) => {
40
+ $C2["ANY"] = "ANY";
41
+ $C2["QUOTE_ANY"] = "QUOTE_ANY";
42
+ $C2["REGEX_ANY"] = "REGEX_ANY";
43
+ $C2["VALUE_FOR_SINGLE"] = "VALUE_FOR_SINGLE";
44
+ $C2["VALUE_FOR_DOUBLE"] = "VALUE_FOR_DOUBLE";
45
+ $C2["VALUE_FOR_BACKTICK"] = "VALUE_FOR_BACKTICK";
46
+ $C2["OPERATOR_OR"] = "OPERATOR_OR";
47
+ $C2["OPERATOR_AND"] = "OPERATOR_AND";
48
+ $C2["OPERATOR_NOT"] = "OPERATOR_NOT";
49
+ $C2["VALUE"] = "VALUE";
50
+ return $C2;
51
+ })($C || {});
52
+ function createTokenCategoryType(type, entries) {
53
+ return {
54
+ type,
55
+ isCategory: true,
56
+ entries: Object.fromEntries(
57
+ entries.filter((_) => _ !== void 0).map((_) => [_.type, _])
58
+ )
59
+ };
60
+ }
61
+ function createTokenType(type, opts) {
62
+ return {
63
+ type,
64
+ ...opts
65
+ };
66
+ }
67
+ function matchWhileCharNotEqualToUnescaped(char) {
68
+ return (c, input, start) => {
69
+ let end = start;
70
+ while (c !== void 0 && c !== char) {
71
+ if (c === "\\") {
72
+ end += 2;
73
+ c = input[end];
74
+ continue;
75
+ }
76
+ end++;
77
+ c = input[end];
78
+ }
79
+ if (start === end)
80
+ return false;
81
+ return input.slice(start, end);
82
+ };
83
+ }
84
+ function matchSymbol(symbols) {
85
+ return (_c, input, start) => {
86
+ for (const sym of symbols) {
87
+ const textSlice = input.slice(start, start + sym.length);
88
+ if (textSlice === sym) {
89
+ return textSlice;
90
+ }
91
+ }
92
+ return false;
93
+ };
94
+ }
95
+ class Lexer {
96
+ constructor(opts = {}) {
97
+ __publicField(this, "symbols");
98
+ __publicField(this, "$");
99
+ __publicField(this, "$categories");
100
+ __publicField(this, "branches");
101
+ __publicField(this, "opts");
102
+ this.opts = parseParserOptions(opts);
103
+ checkParserOpts(this.opts);
104
+ this.symbols = this.calculateSymbolInfo();
105
+ const tokenTypes = this.createTokens();
106
+ this.$ = tokenTypes.$;
107
+ this.$categories = tokenTypes.$categories;
108
+ this.branches = this.createModeBranches();
109
+ }
110
+ calculateSymbolInfo() {
111
+ var _a;
112
+ const opts = this.opts;
113
+ const symOrs = opts.keywords.or.filter((_) => _.isSymbol).map((_) => _.value);
114
+ const symAnds = opts.keywords.and.filter((_) => _.isSymbol).map((_) => _.value);
115
+ const symNots = opts.keywords.not.filter((_) => _.isSymbol).map((_) => _.value);
116
+ const wordOrs = opts.keywords.or.filter((_) => !_.isSymbol).map((_) => _.value);
117
+ const wordAnds = opts.keywords.and.filter((_) => !_.isSymbol).map((_) => _.value);
118
+ const wordNots = opts.keywords.not.filter((_) => !_.isSymbol).map((_) => _.value);
119
+ const syms = [...symOrs, ...symAnds, ...symNots];
120
+ const customPropertyOperators = opts.customPropertyOperators ?? [];
121
+ const expandedPropertySeparator = opts.expandedPropertySeparator ?? "";
122
+ if (expandedPropertySeparator)
123
+ syms.push(expandedPropertySeparator);
124
+ if (customPropertyOperators.length > 0)
125
+ pushIfNotIn(syms, customPropertyOperators);
126
+ if (opts.regexValues)
127
+ syms.push("\\/");
128
+ if (opts.arrayValues) {
129
+ syms.push("\\[");
130
+ }
131
+ const symbols = {
132
+ // all sorted by longest first, so longest matches are matched first
133
+ symOrs: symOrs.sort((a, b) => b.length - a.length),
134
+ symAnds: symAnds.sort((a, b) => b.length - a.length),
135
+ symNots: symNots.sort((a, b) => b.length - a.length),
136
+ wordOrs: wordOrs.sort((a, b) => b.length - a.length),
137
+ wordAnds: wordAnds.sort((a, b) => b.length - a.length),
138
+ wordNots: wordNots.sort((a, b) => b.length - a.length),
139
+ all: syms.sort((a, b) => b.length - a.length)
140
+ };
141
+ const expandedSepAlsoCustom = ((_a = opts.customPropertyOperators) == null ? void 0 : _a.includes(opts.expandedPropertySeparator)) ?? false;
142
+ let customOpAlsoNegation = false;
143
+ if (symbols.symNots.length > 0) {
144
+ for (const op of opts.customPropertyOperators ?? []) {
145
+ for (const sym of symbols.symNots) {
146
+ if (op === sym) {
147
+ customOpAlsoNegation = true;
148
+ break;
149
+ }
150
+ }
151
+ }
152
+ }
153
+ return { ...symbols, expandedSepAlsoCustom, customOpAlsoNegation };
154
+ }
155
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
156
+ createTokens() {
157
+ var _a;
158
+ const opts = this.opts;
159
+ const symbols = this.symbols;
160
+ const $ = {
161
+ [
162
+ "_"
163
+ /* _ */
164
+ ]: createTokenType("_", {
165
+ skip: true,
166
+ matches: (c, input, start) => {
167
+ let end = start;
168
+ while (c === " " || c === " " || c === "\n" || c === "\r" || c === "\v" || c === "\f") {
169
+ end++;
170
+ c = input[end];
171
+ }
172
+ if (start === end)
173
+ return false;
174
+ return input.slice(start, end);
175
+ }
176
+ }),
177
+ [
178
+ "REGEX_START"
179
+ /* REGEX_START */
180
+ ]: createTokenType("REGEX_START", {
181
+ push: "NOT_REGEX",
182
+ matches: (c) => c === "/"
183
+ }),
184
+ [
185
+ "REGEX_END"
186
+ /* REGEX_END */
187
+ ]: createTokenType("REGEX_END", {
188
+ push: "MAIN",
189
+ matches: (c, input, start) => {
190
+ let end = start;
191
+ if (c === "/") {
192
+ end++;
193
+ c = input[end];
194
+ const match = regexFlags.exec(input.slice(end));
195
+ if (match !== null) {
196
+ end += match.input.length;
197
+ }
198
+ return input.slice(start, end);
199
+ } else
200
+ return false;
201
+ }
202
+ }),
203
+ [
204
+ "VALUE_REGEX"
205
+ /* VALUE_REGEX */
206
+ ]: createTokenType("VALUE_REGEX", {
207
+ push: "REGEX_END",
208
+ matches: (c, input, start) => {
209
+ let end = start;
210
+ let inGroup = 0;
211
+ let prevEscaped = false;
212
+ while (c !== void 0 && (c !== "/" || inGroup > 0 || prevEscaped)) {
213
+ if (c === "[")
214
+ inGroup++;
215
+ if (c === "]" && inGroup > 0)
216
+ inGroup--;
217
+ if (c === "\\") {
218
+ if (!prevEscaped) {
219
+ prevEscaped = true;
220
+ } else {
221
+ prevEscaped = false;
222
+ }
223
+ } else {
224
+ prevEscaped && (prevEscaped = false);
225
+ }
226
+ end++;
227
+ c = input[end];
228
+ }
229
+ if (start === end)
230
+ return false;
231
+ return input.slice(start, end);
232
+ }
233
+ }),
234
+ [
235
+ "QUOTE_SINGLE"
236
+ /* QUOTE_SINGLE */
237
+ ]: createTokenType("QUOTE_SINGLE", {
238
+ push: (mode, tokens) => {
239
+ const previous = tokens[tokens.length - 2];
240
+ if (
241
+ /**
242
+ * If we just matched a quote and the previous token was the inside of a quote then we are at the end of the quoted value.
243
+ * Go back to main instead of searching for the quoted value
244
+ * Otherwise input like 'a'b'c' will trap us in a MAIN <=> NOT_SINGLE loop.
245
+ */
246
+ (previous == null ? void 0 : previous.type) === "VALUE_NOT_SINGLE" || (previous == null ? void 0 : previous.type) === "VALUE_UNQUOTED"
247
+ ) {
248
+ return "MAIN";
249
+ }
250
+ switch (mode) {
251
+ case "BRACKET_MAIN":
252
+ return "BRACKET_NOT_SINGLE";
253
+ case "MAIN":
254
+ return "NOT_SINGLE";
255
+ default:
256
+ if (mode.startsWith(BRACKET_PREFIX))
257
+ return "BRACKET_MAIN";
258
+ return "MAIN";
259
+ }
260
+ },
261
+ matches: (c) => c === "'"
262
+ }),
263
+ [
264
+ "QUOTE_DOUBLE"
265
+ /* QUOTE_DOUBLE */
266
+ ]: createTokenType("QUOTE_DOUBLE", {
267
+ push: (mode, tokens) => {
268
+ const previous = tokens[tokens.length - 2];
269
+ if ((previous == null ? void 0 : previous.type) === "VALUE_NOT_DOUBLE" || (previous == null ? void 0 : previous.type) === "VALUE_UNQUOTED") {
270
+ if (mode.startsWith(BRACKET_PREFIX))
271
+ return "BRACKET_MAIN";
272
+ return "MAIN";
273
+ }
274
+ switch (mode) {
275
+ case "BRACKET_MAIN":
276
+ return "BRACKET_NOT_DOUBLE";
277
+ case "MAIN":
278
+ return "NOT_DOUBLE";
279
+ default:
280
+ if (mode.startsWith(BRACKET_PREFIX))
281
+ return "BRACKET_MAIN";
282
+ return "MAIN";
283
+ }
284
+ },
285
+ matches: (c) => c === '"'
286
+ }),
287
+ [
288
+ "QUOTE_BACKTICK"
289
+ /* QUOTE_BACKTICK */
290
+ ]: createTokenType("QUOTE_BACKTICK", {
291
+ push: (mode, tokens) => {
292
+ const previous = tokens[tokens.length - 2];
293
+ if ((previous == null ? void 0 : previous.type) === "VALUE_NOT_BACKTICK" || (previous == null ? void 0 : previous.type) === "VALUE_UNQUOTED") {
294
+ return "MAIN";
295
+ }
296
+ switch (mode) {
297
+ case "BRACKET_MAIN":
298
+ return "BRACKET_NOT_BACKTICK";
299
+ case "MAIN":
300
+ return "NOT_BACKTICK";
301
+ default:
302
+ if (mode.startsWith(BRACKET_PREFIX))
303
+ return "BRACKET_MAIN";
304
+ return "MAIN";
305
+ }
306
+ },
307
+ matches: (c) => c === "`"
308
+ }),
309
+ [
310
+ "VALUE_NOT_SINGLE"
311
+ /* VALUE_NOT_SINGLE */
312
+ ]: createTokenType("VALUE_NOT_SINGLE", {
313
+ push: (mode) => mode.startsWith(BRACKET_PREFIX) ? "BRACKET_MAIN" : "MAIN",
314
+ matches: matchWhileCharNotEqualToUnescaped("'")
315
+ }),
316
+ [
317
+ "VALUE_NOT_DOUBLE"
318
+ /* VALUE_NOT_DOUBLE */
319
+ ]: createTokenType("VALUE_NOT_DOUBLE", {
320
+ push: (mode) => mode.startsWith(BRACKET_PREFIX) ? "BRACKET_MAIN" : "MAIN",
321
+ matches: matchWhileCharNotEqualToUnescaped('"')
322
+ }),
323
+ [
324
+ "VALUE_NOT_BACKTICK"
325
+ /* VALUE_NOT_BACKTICK */
326
+ ]: createTokenType("VALUE_NOT_BACKTICK", {
327
+ push: (mode) => mode.startsWith(BRACKET_PREFIX) ? "BRACKET_MAIN" : "MAIN",
328
+ matches: matchWhileCharNotEqualToUnescaped("`")
329
+ }),
330
+ [
331
+ "VALUE_UNQUOTED"
332
+ /* VALUE_UNQUOTED */
333
+ ]: createTokenType("VALUE_UNQUOTED", {
334
+ push: (mode) => mode.startsWith(BRACKET_PREFIX) ? "BRACKET_MAIN" : "MAIN",
335
+ // manual version of pattern: /(\\[\s\S]|(${syms.length > 0 ? `(?!(${syms.join("|")}))` : ``}[^ \t()'"`\\]))+/,
336
+ matches: (c, input, start, mode) => {
337
+ let end = start;
338
+ while (c !== void 0) {
339
+ if (c === "\\") {
340
+ end += 2;
341
+ c = input[end];
342
+ continue;
343
+ }
344
+ if (mode === "MAIN") {
345
+ let found = false;
346
+ for (const sym of symbols.all) {
347
+ const textSlice = input.slice(end, end + sym.length);
348
+ if (textSlice === sym) {
349
+ found = true;
350
+ break;
351
+ }
352
+ }
353
+ if (found)
354
+ break;
355
+ }
356
+ if (c === " " || c === " " || c === "(" || c === ")" || c === "'" || c === '"' || c === "`" || c === "\\" || mode === "BRACKET_MAIN" && c === "]") {
357
+ break;
358
+ }
359
+ end++;
360
+ c = input[end];
361
+ }
362
+ if (start === end)
363
+ return false;
364
+ return input.slice(start, end);
365
+ }
366
+ }),
367
+ ...symbols.symOrs.length > 0 ? {
368
+ [
369
+ "SYM_OR"
370
+ /* SYM_OR */
371
+ ]: createTokenType("SYM_OR", {
372
+ matches: matchSymbol(symbols.symOrs)
373
+ })
374
+ } : {},
375
+ ...symbols.symAnds.length > 0 ? {
376
+ [
377
+ "SYM_AND"
378
+ /* SYM_AND */
379
+ ]: createTokenType("SYM_AND", {
380
+ matches: matchSymbol(symbols.symAnds)
381
+ })
382
+ } : {},
383
+ ...symbols.symNots.length > 0 ? {
384
+ [
385
+ "SYM_NOT"
386
+ /* SYM_NOT */
387
+ ]: createTokenType("SYM_NOT", {
388
+ matches: matchSymbol(symbols.symNots)
389
+ })
390
+ } : {},
391
+ ...symbols.wordOrs.length > 0 ? {
392
+ [
393
+ "WORD_OR"
394
+ /* WORD_OR */
395
+ ]: createTokenType("WORD_OR", {
396
+ matches: matchSymbol(symbols.wordOrs),
397
+ longerAlt: "VALUE_UNQUOTED"
398
+ /* VALUE_UNQUOTED */
399
+ })
400
+ } : {},
401
+ ...symbols.wordAnds.length > 0 ? {
402
+ [
403
+ "WORD_AND"
404
+ /* WORD_AND */
405
+ ]: createTokenType("WORD_AND", {
406
+ matches: matchSymbol(symbols.wordAnds),
407
+ longerAlt: "VALUE_UNQUOTED"
408
+ /* VALUE_UNQUOTED */
409
+ })
410
+ } : {},
411
+ ...symbols.wordNots.length > 0 ? { [
412
+ "WORD_NOT"
413
+ /* WORD_NOT */
414
+ ]: createTokenType("WORD_NOT", {
415
+ matches: matchSymbol(symbols.wordNots),
416
+ longerAlt: "VALUE_UNQUOTED"
417
+ /* VALUE_UNQUOTED */
418
+ }) } : {},
419
+ ...!isBlank(opts.expandedPropertySeparator ?? "") ? {
420
+ [
421
+ "EXP_PROP_OP"
422
+ /* EXP_PROP_OP */
423
+ ]: createTokenType("EXP_PROP_OP", {
424
+ matches: (_c, input, start) => {
425
+ for (const op of opts.expandedPropertySeparator) {
426
+ const chars = input.slice(start, start + op.length);
427
+ if (chars === op)
428
+ return op;
429
+ }
430
+ return false;
431
+ }
432
+ })
433
+ } : {},
434
+ ...(((_a = opts.customPropertyOperators) == null ? void 0 : _a.length) ?? 0) > 0 && !symbols.customOpAlsoNegation ? {
435
+ [
436
+ "CUSTOM_PROP_OP"
437
+ /* CUSTOM_PROP_OP */
438
+ ]: createTokenType("CUSTOM_PROP_OP", {
439
+ matches: (_c, input, start) => {
440
+ for (const op of opts.customPropertyOperators ?? []) {
441
+ const chars = input.slice(start, start + op.length);
442
+ if (chars === op)
443
+ return op;
444
+ }
445
+ return false;
446
+ }
447
+ })
448
+ } : {},
449
+ [
450
+ "PAREN_L"
451
+ /* PAREN_L */
452
+ ]: createTokenType("PAREN_L", {
453
+ matches: (c) => c === "("
454
+ }),
455
+ [
456
+ "PAREN_R"
457
+ /* PAREN_R */
458
+ ]: createTokenType("PAREN_R", {
459
+ matches: (c) => c === ")"
460
+ }),
461
+ [
462
+ "BRACKET_L"
463
+ /* BRACKET_L */
464
+ ]: createTokenType("BRACKET_L", {
465
+ push: "BRACKET_MAIN",
466
+ matches: (c) => c === "["
467
+ }),
468
+ [
469
+ "BRACKET_R"
470
+ /* BRACKET_R */
471
+ ]: createTokenType("BRACKET_R", {
472
+ push: "MAIN",
473
+ matches: (c) => c === "]"
474
+ })
475
+ };
476
+ const $categories = {
477
+ [
478
+ "ANY"
479
+ /* ANY */
480
+ ]: createTokenCategoryType("ANY", [
481
+ $[
482
+ "REGEX_START"
483
+ /* REGEX_START */
484
+ ],
485
+ $[
486
+ "REGEX_END"
487
+ /* REGEX_END */
488
+ ],
489
+ $[
490
+ "QUOTE_SINGLE"
491
+ /* QUOTE_SINGLE */
492
+ ],
493
+ $[
494
+ "QUOTE_DOUBLE"
495
+ /* QUOTE_DOUBLE */
496
+ ],
497
+ $[
498
+ "QUOTE_BACKTICK"
499
+ /* QUOTE_BACKTICK */
500
+ ],
501
+ $[
502
+ "VALUE_NOT_SINGLE"
503
+ /* VALUE_NOT_SINGLE */
504
+ ],
505
+ $[
506
+ "VALUE_NOT_DOUBLE"
507
+ /* VALUE_NOT_DOUBLE */
508
+ ],
509
+ $[
510
+ "VALUE_NOT_BACKTICK"
511
+ /* VALUE_NOT_BACKTICK */
512
+ ],
513
+ $[
514
+ "VALUE_UNQUOTED"
515
+ /* VALUE_UNQUOTED */
516
+ ],
517
+ $[
518
+ "SYM_OR"
519
+ /* SYM_OR */
520
+ ],
521
+ $[
522
+ "SYM_AND"
523
+ /* SYM_AND */
524
+ ],
525
+ $[
526
+ "SYM_NOT"
527
+ /* SYM_NOT */
528
+ ],
529
+ $[
530
+ "WORD_OR"
531
+ /* WORD_OR */
532
+ ],
533
+ $[
534
+ "WORD_AND"
535
+ /* WORD_AND */
536
+ ],
537
+ $[
538
+ "WORD_NOT"
539
+ /* WORD_NOT */
540
+ ],
541
+ $[
542
+ "EXP_PROP_OP"
543
+ /* EXP_PROP_OP */
544
+ ],
545
+ $[
546
+ "CUSTOM_PROP_OP"
547
+ /* CUSTOM_PROP_OP */
548
+ ],
549
+ $[
550
+ "PAREN_L"
551
+ /* PAREN_L */
552
+ ],
553
+ $[
554
+ "PAREN_R"
555
+ /* PAREN_R */
556
+ ],
557
+ $[
558
+ "BRACKET_L"
559
+ /* BRACKET_L */
560
+ ],
561
+ $[
562
+ "BRACKET_R"
563
+ /* BRACKET_R */
564
+ ]
565
+ ]),
566
+ [
567
+ "VALUE"
568
+ /* VALUE */
569
+ ]: createTokenCategoryType("VALUE", [
570
+ $[
571
+ "VALUE_UNQUOTED"
572
+ /* VALUE_UNQUOTED */
573
+ ],
574
+ $[
575
+ "VALUE_NOT_SINGLE"
576
+ /* VALUE_NOT_SINGLE */
577
+ ],
578
+ $[
579
+ "VALUE_NOT_DOUBLE"
580
+ /* VALUE_NOT_DOUBLE */
581
+ ],
582
+ $[
583
+ "VALUE_NOT_BACKTICK"
584
+ /* VALUE_NOT_BACKTICK */
585
+ ]
586
+ ]),
587
+ [
588
+ "VALUE_FOR_SINGLE"
589
+ /* VALUE_FOR_SINGLE */
590
+ ]: createTokenCategoryType("VALUE_FOR_SINGLE", [
591
+ $[
592
+ "VALUE_NOT_SINGLE"
593
+ /* VALUE_NOT_SINGLE */
594
+ ]
595
+ ]),
596
+ [
597
+ "VALUE_FOR_DOUBLE"
598
+ /* VALUE_FOR_DOUBLE */
599
+ ]: createTokenCategoryType("VALUE_FOR_DOUBLE", [
600
+ $[
601
+ "VALUE_NOT_DOUBLE"
602
+ /* VALUE_NOT_DOUBLE */
603
+ ]
604
+ ]),
605
+ [
606
+ "VALUE_FOR_BACKTICK"
607
+ /* VALUE_FOR_BACKTICK */
608
+ ]: createTokenCategoryType("VALUE_FOR_BACKTICK", [
609
+ $[
610
+ "VALUE_NOT_BACKTICK"
611
+ /* VALUE_NOT_BACKTICK */
612
+ ]
613
+ ]),
614
+ [
615
+ "REGEX_ANY"
616
+ /* REGEX_ANY */
617
+ ]: createTokenCategoryType("REGEX_ANY", [
618
+ $[
619
+ "REGEX_START"
620
+ /* REGEX_START */
621
+ ],
622
+ $[
623
+ "REGEX_END"
624
+ /* REGEX_END */
625
+ ]
626
+ ]),
627
+ [
628
+ "QUOTE_ANY"
629
+ /* QUOTE_ANY */
630
+ ]: createTokenCategoryType("QUOTE_ANY", [
631
+ $[
632
+ "QUOTE_SINGLE"
633
+ /* QUOTE_SINGLE */
634
+ ],
635
+ $[
636
+ "QUOTE_DOUBLE"
637
+ /* QUOTE_DOUBLE */
638
+ ],
639
+ $[
640
+ "QUOTE_BACKTICK"
641
+ /* QUOTE_BACKTICK */
642
+ ]
643
+ ]),
644
+ [
645
+ "OPERATOR_OR"
646
+ /* OPERATOR_OR */
647
+ ]: createTokenCategoryType("OPERATOR_OR", [
648
+ $[
649
+ "SYM_OR"
650
+ /* SYM_OR */
651
+ ],
652
+ $[
653
+ "WORD_OR"
654
+ /* WORD_OR */
655
+ ]
656
+ ]),
657
+ [
658
+ "OPERATOR_AND"
659
+ /* OPERATOR_AND */
660
+ ]: createTokenCategoryType("OPERATOR_AND", [
661
+ $[
662
+ "SYM_AND"
663
+ /* SYM_AND */
664
+ ],
665
+ $[
666
+ "WORD_AND"
667
+ /* WORD_AND */
668
+ ]
669
+ ]),
670
+ [
671
+ "OPERATOR_NOT"
672
+ /* OPERATOR_NOT */
673
+ ]: createTokenCategoryType("OPERATOR_NOT", [
674
+ $[
675
+ "SYM_NOT"
676
+ /* SYM_NOT */
677
+ ],
678
+ $[
679
+ "WORD_NOT"
680
+ /* WORD_NOT */
681
+ ]
682
+ ])
683
+ };
684
+ return { $, $categories };
685
+ }
686
+ createModeBranches() {
687
+ const opts = this.opts;
688
+ const $ = this.$;
689
+ const quotes = [
690
+ $[
691
+ "QUOTE_SINGLE"
692
+ /* QUOTE_SINGLE */
693
+ ],
694
+ $[
695
+ "QUOTE_DOUBLE"
696
+ /* QUOTE_DOUBLE */
697
+ ],
698
+ $[
699
+ "QUOTE_BACKTICK"
700
+ /* QUOTE_BACKTICK */
701
+ ]
702
+ ];
703
+ const parens = [$[
704
+ "PAREN_L"
705
+ /* PAREN_L */
706
+ ], $[
707
+ "PAREN_R"
708
+ /* PAREN_R */
709
+ ]];
710
+ const operators = [
711
+ $[
712
+ "EXP_PROP_OP"
713
+ /* EXP_PROP_OP */
714
+ ],
715
+ $[
716
+ "CUSTOM_PROP_OP"
717
+ /* CUSTOM_PROP_OP */
718
+ ],
719
+ $[
720
+ "SYM_OR"
721
+ /* SYM_OR */
722
+ ],
723
+ $[
724
+ "SYM_AND"
725
+ /* SYM_AND */
726
+ ],
727
+ $[
728
+ "SYM_NOT"
729
+ /* SYM_NOT */
730
+ ],
731
+ $[
732
+ "WORD_OR"
733
+ /* WORD_OR */
734
+ ],
735
+ $[
736
+ "WORD_AND"
737
+ /* WORD_AND */
738
+ ],
739
+ $[
740
+ "WORD_NOT"
741
+ /* WORD_NOT */
742
+ ]
743
+ ].filter((_) => _ !== void 0);
744
+ return {
745
+ [
746
+ "MAIN"
747
+ /* MAIN */
748
+ ]: [
749
+ $[
750
+ "_"
751
+ /* _ */
752
+ ],
753
+ ...parens,
754
+ ...opts.arrayValues ? [$[
755
+ "BRACKET_L"
756
+ /* BRACKET_L */
757
+ ]] : [],
758
+ // => MODE.BRACKET_MAIN
759
+ ...operators,
760
+ ...quotes,
761
+ // => MODE.NOT_*
762
+ ...opts.regexValues ? [$[
763
+ "REGEX_START"
764
+ /* REGEX_START */
765
+ ]] : [],
766
+ // => MODE.NOT_REGEX
767
+ $[
768
+ "VALUE_UNQUOTED"
769
+ /* VALUE_UNQUOTED */
770
+ ]
771
+ ],
772
+ // this is just MAIN by another name, but allows us to properly distinguish start/end quotes
773
+ // // we can have situations like `a"` where the left quote is missing
774
+ // // we want the quote to match a quote so that it pushes the state to main again, instead of shifting how everything is parsed
775
+ [
776
+ "MAYBE_QUOTE_ERROR"
777
+ /* MAYBE_QUOTE_ERROR */
778
+ ]: [
779
+ ...quotes,
780
+ ...opts.regexValues ? [$[
781
+ "REGEX_END"
782
+ /* REGEX_END */
783
+ ]] : []
784
+ ],
785
+ // all => MODE.MAIN
786
+ [
787
+ "NOT_SINGLE"
788
+ /* NOT_SINGLE */
789
+ ]: [$[
790
+ "VALUE_NOT_SINGLE"
791
+ /* VALUE_NOT_SINGLE */
792
+ ], $[
793
+ "QUOTE_SINGLE"
794
+ /* QUOTE_SINGLE */
795
+ ]],
796
+ [
797
+ "NOT_DOUBLE"
798
+ /* NOT_DOUBLE */
799
+ ]: [$[
800
+ "VALUE_NOT_DOUBLE"
801
+ /* VALUE_NOT_DOUBLE */
802
+ ], $[
803
+ "QUOTE_DOUBLE"
804
+ /* QUOTE_DOUBLE */
805
+ ]],
806
+ [
807
+ "NOT_BACKTICK"
808
+ /* NOT_BACKTICK */
809
+ ]: [$[
810
+ "VALUE_NOT_BACKTICK"
811
+ /* VALUE_NOT_BACKTICK */
812
+ ], $[
813
+ "QUOTE_BACKTICK"
814
+ /* QUOTE_BACKTICK */
815
+ ]],
816
+ ...opts.regexValues ? {
817
+ [
818
+ "NOT_REGEX"
819
+ /* NOT_REGEX */
820
+ ]: [
821
+ $[
822
+ "VALUE_REGEX"
823
+ /* VALUE_REGEX */
824
+ ],
825
+ $[
826
+ "REGEX_END"
827
+ /* REGEX_END */
828
+ ]
829
+ // regex is empty
830
+ ],
831
+ // => MODE.REGEX_END
832
+ [
833
+ "REGEX_END"
834
+ /* REGEX_END */
835
+ ]: [$[
836
+ "REGEX_END"
837
+ /* REGEX_END */
838
+ ]]
839
+ // => MODE.MAIN
840
+ } : {},
841
+ ...opts.arrayValues ? {
842
+ [
843
+ "BRACKET_MAIN"
844
+ /* BRACKET_MAIN */
845
+ ]: [
846
+ $[
847
+ "_"
848
+ /* _ */
849
+ ],
850
+ ...quotes,
851
+ $[
852
+ "BRACKET_R"
853
+ /* BRACKET_R */
854
+ ],
855
+ // => MODE.MAIN
856
+ $[
857
+ "VALUE_UNQUOTED"
858
+ /* VALUE_UNQUOTED */
859
+ ]
860
+ ],
861
+ // all the following follow the same logic as the non-bracket modes, except operators and parens and regexes are not supported and are just parsed as values with VALUE_UNQUOTED
862
+ [
863
+ "BRACKET_MAYBE_QUOTE_ERROR"
864
+ /* BRACKET_MAYBE_QUOTE_ERROR */
865
+ ]: [...quotes],
866
+ [
867
+ "BRACKET_NOT_SINGLE"
868
+ /* BRACKET_NOT_SINGLE */
869
+ ]: [
870
+ $[
871
+ "VALUE_NOT_SINGLE"
872
+ /* VALUE_NOT_SINGLE */
873
+ ],
874
+ $[
875
+ "QUOTE_SINGLE"
876
+ /* QUOTE_SINGLE */
877
+ ]
878
+ ],
879
+ [
880
+ "BRACKET_NOT_DOUBLE"
881
+ /* BRACKET_NOT_DOUBLE */
882
+ ]: [
883
+ $[
884
+ "VALUE_NOT_DOUBLE"
885
+ /* VALUE_NOT_DOUBLE */
886
+ ],
887
+ $[
888
+ "QUOTE_DOUBLE"
889
+ /* QUOTE_DOUBLE */
890
+ ]
891
+ ],
892
+ [
893
+ "BRACKET_NOT_BACKTICK"
894
+ /* BRACKET_NOT_BACKTICK */
895
+ ]: [
896
+ $[
897
+ "VALUE_NOT_BACKTICK"
898
+ /* VALUE_NOT_BACKTICK */
899
+ ],
900
+ $[
901
+ "QUOTE_BACKTICK"
902
+ /* QUOTE_BACKTICK */
903
+ ]
904
+ ]
905
+ } : {}
906
+ };
907
+ }
908
+ tokenize(input) {
909
+ const branches = this.createModeBranches();
910
+ const tokens = [];
911
+ let mode = "MAIN";
912
+ let index = 0;
913
+ let c = input[index];
914
+ let branch = branches[mode];
915
+ while (index < input.length) {
916
+ for (const t of branch) {
917
+ let match = t.matches(c, input, index, mode);
918
+ if (match) {
919
+ let matchLength = match === true ? 1 : match.length;
920
+ let type = t.type;
921
+ if (t.longerAlt) {
922
+ const longerMatch = this.$[t.longerAlt].matches(c, input, index, mode);
923
+ const longerMatchLength = longerMatch === true ? 1 : longerMatch.length;
924
+ if (longerMatch && longerMatchLength > matchLength) {
925
+ match = longerMatch;
926
+ matchLength = longerMatchLength;
927
+ type = t.longerAlt;
928
+ }
929
+ }
930
+ const newIndex = index + matchLength;
931
+ const val = match === true ? c : match;
932
+ const token = createToken(type, val, index, newIndex - 1);
933
+ if (!t.skip)
934
+ tokens.push(token);
935
+ if (t.push) {
936
+ mode = typeof t.push === "function" ? t.push(mode, tokens) : t.push;
937
+ branch = branches[mode];
938
+ }
939
+ index = newIndex;
940
+ c = input[index];
941
+ break;
942
+ }
943
+ }
944
+ }
945
+ return tokens;
946
+ }
947
+ }
948
+ function createToken(type, value, startOffset, endOffset) {
949
+ return {
950
+ type,
951
+ value,
952
+ startOffset,
953
+ endOffset
954
+ };
955
+ }
956
+ export {
957
+ $C,
958
+ $T,
959
+ Lexer
960
+ };