Ctrl K
ComunidadGuías…

eslint.config.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// Type-safety linting, focused. Biome owns formatting and base lint; this config
// adds ONLY the type-aware rules Biome cannot run (it does not connect to the
// type checker). Scope: server/ + shared/ production code — the API contract
// surface. The goal is to forbid the escape hatches that strict tsconfig allows:
// `any`, any-typed value flow, and type assertions that bypass the checker.

import tseslint from 'typescript-eslint'

export default tseslint.config(
  {
    ignores: [
      '**/dist/**',
      '**/node_modules/**',
      '**/.wrangler/**',
      'sdk/**',
      'cmd/**',
      'packages/runtime-bridge/**',
      'migrations/**',
      'src/**',
      'e2e/**',
      'scripts/**',
      '**/*.config.*',
      'vitest*.ts',
      // Tests legitimately cast mocks; the contract surface is the target.
      '**/*.test.ts',
      // Excluded from tsconfig.server.json, so typed linting cannot resolve them.
      'server/integration/**',
      // E2E_TEST_AUTH-gated test endpoint; design §1.8 exempts /api/e2e/* from
      // the v1 contract, and it builds partial test fixtures like real test files.
      'server/http/e2e.ts',
    ],
  },
  {
    files: ['server/**/*.ts', 'shared/**/*.ts'],
    plugins: { '@typescript-eslint': tseslint.plugin },
    languageOptions: {
      parser: tseslint.parser,
      parserOptions: { projectService: true, tsconfigRootDir: import.meta.dirname },
    },
    rules: {
      // 1. No `any` — explicit or implicit re-introduction.
      '@typescript-eslint/no-explicit-any': 'error',
      // 2. No `any`-typed value flowing through the code (the contagion Biome misses).
      '@typescript-eslint/no-unsafe-assignment': 'error',
      '@typescript-eslint/no-unsafe-member-access': 'error',
      '@typescript-eslint/no-unsafe-call': 'error',
      '@typescript-eslint/no-unsafe-return': 'error',
      '@typescript-eslint/no-unsafe-argument': 'error',
      // 3. Prefer `satisfies` over object-literal `as` casts (the cast bypasses
      //    excess-property checks). A warning, not a block: at genuine trust
      //    boundaries and in partial test fixtures an assertion is the honest
      //    tool, and `satisfies` cannot express loose-record normalization.
      '@typescript-eslint/consistent-type-assertions': [
        'warn',
        { assertionStyle: 'as', objectLiteralTypeAssertions: 'never' },
      ],
      // 4. Ban ONLY the `x as unknown as T` double cast — it launders a value
      //    through `unknown` to a type it does not overlap. The single
      //    `JSON.parse(x) as unknown` narrowing pattern is safe and stays allowed:
      //    the inner-as-unknown is matched only when it is the operand of an
      //    outer assertion.
      'no-restricted-syntax': [
        'error',
        {
          selector: 'TSAsExpression > TSAsExpression[typeAnnotation.type="TSUnknownKeyword"]',
          message: 'No `as unknown as` double cast — validate at the boundary (zod) instead of telling the compiler to trust you.',
        },
      ],
    },
  },
)