eslint 7.1.0 → 7.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +69 -0
- package/README.md +12 -7
- package/lib/cli-engine/cli-engine.js +2 -2
- package/lib/cli-engine/config-array-factory.js +1 -1
- package/lib/init/config-initializer.js +91 -74
- package/lib/linter/code-path-analysis/code-path-analyzer.js +2 -2
- package/lib/linter/code-path-analysis/code-path-state.js +34 -12
- package/lib/linter/config-comment-parser.js +1 -1
- package/lib/rule-tester/rule-tester.js +9 -0
- package/lib/rules/array-callback-return.js +21 -10
- package/lib/rules/arrow-body-style.js +2 -2
- package/lib/rules/arrow-parens.js +91 -108
- package/lib/rules/camelcase.js +47 -0
- package/lib/rules/comma-dangle.js +2 -1
- package/lib/rules/curly.js +8 -1
- package/lib/rules/func-call-spacing.js +18 -3
- package/lib/rules/{id-blacklist.js → id-denylist.js} +12 -12
- package/lib/rules/id-match.js +2 -1
- package/lib/rules/index.js +6 -1
- package/lib/rules/key-spacing.js +6 -2
- package/lib/rules/keyword-spacing.js +9 -2
- package/lib/rules/max-lines.js +34 -8
- package/lib/rules/multiline-ternary.js +44 -25
- package/lib/rules/no-control-regex.js +1 -1
- package/lib/rules/no-extra-boolean-cast.js +3 -0
- package/lib/rules/no-extra-parens.js +50 -4
- package/lib/rules/no-invalid-regexp.js +1 -1
- package/lib/rules/no-misleading-character-class.js +1 -1
- package/lib/rules/no-mixed-operators.js +3 -2
- package/lib/rules/no-mixed-spaces-and-tabs.js +14 -6
- package/lib/rules/no-promise-executor-return.js +121 -0
- package/lib/rules/no-regex-spaces.js +1 -1
- package/lib/rules/no-restricted-exports.js +6 -0
- package/lib/rules/no-unneeded-ternary.js +6 -4
- package/lib/rules/no-unreachable-loop.js +150 -0
- package/lib/rules/no-unused-expressions.js +1 -1
- package/lib/rules/no-unused-vars.js +5 -2
- package/lib/rules/no-useless-backreference.js +1 -1
- package/lib/rules/object-property-newline.js +1 -1
- package/lib/rules/operator-linebreak.js +2 -5
- package/lib/rules/padded-blocks.js +2 -1
- package/lib/rules/prefer-named-capture-group.js +1 -1
- package/lib/rules/prefer-regex-literals.js +66 -8
- package/lib/rules/quote-props.js +2 -2
- package/lib/rules/semi-spacing.js +1 -0
- package/lib/rules/template-tag-spacing.js +8 -2
- package/lib/rules/utils/ast-utils.js +55 -3
- package/package.json +6 -6
@@ -0,0 +1,150 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Rule to disallow loops with a body that allows only one iteration
|
3
|
+
* @author Milos Djermanovic
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Helpers
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
const allLoopTypes = ["WhileStatement", "DoWhileStatement", "ForStatement", "ForInStatement", "ForOfStatement"];
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Determines whether the given node is the first node in the code path to which a loop statement
|
16
|
+
* 'loops' for the next iteration.
|
17
|
+
* @param {ASTNode} node The node to check.
|
18
|
+
* @returns {boolean} `true` if the node is a looping target.
|
19
|
+
*/
|
20
|
+
function isLoopingTarget(node) {
|
21
|
+
const parent = node.parent;
|
22
|
+
|
23
|
+
if (parent) {
|
24
|
+
switch (parent.type) {
|
25
|
+
case "WhileStatement":
|
26
|
+
return node === parent.test;
|
27
|
+
case "DoWhileStatement":
|
28
|
+
return node === parent.body;
|
29
|
+
case "ForStatement":
|
30
|
+
return node === (parent.update || parent.test || parent.body);
|
31
|
+
case "ForInStatement":
|
32
|
+
case "ForOfStatement":
|
33
|
+
return node === parent.left;
|
34
|
+
|
35
|
+
// no default
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
return false;
|
40
|
+
}
|
41
|
+
|
42
|
+
/**
|
43
|
+
* Creates an array with elements from the first given array that are not included in the second given array.
|
44
|
+
* @param {Array} arrA The array to compare from.
|
45
|
+
* @param {Array} arrB The array to compare against.
|
46
|
+
* @returns {Array} a new array that represents `arrA \ arrB`.
|
47
|
+
*/
|
48
|
+
function getDifference(arrA, arrB) {
|
49
|
+
return arrA.filter(a => !arrB.includes(a));
|
50
|
+
}
|
51
|
+
|
52
|
+
//------------------------------------------------------------------------------
|
53
|
+
// Rule Definition
|
54
|
+
//------------------------------------------------------------------------------
|
55
|
+
|
56
|
+
module.exports = {
|
57
|
+
meta: {
|
58
|
+
type: "problem",
|
59
|
+
|
60
|
+
docs: {
|
61
|
+
description: "disallow loops with a body that allows only one iteration",
|
62
|
+
category: "Possible Errors",
|
63
|
+
recommended: false,
|
64
|
+
url: "https://eslint.org/docs/rules/no-unreachable-loop"
|
65
|
+
},
|
66
|
+
|
67
|
+
schema: [{
|
68
|
+
type: "object",
|
69
|
+
properties: {
|
70
|
+
ignore: {
|
71
|
+
type: "array",
|
72
|
+
items: {
|
73
|
+
enum: allLoopTypes
|
74
|
+
},
|
75
|
+
uniqueItems: true
|
76
|
+
}
|
77
|
+
},
|
78
|
+
additionalProperties: false
|
79
|
+
}],
|
80
|
+
|
81
|
+
messages: {
|
82
|
+
invalid: "Invalid loop. Its body allows only one iteration."
|
83
|
+
}
|
84
|
+
},
|
85
|
+
|
86
|
+
create(context) {
|
87
|
+
const ignoredLoopTypes = context.options[0] && context.options[0].ignore || [],
|
88
|
+
loopTypesToCheck = getDifference(allLoopTypes, ignoredLoopTypes),
|
89
|
+
loopSelector = loopTypesToCheck.join(","),
|
90
|
+
loopsByTargetSegments = new Map(),
|
91
|
+
loopsToReport = new Set();
|
92
|
+
|
93
|
+
let currentCodePath = null;
|
94
|
+
|
95
|
+
return {
|
96
|
+
onCodePathStart(codePath) {
|
97
|
+
currentCodePath = codePath;
|
98
|
+
},
|
99
|
+
|
100
|
+
onCodePathEnd() {
|
101
|
+
currentCodePath = currentCodePath.upper;
|
102
|
+
},
|
103
|
+
|
104
|
+
[loopSelector](node) {
|
105
|
+
|
106
|
+
/**
|
107
|
+
* Ignore unreachable loop statements to avoid unnecessary complexity in the implementation, or false positives otherwise.
|
108
|
+
* For unreachable segments, the code path analysis does not raise events required for this implementation.
|
109
|
+
*/
|
110
|
+
if (currentCodePath.currentSegments.some(segment => segment.reachable)) {
|
111
|
+
loopsToReport.add(node);
|
112
|
+
}
|
113
|
+
},
|
114
|
+
|
115
|
+
onCodePathSegmentStart(segment, node) {
|
116
|
+
if (isLoopingTarget(node)) {
|
117
|
+
const loop = node.parent;
|
118
|
+
|
119
|
+
loopsByTargetSegments.set(segment, loop);
|
120
|
+
}
|
121
|
+
},
|
122
|
+
|
123
|
+
onCodePathSegmentLoop(_, toSegment, node) {
|
124
|
+
const loop = loopsByTargetSegments.get(toSegment);
|
125
|
+
|
126
|
+
/**
|
127
|
+
* The second iteration is reachable, meaning that the loop is valid by the logic of this rule,
|
128
|
+
* only if there is at least one loop event with the appropriate target (which has been already
|
129
|
+
* determined in the `loopsByTargetSegments` map), raised from either:
|
130
|
+
*
|
131
|
+
* - the end of the loop's body (in which case `node === loop`)
|
132
|
+
* - a `continue` statement
|
133
|
+
*
|
134
|
+
* This condition skips loop events raised from `ForInStatement > .right` and `ForOfStatement > .right` nodes.
|
135
|
+
*/
|
136
|
+
if (node === loop || node.type === "ContinueStatement") {
|
137
|
+
|
138
|
+
// Removes loop if it exists in the set. Otherwise, `Set#delete` has no effect and doesn't throw.
|
139
|
+
loopsToReport.delete(loop);
|
140
|
+
}
|
141
|
+
},
|
142
|
+
|
143
|
+
"Program:exit"() {
|
144
|
+
loopsToReport.forEach(
|
145
|
+
node => context.report({ node, messageId: "invalid" })
|
146
|
+
);
|
147
|
+
}
|
148
|
+
};
|
149
|
+
}
|
150
|
+
};
|
@@ -124,7 +124,7 @@ module.exports = {
|
|
124
124
|
return true;
|
125
125
|
}
|
126
126
|
|
127
|
-
return /^(?:Assignment|Call|New|Update|Yield|Await)Expression$/u.test(node.type) ||
|
127
|
+
return /^(?:Assignment|Call|New|Update|Yield|Await|Import)Expression$/u.test(node.type) ||
|
128
128
|
(node.type === "UnaryExpression" && ["delete", "void"].indexOf(node.operator) >= 0);
|
129
129
|
}
|
130
130
|
|
@@ -68,7 +68,8 @@ module.exports = {
|
|
68
68
|
caughtErrorsIgnorePattern: {
|
69
69
|
type: "string"
|
70
70
|
}
|
71
|
-
}
|
71
|
+
},
|
72
|
+
additionalProperties: false
|
72
73
|
}
|
73
74
|
]
|
74
75
|
}
|
@@ -619,7 +620,9 @@ module.exports = {
|
|
619
620
|
// Report the first declaration.
|
620
621
|
if (unusedVar.defs.length > 0) {
|
621
622
|
context.report({
|
622
|
-
node: unusedVar.
|
623
|
+
node: unusedVar.references.length ? unusedVar.references[
|
624
|
+
unusedVar.references.length - 1
|
625
|
+
].identifier : unusedVar.identifiers[0],
|
623
626
|
messageId: "unusedVar",
|
624
627
|
data: unusedVar.references.some(ref => ref.isWrite())
|
625
628
|
? getAssignedMessageData(unusedVar)
|
@@ -77,7 +77,7 @@ module.exports = {
|
|
77
77
|
if (lastTokenOfPreviousProperty.loc.end.line === firstTokenOfCurrentProperty.loc.start.line) {
|
78
78
|
context.report({
|
79
79
|
node,
|
80
|
-
loc: firstTokenOfCurrentProperty.loc
|
80
|
+
loc: firstTokenOfCurrentProperty.loc,
|
81
81
|
messageId,
|
82
82
|
fix(fixer) {
|
83
83
|
const comma = sourceCode.getTokenBefore(firstTokenOfCurrentProperty);
|
@@ -35,11 +35,8 @@ module.exports = {
|
|
35
35
|
properties: {
|
36
36
|
overrides: {
|
37
37
|
type: "object",
|
38
|
-
|
39
|
-
|
40
|
-
type: "string",
|
41
|
-
enum: ["after", "before", "none", "ignore"]
|
42
|
-
}
|
38
|
+
additionalProperties: {
|
39
|
+
enum: ["after", "before", "none", "ignore"]
|
43
40
|
}
|
44
41
|
}
|
45
42
|
},
|
@@ -25,6 +25,15 @@ function isStringLiteral(node) {
|
|
25
25
|
return node.type === "Literal" && typeof node.value === "string";
|
26
26
|
}
|
27
27
|
|
28
|
+
/**
|
29
|
+
* Determines whether the given node is a regex literal.
|
30
|
+
* @param {ASTNode} node Node to check.
|
31
|
+
* @returns {boolean} True if the node is a regex literal.
|
32
|
+
*/
|
33
|
+
function isRegexLiteral(node) {
|
34
|
+
return node.type === "Literal" && Object.prototype.hasOwnProperty.call(node, "regex");
|
35
|
+
}
|
36
|
+
|
28
37
|
/**
|
29
38
|
* Determines whether the given node is a template literal without expressions.
|
30
39
|
* @param {ASTNode} node Node to check.
|
@@ -50,14 +59,28 @@ module.exports = {
|
|
50
59
|
url: "https://eslint.org/docs/rules/prefer-regex-literals"
|
51
60
|
},
|
52
61
|
|
53
|
-
schema: [
|
62
|
+
schema: [
|
63
|
+
{
|
64
|
+
type: "object",
|
65
|
+
properties: {
|
66
|
+
disallowRedundantWrapping: {
|
67
|
+
type: "boolean",
|
68
|
+
default: false
|
69
|
+
}
|
70
|
+
},
|
71
|
+
additionalProperties: false
|
72
|
+
}
|
73
|
+
],
|
54
74
|
|
55
75
|
messages: {
|
56
|
-
unexpectedRegExp: "Use a regular expression literal instead of the 'RegExp' constructor."
|
76
|
+
unexpectedRegExp: "Use a regular expression literal instead of the 'RegExp' constructor.",
|
77
|
+
unexpectedRedundantRegExp: "Regular expression literal is unnecessarily wrapped within a 'RegExp' constructor.",
|
78
|
+
unexpectedRedundantRegExpWithFlags: "Use regular expression literal with flags instead of the 'RegExp' constructor."
|
57
79
|
}
|
58
80
|
},
|
59
81
|
|
60
82
|
create(context) {
|
83
|
+
const [{ disallowRedundantWrapping = false } = {}] = context.options;
|
61
84
|
|
62
85
|
/**
|
63
86
|
* Determines whether the given identifier node is a reference to a global variable.
|
@@ -98,6 +121,40 @@ module.exports = {
|
|
98
121
|
isStringRawTaggedStaticTemplateLiteral(node);
|
99
122
|
}
|
100
123
|
|
124
|
+
/**
|
125
|
+
* Determines whether the relevant arguments of the given are all static string literals.
|
126
|
+
* @param {ASTNode} node Node to check.
|
127
|
+
* @returns {boolean} True if all arguments are static strings.
|
128
|
+
*/
|
129
|
+
function hasOnlyStaticStringArguments(node) {
|
130
|
+
const args = node.arguments;
|
131
|
+
|
132
|
+
if ((args.length === 1 || args.length === 2) && args.every(isStaticString)) {
|
133
|
+
return true;
|
134
|
+
}
|
135
|
+
|
136
|
+
return false;
|
137
|
+
}
|
138
|
+
|
139
|
+
/**
|
140
|
+
* Determines whether the arguments of the given node indicate that a regex literal is unnecessarily wrapped.
|
141
|
+
* @param {ASTNode} node Node to check.
|
142
|
+
* @returns {boolean} True if the node already contains a regex literal argument.
|
143
|
+
*/
|
144
|
+
function isUnnecessarilyWrappedRegexLiteral(node) {
|
145
|
+
const args = node.arguments;
|
146
|
+
|
147
|
+
if (args.length === 1 && isRegexLiteral(args[0])) {
|
148
|
+
return true;
|
149
|
+
}
|
150
|
+
|
151
|
+
if (args.length === 2 && isRegexLiteral(args[0]) && isStaticString(args[1])) {
|
152
|
+
return true;
|
153
|
+
}
|
154
|
+
|
155
|
+
return false;
|
156
|
+
}
|
157
|
+
|
101
158
|
return {
|
102
159
|
Program() {
|
103
160
|
const scope = context.getScope();
|
@@ -110,12 +167,13 @@ module.exports = {
|
|
110
167
|
};
|
111
168
|
|
112
169
|
for (const { node } of tracker.iterateGlobalReferences(traceMap)) {
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
170
|
+
if (disallowRedundantWrapping && isUnnecessarilyWrappedRegexLiteral(node)) {
|
171
|
+
if (node.arguments.length === 2) {
|
172
|
+
context.report({ node, messageId: "unexpectedRedundantRegExpWithFlags" });
|
173
|
+
} else {
|
174
|
+
context.report({ node, messageId: "unexpectedRedundantRegExp" });
|
175
|
+
}
|
176
|
+
} else if (hasOnlyStaticStringArguments(node)) {
|
119
177
|
context.report({ node, messageId: "unexpectedRegExp" });
|
120
178
|
}
|
121
179
|
}
|
package/lib/rules/quote-props.js
CHANGED
@@ -154,7 +154,7 @@ module.exports = {
|
|
154
154
|
|
155
155
|
try {
|
156
156
|
tokens = espree.tokenize(key.value);
|
157
|
-
} catch
|
157
|
+
} catch {
|
158
158
|
return;
|
159
159
|
}
|
160
160
|
|
@@ -239,7 +239,7 @@ module.exports = {
|
|
239
239
|
|
240
240
|
try {
|
241
241
|
tokens = espree.tokenize(key.value);
|
242
|
-
} catch
|
242
|
+
} catch {
|
243
243
|
necessaryQuotes = true;
|
244
244
|
return;
|
245
245
|
}
|
@@ -49,7 +49,10 @@ module.exports = {
|
|
49
49
|
if (never && hasWhitespace) {
|
50
50
|
context.report({
|
51
51
|
node,
|
52
|
-
loc:
|
52
|
+
loc: {
|
53
|
+
start: tagToken.loc.end,
|
54
|
+
end: literalToken.loc.start
|
55
|
+
},
|
53
56
|
messageId: "unexpected",
|
54
57
|
fix(fixer) {
|
55
58
|
const comments = sourceCode.getCommentsBefore(node.quasi);
|
@@ -68,7 +71,10 @@ module.exports = {
|
|
68
71
|
} else if (!never && !hasWhitespace) {
|
69
72
|
context.report({
|
70
73
|
node,
|
71
|
-
loc:
|
74
|
+
loc: {
|
75
|
+
start: node.loc.start,
|
76
|
+
end: literalToken.loc.start
|
77
|
+
},
|
72
78
|
messageId: "missing",
|
73
79
|
fix(fixer) {
|
74
80
|
return fixer.insertTextAfter(tagToken, " ");
|
@@ -416,6 +416,53 @@ function equalTokens(left, right, sourceCode) {
|
|
416
416
|
return true;
|
417
417
|
}
|
418
418
|
|
419
|
+
/**
|
420
|
+
* Check if the given node is a true logical expression or not.
|
421
|
+
*
|
422
|
+
* The three binary expressions logical-or (`||`), logical-and (`&&`), and
|
423
|
+
* coalesce (`??`) are known as `ShortCircuitExpression`.
|
424
|
+
* But ESTree represents those by `LogicalExpression` node.
|
425
|
+
*
|
426
|
+
* This function rejects coalesce expressions of `LogicalExpression` node.
|
427
|
+
* @param {ASTNode} node The node to check.
|
428
|
+
* @returns {boolean} `true` if the node is `&&` or `||`.
|
429
|
+
* @see https://tc39.es/ecma262/#prod-ShortCircuitExpression
|
430
|
+
*/
|
431
|
+
function isLogicalExpression(node) {
|
432
|
+
return (
|
433
|
+
node.type === "LogicalExpression" &&
|
434
|
+
(node.operator === "&&" || node.operator === "||")
|
435
|
+
);
|
436
|
+
}
|
437
|
+
|
438
|
+
/**
|
439
|
+
* Check if the given node is a nullish coalescing expression or not.
|
440
|
+
*
|
441
|
+
* The three binary expressions logical-or (`||`), logical-and (`&&`), and
|
442
|
+
* coalesce (`??`) are known as `ShortCircuitExpression`.
|
443
|
+
* But ESTree represents those by `LogicalExpression` node.
|
444
|
+
*
|
445
|
+
* This function finds only coalesce expressions of `LogicalExpression` node.
|
446
|
+
* @param {ASTNode} node The node to check.
|
447
|
+
* @returns {boolean} `true` if the node is `??`.
|
448
|
+
*/
|
449
|
+
function isCoalesceExpression(node) {
|
450
|
+
return node.type === "LogicalExpression" && node.operator === "??";
|
451
|
+
}
|
452
|
+
|
453
|
+
/**
|
454
|
+
* Check if given two nodes are the pair of a logical expression and a coalesce expression.
|
455
|
+
* @param {ASTNode} left A node to check.
|
456
|
+
* @param {ASTNode} right Another node to check.
|
457
|
+
* @returns {boolean} `true` if the two nodes are the pair of a logical expression and a coalesce expression.
|
458
|
+
*/
|
459
|
+
function isMixedLogicalAndCoalesceExpressions(left, right) {
|
460
|
+
return (
|
461
|
+
(isLogicalExpression(left) && isCoalesceExpression(right)) ||
|
462
|
+
(isCoalesceExpression(left) && isLogicalExpression(right))
|
463
|
+
);
|
464
|
+
}
|
465
|
+
|
419
466
|
//------------------------------------------------------------------------------
|
420
467
|
// Public Interface
|
421
468
|
//------------------------------------------------------------------------------
|
@@ -779,6 +826,7 @@ module.exports = {
|
|
779
826
|
case "LogicalExpression":
|
780
827
|
switch (node.operator) {
|
781
828
|
case "||":
|
829
|
+
case "??":
|
782
830
|
return 4;
|
783
831
|
case "&&":
|
784
832
|
return 5;
|
@@ -1415,7 +1463,7 @@ module.exports = {
|
|
1415
1463
|
|
1416
1464
|
try {
|
1417
1465
|
tokens = espree.tokenize(leftValue, espreeOptions);
|
1418
|
-
} catch
|
1466
|
+
} catch {
|
1419
1467
|
return false;
|
1420
1468
|
}
|
1421
1469
|
|
@@ -1444,7 +1492,7 @@ module.exports = {
|
|
1444
1492
|
|
1445
1493
|
try {
|
1446
1494
|
tokens = espree.tokenize(rightValue, espreeOptions);
|
1447
|
-
} catch
|
1495
|
+
} catch {
|
1448
1496
|
return false;
|
1449
1497
|
}
|
1450
1498
|
|
@@ -1538,5 +1586,9 @@ module.exports = {
|
|
1538
1586
|
*/
|
1539
1587
|
hasOctalEscapeSequence(rawString) {
|
1540
1588
|
return OCTAL_ESCAPE_PATTERN.test(rawString);
|
1541
|
-
}
|
1589
|
+
},
|
1590
|
+
|
1591
|
+
isLogicalExpression,
|
1592
|
+
isCoalesceExpression,
|
1593
|
+
isMixedLogicalAndCoalesceExpressions
|
1542
1594
|
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "7.
|
3
|
+
"version": "7.4.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -52,10 +52,11 @@
|
|
52
52
|
"cross-spawn": "^7.0.2",
|
53
53
|
"debug": "^4.0.1",
|
54
54
|
"doctrine": "^3.0.0",
|
55
|
-
"
|
55
|
+
"enquirer": "^2.3.5",
|
56
|
+
"eslint-scope": "^5.1.0",
|
56
57
|
"eslint-utils": "^2.0.0",
|
57
|
-
"eslint-visitor-keys": "^1.
|
58
|
-
"espree": "^7.
|
58
|
+
"eslint-visitor-keys": "^1.2.0",
|
59
|
+
"espree": "^7.1.0",
|
59
60
|
"esquery": "^1.2.0",
|
60
61
|
"esutils": "^2.0.2",
|
61
62
|
"file-entry-cache": "^5.0.1",
|
@@ -65,7 +66,6 @@
|
|
65
66
|
"ignore": "^4.0.6",
|
66
67
|
"import-fresh": "^3.0.0",
|
67
68
|
"imurmurhash": "^0.1.4",
|
68
|
-
"inquirer": "^7.0.0",
|
69
69
|
"is-glob": "^4.0.0",
|
70
70
|
"js-yaml": "^3.13.1",
|
71
71
|
"json-stable-stringify-without-jsonify": "^1.0.1",
|
@@ -86,7 +86,7 @@
|
|
86
86
|
"devDependencies": {
|
87
87
|
"@babel/core": "^7.4.3",
|
88
88
|
"@babel/preset-env": "^7.4.3",
|
89
|
-
"acorn": "^7.
|
89
|
+
"acorn": "^7.2.0",
|
90
90
|
"babel-loader": "^8.0.5",
|
91
91
|
"chai": "^4.0.1",
|
92
92
|
"cheerio": "^0.22.0",
|