@echoes-of-order/eslint-config 1.121.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/CHANGELOG.md +1093 -0
  2. package/configs/.gitkeep +1 -0
  3. package/configs/admin.js +203 -0
  4. package/configs/api-client.js +46 -0
  5. package/configs/backend.js +895 -0
  6. package/configs/domains.js +123 -0
  7. package/configs/frontend.js +30 -0
  8. package/configs/image-server.js +26 -0
  9. package/configs/ionos-proxy.js +372 -0
  10. package/configs/nestjs.js +156 -0
  11. package/configs/node.js +92 -0
  12. package/configs/react.js +111 -0
  13. package/configs/wiki.js +42 -0
  14. package/index.js +39 -0
  15. package/package.json +85 -0
  16. package/rules/.gitkeep +1 -0
  17. package/rules/__tests__/analyze-relation-usage.test.js.disabled +300 -0
  18. package/rules/__tests__/complexity.test.js.disabled +300 -0
  19. package/rules/__tests__/enforce-dto-factory-in-services.integration.test.js +226 -0
  20. package/rules/__tests__/enforce-dto-factory-in-services.test.js +177 -0
  21. package/rules/__tests__/enforce-entity-dto-create-no-id.integration.test.js +18 -0
  22. package/rules/__tests__/enforce-function-argument-count.test.js.disabled +300 -0
  23. package/rules/__tests__/enforce-repository-token-handling.test.js +58 -0
  24. package/rules/__tests__/english-only-code-strings.test.js.disabled +300 -0
  25. package/rules/__tests__/eslint-rules.integration.test.ts +350 -0
  26. package/rules/__tests__/integration-test-controller-response-dto.js +261 -0
  27. package/rules/__tests__/integration-test-dto-factory-in-services.js +260 -0
  28. package/rules/__tests__/integration-test-no-entity-type-casting.js +161 -0
  29. package/rules/__tests__/integration-test-typeorm-naming-conventions.js +501 -0
  30. package/rules/__tests__/test-config.js +33 -0
  31. package/rules/admin-controller-security.js +180 -0
  32. package/rules/analyze-relation-usage.js +687 -0
  33. package/rules/api-response-dto.js +174 -0
  34. package/rules/auth-guard-required.js +142 -0
  35. package/rules/backend-specific.js +36 -0
  36. package/rules/best-practices.js +421 -0
  37. package/rules/complexity.js +20 -0
  38. package/rules/controller-architecture.js +340 -0
  39. package/rules/controller-naming-conventions.js +190 -0
  40. package/rules/controller-readonly-restriction.js +148 -0
  41. package/rules/controller-swagger-complete.js +312 -0
  42. package/rules/controller-swagger-docs.js +119 -0
  43. package/rules/controller-swagger-english.js +320 -0
  44. package/rules/coordinate-naming.js +132 -0
  45. package/rules/custom-mui-button.js +135 -0
  46. package/rules/dead-code-detection-backend.js +50 -0
  47. package/rules/dead-code-detection-frontend.js +48 -0
  48. package/rules/dead-code-detection.js +71 -0
  49. package/rules/debug-controller-response-dto.js +79 -0
  50. package/rules/deprecate.js +8 -0
  51. package/rules/dto-annotation-property-consistency.js +111 -0
  52. package/rules/dto-entity-mapping-completeness.js +688 -0
  53. package/rules/dto-entity-swagger-separation.js +265 -0
  54. package/rules/dto-entity-type-consistency.js +352 -0
  55. package/rules/dto-entity-type-matching.js +519 -0
  56. package/rules/dto-naming-convention.js +98 -0
  57. package/rules/dto-visibility-modifiers.js +159 -0
  58. package/rules/enforce-api-versioning.js +122 -0
  59. package/rules/enforce-app-module-registration.js +179 -0
  60. package/rules/enforce-basecontroller.js +152 -0
  61. package/rules/enforce-body-request-dto.js +141 -0
  62. package/rules/enforce-controller-response-dto.js +349 -0
  63. package/rules/enforce-custom-error-classes.js +242 -0
  64. package/rules/enforce-database-transaction-safety.js +179 -0
  65. package/rules/enforce-dto-constructor.js +95 -0
  66. package/rules/enforce-dto-create-parameter-types.js +170 -0
  67. package/rules/enforce-dto-create-pattern.js +274 -0
  68. package/rules/enforce-dto-entity-creation.js +164 -0
  69. package/rules/enforce-dto-factory-in-services.js +188 -0
  70. package/rules/enforce-dto-from-entity-method.js +47 -0
  71. package/rules/enforce-dto-from-entity.js +314 -0
  72. package/rules/enforce-dto-naming-conventions.js +212 -0
  73. package/rules/enforce-dto-naming.js +176 -0
  74. package/rules/enforce-dto-usage-simple.js +114 -0
  75. package/rules/enforce-dto-usage.js +407 -0
  76. package/rules/enforce-eager-translation-loading.js +178 -0
  77. package/rules/enforce-entity-creation-pattern.js +137 -0
  78. package/rules/enforce-entity-dto-convert-method.js +157 -0
  79. package/rules/enforce-entity-dto-create-no-id.js +117 -0
  80. package/rules/enforce-entity-dto-extends-base.js +141 -0
  81. package/rules/enforce-entity-dto-from-request-dto-structure.js +113 -0
  82. package/rules/enforce-entity-dto-fromentity-complex.js +69 -0
  83. package/rules/enforce-entity-dto-fromentity-simple.js +69 -0
  84. package/rules/enforce-entity-dto-fromrequestdto-structure.js +262 -0
  85. package/rules/enforce-entity-dto-methods-restriction.js +159 -0
  86. package/rules/enforce-entity-dto-no-request-dto.js +102 -0
  87. package/rules/enforce-entity-dto-optional-auto-fields.js +101 -0
  88. package/rules/enforce-entity-dto-required-methods.js +248 -0
  89. package/rules/enforce-entity-factory-pattern.js +180 -0
  90. package/rules/enforce-entity-instantiation-in-toentity.js +125 -0
  91. package/rules/enforce-enum-for-playable-entities.js +95 -0
  92. package/rules/enforce-error-handling.js +257 -0
  93. package/rules/enforce-explicit-dto-types.js +118 -0
  94. package/rules/enforce-from-request-dto-usage.js +62 -0
  95. package/rules/enforce-generic-entity-dto.js +71 -0
  96. package/rules/enforce-inject-decorator.js +133 -0
  97. package/rules/enforce-lazy-type-loading.js +170 -0
  98. package/rules/enforce-module-existence.js +157 -0
  99. package/rules/enforce-nonentity-dto-create.js +107 -0
  100. package/rules/enforce-playable-entity-naming.js +108 -0
  101. package/rules/enforce-repository-token-handling.js +92 -0
  102. package/rules/enforce-request-dto-no-entity-dto.js +201 -0
  103. package/rules/enforce-request-dto-required-fields.js +217 -0
  104. package/rules/enforce-result-pattern.js +45 -0
  105. package/rules/enforce-service-relation-loading.js +116 -0
  106. package/rules/enforce-test-coverage.js +96 -0
  107. package/rules/enforce-toentity-conditional-assignment.js +132 -0
  108. package/rules/enforce-translations-required.js +203 -0
  109. package/rules/enforce-typeorm-naming-conventions.js +366 -0
  110. package/rules/enforce-vite-health-metrics.js +240 -0
  111. package/rules/entity-required-properties.js +321 -0
  112. package/rules/entity-to-dto-test.js +73 -0
  113. package/rules/enum-database-validation.js +149 -0
  114. package/rules/errors.js +190 -0
  115. package/rules/es6.js +204 -0
  116. package/rules/eslint-plugin-no-comments.js +44 -0
  117. package/rules/filename-class-name-match.js +62 -0
  118. package/rules/forbid-fromentity-outside-entity-folder.js +237 -0
  119. package/rules/function-params-newline.js +111 -0
  120. package/rules/imports.js +264 -0
  121. package/rules/jest.js +13 -0
  122. package/rules/jsx.js +16 -0
  123. package/rules/max-classes-per-file.js +49 -0
  124. package/rules/multiline-formatting.js +146 -0
  125. package/rules/no-blank-lines-between-decorators-and-properties.js +95 -0
  126. package/rules/no-comments.js +62 -0
  127. package/rules/no-dto-constructors.js +126 -0
  128. package/rules/no-dto-default-values.js +220 -0
  129. package/rules/no-dto-duplicates.js +127 -0
  130. package/rules/no-dto-in-entity.js +99 -0
  131. package/rules/no-dynamic-import-in-types.js +71 -0
  132. package/rules/no-dynamic-imports-in-controllers.js +95 -0
  133. package/rules/no-entity-imports-in-controllers.js +101 -0
  134. package/rules/no-entity-in-swagger-docs.js +139 -0
  135. package/rules/no-entity-type-casting.js +104 -0
  136. package/rules/no-fetch.js +77 -0
  137. package/rules/no-import-meta-env.js +151 -0
  138. package/rules/no-inline-styles.js +5 -0
  139. package/rules/no-magic-values.js +85 -0
  140. package/rules/no-partial-type.js +168 -0
  141. package/rules/no-relative-imports.js +31 -0
  142. package/rules/no-tsyringe.js +181 -0
  143. package/rules/no-type-assertion.js +175 -0
  144. package/rules/no-undefined-entity-properties.js +121 -0
  145. package/rules/node.js +44 -0
  146. package/rules/perfectionist.js +50 -0
  147. package/rules/performance-minimal.js +155 -0
  148. package/rules/performance.js +44 -0
  149. package/rules/pino-logger-format.js +200 -0
  150. package/rules/prefer-dto-classes.js +112 -0
  151. package/rules/prefer-dto-create-method.js +225 -0
  152. package/rules/promises.js +17 -0
  153. package/rules/react-hooks.js +15 -0
  154. package/rules/react.js +28 -0
  155. package/rules/regexp.js +70 -0
  156. package/rules/require-dto-response.js +81 -0
  157. package/rules/require-valid-relations.js +388 -0
  158. package/rules/result-pattern.js +162 -0
  159. package/rules/security.js +37 -0
  160. package/rules/service-architecture.js +148 -0
  161. package/rules/sonarjs.js +26 -0
  162. package/rules/strict.js +7 -0
  163. package/rules/style.js +611 -0
  164. package/rules/stylistic.js +93 -0
  165. package/rules/typeorm-column-type-validation.js +224 -0
  166. package/rules/typescript-advanced.js +113 -0
  167. package/rules/typescript-core.js +111 -0
  168. package/rules/typescript.js +146 -0
  169. package/rules/unicorn.js +168 -0
  170. package/rules/variables.js +51 -0
  171. package/rules/websocket-architecture.js +115 -0
