eslint-plugin-nextfriday 1.4.0 → 1.5.1
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/CHANGELOG.md +12 -0
- package/README.md +3 -0
- package/docs/rules/NO_ENV_FALLBACK.md +53 -0
- package/lib/index.cjs +137 -82
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +14 -0
- package/lib/index.d.ts +14 -0
- package/lib/index.js +138 -83
- package/lib/index.js.map +1 -1
- package/package.json +4 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# eslint-plugin-nextfriday
|
|
2
2
|
|
|
3
|
+
## 1.5.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#30](https://github.com/next-friday/eslint-plugin-nextfriday/pull/30) [`cc054bc`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/cc054bc46b902af77e747b72b09eb56854ea9630) Thanks [@nextfridaydeveloper](https://github.com/nextfridaydeveloper)! - Fix package installation warnings by removing preinstall script and making prepare script fail-safe
|
|
8
|
+
|
|
9
|
+
## 1.5.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [#28](https://github.com/next-friday/eslint-plugin-nextfriday/pull/28) [`387c2b8`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/387c2b8a6d0e4668daa035ab3bc3ad2f41e5d8f3) Thanks [@nextfridaydeveloper](https://github.com/nextfridaydeveloper)! - Add new `no-env-fallback` rule to prevent dangerous fallback values for environment variables. This rule disallows using `||`, `??`, or ternary operators with `process.env` to ensure applications fail explicitly when required environment variables are missing rather than silently using default values.
|
|
14
|
+
|
|
3
15
|
## 1.4.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -69,6 +69,7 @@ export default [
|
|
|
69
69
|
"nextfriday/prefer-react-import-types": "error",
|
|
70
70
|
"nextfriday/no-complex-inline-return": "error",
|
|
71
71
|
"nextfriday/no-logic-in-params": "error",
|
|
72
|
+
"nextfriday/no-env-fallback": "error",
|
|
72
73
|
"nextfriday/jsx-pascal-case": "error",
|
|
73
74
|
"nextfriday/prefer-interface-over-inline-types": "error",
|
|
74
75
|
"nextfriday/react-props-destructure": "error",
|
|
@@ -125,6 +126,7 @@ module.exports = {
|
|
|
125
126
|
| [enforce-readonly-component-props](docs/rules/ENFORCE_READONLY_COMPONENT_PROPS.md) | Enforce Readonly wrapper for React component props | ✅ |
|
|
126
127
|
| [no-complex-inline-return](docs/rules/NO_COMPLEX_INLINE_RETURN.md) | Disallow complex inline expressions in return statements - prefer const first | ❌ |
|
|
127
128
|
| [no-logic-in-params](docs/rules/NO_LOGIC_IN_PARAMS.md) | Disallow logic or conditions in function parameters - extract to const first | ❌ |
|
|
129
|
+
| [no-env-fallback](docs/rules/NO_ENV_FALLBACK.md) | Disallow fallback values for environment variables as they can be dangerous | ❌ |
|
|
128
130
|
|
|
129
131
|
## Configurations
|
|
130
132
|
|
|
@@ -144,6 +146,7 @@ Basic configuration without JSX-specific rules:
|
|
|
144
146
|
- `nextfriday/prefer-react-import-types`: `"error"`
|
|
145
147
|
- `nextfriday/no-complex-inline-return`: `"error"`
|
|
146
148
|
- `nextfriday/no-logic-in-params`: `"error"`
|
|
149
|
+
- `nextfriday/no-env-fallback`: `"error"`
|
|
147
150
|
|
|
148
151
|
#### `base/recommended`
|
|
149
152
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# no-env-fallback
|
|
2
|
+
|
|
3
|
+
Disallow fallback values for environment variables as they can be dangerous in production.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
This rule prevents using fallback values with `process.env` environment variables. When environment variables have fallback values (using `||`, `??`, or ternary operators), applications can silently run with default values instead of failing when required configuration is missing. This can lead to security issues, incorrect behavior in production, or hard-to-debug problems.
|
|
8
|
+
|
|
9
|
+
It's safer to let the application fail explicitly when required environment variables are missing, rather than continuing with potentially incorrect default values.
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
**Incorrect** code for this rule:
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
const apiKey = process.env.API_KEY || "default-key";
|
|
17
|
+
const dbUrl = process.env.DATABASE_URL ?? "localhost";
|
|
18
|
+
const port = process.env.PORT ? "8080" : "3000";
|
|
19
|
+
|
|
20
|
+
const config = {
|
|
21
|
+
secret: process.env.SECRET_KEY || "unsafe-default",
|
|
22
|
+
region: process.env.AWS_REGION ?? "us-east-1",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function getToken() {
|
|
26
|
+
return process.env.AUTH_TOKEN || "abc123";
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Correct** code for this rule:
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
const apiKey = process.env.API_KEY;
|
|
34
|
+
const dbUrl = process.env.DATABASE_URL;
|
|
35
|
+
const port = process.env.PORT;
|
|
36
|
+
|
|
37
|
+
const config = {
|
|
38
|
+
secret: process.env.SECRET_KEY,
|
|
39
|
+
region: process.env.AWS_REGION,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
function getToken() {
|
|
43
|
+
return process.env.AUTH_TOKEN;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!process.env.API_KEY) {
|
|
47
|
+
throw new Error("API_KEY environment variable is required");
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## When Not To Use It
|
|
52
|
+
|
|
53
|
+
If your application intentionally uses default values for optional configuration and you have explicit handling for required vs optional environment variables, you may want to disable this rule. However, it's generally safer to validate required environment variables at application startup rather than using fallback values.
|
package/lib/index.cjs
CHANGED
|
@@ -40,7 +40,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
40
40
|
// package.json
|
|
41
41
|
var package_default = {
|
|
42
42
|
name: "eslint-plugin-nextfriday",
|
|
43
|
-
version: "1.
|
|
43
|
+
version: "1.5.1",
|
|
44
44
|
description: "A comprehensive ESLint plugin providing custom rules and configurations for Next Friday development workflows.",
|
|
45
45
|
keywords: [
|
|
46
46
|
"eslint",
|
|
@@ -90,10 +90,9 @@ var package_default = {
|
|
|
90
90
|
"changeset:publish": "npm publish --provenance --access public",
|
|
91
91
|
"changeset:version": "changeset version",
|
|
92
92
|
clear: "rm -rf lib node_modules/.cache .eslintcache",
|
|
93
|
-
eslint: "eslint src --ext .js,.ts
|
|
94
|
-
"eslint:check": "eslint src --ext .js,.ts
|
|
95
|
-
|
|
96
|
-
prepare: "husky",
|
|
93
|
+
eslint: "eslint src --ext .js,.ts --fix",
|
|
94
|
+
"eslint:check": "eslint src --ext .js,.ts",
|
|
95
|
+
prepare: "husky || true",
|
|
97
96
|
prepublishOnly: "pnpm run build",
|
|
98
97
|
prettier: "prettier --write .",
|
|
99
98
|
"prettier:check": "prettier --check .",
|
|
@@ -465,12 +464,65 @@ var noEmoji = createRule6({
|
|
|
465
464
|
});
|
|
466
465
|
var no_emoji_default = noEmoji;
|
|
467
466
|
|
|
468
|
-
// src/rules/no-
|
|
467
|
+
// src/rules/no-env-fallback.ts
|
|
469
468
|
var import_utils7 = require("@typescript-eslint/utils");
|
|
470
469
|
var createRule7 = import_utils7.ESLintUtils.RuleCreator(
|
|
471
470
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
472
471
|
);
|
|
473
|
-
var
|
|
472
|
+
var noEnvFallback = createRule7({
|
|
473
|
+
name: "no-env-fallback",
|
|
474
|
+
meta: {
|
|
475
|
+
type: "problem",
|
|
476
|
+
docs: {
|
|
477
|
+
description: "Disallow fallback values for environment variables as they can be dangerous in production"
|
|
478
|
+
},
|
|
479
|
+
messages: {
|
|
480
|
+
noEnvFallback: "Avoid using fallback values with process.env. Environment variables should fail explicitly when missing rather than silently using a default value."
|
|
481
|
+
},
|
|
482
|
+
schema: []
|
|
483
|
+
},
|
|
484
|
+
defaultOptions: [],
|
|
485
|
+
create(context) {
|
|
486
|
+
const isProcessEnvAccess = (node) => {
|
|
487
|
+
if (node.type !== import_utils7.AST_NODE_TYPES.MemberExpression) {
|
|
488
|
+
return false;
|
|
489
|
+
}
|
|
490
|
+
const { object } = node;
|
|
491
|
+
if (object.type !== import_utils7.AST_NODE_TYPES.MemberExpression) {
|
|
492
|
+
return false;
|
|
493
|
+
}
|
|
494
|
+
const processNode = object.object;
|
|
495
|
+
const envNode = object.property;
|
|
496
|
+
return processNode.type === import_utils7.AST_NODE_TYPES.Identifier && processNode.name === "process" && envNode.type === import_utils7.AST_NODE_TYPES.Identifier && envNode.name === "env";
|
|
497
|
+
};
|
|
498
|
+
return {
|
|
499
|
+
LogicalExpression(node) {
|
|
500
|
+
if ((node.operator === "||" || node.operator === "??") && isProcessEnvAccess(node.left)) {
|
|
501
|
+
context.report({
|
|
502
|
+
node,
|
|
503
|
+
messageId: "noEnvFallback"
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
},
|
|
507
|
+
ConditionalExpression(node) {
|
|
508
|
+
if (isProcessEnvAccess(node.test)) {
|
|
509
|
+
context.report({
|
|
510
|
+
node,
|
|
511
|
+
messageId: "noEnvFallback"
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
var no_env_fallback_default = noEnvFallback;
|
|
519
|
+
|
|
520
|
+
// src/rules/no-explicit-return-type.ts
|
|
521
|
+
var import_utils8 = require("@typescript-eslint/utils");
|
|
522
|
+
var createRule8 = import_utils8.ESLintUtils.RuleCreator(
|
|
523
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
524
|
+
);
|
|
525
|
+
var noExplicitReturnType = createRule8({
|
|
474
526
|
name: "no-explicit-return-type",
|
|
475
527
|
meta: {
|
|
476
528
|
type: "suggestion",
|
|
@@ -510,11 +562,11 @@ var noExplicitReturnType = createRule7({
|
|
|
510
562
|
var no_explicit_return_type_default = noExplicitReturnType;
|
|
511
563
|
|
|
512
564
|
// src/rules/no-logic-in-params.ts
|
|
513
|
-
var
|
|
514
|
-
var
|
|
565
|
+
var import_utils9 = require("@typescript-eslint/utils");
|
|
566
|
+
var createRule9 = import_utils9.ESLintUtils.RuleCreator(
|
|
515
567
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
516
568
|
);
|
|
517
|
-
var noLogicInParams =
|
|
569
|
+
var noLogicInParams = createRule9({
|
|
518
570
|
name: "no-logic-in-params",
|
|
519
571
|
meta: {
|
|
520
572
|
type: "suggestion",
|
|
@@ -529,20 +581,20 @@ var noLogicInParams = createRule8({
|
|
|
529
581
|
defaultOptions: [],
|
|
530
582
|
create(context) {
|
|
531
583
|
const isComplexExpression = (node) => {
|
|
532
|
-
if (node.type ===
|
|
584
|
+
if (node.type === import_utils9.AST_NODE_TYPES.SpreadElement) {
|
|
533
585
|
return false;
|
|
534
586
|
}
|
|
535
|
-
if (node.type ===
|
|
587
|
+
if (node.type === import_utils9.AST_NODE_TYPES.ConditionalExpression) {
|
|
536
588
|
return true;
|
|
537
589
|
}
|
|
538
|
-
if (node.type ===
|
|
590
|
+
if (node.type === import_utils9.AST_NODE_TYPES.LogicalExpression) {
|
|
539
591
|
return true;
|
|
540
592
|
}
|
|
541
|
-
if (node.type ===
|
|
593
|
+
if (node.type === import_utils9.AST_NODE_TYPES.BinaryExpression) {
|
|
542
594
|
const logicalOperators = ["==", "===", "!=", "!==", "<", ">", "<=", ">=", "in", "instanceof"];
|
|
543
595
|
return logicalOperators.includes(node.operator);
|
|
544
596
|
}
|
|
545
|
-
if (node.type ===
|
|
597
|
+
if (node.type === import_utils9.AST_NODE_TYPES.UnaryExpression) {
|
|
546
598
|
return node.operator === "!";
|
|
547
599
|
}
|
|
548
600
|
return false;
|
|
@@ -574,11 +626,11 @@ var noLogicInParams = createRule8({
|
|
|
574
626
|
var no_logic_in_params_default = noLogicInParams;
|
|
575
627
|
|
|
576
628
|
// src/rules/prefer-destructuring-params.ts
|
|
577
|
-
var
|
|
578
|
-
var
|
|
629
|
+
var import_utils10 = require("@typescript-eslint/utils");
|
|
630
|
+
var createRule10 = import_utils10.ESLintUtils.RuleCreator(
|
|
579
631
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
580
632
|
);
|
|
581
|
-
var preferDestructuringParams =
|
|
633
|
+
var preferDestructuringParams = createRule10({
|
|
582
634
|
name: "prefer-destructuring-params",
|
|
583
635
|
meta: {
|
|
584
636
|
type: "suggestion",
|
|
@@ -594,18 +646,18 @@ var preferDestructuringParams = createRule9({
|
|
|
594
646
|
create(context) {
|
|
595
647
|
const isCallbackFunction = (node) => {
|
|
596
648
|
const { parent } = node;
|
|
597
|
-
return parent?.type ===
|
|
649
|
+
return parent?.type === import_utils10.AST_NODE_TYPES.CallExpression;
|
|
598
650
|
};
|
|
599
651
|
const isDeveloperFunction = (node) => {
|
|
600
|
-
if (node.type ===
|
|
652
|
+
if (node.type === import_utils10.AST_NODE_TYPES.FunctionDeclaration) {
|
|
601
653
|
return true;
|
|
602
654
|
}
|
|
603
|
-
if (node.type ===
|
|
655
|
+
if (node.type === import_utils10.AST_NODE_TYPES.FunctionExpression || node.type === import_utils10.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
604
656
|
if (isCallbackFunction(node)) {
|
|
605
657
|
return false;
|
|
606
658
|
}
|
|
607
659
|
const { parent } = node;
|
|
608
|
-
return parent?.type ===
|
|
660
|
+
return parent?.type === import_utils10.AST_NODE_TYPES.VariableDeclarator || parent?.type === import_utils10.AST_NODE_TYPES.AssignmentExpression || parent?.type === import_utils10.AST_NODE_TYPES.Property || parent?.type === import_utils10.AST_NODE_TYPES.MethodDefinition;
|
|
609
661
|
}
|
|
610
662
|
return false;
|
|
611
663
|
};
|
|
@@ -617,7 +669,7 @@ var preferDestructuringParams = createRule9({
|
|
|
617
669
|
if (!isDeveloperFunction(node)) {
|
|
618
670
|
return;
|
|
619
671
|
}
|
|
620
|
-
if (node.type ===
|
|
672
|
+
if (node.type === import_utils10.AST_NODE_TYPES.FunctionDeclaration && node.id) {
|
|
621
673
|
const functionName = node.id.name;
|
|
622
674
|
if (functionName.startsWith("_") || functionName.includes("$") || /^[A-Z][a-zA-Z]*$/.test(functionName)) {
|
|
623
675
|
return;
|
|
@@ -627,7 +679,7 @@ var preferDestructuringParams = createRule9({
|
|
|
627
679
|
return;
|
|
628
680
|
}
|
|
629
681
|
const hasNonDestructuredParams = node.params.some(
|
|
630
|
-
(param) => param.type !==
|
|
682
|
+
(param) => param.type !== import_utils10.AST_NODE_TYPES.ObjectPattern && param.type !== import_utils10.AST_NODE_TYPES.RestElement
|
|
631
683
|
);
|
|
632
684
|
if (hasNonDestructuredParams) {
|
|
633
685
|
context.report({
|
|
@@ -646,11 +698,11 @@ var preferDestructuringParams = createRule9({
|
|
|
646
698
|
var prefer_destructuring_params_default = preferDestructuringParams;
|
|
647
699
|
|
|
648
700
|
// src/rules/prefer-import-type.ts
|
|
649
|
-
var
|
|
650
|
-
var
|
|
701
|
+
var import_utils11 = require("@typescript-eslint/utils");
|
|
702
|
+
var createRule11 = import_utils11.ESLintUtils.RuleCreator(
|
|
651
703
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
652
704
|
);
|
|
653
|
-
var preferImportType =
|
|
705
|
+
var preferImportType = createRule11({
|
|
654
706
|
name: "prefer-import-type",
|
|
655
707
|
meta: {
|
|
656
708
|
type: "suggestion",
|
|
@@ -681,14 +733,14 @@ var preferImportType = createRule10({
|
|
|
681
733
|
return;
|
|
682
734
|
}
|
|
683
735
|
const isTypeOnlyImport = node.specifiers.every((specifier) => {
|
|
684
|
-
if (specifier.type ===
|
|
736
|
+
if (specifier.type === import_utils11.AST_NODE_TYPES.ImportDefaultSpecifier) {
|
|
685
737
|
return false;
|
|
686
738
|
}
|
|
687
|
-
if (specifier.type ===
|
|
739
|
+
if (specifier.type === import_utils11.AST_NODE_TYPES.ImportNamespaceSpecifier) {
|
|
688
740
|
return false;
|
|
689
741
|
}
|
|
690
|
-
if (specifier.type ===
|
|
691
|
-
const importedName = specifier.imported.type ===
|
|
742
|
+
if (specifier.type === import_utils11.AST_NODE_TYPES.ImportSpecifier) {
|
|
743
|
+
const importedName = specifier.imported.type === import_utils11.AST_NODE_TYPES.Identifier ? specifier.imported.name : specifier.imported.value;
|
|
692
744
|
const isKnownTypeOnly = node.source.value === "@typescript-eslint/utils" && ["TSESTree", "RuleContext"].includes(importedName) || node.source.value === "react" && ["Component", "ComponentProps", "ReactNode", "FC", "JSX", "ReactElement", "PropsWithChildren"].includes(
|
|
693
745
|
importedName
|
|
694
746
|
) || importedName.endsWith("Type") || importedName.endsWith("Interface") || importedName.endsWith("Props");
|
|
@@ -716,11 +768,11 @@ var preferImportType = createRule10({
|
|
|
716
768
|
var prefer_import_type_default = preferImportType;
|
|
717
769
|
|
|
718
770
|
// src/rules/prefer-interface-over-inline-types.ts
|
|
719
|
-
var
|
|
720
|
-
var
|
|
771
|
+
var import_utils12 = require("@typescript-eslint/utils");
|
|
772
|
+
var createRule12 = import_utils12.ESLintUtils.RuleCreator(
|
|
721
773
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
722
774
|
);
|
|
723
|
-
var preferInterfaceOverInlineTypes =
|
|
775
|
+
var preferInterfaceOverInlineTypes = createRule12({
|
|
724
776
|
name: "prefer-interface-over-inline-types",
|
|
725
777
|
meta: {
|
|
726
778
|
type: "suggestion",
|
|
@@ -736,54 +788,54 @@ var preferInterfaceOverInlineTypes = createRule11({
|
|
|
736
788
|
defaultOptions: [],
|
|
737
789
|
create(context) {
|
|
738
790
|
function hasJSXInConditional(node) {
|
|
739
|
-
return node.consequent.type ===
|
|
791
|
+
return node.consequent.type === import_utils12.AST_NODE_TYPES.JSXElement || node.consequent.type === import_utils12.AST_NODE_TYPES.JSXFragment || node.alternate.type === import_utils12.AST_NODE_TYPES.JSXElement || node.alternate.type === import_utils12.AST_NODE_TYPES.JSXFragment;
|
|
740
792
|
}
|
|
741
793
|
function hasJSXInLogical(node) {
|
|
742
|
-
return node.right.type ===
|
|
794
|
+
return node.right.type === import_utils12.AST_NODE_TYPES.JSXElement || node.right.type === import_utils12.AST_NODE_TYPES.JSXFragment;
|
|
743
795
|
}
|
|
744
796
|
function hasJSXReturn(block) {
|
|
745
797
|
return block.body.some((stmt) => {
|
|
746
|
-
if (stmt.type ===
|
|
747
|
-
return stmt.argument.type ===
|
|
798
|
+
if (stmt.type === import_utils12.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
|
|
799
|
+
return stmt.argument.type === import_utils12.AST_NODE_TYPES.JSXElement || stmt.argument.type === import_utils12.AST_NODE_TYPES.JSXFragment || stmt.argument.type === import_utils12.AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === import_utils12.AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
|
|
748
800
|
}
|
|
749
801
|
return false;
|
|
750
802
|
});
|
|
751
803
|
}
|
|
752
804
|
function isReactComponent(node) {
|
|
753
|
-
if (node.type ===
|
|
754
|
-
if (node.body.type ===
|
|
805
|
+
if (node.type === import_utils12.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
806
|
+
if (node.body.type === import_utils12.AST_NODE_TYPES.JSXElement || node.body.type === import_utils12.AST_NODE_TYPES.JSXFragment) {
|
|
755
807
|
return true;
|
|
756
808
|
}
|
|
757
|
-
if (node.body.type ===
|
|
809
|
+
if (node.body.type === import_utils12.AST_NODE_TYPES.BlockStatement) {
|
|
758
810
|
return hasJSXReturn(node.body);
|
|
759
811
|
}
|
|
760
|
-
} else if (node.type ===
|
|
761
|
-
if (node.body && node.body.type ===
|
|
812
|
+
} else if (node.type === import_utils12.AST_NODE_TYPES.FunctionExpression || node.type === import_utils12.AST_NODE_TYPES.FunctionDeclaration) {
|
|
813
|
+
if (node.body && node.body.type === import_utils12.AST_NODE_TYPES.BlockStatement) {
|
|
762
814
|
return hasJSXReturn(node.body);
|
|
763
815
|
}
|
|
764
816
|
}
|
|
765
817
|
return false;
|
|
766
818
|
}
|
|
767
819
|
function isInlineTypeAnnotation(node) {
|
|
768
|
-
if (node.type ===
|
|
820
|
+
if (node.type === import_utils12.AST_NODE_TYPES.TSTypeLiteral) {
|
|
769
821
|
return true;
|
|
770
822
|
}
|
|
771
|
-
if (node.type ===
|
|
772
|
-
return node.typeArguments.params.some((param) => param.type ===
|
|
823
|
+
if (node.type === import_utils12.AST_NODE_TYPES.TSTypeReference && node.typeArguments) {
|
|
824
|
+
return node.typeArguments.params.some((param) => param.type === import_utils12.AST_NODE_TYPES.TSTypeLiteral);
|
|
773
825
|
}
|
|
774
|
-
if (node.type ===
|
|
826
|
+
if (node.type === import_utils12.AST_NODE_TYPES.TSUnionType) {
|
|
775
827
|
return node.types.some((type) => isInlineTypeAnnotation(type));
|
|
776
828
|
}
|
|
777
829
|
return false;
|
|
778
830
|
}
|
|
779
831
|
function hasInlineObjectType(node) {
|
|
780
|
-
if (node.type ===
|
|
832
|
+
if (node.type === import_utils12.AST_NODE_TYPES.TSTypeLiteral) {
|
|
781
833
|
return true;
|
|
782
834
|
}
|
|
783
|
-
if (node.type ===
|
|
784
|
-
return node.typeArguments.params.some((param) => param.type ===
|
|
835
|
+
if (node.type === import_utils12.AST_NODE_TYPES.TSTypeReference && node.typeArguments) {
|
|
836
|
+
return node.typeArguments.params.some((param) => param.type === import_utils12.AST_NODE_TYPES.TSTypeLiteral);
|
|
785
837
|
}
|
|
786
|
-
if (node.type ===
|
|
838
|
+
if (node.type === import_utils12.AST_NODE_TYPES.TSUnionType) {
|
|
787
839
|
return node.types.some((type) => hasInlineObjectType(type));
|
|
788
840
|
}
|
|
789
841
|
return false;
|
|
@@ -796,7 +848,7 @@ var preferInterfaceOverInlineTypes = createRule11({
|
|
|
796
848
|
return;
|
|
797
849
|
}
|
|
798
850
|
const param = node.params[0];
|
|
799
|
-
if (param.type ===
|
|
851
|
+
if (param.type === import_utils12.AST_NODE_TYPES.Identifier && param.typeAnnotation) {
|
|
800
852
|
const { typeAnnotation } = param.typeAnnotation;
|
|
801
853
|
if (isInlineTypeAnnotation(typeAnnotation) && hasInlineObjectType(typeAnnotation)) {
|
|
802
854
|
context.report({
|
|
@@ -816,11 +868,11 @@ var preferInterfaceOverInlineTypes = createRule11({
|
|
|
816
868
|
var prefer_interface_over_inline_types_default = preferInterfaceOverInlineTypes;
|
|
817
869
|
|
|
818
870
|
// src/rules/prefer-named-param-types.ts
|
|
819
|
-
var
|
|
820
|
-
var
|
|
871
|
+
var import_utils13 = require("@typescript-eslint/utils");
|
|
872
|
+
var createRule13 = import_utils13.ESLintUtils.RuleCreator(
|
|
821
873
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
822
874
|
);
|
|
823
|
-
var preferNamedParamTypes =
|
|
875
|
+
var preferNamedParamTypes = createRule13({
|
|
824
876
|
name: "prefer-named-param-types",
|
|
825
877
|
meta: {
|
|
826
878
|
type: "suggestion",
|
|
@@ -835,16 +887,16 @@ var preferNamedParamTypes = createRule12({
|
|
|
835
887
|
defaultOptions: [],
|
|
836
888
|
create(context) {
|
|
837
889
|
function hasInlineObjectType(param) {
|
|
838
|
-
if (param.type ===
|
|
890
|
+
if (param.type === import_utils13.AST_NODE_TYPES.AssignmentPattern) {
|
|
839
891
|
return hasInlineObjectType(param.left);
|
|
840
892
|
}
|
|
841
|
-
if (param.type ===
|
|
842
|
-
if (param.typeAnnotation?.typeAnnotation.type ===
|
|
893
|
+
if (param.type === import_utils13.AST_NODE_TYPES.ObjectPattern) {
|
|
894
|
+
if (param.typeAnnotation?.typeAnnotation.type === import_utils13.AST_NODE_TYPES.TSTypeLiteral) {
|
|
843
895
|
return true;
|
|
844
896
|
}
|
|
845
897
|
}
|
|
846
|
-
if (param.type ===
|
|
847
|
-
if (param.typeAnnotation?.typeAnnotation.type ===
|
|
898
|
+
if (param.type === import_utils13.AST_NODE_TYPES.Identifier) {
|
|
899
|
+
if (param.typeAnnotation?.typeAnnotation.type === import_utils13.AST_NODE_TYPES.TSTypeLiteral) {
|
|
848
900
|
return true;
|
|
849
901
|
}
|
|
850
902
|
}
|
|
@@ -878,11 +930,11 @@ var preferNamedParamTypes = createRule12({
|
|
|
878
930
|
var prefer_named_param_types_default = preferNamedParamTypes;
|
|
879
931
|
|
|
880
932
|
// src/rules/prefer-react-import-types.ts
|
|
881
|
-
var
|
|
882
|
-
var
|
|
933
|
+
var import_utils14 = require("@typescript-eslint/utils");
|
|
934
|
+
var createRule14 = import_utils14.ESLintUtils.RuleCreator(
|
|
883
935
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
884
936
|
);
|
|
885
|
-
var preferReactImportTypes =
|
|
937
|
+
var preferReactImportTypes = createRule14({
|
|
886
938
|
name: "prefer-react-import-types",
|
|
887
939
|
meta: {
|
|
888
940
|
type: "suggestion",
|
|
@@ -958,7 +1010,7 @@ var preferReactImportTypes = createRule13({
|
|
|
958
1010
|
]);
|
|
959
1011
|
const allReactExports = /* @__PURE__ */ new Set([...reactTypes, ...reactRuntimeExports]);
|
|
960
1012
|
function checkMemberExpression(node) {
|
|
961
|
-
if (node.object.type ===
|
|
1013
|
+
if (node.object.type === import_utils14.AST_NODE_TYPES.Identifier && node.object.name === "React" && node.property.type === import_utils14.AST_NODE_TYPES.Identifier && allReactExports.has(node.property.name)) {
|
|
962
1014
|
const typeName = node.property.name;
|
|
963
1015
|
const isType = reactTypes.has(typeName);
|
|
964
1016
|
const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
|
|
@@ -975,7 +1027,7 @@ var preferReactImportTypes = createRule13({
|
|
|
975
1027
|
return {
|
|
976
1028
|
MemberExpression: checkMemberExpression,
|
|
977
1029
|
"TSTypeReference > TSQualifiedName": (node) => {
|
|
978
|
-
if (node.left.type ===
|
|
1030
|
+
if (node.left.type === import_utils14.AST_NODE_TYPES.Identifier && node.left.name === "React" && node.right.type === import_utils14.AST_NODE_TYPES.Identifier && allReactExports.has(node.right.name)) {
|
|
979
1031
|
const typeName = node.right.name;
|
|
980
1032
|
const isType = reactTypes.has(typeName);
|
|
981
1033
|
const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
|
|
@@ -995,11 +1047,11 @@ var preferReactImportTypes = createRule13({
|
|
|
995
1047
|
var prefer_react_import_types_default = preferReactImportTypes;
|
|
996
1048
|
|
|
997
1049
|
// src/rules/react-props-destructure.ts
|
|
998
|
-
var
|
|
999
|
-
var
|
|
1050
|
+
var import_utils15 = require("@typescript-eslint/utils");
|
|
1051
|
+
var createRule15 = import_utils15.ESLintUtils.RuleCreator(
|
|
1000
1052
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
1001
1053
|
);
|
|
1002
|
-
var reactPropsDestructure =
|
|
1054
|
+
var reactPropsDestructure = createRule15({
|
|
1003
1055
|
name: "react-props-destructure",
|
|
1004
1056
|
meta: {
|
|
1005
1057
|
type: "suggestion",
|
|
@@ -1015,29 +1067,29 @@ var reactPropsDestructure = createRule14({
|
|
|
1015
1067
|
defaultOptions: [],
|
|
1016
1068
|
create(context) {
|
|
1017
1069
|
function hasJSXInConditional(node) {
|
|
1018
|
-
return node.consequent.type ===
|
|
1070
|
+
return node.consequent.type === import_utils15.AST_NODE_TYPES.JSXElement || node.consequent.type === import_utils15.AST_NODE_TYPES.JSXFragment || node.alternate.type === import_utils15.AST_NODE_TYPES.JSXElement || node.alternate.type === import_utils15.AST_NODE_TYPES.JSXFragment;
|
|
1019
1071
|
}
|
|
1020
1072
|
function hasJSXInLogical(node) {
|
|
1021
|
-
return node.right.type ===
|
|
1073
|
+
return node.right.type === import_utils15.AST_NODE_TYPES.JSXElement || node.right.type === import_utils15.AST_NODE_TYPES.JSXFragment;
|
|
1022
1074
|
}
|
|
1023
1075
|
function hasJSXReturn(block) {
|
|
1024
1076
|
return block.body.some((stmt) => {
|
|
1025
|
-
if (stmt.type ===
|
|
1026
|
-
return stmt.argument.type ===
|
|
1077
|
+
if (stmt.type === import_utils15.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
|
|
1078
|
+
return stmt.argument.type === import_utils15.AST_NODE_TYPES.JSXElement || stmt.argument.type === import_utils15.AST_NODE_TYPES.JSXFragment || stmt.argument.type === import_utils15.AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === import_utils15.AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
|
|
1027
1079
|
}
|
|
1028
1080
|
return false;
|
|
1029
1081
|
});
|
|
1030
1082
|
}
|
|
1031
1083
|
function isReactComponent(node) {
|
|
1032
|
-
if (node.type ===
|
|
1033
|
-
if (node.body.type ===
|
|
1084
|
+
if (node.type === import_utils15.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
1085
|
+
if (node.body.type === import_utils15.AST_NODE_TYPES.JSXElement || node.body.type === import_utils15.AST_NODE_TYPES.JSXFragment) {
|
|
1034
1086
|
return true;
|
|
1035
1087
|
}
|
|
1036
|
-
if (node.body.type ===
|
|
1088
|
+
if (node.body.type === import_utils15.AST_NODE_TYPES.BlockStatement) {
|
|
1037
1089
|
return hasJSXReturn(node.body);
|
|
1038
1090
|
}
|
|
1039
|
-
} else if (node.type ===
|
|
1040
|
-
if (node.body && node.body.type ===
|
|
1091
|
+
} else if (node.type === import_utils15.AST_NODE_TYPES.FunctionExpression || node.type === import_utils15.AST_NODE_TYPES.FunctionDeclaration) {
|
|
1092
|
+
if (node.body && node.body.type === import_utils15.AST_NODE_TYPES.BlockStatement) {
|
|
1041
1093
|
return hasJSXReturn(node.body);
|
|
1042
1094
|
}
|
|
1043
1095
|
}
|
|
@@ -1051,9 +1103,9 @@ var reactPropsDestructure = createRule14({
|
|
|
1051
1103
|
return;
|
|
1052
1104
|
}
|
|
1053
1105
|
const param = node.params[0];
|
|
1054
|
-
if (param.type ===
|
|
1055
|
-
const properties = param.properties.filter((prop) => prop.type ===
|
|
1056
|
-
if (prop.key.type ===
|
|
1106
|
+
if (param.type === import_utils15.AST_NODE_TYPES.ObjectPattern) {
|
|
1107
|
+
const properties = param.properties.filter((prop) => prop.type === import_utils15.AST_NODE_TYPES.Property).map((prop) => {
|
|
1108
|
+
if (prop.key.type === import_utils15.AST_NODE_TYPES.Identifier) {
|
|
1057
1109
|
return prop.key.name;
|
|
1058
1110
|
}
|
|
1059
1111
|
return null;
|
|
@@ -1091,6 +1143,7 @@ var rules = {
|
|
|
1091
1143
|
"md-filename-case-restriction": md_filename_case_restriction_default,
|
|
1092
1144
|
"no-complex-inline-return": no_complex_inline_return_default,
|
|
1093
1145
|
"no-emoji": no_emoji_default,
|
|
1146
|
+
"no-env-fallback": no_env_fallback_default,
|
|
1094
1147
|
"no-explicit-return-type": no_explicit_return_type_default,
|
|
1095
1148
|
"no-logic-in-params": no_logic_in_params_default,
|
|
1096
1149
|
"prefer-destructuring-params": prefer_destructuring_params_default,
|
|
@@ -1114,7 +1167,8 @@ var baseRules = {
|
|
|
1114
1167
|
"nextfriday/prefer-named-param-types": "warn",
|
|
1115
1168
|
"nextfriday/prefer-react-import-types": "warn",
|
|
1116
1169
|
"nextfriday/no-complex-inline-return": "warn",
|
|
1117
|
-
"nextfriday/no-logic-in-params": "warn"
|
|
1170
|
+
"nextfriday/no-logic-in-params": "warn",
|
|
1171
|
+
"nextfriday/no-env-fallback": "warn"
|
|
1118
1172
|
};
|
|
1119
1173
|
var baseRecommendedRules = {
|
|
1120
1174
|
"nextfriday/no-emoji": "error",
|
|
@@ -1126,7 +1180,8 @@ var baseRecommendedRules = {
|
|
|
1126
1180
|
"nextfriday/prefer-named-param-types": "error",
|
|
1127
1181
|
"nextfriday/prefer-react-import-types": "error",
|
|
1128
1182
|
"nextfriday/no-complex-inline-return": "error",
|
|
1129
|
-
"nextfriday/no-logic-in-params": "error"
|
|
1183
|
+
"nextfriday/no-logic-in-params": "error",
|
|
1184
|
+
"nextfriday/no-env-fallback": "error"
|
|
1130
1185
|
};
|
|
1131
1186
|
var jsxRules = {
|
|
1132
1187
|
"nextfriday/jsx-pascal-case": "warn",
|