@wordpress/eslint-plugin 18.1.0 → 19.0.1
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 +21 -20
- package/configs/custom.js +1 -0
- package/package.json +6 -6
- package/rules/__tests__/no-wp-process-env.js +62 -0
- package/rules/__tests__/wp-global-usage.js +129 -0
- package/rules/no-wp-process-env.js +93 -0
- package/rules/wp-global-usage.js +170 -0
- package/rules/__tests__/is-gutenberg-plugin.js +0 -65
- package/rules/gutenberg-phase.js +0 -174
- package/rules/is-gutenberg-plugin.js +0 -94
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Install the module
|
|
|
10
10
|
npm install @wordpress/eslint-plugin --save-dev
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
**Note**: This package requires
|
|
13
|
+
**Note**: This package requires Node.js version with long-term support status (check [Active LTS or Maintenance LTS releases](https://nodejs.org/en/about/previous-releases)). It is not compatible with older versions.
|
|
14
14
|
|
|
15
15
|
## Usage
|
|
16
16
|
|
|
@@ -69,25 +69,26 @@ The granular rulesets will not define any environment globals. As such, if they
|
|
|
69
69
|
|
|
70
70
|
### Rules
|
|
71
71
|
|
|
72
|
-
| Rule | Description
|
|
73
|
-
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
74
|
-
| [data-no-store-string-literals](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/data-no-store-string-literals.md) | Discourage passing string literals to reference data stores | |
|
|
75
|
-
| [dependency-group](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/dependency-group.md) | Enforce dependencies docblocks formatting | ✓ |
|
|
76
|
-
| [
|
|
77
|
-
| [
|
|
78
|
-
| [no-
|
|
79
|
-
| [no-
|
|
80
|
-
| [no-
|
|
81
|
-
| [
|
|
82
|
-
| [
|
|
83
|
-
| [i18n-
|
|
84
|
-
| [
|
|
85
|
-
| [
|
|
86
|
-
| [
|
|
87
|
-
| [
|
|
88
|
-
| [
|
|
89
|
-
| [
|
|
90
|
-
| [
|
|
72
|
+
| Rule | Description | Recommended |
|
|
73
|
+
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------- |
|
|
74
|
+
| [data-no-store-string-literals](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/data-no-store-string-literals.md) | Discourage passing string literals to reference data stores. | |
|
|
75
|
+
| [dependency-group](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/dependency-group.md) | Enforce dependencies docblocks formatting. | ✓ |
|
|
76
|
+
| [i18n-ellipsis](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-ellipsis.md) | Disallow using three dots in translatable strings. | ✓ |
|
|
77
|
+
| [i18n-hyphenated-range](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-hyphenated-range.md) | Disallow hyphenated numerical ranges in translatable strings. | |
|
|
78
|
+
| [i18n-no-collapsible-whitespace](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-no-collapsible-whitespace.md) | Disallow collapsible whitespace in translatable strings. | ✓ |
|
|
79
|
+
| [i18n-no-flanking-whitespace](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-no-flanking-whitespace.md) | Disallow leading or trailing whitespace in translatable strings. | |
|
|
80
|
+
| [i18n-no-placeholders-only](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-no-placeholders-only.md) | Prevent using only placeholders in translatable strings. | ✓ |
|
|
81
|
+
| [i18n-no-variables](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-no-variables.md) | Enforce string literals as translation function arguments. | ✓ |
|
|
82
|
+
| [i18n-text-domain](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-text-domain.md) | Enforce passing valid text domains. | ✓ |
|
|
83
|
+
| [i18n-translator-comments](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-translator-comments.md) | Enforce adding translator comments. | ✓ |
|
|
84
|
+
| [no-base-control-with-label-without-id](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-base-control-with-label-without-id.md) | Disallow the usage of BaseControl component with a label prop set but omitting the id property. | ✓ |
|
|
85
|
+
| [no-unguarded-get-range-at](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-unguarded-get-range-at.md) | Disallow the usage of unguarded `getRangeAt` calls. | ✓ |
|
|
86
|
+
| [no-unsafe-wp-apis](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-unsafe-wp-apis.md) | Disallow the usage of unsafe APIs from `@wordpress/*` packagesl | ✓ |
|
|
87
|
+
| [no-unused-vars-before-return](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md) | Disallow assigning variable values if unused before a return. | ✓ |
|
|
88
|
+
| [no-wp-process-env](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-wp-process-env.md) | Disallow legacy usage of WordPress variables via `process.env` like `process.env.SCRIPT_DEBUG`. | ✓ |
|
|
89
|
+
| [react-no-unsafe-timeout](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/react-no-unsafe-timeout.md) | Disallow unsafe `setTimeout` in component. | |
|
|
90
|
+
| [valid-sprintf](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/valid-sprintf.md) | Enforce valid sprintf usage. | ✓ |
|
|
91
|
+
| [wp-global-usage](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/wp-global-usage.md) | Enforce correct usage of WordPress globals like `globalThis.SCRIPT_DEBUG`. | |
|
|
91
92
|
|
|
92
93
|
### Legacy
|
|
93
94
|
|
package/configs/custom.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/eslint-plugin",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "19.0.1",
|
|
4
4
|
"description": "ESLint plugin for WordPress development.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"url": "https://github.com/WordPress/gutenberg/issues"
|
|
21
21
|
},
|
|
22
22
|
"engines": {
|
|
23
|
-
"node": ">=
|
|
24
|
-
"npm": ">=
|
|
23
|
+
"node": ">=18.12.0",
|
|
24
|
+
"npm": ">=8.19.2"
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
27
|
"configs",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"@babel/eslint-parser": "^7.16.0",
|
|
35
35
|
"@typescript-eslint/eslint-plugin": "^6.4.1",
|
|
36
36
|
"@typescript-eslint/parser": "^6.4.1",
|
|
37
|
-
"@wordpress/babel-preset-default": "^
|
|
38
|
-
"@wordpress/prettier-config": "^
|
|
37
|
+
"@wordpress/babel-preset-default": "^8.0.1",
|
|
38
|
+
"@wordpress/prettier-config": "^4.0.1",
|
|
39
39
|
"cosmiconfig": "^7.0.0",
|
|
40
40
|
"eslint-config-prettier": "^8.3.0",
|
|
41
41
|
"eslint-plugin-import": "^2.25.2",
|
|
@@ -66,5 +66,5 @@
|
|
|
66
66
|
"publishConfig": {
|
|
67
67
|
"access": "public"
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "0e973525f7787401b5a544e0727774d52a78639f"
|
|
70
70
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { RuleTester } from 'eslint';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import rule from '../no-wp-process-env';
|
|
10
|
+
|
|
11
|
+
const ruleTester = new RuleTester( {
|
|
12
|
+
parserOptions: {
|
|
13
|
+
ecmaVersion: 6,
|
|
14
|
+
},
|
|
15
|
+
} );
|
|
16
|
+
|
|
17
|
+
ruleTester.run( 'no-wp-process-env', rule, {
|
|
18
|
+
valid: [
|
|
19
|
+
{ code: 'process.env.NODE_ENV' },
|
|
20
|
+
{ code: 'process.env.WHATEVER' },
|
|
21
|
+
{ code: 'process.env[foo]' },
|
|
22
|
+
{ code: 'process.env["foo"]' },
|
|
23
|
+
{ code: `process['env']["foo"]` },
|
|
24
|
+
{ code: "process['env'][`foo`]" },
|
|
25
|
+
{ code: "process.env[`${ '' }IS_GUTENBERG_PLUGIN`]" },
|
|
26
|
+
{ code: `a.b.c` },
|
|
27
|
+
{ code: `x['y']['z']` },
|
|
28
|
+
{ code: `d[e][f]` },
|
|
29
|
+
{ code: `process[ (()=>'env')() ][ {_:'SCRIPT_DEBUG'}['_'] ]` },
|
|
30
|
+
],
|
|
31
|
+
invalid: [
|
|
32
|
+
{
|
|
33
|
+
code: 'process.env.IS_GUTENBERG_PLUGIN',
|
|
34
|
+
errors: [ { messageId: 'useGlobalThis' } ],
|
|
35
|
+
output: 'globalThis.IS_GUTENBERG_PLUGIN',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
code: 'process.env.SCRIPT_DEBUG',
|
|
39
|
+
errors: [ { messageId: 'useGlobalThis' } ],
|
|
40
|
+
output: 'globalThis.SCRIPT_DEBUG',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
code: 'process.env.IS_WORDPRESS_CORE',
|
|
44
|
+
errors: [ { messageId: 'useGlobalThis' } ],
|
|
45
|
+
output: 'globalThis.IS_WORDPRESS_CORE',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
code: `process['env']["IS_GUTENBERG_PLUGIN"]`,
|
|
49
|
+
errors: [ { messageId: 'useGlobalThis' } ],
|
|
50
|
+
output: 'globalThis.IS_GUTENBERG_PLUGIN',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
code: 'process[`env`][`IS_GUTENBERG_PLUGIN`]',
|
|
54
|
+
errors: [ { messageId: 'useGlobalThis' } ],
|
|
55
|
+
output: 'globalThis.IS_GUTENBERG_PLUGIN',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
code: 'process.env.GUTENBERG_PHASE',
|
|
59
|
+
errors: [ { messageId: 'noGutenbergPhase' } ],
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
} );
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { RuleTester } from 'eslint';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import rule from '../wp-global-usage';
|
|
10
|
+
|
|
11
|
+
const ruleTester = new RuleTester( {
|
|
12
|
+
parserOptions: {
|
|
13
|
+
ecmaVersion: 6,
|
|
14
|
+
},
|
|
15
|
+
} );
|
|
16
|
+
|
|
17
|
+
ruleTester.run( 'wp-global-usage', rule, {
|
|
18
|
+
valid: [
|
|
19
|
+
{ code: "const text = 'SCRIPT_DEBUG'" },
|
|
20
|
+
{ code: 'const config = { SCRIPT_DEBUG: true }' },
|
|
21
|
+
{ code: 'if ( globalThis.IS_GUTENBERG_PLUGIN ) {}' },
|
|
22
|
+
{ code: 'if ( globalThis.IS_WORDPRESS_CORE ) {}' },
|
|
23
|
+
{ code: 'if ( globalThis.SCRIPT_DEBUG ) {}' },
|
|
24
|
+
{ code: 'if ( process.env.SCRIPT_DEBUG ) {}' },
|
|
25
|
+
{ code: 'if ( ! globalThis.IS_GUTENBERG_PLUGIN ) {}' },
|
|
26
|
+
{
|
|
27
|
+
// Ensure whitespace is ok.
|
|
28
|
+
code: `if (
|
|
29
|
+
globalThis.
|
|
30
|
+
IS_GUTENBERG_PLUGIN
|
|
31
|
+
) {}`,
|
|
32
|
+
},
|
|
33
|
+
{ code: 'const test = globalThis.IS_GUTENBERG_PLUGIN ? foo : bar' },
|
|
34
|
+
{ code: 'const test = ! globalThis.IS_GUTENBERG_PLUGIN ? bar : foo' },
|
|
35
|
+
{
|
|
36
|
+
// Ensure whitespace is ok.
|
|
37
|
+
code: `const test = ! globalThis.
|
|
38
|
+
IS_GUTENBERG_PLUGIN ? bar : foo`,
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
invalid: [
|
|
42
|
+
{
|
|
43
|
+
code: 'if ( IS_GUTENBERG_PLUGIN ) {}',
|
|
44
|
+
errors: [
|
|
45
|
+
{
|
|
46
|
+
messageId: 'usedWithoutGlobalThis',
|
|
47
|
+
data: { name: 'IS_GUTENBERG_PLUGIN' },
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
output: 'if ( globalThis.IS_GUTENBERG_PLUGIN ) {}',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
code: 'if ( window.IS_GUTENBERG_PLUGIN ) {}',
|
|
54
|
+
errors: [
|
|
55
|
+
{
|
|
56
|
+
messageId: 'usedWithoutGlobalThis',
|
|
57
|
+
data: { name: 'IS_GUTENBERG_PLUGIN' },
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
output: 'if ( globalThis.IS_GUTENBERG_PLUGIN ) {}',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
code: 'if ( SCRIPT_DEBUG ) {}',
|
|
64
|
+
errors: [
|
|
65
|
+
{
|
|
66
|
+
messageId: 'usedWithoutGlobalThis',
|
|
67
|
+
data: { name: 'SCRIPT_DEBUG' },
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
output: 'if ( globalThis.SCRIPT_DEBUG ) {}',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
code: 'if ( IS_WORDPRESS_CORE ) {}',
|
|
74
|
+
errors: [
|
|
75
|
+
{
|
|
76
|
+
messageId: 'usedWithoutGlobalThis',
|
|
77
|
+
data: { name: 'IS_WORDPRESS_CORE' },
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
output: 'if ( globalThis.IS_WORDPRESS_CORE ) {}',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
code: "if ( window[ 'IS_GUTENBERG_PLUGIN' ] ) {}",
|
|
84
|
+
errors: [
|
|
85
|
+
{
|
|
86
|
+
messageId: 'usedWithoutGlobalThis',
|
|
87
|
+
data: { name: 'IS_GUTENBERG_PLUGIN' },
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
output: 'if ( globalThis.IS_GUTENBERG_PLUGIN ) {}',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
code: 'if ( true ) { globalThis.IS_GUTENBERG_PLUGIN === 2 }',
|
|
94
|
+
errors: [
|
|
95
|
+
{
|
|
96
|
+
messageId: 'usedOutsideConditional',
|
|
97
|
+
data: { name: 'IS_GUTENBERG_PLUGIN' },
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
code: 'if ( globalThis.IS_GUTENBERG_PLUGIN === 2 ) {}',
|
|
103
|
+
errors: [
|
|
104
|
+
{
|
|
105
|
+
messageId: 'usedOutsideConditional',
|
|
106
|
+
data: { name: 'IS_GUTENBERG_PLUGIN' },
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
code: 'if ( true || globalThis.IS_GUTENBERG_PLUGIN === 2 ) {}',
|
|
112
|
+
errors: [
|
|
113
|
+
{
|
|
114
|
+
messageId: 'usedOutsideConditional',
|
|
115
|
+
data: { name: 'IS_GUTENBERG_PLUGIN' },
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
code: 'const isFeatureActive = globalThis.IS_GUTENBERG_PLUGIN;',
|
|
121
|
+
errors: [
|
|
122
|
+
{
|
|
123
|
+
messageId: 'usedOutsideConditional',
|
|
124
|
+
data: { name: 'IS_GUTENBERG_PLUGIN' },
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
} );
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const NAMES = new Set(
|
|
2
|
+
/** @type {const} */ ( [
|
|
3
|
+
'GUTENBERG_PHASE',
|
|
4
|
+
'IS_GUTENBERG_PLUGIN',
|
|
5
|
+
'IS_WORDPRESS_CORE',
|
|
6
|
+
'SCRIPT_DEBUG',
|
|
7
|
+
] )
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
/** @type {import('eslint').Rule.RuleModule} */
|
|
11
|
+
module.exports = {
|
|
12
|
+
meta: {
|
|
13
|
+
type: 'problem',
|
|
14
|
+
schema: [],
|
|
15
|
+
fixable: true,
|
|
16
|
+
messages: {
|
|
17
|
+
useGlobalThis:
|
|
18
|
+
'`{{ name }}` should not be accessed from process.env. Use `globalThis.{{name}}`.',
|
|
19
|
+
noGutenbergPhase:
|
|
20
|
+
'The GUTENBERG_PHASE environement variable is no longer available. Use IS_GUTENBERG_PLUGIN (boolean).',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
create( context ) {
|
|
24
|
+
return {
|
|
25
|
+
MemberExpression( node ) {
|
|
26
|
+
const propertyNameOrValue = memberProperty( node );
|
|
27
|
+
if ( ! propertyNameOrValue ) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if ( ! NAMES.has( propertyNameOrValue ) ) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if ( node.object.type !== 'MemberExpression' ) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const obj = node.object;
|
|
39
|
+
const envCandidateProperty = memberProperty( obj );
|
|
40
|
+
if ( envCandidateProperty !== 'env' ) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (
|
|
45
|
+
obj.object.type !== 'Identifier' ||
|
|
46
|
+
obj.object.name !== 'process'
|
|
47
|
+
) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if ( propertyNameOrValue === 'GUTENBERG_PHASE' ) {
|
|
52
|
+
context.report( {
|
|
53
|
+
node,
|
|
54
|
+
messageId: 'noGutenbergPhase',
|
|
55
|
+
} );
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
context.report( {
|
|
60
|
+
node,
|
|
61
|
+
messageId: 'useGlobalThis',
|
|
62
|
+
data: { name: propertyNameOrValue },
|
|
63
|
+
fix( fixer ) {
|
|
64
|
+
return fixer.replaceText(
|
|
65
|
+
node,
|
|
66
|
+
`globalThis.${ propertyNameOrValue }`
|
|
67
|
+
);
|
|
68
|
+
},
|
|
69
|
+
} );
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @param {import('estree').MemberExpression} node
|
|
77
|
+
*/
|
|
78
|
+
function memberProperty( node ) {
|
|
79
|
+
switch ( node.property.type ) {
|
|
80
|
+
case 'Identifier':
|
|
81
|
+
return node.property.name;
|
|
82
|
+
case 'Literal':
|
|
83
|
+
return node.property.value;
|
|
84
|
+
case 'TemplateLiteral':
|
|
85
|
+
if (
|
|
86
|
+
! node.property.expressions.length &&
|
|
87
|
+
node.property.quasis.length === 1
|
|
88
|
+
) {
|
|
89
|
+
return node.property.quasis[ 0 ].value.raw;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
const NAMES = new Set(
|
|
2
|
+
/** @type {const} */ ( [
|
|
3
|
+
'IS_GUTENBERG_PLUGIN',
|
|
4
|
+
'IS_WORDPRESS_CORE',
|
|
5
|
+
'SCRIPT_DEBUG',
|
|
6
|
+
] )
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Tests whether the IS_GUTENBERG_PLUGIN variable is used as the condition for an
|
|
11
|
+
* if statement or ternary, triggering a violation if not.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```js
|
|
15
|
+
* // good
|
|
16
|
+
* if ( process.env.IS_GUTENBERG_PLUGIN ) {
|
|
17
|
+
*
|
|
18
|
+
* // bad
|
|
19
|
+
* const isFeatureActive = process.env.IS_GUTENBERG_PLUGIN;
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @param {import('estree').Node} node The IS_GUTENBERG_PLUGIN identifier node.
|
|
23
|
+
*/
|
|
24
|
+
function isUsedInConditional( node ) {
|
|
25
|
+
/** @type {import('estree').Node|undefined} */
|
|
26
|
+
let current = node;
|
|
27
|
+
|
|
28
|
+
// Simple negation is the only expresion allowed in the conditional:
|
|
29
|
+
// if ( ! globalThis.SCRIPT_DEBUG ) {}
|
|
30
|
+
// const D = ! globalThis.SCRIPT_DEBUG ? 'yes' : 'no';
|
|
31
|
+
if (
|
|
32
|
+
current.parent.type === 'UnaryExpression' &&
|
|
33
|
+
current.parent.operator === '!'
|
|
34
|
+
) {
|
|
35
|
+
current = current.parent;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Check if the current node is the test of a conditional
|
|
39
|
+
|
|
40
|
+
/** @type {import('estree').Node|undefined} */
|
|
41
|
+
const parent = current.parent;
|
|
42
|
+
|
|
43
|
+
if ( parent.type === 'IfStatement' && parent.test === current ) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
if ( parent.type === 'ConditionalExpression' && parent.test === current ) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** @type {import('eslint').Rule.RuleModule} */
|
|
53
|
+
module.exports = {
|
|
54
|
+
meta: {
|
|
55
|
+
type: 'problem',
|
|
56
|
+
schema: [],
|
|
57
|
+
fixable: true,
|
|
58
|
+
messages: {
|
|
59
|
+
usedOutsideConditional:
|
|
60
|
+
'`globalThis.{{ name }}` should only be used as the condition in an if statement or ternary expression.',
|
|
61
|
+
usedWithoutGlobalThis:
|
|
62
|
+
'`{{ name }}` should not be used directly. Use `globalThis.{{ name }}`.',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
create( context ) {
|
|
66
|
+
return {
|
|
67
|
+
Identifier( node ) {
|
|
68
|
+
// Bypass any identifiers with a node name different to `IS_GUTENBERG_PLUGIN`.
|
|
69
|
+
if ( ! NAMES.has( node.name ) ) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if ( node.parent.type === 'Property' ) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if ( node.parent.type !== 'MemberExpression' ) {
|
|
78
|
+
context.report( {
|
|
79
|
+
node,
|
|
80
|
+
messageId: 'usedWithoutGlobalThis',
|
|
81
|
+
data: { name: node.name },
|
|
82
|
+
fix( fixer ) {
|
|
83
|
+
return fixer.replaceText(
|
|
84
|
+
node,
|
|
85
|
+
`globalThis.${ node.name }`
|
|
86
|
+
);
|
|
87
|
+
},
|
|
88
|
+
} );
|
|
89
|
+
|
|
90
|
+
if ( ! isUsedInConditional( node ) ) {
|
|
91
|
+
context.report( {
|
|
92
|
+
node,
|
|
93
|
+
messageId: 'usedOutsideConditional',
|
|
94
|
+
data: {
|
|
95
|
+
name: node.name,
|
|
96
|
+
},
|
|
97
|
+
} );
|
|
98
|
+
}
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (
|
|
103
|
+
node.parent.object.type === 'Identifier' &&
|
|
104
|
+
node.parent.object.name !== 'globalThis'
|
|
105
|
+
) {
|
|
106
|
+
context.report( {
|
|
107
|
+
node,
|
|
108
|
+
messageId: 'usedWithoutGlobalThis',
|
|
109
|
+
data: { name: node.name },
|
|
110
|
+
fix( fixer ) {
|
|
111
|
+
if ( node.parent.object.name === 'window' ) {
|
|
112
|
+
return fixer.replaceText(
|
|
113
|
+
node.parent,
|
|
114
|
+
`globalThis.${ node.name }`
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
} );
|
|
119
|
+
} else if ( ! isUsedInConditional( node.parent ) ) {
|
|
120
|
+
context.report( {
|
|
121
|
+
node,
|
|
122
|
+
messageId: 'usedOutsideConditional',
|
|
123
|
+
data: {
|
|
124
|
+
name: node.name,
|
|
125
|
+
},
|
|
126
|
+
} );
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
// Check for literals, e.g. when 'IS_GUTENBERG_PLUGIN' is used as a string via something like 'window[ 'IS_GUTENBERG_PLUGIN' ]'.
|
|
131
|
+
Literal( node ) {
|
|
132
|
+
// Bypass any identifiers with a node value different to `IS_GUTENBERG_PLUGIN`.
|
|
133
|
+
if ( ! NAMES.has( node.value ) ) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if ( node.parent.type !== 'MemberExpression' ) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (
|
|
142
|
+
node.parent.object.type === 'Identifier' &&
|
|
143
|
+
node.parent.object.name !== 'globalThis'
|
|
144
|
+
) {
|
|
145
|
+
context.report( {
|
|
146
|
+
node,
|
|
147
|
+
messageId: 'usedWithoutGlobalThis',
|
|
148
|
+
data: { name: node.value },
|
|
149
|
+
fix( fixer ) {
|
|
150
|
+
if ( node.parent.object.name === 'window' ) {
|
|
151
|
+
return fixer.replaceText(
|
|
152
|
+
node.parent,
|
|
153
|
+
`globalThis.${ node.value }`
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
} );
|
|
158
|
+
} else if ( ! isUsedInConditional( node.parent ) ) {
|
|
159
|
+
context.report( {
|
|
160
|
+
node,
|
|
161
|
+
messageId: 'usedOutsideConditional',
|
|
162
|
+
data: {
|
|
163
|
+
name: node.value,
|
|
164
|
+
},
|
|
165
|
+
} );
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
},
|
|
170
|
+
};
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { RuleTester } from 'eslint';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Internal dependencies
|
|
8
|
-
*/
|
|
9
|
-
import rule from '../is-gutenberg-plugin';
|
|
10
|
-
|
|
11
|
-
const ruleTester = new RuleTester( {
|
|
12
|
-
parserOptions: {
|
|
13
|
-
ecmaVersion: 6,
|
|
14
|
-
},
|
|
15
|
-
} );
|
|
16
|
-
|
|
17
|
-
const ERROR_MESSAGE =
|
|
18
|
-
'The `process.env.IS_GUTENBERG_PLUGIN` constant should only be used as the condition in an if statement or ternary expression.';
|
|
19
|
-
|
|
20
|
-
ruleTester.run( 'is-gutenberg-plugin', rule, {
|
|
21
|
-
valid: [
|
|
22
|
-
{ code: `if ( process.env.IS_GUTENBERG_PLUGIN ) {}` },
|
|
23
|
-
{ code: `if ( ! process.env.IS_GUTENBERG_PLUGIN ) {}` },
|
|
24
|
-
{
|
|
25
|
-
// Ensure whitespace is ok.
|
|
26
|
-
code: `if (
|
|
27
|
-
process.env.
|
|
28
|
-
IS_GUTENBERG_PLUGIN
|
|
29
|
-
) {}`,
|
|
30
|
-
},
|
|
31
|
-
{ code: `const test = process.env.IS_GUTENBERG_PLUGIN ? foo : bar` },
|
|
32
|
-
{ code: `const test = ! process.env.IS_GUTENBERG_PLUGIN ? bar : foo` },
|
|
33
|
-
{
|
|
34
|
-
// Ensure whitespace is ok.
|
|
35
|
-
code: `const test = ! process.env.
|
|
36
|
-
IS_GUTENBERG_PLUGIN ? bar : foo`,
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
invalid: [
|
|
40
|
-
{
|
|
41
|
-
code: `if ( IS_GUTENBERG_PLUGIN ) {}`,
|
|
42
|
-
errors: [ { message: ERROR_MESSAGE } ],
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
code: `if ( window[ 'IS_GUTENBERG_PLUGIN' ] ) {}`,
|
|
46
|
-
errors: [ { message: ERROR_MESSAGE } ],
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
code: `if ( true ) { process.env.IS_GUTENBERG_PLUGIN === 2 }`,
|
|
50
|
-
errors: [ { message: ERROR_MESSAGE } ],
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
code: `if ( process.env.IS_GUTENBERG_PLUGIN === 2 ) {}`,
|
|
54
|
-
errors: [ { message: ERROR_MESSAGE } ],
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
code: `if ( true || process.env.IS_GUTENBERG_PLUGIN === 2 ) {}`,
|
|
58
|
-
errors: [ { message: ERROR_MESSAGE } ],
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
code: `const isFeatureActive = process.env.IS_GUTENBERG_PLUGIN;`,
|
|
62
|
-
errors: [ { message: ERROR_MESSAGE } ],
|
|
63
|
-
},
|
|
64
|
-
],
|
|
65
|
-
} );
|
package/rules/gutenberg-phase.js
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Traverse up through the chain of parent AST nodes returning the first parent
|
|
3
|
-
* the predicate returns a truthy value for.
|
|
4
|
-
*
|
|
5
|
-
* @param {Object} sourceNode The AST node to search from.
|
|
6
|
-
* @param {Function} predicate A predicate invoked for each parent.
|
|
7
|
-
*
|
|
8
|
-
* @return {Object | undefined} The first encountered parent node where the predicate
|
|
9
|
-
* returns a truthy value.
|
|
10
|
-
*/
|
|
11
|
-
function findParent( sourceNode, predicate ) {
|
|
12
|
-
if ( ! sourceNode.parent ) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if ( predicate( sourceNode.parent ) ) {
|
|
17
|
-
return sourceNode.parent;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return findParent( sourceNode.parent, predicate );
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Tests whether the GUTENBERG_PHASE variable is accessed via
|
|
25
|
-
* `process.env.GUTENBERG_PHASE`.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```js
|
|
29
|
-
* // good
|
|
30
|
-
* if ( process.env.GUTENBERG_PHASE === 2 ) {
|
|
31
|
-
*
|
|
32
|
-
* // bad
|
|
33
|
-
* if ( GUTENBERG_PHASE === 2 ) {
|
|
34
|
-
* ```
|
|
35
|
-
*
|
|
36
|
-
* @param {Object} node The GUTENBERG_PHASE identifier node.
|
|
37
|
-
* @param {Object} context The eslint context object.
|
|
38
|
-
*/
|
|
39
|
-
function testIsAccessedViaProcessEnv( node, context ) {
|
|
40
|
-
const parent = node.parent;
|
|
41
|
-
|
|
42
|
-
if (
|
|
43
|
-
parent &&
|
|
44
|
-
parent.type === 'MemberExpression' &&
|
|
45
|
-
context.getSource( parent ) === 'process.env.GUTENBERG_PHASE'
|
|
46
|
-
) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
context.report(
|
|
51
|
-
node,
|
|
52
|
-
'The `GUTENBERG_PHASE` constant should be accessed using `process.env.GUTENBERG_PHASE`.'
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Tests whether the GUTENBERG_PHASE variable is used in a strict binary
|
|
58
|
-
* equality expression in a comparison with a number, triggering a
|
|
59
|
-
* violation if not.
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
* ```js
|
|
63
|
-
* // good
|
|
64
|
-
* if ( process.env.GUTENBERG_PHASE === 2 ) {
|
|
65
|
-
*
|
|
66
|
-
* // bad
|
|
67
|
-
* if ( process.env.GUTENBERG_PHASE >= '2' ) {
|
|
68
|
-
* ```
|
|
69
|
-
*
|
|
70
|
-
* @param {Object} node The GUTENBERG_PHASE identifier node.
|
|
71
|
-
* @param {Object} context The eslint context object.
|
|
72
|
-
*/
|
|
73
|
-
function testIsUsedInStrictBinaryExpression( node, context ) {
|
|
74
|
-
const parent = findParent(
|
|
75
|
-
node,
|
|
76
|
-
( candidate ) => candidate.type === 'BinaryExpression'
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
if ( parent ) {
|
|
80
|
-
const comparisonNode =
|
|
81
|
-
node.parent.type === 'MemberExpression' ? node.parent : node;
|
|
82
|
-
|
|
83
|
-
// Test for process.env.GUTENBERG_PHASE === <number> or <number> === process.env.GUTENBERG_PHASE.
|
|
84
|
-
const hasCorrectOperator = [ '===', '!==' ].includes( parent.operator );
|
|
85
|
-
const hasCorrectOperands =
|
|
86
|
-
( parent.left === comparisonNode &&
|
|
87
|
-
typeof parent.right.value === 'number' ) ||
|
|
88
|
-
( parent.right === comparisonNode &&
|
|
89
|
-
typeof parent.left.value === 'number' );
|
|
90
|
-
|
|
91
|
-
if ( hasCorrectOperator && hasCorrectOperands ) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
context.report(
|
|
97
|
-
node,
|
|
98
|
-
'The `GUTENBERG_PHASE` constant should only be used in a strict equality comparison with a primitive number.'
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Tests whether the GUTENBERG_PHASE variable is used as the condition for an
|
|
104
|
-
* if statement, triggering a violation if not.
|
|
105
|
-
*
|
|
106
|
-
* @example
|
|
107
|
-
* ```js
|
|
108
|
-
* // good
|
|
109
|
-
* if ( process.env.GUTENBERG_PHASE === 2 ) {
|
|
110
|
-
*
|
|
111
|
-
* // bad
|
|
112
|
-
* const isFeatureActive = process.env.GUTENBERG_PHASE === 2;
|
|
113
|
-
* ```
|
|
114
|
-
*
|
|
115
|
-
* @param {Object} node The GUTENBERG_PHASE identifier node.
|
|
116
|
-
* @param {Object} context The eslint context object.
|
|
117
|
-
*/
|
|
118
|
-
function testIsUsedInIfOrTernary( node, context ) {
|
|
119
|
-
const conditionalParent = findParent( node, ( candidate ) =>
|
|
120
|
-
[ 'IfStatement', 'ConditionalExpression' ].includes( candidate.type )
|
|
121
|
-
);
|
|
122
|
-
const binaryParent = findParent(
|
|
123
|
-
node,
|
|
124
|
-
( candidate ) => candidate.type === 'BinaryExpression'
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
if (
|
|
128
|
-
conditionalParent &&
|
|
129
|
-
binaryParent &&
|
|
130
|
-
conditionalParent.test &&
|
|
131
|
-
conditionalParent.test.range[ 0 ] === binaryParent.range[ 0 ] &&
|
|
132
|
-
conditionalParent.test.range[ 1 ] === binaryParent.range[ 1 ]
|
|
133
|
-
) {
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
context.report(
|
|
138
|
-
node,
|
|
139
|
-
'The `GUTENBERG_PHASE` constant should only be used as part of the condition in an if statement or ternary expression.'
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
module.exports = {
|
|
144
|
-
meta: {
|
|
145
|
-
type: 'problem',
|
|
146
|
-
schema: [],
|
|
147
|
-
deprecated: true,
|
|
148
|
-
replacedBy: '@wordpress/is-gutenberg-plugin',
|
|
149
|
-
},
|
|
150
|
-
create( context ) {
|
|
151
|
-
return {
|
|
152
|
-
Identifier( node ) {
|
|
153
|
-
// Bypass any identifiers with a node name different to `GUTENBERG_PHASE`.
|
|
154
|
-
if ( node.name !== 'GUTENBERG_PHASE' ) {
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
testIsAccessedViaProcessEnv( node, context );
|
|
159
|
-
testIsUsedInStrictBinaryExpression( node, context );
|
|
160
|
-
testIsUsedInIfOrTernary( node, context );
|
|
161
|
-
},
|
|
162
|
-
Literal( node ) {
|
|
163
|
-
// Bypass any identifiers with a node value different to `GUTENBERG_PHASE`.
|
|
164
|
-
if ( node.value !== 'GUTENBERG_PHASE' ) {
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if ( node.parent && node.parent.type === 'MemberExpression' ) {
|
|
169
|
-
testIsAccessedViaProcessEnv( node, context );
|
|
170
|
-
}
|
|
171
|
-
},
|
|
172
|
-
};
|
|
173
|
-
},
|
|
174
|
-
};
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Traverse up through the chain of parent AST nodes returning the first parent
|
|
3
|
-
* the predicate returns a truthy value for.
|
|
4
|
-
*
|
|
5
|
-
* @param {Object} sourceNode The AST node to search from.
|
|
6
|
-
* @param {Function} predicate A predicate invoked for each parent.
|
|
7
|
-
*
|
|
8
|
-
* @return {Object | undefined} The first encountered parent node where the predicate
|
|
9
|
-
* returns a truthy value.
|
|
10
|
-
*/
|
|
11
|
-
function findParent( sourceNode, predicate ) {
|
|
12
|
-
if ( ! sourceNode.parent ) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if ( predicate( sourceNode.parent ) ) {
|
|
17
|
-
return sourceNode.parent;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return findParent( sourceNode.parent, predicate );
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Tests whether the IS_GUTENBERG_PLUGIN variable is used as the condition for an
|
|
25
|
-
* if statement or ternary, triggering a violation if not.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```js
|
|
29
|
-
* // good
|
|
30
|
-
* if ( process.env.IS_GUTENBERG_PLUGIN ) {
|
|
31
|
-
*
|
|
32
|
-
* // bad
|
|
33
|
-
* const isFeatureActive = process.env.IS_GUTENBERG_PLUGIN;
|
|
34
|
-
* ```
|
|
35
|
-
*
|
|
36
|
-
* @param {Object} node The IS_GUTENBERG_PLUGIN identifier node.
|
|
37
|
-
* @param {Object} context The eslint context object.
|
|
38
|
-
*/
|
|
39
|
-
function isUsedInConditional( node, context ) {
|
|
40
|
-
const conditionalParent = findParent( node, ( candidate ) =>
|
|
41
|
-
[ 'IfStatement', 'ConditionalExpression' ].includes( candidate.type )
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
if ( ! conditionalParent ) {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Allow for whitespace as prettier sometimes breaks this on separate lines.
|
|
49
|
-
const textRegex = /^\s*!?\s*process\s*\.\s*env\s*\.\s*IS_GUTENBERG_PLUGIN$/;
|
|
50
|
-
const testSource = context.getSource( conditionalParent.test );
|
|
51
|
-
|
|
52
|
-
if ( ! textRegex.test( testSource ) ) {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const ERROR_MESSAGE =
|
|
60
|
-
'The `process.env.IS_GUTENBERG_PLUGIN` constant should only be used as the condition in an if statement or ternary expression.';
|
|
61
|
-
|
|
62
|
-
module.exports = {
|
|
63
|
-
meta: {
|
|
64
|
-
type: 'problem',
|
|
65
|
-
schema: [],
|
|
66
|
-
},
|
|
67
|
-
create( context ) {
|
|
68
|
-
return {
|
|
69
|
-
Identifier( node ) {
|
|
70
|
-
// Bypass any identifiers with a node name different to `IS_GUTENBERG_PLUGIN`.
|
|
71
|
-
if ( node.name !== 'IS_GUTENBERG_PLUGIN' ) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if ( ! isUsedInConditional( node, context ) ) {
|
|
76
|
-
context.report( node, ERROR_MESSAGE );
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
// Check for literals, e.g. when 'IS_GUTENBERG_PLUGIN' is used as a string via something like 'window[ 'IS_GUTENBERG_PLUGIN' ]'.
|
|
80
|
-
Literal( node ) {
|
|
81
|
-
// Bypass any identifiers with a node value different to `IS_GUTENBERG_PLUGIN`.
|
|
82
|
-
if ( node.value !== 'IS_GUTENBERG_PLUGIN' ) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if ( node.parent && node.parent.type === 'MemberExpression' ) {
|
|
87
|
-
if ( ! isUsedInConditional( node, context ) ) {
|
|
88
|
-
context.report( node, ERROR_MESSAGE );
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
};
|
|
93
|
-
},
|
|
94
|
-
};
|