@addon24/eslint-config
Version:
ESLint configuration rules for WorldOfTextcraft projects - Centralized configuration for all project types
110 lines (95 loc) • 3.93 kB
JavaScript
;
export default {
meta: {
type: "problem",
docs: {
description: "Enforce @Inject() decorator for service dependencies in constructor parameters",
category: "Best Practices",
recommended: true,
},
messages: {
missingInjectDecorator: "Dependency '{{serviceName}}' in constructor parameter must use @Inject() decorator",
invalidInjectUsage: "@Inject() decorator should only be used on constructor parameters with dependency names (Service, Repository, dataSource, logger, etc.)",
},
fixable: null,
schema: [],
},
create(context) {
const filename = context.getFilename();
// Nur in Controller- und Service-Dateien anwenden
if ((!filename.includes("/controller/") && !filename.includes("/service/")) ||
(!filename.includes("Controller") && !filename.includes("Service"))) {
return {};
}
return {
ClassDeclaration(node) {
// Nur für Controller- und Service-Klassen
if (!node.id || (!node.id.name.endsWith("Controller") && !node.id.name.endsWith("Service"))) {
return;
}
// Finde den Constructor
const constructor = node.body.body.find(
(member) => member.type === "MethodDefinition" && member.key.name === "constructor"
);
if (!constructor || !constructor.value) {
return;
}
// Prüfe Constructor-Parameter
constructor.value.params.forEach((param, index) => {
if (param.type !== "TSParameterProperty") {
return;
}
// Prüfe, ob es ein Service, Repository oder andere Dependency ist
const paramName = param.parameter.name;
const isDependency = paramName.endsWith("Service") ||
paramName.endsWith("Repository") ||
paramName.endsWith("Factory") ||
paramName === "dataSource" ||
paramName === "logger" ||
paramName.endsWith("Entity") ||
paramName.endsWith("Repository");
if (!isDependency) {
return;
}
// Prüfe, ob @Inject() Decorator vorhanden ist
const hasInjectDecorator = param.decorators &&
param.decorators.some(decorator =>
decorator.expression &&
decorator.expression.callee &&
decorator.expression.callee.name === "Inject"
);
if (!hasInjectDecorator) {
context.report({
node: param,
messageId: "missingInjectDecorator",
data: { serviceName: paramName },
});
}
});
},
// Prüfe auch auf @Inject() Decorators, die falsch verwendet werden
Decorator(node) {
if (node.expression && node.expression.callee && node.expression.callee.name === "Inject") {
// Finde den Parameter, auf den dieser Decorator angewendet wird
const parent = node.parent;
if (parent && parent.type === "TSParameterProperty") {
const paramName = parent.parameter.name;
const isDependency = paramName.endsWith("Service") ||
paramName.endsWith("Repository") ||
paramName.endsWith("Factory") ||
paramName === "dataSource" ||
paramName === "logger" ||
paramName.endsWith("Entity");
if (!isDependency) {
context.report({
node: node,
messageId: "invalidInjectUsage",
data: { paramName },
});
}
}
}
},
};
},
};