@so1ve/eslint-config 1.0.0-alpha.3 → 1.0.0-alpha.5

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/dist/index.cjs CHANGED
@@ -597,10 +597,8 @@ const jsdoc = () => [
597
597
  "jsdoc/no-multi-asterisks": "error",
598
598
  "jsdoc/require-param-name": "error",
599
599
  "jsdoc/require-property": "error",
600
- "jsdoc/require-property-description": "error",
601
600
  "jsdoc/require-property-name": "error",
602
601
  "jsdoc/require-returns-check": "error",
603
- "jsdoc/require-returns-description": "error",
604
602
  "jsdoc/require-yields-check": "error",
605
603
  "jsdoc/valid-types": "error"
606
604
  }
@@ -864,239 +862,233 @@ function warnUnnecessaryOffRules() {
864
862
  }
865
863
  }
866
864
 
867
- const typescript = ({
865
+ function typescript({
868
866
  componentExts = [],
867
+ parserOptions,
869
868
  overrides
870
- } = {}) => [
871
- {
872
- // Install the plugins without globs, so they can be configured separately.
873
- plugins: {
874
- import: pluginImport__default["default"],
875
- ts: pluginTs__default["default"]
876
- }
877
- },
878
- {
879
- files: [GLOB_TS, GLOB_TSX, ...componentExts.map((ext) => `**/*.${ext}`)],
880
- languageOptions: {
881
- parser: parserTs__default["default"],
882
- parserOptions: {
883
- sourceType: "module"
869
+ } = {}) {
870
+ const typeAwareRules = {
871
+ "etc/no-assign-mutated-array": "error",
872
+ "etc/no-deprecated": "warn",
873
+ "etc/no-internal": "error",
874
+ "no-throw-literal": "off",
875
+ "ts/no-throw-literal": "error",
876
+ "no-implied-eval": "off",
877
+ "ts/no-implied-eval": "error",
878
+ "dot-notation": "off",
879
+ "ts/dot-notation": ["error", { allowKeywords: true }],
880
+ "no-void": ["error", { allowAsStatement: true }],
881
+ "ts/await-thenable": "error",
882
+ "ts/no-for-in-array": "error",
883
+ "ts/no-unnecessary-type-assertion": "error",
884
+ "ts/restrict-template-expressions": [
885
+ "error",
886
+ {
887
+ allowAny: true,
888
+ allowNumber: true,
889
+ allowBoolean: true
884
890
  }
885
- },
886
- settings: {
887
- "import/resolver": {
888
- node: { extensions: [".js", ".jsx", ".mjs", ".ts", ".tsx", ".d.ts"] },
889
- typescript: {
890
- extensions: [".js", ".jsx", ".mjs", ".ts", ".tsx", ".d.ts"]
891
- }
891
+ ],
892
+ "ts/array-type": ["error", { default: "array", readonly: "array" }],
893
+ "ts/consistent-generic-constructors": "error",
894
+ "ts/consistent-type-exports": "error",
895
+ "ts/consistent-type-assertions": [
896
+ "error",
897
+ { assertionStyle: "as", objectLiteralTypeAssertions: "allow" }
898
+ ],
899
+ "ts/prefer-nullish-coalescing": "error",
900
+ "ts/prefer-optional-chain": "error",
901
+ "ts/prefer-return-this-type": "error",
902
+ "ts/no-unnecessary-type-arguments": "error",
903
+ "ts/non-nullable-type-assertion-style": "error"
904
+ };
905
+ return [
906
+ {
907
+ // Install the plugins without globs, so they can be configured separately.
908
+ plugins: {
909
+ import: pluginImport__default["default"],
910
+ ts: pluginTs__default["default"],
911
+ etc: pluginEtc__default["default"]
892
912
  }
893
913
  },
894
- rules: {
895
- ...renameRules(
896
- pluginTs__default["default"].configs["eslint-recommended"].overrides[0].rules,
897
- "@typescript-eslint/",
898
- "ts/"
899
- ),
900
- ...renameRules(
901
- pluginTs__default["default"].configs.recommended.rules,
902
- "@typescript-eslint/",
903
- "ts/"
904
- ),
905
- "import/named": "off",
906
- // TS
907
- "ts/comma-dangle": "off",
908
- "ts/brace-style": "off",
909
- "ts/comma-spacing": "off",
910
- "ts/func-call-spacing": "off",
911
- "ts/indent": "off",
912
- "ts/keyword-spacing": "off",
913
- "ts/member-delimiter-style": "off",
914
- "ts/no-extra-parens": "off",
915
- "ts/no-extra-semi": "off",
916
- "ts/quotes": "off",
917
- "ts/semi": "off",
918
- "ts/space-before-function-paren": "off",
919
- "ts/type-annotation-spacing": "off",
920
- "ts/ban-ts-comment": [
921
- "error",
922
- {
923
- minimumDescriptionLength: 0
914
+ {
915
+ files: [GLOB_TS, GLOB_TSX, ...componentExts.map((ext) => `**/*.${ext}`)],
916
+ languageOptions: {
917
+ parser: parserTs__default["default"],
918
+ parserOptions: {
919
+ sourceType: "module",
920
+ EXPERIMENTAL_useProjectService: true,
921
+ ...parserOptions
924
922
  }
925
- ],
926
- "ts/ban-types": [
927
- "error",
928
- {
929
- extendDefaults: false,
930
- types: {
931
- String: {
932
- message: "Use `string` instead.",
933
- fixWith: "string"
934
- },
935
- Number: {
936
- message: "Use `number` instead.",
937
- fixWith: "number"
938
- },
939
- Boolean: {
940
- message: "Use `boolean` instead.",
941
- fixWith: "boolean"
942
- },
943
- Symbol: {
944
- message: "Use `symbol` instead.",
945
- fixWith: "symbol"
946
- },
947
- BigInt: {
948
- message: "Use `bigint` instead.",
949
- fixWith: "bigint"
950
- },
951
- Object: {
952
- message: "The `Object` type is mostly the same as `unknown`. You probably want `Record<PropertyKey, unknown>` instead. See https://github.com/typescript-eslint/typescript-eslint/pull/848",
953
- fixWith: "Record<PropertyKey, unknown>"
954
- },
955
- object: {
956
- message: "The `object` type is hard to use. Use `Record<PropertyKey, unknown>` instead. See: https://github.com/typescript-eslint/typescript-eslint/pull/848",
957
- fixWith: "Record<PropertyKey, unknown>"
958
- },
959
- Function: {
960
- message: "Use `(...args: any[]) => any` instead.",
961
- fixWith: "(...args: any[]) => any"
923
+ },
924
+ settings: {
925
+ "import/resolver": {
926
+ node: { extensions: [".js", ".jsx", ".mjs", ".ts", ".tsx", ".d.ts"] },
927
+ typescript: {
928
+ extensions: [".js", ".jsx", ".mjs", ".ts", ".tsx", ".d.ts"]
929
+ }
930
+ }
931
+ },
932
+ rules: {
933
+ ...renameRules(
934
+ pluginTs__default["default"].configs["eslint-recommended"].overrides[0].rules,
935
+ "@typescript-eslint/",
936
+ "ts/"
937
+ ),
938
+ ...renameRules(
939
+ pluginTs__default["default"].configs.recommended.rules,
940
+ "@typescript-eslint/",
941
+ "ts/"
942
+ ),
943
+ "import/named": "off",
944
+ // TS
945
+ "ts/comma-dangle": "off",
946
+ "ts/brace-style": "off",
947
+ "ts/comma-spacing": "off",
948
+ "ts/func-call-spacing": "off",
949
+ "ts/indent": "off",
950
+ "ts/keyword-spacing": "off",
951
+ "ts/member-delimiter-style": "off",
952
+ "ts/no-extra-parens": "off",
953
+ "ts/no-extra-semi": "off",
954
+ "ts/quotes": "off",
955
+ "ts/semi": "off",
956
+ "ts/space-before-function-paren": "off",
957
+ "ts/type-annotation-spacing": "off",
958
+ "ts/ban-ts-comment": [
959
+ "error",
960
+ {
961
+ minimumDescriptionLength: 0
962
+ }
963
+ ],
964
+ "ts/ban-types": [
965
+ "error",
966
+ {
967
+ extendDefaults: false,
968
+ types: {
969
+ String: {
970
+ message: "Use `string` instead.",
971
+ fixWith: "string"
972
+ },
973
+ Number: {
974
+ message: "Use `number` instead.",
975
+ fixWith: "number"
976
+ },
977
+ Boolean: {
978
+ message: "Use `boolean` instead.",
979
+ fixWith: "boolean"
980
+ },
981
+ Symbol: {
982
+ message: "Use `symbol` instead.",
983
+ fixWith: "symbol"
984
+ },
985
+ BigInt: {
986
+ message: "Use `bigint` instead.",
987
+ fixWith: "bigint"
988
+ },
989
+ Object: {
990
+ message: "The `Object` type is mostly the same as `unknown`. You probably want `Record<PropertyKey, unknown>` instead. See https://github.com/typescript-eslint/typescript-eslint/pull/848",
991
+ fixWith: "Record<PropertyKey, unknown>"
992
+ },
993
+ object: {
994
+ message: "The `object` type is hard to use. Use `Record<PropertyKey, unknown>` instead. See: https://github.com/typescript-eslint/typescript-eslint/pull/848",
995
+ fixWith: "Record<PropertyKey, unknown>"
996
+ },
997
+ Function: {
998
+ message: "Use `(...args: any[]) => any` instead.",
999
+ fixWith: "(...args: any[]) => any"
1000
+ }
962
1001
  }
963
1002
  }
1003
+ ],
1004
+ "ts/consistent-type-imports": [
1005
+ "error",
1006
+ { prefer: "type-imports", disallowTypeAnnotations: false }
1007
+ ],
1008
+ "ts/consistent-type-definitions": ["error", "interface"],
1009
+ "ts/consistent-indexed-object-style": ["error", "record"],
1010
+ "ts/prefer-ts-expect-error": "error",
1011
+ "ts/no-require-imports": "error",
1012
+ "ts/method-signature-style": ["error", "property"],
1013
+ // Override JS
1014
+ "no-useless-constructor": "off",
1015
+ "no-invalid-this": "off",
1016
+ "ts/no-invalid-this": "error",
1017
+ "no-redeclare": "off",
1018
+ "ts/no-redeclare": "error",
1019
+ "no-use-before-define": "off",
1020
+ "ts/no-use-before-define": [
1021
+ "error",
1022
+ { functions: false, classes: false, variables: true }
1023
+ ],
1024
+ "object-curly-spacing": "off",
1025
+ "space-before-blocks": "off",
1026
+ "ts/space-before-blocks": "off",
1027
+ "space-before-function-paren": "off",
1028
+ "no-dupe-class-members": "off",
1029
+ "ts/no-dupe-class-members": "error",
1030
+ "no-loss-of-precision": "off",
1031
+ "ts/no-loss-of-precision": "error",
1032
+ "lines-between-class-members": "off",
1033
+ "ts/lines-between-class-members": [
1034
+ "error",
1035
+ "always",
1036
+ { exceptAfterSingleLine: true }
1037
+ ],
1038
+ // so1ve
1039
+ "so1ve/no-inline-type-import": "error",
1040
+ // off
1041
+ "ts/camelcase": "off",
1042
+ "ts/explicit-function-return-type": "off",
1043
+ "ts/explicit-member-accessibility": "off",
1044
+ "ts/no-explicit-any": "off",
1045
+ "ts/no-parameter-properties": "off",
1046
+ "ts/no-empty-interface": "off",
1047
+ "ts/ban-ts-ignore": "off",
1048
+ "ts/no-empty-function": "off",
1049
+ "ts/no-non-null-assertion": "off",
1050
+ "ts/explicit-module-boundary-types": "off",
1051
+ "ts/triple-slash-reference": "off",
1052
+ "ts/prefer-for-of": "error",
1053
+ "ts/no-duplicate-enum-values": "error",
1054
+ "ts/no-non-null-asserted-nullish-coalescing": "error",
1055
+ // handled by unused-imports/no-unused-imports
1056
+ "ts/no-unused-vars": "off",
1057
+ ...typeAwareRules,
1058
+ ...overrides
1059
+ }
1060
+ },
1061
+ {
1062
+ files: [GLOB_MARKDOWN_CODE],
1063
+ languageOptions: {
1064
+ parser: parserTs__default["default"],
1065
+ parserOptions: {
1066
+ sourceType: "module"
964
1067
  }
965
- ],
966
- "ts/consistent-type-imports": [
967
- "error",
968
- { prefer: "type-imports", disallowTypeAnnotations: false }
969
- ],
970
- "ts/consistent-type-definitions": ["error", "interface"],
971
- "ts/consistent-indexed-object-style": ["error", "record"],
972
- "ts/prefer-ts-expect-error": "error",
973
- "ts/no-require-imports": "error",
974
- "ts/method-signature-style": ["error", "property"],
975
- // Override JS
976
- "no-useless-constructor": "off",
977
- "no-invalid-this": "off",
978
- "ts/no-invalid-this": "error",
979
- "no-redeclare": "off",
980
- "ts/no-redeclare": "error",
981
- "no-use-before-define": "off",
982
- "ts/no-use-before-define": [
983
- "error",
984
- { functions: false, classes: false, variables: true }
985
- ],
986
- "object-curly-spacing": "off",
987
- "space-before-blocks": "off",
988
- "ts/space-before-blocks": "off",
989
- "space-before-function-paren": "off",
990
- "no-dupe-class-members": "off",
991
- "ts/no-dupe-class-members": "error",
992
- "no-loss-of-precision": "off",
993
- "ts/no-loss-of-precision": "error",
994
- "lines-between-class-members": "off",
995
- "ts/lines-between-class-members": [
996
- "error",
997
- "always",
998
- { exceptAfterSingleLine: true }
999
- ],
1000
- // so1ve
1001
- "so1ve/no-inline-type-import": "error",
1002
- // off
1003
- "ts/camelcase": "off",
1004
- "ts/explicit-function-return-type": "off",
1005
- "ts/explicit-member-accessibility": "off",
1006
- "ts/no-explicit-any": "off",
1007
- "ts/no-parameter-properties": "off",
1008
- "ts/no-empty-interface": "off",
1009
- "ts/ban-ts-ignore": "off",
1010
- "ts/no-empty-function": "off",
1011
- "ts/no-non-null-assertion": "off",
1012
- "ts/explicit-module-boundary-types": "off",
1013
- "ts/triple-slash-reference": "off",
1014
- "ts/prefer-for-of": "error",
1015
- "ts/no-duplicate-enum-values": "error",
1016
- "ts/no-non-null-asserted-nullish-coalescing": "error",
1017
- // handled by unused-imports/no-unused-imports
1018
- "ts/no-unused-vars": "off",
1019
- ...overrides
1020
- }
1021
- },
1022
- {
1023
- files: ["**/*.d.ts"],
1024
- rules: {
1025
- "eslint-comments/no-unlimited-disable": "off",
1026
- "import/no-duplicates": "off",
1027
- "unused-imports/no-unused-vars": "off"
1028
- }
1029
- },
1030
- {
1031
- files: ["**/*.js", "**/*.cjs"],
1032
- rules: {
1033
- "ts/no-require-imports": "off",
1034
- "ts/no-var-requires": "off"
1035
- }
1036
- }
1037
- ];
1038
- const typescriptWithTypes = ({
1039
- componentExts = [],
1040
- tsconfigPath,
1041
- tsconfigRootDir = process.cwd(),
1042
- overrides = {}
1043
- }) => [
1044
- {
1045
- files: [
1046
- GLOB_TS,
1047
- GLOB_TSX,
1048
- ...componentExts.map((ext) => `**/*.${ext}`),
1049
- `!${GLOB_MARKDOWN}/*.*`
1050
- ],
1051
- plugins: {
1052
- etc: pluginEtc__default["default"]
1068
+ },
1069
+ rules: {
1070
+ ...Object.fromEntries(
1071
+ Object.keys(typeAwareRules).map((k) => [k, "off"])
1072
+ )
1073
+ }
1053
1074
  },
1054
- languageOptions: {
1055
- parser: parserTs__default["default"],
1056
- parserOptions: {
1057
- project: [tsconfigPath],
1058
- tsconfigRootDir,
1059
- EXPERIMENTAL_useProjectService: true
1075
+ {
1076
+ files: ["**/*.d.ts"],
1077
+ rules: {
1078
+ "eslint-comments/no-unlimited-disable": "off",
1079
+ "import/no-duplicates": "off",
1080
+ "unused-imports/no-unused-vars": "off"
1060
1081
  }
1061
1082
  },
1062
- rules: {
1063
- "etc/no-assign-mutated-array": "error",
1064
- "etc/no-deprecated": "warn",
1065
- "etc/no-internal": "error",
1066
- "no-throw-literal": "off",
1067
- "ts/no-throw-literal": "error",
1068
- "no-implied-eval": "off",
1069
- "ts/no-implied-eval": "error",
1070
- "dot-notation": "off",
1071
- "ts/dot-notation": ["error", { allowKeywords: true }],
1072
- "no-void": ["error", { allowAsStatement: true }],
1073
- "ts/await-thenable": "error",
1074
- "ts/no-for-in-array": "error",
1075
- "ts/no-unnecessary-type-assertion": "error",
1076
- "ts/restrict-template-expressions": [
1077
- "error",
1078
- {
1079
- allowAny: true,
1080
- allowNumber: true,
1081
- allowBoolean: true
1082
- }
1083
- ],
1084
- "ts/array-type": ["error", { default: "array", readonly: "array" }],
1085
- "ts/consistent-generic-constructors": "error",
1086
- "ts/consistent-type-exports": "error",
1087
- "ts/consistent-type-assertions": [
1088
- "error",
1089
- { assertionStyle: "as", objectLiteralTypeAssertions: "allow" }
1090
- ],
1091
- "ts/prefer-nullish-coalescing": "error",
1092
- "ts/prefer-optional-chain": "error",
1093
- "ts/prefer-return-this-type": "error",
1094
- "ts/no-unnecessary-type-arguments": "error",
1095
- "ts/non-nullable-type-assertion-style": "error",
1096
- ...overrides
1083
+ {
1084
+ files: ["**/*.js", "**/*.cjs"],
1085
+ rules: {
1086
+ "ts/no-require-imports": "off",
1087
+ "ts/no-var-requires": "off"
1088
+ }
1097
1089
  }
1098
- }
1099
- ];
1090
+ ];
1091
+ }
1100
1092
 
1101
1093
  const unicorn = () => [
1102
1094
  {
@@ -1381,7 +1373,8 @@ function so1ve(options = {}, ...userConfigs) {
1381
1373
  solid: enableSolid = localPkg.isPackageExists("solid-js"),
1382
1374
  typescript: enableTypeScript = localPkg.isPackageExists("typescript"),
1383
1375
  gitignore: enableGitignore = true,
1384
- overrides = {}
1376
+ overrides = {},
1377
+ componentExts = []
1385
1378
  } = options;
1386
1379
  const configs = [];
1387
1380
  if (enableGitignore) {
@@ -1402,13 +1395,11 @@ function so1ve(options = {}, ...userConfigs) {
1402
1395
  node(),
1403
1396
  onlyError(),
1404
1397
  promise(),
1405
- // jsdoc(),
1406
1398
  sortImports(),
1407
1399
  imports(),
1408
1400
  jsdoc(),
1409
1401
  unicorn()
1410
1402
  );
1411
- const componentExts = [];
1412
1403
  if (enableVue) {
1413
1404
  componentExts.push("vue");
1414
1405
  }
@@ -1419,15 +1410,6 @@ function so1ve(options = {}, ...userConfigs) {
1419
1410
  overrides: overrides.typescript
1420
1411
  })
1421
1412
  );
1422
- if (typeof enableTypeScript !== "boolean") {
1423
- configs.push(
1424
- typescriptWithTypes({
1425
- ...enableTypeScript,
1426
- componentExts,
1427
- overrides: overrides.typescriptWithTypes
1428
- })
1429
- );
1430
- }
1431
1413
  }
1432
1414
  if ((_a = options.test) != null ? _a : true) {
1433
1415
  configs.push(
@@ -1668,7 +1650,6 @@ exports.sortImports = sortImports;
1668
1650
  exports.test = test;
1669
1651
  exports.toml = toml;
1670
1652
  exports.typescript = typescript;
1671
- exports.typescriptWithTypes = typescriptWithTypes;
1672
1653
  exports.unicorn = unicorn;
1673
1654
  exports.vue = vue;
1674
1655
  exports.warnUnnecessaryOffRules = warnUnnecessaryOffRules;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { FlatESLintConfigItem } from 'eslint-define-config';
2
+ import { ParserOptions } from '@typescript-eslint/parser';
3
+ export { default as parserTs } from '@typescript-eslint/parser';
2
4
  import { FlatGitignoreOptions } from 'eslint-config-flat-gitignore';
3
5
  export { default as pluginComments } from '@eslint-community/eslint-plugin-eslint-comments';
4
6
  export { default as pluginHtml } from '@html-eslint/eslint-plugin';
@@ -6,7 +8,6 @@ export { default as parserHtml } from '@html-eslint/parser';
6
8
  export { default as pluginSo1ve } from '@so1ve/eslint-plugin';
7
9
  export { default as pluginSortImports } from '@so1ve/eslint-plugin-sort-imports';
8
10
  export { default as pluginTs } from '@typescript-eslint/eslint-plugin';
9
- export { default as parserTs } from '@typescript-eslint/parser';
10
11
  export { default as parserMdx } from 'eslint-mdx';
11
12
  export { default as pluginArrayFunc } from 'eslint-plugin-array-func';
12
13
  export { default as pluginEtc } from 'eslint-plugin-etc';
@@ -46,9 +47,11 @@ interface OptionsComponentExts {
46
47
  */
47
48
  componentExts?: string[];
48
49
  }
49
- interface OptionsTypeScriptWithTypes {
50
- tsconfigPath: string;
51
- tsconfigRootDir?: string;
50
+ interface OptionsTypeScriptParserOptions {
51
+ /**
52
+ * Additional parser options for TypeScript.
53
+ */
54
+ parserOptions?: Partial<ParserOptions>;
52
55
  }
53
56
  interface OptionsHasTypeScript {
54
57
  typescript?: boolean;
@@ -56,7 +59,7 @@ interface OptionsHasTypeScript {
56
59
  interface OptionsOverrides {
57
60
  overrides?: FlatESLintConfigItem["rules"];
58
61
  }
59
- interface Options {
62
+ interface Options extends OptionsComponentExts {
60
63
  /**
61
64
  * Enable gitignore support.
62
65
  *
@@ -73,7 +76,7 @@ interface Options {
73
76
  *
74
77
  * @default auto-detect based on the dependencies
75
78
  */
76
- typescript?: boolean | OptionsTypeScriptWithTypes;
79
+ typescript?: boolean;
77
80
  /**
78
81
  * Enable test support.
79
82
  *
@@ -122,7 +125,6 @@ interface Options {
122
125
  overrides?: {
123
126
  javascript?: FlatESLintConfigItem["rules"];
124
127
  typescript?: FlatESLintConfigItem["rules"];
125
- typescriptWithTypes?: FlatESLintConfigItem["rules"];
126
128
  test?: FlatESLintConfigItem["rules"];
127
129
  vue?: FlatESLintConfigItem["rules"];
128
130
  solid?: FlatESLintConfigItem["rules"];
@@ -157,8 +159,7 @@ declare const test: ({ overrides, }?: OptionsOverrides) => FlatESLintConfigItem[
157
159
 
158
160
  declare const toml: ({ overrides, }?: OptionsOverrides) => FlatESLintConfigItem[];
159
161
 
160
- declare const typescript: ({ componentExts, overrides, }?: OptionsComponentExts & OptionsOverrides) => FlatESLintConfigItem[];
161
- declare const typescriptWithTypes: ({ componentExts, tsconfigPath, tsconfigRootDir, overrides, }: OptionsTypeScriptWithTypes & OptionsComponentExts & OptionsOverrides) => FlatESLintConfigItem[];
162
+ declare function typescript({ componentExts, parserOptions, overrides, }?: OptionsTypeScriptParserOptions & OptionsComponentExts & OptionsOverrides): FlatESLintConfigItem[];
162
163
 
163
164
  declare const unicorn: () => FlatESLintConfigItem[];
164
165
 
@@ -208,4 +209,4 @@ declare function recordRulesStateConfigs(configs: FlatESLintConfigItem[]): FlatE
208
209
  declare function recordRulesState(rules: FlatESLintConfigItem["rules"]): FlatESLintConfigItem["rules"];
209
210
  declare function warnUnnecessaryOffRules(): void;
210
211
 
211
- export { GLOB_ALL_SRC, GLOB_CSS, GLOB_DTS, GLOB_ESLINTRC, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_PACKAGEJSON, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_YAML, Options, OptionsComponentExts, OptionsHasTypeScript, OptionsOverrides, OptionsTypeScriptWithTypes, combine, comments, html, ignores, imports, javascript, jsdoc, jsonc, mdx, node, onlyError, promise, recordRulesState, recordRulesStateConfigs, renameRules, so1ve, solid, sortImports, test, toml, typescript, typescriptWithTypes, unicorn, vue, warnUnnecessaryOffRules, yaml };
212
+ export { GLOB_ALL_SRC, GLOB_CSS, GLOB_DTS, GLOB_ESLINTRC, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_PACKAGEJSON, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_YAML, Options, OptionsComponentExts, OptionsHasTypeScript, OptionsOverrides, OptionsTypeScriptParserOptions, combine, comments, html, ignores, imports, javascript, jsdoc, jsonc, mdx, node, onlyError, promise, recordRulesState, recordRulesStateConfigs, renameRules, so1ve, solid, sortImports, test, toml, typescript, unicorn, vue, warnUnnecessaryOffRules, yaml };
package/dist/index.mjs CHANGED
@@ -586,10 +586,8 @@ const jsdoc = () => [
586
586
  "jsdoc/no-multi-asterisks": "error",
587
587
  "jsdoc/require-param-name": "error",
588
588
  "jsdoc/require-property": "error",
589
- "jsdoc/require-property-description": "error",
590
589
  "jsdoc/require-property-name": "error",
591
590
  "jsdoc/require-returns-check": "error",
592
- "jsdoc/require-returns-description": "error",
593
591
  "jsdoc/require-yields-check": "error",
594
592
  "jsdoc/valid-types": "error"
595
593
  }
@@ -853,239 +851,233 @@ function warnUnnecessaryOffRules() {
853
851
  }
854
852
  }
855
853
 
856
- const typescript = ({
854
+ function typescript({
857
855
  componentExts = [],
856
+ parserOptions,
858
857
  overrides
859
- } = {}) => [
860
- {
861
- // Install the plugins without globs, so they can be configured separately.
862
- plugins: {
863
- import: pluginImport,
864
- ts: pluginTs
865
- }
866
- },
867
- {
868
- files: [GLOB_TS, GLOB_TSX, ...componentExts.map((ext) => `**/*.${ext}`)],
869
- languageOptions: {
870
- parser: parserTs,
871
- parserOptions: {
872
- sourceType: "module"
858
+ } = {}) {
859
+ const typeAwareRules = {
860
+ "etc/no-assign-mutated-array": "error",
861
+ "etc/no-deprecated": "warn",
862
+ "etc/no-internal": "error",
863
+ "no-throw-literal": "off",
864
+ "ts/no-throw-literal": "error",
865
+ "no-implied-eval": "off",
866
+ "ts/no-implied-eval": "error",
867
+ "dot-notation": "off",
868
+ "ts/dot-notation": ["error", { allowKeywords: true }],
869
+ "no-void": ["error", { allowAsStatement: true }],
870
+ "ts/await-thenable": "error",
871
+ "ts/no-for-in-array": "error",
872
+ "ts/no-unnecessary-type-assertion": "error",
873
+ "ts/restrict-template-expressions": [
874
+ "error",
875
+ {
876
+ allowAny: true,
877
+ allowNumber: true,
878
+ allowBoolean: true
873
879
  }
874
- },
875
- settings: {
876
- "import/resolver": {
877
- node: { extensions: [".js", ".jsx", ".mjs", ".ts", ".tsx", ".d.ts"] },
878
- typescript: {
879
- extensions: [".js", ".jsx", ".mjs", ".ts", ".tsx", ".d.ts"]
880
- }
880
+ ],
881
+ "ts/array-type": ["error", { default: "array", readonly: "array" }],
882
+ "ts/consistent-generic-constructors": "error",
883
+ "ts/consistent-type-exports": "error",
884
+ "ts/consistent-type-assertions": [
885
+ "error",
886
+ { assertionStyle: "as", objectLiteralTypeAssertions: "allow" }
887
+ ],
888
+ "ts/prefer-nullish-coalescing": "error",
889
+ "ts/prefer-optional-chain": "error",
890
+ "ts/prefer-return-this-type": "error",
891
+ "ts/no-unnecessary-type-arguments": "error",
892
+ "ts/non-nullable-type-assertion-style": "error"
893
+ };
894
+ return [
895
+ {
896
+ // Install the plugins without globs, so they can be configured separately.
897
+ plugins: {
898
+ import: pluginImport,
899
+ ts: pluginTs,
900
+ etc: pluginEtc
881
901
  }
882
902
  },
883
- rules: {
884
- ...renameRules(
885
- pluginTs.configs["eslint-recommended"].overrides[0].rules,
886
- "@typescript-eslint/",
887
- "ts/"
888
- ),
889
- ...renameRules(
890
- pluginTs.configs.recommended.rules,
891
- "@typescript-eslint/",
892
- "ts/"
893
- ),
894
- "import/named": "off",
895
- // TS
896
- "ts/comma-dangle": "off",
897
- "ts/brace-style": "off",
898
- "ts/comma-spacing": "off",
899
- "ts/func-call-spacing": "off",
900
- "ts/indent": "off",
901
- "ts/keyword-spacing": "off",
902
- "ts/member-delimiter-style": "off",
903
- "ts/no-extra-parens": "off",
904
- "ts/no-extra-semi": "off",
905
- "ts/quotes": "off",
906
- "ts/semi": "off",
907
- "ts/space-before-function-paren": "off",
908
- "ts/type-annotation-spacing": "off",
909
- "ts/ban-ts-comment": [
910
- "error",
911
- {
912
- minimumDescriptionLength: 0
903
+ {
904
+ files: [GLOB_TS, GLOB_TSX, ...componentExts.map((ext) => `**/*.${ext}`)],
905
+ languageOptions: {
906
+ parser: parserTs,
907
+ parserOptions: {
908
+ sourceType: "module",
909
+ EXPERIMENTAL_useProjectService: true,
910
+ ...parserOptions
913
911
  }
914
- ],
915
- "ts/ban-types": [
916
- "error",
917
- {
918
- extendDefaults: false,
919
- types: {
920
- String: {
921
- message: "Use `string` instead.",
922
- fixWith: "string"
923
- },
924
- Number: {
925
- message: "Use `number` instead.",
926
- fixWith: "number"
927
- },
928
- Boolean: {
929
- message: "Use `boolean` instead.",
930
- fixWith: "boolean"
931
- },
932
- Symbol: {
933
- message: "Use `symbol` instead.",
934
- fixWith: "symbol"
935
- },
936
- BigInt: {
937
- message: "Use `bigint` instead.",
938
- fixWith: "bigint"
939
- },
940
- Object: {
941
- message: "The `Object` type is mostly the same as `unknown`. You probably want `Record<PropertyKey, unknown>` instead. See https://github.com/typescript-eslint/typescript-eslint/pull/848",
942
- fixWith: "Record<PropertyKey, unknown>"
943
- },
944
- object: {
945
- message: "The `object` type is hard to use. Use `Record<PropertyKey, unknown>` instead. See: https://github.com/typescript-eslint/typescript-eslint/pull/848",
946
- fixWith: "Record<PropertyKey, unknown>"
947
- },
948
- Function: {
949
- message: "Use `(...args: any[]) => any` instead.",
950
- fixWith: "(...args: any[]) => any"
912
+ },
913
+ settings: {
914
+ "import/resolver": {
915
+ node: { extensions: [".js", ".jsx", ".mjs", ".ts", ".tsx", ".d.ts"] },
916
+ typescript: {
917
+ extensions: [".js", ".jsx", ".mjs", ".ts", ".tsx", ".d.ts"]
918
+ }
919
+ }
920
+ },
921
+ rules: {
922
+ ...renameRules(
923
+ pluginTs.configs["eslint-recommended"].overrides[0].rules,
924
+ "@typescript-eslint/",
925
+ "ts/"
926
+ ),
927
+ ...renameRules(
928
+ pluginTs.configs.recommended.rules,
929
+ "@typescript-eslint/",
930
+ "ts/"
931
+ ),
932
+ "import/named": "off",
933
+ // TS
934
+ "ts/comma-dangle": "off",
935
+ "ts/brace-style": "off",
936
+ "ts/comma-spacing": "off",
937
+ "ts/func-call-spacing": "off",
938
+ "ts/indent": "off",
939
+ "ts/keyword-spacing": "off",
940
+ "ts/member-delimiter-style": "off",
941
+ "ts/no-extra-parens": "off",
942
+ "ts/no-extra-semi": "off",
943
+ "ts/quotes": "off",
944
+ "ts/semi": "off",
945
+ "ts/space-before-function-paren": "off",
946
+ "ts/type-annotation-spacing": "off",
947
+ "ts/ban-ts-comment": [
948
+ "error",
949
+ {
950
+ minimumDescriptionLength: 0
951
+ }
952
+ ],
953
+ "ts/ban-types": [
954
+ "error",
955
+ {
956
+ extendDefaults: false,
957
+ types: {
958
+ String: {
959
+ message: "Use `string` instead.",
960
+ fixWith: "string"
961
+ },
962
+ Number: {
963
+ message: "Use `number` instead.",
964
+ fixWith: "number"
965
+ },
966
+ Boolean: {
967
+ message: "Use `boolean` instead.",
968
+ fixWith: "boolean"
969
+ },
970
+ Symbol: {
971
+ message: "Use `symbol` instead.",
972
+ fixWith: "symbol"
973
+ },
974
+ BigInt: {
975
+ message: "Use `bigint` instead.",
976
+ fixWith: "bigint"
977
+ },
978
+ Object: {
979
+ message: "The `Object` type is mostly the same as `unknown`. You probably want `Record<PropertyKey, unknown>` instead. See https://github.com/typescript-eslint/typescript-eslint/pull/848",
980
+ fixWith: "Record<PropertyKey, unknown>"
981
+ },
982
+ object: {
983
+ message: "The `object` type is hard to use. Use `Record<PropertyKey, unknown>` instead. See: https://github.com/typescript-eslint/typescript-eslint/pull/848",
984
+ fixWith: "Record<PropertyKey, unknown>"
985
+ },
986
+ Function: {
987
+ message: "Use `(...args: any[]) => any` instead.",
988
+ fixWith: "(...args: any[]) => any"
989
+ }
951
990
  }
952
991
  }
992
+ ],
993
+ "ts/consistent-type-imports": [
994
+ "error",
995
+ { prefer: "type-imports", disallowTypeAnnotations: false }
996
+ ],
997
+ "ts/consistent-type-definitions": ["error", "interface"],
998
+ "ts/consistent-indexed-object-style": ["error", "record"],
999
+ "ts/prefer-ts-expect-error": "error",
1000
+ "ts/no-require-imports": "error",
1001
+ "ts/method-signature-style": ["error", "property"],
1002
+ // Override JS
1003
+ "no-useless-constructor": "off",
1004
+ "no-invalid-this": "off",
1005
+ "ts/no-invalid-this": "error",
1006
+ "no-redeclare": "off",
1007
+ "ts/no-redeclare": "error",
1008
+ "no-use-before-define": "off",
1009
+ "ts/no-use-before-define": [
1010
+ "error",
1011
+ { functions: false, classes: false, variables: true }
1012
+ ],
1013
+ "object-curly-spacing": "off",
1014
+ "space-before-blocks": "off",
1015
+ "ts/space-before-blocks": "off",
1016
+ "space-before-function-paren": "off",
1017
+ "no-dupe-class-members": "off",
1018
+ "ts/no-dupe-class-members": "error",
1019
+ "no-loss-of-precision": "off",
1020
+ "ts/no-loss-of-precision": "error",
1021
+ "lines-between-class-members": "off",
1022
+ "ts/lines-between-class-members": [
1023
+ "error",
1024
+ "always",
1025
+ { exceptAfterSingleLine: true }
1026
+ ],
1027
+ // so1ve
1028
+ "so1ve/no-inline-type-import": "error",
1029
+ // off
1030
+ "ts/camelcase": "off",
1031
+ "ts/explicit-function-return-type": "off",
1032
+ "ts/explicit-member-accessibility": "off",
1033
+ "ts/no-explicit-any": "off",
1034
+ "ts/no-parameter-properties": "off",
1035
+ "ts/no-empty-interface": "off",
1036
+ "ts/ban-ts-ignore": "off",
1037
+ "ts/no-empty-function": "off",
1038
+ "ts/no-non-null-assertion": "off",
1039
+ "ts/explicit-module-boundary-types": "off",
1040
+ "ts/triple-slash-reference": "off",
1041
+ "ts/prefer-for-of": "error",
1042
+ "ts/no-duplicate-enum-values": "error",
1043
+ "ts/no-non-null-asserted-nullish-coalescing": "error",
1044
+ // handled by unused-imports/no-unused-imports
1045
+ "ts/no-unused-vars": "off",
1046
+ ...typeAwareRules,
1047
+ ...overrides
1048
+ }
1049
+ },
1050
+ {
1051
+ files: [GLOB_MARKDOWN_CODE],
1052
+ languageOptions: {
1053
+ parser: parserTs,
1054
+ parserOptions: {
1055
+ sourceType: "module"
953
1056
  }
954
- ],
955
- "ts/consistent-type-imports": [
956
- "error",
957
- { prefer: "type-imports", disallowTypeAnnotations: false }
958
- ],
959
- "ts/consistent-type-definitions": ["error", "interface"],
960
- "ts/consistent-indexed-object-style": ["error", "record"],
961
- "ts/prefer-ts-expect-error": "error",
962
- "ts/no-require-imports": "error",
963
- "ts/method-signature-style": ["error", "property"],
964
- // Override JS
965
- "no-useless-constructor": "off",
966
- "no-invalid-this": "off",
967
- "ts/no-invalid-this": "error",
968
- "no-redeclare": "off",
969
- "ts/no-redeclare": "error",
970
- "no-use-before-define": "off",
971
- "ts/no-use-before-define": [
972
- "error",
973
- { functions: false, classes: false, variables: true }
974
- ],
975
- "object-curly-spacing": "off",
976
- "space-before-blocks": "off",
977
- "ts/space-before-blocks": "off",
978
- "space-before-function-paren": "off",
979
- "no-dupe-class-members": "off",
980
- "ts/no-dupe-class-members": "error",
981
- "no-loss-of-precision": "off",
982
- "ts/no-loss-of-precision": "error",
983
- "lines-between-class-members": "off",
984
- "ts/lines-between-class-members": [
985
- "error",
986
- "always",
987
- { exceptAfterSingleLine: true }
988
- ],
989
- // so1ve
990
- "so1ve/no-inline-type-import": "error",
991
- // off
992
- "ts/camelcase": "off",
993
- "ts/explicit-function-return-type": "off",
994
- "ts/explicit-member-accessibility": "off",
995
- "ts/no-explicit-any": "off",
996
- "ts/no-parameter-properties": "off",
997
- "ts/no-empty-interface": "off",
998
- "ts/ban-ts-ignore": "off",
999
- "ts/no-empty-function": "off",
1000
- "ts/no-non-null-assertion": "off",
1001
- "ts/explicit-module-boundary-types": "off",
1002
- "ts/triple-slash-reference": "off",
1003
- "ts/prefer-for-of": "error",
1004
- "ts/no-duplicate-enum-values": "error",
1005
- "ts/no-non-null-asserted-nullish-coalescing": "error",
1006
- // handled by unused-imports/no-unused-imports
1007
- "ts/no-unused-vars": "off",
1008
- ...overrides
1009
- }
1010
- },
1011
- {
1012
- files: ["**/*.d.ts"],
1013
- rules: {
1014
- "eslint-comments/no-unlimited-disable": "off",
1015
- "import/no-duplicates": "off",
1016
- "unused-imports/no-unused-vars": "off"
1017
- }
1018
- },
1019
- {
1020
- files: ["**/*.js", "**/*.cjs"],
1021
- rules: {
1022
- "ts/no-require-imports": "off",
1023
- "ts/no-var-requires": "off"
1024
- }
1025
- }
1026
- ];
1027
- const typescriptWithTypes = ({
1028
- componentExts = [],
1029
- tsconfigPath,
1030
- tsconfigRootDir = process.cwd(),
1031
- overrides = {}
1032
- }) => [
1033
- {
1034
- files: [
1035
- GLOB_TS,
1036
- GLOB_TSX,
1037
- ...componentExts.map((ext) => `**/*.${ext}`),
1038
- `!${GLOB_MARKDOWN}/*.*`
1039
- ],
1040
- plugins: {
1041
- etc: pluginEtc
1057
+ },
1058
+ rules: {
1059
+ ...Object.fromEntries(
1060
+ Object.keys(typeAwareRules).map((k) => [k, "off"])
1061
+ )
1062
+ }
1042
1063
  },
1043
- languageOptions: {
1044
- parser: parserTs,
1045
- parserOptions: {
1046
- project: [tsconfigPath],
1047
- tsconfigRootDir,
1048
- EXPERIMENTAL_useProjectService: true
1064
+ {
1065
+ files: ["**/*.d.ts"],
1066
+ rules: {
1067
+ "eslint-comments/no-unlimited-disable": "off",
1068
+ "import/no-duplicates": "off",
1069
+ "unused-imports/no-unused-vars": "off"
1049
1070
  }
1050
1071
  },
1051
- rules: {
1052
- "etc/no-assign-mutated-array": "error",
1053
- "etc/no-deprecated": "warn",
1054
- "etc/no-internal": "error",
1055
- "no-throw-literal": "off",
1056
- "ts/no-throw-literal": "error",
1057
- "no-implied-eval": "off",
1058
- "ts/no-implied-eval": "error",
1059
- "dot-notation": "off",
1060
- "ts/dot-notation": ["error", { allowKeywords: true }],
1061
- "no-void": ["error", { allowAsStatement: true }],
1062
- "ts/await-thenable": "error",
1063
- "ts/no-for-in-array": "error",
1064
- "ts/no-unnecessary-type-assertion": "error",
1065
- "ts/restrict-template-expressions": [
1066
- "error",
1067
- {
1068
- allowAny: true,
1069
- allowNumber: true,
1070
- allowBoolean: true
1071
- }
1072
- ],
1073
- "ts/array-type": ["error", { default: "array", readonly: "array" }],
1074
- "ts/consistent-generic-constructors": "error",
1075
- "ts/consistent-type-exports": "error",
1076
- "ts/consistent-type-assertions": [
1077
- "error",
1078
- { assertionStyle: "as", objectLiteralTypeAssertions: "allow" }
1079
- ],
1080
- "ts/prefer-nullish-coalescing": "error",
1081
- "ts/prefer-optional-chain": "error",
1082
- "ts/prefer-return-this-type": "error",
1083
- "ts/no-unnecessary-type-arguments": "error",
1084
- "ts/non-nullable-type-assertion-style": "error",
1085
- ...overrides
1072
+ {
1073
+ files: ["**/*.js", "**/*.cjs"],
1074
+ rules: {
1075
+ "ts/no-require-imports": "off",
1076
+ "ts/no-var-requires": "off"
1077
+ }
1086
1078
  }
1087
- }
1088
- ];
1079
+ ];
1080
+ }
1089
1081
 
1090
1082
  const unicorn = () => [
1091
1083
  {
@@ -1370,7 +1362,8 @@ function so1ve(options = {}, ...userConfigs) {
1370
1362
  solid: enableSolid = isPackageExists("solid-js"),
1371
1363
  typescript: enableTypeScript = isPackageExists("typescript"),
1372
1364
  gitignore: enableGitignore = true,
1373
- overrides = {}
1365
+ overrides = {},
1366
+ componentExts = []
1374
1367
  } = options;
1375
1368
  const configs = [];
1376
1369
  if (enableGitignore) {
@@ -1391,13 +1384,11 @@ function so1ve(options = {}, ...userConfigs) {
1391
1384
  node(),
1392
1385
  onlyError(),
1393
1386
  promise(),
1394
- // jsdoc(),
1395
1387
  sortImports(),
1396
1388
  imports(),
1397
1389
  jsdoc(),
1398
1390
  unicorn()
1399
1391
  );
1400
- const componentExts = [];
1401
1392
  if (enableVue) {
1402
1393
  componentExts.push("vue");
1403
1394
  }
@@ -1408,15 +1399,6 @@ function so1ve(options = {}, ...userConfigs) {
1408
1399
  overrides: overrides.typescript
1409
1400
  })
1410
1401
  );
1411
- if (typeof enableTypeScript !== "boolean") {
1412
- configs.push(
1413
- typescriptWithTypes({
1414
- ...enableTypeScript,
1415
- componentExts,
1416
- overrides: overrides.typescriptWithTypes
1417
- })
1418
- );
1419
- }
1420
1402
  }
1421
1403
  if ((_a = options.test) != null ? _a : true) {
1422
1404
  configs.push(
@@ -1479,4 +1461,4 @@ function so1ve(options = {}, ...userConfigs) {
1479
1461
  return merged;
1480
1462
  }
1481
1463
 
1482
- export { GLOB_ALL_SRC, GLOB_CSS, GLOB_DTS, GLOB_ESLINTRC, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_PACKAGEJSON, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_YAML, combine, comments, html, ignores, imports, javascript, jsdoc, jsonc, mdx, node, onlyError, promise, recordRulesState, recordRulesStateConfigs, renameRules, so1ve, solid, sortImports, test, toml, typescript, typescriptWithTypes, unicorn, vue, warnUnnecessaryOffRules, yaml };
1464
+ export { GLOB_ALL_SRC, GLOB_CSS, GLOB_DTS, GLOB_ESLINTRC, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_PACKAGEJSON, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_YAML, combine, comments, html, ignores, imports, javascript, jsdoc, jsonc, mdx, node, onlyError, promise, recordRulesState, recordRulesStateConfigs, renameRules, so1ve, solid, sortImports, test, toml, typescript, unicorn, vue, warnUnnecessaryOffRules, yaml };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@so1ve/eslint-config",
3
- "version": "1.0.0-alpha.3",
3
+ "version": "1.0.0-alpha.5",
4
4
  "author": "Ray <i@mk1.io> (https://github.com/so1ve/)",
5
5
  "description": "Ray's eslint config.",
6
6
  "keywords": [
@@ -71,8 +71,8 @@
71
71
  "toml-eslint-parser": "^0.6.0",
72
72
  "vue-eslint-parser": "^9.3.1",
73
73
  "yaml-eslint-parser": "^1.2.2",
74
- "@so1ve/eslint-plugin": "1.0.0-alpha.3",
75
- "@so1ve/eslint-plugin-sort-imports": "1.0.0-alpha.3"
74
+ "@so1ve/eslint-plugin": "1.0.0-alpha.5",
75
+ "@so1ve/eslint-plugin-sort-imports": "1.0.0-alpha.5"
76
76
  },
77
77
  "devDependencies": {
78
78
  "eslint": "^8.46.0"