@wordpress/eslint-plugin 10.0.2 → 11.0.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 CHANGED
@@ -2,7 +2,15 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
- – Replaced no-shadow eslint rule with @typescript-eslint/no-shadow ([#38665](https://github.com/WordPress/gutenberg/pull/38665)).
5
+ ## 11.0.0 (2022-03-11)
6
+
7
+ ### Breaking Changes
8
+
9
+ - The integration with [Prettier](https://prettier.io) is now optional and gets activated when the `prettier` package is installed in the project ([#39244](https://github.com/WordPress/gutenberg/pull/39244)).
10
+
11
+ ### Bug Fix
12
+
13
+ - Replaced no-shadow eslint rule with @typescript-eslint/no-shadow ([#38665](https://github.com/WordPress/gutenberg/pull/38665)).
6
14
 
7
15
  ## 10.0.0 (2022-01-27)
8
16
 
package/README.md CHANGED
@@ -24,9 +24,21 @@ To opt-in to the default configuration, extend your own project's `.eslintrc` fi
24
24
 
25
25
  Refer to the [ESLint documentation on Shareable Configs](http://eslint.org/docs/developer-guide/shareable-configs) for more information.
26
26
 
27
- The `recommended` preset will include rules governing an ES2015+ environment, and includes rules from the [`eslint-plugin-jsx-a11y`](https://github.com/evcohen/eslint-plugin-jsx-a11y), [`eslint-plugin-react`](https://github.com/yannickcr/eslint-plugin-react), and [`eslint-plugin-prettier`](https://github.com/prettier/eslint-plugin-prettier) projects. It also includes an optional integration with [`@typescript-eslint/eslint-plugin`](https://github.com/typescript-eslint/typescript-eslint) that gets activated when the [`typescript`](https://www.npmjs.com/package/typescript) package is installed in the project.
27
+ The `recommended` preset will include rules governing an ES2015+ environment, and includes rules from the [`eslint-plugin-jsdoc`](https://github.com/gajus/eslint-plugin-jsdoc), [`eslint-plugin-jsx-a11y`](https://github.com/evcohen/eslint-plugin-jsx-a11y), [`eslint-plugin-react`](https://github.com/yannickcr/eslint-plugin-react), and other similar plugins.
28
28
 
29
- There is also `recommended-with-formatting` ruleset for projects that want to opt out from [Prettier](https://prettier.io). It has the native ESLint code formatting rules enabled instead.
29
+ This preset offers an optional integration with the [`eslint-plugin-prettier`](https://github.com/prettier/eslint-plugin-prettier) package that runs [Prettier](https://prettier.io) code formatter and reports differences as individual ESLint issues. You can activate it by installing the [`prettier`](https://www.npmjs.com/package/prettier) package separately with:
30
+
31
+ ```bash
32
+ npm install prettier --save-dev
33
+ ```
34
+
35
+ Finally, this ruleset also includes an optional integration with the [`@typescript-eslint/eslint-plugin`](https://github.com/typescript-eslint/typescript-eslint) package that enables ESLint to support [TypeScript](https://www.typescriptlang.org) language. You can activate it by installing the [`typescript`](https://www.npmjs.com/package/typescript) package separately with:
36
+
37
+ ```bash
38
+ npm install typescript --save-dev
39
+ ```
40
+
41
+ There is also `recommended-with-formatting` ruleset for projects that want to ensure that [Prettier](https://prettier.io) and [TypeScript](https://www.typescriptlang.org) integration is never activated. This preset has the native ESLint code formatting rules enabled instead.
30
42
 
31
43
  ### Rulesets
32
44
 
package/configs/esnext.js CHANGED
@@ -16,7 +16,7 @@ const config = {
16
16
  // Disable ES5-specific (extended from ES5)
17
17
  'vars-on-top': 'off',
18
18
 
19
- // Enable ESNext-specific
19
+ // Enable ESNext-specific.
20
20
  'arrow-parens': [ 'error', 'always' ],
21
21
  'arrow-spacing': 'error',
22
22
  'computed-property-spacing': [ 'error', 'always' ],
@@ -13,20 +13,21 @@ const defaultPrettierConfig = require( '@wordpress/prettier-config' );
13
13
  */
14
14
  const { isPackageInstalled } = require( '../utils' );
15
15
 
16
- const { config: localPrettierConfig } =
17
- cosmiconfigSync( 'prettier' ).search() || {};
18
- const prettierConfig = { ...defaultPrettierConfig, ...localPrettierConfig };
19
-
20
16
  const config = {
21
- extends: [
22
- require.resolve( './recommended-with-formatting.js' ),
23
- 'plugin:prettier/recommended',
24
- ],
25
- rules: {
26
- 'prettier/prettier': [ 'error', prettierConfig ],
27
- },
17
+ extends: [ require.resolve( './recommended-with-formatting.js' ) ],
28
18
  };
29
19
 
20
+ if ( isPackageInstalled( 'prettier' ) ) {
21
+ config.extends.push( 'plugin:prettier/recommended' );
22
+
23
+ const { config: localPrettierConfig } =
24
+ cosmiconfigSync( 'prettier' ).search() || {};
25
+ const prettierConfig = { ...defaultPrettierConfig, ...localPrettierConfig };
26
+ config.rules = {
27
+ 'prettier/prettier': [ 'error', prettierConfig ],
28
+ };
29
+ }
30
+
30
31
  if ( isPackageInstalled( 'typescript' ) ) {
31
32
  config.settings = {
32
33
  'import/resolver': {
@@ -48,7 +49,7 @@ if ( isPackageInstalled( 'typescript' ) ) {
48
49
  // Don't require redundant JSDoc types in TypeScript files.
49
50
  'jsdoc/require-param-type': 'off',
50
51
  'jsdoc/require-returns-type': 'off',
51
- // handled by TS itself
52
+ // Handled by TS itself.
52
53
  'no-unused-vars': 'off',
53
54
  // no-shadow doesn't work correctly in TS, so let's use a TS-dedicated version instead.
54
55
  'no-shadow': 'off',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/eslint-plugin",
3
- "version": "10.0.2",
3
+ "version": "11.0.0",
4
4
  "description": "ESLint plugin for WordPress development.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -34,7 +34,7 @@
34
34
  "@babel/eslint-parser": "^7.16.0",
35
35
  "@typescript-eslint/eslint-plugin": "^5.3.0",
36
36
  "@typescript-eslint/parser": "^5.3.0",
37
- "@wordpress/babel-preset-default": "^6.5.1",
37
+ "@wordpress/babel-preset-default": "^6.6.0",
38
38
  "@wordpress/prettier-config": "^1.1.2",
39
39
  "cosmiconfig": "^7.0.0",
40
40
  "eslint-config-prettier": "^8.3.0",
@@ -46,15 +46,18 @@
46
46
  "eslint-plugin-react": "^7.27.0",
47
47
  "eslint-plugin-react-hooks": "^4.3.0",
48
48
  "globals": "^13.12.0",
49
- "prettier": "npm:wp-prettier@2.2.1-beta-1",
50
49
  "requireindex": "^1.2.0"
51
50
  },
52
51
  "peerDependencies": {
53
52
  "@babel/core": ">=7",
54
53
  "eslint": ">=8",
54
+ "prettier": ">=2",
55
55
  "typescript": ">=4"
56
56
  },
57
57
  "peerDependenciesMeta": {
58
+ "prettier": {
59
+ "optional": true
60
+ },
58
61
  "typescript": {
59
62
  "optional": true
60
63
  }
@@ -62,5 +65,5 @@
62
65
  "publishConfig": {
63
66
  "access": "public"
64
67
  },
65
- "gitHead": "4566ac290359553d04de4eb574545309343f790b"
68
+ "gitHead": "c37fd7edbc3e379540d7b24fce75a6f640a434ae"
66
69
  }
@@ -16,14 +16,14 @@ const ruleTester = new RuleTester( {
16
16
  } );
17
17
 
18
18
  const valid = [
19
- // Callback functions
19
+ // Callback functions.
20
20
  `import { createRegistrySelector } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; createRegistrySelector(( select ) => { select(coreStore); });`,
21
21
  `import { useSelect } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; useSelect(( select ) => { select(coreStore); });`,
22
22
  `import { withSelect } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; withSelect(( select ) => { select(coreStore); });`,
23
23
  `import { withDispatch } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; withDispatch(( select ) => { select(coreStore); });`,
24
24
  `import { withDispatch as withDispatchAlias } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; withDispatchAlias(( select ) => { select(coreStore); });`,
25
25
 
26
- // Direct function calls
26
+ // Direct function calls.
27
27
  `import { useDispatch } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; useDispatch( coreStore );`,
28
28
  `import { dispatch } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; dispatch( coreStore );`,
29
29
  `import { useSelect } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; useSelect( coreStore );`,
@@ -31,7 +31,7 @@ const valid = [
31
31
  `import { resolveSelect } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; resolveSelect( coreStore );`,
32
32
  `import { resolveSelect as resolveSelectAlias } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; resolveSelectAlias( coreStore );`,
33
33
 
34
- // Object property function calls
34
+ // Object property function calls.
35
35
  `import { controls } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; controls.select( coreStore );`,
36
36
  `import { controls } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; controls.dispatch( coreStore );`,
37
37
  `import { controls } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; controls.resolveSelect( coreStore );`,
@@ -54,14 +54,14 @@ const createSuggestionTestCase = ( code, output ) => ( {
54
54
  } );
55
55
 
56
56
  const invalid = [
57
- // Callback functions
57
+ // Callback functions.
58
58
  `import { createRegistrySelector } from '@wordpress/data'; createRegistrySelector(( select ) => { select( 'core' ); });`,
59
59
  `import { useSelect } from '@wordpress/data'; useSelect(( select ) => { select( 'core' ); });`,
60
60
  `import { withSelect } from '@wordpress/data'; withSelect(( select ) => { select( 'core' ); });`,
61
61
  `import { withDispatch } from '@wordpress/data'; withDispatch(( select ) => { select( 'core' ); });`,
62
62
  `import { withDispatch as withDispatchAlias } from '@wordpress/data'; withDispatchAlias(( select ) => { select( 'core' ); });`,
63
63
 
64
- // Direct function calls
64
+ // Direct function calls.
65
65
  `import { useDispatch } from '@wordpress/data'; useDispatch( 'core' );`,
66
66
  `import { dispatch } from '@wordpress/data'; dispatch( 'core' );`,
67
67
  `import { useSelect } from '@wordpress/data'; useSelect( 'core' );`,
@@ -69,14 +69,14 @@ const invalid = [
69
69
  `import { resolveSelect } from '@wordpress/data'; resolveSelect( 'core' );`,
70
70
  `import { resolveSelect as resolveSelectAlias } from '@wordpress/data'; resolveSelectAlias( 'core' );`,
71
71
 
72
- // Object property function calls
72
+ // Object property function calls.
73
73
  `import { controls } from '@wordpress/data'; controls.select( 'core' );`,
74
74
  `import { controls } from '@wordpress/data'; controls.dispatch( 'core' );`,
75
75
  `import { controls } from '@wordpress/data'; controls.resolveSelect( 'core' );`,
76
76
  `import { controls as controlsAlias } from '@wordpress/data'; controlsAlias.resolveSelect( 'core' );`,
77
77
 
78
78
  // Direct function calls suggestions
79
- // Replace core with coreStore and import coreStore
79
+ // Replace core with coreStore and import coreStore.
80
80
  createSuggestionTestCase(
81
81
  `import { select } from '@wordpress/data'; select( 'core' );`,
82
82
  `import { select } from '@wordpress/data';\nimport { store as coreStore } from '@wordpress/core-data'; select( coreStore );`
@@ -103,17 +103,17 @@ const invalid = [
103
103
  `import { a } from './a'; import { select } from '@wordpress/data'; import { b } from './b'; select( 'core' );`,
104
104
  `import { a } from './a'; import { select } from '@wordpress/data';\nimport { store as coreStore } from '@wordpress/core-data'; import { b } from './b'; select( coreStore );`
105
105
  ),
106
- // Replace block-editor with blockEditorStore
106
+ // Replace block-editor with blockEditorStore.
107
107
  createSuggestionTestCase(
108
108
  `import { select } from '@wordpress/data'; select( 'core/block-editor' );`,
109
109
  `import { select } from '@wordpress/data';\nimport { store as blockEditorStore } from '@wordpress/block-editor'; select( blockEditorStore );`
110
110
  ),
111
- // Replace notices with noticesStore
111
+ // Replace notices with noticesStore.
112
112
  createSuggestionTestCase(
113
113
  `import { select } from '@wordpress/data'; select( 'core/notices' );`,
114
114
  `import { select } from '@wordpress/data';\nimport { store as noticesStore } from '@wordpress/notices'; select( noticesStore );`
115
115
  ),
116
- // Replace edit-post with editPostStore
116
+ // Replace edit-post with editPostStore.
117
117
  createSuggestionTestCase(
118
118
  `import { select } from '@wordpress/data'; select( 'core/edit-post' );`,
119
119
  `import { select } from '@wordpress/data';\nimport { store as editPostStore } from '@wordpress/edit-post'; select( editPostStore );`
@@ -82,7 +82,7 @@ module.exports = {
82
82
  // - Normalize `/**` and `/*`
83
83
  // - Case insensitive "Dependencies" vs. "dependencies"
84
84
  // - Ending period
85
- // - "Node" dependencies as an alias for External
85
+ // - "Node" dependencies as an alias for External.
86
86
 
87
87
  if ( locality === 'External' ) {
88
88
  locality = '(External|Node)';
@@ -80,7 +80,7 @@ function testIsUsedInStrictBinaryExpression( node, context ) {
80
80
  const comparisonNode =
81
81
  node.parent.type === 'MemberExpression' ? node.parent : node;
82
82
 
83
- // Test for process.env.GUTENBERG_PHASE === <number> or <number> === process.env.GUTENBERG_PHASE
83
+ // Test for process.env.GUTENBERG_PHASE === <number> or <number> === process.env.GUTENBERG_PHASE.
84
84
  const hasCorrectOperator = [ '===', '!==' ].includes( parent.operator );
85
85
  const hasCorrectOperands =
86
86
  ( parent.left === comparisonNode &&
@@ -18,7 +18,7 @@ function isAcceptableLiteralNode( node ) {
18
18
 
19
19
  if ( 'TemplateLiteral' === node.type ) {
20
20
  // Backticks are fine, but if there's any interpolation in it,
21
- // that's a problem
21
+ // that's a problem.
22
22
  return node.expressions.length === 0;
23
23
  }
24
24
 
@@ -141,7 +141,7 @@ module.exports = {
141
141
  ) {
142
142
  const replaceTextDomain = ( fixer ) => {
143
143
  return fixer.replaceTextRange(
144
- // account for quotes.
144
+ // Account for quotes.
145
145
  [ range[ 0 ] + 1, range[ 1 ] - 1 ],
146
146
  allowedTextDomains[ 0 ]
147
147
  );
@@ -51,7 +51,7 @@ function makeListener( { allowedImports, context } ) {
51
51
 
52
52
  const sourceModule = node.source.value.trim();
53
53
 
54
- // Ignore non-WordPress packages
54
+ // Ignore non-WordPress packages.
55
55
  if ( ! sourceModule.startsWith( '@wordpress/' ) ) {
56
56
  return;
57
57
  }