eslint-plugin-lingui
Version:
ESLint plugin for Lingui
150 lines • 7.39 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = exports.name = void 0;
const utils_1 = require("@typescript-eslint/utils");
const create_rule_1 = require("../create-rule");
const helpers_1 = require("../helpers");
exports.name = 'consistent-plural-format';
exports.rule = (0, create_rule_1.createRule)({
name: 'consistent-plural-format',
meta: {
docs: {
description: 'Enforce consistent format for plural definitions',
recommended: 'error',
},
messages: {
hashRequired: 'Use hash format (e.g., "# book") instead of template literals in plural definitions',
templateRequired: 'Use template literal format (e.g., `${variable} book`) instead of hash format in plural definitions',
},
schema: [
{
type: 'object',
properties: {
style: {
type: 'string',
enum: ['hash', 'template'],
},
},
additionalProperties: false,
},
],
type: 'problem',
},
defaultOptions: [{ style: 'hash' }],
create: function (context) {
const options = context.options[0] || {};
const preferredStyle = options.style || 'hash';
function checkStringValue(value, node) {
const hasHashFormat = value.includes('#');
const hasTemplateLiteralPattern = /\$\{[^}]+\}/.test(value);
if (preferredStyle === 'hash') {
// If it doesn't have hash format but has template literal pattern in string
if (!hasHashFormat && hasTemplateLiteralPattern) {
context.report({
node,
messageId: 'hashRequired',
});
}
}
else if (preferredStyle === 'template') {
// If it has hash format, it should use template literals instead
if (hasHashFormat) {
context.report({
node,
messageId: 'templateRequired',
});
}
}
}
function checkPluralObject(objectNode) {
objectNode.properties.forEach((property) => {
if (property.type === utils_1.TSESTree.AST_NODE_TYPES.Property) {
// Handle template literals
if (property.value.type === utils_1.TSESTree.AST_NODE_TYPES.TemplateLiteral) {
const templateValue = property.value.quasis.map((q) => q.value.raw).join('${...}');
const hasVariables = property.value.expressions.length > 0;
if (preferredStyle === 'hash') {
// Only flag template literals that have variables (expressions)
if (hasVariables) {
context.report({
node: property.value,
messageId: 'hashRequired',
});
}
}
else if (preferredStyle === 'template') {
// Check if template literal contains hash format
if (templateValue.includes('#')) {
context.report({
node: property.value,
messageId: 'templateRequired',
});
}
}
}
// Handle string literals
else if (property.value.type === utils_1.TSESTree.AST_NODE_TYPES.Literal &&
typeof property.value.value === 'string') {
checkStringValue(property.value.value, property.value);
}
}
});
}
return {
[helpers_1.LinguiCallExpressionPluralQuery](node) {
// Check if the second argument is an object expression
if (node.arguments.length >= 2 &&
node.arguments[1].type === utils_1.TSESTree.AST_NODE_TYPES.ObjectExpression) {
checkPluralObject(node.arguments[1]);
}
},
[helpers_1.LinguiPluralComponentQuery](node) {
const attributes = node.openingElement.attributes;
attributes.forEach((attr) => {
if (attr.type === utils_1.TSESTree.AST_NODE_TYPES.JSXAttribute &&
attr.name.type === utils_1.TSESTree.AST_NODE_TYPES.JSXIdentifier &&
(attr.name.name === 'one' ||
attr.name.name === 'other' ||
attr.name.name === 'zero' ||
attr.name.name === 'few' ||
attr.name.name === 'many')) {
if (attr.value) {
// Handle string literals
if (attr.value.type === utils_1.TSESTree.AST_NODE_TYPES.Literal &&
typeof attr.value.value === 'string') {
checkStringValue(attr.value.value, attr.value);
}
// Handle JSX expressions with template literals
else if (attr.value.type === utils_1.TSESTree.AST_NODE_TYPES.JSXExpressionContainer &&
attr.value.expression.type === utils_1.TSESTree.AST_NODE_TYPES.TemplateLiteral) {
const templateValue = attr.value.expression.quasis
.map((q) => q.value.raw)
.join('${...}');
const hasVariables = attr.value.expression.expressions.length > 0;
if (preferredStyle === 'hash') {
// Only flag template literals that have variables (expressions)
if (hasVariables) {
context.report({
node: attr.value.expression,
messageId: 'hashRequired',
});
}
}
else if (preferredStyle === 'template') {
// Check if template literal contains hash format
if (templateValue.includes('#')) {
context.report({
node: attr.value.expression,
messageId: 'templateRequired',
});
}
}
}
}
}
});
},
};
},
});
//# sourceMappingURL=consistent-plural-format.js.map