@skapxd/eslint-opinionated 0.6.0 → 0.8.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 +214 -16
- package/dist/astro/index.d.mts +4 -0
- package/dist/astro/index.d.ts +4 -0
- package/dist/astro/index.js +2 -0
- package/dist/astro/index.js.map +1 -1
- package/dist/astro/index.mjs +2 -2
- package/dist/{chunk-QJQ2E2NG.mjs → chunk-2IXJXIW5.mjs} +19 -3
- package/dist/chunk-2IXJXIW5.mjs.map +1 -0
- package/dist/{chunk-5BA4KA37.mjs → chunk-47EZPLJX.mjs} +151 -41
- package/dist/chunk-47EZPLJX.mjs.map +1 -0
- package/dist/chunk-HB755SJQ.mjs +32 -0
- package/dist/chunk-HB755SJQ.mjs.map +1 -0
- package/dist/{chunk-7H7DRTP2.mjs → chunk-MSH2BTXH.mjs} +2 -2
- package/dist/{chunk-RWQGOTVZ.mjs → chunk-Z6CU2N4C.mjs} +3 -1
- package/dist/chunk-Z6CU2N4C.mjs.map +1 -0
- package/dist/index.js +188 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -5
- package/dist/index.mjs.map +1 -1
- package/dist/next/index.d.mts +10 -0
- package/dist/next/index.d.ts +10 -0
- package/dist/next/index.js +42 -1
- package/dist/next/index.js.map +1 -1
- package/dist/next/index.mjs +3 -2
- package/dist/shared/index.d.mts +6 -0
- package/dist/shared/index.d.ts +6 -0
- package/dist/shared/index.js +147 -13
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +3 -2
- package/package.json +3 -2
- package/dist/chunk-5BA4KA37.mjs.map +0 -1
- package/dist/chunk-QJQ2E2NG.mjs.map +0 -1
- package/dist/chunk-RWQGOTVZ.mjs.map +0 -1
- /package/dist/{chunk-7H7DRTP2.mjs.map → chunk-MSH2BTXH.mjs.map} +0 -0
package/README.md
CHANGED
|
@@ -510,6 +510,51 @@ export default [
|
|
|
510
510
|
Si necesitas una excepción puntual (p. ej. archivos generados), añade después un
|
|
511
511
|
bloque con `linterOptions: { noInlineConfig: false }` para esos globs.
|
|
512
512
|
|
|
513
|
+
## Configurar y sobrescribir reglas
|
|
514
|
+
|
|
515
|
+
Los presets son flat configs normales de ESLint: **el último config que
|
|
516
|
+
matchea un archivo gana**. Para ajustar una regla encima de un preset, esparce
|
|
517
|
+
sus `rules` y sobrescribe la entrada:
|
|
518
|
+
|
|
519
|
+
```js
|
|
520
|
+
export default [
|
|
521
|
+
{
|
|
522
|
+
files: ["src/**/*.{ts,tsx}"],
|
|
523
|
+
...skapxd.configs.shared.frontend,
|
|
524
|
+
rules: {
|
|
525
|
+
...skapxd.configs.shared.frontend.rules,
|
|
526
|
+
// mismo id, nuevas opciones: esta entrada reemplaza a la del preset
|
|
527
|
+
"skapxd/no-deep-relative-imports": ["error", { maxDepth: 1 }],
|
|
528
|
+
},
|
|
529
|
+
},
|
|
530
|
+
];
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
> Las opciones de una regla **se reemplazan completas**, no se mergean: si el
|
|
534
|
+
> preset pasaba opciones y tú la redeclaras, incluye también las que quieras
|
|
535
|
+
> conservar. (Excepción: los patrones *integrados* de `no-default-export` —
|
|
536
|
+
> configs y stories — viven dentro de la regla y nunca se pierden; tus
|
|
537
|
+
> `allowFilePatterns` se suman a ellos.)
|
|
538
|
+
|
|
539
|
+
Referencia rápida de qué se puede configurar (detalle y defaults en la sección
|
|
540
|
+
de cada regla):
|
|
541
|
+
|
|
542
|
+
| Regla | Opciones |
|
|
543
|
+
| --- | --- |
|
|
544
|
+
| `async-functions-return-result` | `allowFilePatterns` (globs), `allowNamePatterns` (regex), `checkMissingReturnType`, `checkMissingReturnTypeWhenCallNames`, `requireCallNames`, `promiseTypeNames`, `resultTypeNames` |
|
|
545
|
+
| `await-requires-result` | `allowFilePatterns` (globs), `trySafeCallNames` |
|
|
546
|
+
| `max-hook-size` | `maxLines`, `maxUseState` |
|
|
547
|
+
| `no-deep-relative-imports` | `maxDepth` |
|
|
548
|
+
| `no-default-export` | `allowFilePatterns` (globs, aditivos a los integrados) |
|
|
549
|
+
| `no-emoji` | `allowFilePatterns` (globs) |
|
|
550
|
+
| `no-functions-inside-components` | `allowJsxCallbacks`, `allowArrayMapCallbacks` (ambas `true` por defecto) |
|
|
551
|
+
| `no-promise-chain` | `methods` |
|
|
552
|
+
|
|
553
|
+
Los `allowFilePatterns` de todas las reglas son **globs** (`*` un segmento,
|
|
554
|
+
`**` cualquier profundidad, `{a,b}` alternativas; un patrón sin prefijo
|
|
555
|
+
matchea en cualquier carpeta). Las 7 reglas restantes no tienen opciones: su
|
|
556
|
+
única configuración es activarlas, apagarlas o cambiar la severidad.
|
|
557
|
+
|
|
513
558
|
## Reglas
|
|
514
559
|
|
|
515
560
|
| Regla | Qué protege |
|
|
@@ -522,6 +567,8 @@ bloque con `linterOptions: { noInlineConfig: false }` para esos globs.
|
|
|
522
567
|
| `skapxd/max-hook-size` | Marca hooks grandes o con demasiados `useState`. |
|
|
523
568
|
| `skapxd/jsx-return-name-pascal-case` | Funciones que retornan JSX deben nombrarse como componentes. |
|
|
524
569
|
| `skapxd/no-deep-relative-imports` | Limita la profundidad de los imports relativos (`../`). |
|
|
570
|
+
| `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. |
|
|
571
|
+
| `skapxd/no-emoji` | Prohíbe emojis en strings y JSX; cada sistema los renderiza distinto. Usa un icono SVG. |
|
|
525
572
|
| `skapxd/no-functions-inside-components` | Prohíbe definir funciones dentro de componentes React. |
|
|
526
573
|
| `skapxd/no-try-catch` | Prohíbe `try/catch`; usa `trySafe` de `@skapxd/result`. |
|
|
527
574
|
| `skapxd/no-promise-chain` | Prohíbe `.then/.catch/.finally`; usa `await` (+ `trySafe`). |
|
|
@@ -610,6 +657,20 @@ async function no(): Promise<Result<number, Error>> {} // se reporta
|
|
|
610
657
|
> Sin información de tipos cae a una comprobación por nombre (`resultTypeNames`),
|
|
611
658
|
> menos estricta.
|
|
612
659
|
|
|
660
|
+
Todas las opciones, con sus defaults:
|
|
661
|
+
|
|
662
|
+
```js
|
|
663
|
+
"skapxd/async-functions-return-result": ["error", {
|
|
664
|
+
allowFilePatterns: [], // globs de archivos exentos, p. ej. ["src/legacy/**"]
|
|
665
|
+
allowNamePatterns: [], // regex de nombres exentos, p. ej. ["^(GET|POST)$"]
|
|
666
|
+
checkMissingReturnType: true, // reportar también funciones SIN anotación de retorno
|
|
667
|
+
checkMissingReturnTypeWhenCallNames: [], // ...o solo si el cuerpo llama a estos nombres
|
|
668
|
+
requireCallNames: [], // acotar la regla a funciones que llamen a estos nombres
|
|
669
|
+
promiseTypeNames: ["Promise"], // wrappers de promesa aceptados (fallback sin tipos)
|
|
670
|
+
resultTypeNames: ["Result"], // nombres de Result aceptados (fallback sin tipos)
|
|
671
|
+
}]
|
|
672
|
+
```
|
|
673
|
+
|
|
613
674
|
### `skapxd/result-error-requires-cause`
|
|
614
675
|
|
|
615
676
|
Evita perder el error original al transformar un `Result` fallido:
|
|
@@ -698,6 +759,30 @@ Sirve para código de pegamento, pero deja el error sin modelar (`Result<T,
|
|
|
698
759
|
unknown>`). Cuando la misma operación se repite o el error importa, el mensaje
|
|
699
760
|
de la regla empuja hacia el camino 1.
|
|
700
761
|
|
|
762
|
+
### `skapxd/no-ad-hoc-ok-result`
|
|
763
|
+
|
|
764
|
+
Prohíbe que una función async **exportada** retorne objetos literales con la
|
|
765
|
+
forma `{ ok: ... }` armados a mano. Un contrato casero fragmenta el sistema:
|
|
766
|
+
cada módulo inventa su variante, la exención type-aware de
|
|
767
|
+
`await-requires-result` no lo reconoce, y `match()` pierde la exhaustividad.
|
|
768
|
+
|
|
769
|
+
```ts
|
|
770
|
+
export async function getUser(id: string) {
|
|
771
|
+
return { ok: false, message: "falló" }; // ❌ contrato inventado
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
export async function getUser(id: string): Promise<Result<User, UserError>> {
|
|
775
|
+
return Result.err({ // ✅ el Result real
|
|
776
|
+
cause: error,
|
|
777
|
+
message: "No pude cargar el usuario.",
|
|
778
|
+
type: "USER_FETCH_FAILED",
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
```
|
|
782
|
+
|
|
783
|
+
Solo mira funciones async exportadas: un helper interno con un objeto `ok`
|
|
784
|
+
cualquiera no es un contrato público y no se reporta.
|
|
785
|
+
|
|
701
786
|
### `skapxd/max-hook-size`
|
|
702
787
|
|
|
703
788
|
Marca hooks que crecen demasiado o acumulan muchos `useState`.
|
|
@@ -705,6 +790,35 @@ Marca hooks que crecen demasiado o acumulan muchos `useState`.
|
|
|
705
790
|
La intención es empujar el diseño hacia `useReducer`, hooks más pequeños o
|
|
706
791
|
módulos de transición de estado.
|
|
707
792
|
|
|
793
|
+
Opciones (los presets `frontend` y `next` usan `maxLines: 120`, `maxUseState: 1`):
|
|
794
|
+
|
|
795
|
+
```js
|
|
796
|
+
"skapxd/max-hook-size": ["error", {
|
|
797
|
+
maxLines: 120, // líneas máximas del cuerpo del hook
|
|
798
|
+
maxUseState: 1, // useState propios permitidos antes de exigir useReducer
|
|
799
|
+
}]
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
### `skapxd/jsx-return-name-pascal-case`
|
|
803
|
+
|
|
804
|
+
Si una función devuelve JSX, es un componente, y debe llamarse como tal:
|
|
805
|
+
PascalCase. El mensaje sugiere el rename concreto.
|
|
806
|
+
|
|
807
|
+
```tsx
|
|
808
|
+
function renderUserCard(user: User) { // ❌ "render*" devuelve JSX → es un componente
|
|
809
|
+
return <article>{user.name}</article>;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
function UserCard({ user }: { user: User }) { // ✅ nombre de componente + props
|
|
813
|
+
return <article>{user.name}</article>;
|
|
814
|
+
}
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
Esta regla es la que mantiene honesto al resto del sistema React: las reglas
|
|
818
|
+
de componentes detectan "componente" por nombre PascalCase, así que una
|
|
819
|
+
función `renderX` que devuelve JSX escaparía de ellas. Esta la captura y
|
|
820
|
+
fuerza el rename — y con el nombre corregido, las demás ya la ven.
|
|
821
|
+
|
|
708
822
|
### `skapxd/no-deep-relative-imports`
|
|
709
823
|
|
|
710
824
|
Limita cuántos niveles puede subir un import relativo. Por defecto **prohíbe
|
|
@@ -730,20 +844,99 @@ Revisa imports estáticos (`import`), re-exports (`export ... from`) e imports
|
|
|
730
844
|
dinámicos (`import(...)`). El remedio habitual es un alias de ruta (`@/...`) o
|
|
731
845
|
acercar el módulo a quien lo usa.
|
|
732
846
|
|
|
847
|
+
### `skapxd/no-default-export`
|
|
848
|
+
|
|
849
|
+
Prohíbe `export default` (incluida la forma `export { x as default }`). Con
|
|
850
|
+
exports nombrados, el nombre del símbolo es el contrato del módulo: renombrar
|
|
851
|
+
con el IDE actualiza todos los usos, `grep` encuentra definición y consumo, y
|
|
852
|
+
los autoimports no inventan nombres distintos por archivo.
|
|
853
|
+
|
|
854
|
+
```ts
|
|
855
|
+
export default function getUser() {} // ❌ cada import puede llamarlo distinto
|
|
856
|
+
export function getUser() {} // ✅ un solo nombre canónico
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
**Dónde sí se permite el default.** Hay entrypoints donde el ecosistema lo
|
|
860
|
+
exige, y la regla los reconoce en capas:
|
|
861
|
+
|
|
862
|
+
1. **Integrados (siempre activos):** configs de tooling (`*.config.{js,mjs,cjs,ts}`:
|
|
863
|
+
`next.config`, `tailwind.config`, `vitest.config`, `eslint.config`, ...) y
|
|
864
|
+
stories de Storybook (`*.stories.*`).
|
|
865
|
+
2. **Preset `next` (automático):** los entrypoints del App Router donde Next
|
|
866
|
+
exige el default — `page`, `layout`, `template`, `error`, `loading`,
|
|
867
|
+
`not-found`, `sitemap`, `robots`, `manifest`, `icon`, `opengraph-image`,
|
|
868
|
+
etc. No hay que configurar nada.
|
|
869
|
+
3. **`allowFilePatterns` (extensible):** si usas un framework o tool que la
|
|
870
|
+
regla aún no contempla, agrega su glob. Los patrones propios se **suman**
|
|
871
|
+
a los integrados, no los reemplazan. Son globs legibles (`*` un segmento,
|
|
872
|
+
`**` cualquier profundidad, `{a,b}` alternativas) y un patrón sin prefijo
|
|
873
|
+
matchea en cualquier carpeta:
|
|
874
|
+
|
|
875
|
+
```js
|
|
876
|
+
"skapxd/no-default-export": ["error", {
|
|
877
|
+
// p. ej. SvelteKit exige default en +page.ts / +layout.ts
|
|
878
|
+
allowFilePatterns: ["+page.ts", "+layout.ts"],
|
|
879
|
+
}]
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
Detalle útil con `React.lazy` (que espera `{ default }`): no hace falta volver
|
|
883
|
+
al default export, basta mapear el named en el import dinámico:
|
|
884
|
+
|
|
885
|
+
```ts
|
|
886
|
+
const Card = lazy(() => import("./card").then((m) => ({ default: m.Card })));
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+
### `skapxd/no-emoji`
|
|
890
|
+
|
|
891
|
+
Prohíbe emojis en strings, template literals y texto JSX. El problema no es
|
|
892
|
+
estético: un emoji se renderiza con la fuente de emojis del **sistema del
|
|
893
|
+
usuario** — Segoe UI Emoji en Windows, Apple Color Emoji en macOS, Noto en
|
|
894
|
+
Android — así que el mismo carácter se ve distinto en cada plataforma, y en
|
|
895
|
+
un Linux sin fuente de emojis directamente no se renderiza (sale el cuadro
|
|
896
|
+
vacío □). Un SVG se ve idéntico en todas partes.
|
|
897
|
+
|
|
898
|
+
```tsx
|
|
899
|
+
<button>Enviar 🚀</button> // ❌ depende de la fuente del sistema
|
|
900
|
+
<button>Enviar <Rocket /></button> // ✅ lucide-react: idéntico en todas partes
|
|
901
|
+
```
|
|
902
|
+
|
|
903
|
+
Detecta por propiedad Unicode (`Extended_Pictographic`), así que los símbolos
|
|
904
|
+
tipográficos normales no se tocan: `→`, `✓`, `©`, `·` pasan sin problema.
|
|
905
|
+
|
|
906
|
+
No revisa comentarios: un emoji en un comentario no llega al navegador. Para
|
|
907
|
+
eximir archivos completos (fixtures, seeds), usa `allowFilePatterns`:
|
|
908
|
+
|
|
909
|
+
```js
|
|
910
|
+
"skapxd/no-emoji": ["error", {
|
|
911
|
+
allowFilePatterns: ["tests/fixtures/**"],
|
|
912
|
+
}]
|
|
913
|
+
```
|
|
914
|
+
|
|
733
915
|
### `skapxd/no-functions-inside-components`
|
|
734
916
|
|
|
735
|
-
Prohíbe **
|
|
736
|
-
con nombre PascalCase)
|
|
737
|
-
re-renders
|
|
917
|
+
Prohíbe definir funciones **con peso propio** dentro de un componente React
|
|
918
|
+
(una función con nombre PascalCase): handlers con nombre, helpers, callbacks de
|
|
919
|
+
`useEffect`. Cada render las recrea, dispara re-renders en hijos memoizados y
|
|
920
|
+
mezcla lógica con composición.
|
|
738
921
|
|
|
739
922
|
```tsx
|
|
740
923
|
function Card() {
|
|
741
|
-
const onClick = () => save(); // ❌
|
|
924
|
+
const onClick = () => save(); // ❌ handler con nombre en el cuerpo
|
|
742
925
|
useEffect(() => subscribe(), []); // ❌ callback dentro del componente
|
|
743
|
-
return
|
|
926
|
+
return (
|
|
927
|
+
<ul>
|
|
928
|
+
{items.map((i) => <Li key={i} />)} {/* ✅ React idiomático */}
|
|
929
|
+
<button onClick={() => save()}>Guardar</button> {/* ✅ React idiomático */}
|
|
930
|
+
</ul>
|
|
931
|
+
);
|
|
744
932
|
}
|
|
745
933
|
```
|
|
746
934
|
|
|
935
|
+
Los dos patrones idiomáticos de React están **permitidos por defecto**: el
|
|
936
|
+
callback anónimo como valor directo de una prop JSX y el callback anónimo de
|
|
937
|
+
`.map(...)` en el render. Forzarlos a salir del componente produce workarounds
|
|
938
|
+
peores que el problema (`.bind(null, ...)`, adapters artificiales).
|
|
939
|
+
|
|
747
940
|
El cuerpo del componente queda como composición declarativa; **toda** función
|
|
748
941
|
—handlers, efectos, memos, mapeos— vive fuera:
|
|
749
942
|
|
|
@@ -764,23 +957,28 @@ function Card() {
|
|
|
764
957
|
helper en minúscula **sí** pueden tener funciones dentro — ahí es donde se mueve
|
|
765
958
|
la lógica.
|
|
766
959
|
|
|
767
|
-
**Opciones
|
|
768
|
-
|
|
769
|
-
|
|
960
|
+
**Opciones.** Las exenciones aplican solo a **flechas de expresión** (sin
|
|
961
|
+
cuerpo `{ }`) en esa posición exacta: el valor directo de una prop JSX, o el
|
|
962
|
+
primer argumento de `.map(...)`. La distinción importa: una flecha de expresión
|
|
963
|
+
solo puede contener una expresión — es declarativa por construcción —, mientras
|
|
964
|
+
que un bloque da pie a `if`s, variables y llamadas que pertenecen fuera:
|
|
965
|
+
|
|
966
|
+
```tsx
|
|
967
|
+
{items.map((i) => <li key={i} />)} // ✅ flecha de expresión
|
|
968
|
+
{items.map((i) => { return <li key={i} />; })} // ❌ bloque: invita a meter lógica
|
|
969
|
+
```
|
|
970
|
+
|
|
971
|
+
Un handler con nombre en el cuerpo (`const onClick = () => ...`), un callback
|
|
972
|
+
de `useEffect` o un `.forEach` siguen reportándose. Para el modo ultraestricto
|
|
973
|
+
(ninguna función inline, como en v0.6.0 y anteriores), apágalas explícitamente:
|
|
770
974
|
|
|
771
975
|
```js
|
|
772
976
|
"skapxd/no-functions-inside-components": ["error", {
|
|
773
|
-
allowJsxCallbacks:
|
|
774
|
-
allowArrayMapCallbacks:
|
|
977
|
+
allowJsxCallbacks: false, // también reporta onClick={() => ...}
|
|
978
|
+
allowArrayMapCallbacks: false, // también reporta items.map((i) => ...)
|
|
775
979
|
}]
|
|
776
980
|
```
|
|
777
981
|
|
|
778
|
-
Ambas exenciones aplican **solo a funciones anónimas inline en esa posición
|
|
779
|
-
exacta**: el valor directo de una prop JSX, o el primer argumento de `.map(...)`.
|
|
780
|
-
Un handler con nombre en el cuerpo (`const onClick = () => ...`), un callback de
|
|
781
|
-
`useEffect` o un `.forEach` siguen reportándose — la lógica con peso sigue
|
|
782
|
-
viviendo fuera del componente.
|
|
783
|
-
|
|
784
982
|
### `skapxd/no-try-catch`
|
|
785
983
|
|
|
786
984
|
Prohíbe `try/catch`. La intención es que los errores se modelen como `Result` en
|
package/dist/astro/index.d.mts
CHANGED
|
@@ -12,6 +12,8 @@ declare function createAstroConfigs(pluginReference: unknown): ({
|
|
|
12
12
|
rules: {
|
|
13
13
|
"skapxd/no-ad-hoc-ok-result": string;
|
|
14
14
|
"skapxd/no-deep-relative-imports": string;
|
|
15
|
+
"skapxd/no-default-export": string;
|
|
16
|
+
"skapxd/no-emoji": string;
|
|
15
17
|
"skapxd/no-promise-chain": string;
|
|
16
18
|
"skapxd/no-try-catch": string;
|
|
17
19
|
"skapxd/one-root-function-per-file": string;
|
|
@@ -27,6 +29,8 @@ declare function createAstroConfigs(pluginReference: unknown): ({
|
|
|
27
29
|
rules: {
|
|
28
30
|
"skapxd/no-ad-hoc-ok-result": string;
|
|
29
31
|
"skapxd/no-deep-relative-imports": string;
|
|
32
|
+
"skapxd/no-default-export": string;
|
|
33
|
+
"skapxd/no-emoji": string;
|
|
30
34
|
"skapxd/no-promise-chain": string;
|
|
31
35
|
"skapxd/no-try-catch": string;
|
|
32
36
|
"skapxd/one-root-function-per-file": string;
|
package/dist/astro/index.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ declare function createAstroConfigs(pluginReference: unknown): ({
|
|
|
12
12
|
rules: {
|
|
13
13
|
"skapxd/no-ad-hoc-ok-result": string;
|
|
14
14
|
"skapxd/no-deep-relative-imports": string;
|
|
15
|
+
"skapxd/no-default-export": string;
|
|
16
|
+
"skapxd/no-emoji": string;
|
|
15
17
|
"skapxd/no-promise-chain": string;
|
|
16
18
|
"skapxd/no-try-catch": string;
|
|
17
19
|
"skapxd/one-root-function-per-file": string;
|
|
@@ -27,6 +29,8 @@ declare function createAstroConfigs(pluginReference: unknown): ({
|
|
|
27
29
|
rules: {
|
|
28
30
|
"skapxd/no-ad-hoc-ok-result": string;
|
|
29
31
|
"skapxd/no-deep-relative-imports": string;
|
|
32
|
+
"skapxd/no-default-export": string;
|
|
33
|
+
"skapxd/no-emoji": string;
|
|
30
34
|
"skapxd/no-promise-chain": string;
|
|
31
35
|
"skapxd/no-try-catch": string;
|
|
32
36
|
"skapxd/one-root-function-per-file": string;
|
package/dist/astro/index.js
CHANGED
|
@@ -38,6 +38,8 @@ module.exports = __toCommonJS(astro_exports);
|
|
|
38
38
|
var baseRules = {
|
|
39
39
|
"skapxd/no-ad-hoc-ok-result": "error",
|
|
40
40
|
"skapxd/no-deep-relative-imports": "error",
|
|
41
|
+
"skapxd/no-default-export": "error",
|
|
42
|
+
"skapxd/no-emoji": "error",
|
|
41
43
|
"skapxd/no-promise-chain": "error",
|
|
42
44
|
"skapxd/no-try-catch": "error",
|
|
43
45
|
"skapxd/one-root-function-per-file": "error",
|
package/dist/astro/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/astro/index.ts","../../src/shared/configs/base-rules.ts","../../src/shared/configs/create-base-language-options.ts","../../src/shared/configs/create-typed-language-options.ts","../../src/astro/configs.ts"],"sourcesContent":["export { createAstroConfigs } from \"./configs\";\n","export const baseRules = {\n \"skapxd/no-ad-hoc-ok-result\": \"error\",\n \"skapxd/no-deep-relative-imports\": \"error\",\n \"skapxd/no-promise-chain\": \"error\",\n \"skapxd/no-try-catch\": \"error\",\n \"skapxd/one-root-function-per-file\": \"error\",\n \"skapxd/prefer-ts-pattern\": \"error\",\n \"skapxd/result-error-requires-cause\": \"error\",\n};\n","import tseslint from \"typescript-eslint\";\n\n// Variante sin type-checking: solo el parser, para presets que aplican a TS\n// pero no necesitan projectService (base, package, next/base, next/react).\nexport function createBaseLanguageOptions() {\n return {\n parser: tseslint.parser,\n };\n}\n","import tseslint from \"typescript-eslint\";\n\nexport function createTypedLanguageOptions() {\n return {\n // Sin el parser explícito, un consumidor que use solo estos presets\n // obtiene \"Parsing error\" en cada archivo TS (espree no parsea TS).\n parser: tseslint.parser,\n parserOptions: {\n projectService: true,\n },\n };\n}\n","import {\n baseRules,\n createBaseLanguageOptions,\n createTypedLanguageOptions,\n} from \"#/shared/configs\";\n\nexport function createAstroConfigs(pluginReference: unknown) {\n const baseLanguageOptions = createBaseLanguageOptions();\n const typedLanguageOptions = createTypedLanguageOptions();\n\n return [\n {\n files: [\"src/**/*.{ts,tsx}\"],\n languageOptions: baseLanguageOptions,\n name: \"skapxd/astro/base\",\n plugins: { skapxd: pluginReference },\n rules: baseRules,\n },\n // Los .astro no llevan parser propio: lo aporta eslint-plugin-astro,\n // que el consumidor debe tener configurado.\n {\n files: [\"src/**/*.astro\"],\n name: \"skapxd/astro/astro-files\",\n plugins: { skapxd: pluginReference },\n rules: baseRules,\n },\n {\n files: [\"src/**/*.{ts,tsx}\"],\n languageOptions: typedLanguageOptions,\n name: \"skapxd/astro/typescript\",\n plugins: { skapxd: pluginReference },\n rules: {\n \"skapxd/await-requires-result\": \"error\",\n \"skapxd/result-error-requires-cause\": \"error\",\n },\n },\n ];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,YAAY;AAAA,EACvB,8BAA8B;AAAA,EAC9B,mCAAmC;AAAA,EACnC,2BAA2B;AAAA,EAC3B,uBAAuB;AAAA,EACvB,qCAAqC;AAAA,EACrC,4BAA4B;AAAA,EAC5B,sCAAsC;AACxC;;;
|
|
1
|
+
{"version":3,"sources":["../../src/astro/index.ts","../../src/shared/configs/base-rules.ts","../../src/shared/configs/create-base-language-options.ts","../../src/shared/configs/create-typed-language-options.ts","../../src/astro/configs.ts"],"sourcesContent":["export { createAstroConfigs } from \"./configs\";\n","export const baseRules = {\n \"skapxd/no-ad-hoc-ok-result\": \"error\",\n \"skapxd/no-deep-relative-imports\": \"error\",\n \"skapxd/no-default-export\": \"error\",\n \"skapxd/no-emoji\": \"error\",\n \"skapxd/no-promise-chain\": \"error\",\n \"skapxd/no-try-catch\": \"error\",\n \"skapxd/one-root-function-per-file\": \"error\",\n \"skapxd/prefer-ts-pattern\": \"error\",\n \"skapxd/result-error-requires-cause\": \"error\",\n};\n","import tseslint from \"typescript-eslint\";\n\n// Variante sin type-checking: solo el parser, para presets que aplican a TS\n// pero no necesitan projectService (base, package, next/base, next/react).\nexport function createBaseLanguageOptions() {\n return {\n parser: tseslint.parser,\n };\n}\n","import tseslint from \"typescript-eslint\";\n\nexport function createTypedLanguageOptions() {\n return {\n // Sin el parser explícito, un consumidor que use solo estos presets\n // obtiene \"Parsing error\" en cada archivo TS (espree no parsea TS).\n parser: tseslint.parser,\n parserOptions: {\n projectService: true,\n },\n };\n}\n","import {\n baseRules,\n createBaseLanguageOptions,\n createTypedLanguageOptions,\n} from \"#/shared/configs\";\n\nexport function createAstroConfigs(pluginReference: unknown) {\n const baseLanguageOptions = createBaseLanguageOptions();\n const typedLanguageOptions = createTypedLanguageOptions();\n\n return [\n {\n files: [\"src/**/*.{ts,tsx}\"],\n languageOptions: baseLanguageOptions,\n name: \"skapxd/astro/base\",\n plugins: { skapxd: pluginReference },\n rules: baseRules,\n },\n // Los .astro no llevan parser propio: lo aporta eslint-plugin-astro,\n // que el consumidor debe tener configurado.\n {\n files: [\"src/**/*.astro\"],\n name: \"skapxd/astro/astro-files\",\n plugins: { skapxd: pluginReference },\n rules: baseRules,\n },\n {\n files: [\"src/**/*.{ts,tsx}\"],\n languageOptions: typedLanguageOptions,\n name: \"skapxd/astro/typescript\",\n plugins: { skapxd: pluginReference },\n rules: {\n \"skapxd/await-requires-result\": \"error\",\n \"skapxd/result-error-requires-cause\": \"error\",\n },\n },\n ];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,YAAY;AAAA,EACvB,8BAA8B;AAAA,EAC9B,mCAAmC;AAAA,EACnC,4BAA4B;AAAA,EAC5B,mBAAmB;AAAA,EACnB,2BAA2B;AAAA,EAC3B,uBAAuB;AAAA,EACvB,qCAAqC;AAAA,EACrC,4BAA4B;AAAA,EAC5B,sCAAsC;AACxC;;;ACVA,+BAAqB;AAId,SAAS,4BAA4B;AAC1C,SAAO;AAAA,IACL,QAAQ,yBAAAA,QAAS;AAAA,EACnB;AACF;;;ACRA,IAAAC,4BAAqB;AAEd,SAAS,6BAA6B;AAC3C,SAAO;AAAA;AAAA;AAAA,IAGL,QAAQ,0BAAAC,QAAS;AAAA,IACjB,eAAe;AAAA,MACb,gBAAgB;AAAA,IAClB;AAAA,EACF;AACF;;;ACLO,SAAS,mBAAmB,iBAA0B;AAC3D,QAAM,sBAAsB,0BAA0B;AACtD,QAAM,uBAAuB,2BAA2B;AAExD,SAAO;AAAA,IACL;AAAA,MACE,OAAO,CAAC,mBAAmB;AAAA,MAC3B,iBAAiB;AAAA,MACjB,MAAM;AAAA,MACN,SAAS,EAAE,QAAQ,gBAAgB;AAAA,MACnC,OAAO;AAAA,IACT;AAAA;AAAA;AAAA,IAGA;AAAA,MACE,OAAO,CAAC,gBAAgB;AAAA,MACxB,MAAM;AAAA,MACN,SAAS,EAAE,QAAQ,gBAAgB;AAAA,MACnC,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,OAAO,CAAC,mBAAmB;AAAA,MAC3B,iBAAiB;AAAA,MACjB,MAAM;AAAA,MACN,SAAS,EAAE,QAAQ,gBAAgB;AAAA,MACnC,OAAO;AAAA,QACL,gCAAgC;AAAA,QAChC,sCAAsC;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AACF;","names":["tseslint","import_typescript_eslint","tseslint"]}
|
package/dist/astro/index.mjs
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
nextAppMetadataFileStems,
|
|
3
|
+
nextAppRouteSegmentFileStems
|
|
4
|
+
} from "./chunk-HB755SJQ.mjs";
|
|
1
5
|
import {
|
|
2
6
|
baseRules,
|
|
3
7
|
createBaseLanguageOptions,
|
|
4
8
|
createTypedLanguageOptions
|
|
5
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-Z6CU2N4C.mjs";
|
|
6
10
|
|
|
7
11
|
// src/next/configs.ts
|
|
12
|
+
var nextDefaultExportFileGlob = `{${[
|
|
13
|
+
...nextAppRouteSegmentFileStems,
|
|
14
|
+
...nextAppMetadataFileStems
|
|
15
|
+
].join(",")}}.{js,jsx,ts,tsx}`;
|
|
8
16
|
function createNextConfigs(pluginReference) {
|
|
9
17
|
const baseLanguageOptions = createBaseLanguageOptions();
|
|
10
18
|
const typedLanguageOptions = createTypedLanguageOptions();
|
|
@@ -13,7 +21,15 @@ function createNextConfigs(pluginReference) {
|
|
|
13
21
|
languageOptions: baseLanguageOptions,
|
|
14
22
|
name: "skapxd/next/base",
|
|
15
23
|
plugins: { skapxd: pluginReference },
|
|
16
|
-
rules:
|
|
24
|
+
rules: {
|
|
25
|
+
...baseRules,
|
|
26
|
+
"skapxd/no-default-export": [
|
|
27
|
+
"error",
|
|
28
|
+
{
|
|
29
|
+
allowFilePatterns: [nextDefaultExportFileGlob]
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
17
33
|
},
|
|
18
34
|
{
|
|
19
35
|
files: ["src/app/api/**/*.{ts,tsx}", "src/server/**/*.{ts,tsx}"],
|
|
@@ -53,4 +69,4 @@ function createNextConfigs(pluginReference) {
|
|
|
53
69
|
export {
|
|
54
70
|
createNextConfigs
|
|
55
71
|
};
|
|
56
|
-
//# sourceMappingURL=chunk-
|
|
72
|
+
//# sourceMappingURL=chunk-2IXJXIW5.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/next/configs.ts"],"sourcesContent":["import { nextAppMetadataFileStems } from \"#/constants/next-app-metadata-file-stems\";\nimport { nextAppRouteSegmentFileStems } from \"#/constants/next-app-route-segment-file-stems\";\nimport {\n baseRules,\n createBaseLanguageOptions,\n createTypedLanguageOptions,\n} from \"#/shared/configs\";\n\n// Entrypoints donde Next exige `export default` (page, layout, sitemap, ...):\n// la regla no-default-export los exime automáticamente en este preset.\nconst nextDefaultExportFileGlob = `{${[\n ...nextAppRouteSegmentFileStems,\n ...nextAppMetadataFileStems,\n].join(\",\")}}.{js,jsx,ts,tsx}`;\n\nexport function createNextConfigs(pluginReference: unknown) {\n const baseLanguageOptions = createBaseLanguageOptions();\n const typedLanguageOptions = createTypedLanguageOptions();\n\n return [\n {\n languageOptions: baseLanguageOptions,\n name: \"skapxd/next/base\",\n plugins: { skapxd: pluginReference },\n rules: {\n ...baseRules,\n \"skapxd/no-default-export\": [\n \"error\",\n {\n allowFilePatterns: [nextDefaultExportFileGlob],\n },\n ],\n },\n },\n {\n files: [\"src/app/api/**/*.{ts,tsx}\", \"src/server/**/*.{ts,tsx}\"],\n languageOptions: typedLanguageOptions,\n name: \"skapxd/next/server\",\n plugins: { skapxd: pluginReference },\n rules: {\n ...baseRules,\n // Obligatoria: todo await resuelve en Result. A diferencia de\n // async-functions-return-result (apagada por defecto), no necesita\n // excepciones para los entrypoints de Next: envolver un await en\n // trySafe es compatible con cualquier firma que imponga el framework.\n \"skapxd/await-requires-result\": \"error\",\n },\n },\n {\n files: [\"**/*.tsx\"],\n languageOptions: baseLanguageOptions,\n name: \"skapxd/next/react\",\n plugins: { skapxd: pluginReference },\n rules: {\n \"skapxd/jsx-return-name-pascal-case\": \"error\",\n \"skapxd/no-functions-inside-components\": \"error\",\n \"skapxd/no-jsx-ternary-null\": \"error\",\n \"skapxd/max-hook-size\": [\n \"error\",\n {\n maxLines: 120,\n maxUseState: 1,\n },\n ],\n },\n },\n ];\n}\n"],"mappings":";;;;;;;;;;;AAUA,IAAM,4BAA4B,IAAI;AAAA,EACpC,GAAG;AAAA,EACH,GAAG;AACL,EAAE,KAAK,GAAG,CAAC;AAEJ,SAAS,kBAAkB,iBAA0B;AAC1D,QAAM,sBAAsB,0BAA0B;AACtD,QAAM,uBAAuB,2BAA2B;AAExD,SAAO;AAAA,IACL;AAAA,MACE,iBAAiB;AAAA,MACjB,MAAM;AAAA,MACN,SAAS,EAAE,QAAQ,gBAAgB;AAAA,MACnC,OAAO;AAAA,QACL,GAAG;AAAA,QACH,4BAA4B;AAAA,UAC1B;AAAA,UACA;AAAA,YACE,mBAAmB,CAAC,yBAAyB;AAAA,UAC/C;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO,CAAC,6BAA6B,0BAA0B;AAAA,MAC/D,iBAAiB;AAAA,MACjB,MAAM;AAAA,MACN,SAAS,EAAE,QAAQ,gBAAgB;AAAA,MACnC,OAAO;AAAA,QACL,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA,QAKH,gCAAgC;AAAA,MAClC;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO,CAAC,UAAU;AAAA,MAClB,iBAAiB;AAAA,MACjB,MAAM;AAAA,MACN,SAAS,EAAE,QAAQ,gBAAgB;AAAA,MACnC,OAAO;AAAA,QACL,sCAAsC;AAAA,QACtC,yCAAyC;AAAA,QACzC,8BAA8B;AAAA,QAC9B,wBAAwB;AAAA,UACtB;AAAA,UACA;AAAA,YACE,UAAU;AAAA,YACV,aAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|