es-check 9.4.6 → 9.5.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
@@ -671,7 +671,7 @@ Tested on lodash, axios, react, moment, express, and chalk. See [benchmarks](./t
671
671
 
672
672
  ## Contributing
673
673
 
674
- ES Check has only 4 core dependencies: [acorn](https://github.com/ternjs/acorn/) for JavaScript parsing, [fast-brake](https://github.com/stackblitz/fast-brake) for lightweight feature detection, [fast-glob](https://github.com/mrmlnc/fast-glob) for file globbing, and [browserslist](https://github.com/browserslist/browserslist) for browser targeting.
674
+ ES Check has only 3 core dependencies: [acorn](https://github.com/ternjs/acorn/) for JavaScript parsing, [fast-glob](https://github.com/mrmlnc/fast-glob) for file globbing, and [browserslist](https://github.com/browserslist/browserslist) for browser targeting.
675
675
 
676
676
  The CLI, logging, and source map support are implemented with custom lightweight solutions using Node.js built-ins to minimize dependencies. To contribute, file an [issue](https://github.com/yowainwright/es-check/issues) or submit a pull request.
677
677
 
@@ -285,28 +285,6 @@ function filterIgnoredFiles(files, pathsToIgnore, globOpts) {
285
285
  });
286
286
  }
287
287
 
288
- function processLightMode(code, ecmaVersion, config, file, isDebug, logger) {
289
- const { parseLightMode } = require("../helpers");
290
- const { error: parseError } = parseLightMode(
291
- code,
292
- ecmaVersion,
293
- config.module,
294
- config.allowHashBang,
295
- file,
296
- );
297
-
298
- const hasParseError = parseError !== null;
299
- const shouldDebugError = hasParseError && isDebug;
300
-
301
- if (shouldDebugError) {
302
- logger.debug(
303
- `ES-Check: failed to parse file: ${file} \n - error: ${parseError.err}`,
304
- );
305
- }
306
-
307
- return parseError;
308
- }
309
-
310
288
  function processFullAST(
311
289
  code,
312
290
  acornOpts,
@@ -425,12 +403,6 @@ function createFileProcessor(config, options) {
425
403
  logger.debug(`ES-Check: checking ${file}`);
426
404
  }
427
405
 
428
- const isLightMode = config.light;
429
-
430
- if (isLightMode) {
431
- return processLightMode(code, ecmaVersion, config, file, isDebug, logger);
432
- }
433
-
434
406
  return processFullAST(
435
407
  code,
436
408
  acornOpts,
package/lib/cli/index.js CHANGED
File without changes
package/lib/cli/parser.js CHANGED
@@ -1,3 +1,22 @@
1
+ const BOOLEAN_FLAGS = new Set([
2
+ "module",
3
+ "allowHashBang",
4
+ "allow-hash-bang",
5
+ "noColor",
6
+ "no-color",
7
+ "verbose",
8
+ "quiet",
9
+ "silent",
10
+ "looseGlobMatching",
11
+ "checkFeatures",
12
+ "checkForPolyfills",
13
+ "checkBrowser",
14
+ "noCache",
15
+ "light",
16
+ "help",
17
+ "version",
18
+ ]);
19
+
1
20
  function parseArgs(argv) {
2
21
  const args = argv.slice(2);
3
22
  const options = {};
@@ -19,15 +38,21 @@ function parseArgs(argv) {
19
38
  options[key] = valueParts.join("=");
20
39
  } else {
21
40
  const key = arg.slice(2);
22
- const nextArg = args[i + 1];
23
- const hasNextArg = nextArg !== undefined;
24
- const nextIsValue = hasNextArg && !nextArg.startsWith("-");
41
+ const isBooleanFlag = BOOLEAN_FLAGS.has(key);
25
42
 
26
- if (nextIsValue) {
27
- options[key] = nextArg;
28
- i++;
29
- } else {
43
+ if (isBooleanFlag) {
30
44
  options[key] = true;
45
+ } else {
46
+ const nextArg = args[i + 1];
47
+ const hasNextArg = nextArg !== undefined;
48
+ const nextIsValue = hasNextArg && !nextArg.startsWith("-");
49
+
50
+ if (nextIsValue) {
51
+ options[key] = nextArg;
52
+ i++;
53
+ } else {
54
+ options[key] = true;
55
+ }
31
56
  }
32
57
  }
33
58
  } else if (isShortOption) {
@@ -41,7 +66,9 @@ function parseArgs(argv) {
41
66
 
42
67
  const nextArg = args[i + 1];
43
68
  const hasNextArg = nextArg !== undefined;
44
- const nextIsValue = hasNextArg && !nextArg.startsWith("-");
69
+ const isBooleanFlag = BOOLEAN_FLAGS.has(lastFlag);
70
+ const nextIsValue =
71
+ hasNextArg && !nextArg.startsWith("-") && !isBooleanFlag;
45
72
 
46
73
  if (nextIsValue) {
47
74
  options[lastFlag] = nextArg;
@@ -0,0 +1,64 @@
1
+ const ES15_FEATURES = {
2
+ StringIsWellFormed: {
3
+ minVersion: 15,
4
+ example: "str.isWellFormed()",
5
+ astInfo: {
6
+ nodeType: "CallExpression",
7
+ property: "isWellFormed",
8
+ },
9
+ },
10
+ StringToWellFormed: {
11
+ minVersion: 15,
12
+ example: "str.toWellFormed()",
13
+ astInfo: {
14
+ nodeType: "CallExpression",
15
+ property: "toWellFormed",
16
+ },
17
+ },
18
+ RegExpUnicodeSetFlag: {
19
+ minVersion: 15,
20
+ example: "/pattern/v",
21
+ astInfo: {
22
+ nodeType: "RegExpLiteral",
23
+ flags: "v",
24
+ },
25
+ },
26
+ PromiseWithResolvers: {
27
+ minVersion: 15,
28
+ example: "Promise.withResolvers()",
29
+ astInfo: {
30
+ nodeType: "CallExpression",
31
+ object: "Promise",
32
+ property: "withResolvers",
33
+ },
34
+ },
35
+ ObjectGroupBy: {
36
+ minVersion: 15,
37
+ example: "Object.groupBy(array, fn)",
38
+ astInfo: {
39
+ nodeType: "CallExpression",
40
+ object: "Object",
41
+ property: "groupBy",
42
+ },
43
+ },
44
+ MapGroupBy: {
45
+ minVersion: 15,
46
+ example: "Map.groupBy(array, fn)",
47
+ astInfo: {
48
+ nodeType: "CallExpression",
49
+ object: "Map",
50
+ property: "groupBy",
51
+ },
52
+ },
53
+ AtomicsWaitAsync: {
54
+ minVersion: 15,
55
+ example: "Atomics.waitAsync(typedArray, index, value)",
56
+ astInfo: {
57
+ nodeType: "CallExpression",
58
+ object: "Atomics",
59
+ property: "waitAsync",
60
+ },
61
+ },
62
+ };
63
+
64
+ module.exports = { ES15_FEATURES };
@@ -0,0 +1,115 @@
1
+ const ES16_FEATURES = {
2
+ ArrayPrototypeGroup: {
3
+ minVersion: 16,
4
+ superseded: true,
5
+ supersededBy: "ObjectGroupBy",
6
+ example: "arr.group(x => x.category)",
7
+ astInfo: {
8
+ nodeType: "CallExpression",
9
+ property: "group",
10
+ excludeObjects: ["console"],
11
+ },
12
+ },
13
+ ArrayPrototypeGroupToMap: {
14
+ minVersion: 16,
15
+ superseded: true,
16
+ supersededBy: "MapGroupBy",
17
+ example: "arr.groupToMap(x => x.category)",
18
+ astInfo: {
19
+ nodeType: "CallExpression",
20
+ property: "groupToMap",
21
+ },
22
+ },
23
+ PromiseTry: {
24
+ minVersion: 16,
25
+ example: "Promise.try(() => syncOrAsyncFunction())",
26
+ astInfo: {
27
+ nodeType: "CallExpression",
28
+ object: "Promise",
29
+ property: "try",
30
+ },
31
+ },
32
+ DuplicateNamedCaptureGroups: {
33
+ minVersion: 16,
34
+ example: "/(?<name>a)|(?<name>b)/",
35
+ astInfo: {
36
+ nodeType: "RegExpLiteral",
37
+ duplicateNamedGroups: true,
38
+ },
39
+ },
40
+ SetUnion: {
41
+ minVersion: 16,
42
+ example: "set1.union(set2)",
43
+ astInfo: {
44
+ nodeType: "CallExpression",
45
+ property: "union",
46
+ },
47
+ },
48
+ SetIntersection: {
49
+ minVersion: 16,
50
+ example: "set1.intersection(set2)",
51
+ astInfo: {
52
+ nodeType: "CallExpression",
53
+ property: "intersection",
54
+ },
55
+ },
56
+ SetDifference: {
57
+ minVersion: 16,
58
+ example: "set1.difference(set2)",
59
+ astInfo: {
60
+ nodeType: "CallExpression",
61
+ property: "difference",
62
+ },
63
+ },
64
+ SetSymmetricDifference: {
65
+ minVersion: 16,
66
+ example: "set1.symmetricDifference(set2)",
67
+ astInfo: {
68
+ nodeType: "CallExpression",
69
+ property: "symmetricDifference",
70
+ },
71
+ },
72
+ SetIsSubsetOf: {
73
+ minVersion: 16,
74
+ example: "set1.isSubsetOf(set2)",
75
+ astInfo: {
76
+ nodeType: "CallExpression",
77
+ property: "isSubsetOf",
78
+ },
79
+ },
80
+ SetIsSupersetOf: {
81
+ minVersion: 16,
82
+ example: "set1.isSupersetOf(set2)",
83
+ astInfo: {
84
+ nodeType: "CallExpression",
85
+ property: "isSupersetOf",
86
+ },
87
+ },
88
+ SetIsDisjointFrom: {
89
+ minVersion: 16,
90
+ example: "set1.isDisjointFrom(set2)",
91
+ astInfo: {
92
+ nodeType: "CallExpression",
93
+ property: "isDisjointFrom",
94
+ },
95
+ },
96
+ Float16Array: {
97
+ minVersion: 16,
98
+ example: "new Float16Array()",
99
+ astInfo: {
100
+ nodeType: "NewExpression",
101
+ callee: "Float16Array",
102
+ },
103
+ },
104
+ RegExpEscape: {
105
+ minVersion: 16,
106
+ example: "RegExp.escape(str)",
107
+ astInfo: {
108
+ nodeType: "CallExpression",
109
+ object: "RegExp",
110
+ property: "escape",
111
+ },
112
+ },
113
+ };
114
+
115
+ module.exports = { ES16_FEATURES };
@@ -1,10 +1,34 @@
1
- const { ES_FEATURES } = require("./es-features");
1
+ const { ES6_FEATURES } = require("./6");
2
+ const { ES7_FEATURES } = require("./7");
3
+ const { ES8_FEATURES } = require("./8");
4
+ const { ES9_FEATURES } = require("./9");
5
+ const { ES10_FEATURES } = require("./10");
6
+ const { ES11_FEATURES } = require("./11");
7
+ const { ES12_FEATURES } = require("./12");
8
+ const { ES13_FEATURES } = require("./13");
9
+ const { ES14_FEATURES } = require("./14");
10
+ const { ES15_FEATURES } = require("./15");
11
+ const { ES16_FEATURES } = require("./16");
2
12
  const {
3
13
  POLYFILL_PATTERNS,
4
14
  IMPORT_PATTERNS,
5
15
  FEATURE_TO_POLYFILL_MAP,
6
16
  } = require("./polyfills");
7
17
 
18
+ const ES_FEATURES = {
19
+ ...ES6_FEATURES,
20
+ ...ES7_FEATURES,
21
+ ...ES8_FEATURES,
22
+ ...ES9_FEATURES,
23
+ ...ES10_FEATURES,
24
+ ...ES11_FEATURES,
25
+ ...ES12_FEATURES,
26
+ ...ES13_FEATURES,
27
+ ...ES14_FEATURES,
28
+ ...ES15_FEATURES,
29
+ ...ES16_FEATURES,
30
+ };
31
+
8
32
  module.exports = {
9
33
  ES_FEATURES,
10
34
  POLYFILL_PATTERNS,
@@ -1,19 +1,11 @@
1
- const { fastBrakeSync } = require("fast-brake/sync");
2
1
  const {
3
2
  ES_FEATURES,
4
3
  POLYFILL_PATTERNS,
5
4
  IMPORT_PATTERNS,
6
5
  FEATURE_TO_POLYFILL_MAP,
7
6
  } = require("./constants");
8
- const esversionPlugin = require("fast-brake/plugins/esversion");
7
+ const { detectFeaturesFromAST } = require("./helpers/astDetector");
9
8
 
10
- const fastbrake = fastBrakeSync({ plugins: [esversionPlugin.default] });
11
-
12
- /**
13
- * Detects polyfills in the code and adds them to the polyfills Set
14
- * @param {string} code - The source code to check
15
- * @param {Set} polyfills - Set to store detected polyfills
16
- */
17
9
  const detectPolyfills = (
18
10
  code,
19
11
  polyfills,
@@ -35,54 +27,6 @@ const detectPolyfills = (
35
27
  }
36
28
  };
37
29
 
38
- const featureNameMap = {
39
- let_const: ["let", "const"],
40
- arrow_functions: "ArrowFunctions",
41
- template_literals: "TemplateLiterals",
42
- destructuring: "Destructuring",
43
- classes: "class",
44
- extends: "extends",
45
- spread_rest: ["RestSpread", "ArraySpread"],
46
- default_parameters: "DefaultParams",
47
- default_params: "DefaultParams",
48
- for_of: "ForOf",
49
- import: "import",
50
- export: "export",
51
- import_export: ["import", "export"],
52
- async_await: "AsyncAwait",
53
- generators: "Generators",
54
- promise: "Promise",
55
- promise_resolve: "PromiseResolve",
56
- promise_reject: "PromiseReject",
57
- promise_any: "PromiseAny",
58
- promise_allSettled: "PromiseAllSettled",
59
- map: "Map",
60
- set: "Set",
61
- weakmap: "WeakMap",
62
- weakset: "WeakSet",
63
- symbol: "Symbol",
64
- proxy: "Proxy",
65
- reflect: "Reflect",
66
- weakref: "WeakRef",
67
- finalization_registry: "FinalizationRegistry",
68
- exponentiation: "ExponentOperator",
69
- object_spread: "ObjectSpread",
70
- rest_spread_properties: "ObjectSpread",
71
- optional_catch: "OptionalCatchBinding",
72
- bigint: "BigInt",
73
- nullish_coalescing: "NullishCoalescing",
74
- optional_chaining: "OptionalChaining",
75
- private_fields: "PrivateClassFields",
76
- logical_assignment: "LogicalAssignment",
77
- numeric_separators: "NumericSeparators",
78
- class_fields: "ClassFields",
79
- top_level_await: "TopLevelAwait",
80
- globalThis: "globalThis",
81
- array_at: "ArrayPrototypeAt",
82
- object_hasOwn: "ObjectHasOwn",
83
- string_replaceAll: "StringReplaceAll",
84
- };
85
-
86
30
  const detectFeatures = (
87
31
  code,
88
32
  ecmaVersion,
@@ -92,56 +36,26 @@ const detectFeatures = (
92
36
  ) => {
93
37
  const { checkForPolyfills, ast } = options;
94
38
 
95
- const polyfills = new Set();
96
- if (checkForPolyfills) detectPolyfills(code, polyfills);
97
-
98
- let detectedFeatures;
99
-
100
- if (ast) {
101
- detectedFeatures = [];
102
- } else {
103
- try {
104
- detectedFeatures = fastbrake.detect(code);
105
- } catch (err) {
106
- const error = new Error(`Failed to parse code: ${err.message}`);
107
- error.type = "ES-Check";
108
- throw error;
109
- }
39
+ if (!ast) {
40
+ const error = new Error("AST is required for feature detection");
41
+ error.type = "ES-Check";
42
+ throw error;
110
43
  }
111
44
 
112
- const foundFeatures = Object.keys(ES_FEATURES).reduce((acc, f) => {
113
- acc[f] = false;
114
- return acc;
115
- }, {});
116
-
117
- detectedFeatures.forEach((feature) => {
118
- const mapped = featureNameMap[feature.name];
119
-
120
- if (mapped) {
121
- if (Array.isArray(mapped)) {
122
- mapped.forEach((name) => {
123
- if (ES_FEATURES[name]) {
124
- foundFeatures[name] = true;
125
- }
126
- });
127
- } else if (ES_FEATURES[mapped]) {
128
- foundFeatures[mapped] = true;
129
- }
130
- }
131
- });
45
+ const polyfills = new Set();
46
+ if (checkForPolyfills) detectPolyfills(code, polyfills);
132
47
 
133
- const unsupportedFeatures = [];
134
- Object.entries(ES_FEATURES).forEach(([featureName, { minVersion }]) => {
135
- const isPolyfilled = checkForPolyfills && polyfills.has(featureName);
136
- if (
137
- foundFeatures[featureName] &&
138
- minVersion > ecmaVersion &&
139
- !ignoreList.has(featureName) &&
140
- !isPolyfilled
141
- ) {
142
- unsupportedFeatures.push(featureName);
143
- }
144
- });
48
+ const foundFeatures = detectFeaturesFromAST(ast);
49
+
50
+ const unsupportedFeatures = Object.entries(ES_FEATURES)
51
+ .filter(
52
+ ([name, { minVersion }]) =>
53
+ foundFeatures[name] &&
54
+ minVersion > ecmaVersion &&
55
+ !ignoreList.has(name) &&
56
+ !(checkForPolyfills && polyfills.has(name)),
57
+ )
58
+ .map(([name]) => name);
145
59
 
146
60
  if (unsupportedFeatures.length > 0) {
147
61
  const error = new Error(
@@ -0,0 +1,144 @@
1
+ const { ES_FEATURES } = require("../constants");
2
+ const { checkMap } = require("./ast");
3
+
4
+ const CHILD_KEYS = [
5
+ "body",
6
+ "declarations",
7
+ "expression",
8
+ "left",
9
+ "right",
10
+ "argument",
11
+ "arguments",
12
+ "callee",
13
+ "object",
14
+ "property",
15
+ "properties",
16
+ "elements",
17
+ "params",
18
+ "id",
19
+ "init",
20
+ "test",
21
+ "consequent",
22
+ "alternate",
23
+ "cases",
24
+ "discriminant",
25
+ "block",
26
+ "handler",
27
+ "finalizer",
28
+ "source",
29
+ "specifiers",
30
+ "declaration",
31
+ "exported",
32
+ "imported",
33
+ "local",
34
+ "key",
35
+ "value",
36
+ "superClass",
37
+ ];
38
+
39
+ function normalizeNodeType(nodeType) {
40
+ if (nodeType === "ExportDeclaration") {
41
+ return [
42
+ "ExportNamedDeclaration",
43
+ "ExportDefaultDeclaration",
44
+ "ExportAllDeclaration",
45
+ ];
46
+ }
47
+ if (nodeType === "BigIntLiteral") {
48
+ return ["Literal"];
49
+ }
50
+ return [nodeType];
51
+ }
52
+
53
+ function buildFeatureIndex(features) {
54
+ const index = {};
55
+ for (const [name, { astInfo }] of Object.entries(features)) {
56
+ if (!astInfo?.nodeType) continue;
57
+ const types = normalizeNodeType(astInfo.nodeType);
58
+ for (const t of types) {
59
+ (index[t] ||= []).push({ name, astInfo });
60
+ }
61
+ }
62
+ return index;
63
+ }
64
+
65
+ const featuresByNodeType = buildFeatureIndex(ES_FEATURES);
66
+
67
+ function matchesFeature(node, astInfo) {
68
+ if (astInfo.childType) {
69
+ return node.elements?.some((el) => el?.type === astInfo.childType) || false;
70
+ }
71
+
72
+ if (astInfo.name && node.type === "Identifier") {
73
+ return node.name === astInfo.name;
74
+ }
75
+
76
+ if (astInfo.nodeType === "BigIntLiteral") {
77
+ return node.bigint !== undefined;
78
+ }
79
+
80
+ if (astInfo.kind && node.kind !== astInfo.kind) {
81
+ return false;
82
+ }
83
+
84
+ if (astInfo.operator && node.operator !== astInfo.operator) {
85
+ return false;
86
+ }
87
+
88
+ if (astInfo.property === "superClass") {
89
+ return node.superClass !== null;
90
+ }
91
+
92
+ if (node.type === "CallExpression" || node.type === "NewExpression") {
93
+ return checkMap(node, astInfo);
94
+ }
95
+
96
+ return true;
97
+ }
98
+
99
+ function detectFeaturesFromAST(ast) {
100
+ const foundFeatures = Object.create(null);
101
+ for (const key of Object.keys(ES_FEATURES)) {
102
+ foundFeatures[key] = false;
103
+ }
104
+
105
+ const remaining = new Set(Object.keys(ES_FEATURES));
106
+ const stack = [ast];
107
+
108
+ while (stack.length > 0 && remaining.size > 0) {
109
+ const node = stack.pop();
110
+ if (!node || typeof node !== "object") continue;
111
+
112
+ const candidates = featuresByNodeType[node.type];
113
+ if (candidates) {
114
+ for (const { name, astInfo } of candidates) {
115
+ if (!remaining.has(name)) continue;
116
+ if (matchesFeature(node, astInfo)) {
117
+ foundFeatures[name] = true;
118
+ remaining.delete(name);
119
+ }
120
+ }
121
+ }
122
+
123
+ for (const key of CHILD_KEYS) {
124
+ const child = node[key];
125
+ if (!child) continue;
126
+ if (Array.isArray(child)) {
127
+ for (let i = child.length - 1; i >= 0; i--) {
128
+ if (child[i]) stack.push(child[i]);
129
+ }
130
+ } else if (child.type) {
131
+ stack.push(child);
132
+ }
133
+ }
134
+ }
135
+
136
+ return foundFeatures;
137
+ }
138
+
139
+ module.exports = {
140
+ normalizeNodeType,
141
+ buildFeatureIndex,
142
+ matchesFeature,
143
+ detectFeaturesFromAST,
144
+ };
@@ -1,6 +1,7 @@
1
1
  const logger = require("./logger");
2
2
  const parsers = require("./parsers");
3
3
  const ast = require("./ast");
4
+ const astDetector = require("./astDetector");
4
5
  const files = require("./files");
5
6
  const cli = require("../cli/utils");
6
7
  const sourcemap = require("./sourcemap");
@@ -12,6 +13,7 @@ module.exports = Object.assign(
12
13
  logger,
13
14
  parsers,
14
15
  ast,
16
+ astDetector,
15
17
  files,
16
18
  cli,
17
19
  sourcemap,
@@ -1,13 +1,3 @@
1
- const { fastBrakeSync } = require("fast-brake/sync");
2
- const esversionPlugin = require("fast-brake/plugins/esversion");
3
- const { ECMA_VERSION_MAP } = require("../constants/versions");
4
-
5
- const fastbrake = fastBrakeSync({ plugins: [esversionPlugin.default] });
6
-
7
- function getTargetVersion(ecmaVersion) {
8
- return ECMA_VERSION_MAP[ecmaVersion] || "es5";
9
- }
10
-
11
1
  function parseCode(code, acornOpts, acorn, file) {
12
2
  try {
13
3
  const ast = acorn.parse(code, acornOpts);
@@ -30,46 +20,6 @@ function parseCode(code, acornOpts, acorn, file) {
30
20
  }
31
21
  }
32
22
 
33
- function parseLightMode(code, ecmaVersion, isModule, allowHashBang, file) {
34
- const targetVersion = getTargetVersion(ecmaVersion);
35
-
36
- const codeToCheck =
37
- allowHashBang && code.startsWith("#!")
38
- ? code.slice(code.indexOf("\n") + 1)
39
- : code;
40
-
41
- try {
42
- const isCompatible = fastbrake.check(codeToCheck, {
43
- target: targetVersion,
44
- sourceType: isModule ? "module" : "script",
45
- });
46
-
47
- if (!isCompatible) {
48
- return {
49
- error: {
50
- err: new Error(
51
- `Code contains features incompatible with ${targetVersion}`,
52
- ),
53
- stack: "",
54
- file,
55
- },
56
- };
57
- }
58
-
59
- return { error: null };
60
- } catch (err) {
61
- return {
62
- error: {
63
- err: new Error(`Failed to check code in light mode: ${err.message}`),
64
- stack: err.stack || "",
65
- file,
66
- },
67
- };
68
- }
69
- }
70
-
71
23
  module.exports = {
72
- getTargetVersion,
73
24
  parseCode,
74
- parseLightMode,
75
25
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "es-check",
3
- "version": "9.4.6",
3
+ "version": "9.5.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",
@@ -17,8 +17,6 @@
17
17
  "es-check": "lib/cli/index.js"
18
18
  },
19
19
  "scripts": {
20
- "commit": "git-cz",
21
- "commit-msg": "commitlint --edit $1",
22
20
  "dev": "pnpm site:dev",
23
21
  "lint": "oxlint lib",
24
22
  "lint:ci": "oxlint lib --quiet",
@@ -52,20 +50,17 @@
52
50
  "url": "https://github.com/yowainwright/es-check/issues"
53
51
  },
54
52
  "homepage": "https://github.com/yowainwright/es-check#readme",
53
+ "website": "https://jeffry.in/es-check",
55
54
  "devDependencies": {
56
- "@commitlint/cli": "20.1.0",
57
- "@commitlint/config-conventional": "^20.0.0",
58
55
  "codependence": "^0.3.1",
59
- "commitizen": "4.3.1",
60
- "oxlint": "^1.24.0",
61
- "pastoralist": "1.8.2-5",
56
+ "oxlint": "^1.29.0",
57
+ "pastoralist": "1.8.2",
62
58
  "prettier": "3.6.2",
63
59
  "release-it": "19.0.6"
64
60
  },
65
61
  "dependencies": {
66
62
  "acorn": "8.15.0",
67
- "browserslist": "^4.23.3",
68
- "fast-brake": "^0.1.4",
63
+ "browserslist": "^4.28.0",
69
64
  "fast-glob": "^3.3.3"
70
65
  },
71
66
  "engines": {
@@ -90,18 +85,6 @@
90
85
  "test js version",
91
86
  "test ecmascript version"
92
87
  ],
93
- "commitlint": {
94
- "extends": [
95
- "@commitlint/config-conventional"
96
- ],
97
- "rules": {
98
- "header-max-length": [
99
- 2,
100
- "always",
101
- 120
102
- ]
103
- }
104
- },
105
88
  "release-it": {
106
89
  "git": {
107
90
  "commitMessage": "chore: release v${version}",
@@ -129,15 +112,15 @@
129
112
  "packageManager": "pnpm@10.12.1",
130
113
  "pastoralist": {
131
114
  "appendix": {
132
- "vite@6.3.6": {
115
+ "vite@6.4.1": {
133
116
  "dependents": {
134
117
  "es-check": "vite (transitive dependency)"
135
118
  },
136
119
  "ledger": {
137
- "addedDate": "2025-11-11T09:03:17.559Z",
120
+ "addedDate": "2025-11-21T20:27:19.148Z",
138
121
  "reason": "Security fix: vite allows server.fs.deny bypass via backslash on Windows (medium)",
139
122
  "securityChecked": true,
140
- "securityCheckDate": "2025-11-11T09:03:17.559Z",
123
+ "securityCheckDate": "2025-11-21T20:27:19.148Z",
141
124
  "securityProvider": "github",
142
125
  "cve": "CVE-2025-62522",
143
126
  "severity": "medium",
@@ -149,14 +132,38 @@
149
132
  "es-check": "tmp (transitive dependency)"
150
133
  },
151
134
  "ledger": {
152
- "addedDate": "2025-11-11T09:03:17.559Z",
153
- "reason": "Security fix: tmp allows arbitrary temporary file / directory write via symbolic link `dir` parameter (low)",
135
+ "addedDate": "2025-11-21T20:27:19.148Z"
136
+ }
137
+ },
138
+ "astro@5.15.9": {
139
+ "dependents": {
140
+ "es-check": "astro (transitive dependency)",
141
+ "es-check-docs": "astro@^5.15.9"
142
+ },
143
+ "ledger": {
144
+ "addedDate": "2025-11-21T20:27:19.148Z",
145
+ "reason": "Security fix: Astro Cloudflare adapter has Stored Cross Site Scripting vulnerability in /_image endpoint (medium)",
154
146
  "securityChecked": true,
155
- "securityCheckDate": "2025-11-11T09:03:17.559Z",
147
+ "securityCheckDate": "2025-11-21T20:27:19.148Z",
156
148
  "securityProvider": "github",
157
- "cve": "CVE-2025-54798",
158
- "severity": "low",
159
- "url": "https://github.com/yowainwright/es-check/security/dependabot/24"
149
+ "cve": "CVE-2025-65019",
150
+ "severity": "medium",
151
+ "url": "https://github.com/yowainwright/es-check/security/dependabot/51"
152
+ }
153
+ },
154
+ "js-yaml@4.1.1": {
155
+ "dependents": {
156
+ "es-check": "js-yaml (transitive dependency)"
157
+ },
158
+ "ledger": {
159
+ "addedDate": "2025-11-21T20:27:19.148Z",
160
+ "reason": "Security fix: js-yaml has prototype pollution in merge (<<) (medium)",
161
+ "securityChecked": true,
162
+ "securityCheckDate": "2025-11-21T20:27:19.148Z",
163
+ "securityProvider": "github",
164
+ "cve": "CVE-2025-64718",
165
+ "severity": "medium",
166
+ "url": "https://github.com/yowainwright/es-check/security/dependabot/46"
160
167
  }
161
168
  }
162
169
  },
@@ -175,8 +182,10 @@
175
182
  },
176
183
  "pnpm": {
177
184
  "overrides": {
178
- "vite": "6.3.6",
179
- "tmp": "0.2.4"
185
+ "vite": "6.4.1",
186
+ "tmp": "0.2.4",
187
+ "astro": "5.15.9",
188
+ "js-yaml": "4.1.1"
180
189
  }
181
190
  }
182
191
  }
@@ -1,28 +0,0 @@
1
- const ES15_FEATURES = {
2
- StringIsWellFormed: {
3
- minVersion: 15,
4
- example: "str.isWellFormed()",
5
- astInfo: {
6
- nodeType: "CallExpression",
7
- property: "isWellFormed",
8
- },
9
- },
10
- StringToWellFormed: {
11
- minVersion: 15,
12
- example: "str.toWellFormed()",
13
- astInfo: {
14
- nodeType: "CallExpression",
15
- property: "toWellFormed",
16
- },
17
- },
18
- RegExpUnicodeSetFlag: {
19
- minVersion: 15,
20
- example: "/pattern/v",
21
- astInfo: {
22
- nodeType: "RegExpLiteral",
23
- flags: "v",
24
- },
25
- },
26
- };
27
-
28
- module.exports = { ES15_FEATURES };
@@ -1,39 +0,0 @@
1
- const ES16_FEATURES = {
2
- ArrayGroup: {
3
- minVersion: 16,
4
- example: "arr.group(x => x.category)",
5
- astInfo: {
6
- nodeType: "CallExpression",
7
- property: "group",
8
- excludeObjects: ["console"],
9
- },
10
- },
11
- ArrayGroupToMap: {
12
- minVersion: 16,
13
- example: "arr.groupToMap(x => x.category)",
14
- astInfo: {
15
- nodeType: "CallExpression",
16
- property: "groupToMap",
17
- excludeObjects: ["console"],
18
- },
19
- },
20
- PromiseTry: {
21
- minVersion: 16,
22
- example: "Promise.try(() => syncOrAsyncFunction())",
23
- astInfo: {
24
- nodeType: "CallExpression",
25
- object: "Promise",
26
- property: "try",
27
- },
28
- },
29
- DuplicateNamedCaptureGroups: {
30
- minVersion: 16,
31
- example: "/(?<name>a)|(?<name>b)/",
32
- astInfo: {
33
- nodeType: "RegExpLiteral",
34
- duplicateNamedGroups: true,
35
- },
36
- },
37
- };
38
-
39
- module.exports = { ES16_FEATURES };
@@ -1,27 +0,0 @@
1
- const { ES6_FEATURES } = require("./6");
2
- const { ES7_FEATURES } = require("./7");
3
- const { ES8_FEATURES } = require("./8");
4
- const { ES9_FEATURES } = require("./9");
5
- const { ES10_FEATURES } = require("./10");
6
- const { ES11_FEATURES } = require("./11");
7
- const { ES12_FEATURES } = require("./12");
8
- const { ES13_FEATURES } = require("./13");
9
- const { ES14_FEATURES } = require("./14");
10
- const { ES15_FEATURES } = require("./15");
11
- const { ES16_FEATURES } = require("./16");
12
-
13
- const ES_FEATURES = {
14
- ...ES6_FEATURES,
15
- ...ES7_FEATURES,
16
- ...ES8_FEATURES,
17
- ...ES9_FEATURES,
18
- ...ES10_FEATURES,
19
- ...ES11_FEATURES,
20
- ...ES12_FEATURES,
21
- ...ES13_FEATURES,
22
- ...ES14_FEATURES,
23
- ...ES15_FEATURES,
24
- ...ES16_FEATURES,
25
- };
26
-
27
- module.exports = { ES_FEATURES };