@skapxd/eslint-opinionated 0.10.0 → 0.11.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 +41 -1
- 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-7VZBQ6FD.mjs → chunk-3NM7FEIN.mjs} +2 -2
- package/dist/{chunk-WO7EUISC.mjs → chunk-EXMF54EM.mjs} +105 -37
- package/dist/chunk-EXMF54EM.mjs.map +1 -0
- package/dist/{chunk-GEVX3BTI.mjs → chunk-J472YWOD.mjs} +2 -1
- package/dist/chunk-J472YWOD.mjs.map +1 -0
- package/dist/{chunk-3WLCAPUA.mjs → chunk-Z2MYYOIS.mjs} +2 -2
- package/dist/index.js +106 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -5
- package/dist/index.mjs.map +1 -1
- package/dist/next/index.d.mts +2 -0
- package/dist/next/index.d.ts +2 -0
- package/dist/next/index.js +1 -0
- package/dist/next/index.js.map +1 -1
- package/dist/next/index.mjs +2 -2
- package/dist/shared/index.d.mts +3 -0
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +105 -36
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +2 -2
- package/package.json +1 -1
- package/dist/chunk-GEVX3BTI.mjs.map +0 -1
- package/dist/chunk-WO7EUISC.mjs.map +0 -1
- /package/dist/{chunk-7VZBQ6FD.mjs.map → chunk-3NM7FEIN.mjs.map} +0 -0
- /package/dist/{chunk-3WLCAPUA.mjs.map → chunk-Z2MYYOIS.mjs.map} +0 -0
package/README.md
CHANGED
|
@@ -548,6 +548,7 @@ de cada regla):
|
|
|
548
548
|
| `no-default-export` | `allowFilePatterns` (globs, aditivos a los integrados) |
|
|
549
549
|
| `no-emoji` | `allowFilePatterns` (globs) |
|
|
550
550
|
| `no-functions-inside-components` | `allowJsxCallbacks`, `allowArrayMapCallbacks` (ambas `true` por defecto) |
|
|
551
|
+
| `no-nested-if` | `allowFilePatterns` (globs) |
|
|
551
552
|
| `no-promise-chain` | `methods` |
|
|
552
553
|
| `no-tunnel-props` | `allowFilePatterns` (globs), `allowPropPatterns` (regex) |
|
|
553
554
|
| `prefer-abort-signal` | `allowFilePatterns` (globs), `effectNames` (default `["useEffect", "useLayoutEffect"]`) |
|
|
@@ -571,6 +572,7 @@ matchea en cualquier carpeta). Las 7 reglas restantes no tienen opciones: su
|
|
|
571
572
|
| `skapxd/no-deep-relative-imports` | Limita la profundidad de los imports relativos (`../`). |
|
|
572
573
|
| `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. |
|
|
573
574
|
| `skapxd/no-emoji` | Prohíbe emojis en strings y JSX; cada sistema los renderiza distinto. Usa un icono SVG. |
|
|
575
|
+
| `skapxd/no-nested-if` | Prohíbe `if` anidados: retorno anticipado o `match()`. Menos carga cognitiva y sin puntos ciegos para las demás reglas. |
|
|
574
576
|
| `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. |
|
|
575
577
|
| `skapxd/prefer-abort-signal` | Listeners en efectos se limpian con `AbortController` (`{ signal }` + `abort()`), no con `removeEventListener`. |
|
|
576
578
|
| `skapxd/no-functions-inside-components` | Prohíbe definir funciones dentro de componentes React. |
|
|
@@ -689,10 +691,19 @@ if (!result.ok) {
|
|
|
689
691
|
}
|
|
690
692
|
```
|
|
691
693
|
|
|
694
|
+
Reconoce todas las formas del guard de Result fallido — `!result.ok`,
|
|
695
|
+
`result.ok === false`, `result.ok !== true`, `Result.isErr(result)` y
|
|
696
|
+
`if (result.error)` — y dentro del guard exige el `cause` en todo
|
|
697
|
+
`Result.err(...)`. Un `Result.err()` **sin argumentos** también se reporta:
|
|
698
|
+
descartar el error por completo es el peor caso, no una exención. Y un `cause`
|
|
699
|
+
con otro valor (`cause: new Error(...)`) no cuenta: tiene que ser literalmente
|
|
700
|
+
el `result.error` del guard.
|
|
701
|
+
|
|
692
702
|
Esta regla es type-aware. Usa TypeScript parser services para confirmar que el
|
|
693
703
|
valor del guard y `Result.err` vienen de `@skapxd/result`. Por eso funciona con
|
|
694
704
|
aliases, re-exports y tipos inferidos, sin depender solo del nombre importado en
|
|
695
|
-
el archivo.
|
|
705
|
+
el archivo. Su punto ciego histórico —el `Result.err` escondido en un `if`
|
|
706
|
+
anidado— lo elimina `skapxd/no-nested-if` de raíz.
|
|
696
707
|
|
|
697
708
|
### `skapxd/await-requires-result`
|
|
698
709
|
|
|
@@ -848,6 +859,35 @@ Revisa imports estáticos (`import`), re-exports (`export ... from`) e imports
|
|
|
848
859
|
dinámicos (`import(...)`). El remedio habitual es un alias de ruta (`@/...`) o
|
|
849
860
|
acercar el módulo a quien lo usa.
|
|
850
861
|
|
|
862
|
+
### `skapxd/no-nested-if`
|
|
863
|
+
|
|
864
|
+
Prohíbe un `if` dentro de otro `if` (en la misma función). Cada nivel de
|
|
865
|
+
anidación suma carga cognitiva para quien lee — y además crea puntos ciegos
|
|
866
|
+
para las demás reglas: un `Result.err` dentro de un if anidado quedaba fuera
|
|
867
|
+
del alcance de `result-error-requires-cause`. Esta regla elimina la categoría
|
|
868
|
+
completa de evasión en vez de parchear cada caso.
|
|
869
|
+
|
|
870
|
+
```ts
|
|
871
|
+
// ❌ anidado: el lector mantiene dos condiciones en la cabeza
|
|
872
|
+
if (!response.ok) {
|
|
873
|
+
if (shouldReport) {
|
|
874
|
+
return Result.err({ cause: response.error, message: "...", type: "X" });
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
// ✅ retorno anticipado: una condición a la vez, camino feliz sin sangría
|
|
879
|
+
if (!response.ok && shouldReport) {
|
|
880
|
+
return Result.err({ cause: response.error, message: "...", type: "X" });
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// ✅ o match() si son variantes de un mismo valor
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
No cuenta como anidación: la cadena `else if` (es secuencia, no anidación), y
|
|
887
|
+
una función definida dentro del `if` (unidad cognitiva aparte). El propio
|
|
888
|
+
código de este plugin se aplanó con retorno anticipado al activar la regla —
|
|
889
|
+
cinco casos, todos quedaron más legibles.
|
|
890
|
+
|
|
851
891
|
### `skapxd/no-default-export`
|
|
852
892
|
|
|
853
893
|
Prohíbe `export default` (incluida la forma `export { x as default }`). Con
|
package/dist/astro/index.d.mts
CHANGED
|
@@ -14,6 +14,7 @@ declare function createAstroConfigs(pluginReference: unknown): ({
|
|
|
14
14
|
"skapxd/no-deep-relative-imports": string;
|
|
15
15
|
"skapxd/no-default-export": string;
|
|
16
16
|
"skapxd/no-emoji": string;
|
|
17
|
+
"skapxd/no-nested-if": string;
|
|
17
18
|
"skapxd/no-promise-chain": string;
|
|
18
19
|
"skapxd/no-try-catch": string;
|
|
19
20
|
"skapxd/one-root-function-per-file": string;
|
|
@@ -31,6 +32,7 @@ declare function createAstroConfigs(pluginReference: unknown): ({
|
|
|
31
32
|
"skapxd/no-deep-relative-imports": string;
|
|
32
33
|
"skapxd/no-default-export": string;
|
|
33
34
|
"skapxd/no-emoji": string;
|
|
35
|
+
"skapxd/no-nested-if": string;
|
|
34
36
|
"skapxd/no-promise-chain": string;
|
|
35
37
|
"skapxd/no-try-catch": string;
|
|
36
38
|
"skapxd/one-root-function-per-file": string;
|
package/dist/astro/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ declare function createAstroConfigs(pluginReference: unknown): ({
|
|
|
14
14
|
"skapxd/no-deep-relative-imports": string;
|
|
15
15
|
"skapxd/no-default-export": string;
|
|
16
16
|
"skapxd/no-emoji": string;
|
|
17
|
+
"skapxd/no-nested-if": string;
|
|
17
18
|
"skapxd/no-promise-chain": string;
|
|
18
19
|
"skapxd/no-try-catch": string;
|
|
19
20
|
"skapxd/one-root-function-per-file": string;
|
|
@@ -31,6 +32,7 @@ declare function createAstroConfigs(pluginReference: unknown): ({
|
|
|
31
32
|
"skapxd/no-deep-relative-imports": string;
|
|
32
33
|
"skapxd/no-default-export": string;
|
|
33
34
|
"skapxd/no-emoji": string;
|
|
35
|
+
"skapxd/no-nested-if": string;
|
|
34
36
|
"skapxd/no-promise-chain": string;
|
|
35
37
|
"skapxd/no-try-catch": string;
|
|
36
38
|
"skapxd/one-root-function-per-file": string;
|
package/dist/astro/index.js
CHANGED
|
@@ -40,6 +40,7 @@ var baseRules = {
|
|
|
40
40
|
"skapxd/no-deep-relative-imports": "error",
|
|
41
41
|
"skapxd/no-default-export": "error",
|
|
42
42
|
"skapxd/no-emoji": "error",
|
|
43
|
+
"skapxd/no-nested-if": "error",
|
|
43
44
|
"skapxd/no-promise-chain": "error",
|
|
44
45
|
"skapxd/no-try-catch": "error",
|
|
45
46
|
"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-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;;;
|
|
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-nested-if\": \"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,uBAAuB;AAAA,EACvB,2BAA2B;AAAA,EAC3B,uBAAuB;AAAA,EACvB,qCAAqC;AAAA,EACrC,4BAA4B;AAAA,EAC5B,sCAAsC;AACxC;;;ACXA,+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
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
baseRules,
|
|
3
3
|
createBaseLanguageOptions,
|
|
4
4
|
createTypedLanguageOptions
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-J472YWOD.mjs";
|
|
6
6
|
|
|
7
7
|
// src/astro/configs.ts
|
|
8
8
|
function createAstroConfigs(pluginReference) {
|
|
@@ -40,4 +40,4 @@ function createAstroConfigs(pluginReference) {
|
|
|
40
40
|
export {
|
|
41
41
|
createAstroConfigs
|
|
42
42
|
};
|
|
43
|
-
//# sourceMappingURL=chunk-
|
|
43
|
+
//# sourceMappingURL=chunk-3NM7FEIN.mjs.map
|
|
@@ -644,14 +644,16 @@ var asyncFunctionsReturnResult = {
|
|
|
644
644
|
return;
|
|
645
645
|
}
|
|
646
646
|
const returnType = node.returnType?.typeAnnotation;
|
|
647
|
+
const missingReturnTypeIsReportable = options.checkMissingReturnType || containsCallNamed(node.body, options.checkMissingReturnTypeWhenCallNames);
|
|
648
|
+
if (!returnType && missingReturnTypeIsReportable) {
|
|
649
|
+
context.report({
|
|
650
|
+
data: { name: functionName },
|
|
651
|
+
messageId: "missingReturnType",
|
|
652
|
+
node: reportNode
|
|
653
|
+
});
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
647
656
|
if (!returnType) {
|
|
648
|
-
if (options.checkMissingReturnType || containsCallNamed(node.body, options.checkMissingReturnTypeWhenCallNames)) {
|
|
649
|
-
context.report({
|
|
650
|
-
data: { name: functionName },
|
|
651
|
-
messageId: "missingReturnType",
|
|
652
|
-
node: reportNode
|
|
653
|
-
});
|
|
654
|
-
}
|
|
655
657
|
return;
|
|
656
658
|
}
|
|
657
659
|
if (isSkapxdResultReturnType(returnType)) {
|
|
@@ -813,14 +815,13 @@ function getAwaitScopeName(node) {
|
|
|
813
815
|
function getEnclosingTrySafeCall(node, trySafeCallNames) {
|
|
814
816
|
let currentNode = node.parent;
|
|
815
817
|
while (currentNode) {
|
|
816
|
-
if (isFunctionNode(currentNode)) {
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
return parent;
|
|
820
|
-
}
|
|
821
|
-
return null;
|
|
818
|
+
if (!isFunctionNode(currentNode)) {
|
|
819
|
+
currentNode = currentNode.parent;
|
|
820
|
+
continue;
|
|
822
821
|
}
|
|
823
|
-
|
|
822
|
+
const parent = currentNode.parent;
|
|
823
|
+
const isTrySafeArgument = parent?.type === "CallExpression" && parent.arguments.includes(currentNode) && isCalleeNamed(parent.callee, trySafeCallNames);
|
|
824
|
+
return isTrySafeArgument ? parent : null;
|
|
824
825
|
}
|
|
825
826
|
return null;
|
|
826
827
|
}
|
|
@@ -954,6 +955,18 @@ var awaitRequiresResult = {
|
|
|
954
955
|
}
|
|
955
956
|
};
|
|
956
957
|
|
|
958
|
+
// src/utils/get-error-member-object.ts
|
|
959
|
+
function getErrorMemberObject(node) {
|
|
960
|
+
const unwrappedNode = unwrapExpression(node);
|
|
961
|
+
if (unwrappedNode.type !== "MemberExpression" || unwrappedNode.object.type !== "Identifier" || !isMemberPropertyNamed(unwrappedNode, "error")) {
|
|
962
|
+
return null;
|
|
963
|
+
}
|
|
964
|
+
return {
|
|
965
|
+
name: unwrappedNode.object.name,
|
|
966
|
+
node: unwrappedNode.object
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
|
|
957
970
|
// src/utils/get-ok-member-object.ts
|
|
958
971
|
function getOkMemberObject(node) {
|
|
959
972
|
const unwrappedNode = unwrapExpression(node);
|
|
@@ -1002,6 +1015,9 @@ function getResultCheckArgument(node, methodName) {
|
|
|
1002
1015
|
// src/utils/get-failed-result-guard.ts
|
|
1003
1016
|
function getFailedResultGuard(node) {
|
|
1004
1017
|
const unwrappedNode = unwrapExpression(node);
|
|
1018
|
+
if (unwrappedNode.type === "MemberExpression") {
|
|
1019
|
+
return getErrorMemberObject(unwrappedNode);
|
|
1020
|
+
}
|
|
1005
1021
|
if (unwrappedNode.type === "UnaryExpression" && unwrappedNode.operator === "!") {
|
|
1006
1022
|
return getOkMemberObject(unwrappedNode.argument) ?? getResultCheckArgument(unwrappedNode.argument, "isOk");
|
|
1007
1023
|
}
|
|
@@ -1119,10 +1135,7 @@ var resultErrorRequiresCause = {
|
|
|
1119
1135
|
if (!isSkapxdResultErrCall(resultErrCall, typeContext)) {
|
|
1120
1136
|
continue;
|
|
1121
1137
|
}
|
|
1122
|
-
if (resultErrCall.arguments.length
|
|
1123
|
-
continue;
|
|
1124
|
-
}
|
|
1125
|
-
if (resultErrPreservesCause(resultErrCall.arguments[0], resultGuard.name)) {
|
|
1138
|
+
if (resultErrCall.arguments.length > 0 && resultErrPreservesCause(resultErrCall.arguments[0], resultGuard.name)) {
|
|
1126
1139
|
continue;
|
|
1127
1140
|
}
|
|
1128
1141
|
context.report({
|
|
@@ -1740,14 +1753,9 @@ function hasAbortSignalOption(callExpression, sourceCode, typeContext) {
|
|
|
1740
1753
|
if (options.type === "ObjectExpression") {
|
|
1741
1754
|
return objectExpressionHasSignal(options);
|
|
1742
1755
|
}
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
sourceCode.getScope(options)
|
|
1747
|
-
);
|
|
1748
|
-
if (initializer?.type === "ObjectExpression") {
|
|
1749
|
-
return objectExpressionHasSignal(initializer);
|
|
1750
|
-
}
|
|
1756
|
+
const initializer = options.type === "Identifier" ? getVariableInitializer(options, sourceCode.getScope(options)) : null;
|
|
1757
|
+
if (initializer?.type === "ObjectExpression") {
|
|
1758
|
+
return objectExpressionHasSignal(initializer);
|
|
1751
1759
|
}
|
|
1752
1760
|
if (typeContext) {
|
|
1753
1761
|
const type = typeContext.services.getTypeAtLocation(options);
|
|
@@ -1760,11 +1768,9 @@ function hasAbortSignalOption(callExpression, sourceCode, typeContext) {
|
|
|
1760
1768
|
function isInsideEffectCallback(node, effectNames) {
|
|
1761
1769
|
let current = node.parent;
|
|
1762
1770
|
while (current) {
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
return true;
|
|
1767
|
-
}
|
|
1771
|
+
const call = isFunctionNode(current) ? current.parent : null;
|
|
1772
|
+
if (call?.type === "CallExpression" && call.arguments[0] === current && isCalleeNamed(call.callee, effectNames)) {
|
|
1773
|
+
return true;
|
|
1768
1774
|
}
|
|
1769
1775
|
current = current.parent;
|
|
1770
1776
|
}
|
|
@@ -1903,6 +1909,67 @@ var noJsxTernaryNull = {
|
|
|
1903
1909
|
}
|
|
1904
1910
|
};
|
|
1905
1911
|
|
|
1912
|
+
// src/utils/get-no-nested-if-options.ts
|
|
1913
|
+
function getNoNestedIfOptions(options = {}) {
|
|
1914
|
+
return {
|
|
1915
|
+
allowFilePatterns: options.allowFilePatterns ?? []
|
|
1916
|
+
};
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1919
|
+
// src/utils/is-nested-if-statement.ts
|
|
1920
|
+
function isNestedIfStatement(node) {
|
|
1921
|
+
if (node.parent?.type === "IfStatement" && node.parent.alternate === node) {
|
|
1922
|
+
return false;
|
|
1923
|
+
}
|
|
1924
|
+
let current = node.parent;
|
|
1925
|
+
while (current && !isFunctionNode(current)) {
|
|
1926
|
+
if (current.type === "IfStatement") {
|
|
1927
|
+
return true;
|
|
1928
|
+
}
|
|
1929
|
+
current = current.parent;
|
|
1930
|
+
}
|
|
1931
|
+
return false;
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1934
|
+
// src/rules/no-nested-if.ts
|
|
1935
|
+
var noNestedIf = {
|
|
1936
|
+
meta: {
|
|
1937
|
+
type: "suggestion",
|
|
1938
|
+
docs: {
|
|
1939
|
+
description: "Prohibe if anidados; usa retorno anticipado (guard clauses) o match() de ts-pattern."
|
|
1940
|
+
},
|
|
1941
|
+
messages: {
|
|
1942
|
+
noNestedIf: "No anides un if dentro de otro: cada nivel suma carga cognitiva y crea puntos ciegos para las demas reglas. Aplana con retorno anticipado (`if (!x) return ...;` y sigue el camino feliz) o decide con `match()` de ts-pattern si son variantes de un mismo valor."
|
|
1943
|
+
},
|
|
1944
|
+
schema: [
|
|
1945
|
+
{
|
|
1946
|
+
additionalProperties: false,
|
|
1947
|
+
properties: {
|
|
1948
|
+
allowFilePatterns: {
|
|
1949
|
+
items: { type: "string" },
|
|
1950
|
+
type: "array"
|
|
1951
|
+
}
|
|
1952
|
+
},
|
|
1953
|
+
type: "object"
|
|
1954
|
+
}
|
|
1955
|
+
]
|
|
1956
|
+
},
|
|
1957
|
+
create(context) {
|
|
1958
|
+
const options = getNoNestedIfOptions(context.options[0]);
|
|
1959
|
+
const filename = context.filename ?? context.getFilename();
|
|
1960
|
+
if (matchesAnyGlob(filename, options.allowFilePatterns)) {
|
|
1961
|
+
return {};
|
|
1962
|
+
}
|
|
1963
|
+
return {
|
|
1964
|
+
IfStatement(node) {
|
|
1965
|
+
if (isNestedIfStatement(node)) {
|
|
1966
|
+
context.report({ messageId: "noNestedIf", node });
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1971
|
+
};
|
|
1972
|
+
|
|
1906
1973
|
// src/utils/is-promise-type.ts
|
|
1907
1974
|
function isPromiseType(type, typeContext) {
|
|
1908
1975
|
return typeContext.checker.getPromisedTypeOfPromise(type) !== void 0;
|
|
@@ -1945,11 +2012,11 @@ var noPromiseChain = {
|
|
|
1945
2012
|
if (!method) {
|
|
1946
2013
|
return;
|
|
1947
2014
|
}
|
|
1948
|
-
if (typeContext
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
2015
|
+
if (typeContext && !isPromiseType(
|
|
2016
|
+
typeContext.services.getTypeAtLocation(callee.object),
|
|
2017
|
+
typeContext
|
|
2018
|
+
)) {
|
|
2019
|
+
return;
|
|
1953
2020
|
}
|
|
1954
2021
|
context.report({
|
|
1955
2022
|
data: { method },
|
|
@@ -1988,10 +2055,11 @@ var rules = {
|
|
|
1988
2055
|
"prefer-abort-signal": preferAbortSignal,
|
|
1989
2056
|
"prefer-ts-pattern": preferTsPattern,
|
|
1990
2057
|
"no-jsx-ternary-null": noJsxTernaryNull,
|
|
2058
|
+
"no-nested-if": noNestedIf,
|
|
1991
2059
|
"no-promise-chain": noPromiseChain
|
|
1992
2060
|
};
|
|
1993
2061
|
|
|
1994
2062
|
export {
|
|
1995
2063
|
rules
|
|
1996
2064
|
};
|
|
1997
|
-
//# sourceMappingURL=chunk-
|
|
2065
|
+
//# sourceMappingURL=chunk-EXMF54EM.mjs.map
|