@sgfe/eslint-plugin-sg 1.0.3

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.

Potentially problematic release.


This version of @sgfe/eslint-plugin-sg might be problematic. Click here for more details.

Files changed (39) hide show
  1. package/LICENSE.md +25 -0
  2. package/README.md +188 -0
  3. package/configs/all-type-checked.js +10 -0
  4. package/configs/all.js +11 -0
  5. package/configs/recommended.js +11 -0
  6. package/configs/rules-recommended.js +11 -0
  7. package/configs/rules.js +11 -0
  8. package/configs/tests-recommended.js +11 -0
  9. package/configs/tests.js +11 -0
  10. package/lib/index.js +90 -0
  11. package/lib/rules/consistent-output.js +70 -0
  12. package/lib/rules/fixer-return.js +170 -0
  13. package/lib/rules/meta-property-ordering.js +108 -0
  14. package/lib/rules/no-deprecated-context-methods.js +98 -0
  15. package/lib/rules/no-deprecated-report-api.js +83 -0
  16. package/lib/rules/no-identical-tests.js +87 -0
  17. package/lib/rules/no-missing-message-ids.js +101 -0
  18. package/lib/rules/no-missing-placeholders.js +131 -0
  19. package/lib/rules/no-only-tests.js +99 -0
  20. package/lib/rules/no-property-in-node.js +86 -0
  21. package/lib/rules/no-unused-message-ids.js +139 -0
  22. package/lib/rules/no-unused-placeholders.js +127 -0
  23. package/lib/rules/no-useless-token-range.js +174 -0
  24. package/lib/rules/prefer-message-ids.js +109 -0
  25. package/lib/rules/prefer-object-rule.js +83 -0
  26. package/lib/rules/prefer-output-null.js +77 -0
  27. package/lib/rules/prefer-placeholders.js +102 -0
  28. package/lib/rules/prefer-replace-text.js +91 -0
  29. package/lib/rules/report-message-format.js +133 -0
  30. package/lib/rules/require-meta-docs-description.js +110 -0
  31. package/lib/rules/require-meta-docs-url.js +175 -0
  32. package/lib/rules/require-meta-fixable.js +137 -0
  33. package/lib/rules/require-meta-has-suggestions.js +168 -0
  34. package/lib/rules/require-meta-schema.js +162 -0
  35. package/lib/rules/require-meta-type.js +77 -0
  36. package/lib/rules/test-case-property-ordering.js +107 -0
  37. package/lib/rules/test-case-shorthand-strings.js +124 -0
  38. package/lib/utils.js +936 -0
  39. package/package.json +76 -0
