UNPKG

eslint-plugin-formatjs

Version:
136 lines (135 loc) 5.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.rule = exports.Element = exports.name = void 0; const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser"); const utils_1 = require("@typescript-eslint/utils"); const context_compat_1 = require("../context-compat"); const util_1 = require("../util"); exports.name = 'blocklist-elements'; function getMessage(type) { return { messageId: 'blocklist', data: { type }, }; } var Element; (function (Element) { Element["literal"] = "literal"; Element["argument"] = "argument"; Element["number"] = "number"; Element["date"] = "date"; Element["time"] = "time"; Element["select"] = "select"; Element["selectordinal"] = "selectordinal"; Element["plural"] = "plural"; Element["tag"] = "tag"; })(Element || (exports.Element = Element = {})); function verifyAst(blocklist, ast) { const errors = []; for (const el of ast) { if ((0, icu_messageformat_parser_1.isLiteralElement)(el) && blocklist.includes(Element.literal)) { errors.push(getMessage(Element.literal)); } if ((0, icu_messageformat_parser_1.isArgumentElement)(el) && blocklist.includes(Element.argument)) { errors.push(getMessage(Element.argument)); } if ((0, icu_messageformat_parser_1.isNumberElement)(el) && blocklist.includes(Element.number)) { errors.push(getMessage(Element.number)); } if ((0, icu_messageformat_parser_1.isDateElement)(el) && blocklist.includes(Element.date)) { errors.push(getMessage(Element.date)); } if ((0, icu_messageformat_parser_1.isTimeElement)(el) && blocklist.includes(Element.time)) { errors.push(getMessage(Element.time)); } if ((0, icu_messageformat_parser_1.isSelectElement)(el) && blocklist.includes(Element.select)) { errors.push(getMessage(Element.select)); } if ((0, icu_messageformat_parser_1.isTagElement)(el) && blocklist.includes(Element.tag)) { errors.push(getMessage(Element.tag)); } if ((0, icu_messageformat_parser_1.isPluralElement)(el)) { if (blocklist.includes(Element.plural)) { errors.push(getMessage(Element.argument)); } if (el.pluralType === 'ordinal' && blocklist.includes(Element.selectordinal)) { errors.push(getMessage(Element.selectordinal)); } } if ((0, icu_messageformat_parser_1.isSelectElement)(el) || (0, icu_messageformat_parser_1.isPluralElement)(el)) { const { options } = el; for (const selector of Object.keys(options)) { verifyAst(blocklist, options[selector].value); } } } return errors; } function checkNode(context, node) { const settings = (0, util_1.getSettings)(context); const msgs = (0, util_1.extractMessages)(node, settings); if (!msgs.length) { return; } const blocklist = context.options[0]; if (!Array.isArray(blocklist) || !blocklist.length) { return; } for (const [{ message: { defaultMessage }, messageNode, },] of msgs) { if (!defaultMessage || !messageNode) { continue; } const errors = verifyAst(blocklist, (0, icu_messageformat_parser_1.parse)(defaultMessage, { ignoreTag: settings.ignoreTag, })); for (const error of errors) { context.report({ node, ...error, }); } } } const createRule = utils_1.ESLintUtils.RuleCreator(_ => 'https://formatjs.github.io/docs/tooling/linter#blocklist-elements'); exports.rule = createRule({ name: exports.name, meta: { type: 'problem', docs: { description: 'Disallow specific elements in ICU message format', url: 'https://formatjs.github.io/docs/tooling/linter#blocklist-elements', }, fixable: 'code', schema: [ { type: 'array', items: { type: 'string', enum: Object.keys(Element), }, }, ], messages: { blocklist: `{{type}} element is blocklisted`, }, }, defaultOptions: [], create(context) { const callExpressionVisitor = node => checkNode(context, node); const parserServices = (0, context_compat_1.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, }; }, });