ecma-evaluator 2.0.10 → 2.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.
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/dist/cjs/Evaluator.d.cts +11 -1
- package/dist/cjs/index.cjs +132 -17
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/Evaluator.d.mts +11 -1
- package/dist/esm/index.mjs +132 -17
- package/dist/esm/index.mjs.map +1 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://996.icu/#/en_US)
|
|
4
4
|
[](https://github.com/996icu/996.ICU/blob/master/LICENSE)
|
|
5
|
-

|
|
6
6
|
[](https://badge.fury.io/js/ecma-evaluator)
|
|
7
7
|
|
|
8
8
|
A tiny, fast, and **secure** JavaScript expression evaluator for safely evaluating expressions and template strings in a sandboxed environment.
|
|
@@ -34,6 +34,6 @@ evalTemplate("Hello {{ name }}!", { name: "World" }); // "Hello World!"
|
|
|
34
34
|
|
|
35
35
|
- [Getting started](/guide/getting-started)
|
|
36
36
|
- [API, supported features, security, and usage reference](/guide/reference)
|
|
37
|
-
- [Online playground](/#playground)
|
|
37
|
+
- [Online playground](https://axetroy.github.io/ecma-evaluator/#playground)
|
|
38
38
|
|
|
39
39
|
See the [documentation site](https://axetroy.github.io/ecma-evaluator/).
|
package/README.zh-CN.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://996.icu/#/zh_CN)
|
|
4
4
|
[](https://github.com/996icu/996.ICU/blob/master/LICENSE)
|
|
5
|
-

|
|
6
6
|
[](https://badge.fury.io/js/ecma-evaluator)
|
|
7
7
|
|
|
8
8
|
一个小巧、快速且**安全**的 JavaScript 表达式求值器,用于在沙箱环境中安全地执行表达式和模板字符串。
|
|
@@ -34,6 +34,6 @@ evalTemplate("你好,{{ name }}!", { name: "世界" }); // "你好,世界
|
|
|
34
34
|
|
|
35
35
|
- [快速开始](/zh-CN/guide/getting-started)
|
|
36
36
|
- [API、支持的特性、安全性和使用说明](/zh-CN/guide/reference)
|
|
37
|
-
- [在线体验](/zh-CN/#playground)
|
|
37
|
+
- [在线体验](https://axetroy.github.io/ecma-evaluator/zh-CN/#playground)
|
|
38
38
|
|
|
39
39
|
也可以访问[文档网站](https://axetroy.github.io/ecma-evaluator/zh-CN/)。
|
package/dist/cjs/Evaluator.d.cts
CHANGED
|
@@ -11,6 +11,12 @@ export interface EvaluatorOptions {
|
|
|
11
11
|
* @default 10000
|
|
12
12
|
*/
|
|
13
13
|
maxEvaluationSteps?: number;
|
|
14
|
+
/**
|
|
15
|
+
* Maximum interpreter recursion depth (hard maximum: 2000). Bounds nested
|
|
16
|
+
* expressions so a deeply nested input cannot exhaust the host call stack.
|
|
17
|
+
* @default 1000
|
|
18
|
+
*/
|
|
19
|
+
maxDepth?: number;
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
export declare class Evaluator {
|
|
@@ -21,4 +27,8 @@ export declare class Evaluator {
|
|
|
21
27
|
evaluate<T = unknown>(expression: string): T;
|
|
22
28
|
}
|
|
23
29
|
|
|
24
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Renders an AST node back to a short source-like string. Returns `null` for
|
|
32
|
+
* node types that have no textual representation.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getNodeString(node: Node): string | null;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -76,6 +76,7 @@ var mutableMethods = [
|
|
|
76
76
|
"Array.prototype.sort",
|
|
77
77
|
"Array.prototype.fill",
|
|
78
78
|
"Array.prototype.copyWithin",
|
|
79
|
+
"Object.create",
|
|
79
80
|
"Object.defineProperty",
|
|
80
81
|
"Object.defineProperties",
|
|
81
82
|
"Object.preventExtensions",
|
|
@@ -379,6 +380,18 @@ var MAX_STRING_LENGTH = 100000;
|
|
|
379
380
|
var MAX_DATA_NODES = 100000;
|
|
380
381
|
var MAX_BIGINT_EXPONENT = 256n;
|
|
381
382
|
var MAX_BIGINT_BITS = 65536;
|
|
383
|
+
var DEFAULT_MAX_DEPTH = 1000;
|
|
384
|
+
var MAX_CONFIGURABLE_DEPTH = 2000;
|
|
385
|
+
var MAX_REGEXP_SOURCE_LENGTH = 1000;
|
|
386
|
+
var MAX_REGEXP_FLAGS_LENGTH = 32;
|
|
387
|
+
var NON_SANDBOX_GLOBALS = new Set([
|
|
388
|
+
"WeakRef",
|
|
389
|
+
"FinalizationRegistry",
|
|
390
|
+
"Iterator",
|
|
391
|
+
"SharedArrayBuffer",
|
|
392
|
+
"escape",
|
|
393
|
+
"unescape"
|
|
394
|
+
]);
|
|
382
395
|
var TYPED_ARRAY_CONSTRUCTORS = new Set([
|
|
383
396
|
Int8Array,
|
|
384
397
|
Uint8Array,
|
|
@@ -387,6 +400,7 @@ var TYPED_ARRAY_CONSTRUCTORS = new Set([
|
|
|
387
400
|
Uint16Array,
|
|
388
401
|
Int32Array,
|
|
389
402
|
Uint32Array,
|
|
403
|
+
"function" == typeof Float16Array ? Float16Array : null,
|
|
390
404
|
Float32Array,
|
|
391
405
|
Float64Array,
|
|
392
406
|
"function" == typeof BigInt64Array ? BigInt64Array : null,
|
|
@@ -394,6 +408,39 @@ var TYPED_ARRAY_CONSTRUCTORS = new Set([
|
|
|
394
408
|
].filter(function(constructor) {
|
|
395
409
|
return "function" == typeof constructor;
|
|
396
410
|
}));
|
|
411
|
+
function isTypedArrayConstructor(value) {
|
|
412
|
+
return TYPED_ARRAY_CONSTRUCTORS.has(value) || "function" == typeof value && "number" == typeof value.BYTES_PER_ELEMENT;
|
|
413
|
+
}
|
|
414
|
+
var TYPED_ARRAY_MUTATORS = function() {
|
|
415
|
+
var map = new Map();
|
|
416
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
417
|
+
try {
|
|
418
|
+
for(var _iterator = TYPED_ARRAY_CONSTRUCTORS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
419
|
+
var constructor = _step.value;
|
|
420
|
+
for(var _i = 0, _iter = [
|
|
421
|
+
"set",
|
|
422
|
+
"fill",
|
|
423
|
+
"reverse",
|
|
424
|
+
"sort",
|
|
425
|
+
"copyWithin"
|
|
426
|
+
]; _i < _iter.length; _i++){
|
|
427
|
+
var name = _iter[_i];
|
|
428
|
+
var method = constructor.prototype[name];
|
|
429
|
+
if ("function" == typeof method && !map.has(method)) map.set(method, name);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
} catch (err) {
|
|
433
|
+
_didIteratorError = true;
|
|
434
|
+
_iteratorError = err;
|
|
435
|
+
} finally{
|
|
436
|
+
try {
|
|
437
|
+
if (!_iteratorNormalCompletion && null != _iterator.return) _iterator.return();
|
|
438
|
+
} finally{
|
|
439
|
+
if (_didIteratorError) throw _iteratorError;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return map;
|
|
443
|
+
}();
|
|
397
444
|
var NO_OBJECT = Symbol("no-object");
|
|
398
445
|
var renderErrorMessage = function(template) {
|
|
399
446
|
var context = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};
|
|
@@ -558,14 +605,20 @@ var BINARY_OPERATION_MAP = {
|
|
|
558
605
|
function createGlobalScope() {
|
|
559
606
|
var scope = Object.create(null);
|
|
560
607
|
var builtin = external_globals_namespaceObject.builtin;
|
|
561
|
-
for(var key in builtin)
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
608
|
+
for(var key in builtin){
|
|
609
|
+
if (!blockedGlobalBuiltIns.includes(key)) {
|
|
610
|
+
if (!NON_SANDBOX_GLOBALS.has(key)) {
|
|
611
|
+
if (Object.hasOwn(globalThis, key)) {
|
|
612
|
+
var isWritable = builtin[key];
|
|
613
|
+
Object.defineProperty(scope, key, {
|
|
614
|
+
value: globalThis[key],
|
|
615
|
+
writable: isWritable,
|
|
616
|
+
enumerable: false,
|
|
617
|
+
configurable: false
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
569
622
|
}
|
|
570
623
|
Object.defineProperty(scope, "globalThis", {
|
|
571
624
|
value: scope,
|
|
@@ -575,6 +628,7 @@ function createGlobalScope() {
|
|
|
575
628
|
});
|
|
576
629
|
return scope;
|
|
577
630
|
}
|
|
631
|
+
var GLOBAL_SCOPE = createGlobalScope();
|
|
578
632
|
var getBlockedMethods = function() {
|
|
579
633
|
var BLOCKED_METHODS = null;
|
|
580
634
|
return function() {
|
|
@@ -629,11 +683,12 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
629
683
|
_class_call_check(this, Evaluator);
|
|
630
684
|
this.maxInputLength = validateLimit(null == options ? void 0 : options.maxInputLength, "maxInputLength", DEFAULT_MAX_INPUT_LENGTH, MAX_CONFIGURABLE_INPUT_LENGTH);
|
|
631
685
|
this.maxEvaluationSteps = validateLimit(null == options ? void 0 : options.maxEvaluationSteps, "maxEvaluationSteps", DEFAULT_MAX_EVALUATION_STEPS, MAX_CONFIGURABLE_EVALUATION_STEPS);
|
|
686
|
+
this.maxDepth = validateLimit(null == options ? void 0 : options.maxDepth, "maxDepth", DEFAULT_MAX_DEPTH, MAX_CONFIGURABLE_DEPTH);
|
|
632
687
|
assertBoundedData(variables, "Evaluation context");
|
|
633
688
|
var clonedVariables = structuredClone(variables);
|
|
634
689
|
this.scopes = [
|
|
635
690
|
clonedVariables,
|
|
636
|
-
|
|
691
|
+
GLOBAL_SCOPE
|
|
637
692
|
].filter(function(scope) {
|
|
638
693
|
return null != scope;
|
|
639
694
|
});
|
|
@@ -641,6 +696,7 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
641
696
|
this.remainingEvaluationSteps = 0;
|
|
642
697
|
this.remainingDataSize = MAX_BUFFER_BYTES;
|
|
643
698
|
this.remainingDataNodes = MAX_DATA_NODES;
|
|
699
|
+
this.evaluationDepth = 0;
|
|
644
700
|
}
|
|
645
701
|
_create_class(Evaluator, [
|
|
646
702
|
{
|
|
@@ -654,9 +710,16 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
654
710
|
this.remainingEvaluationSteps = this.maxEvaluationSteps;
|
|
655
711
|
this.remainingDataSize = MAX_BUFFER_BYTES;
|
|
656
712
|
this.remainingDataNodes = MAX_DATA_NODES;
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
713
|
+
this.evaluationDepth = 0;
|
|
714
|
+
var ast;
|
|
715
|
+
try {
|
|
716
|
+
ast = external_acorn_namespaceObject.parse(expression, {
|
|
717
|
+
ecmaVersion: "latest"
|
|
718
|
+
});
|
|
719
|
+
} catch (error) {
|
|
720
|
+
if (_instanceof(error, RangeError) && /call stack/i.test(error.message)) throw new SyntaxError("Expression nesting is too deep to parse");
|
|
721
|
+
throw error;
|
|
722
|
+
}
|
|
660
723
|
try {
|
|
661
724
|
return this.execute(ast.body);
|
|
662
725
|
} finally{
|
|
@@ -709,9 +772,24 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
709
772
|
{
|
|
710
773
|
key: "visit",
|
|
711
774
|
value: function(node) {
|
|
712
|
-
var _this = this;
|
|
713
775
|
this.remainingEvaluationSteps--;
|
|
714
776
|
if (this.remainingEvaluationSteps < 0) throw new RangeError("Evaluation step limit exceeded");
|
|
777
|
+
this.evaluationDepth++;
|
|
778
|
+
if (this.evaluationDepth > this.maxDepth) {
|
|
779
|
+
this.evaluationDepth--;
|
|
780
|
+
throw new RangeError("Maximum evaluation depth exceeded");
|
|
781
|
+
}
|
|
782
|
+
try {
|
|
783
|
+
return this.visitNode(node);
|
|
784
|
+
} finally{
|
|
785
|
+
this.evaluationDepth--;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
key: "visitNode",
|
|
791
|
+
value: function(node) {
|
|
792
|
+
var _this = this;
|
|
715
793
|
switch(node.type){
|
|
716
794
|
case "ExpressionStatement":
|
|
717
795
|
return this.visit(node.expression);
|
|
@@ -797,10 +875,18 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
797
875
|
throw new SyntaxError("Unsupported operator: ".concat(node.operator));
|
|
798
876
|
}
|
|
799
877
|
},
|
|
878
|
+
{
|
|
879
|
+
key: "assertBoundedRegExp",
|
|
880
|
+
value: function(args) {
|
|
881
|
+
if ("string" == typeof args[0] && args[0].length > MAX_REGEXP_SOURCE_LENGTH) throw new RangeError("RegExp source exceeds the maximum allowed length");
|
|
882
|
+
if ("string" == typeof args[1] && args[1].length > MAX_REGEXP_FLAGS_LENGTH) throw new RangeError("RegExp flags exceed the maximum allowed length");
|
|
883
|
+
}
|
|
884
|
+
},
|
|
800
885
|
{
|
|
801
886
|
key: "assertBoundedConstruction",
|
|
802
887
|
value: function(Constructor, args) {
|
|
803
888
|
var _args_;
|
|
889
|
+
if (Constructor === RegExp) this.assertBoundedRegExp(args);
|
|
804
890
|
var size = args[0];
|
|
805
891
|
if (Constructor === Array && 1 === args.length && "number" == typeof size && size > MAX_ARRAY_LENGTH) throw new RangeError("Array length exceeds the maximum allowed length");
|
|
806
892
|
if (Constructor === ArrayBuffer && (size > MAX_BUFFER_BYTES || (null == (_args_ = args[1]) ? void 0 : _args_.maxByteLength) > MAX_BUFFER_BYTES)) throw new RangeError("ArrayBuffer size exceeds the maximum allowed size");
|
|
@@ -810,7 +896,7 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
810
896
|
var collectionSize = "string" == typeof size || Array.isArray(size) ? size.length : null != (_size_size = null == size ? void 0 : size.size) ? _size_size : null == size ? void 0 : size.length;
|
|
811
897
|
if ("number" == typeof collectionSize && collectionSize > MAX_ARRAY_LENGTH) throw new RangeError("Collection source exceeds the maximum allowed size");
|
|
812
898
|
}
|
|
813
|
-
if (
|
|
899
|
+
if (isTypedArrayConstructor(Constructor)) {
|
|
814
900
|
var byteLength;
|
|
815
901
|
if (_instanceof(size, ArrayBuffer)) {
|
|
816
902
|
var _args_1;
|
|
@@ -905,7 +991,7 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
905
991
|
if ("stack" === property && _instanceof(object, Error)) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
906
992
|
"Accessing error stack"
|
|
907
993
|
]));
|
|
908
|
-
if (null != object &&
|
|
994
|
+
if (null != object && void 0 !== object.__proto__ && object[property] === object.__proto__) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
909
995
|
"Accessing prototype properties"
|
|
910
996
|
]));
|
|
911
997
|
if (null == object) {
|
|
@@ -1047,6 +1133,9 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
1047
1133
|
path
|
|
1048
1134
|
]));
|
|
1049
1135
|
}
|
|
1136
|
+
if (TYPED_ARRAY_MUTATORS.has(func)) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
1137
|
+
"TypedArray.prototype.".concat(TYPED_ARRAY_MUTATORS.get(func))
|
|
1138
|
+
]));
|
|
1050
1139
|
var args = function() {
|
|
1051
1140
|
if (0 === node.arguments.length) return [];
|
|
1052
1141
|
var result = [];
|
|
@@ -1088,7 +1177,8 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
1088
1177
|
if ("string" == typeof args[0] && "" !== args[0] && countLiteralMatches(target, args[0], true) >= MAX_ARRAY_LENGTH) throw new RangeError("Split result exceeds the maximum allowed length");
|
|
1089
1178
|
}
|
|
1090
1179
|
}
|
|
1091
|
-
if (
|
|
1180
|
+
if (func === RegExp) this.assertBoundedRegExp(args);
|
|
1181
|
+
if ((target === Array || isTypedArrayConstructor(target)) && func === target.from) {
|
|
1092
1182
|
var source = args[0];
|
|
1093
1183
|
var _source_size;
|
|
1094
1184
|
var size = "string" == typeof source || Array.isArray(source) ? source.length : null != (_source_size = null == source ? void 0 : source.size) ? _source_size : null == source ? void 0 : source.length;
|
|
@@ -1138,7 +1228,7 @@ function getNodeString(node) {
|
|
|
1138
1228
|
return node.raw;
|
|
1139
1229
|
case "ArrayExpression":
|
|
1140
1230
|
return "[".concat(node.elements.map(function(child) {
|
|
1141
|
-
return getNodeString(child);
|
|
1231
|
+
return null === child ? "" : getNodeString(child);
|
|
1142
1232
|
}).join(","), "]");
|
|
1143
1233
|
case "ObjectExpression":
|
|
1144
1234
|
if (0 === node.properties.length) return "{}";
|
|
@@ -1211,6 +1301,7 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
1211
1301
|
var buffer = "";
|
|
1212
1302
|
var exprStartPos = 0;
|
|
1213
1303
|
var pos = 0;
|
|
1304
|
+
var prevExprChar = "";
|
|
1214
1305
|
while(pos < length){
|
|
1215
1306
|
var char = template[pos];
|
|
1216
1307
|
var nextChar = template[pos + 1];
|
|
@@ -1228,6 +1319,7 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
1228
1319
|
}
|
|
1229
1320
|
state = "EXPR";
|
|
1230
1321
|
exprStartPos = pos;
|
|
1322
|
+
prevExprChar = "";
|
|
1231
1323
|
pos += this.startLen;
|
|
1232
1324
|
continue;
|
|
1233
1325
|
}
|
|
@@ -1237,6 +1329,7 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
1237
1329
|
if ("'" === char) state = "STRING_SQ";
|
|
1238
1330
|
else if ('"' === char) state = "STRING_DQ";
|
|
1239
1331
|
else if ("`" === char) state = "TEMPLATE";
|
|
1332
|
+
else if ("/" === char && this._isRegexPosition(prevExprChar)) state = "REGEX";
|
|
1240
1333
|
else if ("\\" === char) state = "'" === nextChar ? "ESCAPE_SQ" : '"' === nextChar ? "ESCAPE_DQ" : "`" === nextChar ? "ESCAPE_TEMPLATE" : "ESCAPE_EXPR";
|
|
1241
1334
|
else if (this._isMatch(pos, template, this.exprEnd)) {
|
|
1242
1335
|
var exprValue = this.preserveWhitespace ? buffer : buffer.trim();
|
|
@@ -1253,6 +1346,7 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
1253
1346
|
pos += this.endLen;
|
|
1254
1347
|
continue;
|
|
1255
1348
|
}
|
|
1349
|
+
if (!RegExp("\\s", "u").test(char)) prevExprChar = char;
|
|
1256
1350
|
buffer += char;
|
|
1257
1351
|
break;
|
|
1258
1352
|
case "STRING_SQ":
|
|
@@ -1270,6 +1364,17 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
1270
1364
|
else if ("`" === char) state = "EXPR";
|
|
1271
1365
|
buffer += char;
|
|
1272
1366
|
break;
|
|
1367
|
+
case "REGEX":
|
|
1368
|
+
if ("\\" === char) state = "ESCAPE_REGEX";
|
|
1369
|
+
else if ("[" === char) state = "REGEX_CLASS";
|
|
1370
|
+
else if ("/" === char) state = "EXPR";
|
|
1371
|
+
buffer += char;
|
|
1372
|
+
break;
|
|
1373
|
+
case "REGEX_CLASS":
|
|
1374
|
+
if ("\\" === char) state = "ESCAPE_REGEX";
|
|
1375
|
+
else if ("]" === char) state = "REGEX";
|
|
1376
|
+
buffer += char;
|
|
1377
|
+
break;
|
|
1273
1378
|
case "ESCAPE_SQ":
|
|
1274
1379
|
buffer += char;
|
|
1275
1380
|
state = "STRING_SQ";
|
|
@@ -1282,6 +1387,10 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
1282
1387
|
buffer += char;
|
|
1283
1388
|
state = "TEMPLATE";
|
|
1284
1389
|
break;
|
|
1390
|
+
case "ESCAPE_REGEX":
|
|
1391
|
+
buffer += char;
|
|
1392
|
+
state = "REGEX";
|
|
1393
|
+
break;
|
|
1285
1394
|
case "ESCAPE_EXPR":
|
|
1286
1395
|
buffer += char;
|
|
1287
1396
|
state = "EXPR";
|
|
@@ -1307,6 +1416,12 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
1307
1416
|
return tokens;
|
|
1308
1417
|
}
|
|
1309
1418
|
},
|
|
1419
|
+
{
|
|
1420
|
+
key: "_isRegexPosition",
|
|
1421
|
+
value: function(prev) {
|
|
1422
|
+
return "" === prev || "(,=:[!&|?{};+-*%^~<>".includes(prev);
|
|
1423
|
+
}
|
|
1424
|
+
},
|
|
1310
1425
|
{
|
|
1311
1426
|
key: "_isMatch",
|
|
1312
1427
|
value: function(pos, template, sequence) {
|