@w5s/eslint-config 3.5.6 → 3.7.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/dist/index.js CHANGED
@@ -1,12 +1,8 @@
1
- import globals from "globals";
2
- import eslintConfig from "@eslint/js";
3
1
  import { ESLintConfig, Project, interopDefault } from "@w5s/dev";
4
2
  import prettierConfig from "@w5s/prettier-config";
5
- import fs from "node:fs";
6
- import nodePath from "node:path";
7
- import process from "node:process";
8
- import { findUp } from "find-up";
9
- import parseGitignore from "parse-gitignore";
3
+ import globals from "globals";
4
+ import eslintConfig from "@eslint/js";
5
+ import { eslintIgnores } from "@w5s/eslint-config-ignore";
10
6
  import { mergeProcessors, processorPassThrough } from "eslint-merge-processors";
11
7
  //#region src/type/StylisticConfig.ts
12
8
  const defaultConfig = {
@@ -40,6 +36,48 @@ const StylisticConfig = {
40
36
  }
41
37
  };
42
38
  //#endregion
39
+ //#region src/glob.ts
40
+ const sourceGlob$1 = `**/${Project.extensionsToGlob(Project.sourceExtensions())}`;
41
+ const esSourceGlob = `**/${Project.extensionsToGlob(Project.queryExtensions(["javascript", "javascriptreact"]))}`;
42
+ const jsonSourceGlob = `**/${Project.extensionsToGlob([
43
+ ".json",
44
+ ".json5",
45
+ ".jsonc"
46
+ ])}`;
47
+ const tsSourceGlob = `**/${Project.extensionsToGlob(Project.queryExtensions(["typescript", "typescriptreact"]))}`;
48
+ const ymlSourceGlob = `**/${Project.extensionsToGlob(Project.queryExtensions(["yaml"]))}`;
49
+ //#endregion
50
+ //#region src/config/e18e.ts
51
+ const defaultFiles$9 = [sourceGlob$1];
52
+ /**
53
+ * @see https://e18e.dev
54
+ * @param options
55
+ */
56
+ async function e18e(options = {}) {
57
+ const [e18ePlugin] = await Promise.all([interopDefault(import("@e18e/eslint-plugin"))]);
58
+ const { files = defaultFiles$9, rules = {}, stylistic = true, modernization = true, moduleReplacements = false, performanceImprovements = true } = options;
59
+ const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
60
+ return [{
61
+ name: "w5s/e18e/setup",
62
+ plugins: { e18e: e18ePlugin }
63
+ }, {
64
+ name: "w5s/e18e/rules",
65
+ files,
66
+ rules: {
67
+ ...modernization ? e18ePlugin.configs.modernization.rules : {},
68
+ ...moduleReplacements ? e18ePlugin.configs.moduleReplacements.rules : {},
69
+ ...performanceImprovements ? e18ePlugin.configs.performanceImprovements.rules : {},
70
+ "e18e/prefer-array-from-map": "off",
71
+ "e18e/prefer-array-to-reversed": "off",
72
+ "e18e/prefer-array-to-sorted": "off",
73
+ "e18e/prefer-array-to-spliced": "off",
74
+ "e18e/prefer-spread-syntax": "off",
75
+ ...stylisticEnabled ? {} : {},
76
+ ...rules
77
+ }
78
+ }];
79
+ }
80
+ //#endregion
43
81
  //#region src/rules/esRules/bestPractices.ts
