@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,174 @@
1
+ /**
2
+ * ESLint-Regel: API-Methodenaufrufe müssen korrekte Typen verwenden
3
+ *
4
+ * Diese Regel stellt sicher, dass:
5
+ * 1. API-Methodenaufrufe einen generischen Typ haben
6
+ * 2. Keine doppelte ApiResponseDto-Verschachtelung verwendet wird (ApiResponseDto<ApiResponseDto<T>>)
7
+ * 3. Korrekte Error-Handling-Patterns verwendet werden
8
+ *
9
+ * Beispiele:
10
+ * ✅ Erlaubt: api.get<{ data: SomeType }>()
11
+ * ❌ Verboten: api.get() (ohne Generics)
12
+ * ❌ Verboten: api.get<ApiResponseDto<SomeType>>() (doppelte Verschachtelung)
13
+ */
14
+
15
+ export default {
16
+ rules: {
17
+ "require-api-response-dto": {
18
+ meta: {
19
+ type: "problem",
20
+ docs: {
21
+ description: "Ensure correct API method call patterns",
22
+ category: "Best Practices",
23
+ recommended: true,
24
+ },
25
+ schema: [],
26
+ messages: {
27
+ noNestedApiResponseDto: "API-Methodenaufruf '{{methodName}}' sollte den Datentyp direkt verwenden, nicht ApiResponseDto<T>. Der ApiClient gibt bereits ApiResponseDto<T> zurück",
28
+ noGenericType: "API-Methodenaufruf '{{methodName}}' muss einen generischen Typ haben",
29
+ useIsSuccessMethod: "Verwende nicht '{{pattern}}' für API-Response-Prüfung. Nutze stattdessen 'response.isSuccess()' und behandle Fehler mit 'response.getError()'",
30
+ noGenericErrorMessage: "Verwende keine generische Fehlermeldung '{{message}}'. Erstelle eine spezifische, kontextualisierte Nachricht",
31
+ },
32
+ },
33
+ create (context) {
34
+ // API-Methoden, die überwacht werden sollen
35
+ const apiMethods = ["get", "post", "put", "delete", "patch"];
36
+
37
+ // Verbotene Patterns für Datenprüfung (nur ohne vorherige isSuccess() Prüfung)
38
+ const forbiddenDataPatterns = ["!rawResponse", "!rawData"];
39
+
40
+
41
+
42
+ // Verbotene generische Fehlermeldungen
43
+ const forbiddenErrorMessages = [
44
+ "Keine Daten erhalten",
45
+ "Unerwarteter Fehler: Keine Daten in erfolgreicher Response",
46
+ "Fehler aufgetreten"
47
+ ];
48
+
49
+ return {
50
+ CallExpression (node) {
51
+ // Prüfe nur API-Methodenaufrufe
52
+ if (!isApiMethodCall(node, apiMethods)) {
53
+ return;
54
+ }
55
+
56
+ const methodName = node.callee.property.name;
57
+
58
+ // Prüfe auf doppelte ApiResponseDto-Verschachtelung (nur wenn TypeParameter vorhanden)
59
+ if (hasTypeParameters(node)) {
60
+ const firstTypeParam = node.typeParameters.params[0];
61
+ if (isApiResponseDtoType(firstTypeParam)) {
62
+ context.report({
63
+ node,
64
+ messageId: "noNestedApiResponseDto",
65
+ data: { methodName },
66
+ });
67
+ }
68
+ }
69
+ // Momentan deaktiviert: Generics-Prüfung, da sie zu viele false positives erzeugt
70
+ // TODO: Später aktivieren wenn TypeScript-Parser-Integration verbessert ist
71
+ },
72
+
73
+ // Prüfe auf verbotene Data-Checking-Patterns
74
+ UnaryExpression (node) {
75
+ if (node.operator === "!" && node.argument) {
76
+ const source = context.getSourceCode().getText(node.argument);
77
+
78
+ // Prüfe nur auf verbotene rawResponse/rawData patterns
79
+ if (forbiddenDataPatterns.some(pattern => source.includes(pattern.replace("!", "")))) {
80
+ context.report({
81
+ node,
82
+ messageId: "useIsSuccessMethod",
83
+ data: { pattern: `!${source}` },
84
+ });
85
+ }
86
+
87
+ // Erlaube !data und !data.property nach einer isSuccess() Prüfung
88
+ // Diese werden als legitime Validierungen angesehen
89
+ }
90
+ },
91
+
92
+ // Prüfe auf generische Fehlermeldungen
93
+ Literal (node) {
94
+ if (typeof node.value === "string" && forbiddenErrorMessages.includes(node.value)) {
95
+ context.report({
96
+ node,
97
+ messageId: "noGenericErrorMessage",
98
+ data: { message: node.value },
99
+ });
100
+ }
101
+ },
102
+ };
103
+ },
104
+ },
105
+ },
106
+ };
107
+
108
+ /**
109
+ * Prüft ob es sich um einen API-Methodenaufruf handelt
110
+ */
111
+ function isApiMethodCall (node, apiMethods) {
112
+ return (
113
+ node.callee.type === "MemberExpression" &&
114
+ node.callee.property &&
115
+ apiMethods.includes(node.callee.property.name) &&
116
+ node.callee.object &&
117
+ node.callee.object.type === "Identifier" &&
118
+ (node.callee.object.name.toLowerCase().includes("api") ||
119
+ node.callee.object.name === "api")
120
+ );
121
+ }
122
+
123
+ /**
124
+ * Prüft ob der Aufruf generische Type-Parameter hat
125
+ */
126
+ function hasTypeParameters (node) {
127
+ return (
128
+ node.typeParameters &&
129
+ node.typeParameters.params &&
130
+ node.typeParameters.params.length > 0
131
+ );
132
+ }
133
+
134
+ /**
135
+ * Prüft ob der Typ ein ApiResponseDto<T> ist
136
+ */
137
+ function isApiResponseDtoType (typeNode) {
138
+ // Muss TSTypeReference sein
139
+ if (typeNode.type !== "TSTypeReference") {
140
+ return false;
141
+ }
142
+
143
+ // Muss typeName haben
144
+ if (!typeNode.typeName) {
145
+ return false;
146
+ }
147
+
148
+ // Prüfe den Namen
149
+ const typeName = typeNode.typeName.name;
150
+ return typeName === "ApiResponseDto";
151
+ }
152
+
153
+ /**
154
+ * Extrahiert einen String-Representation des Typs für Fehlermeldungen
155
+ */
156
+ function getTypeString (typeNode) {
157
+ if (typeNode.type === "TSTypeReference" && typeNode.typeName) {
158
+ const baseName = typeNode.typeName.name;
159
+ if (typeNode.typeParameters && typeNode.typeParameters.params.length > 0) {
160
+ return `${baseName}<...>`;
161
+ }
162
+ return baseName;
163
+ }
164
+
165
+ if (typeNode.type === "TSTypeLiteral") {
166
+ return "{ ... }";
167
+ }
168
+
169
+ if (typeNode.type === "TSArrayType") {
170
+ return "Array<...>";
171
+ }
172
+
173
+ return typeNode.type || "unknown";
174
+ }
@@ -0,0 +1,142 @@
1
+ const authGuardRequiredRule = {
2
+ meta: {
3
+ type: "problem",
4
+ docs: {
5
+ description: "Erfordert AuthGuard für alle Controller außer konfigurierten Ausnahmen",
6
+ category: "Security",
7
+ recommended: true,
8
+ },
9
+ fixable: null,
10
+ schema: [
11
+ {
12
+ type: "object",
13
+ properties: {
14
+ exemptDirectories: {
15
+ type: "array",
16
+ items: {
17
+ type: "string"
18
+ },
19
+ default: ["/Admin/", "/OAuth/"]
20
+ },
21
+ exemptControllers: {
22
+ type: "array",
23
+ items: {
24
+ type: "string"
25
+ },
26
+ default: ["HealthController.ts", "MetricsController.ts", "BaseController.ts"]
27
+ }
28
+ },
29
+ additionalProperties: false
30
+ }
31
+ ],
32
+ messages: {
33
+ missingAuthGuard: "Controller '{{controllerName}}' muss @UseGuards(AuthGuard) verwenden. Importiere AuthGuard und füge @UseGuards(AuthGuard) vor der Controller-Klasse hinzu.",
34
+ missingAuthGuardImport: "Controller '{{controllerName}}' muss AuthGuard importieren: import AuthGuard from '@/guards/AuthGuard';"
35
+ }
36
+ },
37
+
38
+
39
+ create(context) {
40
+ const options = context.options[0] || {};
41
+ const exemptDirectories = options.exemptDirectories || ["/Admin/", "/OAuth/"];
42
+ const exemptControllers = options.exemptControllers || ["HealthController.ts", "MetricsController.ts", "BaseController.ts"];
43
+
44
+ const filename = context.getFilename();
45
+
46
+ // Prüfe ob es sich um einen Controller handelt
47
+ if (!filename.includes("Controller.ts") || filename.includes("__tests__")) {
48
+ return {};
49
+ }
50
+
51
+ // Automatisch BaseController ausschließen
52
+ if (filename.includes("BaseController.ts")) {
53
+ return {};
54
+ }
55
+
56
+ // Prüfe Ausnahme-Verzeichnisse
57
+ const isExemptDirectory = exemptDirectories.some(dir => filename.includes(dir));
58
+ if (isExemptDirectory) {
59
+ return {};
60
+ }
61
+
62
+ // Prüfe Ausnahme-Controller
63
+ const isExemptController = exemptControllers.some(controller => filename.endsWith(controller));
64
+ if (isExemptController) {
65
+ return {};
66
+ }
67
+
68
+ let hasAuthGuardImport = false;
69
+ let hasUseGuardsDecorator = false;
70
+ let hasAuthGuardInUseGuards = false;
71
+ let controllerClassName = "";
72
+
73
+ return {
74
+ ImportDeclaration(node) {
75
+ if (node.source.value === "@/guards/AuthGuard") {
76
+ hasAuthGuardImport = true;
77
+ }
78
+ },
79
+
80
+ ClassDeclaration(node) {
81
+ if (node.id && node.id.name.endsWith("Controller")) {
82
+ controllerClassName = node.id.name;
83
+
84
+ // Prüfe @UseGuards Decorator
85
+ if (node.decorators) {
86
+ for (const decorator of node.decorators) {
87
+ if (decorator.expression &&
88
+ decorator.expression.type === "CallExpression" &&
89
+ decorator.expression.callee &&
90
+ decorator.expression.callee.name === "UseGuards") {
91
+
92
+ hasUseGuardsDecorator = true;
93
+
94
+ // Prüfe ob AuthGuard in den Argumenten ist
95
+ for (const arg of decorator.expression.arguments) {
96
+ if (arg.name === "AuthGuard") {
97
+ hasAuthGuardInUseGuards = true;
98
+ break;
99
+ }
100
+ }
101
+ break;
102
+ }
103
+ }
104
+ }
105
+ }
106
+ },
107
+
108
+ "Program:exit"() {
109
+ if (controllerClassName) {
110
+ // Prüfe fehlende Imports
111
+ if (!hasAuthGuardImport) {
112
+ context.report({
113
+ loc: { line: 1, column: 0 },
114
+ messageId: "missingAuthGuardImport",
115
+ data: {
116
+ controllerName: controllerClassName
117
+ }
118
+ });
119
+ return;
120
+ }
121
+
122
+ // Prüfe fehlende @UseGuards(AuthGuard)
123
+ if (!hasUseGuardsDecorator || !hasAuthGuardInUseGuards) {
124
+ context.report({
125
+ loc: { line: 1, column: 0 },
126
+ messageId: "missingAuthGuard",
127
+ data: {
128
+ controllerName: controllerClassName
129
+ }
130
+ });
131
+ }
132
+ }
133
+ }
134
+ };
135
+ }
136
+ };
137
+
138
+ export default {
139
+ rules: {
140
+ 'auth-guard-required': authGuardRequiredRule,
141
+ },
142
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Backend Specific Rules
3
+ *
4
+ * Backend-spezifische Regeln für Restriktionen und Sicherheit
5
+ */
6
+
7
+ export default {
8
+ rules: {
9
+ // Backend-spezifische Regeln
10
+ "no-restricted-syntax": [
11
+ "error",
12
+ {
13
+ "selector": "MemberExpression[object.type='MemberExpression'][object.object.type='MetaProperty'][object.object.meta.name='import'][object.object.property.name='meta'][object.object.property.name='env']",
14
+ "message": "Direkte Verwendung von import.meta.env ist nicht erlaubt. Verwende stattdessen ConfigProvider.getXxx()."
15
+ },
16
+ {
17
+ "selector": "MemberExpression[object.type='MemberExpression'][object.object.name='process'][object.property.name='env']",
18
+ "message": "Direkte Verwendung von process.env ist nicht erlaubt. Verwende stattdessen ConfigProvider.getXxx()."
19
+ },
20
+ {
21
+ "selector": "MemberExpression[object.name='process'][property.name='env']",
22
+ "message": "Direkte Verwendung von process.env ist nicht erlaubt. Verwende stattdessen ConfigProvider.getXxx()."
23
+ }
24
+ ],
25
+
26
+ "no-restricted-globals": [
27
+ "error",
28
+ {
29
+ "name": "fetch",
30
+ "message": "Direkte Verwendung von fetch ist nicht erlaubt. Verwende stattdessen den ApiClient aus @echoes-of-order/api-client."
31
+ }
32
+ ],
33
+
34
+ // No-Comments-Regel ist deaktiviert, da sie Probleme verursacht
35
+ },
36
+ };