@skapxd/eslint-opinionated
v3.0.0
Published
Reusable ESLint architectural rules for TypeScript, React, backend, frontend, and package projects
Maintainers
Readme
@skapxd/eslint-opinionated
Reglas de ESLint para que los agentes no negocien la arquitectura de tu proyecto.
Este paquete convierte opiniones de arquitectura en guardrails ejecutables: archivos pequenos, nombres semanticos, errores modelados con Result, causas preservadas y fronteras explicitas. El README queda como puerta de entrada; el detalle vive en docs/ para que npm no entierre lo importante en 2.400 lineas.
Uso rapido
pnpm add -D @skapxd/eslint-opinionated eslint typescript typescript-eslintimport skapxd from "@skapxd/eslint-opinionated";
export default [
skapxd.configs.shared.base,
];Luego ejecutalo como cualquier regla de ESLint:
pnpm eslint
pnpm eslint src
pnpm eslint --max-warnings=0Documentacion
Los enlaces apuntan a GitHub de forma absoluta para que funcionen tambien desde npmjs.com.
| Tema | Contenido | | --- | --- | | Axiomas y motivacion | Por que existe el paquete, que protege y por que las alternativas no bastan. | | Presets y estructura | Shared, backend, frontend, Next.js, NestJS, Astro, package y strict. | | Adopcion incremental y legacy | Lint sobre cambios, olas de adopcion, overrides y propuestas de reglas. | | Pipeline Result | Como encajan @skapxd/result, ts-pattern y el trace global. | | Notas type-aware | Supuestos, limites conocidos y notas de reglas que dependen del checker. | | Indice de reglas | Las 50 fichas individuales en docs/reglas/. |
Reglas
| Regla | Que protege |
| --- | --- |
| skapxd/one-root-function-per-file | Un archivo, una función top-level semántica. |
| skapxd/async-functions-return-result | Funciones async de dominio deben retornar Promise<Result<...>>. Apagada por defecto; opt-in (ver motivos en su sección). |
| skapxd/requires-strict-tsconfig | El tsconfig debe ser implacable (strict, noImplicitReturns, noUncheckedIndexedAccess): sin ellos, el compilador no puede hacer irrepresentable lo inválido. |
| skapxd/result-error-requires-cause | Un Result.err derivado debe preservar cause: result.error. |
| skapxd/result-error-requires-handling | Prohíbe descartar en silencio un Result fallido: el error se transforma o se entrega, nunca se ignora. |
| skapxd/await-requires-result | Todo await debe resolver en un Result: o la función llamada retorna Promise<Result<...>> (preferido) o se envuelve en trySafe. Obligatoria en todos los presets tipados. |
| skapxd/no-ad-hoc-ok-result | Evita contratos { ok: ... } hechos a mano en async exports. |
| skapxd/max-hook-size | Marca hooks grandes o con demasiados useState. |
| skapxd/class-properties-require-readonly | Toda propiedad de clase es readonly: el cambio se modela con instancias nuevas, no con mutación. |
| skapxd/max-public-methods | Una clase, una responsabilidad: máximo N métodos públicos (default 1). Agnóstica al framework, en las reglas base; el preset nest le inyecta sus hooks. |
| skapxd/no-accessors | Prohíbe get/set: un método explícito dice la verdad; el accessor esconde computación (y métodos disfrazados). |
| skapxd/jsx-return-name-pascal-case | Funciones que retornan JSX deben nombrarse como componentes. |
| skapxd/nest-dto-requires-api-property | Toda propiedad pública de un *.dto.ts lleva @ApiProperty: el contrato HTTP se documenta en el DTO. Preset nest. |
| skapxd/nest-dto-requires-validation | Los DTOs de input validan en runtime: class-validator en cada propiedad, @IsOptional si hay ?, @Type junto a @ValidateNested. Preset nest. |
| skapxd/nest-no-direct-instantiation | Prohíbe new sobre imports internos en services: las dependencias entran por el constructor (DI). Preset nest. |
| skapxd/nest-no-inline-query-params | Dos o más @Query('x')/@ApiQuery individuales son un DTO disfrazado: consolida en @Query() filters: Dto. Preset nest. |
| skapxd/nest-no-result-response | Los métodos de un @Controller no retornan Result: el envelope se serializaría al cliente. La activa el preset nest. |
| skapxd/nest-no-swagger-in-controllers | Los controllers no se llenan de decoradores de swagger; el plugin introspecciona los DTOs. Preset nest. |
| skapxd/nest-requires-swagger-plugin | nest-cli.json debe tener el plugin @nestjs/swagger: la premisa de las reglas de swagger, verificada. Preset nest. |
| skapxd/nest-validation-pipe-config | Todo new ValidationPipe configura transform y whitelist: la premisa de las reglas de DTOs. Preset nest. |
| skapxd/no-anonymous-condition | El if solo acepta condiciones ya nombradas; todo cómputo (llamada, comparación, &&/||) se extrae a una const con nombre semántico. |
| skapxd/no-deep-relative-imports | Limita la profundidad de los imports relativos (../). |
| skapxd/no-default-export | Prohíbe export default; el nombre del símbolo es el contrato. Exime configs/stories y, en el preset next, los entrypoints del App Router. |
| skapxd/no-else | Prohíbe else/else if: el else es el estado sin nombre. Retorno anticipado, ternario simple o match(). |
| skapxd/no-emoji | Prohíbe emojis en strings y JSX; cada sistema los renderiza distinto. Usa un icono SVG. |
| skapxd/no-explicit-any | Prohíbe any: apaga el sistema de tipos donde más se necesita. unknown para lo desconocido, el tipo real para lo demás. Wrapper de typescript-eslint. |
| skapxd/no-floating-promises | Promesas sin await ni void: el rechazo muere sin pasar por trySafe. El mensaje corrige el consejo upstream (.then/.catch aquí están prohibidos). Wrapper de typescript-eslint. |
| skapxd/no-unsafe-argument | Impide pasar un any invisible como argumento: la frontera debe declararse unknown y estrecharse con schema o predicate. Wrapper de typescript-eslint. |
| skapxd/no-unsafe-assignment | Impide asignar un any invisible a variables o propiedades: la frontera debe declararse unknown y validarse. Wrapper de typescript-eslint. |
| skapxd/no-unsafe-call | Impide invocar valores any: antes de llamar hay que probar el tipo real con evidencia runtime. Wrapper de typescript-eslint. |
| skapxd/no-unsafe-member-access | Impide leer propiedades sobre any: JSON.parse()/response.json() pasan por unknown + schema/predicate antes de tocar campos. Wrapper de typescript-eslint. |
| skapxd/no-unsafe-return | Impide retornar any desde una funcion tipada: el dato externo se estrecha antes de salir de la frontera. Wrapper de typescript-eslint. |
| skapxd/no-unverified-cast | Prohíbe casts as que estrechan sin evidencia: schema, type predicate honesto o tipo de origen mejor modelado. Wrapper de typescript-eslint. |
| skapxd/prefer-schema-validation | Detecta validadores artesanales con muchos checks estructurales sobre el mismo unknown/any: eso ya es un schema, decláralo. |
| skapxd/no-impossible-branch | Condiciones que el type-checker demuestra constantes: la pregunta ya tiene respuesta. Es @typescript-eslint/no-unnecessary-condition con nombre semántico y mensajes que enseñan el fix. |
| skapxd/no-nested-if | Prohíbe if anidados: retorno anticipado o match(). Menos carga cognitiva y sin puntos ciegos para las demás reglas. |
| skapxd/no-non-null-assertion | Prohíbe el !: es "cállate, yo sé más que tú" dicho al compilador. Modela el tipo o maneja la duda. Wrapper de typescript-eslint. |
| skapxd/no-runtime-state-guard | Prohíbe if (this.x) throw en métodos: el estado inválido se hace irrepresentable en el tipo, no se vigila en runtime. |
| skapxd/no-silenced-compiler | Prohíbe @ts-ignore/@ts-nocheck: silenciar la alarma no arregla el incendio. @ts-expect-error con descripción queda para tests de tipos. Wrapper de ban-ts-comment. |
| skapxd/no-tunnel-props | Ninguna prop viaja más de un nivel: quien la recibe no puede reenviarla a otro componente. Mata el prop drilling. |
| skapxd/prefer-abort-signal | Listeners en efectos se limpian con AbortController ({ signal } + abort()), no con removeEventListener. |
| skapxd/prefer-tagged-union-state | Prohíbe estados inconsistentes representables: flag de loading + campo de error independientes → unión etiquetada. |
| skapxd/prefer-type-over-interface | Las uniones discriminadas son types; un type no crece en silencio por declaration merging. Wrapper de consistent-type-definitions. |
| skapxd/no-functions-inside-components | Prohíbe definir funciones dentro de componentes React. |
| skapxd/no-try-catch | Prohíbe try/catch; usa trySafe de @skapxd/result. |
| skapxd/no-promise-chain | Prohíbe .then/.catch/.finally; usa await (+ trySafe). |
| skapxd/prefer-ts-pattern | Prohíbe switch y ternarios anidados; usa match() de ts-pattern. |
| skapxd/package-requires-typed-exports | Los exports del package.json declaran types por condición (import → .d.mts, require → .d.ts): mata el bug FalseCJS. Preset package. |
| skapxd/untrusted-module-requires-adapter | Los paquetes con tipos mentirosos (@types desfasados) solo se importan desde su adaptador: la mentira vive en UN archivo. Preset package. |
| skapxd/no-jsx-ternary-null | Prefiere cond && <El /> sobre cond ? <El /> : null en JSX. |
Licencia
MIT
