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/files.js
CHANGED
|
@@ -7,18 +7,19 @@ function processBatchedFiles(files, processor, batchSize = 0) {
|
|
|
7
7
|
return files.map(processor);
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
let results = [];
|
|
11
11
|
for (let i = 0; i < files.length; i += batchSize) {
|
|
12
12
|
const batch = files.slice(i, i + batchSize);
|
|
13
13
|
const batchResults = batch.map(processor);
|
|
14
|
-
results.
|
|
14
|
+
results = results.concat(batchResults);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
return results;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
function readFile(file, fs, useCache = false) {
|
|
21
|
-
|
|
21
|
+
const shouldReadFromCache = useCache && fileCache.has(file);
|
|
22
|
+
if (shouldReadFromCache) {
|
|
22
23
|
cacheHits++;
|
|
23
24
|
return fileCache.get(file);
|
|
24
25
|
}
|
|
@@ -62,13 +63,16 @@ function clearFileCache() {
|
|
|
62
63
|
|
|
63
64
|
function getFileCacheStats() {
|
|
64
65
|
const total = cacheHits + cacheMisses;
|
|
66
|
+
const hasNoReads = total === 0;
|
|
67
|
+
const hitPercent = ((cacheHits / total) * 100).toFixed(2);
|
|
68
|
+
const hitRate = hasNoReads ? "0.00%" : hitPercent + "%";
|
|
69
|
+
|
|
65
70
|
return {
|
|
66
71
|
size: fileCache.size,
|
|
67
72
|
keys: Array.from(fileCache.keys()),
|
|
68
73
|
hits: cacheHits,
|
|
69
74
|
misses: cacheMisses,
|
|
70
|
-
hitRate
|
|
71
|
-
total === 0 ? "0.00%" : ((cacheHits / total) * 100).toFixed(2) + "%",
|
|
75
|
+
hitRate,
|
|
72
76
|
};
|
|
73
77
|
}
|
|
74
78
|
|
package/lib/helpers/index.js
CHANGED
|
@@ -8,22 +8,11 @@ const sourcemap = require("./sourcemap");
|
|
|
8
8
|
|
|
9
9
|
const detectFeaturesModule = require("../detectFeatures");
|
|
10
10
|
|
|
11
|
-
module.exports = Object.assign(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
files,
|
|
18
|
-
cli,
|
|
19
|
-
sourcemap,
|
|
20
|
-
{
|
|
21
|
-
detectFeatures: detectFeaturesModule,
|
|
22
|
-
polyfillDetector: {
|
|
23
|
-
detectPolyfills: detectFeaturesModule.detectPolyfills,
|
|
24
|
-
filterPolyfilled: detectFeaturesModule.filterPolyfilled,
|
|
25
|
-
filterPolyfillableFeatures:
|
|
26
|
-
detectFeaturesModule.filterPolyfillableFeatures,
|
|
27
|
-
},
|
|
11
|
+
module.exports = Object.assign({}, logger, parsers, ast, astDetector, files, cli, sourcemap, {
|
|
12
|
+
detectFeatures: detectFeaturesModule,
|
|
13
|
+
polyfillDetector: {
|
|
14
|
+
detectPolyfills: detectFeaturesModule.detectPolyfills,
|
|
15
|
+
filterPolyfilled: detectFeaturesModule.filterPolyfilled,
|
|
16
|
+
filterPolyfillableFeatures: detectFeaturesModule.filterPolyfillableFeatures,
|
|
28
17
|
},
|
|
29
|
-
);
|
|
18
|
+
});
|
package/lib/helpers/logger.js
CHANGED
|
@@ -22,8 +22,7 @@ function supportsColor(stream = process.stdout) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const isTTY = stream.isTTY;
|
|
25
|
-
const colorsDisabled =
|
|
26
|
-
process.env.NO_COLOR || process.env.NODE_DISABLE_COLORS;
|
|
25
|
+
const colorsDisabled = process.env.NO_COLOR || process.env.NODE_DISABLE_COLORS;
|
|
27
26
|
const colorsForced = process.env.FORCE_COLOR;
|
|
28
27
|
|
|
29
28
|
if (!isTTY) return false;
|
|
@@ -52,9 +51,7 @@ function createLogger(options = {}) {
|
|
|
52
51
|
if (!shouldLog) return;
|
|
53
52
|
|
|
54
53
|
const message = args
|
|
55
|
-
.map((arg) =>
|
|
56
|
-
typeof arg === "string" ? arg : util.inspect(arg, { depth: null }),
|
|
57
|
-
)
|
|
54
|
+
.map((arg) => (typeof arg === "string" ? arg : util.inspect(arg, { depth: null })))
|
|
58
55
|
.join(" ");
|
|
59
56
|
|
|
60
57
|
const isErrorLevel = logLevel === "error" || logLevel === "warn";
|
|
@@ -83,8 +80,7 @@ function createLogger(options = {}) {
|
|
|
83
80
|
|
|
84
81
|
function determineLogLevel(logger) {
|
|
85
82
|
const hasLogger = logger !== null && logger !== undefined;
|
|
86
|
-
const hasIsLevelEnabled =
|
|
87
|
-
hasLogger && typeof logger.isLevelEnabled === "function";
|
|
83
|
+
const hasIsLevelEnabled = hasLogger && typeof logger.isLevelEnabled === "function";
|
|
88
84
|
|
|
89
85
|
if (!hasIsLevelEnabled) return null;
|
|
90
86
|
|
package/lib/helpers/parsers.js
CHANGED
|
@@ -8,14 +8,11 @@ function detectRuntime() {
|
|
|
8
8
|
return "node";
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
function stripTypesInNode(code) {
|
|
12
|
-
const moduleAPI = require("module");
|
|
11
|
+
function stripTypesInNode(code, moduleAPI = require("module")) {
|
|
13
12
|
if (typeof moduleAPI.stripTypeScriptTypes === "function") {
|
|
14
13
|
return moduleAPI.stripTypeScriptTypes(code, { mode: "strip" });
|
|
15
14
|
}
|
|
16
|
-
throw new Error(
|
|
17
|
-
"es-check execution on TypeScript files requires Node.js v22.13.0+",
|
|
18
|
-
);
|
|
15
|
+
throw new Error("es-check execution on TypeScript files requires Node.js v22.13.0+");
|
|
19
16
|
}
|
|
20
17
|
|
|
21
18
|
function buildLineOffsets(original, stripped) {
|
|
@@ -23,13 +20,11 @@ function buildLineOffsets(original, stripped) {
|
|
|
23
20
|
const strippedLines = stripped.split("\n");
|
|
24
21
|
const lineCount = Math.max(originalLines.length, strippedLines.length);
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
for (let i = 0; i < lineCount; i++) {
|
|
23
|
+
return Array.from({ length: lineCount }, (_item, i) => {
|
|
28
24
|
const origLen = (originalLines[i] || "").length;
|
|
29
25
|
const stripLen = (strippedLines[i] || "").length;
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
return offsets;
|
|
26
|
+
return origLen - stripLen;
|
|
27
|
+
});
|
|
33
28
|
}
|
|
34
29
|
|
|
35
30
|
function mapPosition(line, column, lineOffsets) {
|
|
@@ -48,15 +43,14 @@ function mapPosition(line, column, lineOffsets) {
|
|
|
48
43
|
}
|
|
49
44
|
|
|
50
45
|
function stripTypesInBun(code) {
|
|
51
|
-
|
|
46
|
+
const hasBunTranspiler = typeof Bun !== "undefined" && typeof Bun.Transpiler !== "undefined";
|
|
47
|
+
if (hasBunTranspiler) {
|
|
52
48
|
const transpiler = new Bun.Transpiler({ loader: "ts" });
|
|
53
49
|
const stripped = transpiler.transformSync(code);
|
|
54
50
|
const lineOffsets = buildLineOffsets(code, stripped);
|
|
55
51
|
return { code: stripped, lineOffsets };
|
|
56
52
|
}
|
|
57
|
-
throw new Error(
|
|
58
|
-
"es-check execution on TypeScript files requires Bun v1.0.0+",
|
|
59
|
-
);
|
|
53
|
+
throw new Error("es-check execution on TypeScript files requires Bun v1.0.0+");
|
|
60
54
|
}
|
|
61
55
|
|
|
62
56
|
function stripTypesInDeno() {
|
|
@@ -88,9 +82,7 @@ function stripTypeScript(code) {
|
|
|
88
82
|
return stripTypesInDeno();
|
|
89
83
|
}
|
|
90
84
|
|
|
91
|
-
throw new Error(
|
|
92
|
-
"es-check execution on TypeScript files is not supported in this runtime",
|
|
93
|
-
);
|
|
85
|
+
throw new Error("es-check execution on TypeScript files is not supported in this runtime");
|
|
94
86
|
}
|
|
95
87
|
|
|
96
88
|
function parseCode(code, acornOpts, acorn, file, options = {}) {
|
|
@@ -104,9 +96,22 @@ function parseCode(code, acornOpts, acorn, file, options = {}) {
|
|
|
104
96
|
const shouldProcessTypeScript = hasTypeScriptOption && isTypeScriptFile;
|
|
105
97
|
|
|
106
98
|
if (shouldProcessTypeScript) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
99
|
+
try {
|
|
100
|
+
const result = stripTypeScript(code);
|
|
101
|
+
processedCode = result.code;
|
|
102
|
+
lineOffsets = result.lineOffsets;
|
|
103
|
+
} catch (err) {
|
|
104
|
+
return {
|
|
105
|
+
ast: null,
|
|
106
|
+
error: {
|
|
107
|
+
err,
|
|
108
|
+
stack: err.stack,
|
|
109
|
+
file,
|
|
110
|
+
line: null,
|
|
111
|
+
column: null,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
110
115
|
}
|
|
111
116
|
|
|
112
117
|
try {
|
package/lib/helpers/sourcemap.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
|
|
3
|
-
const BASE64_CHARS =
|
|
4
|
-
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
3
|
+
const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
5
4
|
const VLQ_BASE_SHIFT = 5;
|
|
6
5
|
const VLQ_BASE = 1 << VLQ_BASE_SHIFT;
|
|
7
6
|
const VLQ_BASE_MASK = VLQ_BASE - 1;
|
|
@@ -21,7 +20,10 @@ function decodeVLQValue(str, startIndex) {
|
|
|
21
20
|
const reachedEnd = index >= str.length;
|
|
22
21
|
if (reachedEnd) break;
|
|
23
22
|
|
|
24
|
-
const
|
|
23
|
+
const char = str[index];
|
|
24
|
+
index += 1;
|
|
25
|
+
|
|
26
|
+
const digit = base64Decode(char);
|
|
25
27
|
const invalidDigit = digit === -1;
|
|
26
28
|
if (invalidDigit) break;
|
|
27
29
|
|
|
@@ -39,12 +41,12 @@ function decodeVLQValue(str, startIndex) {
|
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
function decodeVLQ(str) {
|
|
42
|
-
|
|
44
|
+
let values = [];
|
|
43
45
|
let index = 0;
|
|
44
46
|
|
|
45
47
|
while (index < str.length) {
|
|
46
48
|
const decoded = decodeVLQValue(str, index);
|
|
47
|
-
values.
|
|
49
|
+
values = values.concat(decoded.value);
|
|
48
50
|
index = decoded.nextIndex;
|
|
49
51
|
}
|
|
50
52
|
|
|
@@ -62,20 +64,14 @@ function parseSegment(segment, state) {
|
|
|
62
64
|
const generatedColumn = state.previousGeneratedColumn + values[0];
|
|
63
65
|
|
|
64
66
|
const hasSourceIndex = values.length > 1;
|
|
65
|
-
const sourceIndex = hasSourceIndex
|
|
66
|
-
? state.previousSourceIndex + values[1]
|
|
67
|
-
: null;
|
|
67
|
+
const sourceIndex = hasSourceIndex ? state.previousSourceIndex + values[1] : null;
|
|
68
68
|
const source = hasSourceIndex ? state.sources[sourceIndex] : null;
|
|
69
69
|
|
|
70
70
|
const hasOriginalLine = values.length > 2;
|
|
71
|
-
const originalLine = hasOriginalLine
|
|
72
|
-
? state.previousSourceLine + values[2] + 1
|
|
73
|
-
: null;
|
|
71
|
+
const originalLine = hasOriginalLine ? state.previousSourceLine + values[2] + 1 : null;
|
|
74
72
|
|
|
75
73
|
const hasOriginalColumn = values.length > 3;
|
|
76
|
-
const originalColumn = hasOriginalColumn
|
|
77
|
-
? state.previousSourceColumn + values[3]
|
|
78
|
-
: null;
|
|
74
|
+
const originalColumn = hasOriginalColumn ? state.previousSourceColumn + values[3] : null;
|
|
79
75
|
|
|
80
76
|
const hasNameIndex = values.length > 4;
|
|
81
77
|
const nameIndex = hasNameIndex ? state.previousNameIndex + values[4] : null;
|
|
@@ -92,16 +88,20 @@ function parseSegment(segment, state) {
|
|
|
92
88
|
name,
|
|
93
89
|
};
|
|
94
90
|
|
|
95
|
-
const
|
|
96
|
-
|
|
91
|
+
const previousSourceIndex = sourceIndex ?? state.previousSourceIndex;
|
|
92
|
+
const previousSourceLine = hasOriginalLine
|
|
93
|
+
? state.previousSourceLine + values[2]
|
|
94
|
+
: state.previousSourceLine;
|
|
95
|
+
const previousSourceColumn = originalColumn ?? state.previousSourceColumn;
|
|
96
|
+
const previousNameIndex = nameIndex ?? state.previousNameIndex;
|
|
97
|
+
|
|
98
|
+
const nextState = Object.assign({}, state, {
|
|
97
99
|
previousGeneratedColumn: generatedColumn,
|
|
98
|
-
previousSourceIndex
|
|
99
|
-
previousSourceLine
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
previousNameIndex: nameIndex ?? state.previousNameIndex,
|
|
104
|
-
};
|
|
100
|
+
previousSourceIndex,
|
|
101
|
+
previousSourceLine,
|
|
102
|
+
previousSourceColumn,
|
|
103
|
+
previousNameIndex,
|
|
104
|
+
});
|
|
105
105
|
|
|
106
106
|
return { mapping, nextState };
|
|
107
107
|
}
|
|
@@ -111,16 +111,17 @@ function parseLine(line, state) {
|
|
|
111
111
|
if (hasNoLine) {
|
|
112
112
|
return {
|
|
113
113
|
mappings: [],
|
|
114
|
-
nextState: {
|
|
115
|
-
...state,
|
|
114
|
+
nextState: Object.assign({}, state, {
|
|
116
115
|
generatedLine: state.generatedLine + 1,
|
|
117
116
|
previousGeneratedColumn: 0,
|
|
118
|
-
},
|
|
117
|
+
}),
|
|
119
118
|
};
|
|
120
119
|
}
|
|
121
120
|
|
|
122
121
|
const segments = line.split(",");
|
|
123
|
-
const initialState = {
|
|
122
|
+
const initialState = Object.assign({}, state, {
|
|
123
|
+
previousGeneratedColumn: 0,
|
|
124
|
+
});
|
|
124
125
|
|
|
125
126
|
const result = segments.reduce(
|
|
126
127
|
(acc, segment) => {
|
|
@@ -129,7 +130,7 @@ function parseLine(line, state) {
|
|
|
129
130
|
|
|
130
131
|
return hasMapping
|
|
131
132
|
? {
|
|
132
|
-
mappings:
|
|
133
|
+
mappings: acc.mappings.concat(parsed.mapping),
|
|
133
134
|
state: parsed.nextState,
|
|
134
135
|
}
|
|
135
136
|
: acc;
|
|
@@ -139,10 +140,9 @@ function parseLine(line, state) {
|
|
|
139
140
|
|
|
140
141
|
return {
|
|
141
142
|
mappings: result.mappings,
|
|
142
|
-
nextState: {
|
|
143
|
-
...result.state,
|
|
143
|
+
nextState: Object.assign({}, result.state, {
|
|
144
144
|
generatedLine: state.generatedLine + 1,
|
|
145
|
-
},
|
|
145
|
+
}),
|
|
146
146
|
};
|
|
147
147
|
}
|
|
148
148
|
|
|
@@ -164,7 +164,7 @@ function parseMappings(mappingsString, sources, names) {
|
|
|
164
164
|
(acc, line) => {
|
|
165
165
|
const parsed = parseLine(line, acc.state);
|
|
166
166
|
return {
|
|
167
|
-
mappings:
|
|
167
|
+
mappings: acc.mappings.concat(parsed.mappings),
|
|
168
168
|
state: parsed.nextState,
|
|
169
169
|
};
|
|
170
170
|
},
|
|
@@ -185,8 +185,13 @@ function findClosestMapping(mappings, targetLine, targetColumn) {
|
|
|
185
185
|
distance: Math.abs(mapping.generatedColumn - targetColumn),
|
|
186
186
|
}));
|
|
187
187
|
|
|
188
|
-
const
|
|
189
|
-
|
|
188
|
+
const closest = withDistance.reduce((best, current) => {
|
|
189
|
+
if (!best) return current;
|
|
190
|
+
const isCloser = current.distance < best.distance;
|
|
191
|
+
return isCloser ? current : best;
|
|
192
|
+
}, null);
|
|
193
|
+
|
|
194
|
+
return closest.mapping;
|
|
190
195
|
}
|
|
191
196
|
|
|
192
197
|
function buildSourcePath(sourceRoot, source) {
|
|
@@ -203,11 +208,7 @@ class SourceMapConsumer {
|
|
|
203
208
|
this.mappings = sourceMapData.mappings || "";
|
|
204
209
|
this.file = sourceMapData.file;
|
|
205
210
|
this.sourceRoot = sourceMapData.sourceRoot || "";
|
|
206
|
-
this._parsedMappings = parseMappings(
|
|
207
|
-
this.mappings,
|
|
208
|
-
this.sources,
|
|
209
|
-
this.names,
|
|
210
|
-
);
|
|
211
|
+
this._parsedMappings = parseMappings(this.mappings, this.sources, this.names);
|
|
211
212
|
}
|
|
212
213
|
|
|
213
214
|
originalPositionFor({ line, column }) {
|