eslint-plugin-unicorn
Version:
More than 300 powerful ESLint rules
99 lines (87 loc) • 2.54 kB
JavaScript
import {getBuiltinRule} from './utils/index.js';
import onCssIdentifier from './shared/css-identifiers.js';
import onHtmlIdentifier from './shared/html-identifiers.js';
const baseRule = getBuiltinRule('id-match');
const schema = structuredClone(baseRule.meta.schema);
schema[1].properties.checkNamedSpecifiers = {
type: 'boolean',
description: 'Whether to check named import specifiers and external named export specifiers.',
};
const isNamedSpecifierReport = problem => {
const {parent} = problem.node;
return parent?.type === 'ImportSpecifier'
|| (
parent?.type === 'ExportSpecifier'
&& parent.parent.source
);
};
const shouldIgnoreNamedSpecifierReport = (problem, checkNamedSpecifiers) =>
!checkNamedSpecifiers
&& isNamedSpecifierReport(problem);
/**
@param {import('eslint').Rule.RuleContext} context
*/
const create = context => {
const isCss = context.sourceCode.ast.type === 'StyleSheet';
const isHtml = context.sourceCode.ast.body?.[0]?.type === 'Document';
if (isCss || isHtml) {
const [pattern] = context.options;
const regex = new RegExp(pattern, 'u');
const onIdentifier = isHtml ? onHtmlIdentifier : onCssIdentifier;
onIdentifier(context, ({node, name, location, isDashedName}) => {
if (!regex.test(isDashedName ? name.replace(/^--/, '') : name)) {
return {
node, loc: location, messageId: 'notMatch', data: {name, pattern},
};
}
});
return;
}
const isCheckNamedSpecifiers = context.options[1]?.checkNamedSpecifiers !== false;
const fakeContext = Object.create(context, {
report: {
value(problem) {
if (shouldIgnoreNamedSpecifierReport(problem, isCheckNamedSpecifiers)) {
return;
}
context.report(problem);
},
},
});
const {
Program: onProgram,
Identifier: onIdentifier,
PrivateIdentifier: onPrivateIdentifier,
} = baseRule.create(fakeContext);
context.on('Program', node => onProgram(node));
context.on('Identifier', node => onIdentifier(node));
context.on('PrivateIdentifier', node => onPrivateIdentifier(node));
};
/**
@type {import('eslint').Rule.RuleModule}
*/
const config = {
create,
meta: {
type: 'suggestion',
docs: {
description: 'Require identifiers to match a specified regular expression.',
recommended: false,
},
schema,
defaultOptions: [
baseRule.meta.defaultOptions[0],
{
...baseRule.meta.defaultOptions[1],
checkNamedSpecifiers: true,
},
],
messages: baseRule.meta.messages,
languages: [
'js/js',
'css/css',
'html/html',
],
},
};
export default config;