@@ -0,0 +1,225 @@
1
+ // Neue Regel für DTOs (erzwingt create Methode)
2
+ import { ESLintUtils } from "@typescript-eslint/utils";
3
+
4
+ const createRule = ESLintUtils.RuleCreator(
5
+ (name) => `https://github.com/echoes-of-order/Echoes of Order/blob/main/docs/eslint-rules.md#${name}`
6
+ );
7
+
8
+ export const enforceDtoCreateMethod = createRule({
9
+ name: "enforce-dto-create-method",
10
+ meta: {
11
+ type: "problem",
12
+ docs: {
13
+ description: "Enforce create method for DTOs",
14
+ recommended: "error",
15
+ },
16
+ messages: {
17
+ missingCreateMethod: "DTOs must have a static create() method",
18
+ useCreateMethod: "DTOs must use create() method for initialization, not constructors or fromEntity()",
19
+ },
20
+ schema: [],
21
+ fixable: null,
22
+ },
23
+ defaultOptions: [],
24
+ create(context) {
25
+ const filename = context.getFilename();
26
+
27
+ // Apply to DTOs outside Entity folder
28
+ const isDtoFile = filename.includes("/dto/") && filename.endsWith("Dto.ts");
29
+ const isEntityDtoFile = filename.includes("/dto/Entity/");
30
+
31
+ // console.log(`File: ${filename}, isDtoFile: ${isDtoFile}, isEntityDtoFile: ${isEntityDtoFile}`);
32
+
33
+ if (!isDtoFile || isEntityDtoFile) {
34
+ return {};
35
+ }
36
+
37
+ // console.log(`Applying DTO rules to ${filename}`);
38
+
39
+ return {
40
+ ClassDeclaration(node) {
41
+ const className = node.id.name;
42
+
43
+ // Ausnahme für BaseEntityDto (abstrakte Base-Klasse)
44
+ if (className === "BaseEntityDto" && filename.endsWith("/dto/BaseEntityDto.ts")) {
45
+ return;
46
+ }
47
+
48
+ // console.log(`Processing class: ${className}`);
49
+
50
+ // Check for create method - simple approach
51
+ const createMethod = node.body.body.find(member =>
52
+ member.type === "MethodDefinition" &&
53
+ member.static === true &&
54
+ member.key.name === "create"
55
+ );
56
+
57
+ // console.log(`Create method for ${className}: ${!!createMethod}`);
58
+
59
+ if (createMethod) {
60
+ // console.log(`✅ Allowing ${className} - has create method`);
61
+ // Don't report any errors for DTOs with create method
62
+ return;
63
+ }
64
+
65
+ // Only report error if no create method exists
66
+ console.log(`❌ ${className} missing create method`);
67
+ context.report({
68
+ node: node.id,
69
+ messageId: "missingCreateMethod",
70
+ });
71
+ },
72
+
73
+ // Allow all constructor calls in DTO files
74
+ NewExpression(node) {
75
+ const callee = node.callee;
76
+ if (callee.type === "Identifier" && callee.name.endsWith("Dto")) {
77
+ // Don't report any errors for DTO constructors
78
+ return;
79
+ }
80
+ },
81
+ };
82
+ },
83
+ });
84
+
85
+ // Entity-DTO Regel: Erzwingt fromEntity-Methode und verbietet Default-Werte
86
+ export const enforceDtoFromEntityMethod = createRule({
87
+ name: "enforce-dto-from-entity-method",
88
+ meta: {
89
+ type: "problem",
90
+ docs: {
91
+ description: "Enforce fromEntity method for Entity-DTOs and forbid default values",
92
+ recommended: "error",
93
+ },
94
+ messages: {
95
+ missingFromEntityMethod: "Entity-DTOs must have a static fromEntity(entity: EntityType) method",
96
+ noDefaultValues: "Entity-DTO properties must not have default values (use fromEntity() for initialization)",
97
+ noConstructor: "Entity-DTOs must not have constructors",
98
+ noCreateMethod: "Entity-DTOs must not have create() methods (use fromEntity() instead) - except for entity creation",
99
+ noHelperMethods: "Entity-DTOs must not have helper methods (use direct property assignment in fromEntity)",
100
+ useFromEntityMethod: "Entity-DTOs must use fromEntity() for initialization, not constructors or create()",
101
+ },
102
+ schema: [],
103
+ fixable: null,
104
+ },
105
+ defaultOptions: [],
106
+ create(context) {
107
+ const filename = context.getFilename();
108
+
109
+ // Nur für Entity-DTOs anwenden
110
+ const isEntityDtoFile = filename.includes("/dto/Entity/");
111
+
112
+ if (!isEntityDtoFile) {
113
+ return {};
114
+ }
115
+
116
+ return {
117
+ ClassDeclaration(node) {
118
+ const className = node.id.name;
119
+
120
+ // Prüfe auf fromEntity-Methode
121
+ const fromEntityMethod = node.body.body.find(member =>
122
+ member.type === "MethodDefinition" &&
123
+ member.static === true &&
124
+ member.key.name === "fromEntity"
125
+ );
126
+
127
+ // Prüfe auf create-Methode (verboten)
128
+ const createMethod = node.body.body.find(member =>
129
+ member.type === "MethodDefinition" &&
130
+ member.static === true &&
131
+ member.key.name === "create"
132
+ );
133
+
134
+ // Prüfe auf Constructor (verboten)
135
+ const constructor = node.body.body.find(member =>
136
+ member.type === "MethodDefinition" &&
137
+ member.kind === "constructor"
138
+ );
139
+
140
+ // Prüfe auf Helper-Methoden (verboten)
141
+ const helperMethods = node.body.body.filter(member =>
142
+ member.type === "MethodDefinition" &&
143
+ member.static === true &&
144
+ member.key.name !== "fromEntity" &&
145
+ member.key.name !== "fromEntityArray" &&
146
+ member.key.name !== "toEntity" &&
147
+ member.key.name !== "fromRequestDto" && // Explicitly allowed
148
+ member.key.name !== "create" && // Explicitly allowed for entity creation
149
+ !member.key.name.startsWith("set") &&
150
+ !member.key.name.startsWith("get")
151
+ );
152
+
153
+ // Fehlende fromEntity-Methode
154
+ if (!fromEntityMethod) {
155
+ context.report({
156
+ node: node.id,
157
+ messageId: "missingFromEntityMethod",
158
+ });
159
+ }
160
+
161
+ // create-Methode ist jetzt erlaubt für Entity-Erstellung
162
+
163
+ // Verbotener Constructor
164
+ if (constructor) {
165
+ context.report({
166
+ node: constructor,
167
+ messageId: "noConstructor",
168
+ });
169
+ }
170
+
171
+ // Verbotene Helper-Methoden
172
+ helperMethods.forEach(helperMethod => {
173
+ context.report({
174
+ node: helperMethod,
175
+ messageId: "noHelperMethods",
176
+ });
177
+ });
178
+ },
179
+
180
+ // Prüfe auf Default-Werte in Properties
181
+ PropertyDefinition(node) {
182
+ if (node.value !== null) {
183
+ context.report({
184
+ node: node,
185
+ messageId: "noDefaultValues",
186
+ });
187
+ }
188
+ },
189
+
190
+ // Prüfe auf direkte Constructor-Calls außerhalb von fromEntity und toEntity
191
+ NewExpression(node) {
192
+ const callee = node.callee;
193
+ if (callee.type === "Identifier" && callee.name.endsWith("EntityDto")) {
194
+ // Prüfe ob wir in einer fromEntity oder toEntity-Methode sind
195
+ let current = node;
196
+ let inAllowedMethod = false;
197
+
198
+ while (current && current.parent) {
199
+ if (current.type === "MethodDefinition" &&
200
+ current.static === true &&
201
+ (current.key.name === "fromEntity" || current.key.name === "toEntity" || current.key.name === "fromRequestDto" || current.key.name === "create")) {
202
+ inAllowedMethod = true;
203
+ break;
204
+ }
205
+ current = current.parent;
206
+ }
207
+
208
+ if (!inAllowedMethod) {
209
+ context.report({
210
+ node: node,
211
+ messageId: "useFromEntityMethod",
212
+ });
213
+ }
214
+ }
215
+ },
216
+ };
217
+ },
218
+ });
219
+
220
+ export default {
221
+ rules: {
222
+ "enforce-dto-create-method": enforceDtoCreateMethod,
223
+ "enforce-dto-from-entity-method": enforceDtoFromEntityMethod,
224
+ },
225
+ };
@@ -0,0 +1,17 @@
1
+ export default {
2
+ rules: {
3
+ "no-console": ["error", {
4
+ allow: ["warn", "error", "info"],
5
+ }],
6
+ "prefer-promise-reject-errors": ["error", { allowEmptyReject: false }],
7
+ "require-await": "error",
8
+ "no-return-await": "error",
9
+ "no-async-promise-executor": "error",
10
+ "no-await-in-loop": "error",
11
+ "no-promise-executor-return": "error",
12
+ "prefer-object-has-own": "error",
13
+ "logical-assignment-operators": ["error", "always"],
14
+ "no-unreachable-loop": "error",
15
+ "no-constant-binary-expression": "error",
16
+ },
17
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * React Hooks Rules
3
+ *
4
+ * React-Hooks-spezifische Regeln für Frontend-Projekte
5
+ */
6
+
7
+ export default {
8
+ rules: {
9
+ // React-Hooks-Regeln
10
+ "react-hooks/rules-of-hooks": "error",
11
+ "react-hooks/exhaustive-deps": "error",
12
+ },
13
+ };
14
+
15
+
package/rules/react.js ADDED
@@ -0,0 +1,28 @@
1
+ export default {
2
+ rules: {
3
+ "react-hooks/exhaustive-deps": "off",
4
+ "react/jsx-indent": [2, 2],
5
+ "react/display-name": "off",
6
+ "react/prefer-stateless-function": "error",
7
+ "react/prefer-es6-class": "error",
8
+ "react/jsx-closing-bracket-location": "error",
9
+ "react/jsx-closing-tag-location": "error",
10
+ "react/jsx-pascal-case": "error",
11
+ "react/jsx-tag-spacing": "error",
12
+ "react/jsx-boolean-value": "error",
13
+ "react/no-array-index-key": "error",
14
+ "react/no-string-refs": "error",
15
+ "react/jsx-wrap-multilines": "error",
16
+ "react/self-closing-comp": "error",
17
+ "react/require-render-return": "error",
18
+ "react/sort-comp": "error",
19
+ "react/no-is-mounted": "error",
20
+ "react/forbid-prop-types": "error",
21
+
22
+ // Dead Code Detection für React
23
+ "react/jsx-no-useless-fragment": ["error", {
24
+ "allowExpressions": true
25
+ }],
26
+ },
27
+ };
28
+
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Regexp Rules
3
+ *
4
+ * Performance und Sicherheit für reguläre Ausdrücke
5
+ * Ursprünglich aus dem Image-Server
6
+ */
7
+
8
+ export default {
9
+ rules: {
10
+ // Regexp-Regeln für Performance
11
+ "regexp/confusing-quantifier": "error",
12
+ "regexp/control-character-escape": "error",
13
+ "regexp/negation": "error",
14
+ "regexp/no-dupe-characters-character-class": "error",
15
+ "regexp/no-dupe-disjunctions": "error",
16
+ "regexp/no-empty-alternative": "error",
17
+ "regexp/no-empty-capturing-group": "error",
18
+ "regexp/no-empty-character-class": "error",
19
+ "regexp/no-empty-group": "error",
20
+ "regexp/no-empty-lookarounds-assertion": "error",
21
+ "regexp/no-escape-backspace": "error",
22
+ "regexp/no-invalid-regexp": "error",
23
+ "regexp/no-lazy-ends": "error",
24
+ "regexp/no-misleading-capturing-group": "error",
25
+ "regexp/no-misleading-unicode-character": "error",
26
+ "regexp/no-missing-g-flag": "error",
27
+ "regexp/no-potentially-useless-backreference": "error",
28
+ "regexp/no-super-linear-backtracking": "error",
29
+ "regexp/no-super-linear-move": "error",
30
+ "regexp/no-trivially-nested-assertion": "error",
31
+ "regexp/no-trivially-nested-quantifier": "error",
32
+ "regexp/no-unused-capturing-group": "error",
33
+ "regexp/no-useless-assertions": "error",
34
+ "regexp/no-useless-backreference": "error",
35
+ "regexp/no-useless-character-class": "error",
36
+ "regexp/no-useless-dollar-replacements": "error",
37
+ "regexp/no-useless-escape": "error",
38
+ "regexp/no-useless-flag": "error",
39
+ "regexp/no-useless-lazy": "error",
40
+ "regexp/no-useless-quantifier": "error",
41
+ "regexp/no-useless-range": "error",
42
+ "regexp/no-useless-two-nums-quantifier": "error",
43
+ "regexp/no-zero-quantifier": "error",
44
+ "regexp/optimal-lookaround-quantifier": "error",
45
+ "regexp/optimal-quantifier-concatenation": "error",
46
+ "regexp/prefer-lookaround": "error",
47
+ "regexp/prefer-named-backreference": "error",
48
+ "regexp/prefer-named-capture-group": "error",
49
+ "regexp/prefer-named-replacement": "error",
50
+ "regexp/prefer-plus-quantifier": "error",
51
+ "regexp/prefer-predefined-assertion": "error",
52
+ "regexp/prefer-quantifier": "error",
53
+ "regexp/prefer-range": "error",
54
+ "regexp/prefer-regexp-exec": "error",
55
+ "regexp/prefer-regexp-test": "error",
56
+ "regexp/prefer-result-array-groups": "error",
57
+ "regexp/prefer-set-operation": "error",
58
+ "regexp/prefer-star-quantifier": "error",
59
+ "regexp/prefer-unicode-codepoint-escapes": "error",
60
+ "regexp/require-unicode-regexp": "error",
61
+ "regexp/simplify-set-operations": "error",
62
+ "regexp/sort-alternatives": "error",
63
+ "regexp/sort-character-class-elements": "error",
64
+ "regexp/sort-flags": "error",
65
+ "regexp/strict": "error",
66
+ "regexp/use-ignore-case": "error",
67
+ },
68
+ };
69
+
70
+
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @fileoverview Verhindert die direkte Verwendung von Entities in Controller-Responses und erzwingt DTOs
3
+ */
4
+
5
+ "use strict";
6
+
7
+ const requireDtoResponseRule = {
8
+ meta: {
9
+ type: "problem",
10
+ docs: {
11
+ description: "Verhindert die direkte Verwendung von Entities in Controller-Responses und erzwingt DTOs",
12
+ category: "Security",
13
+ recommended: true,
14
+ },
15
+ fixable: null,
16
+ schema: [],
17
+ messages: {
18
+ entityInResponse: "Entity-Variable '{{variableName}}' darf nicht direkt in sendSuccess() verwendet werden. Controller müssen Entities zu DTOs konvertieren bevor sie als API-Response zurückgegeben werden.",
19
+ },
20
+ },
21
+
22
+ create(context) {
23
+ const filename = context.getFilename();
24
+
25
+ // Nur Controller-Dateien prüfen, außer Tests
26
+ if (!filename.includes("Controller.ts") || filename.includes("test") || filename.includes("spec")) {
27
+ return {};
28
+ }
29
+
30
+ // Entity-Pattern erkennen
31
+ function isEntityPattern(variableName) {
32
+ return (
33
+ variableName.endsWith("Definition") ||
34
+ variableName.endsWith("Entity") ||
35
+ variableName.endsWith("Model") ||
36
+ variableName.endsWith("Record") ||
37
+ variableName.endsWith("Instance") ||
38
+ variableName.startsWith("new") ||
39
+ variableName.includes("Entity") ||
40
+ variableName.includes("Definition")
41
+ );
42
+ }
43
+
44
+ return {
45
+ CallExpression(node) {
46
+ // Prüfe auf this.sendSuccess() Aufrufe
47
+ if (node.callee?.type === "MemberExpression" &&
48
+ node.callee.object?.type === "ThisExpression" &&
49
+ node.callee.property?.name === "sendSuccess") {
50
+
51
+ // Prüfe das zweite Argument (Response-Objekt)
52
+ if (node.arguments.length >= 2 &&
53
+ node.arguments[1]?.type === "ObjectExpression") {
54
+
55
+ const responseObject = node.arguments[1];
56
+
57
+ // Prüfe alle Properties im Response-Objekt
58
+ responseObject.properties.forEach(property => {
59
+ if (property.type === "Property" &&
60
+ property.value?.type === "Identifier") {
61
+
62
+ const variableName = property.value.name;
63
+
64
+ // Melde Entity-Patterns
65
+ if (isEntityPattern(variableName)) {
66
+ context.report({
67
+ node: property.value,
68
+ messageId: "entityInResponse",
69
+ data: { variableName }
70
+ });
71
+ }
72
+ }
73
+ });
74
+ }
75
+ }
76
+ }
77
+ };
78
+ }
79
+ };
80
+
81
+ export default requireDtoResponseRule;