eslint-plugin-lingui
Version:
ESLint plugin for Lingui
95 lines • 4.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const utils_1 = require("@typescript-eslint/utils");
const helpers_1 = require("../helpers");
const create_rule_1 = require("../create-rule");
exports.name = 'no-expression-in-message';
exports.rule = (0, create_rule_1.createRule)({
name: 'no-expression-in-message',
meta: {
docs: {
description: "doesn't allow functions or member expressions in templates",
recommended: 'error',
},
messages: {
default: 'Should be ${variable}, not ${object.property} or ${myFunction()}',
multiplePlaceholders: 'Invalid placeholder: Expected an object with a single key-value pair, but found multiple keys',
},
schema: [
{
type: 'object',
properties: {},
additionalProperties: false,
},
],
type: 'problem',
},
defaultOptions: [],
create: function (context) {
const linguiMacroFunctionNames = ['plural', 'select', 'selectOrdinal', 'ph'];
function checkExpressionsInTplLiteral(node) {
node.expressions.forEach((expression) => checkExpression(expression));
}
function checkExpression(expression) {
if (expression.type === utils_1.TSESTree.AST_NODE_TYPES.Identifier) {
return;
}
const isCallToLinguiMacro = expression.type === utils_1.TSESTree.AST_NODE_TYPES.CallExpression &&
expression.callee.type === utils_1.TSESTree.AST_NODE_TYPES.Identifier &&
linguiMacroFunctionNames.includes(expression.callee.name);
if (isCallToLinguiMacro) {
return;
}
const isExplicitLabel = expression.type === utils_1.TSESTree.AST_NODE_TYPES.ObjectExpression;
if (isExplicitLabel) {
// there can be only one key in the object
if (expression.properties.length === 1) {
return;
}
context.report({
node: expression,
messageId: 'multiplePlaceholders',
});
return;
}
context.report({
node: expression,
messageId: 'default',
});
}
return {
[`${helpers_1.LinguiTaggedTemplateExpressionMessageQuery}, ${helpers_1.LinguiCallExpressionMessageQuery}`](node) {
if (node.type === utils_1.TSESTree.AST_NODE_TYPES.Literal) {
return;
}
checkExpressionsInTplLiteral(node);
},
[`${helpers_1.LinguiTransQuery} JSXExpressionContainer:not([parent.type=JSXAttribute]) > :expression`](node) {
if (node.type === utils_1.TSESTree.AST_NODE_TYPES.Literal) {
// skip strings as expression in JSX, including spaces {' '}
return;
}
if (node.type === utils_1.TSESTree.AST_NODE_TYPES.TemplateLiteral) {
// <Trans>{`How much is ${obj.prop}?`}</Trans>
return checkExpressionsInTplLiteral(node);
}
if (node.type === utils_1.TSESTree.AST_NODE_TYPES.ObjectExpression) {
// <Trans>Hello {{name: obj.prop}}</Trans>
return checkExpression(node);
}
if (node.type === utils_1.TSESTree.AST_NODE_TYPES.CallExpression) {
// <Trans>Hello {ph({name: obj.prop})}</Trans>
return checkExpression(node);
}
if (node.type !== utils_1.TSESTree.AST_NODE_TYPES.Identifier) {
context.report({
node,
messageId: 'default',
});
}
},
};
},
});
//# sourceMappingURL=no-expression-in-message.js.map