@automattic/eslint-config-target-es 2.0.0 → 2.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/CHANGELOG.md +29 -0
- package/README.md +22 -16
- package/SECURITY.md +11 -2
- package/package.json +24 -11
- package/src/flatconfig/all.js +6 -0
- package/src/flatconfig/base.js +21 -0
- package/src/flatconfig/builtins.js +6 -0
- package/src/flatconfig/language.js +6 -0
- package/src/funcs.js +24 -88
- package/src/needsCheck.js +151 -0
- package/src/rulesMap.js +29 -1
- /package/src/{configs → eslintrc}/all.js +0 -0
- /package/src/{configs → eslintrc}/base.js +0 -0
- /package/src/{configs → eslintrc}/builtins.js +0 -0
- /package/src/{configs → eslintrc}/language.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.2.0] - 2024-08-29
|
|
9
|
+
### Added
|
|
10
|
+
- Add mapping for `es-x/no-regexp-duplicate-named-capturing-groups`. [#39005]
|
|
11
|
+
- Support eslint flat configs (`eslint.config.js`). [#37855]
|
|
12
|
+
- Updated `eslint-plugin-es-x` adds additional rules: `es-x/no-arraybuffer-prototype-transfer`, `es-x/no-object-map-groupby`, `es-x/no-promise-withresolvers`, `es-x/no-resizable-and-growable-arraybuffers`, `es-x/no-set-prototype-difference`, `es-x/no-set-prototype-intersection`, `es-x/no-set-prototype-isdisjointfrom`, `es-x/no-set-prototype-issubsetof`, `es-x/no-set-prototype-issupersetof`, `es-x/no-set-prototype-symmetricdifference`, and `es-x/no-set-prototype-union`. [#37830]
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- Updated package dependencies. [#35608] [#36095] [#36325] [#36585] [#36760] [#37147] [#37379] [#37669] [#37828] [#37830] [#38132] [#38662] [#39002]
|
|
16
|
+
|
|
17
|
+
## [2.1.0] - 2024-02-07
|
|
18
|
+
### Added
|
|
19
|
+
- All versions indicated by browserslist are now checked, not just the lowest. Added `getAllBrowsers` function to support this. [#31658]
|
|
20
|
+
- Support for more complex MDN data:
|
|
21
|
+
* Multiple support statements are now all checked. Previously only the first (most recent) was, which may have missed cases where support was backported.
|
|
22
|
+
* `version_removed` is now checked.
|
|
23
|
+
* Ranged versions (≤) are now handled.
|
|
24
|
+
* `prefix`, `alternative_name`, and `flags` now indicate (possible) lack of support. [#31658]
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- Updated package dependencies.
|
|
28
|
+
|
|
29
|
+
### Deprecated
|
|
30
|
+
- Deprecated `getBrowsers` function in favor of the new `getAllBrowsers`. [#31658]
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
- Apparently MDN data considers "preview" a version, but didn't think that worth documenting. Handle it. [#31816]
|
|
34
|
+
|
|
8
35
|
## [2.0.0] - 2023-06-26
|
|
9
36
|
### Changed
|
|
10
37
|
- As `eslint-plugin-es` appears to be abandoned, change to using `eslint-plugin-es-x`. [#31556]
|
|
@@ -41,6 +68,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
41
68
|
### Added
|
|
42
69
|
- Initial release.
|
|
43
70
|
|
|
71
|
+
[2.2.0]: https://github.com/Automattic/eslint-config-target-es/compare/2.1.0...2.2.0
|
|
72
|
+
[2.1.0]: https://github.com/Automattic/eslint-config-target-es/compare/2.0.0...2.1.0
|
|
44
73
|
[2.0.0]: https://github.com/Automattic/eslint-config-target-es/compare/1.0.6...2.0.0
|
|
45
74
|
[1.0.6]: https://github.com/Automattic/eslint-config-target-es/compare/1.0.5...1.0.6
|
|
46
75
|
[1.0.5]: https://github.com/Automattic/eslint-config-target-es/compare/1.0.4...1.0.5
|
package/README.md
CHANGED
|
@@ -14,30 +14,30 @@ npm install --save-dev eslint eslint-plugin-es-x @automattic/eslint-config-targe
|
|
|
14
14
|
|
|
15
15
|
First, you'll probably want to set up a [browserslist] configuration.
|
|
16
16
|
|
|
17
|
-
Then you can use this like any other sharable config in your `.eslintrc.*` file. Three configurations are offered.
|
|
17
|
+
Then you can use this like any other sharable config in your `eslint.config.js` or `.eslintrc.*` file. Three configurations are offered.
|
|
18
18
|
|
|
19
|
-
To check only for language features, such as nullish coalescing,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
extends: [ '@automattic/eslint-config-target-es/language' ],
|
|
23
|
-
}
|
|
24
|
-
```
|
|
19
|
+
* To check only for language features, such as nullish coalescing, use the 'language' config.
|
|
20
|
+
* To check only for builtins, such as Promise, WeakRef, and various features of RegExp, use the 'builtins' config.
|
|
21
|
+
* To check both, use the 'all' config.
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
For `eslint.config.js`, that might look like this:
|
|
27
24
|
```js
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
import eslintConfigTargetEs from '@automattic/eslint-config-target-es/flat/language';
|
|
26
|
+
|
|
27
|
+
export default [
|
|
28
|
+
eslintConfigTargetEs,
|
|
29
|
+
// etc
|
|
30
|
+
];
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
while for eslintrc you'd do like
|
|
34
34
|
```js
|
|
35
35
|
{
|
|
36
|
-
extends: [ '@automattic/eslint-config-target-es/
|
|
36
|
+
extends: [ '@automattic/eslint-config-target-es/rc/language' ],
|
|
37
37
|
}
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
For
|
|
40
|
+
For backwards compatibility, the eslintrc configs may also be accessed without the `/rc/` path component (e.g. as `@automattic/eslint-config-target-es/language`), and `@automattic/eslint-config-target-es` is equivalent to `@automattic/eslint-config-target-es/rc/all`.
|
|
41
41
|
|
|
42
42
|
### Checking built files
|
|
43
43
|
|
|
@@ -45,7 +45,7 @@ If you want to check your built files to make sure you didn't omit transpiling a
|
|
|
45
45
|
```js
|
|
46
46
|
module.exports = {
|
|
47
47
|
root: true,
|
|
48
|
-
extends: [ '@automattic/eslint-config-target-es/language' ],
|
|
48
|
+
extends: [ '@automattic/eslint-config-target-es/rc/language' ],
|
|
49
49
|
env: {
|
|
50
50
|
// Whatever environments you need.
|
|
51
51
|
},
|
|
@@ -57,14 +57,20 @@ eslint --no-eslintrc --no-inline-config --config validate-es.config.js --no-igno
|
|
|
57
57
|
```
|
|
58
58
|
to avoid your standard eslintrc and eslintignore and to avoid errors from any inline directives.
|
|
59
59
|
|
|
60
|
+
Something similar can be done for flat config.
|
|
61
|
+
|
|
60
62
|
### Advanced usage
|
|
61
63
|
|
|
62
64
|
You can import or require `@automattic/eslint-config-target-es/functions` to gain access to some functions that can be used to build your own configuration.
|
|
63
65
|
|
|
64
|
-
As browserslist and MDN use different browser codes, `
|
|
66
|
+
As browserslist and MDN use different browser codes, `getAllBrowsers( { query: } )` will take a browserslist query and return an object with the MDN browser codes and the matched versions for each.
|
|
65
67
|
|
|
66
68
|
`getRules( { query:, builtins: } )` will return the rules config. Set `builtins` true for "builtins", false for "language", or null/undefined for "all".
|
|
67
69
|
|
|
70
|
+
### Caveats
|
|
71
|
+
|
|
72
|
+
Some browsers supported by browserslist are not availble in the MDN data (e.g. Opera Mini) or are no longer being updated (e.g. Internet Explorer). In cases like these where no data is available, features are assumed to be supported. Set the environment variable `DEBUG=@automattic/eslint-config-target-es:warn` to generate messages when this happens.
|
|
73
|
+
|
|
68
74
|
## Security
|
|
69
75
|
|
|
70
76
|
Need to report a security vulnerability? Go to [https://automattic.com/security/](https://automattic.com/security/) or directly to our security bug bounty site [https://hackerone.com/automattic](https://hackerone.com/automattic).
|
package/SECURITY.md
CHANGED
|
@@ -4,11 +4,20 @@ Full details of the Automattic Security Policy can be found on [automattic.com](
|
|
|
4
4
|
|
|
5
5
|
## Supported Versions
|
|
6
6
|
|
|
7
|
-
Generally, only the latest version of Jetpack
|
|
7
|
+
Generally, only the latest version of Jetpack and its associated plugins have continued support. If a critical vulnerability is found in the current version of a plugin, we may opt to backport any patches to previous versions.
|
|
8
8
|
|
|
9
9
|
## Reporting a Vulnerability
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Our HackerOne program covers the below plugin software, as well as a variety of related projects and infrastructure:
|
|
12
|
+
|
|
13
|
+
* [Jetpack](https://jetpack.com/)
|
|
14
|
+
* Jetpack Backup
|
|
15
|
+
* Jetpack Boost
|
|
16
|
+
* Jetpack CRM
|
|
17
|
+
* Jetpack Protect
|
|
18
|
+
* Jetpack Search
|
|
19
|
+
* Jetpack Social
|
|
20
|
+
* Jetpack VideoPress
|
|
12
21
|
|
|
13
22
|
**For responsible disclosure of security issues and to be eligible for our bug bounty program, please submit your report via the [HackerOne](https://hackerone.com/automattic) portal.**
|
|
14
23
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/eslint-config-target-es",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "ESLint sharable config to activate eslint-plugin-es checks based on browserslist targets.",
|
|
5
5
|
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/eslint-config-target-es/README.md#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -17,26 +17,39 @@
|
|
|
17
17
|
"test": "jest tests"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@mdn/browser-compat-data": "5.
|
|
20
|
+
"@mdn/browser-compat-data": "5.5.47",
|
|
21
21
|
"browserslist": "^4.17.6",
|
|
22
22
|
"debug": "^4.3.2",
|
|
23
23
|
"semver": "^7.3.5"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@wordpress/browserslist-config": "5.
|
|
27
|
-
"eslint": "8.
|
|
28
|
-
"eslint-plugin-es-x": "7.
|
|
29
|
-
"
|
|
26
|
+
"@wordpress/browserslist-config": "6.5.0",
|
|
27
|
+
"eslint": "8.57.0",
|
|
28
|
+
"eslint-plugin-es-x": "7.8.0",
|
|
29
|
+
"globals": "15.4.0",
|
|
30
|
+
"jest": "29.7.0"
|
|
30
31
|
},
|
|
31
32
|
"peerDependencies": {
|
|
32
33
|
"eslint": ">=4.19.1",
|
|
33
|
-
"eslint-plugin-es-x": "^7.
|
|
34
|
+
"eslint-plugin-es-x": "^7.6.0",
|
|
35
|
+
"globals": ">=15.4.0"
|
|
36
|
+
},
|
|
37
|
+
"peerDependenciesMeta": {
|
|
38
|
+
"globals": {
|
|
39
|
+
"optional": true
|
|
40
|
+
}
|
|
34
41
|
},
|
|
35
42
|
"exports": {
|
|
36
|
-
".": "./src/
|
|
37
|
-
"./language": "./src/
|
|
38
|
-
"./builtins": "./src/
|
|
39
|
-
"./all": "./src/
|
|
43
|
+
".": "./src/eslintrc/all.js",
|
|
44
|
+
"./language": "./src/eslintrc/language.js",
|
|
45
|
+
"./builtins": "./src/eslintrc/builtins.js",
|
|
46
|
+
"./all": "./src/eslintrc/all.js",
|
|
47
|
+
"./rc/language": "./src/eslintrc/language.js",
|
|
48
|
+
"./rc/builtins": "./src/eslintrc/builtins.js",
|
|
49
|
+
"./rc/all": "./src/eslintrc/all.js",
|
|
50
|
+
"./flat/language": "./src/flatconfig/language.js",
|
|
51
|
+
"./flat/builtins": "./src/flatconfig/builtins.js",
|
|
52
|
+
"./flat/all": "./src/flatconfig/all.js",
|
|
40
53
|
"./functions": "./src/funcs.js"
|
|
41
54
|
}
|
|
42
55
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const esx = require( 'eslint-plugin-es-x' );
|
|
2
|
+
|
|
3
|
+
const flatBase = {
|
|
4
|
+
plugins: {
|
|
5
|
+
'es-x': esx,
|
|
6
|
+
},
|
|
7
|
+
languageOptions: {
|
|
8
|
+
ecmaVersion: 2022,
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
const globals = require( 'globals' );
|
|
14
|
+
if ( globals?.es2022 ) {
|
|
15
|
+
flatBase.languageOptions.globals = globals.es2022;
|
|
16
|
+
}
|
|
17
|
+
} catch ( e ) {
|
|
18
|
+
// `globals` is optional.
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = flatBase;
|
package/src/funcs.js
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
const mdn = require( '@mdn/browser-compat-data' );
|
|
2
1
|
const browserslist = require( 'browserslist' );
|
|
3
2
|
const debug = require( 'debug' );
|
|
4
3
|
const { rules: esRules } = require( 'eslint-plugin-es-x' );
|
|
5
4
|
const semver = require( 'semver' );
|
|
6
5
|
const browsersMap = require( './browsersMap.js' );
|
|
7
|
-
const
|
|
6
|
+
const { needsCheck } = require( './needsCheck.js' );
|
|
8
7
|
|
|
9
8
|
const warn = debug( '@automattic/eslint-config-target-es:warn' );
|
|
10
|
-
const debuglog = debug( '@automattic/eslint-config-target-es:debug' );
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
11
|
* Get the list of supported browsers.
|
|
14
12
|
*
|
|
15
|
-
* @param {object} options
|
|
13
|
+
* @param {object} options - Options.
|
|
16
14
|
* @param {string} options.query - Browserslist query.
|
|
17
|
-
* @
|
|
15
|
+
* @return {object} Browsers mapped to arrays of versions.
|
|
18
16
|
*/
|
|
19
|
-
function
|
|
17
|
+
function getAllBrowsers( options = {} ) {
|
|
20
18
|
const browsers = {};
|
|
21
19
|
for ( const b of browserslist( options.query ) ) {
|
|
22
20
|
const m = b.match( /^([a-z_]+) (all|[0-9.]+)(-.*)?$/ );
|
|
@@ -33,104 +31,41 @@ function getBrowsers( options = {} ) {
|
|
|
33
31
|
continue;
|
|
34
32
|
}
|
|
35
33
|
const ver = m[ 2 ] === 'all' ? '0.0.0' : semver.coerce( m[ 2 ] ).version;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
browsers[ browser ] ||= [];
|
|
35
|
+
browsers[ browser ].push( ver );
|
|
36
|
+
browsers[ browser ].sort( semver.compare );
|
|
39
37
|
}
|
|
40
38
|
return browsers;
|
|
41
39
|
}
|
|
42
40
|
|
|
43
41
|
/**
|
|
44
|
-
*
|
|
42
|
+
* Get the list of supported browsers.
|
|
45
43
|
*
|
|
46
|
-
* @
|
|
47
|
-
* @param {object}
|
|
48
|
-
* @param {
|
|
49
|
-
* @
|
|
50
|
-
* @returns {boolean} Whether the rule needs to be checked.
|
|
44
|
+
* @deprecated since 2.1.0. Use getAllBrowsers instead.
|
|
45
|
+
* @param {object} options - Options.
|
|
46
|
+
* @param {string} options.query - Browserslist query.
|
|
47
|
+
* @return {object} Browsers mapped to minimum versions.
|
|
51
48
|
*/
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if ( ! Array.isArray( paths ) ) {
|
|
59
|
-
paths = [ paths ];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
options.builtins === false &&
|
|
64
|
-
paths.some( path => path.startsWith( 'javascript.builtins.' ) )
|
|
65
|
-
) {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
if (
|
|
69
|
-
options.builtins === true &&
|
|
70
|
-
! paths.some( path => path.startsWith( 'javascript.builtins.' ) )
|
|
71
|
-
) {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
path: for ( const path of paths ) {
|
|
76
|
-
let data = mdn;
|
|
77
|
-
for ( const k of path.split( '.' ) ) {
|
|
78
|
-
data = data[ k ];
|
|
79
|
-
if ( ! data ) {
|
|
80
|
-
warn( `Invalid feature map for rule ${ rule }: ${ path } does not exist` );
|
|
81
|
-
continue path;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
if ( ! data.__compat || ! data.__compat.support ) {
|
|
85
|
-
warn( `Invalid feature map for rule ${ rule }: No data at ${ path }` );
|
|
86
|
-
continue path;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
browser: for ( const browser of Object.keys( browsers ) ) {
|
|
90
|
-
if ( ! data.__compat.support[ browser ] ) {
|
|
91
|
-
debuglog( `No support data for ${ browser } for rule ${ rule } (${ path }), skipping` );
|
|
92
|
-
continue browser;
|
|
93
|
-
}
|
|
94
|
-
let support = data.__compat.support[ browser ];
|
|
95
|
-
if ( Array.isArray( support ) ) {
|
|
96
|
-
support = support[ 0 ];
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if ( support.version_added === null ) {
|
|
100
|
-
debuglog( `No support data for ${ browser } for rule ${ rule } (${ path }), skipping` );
|
|
101
|
-
continue browser;
|
|
102
|
-
} else if ( support.version_added === false ) {
|
|
103
|
-
debuglog( `${ browser } needs check for ${ rule } (${ path })` );
|
|
104
|
-
return true;
|
|
105
|
-
} else if ( support.version_added === true ) {
|
|
106
|
-
continue browser;
|
|
107
|
-
} else if ( semver.gt( semver.coerce( support.version_added ), browsers[ browser ] ) ) {
|
|
108
|
-
debuglog(
|
|
109
|
-
`${ browser } < ${ support.version_added } needs check for ${ rule } (${ path }); we have ${ browsers[ browser ] }`
|
|
110
|
-
);
|
|
111
|
-
return true;
|
|
112
|
-
} else if ( support.partial_implementation ) {
|
|
113
|
-
debuglog(
|
|
114
|
-
`${ browser } needs check for ${ rule } (${ path }) due to partial implementation`
|
|
115
|
-
);
|
|
116
|
-
return true;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
49
|
+
function getBrowsers( options = {} ) {
|
|
50
|
+
warn( 'getBrowsers is deprecated. Use getAllBrowsers instead.' );
|
|
51
|
+
const browsers = getAllBrowsers( options );
|
|
52
|
+
const ret = {};
|
|
53
|
+
for ( const k of Object.keys( browsers ) ) {
|
|
54
|
+
ret[ k ] = browsers[ k ][ 0 ];
|
|
119
55
|
}
|
|
120
|
-
|
|
121
|
-
return false;
|
|
56
|
+
return ret;
|
|
122
57
|
}
|
|
123
58
|
|
|
124
59
|
/**
|
|
125
60
|
* Get the es-x rule configurations.
|
|
126
61
|
*
|
|
127
|
-
* @param {object}
|
|
62
|
+
* @param {object} options - Options.
|
|
128
63
|
* @param {boolean|null} options.builtins - If true, only rules with "javascript.builtins" paths are checked. If false, such rules are not checked. If null/undefined, all may be checked.
|
|
129
|
-
* @param {string}
|
|
130
|
-
* @
|
|
64
|
+
* @param {string} options.query - Browserslist query.
|
|
65
|
+
* @return {object} Rules configuration.
|
|
131
66
|
*/
|
|
132
67
|
function getRules( options = {} ) {
|
|
133
|
-
const browsers =
|
|
68
|
+
const browsers = getAllBrowsers( options );
|
|
134
69
|
const ret = {};
|
|
135
70
|
for ( const rule of Object.keys( esRules ) ) {
|
|
136
71
|
ret[ `es-x/${ rule }` ] = needsCheck( rule, browsers, options ) ? 2 : 0;
|
|
@@ -139,6 +74,7 @@ function getRules( options = {} ) {
|
|
|
139
74
|
}
|
|
140
75
|
|
|
141
76
|
module.exports = {
|
|
77
|
+
getAllBrowsers,
|
|
142
78
|
getBrowsers,
|
|
143
79
|
getRules,
|
|
144
80
|
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
const mdn = require( '@mdn/browser-compat-data' );
|
|
2
|
+
const debug = require( 'debug' );
|
|
3
|
+
const semver = require( 'semver' );
|
|
4
|
+
const rulesMap = require( './rulesMap.js' );
|
|
5
|
+
|
|
6
|
+
const warn = debug( '@automattic/eslint-config-target-es:warn' );
|
|
7
|
+
const debuglog = debug( '@automattic/eslint-config-target-es:debug' );
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Test if a rule needs to be checked.
|
|
11
|
+
*
|
|
12
|
+
* @param {string} rule - Rule.
|
|
13
|
+
* @param {object} browsers - Browsers targeted.
|
|
14
|
+
* @param {object} options - Options.
|
|
15
|
+
* @param {boolean|null} options.builtins - If true, only rules with "javascript.builtins" paths are checked. If false, such rules are not checked. If null/undefined, all may be checked.
|
|
16
|
+
* @return {boolean} Whether the rule needs to be checked.
|
|
17
|
+
*/
|
|
18
|
+
function needsCheck( rule, browsers, options = {} ) {
|
|
19
|
+
let paths = rulesMap[ rule ];
|
|
20
|
+
if ( paths === true || paths === false ) {
|
|
21
|
+
return paths;
|
|
22
|
+
}
|
|
23
|
+
if ( paths === undefined ) {
|
|
24
|
+
warn( `No feature map for rule ${ rule }` );
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
if ( ! Array.isArray( paths ) ) {
|
|
28
|
+
paths = [ paths ];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (
|
|
32
|
+
options.builtins === false &&
|
|
33
|
+
paths.some( path => path.startsWith( 'javascript.builtins.' ) )
|
|
34
|
+
) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (
|
|
38
|
+
options.builtins === true &&
|
|
39
|
+
! paths.some( path => path.startsWith( 'javascript.builtins.' ) )
|
|
40
|
+
) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const semver000 = semver.coerce( '0.0.0' );
|
|
45
|
+
|
|
46
|
+
path: for ( const path of paths ) {
|
|
47
|
+
let data = mdn;
|
|
48
|
+
for ( const k of path.split( '.' ) ) {
|
|
49
|
+
data = data[ k ];
|
|
50
|
+
if ( ! data ) {
|
|
51
|
+
warn( `Invalid feature map for rule ${ rule }: ${ path } does not exist` );
|
|
52
|
+
continue path;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if ( ! data.__compat || ! data.__compat.support ) {
|
|
56
|
+
warn( `Invalid feature map for rule ${ rule }: No data at ${ path }` );
|
|
57
|
+
continue path;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
browser: for ( const browser of Object.keys( browsers ) ) {
|
|
61
|
+
if ( ! data.__compat.support[ browser ] ) {
|
|
62
|
+
warn( `No support data for ${ browser } for rule ${ rule } (${ path }), skipping` );
|
|
63
|
+
continue browser;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const supports = Array.isArray( data.__compat.support[ browser ] )
|
|
67
|
+
? data.__compat.support[ browser ]
|
|
68
|
+
: [ data.__compat.support[ browser ] ];
|
|
69
|
+
const vers = Array.isArray( browsers[ browser ] )
|
|
70
|
+
? browsers[ browser ]
|
|
71
|
+
: [ browsers[ browser ] ];
|
|
72
|
+
|
|
73
|
+
version: for ( const ver of vers ) {
|
|
74
|
+
const results = [];
|
|
75
|
+
support: for ( const support of supports ) {
|
|
76
|
+
if ( support.version_added === null ) {
|
|
77
|
+
continue support;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if ( support.version_added === false ) {
|
|
81
|
+
results.push( 'no support' );
|
|
82
|
+
continue support;
|
|
83
|
+
}
|
|
84
|
+
if ( support.version_added === 'preview' ) {
|
|
85
|
+
results.push( 'added version is "preview"' );
|
|
86
|
+
continue support;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let added, removed;
|
|
90
|
+
if ( support.version_added === true ) {
|
|
91
|
+
added = semver000;
|
|
92
|
+
} else {
|
|
93
|
+
added = support.version_added.startsWith( '≤' )
|
|
94
|
+
? semver000
|
|
95
|
+
: semver.coerce( support.version_added );
|
|
96
|
+
}
|
|
97
|
+
if ( support.version_removed === true ) {
|
|
98
|
+
removed = semver000;
|
|
99
|
+
} else if (
|
|
100
|
+
typeof support.version_removed === 'string' &&
|
|
101
|
+
support.version_removed !== 'preview'
|
|
102
|
+
) {
|
|
103
|
+
removed = support.version_removed.startsWith( '≤' )
|
|
104
|
+
? semver000
|
|
105
|
+
: semver.coerce( support.version_removed );
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const range = removed ? `${ added } – <${ removed }` : `>= ${ added }`;
|
|
109
|
+
|
|
110
|
+
if ( semver.gt( added, ver ) || ( removed && semver.lte( removed, ver ) ) ) {
|
|
111
|
+
results.push( `outside range ${ range }` );
|
|
112
|
+
} else if ( support.partial_implementation ) {
|
|
113
|
+
results.push( `partial implementation for ${ range }` );
|
|
114
|
+
} else if ( support.prefix ) {
|
|
115
|
+
results.push( `prefixed implementation for ${ range }` );
|
|
116
|
+
} else if ( support.alternative_name ) {
|
|
117
|
+
results.push( `alternatively named implementation for ${ range }` );
|
|
118
|
+
} else if ( support.flags ) {
|
|
119
|
+
results.push( `flagged implementation for ${ range }` );
|
|
120
|
+
} else {
|
|
121
|
+
// It's good! Check the next version.
|
|
122
|
+
continue version;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// If there was no support data at all...
|
|
127
|
+
if ( results.length === 0 ) {
|
|
128
|
+
warn( `No support data for ${ browser } for rule ${ rule } (${ path }), skipping` );
|
|
129
|
+
continue browser;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// If no support entry hit the "It's good" case, it's no good. Log the reasons.
|
|
133
|
+
// If there are reasons other than "outside range", skip any "outside range" as irrelevant.
|
|
134
|
+
let results2 = results.filter( v => ! v.startsWith( 'outside range' ) );
|
|
135
|
+
if ( results2.length === 0 ) {
|
|
136
|
+
results2 = results;
|
|
137
|
+
}
|
|
138
|
+
debuglog(
|
|
139
|
+
`${ browser } ${ ver } needs check for ${ rule } (${ path }); ${ results2.join( '; ' ) }`
|
|
140
|
+
);
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
module.exports = {
|
|
150
|
+
needsCheck,
|
|
151
|
+
};
|
package/src/rulesMap.js
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
1
|
// Map of eslint-plugin-es-x rules to MDN compat-data paths.
|
|
2
2
|
// Values are either a path, an array of paths, true to always enable the rule, or false to always disable it.
|
|
3
3
|
module.exports = {
|
|
4
|
-
//
|
|
4
|
+
// ES2025
|
|
5
|
+
'no-regexp-duplicate-named-capturing-groups':
|
|
6
|
+
'javascript.regular_expressions.named_capturing_group.duplicate_named_capturing_groups',
|
|
7
|
+
|
|
8
|
+
// ES2024
|
|
9
|
+
'no-arraybuffer-prototype-transfer': 'javascript.builtins.ArrayBuffer.transfer',
|
|
5
10
|
'no-atomics-waitasync': 'javascript.builtins.Atomics.waitAsync',
|
|
11
|
+
'no-object-map-groupby': [
|
|
12
|
+
'javascript.builtins.Map.groupBy',
|
|
13
|
+
'javascript.builtins.Object.groupBy',
|
|
14
|
+
],
|
|
15
|
+
'no-promise-withresolvers': 'javascript.builtins.Promise.withResolvers',
|
|
16
|
+
'no-regexp-v-flag': 'javascript.builtins.RegExp.unicodeSets',
|
|
17
|
+
'no-resizable-and-growable-arraybuffers': [
|
|
18
|
+
'javascript.builtins.ArrayBuffer.ArrayBuffer.maxByteLength_option',
|
|
19
|
+
'javascript.builtins.ArrayBuffer.maxByteLength',
|
|
20
|
+
'javascript.builtins.ArrayBuffer.resizable',
|
|
21
|
+
'javascript.builtins.ArrayBuffer.resize',
|
|
22
|
+
'javascript.builtins.SharedArrayBuffer.SharedArrayBuffer.maxByteLength_option',
|
|
23
|
+
'javascript.builtins.SharedArrayBuffer.grow',
|
|
24
|
+
'javascript.builtins.SharedArrayBuffer.growable',
|
|
25
|
+
'javascript.builtins.SharedArrayBuffer.maxByteLength',
|
|
26
|
+
],
|
|
27
|
+
'no-set-prototype-difference': 'javascript.builtins.Set.difference',
|
|
28
|
+
'no-set-prototype-intersection': 'javascript.builtins.Set.intersection',
|
|
29
|
+
'no-set-prototype-isdisjointfrom': 'javascript.builtins.Set.isDisjointFrom',
|
|
30
|
+
'no-set-prototype-issubsetof': 'javascript.builtins.Set.isSubsetOf',
|
|
31
|
+
'no-set-prototype-issupersetof': 'javascript.builtins.Set.isSupersetOf',
|
|
32
|
+
'no-set-prototype-symmetricdifference': 'javascript.builtins.Set.symmetricDifference',
|
|
33
|
+
'no-set-prototype-union': 'javascript.builtins.Set.union',
|
|
6
34
|
'no-string-prototype-iswellformed-towellformed': [
|
|
7
35
|
'javascript.builtins.String.isWellFormed',
|
|
8
36
|
'javascript.builtins.String.toWellFormed',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|