js-style-kit 0.2.12 → 0.4.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 +103 -19
- package/dist/bin/index.js +12 -16
- package/dist/bin/index.js.map +1 -1
- package/dist/index.d.ts +9 -8
- package/dist/index.js +289 -90
- package/dist/index.js.map +1 -1
- package/package.json +18 -14
package/dist/index.d.ts
CHANGED
|
@@ -12,13 +12,13 @@ declare const configNames: {
|
|
|
12
12
|
readonly base: "base";
|
|
13
13
|
readonly disableTypeChecked: "typescript-eslint/disable-type-checked";
|
|
14
14
|
readonly ignores: "ignores";
|
|
15
|
+
readonly import: "import";
|
|
15
16
|
readonly jsdoc: "jsdoc";
|
|
16
17
|
readonly markdown: "markdown";
|
|
17
18
|
readonly nextjs: "nextjs";
|
|
18
19
|
readonly perfectionist: "perfectionist";
|
|
19
20
|
readonly preferArrowFunction: "prefer-arrow-function";
|
|
20
21
|
readonly react: "react";
|
|
21
|
-
readonly reactCompiler: "react-compiler";
|
|
22
22
|
readonly reactRefresh: "react-refresh";
|
|
23
23
|
readonly storybook: "storybook:stories";
|
|
24
24
|
readonly storybookConfig: "storybook:config";
|
|
@@ -48,15 +48,16 @@ interface TestingConfig {
|
|
|
48
48
|
interface EslintConfigOptions {
|
|
49
49
|
functionStyle?: "off" | FunctionStyle;
|
|
50
50
|
ignores?: string[];
|
|
51
|
+
importPlugin?: boolean;
|
|
51
52
|
jsdoc?: false | {
|
|
52
53
|
requireJsdoc?: boolean;
|
|
53
54
|
};
|
|
54
55
|
react?: boolean | {
|
|
55
56
|
framework?: "next" | "none" | "vite";
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
reactRefresh?: boolean | undefined;
|
|
57
|
+
reactCompiler?: boolean;
|
|
58
|
+
reactRefresh?: boolean;
|
|
59
59
|
};
|
|
60
|
+
rules?: Record<string, EslintRuleConfig>;
|
|
60
61
|
sorting?: boolean;
|
|
61
62
|
storybook?: boolean;
|
|
62
63
|
testing?: false | TestingConfig;
|
|
@@ -70,10 +71,9 @@ interface EslintConfigOptions {
|
|
|
70
71
|
* @param options - The optional configuration object.
|
|
71
72
|
* @param options.functionStyle - The function style to enforce. Defaults to "arrow".
|
|
72
73
|
* @param options.ignores - Additional paths to ignore. Already excludes `node_modules` and `dist`.
|
|
74
|
+
* @param options.importPlugin - Whether to include the import plugin. Defaults to true.
|
|
73
75
|
* @param options.jsdoc - Whether to include JSDoc rules. Set to false to disable, or provide an object to configure.
|
|
74
|
-
* @param options.react - Whether to include React
|
|
75
|
-
* Can be configured with an object to control next.js support and reactCompiler.
|
|
76
|
-
* Also controls reactRefresh, which is enabled by default when react is true.
|
|
76
|
+
* @param options.react - Whether to include React, React hooks, and React compiler rules.
|
|
77
77
|
* Can specify framework as "next", "none", or "vite" to control related configs:
|
|
78
78
|
* - "next": Includes Next.js config, excludes React Refresh.
|
|
79
79
|
* - "vite" or "none": Includes React Refresh, excludes Next.js.
|
|
@@ -89,10 +89,11 @@ interface EslintConfigOptions {
|
|
|
89
89
|
* @param options.typescript - Whether to include TypeScript rules. Can be a boolean or a string with path to tsconfig.
|
|
90
90
|
* @param options.turbo - Whether to include Turborepo rules. Defaults to false.
|
|
91
91
|
* @param options.unicorn - Whether to include Unicorn rules. Defaults to true.
|
|
92
|
+
* @param options.rules - This is for rules that you need to alter or turn off.
|
|
92
93
|
* @param additionalConfigs - Additional ESLint config objects to be merged into the final configuration.
|
|
93
94
|
* @returns An array of ESLint configuration objects.
|
|
94
95
|
*/
|
|
95
|
-
declare const eslintConfig: ({ functionStyle, ignores, jsdoc, react, sorting, storybook, testing, turbo, typescript, unicorn, }?: EslintConfigOptions, ...additionalConfigs: Linter.Config[]) => Linter.Config[];
|
|
96
|
+
declare const eslintConfig: ({ functionStyle, ignores, importPlugin, jsdoc, react, rules, sorting, storybook, testing, turbo, typescript, unicorn, }?: EslintConfigOptions, ...additionalConfigs: Linter.Config[]) => Linter.Config[];
|
|
96
97
|
|
|
97
98
|
interface PrettierConfigOptions extends Config {
|
|
98
99
|
cssOrderPlugin?: boolean;
|
package/dist/index.js
CHANGED
|
@@ -11,13 +11,13 @@ var configNames = {
|
|
|
11
11
|
base: "base",
|
|
12
12
|
disableTypeChecked: "typescript-eslint/disable-type-checked",
|
|
13
13
|
ignores: "ignores",
|
|
14
|
+
import: "import",
|
|
14
15
|
jsdoc: "jsdoc",
|
|
15
16
|
markdown: "markdown",
|
|
16
17
|
nextjs: "nextjs",
|
|
17
18
|
perfectionist: "perfectionist",
|
|
18
19
|
preferArrowFunction: "prefer-arrow-function",
|
|
19
20
|
react: "react",
|
|
20
|
-
reactCompiler: "react-compiler",
|
|
21
21
|
reactRefresh: "react-refresh",
|
|
22
22
|
storybook: "storybook:stories",
|
|
23
23
|
storybookConfig: "storybook:config",
|
|
@@ -27,9 +27,29 @@ var configNames = {
|
|
|
27
27
|
typescriptTesting: "tseslint-testing",
|
|
28
28
|
unicorn: "unicorn"
|
|
29
29
|
};
|
|
30
|
+
var pluginPrefixMap = /* @__PURE__ */ new Map([
|
|
31
|
+
["@typescript-eslint", configNames.typescript],
|
|
32
|
+
["import", configNames.import],
|
|
33
|
+
["import-x", configNames.import],
|
|
34
|
+
["jest", configNames.testing],
|
|
35
|
+
["jsdoc", configNames.jsdoc],
|
|
36
|
+
["nextjs", configNames.nextjs],
|
|
37
|
+
["perfectionist", configNames.perfectionist],
|
|
38
|
+
["react", configNames.react],
|
|
39
|
+
["react-hooks", configNames.react],
|
|
40
|
+
["react-refresh", configNames.reactRefresh],
|
|
41
|
+
["storybook", configNames.storybook],
|
|
42
|
+
["turbo", configNames.turbo],
|
|
43
|
+
["unicorn", configNames.unicorn],
|
|
44
|
+
["vitest", configNames.testing]
|
|
45
|
+
]);
|
|
30
46
|
|
|
31
47
|
// src/eslint/base/rules.ts
|
|
32
|
-
var baseEslintRules = (functionStyle) => ({
|
|
48
|
+
var baseEslintRules = (functionStyle, typescript) => ({
|
|
49
|
+
...!typescript ? {
|
|
50
|
+
"no-unused-expressions": "warn",
|
|
51
|
+
"no-unused-vars": "warn"
|
|
52
|
+
} : {},
|
|
33
53
|
/**
|
|
34
54
|
* Require return statements in array methods callbacks.
|
|
35
55
|
*
|
|
@@ -84,10 +104,8 @@ var baseEslintRules = (functionStyle) => ({
|
|
|
84
104
|
* 🚫 Not fixable - https://eslint.org/docs/rules/func-names
|
|
85
105
|
*/
|
|
86
106
|
"func-names": ["warn", "as-needed"],
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
functionStyle === "off" || functionStyle === "arrow" ? "off" : ["warn", functionStyle, { allowArrowFunctions: true }]
|
|
90
|
-
),
|
|
107
|
+
// if arrow function, we use the prefer-arrow-functions plugin
|
|
108
|
+
...functionStyle === "off" ? { "func-style": "off" } : functionStyle === "arrow" ? { "func-style": "off" } : { "func-style": ["warn", functionStyle, { allowArrowFunctions: true }] },
|
|
91
109
|
/**
|
|
92
110
|
* Require grouped accessor pairs in object literals and classes.
|
|
93
111
|
*
|
|
@@ -451,13 +469,17 @@ var baseEslintRules = (functionStyle) => ({
|
|
|
451
469
|
});
|
|
452
470
|
|
|
453
471
|
// src/eslint/base/config.ts
|
|
454
|
-
var baseEslintConfig = (functionStyle) => ({
|
|
472
|
+
var baseEslintConfig = (functionStyle, typescript, customRules) => ({
|
|
455
473
|
languageOptions: {
|
|
456
|
-
ecmaVersion:
|
|
474
|
+
ecmaVersion: "latest",
|
|
475
|
+
sourceType: "module"
|
|
457
476
|
},
|
|
458
477
|
linterOptions: { reportUnusedDisableDirectives: true },
|
|
459
478
|
name: configNames.base,
|
|
460
|
-
rules:
|
|
479
|
+
rules: {
|
|
480
|
+
...baseEslintRules(functionStyle, typescript),
|
|
481
|
+
...customRules ?? {}
|
|
482
|
+
}
|
|
461
483
|
});
|
|
462
484
|
|
|
463
485
|
// src/eslint/ignores.ts
|
|
@@ -467,9 +489,7 @@ var ignoresConfig = ({
|
|
|
467
489
|
userIgnores = []
|
|
468
490
|
} = {}) => ({
|
|
469
491
|
ignores: [
|
|
470
|
-
"**/node_modules/",
|
|
471
492
|
"**/dist/",
|
|
472
|
-
".git/",
|
|
473
493
|
...next ? [".next"] : [],
|
|
474
494
|
...storybook ? ["!.storybook"] : [],
|
|
475
495
|
...userIgnores
|
|
@@ -477,6 +497,110 @@ var ignoresConfig = ({
|
|
|
477
497
|
name: configNames.ignores
|
|
478
498
|
});
|
|
479
499
|
|
|
500
|
+
// src/eslint/import/config.ts
|
|
501
|
+
import tsParser from "@typescript-eslint/parser";
|
|
502
|
+
import { createTypeScriptImportResolver } from "eslint-import-resolver-typescript";
|
|
503
|
+
import importXPlugin from "eslint-plugin-import-x";
|
|
504
|
+
|
|
505
|
+
// src/eslint/import/rules.ts
|
|
506
|
+
var importRules = (typescript) => ({
|
|
507
|
+
// these rules are better handled by typescript
|
|
508
|
+
...!typescript ? {
|
|
509
|
+
"import-x/default": "warn",
|
|
510
|
+
"import-x/export": "warn",
|
|
511
|
+
"import-x/named": "warn",
|
|
512
|
+
"import-x/namespace": "warn",
|
|
513
|
+
"import-x/no-unresolved": "warn"
|
|
514
|
+
} : {},
|
|
515
|
+
/**
|
|
516
|
+
* Disallow non-import statements appearing before import statements.
|
|
517
|
+
*
|
|
518
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import-x/blob/main/docs/rules/first.md
|
|
519
|
+
*/
|
|
520
|
+
"import-x/first": "warn",
|
|
521
|
+
/**
|
|
522
|
+
* Require a newline after the last import-x/require.
|
|
523
|
+
*
|
|
524
|
+
* 🔧 Fixable - https://github.com/import-js/eslint-plugin-import-x/blob/main/docs/rules/newline-after-import.md
|
|
525
|
+
*/
|
|
526
|
+
"import-x/newline-after-import": "warn",
|
|
527
|
+
/**
|
|
528
|
+
* Disallow import of modules using absolute paths.
|
|
529
|
+
*
|
|
530
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import-x/blob/main/docs/rules/no-absolute-path.md
|
|
531
|
+
*/
|
|
532
|
+
"import-x/no-absolute-path": "warn",
|
|
533
|
+
/**
|
|
534
|
+
* Disallow cyclical dependencies between modules.
|
|
535
|
+
*
|
|
536
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import-x/blob/main/docs/rules/no-cycle.md
|
|
537
|
+
*/
|
|
538
|
+
"import-x/no-cycle": "warn",
|
|
539
|
+
"import-x/no-duplicates": "warn",
|
|
540
|
+
/**
|
|
541
|
+
* Disallow the use of extraneous packages.
|
|
542
|
+
*
|
|
543
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import-x/blob/main/docs/rules/no-extraneous-dependencies.md
|
|
544
|
+
*/
|
|
545
|
+
"import-x/no-extraneous-dependencies": ["warn", { includeTypes: true }],
|
|
546
|
+
/**
|
|
547
|
+
* Disallow mutable exports.
|
|
548
|
+
*
|
|
549
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import-x/blob/main/docs/rules/no-mutable-exports.md
|
|
550
|
+
*/
|
|
551
|
+
"import-x/no-mutable-exports": "warn",
|
|
552
|
+
// red flags (thus, warnings)
|
|
553
|
+
"import-x/no-named-as-default": "warn",
|
|
554
|
+
"import-x/no-named-as-default-member": "warn",
|
|
555
|
+
/**
|
|
556
|
+
* Disallow importing packages through relative paths.
|
|
557
|
+
*
|
|
558
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import-x/blob/main/docs/rules/no-relative-packages.md
|
|
559
|
+
*/
|
|
560
|
+
"import-x/no-relative-packages": "warn",
|
|
561
|
+
/**
|
|
562
|
+
* Disallow a module from importing itself.
|
|
563
|
+
*
|
|
564
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import-x/blob/main/docs/rules/no-self-import.md
|
|
565
|
+
*/
|
|
566
|
+
"import-x/no-self-import": "warn",
|
|
567
|
+
/**
|
|
568
|
+
* Ensures that there are no useless path segments.
|
|
569
|
+
*
|
|
570
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import-x/blob/main/docs/rules/no-useless-path-segments.md
|
|
571
|
+
*/
|
|
572
|
+
"import-x/no-useless-path-segments": ["warn"]
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
// src/eslint/import/config.ts
|
|
576
|
+
var importConfig = (typescript, customRules) => ({
|
|
577
|
+
languageOptions: {
|
|
578
|
+
ecmaVersion: "latest",
|
|
579
|
+
parser: tsParser,
|
|
580
|
+
sourceType: "module"
|
|
581
|
+
},
|
|
582
|
+
name: configNames.import,
|
|
583
|
+
plugins: {
|
|
584
|
+
"import-x": importXPlugin
|
|
585
|
+
},
|
|
586
|
+
rules: {
|
|
587
|
+
...importRules(typescript),
|
|
588
|
+
...customRules ?? {}
|
|
589
|
+
},
|
|
590
|
+
settings: {
|
|
591
|
+
"import-x/resolver": {
|
|
592
|
+
node: true,
|
|
593
|
+
typescript
|
|
594
|
+
},
|
|
595
|
+
"import-x/resolver-next": [
|
|
596
|
+
createTypeScriptImportResolver({
|
|
597
|
+
alwaysTryTypes: true,
|
|
598
|
+
bun: true
|
|
599
|
+
})
|
|
600
|
+
]
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
|
|
480
604
|
// src/eslint/jsdoc/config.ts
|
|
481
605
|
import jsdoc from "eslint-plugin-jsdoc";
|
|
482
606
|
|
|
@@ -551,14 +675,17 @@ var jsdocRules = (requireJsdoc = false, typescript = true) => ({
|
|
|
551
675
|
});
|
|
552
676
|
|
|
553
677
|
// src/eslint/jsdoc/config.ts
|
|
554
|
-
var jsdocConfig = (requireJsdoc = false,
|
|
678
|
+
var jsdocConfig = (requireJsdoc = false, customRules) => ({
|
|
555
679
|
files: ["**/*.{js,jsx,ts,tsx,cjs,mjs}"],
|
|
556
680
|
ignores: ["**/*.{test,spec}.{js,jsx,ts,tsx,cjs,mjs}"],
|
|
557
681
|
name: configNames.jsdoc,
|
|
558
682
|
plugins: {
|
|
559
683
|
jsdoc
|
|
560
684
|
},
|
|
561
|
-
rules:
|
|
685
|
+
rules: {
|
|
686
|
+
...jsdocRules(requireJsdoc),
|
|
687
|
+
...customRules ?? {}
|
|
688
|
+
}
|
|
562
689
|
});
|
|
563
690
|
|
|
564
691
|
// src/eslint/nextjs/config.ts
|
|
@@ -590,12 +717,15 @@ var nextjsRules = {
|
|
|
590
717
|
};
|
|
591
718
|
|
|
592
719
|
// src/eslint/nextjs/config.ts
|
|
593
|
-
var nextjsConfig = () => ({
|
|
720
|
+
var nextjsConfig = (customRules) => ({
|
|
594
721
|
name: configNames.nextjs,
|
|
595
722
|
plugins: {
|
|
596
723
|
nextjs
|
|
597
724
|
},
|
|
598
|
-
rules:
|
|
725
|
+
rules: {
|
|
726
|
+
...nextjsRules,
|
|
727
|
+
...customRules ?? {}
|
|
728
|
+
}
|
|
599
729
|
});
|
|
600
730
|
|
|
601
731
|
// src/eslint/perfectionist/config.ts
|
|
@@ -630,17 +760,20 @@ var perfectionistRules = {
|
|
|
630
760
|
};
|
|
631
761
|
|
|
632
762
|
// src/eslint/perfectionist/config.ts
|
|
633
|
-
var perfectionistConfig = {
|
|
763
|
+
var perfectionistConfig = (customRules) => ({
|
|
634
764
|
name: configNames.perfectionist,
|
|
635
765
|
plugins: {
|
|
636
766
|
perfectionist
|
|
637
767
|
},
|
|
638
|
-
rules:
|
|
639
|
-
|
|
768
|
+
rules: {
|
|
769
|
+
...perfectionistRules,
|
|
770
|
+
...customRules ?? {}
|
|
771
|
+
}
|
|
772
|
+
});
|
|
640
773
|
|
|
641
774
|
// src/eslint/prefer-arrow-function/config.ts
|
|
642
775
|
import preferArrowFunctions from "eslint-plugin-prefer-arrow-functions";
|
|
643
|
-
var preferArrowFunctionConfig = () => ({
|
|
776
|
+
var preferArrowFunctionConfig = (customRules) => ({
|
|
644
777
|
name: configNames.preferArrowFunction,
|
|
645
778
|
plugins: {
|
|
646
779
|
"prefer-arrow-functions": preferArrowFunctions
|
|
@@ -652,20 +785,46 @@ var preferArrowFunctionConfig = () => ({
|
|
|
652
785
|
returnStyle: "unchanged",
|
|
653
786
|
singleReturnOnly: false
|
|
654
787
|
}
|
|
655
|
-
]
|
|
788
|
+
],
|
|
789
|
+
...customRules ?? {}
|
|
656
790
|
}
|
|
657
791
|
});
|
|
658
792
|
|
|
659
|
-
// src/eslint/
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
793
|
+
// src/eslint/process-custom-rules.ts
|
|
794
|
+
var processCustomRules = (customRules) => {
|
|
795
|
+
const categorizedRules = Object.values(configNames).reduce(
|
|
796
|
+
(acc, configName) => {
|
|
797
|
+
acc[configName] = {};
|
|
798
|
+
return acc;
|
|
799
|
+
},
|
|
800
|
+
{}
|
|
801
|
+
);
|
|
802
|
+
for (const [ruleKey, ruleValue] of Object.entries(customRules)) {
|
|
803
|
+
if (!ruleKey.includes("/") && !ruleKey.startsWith("@")) {
|
|
804
|
+
categorizedRules[configNames.base][ruleKey] = ruleValue;
|
|
805
|
+
continue;
|
|
806
|
+
}
|
|
807
|
+
let prefix = null;
|
|
808
|
+
if (ruleKey.startsWith("@")) {
|
|
809
|
+
const firstSlashIndex = ruleKey.indexOf("/");
|
|
810
|
+
if (firstSlashIndex !== -1) {
|
|
811
|
+
prefix = ruleKey.substring(0, firstSlashIndex);
|
|
812
|
+
}
|
|
813
|
+
} else {
|
|
814
|
+
const firstSlashIndex = ruleKey.indexOf("/");
|
|
815
|
+
if (firstSlashIndex !== -1) {
|
|
816
|
+
prefix = ruleKey.substring(0, firstSlashIndex);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
const configName = prefix ? pluginPrefixMap.get(prefix) ?? configNames.base : configNames.base;
|
|
820
|
+
categorizedRules[configName][ruleKey] = ruleValue;
|
|
668
821
|
}
|
|
822
|
+
return Object.entries(categorizedRules).reduce((acc, [configName, rules2]) => {
|
|
823
|
+
if (Object.keys(rules2).length > 0) {
|
|
824
|
+
acc[configName] = rules2;
|
|
825
|
+
}
|
|
826
|
+
return acc;
|
|
827
|
+
}, {});
|
|
669
828
|
};
|
|
670
829
|
|
|
671
830
|
// src/eslint/react-refresh/config.ts
|
|
@@ -688,13 +847,13 @@ var reactRefreshRules = {
|
|
|
688
847
|
};
|
|
689
848
|
|
|
690
849
|
// src/eslint/react-refresh/config.ts
|
|
691
|
-
var reactRefreshEslintConfig = () => {
|
|
850
|
+
var reactRefreshEslintConfig = (customRules) => {
|
|
692
851
|
return {
|
|
693
852
|
name: configNames.reactRefresh,
|
|
694
853
|
plugins: {
|
|
695
854
|
"react-refresh": reactRefresh
|
|
696
855
|
},
|
|
697
|
-
rules: reactRefreshRules
|
|
856
|
+
rules: customRules ?? reactRefreshRules
|
|
698
857
|
};
|
|
699
858
|
};
|
|
700
859
|
|
|
@@ -716,6 +875,7 @@ var reactRules = (functionStyle, typescript) => {
|
|
|
716
875
|
*/
|
|
717
876
|
...typescript ? {} : { "react/prop-types": "warn" },
|
|
718
877
|
"react-hooks/exhaustive-deps": "warn",
|
|
878
|
+
"react-hooks/react-compiler": "warn",
|
|
719
879
|
"react-hooks/rules-of-hooks": "warn",
|
|
720
880
|
/**
|
|
721
881
|
* Require an explicit type when using button elements.
|
|
@@ -833,7 +993,7 @@ var reactRules = (functionStyle, typescript) => {
|
|
|
833
993
|
};
|
|
834
994
|
|
|
835
995
|
// src/eslint/react/config.ts
|
|
836
|
-
var reactEslintConfig = (functionStyle, typescript) => {
|
|
996
|
+
var reactEslintConfig = (functionStyle, typescript, customRules) => {
|
|
837
997
|
return {
|
|
838
998
|
languageOptions: {
|
|
839
999
|
globals: {
|
|
@@ -850,7 +1010,10 @@ var reactEslintConfig = (functionStyle, typescript) => {
|
|
|
850
1010
|
react,
|
|
851
1011
|
"react-hooks": pluginReactHooks
|
|
852
1012
|
},
|
|
853
|
-
rules:
|
|
1013
|
+
rules: {
|
|
1014
|
+
...reactRules(functionStyle, typescript),
|
|
1015
|
+
...customRules ?? {}
|
|
1016
|
+
},
|
|
854
1017
|
settings: {
|
|
855
1018
|
react: {
|
|
856
1019
|
version: "detect"
|
|
@@ -861,7 +1024,7 @@ var reactEslintConfig = (functionStyle, typescript) => {
|
|
|
861
1024
|
|
|
862
1025
|
// src/eslint/storybook/config.ts
|
|
863
1026
|
import storybookPlugin from "eslint-plugin-storybook";
|
|
864
|
-
var storybookConfig = [
|
|
1027
|
+
var storybookConfig = (customRules) => [
|
|
865
1028
|
{
|
|
866
1029
|
files: [
|
|
867
1030
|
"**/*.stories.@(ts|tsx|js|jsx|mjs|cjs)",
|
|
@@ -872,6 +1035,7 @@ var storybookConfig = [
|
|
|
872
1035
|
storybook: storybookPlugin
|
|
873
1036
|
},
|
|
874
1037
|
rules: {
|
|
1038
|
+
// Default Storybook rules
|
|
875
1039
|
"import/no-anonymous-default-export": "off",
|
|
876
1040
|
"react-hooks/rules-of-hooks": "off",
|
|
877
1041
|
"storybook/await-interactions": "warn",
|
|
@@ -884,7 +1048,9 @@ var storybookConfig = [
|
|
|
884
1048
|
"storybook/prefer-pascal-case": "warn",
|
|
885
1049
|
"storybook/story-exports": "warn",
|
|
886
1050
|
"storybook/use-storybook-expect": "warn",
|
|
887
|
-
"storybook/use-storybook-testing-library": "warn"
|
|
1051
|
+
"storybook/use-storybook-testing-library": "warn",
|
|
1052
|
+
// Merge custom rules
|
|
1053
|
+
...customRules ?? {}
|
|
888
1054
|
}
|
|
889
1055
|
},
|
|
890
1056
|
{
|
|
@@ -1003,7 +1169,7 @@ var testingConfig = ({
|
|
|
1003
1169
|
formattingRules: true,
|
|
1004
1170
|
framework: "vitest",
|
|
1005
1171
|
itOrTest: "test"
|
|
1006
|
-
}) => ({
|
|
1172
|
+
}, customRules) => ({
|
|
1007
1173
|
files: files ?? ["**/*.{test,spec}.{ts,tsx,js,jsx}"],
|
|
1008
1174
|
languageOptions: {
|
|
1009
1175
|
globals: framework === "vitest" ? { ...vitest.environments.env.globals } : jest.environments.globals.globals
|
|
@@ -1032,7 +1198,8 @@ var testingConfig = ({
|
|
|
1032
1198
|
"jest/padding-around-describe-blocks": "warn",
|
|
1033
1199
|
"jest/padding-around-expect-groups": "warn",
|
|
1034
1200
|
"jest/padding-around-test-blocks": "warn"
|
|
1035
|
-
} : {}
|
|
1201
|
+
} : {},
|
|
1202
|
+
...customRules ?? {}
|
|
1036
1203
|
},
|
|
1037
1204
|
...framework !== "jest" && framework !== "vitest" ? {
|
|
1038
1205
|
settings: {
|
|
@@ -1045,12 +1212,12 @@ var testingConfig = ({
|
|
|
1045
1212
|
|
|
1046
1213
|
// src/eslint/turbo/config.ts
|
|
1047
1214
|
import turbo from "eslint-plugin-turbo";
|
|
1048
|
-
var turboConfig = () => ({
|
|
1215
|
+
var turboConfig = (customRules) => ({
|
|
1049
1216
|
name: configNames.turbo,
|
|
1050
1217
|
plugins: {
|
|
1051
1218
|
turbo
|
|
1052
1219
|
},
|
|
1053
|
-
rules: {
|
|
1220
|
+
rules: customRules ?? {
|
|
1054
1221
|
"turbo/no-undeclared-env-vars": "warn"
|
|
1055
1222
|
}
|
|
1056
1223
|
});
|
|
@@ -1150,7 +1317,12 @@ var tseslintRules = {
|
|
|
1150
1317
|
"@typescript-eslint/prefer-includes": "warn",
|
|
1151
1318
|
"@typescript-eslint/prefer-literal-enum-member": "warn",
|
|
1152
1319
|
"@typescript-eslint/prefer-namespace-keyword": "warn",
|
|
1153
|
-
"@typescript-eslint/prefer-nullish-coalescing":
|
|
1320
|
+
"@typescript-eslint/prefer-nullish-coalescing": [
|
|
1321
|
+
"warn",
|
|
1322
|
+
{
|
|
1323
|
+
ignorePrimitives: { string: true }
|
|
1324
|
+
}
|
|
1325
|
+
],
|
|
1154
1326
|
"@typescript-eslint/prefer-optional-chain": "warn",
|
|
1155
1327
|
"@typescript-eslint/prefer-promise-reject-errors": "warn",
|
|
1156
1328
|
"@typescript-eslint/prefer-reduce-type-parameter": "warn",
|
|
@@ -1191,7 +1363,7 @@ var tseslintRules = {
|
|
|
1191
1363
|
};
|
|
1192
1364
|
|
|
1193
1365
|
// src/eslint/typescript/config.ts
|
|
1194
|
-
var tseslintConfig = (tsconfigPath) => {
|
|
1366
|
+
var tseslintConfig = (tsconfigPath, customRules) => {
|
|
1195
1367
|
const userCwd = process.cwd();
|
|
1196
1368
|
return tseslint.config(
|
|
1197
1369
|
{
|
|
@@ -1206,7 +1378,10 @@ var tseslintConfig = (tsconfigPath) => {
|
|
|
1206
1378
|
plugins: {
|
|
1207
1379
|
"@typescript-eslint": tseslint.plugin
|
|
1208
1380
|
},
|
|
1209
|
-
rules:
|
|
1381
|
+
rules: {
|
|
1382
|
+
...tseslintRules,
|
|
1383
|
+
...customRules ?? {}
|
|
1384
|
+
}
|
|
1210
1385
|
},
|
|
1211
1386
|
{
|
|
1212
1387
|
// disable type-aware linting on JS files
|
|
@@ -1296,108 +1471,132 @@ var rules = {
|
|
|
1296
1471
|
};
|
|
1297
1472
|
|
|
1298
1473
|
// src/eslint/unicorn/config.ts
|
|
1299
|
-
var unicornConfig = {
|
|
1474
|
+
var unicornConfig = (customRules) => ({
|
|
1300
1475
|
name: configNames.unicorn,
|
|
1301
1476
|
plugins: {
|
|
1302
1477
|
unicorn
|
|
1303
1478
|
},
|
|
1304
|
-
rules
|
|
1305
|
-
|
|
1479
|
+
rules: {
|
|
1480
|
+
...rules,
|
|
1481
|
+
...customRules ?? {}
|
|
1482
|
+
}
|
|
1483
|
+
});
|
|
1306
1484
|
|
|
1307
1485
|
// src/eslint/index.ts
|
|
1486
|
+
var defaultTestingConfig = {
|
|
1487
|
+
filenamePattern: "test",
|
|
1488
|
+
files: ["**/*.{test,spec}.{ts,tsx,js,jsx}"],
|
|
1489
|
+
formattingRules: true,
|
|
1490
|
+
framework: "vitest",
|
|
1491
|
+
itOrTest: "it"
|
|
1492
|
+
};
|
|
1308
1493
|
var eslintConfig = ({
|
|
1309
1494
|
functionStyle = "arrow",
|
|
1310
1495
|
ignores = [],
|
|
1496
|
+
importPlugin = true,
|
|
1311
1497
|
jsdoc: jsdoc2 = { requireJsdoc: false },
|
|
1312
1498
|
react: react2 = false,
|
|
1499
|
+
rules: rules2,
|
|
1313
1500
|
sorting = true,
|
|
1314
1501
|
storybook = false,
|
|
1315
|
-
testing,
|
|
1316
|
-
/**
|
|
1317
|
-
* Some preceding documentation...
|
|
1318
|
-
*
|
|
1319
|
-
* @param options.turbo - Whether to include Turborepo rules. Defaults to false.
|
|
1320
|
-
*
|
|
1321
|
-
* Some following documentation...
|
|
1322
|
-
*/
|
|
1502
|
+
testing = defaultTestingConfig,
|
|
1323
1503
|
turbo: turbo2 = false,
|
|
1324
1504
|
typescript = true,
|
|
1325
1505
|
unicorn: unicorn2 = true
|
|
1326
1506
|
} = {}, ...additionalConfigs) => {
|
|
1507
|
+
const categorizedRules = rules2 === void 0 ? {} : processCustomRules(rules2);
|
|
1508
|
+
const usingNextjs = isObject(react2) && react2.framework === "next";
|
|
1327
1509
|
const configs = [
|
|
1328
1510
|
ignoresConfig({
|
|
1329
|
-
next:
|
|
1511
|
+
next: usingNextjs,
|
|
1330
1512
|
storybook,
|
|
1331
1513
|
userIgnores: ignores
|
|
1332
1514
|
}),
|
|
1333
|
-
baseEslintConfig(
|
|
1515
|
+
baseEslintConfig(
|
|
1516
|
+
functionStyle,
|
|
1517
|
+
Boolean(typescript),
|
|
1518
|
+
categorizedRules[configNames.base]
|
|
1519
|
+
)
|
|
1334
1520
|
];
|
|
1335
1521
|
if (jsdoc2 !== false) {
|
|
1336
|
-
configs.push(
|
|
1522
|
+
configs.push(
|
|
1523
|
+
jsdocConfig(
|
|
1524
|
+
jsdoc2.requireJsdoc ?? false,
|
|
1525
|
+
categorizedRules[configNames.jsdoc]
|
|
1526
|
+
)
|
|
1527
|
+
);
|
|
1337
1528
|
}
|
|
1338
1529
|
if (typescript) {
|
|
1339
1530
|
configs.push(
|
|
1340
1531
|
...tseslintConfig(
|
|
1341
|
-
isString(typescript) ? typescript : void 0
|
|
1532
|
+
isString(typescript) ? typescript : void 0,
|
|
1533
|
+
categorizedRules[configNames.typescript]
|
|
1342
1534
|
)
|
|
1343
1535
|
);
|
|
1344
1536
|
}
|
|
1537
|
+
if (importPlugin) {
|
|
1538
|
+
configs.push(
|
|
1539
|
+
importConfig(Boolean(typescript), categorizedRules[configNames.import])
|
|
1540
|
+
);
|
|
1541
|
+
}
|
|
1345
1542
|
if (react2) {
|
|
1346
|
-
configs.push(reactEslintConfig(functionStyle, Boolean(typescript)));
|
|
1347
|
-
const shouldUseReactCompiler = react2 === true || isObject(react2) && react2.reactCompiler !== false;
|
|
1348
|
-
if (shouldUseReactCompiler) {
|
|
1349
|
-
configs.push(reactCompilerEslintConfig);
|
|
1350
|
-
}
|
|
1351
|
-
const isNextFramework = isObject(react2) && (react2.framework === "next" || react2.next === true && react2.framework === void 0);
|
|
1352
|
-
if (isNextFramework) {
|
|
1353
|
-
configs.push(nextjsConfig());
|
|
1354
|
-
}
|
|
1355
1543
|
const shouldUseReactRefresh = (
|
|
1356
1544
|
// Explicit setting takes precedence
|
|
1357
1545
|
isObject(react2) && react2.reactRefresh === true || // Framework-based default (vite/none use reactRefresh by default)
|
|
1358
1546
|
isObject(react2) && (react2.framework === "vite" || react2.framework === "none") && react2.reactRefresh !== false
|
|
1359
1547
|
);
|
|
1360
1548
|
if (shouldUseReactRefresh) {
|
|
1361
|
-
configs.push(
|
|
1549
|
+
configs.push(
|
|
1550
|
+
reactRefreshEslintConfig(categorizedRules[configNames.reactRefresh])
|
|
1551
|
+
);
|
|
1552
|
+
}
|
|
1553
|
+
configs.push(
|
|
1554
|
+
reactEslintConfig(
|
|
1555
|
+
functionStyle,
|
|
1556
|
+
Boolean(typescript),
|
|
1557
|
+
categorizedRules[configNames.react]
|
|
1558
|
+
)
|
|
1559
|
+
);
|
|
1560
|
+
if (usingNextjs) {
|
|
1561
|
+
configs.push(nextjsConfig(categorizedRules[configNames.nextjs]));
|
|
1362
1562
|
}
|
|
1363
1563
|
}
|
|
1364
1564
|
if (testing !== false) {
|
|
1365
|
-
const
|
|
1366
|
-
filenamePattern: "test",
|
|
1367
|
-
files: ["**/*.{test,spec}.{ts,tsx,js,jsx}"],
|
|
1368
|
-
formattingRules: true,
|
|
1369
|
-
framework: "vitest",
|
|
1370
|
-
itOrTest: "it"
|
|
1371
|
-
};
|
|
1372
|
-
const mergedTestingConfig = {
|
|
1373
|
-
...defaultTestingConfig,
|
|
1374
|
-
...isObject(testing) ? testing : {}
|
|
1375
|
-
};
|
|
1565
|
+
const mergedTestingConfig = isObject(testing) ? { ...defaultTestingConfig, ...testing } : defaultTestingConfig;
|
|
1376
1566
|
const { filenamePattern, files, formattingRules, framework, itOrTest } = mergedTestingConfig;
|
|
1377
1567
|
configs.push(
|
|
1378
|
-
testingConfig(
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1568
|
+
testingConfig(
|
|
1569
|
+
{
|
|
1570
|
+
filenamePattern,
|
|
1571
|
+
files,
|
|
1572
|
+
formattingRules,
|
|
1573
|
+
framework,
|
|
1574
|
+
itOrTest
|
|
1575
|
+
},
|
|
1576
|
+
categorizedRules[configNames.testing]
|
|
1577
|
+
)
|
|
1385
1578
|
);
|
|
1386
1579
|
}
|
|
1387
1580
|
if (sorting) {
|
|
1388
|
-
configs.push(
|
|
1581
|
+
configs.push(
|
|
1582
|
+
perfectionistConfig(categorizedRules[configNames.perfectionist])
|
|
1583
|
+
);
|
|
1389
1584
|
}
|
|
1390
1585
|
if (unicorn2) {
|
|
1391
|
-
configs.push(unicornConfig);
|
|
1586
|
+
configs.push(unicornConfig(categorizedRules[configNames.unicorn]));
|
|
1392
1587
|
}
|
|
1393
1588
|
if (functionStyle === "arrow") {
|
|
1394
|
-
configs.push(
|
|
1589
|
+
configs.push(
|
|
1590
|
+
preferArrowFunctionConfig(
|
|
1591
|
+
categorizedRules[configNames.preferArrowFunction]
|
|
1592
|
+
)
|
|
1593
|
+
);
|
|
1395
1594
|
}
|
|
1396
1595
|
if (storybook) {
|
|
1397
|
-
configs.push(...storybookConfig);
|
|
1596
|
+
configs.push(...storybookConfig(categorizedRules[configNames.storybook]));
|
|
1398
1597
|
}
|
|
1399
1598
|
if (turbo2) {
|
|
1400
|
-
configs.push(turboConfig());
|
|
1599
|
+
configs.push(turboConfig(categorizedRules[configNames.turbo]));
|
|
1401
1600
|
}
|
|
1402
1601
|
if (additionalConfigs.length > 0) {
|
|
1403
1602
|
configs.push(...additionalConfigs);
|