@generaltranslation/gt-next-lint
Version:
ESLint plugin for General Translation Next.js integration
140 lines (139 loc) • 6.88 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_rules_utils = require("./utils.js");
//#region src/rules/no-dynamic-string.ts
const TRANSLATION_FUNCTIONS = ["useGT", "getGT"];
function isTranslationFunction(name) {
return TRANSLATION_FUNCTIONS.includes(name);
}
const noDynamicString = {
meta: {
type: "problem",
docs: {
description: "Translation functions must use string literals as the first argument",
category: "Best Practices",
recommended: true,
url: "https://github.com/generaltranslation/gt/tree/main/packages/next-lint#no-dynamic-string"
},
fixable: void 0,
schema: [],
messages: { dynamicString: "Translation function must use a constant string literal as the first argument. Use t('Hello, {name}!', { name: value }) instead of template literals or string concatenation." }
},
create(context) {
const trackedFunctions = /* @__PURE__ */ new Map();
const translationVariables = /* @__PURE__ */ new Set();
function trackImport(localName, importedName, source) {
if (require_rules_utils.isGTModule(source) && isTranslationFunction(importedName)) trackedFunctions.set(localName, {
name: importedName,
isTranslationFunction: true
});
}
function trackNamespaceImport(localName, source) {
if (require_rules_utils.isGTModule(source)) trackedFunctions.set(localName, {
name: localName,
isTranslationFunction: false
});
}
function validateTranslationCall(node) {
if (!require_rules_utils.isAstNode(node) || !Array.isArray(node.arguments)) return;
const firstArg = node.arguments[0];
if (!firstArg) return;
if (!require_rules_utils.isStringLiteral(firstArg)) context.report({
node: firstArg,
messageId: "dynamicString"
});
}
function handleCallExpression(node) {
if (!require_rules_utils.isAstNode(node) || !require_rules_utils.isAstNode(node.callee)) return;
if (node.callee.type === "Identifier") {
const functionName = require_rules_utils.getNodeName(node.callee);
if (!functionName) return;
if (trackedFunctions.has(functionName)) {
if (trackedFunctions.get(functionName).isTranslationFunction) validateTranslationCall(node);
} else if (translationVariables.has(functionName)) validateTranslationCall(node);
} else if (node.callee.type === "MemberExpression") {
const objectName = require_rules_utils.getNodeName(node.callee.object);
const propertyName = require_rules_utils.getNodeName(node.callee.property);
if (!objectName || !propertyName) return;
if (trackedFunctions.has(objectName) && isTranslationFunction(propertyName)) validateTranslationCall(node);
}
}
function handleAssignment(node) {
if (require_rules_utils.isAstNode(node) && node.type === "VariableDeclarator" && require_rules_utils.isAstNode(node.id) && node.id.type === "Identifier" && require_rules_utils.isAstNode(node.init)) {
if (node.init.type === "CallExpression") {
const callExpression = node.init;
if (require_rules_utils.isAstNode(callExpression.callee) && callExpression.callee.type === "Identifier") {
const functionName = require_rules_utils.getNodeName(callExpression.callee);
if (!functionName) return;
if (trackedFunctions.has(functionName)) {
if (trackedFunctions.get(functionName).isTranslationFunction) {
const variableName = require_rules_utils.getNodeName(node.id);
if (variableName) translationVariables.add(variableName);
}
}
} else if (require_rules_utils.isAstNode(callExpression.callee) && callExpression.callee.type === "MemberExpression") {
const objectName = require_rules_utils.getNodeName(callExpression.callee.object);
const propertyName = require_rules_utils.getNodeName(callExpression.callee.property);
if (objectName && propertyName && trackedFunctions.has(objectName) && isTranslationFunction(propertyName)) {
const variableName = require_rules_utils.getNodeName(node.id);
if (variableName) translationVariables.add(variableName);
}
}
} else if (node.init.type === "AwaitExpression" && require_rules_utils.isAstNode(node.init.argument) && node.init.argument.type === "CallExpression") {
const callExpression = node.init.argument;
if (require_rules_utils.isAstNode(callExpression.callee) && callExpression.callee.type === "Identifier") {
const functionName = require_rules_utils.getNodeName(callExpression.callee);
if (!functionName) return;
if (trackedFunctions.has(functionName)) {
if (trackedFunctions.get(functionName).isTranslationFunction) {
const variableName = require_rules_utils.getNodeName(node.id);
if (variableName) translationVariables.add(variableName);
}
}
} else if (require_rules_utils.isAstNode(callExpression.callee) && callExpression.callee.type === "MemberExpression") {
const objectName = require_rules_utils.getNodeName(callExpression.callee.object);
const propertyName = require_rules_utils.getNodeName(callExpression.callee.property);
if (objectName && propertyName && trackedFunctions.has(objectName) && isTranslationFunction(propertyName)) {
const variableName = require_rules_utils.getNodeName(node.id);
if (variableName) translationVariables.add(variableName);
}
}
} else if (node.init.type === "Identifier") {
const assignedFrom = require_rules_utils.getNodeName(node.init);
if (assignedFrom && translationVariables.has(assignedFrom)) {
const variableName = require_rules_utils.getNodeName(node.id);
if (variableName) translationVariables.add(variableName);
}
}
}
}
return {
ImportDeclaration(node) {
if (!require_rules_utils.isAstNode(node) || !require_rules_utils.isAstNode(node.source)) return;
const source = node.source.value;
if (typeof source !== "string") return;
if (!require_rules_utils.isGTModule(source)) return;
const specifiers = Array.isArray(node.specifiers) ? node.specifiers : [];
for (const specifier of specifiers) {
if (!require_rules_utils.isAstNode(specifier)) continue;
if (specifier.type === "ImportSpecifier") {
const importedName = require_rules_utils.getNodeName(specifier.imported);
const localName = require_rules_utils.getNodeName(specifier.local);
if (importedName && localName) trackImport(localName, importedName, source);
} else if (specifier.type === "ImportNamespaceSpecifier") {
const localName = require_rules_utils.getNodeName(specifier.local);
if (localName) trackNamespaceImport(localName, source);
}
}
},
VariableDeclarator(node) {
handleAssignment(node);
},
CallExpression(node) {
handleCallExpression(node);
}
};
}
};
//#endregion
exports.noDynamicString = noDynamicString;
//# sourceMappingURL=no-dynamic-string.js.map