44
82
  const bestPractices = () => ({
45
83
  "accessor-pairs": "off",
@@ -443,21 +481,10 @@ const esRules = () => ({
443
481
  ...overrides()
444
482
  });
445
483
  //#endregion
446
- //#region src/glob.ts
447
- const sourceGlob$1 = `**/${Project.extensionsToGlob(Project.sourceExtensions())}`;
448
- const esSourceGlob = `**/${Project.extensionsToGlob(Project.queryExtensions(["javascript", "javascriptreact"]))}`;
449
- const jsonSourceGlob = `**/${Project.extensionsToGlob([
450
- ".json",
451
- ".json5",
452
- ".jsonc"
453
- ])}`;
454
- const tsSourceGlob = `**/${Project.extensionsToGlob(Project.queryExtensions(["typescript", "typescriptreact"]))}`;
455
- const ymlSourceGlob = `**/${Project.extensionsToGlob(Project.queryExtensions(["yaml"]))}`;
456
- //#endregion
457
484
  //#region src/config/es.ts
458
- const defaultFiles$7 = [esSourceGlob];
485
+ const defaultFiles$8 = [esSourceGlob];
459
486
  async function es(options) {
460
- const { rules = {} } = options;
487
+ const { recommended = true, rules = {} } = options;
461
488
  return [{
462
489
  name: "w5s/es/setup",
463
490
  languageOptions: {
@@ -483,79 +510,31 @@ async function es(options) {
483
510
  linterOptions: { reportUnusedDisableDirectives: true }
484
511
  }, {
485
512
  name: "w5s/es/rules",
486
- files: defaultFiles$7,
513
+ files: defaultFiles$8,
487
514
  rules: {
488
- ...eslintConfig.configs.recommended.rules,
489
- ...esRules(),
515
+ ...recommended ? es["recommended"] : {},
490
516
  ...rules
491
517
  }
492
518
  }];
493
519
  }
520
+ /**
521
+ * Recommended rules
522
+ */
523
+ es["recommended"] = {
524
+ ...eslintConfig.configs.recommended.rules,
525
+ ...esRules()
526
+ };
494
527
  //#endregion
495
528
  //#region src/config/ignores.ts
496
- const getGitignore = async (cwd, prefix = "") => {
497
- const gitIgnoreFile = await findUp(nodePath.join(prefix, ".gitignore"), { cwd });
498
- if (gitIgnoreFile != null) {
499
- const { patterns } = parseGitignore.parse(await fs.promises.readFile(gitIgnoreFile));
500
- return patterns.map((pattern) => nodePath.join(prefix, pattern));
501
- }
502
- return [];
503
- };
504
529
  async function ignores(options = {}) {
505
- const cwd = process.cwd();
506
- const [ignoreRoot, ignoreAndroid, ignoreIOS] = await Promise.all([
507
- getGitignore(cwd),
508
- getGitignore(cwd, "android"),
509
- getGitignore(cwd, "ios")
510
- ]);
511
- return [{
512
- ignores: [
513
- "**/node_modules",
514
- "**/dist",
515
- "**/package-lock.json",
516
- "**/yarn.lock",
517
- "**/pnpm-lock.yaml",
518
- "**/bun.lockb",
519
- "**/.docusaurus",
520
- "**/output",
521
- "**/coverage",
522
- "**/temp",
523
- "**/.temp",
524
- "**/tmp",
525
- "**/.tmp",
526
- "**/.history",
527
- "**/.vitepress/cache",
528
- "**/.nuxt",
529
- "**/.next",
530
- "**/.svelte-kit",
531
- "**/.vercel",
532
- "**/.changeset",
533
- "**/.idea",
534
- "**/.cache",
535
- "**/.output",
536
- "**/.vite-inspect",
537
- "**/.yarn",
538
- "**/vendor",
539
- "**/vendors",
540
- "**/*.min.*",
541
- "**/*.timestamp-*.mjs",
542
- ".modules/",
543
- ".go/",
544
- ".pnpm-store/",
545
- ...ignoreRoot,
546
- ...ignoreAndroid,
547
- ...ignoreIOS,
548
- ...options.ignores ?? []
549
- ],
550
- name: "w5s/ignore"
551
- }];
530
+ return [await eslintIgnores(options)];
552
531
  }
553
532
  //#endregion
554
533
  //#region src/config/jsdoc.ts
555
- const defaultFiles$6 = [sourceGlob$1];
534
+ const defaultFiles$7 = [sourceGlob$1];
556
535
  async function jsdoc(options = {}) {
557
536
  const [jsdocPlugin] = await Promise.all([interopDefault(import("eslint-plugin-jsdoc"))]);
558
- const { files = defaultFiles$6, rules = {}, stylistic = true } = options;
537
+ const { files = defaultFiles$7, recommended = true, rules = {}, stylistic = true } = options;
559
538
  const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
560
539
  return [{
561
540
  name: "w5s/jsdoc/setup",
@@ -564,14 +543,16 @@ async function jsdoc(options = {}) {
564
543
  name: "w5s/jsdoc/rules",
565
544
  files,
566
545
  rules: {
567
- ...jsdocPlugin.configs["flat/recommended-typescript-flavor"].rules,
568
- "jsdoc/no-undefined-types": "off",
569
- "jsdoc/require-hyphen-before-param-description": ["warn", "always"],
570
- "jsdoc/require-jsdoc": "off",
571
- "jsdoc/require-param-description": "off",
572
- "jsdoc/require-param-type": "off",
573
- "jsdoc/require-returns": "off",
574
- "jsdoc/valid-types": "off",
546
+ ...recommended ? jsdocPlugin.configs["flat/recommended-typescript-flavor"].rules : {},
547
+ ...recommended ? {
548
+ "jsdoc/no-undefined-types": "off",
549
+ "jsdoc/require-hyphen-before-param-description": ["warn", "always"],
550
+ "jsdoc/require-jsdoc": "off",
551
+ "jsdoc/require-param-description": "off",
552
+ "jsdoc/require-param-type": "off",
553
+ "jsdoc/require-returns": "off",
554
+ "jsdoc/valid-types": "off"
555
+ } : {},
575
556
  ...stylisticEnabled ? {
576
557
  ...jsdocPlugin.configs["flat/stylistic-typescript"].rules,
577
558
  "jsdoc/check-alignment": "warn",
@@ -589,10 +570,10 @@ async function jsdoc(options = {}) {
589
570
  }
590
571
  //#endregion
591
572
  //#region src/config/jsonc.ts
592
- const defaultFiles$5 = [jsonSourceGlob];
573
+ const defaultFiles$6 = [jsonSourceGlob];
593
574
  async function jsonc(options = {}) {
594
575
  const [jsoncPlugin, jsoncParser] = await Promise.all([interopDefault(import("eslint-plugin-jsonc")), interopDefault(import("jsonc-eslint-parser"))]);
595
- const { files = defaultFiles$5, rules = {}, stylistic = true } = options;
576
+ const { files = defaultFiles$6, recommended = true, rules = {}, stylistic = true } = options;
596
577
  const { enabled: stylisticEnabled, indent } = StylisticConfig.from(stylistic);
597
578
  return [
598
579
  {
@@ -604,7 +585,7 @@ async function jsonc(options = {}) {
604
585
  languageOptions: { parser: jsoncParser },
605
586
  name: "w5s/jsonc/rules",
606
587
  rules: {
607
- ...jsoncPlugin.configs["flat/recommended-with-json"][0]?.rules,
588
+ ...recommended ? jsoncPlugin.configs["flat/recommended-with-json"][0]?.rules : {},
608
589
  ...stylisticEnabled ? {
609
590
  "jsonc/array-bracket-spacing": ["error", "never"],
610
591
  "jsonc/comma-dangle": ["error", "never"],
@@ -829,28 +810,38 @@ function sortPackageJson() {
829
810
  //#endregion
830
811
  //#region src/config/imports.ts
831
812
  async function imports(options = {}) {
832
- const { rules = {}, stylistic = true } = options;
813
+ const { rules = {}, recommended = true, stylistic = true } = options;
833
814
  const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
834
815
  const [importPlugin] = await Promise.all([interopDefault(import("eslint-plugin-import"))]);
835
816
  return [{
836
817
  name: "w5s/import/rules",
837
818
  plugins: { import: importPlugin },
838
819
  rules: {
839
- "import/first": "error",
840
- "import/no-duplicates": "error",
841
- "import/no-mutable-exports": "error",
842
- "import/no-named-default": "error",
843
- ...stylisticEnabled ? { "import/newline-after-import": ["error", { count: 1 }] } : {},
820
+ ...recommended ? imports["recommended"] : {},
821
+ ...stylisticEnabled ? imports["stylistic"] : {},
844
822
  ...rules
845
823
  }
846
824
  }];
847
825
  }
826
+ /**
827
+ * Recommended rules
828
+ */
829
+ imports["recommended"] = {
830
+ "import/first": "error",
831
+ "import/no-duplicates": "error",
832
+ "import/no-mutable-exports": "error",
833
+ "import/no-named-default": "error"
834
+ };
835
+ /**
836
+ * Stylistic rules
837
+ */
838
+ imports["stylistic"] = { "import/newline-after-import": ["error", { count: 1 }] };
848
839
  //#endregion
849
840
  //#region src/config/markdown.ts
850
- const defaultFiles$4 = [`**/${Project.extensionsToGlob(Project.queryExtensions(["markdown"]))}`];
841
+ const defaultFiles$5 = [`**/${Project.extensionsToGlob(Project.queryExtensions(["markdown"]))}`];
851
842
  async function markdown(options = {}) {
852
843
  const [markdownPlugin] = await Promise.all([interopDefault(import("@eslint/markdown"))]);
853
- const { language = "markdown/gfm", files = defaultFiles$4, rules = {}, stylistic = true } = options;
844
+ const { language = "markdown/gfm", files = defaultFiles$5, recommended = true, rules = {}, stylistic = true } = options;
854
845
  const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
855
846
  return [{
856
847
  name: "w5s/markdown/setup",
@@ -861,32 +852,58 @@ async function markdown(options = {}) {
861
852
  name: "w5s/markdown/rules",
862
853
  processor: mergeProcessors([markdownPlugin.processors.markdown, processorPassThrough]),
863
854
  rules: {
864
- ...markdownPlugin.configs.recommended.at(0)?.rules,
855
+ ...recommended ? markdownPlugin.configs.recommended.at(0)?.rules : {},
865
856
  ...stylisticEnabled ? {} : {},
866
857
  ...rules
867
858
  }
868
859
  }];
869
860
  }
870
861
  //#endregion
862
+ //#region src/config/next.ts
863
+ const defaultFiles$4 = [sourceGlob$1];
864
+ async function next(options = {}) {
865
+ const [nextPlugin] = await Promise.all([interopDefault(import("@next/eslint-plugin-next"))]);
866
+ const { files = defaultFiles$4, recommended = true, rules = {} } = options;
867
+ return [{
868
+ name: "w5s/next/setup",
869
+ plugins: { next: nextPlugin }
870
+ }, {
871
+ name: "w5s/next/rules",
872
+ files,
873
+ languageOptions: {
874
+ parserOptions: { ecmaFeatures: { jsx: true } },
875
+ sourceType: "module"
876
+ },
877
+ settings: { react: { version: "detect" } },
878
+ rules: {
879
+ ...recommended ? ESLintConfig.renameRules(nextPlugin.configs.recommended.rules ?? {}, { "@next/next": "next" }) : {},
880
+ ...recommended ? ESLintConfig.renameRules(nextPlugin.configs["core-web-vitals"].rules ?? {}, { "@next/next": "next" }) : {},
881
+ ...rules
882
+ }
883
+ }];
884
+ }
885
+ //#endregion
871
886
  //#region src/config/node.ts
872
887
  async function node(options = {}) {
873
888
  const [nodePlugin] = await Promise.all([interopDefault(import("eslint-plugin-n"))]);
874
- const { rules = {} } = options;
889
+ const { recommended, rules = {} } = options;
875
890
  return [{
876
891
  name: "w5s/node/setup",
877
892
  plugins: { node: nodePlugin }
878
893
  }, {
879
894
  name: "w5s/node/rules",
880
895
  rules: {
881
- "node/no-deprecated-api": "error",
882
- "node/no-exports-assign": "error",
883
- "node/no-new-require": "error",
884
- "node/no-path-concat": "error",
885
- "node/prefer-global/buffer": ["error", "never"],
886
- "node/prefer-global/console": ["error", "always"],
887
- "node/prefer-global/url": ["error", "always"],
888
- "node/prefer-global/url-search-params": ["error", "always"],
889
- "node/process-exit-as-throw": "error",
896
+ ...recommended ? {
897
+ "node/no-deprecated-api": "error",
898
+ "node/no-exports-assign": "error",
899
+ "node/no-new-require": "error",
900
+ "node/no-path-concat": "error",
901
+ "node/prefer-global/buffer": ["error", "never"],
902
+ "node/prefer-global/console": ["error", "always"],
903
+ "node/prefer-global/url": ["error", "always"],
904
+ "node/prefer-global/url-search-params": ["error", "always"],
905
+ "node/process-exit-as-throw": "error"
906
+ } : {},
890
907
  ...rules
891
908
  }
892
909
  }];
@@ -947,7 +964,7 @@ const defaultFiles$3 = [
947
964
  ];
948
965
  async function test(options = {}) {
949
966
  const [vitestPlugin] = await Promise.all([interopDefault(import("@vitest/eslint-plugin"))]);
950
- const { files = defaultFiles$3, rules = {}, stylistic = true } = options;
967
+ const { files = defaultFiles$3, recommended = true, rules = {}, stylistic = true } = options;
951
968
  const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
952
969
  return [{
953
970
  name: "w5s/test/setup",
@@ -956,7 +973,9 @@ async function test(options = {}) {
956
973
  files,
957
974
  name: "w5s/test/rules",
958
975
  rules: {
959
- ...vitestPlugin.configs.recommended.rules,
976
+ ...recommended ? ESLintConfig.renameRules(vitestPlugin.configs.recommended.rules, { vitest: "test" }) : {},
977
+ "test/valid-title": ESLintConfig.fixme(void 0),
978
+ "e18e/prefer-static-regex": "off",
960
979
  ...stylisticEnabled ? {} : {},
961
980
  ...rules
962
981
  }
@@ -1069,7 +1088,7 @@ async function ts(options = {}) {
1069
1088
  const defaultFiles$1 = [sourceGlob$1];
1070
1089
  async function unicorn(options = {}) {
1071
1090
  const [unicornPlugin] = await Promise.all([interopDefault(import("eslint-plugin-unicorn"))]);
1072
- const { files = defaultFiles$1, rules = {}, stylistic = true } = options;
1091
+ const { files = defaultFiles$1, recommended = true, rules = {}, stylistic = true } = options;
1073
1092
  const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
1074
1093
  return [
1075
1094
  {
@@ -1080,7 +1099,7 @@ async function unicorn(options = {}) {
1080
1099
  name: "w5s/unicorn/rules",
1081
1100
  files,
1082
1101
  rules: {
1083
- ...unicornPlugin.configs.recommended?.rules,
1102
+ ...recommended ? unicornPlugin.configs.recommended?.rules : {},
1084
1103
  "unicorn/consistent-destructuring": "off",
1085
1104
  "unicorn/consistent-function-scoping": "off",
1086
1105
  "unicorn/filename-case": "off",
@@ -1097,7 +1116,6 @@ async function unicorn(options = {}) {
1097
1116
  "unicorn/no-object-as-default-parameter": "off",
1098
1117
  "unicorn/no-process-exit": "off",
1099
1118
  "unicorn/no-unreadable-array-destructuring": "off",
1100
- "unicorn/no-unused-properties": "warn",
1101
1119
  "unicorn/no-useless-undefined": "off",
1102
1120
  "unicorn/prefer-add-event-listener": "off",
1103
1121
  "unicorn/prefer-default-parameters": "off",
@@ -1120,7 +1138,7 @@ async function unicorn(options = {}) {
1120
1138
  const defaultFiles = [ymlSourceGlob];
1121
1139
  async function yml(options = {}) {
1122
1140
  const [ymlPlugin] = await Promise.all([interopDefault(import("eslint-plugin-yml"))]);
1123
- const { files = defaultFiles, rules = {}, stylistic = true } = options;
1141
+ const { files = defaultFiles, recommended = true, rules = {}, stylistic = true } = options;
1124
1142
  const { enabled: stylisticEnabled, indent, quotes } = StylisticConfig.from(stylistic);
1125
1143
  return [{
1126
1144
  name: "w5s/yml/setup",
@@ -1130,10 +1148,10 @@ async function yml(options = {}) {
1130
1148
  language: "yml/yaml",
1131
1149
  name: "w5s/yml/rules",
1132
1150
  rules: {
1133
- ...ymlPlugin.configs["recommended"].reduce((acc, config) => ({
1151
+ ...recommended ? ymlPlugin.configs["recommended"].reduce((acc, config) => ({
1134
1152
  ...acc,
1135
1153
  ...config.rules
1136
- }), {}),
1154
+ }), {}) : {},
1137
1155
  ...stylisticEnabled ? {
1138
1156
  "style/spaced-comment": "off",
1139
1157
  "yml/block-mapping-question-indicator-newline": "error",
@@ -1173,40 +1191,17 @@ async function defineConfig(options = {}) {
1173
1191
  enabled: true,
1174
1192
  ...optionsOrBoolean
1175
1193
  });
1176
- const esOptions = toOption(options.es);
1177
- const importOptions = toOption(options.import);
1178
- const jsdocOptions = toOption(options.jsdoc);
1179
- const jsoncOptions = toOption(options.jsonc);
1180
- const markdownOptions = toOption(options.markdown);
1181
- const nodeOptions = toOption(options.node);
1182
- const tsOptions = toOption(options.ts);
1183
- const unicornOptions = toOption(options.unicorn);
1184
- const ymlOptions = toOption(options.yml);
1185
- const returnValue = [];
1186
- const append = (config) => {
1187
- returnValue.push(config);
1188
- };
1189
- append(es(esOptions));
1190
- append(ignores(options));
1191
- if (jsoncOptions.enabled) append(jsonc(jsoncOptions));
1192
- if (jsdocOptions.enabled) append(jsdoc(jsdocOptions));
1193
- if (stylisticOptions.enabled) append(stylistic(stylisticOptions));
1194
- if (importOptions.enabled) append(imports(importOptions));
1195
- if (markdownOptions.enabled) append(markdown(markdownOptions));
1196
- if (nodeOptions.enabled) append(node(nodeOptions));
1197
- if (tsOptions.enabled) append(ts(tsOptions));
1198
- if (ymlOptions.enabled) append(yml(ymlOptions));
1199
- if (unicornOptions.enabled) append(unicorn(unicornOptions));
1200
- return (await Promise.all(returnValue)).reduce((acc, curr) => [...acc, ...curr], []);
1194
+ const includeEnabled = (factory, input) => input.enabled ? [factory(input)] : [];
1195
+ return ESLintConfig.concat(...includeEnabled(e18e, toOption(options.e18e)), ...includeEnabled(es, toOption(options.es)), ...includeEnabled(ts, toOption(options.ts)), ...includeEnabled(ignores, toOption(options)), ...includeEnabled(jsonc, toOption(options.jsonc)), ...includeEnabled(jsdoc, toOption(options.jsdoc)), ...includeEnabled(stylistic, toOption(options.stylistic)), ...includeEnabled(imports, toOption(options.import)), ...includeEnabled(markdown, toOption(options.markdown)), ...includeEnabled(next, toOption(options.next)), ...includeEnabled(node, toOption(options.node)), ...includeEnabled(unicorn, toOption(options.unicorn)), ...includeEnabled(yml, toOption(options.yml)), ...includeEnabled(test, toOption(options.test)));
1201
1196
  }
1202
1197
  //#endregion
1203
1198
  //#region src/meta.ts
1204
1199
  const meta = Object.freeze({
1205
1200
  name: "@w5s/eslint-config",
1206
- version: "3.5.6",
1201
+ version: "3.7.0",
1207
1202
  buildNumber: 1
1208
1203
  });
1209
1204
  //#endregion
1210
- export { StylisticConfig, defineConfig as default, defineConfig, es, ignores, imports, jsdoc, jsonc, markdown, meta, node, stylistic, test, ts, unicorn, yml };
1205
+ export { StylisticConfig, defineConfig as default, defineConfig, e18e, es, ignores, imports, jsdoc, jsonc, markdown, meta, next, node, stylistic, test, ts, unicorn, yml };
1211
1206
 
1212
1207
  //# sourceMappingURL=index.js.map