lib/rules/i18n-no-template-literal.js (64 lines of code) (raw):
'use strict';
const { I18N_METHODS } = require('../i18n.js');
const toStaticString = (quasis) => {
return quasis
.map((quasi) => {
let text = quasi.value.raw;
text = text.replace(/'/g, "\\'"); // Escape single quotes
text = text.replace(/"/g, '\\"'); // Escape double quotes
return text;
})
.join('')
.replace(/\s+/g, ' ')
.trim();
};
module.exports = {
meta: {
docs: {
category: 'Possible Errors',
description:
'Ensure predictable static values are passed as i18n method arguments',
},
fixable: 'code',
schema: [],
messages: {
noStaticTemplate:
'Do not use template literals on i18n.{{method}} for positional argument {{position}}. Use literal strings instead.',
},
},
create(context) {
return {
CallExpression(node) {
const { callee, arguments: args } = node;
if (!callee.type === 'MemberExpression' || !args.length) {
return;
}
const { object, property } = node.callee;
if (object?.name !== 'i18n') {
return;
}
const positions = I18N_METHODS[property.name] || [];
positions.forEach((position) => {
const arg = args[position];
if (arg.type === 'TemplateLiteral') {
// Template literal without dynamic placeholders
const reportObject = {
node,
messageId: 'noStaticTemplate',
data: {
method: property.name,
position,
},
};
if (!arg.expressions || arg.expressions.length === 0) {
reportObject.fix = (fixer) => {
const fixedValue = toStaticString(arg.quasis);
return fixer.replaceText(arg, `'${fixedValue}'`);
};
}
context.report(reportObject);
}
});
},
};
},
};