UNPKG

@addon24/eslint-config

Version:

ESLint configuration rules for WorldOfTextcraft projects - Centralized configuration for all project types

163 lines (146 loc) 5.63 kB
/** * @fileoverview Enforce that Entities can only be initialized in DTO fromEntity methods * @author WorldOfTextcraft Team */ //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ /** @type {import('eslint').Rule.RuleModule} */ export default { meta: { type: "problem", docs: { description: "Entities dürfen nur in DTO fromEntity-Methoden manuell initialisiert werden", category: "Architecture", recommended: true, }, fixable: null, schema: [], messages: { entityInitializationForbidden: "Manuelle Entity-Initialisierung 'new {{entityName}}()' ist nur in DTO fromEntity, fromEntityArray und toEntity-Methoden erlaubt", entityPropertyAssignmentForbidden: "Manuelle Property-Zuweisung an Entity '{{entityName}}' ist nur in DTO fromEntity, fromEntityArray und toEntity-Methoden erlaubt", useRepositoryCreate: "Verwende repository.create() oder DTO.fromEntity() statt manueller Entity-Initialisierung", }, }, create(context) { //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- const filename = context.getFilename(); const isServiceFile = (filename.includes("/service/") && filename.endsWith(".ts") && !filename.includes("test")) || filename.includes("test-fixtures"); const isDtoFile = filename.includes("/dto/") && filename.endsWith(".ts"); const isEntityFile = filename.includes("/entity/") && filename.endsWith(".ts"); const isTestFixture = filename.includes("test-fixtures"); const isInvalidTestFixture = filename.includes("InvalidEntityFactoryPattern"); /** * Check if we are in a fromEntity method * @param {ASTNode} node - The current node * @returns {boolean} True if in fromEntity method */ function isInFromEntityMethod(node) { let current = node; while (current && current.parent) { if (current.type === "MethodDefinition" && current.static === true && current.key?.name === "fromEntity") { return true; } current = current.parent; } return false; } /** * Check if we are in a fromEntityArray method * @param {ASTNode} node - The current node * @returns {boolean} True if in fromEntityArray method */ function isInFromEntityArrayMethod(node) { let current = node; while (current && current.parent) { if (current.type === "MethodDefinition" && current.static === true && current.key?.name === "fromEntityArray") { return true; } current = current.parent; } return false; } /** * Check if we are in a toEntity method * @param {ASTNode} node - The current node * @returns {boolean} True if in toEntity method */ function isInToEntityMethod(node) { let current = node; while (current && current.parent) { if (current.type === "MethodDefinition" && current.static === true && current.key?.name === "toEntity") { return true; } current = current.parent; } return false; } /** * Check if we are in a DTO fromEntity method * @param {ASTNode} node - The current node * @returns {boolean} True if in DTO fromEntity method */ function isInDtoFromEntityMethod(node) { return isDtoFile && (isInFromEntityMethod(node) || isInFromEntityArrayMethod(node) || isInToEntityMethod(node)); } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { // Überwache new Entity() Aufrufe NewExpression(node) { // Ignoriere Test-Fixtures, außer für InvalidEntityFactoryPattern if (isTestFixture && !isInvalidTestFixture) { return; } const entityName = node.callee?.name; // Prüfe ob es eine Entity ist (Name endet mit "Entity") if (entityName && entityName.endsWith("Entity")) { // Erlaube nur in DTO fromEntity-Methoden if (!isInDtoFromEntityMethod(node)) { context.report({ node, messageId: "entityInitializationForbidden", data: { entityName, }, }); } } }, // Überwache Property-Zuweisungen an Entities AssignmentExpression(node) { // Ignoriere Test-Fixtures, außer für InvalidEntityFactoryPattern if (isTestFixture && !isInvalidTestFixture) { return; } if (isServiceFile || isEntityFile) { // Prüfe ob links eine Entity-Variable ist (kann auch camelCase sein) if (node.left.type === "MemberExpression" && node.left.object?.name && (node.left.object.name.endsWith("Entity") || node.left.object.name.match(/^[a-z][a-zA-Z]*Entity$/))) { // Erlaube nur in DTO fromEntity-Methoden if (!isInDtoFromEntityMethod(node)) { context.report({ node, messageId: "entityPropertyAssignmentForbidden", data: { entityName: node.left.object.name, }, }); } } } }, }; }, };