@testgorilla/tgo-linting 4.0.0 → 5.1.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.
package/Readme.md CHANGED
@@ -8,11 +8,45 @@ Linting rules and code quality standards for TestGorilla projects.
8
8
  npm install @testgorilla/tgo-linting @angular-eslint/template-parser --save-dev
9
9
  ```
10
10
 
11
+ ## Compatibility
12
+
13
+ | tgo-linting | ESLint | angular-eslint | Angular |
14
+ | ----------- | --------------------- | -------------- | ------------------------------------------------ |
15
+ | 5.1+ | `^10.0.0` | 21.x | any (angular-eslint 21 bundles its own compiler) |
16
+ | 5.0 | `^9.0.0 \|\| ^10.0.0` | 21.x | any (angular-eslint 21 bundles its own compiler) |
17
+ | 4.x | `^8.57.0 \|\| ^9.0.0` | 20.x | any |
18
+
19
+ > **ESLint 9 support ended in 5.1.0.** 5.0.0 kept the `^9.0.0 || ^10.0.0` peer range so
20
+ > repos could adopt the preset before finishing their ESLint 10 migration. All consumers
21
+ > completed that migration alongside the Angular 21 upgrade, so 5.1.0 narrows the range to
22
+ > ESLint 10 only. Stay on 5.0.0 if you are still on ESLint 9 — and note that 5.0.0 also
23
+ > required an `eslint-plugin-rxjs-x` override to install cleanly on 9, which 5.1.0 no
24
+ > longer needs.
25
+
26
+ ### Upgrading to 5.1.0
27
+
28
+ 5.1.0 restores the `@eslint/js` recommended baseline in the `recommended()` preset. Up to
29
+ 5.0.0 the preset only spread the typescript-eslint configs, whose `eslint-recommended` slice
30
+ _disables_ the core rules TypeScript already covers but never _enables_ the rest — so core
31
+ rules such as `no-prototype-builtins`, `no-duplicate-case`, `no-async-promise-executor`,
32
+ `no-unsafe-optional-chaining` and `no-misleading-character-class` were silently inactive in
33
+ consumers. The same release cherry-picks `@angular-eslint/template/no-any` and
34
+ `template/no-duplicate-attributes` onto the HTML block.
35
+
36
+ No config change is needed, but expect new violations on first run after the bump. Dry-run
37
+ `npx eslint .` before merging the upgrade.
38
+
39
+ 5.1.0 also drops ESLint 9: both the `eslint` peer range and the bundled `@eslint/js`
40
+ dependency are now `^10.0.0`. `@eslint/js@10.0.1` itself declares an `eslint: ^10.0.0`
41
+ peer, so an ESLint 9 install would fail to resolve rather than degrade quietly.
42
+
11
43
  ## Usage
12
44
 
13
- This package supports both modern flat config (ESLint 9+) and legacy config formats (ESLint 8.x and below).
45
+ This package requires ESLint flat config (`eslint.config.js`/`.mjs`) and ESLint 10.
46
+ Support for legacy `.eslintrc.*` configs and ESLint 8 was removed in 5.0.0; ESLint 9
47
+ support ended in 5.1.0.
14
48
 
15
- ### Flat Config (ESLint 9+)
49
+ ### Flat Config
16
50
 
17
51
  **Recommended approach:**
18
52
 
@@ -44,51 +78,6 @@ export default [
44
78
  ];
45
79
  ```
46
80
 
47
- ### Legacy Config (ESLint 8.x and below)
48
-
49
- **Using the legacy preset:**
50
-
51
- ```javascript
52
- // .eslintrc.js
53
- const { legacy } = require('@testgorilla/tgo-linting');
54
-
55
- module.exports = {
56
- // Your base config
57
- extends: [
58
- // Your other extends
59
- ],
60
- plugins: ['tgo'],
61
- overrides: [
62
- {
63
- files: ['*.html'],
64
- parser: '@angular-eslint/template-parser',
65
- ...legacy,
66
- },
67
- ],
68
- };
69
- ```
70
-
71
- **Manual configuration:**
72
-
73
- ```javascript
74
- // .eslintrc.js
75
- module.exports = {
76
- plugins: ['tgo'],
77
- extends: [
78
- // Your other extends
79
- ],
80
- overrides: [
81
- {
82
- files: ['*.html'],
83
- parser: '@angular-eslint/template-parser',
84
- rules: {
85
- 'tgo/require-data-testid': 'warn', // Example rule configuration
86
- },
87
- },
88
- ],
89
- };
90
- ```
91
-
92
81
  ## Important Notes
93
82
 
94
83
  - **Template Parser Required:** The `tgo/require-data-testid` rule only works with HTML/Angular templates. You must configure `@angular-eslint/template-parser` for `.html` files.
@@ -98,8 +87,8 @@ module.exports = {
98
87
 
99
88
  ### Available Rules
100
89
 
101
- | Rule | Description |
102
- |------|-------------|
90
+ | Rule | Description |
91
+ | ------------------------- | ----------------------------------------------------------------------------- |
103
92
  | `tgo/require-data-testid` | Ensures specific HTML elements have a `data-testid` attribute for E2E testing |
104
93
 
105
94
  ### Rule Documentation
@@ -113,10 +102,11 @@ Detailed documentation for each rule, including examples and configuration optio
113
102
  To add a new ESLint rule to this package:
114
103
 
115
104
  1. **Create the rule file** in `src/rules/`:
105
+
116
106
  ```typescript
117
107
  // src/rules/your-rule-name.ts
118
- import { Rule } from 'eslint'
119
-
108
+ import { Rule } from 'eslint';
109
+
120
110
  const rule: Rule.RuleModule = {
121
111
  meta: {
122
112
  type: 'problem', // or 'suggestion' or 'layout'
@@ -134,22 +124,23 @@ To add a new ESLint rule to this package:
134
124
  // Your rule implementation
135
125
  return {
136
126
  // AST node visitors
137
- }
127
+ };
138
128
  },
139
- }
140
-
141
- export default rule
129
+ };
130
+
131
+ export default rule;
142
132
  ```
143
133
 
144
134
  2. **Add tests** in `src/rules/your-rule-name.spec.ts`:
135
+
145
136
  ```typescript
146
- import { RuleTester } from '@typescript-eslint/rule-tester'
147
- import rule from './your-rule-name'
148
-
137
+ import { RuleTester } from '@typescript-eslint/rule-tester';
138
+ import rule from './your-rule-name';
139
+
149
140
  const ruleTester = new RuleTester({
150
141
  parser: '@angular-eslint/template-parser',
151
- })
152
-
142
+ });
143
+
153
144
  ruleTester.run('your-rule-name', rule, {
154
145
  valid: [
155
146
  // Test cases that should pass
@@ -157,20 +148,22 @@ To add a new ESLint rule to this package:
157
148
  invalid: [
158
149
  // Test cases that should fail
159
150
  ],
160
- })
151
+ });
161
152
  ```
162
153
 
163
154
  3. **Export the rule** in `src/rules/index.ts`:
155
+
164
156
  ```typescript
165
- import yourRuleName from './your-rule-name'
166
-
157
+ import yourRuleName from './your-rule-name';
158
+
167
159
  export const rules = {
168
160
  'require-data-testid': requireDataTestId,
169
161
  'your-rule-name': yourRuleName,
170
- }
162
+ };
171
163
  ```
172
164
 
173
165
  4. **Add to recommended config** (optional) in `src/configs/recommended.ts`:
166
+
174
167
  ```typescript
175
168
  rules: {
176
169
  'tgo/require-data-testid': 'warn',
@@ -179,6 +172,7 @@ To add a new ESLint rule to this package:
179
172
  ```
180
173
 
181
174
  5. **Document the rule** in `src/rules/your-rule-name.md`:
175
+
182
176
  - Describe what the rule does
183
177
  - Provide configuration options
184
178
  - Show correct and incorrect code examples
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testgorilla/tgo-linting",
3
- "version": "4.0.0",
3
+ "version": "5.1.0",
4
4
  "displayName": "TGO Linting",
5
5
  "description": "Linting rules and code quality standards for TestGorilla projects",
6
6
  "author": "TestGorilla",
@@ -24,13 +24,14 @@
24
24
  "registry": "https://registry.npmjs.org/"
25
25
  },
26
26
  "dependencies": {
27
- "@angular-eslint/eslint-plugin": "^20.7.0",
28
- "@angular-eslint/eslint-plugin-template": "^20.7.0",
29
- "@angular-eslint/template-parser": "^20.7.0",
27
+ "@angular-eslint/eslint-plugin": "^21.4.0",
28
+ "@angular-eslint/eslint-plugin-template": "^21.4.0",
29
+ "@angular-eslint/template-parser": "^21.4.0",
30
+ "@eslint/js": "^10.0.0",
30
31
  "@typescript-eslint/utils": "^8.56.1",
31
32
  "eslint-config-prettier": "10.1.8",
32
33
  "eslint-import-resolver-typescript": "4.4.4",
33
- "eslint-plugin-import-x": "4.16.1",
34
+ "eslint-plugin-import-x": "4.16.2",
34
35
  "eslint-plugin-jsdoc": "62.7.1",
35
36
  "eslint-plugin-no-unsanitized": "4.1.5",
36
37
  "eslint-plugin-rxjs-x": "1.0.2",
@@ -38,7 +39,7 @@
38
39
  "typescript-eslint": "8.56.1"
39
40
  },
