blob: 9ac37575ca10a587c3da2c50e6fff7005a84f829 [file] [edit]
'use strict';
const utils = require('../utils');
/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
meta: {
type: 'suggestion',
docs: {
description:
'require only rules with options to implement a `meta.defaultOptions` property',
category: 'Rules',
recommended: false,
url: 'https://github.com/eslint-community/eslint-plugin-eslint-plugin/tree/HEAD/docs/rules/require-meta-default-options.md',
},
fixable: 'code',
schema: [],
messages: {
missingDefaultOptions:
'Rule with non-empty schema is missing a `meta.defaultOptions` property.',
unnecessaryDefaultOptions:
'Rule with empty schema should not have a `meta.defaultOptions` property.',
defaultOptionsMustBeArray: 'Default options must be an array.',
defaultOptionsMustNotBeEmpty: 'Default options must not be empty.',
},
},
create(context) {
const sourceCode = utils.getSourceCode(context);
const { scopeManager } = sourceCode;
const ruleInfo = utils.getRuleInfo(sourceCode);
if (!ruleInfo) {
return {};
}
const metaNode = ruleInfo.meta;
const schemaNode = utils.getMetaSchemaNode(metaNode, scopeManager);
const schemaProperty = utils.getMetaSchemaNodeProperty(
schemaNode,
scopeManager,
);
if (!schemaProperty) {
return {};
}
const metaDefaultOptions = utils
.evaluateObjectProperties(metaNode, scopeManager)
.find(
(p) =>
p.type === 'Property' && utils.getKeyName(p) === 'defaultOptions',
);
if (
schemaProperty.type === 'ArrayExpression' &&
schemaProperty.elements.length === 0
) {
if (metaDefaultOptions) {
context.report({
node: metaDefaultOptions,
messageId: 'unnecessaryDefaultOptions',
fix(fixer) {
return fixer.remove(metaDefaultOptions);
},
});
}
return {};
}
if (!metaDefaultOptions) {
context.report({
node: metaNode,
messageId: 'missingDefaultOptions',
fix(fixer) {
return fixer.insertTextAfter(schemaProperty, ', defaultOptions: []');
},
});
return {};
}
if (metaDefaultOptions.value.type !== 'ArrayExpression') {
context.report({
node: metaDefaultOptions.value,
messageId: 'defaultOptionsMustBeArray',
});
return {};
}
const isArrayRootSchema =
schemaProperty.type === 'ObjectExpression' &&
schemaProperty.properties.find((property) => property.key.name === 'type')
?.value.value === 'array';
if (metaDefaultOptions.value.elements.length === 0 && !isArrayRootSchema) {
context.report({
node: metaDefaultOptions.value,
messageId: 'defaultOptionsMustNotBeEmpty',
});
return {};
}
return {};
},
};