es-check 9.6.0-1 → 9.6.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 CHANGED
@@ -80,7 +80,7 @@ Modern JavaScript builds assume proper transpilation via tools like Babel. ES Ch
80
80
 
81
81
  ## What features does ES Check check for?
82
82
 
83
- ES Check validates syntax by default. Add `--checkFeatures` for ES version-specific feature checking. View supported [features](./lib/helpers/detectFeatures/constants/es-features/).
83
+ ES Check validates syntax by default. Add `--checkFeatures` for ES version-specific feature checking. View supported [features](./lib/constants/es-features/).
84
84
 
85
85
  ---
86
86
 
@@ -118,7 +118,7 @@ Usage: index [options] [ecmaVersion] [files...]
118
118
 
119
119
  Arguments:
120
120
  ecmaVersion ecmaVersion to check files against. Can be: es3, es4, es5, es6/es2015, es7/es2016, es8/es2017, es9/es2018, es10/es2019, es11/es2020, es12/es2021,
121
- es13/es2022, es14/es2023
121
+ es13/es2022, es14/es2023, es15/es2024, es16/es2025
122
122
  files a glob of files to to test the EcmaScript version against
123
123
 
124
124
  ```
@@ -142,6 +142,7 @@ Here's a comprehensive list of all available options:
142
142
  | `--silent` | Silent mode: does not output anything, giving no indication of success or failure other than the exit code (default: false) |
143
143
  | `--checkFeatures` | Check for actual ES version specific features (default: false) |
144
144
  | `--checkForPolyfills` | Consider polyfills when checking features (only works with --checkFeatures) (default: false) |
145
+ | `--ignorePolyfillable [lib]` | Ignore polyfillable features; optionally specify library (e.g., `core-js`) to limit scope |
145
146
  | `--ignore <features>` | Comma-separated list of features to ignore, e.g., "ErrorCause,TopLevelAwait" |
146
147
  | `--ignoreFile <path>` | Path to JSON file containing features to ignore |
147
148
  | `--allowList <features>` | Comma-separated list of features to allow even in lower ES versions, e.g., "const,let" |
@@ -309,6 +310,7 @@ Here's an example of what an `.escheckrc` file will look like:
309
310
  "looseGlobMatching": false,
310
311
  "checkFeatures": true,
311
312
  "checkForPolyfills": true,
313
+ "ignorePolyfillable": "core-js",
312
314
  "ignore": ["ErrorCause", "TopLevelAwait"],
313
315
  "allowList": ["ArrayToSorted", "ObjectHasOwn"],
314
316
  "checkBrowser": false,
@@ -320,22 +322,23 @@ Here's an example of what an `.escheckrc` file will look like:
320
322
 
321
323
  ### Configuration Options
322
324
 
323
- | Option | Type | Description |
324
- | ------------------- | --------------- | ------------------------------------------------------------------ |
325
- | `ecmaVersion` | String | ECMAScript version to check against (e.g., "es5", "es6", "es2020") |
326
- | `files` | String or Array | Files or glob patterns to check |
327
- | `module` | Boolean | Whether to parse files as ES modules |
328
- | `not` | Array | Files or glob patterns to exclude |
329
- | `allowHashBang` | Boolean | Whether to allow hash bang in files |
330
- | `looseGlobMatching` | Boolean | Whether to ignore missing files in globs |
331
- | `checkFeatures` | Boolean | Whether to check for ES version specific features |
332
- | `checkForPolyfills` | Boolean | Whether to consider polyfills when checking features |
333
- | `ignore` | Array | Features to ignore when checking |
334
- | `allowList` | Array | Features to allow even in lower ES versions |
335
- | `checkBrowser` | Boolean | Whether to use browserslist configuration to determine ES version |
336
- | `browserslistQuery` | String | Custom browserslist query to use |
337
- | `browserslistPath` | String | Path to custom browserslist configuration |
338
- | `browserslistEnv` | String | Browserslist environment to use |
325
+ | Option | Type | Description |
326
+ | -------------------- | --------------- | ------------------------------------------------------------------------------------ |
327
+ | `ecmaVersion` | String | ECMAScript version to check against (e.g., "es5", "es6", "es2020") |
328
+ | `files` | String or Array | Files or glob patterns to check |
329
+ | `module` | Boolean | Whether to parse files as ES modules |
330
+ | `not` | Array | Files or glob patterns to exclude |
331
+ | `allowHashBang` | Boolean | Whether to allow hash bang in files |
332
+ | `looseGlobMatching` | Boolean | Whether to ignore missing files in globs |
333
+ | `checkFeatures` | Boolean | Whether to check for ES version specific features |
334
+ | `checkForPolyfills` | Boolean | Whether to consider polyfills when checking features |
335
+ | `ignorePolyfillable` | Boolean/String | Ignore polyfillable features; set to library name (e.g., `"core-js"`) to limit scope |
336
+ | `ignore` | Array | Features to ignore when checking |
337
+ | `allowList` | Array | Features to allow even in lower ES versions |
338
+ | `checkBrowser` | Boolean | Whether to use browserslist configuration to determine ES version |
339
+ | `browserslistQuery` | String | Custom browserslist query to use |
340
+ | `browserslistPath` | String | Path to custom browserslist configuration |
341
+ | `browserslistEnv` | String | Browserslist environment to use |
339
342
 
340
343
  ### Multiple Configurations
341
344
 
@@ -443,7 +446,23 @@ ES Check provides three ways to handle polyfilled features:
443
446
  es-check es2022 './dist/**/*.js' --checkFeatures --allowList="ArrayToSorted,ObjectHasOwn"
444
447
  ```
