@automattic/eslint-plugin-wpvip 0.4.11 → 0.4.12

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # WordPress VIP ESLint plugin
2
2
 
3
- This is an ESLint plugin to provide WordPress VIP's (internal) JavaScript and TypeScript coding standards. It extends [`@wordpress/eslint-plugin`](https://github.com/WordPress/gutenberg/tree/trunk/packages/eslint-plugin).
3
+ This is an ESLint plugin to provide WordPress VIP's (internal) JavaScript and TypeScript coding standards. It is inspired by and borrows from [`@wordpress/eslint-plugin`](https://github.com/WordPress/gutenberg/tree/trunk/packages/eslint-plugin).
4
4
 
5
5
  ## Installation
6
6
 
@@ -12,104 +12,85 @@ npm install --save-dev eslint @automattic/eslint-plugin-wpvip
12
12
 
13
13
  ## Configuration
14
14
 
15
- Create an `.eslintrc.js` file with your desired configs. **Note:** The `init` file allows you to avoid installing peer dependencies (available from `v0.5.0`).
15
+ Create an `.eslintrc.js` file. **Note:** The `init` file allows you to avoid installing peer dependencies (available from `v0.5.0`).
16
16
 
17
17
  ```js
18
18
  require( '@automattic/eslint-plugin-wpvip/init' );
19
19
 
20
20
  module.exports = {
21
21
  extends: [
22
- 'plugin:@automattic/wpvip/base',
23
- ]
24
- }
22
+ 'plugin:@automattic/wpvip/recommended',
23
+ ],
24
+ };
25
25
  ```
26
26
 
27
- And that's it! Code editors that are configured to work with ESLint will automatically pick up the rules and flag any errors or warnings.
28
-
29
- Tip: Set up a `lint` npm script in `package.json`:
30
-
31
- ```json
32
- "scripts": {
33
- "lint": "eslint ."
34
- }
35
- ```
27
+ And that's it! It works automatically with most Babel and TypeScript projects. Code editors that are configured to work with ESLint will automatically pick up the rules and flag any errors or warnings.
36
28
 
37
29
  You may also wish to define an `.eslintignore` file if there are files or paths that you do not want to lint.
38
30
 
39
- ## TypeScript
31
+ ## Recommended config
40
32
 
41
- TypeScript rules are automatically added whenever your project has installed the [`typescript` NPM package]() as a dependency.
33
+ The "recommended" config includes rules for JavaScript, TypeScript, Jest, and React, including rules related to formatting and white space. It is intended to be strict! Opinionated defaults keep our codebases consistent and reduce the friction we experience when context-switching between projects.
42
34
 
