esupgrade 2025.0.2 → 2025.2.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/AGENTS.md +3 -0
- package/README.md +76 -7
- package/bin/esupgrade.js +47 -30
- package/images/logo-dark.svg +2 -2
- package/images/logo-light.svg +2 -2
- package/package.json +1 -1
- package/src/newlyAvailable.js +1 -0
- package/src/widelyAvailable.js +476 -0
- package/tests/cli.test.js +13 -17
- package/tests/widelyAvailable.test.js +1168 -0
package/AGENTS.md
ADDED
package/README.md
CHANGED
|
@@ -73,7 +73,7 @@ For more information about Baseline browser support, visit [web.dev/baseline][ba
|
|
|
73
73
|
|
|
74
74
|
### Widely available
|
|
75
75
|
|
|
76
|
-
#### `var` →
|
|
76
|
+
#### `var` → [const][mdn-const] & [let][mdn-let]
|
|
77
77
|
|
|
78
78
|
```diff
|
|
79
79
|
-var x = 1;
|
|
@@ -84,7 +84,7 @@ For more information about Baseline browser support, visit [web.dev/baseline][ba
|
|
|
84
84
|
+y = 3;
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
#### String concatenation → Template literals
|
|
87
|
+
#### String concatenation → [Template literals][mdn-template-literals]
|
|
88
88
|
|
|
89
89
|
```diff
|
|
90
90
|
-const greeting = 'Hello ' + name + '!';
|
|
@@ -93,7 +93,22 @@ For more information about Baseline browser support, visit [web.dev/baseline][ba
|
|
|
93
93
|
+const message = `You have ${count} items`;
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
#### `
|
|
96
|
+
#### Traditional `for` loops → [`for...of` loops][mdn-for-of]
|
|
97
|
+
|
|
98
|
+
```diff
|
|
99
|
+
-for (let i = 0; i < items.length; i++) {
|
|
100
|
+
- const item = items[i];
|
|
101
|
+
- console.log(item);
|
|
102
|
+
-}
|
|
103
|
+
+for (const item of items) {
|
|
104
|
+
+ console.log(item);
|
|
105
|
+
+}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
> [!NOTE]
|
|
109
|
+
> Transformations are limited to loops that start at 0, increment by 1, and where the index variable is not used in the loop body.
|
|
110
|
+
|
|
111
|
+
#### `Array.from().forEach()` → [`for...of` loops][mdn-for-of]
|
|
97
112
|
|
|
98
113
|
```diff
|
|
99
114
|
-Array.from(items).forEach(item => {
|
|
@@ -104,7 +119,44 @@ For more information about Baseline browser support, visit [web.dev/baseline][ba
|
|
|
104
119
|
+}
|
|
105
120
|
```
|
|
106
121
|
|
|
107
|
-
#### `
|
|
122
|
+
#### DOM `forEach()` → [`for...of` loops][mdn-for-of]
|
|
123
|
+
|
|
124
|
+
```diff
|
|
125
|
+
-document.querySelectorAll('.item').forEach(item => {
|
|
126
|
+
- item.classList.add('active');
|
|
127
|
+
-});
|
|
128
|
+
+for (const item of document.querySelectorAll('.item')) {
|
|
129
|
+
+ item.classList.add('active');
|
|
130
|
+
+}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Supports:
|
|
134
|
+
|
|
135
|
+
- `document.querySelectorAll()`
|
|
136
|
+
- `document.getElementsByTagName()`
|
|
137
|
+
- `document.getElementsByClassName()`
|
|
138
|
+
- `document.getElementsByName()`
|
|
139
|
+
- `window.frames`
|
|
140
|
+
|
|
141
|
+
> [!NOTE]
|
|
142
|
+
> Transformations limited to inline arrow or function expressions with block statement bodies.
|
|
143
|
+
> Callbacks with index parameters or expression bodies are not transformed.
|
|
144
|
+
|
|
145
|
+
#### `Array.from()` → [Array spread [...]][mdn-spread]
|
|
146
|
+
|
|
147
|
+
```diff
|
|
148
|
+
-const doubled = Array.from(numbers).map(n => n * 2);
|
|
149
|
+
-const filtered = Array.from(items).filter(x => x > 5);
|
|
150
|
+
-const arr = Array.from(iterable);
|
|
151
|
+
+const doubled = [...numbers].map(n => n * 2);
|
|
152
|
+
+const filtered = [...items].filter(x => x > 5);
|
|
153
|
+
+const arr = [...iterable];
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
> [!NOTE]
|
|
157
|
+
> `Array.from()` with a mapping function or thisArg is not converted.
|
|
158
|
+
|
|
159
|
+
#### `Object.assign({}, ...)` → [Object spread {...}][mdn-spread]
|
|
108
160
|
|
|
109
161
|
```diff
|
|
110
162
|
-const obj = Object.assign({}, obj1, obj2);
|
|
@@ -113,7 +165,7 @@ For more information about Baseline browser support, visit [web.dev/baseline][ba
|
|
|
113
165
|
+const copy = { ...original };
|
|
114
166
|
```
|
|
115
167
|
|
|
116
|
-
#### `.concat()` → Array spread
|
|
168
|
+
#### `.concat()` → [Array spread [...]][mdn-spread]
|
|
117
169
|
|
|
118
170
|
```diff
|
|
119
171
|
-const combined = arr1.concat(arr2, arr3);
|
|
@@ -122,7 +174,16 @@ For more information about Baseline browser support, visit [web.dev/baseline][ba
|
|
|
122
174
|
+const withItem = [...array, item];
|
|
123
175
|
```
|
|
124
176
|
|
|
125
|
-
####
|
|
177
|
+
#### `Math.pow()` → [Exponentiation operator \*\*][mdn-exponentiation]
|
|
178
|
+
|
|
179
|
+
```diff
|
|
180
|
+
-const result = Math.pow(2, 3);
|
|
181
|
+
-const area = Math.PI * Math.pow(radius, 2);
|
|
182
|
+
+const result = 2 ** 3;
|
|
183
|
+
+const area = Math.PI * radius ** 2;
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### Function expressions → [Arrow functions][mdn-arrow-functions]
|
|
126
187
|
|
|
127
188
|
```diff
|
|
128
189
|
-const fn = function(x) { return x * 2; };
|
|
@@ -145,7 +206,7 @@ For more information about Baseline browser support, visit [web.dev/baseline][ba
|
|
|
145
206
|
> [!CAUTION]
|
|
146
207
|
> These transformations are mainly to harden code for future releases and should be used with caution.
|
|
147
208
|
|
|
148
|
-
#### `new Promise((resolve) => { ... })` →
|
|
209
|
+
#### `new Promise((resolve) => { ... })` → [Promise.try][mdn-promise-try]
|
|
149
210
|
|
|
150
211
|
```diff
|
|
151
212
|
-new Promise((resolve) => {
|
|
@@ -158,4 +219,12 @@ For more information about Baseline browser support, visit [web.dev/baseline][ba
|
|
|
158
219
|
```
|
|
159
220
|
|
|
160
221
|
[baseline]: https://web.dev/baseline/
|
|
222
|
+
[mdn-arrow-functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
|
|
223
|
+
[mdn-const]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
|
|
224
|
+
[mdn-exponentiation]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation
|
|
225
|
+
[mdn-for-of]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
|
|
226
|
+
[mdn-let]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
|
|
227
|
+
[mdn-promise-try]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/try
|
|
228
|
+
[mdn-spread]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
|
|
229
|
+
[mdn-template-literals]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
|
|
161
230
|
[pre-commit]: https://pre-commit.com/
|
package/bin/esupgrade.js
CHANGED
|
@@ -98,50 +98,52 @@ function processFile(filePath, options) {
|
|
|
98
98
|
|
|
99
99
|
if (result.modified) {
|
|
100
100
|
if (options.check) {
|
|
101
|
-
|
|
101
|
+
// Group changes by type for summary
|
|
102
|
+
const changesByType = {}
|
|
102
103
|
if (result.changes && result.changes.length > 0) {
|
|
103
|
-
// Group changes by type
|
|
104
|
-
const changesByType = {}
|
|
105
|
-
|
|
106
104
|
for (const change of result.changes) {
|
|
107
105
|
if (!changesByType[change.type]) {
|
|
108
|
-
changesByType[change.type] =
|
|
106
|
+
changesByType[change.type] = 0
|
|
109
107
|
}
|
|
110
|
-
changesByType[change.type]
|
|
108
|
+
changesByType[change.type]++
|
|
111
109
|
}
|
|
110
|
+
}
|
|
112
111
|
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
const transformations = Object.keys(changesByType)
|
|
113
|
+
.map((type) => {
|
|
115
114
|
const displayName = type
|
|
116
115
|
.replace(/([A-Z])/g, " $1")
|
|
117
116
|
.trim()
|
|
118
117
|
.toLowerCase()
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
return displayName
|
|
119
|
+
})
|
|
120
|
+
.join(", ")
|
|
121
|
+
|
|
122
|
+
console.log(`✗ ${filePath}`)
|
|
123
|
+
if (transformations) {
|
|
124
|
+
console.log(` ${transformations}`)
|
|
123
125
|
}
|
|
124
126
|
}
|
|
125
127
|
|
|
126
128
|
if (options.write) {
|
|
127
129
|
fs.writeFileSync(filePath, result.code, "utf8")
|
|
128
130
|
if (!options.check) {
|
|
129
|
-
console.log(`✓
|
|
131
|
+
console.log(`✓ ${filePath}`)
|
|
130
132
|
} else {
|
|
131
|
-
console.log(` ✓
|
|
133
|
+
console.log(` ✓ written`)
|
|
132
134
|
}
|
|
133
135
|
}
|
|
134
136
|
|
|
135
|
-
return true
|
|
137
|
+
return { modified: true, changes: result.changes }
|
|
136
138
|
} else {
|
|
137
139
|
if (!options.check) {
|
|
138
|
-
console.log(`
|
|
140
|
+
console.log(` ${filePath}`)
|
|
139
141
|
}
|
|
140
|
-
return false
|
|
142
|
+
return { modified: false, changes: [] }
|
|
141
143
|
}
|
|
142
144
|
} catch (error) {
|
|
143
|
-
console.error(
|
|
144
|
-
return false
|
|
145
|
+
console.error(`✗ Error: ${filePath}: ${error.message}`)
|
|
146
|
+
return { modified: false, changes: [] }
|
|
145
147
|
}
|
|
146
148
|
}
|
|
147
149
|
|
|
@@ -153,27 +155,42 @@ function processFiles(patterns, options) {
|
|
|
153
155
|
process.exit(0)
|
|
154
156
|
}
|
|
155
157
|
|
|
156
|
-
console.log(`Processing ${files.length} file(s) with baseline: ${options.baseline}\n`)
|
|
157
|
-
|
|
158
158
|
let modifiedCount = 0
|
|
159
|
+
const allChanges = []
|
|
160
|
+
|
|
159
161
|
for (const file of files) {
|
|
160
|
-
|
|
162
|
+
const result = processFile(file, options)
|
|
163
|
+
if (result.modified) {
|
|
161
164
|
modifiedCount++
|
|
165
|
+
allChanges.push(...result.changes)
|
|
162
166
|
}
|
|
163
167
|
}
|
|
164
168
|
|
|
165
169
|
// Summary
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if (
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
if (options.check) {
|
|
171
|
+
console.log("")
|
|
172
|
+
if (modifiedCount > 0) {
|
|
173
|
+
// Count unique transformation types
|
|
174
|
+
const transformTypes = new Set(allChanges.map((c) => c.type))
|
|
175
|
+
const typeCount = transformTypes.size
|
|
176
|
+
const totalChanges = allChanges.length
|
|
177
|
+
|
|
178
|
+
console.log(
|
|
179
|
+
`${modifiedCount} file(s) need upgrading (${totalChanges} change${totalChanges !== 1 ? "s" : ""}, ${typeCount} type${typeCount !== 1 ? "s" : ""})`,
|
|
180
|
+
)
|
|
181
|
+
if (options.write) {
|
|
182
|
+
console.log("Changes have been written")
|
|
183
|
+
}
|
|
172
184
|
} else {
|
|
173
|
-
console.log(
|
|
185
|
+
console.log("All files are up to date")
|
|
174
186
|
}
|
|
175
187
|
} else {
|
|
176
|
-
console.log("
|
|
188
|
+
console.log("")
|
|
189
|
+
if (modifiedCount > 0) {
|
|
190
|
+
console.log(`✓ ${modifiedCount} file(s) upgraded`)
|
|
191
|
+
} else {
|
|
192
|
+
console.log("All files are up to date")
|
|
193
|
+
}
|
|
177
194
|
}
|
|
178
195
|
|
|
179
196
|
// Exit with code 1 if --check specified and there were changes
|
package/images/logo-dark.svg
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="320" font-family="Segoe UI, system-ui, sans-serif" viewBox="0 0 1280 640">
|
|
2
2
|
<circle cx="260" cy="320" r="200" fill="#f7df1e"/>
|
|
3
3
|
<path fill="none" stroke="#191919" stroke-width="48" d="m167 409 95-95 95 95m-190 -95 95-95 95 95m415 50"/>
|
|
4
|
-
<text x="241" y="148" fill="#c9d1d9" font-size="
|
|
4
|
+
<text x="241" y="148" fill="#c9d1d9" font-size="90" font-weight="bold" transform="matrix(1.6 0 0 1.6 120 120)">
|
|
5
5
|
esupgrade
|
|
6
6
|
</text>
|
|
7
|
-
<text x="241" y="192" fill="#c9d1d9" font-size="
|
|
7
|
+
<text x="241" y="192" fill="#c9d1d9" font-size="27" font-style="italic" transform="matrix(1.6 0 0 1.6 120 120)">
|
|
8
8
|
Auto-upgrade your JavaScript syntax
|
|
9
9
|
</text>
|
|
10
10
|
</svg>
|
package/images/logo-light.svg
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="320" font-family="Segoe UI, system-ui, sans-serif" viewBox="0 0 1280 640">
|
|
2
2
|
<circle cx="260" cy="320" r="200" fill="#f7df1e"/>
|
|
3
3
|
<path fill="none" stroke="#191919" stroke-width="48" d="m167 409 95-95 95 95m-190 -95 95-95 95 95m415 50"/>
|
|
4
|
-
<text x="241" y="148" font-size="
|
|
4
|
+
<text x="241" y="148" font-size="90" font-weight="bold" transform="matrix(1.6 0 0 1.6 120 120)">
|
|
5
5
|
esupgrade
|
|
6
6
|
</text>
|
|
7
|
-
<text x="241" y="192" font-size="
|
|
7
|
+
<text x="241" y="192" font-size="27" font-style="italic" transform="matrix(1.6 0 0 1.6 120 120)">
|
|
8
8
|
Auto-upgrade your JavaScript syntax
|
|
9
9
|
</text>
|
|
10
10
|
</svg>
|
package/package.json
CHANGED
package/src/newlyAvailable.js
CHANGED