ESLint blanket-exempted every *.spec.ts from the any ban, and no gate type-checked spec files at all (ng test is transpile-only), so a wrong cast in a test could never fail the build. 76 `as any` + 12 `as Extract<>` state-narrowing casts in the three biggest wizard specs read one variant's fields off a whole-union value: if the reducer returned the wrong variant, the assertion silently read undefined instead of failing. expectTag(state, tag) (libs/shared/src/testing/expect-tag.ts) asserts and narrows in one call, replacing every one of those casts. Removes the spec-file any exemption, adds `npm run typecheck` (tsc --noEmit over each project's tsconfig.spec.json) to CI, and forbids production code from importing libs/shared/src/testing via dependency-cruiser. Backend: AanvraagBuilder now models ZaakUrl (closing the last post-Build() mutation) and guards AtStep; null-forgiving `!` on endpoint assertions replaced with Assert.NotNull so a null DTO fails by name, not NullReferenceException. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
52 lines
2.2 KiB
JavaScript
52 lines
2.2 KiB
JavaScript
import tseslint from 'typescript-eslint';
|
|
import angular from 'angular-eslint';
|
|
|
|
/**
|
|
* ESLint now owns only the rules that are NOT dependency-graph shaped: no `any`, and
|
|
* template accessibility. The architecture's **boundary** rules — bounded-context
|
|
* direction (herregistratie → registratie → shared, auth/brief/beheer → shared; shared
|
|
* depends on nothing), `domain/` framework-freedom, `contracts/` purity, `ui ↛
|
|
* infrastructure`, and ApiClient confinement — moved to **dependency-cruiser** (WP-38,
|
|
* `.dependency-cruiser.base.js` + one thin per-app config, WP-67): one declarative source
|
|
* (per app) that also emits the architecture graph
|
|
* (`npm run dep:graph`) and is enforced by `npm run dep:check` (in CI). That replaced the
|
|
* per-context `no-restricted-imports` blocks that had to be hand-copied (and had left
|
|
* `herregistratie` uncovered).
|
|
*/
|
|
export default [
|
|
{
|
|
ignores: [
|
|
'dist/**',
|
|
'node_modules/**',
|
|
'storybook-static*/**',
|
|
'.angular/**',
|
|
'coverage/**',
|
|
'backend/**',
|
|
// Generated client — owns its own /* eslint-disable */ header.
|
|
'libs/shared/src/infrastructure/api-client.ts',
|
|
],
|
|
},
|
|
{
|
|
files: ['{apps,libs}/**/*.ts'],
|
|
languageOptions: {
|
|
parser: tseslint.parser,
|
|
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
|
|
},
|
|
plugins: { '@typescript-eslint': tseslint.plugin },
|
|
rules: { '@typescript-eslint/no-explicit-any': 'error' },
|
|
// This repo has no .html files — every template is inline. This processor
|
|
// extracts each component's template string into a virtual `*.html` file,
|
|
// which the template-a11y block below (`files: ['{apps,libs}/**/*.html']`) then lints.
|
|
processor: angular.processInlineTemplates,
|
|
},
|
|
|
|
// Template a11y (WP-17): the official angular-eslint accessibility bundle
|
|
// (alt-text, label-has-associated-control, click/mouse-events-have-key-events,
|
|
// interactive-supports-focus, valid-aria, no-autofocus, and more) linting the
|
|
// virtual `.html` files the processor above extracts from inline templates.
|
|
...angular.configs.templateAccessibility.map((c) => ({
|
|
...c,
|
|
files: ['{apps,libs}/**/*.html'],
|
|
})),
|
|
];
|