@w5s/eslint-config 3.11.0 → 3.13.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,15 +1,38 @@
1
1
  import { ESLintConfig, Project, interopDefault } from "@w5s/dev";
2
2
  import prettierConfig from "@w5s/prettier-config";
3
- import globals from "globals";
4
3
  import eslintConfig from "@eslint/js";
4
+ import globals from "globals";
5
5
  import { eslintIgnores } from "@w5s/eslint-config-ignore";
6
6
  import { mergeProcessors, processorPassThrough } from "eslint-merge-processors";
7
+ //#region src/glob.ts
8
+ const sourceGlob$1 = `**/${Project.extensionsToGlob(Project.sourceExtensions())}`;
9
+ const esSourceGlob = `**/${Project.extensionsToGlob(Project.queryExtensions(["javascript", "javascriptreact"]))}`;
10
+ const jsonSourceGlob = `**/${Project.extensionsToGlob([
11
+ ".json",
12
+ ".json5",
13
+ ".jsonc"
14
+ ])}`;
15
+ const tsSourceGlob = `**/${Project.extensionsToGlob(Project.queryExtensions(["typescript", "typescriptreact"]))}`;
16
+ const ymlSourceGlob = `**/${Project.extensionsToGlob(Project.queryExtensions(["yaml"]))}`;
17
+ //#endregion
18
+ //#region src/internal/withDefaultFiles.ts
19
+ /**
20
+ * withDefaultFiles
21
+ *
22
+ * @param options The options to process.
23
+ * @param defaultFiles The default files to apply.
24
+ * @returns An array of strings representing the combined files.
25
+ */
26
+ function withDefaultFiles(options, defaultFiles) {
27
+ return typeof options === "function" ? options(defaultFiles) : [...options == null ? [] : options.flat(), ...defaultFiles];
28
+ }
29
+ //#endregion
7
30
  //#region src/type/StylisticConfig.ts
8
31
  const defaultConfig = {
9
32
  enabled: true,
10
33
  indent: prettierConfig.tabWidth ?? 2,
11
- quotes: prettierConfig.singleQuote ? "single" : "double",
12
34
  jsx: true,
35
+ quotes: prettierConfig.singleQuote ? "single" : "double",
13
36
  semi: prettierConfig.semi ?? true
14
37
  };
15
38
  /**
@@ -36,33 +59,22 @@ const StylisticConfig = {
36
59
  }
37
60
  };
38
61
  //#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
62
  //#region src/config/e18e.ts
51
- const defaultFiles$10 = [sourceGlob$1];
63
+ const defaultFiles$11 = [sourceGlob$1];
52
64
  /**
53
65
  * @see https://e18e.dev
54
66
  * @param options
55
67
  */