445
448
 
446
- 3. **--ignore**: Completely ignore specific features during checking
449
+ 3. **--ignorePolyfillable**: Ignore all features that can be polyfilled (or limit to a specific library)
450
+
451
+ ```sh
452
+ # Ignore all polyfillable features
453
+ es-check es2017 './dist/**/*.js' --checkFeatures --ignorePolyfillable
454
+
455
+ # Ignore only features polyfillable by core-js
456
+ es-check es2017 './dist/**/*.js' --checkFeatures --ignorePolyfillable=core-js
457
+ ```
458
+
459
+ 4. **--allowList**: Explicitly specify features to allow regardless of ES version
460
+
461
+ ```sh
462
+ es-check es2022 './dist/**/*.js' --checkFeatures --allowList="ArrayToSorted,ObjectHasOwn"
463
+ ```
464
+
465
+ 5. **--ignore**: Completely ignore specific features during checking
447
466
  ```sh
448
467
  es-check es2022 './dist/**/*.js' --checkFeatures --ignore="ArrayToSorted,ObjectHasOwn"
449
468
  ```
@@ -451,6 +470,7 @@ ES Check provides three ways to handle polyfilled features:
451
470
  #### When to use each option:
452
471
 
453
472
  - Use `--checkForPolyfills` when you have a standard polyfill setup (like core-js) and want automatic detection
473
+ - Use `--ignorePolyfillable` when you know polyfills are provided externally and don't want to flag polyfillable features
454
474
  - Use `--allowList` when you have custom polyfills or want to be explicit about which features are allowed
455
475
  - Use `--ignore` as a temporary solution when you're working on fixes
456
476
 
@@ -584,7 +604,11 @@ flowchart LR
584
604
  E -->|No| F[Success]
585
605
  G --> G1{Features<br/>Valid?}
586
606
  G1 -->|Pass| H{--checkForPolyfills?}
587
- G1 -->|Fail| D
607
+ G1 -->|Fail| L{--ignorePolyfillable?}
608
+ L -->|Yes| M{Feature<br/>Polyfillable?}
609
+ L -->|No| D
610
+ M -->|Yes| F
611
+ M -->|No| D
588
612
  H -->|Yes| I{Polyfills<br/>Detected?}
589
613
  H -->|No| F
590
614
  I -->|Yes| F
@@ -693,9 +717,9 @@ To update ES version support:
693
717
 
694
718
  To update ES feature detection:
695
719
 
