@addon24/eslint-config
Version:
ESLint configuration rules for WorldOfTextcraft projects - Centralized configuration for all project types
128 lines (106 loc) • 3.75 kB
JavaScript
import fs from "fs";
import path from "path";
const noDtoDuplicatesRule = {
meta: {
type: "problem",
docs: {
description: "Prevents duplicate DTO class names across the dto directory",
category: "Architecture",
recommended: true,
},
schema: [],
messages: {
dtoDuplicateFound: "DTO-Klasse '{{className}}' existiert bereits in '{{existingFile}}'. Duplikate sind nicht erlaubt. Aktuelle Datei: '{{currentFile}}'. Entscheide selbst, welche Datei wir behalten! Lösche alle unnötigen - passe ggf. den Namen der Datei+Klasse an und korrigiere die Imports.",
},
},
create(context) {
return {
ClassDeclaration(node) {
const filename = context.getFilename();
const className = node.id?.name;
if (!className) return;
// Prüfe nur Dateien im dto-Verzeichnis
if (!filename.includes("/dto/") || !filename.endsWith(".ts")) {
return;
}
// Prüfe, ob es sich um eine DTO-Klasse handelt (endet mit "Dto")
if (!className.endsWith("Dto")) {
return;
}
// In Tests verwenden wir gemockte Dateien
// Suche nach anderen Dateien mit dem gleichen Klassennamen
const dtoDirectory = findDtoDirectory(filename);
if (!dtoDirectory) {
return;
}
const duplicateFiles = findDuplicateFiles(dtoDirectory, className, filename);
if (duplicateFiles.length > 0) {
// Berichte den ersten gefundenen Duplikat
const existingFile = duplicateFiles[0];
context.report({
node: node,
messageId: "dtoDuplicateFound",
data: {
className: className,
currentFile: filename,
existingFile: existingFile
},
});
}
},
};
},
};
// Hilfsmethode um das dto-Verzeichnis zu finden
function findDtoDirectory(filename) {
const pathParts = filename.split(path.sep);
const dtoIndex = pathParts.findIndex(part => part === "dto");
if (dtoIndex === -1) {
return null;
}
// Konstruiere den Pfad bis zum dto-Verzeichnis
return pathParts.slice(0, dtoIndex + 1).join(path.sep);
}
// Hilfsmethode um Duplikate zu finden
function findDuplicateFiles(dtoDirectory, className, currentFile) {
const duplicateFiles = [];
try {
// Rekursiv durchsuche das dto-Verzeichnis
const searchDirectory = (dir) => {
if (!fs.existsSync(dir)) {
return;
}
const items = fs.readdirSync(dir);
for (const item of items) {
const fullPath = path.join(dir, item);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
// Rekursiv in Unterverzeichnisse suchen
searchDirectory(fullPath);
} else if (stat.isFile() && item.endsWith('.ts')) {
// Überspringe die aktuelle Datei
if (fullPath === currentFile) {
continue;
}
try {
const content = fs.readFileSync(fullPath, "utf8");
// Suche nach der Klasse mit dem gleichen Namen
const classRegex = new RegExp(`export\\s+(default\\s+)?class\\s+${className}\\b`);
if (classRegex.test(content)) {
duplicateFiles.push(fullPath);
}
} catch (error) {
// Ignoriere Dateien, die nicht gelesen werden können
continue;
}
}
}
};
searchDirectory(dtoDirectory);
} catch (error) {
// Ignoriere Fehler beim Durchsuchen der Dateien
return [];
}
return duplicateFiles;
}
export default noDtoDuplicatesRule;