56
68
  async function e18e(options = {}) {
57
69
  const [e18ePlugin] = await Promise.all([interopDefault(import("@e18e/eslint-plugin"))]);
58
- const { files = defaultFiles$10, rules = {}, stylistic = true, modernization = true, moduleReplacements = false, performanceImprovements = true } = options;
70
+ const { files, modernization = true, moduleReplacements = false, performanceImprovements = true, rules = {}, stylistic = true } = options;
59
71
  const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
60
72
  return [{
61
73
  name: "w5s/e18e/setup",
62
74
  plugins: { e18e: e18ePlugin }
63
75
  }, {
76
+ files: withDefaultFiles(files, defaultFiles$11),
64
77
  name: "w5s/e18e/rules",
65
- files,
66
78
  rules: {
67
79
  ...modernization ? e18ePlugin.configs.modernization.rules : {},
68
80
  ...moduleReplacements ? e18ePlugin.configs.moduleReplacements.rules : {},
@@ -83,15 +95,15 @@ const bestPractices = () => ({
83
95
  "accessor-pairs": "off",
84
96
  "array-callback-return": ["error", { allowImplicit: true }],
85
97
  "block-scoped-var": "error",
86
- "complexity": ["off", 20],
87
98
  "class-methods-use-this": ["error", { exceptMethods: [] }],
99
+ "complexity": ["off", 20],
88
100
  "consistent-return": "error",
89
101
  "curly": ["error", "multi-line"],
90
102
  "default-case": ["error", { commentPattern: "^no default$" }],
91
103
  "default-case-last": "error",
92
104
  "default-param-last": "error",
93
- "dot-notation": ["error", { allowKeywords: true }],
94
105
  "dot-location": ["error", "property"],
106
+ "dot-notation": ["error", { allowKeywords: true }],
95
107
  "eqeqeq": [
96
108
  "error",
97
109
  "always",
@@ -121,12 +133,11 @@ const bestPractices = () => ({
121
133
  "no-fallthrough": "error",
122
134
  "no-floating-decimal": "error",
123
135
  "no-global-assign": ["error", { exceptions: [] }],
124
- "no-native-reassign": "off",
125
136
  "no-implicit-coercion": ["off", {
137
+ allow: [],
126
138
  boolean: false,
127
139
  number: true,
128
- string: true,
129
- allow: []
140
+ string: true
130
141
  }],
131
142
  "no-implicit-globals": "off",
132
143
  "no-implied-eval": "error",
@@ -139,13 +150,14 @@ const bestPractices = () => ({
139
150
  "no-lone-blocks": "error",
140
151
  "no-loop-func": "error",
141
152
  "no-magic-numbers": ["off", {
142
- ignore: [],
143
- ignoreArrayIndexes: true,
153
+ detectObjects: false,
144
154
  enforceConst: true,
145
- detectObjects: false
155
+ ignore: [],
156
+ ignoreArrayIndexes: true
146
157
  }],
147
158
  "no-multi-spaces": ["error", { ignoreEOLComments: false }],
148
159
  "no-multi-str": "error",
160
+ "no-native-reassign": "off",
149
161
  "no-new": "error",
150
162
  "no-new-func": "error",
151
163
  "no-new-wrappers": "error",
@@ -154,7 +166,6 @@ const bestPractices = () => ({
154
166
  "no-octal": "error",
155
167
  "no-octal-escape": "error",
156
168
  "no-param-reassign": ["error", {
157
- props: true,
158
169
  ignorePropertyModificationsFor: [
159
170
  "acc",
160
171
  "accumulator",
@@ -167,59 +178,60 @@ const bestPractices = () => ({
167
178
  "response",
168
179
  "$scope",
169
180
  "staticContext"
170
- ]
181
+ ],
182
+ props: true
171
183
  }],
172
184
  "no-proto": "error",
173
185
  "no-redeclare": "error",
174
186
  "no-restricted-properties": [
175
187
  "error",
176
188
  {
189
+ message: "arguments.callee is deprecated",
177
190
  object: "arguments",
178
- property: "callee",
179
- message: "arguments.callee is deprecated"
191
+ property: "callee"
180
192
  },
181
193
  {
194
+ message: "Please use Number.isFinite instead",
182
195
  object: "global",
183
- property: "isFinite",
184
- message: "Please use Number.isFinite instead"
196
+ property: "isFinite"
185
197
  },
186
198
  {
199
+ message: "Please use Number.isFinite instead",
187
200
  object: "self",
188
- property: "isFinite",
189
- message: "Please use Number.isFinite instead"
201
+ property: "isFinite"
190
202
  },
191
203
  {
204
+ message: "Please use Number.isFinite instead",
192
205
  object: "window",
193
- property: "isFinite",
194
- message: "Please use Number.isFinite instead"
206
+ property: "isFinite"
195
207
  },
196
208
  {
209
+ message: "Please use Number.isNaN instead",
197
210
  object: "global",
198
- property: "isNaN",
199
- message: "Please use Number.isNaN instead"
211
+ property: "isNaN"
200
212
  },
201
213
  {
214
+ message: "Please use Number.isNaN instead",
202
215
  object: "self",
203
- property: "isNaN",
204
- message: "Please use Number.isNaN instead"
216
+ property: "isNaN"
205
217
  },
206
218
  {
219
+ message: "Please use Number.isNaN instead",
207
220
  object: "window",
208
- property: "isNaN",
209
- message: "Please use Number.isNaN instead"
221
+ property: "isNaN"
210
222
  },
211
223
  {
212
- property: "__defineGetter__",
213
- message: "Please use Object.defineProperty instead."
224
+ message: "Please use Object.defineProperty instead.",
225
+ property: "__defineGetter__"
214
226
  },
215
227
  {
216
- property: "__defineSetter__",
217
- message: "Please use Object.defineProperty instead."
228
+ message: "Please use Object.defineProperty instead.",
229
+ property: "__defineSetter__"
218
230
  },
219
231
  {
232
+ message: "Use the exponentiation operator (**) instead.",
220
233
  object: "Math",
221
- property: "pow",
222
- message: "Use the exponentiation operator (**) instead."
234
+ property: "pow"
223
235
  }
224
236
  ],
225
237
  "no-return-assign": ["error", "always"],
@@ -232,8 +244,8 @@ const bestPractices = () => ({
232
244
  "no-unmodified-loop-condition": "off",
233
245
  "no-unused-expressions": ["error", {
234
246
  allowShortCircuit: false,
235
- allowTernary: false,
236
- allowTaggedTemplates: false
247
+ allowTaggedTemplates: false,
248
+ allowTernary: false
237
249
  }],
238
250
  "no-unused-labels": "error",
239
251
  "no-useless-call": "off",
@@ -243,17 +255,17 @@ const bestPractices = () => ({
243
255
  "no-useless-return": "error",
244
256
  "no-void": "error",
245
257
  "no-warning-comments": ["off", {
258
+ location: "start",
246
259
  terms: [
247
260
  "todo",
248
261
  "fixme",
249
262
  "xxx"
250
- ],
251
- location: "start"
263
+ ]
252
264
  }],
253
265
  "no-with": "error",
254
- "prefer-promise-reject-errors": ["error", { allowEmptyReject: true }],
255
266
  "prefer-named-capture-group": "off",
256
267
  "prefer-object-has-own": "off",
268
+ "prefer-promise-reject-errors": ["error", { allowEmptyReject: true }],
257
269
  "prefer-regex-literals": ["error", { disallowRedundantWrapping: true }],
258
270
  "radix": "error",
259
271
  "require-await": "off",
@@ -293,10 +305,10 @@ const errors = () => ({
293
305
  "all",
294
306
  {
295
307
  conditionalAssign: true,
296
- nestedBinaryExpressions: false,
297
- returnAssign: false,
308
+ enforceForArrowConditionals: false,
298
309
  ignoreJSX: "all",
299
- enforceForArrowConditionals: false
310
+ nestedBinaryExpressions: false,
311
+ returnAssign: false
300
312
  }
301
313
  ],
302
314
  "no-extra-semi": "error",
@@ -307,8 +319,9 @@ const errors = () => ({
307
319
  "no-irregular-whitespace": "error",
308
320
  "no-loss-of-precision": "error",
309
321
  "no-misleading-character-class": "error",
310
- "no-obj-calls": "error",
322
+ "no-negated-in-lhs": "off",
311
323
  "no-new-native-nonconstructor": "off",
324
+ "no-obj-calls": "error",
312
325
  "no-promise-executor-return": "error",
313
326
  "no-prototype-builtins": "error",
314
327
  "no-regex-spaces": "error",
@@ -323,7 +336,6 @@ const errors = () => ({
323
336
  "no-unsafe-optional-chaining": ["error", { disallowArithmeticOperators: true }],
324
337
  "no-unused-private-class-members": "off",
325
338
  "no-useless-backreference": "error",
326
- "no-negated-in-lhs": "off",
327
339
  "require-atomic-updates": "off",
328
340
  "use-isnan": "error",
329
341
  "valid-jsdoc": "off",
@@ -339,13 +351,13 @@ const es6 = () => ({
339
351
  ],
340
352
  "arrow-parens": ["error", "always"],
341
353
  "arrow-spacing": ["error", {
342
- before: true,
343
- after: true
354
+ after: true,
355
+ before: true
344
356
  }],
345
357
  "constructor-super": "error",
346
358
  "generator-star-spacing": ["error", {
347
- before: false,
348
- after: true
359
+ after: true,
360
+ before: false
349
361
  }],
350
362
  "no-class-assign": "error",
351
363
  "no-confusing-arrow": ["error", { allowParens: true }],
@@ -363,16 +375,16 @@ const es6 = () => ({
363
375
  "no-useless-constructor": "error",
364
376
  "no-useless-rename": ["error", {
365
377
  ignoreDestructuring: false,
366
- ignoreImport: false,
367
- ignoreExport: false
378
+ ignoreExport: false,
379
+ ignoreImport: false
368
380
  }],
369
381
  "no-var": "error",
370
382
  "object-shorthand": [
371
383
  "error",
372
384
  "always",
373
385
  {
374
- ignoreConstructors: false,
375
- avoidQuotes: true
386
+ avoidQuotes: true,
387
+ ignoreConstructors: false
376
388
  }
377
389
  ],
378
390
  "prefer-arrow-callback": ["error", {
@@ -386,13 +398,13 @@ const es6 = () => ({
386
398
  "prefer-destructuring": [
387
399
  "error",
388
400
  {
389
- VariableDeclarator: {
390
- array: false,
391
- object: true
392
- },
393
401
  AssignmentExpression: {
394
402
  array: true,
395
403
  object: false
404
+ },
405
+ VariableDeclarator: {
406
+ array: false,
407
+ object: true
396
408
  }
397
409
  },
398
410
  { enforceForRenamedProperties: false }
@@ -446,12 +458,12 @@ const variables = () => ({
446
458
  "no-restricted-globals": [
447
459
  "error",
448
460
  {
449
- name: "isFinite",
450
- message: "Use Number.isFinite instead https://github.com/airbnb/javascript#standard-library--isfinite"
461
+ message: "Use Number.isFinite instead https://github.com/airbnb/javascript#standard-library--isfinite",
462
+ name: "isFinite"
451
463
  },
452
464
  {
453
- name: "isNaN",
454
- message: "Use Number.isNaN instead https://github.com/airbnb/javascript#standard-library--isnan"
465
+ message: "Use Number.isNaN instead https://github.com/airbnb/javascript#standard-library--isnan",
466
+ name: "isNaN"
455
467
  }
456
468
  ],
457
469
  "no-shadow": "error",
@@ -460,13 +472,13 @@ const variables = () => ({
460
472
  "no-undef-init": "error",
461
473
  "no-undefined": "off",
462
474
  "no-unused-vars": ["error", {
463
- vars: "all",
464
475
  args: "after-used",
465
- ignoreRestSiblings: true
476
+ ignoreRestSiblings: true,
477
+ vars: "all"
466
478
  }],
467
479
  "no-use-before-define": ["error", {
468
- functions: true,
469
480
  classes: true,
481
+ functions: true,
470
482
  variables: true
471
483
  }]
472
484
  });
@@ -482,11 +494,10 @@ const esRules = () => ({
482
494
  });
483
495
  //#endregion
484
496
  //#region src/config/es.ts
485
- const defaultFiles$9 = [esSourceGlob];
497
+ const defaultFiles$10 = [esSourceGlob];
486
498
  async function es(options) {
487
499
  const { recommended = true, rules = {} } = options;
488
500
  return [{
489
- name: "w5s/es/setup",
490
501
  languageOptions: {
491
502
  ecmaVersion: Project.ecmaVersion(),
492
503
  globals: {
@@ -507,10 +518,11 @@ async function es(options) {
507
518
  },
508
519
  sourceType: "module"
509
520
  },
510
- linterOptions: { reportUnusedDisableDirectives: true }
521
+ linterOptions: { reportUnusedDisableDirectives: true },
522
+ name: "w5s/es/setup"
511
523
  }, {
524
+ files: defaultFiles$10,
512
525
  name: "w5s/es/rules",
513
- files: defaultFiles$9,
514
526
  rules: {
515
527
  ...recommended ? es["recommended"] : {},
516
528
  ...rules
@@ -530,18 +542,49 @@ async function ignores(options = {}) {
530
542
  return [await eslintIgnores(options)];
531
543
  }
532
544
  //#endregion
545
+ //#region src/config/imports.ts
546
+ async function imports(options = {}) {
547
+ const { recommended = true, rules = {}, stylistic = true } = options;
548
+ const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
549
+ const [importPlugin] = await Promise.all([interopDefault(import("eslint-plugin-import"))]);
550
+ return [{
551
+ name: "w5s/import/setup",
552
+ plugins: { import: importPlugin }
553
+ }, {
554
+ name: "w5s/import/rules",
555
+ rules: {
556
+ ...recommended ? imports["recommended"] : {},
557
+ ...stylisticEnabled ? imports["stylistic"] : {},
558
+ ...rules
559
+ }
560
+ }];
561
+ }
562
+ /**
563
+ * Recommended rules
564
+ */
565
+ imports["recommended"] = {
566
+ "import/first": "error",
567
+ "import/no-duplicates": "error",
568
+ "import/no-mutable-exports": "error",
569
+ "import/no-named-default": "error"
570
+ };
571
+ /**
572
+ * Stylistic rules
573
+ */
574
+ imports["stylistic"] = { "import/newline-after-import": ["error", { count: 1 }] };
575
+ //#endregion
533
576
  //#region src/config/jsdoc.ts
534
- const defaultFiles$8 = [sourceGlob$1];
577
+ const defaultFiles$9 = [sourceGlob$1];
535
578
  async function jsdoc(options = {}) {
536
579
  const [jsdocPlugin] = await Promise.all([interopDefault(import("eslint-plugin-jsdoc"))]);
537
- const { files = defaultFiles$8, recommended = true, rules = {}, stylistic = true } = options;
580
+ const { files, recommended = true, rules = {}, stylistic = true } = options;
538
581
  const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
539
582
  return [{
540
583
  name: "w5s/jsdoc/setup",
541
584
  plugins: { jsdoc: jsdocPlugin }
542
585
  }, {
586
+ files: withDefaultFiles(files, defaultFiles$9),
543
587
  name: "w5s/jsdoc/rules",
544
- files,
545
588
  rules: {
546
589
  ...recommended ? jsdocPlugin.configs["flat/recommended-typescript-flavor"].rules : {},
547
590
  ...recommended ? {
@@ -570,10 +613,10 @@ async function jsdoc(options = {}) {
570
613
  }
571
614
  //#endregion
572
615
  //#region src/config/jsonc.ts
573
- const defaultFiles$7 = [jsonSourceGlob];
616
+ const defaultFiles$8 = [jsonSourceGlob];
574
617
  async function jsonc(options = {}) {
575
618
  const [jsoncPlugin, jsoncParser] = await Promise.all([interopDefault(import("eslint-plugin-jsonc")), interopDefault(import("jsonc-eslint-parser"))]);
576
- const { files = defaultFiles$7, recommended = true, rules = {}, stylistic = true } = options;
619
+ const { files, recommended = true, rules = {}, stylistic = true } = options;
577
620
  const { enabled: stylisticEnabled, indent } = StylisticConfig.from(stylistic);
578
621
  return [
579
622
  {
@@ -581,7 +624,7 @@ async function jsonc(options = {}) {
581
624
  plugins: { jsonc: jsoncPlugin }
582
625
  },
583
626
  {
584
- files,
627
+ files: withDefaultFiles(files, defaultFiles$8),
585
628
  languageOptions: { parser: jsoncParser },
586
629
  name: "w5s/jsonc/rules",
587
630
  rules: {
@@ -611,31 +654,6 @@ async function jsonc(options = {}) {
611
654
  stylisticEnabled ? sortTsconfigJson() : {}
612
655
  ];
613
656
  }
614
- function sortTsconfigJson() {
615
- return {
616
- files: ["**/tsconfig*.json"],
617
- rules: { "jsonc/sort-keys": [
618
- "error",
619
- {
620
- order: [
621
- "$schema",
622
- "display",
623
- "extends",
624
- "compilerOptions",
625
- "include",
626
- "exclude",
627
- "files",
628
- "references"
629
- ],
630
- pathPattern: "^$"
631
- },
632
- {
633
- order: { type: "asc" },
634
- pathPattern: ".*"
635
- }
636
- ] }
637
- };
638
- }
639
657
  function sortPackageJson() {
640
658
  return {
641
659
  files: ["**/package.json"],
@@ -807,48 +825,52 @@ function sortPackageJson() {
807
825
  ] }
808
826
  };
809
827
  }
810
- //#endregion
811
- //#region src/config/imports.ts
812
- async function imports(options = {}) {
813
- const { rules = {}, recommended = true, stylistic = true } = options;
814
- const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
815
- const [importPlugin] = await Promise.all([interopDefault(import("eslint-plugin-import"))]);
816
- return [{
817
- name: "w5s/import/rules",
818
- plugins: { import: importPlugin },
819
- rules: {
820
- ...recommended ? imports["recommended"] : {},
821
- ...stylisticEnabled ? imports["stylistic"] : {},
822
- ...rules
823
- }
824
- }];
828
+ function sortTsconfigJson() {
829
+ return {
830
+ files: ["**/tsconfig*.json"],
831
+ rules: { "jsonc/sort-keys": [
832
+ "error",
833
+ {
834
+ order: [
835
+ "$schema",
836
+ "display",
837
+ "extends",
838
+ "compilerOptions",
839
+ "include",
840
+ "exclude",
841
+ "files",
842
+ "references"
843
+ ],
844
+ pathPattern: "^$"
845
+ },
846
+ {
847
+ order: { type: "asc" },
848
+ pathPattern: ".*"
849
+ }
850
+ ] }
851
+ };
825
852
  }
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 }] };
839
853
  //#endregion
840
854
  //#region src/config/markdown.ts
841
- const defaultFiles$6 = [`**/${Project.extensionsToGlob(Project.queryExtensions(["markdown"]))}`];
855
+ const defaultFiles$7 = [
856
+ `**/${Project.extensionsToGlob(Project.queryExtensions(["markdown"]))}`,
857
+ "**/CHANGELOG.md",
858
+ "**/CODE_OF_CONDUCT.md"
859
+ ];
842
860
  async function markdown(options = {}) {
843
861
  const [markdownPlugin] = await Promise.all([interopDefault(import("@eslint/markdown"))]);
844
- const { language = "markdown/gfm", files = defaultFiles$6, recommended = true, rules = {}, stylistic = true } = options;
862
+ const { files, language = "markdown/gfm", languageOptions, recommended = true, rules = {}, stylistic = true } = options;
845
863
  const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
846
864
  return [{
847
865
  name: "w5s/markdown/setup",
848
866
  plugins: { markdown: markdownPlugin }
849
867
  }, {
850
- files,
868
+ files: withDefaultFiles(files, defaultFiles$7),
851
869
  language,
870
+ languageOptions: {
871
+ frontmatter: "yaml",
872
+ ...languageOptions
873
+ },
852
874
  name: "w5s/markdown/rules",
853
875
  processor: mergeProcessors([markdownPlugin.processors.markdown, processorPassThrough]),
854
876
  rules: {
@@ -860,26 +882,26 @@ async function markdown(options = {}) {
860
882
  }
861
883
  //#endregion
862
884
  //#region src/config/next.ts
863
- const defaultFiles$5 = [sourceGlob$1];
885
+ const defaultFiles$6 = [sourceGlob$1];
864
886
  async function next(options = {}) {
865
887
  const [nextPlugin] = await Promise.all([interopDefault(import("@next/eslint-plugin-next"))]);
866
- const { files = defaultFiles$5, recommended = true, rules = {} } = options;
888
+ const { files, recommended = true, rules = {} } = options;
867
889
  return [{
868
890
  name: "w5s/next/setup",
869
891
  plugins: { next: nextPlugin }
870
892
  }, {
871
- name: "w5s/next/rules",
872
- files,
893
+ files: withDefaultFiles(files, defaultFiles$6),
873
894
  languageOptions: {
874
895
  parserOptions: { ecmaFeatures: { jsx: true } },
875
896
  sourceType: "module"
876
897
  },
877
- settings: { react: { version: "detect" } },
898
+ name: "w5s/next/rules",
878
899
  rules: {
879
900
  ...recommended ? ESLintConfig.renameRules(nextPlugin.configs.recommended.rules ?? {}, { "@next/next": "next" }) : {},
880
901
  ...recommended ? ESLintConfig.renameRules(nextPlugin.configs["core-web-vitals"].rules ?? {}, { "@next/next": "next" }) : {},
881
902
  ...rules
882
- }
903
+ },
904
+ settings: { react: { version: "detect" } }
883
905
  }];
884
906
  }
885
907
  //#endregion
@@ -909,21 +931,41 @@ async function node(options = {}) {
909
931
  }];
910
932
  }
911
933
  //#endregion
934
+ //#region src/config/perfectionist.ts
935
+ const defaultFiles$5 = [sourceGlob$1];
936
+ async function perfectionist(options = {}) {
937
+ const [perfectionistPlugin] = await Promise.all([interopDefault(import("eslint-plugin-perfectionist"))]);
938
+ const { files, recommended = true, rules = {}, stylistic = true } = options;
939
+ const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
940
+ return [{
941
+ name: "w5s/perfectionist/setup",
942
+ plugins: { perfectionist: perfectionistPlugin }
943
+ }, {
944
+ files: withDefaultFiles(files, defaultFiles$5),
945
+ name: "w5s/perfectionist/rules",
946
+ rules: {
947
+ ...recommended ? perfectionistPlugin.configs["recommended-natural"].rules : {},
948
+ ...stylisticEnabled ? {} : {},
949
+ ...rules
950
+ }
951
+ }];
952
+ }
953
+ //#endregion
912
954
  //#region src/config/react.ts
913
955
  const defaultFiles$4 = [sourceGlob$1];
914
956
  async function react(options = {}) {
915
957
  const [reactPlugin] = await Promise.all([interopDefault(import("@eslint-react/eslint-plugin"))]);
916
- const { files = defaultFiles$4, recommended, rules = {} } = options;
958
+ const { files, recommended, rules = {} } = options;
917
959
  return [{
918
960
  name: "w5s/react/setup",
919
961
  plugins: { react: reactPlugin }
920
962
  }, {
921
- name: "w5s/react/rules",
922
- files,
963
+ files: withDefaultFiles(files, defaultFiles$4),
923
964
  languageOptions: {
924
965
  parserOptions: { ecmaFeatures: { jsx: true } },
925
966
  sourceType: "module"
926
967
  },
968
+ name: "w5s/react/rules",
927
969
  rules: {
928
970
  ...recommended ? reactPlugin.configs["recommended"].rules : {},
929
971
  ...rules
@@ -959,16 +1001,16 @@ async function stylistic(options = {}) {
959
1001
  { overrides: {
960
1002
  ":": "before",
961
1003
  "?": "before",
962
- "|>": "before",
963
- "|": "before"
1004
+ "|": "before",
1005
+ "|>": "before"
964
1006
  } }
965
1007
  ],
966
1008
  "style/quotes": [
967
1009
  "error",
968
1010
  quotes ?? StylisticConfig.default.quotes,
969
1011
  {
970
- avoidEscape: true,
971
- allowTemplateLiterals: "always"
1012
+ allowTemplateLiterals: "always",
1013
+ avoidEscape: true
972
1014
  }
973
1015
  ]
974
1016
  } : {},
@@ -986,18 +1028,18 @@ const defaultFiles$3 = [
986
1028
  ];
987
1029
  async function test(options = {}) {
988
1030
  const [vitestPlugin] = await Promise.all([interopDefault(import("@vitest/eslint-plugin"))]);
989
- const { files = defaultFiles$3, recommended = true, rules = {}, stylistic = true } = options;
1031
+ const { files, recommended = true, rules = {}, stylistic = true } = options;
990
1032
  const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
991
1033
  return [{
992
1034
  name: "w5s/test/setup",
993
1035
  plugins: { test: vitestPlugin }
994
1036
  }, {
995
- files,
1037
+ files: withDefaultFiles(files, defaultFiles$3),
996
1038
  name: "w5s/test/rules",
997
1039
  rules: {
998
1040
  ...recommended ? ESLintConfig.renameRules(vitestPlugin.configs.recommended.rules, { vitest: "test" }) : {},
999
- "test/valid-title": ESLintConfig.fixme(void 0),
1000
1041
  "e18e/prefer-static-regex": "off",
1042
+ "test/valid-title": ESLintConfig.fixme(void 0),
1001
1043
  ...stylisticEnabled ? {} : {},
1002
1044
  ...rules
1003
1045
  }
@@ -1076,7 +1118,7 @@ async function ts(options = {}) {
1076
1118
  const tsRecommendedRules = tsPlugin.configs["eslint-recommended"].overrides[0].rules;
1077
1119
  const tsStrictRules = tsPlugin.configs["strict"].rules;
1078
1120
  const tsTypeCheckedRules = tsPlugin.configs["recommended-type-checked-only"].rules;
1079
- const { files = defaultFiles$2, rules = {}, stylistic = true, typeChecked = false } = options;
1121
+ const { files, rules = {}, stylistic = true, typeChecked = false } = options;
1080
1122
  const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
1081
1123
  return [
1082
1124
  {
@@ -1084,7 +1126,7 @@ async function ts(options = {}) {
1084
1126
  plugins: { ts: tsPlugin }
1085
1127
  },
1086
1128
  {
1087
- files,
1129
+ files: withDefaultFiles(files, defaultFiles$2),
1088
1130
  languageOptions: {
1089
1131
  parser: tsParser,
1090
1132
  parserOptions: { sourceType: "module" }
@@ -1110,7 +1152,7 @@ async function ts(options = {}) {
1110
1152
  const defaultFiles$1 = [sourceGlob$1];
1111
1153
  async function unicorn(options = {}) {
1112
1154
  const [unicornPlugin] = await Promise.all([interopDefault(import("eslint-plugin-unicorn"))]);
1113
- const { files = defaultFiles$1, recommended = true, rules = {}, stylistic = true } = options;
1155
+ const { files, recommended = true, rules = {}, stylistic = true } = options;
1114
1156
  const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
1115
1157
  return [
1116
1158
  {
@@ -1118,8 +1160,8 @@ async function unicorn(options = {}) {
1118
1160
  plugins: { unicorn: unicornPlugin }
1119
1161
  },
1120
1162
  {
1163
+ files: withDefaultFiles(files, defaultFiles$1),
1121
1164
  name: "w5s/unicorn/rules",
1122
- files,
1123
1165
  rules: {
1124
1166
  ...recommended && unicornPlugin.configs["unopinionated"].rules,
1125
1167
  "unicorn/new-for-builtins": "off",
@@ -1138,8 +1180,8 @@ async function unicorn(options = {}) {
1138
1180
  }
1139
1181
  },
1140
1182
  {
1141
- name: "w5s/unicorn/overrides",
1142
1183
  files: ["**/*.config.cjs", "**/*.config.js"],
1184
+ name: "w5s/unicorn/overrides",
1143
1185
  rules: { "unicorn/prefer-module": "off" }
1144
1186
  }
1145
1187
  ];
@@ -1149,13 +1191,13 @@ async function unicorn(options = {}) {
1149
1191
  const defaultFiles = [ymlSourceGlob];
1150
1192
  async function yml(options = {}) {
1151
1193
  const [ymlPlugin] = await Promise.all([interopDefault(import("eslint-plugin-yml"))]);
1152
- const { files = defaultFiles, recommended = true, rules = {}, stylistic = true } = options;
1194
+ const { files, recommended = true, rules = {}, stylistic = true } = options;
1153
1195
  const { enabled: stylisticEnabled, indent, quotes } = StylisticConfig.from(stylistic);
1154
1196
  return [{
1155
1197
  name: "w5s/yml/setup",
1156
1198
  plugins: { yml: ymlPlugin }
1157
1199
  }, {
1158
- files,
1200
+ files: withDefaultFiles(files, defaultFiles),
1159
1201
  language: "yml/yaml",
1160
1202
  name: "w5s/yml/rules",
1161
1203
  rules: {
@@ -1190,29 +1232,30 @@ async function yml(options = {}) {
1190
1232
  //#endregion
1191
1233
  //#region src/defineConfig.ts
1192
1234
  async function defineConfig(options = {}) {
1193
- const stylisticOptions = typeof options.stylistic === "boolean" ? { enabled: options.stylistic } : {
1235
+ const { plugins = {}, rules } = options;
1236
+ const stylisticOptions = typeof plugins.stylistic === "boolean" ? { enabled: plugins.stylistic } : {
1194
1237
  enabled: true,
1195
- ...options.stylistic
1238
+ ...plugins.stylistic
1196
1239
  };
1197
1240
  const withDefaultStylistic = (_options) => ({
1198
1241
  stylistic: stylisticOptions,
1199
1242
  ..._options
1200
1243
  });
1201
- const toOption = (optionsOrBoolean) => withDefaultStylistic(typeof optionsOrBoolean === "boolean" ? { enabled: optionsOrBoolean } : {
1202
- enabled: true,
1244
+ const toOption = (optionsOrBoolean, defaultEnabled = true) => withDefaultStylistic(typeof optionsOrBoolean === "boolean" ? { enabled: optionsOrBoolean } : optionsOrBoolean === void 0 ? { enabled: defaultEnabled } : {
1245
+ enabled: defaultEnabled,
1203
1246
  ...optionsOrBoolean
1204
1247
  });
1205
1248
  const includeEnabled = (factory, input) => input.enabled ? [factory(input)] : [];
1206
- 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(react, toOption(options.react)), ...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)));
1249
+ return ESLintConfig.concat(...includeEnabled(e18e, toOption(plugins.e18e)), ...includeEnabled(es, toOption(plugins.es)), ...includeEnabled(ts, toOption(plugins.ts)), ...includeEnabled(ignores, toOption(options)), ...includeEnabled(jsonc, toOption(plugins.jsonc)), ...includeEnabled(jsdoc, toOption(plugins.jsdoc)), ...includeEnabled(react, toOption(plugins.react)), ...includeEnabled(stylistic, toOption(plugins.stylistic)), ...includeEnabled(imports, toOption(plugins.import)), ...includeEnabled(markdown, toOption(plugins.markdown)), ...includeEnabled(next, toOption(plugins.next, false)), ...includeEnabled(node, toOption(plugins.node)), ...includeEnabled(perfectionist, toOption(plugins.perfectionist)), ...includeEnabled(unicorn, toOption(plugins.unicorn)), ...includeEnabled(yml, toOption(plugins.yml)), ...includeEnabled(test, toOption(plugins.test)), ...rules ? [{ rules }] : []);
1207
1250
  }
1208
1251
  //#endregion
1209
1252
  //#region src/meta.ts
1210
1253
  const meta = Object.freeze({
1254
+ buildNumber: 1,
1211
1255
  name: "@w5s/eslint-config",
1212
- version: "3.11.0",
1213
- buildNumber: 1
1256
+ version: "3.13.0"
1214
1257
  });
1215
1258
  //#endregion
1216
- export { StylisticConfig, defineConfig as default, defineConfig, e18e, es, ignores, imports, jsdoc, jsonc, markdown, meta, next, node, react, stylistic, test, ts, unicorn, yml };
1259
+ export { StylisticConfig, defineConfig as default, defineConfig, e18e, es, ignores, imports, jsdoc, jsonc, markdown, meta, next, node, perfectionist, react, stylistic, test, ts, unicorn, yml };
1217
1260
 
1218
1261
  //# sourceMappingURL=index.js.map