696
- - Add features to [version-specific files](./lib/helpers/detectFeatures/constants/es-features/) (e.g., `6.js` for ES6 features)
697
- - Update [polyfill patterns](./lib/helpers/detectFeatures/constants/polyfills.js) if needed
698
- - Feature detection uses [acorn walk](https://github.com/acornjs/acorn/blob/master/acorn-walk/README.md)
720
+ - Add features to [version-specific files](./lib/constants/es-features/) (e.g., `6.js` for ES6 features)
721
+ - Update [polyfill patterns](./lib/constants/es-features/polyfills.js) if needed
722
+ - Feature detection uses AST traversal via [Acorn](https://github.com/acornjs/acorn/)
699
723
 
700
724
  Tests are located in `tests/unit/` and mirror the `lib/` structure. Please add tests for new features!
701
725
 
@@ -329,7 +329,11 @@ function processFullAST(
329
329
  esVersion,
330
330
  parseSourceType,
331
331
  ignoreList,
332
- { ast, checkForPolyfills: config.checkForPolyfills },
332
+ {
333
+ ast,
334
+ checkForPolyfills: config.checkForPolyfills,
335
+ ignorePolyfillable: config.ignorePolyfillable,
336
+ },
333
337
  );
334
338
  foundFeatures = result.foundFeatures;
335
339
  unsupportedFeatures = result.unsupportedFeatures;
@@ -47,6 +47,7 @@ const ES13_FEATURES = {
47
47
  nodeType: "CallExpression",
48
48
  property: "at",
49
49
  excludeCallerTypes: ["ObjectExpression"],
50
+ requireNumericArg: true,
50
51
  },
51
52
  },
52
53
  ObjectHasOwn: {
@@ -15,57 +15,57 @@ const POLYFILL_PATTERNS = [
15
15
  const IMPORT_PATTERNS = [
16
16
  {
17
17
  pattern:
18
- /(?:from\s+|require\s*\(\s*)['"]core-js\/modules\/es\.array\.to-sorted['"]/,
18
+ /(?:from\s+|require\s*\(\s*|import\s+)['"]core-js\/modules\/es\.array\.to-sorted['"]/,
19
19
  feature: "ArrayToSorted",
20
20
  },
21
21
  {
22
22
  pattern:
23
- /(?:from\s+|require\s*\(\s*)['"]core-js\/modules\/es\.array\.find-last['"]/,
23
+ /(?:from\s+|require\s*\(\s*|import\s+)['"]core-js\/modules\/es\.array\.find-last['"]/,
24
24
  feature: "ArrayFindLast",
25
25
  },
26
26
  {
27
27
  pattern:
28
- /(?:from\s+|require\s*\(\s*)['"]core-js\/modules\/es\.array\.find-last-index['"]/,
28
+ /(?:from\s+|require\s*\(\s*|import\s+)['"]core-js\/modules\/es\.array\.find-last-index['"]/,
29
29
  feature: "ArrayFindLastIndex",
30
30
  },
31
31
  {
32
32
  pattern:
33
- /(?:from\s+|require\s*\(\s*)['"]core-js\/modules\/es\.array\.at['"]/,
33
+ /(?:from\s+|require\s*\(\s*|import\s+)['"]core-js\/modules\/es\.array\.at['"]/,
34
34
  feature: "ArrayAt",
35
35
  },
36
36
  {
37
37
  pattern:
38
- /(?:from\s+|require\s*\(\s*)['"]core-js\/modules\/es\.string\.replace-all['"]/,
38
+ /(?:from\s+|require\s*\(\s*|import\s+)['"]core-js\/modules\/es\.string\.replace-all['"]/,
39
39
  feature: "StringReplaceAll",
40
40
  },
41
41
  {
42
42
  pattern:
43
- /(?:from\s+|require\s*\(\s*)['"]core-js\/modules\/es\.string\.match-all['"]/,
43
+ /(?:from\s+|require\s*\(\s*|import\s+)['"]core-js\/modules\/es\.string\.match-all['"]/,
44
44
  feature: "StringMatchAll",
45
45
  },
46
46
  {
47
47
  pattern:
48
- /(?:from\s+|require\s*\(\s*)['"]core-js\/modules\/es\.string\.at['"]/,
48
+ /(?:from\s+|require\s*\(\s*|import\s+)['"]core-js\/modules\/es\.string\.at['"]/,
49
49
  feature: "StringAt",
50
50
  },
51
51
  {
52
52
  pattern:
53
- /(?:from\s+|require\s*\(\s*)['"]core-js\/modules\/es\.object\.has-own['"]/,
53
+ /(?:from\s+|require\s*\(\s*|import\s+)['"]core-js\/modules\/es\.object\.has-own['"]/,
54
54
  feature: "ObjectHasOwn",
55
55
  },
56
56
  {
57
57
  pattern:
58
- /(?:from\s+|require\s*\(\s*)['"]core-js\/modules\/es\.promise\.any['"]/,
58
+ /(?:from\s+|require\s*\(\s*|import\s+)['"]core-js\/modules\/es\.promise\.any['"]/,
59
59
  feature: "PromiseAny",
60
60
  },
61
61
  {
62
62
  pattern:
63
- /(?:from\s+|require\s*\(\s*)['"]core-js\/modules\/es\.regexp\.exec['"]/,
63
+ /(?:from\s+|require\s*\(\s*|import\s+)['"]core-js\/modules\/es\.regexp\.exec['"]/,
64
64
  feature: "RegExpExec",
65
65
  },
66
66
  {
67
67
  pattern:
68
- /(?:from\s+|require\s*\(\s*)['"]core-js\/modules\/es\.global-this['"]/,
68
+ /(?:from\s+|require\s*\(\s*|import\s+)['"]core-js\/modules\/es\.global-this['"]/,
69
69
  feature: "GlobalThis",
70
70
  },
71
71
  ];
@@ -63,7 +63,7 @@ const detectFeatures = (
63
63
  ignoreList = new Set(),
64
64
  options = {},
65
65
  ) => {
66
- const { checkForPolyfills, ast } = options;
66
+ const { checkForPolyfills, ast, ignorePolyfillable } = options;
67
67
 
68
68
  if (!ast) {
69
69
  const error = new Error("AST is required for feature detection");
@@ -76,13 +76,18 @@ const detectFeatures = (
76
76
 
77
77
  const foundFeatures = detectFeaturesFromAST(ast);
78
78
 
79
+ const polyfillableSet = ignorePolyfillable
80
+ ? getPolyfillableFeatures(ignorePolyfillable)
81
+ : null;
82
+
79
83
  const unsupportedFeatures = Object.entries(ES_FEATURES)
80
84
  .filter(
81
85
  ([name, { minVersion }]) =>
82
86
  foundFeatures[name] &&
83
87
  minVersion > ecmaVersion &&
84
88
  !ignoreList.has(name) &&
85
- !(checkForPolyfills && polyfills.has(name)),
89
+ !(checkForPolyfills && polyfills.has(name)) &&
90
+ !(polyfillableSet && polyfillableSet.has(name)),
86
91
  )
87
92
  .map(([name]) => name);
88
93
 
@@ -13,6 +13,25 @@ function hasOptionsCause(node) {
13
13
  );
14
14
  }
15
15
 
16
+ function hasNumericArgument(node) {
17
+ const args = node.arguments;
18
+ const hasArgs = args && args.length === 1;
19
+ if (!hasArgs) return false;
20
+
21
+ const arg = args[0];
22
+ const isNumericLiteral =
23
+ arg.type === "Literal" && typeof arg.value === "number";
24
+
25
+ const isUnaryExpression = arg.type === "UnaryExpression";
26
+ const isNegationOperator = arg.operator === "-";
27
+ const hasNumericLiteralArgument =
28
+ arg.argument?.type === "Literal" && typeof arg.argument.value === "number";
29
+ const isNegativeNumeric =
30
+ isUnaryExpression && isNegationOperator && hasNumericLiteralArgument;
31
+
32
+ return isNumericLiteral || isNegativeNumeric;
33
+ }
34
+
16
35
  function checkMap(node, astInfo) {
17
36
  const callee = node.callee;
18
37
  const calleeObject = callee?.object;
@@ -60,6 +79,9 @@ function checkMap(node, astInfo) {
60
79
  const hasExcludedCallerType =
61
80
  astInfo.excludeCallerTypes?.includes(callerType);
62
81
 
82
+ const hasNumericArgMismatch =
83
+ astInfo.requireNumericArg && !hasNumericArgument(node);
84
+
63
85
  const hasMismatch =
64
86
  hasKindMismatch ||
65
87
  hasOperatorMismatch ||
@@ -70,7 +92,8 @@ function checkMap(node, astInfo) {
70
92
  hasPropertyWithExclusion ||
71
93
  hasObjectAndPropertyMismatch ||
72
94
  hasOptionsCauseMismatch ||
73
- hasExcludedCallerType;
95
+ hasExcludedCallerType ||
96
+ hasNumericArgMismatch;
74
97
 
75
98
  if (hasMismatch) return false;
76
99
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "es-check",
3
- "version": "9.6.0-1",
3
+ "version": "9.6.0",
4
4
  "description": "Checks the ECMAScript version of .js glob against a specified version of ECMAScript with a shell command",
5
5
  "main": "lib/index.js",
6
6
  "license": "MIT",