@skapxd/eslint-opinionated 0.6.0 → 0.7.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 +186 -16
- package/dist/astro/index.d.mts +2 -0
- package/dist/astro/index.d.ts +2 -0
- package/dist/astro/index.js +1 -0
- package/dist/astro/index.js.map +1 -1
- package/dist/astro/index.mjs +2 -2
- package/dist/{chunk-QJQ2E2NG.mjs → chunk-72XIHMY7.mjs} +19 -3
- package/dist/chunk-72XIHMY7.mjs.map +1 -0
- package/dist/{chunk-5BA4KA37.mjs → chunk-G6TJUBFT.mjs} +89 -41
- package/dist/chunk-G6TJUBFT.mjs.map +1 -0
- package/dist/chunk-HB755SJQ.mjs +32 -0
- package/dist/chunk-HB755SJQ.mjs.map +1 -0
- package/dist/{chunk-RWQGOTVZ.mjs → chunk-LDAR6XT6.mjs} +2 -1
- package/dist/chunk-LDAR6XT6.mjs.map +1 -0
- package/dist/{chunk-7H7DRTP2.mjs → chunk-OVPAO7Q3.mjs} +2 -2
- package/dist/index.js +125 -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 +8 -0
- package/dist/next/index.d.ts +8 -0
- package/dist/next/index.js +41 -1
- package/dist/next/index.js.map +1 -1
- package/dist/next/index.mjs +3 -2
- package/dist/shared/index.d.mts +3 -0
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +84 -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-OVPAO7Q3.mjs.map} +0 -0
package/README.md
CHANGED
|
@@ -510,6 +510,50 @@ 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-functions-inside-components` | `allowJsxCallbacks`, `allowArrayMapCallbacks` (ambas `true` por defecto) |
|
|
550
|
+
| `no-promise-chain` | `methods` |
|
|
551
|
+
|
|
552
|
+
Los `allowFilePatterns` de todas las reglas son **globs** (`*` un segmento,
|
|
553
|
+
`**` cualquier profundidad, `{a,b}` alternativas; un patrón sin prefijo
|
|
554
|
+
matchea en cualquier carpeta). Las 7 reglas restantes no tienen opciones: su
|
|
555
|
+
única configuración es activarlas, apagarlas o cambiar la severidad.
|
|
556
|
+
|
|
513
557
|
## Reglas
|
|
514
558
|
|
|
515
559
|
| Regla | Qué protege |
|
|
@@ -522,6 +566,7 @@ bloque con `linterOptions: { noInlineConfig: false }` para esos globs.
|
|
|
522
566
|
| `skapxd/max-hook-size` | Marca hooks grandes o con demasiados `useState`. |
|
|
523
567
|
| `skapxd/jsx-return-name-pascal-case` | Funciones que retornan JSX deben nombrarse como componentes. |
|
|
524
568
|
| `skapxd/no-deep-relative-imports` | Limita la profundidad de los imports relativos (`../`). |
|
|
569
|
+
| `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. |
|
|
525
570
|
| `skapxd/no-functions-inside-components` | Prohíbe definir funciones dentro de componentes React. |
|
|
526
571
|
| `skapxd/no-try-catch` | Prohíbe `try/catch`; usa `trySafe` de `@skapxd/result`. |
|
|
527
572
|
| `skapxd/no-promise-chain` | Prohíbe `.then/.catch/.finally`; usa `await` (+ `trySafe`). |
|
|
@@ -610,6 +655,20 @@ async function no(): Promise<Result<number, Error>> {} // se reporta
|
|
|
610
655
|
> Sin información de tipos cae a una comprobación por nombre (`resultTypeNames`),
|
|
611
656
|
> menos estricta.
|
|
612
657
|
|
|
658
|
+
Todas las opciones, con sus defaults:
|
|
659
|
+
|
|
660
|
+
```js
|
|
661
|
+
"skapxd/async-functions-return-result": ["error", {
|
|
662
|
+
allowFilePatterns: [], // globs de archivos exentos, p. ej. ["src/legacy/**"]
|
|
663
|
+
allowNamePatterns: [], // regex de nombres exentos, p. ej. ["^(GET|POST)$"]
|
|
664
|
+
checkMissingReturnType: true, // reportar también funciones SIN anotación de retorno
|
|
665
|
+
checkMissingReturnTypeWhenCallNames: [], // ...o solo si el cuerpo llama a estos nombres
|
|
666
|
+
requireCallNames: [], // acotar la regla a funciones que llamen a estos nombres
|
|
667
|
+
promiseTypeNames: ["Promise"], // wrappers de promesa aceptados (fallback sin tipos)
|
|
668
|
+
resultTypeNames: ["Result"], // nombres de Result aceptados (fallback sin tipos)
|
|
669
|
+
}]
|
|
670
|
+
```
|
|
671
|
+
|
|
613
672
|
### `skapxd/result-error-requires-cause`
|
|
614
673
|
|
|
615
674
|
Evita perder el error original al transformar un `Result` fallido:
|
|
@@ -698,6 +757,30 @@ Sirve para código de pegamento, pero deja el error sin modelar (`Result<T,
|
|
|
698
757
|
unknown>`). Cuando la misma operación se repite o el error importa, el mensaje
|
|
699
758
|
de la regla empuja hacia el camino 1.
|
|
700
759
|
|
|
760
|
+
### `skapxd/no-ad-hoc-ok-result`
|
|
761
|
+
|
|
762
|
+
Prohíbe que una función async **exportada** retorne objetos literales con la
|
|
763
|
+
forma `{ ok: ... }` armados a mano. Un contrato casero fragmenta el sistema:
|
|
764
|
+
cada módulo inventa su variante, la exención type-aware de
|
|
765
|
+
`await-requires-result` no lo reconoce, y `match()` pierde la exhaustividad.
|
|
766
|
+
|
|
767
|
+
```ts
|
|
768
|
+
export async function getUser(id: string) {
|
|
769
|
+
return { ok: false, message: "falló" }; // ❌ contrato inventado
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
export async function getUser(id: string): Promise<Result<User, UserError>> {
|
|
773
|
+
return Result.err({ // ✅ el Result real
|
|
774
|
+
cause: error,
|
|
775
|
+
message: "No pude cargar el usuario.",
|
|
776
|
+
type: "USER_FETCH_FAILED",
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
Solo mira funciones async exportadas: un helper interno con un objeto `ok`
|
|
782
|
+
cualquiera no es un contrato público y no se reporta.
|
|
783
|
+
|
|
701
784
|
### `skapxd/max-hook-size`
|
|
702
785
|
|
|
703
786
|
Marca hooks que crecen demasiado o acumulan muchos `useState`.
|
|
@@ -705,6 +788,35 @@ Marca hooks que crecen demasiado o acumulan muchos `useState`.
|
|
|
705
788
|
La intención es empujar el diseño hacia `useReducer`, hooks más pequeños o
|
|
706
789
|
módulos de transición de estado.
|
|
707
790
|
|
|
791
|
+
Opciones (los presets `frontend` y `next` usan `maxLines: 120`, `maxUseState: 1`):
|
|
792
|
+
|
|
793
|
+
```js
|
|
794
|
+
"skapxd/max-hook-size": ["error", {
|
|
795
|
+
maxLines: 120, // líneas máximas del cuerpo del hook
|
|
796
|
+
maxUseState: 1, // useState propios permitidos antes de exigir useReducer
|
|
797
|
+
}]
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
### `skapxd/jsx-return-name-pascal-case`
|
|
801
|
+
|
|
802
|
+
Si una función devuelve JSX, es un componente, y debe llamarse como tal:
|
|
803
|
+
PascalCase. El mensaje sugiere el rename concreto.
|
|
804
|
+
|
|
805
|
+
```tsx
|
|
806
|
+
function renderUserCard(user: User) { // ❌ "render*" devuelve JSX → es un componente
|
|
807
|
+
return <article>{user.name}</article>;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
function UserCard({ user }: { user: User }) { // ✅ nombre de componente + props
|
|
811
|
+
return <article>{user.name}</article>;
|
|
812
|
+
}
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
Esta regla es la que mantiene honesto al resto del sistema React: las reglas
|
|
816
|
+
de componentes detectan "componente" por nombre PascalCase, así que una
|
|
817
|
+
función `renderX` que devuelve JSX escaparía de ellas. Esta la captura y
|
|
818
|
+
fuerza el rename — y con el nombre corregido, las demás ya la ven.
|
|
819
|
+
|
|
708
820
|
### `skapxd/no-deep-relative-imports`
|
|
709
821
|
|
|
710
822
|
Limita cuántos niveles puede subir un import relativo. Por defecto **prohíbe
|
|
@@ -730,20 +842,73 @@ Revisa imports estáticos (`import`), re-exports (`export ... from`) e imports
|
|
|
730
842
|
dinámicos (`import(...)`). El remedio habitual es un alias de ruta (`@/...`) o
|
|
731
843
|
acercar el módulo a quien lo usa.
|
|
732
844
|
|
|
845
|
+
### `skapxd/no-default-export`
|
|
846
|
+
|
|
847
|
+
Prohíbe `export default` (incluida la forma `export { x as default }`). Con
|
|
848
|
+
exports nombrados, el nombre del símbolo es el contrato del módulo: renombrar
|
|
849
|
+
con el IDE actualiza todos los usos, `grep` encuentra definición y consumo, y
|
|
850
|
+
los autoimports no inventan nombres distintos por archivo.
|
|
851
|
+
|
|
852
|
+
```ts
|
|
853
|
+
export default function getUser() {} // ❌ cada import puede llamarlo distinto
|
|
854
|
+
export function getUser() {} // ✅ un solo nombre canónico
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
**Dónde sí se permite el default.** Hay entrypoints donde el ecosistema lo
|
|
858
|
+
exige, y la regla los reconoce en capas:
|
|
859
|
+
|
|
860
|
+
1. **Integrados (siempre activos):** configs de tooling (`*.config.{js,mjs,cjs,ts}`:
|
|
861
|
+
`next.config`, `tailwind.config`, `vitest.config`, `eslint.config`, ...) y
|
|
862
|
+
stories de Storybook (`*.stories.*`).
|
|
863
|
+
2. **Preset `next` (automático):** los entrypoints del App Router donde Next
|
|
864
|
+
exige el default — `page`, `layout`, `template`, `error`, `loading`,
|
|
865
|
+
`not-found`, `sitemap`, `robots`, `manifest`, `icon`, `opengraph-image`,
|
|
866
|
+
etc. No hay que configurar nada.
|
|
867
|
+
3. **`allowFilePatterns` (extensible):** si usas un framework o tool que la
|
|
868
|
+
regla aún no contempla, agrega su glob. Los patrones propios se **suman**
|
|
869
|
+
a los integrados, no los reemplazan. Son globs legibles (`*` un segmento,
|
|
870
|
+
`**` cualquier profundidad, `{a,b}` alternativas) y un patrón sin prefijo
|
|
871
|
+
matchea en cualquier carpeta:
|
|
872
|
+
|
|
873
|
+
```js
|
|
874
|
+
"skapxd/no-default-export": ["error", {
|
|
875
|
+
// p. ej. SvelteKit exige default en +page.ts / +layout.ts
|
|
876
|
+
allowFilePatterns: ["+page.ts", "+layout.ts"],
|
|
877
|
+
}]
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
Detalle útil con `React.lazy` (que espera `{ default }`): no hace falta volver
|
|
881
|
+
al default export, basta mapear el named en el import dinámico:
|
|
882
|
+
|
|
883
|
+
```ts
|
|
884
|
+
const Card = lazy(() => import("./card").then((m) => ({ default: m.Card })));
|
|
885
|
+
```
|
|
886
|
+
|
|
733
887
|
### `skapxd/no-functions-inside-components`
|
|
734
888
|
|
|
735
|
-
Prohíbe **
|
|
736
|
-
con nombre PascalCase)
|
|
737
|
-
re-renders
|
|
889
|
+
Prohíbe definir funciones **con peso propio** dentro de un componente React
|
|
890
|
+
(una función con nombre PascalCase): handlers con nombre, helpers, callbacks de
|
|
891
|
+
`useEffect`. Cada render las recrea, dispara re-renders en hijos memoizados y
|
|
892
|
+
mezcla lógica con composición.
|
|
738
893
|
|
|
739
894
|
```tsx
|
|
740
895
|
function Card() {
|
|
741
|
-
const onClick = () => save(); // ❌
|
|
896
|
+
const onClick = () => save(); // ❌ handler con nombre en el cuerpo
|
|
742
897
|
useEffect(() => subscribe(), []); // ❌ callback dentro del componente
|
|
743
|
-
return
|
|
898
|
+
return (
|
|
899
|
+
<ul>
|
|
900
|
+
{items.map((i) => <Li key={i} />)} {/* ✅ React idiomático */}
|
|
901
|
+
<button onClick={() => save()}>Guardar</button> {/* ✅ React idiomático */}
|
|
902
|
+
</ul>
|
|
903
|
+
);
|
|
744
904
|
}
|
|
745
905
|
```
|
|
746
906
|
|
|
907
|
+
Los dos patrones idiomáticos de React están **permitidos por defecto**: el
|
|
908
|
+
callback anónimo como valor directo de una prop JSX y el callback anónimo de
|
|
909
|
+
`.map(...)` en el render. Forzarlos a salir del componente produce workarounds
|
|
910
|
+
peores que el problema (`.bind(null, ...)`, adapters artificiales).
|
|
911
|
+
|
|
747
912
|
El cuerpo del componente queda como composición declarativa; **toda** función
|
|
748
913
|
—handlers, efectos, memos, mapeos— vive fuera:
|
|
749
914
|
|
|
@@ -764,23 +929,28 @@ function Card() {
|
|
|
764
929
|
helper en minúscula **sí** pueden tener funciones dentro — ahí es donde se mueve
|
|
765
930
|
la lógica.
|
|
766
931
|
|
|
767
|
-
**Opciones
|
|
768
|
-
|
|
769
|
-
|
|
932
|
+
**Opciones.** Las exenciones aplican solo a **flechas de expresión** (sin
|
|
933
|
+
cuerpo `{ }`) en esa posición exacta: el valor directo de una prop JSX, o el
|
|
934
|
+
primer argumento de `.map(...)`. La distinción importa: una flecha de expresión
|
|
935
|
+
solo puede contener una expresión — es declarativa por construcción —, mientras
|
|
936
|
+
que un bloque da pie a `if`s, variables y llamadas que pertenecen fuera:
|
|
937
|
+
|
|
938
|
+
```tsx
|
|
939
|
+
{items.map((i) => <li key={i} />)} // ✅ flecha de expresión
|
|
940
|
+
{items.map((i) => { return <li key={i} />; })} // ❌ bloque: invita a meter lógica
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
Un handler con nombre en el cuerpo (`const onClick = () => ...`), un callback
|
|
944
|
+
de `useEffect` o un `.forEach` siguen reportándose. Para el modo ultraestricto
|
|
945
|
+
(ninguna función inline, como en v0.6.0 y anteriores), apágalas explícitamente:
|
|
770
946
|
|
|
771
947
|
```js
|
|
772
948
|
"skapxd/no-functions-inside-components": ["error", {
|
|
773
|
-
allowJsxCallbacks:
|
|
774
|
-
allowArrayMapCallbacks:
|
|
949
|
+
allowJsxCallbacks: false, // también reporta onClick={() => ...}
|
|
950
|
+
allowArrayMapCallbacks: false, // también reporta items.map((i) => ...)
|
|
775
951
|
}]
|
|
776
952
|
```
|
|
777
953
|
|
|
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
954
|
### `skapxd/no-try-catch`
|
|
785
955
|
|
|
786
956
|
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,7 @@ 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;
|
|
15
16
|
"skapxd/no-promise-chain": string;
|
|
16
17
|
"skapxd/no-try-catch": string;
|
|
17
18
|
"skapxd/one-root-function-per-file": string;
|
|
@@ -27,6 +28,7 @@ declare function createAstroConfigs(pluginReference: unknown): ({
|
|
|
27
28
|
rules: {
|
|
28
29
|
"skapxd/no-ad-hoc-ok-result": string;
|
|
29
30
|
"skapxd/no-deep-relative-imports": string;
|
|
31
|
+
"skapxd/no-default-export": string;
|
|
30
32
|
"skapxd/no-promise-chain": string;
|
|
31
33
|
"skapxd/no-try-catch": string;
|
|
32
34
|
"skapxd/one-root-function-per-file": string;
|
package/dist/astro/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ 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;
|
|
15
16
|
"skapxd/no-promise-chain": string;
|
|
16
17
|
"skapxd/no-try-catch": string;
|
|
17
18
|
"skapxd/one-root-function-per-file": string;
|
|
@@ -27,6 +28,7 @@ declare function createAstroConfigs(pluginReference: unknown): ({
|
|
|
27
28
|
rules: {
|
|
28
29
|
"skapxd/no-ad-hoc-ok-result": string;
|
|
29
30
|
"skapxd/no-deep-relative-imports": string;
|
|
31
|
+
"skapxd/no-default-export": string;
|
|
30
32
|
"skapxd/no-promise-chain": string;
|
|
31
33
|
"skapxd/no-try-catch": string;
|
|
32
34
|
"skapxd/one-root-function-per-file": string;
|
package/dist/astro/index.js
CHANGED
|
@@ -38,6 +38,7 @@ 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",
|
|
41
42
|
"skapxd/no-promise-chain": "error",
|
|
42
43
|
"skapxd/no-try-catch": "error",
|
|
43
44
|
"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-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,2BAA2B;AAAA,EAC3B,uBAAuB;AAAA,EACvB,qCAAqC;AAAA,EACrC,4BAA4B;AAAA,EAC5B,sCAAsC;AACxC;;;ACTA,+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-LDAR6XT6.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-72XIHMY7.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":[]}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
nextAppMetadataFileStems,
|
|
3
|
+
nextAppRouteSegmentFileStems
|
|
4
|
+
} from "./chunk-HB755SJQ.mjs";
|
|
5
|
+
|
|
1
6
|
// src/utils/get-file-name.ts
|
|
2
7
|
function getFileName(filename) {
|
|
3
8
|
return filename.split(/[\\/]/).at(-1) ?? filename;
|
|
@@ -47,33 +52,6 @@ function isInsideAppDirectory(filename) {
|
|
|
47
52
|
return getPathParts(filename).includes("app");
|
|
48
53
|
}
|
|
49
54
|
|
|
50
|
-
// src/constants/next-app-metadata-file-stems.ts
|
|
51
|
-
var nextAppMetadataFileStems = [
|
|
52
|
-
"apple-icon",
|
|
53
|
-
"icon",
|
|
54
|
-
"manifest",
|
|
55
|
-
"opengraph-image",
|
|
56
|
-
"robots",
|
|
57
|
-
"sitemap",
|
|
58
|
-
"twitter-image"
|
|
59
|
-
];
|
|
60
|
-
|
|
61
|
-
// src/constants/next-app-route-segment-file-stems.ts
|
|
62
|
-
var nextAppRouteSegmentFileStems = [
|
|
63
|
-
"default",
|
|
64
|
-
"error",
|
|
65
|
-
"forbidden",
|
|
66
|
-
"global-error",
|
|
67
|
-
"global-not-found",
|
|
68
|
-
"layout",
|
|
69
|
-
"loading",
|
|
70
|
-
"not-found",
|
|
71
|
-
"page",
|
|
72
|
-
"route",
|
|
73
|
-
"template",
|
|
74
|
-
"unauthorized"
|
|
75
|
-
];
|
|
76
|
-
|
|
77
55
|
// src/constants/next-project-root-file-stems.ts
|
|
78
56
|
var nextProjectRootFileStems = [
|
|
79
57
|
"instrumentation",
|
|
@@ -580,6 +558,16 @@ function isSkapxdResultOrPromiseResultType(type, typeContext) {
|
|
|
580
558
|
return Boolean(promisedType && isSkapxdResultType(promisedType, typeContext));
|
|
581
559
|
}
|
|
582
560
|
|
|
561
|
+
// src/utils/matches-any-glob.ts
|
|
562
|
+
import picomatch from "picomatch";
|
|
563
|
+
function matchesAnyGlob(filePath, globs) {
|
|
564
|
+
const normalized = filePath.replaceAll("\\", "/");
|
|
565
|
+
return globs.some((glob) => {
|
|
566
|
+
const anchored = glob.startsWith("/") || glob.startsWith("**") ? glob : `**/${glob}`;
|
|
567
|
+
return picomatch(anchored)(normalized);
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
|
|
583
571
|
// src/utils/matches-any-pattern.ts
|
|
584
572
|
function matchesAnyPattern(value, patterns) {
|
|
585
573
|
return patterns.some((pattern) => new RegExp(pattern).test(value));
|
|
@@ -642,7 +630,7 @@ var asyncFunctionsReturnResult = {
|
|
|
642
630
|
return isPromiseOfResultType(annotation, options);
|
|
643
631
|
}
|
|
644
632
|
function reportIfInvalidAsyncReturn(node, name, reportNode = node) {
|
|
645
|
-
if (!node.async ||
|
|
633
|
+
if (!node.async || matchesAnyGlob(filename, options.allowFilePatterns)) {
|
|
646
634
|
return;
|
|
647
635
|
}
|
|
648
636
|
const functionName = name ?? "anonymous";
|
|
@@ -939,7 +927,7 @@ var awaitRequiresResult = {
|
|
|
939
927
|
}
|
|
940
928
|
return {
|
|
941
929
|
AwaitExpression(node) {
|
|
942
|
-
if (
|
|
930
|
+
if (matchesAnyGlob(filename, options.allowFilePatterns)) {
|
|
943
931
|
return;
|
|
944
932
|
}
|
|
945
933
|
if (typeContext && isSkapxdResultOrPromiseResultExpression(node.argument, typeContext)) {
|
|
@@ -1337,20 +1325,74 @@ var noDeepRelativeImports = {
|
|
|
1337
1325
|
}
|
|
1338
1326
|
};
|
|
1339
1327
|
|
|
1340
|
-
// src/
|
|
1341
|
-
|
|
1328
|
+
// src/constants/default-export-allowed-file-patterns.ts
|
|
1329
|
+
var defaultExportAllowedFilePatterns = [
|
|
1330
|
+
"*.config.*",
|
|
1331
|
+
"*.stories.*"
|
|
1332
|
+
];
|
|
1333
|
+
|
|
1334
|
+
// src/utils/get-no-default-export-options.ts
|
|
1335
|
+
function getNoDefaultExportOptions(options = {}) {
|
|
1342
1336
|
return {
|
|
1343
|
-
|
|
1344
|
-
|
|
1337
|
+
allowFilePatterns: [
|
|
1338
|
+
...defaultExportAllowedFilePatterns,
|
|
1339
|
+
...options.allowFilePatterns ?? []
|
|
1340
|
+
]
|
|
1345
1341
|
};
|
|
1346
1342
|
}
|
|
1347
1343
|
|
|
1348
|
-
// src/
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1344
|
+
// src/rules/no-default-export.ts
|
|
1345
|
+
var noDefaultExport = {
|
|
1346
|
+
meta: {
|
|
1347
|
+
type: "suggestion",
|
|
1348
|
+
docs: {
|
|
1349
|
+
description: "Prohibe export default; un export nombrado hace del nombre el contrato del modulo."
|
|
1350
|
+
},
|
|
1351
|
+
messages: {
|
|
1352
|
+
noDefaultExport: 'No uses `export default`: un export nombrado hace el simbolo renombrable con el IDE, grepeable y estable en autoimports. Si este archivo es un entrypoint donde un framework o tool exige el default, agrega su glob en `allowFilePatterns` de skapxd/no-default-export (p. ej. "+page.ts").'
|
|
1353
|
+
},
|
|
1354
|
+
schema: [
|
|
1355
|
+
{
|
|
1356
|
+
additionalProperties: false,
|
|
1357
|
+
properties: {
|
|
1358
|
+
allowFilePatterns: {
|
|
1359
|
+
items: { type: "string" },
|
|
1360
|
+
type: "array"
|
|
1361
|
+
}
|
|
1362
|
+
},
|
|
1363
|
+
type: "object"
|
|
1364
|
+
}
|
|
1365
|
+
]
|
|
1366
|
+
},
|
|
1367
|
+
create(context) {
|
|
1368
|
+
const options = getNoDefaultExportOptions(context.options[0]);
|
|
1369
|
+
const filename = context.filename ?? context.getFilename();
|
|
1370
|
+
if (matchesAnyGlob(filename, options.allowFilePatterns)) {
|
|
1371
|
+
return {};
|
|
1372
|
+
}
|
|
1373
|
+
return {
|
|
1374
|
+
ExportDefaultDeclaration(node) {
|
|
1375
|
+
context.report({ messageId: "noDefaultExport", node });
|
|
1376
|
+
},
|
|
1377
|
+
// Cubre la forma indirecta: `export { algo as default }`.
|
|
1378
|
+
ExportNamedDeclaration(node) {
|
|
1379
|
+
for (const specifier of node.specifiers ?? []) {
|
|
1380
|
+
const exportedName = specifier.exported?.name ?? specifier.exported?.value;
|
|
1381
|
+
if (exportedName === "default") {
|
|
1382
|
+
context.report({ messageId: "noDefaultExport", node: specifier });
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
};
|
|
1352
1387
|
}
|
|
1353
|
-
|
|
1388
|
+
};
|
|
1389
|
+
|
|
1390
|
+
// src/utils/get-no-functions-inside-components-options.ts
|
|
1391
|
+
function getNoFunctionsInsideComponentsOptions(options = {}) {
|
|
1392
|
+
return {
|
|
1393
|
+
allowArrayMapCallbacks: options.allowArrayMapCallbacks ?? true,
|
|
1394
|
+
allowJsxCallbacks: options.allowJsxCallbacks ?? true
|
|
1395
|
+
};
|
|
1354
1396
|
}
|
|
1355
1397
|
|
|
1356
1398
|
// src/utils/is-array-map-callback.ts
|
|
@@ -1363,6 +1405,11 @@ function isArrayMapCallback(node) {
|
|
|
1363
1405
|
return callee?.type === "MemberExpression" && !callee.computed && callee.property?.type === "Identifier" && callee.property.name === "map";
|
|
1364
1406
|
}
|
|
1365
1407
|
|
|
1408
|
+
// src/utils/is-expression-arrow-function.ts
|
|
1409
|
+
function isExpressionArrowFunction(node) {
|
|
1410
|
+
return node.type === "ArrowFunctionExpression" && node.body.type !== "BlockStatement";
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1366
1413
|
// src/utils/is-jsx-attribute-callback.ts
|
|
1367
1414
|
function isJsxAttributeCallback(node) {
|
|
1368
1415
|
return node.parent?.type === "JSXExpressionContainer" && node.parent.parent?.type === "JSXAttribute";
|
|
@@ -1376,7 +1423,7 @@ var noFunctionsInsideComponents = {
|
|
|
1376
1423
|
description: "Prohibe definir funciones dentro de componentes React; se recrean en cada render."
|
|
1377
1424
|
},
|
|
1378
1425
|
messages: {
|
|
1379
|
-
functionInsideComponent: "No definas funciones dentro del componente `{{component}}`: se recrean en cada render. Muevela a un hook (`useX`) o a un helper fuera del componente."
|
|
1426
|
+
functionInsideComponent: "No definas funciones dentro del componente `{{component}}`: se recrean en cada render. Muevela a un hook (`useX`) o a un helper fuera del componente. Los callbacks inline de JSX y .map solo se permiten como flecha de expresion (sin cuerpo `{ }`): un bloque ya da pie a ifs y logica que pertenece fuera."
|
|
1380
1427
|
},
|
|
1381
1428
|
schema: [
|
|
1382
1429
|
{
|
|
@@ -1395,7 +1442,7 @@ var noFunctionsInsideComponents = {
|
|
|
1395
1442
|
return isFunctionNode(node) && isPascalCaseName(getFunctionName(node));
|
|
1396
1443
|
}
|
|
1397
1444
|
function isAllowedInlineCallback(node) {
|
|
1398
|
-
if (!
|
|
1445
|
+
if (!isExpressionArrowFunction(node)) {
|
|
1399
1446
|
return false;
|
|
1400
1447
|
}
|
|
1401
1448
|
if (options.allowJsxCallbacks && isJsxAttributeCallback(node)) {
|
|
@@ -1599,6 +1646,7 @@ var rules = {
|
|
|
1599
1646
|
"result-error-requires-cause": resultErrorRequiresCause,
|
|
1600
1647
|
"max-hook-size": maxHookSize,
|
|
1601
1648
|
"no-deep-relative-imports": noDeepRelativeImports,
|
|
1649
|
+
"no-default-export": noDefaultExport,
|
|
1602
1650
|
"no-functions-inside-components": noFunctionsInsideComponents,
|
|
1603
1651
|
"no-try-catch": noTryCatch,
|
|
1604
1652
|
"prefer-ts-pattern": preferTsPattern,
|
|
@@ -1609,4 +1657,4 @@ var rules = {
|
|
|
1609
1657
|
export {
|
|
1610
1658
|
rules
|
|
1611
1659
|
};
|
|
1612
|
-
//# sourceMappingURL=chunk-
|
|
1660
|
+
//# sourceMappingURL=chunk-G6TJUBFT.mjs.map
|