expressionish 0.1.0 → 0.1.1
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/expressionish.d.ts +540 -0
- package/dist/expressionish.mjs +1429 -0
- package/dist/expressionish.mjs.map +7 -0
- package/package.json +4 -4
|
@@ -0,0 +1,1429 @@
|
|
|
1
|
+
// src/misc/split.ts
|
|
2
|
+
var HIGH_SURROGATE_START = 55296;
|
|
3
|
+
var HIGH_SURROGATE_END = 56319;
|
|
4
|
+
var LOW_SURROGATE_START = 56320;
|
|
5
|
+
var REGIONAL_INDICATOR_START = 127462;
|
|
6
|
+
var REGIONAL_INDICATOR_END = 127487;
|
|
7
|
+
var FITZPATRICK_MODIFIER_START = 127995;
|
|
8
|
+
var FITZPATRICK_MODIFIER_END = 127999;
|
|
9
|
+
var VARIATION_MODIFIER_START = 65024;
|
|
10
|
+
var VARIATION_MODIFIER_END = 65039;
|
|
11
|
+
var DIACRITICAL_MARKS_START = 8400;
|
|
12
|
+
var DIACRITICAL_MARKS_END = 8447;
|
|
13
|
+
var ZWJ = 8205;
|
|
14
|
+
var GRAPHEMS = /* @__PURE__ */ new Set([
|
|
15
|
+
776,
|
|
16
|
+
// ( ◌̈ ) COMBINING DIAERESIS
|
|
17
|
+
2359,
|
|
18
|
+
// ( ष ) DEVANAGARI LETTER SSA
|
|
19
|
+
2367,
|
|
20
|
+
// ( ि ) DEVANAGARI VOWEL SIGN I
|
|
21
|
+
2984,
|
|
22
|
+
// ( ந ) TAMIL LETTER NA
|
|
23
|
+
3007,
|
|
24
|
+
// ( ி ) TAMIL VOWEL SIGN I
|
|
25
|
+
3021,
|
|
26
|
+
// ( ◌்) TAMIL SIGN VIRAMA
|
|
27
|
+
3633,
|
|
28
|
+
// ( ◌ั ) THAI CHARACTER MAI HAN-AKAT
|
|
29
|
+
3635,
|
|
30
|
+
// ( ำ ) THAI CHARACTER SARA AM
|
|
31
|
+
3648,
|
|
32
|
+
// ( เ ) THAI CHARACTER SARA E
|
|
33
|
+
3657,
|
|
34
|
+
// ( เ ) THAI CHARACTER MAI THO
|
|
35
|
+
4352,
|
|
36
|
+
// ( ᄀ ) HANGUL CHOSEONG KIYEOK
|
|
37
|
+
4449,
|
|
38
|
+
// ( ᅡ ) HANGUL JUNGSEONG A
|
|
39
|
+
4520
|
|
40
|
+
// ( ᆨ ) HANGUL JONGSEONG KIYEOK
|
|
41
|
+
]);
|
|
42
|
+
var betweenInclusive = (value, lower, upper) => {
|
|
43
|
+
return value >= lower && value <= upper;
|
|
44
|
+
};
|
|
45
|
+
var codePointFromSurrogatePair = (pair) => {
|
|
46
|
+
const highOffset = pair.charCodeAt(0) - HIGH_SURROGATE_START;
|
|
47
|
+
const lowOffset = pair.charCodeAt(1) - LOW_SURROGATE_START;
|
|
48
|
+
return (highOffset << 10) + lowOffset + 65536;
|
|
49
|
+
};
|
|
50
|
+
var tokenize = (input) => {
|
|
51
|
+
if (typeof input !== "string") {
|
|
52
|
+
throw new Error("string cannot be undefined or null");
|
|
53
|
+
}
|
|
54
|
+
const asciiPunct = /^[\x01-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]$/;
|
|
55
|
+
const result = [];
|
|
56
|
+
let idx = 0;
|
|
57
|
+
let inc = 0;
|
|
58
|
+
let tok = null;
|
|
59
|
+
let escaped = false;
|
|
60
|
+
while (idx < input.length) {
|
|
61
|
+
const idxInc = idx + inc;
|
|
62
|
+
const current = input[idxInc];
|
|
63
|
+
if (idxInc < input.length - 1 && current && betweenInclusive(current.charCodeAt(0), HIGH_SURROGATE_START, HIGH_SURROGATE_END)) {
|
|
64
|
+
const currPair = codePointFromSurrogatePair(current + input[idxInc + 1]);
|
|
65
|
+
const nextPair = codePointFromSurrogatePair(input.substring(idxInc + 2, idxInc + 5));
|
|
66
|
+
if (betweenInclusive(currPair, REGIONAL_INDICATOR_START, REGIONAL_INDICATOR_END) && betweenInclusive(nextPair, REGIONAL_INDICATOR_START, REGIONAL_INDICATOR_END)) {
|
|
67
|
+
inc += 4;
|
|
68
|
+
} else if (betweenInclusive(nextPair, FITZPATRICK_MODIFIER_START, FITZPATRICK_MODIFIER_END)) {
|
|
69
|
+
inc += 4;
|
|
70
|
+
} else {
|
|
71
|
+
inc += 2;
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
inc += 1;
|
|
75
|
+
}
|
|
76
|
+
if (GRAPHEMS.has((input[idx + inc] + "").charCodeAt(0))) {
|
|
77
|
+
inc += 1;
|
|
78
|
+
}
|
|
79
|
+
if (betweenInclusive((input[idx + inc] + "").charCodeAt(0), VARIATION_MODIFIER_START, VARIATION_MODIFIER_END)) {
|
|
80
|
+
inc += 1;
|
|
81
|
+
}
|
|
82
|
+
if (betweenInclusive((input[idx + inc] + "").charCodeAt(0), DIACRITICAL_MARKS_START, DIACRITICAL_MARKS_END)) {
|
|
83
|
+
inc += 1;
|
|
84
|
+
}
|
|
85
|
+
if ((input[idx + inc] + "").charCodeAt(0) === ZWJ) {
|
|
86
|
+
inc += 1;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (inc > 1) {
|
|
90
|
+
if (tok != null) {
|
|
91
|
+
result.push(tok);
|
|
92
|
+
tok = null;
|
|
93
|
+
}
|
|
94
|
+
result.push({ position: idx, value: input.substring(idx, idx + inc) });
|
|
95
|
+
escaped = false;
|
|
96
|
+
} else if (input.substring(idx, idx + 2) === "``") {
|
|
97
|
+
if (tok != null) {
|
|
98
|
+
result.push(tok);
|
|
99
|
+
tok = null;
|
|
100
|
+
}
|
|
101
|
+
if (escaped) {
|
|
102
|
+
result.push({ position: idx, value: "`" });
|
|
103
|
+
escaped = false;
|
|
104
|
+
} else {
|
|
105
|
+
result.push({ position: idx, value: "``" });
|
|
106
|
+
inc += 1;
|
|
107
|
+
}
|
|
108
|
+
} else if (input[idx] === "\\") {
|
|
109
|
+
if (tok != null) {
|
|
110
|
+
result.push(tok);
|
|
111
|
+
tok = null;
|
|
112
|
+
}
|
|
113
|
+
result.push({ position: idx, value: "\\" });
|
|
114
|
+
escaped = !escaped;
|
|
115
|
+
} else if (asciiPunct.test(input[idx])) {
|
|
116
|
+
if (tok != null) {
|
|
117
|
+
result.push(tok);
|
|
118
|
+
tok = null;
|
|
119
|
+
}
|
|
120
|
+
result.push({ position: idx, value: input[idx] });
|
|
121
|
+
escaped = false;
|
|
122
|
+
} else if (escaped) {
|
|
123
|
+
result.push({ position: idx, value: input[idx] });
|
|
124
|
+
escaped = false;
|
|
125
|
+
} else if (tok == null) {
|
|
126
|
+
tok = { position: idx, value: input[idx] };
|
|
127
|
+
} else {
|
|
128
|
+
tok.value += input[idx];
|
|
129
|
+
}
|
|
130
|
+
idx += inc;
|
|
131
|
+
inc = 0;
|
|
132
|
+
}
|
|
133
|
+
if (tok != null) {
|
|
134
|
+
result.push(tok);
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// src/parse/base-token.ts
|
|
140
|
+
var BaseToken = class {
|
|
141
|
+
position;
|
|
142
|
+
type;
|
|
143
|
+
value;
|
|
144
|
+
constructor(options) {
|
|
145
|
+
this.position = options.position;
|
|
146
|
+
this.type = options.type || "UNKNOWN";
|
|
147
|
+
this.value = options.value;
|
|
148
|
+
}
|
|
149
|
+
toJSON() {
|
|
150
|
+
return {
|
|
151
|
+
position: this.position,
|
|
152
|
+
type: this.type,
|
|
153
|
+
value: this.value
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
async evaluate(options) {
|
|
157
|
+
if (options.onlyValidate) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
return this.value;
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// src/parse/sequence-token.ts
|
|
165
|
+
var SequenceToken = class extends BaseToken {
|
|
166
|
+
value;
|
|
167
|
+
constructor(options) {
|
|
168
|
+
super({
|
|
169
|
+
...options,
|
|
170
|
+
type: "LIST"
|
|
171
|
+
});
|
|
172
|
+
this.value = [];
|
|
173
|
+
}
|
|
174
|
+
add(token) {
|
|
175
|
+
if (token.type !== "TEXT" || !this.value.length || this.value[this.value.length - 1].type !== "TEXT") {
|
|
176
|
+
this.value.push(token);
|
|
177
|
+
} else {
|
|
178
|
+
this.value[this.value.length - 1].value += token.value;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
get unwrap() {
|
|
182
|
+
if (this.value.length === 1) {
|
|
183
|
+
return this.value[0];
|
|
184
|
+
}
|
|
185
|
+
return this;
|
|
186
|
+
}
|
|
187
|
+
toJSON() {
|
|
188
|
+
const unwrapped = this.unwrap;
|
|
189
|
+
if (unwrapped !== this) {
|
|
190
|
+
return unwrapped.toJSON();
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
position: this.position,
|
|
194
|
+
type: this.type,
|
|
195
|
+
value: this.value.map((token) => token.toJSON())
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
async evaluate(options) {
|
|
199
|
+
if (this.value == null || this.value.length === 0) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (this.value.length === 1) {
|
|
203
|
+
return this.value[0].evaluate(options || {});
|
|
204
|
+
}
|
|
205
|
+
return (await Promise.all(this.value.map((token) => token.evaluate(options || {})))).reduce((prev, curr) => {
|
|
206
|
+
if (prev == null) {
|
|
207
|
+
return curr;
|
|
208
|
+
}
|
|
209
|
+
if (curr == null) {
|
|
210
|
+
return prev;
|
|
211
|
+
}
|
|
212
|
+
return prev + curr;
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
// src/parse/root/token.ts
|
|
218
|
+
var RootToken = class extends SequenceToken {
|
|
219
|
+
lookups;
|
|
220
|
+
variables;
|
|
221
|
+
expression;
|
|
222
|
+
logicOperators;
|
|
223
|
+
comparisonOperators;
|
|
224
|
+
constructor(options) {
|
|
225
|
+
super({
|
|
226
|
+
position: 0
|
|
227
|
+
});
|
|
228
|
+
this.type = "ROOT";
|
|
229
|
+
this.lookups = options.lookups;
|
|
230
|
+
this.variables = options.variables;
|
|
231
|
+
this.logicOperators = options.logicalOperators || /* @__PURE__ */ new Map();
|
|
232
|
+
this.comparisonOperators = options.comparisonOperators || /* @__PURE__ */ new Map();
|
|
233
|
+
this.expression = options.expression;
|
|
234
|
+
}
|
|
235
|
+
toJSON() {
|
|
236
|
+
return super.toJSON();
|
|
237
|
+
}
|
|
238
|
+
async evaluate(options = {}) {
|
|
239
|
+
return super.evaluate({
|
|
240
|
+
...options,
|
|
241
|
+
lookups: this.lookups,
|
|
242
|
+
variables: this.variables,
|
|
243
|
+
logicalOperators: this.logicOperators,
|
|
244
|
+
comparisonOperators: this.comparisonOperators,
|
|
245
|
+
expression: this.expression
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
// src/parse/text/token.ts
|
|
251
|
+
var TextToken = class extends BaseToken {
|
|
252
|
+
value;
|
|
253
|
+
constructor(options) {
|
|
254
|
+
super({
|
|
255
|
+
...options,
|
|
256
|
+
type: "TEXT"
|
|
257
|
+
});
|
|
258
|
+
this.value = options.value || "";
|
|
259
|
+
}
|
|
260
|
+
toJSON() {
|
|
261
|
+
return {
|
|
262
|
+
position: this.position,
|
|
263
|
+
type: this.type,
|
|
264
|
+
value: this.value
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
// src/errors.ts
|
|
270
|
+
var ExpressionError = class extends Error {
|
|
271
|
+
/** When defined: where the error was encountered within the expression text */
|
|
272
|
+
position;
|
|
273
|
+
constructor(message, position) {
|
|
274
|
+
super(message);
|
|
275
|
+
Error.captureStackTrace(this, this.constructor);
|
|
276
|
+
this.name = "ExpressionError";
|
|
277
|
+
this.message = message;
|
|
278
|
+
this.position = position;
|
|
279
|
+
}
|
|
280
|
+
static get name() {
|
|
281
|
+
return "ExpressionError";
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
var ExpressionArgumentsError = class extends ExpressionError {
|
|
285
|
+
/** The index of the argument in the arguments list */
|
|
286
|
+
index;
|
|
287
|
+
/** The variable name the arguments list belongs to */
|
|
288
|
+
varname;
|
|
289
|
+
constructor(message, position, index, varname) {
|
|
290
|
+
super(message, position);
|
|
291
|
+
Error.captureStackTrace(this, this.constructor);
|
|
292
|
+
this.name = "ExpressionArgumentsError";
|
|
293
|
+
this.index = index || -1;
|
|
294
|
+
this.varname = varname;
|
|
295
|
+
}
|
|
296
|
+
static get name() {
|
|
297
|
+
return "ExpressionArgumentsError";
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
var ExpressionVariableError = class extends ExpressionError {
|
|
301
|
+
/** The associated variable name */
|
|
302
|
+
varname;
|
|
303
|
+
constructor(message, position, varname) {
|
|
304
|
+
super(message, position);
|
|
305
|
+
Error.captureStackTrace(this, this.constructor);
|
|
306
|
+
this.name = "ExpressionVariableError";
|
|
307
|
+
this.varname = varname;
|
|
308
|
+
}
|
|
309
|
+
static get name() {
|
|
310
|
+
return "ExpressionVariableError";
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
var ExpressionSyntaxError = class extends ExpressionError {
|
|
314
|
+
/** The character associated with the error */
|
|
315
|
+
character;
|
|
316
|
+
constructor(message, position, character) {
|
|
317
|
+
super(message, position);
|
|
318
|
+
Error.captureStackTrace(this, this.constructor);
|
|
319
|
+
this.name = "ExpressionSyntaxError";
|
|
320
|
+
this.character = character;
|
|
321
|
+
}
|
|
322
|
+
static get name() {
|
|
323
|
+
return "ExpressionSyntaxError";
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
// src/parse/lookup/token.ts
|
|
328
|
+
var LookupToken = class extends BaseToken {
|
|
329
|
+
prefix;
|
|
330
|
+
value;
|
|
331
|
+
arguments;
|
|
332
|
+
constructor(options) {
|
|
333
|
+
super({
|
|
334
|
+
...options,
|
|
335
|
+
type: "LOOKUP"
|
|
336
|
+
});
|
|
337
|
+
this.value = options.value;
|
|
338
|
+
this.prefix = options.prefix;
|
|
339
|
+
this.arguments = options.arguments;
|
|
340
|
+
}
|
|
341
|
+
toJSON() {
|
|
342
|
+
return {
|
|
343
|
+
position: this.position,
|
|
344
|
+
type: this.type,
|
|
345
|
+
prefix: this.prefix,
|
|
346
|
+
value: this.value,
|
|
347
|
+
arguments: this.arguments ? this.arguments.toJSON() : void 0
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
async evaluate(options) {
|
|
351
|
+
if (!options.lookups) {
|
|
352
|
+
throw new ExpressionVariableError(`lookup map invalid`, this.position, this.value);
|
|
353
|
+
}
|
|
354
|
+
const lookup = options.lookups.get(this.prefix);
|
|
355
|
+
if (lookup == null) {
|
|
356
|
+
throw new ExpressionVariableError(`unknown lookup prefix`, this.position, this.prefix);
|
|
357
|
+
}
|
|
358
|
+
const variable = await lookup(options.data || {}, this.value);
|
|
359
|
+
if (variable == null) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
if (options.preeval) {
|
|
363
|
+
await options.preeval(options.data || {}, variable);
|
|
364
|
+
}
|
|
365
|
+
if (variable.preeval) {
|
|
366
|
+
await variable.preeval(options.data || {}, variable);
|
|
367
|
+
}
|
|
368
|
+
let args = [];
|
|
369
|
+
if (this.arguments) {
|
|
370
|
+
args = await this.arguments.evaluate(options);
|
|
371
|
+
}
|
|
372
|
+
if (options.onlyValidate) {
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
if (variable.argsCheck) {
|
|
376
|
+
await variable.argsCheck(options.data || {}, ...args);
|
|
377
|
+
}
|
|
378
|
+
return variable.evaluate(options.data || {}, ...args);
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
// src/parse/arguments/token.ts
|
|
383
|
+
var ArgumentsToken = class extends BaseToken {
|
|
384
|
+
value;
|
|
385
|
+
constructor(options) {
|
|
386
|
+
super({
|
|
387
|
+
...options,
|
|
388
|
+
type: "ARGUMENTS_LIST"
|
|
389
|
+
});
|
|
390
|
+
this.value = options.value || [];
|
|
391
|
+
}
|
|
392
|
+
toJSON() {
|
|
393
|
+
return {
|
|
394
|
+
position: this.position,
|
|
395
|
+
type: this.type,
|
|
396
|
+
value: this.value.map((item) => item.toJSON())
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
async evaluate(options) {
|
|
400
|
+
return Promise.all(this.value.map((item) => item.evaluate(options)));
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
// src/parse/text/escape.ts
|
|
405
|
+
var escape_default = (tokens, cursor, escapeChars) => {
|
|
406
|
+
const count = tokens.length;
|
|
407
|
+
if (cursor + 1 >= count || tokens[cursor].value != "\\") {
|
|
408
|
+
return [false];
|
|
409
|
+
}
|
|
410
|
+
if (escapeChars == null) {
|
|
411
|
+
escapeChars = '"$[,]\\rnt`';
|
|
412
|
+
}
|
|
413
|
+
if (escapeChars.includes("`") && tokens[cursor + 1].value === "`" && tokens[cursor + 2].value === "`") {
|
|
414
|
+
return [true, cursor + 3, { position: cursor, value: "``" }];
|
|
415
|
+
}
|
|
416
|
+
if (!escapeChars.includes(tokens[cursor + 1].value)) {
|
|
417
|
+
return [true, cursor + 1, { position: cursor, value: "\\" }];
|
|
418
|
+
}
|
|
419
|
+
cursor += 1;
|
|
420
|
+
const token = { ...tokens[cursor] };
|
|
421
|
+
switch (token.value) {
|
|
422
|
+
case "n":
|
|
423
|
+
token.value = "\n";
|
|
424
|
+
break;
|
|
425
|
+
case "r":
|
|
426
|
+
token.value = "\r";
|
|
427
|
+
break;
|
|
428
|
+
case "t":
|
|
429
|
+
token.value = " ";
|
|
430
|
+
break;
|
|
431
|
+
}
|
|
432
|
+
return [true, cursor + 1, token];
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
// src/parse/text/quote.ts
|
|
436
|
+
var quote_default = (tokens, cursor) => {
|
|
437
|
+
const count = tokens.length;
|
|
438
|
+
if (cursor >= count || tokens[cursor] == null || tokens[cursor].value !== '"') {
|
|
439
|
+
return [false];
|
|
440
|
+
}
|
|
441
|
+
const start = cursor;
|
|
442
|
+
cursor += 1;
|
|
443
|
+
let text = "";
|
|
444
|
+
while (cursor < count) {
|
|
445
|
+
if (tokens[cursor].value === '"') {
|
|
446
|
+
return [
|
|
447
|
+
true,
|
|
448
|
+
cursor + 1,
|
|
449
|
+
new TextToken({
|
|
450
|
+
position: start,
|
|
451
|
+
value: text
|
|
452
|
+
})
|
|
453
|
+
];
|
|
454
|
+
}
|
|
455
|
+
const [tokenized, tokenizeCursor, tokenizeResult] = escape_default(tokens, cursor, '\\"nrt');
|
|
456
|
+
if (tokenized) {
|
|
457
|
+
cursor = tokenizeCursor;
|
|
458
|
+
text += tokenizeResult.value;
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
text += tokens[cursor].value;
|
|
462
|
+
cursor += 1;
|
|
463
|
+
}
|
|
464
|
+
throw new ExpressionSyntaxError("End quote missing", tokens[start].position);
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
// src/parse/if/token.ts
|
|
468
|
+
var IfToken = class extends BaseToken {
|
|
469
|
+
value;
|
|
470
|
+
whenTrue;
|
|
471
|
+
whenFalse;
|
|
472
|
+
constructor(options) {
|
|
473
|
+
super({
|
|
474
|
+
position: options.position,
|
|
475
|
+
type: "IF"
|
|
476
|
+
});
|
|
477
|
+
this.value = options.value;
|
|
478
|
+
this.whenTrue = options.whenTrue;
|
|
479
|
+
this.whenFalse = options.whenFalse;
|
|
480
|
+
}
|
|
481
|
+
toJSON() {
|
|
482
|
+
return {
|
|
483
|
+
position: this.position,
|
|
484
|
+
type: this.type,
|
|
485
|
+
value: this.value.toJSON(),
|
|
486
|
+
whenTrue: this.whenTrue.toJSON(),
|
|
487
|
+
whenFalse: this.whenFalse ? this.whenFalse.toJSON() : void 0
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
async evaluate(options) {
|
|
491
|
+
const result = await this.value.evaluate(options);
|
|
492
|
+
if (options.onlyValidate) {
|
|
493
|
+
await this.whenTrue.evaluate(options);
|
|
494
|
+
if (this.whenFalse) {
|
|
495
|
+
await this.whenFalse.evaluate(options);
|
|
496
|
+
}
|
|
497
|
+
} else if (result) {
|
|
498
|
+
return this.whenTrue.evaluate(options);
|
|
499
|
+
}
|
|
500
|
+
if (this.whenFalse) {
|
|
501
|
+
return this.whenFalse.evaluate(options);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
// src/parse/comparison/operators.ts
|
|
507
|
+
var toNumber = (data, v1, v2) => {
|
|
508
|
+
if (v1 === "" || v2 === "") {
|
|
509
|
+
return [v1, v2];
|
|
510
|
+
}
|
|
511
|
+
const v1Num = Number(v1);
|
|
512
|
+
if (!Number.isFinite(v1Num)) {
|
|
513
|
+
return [v1, v2];
|
|
514
|
+
}
|
|
515
|
+
const v2Num = Number(v2);
|
|
516
|
+
if (!Number.isFinite(v2Num)) {
|
|
517
|
+
return [v1, v2];
|
|
518
|
+
}
|
|
519
|
+
return [v1Num, v2Num];
|
|
520
|
+
};
|
|
521
|
+
var isStrictEqual = (data, v1, v2) => {
|
|
522
|
+
[v1, v2] = toNumber(data, v1, v2);
|
|
523
|
+
return v1 === v2;
|
|
524
|
+
};
|
|
525
|
+
var isTruthy = (data, v1) => {
|
|
526
|
+
return v1 != null && v1 !== false && v1 !== 0 && v1 !== "";
|
|
527
|
+
};
|
|
528
|
+
var operators_default = /* @__PURE__ */ new Map([
|
|
529
|
+
["istruthy", {
|
|
530
|
+
maxArgumentsCount: 1,
|
|
531
|
+
evaluate: isTruthy
|
|
532
|
+
}],
|
|
533
|
+
["!istruthy", {
|
|
534
|
+
maxArgumentsCount: 1,
|
|
535
|
+
evaluate: (data, v1) => !isTruthy(data, v1)
|
|
536
|
+
}],
|
|
537
|
+
["===", {
|
|
538
|
+
minArgumentsCount: 2,
|
|
539
|
+
evaluate: isStrictEqual
|
|
540
|
+
}],
|
|
541
|
+
["!==", {
|
|
542
|
+
minArgumentsCount: 2,
|
|
543
|
+
evaluate: (data, v1, v2) => !isStrictEqual(data, v1, v2)
|
|
544
|
+
}],
|
|
545
|
+
["<", {
|
|
546
|
+
minArgumentsCount: 2,
|
|
547
|
+
evaluate: (data, v1, v2) => {
|
|
548
|
+
[v1, v2] = toNumber(data, v1, v2);
|
|
549
|
+
if (typeof v1 !== "number" || typeof v2 !== "number") {
|
|
550
|
+
return false;
|
|
551
|
+
}
|
|
552
|
+
return v1 < v2;
|
|
553
|
+
}
|
|
554
|
+
}],
|
|
555
|
+
["<=", {
|
|
556
|
+
minArgumentsCount: 2,
|
|
557
|
+
evaluate: (data, v1, v2) => {
|
|
558
|
+
[v1, v2] = toNumber(data, v1, v2);
|
|
559
|
+
if (typeof v1 !== "number" || typeof v2 !== "number") {
|
|
560
|
+
return false;
|
|
561
|
+
}
|
|
562
|
+
return v1 <= v2;
|
|
563
|
+
}
|
|
564
|
+
}],
|
|
565
|
+
[">", {
|
|
566
|
+
minArgumentsCount: 2,
|
|
567
|
+
evaluate: (data, v1, v2) => {
|
|
568
|
+
[v1, v2] = toNumber(data, v1, v2);
|
|
569
|
+
if (typeof v1 !== "number" || typeof v2 !== "number") {
|
|
570
|
+
return false;
|
|
571
|
+
}
|
|
572
|
+
return v1 > v2;
|
|
573
|
+
}
|
|
574
|
+
}],
|
|
575
|
+
[">=", {
|
|
576
|
+
minArgumentsCount: 2,
|
|
577
|
+
evaluate: (data, v1, v2) => {
|
|
578
|
+
[v1, v2] = toNumber(data, v1, v2);
|
|
579
|
+
if (typeof v1 !== "number" || typeof v2 !== "number") {
|
|
580
|
+
return false;
|
|
581
|
+
}
|
|
582
|
+
return v1 >= v2;
|
|
583
|
+
}
|
|
584
|
+
}]
|
|
585
|
+
]);
|
|
586
|
+
|
|
587
|
+
// src/parse/comparison/token.ts
|
|
588
|
+
var ComparisonToken = class extends BaseToken {
|
|
589
|
+
value;
|
|
590
|
+
left;
|
|
591
|
+
right;
|
|
592
|
+
constructor(options) {
|
|
593
|
+
super({
|
|
594
|
+
...options,
|
|
595
|
+
type: "COMPARISON"
|
|
596
|
+
});
|
|
597
|
+
this.value = options.value;
|
|
598
|
+
this.left = options.left;
|
|
599
|
+
this.right = options.right;
|
|
600
|
+
}
|
|
601
|
+
toJSON() {
|
|
602
|
+
return {
|
|
603
|
+
position: this.position,
|
|
604
|
+
type: this.type,
|
|
605
|
+
value: this.value,
|
|
606
|
+
left: this.left.toJSON(),
|
|
607
|
+
right: this.right ? this.right.toJSON() : void 0
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
async evaluate(options) {
|
|
611
|
+
if (!this.value || this.value === "") {
|
|
612
|
+
this.value = "istruthy";
|
|
613
|
+
}
|
|
614
|
+
const operator = operators_default.get(this.value);
|
|
615
|
+
if (operator == null) {
|
|
616
|
+
return false;
|
|
617
|
+
}
|
|
618
|
+
const left = await this.left.evaluate(options);
|
|
619
|
+
let right;
|
|
620
|
+
if (this.right) {
|
|
621
|
+
right = await this.right.evaluate(options);
|
|
622
|
+
}
|
|
623
|
+
if (options.onlyValidate) {
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
return operator.evaluate(options.data || {}, left, right);
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
// src/parse/variable/token.ts
|
|
631
|
+
var VariableToken = class extends BaseToken {
|
|
632
|
+
value;
|
|
633
|
+
arguments;
|
|
634
|
+
constructor(options) {
|
|
635
|
+
super({
|
|
636
|
+
...options,
|
|
637
|
+
type: "VARIABLE"
|
|
638
|
+
});
|
|
639
|
+
this.value = options.value || "";
|
|
640
|
+
this.arguments = options.arguments;
|
|
641
|
+
}
|
|
642
|
+
toJSON() {
|
|
643
|
+
return {
|
|
644
|
+
position: this.position,
|
|
645
|
+
type: this.type,
|
|
646
|
+
value: this.value,
|
|
647
|
+
arguments: this.arguments ? this.arguments.toJSON() : void 0
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
async evaluate(options) {
|
|
651
|
+
if (!options.variables || !options.variables.has(this.value)) {
|
|
652
|
+
throw new Error("unknown variable");
|
|
653
|
+
}
|
|
654
|
+
const variable = options.variables.get(this.value);
|
|
655
|
+
if (options.preeval) {
|
|
656
|
+
await options.preeval(options.data || {}, variable);
|
|
657
|
+
}
|
|
658
|
+
if (variable.preeval) {
|
|
659
|
+
await variable.preeval(options.data || {}, variable);
|
|
660
|
+
}
|
|
661
|
+
let args = [];
|
|
662
|
+
if (this.arguments) {
|
|
663
|
+
args = await this.arguments.evaluate(options);
|
|
664
|
+
}
|
|
665
|
+
if (variable.argsCheck) {
|
|
666
|
+
await variable.argsCheck(options.data || {}, ...args);
|
|
667
|
+
}
|
|
668
|
+
if (options.onlyValidate) {
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
return variable.evaluate(options.data || {}, ...args);
|
|
672
|
+
}
|
|
673
|
+
};
|
|
674
|
+
|
|
675
|
+
// src/parse/variable/tokenize.ts
|
|
676
|
+
var tokenize_default2 = (tokens, cursor, options) => {
|
|
677
|
+
const count = tokens.length;
|
|
678
|
+
if (cursor + 1 >= count || tokens[cursor].value !== "$") {
|
|
679
|
+
return [false];
|
|
680
|
+
}
|
|
681
|
+
const start = cursor;
|
|
682
|
+
cursor += 1;
|
|
683
|
+
const name = tokens[cursor].value;
|
|
684
|
+
if (!/^[a-z][a-z\d]*/i.test(name)) {
|
|
685
|
+
return [false];
|
|
686
|
+
}
|
|
687
|
+
if (!options.variables.has(name)) {
|
|
688
|
+
throw new ExpressionVariableError("unknown variable", tokens[cursor].position, name);
|
|
689
|
+
}
|
|
690
|
+
cursor += 1;
|
|
691
|
+
const [tokenized, tCursor, tResult] = tokenize_default(tokens, cursor, options);
|
|
692
|
+
if (tokenized) {
|
|
693
|
+
cursor = tCursor;
|
|
694
|
+
}
|
|
695
|
+
return [
|
|
696
|
+
true,
|
|
697
|
+
cursor,
|
|
698
|
+
new VariableToken({
|
|
699
|
+
position: start,
|
|
700
|
+
value: name,
|
|
701
|
+
arguments: tResult
|
|
702
|
+
})
|
|
703
|
+
];
|
|
704
|
+
};
|
|
705
|
+
|
|
706
|
+
// src/parse/whitespace/tokenize.ts
|
|
707
|
+
var tokenize_default3 = ((tokens, cursor) => {
|
|
708
|
+
const count = tokens.length;
|
|
709
|
+
if (cursor >= count) {
|
|
710
|
+
return [false];
|
|
711
|
+
}
|
|
712
|
+
let ws = "";
|
|
713
|
+
let index = cursor;
|
|
714
|
+
while (index < count && (tokens[index].value === " " || tokens[index].value === "\n" || tokens[index].value === "\r" || tokens[index].value === " " || tokens[index].value === "\b" || tokens[index].value === "\f")) {
|
|
715
|
+
ws += tokens[index].value;
|
|
716
|
+
index += 1;
|
|
717
|
+
}
|
|
718
|
+
if (cursor === index) {
|
|
719
|
+
return [false];
|
|
720
|
+
}
|
|
721
|
+
return [true, index, ws];
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
// src/parse/comparison/tokenize.ts
|
|
725
|
+
var tokenizeOperator = (tokens, cursor, options) => {
|
|
726
|
+
const count = tokens.length;
|
|
727
|
+
if (cursor >= count || tokens[cursor].value === "," || tokens[cursor].value === "]" || /^\s/.test(tokens[cursor].value)) {
|
|
728
|
+
return [false];
|
|
729
|
+
}
|
|
730
|
+
let operator = "";
|
|
731
|
+
if (tokens[cursor].value === "!") {
|
|
732
|
+
operator = "!";
|
|
733
|
+
cursor += 1;
|
|
734
|
+
if (cursor >= count || tokens[cursor].value === "," || tokens[cursor].value === "]" || /^\s/.test(tokens[cursor].value)) {
|
|
735
|
+
return [false];
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
if (/^[a-z]+$/i.test(tokens[cursor].value)) {
|
|
739
|
+
operator += tokens[cursor].value.toLowerCase();
|
|
740
|
+
cursor += 1;
|
|
741
|
+
} else {
|
|
742
|
+
let operatorAccumulator = operator;
|
|
743
|
+
let tmpCursor = cursor;
|
|
744
|
+
while (tmpCursor < count) {
|
|
745
|
+
if (!/^[\x21-\x2F\x3A-\x40\x5E-\x60]$/.test(tokens[tmpCursor].value)) {
|
|
746
|
+
break;
|
|
747
|
+
}
|
|
748
|
+
operatorAccumulator += tokens[tmpCursor].value;
|
|
749
|
+
tmpCursor += 1;
|
|
750
|
+
if (options.operators.has(operatorAccumulator)) {
|
|
751
|
+
operator = operatorAccumulator;
|
|
752
|
+
cursor = tmpCursor;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
if (cursor >= count || !options.operators.has(operator) || tokens[cursor].value !== "," && tokens[cursor].value !== "]" && !/^\s+$/.test(tokens[cursor].value)) {
|
|
757
|
+
return [false];
|
|
758
|
+
}
|
|
759
|
+
const [wsRem, wsCursor] = tokenize_default3(tokens, cursor);
|
|
760
|
+
if (wsRem) {
|
|
761
|
+
cursor = wsCursor;
|
|
762
|
+
}
|
|
763
|
+
return [true, cursor, operator];
|
|
764
|
+
};
|
|
765
|
+
var tokenize_default6 = (tokens, cursor, options) => {
|
|
766
|
+
const count = tokens.length;
|
|
767
|
+
if (cursor >= count || tokens[cursor].value === "," || tokens[cursor].value === "]") {
|
|
768
|
+
return [false];
|
|
769
|
+
}
|
|
770
|
+
const mergedOperators = new Map(operators_default);
|
|
771
|
+
if (options.comparisonOperators) {
|
|
772
|
+
options.comparisonOperators.forEach((operator2, key) => {
|
|
773
|
+
mergedOperators.set(key, operator2);
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
const start = tokens[cursor].position;
|
|
777
|
+
const consumeWS = () => {
|
|
778
|
+
const [wsRem, wsCursor, wsResult] = tokenize_default3(tokens, cursor);
|
|
779
|
+
if (wsRem) {
|
|
780
|
+
cursor = wsCursor;
|
|
781
|
+
return wsResult;
|
|
782
|
+
}
|
|
783
|
+
return "";
|
|
784
|
+
};
|
|
785
|
+
const left = new SequenceToken({ position: start });
|
|
786
|
+
let operator;
|
|
787
|
+
let right;
|
|
788
|
+
while (cursor < count) {
|
|
789
|
+
const position = cursor;
|
|
790
|
+
const ws = consumeWS();
|
|
791
|
+
if (cursor >= count || tokens[cursor].value === "," || tokens[cursor].value === "]") {
|
|
792
|
+
break;
|
|
793
|
+
}
|
|
794
|
+
if (left.value.length > 0 && operator == null && ws !== "") {
|
|
795
|
+
const [opTokenized, opCursor, opResult] = tokenizeOperator(tokens, cursor, { ...options, operators: mergedOperators });
|
|
796
|
+
if (opTokenized) {
|
|
797
|
+
if (left.value.length === 0) {
|
|
798
|
+
throw new ExpressionSyntaxError("left operand not specified", start);
|
|
799
|
+
}
|
|
800
|
+
cursor = opCursor;
|
|
801
|
+
operator = opResult;
|
|
802
|
+
right = new SequenceToken({ position: cursor });
|
|
803
|
+
continue;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
const parts = right ? right : left;
|
|
807
|
+
if (ws !== "") {
|
|
808
|
+
parts.add(new TextToken({ position, value: ws }));
|
|
809
|
+
}
|
|
810
|
+
const [eTokenized, eCursor, eResult] = escape_default(tokens, cursor, '"$,\\`]');
|
|
811
|
+
if (eTokenized) {
|
|
812
|
+
parts.add(new TextToken({ position, value: eResult.value }));
|
|
813
|
+
cursor = eCursor;
|
|
814
|
+
}
|
|
815
|
+
let [tokenized, tCursor, tResult] = quote_default(tokens, cursor);
|
|
816
|
+
if (tokenized) {
|
|
817
|
+
parts.add(tResult);
|
|
818
|
+
cursor = tCursor;
|
|
819
|
+
continue;
|
|
820
|
+
}
|
|
821
|
+
[tokenized, tCursor, tResult] = tokenize_default5(tokens, cursor, options);
|
|
822
|
+
if (tokenized) {
|
|
823
|
+
parts.add(tResult);
|
|
824
|
+
cursor = tCursor;
|
|
825
|
+
continue;
|
|
826
|
+
}
|
|
827
|
+
[tokenized, tCursor, tResult] = tokenize_default4(tokens, cursor, options);
|
|
828
|
+
if (tokenized) {
|
|
829
|
+
parts.add(tResult);
|
|
830
|
+
cursor = tCursor;
|
|
831
|
+
continue;
|
|
832
|
+
}
|
|
833
|
+
[tokenized, tCursor, tResult] = tokenize_default2(tokens, cursor, options);
|
|
834
|
+
if (tokenized) {
|
|
835
|
+
parts.add(tResult);
|
|
836
|
+
cursor = tCursor;
|
|
837
|
+
continue;
|
|
838
|
+
}
|
|
839
|
+
parts.add(new TextToken(tokens[cursor]));
|
|
840
|
+
cursor += 1;
|
|
841
|
+
}
|
|
842
|
+
if (!left.value.length) {
|
|
843
|
+
return [false];
|
|
844
|
+
}
|
|
845
|
+
operator = operator || "istruthy";
|
|
846
|
+
if (operators_default.get(operator)?.maxArgumentsCount === 1 && right != null && (!(right instanceof SequenceToken) || right.value.length !== 0)) {
|
|
847
|
+
throw new ExpressionArgumentsError(`comparison operator ${operator} must not have a right-hand-side value`);
|
|
848
|
+
}
|
|
849
|
+
if (operators_default.get(operator)?.minArgumentsCount === 2 && (right == null || right instanceof SequenceToken && right.value.length === 0)) {
|
|
850
|
+
throw new ExpressionArgumentsError(`comparison operator ${operator} requires a right-hand-side value`);
|
|
851
|
+
}
|
|
852
|
+
return [
|
|
853
|
+
true,
|
|
854
|
+
cursor,
|
|
855
|
+
new ComparisonToken({
|
|
856
|
+
position: start,
|
|
857
|
+
value: operator,
|
|
858
|
+
left: left.unwrap,
|
|
859
|
+
right: right ? right.unwrap : void 0
|
|
860
|
+
})
|
|
861
|
+
];
|
|
862
|
+
};
|
|
863
|
+
|
|
864
|
+
// src/parse/logic/operators.ts
|
|
865
|
+
var not = (data, arg) => arg == null || arg === false || arg === 0 || arg === "";
|
|
866
|
+
var operators_default2 = /* @__PURE__ */ new Map([
|
|
867
|
+
["not", {
|
|
868
|
+
minArgumentsCount: 1,
|
|
869
|
+
maxArgumentsCount: 1,
|
|
870
|
+
evaluate: not
|
|
871
|
+
}],
|
|
872
|
+
["and", {
|
|
873
|
+
minArgumentsCount: 1,
|
|
874
|
+
evaluate: (data, ...args) => {
|
|
875
|
+
if (args == null || !args.length) {
|
|
876
|
+
return false;
|
|
877
|
+
}
|
|
878
|
+
return !args.some((item) => not(data, item));
|
|
879
|
+
}
|
|
880
|
+
}],
|
|
881
|
+
["or", {
|
|
882
|
+
minArgumentsCount: 1,
|
|
883
|
+
evaluate: (data, ...args) => {
|
|
884
|
+
if (args == null || !args.length) {
|
|
885
|
+
return false;
|
|
886
|
+
}
|
|
887
|
+
return args.some((item) => !not(data, item));
|
|
888
|
+
}
|
|
889
|
+
}]
|
|
890
|
+
]);
|
|
891
|
+
|
|
892
|
+
// src/parse/logic/token.ts
|
|
893
|
+
var LogicToken = class extends BaseToken {
|
|
894
|
+
value;
|
|
895
|
+
arguments;
|
|
896
|
+
constructor(options) {
|
|
897
|
+
super({
|
|
898
|
+
...options,
|
|
899
|
+
type: "LOGIC"
|
|
900
|
+
});
|
|
901
|
+
this.value = options.value;
|
|
902
|
+
this.arguments = options.arguments;
|
|
903
|
+
}
|
|
904
|
+
toJSON() {
|
|
905
|
+
return {
|
|
906
|
+
position: this.position,
|
|
907
|
+
type: this.type,
|
|
908
|
+
value: this.value,
|
|
909
|
+
arguments: this.arguments.toJSON()
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
async evaluate(options) {
|
|
913
|
+
let operator;
|
|
914
|
+
if (options.logicalOperators?.has(this.value)) {
|
|
915
|
+
operator = options.logicalOperators.get(this.value);
|
|
916
|
+
} else if (operators_default2.has(this.value)) {
|
|
917
|
+
operator = operators_default2.get(this.value);
|
|
918
|
+
} else {
|
|
919
|
+
return false;
|
|
920
|
+
}
|
|
921
|
+
const args = await this.arguments.evaluate(options);
|
|
922
|
+
if (operator.argsCheck) {
|
|
923
|
+
operator.argsCheck(options.data || {}, ...args);
|
|
924
|
+
}
|
|
925
|
+
if (options.onlyValidate) {
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
return operator.evaluate(options.data || {}, ...args);
|
|
929
|
+
}
|
|
930
|
+
};
|
|
931
|
+
|
|
932
|
+
// src/parse/logic/tokenize.ts
|
|
933
|
+
var tokenizeLogicOperator = (tokens, cursor, options) => {
|
|
934
|
+
const count = tokens.length;
|
|
935
|
+
if (cursor + 1 >= count || tokens[cursor].value !== "$") {
|
|
936
|
+
return [false];
|
|
937
|
+
}
|
|
938
|
+
const start = tokens[cursor].position;
|
|
939
|
+
cursor += 1;
|
|
940
|
+
const mergedOperators = new Map(operators_default2);
|
|
941
|
+
if (options.logicalOperators) {
|
|
942
|
+
options.logicalOperators.forEach((operator2, key) => {
|
|
943
|
+
mergedOperators.set(key, operator2);
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
let operator;
|
|
947
|
+
if (mergedOperators.has(tokens[cursor].value)) {
|
|
948
|
+
operator = tokens[cursor].value;
|
|
949
|
+
cursor += 1;
|
|
950
|
+
if (cursor >= count) {
|
|
951
|
+
return [false];
|
|
952
|
+
}
|
|
953
|
+
} else {
|
|
954
|
+
return [false];
|
|
955
|
+
}
|
|
956
|
+
if (tokens[cursor].value !== "[") {
|
|
957
|
+
throw new ExpressionSyntaxError("Logic Operators require atleast one argument", tokens[cursor].position);
|
|
958
|
+
}
|
|
959
|
+
const argsStart = tokens[cursor].position;
|
|
960
|
+
cursor += 1;
|
|
961
|
+
const consumeWS = (notEnd) => {
|
|
962
|
+
const [tokenized, tCursor, ws] = tokenize_default3(tokens, cursor);
|
|
963
|
+
if (tokenized) {
|
|
964
|
+
cursor = tCursor;
|
|
965
|
+
}
|
|
966
|
+
if (notEnd && cursor >= count) {
|
|
967
|
+
throw new ExpressionSyntaxError("unexpected end of expression");
|
|
968
|
+
}
|
|
969
|
+
return ws;
|
|
970
|
+
};
|
|
971
|
+
consumeWS(true);
|
|
972
|
+
const args = [];
|
|
973
|
+
while (cursor < count) {
|
|
974
|
+
consumeWS();
|
|
975
|
+
if (cursor >= count) {
|
|
976
|
+
break;
|
|
977
|
+
}
|
|
978
|
+
let [tokenize3, tCursor, tResult] = tokenizeLogicOperator(tokens, cursor, options);
|
|
979
|
+
if (!tokenize3) {
|
|
980
|
+
[tokenize3, tCursor, tResult] = tokenize_default6(tokens, cursor, options);
|
|
981
|
+
}
|
|
982
|
+
if (!tokenize3) {
|
|
983
|
+
throw new ExpressionArgumentsError("conditional expected", tokens[cursor].position, args.length);
|
|
984
|
+
}
|
|
985
|
+
args.push(tResult);
|
|
986
|
+
cursor = tCursor;
|
|
987
|
+
if (tokens[cursor].value === ",") {
|
|
988
|
+
cursor += 1;
|
|
989
|
+
continue;
|
|
990
|
+
}
|
|
991
|
+
if (tokens[cursor].value === "]") {
|
|
992
|
+
const opDef = operators_default2.get(operator);
|
|
993
|
+
if (opDef.minArgumentsCount != null && args.length < opDef.minArgumentsCount) {
|
|
994
|
+
throw new ExpressionArgumentsError(`$${operator} expects atleast ${opDef.minArgumentsCount} argument(s)`);
|
|
995
|
+
}
|
|
996
|
+
if (opDef.maxArgumentsCount != null && args.length > opDef.maxArgumentsCount) {
|
|
997
|
+
throw new ExpressionArgumentsError(`$${operator} expects at most ${opDef.maxArgumentsCount} argument(s)`);
|
|
998
|
+
}
|
|
999
|
+
return [
|
|
1000
|
+
true,
|
|
1001
|
+
cursor + 1,
|
|
1002
|
+
new LogicToken({
|
|
1003
|
+
position: start,
|
|
1004
|
+
value: operator,
|
|
1005
|
+
arguments: new ArgumentsToken({
|
|
1006
|
+
position: argsStart,
|
|
1007
|
+
value: args
|
|
1008
|
+
})
|
|
1009
|
+
})
|
|
1010
|
+
];
|
|
1011
|
+
}
|
|
1012
|
+
throw new ExpressionSyntaxError("unexpected token", tokens[cursor].position);
|
|
1013
|
+
}
|
|
1014
|
+
throw new ExpressionSyntaxError("unexpected end of expression", count);
|
|
1015
|
+
};
|
|
1016
|
+
var tokenize_default7 = tokenizeLogicOperator;
|
|
1017
|
+
|
|
1018
|
+
// src/parse/if/tokenize.ts
|
|
1019
|
+
var tokenize_default4 = (tokens, cursor, options) => {
|
|
1020
|
+
const count = tokens.length;
|
|
1021
|
+
if (cursor + 1 >= count || tokens[cursor].value !== "$" || tokens[cursor + 1].value !== "if") {
|
|
1022
|
+
return [false];
|
|
1023
|
+
}
|
|
1024
|
+
const start = tokens[cursor].position;
|
|
1025
|
+
cursor += 2;
|
|
1026
|
+
if (cursor >= count) {
|
|
1027
|
+
throw new ExpressionArgumentsError("$if requires atleast 2 arguments", start, 0, "if");
|
|
1028
|
+
}
|
|
1029
|
+
if (tokens[cursor].value !== "[") {
|
|
1030
|
+
throw new ExpressionArgumentsError("$if requires atleast 2 arguments", tokens[cursor].position, 0, "if");
|
|
1031
|
+
}
|
|
1032
|
+
cursor += 1;
|
|
1033
|
+
const consumeWS = (notEnd) => {
|
|
1034
|
+
const [tokenized, tCursor2, ws] = tokenize_default3(tokens, cursor);
|
|
1035
|
+
if (tokenized) {
|
|
1036
|
+
cursor = tCursor2;
|
|
1037
|
+
}
|
|
1038
|
+
if (notEnd && cursor >= count) {
|
|
1039
|
+
throw new ExpressionSyntaxError("unexpected end of expression");
|
|
1040
|
+
}
|
|
1041
|
+
return ws;
|
|
1042
|
+
};
|
|
1043
|
+
consumeWS(true);
|
|
1044
|
+
let [tokenize3, tCursor, tResult] = tokenize_default7(tokens, cursor, options);
|
|
1045
|
+
if (!tokenize3) {
|
|
1046
|
+
[tokenize3, tCursor, tResult] = tokenize_default6(tokens, cursor, options);
|
|
1047
|
+
if (!tokenize3) {
|
|
1048
|
+
throw new ExpressionArgumentsError("$if requires the first argument to be a conditional", tokens[cursor].position, 0, "if");
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
const condition = tResult;
|
|
1052
|
+
cursor = tCursor;
|
|
1053
|
+
if (cursor >= count) {
|
|
1054
|
+
throw new ExpressionSyntaxError("unexpected end of expression");
|
|
1055
|
+
}
|
|
1056
|
+
if (tokens[cursor].value === "]") {
|
|
1057
|
+
throw new ExpressionArgumentsError("$if requires atleast 2 arguments", tokens[cursor].position, 2, "if");
|
|
1058
|
+
}
|
|
1059
|
+
if (tokens[cursor].value !== ",") {
|
|
1060
|
+
throw new ExpressionSyntaxError("expected end of conditional", tokens[cursor].position);
|
|
1061
|
+
}
|
|
1062
|
+
cursor += 1;
|
|
1063
|
+
consumeWS(true);
|
|
1064
|
+
if (cursor >= count) {
|
|
1065
|
+
throw new ExpressionSyntaxError("unexpected end of expression");
|
|
1066
|
+
}
|
|
1067
|
+
const [wtTokenize, wtCursor, whenTrue] = argument_default(tokens, cursor, options);
|
|
1068
|
+
if (!wtTokenize) {
|
|
1069
|
+
throw new ExpressionArgumentsError("$if must have atleast a condition and 1 parameter", tokens[cursor].position, 1, "if");
|
|
1070
|
+
} else {
|
|
1071
|
+
cursor = wtCursor;
|
|
1072
|
+
if (cursor >= count) {
|
|
1073
|
+
throw new ExpressionSyntaxError("unexpected end of expression");
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
let wfTokenize, wfCursor, whenFalse;
|
|
1077
|
+
if (tokens[cursor].value === ",") {
|
|
1078
|
+
cursor += 1;
|
|
1079
|
+
consumeWS(true);
|
|
1080
|
+
if (tokens[cursor].value !== "]") {
|
|
1081
|
+
[wfTokenize, wfCursor, whenFalse] = argument_default(tokens, cursor, options);
|
|
1082
|
+
if (!wfTokenize) {
|
|
1083
|
+
throw new ExpressionSyntaxError("expected 3rd parameter");
|
|
1084
|
+
}
|
|
1085
|
+
cursor = wfCursor;
|
|
1086
|
+
if (cursor >= count) {
|
|
1087
|
+
throw new ExpressionSyntaxError("unexpected end of expression");
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
if (tokens[cursor].value !== "]") {
|
|
1092
|
+
throw new ExpressionSyntaxError("expected end of arguments list", tokens[cursor].position);
|
|
1093
|
+
}
|
|
1094
|
+
return [
|
|
1095
|
+
true,
|
|
1096
|
+
cursor + 1,
|
|
1097
|
+
new IfToken({
|
|
1098
|
+
position: start,
|
|
1099
|
+
value: condition,
|
|
1100
|
+
whenTrue,
|
|
1101
|
+
whenFalse
|
|
1102
|
+
})
|
|
1103
|
+
];
|
|
1104
|
+
};
|
|
1105
|
+
|
|
1106
|
+
// src/parse/arguments/argument.ts
|
|
1107
|
+
var argument_default = (tokens, cursor, options) => {
|
|
1108
|
+
const count = tokens.length;
|
|
1109
|
+
if (cursor >= count) {
|
|
1110
|
+
return [false];
|
|
1111
|
+
}
|
|
1112
|
+
const start = tokens[cursor].position;
|
|
1113
|
+
const consumeWS = (notEnd) => {
|
|
1114
|
+
const [tokenized, tCursor, ws] = tokenize_default3(tokens, cursor);
|
|
1115
|
+
if (tokenized) {
|
|
1116
|
+
cursor = tCursor;
|
|
1117
|
+
}
|
|
1118
|
+
if (notEnd && cursor >= count) {
|
|
1119
|
+
throw new ExpressionSyntaxError("unexpected end of expression");
|
|
1120
|
+
}
|
|
1121
|
+
return ws || "";
|
|
1122
|
+
};
|
|
1123
|
+
consumeWS();
|
|
1124
|
+
if (cursor >= count) {
|
|
1125
|
+
return [false];
|
|
1126
|
+
}
|
|
1127
|
+
const parts = new SequenceToken({ position: start });
|
|
1128
|
+
while (cursor < count) {
|
|
1129
|
+
const position = tokens[cursor].position;
|
|
1130
|
+
const whitespace = consumeWS();
|
|
1131
|
+
if (cursor >= count) {
|
|
1132
|
+
break;
|
|
1133
|
+
}
|
|
1134
|
+
if (tokens[cursor].value === "]" || tokens[cursor].value === ",") {
|
|
1135
|
+
return [true, cursor, parts.unwrap];
|
|
1136
|
+
}
|
|
1137
|
+
if (whitespace !== "") {
|
|
1138
|
+
parts.add(new TextToken({ position, value: whitespace }));
|
|
1139
|
+
}
|
|
1140
|
+
const [eTokenized, eCursor, eResult] = escape_default(tokens, cursor, '"$,\\`]');
|
|
1141
|
+
if (eTokenized) {
|
|
1142
|
+
parts.add(new TextToken({ position, value: eResult.value }));
|
|
1143
|
+
cursor = eCursor;
|
|
1144
|
+
}
|
|
1145
|
+
let [tokenized, tCursor, tResult] = block_default(tokens, cursor, options);
|
|
1146
|
+
if (tokenized) {
|
|
1147
|
+
parts.add(tResult);
|
|
1148
|
+
cursor = tCursor;
|
|
1149
|
+
continue;
|
|
1150
|
+
}
|
|
1151
|
+
[tokenized, tCursor, tResult] = quote_default(tokens, cursor);
|
|
1152
|
+
if (tokenized) {
|
|
1153
|
+
parts.add(tResult);
|
|
1154
|
+
cursor = tCursor;
|
|
1155
|
+
continue;
|
|
1156
|
+
}
|
|
1157
|
+
[tokenized, tCursor, tResult] = tokenize_default5(tokens, cursor, options);
|
|
1158
|
+
if (tokenized) {
|
|
1159
|
+
parts.add(tResult);
|
|
1160
|
+
cursor = tCursor;
|
|
1161
|
+
continue;
|
|
1162
|
+
}
|
|
1163
|
+
[tokenized, tCursor, tResult] = tokenize_default4(tokens, cursor, options);
|
|
1164
|
+
if (tokenized) {
|
|
1165
|
+
parts.add(tResult);
|
|
1166
|
+
cursor = tCursor;
|
|
1167
|
+
continue;
|
|
1168
|
+
}
|
|
1169
|
+
[tokenized, tCursor, tResult] = tokenize_default2(tokens, cursor, options);
|
|
1170
|
+
if (tokenized) {
|
|
1171
|
+
parts.add(tResult);
|
|
1172
|
+
cursor = tCursor;
|
|
1173
|
+
continue;
|
|
1174
|
+
}
|
|
1175
|
+
parts.add(new TextToken(tokens[cursor]));
|
|
1176
|
+
cursor += 1;
|
|
1177
|
+
}
|
|
1178
|
+
throw new ExpressionSyntaxError("unexpected end of arguments list");
|
|
1179
|
+
};
|
|
1180
|
+
|
|
1181
|
+
// src/parse/arguments/tokenize.ts
|
|
1182
|
+
var tokenize_default = (tokens, cursor, options) => {
|
|
1183
|
+
const count = tokens.length;
|
|
1184
|
+
if (cursor >= count || tokens[cursor].value !== "[") {
|
|
1185
|
+
return [false];
|
|
1186
|
+
}
|
|
1187
|
+
const start = tokens[cursor].position;
|
|
1188
|
+
cursor += 1;
|
|
1189
|
+
const consumeWS = () => {
|
|
1190
|
+
const [wsRem, wsCursor, wsResult] = tokenize_default3(tokens, cursor);
|
|
1191
|
+
if (wsRem) {
|
|
1192
|
+
cursor = wsCursor;
|
|
1193
|
+
return wsResult;
|
|
1194
|
+
}
|
|
1195
|
+
return "";
|
|
1196
|
+
};
|
|
1197
|
+
consumeWS();
|
|
1198
|
+
const args = [];
|
|
1199
|
+
while (cursor < count) {
|
|
1200
|
+
consumeWS();
|
|
1201
|
+
if (cursor >= count) {
|
|
1202
|
+
break;
|
|
1203
|
+
}
|
|
1204
|
+
const [aTokenized, aCursor, aResult] = argument_default(tokens, cursor, options);
|
|
1205
|
+
if (!aTokenized) {
|
|
1206
|
+
throw new ExpressionSyntaxError("encountered missing or invalid argument", tokens[cursor].position);
|
|
1207
|
+
}
|
|
1208
|
+
cursor = aCursor;
|
|
1209
|
+
args.push(aResult);
|
|
1210
|
+
if (cursor >= count) {
|
|
1211
|
+
break;
|
|
1212
|
+
}
|
|
1213
|
+
if (tokens[cursor].value === "]") {
|
|
1214
|
+
return [
|
|
1215
|
+
true,
|
|
1216
|
+
cursor + 1,
|
|
1217
|
+
new ArgumentsToken({
|
|
1218
|
+
position: start,
|
|
1219
|
+
value: args
|
|
1220
|
+
})
|
|
1221
|
+
];
|
|
1222
|
+
}
|
|
1223
|
+
if (tokens[cursor].value !== ",") {
|
|
1224
|
+
throw new ExpressionSyntaxError("expected end of argument", tokens[cursor].position);
|
|
1225
|
+
}
|
|
1226
|
+
cursor += 1;
|
|
1227
|
+
}
|
|
1228
|
+
if (cursor >= count) {
|
|
1229
|
+
throw new ExpressionSyntaxError("unexpected end of expression");
|
|
1230
|
+
}
|
|
1231
|
+
throw new ExpressionSyntaxError("unexpected end of arguments list", tokens[cursor].position);
|
|
1232
|
+
};
|
|
1233
|
+
|
|
1234
|
+
// src/parse/lookup/tokenize.ts
|
|
1235
|
+
var tokenize_default5 = (tokens, cursor, options) => {
|
|
1236
|
+
const count = tokens.length;
|
|
1237
|
+
if (cursor + 1 >= count || tokens[cursor].value !== "$") {
|
|
1238
|
+
return [false];
|
|
1239
|
+
}
|
|
1240
|
+
const start = tokens[cursor].position;
|
|
1241
|
+
cursor += 1;
|
|
1242
|
+
let prefixAccumulator = "";
|
|
1243
|
+
let prefix = "";
|
|
1244
|
+
let tmpCursor = cursor;
|
|
1245
|
+
while (tmpCursor < count) {
|
|
1246
|
+
const val = tokens[tmpCursor].value;
|
|
1247
|
+
if (!/[\x21-\x47\x3A-\x40\x5B\x5D-\x60\x7B-\x7E]/.test(val)) {
|
|
1248
|
+
break;
|
|
1249
|
+
}
|
|
1250
|
+
prefixAccumulator += val;
|
|
1251
|
+
tmpCursor += 1;
|
|
1252
|
+
if (options.lookups.has(prefixAccumulator)) {
|
|
1253
|
+
prefix = prefixAccumulator;
|
|
1254
|
+
cursor = tmpCursor;
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
if (cursor >= count || !prefix) {
|
|
1258
|
+
return [false];
|
|
1259
|
+
}
|
|
1260
|
+
let name = "";
|
|
1261
|
+
if (!/^[a-z]/i.test(tokens[cursor].value)) {
|
|
1262
|
+
return [false];
|
|
1263
|
+
}
|
|
1264
|
+
while (cursor < count && (/^[a-z\d]+$/i.test(tokens[cursor].value) || tokens[cursor].value === "_" || tokens[cursor].value === "-")) {
|
|
1265
|
+
name += tokens[cursor].value;
|
|
1266
|
+
cursor += 1;
|
|
1267
|
+
}
|
|
1268
|
+
if (!/^[a-z][a-z\d_-]+/i.test(name)) {
|
|
1269
|
+
return [false];
|
|
1270
|
+
}
|
|
1271
|
+
let args;
|
|
1272
|
+
const [tokenized, tokenizedCursor, tokenizedResult] = tokenize_default(tokens, cursor, options);
|
|
1273
|
+
if (tokenized) {
|
|
1274
|
+
cursor = tokenizedCursor;
|
|
1275
|
+
args = tokenizedResult;
|
|
1276
|
+
}
|
|
1277
|
+
return [
|
|
1278
|
+
true,
|
|
1279
|
+
cursor,
|
|
1280
|
+
new LookupToken({
|
|
1281
|
+
position: start,
|
|
1282
|
+
prefix,
|
|
1283
|
+
value: name,
|
|
1284
|
+
arguments: args
|
|
1285
|
+
})
|
|
1286
|
+
];
|
|
1287
|
+
};
|
|
1288
|
+
|
|
1289
|
+
// src/parse/text/block.ts
|
|
1290
|
+
var block_default = (tokens, cursor, options) => {
|
|
1291
|
+
const count = tokens.length;
|
|
1292
|
+
if (cursor + 1 >= count || tokens[cursor].value !== "``") {
|
|
1293
|
+
return [false];
|
|
1294
|
+
}
|
|
1295
|
+
cursor += 1;
|
|
1296
|
+
const result = new SequenceToken({ position: tokens[cursor].position });
|
|
1297
|
+
while (cursor < count) {
|
|
1298
|
+
if (tokens[cursor].value === "``") {
|
|
1299
|
+
return [true, cursor + 1, result.unwrap];
|
|
1300
|
+
}
|
|
1301
|
+
let [tokenized, tCursor, tResult] = tokenize_default5(tokens, cursor, options);
|
|
1302
|
+
if (tokenized) {
|
|
1303
|
+
result.add(tResult);
|
|
1304
|
+
cursor = tCursor;
|
|
1305
|
+
continue;
|
|
1306
|
+
}
|
|
1307
|
+
[tokenized, tCursor, tResult] = tokenize_default4(tokens, cursor, options);
|
|
1308
|
+
if (tokenized) {
|
|
1309
|
+
result.add(tResult);
|
|
1310
|
+
cursor = tCursor;
|
|
1311
|
+
continue;
|
|
1312
|
+
}
|
|
1313
|
+
[tokenized, tCursor, tResult] = tokenize_default2(tokens, cursor, options);
|
|
1314
|
+
if (tokenized) {
|
|
1315
|
+
result.add(tResult);
|
|
1316
|
+
cursor = tCursor;
|
|
1317
|
+
continue;
|
|
1318
|
+
}
|
|
1319
|
+
result.add(new TextToken(tokens[cursor]));
|
|
1320
|
+
cursor += 1;
|
|
1321
|
+
}
|
|
1322
|
+
return [false];
|
|
1323
|
+
};
|
|
1324
|
+
|
|
1325
|
+
// src/parse/root/tokenize.ts
|
|
1326
|
+
var tokenize_default8 = (options) => {
|
|
1327
|
+
const result = new RootToken(options);
|
|
1328
|
+
const tokens = tokenize(options.expression);
|
|
1329
|
+
const count = tokens.length;
|
|
1330
|
+
let cursor = 0;
|
|
1331
|
+
while (cursor < count) {
|
|
1332
|
+
const [eTokenized, eCursor, eResult] = escape_default(tokens, cursor);
|
|
1333
|
+
if (eTokenized) {
|
|
1334
|
+
result.add(new TextToken(eResult));
|
|
1335
|
+
cursor = eCursor;
|
|
1336
|
+
continue;
|
|
1337
|
+
}
|
|
1338
|
+
let [tokenized, tCursor, tResult] = block_default(tokens, cursor, options);
|
|
1339
|
+
if (tokenized) {
|
|
1340
|
+
result.add(tResult);
|
|
1341
|
+
cursor = tCursor;
|
|
1342
|
+
continue;
|
|
1343
|
+
}
|
|
1344
|
+
[tokenized, tCursor, tResult] = tokenize_default5(tokens, cursor, options);
|
|
1345
|
+
if (tokenized) {
|
|
1346
|
+
result.add(tResult);
|
|
1347
|
+
cursor = tCursor;
|
|
1348
|
+
continue;
|
|
1349
|
+
}
|
|
1350
|
+
[tokenized, tCursor, tResult] = tokenize_default4(tokens, cursor, options);
|
|
1351
|
+
if (tokenized) {
|
|
1352
|
+
result.add(tResult);
|
|
1353
|
+
cursor = tCursor;
|
|
1354
|
+
continue;
|
|
1355
|
+
}
|
|
1356
|
+
[tokenized, tCursor, tResult] = tokenize_default2(tokens, cursor, options);
|
|
1357
|
+
if (tokenized) {
|
|
1358
|
+
result.add(tResult);
|
|
1359
|
+
cursor = tCursor;
|
|
1360
|
+
continue;
|
|
1361
|
+
}
|
|
1362
|
+
result.add(new TextToken(tokens[cursor]));
|
|
1363
|
+
cursor += 1;
|
|
1364
|
+
}
|
|
1365
|
+
return result;
|
|
1366
|
+
};
|
|
1367
|
+
|
|
1368
|
+
// src/expressionish.ts
|
|
1369
|
+
var tokenize2 = (options) => {
|
|
1370
|
+
if (options == null) {
|
|
1371
|
+
throw new TypeError("options not specified");
|
|
1372
|
+
}
|
|
1373
|
+
if (options.variables == null) {
|
|
1374
|
+
throw new TypeError("variables map is null");
|
|
1375
|
+
}
|
|
1376
|
+
if (!(options.variables instanceof Map)) {
|
|
1377
|
+
throw new TypeError("variables map is not a Map instance");
|
|
1378
|
+
}
|
|
1379
|
+
if (options.lookups == null) {
|
|
1380
|
+
options.lookups = /* @__PURE__ */ new Map();
|
|
1381
|
+
} else if (!(options.lookups instanceof Map)) {
|
|
1382
|
+
throw new TypeError("lookups option specified but is not a Map instance");
|
|
1383
|
+
}
|
|
1384
|
+
if (options.logicalOperators == null) {
|
|
1385
|
+
options.logicalOperators = /* @__PURE__ */ new Map();
|
|
1386
|
+
} else if (!(options.logicalOperators instanceof Map)) {
|
|
1387
|
+
throw new TypeError("logical operators options specified but is not a Map instance");
|
|
1388
|
+
}
|
|
1389
|
+
if (options.comparisonOperators == null) {
|
|
1390
|
+
options.comparisonOperators = /* @__PURE__ */ new Map();
|
|
1391
|
+
} else if (!(options.comparisonOperators instanceof Map)) {
|
|
1392
|
+
throw new TypeError("comparison operators options specified but is not a Map instance");
|
|
1393
|
+
}
|
|
1394
|
+
if (options.expression == null) {
|
|
1395
|
+
throw new TypeError("expression not specified");
|
|
1396
|
+
}
|
|
1397
|
+
if (typeof options.expression !== "string") {
|
|
1398
|
+
throw new TypeError("expression must be a string");
|
|
1399
|
+
}
|
|
1400
|
+
return tokenize_default8(options);
|
|
1401
|
+
};
|
|
1402
|
+
var evaluate = async (options) => tokenize2(options).evaluate({
|
|
1403
|
+
onlyValidate: options.onlyValidate,
|
|
1404
|
+
preeval: options.preeval,
|
|
1405
|
+
data: options.data
|
|
1406
|
+
});
|
|
1407
|
+
export {
|
|
1408
|
+
ArgumentsToken,
|
|
1409
|
+
BaseToken,
|
|
1410
|
+
ComparisonToken,
|
|
1411
|
+
ExpressionArgumentsError,
|
|
1412
|
+
ExpressionError,
|
|
1413
|
+
ExpressionSyntaxError,
|
|
1414
|
+
ExpressionVariableError,
|
|
1415
|
+
IfToken,
|
|
1416
|
+
LogicToken,
|
|
1417
|
+
LookupToken,
|
|
1418
|
+
RootToken,
|
|
1419
|
+
SequenceToken,
|
|
1420
|
+
TextToken,
|
|
1421
|
+
VariableToken,
|
|
1422
|
+
evaluate,
|
|
1423
|
+
tokenize2 as tokenize
|
|
1424
|
+
};
|
|
1425
|
+
/*!
|
|
1426
|
+
The MIT License (MIT) @ Copyright (c) 2016 Justin Sippel, Vitaly Domnikov
|
|
1427
|
+
https://github.com/bluelovers/runes/blob/8013b6e4021a41d6b579d76b3332c87389c5f092/LICENSE
|
|
1428
|
+
*/
|
|
1429
|
+
//# sourceMappingURL=expressionish.mjs.map
|