@favorodera/eslint-config 0.1.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -6
- package/dist/index.d.mts +287 -182
- package/dist/index.mjs +447 -373
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FlatConfigComposer
|
|
1
|
+
import { FlatConfigComposer } from "eslint-flat-config-utils";
|
|
2
2
|
import { defu } from "defu";
|
|
3
3
|
import globals from "globals";
|
|
4
4
|
import { mergeProcessors, processorPassThrough } from "eslint-merge-processors";
|
|
@@ -126,57 +126,70 @@ function resolveOptions(value, defaults) {
|
|
|
126
126
|
if (!value) return false;
|
|
127
127
|
return defu(value === true ? {} : value, defaults);
|
|
128
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Creates a new object that omits the specified keys from the target object.
|
|
131
|
+
* @template TTarget The type of the target object.
|
|
132
|
+
* @template TTargetKeys The type of the keys to omit from the target object.
|
|
133
|
+
* @param target The target object from which to omit the specified keys.
|
|
134
|
+
* @param keys An array of keys to omit from the target object.
|
|
135
|
+
* @returns A new object that contains all properties of the target object except for the specified keys.
|
|
136
|
+
*/
|
|
137
|
+
function omit(target, keys) {
|
|
138
|
+
const targetClone = { ...target };
|
|
139
|
+
for (const key of keys) Reflect.deleteProperty(targetClone, key);
|
|
140
|
+
return targetClone;
|
|
141
|
+
}
|
|
129
142
|
//#endregion
|
|
130
143
|
//#region src/configs/imports.ts
|
|
131
|
-
const importsDefaults = { files: [
|
|
132
|
-
jsGlob,
|
|
133
|
-
tsGlob,
|
|
134
|
-
vueGlob
|
|
135
|
-
] };
|
|
136
144
|
/**
|
|
137
145
|
* Constructs the flat config items for imports linting, providing plugin setup and
|
|
138
146
|
* specific rules to enforce consistent import ordering and quality.
|
|
139
|
-
* @param options Configuration options for imports linting.
|
|
140
147
|
* @returns Promise resolving to imports ESLint config items.
|
|
141
148
|
*/
|
|
142
|
-
async function imports(
|
|
143
|
-
const resolved = defu(options, importsDefaults);
|
|
149
|
+
async function imports() {
|
|
144
150
|
const importPlugin = await importModule(import("eslint-plugin-import-lite"));
|
|
145
|
-
const
|
|
151
|
+
const files = [
|
|
152
|
+
jsGlob,
|
|
153
|
+
tsGlob,
|
|
154
|
+
vueGlob
|
|
155
|
+
];
|
|
156
|
+
const recommendedConfig = importPlugin.configs.recommended;
|
|
157
|
+
const { rules = {} } = recommendedConfig;
|
|
146
158
|
return [{
|
|
147
|
-
|
|
148
|
-
|
|
159
|
+
...omit(recommendedConfig, [
|
|
160
|
+
"rules",
|
|
161
|
+
"files",
|
|
162
|
+
"name"
|
|
163
|
+
]),
|
|
164
|
+
name: "favorodera/imports/setup"
|
|
149
165
|
}, {
|
|
150
|
-
files
|
|
166
|
+
files,
|
|
151
167
|
name: "favorodera/imports/rules",
|
|
152
168
|
rules: {
|
|
153
|
-
...
|
|
169
|
+
...rules,
|
|
154
170
|
"import/consistent-type-specifier-style": ["error", "prefer-top-level"],
|
|
155
171
|
"import/first": "error",
|
|
156
172
|
"import/newline-after-import": ["error", { count: 1 }],
|
|
157
173
|
"import/no-duplicates": ["error", { "prefer-inline": true }],
|
|
158
174
|
"import/no-mutable-exports": "error",
|
|
159
|
-
"import/no-named-default": "error"
|
|
160
|
-
...resolved.overrides
|
|
175
|
+
"import/no-named-default": "error"
|
|
161
176
|
}
|
|
162
177
|
}];
|
|
163
178
|
}
|
|
164
179
|
//#endregion
|
|
165
180
|
//#region src/configs/javascript.ts
|
|
166
|
-
const javascriptDefaults = { files: [
|
|
167
|
-
jsGlob,
|
|
168
|
-
tsGlob,
|
|
169
|
-
vueGlob
|
|
170
|
-
] };
|
|
171
181
|
/**
|
|
172
182
|
* Constructs the flat config items for core JavaScript linting, setting up the required
|
|
173
183
|
* language options, globals, and recommended baseline rules.
|
|
174
|
-
* @param options Javascript configuration options.
|
|
175
184
|
* @returns Promise resolving to javascript ESLint config items.
|
|
176
185
|
*/
|
|
177
|
-
async function javascript(
|
|
178
|
-
const
|
|
179
|
-
const
|
|
186
|
+
async function javascript() {
|
|
187
|
+
const jsPlugin = await importModule(import("@eslint/js"));
|
|
188
|
+
const files = [
|
|
189
|
+
jsGlob,
|
|
190
|
+
tsGlob,
|
|
191
|
+
vueGlob
|
|
192
|
+
];
|
|
180
193
|
return [{
|
|
181
194
|
languageOptions: {
|
|
182
195
|
ecmaVersion: "latest",
|
|
@@ -193,15 +206,16 @@ async function javascript(options) {
|
|
|
193
206
|
linterOptions: { reportUnusedDisableDirectives: true },
|
|
194
207
|
name: "favorodera/javascript/setup"
|
|
195
208
|
}, {
|
|
196
|
-
files
|
|
209
|
+
files,
|
|
197
210
|
name: "favorodera/javascript/rules",
|
|
198
211
|
rules: {
|
|
199
|
-
...
|
|
200
|
-
"array-callback-return": "error",
|
|
212
|
+
...jsPlugin.configs.recommended.rules,
|
|
213
|
+
"array-callback-return": ["error", { allowImplicit: true }],
|
|
201
214
|
"block-scoped-var": "error",
|
|
202
215
|
"default-case-last": "error",
|
|
203
216
|
"dot-notation": "error",
|
|
204
217
|
"eqeqeq": "error",
|
|
218
|
+
"getter-return": ["error", { allowImplicit: true }],
|
|
205
219
|
"new-cap": "error",
|
|
206
220
|
"no-alert": "error",
|
|
207
221
|
"no-array-constructor": "error",
|
|
@@ -284,75 +298,91 @@ async function javascript(options) {
|
|
|
284
298
|
"unicode-bom": "error",
|
|
285
299
|
"valid-typeof": ["error", { requireStringLiterals: true }],
|
|
286
300
|
"vars-on-top": "error",
|
|
287
|
-
"yoda": "error"
|
|
288
|
-
...resolved.overrides
|
|
301
|
+
"yoda": "error"
|
|
289
302
|
}
|
|
290
303
|
}];
|
|
291
304
|
}
|
|
292
305
|
//#endregion
|
|
293
306
|
//#region src/configs/jsdoc.ts
|
|
294
|
-
const jsdocDefaults = { files: [
|
|
295
|
-
jsGlob,
|
|
296
|
-
tsGlob,
|
|
297
|
-
vueGlob
|
|
298
|
-
] };
|
|
299
307
|
/**
|
|
300
308
|
* Constructs the flat config items for JSDoc linting, ensuring comments follow
|
|
301
309
|
* proper styling, parameter checks, and types alignment.
|
|
302
|
-
* @param options JSDoc configuration options.
|
|
303
310
|
* @returns Promise resolving to JSDoc ESLint config items.
|
|
304
311
|
*/
|
|
305
|
-
async function jsdoc(
|
|
306
|
-
const resolved = defu(options, jsdocDefaults);
|
|
312
|
+
async function jsdoc() {
|
|
307
313
|
const jsdocPlugin = await importModule(import("eslint-plugin-jsdoc"));
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
314
|
+
const files = [
|
|
315
|
+
jsGlob,
|
|
316
|
+
tsGlob,
|
|
317
|
+
vueGlob
|
|
318
|
+
];
|
|
319
|
+
const recommendedConfig = jsdocPlugin.configs["flat/recommended-typescript-error"];
|
|
320
|
+
const stylisticConfig = jsdocPlugin.configs["flat/stylistic-typescript-error"];
|
|
321
|
+
const { rules: recommendedRules = {} } = recommendedConfig;
|
|
322
|
+
const recommendedRest = omit(recommendedConfig, [
|
|
323
|
+
"rules",
|
|
324
|
+
"files",
|
|
325
|
+
"name"
|
|
326
|
+
]);
|
|
327
|
+
const { rules: stylisticRules = {} } = stylisticConfig;
|
|
328
|
+
const stylisticRest = omit(stylisticConfig, [
|
|
329
|
+
"rules",
|
|
330
|
+
"files",
|
|
331
|
+
"name"
|
|
332
|
+
]);
|
|
333
|
+
const rules = {
|
|
334
|
+
...recommendedRules,
|
|
335
|
+
...stylisticRules
|
|
311
336
|
};
|
|
312
|
-
return [
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
"jsdoc/
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
337
|
+
return [
|
|
338
|
+
{
|
|
339
|
+
...recommendedRest,
|
|
340
|
+
name: "favorodera/jsdoc/recommended/setup"
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
...stylisticRest,
|
|
344
|
+
name: "favorodera/jsdoc/stylistic/setup"
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
files,
|
|
348
|
+
name: "favorodera/jsdoc/rules",
|
|
349
|
+
rules: {
|
|
350
|
+
...rules,
|
|
351
|
+
"jsdoc/check-indentation": "error",
|
|
352
|
+
"jsdoc/check-template-names": "error",
|
|
353
|
+
"jsdoc/imports-as-dependencies": "error",
|
|
354
|
+
"jsdoc/lines-before-block": ["error", { ignoreSingleLines: false }],
|
|
355
|
+
"jsdoc/multiline-blocks": "error",
|
|
356
|
+
"jsdoc/no-bad-blocks": "error",
|
|
357
|
+
"jsdoc/no-blank-block-descriptions": "error",
|
|
358
|
+
"jsdoc/no-blank-blocks": "error",
|
|
359
|
+
"jsdoc/require-throws-type": "off",
|
|
360
|
+
"jsdoc/sort-tags": "error"
|
|
361
|
+
}
|
|
331
362
|
}
|
|
332
|
-
|
|
363
|
+
];
|
|
333
364
|
}
|
|
334
365
|
//#endregion
|
|
335
366
|
//#region src/configs/jsonc.ts
|
|
336
|
-
const jsoncDefaults = { files: [
|
|
337
|
-
json5Glob,
|
|
338
|
-
jsoncGlob,
|
|
339
|
-
jsonGlob
|
|
340
|
-
] };
|
|
341
367
|
/**
|
|
342
368
|
* Constructs the flat config items for JSON, JSON5, and JSONC linting, setting up
|
|
343
369
|
* the custom parser, rule validations, and sorting rules for package.json/tsconfig.json.
|
|
344
|
-
* @param options JSONC configuration options.
|
|
345
370
|
* @returns Promise resolving to JSONC ESLint config items.
|
|
346
371
|
*/
|
|
347
|
-
async function jsonc(
|
|
348
|
-
const
|
|
372
|
+
async function jsonc() {
|
|
373
|
+
const jsoncPlugin = await importModule(import("eslint-plugin-jsonc"));
|
|
374
|
+
const files = [
|
|
375
|
+
json5Glob,
|
|
376
|
+
jsoncGlob,
|
|
377
|
+
jsonGlob
|
|
378
|
+
];
|
|
349
379
|
return [
|
|
350
380
|
{
|
|
351
381
|
name: "favorodera/jsonc/setup",
|
|
352
|
-
plugins: { jsonc:
|
|
382
|
+
plugins: { jsonc: jsoncPlugin }
|
|
353
383
|
},
|
|
354
384
|
{
|
|
355
|
-
files
|
|
385
|
+
files,
|
|
356
386
|
language: "jsonc/x",
|
|
357
387
|
name: "favorodera/jsonc/rules",
|
|
358
388
|
rules: {
|
|
@@ -400,8 +430,7 @@ async function jsonc(options) {
|
|
|
400
430
|
"jsonc/quotes": "error",
|
|
401
431
|
"jsonc/space-unary-ops": "error",
|
|
402
432
|
"jsonc/valid-json-number": "error",
|
|
403
|
-
"jsonc/vue-custom-block/no-parsing-error": "error"
|
|
404
|
-
...resolved.overrides
|
|
433
|
+
"jsonc/vue-custom-block/no-parsing-error": "error"
|
|
405
434
|
}
|
|
406
435
|
},
|
|
407
436
|
{
|
|
@@ -622,7 +651,7 @@ async function jsonc(options) {
|
|
|
622
651
|
] }
|
|
623
652
|
},
|
|
624
653
|
{
|
|
625
|
-
files
|
|
654
|
+
files,
|
|
626
655
|
language: "jsonc/x",
|
|
627
656
|
name: "favorodera/jsonc/disables",
|
|
628
657
|
rules: { "no-irregular-whitespace": "off" }
|
|
@@ -631,10 +660,7 @@ async function jsonc(options) {
|
|
|
631
660
|
}
|
|
632
661
|
//#endregion
|
|
633
662
|
//#region src/configs/markdown.ts
|
|
634
|
-
const markdownDefaults = {
|
|
635
|
-
files: [mdGlob],
|
|
636
|
-
gfm: true
|
|
637
|
-
};
|
|
663
|
+
const markdownDefaults = { gfm: true };
|
|
638
664
|
/**
|
|
639
665
|
* Constructs the flat config items for Markdown linting, extracting and linting
|
|
640
666
|
* embedded code blocks within the document according to specified rules.
|
|
@@ -644,32 +670,29 @@ const markdownDefaults = {
|
|
|
644
670
|
async function markdown(options) {
|
|
645
671
|
const resolved = defu(options, markdownDefaults);
|
|
646
672
|
const markdownPlugin = await importModule(import("@eslint/markdown"));
|
|
647
|
-
const
|
|
673
|
+
const [recommendedConfig] = markdownPlugin.configs.recommended;
|
|
674
|
+
const { rules = {} } = recommendedConfig;
|
|
648
675
|
return [
|
|
649
676
|
{
|
|
650
|
-
|
|
651
|
-
|
|
677
|
+
...omit(recommendedConfig, [
|
|
678
|
+
"rules",
|
|
679
|
+
"files",
|
|
680
|
+
"name",
|
|
681
|
+
"language"
|
|
682
|
+
]),
|
|
683
|
+
name: "favorodera/markdown/setup"
|
|
652
684
|
},
|
|
653
685
|
{
|
|
654
|
-
files:
|
|
686
|
+
files: [mdGlob],
|
|
655
687
|
ignores: [mdInMdGlob],
|
|
656
|
-
name: "favorodera/markdown/processor",
|
|
657
|
-
processor: mergeProcessors([markdownPlugin.processors?.markdown, processorPassThrough])
|
|
658
|
-
},
|
|
659
|
-
{
|
|
660
|
-
files: resolved.files,
|
|
661
688
|
language: resolved.gfm ? "md/gfm" : "md/commonmark",
|
|
662
689
|
languageOptions: { frontmatter: "yaml" },
|
|
663
|
-
name: "favorodera/markdown/parser"
|
|
664
|
-
},
|
|
665
|
-
{
|
|
666
|
-
files: resolved.files,
|
|
667
690
|
name: "favorodera/markdown/rules",
|
|
691
|
+
processor: mergeProcessors([markdownPlugin.processors?.markdown, processorPassThrough]),
|
|
668
692
|
rules: {
|
|
669
|
-
...
|
|
693
|
+
...rules,
|
|
670
694
|
"md/fenced-code-language": "off",
|
|
671
|
-
"md/no-missing-label-refs": "off"
|
|
672
|
-
...resolved.overrides
|
|
695
|
+
"md/no-missing-label-refs": "off"
|
|
673
696
|
}
|
|
674
697
|
},
|
|
675
698
|
{
|
|
@@ -709,31 +732,34 @@ async function markdown(options) {
|
|
|
709
732
|
}
|
|
710
733
|
//#endregion
|
|
711
734
|
//#region src/configs/node.ts
|
|
712
|
-
const nodeDefaults = { files: [
|
|
713
|
-
jsGlob,
|
|
714
|
-
tsGlob,
|
|
715
|
-
vueGlob
|
|
716
|
-
] };
|
|
717
735
|
/**
|
|
718
736
|
* Constructs the flat config items for Node.js linting, providing rules
|
|
719
737
|
* to enforce best practices for Node.js environments.
|
|
720
|
-
* @param options Node configuration options.
|
|
721
738
|
* @returns Promise resolving to Node ESLint config items.
|
|
722
739
|
*/
|
|
723
|
-
async function node(
|
|
724
|
-
const resolved = defu(options, nodeDefaults);
|
|
740
|
+
async function node() {
|
|
725
741
|
const nodePlugin = await importModule(import("eslint-plugin-n"));
|
|
726
|
-
const
|
|
742
|
+
const files = [
|
|
743
|
+
jsGlob,
|
|
744
|
+
tsGlob,
|
|
745
|
+
vueGlob
|
|
746
|
+
];
|
|
747
|
+
const recommendedConfig = nodePlugin.configs["flat/recommended-module"];
|
|
748
|
+
const { rules = {} } = recommendedConfig;
|
|
727
749
|
return [
|
|
728
750
|
{
|
|
729
|
-
|
|
730
|
-
|
|
751
|
+
...omit(recommendedConfig, [
|
|
752
|
+
"rules",
|
|
753
|
+
"files",
|
|
754
|
+
"name"
|
|
755
|
+
]),
|
|
756
|
+
name: "favorodera/node/setup"
|
|
731
757
|
},
|
|
732
758
|
{
|
|
733
|
-
files
|
|
759
|
+
files,
|
|
734
760
|
name: "favorodera/node/rules",
|
|
735
761
|
rules: {
|
|
736
|
-
...
|
|
762
|
+
...rules,
|
|
737
763
|
"node/callback-return": "error",
|
|
738
764
|
"node/handle-callback-err": ["error", "^(err|error)$"],
|
|
739
765
|
"node/no-callback-literal": "error",
|
|
@@ -752,12 +778,11 @@ async function node(options) {
|
|
|
752
778
|
"node/prefer-node-protocol": "error",
|
|
753
779
|
"node/prefer-promises/dns": "error",
|
|
754
780
|
"node/prefer-promises/fs": "error",
|
|
755
|
-
"node/no-process-exit": "off"
|
|
756
|
-
...resolved.overrides
|
|
781
|
+
"node/no-process-exit": "off"
|
|
757
782
|
}
|
|
758
783
|
},
|
|
759
784
|
{
|
|
760
|
-
files
|
|
785
|
+
files,
|
|
761
786
|
name: "favorodera/node/disables",
|
|
762
787
|
rules: {
|
|
763
788
|
"node/no-missing-import": "off",
|
|
@@ -769,22 +794,15 @@ async function node(options) {
|
|
|
769
794
|
//#endregion
|
|
770
795
|
//#region src/configs/perfectionist.ts
|
|
771
796
|
const perfectionistDefaults = {
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
newlinesInside: "ignore",
|
|
782
|
-
order: "asc",
|
|
783
|
-
partitionByComment: true,
|
|
784
|
-
partitionByNewLine: true,
|
|
785
|
-
specialCharacters: "keep",
|
|
786
|
-
type: "natural"
|
|
787
|
-
}
|
|
797
|
+
ignoreCase: true,
|
|
798
|
+
locales: "en-US",
|
|
799
|
+
newlinesBetween: "ignore",
|
|
800
|
+
newlinesInside: "ignore",
|
|
801
|
+
order: "asc",
|
|
802
|
+
partitionByComment: true,
|
|
803
|
+
partitionByNewLine: true,
|
|
804
|
+
specialCharacters: "keep",
|
|
805
|
+
type: "natural"
|
|
788
806
|
};
|
|
789
807
|
/**
|
|
790
808
|
* Constructs the flat config items for Perfectionist linting, providing rules
|
|
@@ -795,19 +813,27 @@ const perfectionistDefaults = {
|
|
|
795
813
|
async function perfectionist(options) {
|
|
796
814
|
const resolved = defu(options, perfectionistDefaults);
|
|
797
815
|
const perfectionistPlugin = await importModule(import("eslint-plugin-perfectionist"));
|
|
798
|
-
const
|
|
799
|
-
|
|
816
|
+
const files = [
|
|
817
|
+
jsGlob,
|
|
818
|
+
tsGlob,
|
|
819
|
+
vueGlob
|
|
820
|
+
];
|
|
821
|
+
const safeType = resolved.type ?? "natural";
|
|
822
|
+
const presetConfig = perfectionistPlugin.configs[`recommended-${safeType}`];
|
|
823
|
+
const { rules = {} } = presetConfig;
|
|
800
824
|
return [{
|
|
825
|
+
...omit(presetConfig, [
|
|
826
|
+
"rules",
|
|
827
|
+
"settings",
|
|
828
|
+
"files",
|
|
829
|
+
"name"
|
|
830
|
+
]),
|
|
801
831
|
name: "favorodera/perfectionist/setup",
|
|
802
|
-
|
|
803
|
-
settings: { perfectionist: resolved.settings }
|
|
832
|
+
settings: { perfectionist: resolved }
|
|
804
833
|
}, {
|
|
805
|
-
files
|
|
834
|
+
files,
|
|
806
835
|
name: "favorodera/perfectionist/rules",
|
|
807
|
-
rules
|
|
808
|
-
...baseRules,
|
|
809
|
-
...resolved.overrides
|
|
810
|
-
}
|
|
836
|
+
rules
|
|
811
837
|
}];
|
|
812
838
|
}
|
|
813
839
|
//#endregion
|
|
@@ -848,6 +874,15 @@ async function pnpm() {
|
|
|
848
874
|
name: "favorodera/pnpm/pnpm-workspace-yaml",
|
|
849
875
|
rules: {
|
|
850
876
|
"pnpm/yaml-enforce-settings": ["error", { settings: {
|
|
877
|
+
allowBuilds: {
|
|
878
|
+
"@parcel/watcher": true,
|
|
879
|
+
"@tailwindcss/oxide": true,
|
|
880
|
+
"better-sqlite3": true,
|
|
881
|
+
"esbuild": true,
|
|
882
|
+
"sharp": true,
|
|
883
|
+
"unrs-resolver": true,
|
|
884
|
+
"vue-demi": true
|
|
885
|
+
},
|
|
851
886
|
shellEmulator: true,
|
|
852
887
|
trustPolicy: "no-downgrade"
|
|
853
888
|
} }],
|
|
@@ -861,19 +896,12 @@ async function pnpm() {
|
|
|
861
896
|
//#endregion
|
|
862
897
|
//#region src/configs/stylistic.ts
|
|
863
898
|
const stylisticDefaults = {
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
braceStyle: "1tbs",
|
|
871
|
-
experimental: false,
|
|
872
|
-
indent: 2,
|
|
873
|
-
jsx: false,
|
|
874
|
-
quotes: "single",
|
|
875
|
-
semi: false
|
|
876
|
-
}
|
|
899
|
+
braceStyle: "1tbs",
|
|
900
|
+
experimental: false,
|
|
901
|
+
indent: 2,
|
|
902
|
+
jsx: false,
|
|
903
|
+
quotes: "single",
|
|
904
|
+
semi: false
|
|
877
905
|
};
|
|
878
906
|
/**
|
|
879
907
|
* Constructs the flat config items for Stylistic linting, applying customized
|
|
@@ -884,18 +912,28 @@ const stylisticDefaults = {
|
|
|
884
912
|
async function stylistic(options) {
|
|
885
913
|
const resolved = defu(options, stylisticDefaults);
|
|
886
914
|
const stylePlugin = await importModule(import("@stylistic/eslint-plugin"));
|
|
887
|
-
const
|
|
915
|
+
const files = [
|
|
916
|
+
jsGlob,
|
|
917
|
+
tsGlob,
|
|
918
|
+
vueGlob
|
|
919
|
+
];
|
|
920
|
+
const recommendedConfig = stylePlugin.configs.customize({
|
|
888
921
|
pluginName: "style",
|
|
889
|
-
...resolved
|
|
890
|
-
})
|
|
922
|
+
...resolved
|
|
923
|
+
});
|
|
924
|
+
const { rules = {} } = recommendedConfig;
|
|
891
925
|
return [{
|
|
892
|
-
|
|
893
|
-
|
|
926
|
+
...omit(recommendedConfig, [
|
|
927
|
+
"rules",
|
|
928
|
+
"files",
|
|
929
|
+
"name"
|
|
930
|
+
]),
|
|
931
|
+
name: "favorodera/stylistic/setup"
|
|
894
932
|
}, {
|
|
895
|
-
files
|
|
933
|
+
files,
|
|
896
934
|
name: "favorodera/stylistic/rules",
|
|
897
935
|
rules: {
|
|
898
|
-
...
|
|
936
|
+
...rules,
|
|
899
937
|
"style/array-bracket-newline": "error",
|
|
900
938
|
"style/array-element-newline": "error",
|
|
901
939
|
"style/curly-newline": ["error", "always"],
|
|
@@ -913,21 +951,13 @@ async function stylistic(options) {
|
|
|
913
951
|
"style/object-curly-newline": "error",
|
|
914
952
|
"style/semi-style": "error",
|
|
915
953
|
"style/switch-colon-spacing": "error",
|
|
916
|
-
"style/wrap-regex": "error"
|
|
917
|
-
...resolved.overrides
|
|
954
|
+
"style/wrap-regex": "error"
|
|
918
955
|
}
|
|
919
956
|
}];
|
|
920
957
|
}
|
|
921
958
|
//#endregion
|
|
922
959
|
//#region src/configs/tailwind.ts
|
|
923
|
-
const tailwindDefaults = {
|
|
924
|
-
files: [
|
|
925
|
-
jsGlob,
|
|
926
|
-
tsGlob,
|
|
927
|
-
vueGlob
|
|
928
|
-
],
|
|
929
|
-
settings: { detectComponentClasses: true }
|
|
930
|
-
};
|
|
960
|
+
const tailwindDefaults = { detectComponentClasses: true };
|
|
931
961
|
/**
|
|
932
962
|
* Constructs the flat config items for Tailwind CSS linting, providing custom settings
|
|
933
963
|
* to parse and lint utility classes, and enforcing consistent ordering.
|
|
@@ -937,59 +967,75 @@ const tailwindDefaults = {
|
|
|
937
967
|
async function tailwind(options) {
|
|
938
968
|
const resolved = defu(options, tailwindDefaults);
|
|
939
969
|
const tailwindPlugin = await importModule(import("eslint-plugin-better-tailwindcss"));
|
|
940
|
-
const
|
|
941
|
-
|
|
942
|
-
|
|
970
|
+
const files = [
|
|
971
|
+
jsGlob,
|
|
972
|
+
tsGlob,
|
|
973
|
+
vueGlob
|
|
974
|
+
];
|
|
975
|
+
const recommendedConfig = tailwindPlugin.configs["recommended-error"];
|
|
976
|
+
const stylisticConfig = tailwindPlugin.configs["stylistic-error"];
|
|
977
|
+
const { rules: recommendedRules } = recommendedConfig;
|
|
978
|
+
const recommendedRest = omit(recommendedConfig, ["rules"]);
|
|
979
|
+
const { rules: stylisticRules } = stylisticConfig;
|
|
980
|
+
const stylisticRest = omit(stylisticConfig, ["rules"]);
|
|
981
|
+
const rules = {
|
|
982
|
+
...recommendedRules,
|
|
983
|
+
...stylisticRules
|
|
943
984
|
};
|
|
944
|
-
return [
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
985
|
+
return [
|
|
986
|
+
{
|
|
987
|
+
...recommendedRest,
|
|
988
|
+
name: "favorodera/tailwind/recommended/setup"
|
|
989
|
+
},
|
|
990
|
+
{
|
|
991
|
+
...stylisticRest,
|
|
992
|
+
name: "favorodera/tailwind/stylistic/setup"
|
|
993
|
+
},
|
|
994
|
+
{
|
|
995
|
+
files,
|
|
996
|
+
name: "favorodera/tailwind/rules",
|
|
997
|
+
rules: {
|
|
998
|
+
...rules,
|
|
999
|
+
"tailwind/enforce-consistent-class-order": ["error", {
|
|
1000
|
+
componentClassOrder: "asc",
|
|
1001
|
+
componentClassPosition: "start",
|
|
1002
|
+
order: "strict",
|
|
1003
|
+
unknownClassOrder: "asc",
|
|
1004
|
+
unknownClassPosition: "start"
|
|
1005
|
+
}],
|
|
1006
|
+
"tailwind/enforce-consistent-line-wrapping": ["error", { group: "emptyLine" }],
|
|
1007
|
+
"tailwind/enforce-consistent-variant-order": "error",
|
|
1008
|
+
"tailwind/enforce-logical-properties": "error",
|
|
1009
|
+
"tailwind/enforce-consistent-important-position": "off",
|
|
1010
|
+
"tailwind/enforce-consistent-variable-syntax": "off",
|
|
1011
|
+
"tailwind/enforce-shorthand-classes": "off"
|
|
1012
|
+
},
|
|
1013
|
+
settings: { "better-tailwindcss": resolved }
|
|
967
1014
|
}
|
|
968
|
-
|
|
1015
|
+
];
|
|
969
1016
|
}
|
|
970
1017
|
//#endregion
|
|
971
1018
|
//#region src/configs/test.ts
|
|
972
|
-
const testDefaults = { files: [testGlob] };
|
|
973
1019
|
/**
|
|
974
1020
|
* Constructs the flat config items for test linting, extending
|
|
975
1021
|
* the recommended Vitest rule sets.
|
|
976
|
-
* @param options Test configuration options.
|
|
977
1022
|
* @returns Promise resolving to test ESLint config items.
|
|
978
1023
|
*/
|
|
979
|
-
async function test(
|
|
980
|
-
const resolved = defu(options, testDefaults);
|
|
1024
|
+
async function test() {
|
|
981
1025
|
const testPlugin = await importModule(import("@vitest/eslint-plugin"));
|
|
982
|
-
const
|
|
1026
|
+
const files = [testGlob];
|
|
1027
|
+
const recommendedConfig = testPlugin.configs.recommended;
|
|
1028
|
+
const { rules } = recommendedConfig;
|
|
983
1029
|
return [
|
|
984
1030
|
{
|
|
985
|
-
|
|
986
|
-
|
|
1031
|
+
...omit(recommendedConfig, ["rules", "name"]),
|
|
1032
|
+
name: "favorodera/test/setup"
|
|
987
1033
|
},
|
|
988
1034
|
{
|
|
989
|
-
files
|
|
1035
|
+
files,
|
|
990
1036
|
name: "favorodera/test/rules",
|
|
991
1037
|
rules: {
|
|
992
|
-
...
|
|
1038
|
+
...rules,
|
|
993
1039
|
"test/consistent-each-for": ["error", {
|
|
994
1040
|
describe: "for",
|
|
995
1041
|
it: "for",
|
|
@@ -1042,12 +1088,11 @@ async function test(options) {
|
|
|
1042
1088
|
"test/require-hook": "error",
|
|
1043
1089
|
"test/require-to-throw-message": "error",
|
|
1044
1090
|
"test/require-top-level-describe": "error",
|
|
1045
|
-
"test/warn-todo": "warn"
|
|
1046
|
-
...resolved.overrides
|
|
1091
|
+
"test/warn-todo": "warn"
|
|
1047
1092
|
}
|
|
1048
1093
|
},
|
|
1049
1094
|
{
|
|
1050
|
-
files
|
|
1095
|
+
files,
|
|
1051
1096
|
name: "favorodera/test/disables",
|
|
1052
1097
|
rules: { "no-unused-expressions": "off" }
|
|
1053
1098
|
}
|
|
@@ -1055,29 +1100,30 @@ async function test(options) {
|
|
|
1055
1100
|
}
|
|
1056
1101
|
//#endregion
|
|
1057
1102
|
//#region src/configs/typescript.ts
|
|
1058
|
-
const typescriptDefaults = { files: [tsGlob] };
|
|
1059
1103
|
/**
|
|
1060
1104
|
* Constructs the flat config items for TypeScript linting, initializing the parser
|
|
1061
1105
|
* and extending the recommended and strict type-aware rule sets.
|
|
1062
|
-
* @param options TypeScript configuration options.
|
|
1063
1106
|
* @returns Promise resolving to TypeScript ESLint config items.
|
|
1064
1107
|
*/
|
|
1065
|
-
async function typescript(
|
|
1066
|
-
const resolved = defu(options, typescriptDefaults);
|
|
1108
|
+
async function typescript() {
|
|
1067
1109
|
const tsEsLint = await importModule(import("typescript-eslint"));
|
|
1068
|
-
const
|
|
1110
|
+
const files = [tsGlob];
|
|
1111
|
+
const [baseConfig, eslintRecommended, strictConfig] = tsEsLint.configs.strict;
|
|
1112
|
+
const stylisticConfig = tsEsLint.configs.stylistic[2];
|
|
1113
|
+
const baseRest = omit(baseConfig, ["rules", "name"]);
|
|
1114
|
+
const rules = {
|
|
1115
|
+
...eslintRecommended?.rules,
|
|
1116
|
+
...strictConfig?.rules,
|
|
1117
|
+
...stylisticConfig?.rules
|
|
1118
|
+
};
|
|
1069
1119
|
return [{
|
|
1070
|
-
|
|
1071
|
-
|
|
1120
|
+
...baseRest,
|
|
1121
|
+
name: "favorodera/typescript/setup"
|
|
1072
1122
|
}, {
|
|
1073
|
-
files
|
|
1074
|
-
languageOptions: {
|
|
1075
|
-
parser: tsEsLint.parser,
|
|
1076
|
-
parserOptions: { sourceType: "module" }
|
|
1077
|
-
},
|
|
1123
|
+
files,
|
|
1078
1124
|
name: "favorodera/typescript/rules",
|
|
1079
1125
|
rules: {
|
|
1080
|
-
...
|
|
1126
|
+
...rules,
|
|
1081
1127
|
"ts/array-type": ["error", {
|
|
1082
1128
|
default: "generic",
|
|
1083
1129
|
readonly: "generic"
|
|
@@ -1087,66 +1133,65 @@ async function typescript(options) {
|
|
|
1087
1133
|
"ts/method-signature-style": "error",
|
|
1088
1134
|
"ts/no-import-type-side-effects": "error",
|
|
1089
1135
|
"ts/no-loop-func": "error",
|
|
1090
|
-
"ts/no-redeclare": "error"
|
|
1091
|
-
...resolved.overrides
|
|
1136
|
+
"ts/no-redeclare": "error"
|
|
1092
1137
|
}
|
|
1093
1138
|
}];
|
|
1094
1139
|
}
|
|
1095
1140
|
//#endregion
|
|
1096
1141
|
//#region src/configs/unicorn.ts
|
|
1097
|
-
const unicornDefaults = { files: [
|
|
1098
|
-
jsGlob,
|
|
1099
|
-
tsGlob,
|
|
1100
|
-
vueGlob
|
|
1101
|
-
] };
|
|
1102
1142
|
/**
|
|
1103
1143
|
* Constructs the flat config items for Unicorn linting, providing a collection of
|
|
1104
1144
|
* awesome ESLint rules to improve code quality and enforce best practices.
|
|
1105
|
-
* @param options Unicorn configuration options.
|
|
1106
1145
|
* @returns Promise resolving to Unicorn ESLint config items.
|
|
1107
1146
|
*/
|
|
1108
|
-
async function unicorn(
|
|
1109
|
-
const resolved = defu(options, unicornDefaults);
|
|
1147
|
+
async function unicorn() {
|
|
1110
1148
|
const unicornPlugin = await importModule(import("eslint-plugin-unicorn"));
|
|
1111
|
-
const
|
|
1149
|
+
const files = [
|
|
1150
|
+
jsGlob,
|
|
1151
|
+
tsGlob,
|
|
1152
|
+
vueGlob
|
|
1153
|
+
];
|
|
1154
|
+
const recommendedConfig = unicornPlugin.configs.recommended;
|
|
1155
|
+
const { rules = {} } = recommendedConfig;
|
|
1112
1156
|
return [{
|
|
1113
|
-
|
|
1114
|
-
|
|
1157
|
+
...omit(recommendedConfig, [
|
|
1158
|
+
"rules",
|
|
1159
|
+
"files",
|
|
1160
|
+
"name"
|
|
1161
|
+
]),
|
|
1162
|
+
name: "favorodera/unicorn/setup"
|
|
1115
1163
|
}, {
|
|
1116
|
-
files
|
|
1117
|
-
languageOptions: { globals: globals.builtin },
|
|
1164
|
+
files,
|
|
1118
1165
|
name: "favorodera/unicorn/rules",
|
|
1119
1166
|
rules: {
|
|
1120
|
-
...
|
|
1167
|
+
...rules,
|
|
1121
1168
|
"unicorn/filename-case": "off",
|
|
1122
1169
|
"unicorn/no-process-exit": "off",
|
|
1123
|
-
"unicorn/prevent-abbreviations": "off"
|
|
1124
|
-
...resolved.overrides
|
|
1170
|
+
"unicorn/prevent-abbreviations": "off"
|
|
1125
1171
|
}
|
|
1126
1172
|
}];
|
|
1127
1173
|
}
|
|
1128
1174
|
//#endregion
|
|
1129
1175
|
//#region src/configs/unused-imports.ts
|
|
1130
|
-
const unusedImportsDefaults = { files: [
|
|
1131
|
-
jsGlob,
|
|
1132
|
-
tsGlob,
|
|
1133
|
-
vueGlob
|
|
1134
|
-
] };
|
|
1135
1176
|
/**
|
|
1136
1177
|
* Constructs the flat config items for unused imports linting, providing plugin setup and
|
|
1137
1178
|
* specific rules to detect and remove unused imports and variables.
|
|
1138
|
-
* @param options Configuration options for unused imports linting.
|
|
1139
1179
|
* @returns Promise resolving to unused imports ESLint config items.
|
|
1140
1180
|
*/
|
|
1141
|
-
async function unusedImports(
|
|
1142
|
-
const
|
|
1181
|
+
async function unusedImports() {
|
|
1182
|
+
const unusedImportsPlugin = await importModule(import("eslint-plugin-unused-imports"));
|
|
1183
|
+
const files = [
|
|
1184
|
+
jsGlob,
|
|
1185
|
+
tsGlob,
|
|
1186
|
+
vueGlob
|
|
1187
|
+
];
|
|
1143
1188
|
return [
|
|
1144
1189
|
{
|
|
1145
1190
|
name: "favorodera/unused-imports/setup",
|
|
1146
|
-
plugins: { "unused-imports":
|
|
1191
|
+
plugins: { "unused-imports": unusedImportsPlugin }
|
|
1147
1192
|
},
|
|
1148
1193
|
{
|
|
1149
|
-
files
|
|
1194
|
+
files,
|
|
1150
1195
|
name: "favorodera/unused-imports/rules",
|
|
1151
1196
|
rules: {
|
|
1152
1197
|
"unused-imports/no-unused-imports": "error",
|
|
@@ -1156,12 +1201,11 @@ async function unusedImports(options) {
|
|
|
1156
1201
|
ignoreRestSiblings: true,
|
|
1157
1202
|
vars: "all",
|
|
1158
1203
|
varsIgnorePattern: "^_"
|
|
1159
|
-
}]
|
|
1160
|
-
...resolved.overrides
|
|
1204
|
+
}]
|
|
1161
1205
|
}
|
|
1162
1206
|
},
|
|
1163
1207
|
{
|
|
1164
|
-
files
|
|
1208
|
+
files,
|
|
1165
1209
|
name: "favorodera/unused-imports/disables",
|
|
1166
1210
|
rules: {
|
|
1167
1211
|
"no-unused-vars": "off",
|
|
@@ -1177,167 +1221,196 @@ const sfcBlocksDefaults = { blocks: {
|
|
|
1177
1221
|
styles: true,
|
|
1178
1222
|
template: false
|
|
1179
1223
|
} };
|
|
1180
|
-
const vueDefaults = {
|
|
1181
|
-
files: [vueGlob],
|
|
1182
|
-
sfcBlocks: sfcBlocksDefaults
|
|
1183
|
-
};
|
|
1224
|
+
const vueDefaults = { sfcBlocks: sfcBlocksDefaults };
|
|
1184
1225
|
/**
|
|
1185
|
-
* Constructs the flat config items for Vue linting, setting up the custom template parser,
|
|
1226
|
+
* Constructs the flat config items for Vue and accessibility linting, setting up the custom template parser,
|
|
1186
1227
|
* Vue block processors, and rules to enforce recommended component syntax.
|
|
1187
1228
|
* @param options Vue configuration options.
|
|
1188
1229
|
* @returns Promise resolving to Vue ESLint config items.
|
|
1189
1230
|
*/
|
|
1190
1231
|
async function vue(options) {
|
|
1191
|
-
const
|
|
1192
|
-
const
|
|
1193
|
-
const [vuePlugin, vueParser, tsEsLint] = await Promise.all([
|
|
1232
|
+
const sfcBlocks = resolveOptions(defu(options, vueDefaults).sfcBlocks, sfcBlocksDefaults);
|
|
1233
|
+
const [vuePlugin, vueParser, tsEsLint, a11yPlugin] = await Promise.all([
|
|
1194
1234
|
importModule(import("eslint-plugin-vue")),
|
|
1195
1235
|
importModule(import("vue-eslint-parser")),
|
|
1196
|
-
importModule(import("typescript-eslint"))
|
|
1236
|
+
importModule(import("typescript-eslint")),
|
|
1237
|
+
importModule(import("eslint-plugin-vuejs-accessibility"))
|
|
1238
|
+
]);
|
|
1239
|
+
const vueRecommendedConfig = vuePlugin.configs["flat/recommended-error"];
|
|
1240
|
+
const a11yRecommendedConfig = a11yPlugin.configs["flat/recommended"];
|
|
1241
|
+
const [vueBase] = vueRecommendedConfig;
|
|
1242
|
+
const vueBaseRest = omit(vueBase, [
|
|
1243
|
+
"rules",
|
|
1244
|
+
"files",
|
|
1245
|
+
"name"
|
|
1197
1246
|
]);
|
|
1198
|
-
const
|
|
1247
|
+
const vueRules = extractRules(vueRecommendedConfig);
|
|
1248
|
+
const [a11yBase] = a11yRecommendedConfig;
|
|
1249
|
+
const a11yBaseRest = omit(a11yBase, ["name"]);
|
|
1250
|
+
const a11yRules = extractRules(a11yRecommendedConfig);
|
|
1199
1251
|
const processor = sfcBlocks === false ? vuePlugin.processors[".vue"] : mergeProcessors([vuePlugin.processors[".vue"], vueBlocksProcessor(sfcBlocks)]);
|
|
1200
|
-
return [
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
files: resolved.files,
|
|
1221
|
-
languageOptions: {
|
|
1222
|
-
parser: vueParser,
|
|
1223
|
-
parserOptions: {
|
|
1224
|
-
extraFileExtensions: [".vue"],
|
|
1225
|
-
parser: tsEsLint.parser,
|
|
1226
|
-
sourceType: "module"
|
|
1227
|
-
}
|
|
1252
|
+
return [
|
|
1253
|
+
{
|
|
1254
|
+
...vueBaseRest,
|
|
1255
|
+
languageOptions: { globals: {
|
|
1256
|
+
computed: "readonly",
|
|
1257
|
+
defineEmits: "readonly",
|
|
1258
|
+
defineExpose: "readonly",
|
|
1259
|
+
defineProps: "readonly",
|
|
1260
|
+
onMounted: "readonly",
|
|
1261
|
+
onUnmounted: "readonly",
|
|
1262
|
+
reactive: "readonly",
|
|
1263
|
+
ref: "readonly",
|
|
1264
|
+
shallowReactive: "readonly",
|
|
1265
|
+
shallowRef: "readonly",
|
|
1266
|
+
toRef: "readonly",
|
|
1267
|
+
toRefs: "readonly",
|
|
1268
|
+
watch: "readonly",
|
|
1269
|
+
watchEffect: "readonly"
|
|
1270
|
+
} },
|
|
1271
|
+
name: "favorodera/vue/setup"
|
|
1228
1272
|
},
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
singleline: "always"
|
|
1242
|
-
}],
|
|
1243
|
-
"vue/comment-directive": ["error", { reportUnusedDisableDirectives: true }],
|
|
1244
|
-
"vue/define-macros-order": ["error", {
|
|
1245
|
-
defineExposeLast: true,
|
|
1246
|
-
order: [
|
|
1247
|
-
"defineOptions",
|
|
1248
|
-
"definePage",
|
|
1249
|
-
"defineSlots",
|
|
1250
|
-
"defineEmits",
|
|
1251
|
-
"defineProps",
|
|
1252
|
-
"defineModel"
|
|
1253
|
-
]
|
|
1254
|
-
}],
|
|
1255
|
-
"vue/define-props-declaration": ["error", "type-based"],
|
|
1256
|
-
"vue/define-props-destructuring": ["error", { destructure: "never" }],
|
|
1257
|
-
"vue/multi-word-component-names": "off",
|
|
1258
|
-
"vue/next-tick-style": ["error", "promise"],
|
|
1259
|
-
"vue/no-import-compiler-macros": "error",
|
|
1260
|
-
"vue/no-negated-v-if-condition": "error",
|
|
1261
|
-
"vue/no-reserved-component-names": ["error", {
|
|
1262
|
-
disallowVue3BuiltInComponents: true,
|
|
1263
|
-
disallowVueBuiltInComponents: true,
|
|
1264
|
-
htmlElementCaseSensitive: false
|
|
1265
|
-
}],
|
|
1266
|
-
"vue/no-root-v-if": "error",
|
|
1267
|
-
"vue/no-template-target-blank": "error",
|
|
1268
|
-
"vue/no-unused-emit-declarations": "error",
|
|
1269
|
-
"vue/no-unused-properties": "error",
|
|
1270
|
-
"vue/no-unused-refs": "error",
|
|
1271
|
-
"vue/no-use-v-else-with-v-for": "error",
|
|
1272
|
-
"vue/no-useless-mustaches": "error",
|
|
1273
|
-
"vue/no-useless-v-bind": "error",
|
|
1274
|
-
"vue/padding-line-between-blocks": "error",
|
|
1275
|
-
"vue/padding-line-between-tags": ["error", [
|
|
1276
|
-
{
|
|
1277
|
-
blankLine: "always",
|
|
1278
|
-
next: "*:multi-line",
|
|
1279
|
-
prev: "*:single-line"
|
|
1280
|
-
},
|
|
1281
|
-
{
|
|
1282
|
-
blankLine: "always",
|
|
1283
|
-
next: "*:single-line",
|
|
1284
|
-
prev: "*:multi-line"
|
|
1285
|
-
},
|
|
1286
|
-
{
|
|
1287
|
-
blankLine: "always",
|
|
1288
|
-
next: "*:multi-line",
|
|
1289
|
-
prev: "*:multi-line"
|
|
1290
|
-
},
|
|
1291
|
-
{
|
|
1292
|
-
blankLine: "never",
|
|
1293
|
-
next: "*:single-line",
|
|
1294
|
-
prev: "*:single-line"
|
|
1273
|
+
{
|
|
1274
|
+
...a11yBaseRest,
|
|
1275
|
+
name: "favorodera/vue/a11y/setup"
|
|
1276
|
+
},
|
|
1277
|
+
{
|
|
1278
|
+
files: [vueGlob],
|
|
1279
|
+
languageOptions: {
|
|
1280
|
+
parser: vueParser,
|
|
1281
|
+
parserOptions: {
|
|
1282
|
+
extraFileExtensions: [".vue"],
|
|
1283
|
+
parser: tsEsLint.parser,
|
|
1284
|
+
sourceType: "module"
|
|
1295
1285
|
}
|
|
1296
|
-
|
|
1297
|
-
"vue/
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1286
|
+
},
|
|
1287
|
+
name: "favorodera/vue/rules",
|
|
1288
|
+
processor,
|
|
1289
|
+
rules: {
|
|
1290
|
+
...vueRules,
|
|
1291
|
+
"vue/block-lang": ["error", { script: { lang: "ts" } }],
|
|
1292
|
+
"vue/block-order": ["error", { order: [
|
|
1293
|
+
"script",
|
|
1294
|
+
"template",
|
|
1295
|
+
"style"
|
|
1296
|
+
] }],
|
|
1297
|
+
"vue/block-tag-newline": ["error", {
|
|
1298
|
+
multiline: "always",
|
|
1299
|
+
singleline: "always"
|
|
1300
|
+
}],
|
|
1301
|
+
"vue/comment-directive": ["error", { reportUnusedDisableDirectives: true }],
|
|
1302
|
+
"vue/define-macros-order": ["error", {
|
|
1303
|
+
defineExposeLast: true,
|
|
1304
|
+
order: [
|
|
1305
|
+
"defineOptions",
|
|
1306
|
+
"definePage",
|
|
1307
|
+
"defineSlots",
|
|
1308
|
+
"defineEmits",
|
|
1309
|
+
"defineProps",
|
|
1310
|
+
"defineModel"
|
|
1311
|
+
]
|
|
1312
|
+
}],
|
|
1313
|
+
"vue/define-props-declaration": ["error", "type-based"],
|
|
1314
|
+
"vue/define-props-destructuring": ["error", { destructure: "never" }],
|
|
1315
|
+
"vue/multi-word-component-names": "off",
|
|
1316
|
+
"vue/next-tick-style": ["error", "promise"],
|
|
1317
|
+
"vue/no-import-compiler-macros": "error",
|
|
1318
|
+
"vue/no-negated-v-if-condition": "error",
|
|
1319
|
+
"vue/no-reserved-component-names": ["error", {
|
|
1320
|
+
disallowVue3BuiltInComponents: true,
|
|
1321
|
+
disallowVueBuiltInComponents: true,
|
|
1322
|
+
htmlElementCaseSensitive: false
|
|
1323
|
+
}],
|
|
1324
|
+
"vue/no-root-v-if": "error",
|
|
1325
|
+
"vue/no-template-target-blank": "error",
|
|
1326
|
+
"vue/no-unused-emit-declarations": "error",
|
|
1327
|
+
"vue/no-unused-properties": "error",
|
|
1328
|
+
"vue/no-unused-refs": "error",
|
|
1329
|
+
"vue/no-use-v-else-with-v-for": "error",
|
|
1330
|
+
"vue/no-useless-mustaches": "error",
|
|
1331
|
+
"vue/no-useless-v-bind": "error",
|
|
1332
|
+
"vue/padding-line-between-blocks": "error",
|
|
1333
|
+
"vue/padding-line-between-tags": ["error", [
|
|
1334
|
+
{
|
|
1335
|
+
blankLine: "always",
|
|
1336
|
+
next: "*:multi-line",
|
|
1337
|
+
prev: "*:single-line"
|
|
1338
|
+
},
|
|
1339
|
+
{
|
|
1340
|
+
blankLine: "always",
|
|
1341
|
+
next: "*:single-line",
|
|
1342
|
+
prev: "*:multi-line"
|
|
1343
|
+
},
|
|
1344
|
+
{
|
|
1345
|
+
blankLine: "always",
|
|
1346
|
+
next: "*:multi-line",
|
|
1347
|
+
prev: "*:multi-line"
|
|
1348
|
+
},
|
|
1349
|
+
{
|
|
1350
|
+
blankLine: "never",
|
|
1351
|
+
next: "*:single-line",
|
|
1352
|
+
prev: "*:single-line"
|
|
1353
|
+
}
|
|
1354
|
+
]],
|
|
1355
|
+
"vue/prefer-prop-type-boolean-first": "error",
|
|
1356
|
+
"vue/prefer-separate-static-class": "error",
|
|
1357
|
+
"vue/prefer-single-event-payload": "error",
|
|
1358
|
+
"vue/prefer-use-template-ref": "error",
|
|
1359
|
+
"vue/slot-name-casing": ["error", "kebab-case"],
|
|
1360
|
+
"vue/v-for-delimiter-style": ["error", "in"]
|
|
1361
|
+
}
|
|
1362
|
+
},
|
|
1363
|
+
{
|
|
1364
|
+
files: [vueGlob],
|
|
1365
|
+
name: "favorodera/vue/a11y/rules",
|
|
1366
|
+
rules: {
|
|
1367
|
+
...a11yRules,
|
|
1368
|
+
"vue-a11y/no-aria-hidden-on-focusable": "error",
|
|
1369
|
+
"vue-a11y/no-onchange": "error",
|
|
1370
|
+
"vue-a11y/no-role-presentation-on-focusable": "error"
|
|
1371
|
+
}
|
|
1304
1372
|
}
|
|
1305
|
-
|
|
1373
|
+
];
|
|
1306
1374
|
}
|
|
1307
1375
|
//#endregion
|
|
1308
1376
|
//#region src/configs/yaml.ts
|
|
1309
|
-
const yamlDefaults = { files: [yamlGlob] };
|
|
1310
1377
|
/**
|
|
1311
1378
|
* Constructs the flat config items for YAML linting, setting up
|
|
1312
1379
|
* the custom parser and rule validations.
|
|
1313
|
-
* @param options YAML configuration options.
|
|
1314
1380
|
* @returns Promise resolving to YAML ESLint config items.
|
|
1315
1381
|
*/
|
|
1316
|
-
async function yaml(
|
|
1317
|
-
const resolved = defu(options, yamlDefaults);
|
|
1382
|
+
async function yaml() {
|
|
1318
1383
|
const [yamlPlugin, yamlParser] = await Promise.all([importModule(import("eslint-plugin-yml")), importModule(import("yaml-eslint-parser"))]);
|
|
1319
|
-
const
|
|
1384
|
+
const standardConfig = yamlPlugin.configs.standard;
|
|
1385
|
+
const [pluginConfig] = standardConfig;
|
|
1386
|
+
const pluginRest = omit(pluginConfig, [
|
|
1387
|
+
"rules",
|
|
1388
|
+
"files",
|
|
1389
|
+
"name"
|
|
1390
|
+
]);
|
|
1391
|
+
const rules = extractRules(standardConfig);
|
|
1320
1392
|
return [
|
|
1321
1393
|
{
|
|
1322
|
-
|
|
1323
|
-
|
|
1394
|
+
...pluginRest,
|
|
1395
|
+
name: "favorodera/yaml/setup"
|
|
1324
1396
|
},
|
|
1325
1397
|
{
|
|
1326
|
-
files:
|
|
1398
|
+
files: [yamlGlob],
|
|
1399
|
+
language: "yaml/yaml",
|
|
1327
1400
|
languageOptions: { parser: yamlParser },
|
|
1328
1401
|
name: "favorodera/yaml/rules",
|
|
1329
1402
|
rules: {
|
|
1330
|
-
...
|
|
1403
|
+
...rules,
|
|
1331
1404
|
"yaml/quotes": ["error", {
|
|
1332
1405
|
avoidEscape: true,
|
|
1333
1406
|
prefer: "single"
|
|
1334
1407
|
}],
|
|
1335
|
-
"yaml/require-string-key": "error"
|
|
1336
|
-
...resolved.overrides
|
|
1408
|
+
"yaml/require-string-key": "error"
|
|
1337
1409
|
}
|
|
1338
1410
|
},
|
|
1339
1411
|
{
|
|
1340
1412
|
files: [pnpmWorkspaceGlob],
|
|
1413
|
+
language: "yaml/yaml",
|
|
1341
1414
|
languageOptions: { parser: yamlParser },
|
|
1342
1415
|
name: "favorodera/yaml/sort/pnpm-workspace-yaml",
|
|
1343
1416
|
rules: { "yaml/sort-keys": [
|
|
@@ -1452,9 +1525,10 @@ function factory(options = {}) {
|
|
|
1452
1525
|
"markdown": "md",
|
|
1453
1526
|
"n": "node",
|
|
1454
1527
|
"vitest": "test",
|
|
1528
|
+
"vuejs-accessibility": "vue-a11y",
|
|
1455
1529
|
"yml": "yaml"
|
|
1456
1530
|
});
|
|
1457
1531
|
return composer;
|
|
1458
1532
|
}
|
|
1459
1533
|
//#endregion
|
|
1460
|
-
export { codeInMdGlob, extractRules, factory, ignoresGlob, importModule, jsGlob, json5Glob, jsonGlob, jsoncGlob, mdGlob, mdInMdGlob, packageJsonGlob, pnpmWorkspaceGlob, scriptsGlob, testGlob, tsConfigGlob, tsGlob, vueGlob, yamlGlob };
|
|
1534
|
+
export { codeInMdGlob, extractRules, factory, ignoresGlob, importModule, jsGlob, json5Glob, jsonGlob, jsoncGlob, mdGlob, mdInMdGlob, omit, packageJsonGlob, pnpmWorkspaceGlob, scriptsGlob, testGlob, tsConfigGlob, tsGlob, vueGlob, yamlGlob };
|