es-check 9.6.4 → 9.7.2
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 +4 -1
- package/lib/browserslist.js +23 -13
- package/lib/cache.js +2 -1
- package/lib/check-runner/index.js +13 -31
- package/lib/check-runner/utils.js +80 -121
- package/lib/cli/constants.js +4 -7
- package/lib/cli/handler.js +66 -76
- package/lib/cli/parser.js +16 -12
- package/lib/cli/utils.js +21 -25
- package/lib/constants/es-features/15.js +17 -1
- package/lib/constants/es-features/16.js +34 -0
- package/lib/constants/es-features/17.js +90 -11
- package/lib/constants/es-features/9.js +2 -1
- package/lib/constants/es-features/globals.js +71 -0
- package/lib/constants/es-features/index.js +19 -19
- package/lib/constants/es-features/polyfills.js +15 -43
- package/lib/constants/featureParserMapping.js +2 -7
- package/lib/constants/index.js +59 -1
- package/lib/constants/polyfillableFeatures.js +12 -0
- package/lib/constants/versions.js +1 -1
- package/lib/detectFeatures.js +54 -50
- package/lib/helpers/ast.js +66 -154
- package/lib/helpers/astDetector.js +1647 -68
- package/lib/helpers/files.js +9 -5
- package/lib/helpers/index.js +7 -18
- package/lib/helpers/logger.js +3 -7
- package/lib/helpers/parsers.js +25 -20
- package/lib/helpers/sourcemap.js +40 -39
- package/package.json +116 -198
package/lib/helpers/ast.js
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
|
+
const {
|
|
2
|
+
ARRAY_CONSTRUCTOR_FUNCTIONS,
|
|
3
|
+
ARRAY_LIKE_NAMES,
|
|
4
|
+
ARRAY_METHODS,
|
|
5
|
+
COMMON_NON_ARRAY_NAMES,
|
|
6
|
+
COMMON_NON_SET_NAMES,
|
|
7
|
+
SET_LIKE_NAMES,
|
|
8
|
+
} = require("../constants");
|
|
9
|
+
|
|
1
10
|
function hasOptionsCause(node) {
|
|
2
11
|
const args = node.arguments;
|
|
3
|
-
|
|
12
|
+
const hasTooFewArgs = !args || args.length < 2;
|
|
13
|
+
if (hasTooFewArgs) return false;
|
|
4
14
|
|
|
5
15
|
const optionsArg = args[1];
|
|
6
16
|
if (optionsArg?.type !== "ObjectExpression") return false;
|
|
7
17
|
|
|
8
|
-
return optionsArg.properties?.some(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
18
|
+
return optionsArg.properties?.some(isCauseProperty);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function isCauseProperty(prop) {
|
|
22
|
+
const isProperty = prop.type === "Property";
|
|
23
|
+
const hasIdentifierKey = prop.key?.type === "Identifier";
|
|
24
|
+
const isCauseKey = prop.key?.name === "cause";
|
|
25
|
+
const hasCauseProperty = isProperty && hasIdentifierKey && isCauseKey;
|
|
26
|
+
return hasCauseProperty;
|
|
14
27
|
}
|
|
15
28
|
|
|
16
29
|
function hasNumericArgument(node) {
|
|
@@ -19,76 +32,17 @@ function hasNumericArgument(node) {
|
|
|
19
32
|
if (!hasArgs) return false;
|
|
20
33
|
|
|
21
34
|
const arg = args[0];
|
|
22
|
-
const isNumericLiteral =
|
|
23
|
-
arg.type === "Literal" && typeof arg.value === "number";
|
|
35
|
+
const isNumericLiteral = arg.type === "Literal" && typeof arg.value === "number";
|
|
24
36
|
|
|
25
37
|
const isUnaryExpression = arg.type === "UnaryExpression";
|
|
26
38
|
const isNegationOperator = arg.operator === "-";
|
|
27
39
|
const hasNumericLiteralArgument =
|
|
28
40
|
arg.argument?.type === "Literal" && typeof arg.argument.value === "number";
|
|
29
|
-
const isNegativeNumeric =
|
|
30
|
-
isUnaryExpression && isNegationOperator && hasNumericLiteralArgument;
|
|
41
|
+
const isNegativeNumeric = isUnaryExpression && isNegationOperator && hasNumericLiteralArgument;
|
|
31
42
|
|
|
32
43
|
return isNumericLiteral || isNegativeNumeric;
|
|
33
44
|
}
|
|
34
45
|
|
|
35
|
-
const ARRAY_LIKE_NAMES = new Set([
|
|
36
|
-
"arr",
|
|
37
|
-
"array",
|
|
38
|
-
"list",
|
|
39
|
-
"items",
|
|
40
|
-
"values",
|
|
41
|
-
"arguments",
|
|
42
|
-
]);
|
|
43
|
-
|
|
44
|
-
const ARRAY_CONSTRUCTOR_FUNCTIONS = new Set([
|
|
45
|
-
"Array",
|
|
46
|
-
"from",
|
|
47
|
-
"of",
|
|
48
|
-
"slice",
|
|
49
|
-
"filter",
|
|
50
|
-
"map",
|
|
51
|
-
"concat",
|
|
52
|
-
]);
|
|
53
|
-
|
|
54
|
-
const ARRAY_METHODS = new Set([
|
|
55
|
-
"slice",
|
|
56
|
-
"filter",
|
|
57
|
-
"map",
|
|
58
|
-
"concat",
|
|
59
|
-
"from",
|
|
60
|
-
"of",
|
|
61
|
-
]);
|
|
62
|
-
|
|
63
|
-
const COMMON_NON_ARRAY_NAMES = new Set([
|
|
64
|
-
"obj",
|
|
65
|
-
"object",
|
|
66
|
-
"foo",
|
|
67
|
-
"bar",
|
|
68
|
-
"baz",
|
|
69
|
-
"data",
|
|
70
|
-
"config",
|
|
71
|
-
"options",
|
|
72
|
-
"params",
|
|
73
|
-
"props",
|
|
74
|
-
"state",
|
|
75
|
-
"item",
|
|
76
|
-
"element",
|
|
77
|
-
"node",
|
|
78
|
-
"target",
|
|
79
|
-
"source",
|
|
80
|
-
"result",
|
|
81
|
-
"response",
|
|
82
|
-
"request",
|
|
83
|
-
"payload",
|
|
84
|
-
"model",
|
|
85
|
-
"view",
|
|
86
|
-
"controller",
|
|
87
|
-
"service",
|
|
88
|
-
"utils",
|
|
89
|
-
"helpers",
|
|
90
|
-
"custom",
|
|
91
|
-
]);
|
|
92
46
|
function isArrayExpression(calleeObject) {
|
|
93
47
|
return calleeObject.type === "ArrayExpression";
|
|
94
48
|
}
|
|
@@ -121,8 +75,7 @@ function isArrayConstructorCall(calleeObject) {
|
|
|
121
75
|
if (isMemberExpressionCallee) {
|
|
122
76
|
const innerProperty = innerCallee.property;
|
|
123
77
|
const hasPropertyName = innerProperty?.name;
|
|
124
|
-
const isArrayMethod =
|
|
125
|
-
hasPropertyName && ARRAY_METHODS.has(innerProperty.name);
|
|
78
|
+
const isArrayMethod = hasPropertyName && ARRAY_METHODS.has(innerProperty.name);
|
|
126
79
|
return isArrayMethod;
|
|
127
80
|
}
|
|
128
81
|
|
|
@@ -144,42 +97,9 @@ function isArrayLikeCall(node) {
|
|
|
144
97
|
return isArray;
|
|
145
98
|
}
|
|
146
99
|
|
|
147
|
-
// ── Set-like call detection (mirrors Array-like approach) ──
|
|
148
|
-
|
|
149
|
-
const SET_LIKE_NAMES = new Set(["set", "sets", "seta", "setb", "set1", "set2"]);
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Words that start/end with "set" but are not Set instances.
|
|
153
|
-
* Used as a blocklist when the broader startsWith/endsWith heuristic is active.
|
|
154
|
-
*/
|
|
155
|
-
const COMMON_NON_SET_NAMES = new Set([
|
|
156
|
-
"settings",
|
|
157
|
-
"setup",
|
|
158
|
-
"setter",
|
|
159
|
-
"setstate",
|
|
160
|
-
"setvalue",
|
|
161
|
-
"setdata",
|
|
162
|
-
"setitem",
|
|
163
|
-
"setinterval",
|
|
164
|
-
"settimeout",
|
|
165
|
-
"offset",
|
|
166
|
-
"dataset",
|
|
167
|
-
"reset",
|
|
168
|
-
"asset",
|
|
169
|
-
"charset",
|
|
170
|
-
"onset",
|
|
171
|
-
"subset",
|
|
172
|
-
"mindset",
|
|
173
|
-
"closet",
|
|
174
|
-
"baseset",
|
|
175
|
-
]);
|
|
176
|
-
|
|
177
100
|
function isSetConstructorCall(calleeObject) {
|
|
178
|
-
|
|
179
|
-
if (
|
|
180
|
-
calleeObject.type === "NewExpression" &&
|
|
181
|
-
calleeObject.callee?.name === "Set"
|
|
182
|
-
) {
|
|
101
|
+
const isNewSet = calleeObject.type === "NewExpression" && calleeObject.callee?.name === "Set";
|
|
102
|
+
if (isNewSet) {
|
|
183
103
|
return true;
|
|
184
104
|
}
|
|
185
105
|
return false;
|
|
@@ -189,38 +109,41 @@ function isSetLikeIdentifier(calleeObject) {
|
|
|
189
109
|
if (calleeObject.type !== "Identifier") return false;
|
|
190
110
|
const name = calleeObject.name.toLowerCase();
|
|
191
111
|
if (COMMON_NON_SET_NAMES.has(name)) return false;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
);
|
|
112
|
+
const hasKnownSetName = SET_LIKE_NAMES.has(name);
|
|
113
|
+
const hasSetPrefix = name.startsWith("set");
|
|
114
|
+
const hasSetSuffix = name.endsWith("set");
|
|
115
|
+
const isSetLike = hasKnownSetName || hasSetPrefix || hasSetSuffix;
|
|
116
|
+
return isSetLike;
|
|
195
117
|
}
|
|
196
118
|
|
|
197
119
|
function isSetLikeCall(node) {
|
|
198
120
|
const calleeObject = node.callee?.object;
|
|
199
121
|
if (!calleeObject) return false;
|
|
200
122
|
|
|
201
|
-
return (
|
|
202
|
-
|
|
203
|
-
|
|
123
|
+
return isSetConstructorCall(calleeObject) || isSetLikeIdentifier(calleeObject);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function getStaticPropertyName(node, property = node?.property) {
|
|
127
|
+
if (property?.type === "PrivateIdentifier") return null;
|
|
128
|
+
if (!node?.computed) return property?.name;
|
|
129
|
+
const isLiteral = property?.type === "Literal";
|
|
130
|
+
if (!isLiteral) return null;
|
|
131
|
+
return String(property.value);
|
|
204
132
|
}
|
|
205
133
|
|
|
206
134
|
function checkMap(node, astInfo) {
|
|
207
135
|
const callee = node.callee;
|
|
208
136
|
const calleeObject = callee?.object;
|
|
209
|
-
const calleeProperty = callee?.property;
|
|
210
137
|
const calleeObjectName = calleeObject?.name;
|
|
211
|
-
const calleePropertyName =
|
|
138
|
+
const calleePropertyName = getStaticPropertyName(callee);
|
|
212
139
|
|
|
213
140
|
const hasKindMismatch = astInfo.kind && node.kind !== astInfo.kind;
|
|
214
|
-
const hasOperatorMismatch =
|
|
215
|
-
|
|
216
|
-
const hasCalleeMismatch =
|
|
217
|
-
astInfo.callee && (!callee || callee.name !== astInfo.callee);
|
|
141
|
+
const hasOperatorMismatch = astInfo.operator && node.operator !== astInfo.operator;
|
|
142
|
+
const hasCalleeMismatch = astInfo.callee && (!callee || callee.name !== astInfo.callee);
|
|
218
143
|
|
|
219
144
|
const hasCalleeObject = calleeObjectName === astInfo.object;
|
|
220
|
-
const hasCalleeIdentifier =
|
|
221
|
-
|
|
222
|
-
const hasPropertyMismatch =
|
|
223
|
-
astInfo.property && calleePropertyName !== astInfo.property;
|
|
145
|
+
const hasCalleeIdentifier = callee?.type === "Identifier" && callee?.name === astInfo.object;
|
|
146
|
+
const hasPropertyMismatch = astInfo.property && calleePropertyName !== astInfo.property;
|
|
224
147
|
const hasPropertyMatch = calleePropertyName === astInfo.property;
|
|
225
148
|
const shouldExclude = astInfo.excludeObjects?.includes(calleeObjectName);
|
|
226
149
|
|
|
@@ -229,50 +152,38 @@ function checkMap(node, astInfo) {
|
|
|
229
152
|
needsObjectAndProperty && !(hasCalleeObject && hasPropertyMatch);
|
|
230
153
|
|
|
231
154
|
const hasObjectPropertyMismatch =
|
|
232
|
-
!needsObjectAndProperty &&
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
const
|
|
237
|
-
!needsObjectAndProperty &&
|
|
238
|
-
astInfo.object &&
|
|
239
|
-
!hasCalleeObject &&
|
|
240
|
-
!hasCalleeIdentifier;
|
|
241
|
-
const hasPropertyWithoutMatch =
|
|
242
|
-
astInfo.property && !astInfo.object && !hasPropertyMatch;
|
|
155
|
+
!needsObjectAndProperty && astInfo.object && hasCalleeObject && hasPropertyMismatch;
|
|
156
|
+
const needsObjectOnly = !needsObjectAndProperty && astInfo.object;
|
|
157
|
+
const hasNoCalleeObjectMatch = !hasCalleeObject && !hasCalleeIdentifier;
|
|
158
|
+
const hasObjectButNoMatch = needsObjectOnly && hasNoCalleeObjectMatch;
|
|
159
|
+
const hasPropertyWithoutMatch = astInfo.property && !astInfo.object && !hasPropertyMatch;
|
|
243
160
|
const hasPropertyWithExclusion =
|
|
244
161
|
astInfo.property && !astInfo.object && hasPropertyMatch && shouldExclude;
|
|
245
162
|
|
|
246
|
-
const hasOptionsCauseMismatch =
|
|
247
|
-
astInfo.hasOptionsCause && !hasOptionsCause(node);
|
|
163
|
+
const hasOptionsCauseMismatch = astInfo.hasOptionsCause && !hasOptionsCause(node);
|
|
248
164
|
|
|
249
165
|
const callerType = calleeObject?.type;
|
|
250
|
-
const hasExcludedCallerType =
|
|
251
|
-
astInfo.excludeCallerTypes?.includes(callerType);
|
|
166
|
+
const hasExcludedCallerType = astInfo.excludeCallerTypes?.includes(callerType);
|
|
252
167
|
|
|
253
|
-
const hasNumericArgMismatch =
|
|
254
|
-
astInfo.requireNumericArg && !hasNumericArgument(node);
|
|
168
|
+
const hasNumericArgMismatch = astInfo.requireNumericArg && !hasNumericArgument(node);
|
|
255
169
|
|
|
256
|
-
const hasArrayLikeCallMismatch =
|
|
257
|
-
astInfo.requireArrayLikeCall && !isArrayLikeCall(node);
|
|
170
|
+
const hasArrayLikeCallMismatch = astInfo.requireArrayLikeCall && !isArrayLikeCall(node);
|
|
258
171
|
|
|
259
|
-
const hasSetLikeCallMismatch =
|
|
260
|
-
astInfo.requireSetLikeCall && !isSetLikeCall(node);
|
|
172
|
+
const hasSetLikeCallMismatch = astInfo.requireSetLikeCall && !isSetLikeCall(node);
|
|
261
173
|
|
|
262
|
-
const
|
|
263
|
-
hasKindMismatch ||
|
|
264
|
-
hasOperatorMismatch ||
|
|
265
|
-
hasCalleeMismatch ||
|
|
266
|
-
hasObjectPropertyMismatch ||
|
|
174
|
+
const mismatchChecks = [
|
|
175
|
+
hasKindMismatch || hasOperatorMismatch || hasCalleeMismatch || hasObjectPropertyMismatch,
|
|
267
176
|
hasObjectButNoMatch ||
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
177
|
+
hasPropertyWithoutMatch ||
|
|
178
|
+
hasPropertyWithExclusion ||
|
|
179
|
+
hasObjectAndPropertyMismatch,
|
|
271
180
|
hasOptionsCauseMismatch ||
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
hasSetLikeCallMismatch
|
|
181
|
+
hasExcludedCallerType ||
|
|
182
|
+
hasNumericArgMismatch ||
|
|
183
|
+
hasArrayLikeCallMismatch,
|
|
184
|
+
hasSetLikeCallMismatch,
|
|
185
|
+
];
|
|
186
|
+
const hasMismatch = mismatchChecks.includes(true);
|
|
276
187
|
|
|
277
188
|
if (hasMismatch) return false;
|
|
278
189
|
|
|
@@ -281,4 +192,5 @@ function checkMap(node, astInfo) {
|
|
|
281
192
|
|
|
282
193
|
module.exports = {
|
|
283
194
|
checkMap,
|
|
195
|
+
getStaticPropertyName,
|
|
284
196
|
};
|