esupgrade 2025.14.3 → 2025.16.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/.gitattributes +2 -0
- package/.github/agents/superjoe.agent.md +66 -0
- package/.github/copilot-instructions.md +11 -1
- package/.github/workflows/ci.yml +1 -1
- package/.pre-commit-config.yaml +11 -0
- package/AGENTS.md +33 -0
- package/CONTRIBUTING.md +4 -0
- package/README.md +202 -0
- package/bin/esupgrade.js +18 -17
- package/eslint.config.cjs +12 -0
- package/package.json +3 -4
- package/src/index.js +40 -13
- package/src/jQuery/HTMLInputElement.json +389 -0
- package/src/jQuery/addClassToClassList.js +49 -0
- package/src/jQuery/afterToAfter.js +54 -0
- package/src/jQuery/appendToAppend.js +55 -0
- package/src/jQuery/attrToGetSetRemove.js +52 -0
- package/src/jQuery/beforeToBefore.js +47 -0
- package/src/jQuery/childrenToChildrenArray.js +48 -0
- package/src/jQuery/clickToAddEventListener.js +52 -0
- package/src/jQuery/closestToClosest.js +43 -0
- package/src/jQuery/cssToStyleAndComputed.js +120 -0
- package/src/jQuery/eachToForOf.js +92 -0
- package/src/jQuery/emptyToReplaceChildren.js +33 -0
- package/src/jQuery/findToQuerySelectorAll.js +57 -0
- package/src/jQuery/hasClassToClassListContains.js +36 -0
- package/src/jQuery/htmlToInnerHTML.js +61 -0
- package/src/jQuery/idSelectorToGetElementById.js +54 -0
- package/src/jQuery/inArrayToIncludes.js +77 -0
- package/src/jQuery/nextToNextElementSibling.js +79 -0
- package/src/jQuery/offToRemoveEventListener.js +36 -0
- package/src/jQuery/onToAddEventListener.js +51 -0
- package/src/jQuery/parentToParentElement.js +60 -0
- package/src/jQuery/prependToPrepend.js +54 -0
- package/src/jQuery/prevToPreviousElementSibling.js +77 -0
- package/src/jQuery/propToDirectProperty.js +175 -0
- package/src/jQuery/readyToDOMContentLoaded.js +79 -0
- package/src/jQuery/removeClassToClassList.js +45 -0
- package/src/jQuery/removeToRemove.js +49 -0
- package/src/jQuery/selectorToQuerySelectorAll.js +68 -0
- package/src/jQuery/showHideToStyleDisplay.js +56 -0
- package/src/jQuery/siblingsToSiblingsArray.js +71 -0
- package/src/jQuery/staticEachToForEach.js +42 -0
- package/src/jQuery/staticGrepToFilter.js +36 -0
- package/src/jQuery/staticMapToMap.js +33 -0
- package/src/jQuery/textToTextContent.js +49 -0
- package/src/jQuery/toggleClassToClassList.js +36 -0
- package/src/jQuery/triggerToDispatchEvent.js +65 -0
- package/src/jQuery/trimToStringTrim.js +30 -0
- package/src/jQuery/unwrapJQueryIdentifier.js +51 -0
- package/src/jQuery/utils.js +384 -0
- package/src/jQuery/valToValue.js +40 -0
- package/src/jQuery/widthHeightToClient.js +49 -0
- package/src/jQuery.js +46 -0
- package/src/types.js +51 -0
- package/src/widelyAvailable/arrayFilterToFind.js +80 -0
- package/src/widelyAvailable/mathPowToExponentiation.js +29 -1
- package/src/widelyAvailable.js +1 -0
- package/src/worker.js +2 -2
- package/tests/cli.test.js +62 -0
- package/tests/general.test.js +16 -0
- package/tests/jQuery/addClassToClassList.test.js +34 -0
- package/tests/jQuery/afterToAfter.test.js +38 -0
- package/tests/jQuery/appendToAppend.test.js +44 -0
- package/tests/jQuery/attrToGetSetRemove.test.js +44 -0
- package/tests/jQuery/beforeToBefore.test.js +44 -0
- package/tests/jQuery/childrenToChildrenArray.test.js +32 -0
- package/tests/jQuery/clickToAddEventListener.test.js +44 -0
- package/tests/jQuery/closestToClosest.test.js +38 -0
- package/tests/jQuery/cssToStyleAndComputed.test.js +71 -0
- package/tests/jQuery/eachToForOf.test.js +57 -0
- package/tests/jQuery/emptyToReplaceChildren.test.js +26 -0
- package/tests/jQuery/findToQuerySelectorAll.test.js +47 -0
- package/tests/jQuery/hasClassToClassListContains.test.js +41 -0
- package/tests/jQuery/htmlToInnerHTML.test.js +38 -0
- package/tests/jQuery/idSelectorToGetElementById.test.js +31 -0
- package/tests/jQuery/inArrayToIncludes.test.js +69 -0
- package/tests/jQuery/nextToNextElementSibling.test.js +37 -0
- package/tests/jQuery/offToRemoveEventListener.test.js +43 -0
- package/tests/jQuery/onToAddEventListener.test.js +41 -0
- package/tests/jQuery/parentToParentElement.test.js +34 -0
- package/tests/jQuery/prependToPrepend.test.js +32 -0
- package/tests/jQuery/prevToPreviousElementSibling.test.js +37 -0
- package/tests/jQuery/propToDirectProperty.test.js +65 -0
- package/tests/jQuery/readyToDOMContentLoaded.test.js +40 -0
- package/tests/jQuery/removeClassToClassList.test.js +47 -0
- package/tests/jQuery/removeToRemove.test.js +26 -0
- package/tests/jQuery/selectorToQuerySelectorAll.test.js +36 -0
- package/tests/jQuery/showHideToStyleDisplay.test.js +38 -0
- package/tests/jQuery/siblingsToSiblingsArray.test.js +32 -0
- package/tests/jQuery/staticEachToForEach.test.js +80 -0
- package/tests/jQuery/staticGrepToFilter.test.js +50 -0
- package/tests/jQuery/staticMapToMap.test.js +56 -0
- package/tests/jQuery/textToTextContent.test.js +38 -0
- package/tests/jQuery/toggleClassToClassList.test.js +38 -0
- package/tests/jQuery/triggerToDispatchEvent.test.js +45 -0
- package/tests/jQuery/trimToStringTrim.test.js +32 -0
- package/tests/jQuery/unwrapJQueryIdentifier.test.js +26 -0
- package/tests/jQuery/utils.test.js +283 -0
- package/tests/jQuery/valToValue.test.js +38 -0
- package/tests/jQuery/widthHeightToClient.test.js +38 -0
- package/tests/types.test.js +1 -5
- package/tests/widelyAvailable/array-filter-to-find.test.js +173 -0
- package/tests/widelyAvailable/math-pow-to-exponentiation.test.js +21 -2
- package/tests/widelyAvailable/string-concat-to-template.test.js +1 -1
- package/tests/widelyAvailable/substr-to-slice.test.js +4 -1
package/.gitattributes
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
# For format details, see: https://gh.io/customagents/config
|
|
3
|
+
|
|
4
|
+
name: SuperJoe
|
|
5
|
+
description: CodingJoe's digital clone following his coding guidelines and best practices.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# SuperJoe
|
|
10
|
+
|
|
11
|
+
## Planning
|
|
12
|
+
|
|
13
|
+
You MUST ALWAYS follow the `naming-things` guidelines. Use the following command to access the guidelines:
|
|
14
|
+
```console
|
|
15
|
+
curl -sSL https://raw.githubusercontent.com/codingjoe/naming-things/refs/heads/main/README.md | cat
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
You MUST ALWAYS read the `CONTRIBUTING.md` file before planning or writing any code.
|
|
19
|
+
You MUST ALWAYS search the documentation and amend or update it as necessary.
|
|
20
|
+
You MUST ALWAYS check for pre-commit hooks and run them before committing code.
|
|
21
|
+
You MUST ALWAYS ensure that all new code is fully tested with 100% coverage. Unreachable code branches MUST be removed.
|
|
22
|
+
|
|
23
|
+
## Writing Code
|
|
24
|
+
|
|
25
|
+
Less code is more! Use the latest language features and libraries to achieve more with less code.
|
|
26
|
+
|
|
27
|
+
Do not add new dependencies, but if you do, they must be widely adopted and well-maintained in the open-source community.
|
|
28
|
+
|
|
29
|
+
You are a strong FOSS advocate with a preference for permissive licenses like BSD or MIT.
|
|
30
|
+
|
|
31
|
+
Use generators instead of adding items to lists or arrays.
|
|
32
|
+
|
|
33
|
+
Use class syntax for all object-oriented code.
|
|
34
|
+
Use named functions instead of anonymous functions whenever possible.
|
|
35
|
+
Avoid overly complex functions. Break them into smaller functions if necessary.
|
|
36
|
+
Docstrings should be written in present tense imperative mood.
|
|
37
|
+
They must start with a capital letter and end with a period.
|
|
38
|
+
Docstrings must describe the external behavior of the function, class, or method.
|
|
39
|
+
Docstrings should avoid redundant phrases like "This function" or "This method".
|
|
40
|
+
Class docstrings must not repeat the class name or start with a verb since they don't do anything themselves.
|
|
41
|
+
Avoid code comments unless they describe behavior of 3rd party code or complex algorithms.
|
|
42
|
+
Avoid loops in favor of recursive functions or generator functions.
|
|
43
|
+
Avoid functions or other code inside functions.
|
|
44
|
+
Avoid if-statements in favor of switch/match-statements or polymorphism.
|
|
45
|
+
Do not assign names to objects which are returned in the next line.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
## Python
|
|
49
|
+
|
|
50
|
+
Follow PEP 8 guidelines for code style.
|
|
51
|
+
EAFP (Easier to Ask Forgiveness than Permission) is preferred over LBYL (Look Before You Leap).
|
|
52
|
+
Use type hints for all public functions, classes, and methods.
|
|
53
|
+
Use dataclasses for simple data structures.
|
|
54
|
+
Use context managers for resource management.
|
|
55
|
+
Use list/set/dict comprehensions instead of loops for creating collections.
|
|
56
|
+
Use generators for large data sets to save memory.
|
|
57
|
+
Use the walrus operator (`:=`) for inline assignments when it improves readability.
|
|
58
|
+
|
|
59
|
+
### JavaScript
|
|
60
|
+
|
|
61
|
+
Use `#` for private methods.
|
|
62
|
+
Write docstrings with jsdoc type annotations for all functions, classes, and methods.
|
|
63
|
+
|
|
64
|
+
### TypeScript
|
|
65
|
+
|
|
66
|
+
Use `#` for private methods.
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
When writing code, you MUST ALWAYS follow the [naming guidelines](https://raw.githubusercontent.com/codingjoe/naming-things/refs/heads/main/README.md).
|
|
2
2
|
|
|
3
|
+
Usage:
|
|
4
|
+
|
|
5
|
+
```console
|
|
6
|
+
curl -sL https://raw.githubusercontent.com/codingjoe/naming-things/refs/heads/main/README.md
|
|
7
|
+
```
|
|
8
|
+
|
|
3
9
|
All code must be fully tested with a 100% coverage. Unreachable code must be removed.
|
|
4
10
|
Follow the [CONTRIBUTING.md](./CONTRIBUTING.md) guidelines for testing and linting.
|
|
5
11
|
The test suite will fail if the line coverage is below 100%.
|
|
6
|
-
The test coverage will be written to stdout
|
|
12
|
+
The test coverage will be written to stdout when running the tests via `npm test | grep -v '100.00'`.
|
|
7
13
|
|
|
8
14
|
All transformers must be documented in the README.md.
|
|
9
15
|
|
|
@@ -20,3 +26,7 @@ Docstrings must describe the external behavior of the function, class, or method
|
|
|
20
26
|
Docstrings should avoid redundant phrases like "This function" or "This method".
|
|
21
27
|
Class docstrings must not repeat the class name or start with a verb since they don't do anything themselves.
|
|
22
28
|
Avoid code comments unless they describe behavior of 3rd party code or complex algorithms.
|
|
29
|
+
Avoid loops in favor of recursive functions or generator functions.
|
|
30
|
+
Avoid functions or other code inside functions.
|
|
31
|
+
Avoid if-statements in favor of switch-statements or polymorphism.
|
|
32
|
+
Do not assign names to objects which are returned in the next line.
|
package/.github/workflows/ci.yml
CHANGED
|
@@ -28,7 +28,7 @@ jobs:
|
|
|
28
28
|
node-version-file: package.json
|
|
29
29
|
- run: npm ci
|
|
30
30
|
- run: node --test --experimental-test-coverage --test-reporter=spec --test-reporter=lcov --test-reporter-destination=stdout --test-reporter-destination=lcov.info
|
|
31
|
-
- uses: codecov/codecov-action@
|
|
31
|
+
- uses: codecov/codecov-action@v6
|
|
32
32
|
with:
|
|
33
33
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
34
34
|
flags: javascript
|
package/.pre-commit-config.yaml
CHANGED
|
@@ -21,6 +21,7 @@ repos:
|
|
|
21
21
|
- mdformat-footnote
|
|
22
22
|
- mdformat-gfm
|
|
23
23
|
- mdformat-gfm-alerts
|
|
24
|
+
exclude: '.github/agents/'
|
|
24
25
|
- repo: https://github.com/google/yamlfmt
|
|
25
26
|
rev: v0.21.0
|
|
26
27
|
hooks:
|
|
@@ -30,6 +31,16 @@ repos:
|
|
|
30
31
|
hooks:
|
|
31
32
|
- id: write-good
|
|
32
33
|
args: [--no-passive]
|
|
34
|
+
- repo: https://github.com/pre-commit/mirrors-eslint
|
|
35
|
+
rev: v10.3.0
|
|
36
|
+
hooks:
|
|
37
|
+
- id: eslint
|
|
38
|
+
args: ["--fix"]
|
|
39
|
+
require_serial: true
|
|
40
|
+
additional_dependencies:
|
|
41
|
+
- "@eslint/js@9.39.2"
|
|
42
|
+
- "eslint@9.39.2"
|
|
43
|
+
- "globals@17.0.0"
|
|
33
44
|
- repo: local
|
|
34
45
|
hooks:
|
|
35
46
|
- id: esupgrade
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# esupgrade
|
|
2
|
+
|
|
3
|
+
The package includes transformers for upgrading JavaScript syntax.
|
|
4
|
+
|
|
5
|
+
## Categories
|
|
6
|
+
|
|
7
|
+
- [Widely Available](./src/widelyAvailable/): Transformers for features available in all major browsers for at least 30 months.
|
|
8
|
+
- [Newly Available](./src/newlyAvailable/): Transformers for features available in all major browsers for 0-30 months.
|
|
9
|
+
|
|
10
|
+
For a full list of transformations, see [README.md](./README.md).
|
|
11
|
+
|
|
12
|
+
## Package Structure
|
|
13
|
+
|
|
14
|
+
- [bin/](./bin/): Command-line interface script.
|
|
15
|
+
- [src/](./src/): Source code and transformers.
|
|
16
|
+
- [tests/](./tests/): Test suite.
|
|
17
|
+
|
|
18
|
+
For contributing guidelines, see [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
19
|
+
|
|
20
|
+
## Instructions
|
|
21
|
+
|
|
22
|
+
Use EOF syntax to run node scripts directly from the command line. For example:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
node --input-type=module <<'EOF'
|
|
26
|
+
import { transform } from './src/index.js';
|
|
27
|
+
|
|
28
|
+
const sample = "const v = $(input).val();";
|
|
29
|
+
const res = transform(sample);
|
|
30
|
+
console.log('modified:', res.modified);
|
|
31
|
+
console.log('code:\n' + res.code);
|
|
32
|
+
EOF
|
|
33
|
+
```
|
package/CONTRIBUTING.md
CHANGED
|
@@ -20,3 +20,7 @@ Or instead run the linters once with:
|
|
|
20
20
|
```console
|
|
21
21
|
uvx pre-commit run --all-files
|
|
22
22
|
```
|
|
23
|
+
|
|
24
|
+
## Naming conversions
|
|
25
|
+
|
|
26
|
+
When writing code, please follow the [naming guidelines](https://raw.githubusercontent.com/codingjoe/naming-things/refs/heads/main/README.md).
|
package/README.md
CHANGED
|
@@ -15,6 +15,12 @@ Keeping your JavaScript and TypeScript code up to date with full browser compati
|
|
|
15
15
|
esupgrade is safe and meant to be used automatically on your codebase.
|
|
16
16
|
We recommend integrating it into your development workflow using [pre-commit].
|
|
17
17
|
|
|
18
|
+
To try it out on a repository without writing changes, run:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx esupgrade $(git ls-files | grep -E -i -w '.*\.(t|j)sx?')
|
|
22
|
+
```
|
|
23
|
+
|
|
18
24
|
### pre-commit
|
|
19
25
|
|
|
20
26
|
```bash
|
|
@@ -218,6 +224,17 @@ Supports:
|
|
|
218
224
|
+const clone = [...Array.from(items)];
|
|
219
225
|
```
|
|
220
226
|
|
|
227
|
+
#### `Array.filter()[0]` → [`Array.find()`][mdn-find]
|
|
228
|
+
|
|
229
|
+
```diff
|
|
230
|
+
-const first = [1, 2, 3].filter(n => n > 1)[0];
|
|
231
|
+
+const first = [1, 2, 3].find(n => n > 1);
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Transforms `filter(predicate)[0]` to the more explicit and performant `find(predicate)`, which stops at the first match instead of filtering the entire array.
|
|
235
|
+
|
|
236
|
+
Transformations are limited to when the receiver can be verified as an array (array literals, `new Array()`, or known array method chains) and `filter()` is called with exactly one argument.
|
|
237
|
+
|
|
221
238
|
#### `Math.pow()` → [Exponentiation operator \*\*][mdn-exponentiation]
|
|
222
239
|
|
|
223
240
|
```diff
|
|
@@ -565,6 +582,189 @@ These transformations are mainly to harden code for future releases and should b
|
|
|
565
582
|
+});
|
|
566
583
|
```
|
|
567
584
|
|
|
585
|
+
<picture>
|
|
586
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://jquery.com/wp-content/themes/jquery/images/logo-jquery@2x.png">
|
|
587
|
+
<source media="(prefers-color-scheme: light)" srcset="https://upload.wikimedia.org/wikipedia/commons/f/fd/JQuery-Logo.svg">
|
|
588
|
+
<img alt="jQuery logo" src="https://upload.wikimedia.org/wikipedia/commons/f/fd/JQuery-Logo.svg" height="32" align="right">
|
|
589
|
+
</picture>
|
|
590
|
+
|
|
591
|
+
## jQuery
|
|
592
|
+
|
|
593
|
+
esupgrade can transform common [jQuery] patterns to modern, standards-based DOM APIs via the `--jQuery` argument.
|
|
594
|
+
For further reading, we recommend: [You Might Not Need jQuery](https://youmightnotneedjquery.com/).
|
|
595
|
+
|
|
596
|
+
```bash
|
|
597
|
+
npx esupgrade --jQuery <files>
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
> [!WARNING]
|
|
601
|
+
> jQuery transformers are experimental and may produce unsafe code in complex scenarios.
|
|
602
|
+
> Review all changes before applying them to your codebase.
|
|
603
|
+
|
|
604
|
+
### Selection
|
|
605
|
+
|
|
606
|
+
#### `$(selector)` → `document.querySelectorAll()` / `document.getElementById()`
|
|
607
|
+
|
|
608
|
+
```diff
|
|
609
|
+
-$('.foo')
|
|
610
|
+
- $('#bar')
|
|
611
|
+
+document.querySelectorAll('.foo')
|
|
612
|
+
+document.getElementById('bar')
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
Skipped when jQuery chaining is present (e.g. `$('.x').css(...).addClass(...)`).
|
|
616
|
+
|
|
617
|
+
### Class and Attributes
|
|
618
|
+
|
|
619
|
+
#### Class helpers
|
|
620
|
+
|
|
621
|
+
```diff
|
|
622
|
+
-$(el).addClass('a b');
|
|
623
|
+
-$(el).removeClass('a');
|
|
624
|
+
-$(el).toggleClass('x');
|
|
625
|
+
-$(el).hasClass('x');
|
|
626
|
+
+el.classList.add('a', 'b');
|
|
627
|
+
+el.classList.remove('a');
|
|
628
|
+
+el.classList.toggle('x');
|
|
629
|
+
+el.classList.contains('x');
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
#### Attribute helpers
|
|
633
|
+
|
|
634
|
+
```diff
|
|
635
|
+
-$(el).attr('data');
|
|
636
|
+
-$(el).attr('data', v);
|
|
637
|
+
-$(el).removeAttr('disabled');
|
|
638
|
+
+el.getAttribute('data');
|
|
639
|
+
+el.setAttribute('data', v);
|
|
640
|
+
+el.removeAttribute('disabled');
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### Content and Value
|
|
644
|
+
|
|
645
|
+
#### Text and HTML accessors
|
|
646
|
+
|
|
647
|
+
```diff
|
|
648
|
+
-const text = $(el).text();
|
|
649
|
+
-$(el).text('new text');
|
|
650
|
+
-const html = $(el).html();
|
|
651
|
+
-$(el).html('<b>bold</b>');
|
|
652
|
+
+const text = el.textContent;
|
|
653
|
+
+el.textContent = 'new text';
|
|
654
|
+
+const html = el.innerHTML;
|
|
655
|
+
+el.innerHTML = '<b>bold</b>';
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
#### Value accessors
|
|
659
|
+
|
|
660
|
+
```diff
|
|
661
|
+
-const val = $(el).val();
|
|
662
|
+
-$(el).val('new value');
|
|
663
|
+
+const val = el.value;
|
|
664
|
+
+el.value = 'new value';
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
### DOM Manipulation
|
|
668
|
+
|
|
669
|
+
#### Insertion and Removal
|
|
670
|
+
|
|
671
|
+
```diff
|
|
672
|
+
-$(parent).append(child);
|
|
673
|
+
-$(parent).prepend(child);
|
|
674
|
+
-$(el).before(node);
|
|
675
|
+
-$(el).after(node);
|
|
676
|
+
-$(el).remove();
|
|
677
|
+
-$(el).empty();
|
|
678
|
+
+parent.append(child);
|
|
679
|
+
+parent.prepend(child);
|
|
680
|
+
+el.before(node);
|
|
681
|
+
+el.after(node);
|
|
682
|
+
+el.remove();
|
|
683
|
+
+el.replaceChildren();
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
### Events
|
|
687
|
+
|
|
688
|
+
#### Event Listeners
|
|
689
|
+
|
|
690
|
+
```diff
|
|
691
|
+
-$(el).on('click', handler);
|
|
692
|
+
-$(el).off('click', handler);
|
|
693
|
+
-$(el).click(handler);
|
|
694
|
+
+el.addEventListener('click', handler);
|
|
695
|
+
+el.removeEventListener('click', handler);
|
|
696
|
+
+el.addEventListener('click', handler);
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
#### Dispatching and Ready
|
|
700
|
+
|
|
701
|
+
```diff
|
|
702
|
+
-$(el).trigger('custom');
|
|
703
|
+
-$(document).ready(fn);
|
|
704
|
+
+el.dispatchEvent(new CustomEvent('custom'));
|
|
705
|
+
+document.addEventListener('DOMContentLoaded', fn);
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
### Traversal
|
|
709
|
+
|
|
710
|
+
#### Traversal helpers
|
|
711
|
+
|
|
712
|
+
```diff
|
|
713
|
+
-$(el).find('.sel');
|
|
714
|
+
-$(el).parent();
|
|
715
|
+
-$(el).closest('.sel');
|
|
716
|
+
-$(el).next();
|
|
717
|
+
-$(el).prev();
|
|
718
|
+
-$(el).children();
|
|
719
|
+
-$(el).siblings();
|
|
720
|
+
+el.querySelectorAll('.sel');
|
|
721
|
+
+el.parentElement;
|
|
722
|
+
+el.closest('.sel');
|
|
723
|
+
+el.nextElementSibling;
|
|
724
|
+
+el.previousElementSibling;
|
|
725
|
+
+Array.from(el.children);
|
|
726
|
+
+Array.from(el.parentElement.children).filter(c => c !== el);
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
### Style and Sizing
|
|
730
|
+
|
|
731
|
+
#### CSS and Display
|
|
732
|
+
|
|
733
|
+
```diff
|
|
734
|
+
-$(el).css('color');
|
|
735
|
+
-$(el).css('color', 'red');
|
|
736
|
+
-$(el).show();
|
|
737
|
+
-$(el).hide();
|
|
738
|
+
+getComputedStyle(el).color;
|
|
739
|
+
+el.style.color = 'red';
|
|
740
|
+
+el.style.display = '';
|
|
741
|
+
+el.style.display = 'none';
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
#### Dimensions
|
|
745
|
+
|
|
746
|
+
```diff
|
|
747
|
+
-$(el).width();
|
|
748
|
+
-$(el).height();
|
|
749
|
+
+el.clientWidth;
|
|
750
|
+
+el.clientHeight;
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
### Static Utilities
|
|
754
|
+
|
|
755
|
+
#### Collection and String utilities
|
|
756
|
+
|
|
757
|
+
```diff
|
|
758
|
+
-$.each(array, fn);
|
|
759
|
+
-$.map(array, fn);
|
|
760
|
+
-$.inArray(val, array) !== -1;
|
|
761
|
+
-$.trim(str);
|
|
762
|
+
+array.forEach(fn);
|
|
763
|
+
+array.map(fn);
|
|
764
|
+
+array.includes(val);
|
|
765
|
+
+str.trim();
|
|
766
|
+
```
|
|
767
|
+
|
|
568
768
|
## Versioning
|
|
569
769
|
|
|
570
770
|
esupgrade uses the [calver] `YYYY.MINOR.PATCH` versioning scheme.
|
|
@@ -587,6 +787,7 @@ Furthermore, esupgrade supports JavaScript, TypeScript, and more, while lebab is
|
|
|
587
787
|
[baseline]: https://web.dev/baseline/
|
|
588
788
|
[calver]: https://calver.org/
|
|
589
789
|
[django-upgrade]: https://github.com/adamchainz/django-upgrade
|
|
790
|
+
[jquery]: https://jquery.com/
|
|
590
791
|
[mdn-arrow-functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
|
|
591
792
|
[mdn-async-await]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
|
|
592
793
|
[mdn-classes]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
|
|
@@ -595,6 +796,7 @@ Furthermore, esupgrade supports JavaScript, TypeScript, and more, while lebab is
|
|
|
595
796
|
[mdn-default-parameters]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters
|
|
596
797
|
[mdn-endswith]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
|
|
597
798
|
[mdn-exponentiation]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation
|
|
799
|
+
[mdn-find]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
|
|
598
800
|
[mdn-for-of]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
|
|
599
801
|
[mdn-functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions
|
|
600
802
|
[mdn-globalthis]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis
|
package/bin/esupgrade.js
CHANGED
|
@@ -30,11 +30,12 @@ class WorkerRunner {
|
|
|
30
30
|
* Run a worker thread to process a file.
|
|
31
31
|
* @param {string} filePath - Path to the file to process.
|
|
32
32
|
* @param {string} baseline - Baseline level for transformations.
|
|
33
|
+
* @param {boolean} jQuery - Whether to include jQuery transformers.
|
|
33
34
|
* @returns {Promise<Object>} Worker message result.
|
|
34
35
|
*/
|
|
35
|
-
async run(filePath, baseline) {
|
|
36
|
+
async run(filePath, baseline, jQuery) {
|
|
36
37
|
const worker = new Worker(this.workerPath, {
|
|
37
|
-
workerData: { filePath, baseline },
|
|
38
|
+
workerData: { filePath, baseline, jQuery },
|
|
38
39
|
})
|
|
39
40
|
|
|
40
41
|
const [message] = await once(worker, "message")
|
|
@@ -57,6 +58,7 @@ class FileProcessor {
|
|
|
57
58
|
* @param {string} options.baseline - Baseline level for transformations.
|
|
58
59
|
* @param {boolean} options.check - Whether to only check for changes.
|
|
59
60
|
* @param {boolean} options.write - Whether to write changes to file.
|
|
61
|
+
* @param {boolean} options.jQuery - Whether to include jQuery transformers.
|
|
60
62
|
* @returns {Promise<{modified: boolean, error: boolean}>} Result of processing.
|
|
61
63
|
*/
|
|
62
64
|
async processFile(filePath, options) {
|
|
@@ -73,7 +75,11 @@ class FileProcessor {
|
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
try {
|
|
76
|
-
const workerResult = await this.workerRunner.run(
|
|
78
|
+
const workerResult = await this.workerRunner.run(
|
|
79
|
+
filePath,
|
|
80
|
+
options.baseline,
|
|
81
|
+
options.jQuery,
|
|
82
|
+
)
|
|
77
83
|
|
|
78
84
|
if (!workerResult.success) {
|
|
79
85
|
console.error(`\x1b[31m✗\x1b[0m Error: ${filePath}: ${workerResult.error}`)
|
|
@@ -193,6 +199,7 @@ class CLIRunner {
|
|
|
193
199
|
async run(patterns, options) {
|
|
194
200
|
console.time("Processing")
|
|
195
201
|
// Hand CLI-provided names directly to the worker pool; file validation occurs in processFile.
|
|
202
|
+
// Pass jQuery to worker pool
|
|
196
203
|
const results = await this.workerPool.processFiles(patterns, options)
|
|
197
204
|
console.timeEnd("Processing")
|
|
198
205
|
|
|
@@ -259,21 +266,15 @@ program
|
|
|
259
266
|
.choices(["widely-available", "newly-available"])
|
|
260
267
|
.default("widely-available"),
|
|
261
268
|
)
|
|
262
|
-
.option(
|
|
263
|
-
|
|
269
|
+
.option(
|
|
270
|
+
"--check",
|
|
271
|
+
"Report which files need upgrading and exit with code 1 if any do",
|
|
272
|
+
false,
|
|
273
|
+
)
|
|
274
|
+
.option("--write", "Write changes to files", false)
|
|
275
|
+
.option("--jquery, --jQuery", "Enable jQuery specific transformers", false)
|
|
264
276
|
.action(async (files, options) => {
|
|
265
|
-
|
|
266
|
-
// Default: write is false (read-only mode unless --write is specified)
|
|
267
|
-
const shouldWrite = options.write || false
|
|
268
|
-
const shouldCheck = options.check || false
|
|
269
|
-
|
|
270
|
-
const processingOptions = {
|
|
271
|
-
baseline: options.baseline,
|
|
272
|
-
write: shouldWrite,
|
|
273
|
-
check: shouldCheck,
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
await cliRunner.run(files, processingOptions)
|
|
277
|
+
await cliRunner.run(files, options)
|
|
277
278
|
})
|
|
278
279
|
|
|
279
280
|
program.parse()
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const js = require("@eslint/js")
|
|
2
|
+
const globals = require("globals")
|
|
3
|
+
const defineConfig = require("eslint/config").defineConfig
|
|
4
|
+
|
|
5
|
+
module.exports = defineConfig([
|
|
6
|
+
{
|
|
7
|
+
files: ["**/*.{js,mjs,cjs}"],
|
|
8
|
+
plugins: { js },
|
|
9
|
+
extends: ["js/recommended"],
|
|
10
|
+
languageOptions: { globals: globals.node },
|
|
11
|
+
},
|
|
12
|
+
])
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "esupgrade",
|
|
3
|
-
"version": "2025.
|
|
3
|
+
"version": "2025.16.0",
|
|
4
4
|
"description": "Auto-upgrade your JavaScript syntax",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"esupgrade": "./bin/esupgrade.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"test": "node --test --experimental-test-coverage --test-
|
|
11
|
+
"test": "node --test --experimental-test-coverage --test-reporter=spec --test-reporter=lcov --test-reporter-destination=stdout --test-reporter-destination=lcov.info --test-coverage-exclude=tests/**/* tests/*.test.js tests/**/*.test.js"
|
|
12
12
|
},
|
|
13
13
|
"keywords": [
|
|
14
14
|
"javascript",
|
|
@@ -36,6 +36,5 @@
|
|
|
36
36
|
"repository": {
|
|
37
37
|
"type": "git",
|
|
38
38
|
"url": "https://github.com/codingjoe/esupgrade.git"
|
|
39
|
-
}
|
|
40
|
-
"devDependencies": {}
|
|
39
|
+
}
|
|
41
40
|
}
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import jscodeshift from "jscodeshift"
|
|
2
2
|
import * as newlyAvailable from "./newlyAvailable.js"
|
|
3
3
|
import * as widelyAvailable from "./widelyAvailable.js"
|
|
4
|
+
import * as jQueryTransformers from "./jQuery.js"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Transformer function type.
|
|
8
|
+
*
|
|
9
|
+
* @typedef {function(import('jscodeshift').Collection): boolean} Transformer
|
|
10
|
+
*/
|
|
4
11
|
|
|
5
12
|
/**
|
|
6
13
|
* Result of a transformation.
|
|
@@ -10,32 +17,52 @@ import * as widelyAvailable from "./widelyAvailable.js"
|
|
|
10
17
|
* @property {boolean} modified - Whether the code was modified
|
|
11
18
|
*/
|
|
12
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Apply transformers to code recursively until no changes occur.
|
|
22
|
+
*
|
|
23
|
+
* @param {string} code - The source code to transform.
|
|
24
|
+
* @param {import('jscodeshift').JSCodeshift} j - jscodeshift instance.
|
|
25
|
+
* @param {Transformer[]} transformers - Transformer functions.
|
|
26
|
+
* @param {boolean} globalModified - Whether any modifications have occurred.
|
|
27
|
+
* @returns {TransformResult} Object with transformed code and modification status.
|
|
28
|
+
*/
|
|
29
|
+
function applyTransformersRecursively(code, j, transformers, globalModified = false) {
|
|
30
|
+
const root = j(code)
|
|
31
|
+
let passModified = false
|
|
32
|
+
|
|
33
|
+
for (const transformer of transformers) {
|
|
34
|
+
passModified = transformer(root) || passModified
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (passModified) {
|
|
38
|
+
return applyTransformersRecursively(root.toSource(), j, transformers, passModified)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
code,
|
|
43
|
+
modified: globalModified,
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
13
47
|
/**
|
|
14
48
|
* Transform JavaScript code using the specified transformers.
|
|
15
49
|
*
|
|
16
50
|
* @param {string} code - The source code to transform.
|
|
17
51
|
* @param {string} baseline - Baseline level ('widely-available' or 'newly-available').
|
|
52
|
+
* @param {boolean} jQuery - Whether to include jQuery transformers.
|
|
18
53
|
* @returns {TransformResult} Object with transformed code and modification status.
|
|
19
54
|
*/
|
|
20
|
-
export function transform(code, baseline = "widely-available") {
|
|
55
|
+
export function transform(code, baseline = "widely-available", jQuery) {
|
|
21
56
|
const j = jscodeshift.withParser("tsx")
|
|
22
|
-
const root = j(code)
|
|
23
|
-
|
|
24
|
-
let modified = false
|
|
25
57
|
|
|
26
|
-
|
|
58
|
+
let transformers =
|
|
27
59
|
baseline === "newly-available"
|
|
28
60
|
? { ...widelyAvailable, ...newlyAvailable }
|
|
29
61
|
: widelyAvailable
|
|
30
62
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
modified = true
|
|
34
|
-
}
|
|
63
|
+
if (jQuery) {
|
|
64
|
+
transformers = { ...transformers, ...jQueryTransformers }
|
|
35
65
|
}
|
|
36
66
|
|
|
37
|
-
return
|
|
38
|
-
code: root.toSource(),
|
|
39
|
-
modified,
|
|
40
|
-
}
|
|
67
|
+
return applyTransformersRecursively(code, j, Object.values(transformers))
|
|
41
68
|
}
|