40
41
  "peerDependencies": {
41
- "eslint": "^8.57.0 || ^9.0.0",
42
+ "eslint": "^10.0.0",
42
43
  "typescript": ">=4.8.4 <6.0.0",
43
44
  "tslib": "^2.0.0"
44
45
  },
@@ -10,6 +10,7 @@ const eslint_plugin_template_1 = tslib_1.__importDefault(require("@angular-eslin
10
10
  // parser and letting ESLint fall back to espree (parser errors on every `.html`).
11
11
  // Namespace import preserves the parse/parseForESLint functions ESLint expects.
12
12
  const angularTemplateParser = tslib_1.__importStar(require("@angular-eslint/template-parser"));
13
+ const js_1 = tslib_1.__importDefault(require("@eslint/js"));
13
14
  const eslint_config_prettier_1 = tslib_1.__importDefault(require("eslint-config-prettier"));
14
15
  const eslint_plugin_import_x_1 = tslib_1.__importDefault(require("eslint-plugin-import-x"));
15
16
  const eslint_plugin_jsdoc_1 = tslib_1.__importDefault(require("eslint-plugin-jsdoc"));
@@ -72,9 +73,19 @@ function recommended(opts) {
72
73
  'rxjs-x': eslint_plugin_rxjs_x_1.default,
73
74
  },
74
75
  rules: {
75
- // Spread recommended + recommendedTypeChecked, then disable ESLint formatting
76
- // rules that conflict with Prettier. Prettier runs separately in consumer
76
+ // Spread @eslint/js recommended + typescript-eslint recommended +
77
+ // recommendedTypeChecked, then disable ESLint formatting rules that
78
+ // conflict with Prettier. Prettier runs separately in consumer
77
79
  // pipelines (pre-commit / lint-staged / CI), not as an ESLint rule.
80
+ //
81
+ // ORDER MATTERS: `tseslint.configs.recommended` never *enables* core
82
+ // ESLint rules — its `eslint-recommended` slice only turns OFF the
83
+ // core rules the TypeScript compiler already covers (no-undef,
84
+ // no-unreachable, …). Spreading `js.configs.recommended` first gives
85
+ // consumers the core-rules baseline (no-prototype-builtins,
86
+ // no-duplicate-case, no-async-promise-executor, …) while letting the
87
+ // tseslint offs win for the TS-redundant ones.
88
+ ...js_1.default.configs.recommended.rules,
78
89
  ...tseslintRecommended,
79
90
  ...tseslintRecommendedTypeChecked,
80
91
  ...eslint_config_prettier_1.default.rules,
@@ -497,6 +508,11 @@ function recommended(opts) {
497
508
  ...eslint_plugin_template_1.default.configs.recommended.rules,
498
509
  'tgo/require-data-testid': 'error',
499
510
  '@angular-eslint/template/prefer-control-flow': 'error',
511
+ // Real-bug-class template rules that live only in the `all` config
512
+ // (`recommended` ships just 3 rules). Cherry-picked instead of
513
+ // spreading `all`, which would pull in unvetted opinionated rules.
514
+ '@angular-eslint/template/no-any': 'error',
515
+ '@angular-eslint/template/no-duplicate-attributes': 'error',
500
516
  },
501
517
  },
502
518
  // ── Spec / mock files (default glob: *.spec.ts, *.integration.spec.ts,
@@ -1 +1 @@
1
- {"version":3,"file":"recommended.js","sourceRoot":"","sources":["../../../../../packages/tgo-linting/src/configs/recommended.ts"],"names":[],"mappings":"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","sourcesContent":["import angular from '@angular-eslint/eslint-plugin';\nimport angularTemplate from '@angular-eslint/eslint-plugin-template';\n// `@angular-eslint/template-parser` is a TypeScript-compiled ES module with\n// `__esModule: true` and only named exports — there is no `default`. A default\n// import via `__importDefault` resolves to `undefined`, silently dropping the\n// parser and letting ESLint fall back to espree (parser errors on every `.html`).\n// Namespace import preserves the parse/parseForESLint functions ESLint expects.\nimport * as angularTemplateParser from '@angular-eslint/template-parser';\nimport prettierConfig from 'eslint-config-prettier';\nimport importX from 'eslint-plugin-import-x';\nimport jsdoc from 'eslint-plugin-jsdoc';\nimport noUnsanitized from 'eslint-plugin-no-unsanitized';\nimport rxjsX from 'eslint-plugin-rxjs-x';\nimport security from 'eslint-plugin-security';\nimport tseslint, { type ConfigArray } from 'typescript-eslint';\n\nimport { tgoPlugin } from '../plugin';\n\n// `tseslint.configs.recommended` etc. are arrays of mixed config objects\n// (some carry `name`, some carry `rules`, etc.). Flatten their rule maps via\n// reduce; cast the result to a permissive record so the spread into the\n// strongly-typed `rules` block below doesn't leak unrelated config keys.\ntype RulesRecord = Record<string, unknown>;\n\nconst tseslintRecommended = tseslint.configs.recommended.reduce<RulesRecord>(\n (acc, cfg) => ({ ...acc, ...(cfg.rules ?? {}) }),\n {}\n);\nconst tseslintRecommendedTypeChecked = tseslint.configs.recommendedTypeChecked.reduce<RulesRecord>(\n (acc, cfg) => ({ ...acc, ...(cfg.rules ?? {}) }),\n {}\n);\n\nexport interface RecommendedOptions {\n /** Absolute path to the consumer repo root. Pass `import.meta.dirname`. */\n tsconfigRootDir: string;\n /** tsconfig path (relative to tsconfigRootDir). Default: 'tsconfig.json'. */\n project?: string;\n /** Glob for source TS files. Default: ['src/**\\/*.ts']. */\n tsFiles?: string[];\n /** Glob for HTML templates. Default: ['src/**\\/*.html']. */\n htmlFiles?: string[];\n /** Glob for spec files (relaxations applied). Default: ['src/**\\/*.spec.ts', 'src/**\\/*.integration.spec.ts']. */\n specFiles?: string[];\n}\n\n/**\n * Strict default ESLint flat-config preset for TGO Angular frontends.\n *\n * Type-aware rules (no-unsafe-*, restrict-*, no-floating-promises, etc.) are\n * at `error`. The previously-deferred warn severities were ratcheted to error\n * after the strict tsconfig migration landed in consumer codebases. Two rules\n * remain explicitly relaxed in the preset:\n * - `@typescript-eslint/consistent-type-imports` (off — Angular DI conflict)\n * - `@angular-eslint/use-component-view-encapsulation` (off — separate\n * styling refactor workstream)\n * See the inline comments at each rule for full rationale.\n *\n * The spec/mock files block (default glob: *.spec.ts + *.integration.spec.ts\n * + *.mock.ts + *.mocks.ts) relaxes type-aware family rules and a few others\n * to match the idiomatic test-code shape (bracket access, fire-trigger\n * subscribes, mock literals with `any` typing).\n */\nexport function recommended(opts: RecommendedOptions): ConfigArray {\n const {\n tsconfigRootDir,\n project = 'tsconfig.json',\n tsFiles = ['src/**/*.ts'],\n htmlFiles = ['src/**/*.html'],\n specFiles = [\n 'src/**/*.spec.ts',\n 'src/**/*.integration.spec.ts',\n 'src/**/*.mock.ts',\n 'src/**/*.mocks.ts',\n ],\n } = opts;\n\n return tseslint.config(\n // ── TypeScript files (*.ts) ──────────────────────────────────────────\n {\n files: tsFiles,\n languageOptions: {\n parser: tseslint.parser,\n parserOptions: {\n project,\n tsconfigRootDir,\n sourceType: 'module',\n },\n },\n settings: {\n 'import-x/resolver': {\n typescript: { project },\n node: true,\n },\n },\n plugins: {\n '@typescript-eslint': tseslint.plugin,\n '@angular-eslint': angular,\n 'import-x': importX,\n jsdoc,\n 'no-unsanitized': noUnsanitized,\n security,\n 'rxjs-x': rxjsX,\n },\n rules: {\n // Spread recommended + recommendedTypeChecked, then disable ESLint formatting\n // rules that conflict with Prettier. Prettier runs separately in consumer\n // pipelines (pre-commit / lint-staged / CI), not as an ESLint rule.\n ...tseslintRecommended,\n ...tseslintRecommendedTypeChecked,\n ...prettierConfig.rules,\n\n // ══════════════════════════════════════════════════════════════════\n // Type-aware rules — ERROR (ratcheted from warn after TS strict landed\n // in consumer codebases).\n // ══════════════════════════════════════════════════════════════════\n // `_`-prefix is the conventional opt-out for intentionally-unused\n // identifiers in TypeScript (matches the `noUnusedParameters` compiler\n // option's behavior). Mock/stub methods that need a signature-compatible\n // parameter but ignore the value (e.g. `configure(_config?: …) {}`),\n // destructured rest collectors (`const { _internal: _, ...rest } = obj`),\n // and `catch (_e: unknown)` blocks all benefit. Production code can't\n // accidentally hide real unused names — pick a different prefix.\n '@typescript-eslint/no-unused-vars': [\n 'error',\n {\n argsIgnorePattern: '^_',\n varsIgnorePattern: '^_',\n caughtErrorsIgnorePattern: '^_',\n },\n ],\n '@typescript-eslint/no-unsafe-assignment': 'error',\n '@typescript-eslint/no-unsafe-call': 'error',\n '@typescript-eslint/no-unsafe-member-access': 'error',\n '@typescript-eslint/no-unsafe-return': 'error',\n '@typescript-eslint/no-unsafe-argument': 'error',\n '@typescript-eslint/no-unsafe-enum-comparison': 'error',\n '@typescript-eslint/no-unsafe-unary-minus': 'error',\n '@typescript-eslint/no-floating-promises': 'error',\n '@typescript-eslint/no-misused-promises': 'error',\n '@typescript-eslint/await-thenable': 'error',\n '@typescript-eslint/only-throw-error': 'error',\n '@typescript-eslint/prefer-promise-reject-errors': 'error',\n '@typescript-eslint/require-await': 'error',\n '@typescript-eslint/return-await': ['error', 'in-try-catch'],\n '@typescript-eslint/no-base-to-string': 'error',\n '@typescript-eslint/restrict-template-expressions': 'error',\n '@typescript-eslint/restrict-plus-operands': 'error',\n '@typescript-eslint/no-unnecessary-type-assertion': 'error',\n '@typescript-eslint/no-redundant-type-constituents': 'error',\n '@typescript-eslint/no-deprecated': 'error',\n '@typescript-eslint/no-meaningless-void-operator': 'error',\n '@typescript-eslint/prefer-readonly': 'error',\n '@typescript-eslint/prefer-nullish-coalescing': 'error',\n '@typescript-eslint/prefer-optional-chain': 'error',\n '@typescript-eslint/prefer-includes': 'error',\n '@typescript-eslint/prefer-string-starts-ends-with': 'error',\n '@typescript-eslint/prefer-literal-enum-member': 'error',\n '@typescript-eslint/no-mixed-enums': 'error',\n '@typescript-eslint/switch-exhaustiveness-check': 'error',\n '@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',\n '@typescript-eslint/unbound-method': 'error',\n '@typescript-eslint/no-wrapper-object-types': 'error',\n '@typescript-eslint/no-unsafe-function-type': 'off',\n 'dot-notation': 'off',\n '@typescript-eslint/dot-notation': ['error', { allowIndexSignaturePropertyAccess: true }],\n\n // ══════════════════════════════════════════════════════════════════\n // Type-aware rules at error — purely syntactic, safe without TS strict.\n // ══════════════════════════════════════════════════════════════════\n '@typescript-eslint/no-explicit-any': 'error',\n '@typescript-eslint/no-non-null-assertion': 'error',\n '@typescript-eslint/no-namespace': 'error',\n '@typescript-eslint/no-misused-new': 'error',\n '@typescript-eslint/no-empty-object-type': 'error',\n '@typescript-eslint/triple-slash-reference': [\n 'error',\n { path: 'always', types: 'prefer-import', lib: 'always' },\n ],\n '@typescript-eslint/unified-signatures': 'error',\n '@typescript-eslint/prefer-function-type': 'error',\n '@typescript-eslint/prefer-namespace-keyword': 'error',\n '@typescript-eslint/prefer-for-of': 'error',\n '@typescript-eslint/adjacent-overload-signatures': 'error',\n '@typescript-eslint/consistent-type-assertions': 'error',\n '@typescript-eslint/no-inferrable-types': ['error', { ignoreParameters: true }],\n '@typescript-eslint/no-shadow': ['error', { hoist: 'all' }],\n '@typescript-eslint/no-unused-expressions': 'error',\n '@typescript-eslint/no-this-alias': 'error',\n '@typescript-eslint/no-for-in-array': 'error',\n '@typescript-eslint/ban-ts-comment': 'error',\n // consistent-type-imports — disabled preset-wide. The rule is not\n // Angular-aware: it converts constructor-injected service imports to\n // `import type { X }`, which then fails the Angular AOT compiler with\n // TS-992003 (\"No suitable injection token\") because Angular reads the\n // parameter type as a runtime DI token. The escape is one\n // `eslint-disable-next-line` comment per DI import, which scales with\n // the number of constructor-injected services in the codebase. Off\n // until either (a) consumer codebases migrate from constructor DI to\n // `inject()` everywhere — at which point the rule becomes safe and\n // valuable — or (b) we adopt a typescript-eslint variant that\n // recognises Angular DI sites.\n '@typescript-eslint/consistent-type-imports': 'off',\n '@typescript-eslint/no-import-type-side-effects': 'error',\n\n // High-friction rules — explicitly off (see plan rationale).\n '@typescript-eslint/explicit-function-return-type': 'off',\n '@typescript-eslint/no-empty-function': 'off',\n '@typescript-eslint/no-use-before-define': 'off',\n '@typescript-eslint/no-require-imports': 'off',\n '@typescript-eslint/array-type': 'off',\n '@typescript-eslint/parameter-properties': 'off',\n '@typescript-eslint/explicit-member-accessibility': ['off', { accessibility: 'explicit' }],\n\n // Naming convention — Angular-friendly, lenient. Error severity (ratcheted\n // from warn). Selectors below opt out of naming enforcement for the\n // identifier kinds that legitimately mirror the snake_case shape of\n // TestGorilla's backend API (DTOs, destructured server responses,\n // class fields that proxy API field names, Quill keyboard-shortcut /\n // language object-literal method keys like `Cmd-Z` or `c++`).\n // Last-matching-selector-wins, so the additions go at the tail.\n '@typescript-eslint/naming-convention': [\n 'error',\n {\n selector: 'default',\n format: ['camelCase'],\n leadingUnderscore: 'allow',\n trailingUnderscore: 'allow',\n },\n {\n selector: 'variable',\n format: ['camelCase', 'UPPER_CASE', 'PascalCase'],\n leadingUnderscore: 'allow',\n },\n { selector: 'parameter', format: ['camelCase'], leadingUnderscore: 'allow' },\n {\n selector: 'memberLike',\n modifiers: ['private'],\n format: ['camelCase'],\n leadingUnderscore: 'allow',\n },\n { selector: 'typeLike', format: ['PascalCase'] },\n { selector: 'enumMember', format: ['PascalCase', 'UPPER_CASE'] },\n // API payloads commonly use snake_case — opt out of property naming entirely.\n { selector: 'objectLiteralProperty', format: null },\n { selector: 'import', format: null },\n // Interface / type members modelling API shape.\n { selector: 'typeProperty', format: null },\n // DTO classes + UPPER_CASE static const-like fields + PascalCase class-field\n // re-exports of types/enums to templates.\n { selector: 'classProperty', format: null, leadingUnderscore: 'allow' },\n // `const { foo_bar } = result;` destructured locals/parameters keep API names.\n { selector: 'variable', modifiers: ['destructured'], format: null },\n { selector: 'parameter', modifiers: ['destructured'], format: null },\n // Quill keyboard shortcuts (`Cmd-Z`, `Ctrl-Shift-K`) and language keys (`c++`, `c#`).\n { selector: 'objectLiteralMethod', format: null },\n ],\n\n '@typescript-eslint/no-restricted-types': [\n 'error',\n {\n types: {\n Object: {\n message: 'Avoid using the `Object` type. Did you mean `object`?',\n fixWith: 'object',\n },\n Function: {\n message: 'Avoid using the `Function` type. Prefer a specific function type.',\n fixWith: '() => void',\n },\n Boolean: {\n message: 'Avoid using the `Boolean` type. Did you mean `boolean`?',\n fixWith: 'boolean',\n },\n Number: {\n message: 'Avoid using the `Number` type. Did you mean `number`?',\n fixWith: 'number',\n },\n String: {\n message: 'Avoid using the `String` type. Did you mean `string`?',\n fixWith: 'string',\n },\n Symbol: {\n message: 'Avoid using the `Symbol` type. Did you mean `symbol`?',\n fixWith: 'symbol',\n },\n },\n },\n ],\n\n // ══════════════════════════════════════════════════════════════════\n // Angular structural rules — error.\n // ══════════════════════════════════════════════════════════════════\n '@angular-eslint/component-class-suffix': 'error',\n '@angular-eslint/component-selector': [\n 'error',\n { type: 'element', prefix: 'tgo', style: 'kebab-case' },\n ],\n '@angular-eslint/contextual-lifecycle': 'error',\n '@angular-eslint/directive-class-suffix': 'error',\n '@angular-eslint/directive-selector': [\n 'error',\n { type: 'attribute', prefix: 'tgo', style: 'camelCase' },\n ],\n '@angular-eslint/no-conflicting-lifecycle': 'error',\n '@angular-eslint/no-input-rename': 'error',\n '@angular-eslint/no-inputs-metadata-property': 'error',\n '@angular-eslint/no-output-native': 'error',\n '@angular-eslint/no-output-on-prefix': 'error',\n '@angular-eslint/no-output-rename': 'error',\n '@angular-eslint/no-outputs-metadata-property': 'error',\n '@angular-eslint/use-lifecycle-interface': 'error',\n '@angular-eslint/use-pipe-transform-interface': 'error',\n '@angular-eslint/prefer-standalone': 'error',\n '@angular-eslint/prefer-on-push-component-change-detection': 'error',\n // use-component-view-encapsulation — off in the preset. Re-enabling\n // requires per-component audit of every `ViewEncapsulation.None` site\n // (third-party DOM targets, global content-projection slots, intentional\n // style leaks) and a refactor for the accidental ones. That work belongs\n // in a dedicated styling-focused workstream in each consumer codebase,\n // not in this preset's strict default. Consumers can override to\n // `error` locally if they want to gate on it sooner. TODO: revisit\n // when at least one consumer ships the per-component audit.\n '@angular-eslint/use-component-view-encapsulation': 'off',\n '@angular-eslint/no-queries-metadata-property': 'error',\n '@angular-eslint/no-duplicates-in-metadata-arrays': 'error',\n '@angular-eslint/no-async-lifecycle-method': 'error',\n '@angular-eslint/no-empty-lifecycle-method': 'error',\n\n // ══════════════════════════════════════════════════════════════════\n // Import discipline (eslint-plugin-import-x).\n // ══════════════════════════════════════════════════════════════════\n // PERF NOTE — full-repo lint with this rule enabled costs ~+45s wall and ~+1 GB peak RSS\n // (measured: 92.8s / 3.38 GB OFF vs 138.6s / 4.44 GB ON across 2,337 files). It walks the\n // full import graph and finds zero violations today. Kept active to preserve the rule as\n // part of the canonical rule set; revisit moving it to OXLint's fast path as part of the\n // toolchain decision (Phase 1, Workstream 1) rather than disabling.\n 'import-x/no-self-import': 'error',\n 'import-x/no-duplicates': 'error',\n // PERF NOTE — TIMING profile shows this rule at 64-75% of total rule execution time\n // (~1.1-1.3s per file). It walks every import looking for @deprecated JSDoc tags. Ratcheted\n // to error along with the rest of the type-aware family after TS strict landed. Revisit\n // migrating to OXLint's fast path with Workstream 1 if total lint time becomes a concern.\n 'import-x/no-deprecated': 'error',\n 'import-x/no-relative-packages': 'error',\n 'import-x/no-mutable-exports': 'error',\n 'import-x/no-extraneous-dependencies': 'error',\n // Consumers carve out routing/lazy/config/stories paths.\n 'import-x/no-default-export': 'error',\n 'import-x/order': [\n 'error',\n {\n groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'type'],\n 'newlines-between': 'always',\n alphabetize: { order: 'asc', caseInsensitive: true },\n },\n ],\n\n // ══════════════════════════════════════════════════════════════════\n // JSDoc.\n // ══════════════════════════════════════════════════════════════════\n 'jsdoc/check-alignment': 'error',\n\n // ══════════════════════════════════════════════════════════════════\n // Security: XSS guards (no-unsanitized).\n // ══════════════════════════════════════════════════════════════════\n 'no-unsanitized/method': 'error',\n 'no-unsanitized/property': 'error',\n\n // ══════════════════════════════════════════════════════════════════\n // Security: cherry-picked from eslint-plugin-security.\n // Most rules in this plugin are Node-specific and noisy in browser code; only the\n // browser-relevant detectors are enabled. Plugin defaults explicitly turned off below.\n // ══════════════════════════════════════════════════════════════════\n 'security/detect-eval-with-expression': 'error',\n 'security/detect-unsafe-regex': 'error',\n 'security/detect-bidi-characters': 'error', // CVE-2021-42574 trojan-source guard.\n 'security/detect-non-literal-regexp': 'off',\n 'security/detect-pseudoRandomBytes': 'off',\n 'security/detect-non-literal-require': 'off',\n 'security/detect-non-literal-fs-filename': 'off',\n 'security/detect-object-injection': 'off',\n 'security/detect-buffer-noassert': 'off',\n 'security/detect-child-process': 'off',\n 'security/detect-disable-mustache-escape': 'off',\n 'security/detect-new-buffer': 'off',\n 'security/detect-no-csrf-before-method-override': 'off',\n 'security/detect-possible-timing-attacks': 'off',\n\n // ══════════════════════════════════════════════════════════════════\n // RxJS hygiene (eslint-plugin-rxjs-x). Error severity (ratcheted from\n // warn after TS strict landed). All five are real-bug-class rules\n // (async-in-subscribe, untyped catch in pipe, nested subscribes that\n // should be flatMap, completer-not-last, leaking subscriptions).\n // ══════════════════════════════════════════════════════════════════\n 'rxjs-x/no-async-subscribe': 'error',\n 'rxjs-x/no-implicit-any-catch': 'error',\n 'rxjs-x/no-nested-subscribe': 'error',\n 'rxjs-x/no-unsafe-takeuntil': 'error',\n 'rxjs-x/no-ignored-subscription': 'error',\n\n // ══════════════════════════════════════════════════════════════════\n // Core ESLint — error.\n // ══════════════════════════════════════════════════════════════════\n 'arrow-body-style': 'error',\n complexity: ['error', 15],\n 'constructor-super': 'error',\n curly: 'error',\n 'default-case-last': 'error',\n eqeqeq: ['error', 'always'],\n 'guard-for-in': 'error',\n 'id-denylist': [\n 'error',\n 'any',\n 'Number',\n 'number',\n 'String',\n 'string',\n 'Boolean',\n 'boolean',\n 'Undefined',\n 'undefined',\n ],\n 'max-classes-per-file': 'off',\n 'max-depth': ['error', 4],\n 'max-nested-callbacks': ['error', 3],\n 'max-params': ['error', 5],\n 'no-bitwise': 'error',\n 'no-caller': 'error',\n 'no-cond-assign': 'error',\n 'no-console': [\n 'error',\n {\n allow: [\n 'warn',\n 'dir',\n 'timeLog',\n 'assert',\n 'clear',\n 'count',\n 'countReset',\n 'group',\n 'groupEnd',\n 'table',\n 'dirxml',\n 'error',\n 'groupCollapsed',\n 'Console',\n 'profile',\n 'profileEnd',\n 'timeStamp',\n 'context',\n ],\n },\n ],\n 'no-debugger': 'error',\n 'no-empty': 'off',\n 'no-empty-function': 'off',\n 'no-eval': 'error',\n 'no-fallthrough': 'error',\n 'no-implicit-coercion': 'error',\n 'no-invalid-this': 'off',\n 'no-new-wrappers': 'error',\n 'no-param-reassign': 'error',\n 'no-restricted-imports': [\n 'error',\n {\n paths: [\n { name: 'rxjs/Rx', message: 'Use the rxjs barrel (`rxjs`) instead.' },\n {\n name: 'lodash',\n message:\n 'Import per-method from lodash (e.g., `lodash/cloneDeep`) for tree-shaking.',\n },\n { name: 'moment', message: 'Use date-fns (already a project dep).' },\n ],\n },\n ],\n // Block direct DomSanitizer.bypassSecurityTrust* calls — production callers should use\n // sanitization wrapper pipes. Consumers carve out the wrappers themselves.\n 'no-restricted-syntax': [\n 'error',\n {\n selector:\n 'CallExpression[callee.property.name=/^bypassSecurityTrust(Html|Script|Url|ResourceUrl|Style)$/]',\n message:\n 'Use the bypass-sanitization-{html,url}.pipe.ts wrappers in src/@testgorilla/pipes instead of calling DomSanitizer.bypassSecurityTrust* directly. If a TS-side bypass is genuinely required, add an inline eslint-disable-next-line with a SECURITY comment explaining why.',\n },\n ],\n 'no-script-url': 'error',\n 'no-template-curly-in-string': 'error',\n 'no-throw-literal': 'error',\n 'no-undef-init': 'error',\n 'no-underscore-dangle': ['error', { allow: ['_state'], allowAfterThis: true }],\n 'no-unsafe-finally': 'error',\n 'no-unused-labels': 'error',\n 'no-use-before-define': 'off',\n 'no-useless-concat': 'error',\n 'no-useless-return': 'error',\n 'no-var': 'error',\n 'object-shorthand': 'error',\n 'one-var': ['error', 'never'],\n 'prefer-arrow-callback': 'error',\n 'prefer-const': 'error',\n 'prefer-object-spread': 'error',\n 'prefer-template': 'error',\n 'quote-props': ['error', 'as-needed'],\n radix: 'error',\n 'use-isnan': 'error',\n yoda: 'error',\n\n // ── Off — Prettier owns formatting. eslint-config-prettier disables most of these;\n // listing explicitly overrides any preset that re-enables them.\n 'arrow-parens': 'off',\n 'brace-style': 'off',\n 'comma-dangle': 'off',\n 'eol-last': 'off',\n 'linebreak-style': 'off',\n 'max-len': 'off',\n 'new-parens': 'off',\n 'newline-per-chained-call': 'off',\n 'no-extra-semi': 'off',\n 'no-irregular-whitespace': 'off',\n 'no-multiple-empty-lines': 'off',\n 'no-trailing-spaces': 'off',\n 'padded-blocks': 'off',\n quotes: 'off',\n semi: 'off',\n 'space-in-parens': 'off',\n },\n },\n\n // ── HTML template files (*.html) ─────────────────────────────────────\n // a11y rule set is deferred to a separate workstream.\n {\n files: htmlFiles,\n languageOptions: {\n parser: angularTemplateParser,\n },\n plugins: {\n '@angular-eslint/template': angularTemplate,\n tgo: tgoPlugin,\n },\n rules: {\n ...(angularTemplate.configs.recommended.rules as RulesRecord),\n 'tgo/require-data-testid': 'error',\n '@angular-eslint/template/prefer-control-flow': 'error',\n },\n },\n\n // ── Spec / mock files (default glob: *.spec.ts, *.integration.spec.ts,\n // *.mock.ts, *.mocks.ts) — relax type-aware and a few style rules to\n // match the idiomatic test-code shape (bracket access for production\n // internals, fire-trigger subscribes that Jest cleans up via test\n // isolation, mock literals with `any`-shaped fixtures, snake_case API\n // field names re-used in fixture object literals). Also allows `ui-*`\n // selectors for mocks that substitute Canopy UI library components. ──\n {\n files: specFiles,\n rules: {\n '@typescript-eslint/unbound-method': 'off',\n '@typescript-eslint/no-unsafe-call': 'off',\n '@typescript-eslint/no-unsafe-member-access': 'off',\n '@typescript-eslint/no-unsafe-assignment': 'off',\n '@typescript-eslint/no-unsafe-return': 'off',\n '@typescript-eslint/no-unsafe-argument': 'off',\n '@typescript-eslint/no-explicit-any': 'off',\n '@typescript-eslint/naming-convention': 'off',\n 'max-params': 'off',\n 'max-nested-callbacks': 'off',\n // dot-notation: rule's autofix converts `service['privateField']` →\n // `service.privateField`, which trips TS access-modifier checks\n // (TS2341/TS2445) and/or no-underscore-dangle on `_`-prefixed\n // internals. Bracket access is the standard idiom for reaching\n // production internals from tests; the noise is purely cosmetic.\n '@typescript-eslint/dot-notation': 'off',\n // no-ignored-subscription: the canonical pattern in specs is\n // `service.method().subscribe()` used as a fire-trigger for the\n // production code's side effect (typically an HTTP request the spec\n // then asserts via `httpTesting.expectOne`). Jest test isolation\n // makes leaks impossible by construction, so the rule's\n // memory-leak-prevention signal is zero here while the noise is\n // substantial.\n 'rxjs-x/no-ignored-subscription': 'off',\n // component-selector: mocks that substitute Canopy UI library\n // components (`ui-*` selectors owned by `@testgorilla/tgo-ui`)\n // must use the same selectors to slot in correctly under\n // TestBed.overrideComponent.\n '@angular-eslint/component-selector': [\n 'error',\n { type: 'element', prefix: ['tgo', 'ui'], style: 'kebab-case' },\n ],\n // no-non-null-assertion: idiomatic `querySelector('input')!` after\n // an `expect(...).toBeDefined()` or after a static template\n // guarantees the element exists. The spec has already proven\n // non-null upstream; the rule's signal is zero here while the\n // noise is substantial. Same precedent as `dot-notation` /\n // `no-ignored-subscription` — spec-file relaxations match the\n // idiomatic test shape. Production code keeps the rule at error.\n '@typescript-eslint/no-non-null-assertion': 'off',\n // no-underscore-dangle: specs routinely reach into `_`-prefixed\n // internals of services and SignalStore factories to assert\n // against private state (e.g. `(store as unknown as\n // { _resetSubject: ... })._resetSubject()`). The SignalStore\n // factory block already disables this rule for `*.store.ts` /\n // `*.store.feature.ts`, but `*.store.spec.ts` matches the spec\n // block instead — so the disable needs to be here too.\n 'no-underscore-dangle': 'off',\n },\n },\n\n // ── NgRx SignalStore factory files (*.store.ts, *.store.feature.ts) —\n // three rules conflict with the SignalStore authoring pattern:\n // - `explicit-function-return-type`: signalStore() / withFeature()\n // rely on inferred generic return types; naming the type either\n // duplicates inference or narrows below what's intended.\n // - `no-underscore-dangle`: SignalStore convention uses `_`-prefixed\n // internal helpers (e.g. `_state`, `_load`) that don't leak through\n // the public store API.\n // - `prefer-arrow-callback`: factories pass `function` keyword\n // callbacks for proper `this`-binding inside the feature; arrow\n // conversion can change semantics. ──\n {\n files: ['src/**/*.store.ts', 'src/**/*.store.feature.ts'],\n rules: {\n '@typescript-eslint/explicit-function-return-type': 'off',\n 'no-underscore-dangle': 'off',\n 'prefer-arrow-callback': 'off',\n },\n },\n\n // ── JS files ─────────────────────────────────────────────────────────\n {\n files: ['**/*.js'],\n languageOptions: {\n ecmaVersion: 2020,\n sourceType: 'module',\n },\n rules: {\n '@typescript-eslint/no-require-imports': 'off',\n },\n }\n );\n}\n"]}
1
+ {"version":3,"file":"recommended.js","sourceRoot":"","sources":["../../../../../packages/tgo-linting/src/configs/recommended.ts"],"names":[],"mappings":"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","sourcesContent":["import angular from '@angular-eslint/eslint-plugin';\nimport angularTemplate from '@angular-eslint/eslint-plugin-template';\n// `@angular-eslint/template-parser` is a TypeScript-compiled ES module with\n// `__esModule: true` and only named exports — there is no `default`. A default\n// import via `__importDefault` resolves to `undefined`, silently dropping the\n// parser and letting ESLint fall back to espree (parser errors on every `.html`).\n// Namespace import preserves the parse/parseForESLint functions ESLint expects.\nimport * as angularTemplateParser from '@angular-eslint/template-parser';\nimport js from '@eslint/js';\nimport prettierConfig from 'eslint-config-prettier';\nimport importX from 'eslint-plugin-import-x';\nimport jsdoc from 'eslint-plugin-jsdoc';\nimport noUnsanitized from 'eslint-plugin-no-unsanitized';\nimport rxjsX from 'eslint-plugin-rxjs-x';\nimport security from 'eslint-plugin-security';\nimport tseslint, { type ConfigArray } from 'typescript-eslint';\n\nimport { tgoPlugin } from '../plugin';\n\n// `tseslint.configs.recommended` etc. are arrays of mixed config objects\n// (some carry `name`, some carry `rules`, etc.). Flatten their rule maps via\n// reduce; cast the result to a permissive record so the spread into the\n// strongly-typed `rules` block below doesn't leak unrelated config keys.\ntype RulesRecord = Record<string, unknown>;\n\nconst tseslintRecommended = tseslint.configs.recommended.reduce<RulesRecord>(\n (acc, cfg) => ({ ...acc, ...(cfg.rules ?? {}) }),\n {}\n);\nconst tseslintRecommendedTypeChecked = tseslint.configs.recommendedTypeChecked.reduce<RulesRecord>(\n (acc, cfg) => ({ ...acc, ...(cfg.rules ?? {}) }),\n {}\n);\n\nexport interface RecommendedOptions {\n /** Absolute path to the consumer repo root. Pass `import.meta.dirname`. */\n tsconfigRootDir: string;\n /** tsconfig path (relative to tsconfigRootDir). Default: 'tsconfig.json'. */\n project?: string;\n /** Glob for source TS files. Default: ['src/**\\/*.ts']. */\n tsFiles?: string[];\n /** Glob for HTML templates. Default: ['src/**\\/*.html']. */\n htmlFiles?: string[];\n /** Glob for spec files (relaxations applied). Default: ['src/**\\/*.spec.ts', 'src/**\\/*.integration.spec.ts']. */\n specFiles?: string[];\n}\n\n/**\n * Strict default ESLint flat-config preset for TGO Angular frontends.\n *\n * Type-aware rules (no-unsafe-*, restrict-*, no-floating-promises, etc.) are\n * at `error`. The previously-deferred warn severities were ratcheted to error\n * after the strict tsconfig migration landed in consumer codebases. Two rules\n * remain explicitly relaxed in the preset:\n * - `@typescript-eslint/consistent-type-imports` (off — Angular DI conflict)\n * - `@angular-eslint/use-component-view-encapsulation` (off — separate\n * styling refactor workstream)\n * See the inline comments at each rule for full rationale.\n *\n * The spec/mock files block (default glob: *.spec.ts + *.integration.spec.ts\n * + *.mock.ts + *.mocks.ts) relaxes type-aware family rules and a few others\n * to match the idiomatic test-code shape (bracket access, fire-trigger\n * subscribes, mock literals with `any` typing).\n */\nexport function recommended(opts: RecommendedOptions): ConfigArray {\n const {\n tsconfigRootDir,\n project = 'tsconfig.json',\n tsFiles = ['src/**/*.ts'],\n htmlFiles = ['src/**/*.html'],\n specFiles = [\n 'src/**/*.spec.ts',\n 'src/**/*.integration.spec.ts',\n 'src/**/*.mock.ts',\n 'src/**/*.mocks.ts',\n ],\n } = opts;\n\n return tseslint.config(\n // ── TypeScript files (*.ts) ──────────────────────────────────────────\n {\n files: tsFiles,\n languageOptions: {\n parser: tseslint.parser,\n parserOptions: {\n project,\n tsconfigRootDir,\n sourceType: 'module',\n },\n },\n settings: {\n 'import-x/resolver': {\n typescript: { project },\n node: true,\n },\n },\n plugins: {\n '@typescript-eslint': tseslint.plugin,\n '@angular-eslint': angular,\n 'import-x': importX,\n jsdoc,\n 'no-unsanitized': noUnsanitized,\n security,\n 'rxjs-x': rxjsX,\n },\n rules: {\n // Spread @eslint/js recommended + typescript-eslint recommended +\n // recommendedTypeChecked, then disable ESLint formatting rules that\n // conflict with Prettier. Prettier runs separately in consumer\n // pipelines (pre-commit / lint-staged / CI), not as an ESLint rule.\n //\n // ORDER MATTERS: `tseslint.configs.recommended` never *enables* core\n // ESLint rules — its `eslint-recommended` slice only turns OFF the\n // core rules the TypeScript compiler already covers (no-undef,\n // no-unreachable, …). Spreading `js.configs.recommended` first gives\n // consumers the core-rules baseline (no-prototype-builtins,\n // no-duplicate-case, no-async-promise-executor, …) while letting the\n // tseslint offs win for the TS-redundant ones.\n ...(js.configs.recommended.rules as RulesRecord),\n ...tseslintRecommended,\n ...tseslintRecommendedTypeChecked,\n ...prettierConfig.rules,\n\n // ══════════════════════════════════════════════════════════════════\n // Type-aware rules — ERROR (ratcheted from warn after TS strict landed\n // in consumer codebases).\n // ══════════════════════════════════════════════════════════════════\n // `_`-prefix is the conventional opt-out for intentionally-unused\n // identifiers in TypeScript (matches the `noUnusedParameters` compiler\n // option's behavior). Mock/stub methods that need a signature-compatible\n // parameter but ignore the value (e.g. `configure(_config?: …) {}`),\n // destructured rest collectors (`const { _internal: _, ...rest } = obj`),\n // and `catch (_e: unknown)` blocks all benefit. Production code can't\n // accidentally hide real unused names — pick a different prefix.\n '@typescript-eslint/no-unused-vars': [\n 'error',\n {\n argsIgnorePattern: '^_',\n varsIgnorePattern: '^_',\n caughtErrorsIgnorePattern: '^_',\n },\n ],\n '@typescript-eslint/no-unsafe-assignment': 'error',\n '@typescript-eslint/no-unsafe-call': 'error',\n '@typescript-eslint/no-unsafe-member-access': 'error',\n '@typescript-eslint/no-unsafe-return': 'error',\n '@typescript-eslint/no-unsafe-argument': 'error',\n '@typescript-eslint/no-unsafe-enum-comparison': 'error',\n '@typescript-eslint/no-unsafe-unary-minus': 'error',\n '@typescript-eslint/no-floating-promises': 'error',\n '@typescript-eslint/no-misused-promises': 'error',\n '@typescript-eslint/await-thenable': 'error',\n '@typescript-eslint/only-throw-error': 'error',\n '@typescript-eslint/prefer-promise-reject-errors': 'error',\n '@typescript-eslint/require-await': 'error',\n '@typescript-eslint/return-await': ['error', 'in-try-catch'],\n '@typescript-eslint/no-base-to-string': 'error',\n '@typescript-eslint/restrict-template-expressions': 'error',\n '@typescript-eslint/restrict-plus-operands': 'error',\n '@typescript-eslint/no-unnecessary-type-assertion': 'error',\n '@typescript-eslint/no-redundant-type-constituents': 'error',\n '@typescript-eslint/no-deprecated': 'error',\n '@typescript-eslint/no-meaningless-void-operator': 'error',\n '@typescript-eslint/prefer-readonly': 'error',\n '@typescript-eslint/prefer-nullish-coalescing': 'error',\n '@typescript-eslint/prefer-optional-chain': 'error',\n '@typescript-eslint/prefer-includes': 'error',\n '@typescript-eslint/prefer-string-starts-ends-with': 'error',\n '@typescript-eslint/prefer-literal-enum-member': 'error',\n '@typescript-eslint/no-mixed-enums': 'error',\n '@typescript-eslint/switch-exhaustiveness-check': 'error',\n '@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',\n '@typescript-eslint/unbound-method': 'error',\n '@typescript-eslint/no-wrapper-object-types': 'error',\n '@typescript-eslint/no-unsafe-function-type': 'off',\n 'dot-notation': 'off',\n '@typescript-eslint/dot-notation': ['error', { allowIndexSignaturePropertyAccess: true }],\n\n // ══════════════════════════════════════════════════════════════════\n // Type-aware rules at error — purely syntactic, safe without TS strict.\n // ══════════════════════════════════════════════════════════════════\n '@typescript-eslint/no-explicit-any': 'error',\n '@typescript-eslint/no-non-null-assertion': 'error',\n '@typescript-eslint/no-namespace': 'error',\n '@typescript-eslint/no-misused-new': 'error',\n '@typescript-eslint/no-empty-object-type': 'error',\n '@typescript-eslint/triple-slash-reference': [\n 'error',\n { path: 'always', types: 'prefer-import', lib: 'always' },\n ],\n '@typescript-eslint/unified-signatures': 'error',\n '@typescript-eslint/prefer-function-type': 'error',\n '@typescript-eslint/prefer-namespace-keyword': 'error',\n '@typescript-eslint/prefer-for-of': 'error',\n '@typescript-eslint/adjacent-overload-signatures': 'error',\n '@typescript-eslint/consistent-type-assertions': 'error',\n '@typescript-eslint/no-inferrable-types': ['error', { ignoreParameters: true }],\n '@typescript-eslint/no-shadow': ['error', { hoist: 'all' }],\n '@typescript-eslint/no-unused-expressions': 'error',\n '@typescript-eslint/no-this-alias': 'error',\n '@typescript-eslint/no-for-in-array': 'error',\n '@typescript-eslint/ban-ts-comment': 'error',\n // consistent-type-imports — disabled preset-wide. The rule is not\n // Angular-aware: it converts constructor-injected service imports to\n // `import type { X }`, which then fails the Angular AOT compiler with\n // TS-992003 (\"No suitable injection token\") because Angular reads the\n // parameter type as a runtime DI token. The escape is one\n // `eslint-disable-next-line` comment per DI import, which scales with\n // the number of constructor-injected services in the codebase. Off\n // until either (a) consumer codebases migrate from constructor DI to\n // `inject()` everywhere — at which point the rule becomes safe and\n // valuable — or (b) we adopt a typescript-eslint variant that\n // recognises Angular DI sites.\n '@typescript-eslint/consistent-type-imports': 'off',\n '@typescript-eslint/no-import-type-side-effects': 'error',\n\n // High-friction rules — explicitly off (see plan rationale).\n '@typescript-eslint/explicit-function-return-type': 'off',\n '@typescript-eslint/no-empty-function': 'off',\n '@typescript-eslint/no-use-before-define': 'off',\n '@typescript-eslint/no-require-imports': 'off',\n '@typescript-eslint/array-type': 'off',\n '@typescript-eslint/parameter-properties': 'off',\n '@typescript-eslint/explicit-member-accessibility': ['off', { accessibility: 'explicit' }],\n\n // Naming convention — Angular-friendly, lenient. Error severity (ratcheted\n // from warn). Selectors below opt out of naming enforcement for the\n // identifier kinds that legitimately mirror the snake_case shape of\n // TestGorilla's backend API (DTOs, destructured server responses,\n // class fields that proxy API field names, Quill keyboard-shortcut /\n // language object-literal method keys like `Cmd-Z` or `c++`).\n // Last-matching-selector-wins, so the additions go at the tail.\n '@typescript-eslint/naming-convention': [\n 'error',\n {\n selector: 'default',\n format: ['camelCase'],\n leadingUnderscore: 'allow',\n trailingUnderscore: 'allow',\n },\n {\n selector: 'variable',\n format: ['camelCase', 'UPPER_CASE', 'PascalCase'],\n leadingUnderscore: 'allow',\n },\n { selector: 'parameter', format: ['camelCase'], leadingUnderscore: 'allow' },\n {\n selector: 'memberLike',\n modifiers: ['private'],\n format: ['camelCase'],\n leadingUnderscore: 'allow',\n },\n { selector: 'typeLike', format: ['PascalCase'] },\n { selector: 'enumMember', format: ['PascalCase', 'UPPER_CASE'] },\n // API payloads commonly use snake_case — opt out of property naming entirely.\n { selector: 'objectLiteralProperty', format: null },\n { selector: 'import', format: null },\n // Interface / type members modelling API shape.\n { selector: 'typeProperty', format: null },\n // DTO classes + UPPER_CASE static const-like fields + PascalCase class-field\n // re-exports of types/enums to templates.\n { selector: 'classProperty', format: null, leadingUnderscore: 'allow' },\n // `const { foo_bar } = result;` destructured locals/parameters keep API names.\n { selector: 'variable', modifiers: ['destructured'], format: null },\n { selector: 'parameter', modifiers: ['destructured'], format: null },\n // Quill keyboard shortcuts (`Cmd-Z`, `Ctrl-Shift-K`) and language keys (`c++`, `c#`).\n { selector: 'objectLiteralMethod', format: null },\n ],\n\n '@typescript-eslint/no-restricted-types': [\n 'error',\n {\n types: {\n Object: {\n message: 'Avoid using the `Object` type. Did you mean `object`?',\n fixWith: 'object',\n },\n Function: {\n message: 'Avoid using the `Function` type. Prefer a specific function type.',\n fixWith: '() => void',\n },\n Boolean: {\n message: 'Avoid using the `Boolean` type. Did you mean `boolean`?',\n fixWith: 'boolean',\n },\n Number: {\n message: 'Avoid using the `Number` type. Did you mean `number`?',\n fixWith: 'number',\n },\n String: {\n message: 'Avoid using the `String` type. Did you mean `string`?',\n fixWith: 'string',\n },\n Symbol: {\n message: 'Avoid using the `Symbol` type. Did you mean `symbol`?',\n fixWith: 'symbol',\n },\n },\n },\n ],\n\n // ══════════════════════════════════════════════════════════════════\n // Angular structural rules — error.\n // ══════════════════════════════════════════════════════════════════\n '@angular-eslint/component-class-suffix': 'error',\n '@angular-eslint/component-selector': [\n 'error',\n { type: 'element', prefix: 'tgo', style: 'kebab-case' },\n ],\n '@angular-eslint/contextual-lifecycle': 'error',\n '@angular-eslint/directive-class-suffix': 'error',\n '@angular-eslint/directive-selector': [\n 'error',\n { type: 'attribute', prefix: 'tgo', style: 'camelCase' },\n ],\n '@angular-eslint/no-conflicting-lifecycle': 'error',\n '@angular-eslint/no-input-rename': 'error',\n '@angular-eslint/no-inputs-metadata-property': 'error',\n '@angular-eslint/no-output-native': 'error',\n '@angular-eslint/no-output-on-prefix': 'error',\n '@angular-eslint/no-output-rename': 'error',\n '@angular-eslint/no-outputs-metadata-property': 'error',\n '@angular-eslint/use-lifecycle-interface': 'error',\n '@angular-eslint/use-pipe-transform-interface': 'error',\n '@angular-eslint/prefer-standalone': 'error',\n '@angular-eslint/prefer-on-push-component-change-detection': 'error',\n // use-component-view-encapsulation — off in the preset. Re-enabling\n // requires per-component audit of every `ViewEncapsulation.None` site\n // (third-party DOM targets, global content-projection slots, intentional\n // style leaks) and a refactor for the accidental ones. That work belongs\n // in a dedicated styling-focused workstream in each consumer codebase,\n // not in this preset's strict default. Consumers can override to\n // `error` locally if they want to gate on it sooner. TODO: revisit\n // when at least one consumer ships the per-component audit.\n '@angular-eslint/use-component-view-encapsulation': 'off',\n '@angular-eslint/no-queries-metadata-property': 'error',\n '@angular-eslint/no-duplicates-in-metadata-arrays': 'error',\n '@angular-eslint/no-async-lifecycle-method': 'error',\n '@angular-eslint/no-empty-lifecycle-method': 'error',\n\n // ══════════════════════════════════════════════════════════════════\n // Import discipline (eslint-plugin-import-x).\n // ══════════════════════════════════════════════════════════════════\n // PERF NOTE — full-repo lint with this rule enabled costs ~+45s wall and ~+1 GB peak RSS\n // (measured: 92.8s / 3.38 GB OFF vs 138.6s / 4.44 GB ON across 2,337 files). It walks the\n // full import graph and finds zero violations today. Kept active to preserve the rule as\n // part of the canonical rule set; revisit moving it to OXLint's fast path as part of the\n // toolchain decision (Phase 1, Workstream 1) rather than disabling.\n 'import-x/no-self-import': 'error',\n 'import-x/no-duplicates': 'error',\n // PERF NOTE — TIMING profile shows this rule at 64-75% of total rule execution time\n // (~1.1-1.3s per file). It walks every import looking for @deprecated JSDoc tags. Ratcheted\n // to error along with the rest of the type-aware family after TS strict landed. Revisit\n // migrating to OXLint's fast path with Workstream 1 if total lint time becomes a concern.\n 'import-x/no-deprecated': 'error',\n 'import-x/no-relative-packages': 'error',\n 'import-x/no-mutable-exports': 'error',\n 'import-x/no-extraneous-dependencies': 'error',\n // Consumers carve out routing/lazy/config/stories paths.\n 'import-x/no-default-export': 'error',\n 'import-x/order': [\n 'error',\n {\n groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'type'],\n 'newlines-between': 'always',\n alphabetize: { order: 'asc', caseInsensitive: true },\n },\n ],\n\n // ══════════════════════════════════════════════════════════════════\n // JSDoc.\n // ══════════════════════════════════════════════════════════════════\n 'jsdoc/check-alignment': 'error',\n\n // ══════════════════════════════════════════════════════════════════\n // Security: XSS guards (no-unsanitized).\n // ══════════════════════════════════════════════════════════════════\n 'no-unsanitized/method': 'error',\n 'no-unsanitized/property': 'error',\n\n // ══════════════════════════════════════════════════════════════════\n // Security: cherry-picked from eslint-plugin-security.\n // Most rules in this plugin are Node-specific and noisy in browser code; only the\n // browser-relevant detectors are enabled. Plugin defaults explicitly turned off below.\n // ══════════════════════════════════════════════════════════════════\n 'security/detect-eval-with-expression': 'error',\n 'security/detect-unsafe-regex': 'error',\n 'security/detect-bidi-characters': 'error', // CVE-2021-42574 trojan-source guard.\n 'security/detect-non-literal-regexp': 'off',\n 'security/detect-pseudoRandomBytes': 'off',\n 'security/detect-non-literal-require': 'off',\n 'security/detect-non-literal-fs-filename': 'off',\n 'security/detect-object-injection': 'off',\n 'security/detect-buffer-noassert': 'off',\n 'security/detect-child-process': 'off',\n 'security/detect-disable-mustache-escape': 'off',\n 'security/detect-new-buffer': 'off',\n 'security/detect-no-csrf-before-method-override': 'off',\n 'security/detect-possible-timing-attacks': 'off',\n\n // ══════════════════════════════════════════════════════════════════\n // RxJS hygiene (eslint-plugin-rxjs-x). Error severity (ratcheted from\n // warn after TS strict landed). All five are real-bug-class rules\n // (async-in-subscribe, untyped catch in pipe, nested subscribes that\n // should be flatMap, completer-not-last, leaking subscriptions).\n // ══════════════════════════════════════════════════════════════════\n 'rxjs-x/no-async-subscribe': 'error',\n 'rxjs-x/no-implicit-any-catch': 'error',\n 'rxjs-x/no-nested-subscribe': 'error',\n 'rxjs-x/no-unsafe-takeuntil': 'error',\n 'rxjs-x/no-ignored-subscription': 'error',\n\n // ══════════════════════════════════════════════════════════════════\n // Core ESLint — error.\n // ══════════════════════════════════════════════════════════════════\n 'arrow-body-style': 'error',\n complexity: ['error', 15],\n 'constructor-super': 'error',\n curly: 'error',\n 'default-case-last': 'error',\n eqeqeq: ['error', 'always'],\n 'guard-for-in': 'error',\n 'id-denylist': [\n 'error',\n 'any',\n 'Number',\n 'number',\n 'String',\n 'string',\n 'Boolean',\n 'boolean',\n 'Undefined',\n 'undefined',\n ],\n 'max-classes-per-file': 'off',\n 'max-depth': ['error', 4],\n 'max-nested-callbacks': ['error', 3],\n 'max-params': ['error', 5],\n 'no-bitwise': 'error',\n 'no-caller': 'error',\n 'no-cond-assign': 'error',\n 'no-console': [\n 'error',\n {\n allow: [\n 'warn',\n 'dir',\n 'timeLog',\n 'assert',\n 'clear',\n 'count',\n 'countReset',\n 'group',\n 'groupEnd',\n 'table',\n 'dirxml',\n 'error',\n 'groupCollapsed',\n 'Console',\n 'profile',\n 'profileEnd',\n 'timeStamp',\n 'context',\n ],\n },\n ],\n 'no-debugger': 'error',\n 'no-empty': 'off',\n 'no-empty-function': 'off',\n 'no-eval': 'error',\n 'no-fallthrough': 'error',\n 'no-implicit-coercion': 'error',\n 'no-invalid-this': 'off',\n 'no-new-wrappers': 'error',\n 'no-param-reassign': 'error',\n 'no-restricted-imports': [\n 'error',\n {\n paths: [\n { name: 'rxjs/Rx', message: 'Use the rxjs barrel (`rxjs`) instead.' },\n {\n name: 'lodash',\n message:\n 'Import per-method from lodash (e.g., `lodash/cloneDeep`) for tree-shaking.',\n },\n { name: 'moment', message: 'Use date-fns (already a project dep).' },\n ],\n },\n ],\n // Block direct DomSanitizer.bypassSecurityTrust* calls — production callers should use\n // sanitization wrapper pipes. Consumers carve out the wrappers themselves.\n 'no-restricted-syntax': [\n 'error',\n {\n selector:\n 'CallExpression[callee.property.name=/^bypassSecurityTrust(Html|Script|Url|ResourceUrl|Style)$/]',\n message:\n 'Use the bypass-sanitization-{html,url}.pipe.ts wrappers in src/@testgorilla/pipes instead of calling DomSanitizer.bypassSecurityTrust* directly. If a TS-side bypass is genuinely required, add an inline eslint-disable-next-line with a SECURITY comment explaining why.',\n },\n ],\n 'no-script-url': 'error',\n 'no-template-curly-in-string': 'error',\n 'no-throw-literal': 'error',\n 'no-undef-init': 'error',\n 'no-underscore-dangle': ['error', { allow: ['_state'], allowAfterThis: true }],\n 'no-unsafe-finally': 'error',\n 'no-unused-labels': 'error',\n 'no-use-before-define': 'off',\n 'no-useless-concat': 'error',\n 'no-useless-return': 'error',\n 'no-var': 'error',\n 'object-shorthand': 'error',\n 'one-var': ['error', 'never'],\n 'prefer-arrow-callback': 'error',\n 'prefer-const': 'error',\n 'prefer-object-spread': 'error',\n 'prefer-template': 'error',\n 'quote-props': ['error', 'as-needed'],\n radix: 'error',\n 'use-isnan': 'error',\n yoda: 'error',\n\n // ── Off — Prettier owns formatting. eslint-config-prettier disables most of these;\n // listing explicitly overrides any preset that re-enables them.\n 'arrow-parens': 'off',\n 'brace-style': 'off',\n 'comma-dangle': 'off',\n 'eol-last': 'off',\n 'linebreak-style': 'off',\n 'max-len': 'off',\n 'new-parens': 'off',\n 'newline-per-chained-call': 'off',\n 'no-extra-semi': 'off',\n 'no-irregular-whitespace': 'off',\n 'no-multiple-empty-lines': 'off',\n 'no-trailing-spaces': 'off',\n 'padded-blocks': 'off',\n quotes: 'off',\n semi: 'off',\n 'space-in-parens': 'off',\n },\n },\n\n // ── HTML template files (*.html) ─────────────────────────────────────\n // a11y rule set is deferred to a separate workstream.\n {\n files: htmlFiles,\n languageOptions: {\n parser: angularTemplateParser,\n },\n plugins: {\n '@angular-eslint/template': angularTemplate,\n tgo: tgoPlugin,\n },\n rules: {\n ...(angularTemplate.configs.recommended.rules as RulesRecord),\n 'tgo/require-data-testid': 'error',\n '@angular-eslint/template/prefer-control-flow': 'error',\n // Real-bug-class template rules that live only in the `all` config\n // (`recommended` ships just 3 rules). Cherry-picked instead of\n // spreading `all`, which would pull in unvetted opinionated rules.\n '@angular-eslint/template/no-any': 'error',\n '@angular-eslint/template/no-duplicate-attributes': 'error',\n },\n },\n\n // ── Spec / mock files (default glob: *.spec.ts, *.integration.spec.ts,\n // *.mock.ts, *.mocks.ts) — relax type-aware and a few style rules to\n // match the idiomatic test-code shape (bracket access for production\n // internals, fire-trigger subscribes that Jest cleans up via test\n // isolation, mock literals with `any`-shaped fixtures, snake_case API\n // field names re-used in fixture object literals). Also allows `ui-*`\n // selectors for mocks that substitute Canopy UI library components. ──\n {\n files: specFiles,\n rules: {\n '@typescript-eslint/unbound-method': 'off',\n '@typescript-eslint/no-unsafe-call': 'off',\n '@typescript-eslint/no-unsafe-member-access': 'off',\n '@typescript-eslint/no-unsafe-assignment': 'off',\n '@typescript-eslint/no-unsafe-return': 'off',\n '@typescript-eslint/no-unsafe-argument': 'off',\n '@typescript-eslint/no-explicit-any': 'off',\n '@typescript-eslint/naming-convention': 'off',\n 'max-params': 'off',\n 'max-nested-callbacks': 'off',\n // dot-notation: rule's autofix converts `service['privateField']` →\n // `service.privateField`, which trips TS access-modifier checks\n // (TS2341/TS2445) and/or no-underscore-dangle on `_`-prefixed\n // internals. Bracket access is the standard idiom for reaching\n // production internals from tests; the noise is purely cosmetic.\n '@typescript-eslint/dot-notation': 'off',\n // no-ignored-subscription: the canonical pattern in specs is\n // `service.method().subscribe()` used as a fire-trigger for the\n // production code's side effect (typically an HTTP request the spec\n // then asserts via `httpTesting.expectOne`). Jest test isolation\n // makes leaks impossible by construction, so the rule's\n // memory-leak-prevention signal is zero here while the noise is\n // substantial.\n 'rxjs-x/no-ignored-subscription': 'off',\n // component-selector: mocks that substitute Canopy UI library\n // components (`ui-*` selectors owned by `@testgorilla/tgo-ui`)\n // must use the same selectors to slot in correctly under\n // TestBed.overrideComponent.\n '@angular-eslint/component-selector': [\n 'error',\n { type: 'element', prefix: ['tgo', 'ui'], style: 'kebab-case' },\n ],\n // no-non-null-assertion: idiomatic `querySelector('input')!` after\n // an `expect(...).toBeDefined()` or after a static template\n // guarantees the element exists. The spec has already proven\n // non-null upstream; the rule's signal is zero here while the\n // noise is substantial. Same precedent as `dot-notation` /\n // `no-ignored-subscription` — spec-file relaxations match the\n // idiomatic test shape. Production code keeps the rule at error.\n '@typescript-eslint/no-non-null-assertion': 'off',\n // no-underscore-dangle: specs routinely reach into `_`-prefixed\n // internals of services and SignalStore factories to assert\n // against private state (e.g. `(store as unknown as\n // { _resetSubject: ... })._resetSubject()`). The SignalStore\n // factory block already disables this rule for `*.store.ts` /\n // `*.store.feature.ts`, but `*.store.spec.ts` matches the spec\n // block instead — so the disable needs to be here too.\n 'no-underscore-dangle': 'off',\n },\n },\n\n // ── NgRx SignalStore factory files (*.store.ts, *.store.feature.ts) —\n // three rules conflict with the SignalStore authoring pattern:\n // - `explicit-function-return-type`: signalStore() / withFeature()\n // rely on inferred generic return types; naming the type either\n // duplicates inference or narrows below what's intended.\n // - `no-underscore-dangle`: SignalStore convention uses `_`-prefixed\n // internal helpers (e.g. `_state`, `_load`) that don't leak through\n // the public store API.\n // - `prefer-arrow-callback`: factories pass `function` keyword\n // callbacks for proper `this`-binding inside the feature; arrow\n // conversion can change semantics. ──\n {\n files: ['src/**/*.store.ts', 'src/**/*.store.feature.ts'],\n rules: {\n '@typescript-eslint/explicit-function-return-type': 'off',\n 'no-underscore-dangle': 'off',\n 'prefer-arrow-callback': 'off',\n },\n },\n\n // ── JS files ─────────────────────────────────────────────────────────\n {\n files: ['**/*.js'],\n languageOptions: {\n ecmaVersion: 2020,\n sourceType: 'module',\n },\n rules: {\n '@typescript-eslint/no-require-imports': 'off',\n },\n }\n );\n}\n"]}