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.
@@ -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
- if (!args || args.length < 2) return false;
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
- (prop) =>
10
- prop.type === "Property" &&
11
- prop.key?.type === "Identifier" &&
12
- prop.key?.name === "cause",
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
- // new Set() or new Set([...])
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
- return (
193
- SET_LIKE_NAMES.has(name) || name.startsWith("set") || name.endsWith("set")
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
- isSetConstructorCall(calleeObject) || isSetLikeIdentifier(calleeObject)
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 = calleeProperty?.name;
138
+ const calleePropertyName = getStaticPropertyName(callee);
212
139
 
213
140
  const hasKindMismatch = astInfo.kind && node.kind !== astInfo.kind;
214
- const hasOperatorMismatch =
215
- astInfo.operator && node.operator !== astInfo.operator;
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
- callee?.type === "Identifier" && callee?.name === astInfo.object;
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
- astInfo.object &&
234
- hasCalleeObject &&
235
- hasPropertyMismatch;
236
- const hasObjectButNoMatch =
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 hasMismatch =
263
- hasKindMismatch ||
264
- hasOperatorMismatch ||
265
- hasCalleeMismatch ||
266
- hasObjectPropertyMismatch ||
174
+ const mismatchChecks = [
175
+ hasKindMismatch || hasOperatorMismatch || hasCalleeMismatch || hasObjectPropertyMismatch,
267
176
  hasObjectButNoMatch ||
268
- hasPropertyWithoutMatch ||
269
- hasPropertyWithExclusion ||
270
- hasObjectAndPropertyMismatch ||
177
+ hasPropertyWithoutMatch ||
178
+ hasPropertyWithExclusion ||
179
+ hasObjectAndPropertyMismatch,
271
180
  hasOptionsCauseMismatch ||
272
- hasExcludedCallerType ||
273
- hasNumericArgMismatch ||
274
- hasArrayLikeCallMismatch ||
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
  };