UNPKG

eslint-plugin-formatjs

Version:
71 lines (70 loc) 2.44 kB
import { isPluralElement, parse, } from '@formatjs/icu-messageformat-parser'; import { getParserServices } from '../context-compat.js'; import { extractMessages, getSettings } from '../util.js'; function verifyAst(ast, pluralCount = { count: 0 }) { const errors = []; for (const el of ast) { if (isPluralElement(el)) { pluralCount.count++; if (pluralCount.count > 1) { errors.push({ messageId: 'noMultiplePlurals', data: {} }); } const { options } = el; for (const selector of Object.keys(options)) { errors.push(...verifyAst(options[selector].value, pluralCount)); } } } return errors; } function checkNode(context, node) { const settings = getSettings(context); const msgs = extractMessages(node, settings); for (const [{ message: { defaultMessage }, messageNode, },] of msgs) { if (!defaultMessage || !messageNode) { continue; } const errors = verifyAst(parse(defaultMessage, { ignoreTag: settings.ignoreTag, })); for (const error of errors) { context.report({ node, ...error, }); } } } export const name = 'no-multiple-plurals'; export const rule = { meta: { type: 'problem', docs: { description: 'Disallow multiple plural rules in the same message', url: 'https://formatjs.github.io/docs/tooling/linter#no-multiple-plurals', }, fixable: 'code', schema: [], messages: { noMultiplePlurals: 'Multiple plural rules in the same message', }, }, defaultOptions: [], create(context) { const callExpressionVisitor = (node) => checkNode(context, node); const parserServices = getParserServices(context); //@ts-expect-error defineTemplateBodyVisitor exists in Vue parser if (parserServices?.defineTemplateBodyVisitor) { //@ts-expect-error return parserServices.defineTemplateBodyVisitor({ CallExpression: callExpressionVisitor, }, { CallExpression: callExpressionVisitor, }); } return { JSXOpeningElement: (node) => checkNode(context, node), CallExpression: callExpressionVisitor, }; }, };