43
- ## Prettier
35
+ If your project has installed [Prettier](https://prettier.io/) as a dependency, then many formatting tasks will be delegated to it (via `eslint-plugin-prettier`). You are encouraged to define your own [`.prettierrc` configuration file](https://prettier.io/docs/en/configuration.html) to fine-tune your project’s formatting.
44
36
 
45
- Prettier integration with ESLint is automatically enabled. Further, by default, this plugin provides the [WordPress prettier config](https://github.com/WordPress/gutenberg/blob/605aeb0f4f7d2225120e498f95ae27b9f56d77a3/packages/prettier-config/lib/index.js). You can define your own [`.prettierrc` configuration file](https://prettier.io/docs/en/configuration.html), which will be merged with the default. The following `.prettierrc` will use spaces for indentation instead of tabs:
37
+ Of course, this recommended config may not be ideal for every project, so feel free to "build your own" using the available modular configs. The recommended config is equivalent to:
46
38
 
47
- ```json
48
- {
49
- "useTabs": false
50
- }
39
+ ```js
40
+ module.exports = {
41
+ extends: [
42
+ 'plugin:@automattic/wpvip/javascript',
43
+ 'plugin:@automattic/wpvip/typescript', // when "typescript" is installed
44
+ 'plugin:@automattic/wpvip/formatting',
45
+ 'plugin:@automattic/wpvip/testing', // when "jest" is installed
46
+ 'plugin:@automattic/wpvip/react', // when "react" is installed
47
+ 'plugin:@automattic/wpvip/prettier', // when "prettier" is installed
48
+ ],
49
+ };
51
50
  ```
52
51
 
53
- If you wish to disable the automatic Prettier integration, add the `prettier-off` config to your `.eslintrc.js`:
54
-
55
- ```json
56
- {
57
- "extends": [
58
- "plugin:@automattic/wpvip/base",
59
- "plugin:@automattic/wpvip/prettier-off"
60
- ]
61
- }
62
- ```
52
+ Note that the order of configs can matter, since they can contain overrides. It is particularly important to add the `prettier` config last.
63
53
 
64
54
  ## CLI
65
55
 
66
56
  The `cli` config allows certain behaviors that are usually against best practice but are useful in a codebase that produces a CLI tool:
67
57
 
68
- ```json
69
- {
70
- "extends": [
71
- "plugin:@automattic/wpvip/base",
72
- "plugin:@automattic/wpvip/cli"
73
- ]
74
- }
58
+ ```js
59
+ module.exports = {
60
+ extends: [
61
+ 'plugin:@automattic/wpvip/recommended',
62
+ 'plugin:@automattic/wpvip/cli',
63
+ ],
64
+ };
75
65
  ```
76
66
 
77
- If your project is not a CLI tool but calls `console` or `process` methods occasionally, don't use this config—just add ignore statements in those few spots.
67
+ If your project is not a CLI tool but calls `console` or `process` methods occasionally, you probably don't need this config. Instead, disable those rules only where necessary and include an explanation:
68
+
69
+ ```js
70
+ // Intentionally exiting because we have observed an unrecoverable error.
71
+ // eslint-disable-next-line no-process-exit
72
+ process.exit( 1 );
73
+ ```
78
74
 
79
75
  ## JSDoc
80
76
 
81
- The `base` config includes rules related to enforce [JSDoc](https://jsdoc.app/) best practices, but they are not triggered if your code does not provide `@param` or `@return` markers:
77
+ JSDoc is considered optional, especially compared to better alternatives like TypeScript and OpenAPI documentation. If you want to enforce the use of JSDoc, use the `jsdoc` config:
82
78
 
83
79
  ```js
84
- /**
85
- * No rules are triggered for this docblock, because there are no param or
86
- * return markers
87
- */
88
- function myFunc1() {}
89
-
90
- /**
91
- * Rules *are* triggered for this docblock.
92
- *
93
- * @param myArg
94
- */
95
- function myFunc2(myArg) {}
80
+ module.exports = {
81
+ extends: [
82
+ 'plugin:@automattic/wpvip/recommended',
83
+ 'plugin:@automattic/wpvip/jsdoc',
84
+ ],
85
+ };
96
86
  ```
97
87
 
98
- If you want to enforce the use of JSDoc, use the `jsdoc` config:
99
-
100
- ```json
101
- {
102
- "extends": [
103
- "plugin:@automattic/wpvip/base",
104
- "plugin:@automattic/wpvip/jsdoc"
105
- ]
106
- }
107
- ```
88
+ Note that rules that require `@param` and `@return` types are relaxed in TypeScript files.
108
89
 
109
90
  ## "Weak" configs
110
91
 
111
- This plugin provides a few "weak" configs for legacy codebases that are working to transition to stronger standards. These configs downgrade select rules from the `base` config to warnings. Warnings will still be visible in code editors, but will not fail continous integration workflows.
92
+ This plugin provides a few so-called "weak" configs for legacy codebases that are working to transition to stronger standards. These configs downgrade select rules from the `recommended` config to warnings. Warnings will still be visible in code editors and other outputs but will not fail continous integration workflows.
112
93
 
113
- These configs are intended for temporary use and should not be used long-term. We also do not recommend the use of tools like [eslines](https://github.com/Automattic/eslines) to ignore errors or warnings. While the intention is to prevent large-scale changes and transition slowly to stronger standards, the effect is usually that the transition stalls and stops completely.
94
+ These configs are intended for temporary use and should not be used long-term. We also do not recommend the use of tools like [eslines](https://github.com/Automattic/eslines) to ignore errors or warnings. While the intention is to prevent large-scale changes and transition slowly to stronger standards, the effect is usually that the transition stalls and eventually stops completely.
114
95
 
115
- Two "weak" configs are available: `weak` and `weak-typescript`. While pull requests on this project are always welcome, please carefully consider whether adding rules to these configs is truly necessary.
96
+ Three "weak" configs are available: `weak-javascript`, `weak-typescript`, and `weak-jest`. While pull requests on this project are always welcome, please carefully consider whether adding rules to these configs is truly necessary. Ideally, we work to remove rules from these configs until they are no longer needed.
@@ -4,13 +4,13 @@ module.exports = {
4
4
  * disable errors, include a brief justification or reasoning.
5
5
  */
6
6
  rules: {
7
- 'array-bracket-spacing': [ 'error', 'always' ],
7
+ 'array-bracket-spacing': ['error', 'always'],
8
8
 
9
- 'arrow-parens': [ 'error', 'always' ],
9
+ 'arrow-parens': ['error', 'always'],
10
10
 
11
11
  'arrow-spacing': 'error',
12
12
 
13
- 'brace-style': [ 'error', '1tbs' ],
13
+ 'brace-style': ['error', '1tbs'],
14
14
 
15
15
  // Identifiers should be in camelCase. Object properties are excluded
16
16
  // (including when destructuring) since they often come from external
@@ -23,24 +23,24 @@ module.exports = {
23
23
  },
24
24
  ],
25
25
 
26
- 'comma-dangle': [ 'error', 'always-multiline' ],
26
+ 'comma-dangle': ['error', 'always-multiline'],
27
27
 
28
28
  'comma-spacing': 'error',
29
29
 
30
- 'comma-style': [ 'error', 'last' ],
30
+ 'comma-style': ['error', 'last'],
31
31
 
32
- 'computed-property-spacing': [ 'error', 'always' ],
32
+ 'computed-property-spacing': ['error', 'always'],
33
33
 
34
- curly: [ 'error', 'all' ],
34
+ curly: ['error', 'all'],
35
35
 
36
36
  'dot-notation': 'error',
37
37
 
38
38
  // Files must end in a newline.
39
- 'eol-last': [ 'error', 'always' ],
39
+ 'eol-last': ['error', 'always'],
40
40
 
41
41
  'func-call-spacing': 'error',
42
42
 
43
- indent: [ 'error', 'tab', { SwitchCase: 1 } ],
43
+ indent: ['error', 'tab', { SwitchCase: 1 }],
44
44
 
45
45
  'key-spacing': 'error',
46
46
 
@@ -58,19 +58,19 @@ module.exports = {
58
58
 
59
59
  'no-multi-str': 'error',
60
60
 
61
- 'no-multiple-empty-lines': [ 'error', { max: 1 } ],
61
+ 'no-multiple-empty-lines': ['error', { max: 1 }],
62
62
 
63
63
  'no-trailing-spaces': 'error',
64
64
 
65
65
  'no-whitespace-before-property': 'error',
66
66
 
67
- 'object-curly-spacing': [ 'error', 'always' ],
67
+ 'object-curly-spacing': ['error', 'always'],
68
68
 
69
69
  'object-shorthand': 'error',
70
70
 
71
71
  'operator-linebreak': 'error',
72
72
 
73
- 'padded-blocks': [ 'error', 'never' ],
73
+ 'padded-blocks': ['error', 'never'],
74
74
 
75
75
  // Arrow functions should be used for function arguments and callbacks.
76
76
  'prefer-arrow-callback': 'warn',
@@ -81,30 +81,28 @@ module.exports = {
81
81
  { allowTemplateLiterals: true, avoidEscape: true },
82
82
  ],
83
83
 
84
- 'quote-props': [ 'error', 'as-needed' ],
84
+ 'quote-props': ['error', 'as-needed'],
85
85
 
86
86
  semi: 'error',
87
87
 
88
88
  'semi-spacing': 'error',
89
89
 
90
- 'space-before-blocks': [ 'error', 'always' ],
90
+ 'space-before-blocks': ['error', 'always'],
91
91
 
92
92
  'space-before-function-paren': [
93
93
  'error',
94
94
  { anonymous: 'never', named: 'never', asyncArrow: 'always' },
95
95
  ],
96
96
 
97
- 'space-in-parens': [ 'error', 'always' ],
97
+ 'space-in-parens': ['error', 'always'],
98
98
 
99
99
  'space-infix-ops': 'error',
100
100
 
101
- 'space-unary-ops': [ 'error', { overrides: { '!': true, yield: true } } ],
101
+ 'space-unary-ops': ['error', { overrides: { '!': true, yield: true } }],
102
102
 
103
103
  // Comments should always include consistent spacing for readability.
104
104
  'spaced-comment': 'warn',
105
105
 
106
- 'template-curly-spacing': [ 'error', 'always' ],
107
-
106
+ 'template-curly-spacing': ['error', 'always'],
108
107
  },
109
108
  };
110
-
package/configs/index.js CHANGED
@@ -1,14 +1,15 @@
1
1
  module.exports = {
2
- base: require( './base' ),
3
- cli: require( './cli' ),
4
- formatting: require( './formatting' ),
5
- javascript: require( './javascript' ),
6
- jsdoc: require( './jsdoc' ),
7
- prettier: require( './prettier' ),
8
- react: require( './react' ),
9
- testing: require( './testing' ),
10
- typescript: require( './typescript' ),
11
- 'weak-javascript': require( './weak-javascript' ),
12
- 'weak-testing': require( './weak-testing' ),
13
- 'weak-typescript': require( './weak-typescript' ),
2
+ base: require('./javascript'), // synonym for javascript
3
+ cli: require('./cli'),
4
+ formatting: require('./formatting'),
5
+ javascript: require('./javascript'),
6
+ jsdoc: require('./jsdoc'),
7
+ prettier: require('./prettier'),
8
+ react: require('./react'),
9
+ recommended: require('./recommended'),
10
+ testing: require('./testing'),
11
+ typescript: require('./typescript'),
12
+ 'weak-javascript': require('./weak-javascript'),
13
+ 'weak-testing': require('./weak-testing'),
14
+ 'weak-typescript': require('./weak-typescript'),
14
15
  };
@@ -12,6 +12,8 @@ module.exports = {
12
12
  node: true,
13
13
  },
14
14
 
15
+ extends: ['plugin:json/recommended', 'plugin:security/recommended'],
16
+
15
17
  parser: '@babel/eslint-parser',
16
18
 
17
19
  parserOptions: {
@@ -22,15 +24,14 @@ module.exports = {
22
24
  /**
23
25
  * Note: We must explicitly add this plugin to use our custom rules.
24
26
  */
25
- plugins: [ '@automattic/wpvip', 'import' ],
27
+ plugins: ['@automattic/wpvip', 'import'],
26
28
 
27
29
  /**
28
30
  * Please include a short description of the rule. For rules that downgrade or
29
31
  * disable errors, include a brief justification or reasoning.
30
32
  */
31
33
  rules: {
32
- // These rules are from eslint:recommended, but are enumerated here for
33
- // visibility:
34
+ // BEGIN eslint:recommended, enumerated here for visibility:
34
35
  // https://github.com/eslint/eslint/blob/main/packages/js/src/configs/eslint-recommended.js
35
36
  'constructor-super': 'error',
36
37
  'for-direction': 'error',
@@ -93,6 +94,7 @@ module.exports = {
93
94
  'require-yield': 'error',
94
95
  'use-isnan': 'error',
95
96
  // 'valid-typeof': 'error', // extended below
97
+ // END eslint:recommended
96
98
 
97
99
  // Async/await must not be used in a `.forEach` method, because the result
98
100
  // will not be awaited in the outer scope.
@@ -137,7 +139,7 @@ module.exports = {
137
139
 
138
140
  // Enforce Unix linebreaks. Included here and not in "formatting" since it
139
141
  // is not controversial and helps with interchange.
140
- 'linebreak-style': [ 'error', 'unix' ],
142
+ 'linebreak-style': ['error', 'unix'],
141
143
 
142
144
  'no-alert': 'error',
143
145
 
@@ -149,7 +151,7 @@ module.exports = {
149
151
 
150
152
  'no-caller': 'error',
151
153
 
152
- 'no-cond-assign': [ 'error', 'except-parens' ],
154
+ 'no-cond-assign': ['error', 'except-parens'],
153
155
 
154
156
  // `console.log` should not be used directly in code. Ideally, delegate to a
155
157
  // logging function that logs on your behalf (and ignore this rule there).
@@ -161,7 +163,7 @@ module.exports = {
161
163
 
162
164
  'no-else-return': 'error',
163
165
 
164
- 'no-empty': [ 'error', { allowEmptyCatch: true } ],
166
+ 'no-empty': ['error', { allowEmptyCatch: true }],
165
167
 
166
168
  'no-eq-null': 'error',
167
169
 
@@ -179,7 +181,7 @@ module.exports = {
179
181
 
180
182
  'no-unused-expressions': 'error',
181
183
 
182
- 'no-unused-vars': [ 'error', { ignoreRestSiblings: true } ],
184
+ 'no-unused-vars': ['error', { ignoreRestSiblings: true }],
183
185
 
184
186
  'no-useless-computed-key': 'error',
185
187
 
@@ -189,9 +191,9 @@ module.exports = {
189
191
 
190
192
  'no-var': 'error',
191
193
 
192
- 'one-var': [ 'error', 'never' ],
194
+ 'one-var': ['error', 'never'],
193
195
 
194
- 'prefer-const': [ 'error', { destructuring: 'all' } ],
196
+ 'prefer-const': ['error', { destructuring: 'all' }],
195
197
 
196
198
  radix: 'error',
197
199
 
@@ -203,6 +205,6 @@ module.exports = {
203
205
  },
204
206
  ],
205
207
 
206
- 'wrap-iife': [ 'error', 'any' ],
208
+ 'wrap-iife': ['error', 'any'],
207
209
  },
208
210
  };
package/configs/jsdoc.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * https://github.com/WordPress/gutenberg/blob/%40wordpress/eslint-plugin%4014.1.0/packages/eslint-plugin/configs/jsdoc.js
4
4
  */
5
5
 
6
- const globals = require( 'globals' );
6
+ const globals = require('globals');
7
7
 
8
8
  /**
9
9
  * Helpful utilities that are globally defined and known to the TypeScript compiler.
@@ -41,7 +41,7 @@ const typescriptUtilityTypes = [
41
41
  ];
42
42
 
43
43
  module.exports = {
44
- extends: [ 'plugin:jsdoc/recommended' ],
44
+ extends: ['plugin:jsdoc/recommended'],
45
45
  settings: {
46
46
  jsdoc: {
47
47
  preferredTypes: {
@@ -61,9 +61,7 @@ module.exports = {
61
61
  // Required to reference browser types because we don't have the `browser` environment enabled for the project.
62
62
  // Here we filter out all browser globals that don't begin with an uppercase letter because those
63
63
  // generally refer to window-level event listeners and are not a valid type to reference (e.g. `onclick`).
64
- ...Object.keys( globals.browser ).filter( ( key ) =>
65
- /^[A-Z]/.test( key ),
66
- ),
64
+ ...Object.keys(globals.browser).filter((key) => /^[A-Z]/.test(key)),
67
65
  ...typescriptUtilityTypes,
68
66
  'void',
69
67
  'JSX',
@@ -75,17 +73,14 @@ module.exports = {
75
73
  'jsdoc/require-returns': 'off',
76
74
  'jsdoc/require-yields': 'off',
77
75
  'jsdoc/tag-lines': 'off',
78
- 'jsdoc/no-multi-asterisks': [
79
- 'error',
80
- { preventAtMiddleLines: false },
81
- ],
76
+ 'jsdoc/no-multi-asterisks': ['error', { preventAtMiddleLines: false }],
82
77
  'jsdoc/check-access': 'error',
83
78
  'jsdoc/check-alignment': 'error',
84
79
  'jsdoc/check-line-alignment': [
85
80
  'error',
86
81
  'always',
87
82
  {
88
- tags: [ 'param', 'arg', 'argument', 'property', 'prop' ],
83
+ tags: ['param', 'arg', 'argument', 'property', 'prop'],
89
84
  preserveMainDescriptionPostDelimiter: true,
90
85
  },
91
86
  ],
@@ -4,8 +4,8 @@
4
4
  */
5
5
 
6
6
  module.exports = {
7
- extends: [ 'plugin:jsx-a11y/recommended' ],
8
- plugins: [ 'jsx-a11y' ],
7
+ extends: ['plugin:jsx-a11y/recommended'],
8
+ plugins: ['jsx-a11y'],
9
9
  rules: {
10
10
  'jsx-a11y/label-has-associated-control': [
11
11
  'error',
@@ -4,8 +4,8 @@
4
4
  */
5
5
 
6
6
  module.exports = {
7
- extends: [ 'plugin:prettier/recommended' ],
8
- plugins: [ 'prettier' ],
7
+ extends: ['plugin:prettier/recommended'],
8
+ plugins: ['prettier'],
9
9
  rules: {
10
10
  'prettier/prettier': 'error',
11
11
  },
package/configs/react.js CHANGED
@@ -7,19 +7,23 @@ module.exports = {
7
7
  extends: [
8
8
  'plugin:react/recommended',
9
9
  'plugin:react-hooks/recommended',
10
- require( './jsx-ally' ),
10
+ require('./jsx-ally'),
11
11
  ],
12
+
12
13
  parserOptions: {
13
14
  ecmaFeatures: {
14
15
  jsx: true,
15
16
  },
16
17
  },
18
+
17
19
  settings: {
18
20
  react: {
19
21
  version: 'detect',
20
22
  },
21
23
  },
22
- plugins: [ '@automattic/wpvip', 'react', 'react-hooks' ],
24
+
25
+ plugins: ['@automattic/wpvip', 'react', 'react-hooks'],
26
+
23
27
  rules: {
24
28
  '@automattic/wpvip/no-unused-vars-before-return': [
25
29
  'error',
@@ -27,7 +31,9 @@ module.exports = {
27
31
  excludePattern: '^use',
28
32
  },
29
33
  ],
34
+
30
35
  'react/display-name': 'off',
36
+
31
37
  'react/jsx-curly-spacing': [
32
38
  'error',
33
39
  {
@@ -35,13 +41,21 @@ module.exports = {
35
41
  children: true,
36
42
  },
37
43
  ],
44
+
38
45
  'react/jsx-equals-spacing': 'error',
39
- 'react/jsx-indent': [ 'error', 'tab' ],
40
- 'react/jsx-indent-props': [ 'error', 'tab' ],
46
+
47
+ 'react/jsx-indent': ['error', 'tab'],
48
+
49
+ 'react/jsx-indent-props': ['error', 'tab'],
50
+
41
51
  'react/jsx-key': 'error',
52
+
42
53
  'react/jsx-tag-spacing': 'error',
54
+
43
55
  'react/no-children-prop': 'off',
56
+
44
57
  'react/prop-types': 'off',
58
+
45
59
  'react/react-in-jsx-scope': 'off',
46
60
  },
47
61
  };
@@ -0,0 +1,28 @@
1
+ const debugLog = require('../utils/debug-log');
2
+ const isPackageInstalled = require('../utils/is-package-installed');
3
+
4
+ const config = {
5
+ extends: [require.resolve('./javascript')],
6
+ };
7
+
8
+ if (isPackageInstalled('typescript')) {
9
+ config.extends.push(require.resolve('./typescript'));
10
+ }
11
+
12
+ config.extends.push(require.resolve('./formatting'));
13
+
14
+ if (isPackageInstalled('jest')) {
15
+ config.extends.push(require.resolve('./testing'));
16
+ }
17
+
18
+ if (isPackageInstalled('react')) {
19
+ config.extends.push(require.resolve('./react'));
20
+ }
21
+
22
+ if (isPackageInstalled('prettier')) {
23
+ config.extends.push(require.resolve('./prettier'));
24
+ }
25
+
26
+ debugLog(`Using the following configs:\n${config.extends.join('\n')}`);
27
+
28
+ module.exports = config;
@@ -5,11 +5,11 @@
5
5
  */
6
6
 
7
7
  module.exports = {
8
- extends: [ 'plugin:jest/recommended' ],
8
+ extends: ['plugin:jest/recommended'],
9
9
 
10
10
  env: {
11
11
  'jest/globals': true,
12
12
  },
13
13
 
14
- plugins: [ 'jest' ],
14
+ plugins: ['jest'],
15
15
  };
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  module.exports = {
7
- ignorePatterns: [ '**/*.d.ts' ],
7
+ ignorePatterns: ['**/*.d.ts'],
8
8
 
9
9
  overrides: [
10
10
  {
@@ -14,7 +14,7 @@ module.exports = {
14
14
  'plugin:@typescript-eslint/strict',
15
15
  ],
16
16
 
17
- files: [ '**/*.ts', '**/*.tsx' ],
17
+ files: ['**/*.ts', '**/*.tsx'],
18
18
 
19
19
  parser: '@typescript-eslint/parser',
20
20
 
@@ -39,12 +39,12 @@ module.exports = {
39
39
  },
40
40
  ],
41
41
 
42
- plugins: [ '@typescript-eslint', 'jsdoc' ],
42
+ plugins: ['@typescript-eslint', 'jsdoc'],
43
43
 
44
44
  settings: {
45
45
  'import/resolver': {
46
46
  node: {
47
- extensions: [ '.js', '.jsx', '.ts', '.tsx' ],
47
+ extensions: ['.js', '.jsx', '.ts', '.tsx'],
48
48
  },
49
49
  },
50
50
  },
@@ -10,7 +10,7 @@ module.exports = {
10
10
  overrides: [
11
11
  {
12
12
  // Don't apply weak rules to TypeScript files.
13
- files: [ '**/*.js', '**/*.jsx' ],
13
+ files: ['**/*.js', '**/*.jsx'],
14
14
 
15
15
  /**
16
16
  * Downgrade rules from the base preset to "warn". Do not disable rules (set
@@ -21,4 +21,3 @@ module.exports = {
21
21
  'jest/no-standalone-expect': 'warn',
22
22
  },
23
23
  };
24
-
@@ -5,9 +5,15 @@
5
5
  * you migrate an existing project to TypeScript.
6
6
  */
7
7
  module.exports = {
8
- /**
9
- * Downgrade rules from the base preset to "warn". Do not disable rules (set
10
- * to "off"). If a rule is already set to a warning, do not disable it.
11
- */
12
- rules: {},
8
+ overrides: [
9
+ {
10
+ files: ['**/*.ts', '**/*.tsx'],
11
+
12
+ /**
13
+ * Downgrade rules from the base preset to "warn". Do not disable rules (set
14
+ * to "off"). If a rule is already set to a warning, do not disable it.
15
+ */
16
+ rules: {},
17
+ },
18
+ ],
13
19
  };
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  module.exports = {
2
- configs: require( './configs' ),
3
- rules: require( './rules' ),
2
+ configs: require('./configs'),
3
+ rules: require('./rules'),
4
4
  };
package/init.js CHANGED
@@ -1 +1 @@
1
- require( '@rushstack/eslint-patch/modern-module-resolution' );
1
+ require('@rushstack/eslint-patch/modern-module-resolution');
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@automattic/eslint-plugin-wpvip",
3
- "version": "0.4.11",
3
+ "version": "0.4.12",
4
4
  "description": "ESLint plugin for internal WordPress VIP projects",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "jest": "jest",
8
8
  "jest:update-snapshot": "jest --updateSnapshot",
9
9
  "link-plugin": "mkdir -p ./node_modules/@automattic; ln -fns $(pwd) ./node_modules/@automattic/eslint-plugin-wpvip",
10
- "lint": "eslint .",
11
- "test": "npm run link-plugin && npm run lint && jest"
10
+ "lint": "npm run link-plugin && eslint .",
11
+ "test": "jest"
12
12
  },
13
13
  "repository": {
14
14
  "type": "git",
@@ -29,14 +29,17 @@
29
29
  "@rushstack/eslint-patch": "1.2.0",
30
30
  "@typescript-eslint/eslint-plugin": "5.55.0",
31
31
  "@typescript-eslint/parser": "5.55.0",
32
+ "eslint-config-prettier": "8.7.0",
32
33
  "eslint-plugin-import": "2.27.5",
33
34
  "eslint-plugin-jest": "27.2.1",
34
35
  "eslint-plugin-jsdoc": "40.0.2",
35
36
  "eslint-plugin-json": "3.1.0",
36
37
  "eslint-plugin-jsx-a11y": "6.7.1",
38
+ "eslint-plugin-prettier": "4.2.1",
37
39
  "eslint-plugin-react": "7.32.2",
38
40
  "eslint-plugin-react-hooks": "4.6.0",
39
41
  "eslint-plugin-security": "1.7.1",
42
+ "find-package-json": "1.2.0",
40
43
  "globals": "13.20.0"
41
44
  },
42
45
  "peerDependencies": {
@@ -44,8 +47,6 @@
44
47
  },
45
48
  "devDependencies": {
46
49
  "eslint": "8.35.0",
47
- "eslint-config-prettier": "8.7.0",
48
- "eslint-plugin-eslint-plugin": "5.0.8",
49
50
  "jest": "29.5.0",
50
51
  "prettier": "2.8.4",
51
52
  "typescript": "4.9.5"
@@ -17,7 +17,7 @@ module.exports = {
17
17
  schema: [],
18
18
  fixable: 'code',
19
19
  },
20
- create( context ) {
20
+ create(context) {
21
21
  const comments = context.getSourceCode().getAllComments();
22
22
 
23
23
  /**
@@ -45,8 +45,8 @@ module.exports = {
45
45
  *
46
46
  * @return {string} Expected comment node value.
47
47
  */
48
- function getCommentValue( locality ) {
49
- return `*\n * ${ locality } dependencies\n `;
48
+ function getCommentValue(locality) {
49
+ return `*\n * ${locality} dependencies\n `;
50
50
  }
51
51
 
52
52
  /**
@@ -57,10 +57,10 @@ module.exports = {
57
57
  *
58
58
  * @return {WPPackageLocality} Package locality.
59
59
  */
60
- function getPackageLocality( source ) {
61
- if ( source.startsWith( '.' ) ) {
60
+ function getPackageLocality(source) {
61
+ if (source.startsWith('.')) {
62
62
  return 'Internal';
63
- } else if ( source.startsWith( '@wordpress/' ) ) {
63
+ } else if (source.startsWith('@wordpress/')) {
64
64
  return 'WordPress';
65
65
  }
66
66
 
@@ -76,9 +76,9 @@ module.exports = {
76
76
  *
77
77
  * @return {boolean} Whether comment node satisfies locality.
78
78
  */
79
- function isLocalityDependencyBlock( node, locality ) {
79
+ function isLocalityDependencyBlock(node, locality) {
80
80
  const { type, value } = node;
81
- if ( type !== 'Block' ) {
81
+ if (type !== 'Block') {
82
82
  return false;
83
83
  }
84
84
 
@@ -88,16 +88,16 @@ module.exports = {
88
88
  // - Ending period
89
89
  // - "Node" dependencies as an alias for External.
90
90
 
91
- if ( locality === 'External' ) {
91
+ if (locality === 'External') {
92
92
  locality = '(External|Node)';
93
93
  }
94
94
 
95
95
  // eslint-disable-next-line security/detect-non-literal-regexp
96
96
  const pattern = new RegExp(
97
- `^\\*?\\n \\* ${ locality } dependencies\\.?\\n $`,
98
- 'i',
97
+ `^\\*?\\n \\* ${locality} dependencies\\.?\\n $`,
98
+ 'i'
99
99
  );
100
- return pattern.test( value );
100
+ return pattern.test(value);
101
101
  }
102
102
 
103
103
  /**
@@ -109,12 +109,12 @@ module.exports = {
109
109
  *
110
110
  * @return {boolean} Whether node occurs before reference.
111
111
  */
112
- function isBefore( node, reference ) {
113
- if ( ! node.range || ! reference.range ) {
112
+ function isBefore(node, reference) {
113
+ if (!node.range || !reference.range) {
114
114
  return false;
115
115
  }
116
116
 
117
- return node.range[ 0 ] < reference.range[ 0 ];
117
+ return node.range[0] < reference.range[0];
118
118
  }
119
119
 
120
120
  /**
@@ -128,22 +128,22 @@ module.exports = {
128
128
  *
129
129
  * @return {WPDependencyBlockCorrection | undefined} Correction, if applicable.
130
130
  */
131
- function getDependencyBlockCorrection( node, locality ) {
132
- const value = getCommentValue( locality );
131
+ function getDependencyBlockCorrection(node, locality) {
132
+ const value = getCommentValue(locality);
133
133
 
134
- for ( const comment of comments ) {
135
- if ( ! isBefore( comment, node ) ) {
134
+ for (const comment of comments) {
135
+ if (!isBefore(comment, node)) {
136
136
  // Exhausted options.
137
137
  break;
138
138
  }
139
139
 
140
- if ( ! isLocalityDependencyBlock( comment, locality ) ) {
140
+ if (!isLocalityDependencyBlock(comment, locality)) {
141
141
  // Not usable (either not an block comment, or not one
142
142
  // matching a tolerable pattern).
143
143
  continue;
144
144
  }
145
145
 
146
- if ( comment.value === value ) {
146
+ if (comment.value === value) {
147
147
  // No change needed. (OK)
148
148
  return;
149
149
  }
@@ -159,7 +159,7 @@ module.exports = {
159
159
  /**
160
160
  * @param {import('estree').Program} node Program node.
161
161
  */
162
- Program( node ) {
162
+ Program(node) {
163
163
  /**
164
164
  * The set of package localities which have been reported for
165
165
  * the current program. Each locality is reported at most one
@@ -181,29 +181,25 @@ module.exports = {
181
181
  // Since we only care to enforce imports which occur at the
182
182
  // top-level scope, match on Program and test its children,
183
183
  // rather than matching the import nodes directly.
184
- node.body.forEach( ( child ) => {
184
+ node.body.forEach((child) => {
185
185
  /** @type {string} */
186
186
  let source;
187
- switch ( child.type ) {
187
+ switch (child.type) {
188
188
  case 'ImportDeclaration':
189
- source = /** @type {string} */ (
190
- child.source.value
191
- );
192
- candidates.push( [ child, source ] );
189
+ source = /** @type {string} */ (child.source.value);
190
+ candidates.push([child, source]);
193
191
  break;
194
192
 
195
193
  case 'VariableDeclaration':
196
- child.declarations.forEach( ( declaration ) => {
194
+ child.declarations.forEach((declaration) => {
197
195
  const { init } = declaration;
198
196
  if (
199
- ! init ||
197
+ !init ||
200
198
  init.type !== 'CallExpression' ||
201
- /** @type {import('estree').CallExpression} */ (
202
- init
203
- ).callee.type !== 'Identifier' ||
204
- /** @type {import('estree').Identifier} */ (
205
- init.callee
206
- ).name !== 'require'
199
+ /** @type {import('estree').CallExpression} */ (init).callee
200
+ .type !== 'Identifier' ||
201
+ /** @type {import('estree').Identifier} */ (init.callee)
202
+ .name !== 'require'
207
203
  ) {
208
204
  return;
209
205
  }
@@ -211,51 +207,45 @@ module.exports = {
211
207
  const { arguments: args } = init;
212
208
  if (
213
209
  args.length === 1 &&
214
- args[ 0 ].type === 'Literal' &&
215
- typeof args[ 0 ].value === 'string'
210
+ args[0].type === 'Literal' &&
211
+ typeof args[0].value === 'string'
216
212
  ) {
217
- source = args[ 0 ].value;
218
- candidates.push( [ child, source ] );
213
+ source = args[0].value;
214
+ candidates.push([child, source]);
219
215
  }
220
- } );
216
+ });
221
217
  }
222
- } );
218
+ });
223
219
 
224
- for ( const [ child, source ] of candidates ) {
225
- const locality = getPackageLocality( source );
226
- if ( verified.has( locality ) ) {
220
+ for (const [child, source] of candidates) {
221
+ const locality = getPackageLocality(source);
222
+ if (verified.has(locality)) {
227
223
  continue;
228
224
  }
229
225
 
230
226
  // Avoid verifying any other imports for the locality,
231
227
  // regardless whether a correction must be made.
232
- verified.add( locality );
228
+ verified.add(locality);
233
229
 
234
230
  // Determine whether a correction must be made.
235
- const correction = getDependencyBlockCorrection(
236
- child,
237
- locality,
238
- );
239
- if ( ! correction ) {
231
+ const correction = getDependencyBlockCorrection(child, locality);
232
+ if (!correction) {
240
233
  continue;
241
234
  }
242
235
 
243
- context.report( {
236
+ context.report({
244
237
  node: child,
245
- message: `Expected preceding "${ locality } dependencies" comment block`,
246
- fix( fixer ) {
238
+ message: `Expected preceding "${locality} dependencies" comment block`,
239
+ fix(fixer) {
247
240
  const { comment, value } = correction;
248
- const text = `/*${ value }*/`;
249
- if ( comment && comment.range ) {
250
- return fixer.replaceTextRange(
251
- comment.range,
252
- text,
253
- );
241
+ const text = `/*${value}*/`;
242
+ if (comment && comment.range) {
243
+ return fixer.replaceTextRange(comment.range, text);
254
244
  }
255
245
 
256
- return fixer.insertTextBefore( child, text + '\n' );
246
+ return fixer.insertTextBefore(child, text + '\n');
257
247
  },
258
- } );
248
+ });
259
249
  }
260
250
  },
261
251
  };
package/rules/index.js CHANGED
@@ -2,8 +2,8 @@
2
2
  * Custom ESLint rules
3
3
  */
4
4
  module.exports = {
5
- 'dependency-group': require( './dependency-group' ),
6
- 'no-async-foreach': require( './no-async-foreach' ),
7
- 'no-unguarded-get-range-at': require( './no-unguarded-get-range-at' ),
8
- 'no-unused-vars-before-return': require( './no-unused-vars-before-return' ),
5
+ 'dependency-group': require('./dependency-group'),
6
+ 'no-async-foreach': require('./no-async-foreach'),
7
+ 'no-unguarded-get-range-at': require('./no-unguarded-get-range-at'),
8
+ 'no-unused-vars-before-return': require('./no-unused-vars-before-return'),
9
9
  };
@@ -8,27 +8,25 @@
8
8
  */
9
9
 
10
10
  module.exports = {
11
- create( context ) {
11
+ create(context) {
12
12
  return {
13
- ExpressionStatement( node ) {
13
+ ExpressionStatement(node) {
14
14
  const { callee } = node.expression;
15
- if ( ! callee || ! callee.property || ! callee.property.name ) {
15
+ if (!callee || !callee.property || !callee.property.name) {
16
16
  return;
17
17
  }
18
- if ( callee.property.name === 'forEach' ) {
19
- const functionArguments = node.expression.arguments.find(
20
- ( exp ) => {
21
- return (
22
- exp.type === 'ArrowFunctionExpression' ||
23
- exp.type === 'FunctionExpression'
24
- );
25
- },
26
- );
27
- if ( functionArguments ) {
28
- if ( functionArguments.async ) {
18
+ if (callee.property.name === 'forEach') {
19
+ const functionArguments = node.expression.arguments.find((exp) => {
20
+ return (
21
+ exp.type === 'ArrowFunctionExpression' ||
22
+ exp.type === 'FunctionExpression'
23
+ );
24
+ });
25
+ if (functionArguments) {
26
+ if (functionArguments.async) {
29
27
  context.report(
30
28
  node,
31
- 'Avoid passing an async function to Array.prototype.forEach',
29
+ 'Avoid passing an async function to Array.prototype.forEach'
32
30
  );
33
31
  }
34
32
  }
@@ -8,15 +8,15 @@ module.exports = {
8
8
  type: 'problem',
9
9
  schema: [],
10
10
  },
11
- create( context ) {
11
+ create(context) {
12
12
  return {
13
13
  'CallExpression[callee.object.callee.property.name="getSelection"][callee.property.name="getRangeAt"]'(
14
- node,
14
+ node
15
15
  ) {
16
- context.report( {
16
+ context.report({
17
17
  node,
18
18
  message: 'Avoid unguarded getRangeAt',
19
- } );
19
+ });
20
20
  },
21
21
  };
22
22
  },
@@ -23,16 +23,16 @@ const FUNCTION_SCOPE_JSX_IDENTIFIERS = new WeakMap();
23
23
  *
24
24
  * @return {ESLintScope|undefined} Function scope, if known.
25
25
  */
26
- function getClosestFunctionScope( context ) {
26
+ function getClosestFunctionScope(context) {
27
27
  let functionScope = context.getScope();
28
- while ( functionScope.type !== 'function' && functionScope.upper ) {
28
+ while (functionScope.type !== 'function' && functionScope.upper) {
29
29
  functionScope = functionScope.upper;
30
30
  }
31
31
 
32
32
  return functionScope;
33
33
  }
34
34
 
35
- module.exports = /** @type {import('eslint').Rule} */ ( {
35
+ module.exports = /** @type {import('eslint').Rule} */ ({
36
36
  meta: {
37
37
  type: 'problem',
38
38
  schema: [
@@ -50,8 +50,8 @@ module.exports = /** @type {import('eslint').Rule} */ ( {
50
50
  /**
51
51
  * @param {ESLintRuleContext} context Rule context.
52
52
  */
53
- create( context ) {
54
- const options = context.options[ 0 ] || {};
53
+ create(context) {
54
+ const options = context.options[0] || {};
55
55
  const { excludePattern } = options;
56
56
 
57
57
  /**
@@ -65,41 +65,35 @@ module.exports = /** @type {import('eslint').Rule} */ ( {
65
65
  *
66
66
  * @return {boolean} Whether declarator is emempt from consideration.
67
67
  */
68
- function isExemptObjectDestructureDeclarator( node ) {
69
- return (
70
- node.id.type === 'ObjectPattern' &&
71
- node.id.properties.length > 1
72
- );
68
+ function isExemptObjectDestructureDeclarator(node) {
69
+ return node.id.type === 'ObjectPattern' && node.id.properties.length > 1;
73
70
  }
74
71
 
75
72
  return {
76
- JSXIdentifier( node ) {
73
+ JSXIdentifier(node) {
77
74
  // Currently, a scope's variable references does not include JSX
78
75
  // identifiers. Account for this by visiting JSX identifiers
79
76
  // first, and tracking them in a map per function scope, which
80
77
  // is later merged with the known variable references.
81
- const functionScope = getClosestFunctionScope( context );
82
- if ( ! functionScope ) {
78
+ const functionScope = getClosestFunctionScope(context);
79
+ if (!functionScope) {
83
80
  return;
84
81
  }
85
82
 
86
- if ( ! FUNCTION_SCOPE_JSX_IDENTIFIERS.has( functionScope ) ) {
87
- FUNCTION_SCOPE_JSX_IDENTIFIERS.set(
88
- functionScope,
89
- new Set(),
90
- );
83
+ if (!FUNCTION_SCOPE_JSX_IDENTIFIERS.has(functionScope)) {
84
+ FUNCTION_SCOPE_JSX_IDENTIFIERS.set(functionScope, new Set());
91
85
  }
92
86
 
93
- FUNCTION_SCOPE_JSX_IDENTIFIERS.get( functionScope ).add( node );
87
+ FUNCTION_SCOPE_JSX_IDENTIFIERS.get(functionScope).add(node);
94
88
  },
95
- 'ReturnStatement:exit'( node ) {
96
- const functionScope = getClosestFunctionScope( context );
97
- if ( ! functionScope ) {
89
+ 'ReturnStatement:exit'(node) {
90
+ const functionScope = getClosestFunctionScope(context);
91
+ if (!functionScope) {
98
92
  return;
99
93
  }
100
94
 
101
- for ( const variable of functionScope.variables ) {
102
- const declaratorCandidate = variable.defs.find( ( def ) => {
95
+ for (const variable of functionScope.variables) {
96
+ const declaratorCandidate = variable.defs.find((def) => {
103
97
  return (
104
98
  def.node.type === 'VariableDeclarator' &&
105
99
  // Allow declarations which are not initialized.
@@ -107,21 +101,21 @@ module.exports = /** @type {import('eslint').Rule} */ ( {
107
101
  // Target function calls as "expensive".
108
102
  def.node.init.type === 'CallExpression' &&
109
103
  // Allow unused if part of an object destructuring.
110
- ! isExemptObjectDestructureDeclarator( def.node ) &&
104
+ !isExemptObjectDestructureDeclarator(def.node) &&
111
105
  // Only target assignments preceding `return`.
112
- def.node.range[ 1 ] < node.range[ 1 ]
106
+ def.node.range[1] < node.range[1]
113
107
  );
114
- } );
108
+ });
115
109
 
116
- if ( ! declaratorCandidate ) {
110
+ if (!declaratorCandidate) {
117
111
  continue;
118
112
  }
119
113
 
120
114
  if (
121
115
  excludePattern !== undefined &&
122
116
  // eslint-disable-next-line security/detect-non-literal-regexp
123
- new RegExp( excludePattern ).test(
124
- declaratorCandidate.node.init.callee.name,
117
+ new RegExp(excludePattern).test(
118
+ declaratorCandidate.node.init.callee.name
125
119
  )
126
120
  ) {
127
121
  continue;
@@ -130,33 +124,32 @@ module.exports = /** @type {import('eslint').Rule} */ ( {
130
124
  // The first entry in `references` is the declaration
131
125
  // itself, which can be ignored.
132
126
  const identifiers = variable.references
133
- .slice( 1 )
134
- .map( ( reference ) => reference.identifier );
127
+ .slice(1)
128
+ .map((reference) => reference.identifier);
135
129
 
136
130
  // Merge with any JSX identifiers in scope, if any.
137
- if ( FUNCTION_SCOPE_JSX_IDENTIFIERS.has( functionScope ) ) {
131
+ if (FUNCTION_SCOPE_JSX_IDENTIFIERS.has(functionScope)) {
138
132
  const jsxIdentifiers =
139
- FUNCTION_SCOPE_JSX_IDENTIFIERS.get( functionScope );
133
+ FUNCTION_SCOPE_JSX_IDENTIFIERS.get(functionScope);
140
134
 
141
- identifiers.push( ...jsxIdentifiers );
135
+ identifiers.push(...jsxIdentifiers);
142
136
  }
143
137
 
144
138
  const isUsedBeforeReturn = identifiers.some(
145
- ( identifier ) =>
146
- identifier.range[ 1 ] < node.range[ 1 ],
139
+ (identifier) => identifier.range[1] < node.range[1]
147
140
  );
148
141
 
149
- if ( isUsedBeforeReturn ) {
142
+ if (isUsedBeforeReturn) {
150
143
  continue;
151
144
  }
152
145
 
153
146
  context.report(
154
147
  declaratorCandidate.node,
155
148
  'Variables should not be assigned until just prior its first reference. ' +
156
- 'An early return statement may leave this variable unused.',
149
+ 'An early return statement may leave this variable unused.'
157
150
  );
158
151
  }
159
152
  },
160
153
  };
161
154
  },
162
- } );
155
+ });
@@ -0,0 +1,7 @@
1
+ module.exports = function debugLog(message) {
2
+ if (process.env.DEBUG) {
3
+ // Debugging output.
4
+ // eslint-disable-next-line no-console
5
+ console.log(message);
6
+ }
7
+ };
@@ -0,0 +1,34 @@
1
+ const fs = require('node:fs');
2
+ const debugLog = require('./debug-log');
3
+ const findPackageJson = require('find-package-json');
4
+
5
+ function findParent() {
6
+ const packages = [...findPackageJson()];
7
+ const firstPackage = packages.shift();
8
+
9
+ // A little hack to help us use this plugin to lint itself: When installed via
10
+ // NPM, .eslintrc.js will be missing (due to .npmignore).
11
+ if ('@automattic/eslint-plugin-wpvip' === firstPackage.name) {
12
+ const eslintRc = firstPackage.__path.replace(
13
+ /package\.json$/,
14
+ '.eslintrc.js'
15
+ );
16
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
17
+ if (fs.statSync(eslintRc)) {
18
+ return firstPackage;
19
+ }
20
+ }
21
+
22
+ return packages.pop() || {};
23
+ }
24
+
25
+ const parent = findParent();
26
+
27
+ debugLog(`Found package.json: ${parent.__path || 'none'}`);
28
+
29
+ module.exports = function isPackageInstalled(packageName) {
30
+ const isDevDependency = !!parent.devDependencies?.[`${packageName}`];
31
+ const isProdDependency = !!parent.dependencies?.[`${packageName}`];
32
+
33
+ return isDevDependency || isProdDependency;
34
+ };
package/.eslintignore DELETED
@@ -1,2 +0,0 @@
1
- __fixtures__/**/allowed.*
2
- __fixtures__/**/disallowed.*
package/.eslintrc.js DELETED
@@ -1,17 +0,0 @@
1
- /**
2
- * Do not copy this .eslintrc for your project. See the README for instructions.
3
- */
4
-
5
- module.exports = {
6
- extends: [
7
- 'plugin:eslint-plugin/recommended', // linting for eslint plugins!
8
- 'plugin:@automattic/wpvip/base',
9
- 'plugin:@automattic/wpvip/formatting',
10
- 'plugin:@automattic/wpvip/testing',
11
- 'plugin:@automattic/wpvip/typescript',
12
- ],
13
- parserOptions: {
14
- project: './tsconfig.json',
15
- },
16
- root: true,
17
- };
package/.nvmrc DELETED
@@ -1 +0,0 @@
1
- 16
package/configs/base.js DELETED
@@ -1,7 +0,0 @@
1
- module.exports = {
2
- extends: [
3
- 'plugin:json/recommended',
4
- 'plugin:security/recommended',
5
- require.resolve( './javascript' ),
6
- ],
7
- };
package/tsconfig.json DELETED
@@ -1,30 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- // Allow JavaScript files as we migrate.
4
- "allowJs": true,
5
- "checkJs": false,
6
-
7
- // https://www.typescriptlang.org/tsconfig#isolatedModules
8
- "isolatedModules": true,
9
-
10
- // Custom output directory (Nest default is ./dist).
11
- "outDir": "./build",
12
-
13
- // Preserve comments in output.
14
- "removeComments": true,
15
-
16
- // Allow importing JSON files directly.
17
- "resolveJsonModule": true,
18
-
19
- // The options below come from the default Nest tsconfig, minus those that
20
- // are overridden above.
21
- "allowSyntheticDefaultImports": true,
22
- "baseUrl": ".",
23
- "declaration": true,
24
- "emitDecoratorMetadata": true,
25
- "experimentalDecorators": true,
26
- "incremental": true,
27
- "sourceMap": true,
28
- "strictNullChecks": true
29
- }
30
- }