mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-05 06:13:40 +00:00
Epic P7. Locks in the epic's gains with ESLint gates so the adoption work does not regress. - ccs/no-new-throw-error (error): custom flat-config rule that flags NEW throw new Error(...) outside a generated baseline allowlist. Forces the typed-error taxonomy (src/errors/error-types.ts). Existing 338 sites are grandfathered in eslint-rules/throw-error-baseline.json; only NEW violations error. Rule normalizes the filename to repo-root-relative to match baseline keys regardless of how ESLint reports paths. - max-lines (warn, 400, skipBlankLines/skipComments): warns on files over 400 LOC (goal of P5/P6 god-file splits). Currently 51 warnings on the not-yet-split god-files (P6 territory). - scripts/generate-throw-error-baseline.js: emits the allowlist from raw source (superset of real throws; never undercounts). Run after intentionally grandfathering a site, or quarterly to prune. - tests/unit/eslint-rules/no-throw-new-error.test.ts: rule logic (flags off-allowlist, passes on-allowlist/typed/rethrow, line-sensitivity). - docs/code-standards.md: Lint Enforcement Gates section. - docs/logging-contract.md: error.code -> ExitCode table (from P4). validate + validate:ci-parity green.
70 lines
2.4 KiB
JavaScript
70 lines
2.4 KiB
JavaScript
import tseslint from '@typescript-eslint/eslint-plugin';
|
|
import tsparser from '@typescript-eslint/parser';
|
|
import prettier from 'eslint-config-prettier';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import noNewThrowError from './eslint-rules/no-new-throw-error.js';
|
|
|
|
const __configDir = path.dirname(fileURLToPath(import.meta.url));
|
|
const baselinePath = path.join(__configDir, 'eslint-rules', 'throw-error-baseline.json');
|
|
const throwErrorBaseline = JSON.parse(fs.readFileSync(baselinePath, 'utf8'));
|
|
|
|
export default [
|
|
{
|
|
files: ['src/**/*.ts'],
|
|
ignores: ['src/**/__tests__/**'],
|
|
languageOptions: {
|
|
parser: tsparser,
|
|
parserOptions: {
|
|
ecmaVersion: 2020,
|
|
sourceType: 'module',
|
|
project: './tsconfig.json',
|
|
},
|
|
},
|
|
plugins: {
|
|
'@typescript-eslint': tseslint,
|
|
// Local enforcement rules (P7 gates).
|
|
ccs: { rules: { 'no-new-throw-error': noNewThrowError } },
|
|
},
|
|
rules: {
|
|
// TypeScript rules - upgraded to errors for stricter type safety
|
|
'@typescript-eslint/no-unused-vars': [
|
|
'error',
|
|
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' },
|
|
],
|
|
'@typescript-eslint/no-explicit-any': 'error',
|
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
'@typescript-eslint/no-non-null-assertion': 'error',
|
|
|
|
// General code quality
|
|
'no-console': 'off', // CLI tool needs console
|
|
'prefer-const': 'error',
|
|
'no-var': 'error',
|
|
'eqeqeq': ['error', 'always'],
|
|
|
|
// P7 enforcement gates:
|
|
// - no-new-throw-error: error on NEW throw new Error(...) outside the
|
|
// generated baseline (eslint-rules/throw-error-baseline.json). Forces
|
|
// the typed-error taxonomy (src/errors/error-types.ts). Regenerate the
|
|
// baseline with: node scripts/generate-throw-error-baseline.js
|
|
// - max-lines: warn on files over 400 LOC (goal of P5/P6 god-file splits).
|
|
'ccs/no-new-throw-error': ['error', { allowlist: throwErrorBaseline }],
|
|
'max-lines': ['warn', { max: 400, skipBlankLines: true, skipComments: true }],
|
|
},
|
|
},
|
|
{
|
|
files: ['tests/**/*.js', 'scripts/**/*.js'],
|
|
languageOptions: {
|
|
ecmaVersion: 2020,
|
|
sourceType: 'commonjs',
|
|
},
|
|
rules: {
|
|
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
|
'prefer-const': 'error',
|
|
'no-var': 'error',
|
|
},
|
|
},
|
|
prettier,
|
|
];
|