waffensachkunde

Waffensachkunde – Lernsoftware für die Sachkundeprüfung nach § 7 WaffG. Barrierefrei, offline, EUPL-1.2.

/ app eslint.config.mjs

5,5 KB Rohdatei
app/eslint.config.mjs — 161 Zeilen
1 import js from '@eslint/js';
2 import { defineConfig, globalIgnores } from 'eslint/config';
3 import prettierAus from 'eslint-config-prettier';
4 import jsxA11y from 'eslint-plugin-jsx-a11y';
5 import reactHooks from 'eslint-plugin-react-hooks';
6 import reactRefresh from 'eslint-plugin-react-refresh';
7 import globals from 'globals';
8 import tseslint from 'typescript-eslint';
9
10 export default defineConfig([
11 globalIgnores([
12 'out/**',
13 'dist/**',
14 'release/**',
15 'build/**',
16 'node_modules/**',
17 'coverage/**',
18 'playwright-report/**',
19 'test-results/**',
20 ]),
21
22 js.configs.recommended,
23
24 // ── Typbewusste Regeln (nur für TypeScript-Dateien) ──────────────────
25 {
26 files: ['**/*.{ts,tsx}'],
27 extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked],
28 languageOptions: {
29 parserOptions: {
30 projectService: true,
31 tsconfigRootDir: import.meta.dirname,
32 },
33 },
34 },
35
36 /* Diese Konfigurationsdatei selbst wird ohne Typinformationen geprüft:
37 mehrere ESLint-Plugins liefern keine Typdeklarationen mit, was sonst
38 nur Rauschen aus `no-unsafe-*` erzeugen würde. */
39 {
40 files: ['**/*.{js,mjs,cjs}'],
41 languageOptions: {
42 globals: { ...globals.node },
43 },
44 },
45
46 // ── Main- und Preload-Prozess (Node-Umgebung) ────────────────────────
47 {
48 files: ['src/main/**/*.ts', 'src/preload/**/*.ts', 'e2e/**/*.ts', '*.config.ts'],
49 languageOptions: {
50 globals: { ...globals.node },
51 },
52 },
53
54 // ── Renderer (Browser-Umgebung, React) ───────────────────────────────
55 {
56 files: ['src/renderer/**/*.{ts,tsx}', 'tests/**/*.{ts,tsx}'],
57 languageOptions: {
58 globals: { ...globals.browser },
59 },
60 plugins: {
61 'react-hooks': reactHooks,
62 'react-refresh': reactRefresh,
63 },
64 rules: {
65 ...reactHooks.configs.recommended.rules,
66 'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
67 },
68 },
69
70 /* Der Renderer läuft in der Sandbox und hat keinerlei Node-Zugriff.
71 tsconfig.web.json lädt die Node-Typen trotzdem mit – `AnwendungsInfo`
72 in src/shared/ipc.ts benennt die Plattform als `NodeJS.Platform`.
73 Diese Regel verhindert, dass dadurch versehentlich Node-APIs in
74 Renderer-Code landen, die erst zur Laufzeit knallen würden. */
75 {
76 files: ['src/renderer/**/*.{ts,tsx}'],
77 rules: {
78 'no-restricted-imports': [
79 'error',
80 {
81 patterns: [
82 {
83 group: ['node:*', 'fs', 'path', 'child_process', 'electron'],
84 message:
85 'Der Renderer hat keinen Node-Zugriff. Bitte einen typisierten IPC-Kanal in src/shared/ipc.ts ergänzen.',
86 },
87 ],
88 },
89 ],
90 },
91 },
92
93 /* ── Barrierefreiheit ────────────────────────────────────────────────
94 `jsx-a11y` ist hier keine Kür: Barrierefreiheit ist Definition of Done.
95 Deshalb der strikte Regelsatz – Verstöße sind Fehler, keine Warnungen. */
96 {
97 files: ['src/renderer/**/*.tsx', 'tests/**/*.tsx'],
98 plugins: { 'jsx-a11y': jsxA11y },
99 rules: jsxA11y.flatConfigs.strict.rules,
100 },
101
102 // ── Tests ────────────────────────────────────────────────────────────
103 {
104 files: ['tests/**/*.{ts,tsx}', 'e2e/**/*.ts'],
105 rules: {
106 // In Tests sind bewusste Nicht-Null-Zusicherungen praktikabel.
107 '@typescript-eslint/no-non-null-assertion': 'off',
108 },
109 },
110
111 /* ── Die Konsolenwache darf niemand versehentlich umgehen ────────────
112 `e2e/konsolenwache.ts` hängt an `test` zwei automatische Fixtures, die
113 jede Konsolenausgabe der laufenden Anwendung auffangen. Wer `test`
114 wieder direkt von `@playwright/test` bezieht, bekommt sie nicht – und
115 zwar lautlos: Die Suite läuft grün weiter und hört nur eben nicht mehr
116 zu. Genau diese Art von stiller Lücke war der Grund, warum der
117 CSP-Konsolenfehler jahrelang unbemerkt bei jedem Start auflief. */
118 {
119 files: ['e2e/**/*.spec.ts'],
120 rules: {
121 'no-restricted-imports': [
122 'error',
123 {
124 paths: [
125 {
126 name: '@playwright/test',
127 importNames: ['test'],
128 message:
129 '`test` bitte aus ./konsolenwache beziehen – nur darüber hört jemand die Konsole der Anwendung ab.',
130 },
131 ],
132 },
133 ],
134 },
135 },
136
137 // ── Projektweite Verschärfungen ──────────────────────────────────────
138 {
139 files: ['**/*.{ts,tsx}'],
140 rules: {
141 '@typescript-eslint/consistent-type-imports': [
142 'error',
143 { prefer: 'type-imports', fixStyle: 'inline-type-imports' },
144 ],
145 '@typescript-eslint/no-unused-vars': [
146 'error',
147 {
148 argsIgnorePattern: '^_',
149 varsIgnorePattern: '^_',
150 caughtErrors: 'all',
151 caughtErrorsIgnorePattern: '^_',
152 },
153 ],
154 'no-console': ['warn', { allow: ['warn', 'error', 'info'] }],
155 eqeqeq: ['error', 'always', { null: 'ignore' }],
156 },
157 },
158
159 // Muss zuletzt stehen: schaltet alle Regeln ab, die mit Prettier kollidieren.
160 prettierAus,
161 ]);