eslint-plugin-nextfriday 1.4.0 → 1.5.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/CHANGELOG.md +6 -0
- package/README.md +3 -0
- package/docs/rules/NO_ENV_FALLBACK.md +53 -0
- package/lib/index.cjs +136 -80
- 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 +137 -81
- package/lib/index.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# eslint-plugin-nextfriday
|
|
2
2
|
|
|
3
|
+
## 1.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#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.
|
|
8
|
+
|
|
3
9
|
## 1.4.0
|
|
4
10
|
|
|
5
11
|
### 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.0",
|
|
44
44
|
description: "A comprehensive ESLint plugin providing custom rules and configurations for Next Friday development workflows.",
|
|
45
45
|
keywords: [
|
|
46
46
|
"eslint",
|
|
@@ -90,8 +90,8 @@ 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
|
|
93
|
+
eslint: "eslint src --ext .js,.ts --fix",
|
|
94
|
+
"eslint:check": "eslint src --ext .js,.ts",
|
|
95
95
|
preinstall: "npx only-allow pnpm",
|
|
96
96
|
prepare: "husky",
|
|
97
97
|
prepublishOnly: "pnpm run build",
|
|
@@ -465,12 +465,65 @@ var noEmoji = createRule6({
|
|
|
465
465
|
});
|
|
466
466
|
var no_emoji_default = noEmoji;
|
|
467
467
|
|
|
468
|
-
// src/rules/no-
|
|
468
|
+
// src/rules/no-env-fallback.ts
|
|
469
469
|
var import_utils7 = require("@typescript-eslint/utils");
|
|
470
470
|
var createRule7 = import_utils7.ESLintUtils.RuleCreator(
|
|
471
471
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
472
472
|
);
|
|
473
|
-
var
|
|
473
|
+
var noEnvFallback = createRule7({
|
|
474
|
+
name: "no-env-fallback",
|
|
475
|
+
meta: {
|
|
476
|
+
type: "problem",
|
|
477
|
+
docs: {
|
|
478
|
+
description: "Disallow fallback values for environment variables as they can be dangerous in production"
|
|
479
|
+
},
|
|
480
|
+
messages: {
|
|
481
|
+
noEnvFallback: "Avoid using fallback values with process.env. Environment variables should fail explicitly when missing rather than silently using a default value."
|
|
482
|
+
},
|
|
483
|
+
schema: []
|
|
484
|
+
},
|
|
485
|
+
defaultOptions: [],
|
|
486
|
+
create(context) {
|
|
487
|
+
const isProcessEnvAccess = (node) => {
|
|
488
|
+
if (node.type !== import_utils7.AST_NODE_TYPES.MemberExpression) {
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
const { object } = node;
|
|
492
|
+
if (object.type !== import_utils7.AST_NODE_TYPES.MemberExpression) {
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
const processNode = object.object;
|
|
496
|
+
const envNode = object.property;
|
|
497
|
+
return processNode.type === import_utils7.AST_NODE_TYPES.Identifier && processNode.name === "process" && envNode.type === import_utils7.AST_NODE_TYPES.Identifier && envNode.name === "env";
|
|
498
|
+
};
|
|
499
|
+
return {
|
|
500
|
+
LogicalExpression(node) {
|
|
501
|
+
if ((node.operator === "||" || node.operator === "??") && isProcessEnvAccess(node.left)) {
|
|
502
|
+
context.report({
|
|
503
|
+
node,
|
|
504
|
+
messageId: "noEnvFallback"
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
},
|
|
508
|
+
ConditionalExpression(node) {
|
|
509
|
+
if (isProcessEnvAccess(node.test)) {
|
|
510
|
+
context.report({
|
|
511
|
+
node,
|
|
512
|
+
messageId: "noEnvFallback"
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
var no_env_fallback_default = noEnvFallback;
|
|
520
|
+
|
|
521
|
+
// src/rules/no-explicit-return-type.ts
|
|
522
|
+
var import_utils8 = require("@typescript-eslint/utils");
|
|
523
|
+
var createRule8 = import_utils8.ESLintUtils.RuleCreator(
|
|
524
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
525
|
+
);
|
|
526
|
+
var noExplicitReturnType = createRule8({
|
|
474
527
|
name: "no-explicit-return-type",
|
|
475
528
|
meta: {
|
|
476
529
|
type: "suggestion",
|
|
@@ -510,11 +563,11 @@ var noExplicitReturnType = createRule7({
|
|
|
510
563
|
var no_explicit_return_type_default = noExplicitReturnType;
|
|
511
564
|
|
|
512
565
|
// src/rules/no-logic-in-params.ts
|
|
513
|
-
var
|
|
514
|
-
var
|
|
566
|
+
var import_utils9 = require("@typescript-eslint/utils");
|
|
567
|
+
var createRule9 = import_utils9.ESLintUtils.RuleCreator(
|
|
515
568
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
516
569
|
);
|
|
517
|
-
var noLogicInParams =
|
|
570
|
+
var noLogicInParams = createRule9({
|
|
518
571
|
name: "no-logic-in-params",
|
|
519
572
|
meta: {
|
|
520
573
|
type: "suggestion",
|
|
@@ -529,20 +582,20 @@ var noLogicInParams = createRule8({
|
|
|
529
582
|
defaultOptions: [],
|
|
530
583
|
create(context) {
|
|
531
584
|
const isComplexExpression = (node) => {
|
|
532
|
-
if (node.type ===
|
|
585
|
+
if (node.type === import_utils9.AST_NODE_TYPES.SpreadElement) {
|
|
533
586
|
return false;
|
|
534
587
|
}
|
|
535
|
-
if (node.type ===
|
|
588
|
+
if (node.type === import_utils9.AST_NODE_TYPES.ConditionalExpression) {
|
|
536
589
|
return true;
|
|
537
590
|
}
|
|
538
|
-
if (node.type ===
|
|
591
|
+
if (node.type === import_utils9.AST_NODE_TYPES.LogicalExpression) {
|
|
539
592
|
return true;
|
|
540
593
|
}
|
|
541
|
-
if (node.type ===
|
|
594
|
+
if (node.type === import_utils9.AST_NODE_TYPES.BinaryExpression) {
|
|
542
595
|
const logicalOperators = ["==", "===", "!=", "!==", "<", ">", "<=", ">=", "in", "instanceof"];
|
|
543
596
|
return logicalOperators.includes(node.operator);
|
|
544
597
|
}
|
|
545
|
-
if (node.type ===
|
|
598
|
+
if (node.type === import_utils9.AST_NODE_TYPES.UnaryExpression) {
|
|
546
599
|
return node.operator === "!";
|
|
547
600
|
}
|
|
548
601
|
return false;
|
|
@@ -574,11 +627,11 @@ var noLogicInParams = createRule8({
|
|
|
574
627
|
var no_logic_in_params_default = noLogicInParams;
|
|
575
628
|
|
|
576
629
|
// src/rules/prefer-destructuring-params.ts
|
|
577
|
-
var
|
|
578
|
-
var
|
|
630
|
+
var import_utils10 = require("@typescript-eslint/utils");
|
|
631
|
+
var createRule10 = import_utils10.ESLintUtils.RuleCreator(
|
|
579
632
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
580
633
|
);
|
|
581
|
-
var preferDestructuringParams =
|
|
634
|
+
var preferDestructuringParams = createRule10({
|
|
582
635
|
name: "prefer-destructuring-params",
|
|
583
636
|
meta: {
|
|
584
637
|
type: "suggestion",
|
|
@@ -594,18 +647,18 @@ var preferDestructuringParams = createRule9({
|
|
|
594
647
|
create(context) {
|
|
595
648
|
const isCallbackFunction = (node) => {
|
|
596
649
|
const { parent } = node;
|
|
597
|
-
return parent?.type ===
|
|
650
|
+
return parent?.type === import_utils10.AST_NODE_TYPES.CallExpression;
|
|
598
651
|
};
|
|
599
652
|
const isDeveloperFunction = (node) => {
|
|
600
|
-
if (node.type ===
|
|
653
|
+
if (node.type === import_utils10.AST_NODE_TYPES.FunctionDeclaration) {
|
|
601
654
|
return true;
|
|
602
655
|
}
|
|
603
|
-
if (node.type ===
|
|
656
|
+
if (node.type === import_utils10.AST_NODE_TYPES.FunctionExpression || node.type === import_utils10.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
604
657
|
if (isCallbackFunction(node)) {
|
|
605
658
|
return false;
|
|
606
659
|
}
|
|
607
660
|
const { parent } = node;
|
|
608
|
-
return parent?.type ===
|
|
661
|
+
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
662
|
}
|
|
610
663
|
return false;
|
|
611
664
|
};
|
|
@@ -617,7 +670,7 @@ var preferDestructuringParams = createRule9({
|
|
|
617
670
|
if (!isDeveloperFunction(node)) {
|
|
618
671
|
return;
|
|
619
672
|
}
|
|
620
|
-
if (node.type ===
|
|
673
|
+
if (node.type === import_utils10.AST_NODE_TYPES.FunctionDeclaration && node.id) {
|
|
621
674
|
const functionName = node.id.name;
|
|
622
675
|
if (functionName.startsWith("_") || functionName.includes("$") || /^[A-Z][a-zA-Z]*$/.test(functionName)) {
|
|
623
676
|
return;
|
|
@@ -627,7 +680,7 @@ var preferDestructuringParams = createRule9({
|
|
|
627
680
|
return;
|
|
628
681
|
}
|
|
629
682
|
const hasNonDestructuredParams = node.params.some(
|
|
630
|
-
(param) => param.type !==
|
|
683
|
+
(param) => param.type !== import_utils10.AST_NODE_TYPES.ObjectPattern && param.type !== import_utils10.AST_NODE_TYPES.RestElement
|
|
631
684
|
);
|
|
632
685
|
if (hasNonDestructuredParams) {
|
|
633
686
|
context.report({
|
|
@@ -646,11 +699,11 @@ var preferDestructuringParams = createRule9({
|
|
|
646
699
|
var prefer_destructuring_params_default = preferDestructuringParams;
|
|
647
700
|
|
|
648
701
|
// src/rules/prefer-import-type.ts
|
|
649
|
-
var
|
|
650
|
-
var
|
|
702
|
+
var import_utils11 = require("@typescript-eslint/utils");
|
|
703
|
+
var createRule11 = import_utils11.ESLintUtils.RuleCreator(
|
|
651
704
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
652
705
|
);
|
|
653
|
-
var preferImportType =
|
|
706
|
+
var preferImportType = createRule11({
|
|
654
707
|
name: "prefer-import-type",
|
|
655
708
|
meta: {
|
|
656
709
|
type: "suggestion",
|
|
@@ -681,14 +734,14 @@ var preferImportType = createRule10({
|
|
|
681
734
|
return;
|
|
682
735
|
}
|
|
683
736
|
const isTypeOnlyImport = node.specifiers.every((specifier) => {
|
|
684
|
-
if (specifier.type ===
|
|
737
|
+
if (specifier.type === import_utils11.AST_NODE_TYPES.ImportDefaultSpecifier) {
|
|
685
738
|
return false;
|
|
686
739
|
}
|
|
687
|
-
if (specifier.type ===
|
|
740
|
+
if (specifier.type === import_utils11.AST_NODE_TYPES.ImportNamespaceSpecifier) {
|
|
688
741
|
return false;
|
|
689
742
|
}
|
|
690
|
-
if (specifier.type ===
|
|
691
|
-
const importedName = specifier.imported.type ===
|
|
743
|
+
if (specifier.type === import_utils11.AST_NODE_TYPES.ImportSpecifier) {
|
|
744
|
+
const importedName = specifier.imported.type === import_utils11.AST_NODE_TYPES.Identifier ? specifier.imported.name : specifier.imported.value;
|
|
692
745
|
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
746
|
importedName
|
|
694
747
|
) || importedName.endsWith("Type") || importedName.endsWith("Interface") || importedName.endsWith("Props");
|
|
@@ -716,11 +769,11 @@ var preferImportType = createRule10({
|
|
|
716
769
|
var prefer_import_type_default = preferImportType;
|
|
717
770
|
|
|
718
771
|
// src/rules/prefer-interface-over-inline-types.ts
|
|
719
|
-
var
|
|
720
|
-
var
|
|
772
|
+
var import_utils12 = require("@typescript-eslint/utils");
|
|
773
|
+
var createRule12 = import_utils12.ESLintUtils.RuleCreator(
|
|
721
774
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
722
775
|
);
|
|
723
|
-
var preferInterfaceOverInlineTypes =
|
|
776
|
+
var preferInterfaceOverInlineTypes = createRule12({
|
|
724
777
|
name: "prefer-interface-over-inline-types",
|
|
725
778
|
meta: {
|
|
726
779
|
type: "suggestion",
|
|
@@ -736,54 +789,54 @@ var preferInterfaceOverInlineTypes = createRule11({
|
|
|
736
789
|
defaultOptions: [],
|
|
737
790
|
create(context) {
|
|
738
791
|
function hasJSXInConditional(node) {
|
|
739
|
-
return node.consequent.type ===
|
|
792
|
+
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
793
|
}
|
|
741
794
|
function hasJSXInLogical(node) {
|
|
742
|
-
return node.right.type ===
|
|
795
|
+
return node.right.type === import_utils12.AST_NODE_TYPES.JSXElement || node.right.type === import_utils12.AST_NODE_TYPES.JSXFragment;
|
|
743
796
|
}
|
|
744
797
|
function hasJSXReturn(block) {
|
|
745
798
|
return block.body.some((stmt) => {
|
|
746
|
-
if (stmt.type ===
|
|
747
|
-
return stmt.argument.type ===
|
|
799
|
+
if (stmt.type === import_utils12.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
|
|
800
|
+
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
801
|
}
|
|
749
802
|
return false;
|
|
750
803
|
});
|
|
751
804
|
}
|
|
752
805
|
function isReactComponent(node) {
|
|
753
|
-
if (node.type ===
|
|
754
|
-
if (node.body.type ===
|
|
806
|
+
if (node.type === import_utils12.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
807
|
+
if (node.body.type === import_utils12.AST_NODE_TYPES.JSXElement || node.body.type === import_utils12.AST_NODE_TYPES.JSXFragment) {
|
|
755
808
|
return true;
|
|
756
809
|
}
|
|
757
|
-
if (node.body.type ===
|
|
810
|
+
if (node.body.type === import_utils12.AST_NODE_TYPES.BlockStatement) {
|
|
758
811
|
return hasJSXReturn(node.body);
|
|
759
812
|
}
|
|
760
|
-
} else if (node.type ===
|
|
761
|
-
if (node.body && node.body.type ===
|
|
813
|
+
} else if (node.type === import_utils12.AST_NODE_TYPES.FunctionExpression || node.type === import_utils12.AST_NODE_TYPES.FunctionDeclaration) {
|
|
814
|
+
if (node.body && node.body.type === import_utils12.AST_NODE_TYPES.BlockStatement) {
|
|
762
815
|
return hasJSXReturn(node.body);
|
|
763
816
|
}
|
|
764
817
|
}
|
|
765
818
|
return false;
|
|
766
819
|
}
|
|
767
820
|
function isInlineTypeAnnotation(node) {
|
|
768
|
-
if (node.type ===
|
|
821
|
+
if (node.type === import_utils12.AST_NODE_TYPES.TSTypeLiteral) {
|
|
769
822
|
return true;
|
|
770
823
|
}
|
|
771
|
-
if (node.type ===
|
|
772
|
-
return node.typeArguments.params.some((param) => param.type ===
|
|
824
|
+
if (node.type === import_utils12.AST_NODE_TYPES.TSTypeReference && node.typeArguments) {
|
|
825
|
+
return node.typeArguments.params.some((param) => param.type === import_utils12.AST_NODE_TYPES.TSTypeLiteral);
|
|
773
826
|
}
|
|
774
|
-
if (node.type ===
|
|
827
|
+
if (node.type === import_utils12.AST_NODE_TYPES.TSUnionType) {
|
|
775
828
|
return node.types.some((type) => isInlineTypeAnnotation(type));
|
|
776
829
|
}
|
|
777
830
|
return false;
|
|
778
831
|
}
|
|
779
832
|
function hasInlineObjectType(node) {
|
|
780
|
-
if (node.type ===
|
|
833
|
+
if (node.type === import_utils12.AST_NODE_TYPES.TSTypeLiteral) {
|
|
781
834
|
return true;
|
|
782
835
|
}
|
|
783
|
-
if (node.type ===
|
|
784
|
-
return node.typeArguments.params.some((param) => param.type ===
|
|
836
|
+
if (node.type === import_utils12.AST_NODE_TYPES.TSTypeReference && node.typeArguments) {
|
|
837
|
+
return node.typeArguments.params.some((param) => param.type === import_utils12.AST_NODE_TYPES.TSTypeLiteral);
|
|
785
838
|
}
|
|
786
|
-
if (node.type ===
|
|
839
|
+
if (node.type === import_utils12.AST_NODE_TYPES.TSUnionType) {
|
|
787
840
|
return node.types.some((type) => hasInlineObjectType(type));
|
|
788
841
|
}
|
|
789
842
|
return false;
|
|
@@ -796,7 +849,7 @@ var preferInterfaceOverInlineTypes = createRule11({
|
|
|
796
849
|
return;
|
|
797
850
|
}
|
|
798
851
|
const param = node.params[0];
|
|
799
|
-
if (param.type ===
|
|
852
|
+
if (param.type === import_utils12.AST_NODE_TYPES.Identifier && param.typeAnnotation) {
|
|
800
853
|
const { typeAnnotation } = param.typeAnnotation;
|
|
801
854
|
if (isInlineTypeAnnotation(typeAnnotation) && hasInlineObjectType(typeAnnotation)) {
|
|
802
855
|
context.report({
|
|
@@ -816,11 +869,11 @@ var preferInterfaceOverInlineTypes = createRule11({
|
|
|
816
869
|
var prefer_interface_over_inline_types_default = preferInterfaceOverInlineTypes;
|
|
817
870
|
|
|
818
871
|
// src/rules/prefer-named-param-types.ts
|
|
819
|
-
var
|
|
820
|
-
var
|
|
872
|
+
var import_utils13 = require("@typescript-eslint/utils");
|
|
873
|
+
var createRule13 = import_utils13.ESLintUtils.RuleCreator(
|
|
821
874
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
822
875
|
);
|
|
823
|
-
var preferNamedParamTypes =
|
|
876
|
+
var preferNamedParamTypes = createRule13({
|
|
824
877
|
name: "prefer-named-param-types",
|
|
825
878
|
meta: {
|
|
826
879
|
type: "suggestion",
|
|
@@ -835,16 +888,16 @@ var preferNamedParamTypes = createRule12({
|
|
|
835
888
|
defaultOptions: [],
|
|
836
889
|
create(context) {
|
|
837
890
|
function hasInlineObjectType(param) {
|
|
838
|
-
if (param.type ===
|
|
891
|
+
if (param.type === import_utils13.AST_NODE_TYPES.AssignmentPattern) {
|
|
839
892
|
return hasInlineObjectType(param.left);
|
|
840
893
|
}
|
|
841
|
-
if (param.type ===
|
|
842
|
-
if (param.typeAnnotation?.typeAnnotation.type ===
|
|
894
|
+
if (param.type === import_utils13.AST_NODE_TYPES.ObjectPattern) {
|
|
895
|
+
if (param.typeAnnotation?.typeAnnotation.type === import_utils13.AST_NODE_TYPES.TSTypeLiteral) {
|
|
843
896
|
return true;
|
|
844
897
|
}
|
|
845
898
|
}
|
|
846
|
-
if (param.type ===
|
|
847
|
-
if (param.typeAnnotation?.typeAnnotation.type ===
|
|
899
|
+
if (param.type === import_utils13.AST_NODE_TYPES.Identifier) {
|
|
900
|
+
if (param.typeAnnotation?.typeAnnotation.type === import_utils13.AST_NODE_TYPES.TSTypeLiteral) {
|
|
848
901
|
return true;
|
|
849
902
|
}
|
|
850
903
|
}
|
|
@@ -878,11 +931,11 @@ var preferNamedParamTypes = createRule12({
|
|
|
878
931
|
var prefer_named_param_types_default = preferNamedParamTypes;
|
|
879
932
|
|
|
880
933
|
// src/rules/prefer-react-import-types.ts
|
|
881
|
-
var
|
|
882
|
-
var
|
|
934
|
+
var import_utils14 = require("@typescript-eslint/utils");
|
|
935
|
+
var createRule14 = import_utils14.ESLintUtils.RuleCreator(
|
|
883
936
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
884
937
|
);
|
|
885
|
-
var preferReactImportTypes =
|
|
938
|
+
var preferReactImportTypes = createRule14({
|
|
886
939
|
name: "prefer-react-import-types",
|
|
887
940
|
meta: {
|
|
888
941
|
type: "suggestion",
|
|
@@ -958,7 +1011,7 @@ var preferReactImportTypes = createRule13({
|
|
|
958
1011
|
]);
|
|
959
1012
|
const allReactExports = /* @__PURE__ */ new Set([...reactTypes, ...reactRuntimeExports]);
|
|
960
1013
|
function checkMemberExpression(node) {
|
|
961
|
-
if (node.object.type ===
|
|
1014
|
+
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
1015
|
const typeName = node.property.name;
|
|
963
1016
|
const isType = reactTypes.has(typeName);
|
|
964
1017
|
const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
|
|
@@ -975,7 +1028,7 @@ var preferReactImportTypes = createRule13({
|
|
|
975
1028
|
return {
|
|
976
1029
|
MemberExpression: checkMemberExpression,
|
|
977
1030
|
"TSTypeReference > TSQualifiedName": (node) => {
|
|
978
|
-
if (node.left.type ===
|
|
1031
|
+
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
1032
|
const typeName = node.right.name;
|
|
980
1033
|
const isType = reactTypes.has(typeName);
|
|
981
1034
|
const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
|
|
@@ -995,11 +1048,11 @@ var preferReactImportTypes = createRule13({
|
|
|
995
1048
|
var prefer_react_import_types_default = preferReactImportTypes;
|
|
996
1049
|
|
|
997
1050
|
// src/rules/react-props-destructure.ts
|
|
998
|
-
var
|
|
999
|
-
var
|
|
1051
|
+
var import_utils15 = require("@typescript-eslint/utils");
|
|
1052
|
+
var createRule15 = import_utils15.ESLintUtils.RuleCreator(
|
|
1000
1053
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
1001
1054
|
);
|
|
1002
|
-
var reactPropsDestructure =
|
|
1055
|
+
var reactPropsDestructure = createRule15({
|
|
1003
1056
|
name: "react-props-destructure",
|
|
1004
1057
|
meta: {
|
|
1005
1058
|
type: "suggestion",
|
|
@@ -1015,29 +1068,29 @@ var reactPropsDestructure = createRule14({
|
|
|
1015
1068
|
defaultOptions: [],
|
|
1016
1069
|
create(context) {
|
|
1017
1070
|
function hasJSXInConditional(node) {
|
|
1018
|
-
return node.consequent.type ===
|
|
1071
|
+
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
1072
|
}
|
|
1020
1073
|
function hasJSXInLogical(node) {
|
|
1021
|
-
return node.right.type ===
|
|
1074
|
+
return node.right.type === import_utils15.AST_NODE_TYPES.JSXElement || node.right.type === import_utils15.AST_NODE_TYPES.JSXFragment;
|
|
1022
1075
|
}
|
|
1023
1076
|
function hasJSXReturn(block) {
|
|
1024
1077
|
return block.body.some((stmt) => {
|
|
1025
|
-
if (stmt.type ===
|
|
1026
|
-
return stmt.argument.type ===
|
|
1078
|
+
if (stmt.type === import_utils15.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
|
|
1079
|
+
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
1080
|
}
|
|
1028
1081
|
return false;
|
|
1029
1082
|
});
|
|
1030
1083
|
}
|
|
1031
1084
|
function isReactComponent(node) {
|
|
1032
|
-
if (node.type ===
|
|
1033
|
-
if (node.body.type ===
|
|
1085
|
+
if (node.type === import_utils15.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
1086
|
+
if (node.body.type === import_utils15.AST_NODE_TYPES.JSXElement || node.body.type === import_utils15.AST_NODE_TYPES.JSXFragment) {
|
|
1034
1087
|
return true;
|
|
1035
1088
|
}
|
|
1036
|
-
if (node.body.type ===
|
|
1089
|
+
if (node.body.type === import_utils15.AST_NODE_TYPES.BlockStatement) {
|
|
1037
1090
|
return hasJSXReturn(node.body);
|
|
1038
1091
|
}
|
|
1039
|
-
} else if (node.type ===
|
|
1040
|
-
if (node.body && node.body.type ===
|
|
1092
|
+
} else if (node.type === import_utils15.AST_NODE_TYPES.FunctionExpression || node.type === import_utils15.AST_NODE_TYPES.FunctionDeclaration) {
|
|
1093
|
+
if (node.body && node.body.type === import_utils15.AST_NODE_TYPES.BlockStatement) {
|
|
1041
1094
|
return hasJSXReturn(node.body);
|
|
1042
1095
|
}
|
|
1043
1096
|
}
|
|
@@ -1051,9 +1104,9 @@ var reactPropsDestructure = createRule14({
|
|
|
1051
1104
|
return;
|
|
1052
1105
|
}
|
|
1053
1106
|
const param = node.params[0];
|
|
1054
|
-
if (param.type ===
|
|
1055
|
-
const properties = param.properties.filter((prop) => prop.type ===
|
|
1056
|
-
if (prop.key.type ===
|
|
1107
|
+
if (param.type === import_utils15.AST_NODE_TYPES.ObjectPattern) {
|
|
1108
|
+
const properties = param.properties.filter((prop) => prop.type === import_utils15.AST_NODE_TYPES.Property).map((prop) => {
|
|
1109
|
+
if (prop.key.type === import_utils15.AST_NODE_TYPES.Identifier) {
|
|
1057
1110
|
return prop.key.name;
|
|
1058
1111
|
}
|
|
1059
1112
|
return null;
|
|
@@ -1091,6 +1144,7 @@ var rules = {
|
|
|
1091
1144
|
"md-filename-case-restriction": md_filename_case_restriction_default,
|
|
1092
1145
|
"no-complex-inline-return": no_complex_inline_return_default,
|
|
1093
1146
|
"no-emoji": no_emoji_default,
|
|
1147
|
+
"no-env-fallback": no_env_fallback_default,
|
|
1094
1148
|
"no-explicit-return-type": no_explicit_return_type_default,
|
|
1095
1149
|
"no-logic-in-params": no_logic_in_params_default,
|
|
1096
1150
|
"prefer-destructuring-params": prefer_destructuring_params_default,
|
|
@@ -1114,7 +1168,8 @@ var baseRules = {
|
|
|
1114
1168
|
"nextfriday/prefer-named-param-types": "warn",
|
|
1115
1169
|
"nextfriday/prefer-react-import-types": "warn",
|
|
1116
1170
|
"nextfriday/no-complex-inline-return": "warn",
|
|
1117
|
-
"nextfriday/no-logic-in-params": "warn"
|
|
1171
|
+
"nextfriday/no-logic-in-params": "warn",
|
|
1172
|
+
"nextfriday/no-env-fallback": "warn"
|
|
1118
1173
|
};
|
|
1119
1174
|
var baseRecommendedRules = {
|
|
1120
1175
|
"nextfriday/no-emoji": "error",
|
|
@@ -1126,7 +1181,8 @@ var baseRecommendedRules = {
|
|
|
1126
1181
|
"nextfriday/prefer-named-param-types": "error",
|
|
1127
1182
|
"nextfriday/prefer-react-import-types": "error",
|
|
1128
1183
|
"nextfriday/no-complex-inline-return": "error",
|
|
1129
|
-
"nextfriday/no-logic-in-params": "error"
|
|
1184
|
+
"nextfriday/no-logic-in-params": "error",
|
|
1185
|
+
"nextfriday/no-env-fallback": "error"
|
|
1130
1186
|
};
|
|
1131
1187
|
var jsxRules = {
|
|
1132
1188
|
"nextfriday/jsx-pascal-case": "warn",
|