@@ -0,0 +1,110 @@
1
+ 'use strict';
2
+
3
+ const { getStaticValue } = require('eslint-utils');
4
+ const utils = require('../utils');
5
+
6
+ // ------------------------------------------------------------------------------
7
+ // Rule Definition
8
+ // ------------------------------------------------------------------------------
9
+
10
+ const DEFAULT_PATTERN = new RegExp('^(enforce|require|disallow)');
11
+
12
+ /** @type {import('eslint').Rule.RuleModule} */
13
+ module.exports = {
14
+ meta: {
15
+ type: 'suggestion',
16
+ docs: {
17
+ description:
18
+ 'require rules to implement a `meta.docs.description` property with the correct format',
19
+ category: 'Rules',
20
+ recommended: false,
21
+ url: 'https://github.com/eslint-community/eslint-plugin-eslint-plugin/tree/HEAD/docs/rules/require-meta-docs-description.md',
22
+ },
23
+ fixable: null,
24
+ schema: [
25
+ {
26
+ type: 'object',
27
+ properties: {
28
+ pattern: {
29
+ type: 'string',
30
+ description:
31
+ "A regular expression that the description must match. Use `'.+'` to allow anything.",
32
+ default: '^(enforce|require|disallow)',
33
+ },
34
+ },
35
+ additionalProperties: false,
36
+ },
37
+ ],
38
+ messages: {
39
+ extraWhitespace:
40
+ '`meta.docs.description` must not have leading nor trailing whitespace.',
41
+ mismatch: '`meta.docs.description` must match the regexp {{pattern}}.',
42
+ missing: '`meta.docs.description` is required.',
43
+ wrongType: '`meta.docs.description` must be a non-empty string.',
44
+ },
45
+ },
46
+
47
+ create(context) {
48
+ const sourceCode = context.sourceCode || context.getSourceCode(); // TODO: just use context.sourceCode when dropping eslint < v9
49
+ const ruleInfo = utils.getRuleInfo(sourceCode);
50
+ if (!ruleInfo) {
51
+ return {};
52
+ }
53
+
54
+ return {
55
+ Program(ast) {
56
+ const scope = sourceCode.getScope?.(ast) || context.getScope(); // TODO: just use sourceCode.getScope() when we drop support for ESLint < v9.0.0
57
+ const { scopeManager } = sourceCode;
58
+
59
+ const pattern =
60
+ context.options[0] && context.options[0].pattern
61
+ ? new RegExp(context.options[0].pattern)
62
+ : DEFAULT_PATTERN;
63
+
64
+ const metaNode = ruleInfo.meta;
65
+ const docsNode = utils
66
+ .evaluateObjectProperties(metaNode, scopeManager)
67
+ .find((p) => p.type === 'Property' && utils.getKeyName(p) === 'docs');
68
+
69
+ const descriptionNode = utils
70
+ .evaluateObjectProperties(docsNode && docsNode.value, scopeManager)
71
+ .find(
72
+ (p) =>
73
+ p.type === 'Property' && utils.getKeyName(p) === 'description'
74
+ );
75
+
76
+ if (!descriptionNode) {
77
+ context.report({
78
+ node: docsNode || metaNode || ruleInfo.create,
79
+ messageId: 'missing',
80
+ });
81
+ return;
82
+ }
83
+
84
+ const staticValue = getStaticValue(descriptionNode.value, scope);
85
+ if (!staticValue) {
86
+ // Ignore non-static values since we can't determine what they look like.
87
+ return;
88
+ }
89
+
90
+ if (typeof staticValue.value !== 'string' || staticValue.value === '') {
91
+ context.report({
92
+ node: descriptionNode.value,
93
+ messageId: 'wrongType',
94
+ });
95
+ } else if (staticValue.value !== staticValue.value.trim()) {
96
+ context.report({
97
+ node: descriptionNode.value,
98
+ messageId: 'extraWhitespace',
99
+ });
100
+ } else if (!pattern.test(staticValue.value)) {
101
+ context.report({
102
+ node: descriptionNode.value,
103
+ messageId: 'mismatch',
104
+ data: { pattern },
105
+ });
106
+ }
107
+ },
108
+ };
109
+ },
110
+ };
@@ -0,0 +1,175 @@
1
+ /**
2
+ * @author Toru Nagashima <https://github.com/mysticatea>
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ // -----------------------------------------------------------------------------
8
+ // Requirements
9
+ // -----------------------------------------------------------------------------
10
+
11
+ const path = require('path');
12
+ const util = require('../utils');
13
+ const { getStaticValue } = require('eslint-utils');
14
+
15
+ // -----------------------------------------------------------------------------
16
+ // Rule Definition
17
+ // -----------------------------------------------------------------------------
18
+
19
+ /** @type {import('eslint').Rule.RuleModule} */
20
+ module.exports = {
21
+ meta: {
22
+ type: 'suggestion',
23
+ docs: {
24
+ description: 'require rules to implement a `meta.docs.url` property',
25
+ category: 'Rules',
26
+ recommended: false,
27
+ url: 'https://github.com/eslint-community/eslint-plugin-eslint-plugin/tree/HEAD/docs/rules/require-meta-docs-url.md',
28
+ },
29
+ fixable: 'code',
30
+ schema: [
31
+ {
32
+ type: 'object',
33
+ properties: {
34
+ pattern: {
35
+ type: 'string',
36
+ description:
37
+ "A pattern to enforce rule's document URL. It replaces `{{name}}` placeholder by each rule name. The rule name is the basename of each rule file. Omitting this allows any URL.",
38
+ },
39
+ },
40
+ additionalProperties: false,
41
+ },
42
+ ],
43
+ messages: {
44
+ mismatch: '`meta.docs.url` property must be `{{expectedUrl}}`.',
45
+ missing: '`meta.docs.url` property is missing.',
46
+ wrongType: '`meta.docs.url` property must be a string.',
47
+ },
48
+ },
49
+
50
+ /**
51
+ * Creates AST event handlers for require-meta-docs-url.
52
+ * @param {RuleContext} context - The rule context.
53
+ * @returns {Object} AST event handlers.
54
+ */
55
+ create(context) {
56
+ const options = context.options[0] || {};
57
+ const filename = context.filename || context.getFilename(); // TODO: just use context.filename when dropping eslint < v9
58
+ const ruleName =
59
+ filename === '<input>'
60
+ ? undefined
61
+ : path.basename(filename, path.extname(filename));
62
+ const expectedUrl =
63
+ !options.pattern || !ruleName
64
+ ? undefined
65
+ : options.pattern.replaceAll(/{{\s*name\s*}}/g, ruleName);
66
+
67
+ /**
68
+ * Check whether a given URL is the expected URL.
69
+ * @param {string} url The URL to check.
70
+ * @returns {boolean} `true` if the node is the expected URL.
71
+ */
72
+ function isExpectedUrl(url) {
73
+ return Boolean(
74
+ typeof url === 'string' &&
75
+ (expectedUrl === undefined || url === expectedUrl)
76
+ );
77
+ }
78
+
79
+ const sourceCode = context.sourceCode || context.getSourceCode(); // TODO: just use context.sourceCode when dropping eslint < v9
80
+ const ruleInfo = util.getRuleInfo(sourceCode);
81
+ if (!ruleInfo) {
82
+ return {};
83
+ }
84
+
85
+ return {
86
+ Program(ast) {
87
+ const scope = sourceCode.getScope?.(ast) || context.getScope(); // TODO: just use sourceCode.getScope() when we drop support for ESLint < v9.0.0
88
+ const { scopeManager } = sourceCode;
89
+
90
+ const metaNode = ruleInfo.meta;
91
+ const docsPropNode = util
92
+ .evaluateObjectProperties(metaNode, scopeManager)
93
+ .find((p) => p.type === 'Property' && util.getKeyName(p) === 'docs');
94
+ const urlPropNode = util
95
+ .evaluateObjectProperties(
96
+ docsPropNode && docsPropNode.value,
97
+ scopeManager
98
+ )
99
+ .find((p) => p.type === 'Property' && util.getKeyName(p) === 'url');
100
+
101
+ const staticValue = urlPropNode
102
+ ? getStaticValue(urlPropNode.value, scope)
103
+ : undefined;
104
+ if (urlPropNode && !staticValue) {
105
+ // Ignore non-static values since we can't determine what they look like.
106
+ return;
107
+ }
108
+
109
+ if (isExpectedUrl(staticValue && staticValue.value)) {
110
+ return;
111
+ }
112
+
113
+ context.report({
114
+ node:
115
+ (urlPropNode && urlPropNode.value) ||
116
+ (docsPropNode && docsPropNode.value) ||
117
+ metaNode ||
118
+ ruleInfo.create,
119
+
120
+ // eslint-disable-next-line unicorn/no-negated-condition -- actually more clear like this
121
+ messageId: !urlPropNode
122
+ ? 'missing'
123
+ : // eslint-disable-next-line unicorn/no-nested-ternary,unicorn/no-negated-condition -- this is fine for now
124
+ !expectedUrl
125
+ ? 'wrongType'
126
+ : /* otherwise */ 'mismatch',
127
+
128
+ data: {
129
+ expectedUrl,
130
+ },
131
+
132
+ fix(fixer) {
133
+ if (!expectedUrl) {
134
+ return null;
135
+ }
136
+
137
+ const urlString = JSON.stringify(expectedUrl);
138
+ if (urlPropNode) {
139
+ if (
140
+ urlPropNode.value.type === 'Literal' ||
141
+ (urlPropNode.value.type === 'Identifier' &&
142
+ urlPropNode.value.name === 'undefined')
143
+ ) {
144
+ return fixer.replaceText(urlPropNode.value, urlString);
145
+ }
146
+ } else if (
147
+ docsPropNode &&
148
+ docsPropNode.value.type === 'ObjectExpression'
149
+ ) {
150
+ return util.insertProperty(
151
+ fixer,
152
+ docsPropNode.value,
153
+ `url: ${urlString}`,
154
+ sourceCode
155
+ );
156
+ } else if (
157
+ !docsPropNode &&
158
+ metaNode &&
159
+ metaNode.type === 'ObjectExpression'
160
+ ) {
161
+ return util.insertProperty(
162
+ fixer,
163
+ metaNode,
164
+ `docs: {\nurl: ${urlString}\n}`,
165
+ sourceCode
166
+ );
167
+ }
168
+
169
+ return null;
170
+ },
171
+ });
172
+ },
173
+ };
174
+ },
175
+ };
@@ -0,0 +1,137 @@
1
+ /**
2
+ * @fileoverview require rules to implement a `meta.fixable` property
3
+ * @author Teddy Katz
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ const { getStaticValue } = require('eslint-utils');
9
+ const utils = require('../utils');
10
+
11
+ // ------------------------------------------------------------------------------
12
+ // Rule Definition
13
+ // ------------------------------------------------------------------------------
14
+
15
+ /** @type {import('eslint').Rule.RuleModule} */
16
+ module.exports = {
17
+ meta: {
18
+ type: 'problem',
19
+ docs: {
20
+ description: 'require rules to implement a `meta.fixable` property',
21
+ category: 'Rules',
22
+ recommended: true,
23
+ url: 'https://github.com/eslint-community/eslint-plugin-eslint-plugin/tree/HEAD/docs/rules/require-meta-fixable.md',
24
+ },
25
+ schema: [
26
+ {
27
+ type: 'object',
28
+ properties: {
29
+ catchNoFixerButFixableProperty: {
30
+ type: 'boolean',
31
+ default: false,
32
+ description:
33
+ "Whether the rule should attempt to detect rules that do not have a fixer but enable the `meta.fixable` property. This option is off by default because it increases the chance of false positives since fixers can't always be detected when helper functions are used.",
34
+ },
35
+ },
36
+ additionalProperties: false,
37
+ },
38
+ ],
39
+ messages: {
40
+ invalid: '`meta.fixable` must be either `code`, `whitespace`, or `null`.',
41
+ missing:
42
+ '`meta.fixable` must be either `code` or `whitespace` for fixable rules.',
43
+ noFixerButFixableValue:
44
+ '`meta.fixable` is enabled but no fixer detected.',
45
+ },
46
+ },
47
+
48
+ create(context) {
49
+ const catchNoFixerButFixableProperty =
50
+ context.options[0] && context.options[0].catchNoFixerButFixableProperty;
51
+
52
+ const sourceCode = context.sourceCode || context.getSourceCode(); // TODO: just use context.sourceCode when dropping eslint < v9
53
+ const { scopeManager } = sourceCode;
54
+ const ruleInfo = utils.getRuleInfo(sourceCode);
55
+ let contextIdentifiers;
56
+ let usesFixFunctions;
57
+
58
+ if (!ruleInfo) {
59
+ return {};
60
+ }
61
+
62
+ return {
63
+ Program(ast) {
64
+ contextIdentifiers = utils.getContextIdentifiers(scopeManager, ast);
65
+ },
66
+ CallExpression(node) {
67
+ if (
68
+ node.callee.type === 'MemberExpression' &&
69
+ contextIdentifiers.has(node.callee.object) &&
70
+ node.callee.property.type === 'Identifier' &&
71
+ node.callee.property.name === 'report' &&
72
+ (node.arguments.length > 4 ||
73
+ (node.arguments.length === 1 &&
74
+ utils
75
+ .evaluateObjectProperties(node.arguments[0], scopeManager)
76
+ .some((prop) => utils.getKeyName(prop) === 'fix')))
77
+ ) {
78
+ usesFixFunctions = true;
79
+ }
80
+ },
81
+ 'Program:exit'(ast) {
82
+ const scope = sourceCode.getScope?.(ast) || context.getScope(); // TODO: just use sourceCode.getScope() when we drop support for ESLint < v9.0.0
83
+ const metaFixableProp =
84
+ ruleInfo &&
85
+ utils
86
+ .evaluateObjectProperties(ruleInfo.meta, scopeManager)
87
+ .find((prop) => utils.getKeyName(prop) === 'fixable');
88
+
89
+ if (metaFixableProp) {
90
+ const staticValue = getStaticValue(metaFixableProp.value, scope);
91
+ if (!staticValue) {
92
+ // Ignore non-static values since we can't determine what they look like.
93
+ return;
94
+ }
95
+
96
+ if (
97
+ !['code', 'whitespace', null, undefined].includes(staticValue.value)
98
+ ) {
99
+ // `fixable` property has an invalid value.
100
+ context.report({
101
+ node: metaFixableProp.value,
102
+ messageId: 'invalid',
103
+ });
104
+ return;
105
+ }
106
+
107
+ if (
108
+ usesFixFunctions &&
109
+ !['code', 'whitespace'].includes(staticValue.value)
110
+ ) {
111
+ // Rule is fixable but `fixable` property does not have a fixable value.
112
+ context.report({
113
+ node: metaFixableProp.value,
114
+ messageId: 'missing',
115
+ });
116
+ } else if (
117
+ catchNoFixerButFixableProperty &&
118
+ !usesFixFunctions &&
119
+ ['code', 'whitespace'].includes(staticValue.value)
120
+ ) {
121
+ // Rule is NOT fixable but `fixable` property has a fixable value.
122
+ context.report({
123
+ node: metaFixableProp.value,
124
+ messageId: 'noFixerButFixableValue',
125
+ });
126
+ }
127
+ } else if (!metaFixableProp && usesFixFunctions) {
128
+ // Rule is fixable but is missing the `fixable` property.
129
+ context.report({
130
+ node: ruleInfo.meta || ruleInfo.create,
131
+ messageId: 'missing',
132
+ });
133
+ }
134
+ },
135
+ };
136
+ },
137
+ };
@@ -0,0 +1,168 @@
1
+ 'use strict';
2
+
3
+ const utils = require('../utils');
4
+ const { getStaticValue } = require('eslint-utils');
5
+
6
+ // ------------------------------------------------------------------------------
7
+ // Rule Definition
8
+ // ------------------------------------------------------------------------------
9
+
10
+ /** @type {import('eslint').Rule.RuleModule} */
11
+ module.exports = {
12
+ meta: {
13
+ type: 'problem',
14
+ docs: {
15
+ description:
16
+ 'require suggestable rules to implement a `meta.hasSuggestions` property',
17
+ category: 'Rules',
18
+ recommended: true,
19
+ url: 'https://github.com/eslint-community/eslint-plugin-eslint-plugin/tree/HEAD/docs/rules/require-meta-has-suggestions.md',
20
+ },
21
+ fixable: 'code',
22
+ schema: [],
23
+ messages: {
24
+ shouldBeSuggestable:
25
+ '`meta.hasSuggestions` must be `true` for suggestable rules.',
26
+ shouldNotBeSuggestable:
27
+ '`meta.hasSuggestions` cannot be `true` for non-suggestable rules.',
28
+ },
29
+ },
30
+
31
+ create(context) {
32
+ const sourceCode = context.sourceCode || context.getSourceCode(); // TODO: just use context.sourceCode when dropping eslint < v9
33
+ const { scopeManager } = sourceCode;
34
+ const ruleInfo = utils.getRuleInfo(sourceCode);
35
+ if (!ruleInfo) {
36
+ return {};
37
+ }
38
+ let contextIdentifiers;
39
+ let ruleReportsSuggestions;
40
+
41
+ /**
42
+ * Check if a "suggest" object property from a rule violation report should be considered to contain suggestions.
43
+ * @param {Node} node - the "suggest" object property to check
44
+ * @returns {boolean} whether this property should be considered to contain suggestions
45
+ */
46
+ function doesPropertyContainSuggestions(node) {
47
+ const scope = sourceCode.getScope?.(node) || context.getScope(); // TODO: just use sourceCode.getScope() when we drop support for ESLint < v9.0.0
48
+ const staticValue = getStaticValue(node.value, scope);
49
+ if (
50
+ !staticValue ||
51
+ (Array.isArray(staticValue.value) && staticValue.value.length > 0) ||
52
+ (Array.isArray(staticValue.value) &&
53
+ staticValue.value.length === 0 &&
54
+ node.value.type === 'Identifier') // Array variable can have suggestions pushed to it.
55
+ ) {
56
+ // These are all considered reporting suggestions:
57
+ // suggest: [{...}]
58
+ // suggest: getSuggestions()
59
+ // suggest: MY_SUGGESTIONS
60
+ return true;
61
+ }
62
+ return false;
63
+ }
64
+
65
+ return {
66
+ Program(ast) {
67
+ contextIdentifiers = utils.getContextIdentifiers(scopeManager, ast);
68
+ },
69
+ CallExpression(node) {
70
+ if (
71
+ node.callee.type === 'MemberExpression' &&
72
+ contextIdentifiers.has(node.callee.object) &&
73
+ node.callee.property.type === 'Identifier' &&
74
+ node.callee.property.name === 'report' &&
75
+ (node.arguments.length > 4 ||
76
+ (node.arguments.length === 1 &&
77
+ node.arguments[0].type === 'ObjectExpression'))
78
+ ) {
79
+ const suggestProp = utils
80
+ .evaluateObjectProperties(node.arguments[0], scopeManager)
81
+ .find((prop) => utils.getKeyName(prop) === 'suggest');
82
+ if (suggestProp && doesPropertyContainSuggestions(suggestProp)) {
83
+ ruleReportsSuggestions = true;
84
+ }
85
+ }
86
+ },
87
+ Property(node) {
88
+ // In order to reduce false positives, we will also check for a `suggest` property anywhere in the file.
89
+ // This is helpful especially in the event that helper functions are used for reporting violations.
90
+ if (
91
+ node.key.type === 'Identifier' &&
92
+ node.key.name === 'suggest' &&
93
+ doesPropertyContainSuggestions(node)
94
+ ) {
95
+ ruleReportsSuggestions = true;
96
+ }
97
+ },
98
+ 'Program:exit'(node) {
99
+ const scope = sourceCode.getScope?.(node) || context.getScope(); // TODO: just use sourceCode.getScope() when we drop support for ESLint < v9.0.0
100
+ const metaNode = ruleInfo && ruleInfo.meta;
101
+ const hasSuggestionsProperty = utils
102
+ .evaluateObjectProperties(metaNode, scopeManager)
103
+ .find((prop) => utils.getKeyName(prop) === 'hasSuggestions');
104
+ const hasSuggestionsStaticValue =
105
+ hasSuggestionsProperty &&
106
+ getStaticValue(hasSuggestionsProperty.value, scope);
107
+
108
+ if (ruleReportsSuggestions) {
109
+ if (!hasSuggestionsProperty) {
110
+ // Rule reports suggestions but is missing the `meta.hasSuggestions` property altogether.
111
+ context.report({
112
+ node: metaNode || ruleInfo.create,
113
+ messageId: 'shouldBeSuggestable',
114
+ fix(fixer) {
115
+ if (metaNode && metaNode.type === 'ObjectExpression') {
116
+ if (metaNode.properties.length === 0) {
117
+ // If object is empty, just replace entire object.
118
+ return fixer.replaceText(
119
+ metaNode,
120
+ '{ hasSuggestions: true }'
121
+ );
122
+ }
123
+ // Add new property to start of property list.
124
+ return fixer.insertTextBefore(
125
+ metaNode.properties[0],
126
+ 'hasSuggestions: true, '
127
+ );
128
+ }
129
+ },
130
+ });
131
+ } else if (
132
+ hasSuggestionsStaticValue &&
133
+ hasSuggestionsStaticValue.value !== true
134
+ ) {
135
+ // Rule reports suggestions but does not have `meta.hasSuggestions` property enabled.
136
+ context.report({
137
+ node: hasSuggestionsProperty.value,
138
+ messageId: 'shouldBeSuggestable',
139
+ fix(fixer) {
140
+ if (
141
+ hasSuggestionsProperty.value.type === 'Literal' ||
142
+ (hasSuggestionsProperty.value.type === 'Identifier' &&
143
+ hasSuggestionsProperty.value.name === 'undefined')
144
+ ) {
145
+ return fixer.replaceText(
146
+ hasSuggestionsProperty.value,
147
+ 'true'
148
+ );
149
+ }
150
+ },
151
+ });
152
+ }
153
+ } else if (
154
+ !ruleReportsSuggestions &&
155
+ hasSuggestionsProperty &&
156
+ hasSuggestionsStaticValue &&
157
+ hasSuggestionsStaticValue.value === true
158
+ ) {
159
+ // Rule does not report suggestions but has the `meta.hasSuggestions` property enabled.
160
+ context.report({
161
+ node: hasSuggestionsProperty.value,
162
+ messageId: 'shouldNotBeSuggestable',
163
+ });
164
+ }
165
+ },
166
+ };
167
+ },
168
+ };