@favorodera/eslint-config 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -6
- package/dist/index.cjs +542 -393
- package/dist/index.d.cts +5963 -1590
- package/dist/index.d.mts +5965 -1592
- package/dist/index.mjs +574 -425
- package/package.json +4 -1
package/dist/index.cjs
CHANGED
|
@@ -23,11 +23,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
//#endregion
|
|
24
24
|
let eslint_flat_config_utils = require("eslint-flat-config-utils");
|
|
25
25
|
let defu = require("defu");
|
|
26
|
+
let globals = require("globals");
|
|
27
|
+
globals = __toESM(globals, 1);
|
|
26
28
|
let eslint_merge_processors = require("eslint-merge-processors");
|
|
27
29
|
let eslint_processor_vue_blocks = require("eslint-processor-vue-blocks");
|
|
28
30
|
eslint_processor_vue_blocks = __toESM(eslint_processor_vue_blocks, 1);
|
|
29
|
-
let globals = require("globals");
|
|
30
|
-
globals = __toESM(globals, 1);
|
|
31
31
|
//#region src/globs.ts
|
|
32
32
|
/** Glob pattern for matching JavaScript files */
|
|
33
33
|
const jsGlob = "**/*.{js,cjs,mjs}";
|
|
@@ -51,11 +51,9 @@ const jsoncGlob = "**/*.jsonc";
|
|
|
51
51
|
const tsConfigGlob = ["**/tsconfig.json", "**/tsconfig.*.json"];
|
|
52
52
|
/** Glob pattern for matching package.json files */
|
|
53
53
|
const packageJsonGlob = "**/package.json";
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
*/
|
|
58
|
-
const ignoresGlob = [
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region src/configs/ignores.ts
|
|
56
|
+
const defaultPatterns = [
|
|
59
57
|
"**/node_modules/**",
|
|
60
58
|
"**/dist/**",
|
|
61
59
|
"**/package-lock.json",
|
|
@@ -92,9 +90,28 @@ const ignoresGlob = [
|
|
|
92
90
|
"**/.agents",
|
|
93
91
|
"**/.*/skills"
|
|
94
92
|
];
|
|
93
|
+
/**
|
|
94
|
+
* Globs for ignoring files and directories from ESLint scanning.
|
|
95
|
+
* @param patterns Additional ignore patterns or a function to modify the defaults.
|
|
96
|
+
* @returns An array containing the ignore flat config item.
|
|
97
|
+
*/
|
|
98
|
+
function ignores(patterns = []) {
|
|
99
|
+
return [{
|
|
100
|
+
ignores: typeof patterns === "function" ? patterns(defaultPatterns) : [...defaultPatterns, ...patterns],
|
|
101
|
+
name: "favorodera/ignores"
|
|
102
|
+
}];
|
|
103
|
+
}
|
|
95
104
|
//#endregion
|
|
96
105
|
//#region src/utils.ts
|
|
97
106
|
/**
|
|
107
|
+
* Extracts and merges the rules from multiple ESLint configuration arrays.
|
|
108
|
+
* @param configArrays Rest parameter representing multiple arrays of ESLint flat config items.
|
|
109
|
+
* @returns A single object containing all the merged rules from the provided configurations.
|
|
110
|
+
*/
|
|
111
|
+
function extractRules(...configArrays) {
|
|
112
|
+
return Object.assign({}, ...configArrays.flat().map((config) => config?.rules || {}));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
98
115
|
* Resolves a module (or a promise of one) and returns its default export
|
|
99
116
|
* if present, otherwise returns the module itself.
|
|
100
117
|
*
|
|
@@ -121,108 +138,6 @@ function resolveOptions(value, defaults) {
|
|
|
121
138
|
if (!value) return false;
|
|
122
139
|
return (0, defu.defu)(value === true ? {} : value, defaults);
|
|
123
140
|
}
|
|
124
|
-
/**
|
|
125
|
-
* Extracts and merges the rules from multiple ESLint configuration arrays.
|
|
126
|
-
* @param configArrays Rest parameter representing multiple arrays of ESLint flat config items.
|
|
127
|
-
* @returns A single object containing all the merged rules from the provided configurations.
|
|
128
|
-
*/
|
|
129
|
-
function extractRules(...configArrays) {
|
|
130
|
-
return Object.assign({}, ...configArrays.flat().map((config) => config?.rules || {}));
|
|
131
|
-
}
|
|
132
|
-
//#endregion
|
|
133
|
-
//#region src/configs/vue.ts
|
|
134
|
-
const sfcBlocksDefaults = { blocks: {
|
|
135
|
-
styles: true,
|
|
136
|
-
customBlocks: true,
|
|
137
|
-
template: false
|
|
138
|
-
} };
|
|
139
|
-
const vueDefaults = {
|
|
140
|
-
files: [vueGlob],
|
|
141
|
-
sfcBlocks: sfcBlocksDefaults
|
|
142
|
-
};
|
|
143
|
-
/**
|
|
144
|
-
* Constructs the flat config items for Vue linting, setting up the custom template parser,
|
|
145
|
-
* Vue block processors, and rules to enforce recommended component syntax.
|
|
146
|
-
* @param options Vue configuration options.
|
|
147
|
-
* @returns Promise resolving to Vue ESLint config items.
|
|
148
|
-
*/
|
|
149
|
-
async function vue(options) {
|
|
150
|
-
const resolved = (0, defu.defu)(options, vueDefaults);
|
|
151
|
-
const sfcBlocks = resolveOptions(resolved.sfcBlocks, sfcBlocksDefaults);
|
|
152
|
-
const [vuePlugin, vueParser, tsEsLint] = await Promise.all([
|
|
153
|
-
importModule(import("eslint-plugin-vue")),
|
|
154
|
-
importModule(import("vue-eslint-parser")),
|
|
155
|
-
importModule(import("typescript-eslint"))
|
|
156
|
-
]);
|
|
157
|
-
const baseRules = extractRules(vuePlugin.configs["flat/essential"], vuePlugin.configs["flat/strongly-recommended"], vuePlugin.configs["flat/recommended"]);
|
|
158
|
-
const processor = sfcBlocks === false ? vuePlugin.processors[".vue"] : (0, eslint_merge_processors.mergeProcessors)([vuePlugin.processors[".vue"], (0, eslint_processor_vue_blocks.default)(sfcBlocks)]);
|
|
159
|
-
return [{
|
|
160
|
-
name: "favorodera/vue/setup",
|
|
161
|
-
plugins: { vue: vuePlugin },
|
|
162
|
-
languageOptions: { globals: {
|
|
163
|
-
computed: "readonly",
|
|
164
|
-
defineEmits: "readonly",
|
|
165
|
-
defineExpose: "readonly",
|
|
166
|
-
defineProps: "readonly",
|
|
167
|
-
onMounted: "readonly",
|
|
168
|
-
onUnmounted: "readonly",
|
|
169
|
-
reactive: "readonly",
|
|
170
|
-
ref: "readonly",
|
|
171
|
-
shallowReactive: "readonly",
|
|
172
|
-
shallowRef: "readonly",
|
|
173
|
-
toRef: "readonly",
|
|
174
|
-
toRefs: "readonly",
|
|
175
|
-
watch: "readonly",
|
|
176
|
-
watchEffect: "readonly"
|
|
177
|
-
} }
|
|
178
|
-
}, {
|
|
179
|
-
name: "favorodera/vue/rules",
|
|
180
|
-
files: resolved.files,
|
|
181
|
-
languageOptions: {
|
|
182
|
-
parser: vueParser,
|
|
183
|
-
parserOptions: {
|
|
184
|
-
parser: tsEsLint.parser,
|
|
185
|
-
extraFileExtensions: [".vue"],
|
|
186
|
-
sourceType: "module"
|
|
187
|
-
}
|
|
188
|
-
},
|
|
189
|
-
processor,
|
|
190
|
-
rules: {
|
|
191
|
-
...baseRules,
|
|
192
|
-
"vue/block-order": ["error", { order: [
|
|
193
|
-
"script",
|
|
194
|
-
"template",
|
|
195
|
-
"style"
|
|
196
|
-
] }],
|
|
197
|
-
"vue/component-name-in-template-casing": ["error", "PascalCase"],
|
|
198
|
-
"vue/component-options-name-casing": ["error", "PascalCase"],
|
|
199
|
-
"vue/multi-word-component-names": "off",
|
|
200
|
-
"vue/block-tag-newline": ["error", {
|
|
201
|
-
multiline: "ignore",
|
|
202
|
-
singleline: "ignore"
|
|
203
|
-
}],
|
|
204
|
-
"vue/multiline-html-element-content-newline": ["error", {
|
|
205
|
-
allowEmptyLines: true,
|
|
206
|
-
ignores: ["pre", "textarea"]
|
|
207
|
-
}],
|
|
208
|
-
...resolved.overrides
|
|
209
|
-
}
|
|
210
|
-
}];
|
|
211
|
-
}
|
|
212
|
-
//#endregion
|
|
213
|
-
//#region src/configs/ignores.ts
|
|
214
|
-
const defaultPatterns = ignoresGlob;
|
|
215
|
-
/**
|
|
216
|
-
* Globs for ignoring files and directories from ESLint scanning.
|
|
217
|
-
* @param patterns Additional ignore patterns or a function to modify the defaults.
|
|
218
|
-
* @returns An array containing the ignore flat config item.
|
|
219
|
-
*/
|
|
220
|
-
function ignores(patterns = []) {
|
|
221
|
-
return [{
|
|
222
|
-
name: "favorodera/ignores",
|
|
223
|
-
ignores: typeof patterns === "function" ? patterns(defaultPatterns) : [...defaultPatterns, ...patterns]
|
|
224
|
-
}];
|
|
225
|
-
}
|
|
226
141
|
//#endregion
|
|
227
142
|
//#region src/configs/imports.ts
|
|
228
143
|
const importsDefaults = { files: [
|
|
@@ -247,16 +162,16 @@ async function imports(options) {
|
|
|
247
162
|
"unused-imports": unusedImportsPlugin
|
|
248
163
|
}
|
|
249
164
|
}, {
|
|
250
|
-
name: "favorodera/imports/rules",
|
|
251
165
|
files: resolved.files,
|
|
166
|
+
name: "favorodera/imports/rules",
|
|
252
167
|
rules: {
|
|
253
168
|
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { "import-lite": "import" }),
|
|
254
|
-
"import/consistent-type-specifier-style": ["error", "top-level"],
|
|
169
|
+
"import/consistent-type-specifier-style": ["error", "prefer-top-level"],
|
|
255
170
|
"import/first": "error",
|
|
171
|
+
"import/newline-after-import": ["error", { count: 1 }],
|
|
256
172
|
"import/no-duplicates": "error",
|
|
257
173
|
"import/no-mutable-exports": "error",
|
|
258
174
|
"import/no-named-default": "error",
|
|
259
|
-
"import/newline-after-import": ["error", { count: 1 }],
|
|
260
175
|
"unused-imports/no-unused-imports": "error",
|
|
261
176
|
"unused-imports/no-unused-vars": ["error", {
|
|
262
177
|
args: "after-used",
|
|
@@ -286,10 +201,8 @@ async function javascript(options) {
|
|
|
286
201
|
const resolved = (0, defu.defu)(options, javascriptDefaults);
|
|
287
202
|
const baseRules = (await importModule(import("@eslint/js"))).configs.recommended.rules;
|
|
288
203
|
return [{
|
|
289
|
-
name: "favorodera/javascript/setup",
|
|
290
204
|
languageOptions: {
|
|
291
205
|
ecmaVersion: "latest",
|
|
292
|
-
sourceType: "module",
|
|
293
206
|
globals: {
|
|
294
207
|
...globals.default.browser,
|
|
295
208
|
...globals.default.es2021,
|
|
@@ -297,12 +210,14 @@ async function javascript(options) {
|
|
|
297
210
|
document: "readonly",
|
|
298
211
|
navigator: "readonly",
|
|
299
212
|
window: "readonly"
|
|
300
|
-
}
|
|
213
|
+
},
|
|
214
|
+
sourceType: "module"
|
|
301
215
|
},
|
|
302
|
-
linterOptions: { reportUnusedDisableDirectives: true }
|
|
216
|
+
linterOptions: { reportUnusedDisableDirectives: true },
|
|
217
|
+
name: "favorodera/javascript/setup"
|
|
303
218
|
}, {
|
|
304
|
-
name: "favorodera/javascript/rules",
|
|
305
219
|
files: resolved.files,
|
|
220
|
+
name: "favorodera/javascript/rules",
|
|
306
221
|
rules: {
|
|
307
222
|
...baseRules,
|
|
308
223
|
"accessor-pairs": ["error", {
|
|
@@ -316,232 +231,87 @@ async function javascript(options) {
|
|
|
316
231
|
}];
|
|
317
232
|
}
|
|
318
233
|
//#endregion
|
|
319
|
-
//#region src/configs/
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
234
|
+
//#region src/configs/jsdoc.ts
|
|
235
|
+
const jsdocDefaults = { files: [
|
|
236
|
+
jsGlob,
|
|
237
|
+
tsGlob,
|
|
238
|
+
vueGlob
|
|
239
|
+
] };
|
|
324
240
|
/**
|
|
325
|
-
* Constructs the flat config items for
|
|
326
|
-
*
|
|
327
|
-
* @param options
|
|
328
|
-
* @returns Promise resolving to
|
|
241
|
+
* Constructs the flat config items for JSDoc linting, ensuring comments follow
|
|
242
|
+
* proper styling, parameter checks, and types alignment.
|
|
243
|
+
* @param options JSDoc configuration options.
|
|
244
|
+
* @returns Promise resolving to JSDoc ESLint config items.
|
|
329
245
|
*/
|
|
330
|
-
async function
|
|
331
|
-
const resolved = (0, defu.defu)(options,
|
|
332
|
-
const
|
|
333
|
-
const baseRules =
|
|
246
|
+
async function jsdoc(options) {
|
|
247
|
+
const resolved = (0, defu.defu)(options, jsdocDefaults);
|
|
248
|
+
const jsdocPlugin = await importModule(import("eslint-plugin-jsdoc"));
|
|
249
|
+
const baseRules = {
|
|
250
|
+
...jsdocPlugin.configs["flat/recommended-typescript-error"]?.rules,
|
|
251
|
+
...jsdocPlugin.configs["flat/stylistic-typescript-error"]?.rules
|
|
252
|
+
};
|
|
253
|
+
return [{
|
|
254
|
+
name: "favorodera/jsdoc/setup",
|
|
255
|
+
plugins: { jsdoc: jsdocPlugin }
|
|
256
|
+
}, {
|
|
257
|
+
files: resolved.files,
|
|
258
|
+
name: "favorodera/tailwind/rules",
|
|
259
|
+
rules: {
|
|
260
|
+
...baseRules,
|
|
261
|
+
"jsdoc/check-access": "warn",
|
|
262
|
+
"jsdoc/check-alignment": "warn",
|
|
263
|
+
"jsdoc/check-param-names": "warn",
|
|
264
|
+
"jsdoc/check-property-names": "warn",
|
|
265
|
+
"jsdoc/check-types": "warn",
|
|
266
|
+
"jsdoc/empty-tags": "warn",
|
|
267
|
+
"jsdoc/implements-on-classes": "warn",
|
|
268
|
+
"jsdoc/multiline-blocks": "warn",
|
|
269
|
+
"jsdoc/no-defaults": "warn",
|
|
270
|
+
"jsdoc/no-multi-asterisks": "warn",
|
|
271
|
+
"jsdoc/require-param-name": "warn",
|
|
272
|
+
"jsdoc/require-property": "warn",
|
|
273
|
+
"jsdoc/require-property-description": "warn",
|
|
274
|
+
"jsdoc/require-property-name": "warn",
|
|
275
|
+
"jsdoc/require-returns-check": "warn",
|
|
276
|
+
"jsdoc/require-returns-description": "warn",
|
|
277
|
+
"jsdoc/require-yields-check": "warn",
|
|
278
|
+
...resolved.overrides
|
|
279
|
+
}
|
|
280
|
+
}];
|
|
281
|
+
}
|
|
282
|
+
//#endregion
|
|
283
|
+
//#region src/configs/jsonc.ts
|
|
284
|
+
const jsoncDefaults = { files: [
|
|
285
|
+
json5Glob,
|
|
286
|
+
jsoncGlob,
|
|
287
|
+
jsonGlob
|
|
288
|
+
] };
|
|
289
|
+
/**
|
|
290
|
+
* Constructs the flat config items for JSON, JSON5, and JSONC linting, setting up
|
|
291
|
+
* the custom parser, rule validations, and sorting rules for package.json/tsconfig.json.
|
|
292
|
+
* @param options JSONC configuration options.
|
|
293
|
+
* @returns Promise resolving to JSONC ESLint config items.
|
|
294
|
+
*/
|
|
295
|
+
async function jsonc(options) {
|
|
296
|
+
const resolved = (0, defu.defu)(options, jsoncDefaults);
|
|
334
297
|
return [
|
|
335
298
|
{
|
|
336
|
-
name: "favorodera/
|
|
337
|
-
plugins: {
|
|
299
|
+
name: "favorodera/jsonc/setup",
|
|
300
|
+
plugins: { jsonc: await importModule(import("eslint-plugin-jsonc")) }
|
|
338
301
|
},
|
|
339
302
|
{
|
|
340
|
-
name: "favorodera/markdown/rules",
|
|
341
303
|
files: resolved.files,
|
|
342
|
-
language:
|
|
343
|
-
|
|
344
|
-
processor: (0, eslint_merge_processors.mergeProcessors)([markdownPlugin.processors?.markdown, eslint_merge_processors.processorPassThrough]),
|
|
345
|
-
rules: {
|
|
346
|
-
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { markdown: "md" }),
|
|
347
|
-
"md/fenced-code-language": "off",
|
|
348
|
-
"md/no-missing-label-refs": "off",
|
|
349
|
-
...resolved.overrides
|
|
350
|
-
}
|
|
351
|
-
},
|
|
352
|
-
{
|
|
353
|
-
name: "favorodera/markdown/disables/code",
|
|
354
|
-
files: [codeInMdGlob],
|
|
355
|
-
languageOptions: { parserOptions: { ecmaFeatures: { impliedStrict: true } } },
|
|
356
|
-
rules: {
|
|
357
|
-
"no-alert": "off",
|
|
358
|
-
"no-console": "off",
|
|
359
|
-
"no-labels": "off",
|
|
360
|
-
"no-lone-blocks": "off",
|
|
361
|
-
"no-restricted-syntax": "off",
|
|
362
|
-
"no-undef": "off",
|
|
363
|
-
"no-unused-expressions": "off",
|
|
364
|
-
"no-unused-labels": "off",
|
|
365
|
-
"no-unused-vars": "off",
|
|
366
|
-
"node/prefer-global/process": "off",
|
|
367
|
-
"style/comma-dangle": "off",
|
|
368
|
-
"style/eol-last": "off",
|
|
369
|
-
"style/padding-line-between-statements": "off",
|
|
370
|
-
"ts/consistent-type-imports": "off",
|
|
371
|
-
"ts/explicit-function-return-type": "off",
|
|
372
|
-
"ts/no-namespace": "off",
|
|
373
|
-
"ts/no-redeclare": "off",
|
|
374
|
-
"ts/no-require-imports": "off",
|
|
375
|
-
"ts/no-unused-expressions": "off",
|
|
376
|
-
"ts/no-unused-vars": "off",
|
|
377
|
-
"ts/no-use-before-define": "off",
|
|
378
|
-
"unicode-bom": "off",
|
|
379
|
-
"unused-imports/no-unused-imports": "off",
|
|
380
|
-
"unused-imports/no-unused-vars": "off"
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
];
|
|
384
|
-
}
|
|
385
|
-
//#endregion
|
|
386
|
-
//#region src/configs/stylistic.ts
|
|
387
|
-
const stylisticDefaults = {
|
|
388
|
-
settings: {
|
|
389
|
-
indent: 2,
|
|
390
|
-
experimental: false,
|
|
391
|
-
quotes: "single",
|
|
392
|
-
semi: false,
|
|
393
|
-
jsx: false
|
|
394
|
-
},
|
|
395
|
-
files: [
|
|
396
|
-
jsGlob,
|
|
397
|
-
tsGlob,
|
|
398
|
-
vueGlob
|
|
399
|
-
]
|
|
400
|
-
};
|
|
401
|
-
/**
|
|
402
|
-
* Constructs the flat config items for Stylistic linting, applying customized
|
|
403
|
-
* formatting settings such as quotes, indentation, and spacing.
|
|
404
|
-
* @param options Stylistic configuration options.
|
|
405
|
-
* @returns Promise resolving to stylistic ESLint config items.
|
|
406
|
-
*/
|
|
407
|
-
async function stylistic(options) {
|
|
408
|
-
const resolved = (0, defu.defu)(options, stylisticDefaults);
|
|
409
|
-
const stylePlugin = await importModule(import("@stylistic/eslint-plugin"));
|
|
410
|
-
const baseRules = stylePlugin.configs.customize({
|
|
411
|
-
pluginName: "style",
|
|
412
|
-
...resolved.settings
|
|
413
|
-
})?.rules || {};
|
|
414
|
-
return [{
|
|
415
|
-
name: "favorodera/stylistic/setup",
|
|
416
|
-
plugins: { style: stylePlugin }
|
|
417
|
-
}, {
|
|
418
|
-
name: "favorodera/stylistic/rules",
|
|
419
|
-
files: resolved.files,
|
|
420
|
-
rules: {
|
|
421
|
-
...baseRules,
|
|
422
|
-
"style/quotes": [
|
|
423
|
-
"error",
|
|
424
|
-
"single",
|
|
425
|
-
{ avoidEscape: true }
|
|
426
|
-
],
|
|
427
|
-
"style/no-multiple-empty-lines": ["error", {
|
|
428
|
-
max: 2,
|
|
429
|
-
maxEOF: 2,
|
|
430
|
-
maxBOF: 0
|
|
431
|
-
}],
|
|
432
|
-
"style/padded-blocks": "off",
|
|
433
|
-
"style/no-trailing-spaces": ["error", { skipBlankLines: true }],
|
|
434
|
-
"style/brace-style": "off",
|
|
435
|
-
"style/generator-star-spacing": ["error", {
|
|
436
|
-
after: true,
|
|
437
|
-
before: false
|
|
438
|
-
}],
|
|
439
|
-
"style/yield-star-spacing": ["error", {
|
|
440
|
-
after: true,
|
|
441
|
-
before: false
|
|
442
|
-
}],
|
|
443
|
-
...resolved.overrides
|
|
444
|
-
}
|
|
445
|
-
}];
|
|
446
|
-
}
|
|
447
|
-
//#endregion
|
|
448
|
-
//#region src/configs/tailwind.ts
|
|
449
|
-
const tailwindDefaults = {
|
|
450
|
-
files: [
|
|
451
|
-
jsGlob,
|
|
452
|
-
tsGlob,
|
|
453
|
-
vueGlob
|
|
454
|
-
],
|
|
455
|
-
settings: { detectComponentClasses: true }
|
|
456
|
-
};
|
|
457
|
-
/**
|
|
458
|
-
* Constructs the flat config items for Tailwind CSS linting, providing custom settings
|
|
459
|
-
* to parse and lint utility classes, and enforcing consistent ordering.
|
|
460
|
-
* @param options Tailwind configuration options.
|
|
461
|
-
* @returns Promise resolving to Tailwind ESLint config items.
|
|
462
|
-
*/
|
|
463
|
-
async function tailwind(options) {
|
|
464
|
-
const resolved = (0, defu.defu)(options, tailwindDefaults);
|
|
465
|
-
const tailwindPlugin = await importModule(import("eslint-plugin-better-tailwindcss"));
|
|
466
|
-
const baseRules = {
|
|
467
|
-
...tailwindPlugin.configs["recommended-error"].rules,
|
|
468
|
-
...tailwindPlugin.configs["stylistic-error"].rules
|
|
469
|
-
};
|
|
470
|
-
return [{
|
|
471
|
-
name: "favorodera/tailwind/setup",
|
|
472
|
-
plugins: { tailwind: tailwindPlugin },
|
|
473
|
-
settings: { tailwindcss: resolved.settings }
|
|
474
|
-
}, {
|
|
475
|
-
name: "favorodera/tailwind/rules",
|
|
476
|
-
files: resolved.files,
|
|
477
|
-
rules: {
|
|
478
|
-
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { "better-tailwindcss": "tailwind" }),
|
|
479
|
-
"tailwind/no-unregistered-classes": "off",
|
|
480
|
-
"tailwind/enforce-consistent-line-wrapping": ["error", { group: "emptyLine" }],
|
|
481
|
-
...resolved.overrides
|
|
482
|
-
}
|
|
483
|
-
}];
|
|
484
|
-
}
|
|
485
|
-
//#endregion
|
|
486
|
-
//#region src/configs/typescript.ts
|
|
487
|
-
const typescriptDefaults = { files: [tsGlob] };
|
|
488
|
-
/**
|
|
489
|
-
* Constructs the flat config items for TypeScript linting, initializing the parser
|
|
490
|
-
* and extending the recommended and strict type-aware rule sets.
|
|
491
|
-
* @param options TypeScript configuration options.
|
|
492
|
-
* @returns Promise resolving to TypeScript ESLint config items.
|
|
493
|
-
*/
|
|
494
|
-
async function typescript(options) {
|
|
495
|
-
const resolved = (0, defu.defu)(options, typescriptDefaults);
|
|
496
|
-
const tsEsLint = await importModule(import("typescript-eslint"));
|
|
497
|
-
const baseRules = extractRules(tsEsLint.configs.recommended, tsEsLint.configs.strict);
|
|
498
|
-
return [{
|
|
499
|
-
name: "favorodera/typescript/setup",
|
|
500
|
-
plugins: { ts: tsEsLint.plugin }
|
|
501
|
-
}, {
|
|
502
|
-
name: "favorodera/typescript/rules",
|
|
503
|
-
files: resolved.files,
|
|
504
|
-
languageOptions: {
|
|
505
|
-
parser: tsEsLint.parser,
|
|
506
|
-
parserOptions: { sourceType: "module" }
|
|
507
|
-
},
|
|
508
|
-
rules: {
|
|
509
|
-
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { "@typescript-eslint": "ts" }),
|
|
510
|
-
"ts/consistent-type-imports": ["error", { prefer: "type-imports" }],
|
|
511
|
-
"ts/no-empty-object-type": ["error", { allowInterfaces: "with-single-extends" }],
|
|
512
|
-
"ts/array-type": ["error", {
|
|
513
|
-
default: "generic",
|
|
514
|
-
readonly: "generic"
|
|
515
|
-
}],
|
|
516
|
-
...resolved.overrides
|
|
517
|
-
}
|
|
518
|
-
}];
|
|
519
|
-
}
|
|
520
|
-
//#endregion
|
|
521
|
-
//#region src/configs/jsonc.ts
|
|
522
|
-
const jsoncDefaults = { files: [
|
|
523
|
-
json5Glob,
|
|
524
|
-
jsoncGlob,
|
|
525
|
-
jsonGlob
|
|
526
|
-
] };
|
|
527
|
-
/**
|
|
528
|
-
* Constructs the flat config items for JSON, JSON5, and JSONC linting, setting up
|
|
529
|
-
* the custom parser, rule validations, and sorting rules for package.json/tsconfig.json.
|
|
530
|
-
* @param options JSONC configuration options.
|
|
531
|
-
* @returns Promise resolving to JSONC ESLint config items.
|
|
532
|
-
*/
|
|
533
|
-
async function jsonc(options) {
|
|
534
|
-
const resolved = (0, defu.defu)(options, jsoncDefaults);
|
|
535
|
-
return [
|
|
536
|
-
{
|
|
537
|
-
name: "favorodera/jsonc/setup",
|
|
538
|
-
plugins: { jsonc: await importModule(import("eslint-plugin-jsonc")) }
|
|
539
|
-
},
|
|
540
|
-
{
|
|
541
|
-
name: "favorodera/jsonc/rules",
|
|
542
|
-
files: resolved.files,
|
|
543
|
-
language: "jsonc/x",
|
|
304
|
+
language: "jsonc/x",
|
|
305
|
+
name: "favorodera/jsonc/rules",
|
|
544
306
|
rules: {
|
|
307
|
+
"jsonc/array-bracket-spacing": ["error", "never"],
|
|
308
|
+
"jsonc/comma-dangle": ["error", "never"],
|
|
309
|
+
"jsonc/comma-style": ["error", "last"],
|
|
310
|
+
"jsonc/indent": ["error", 2],
|
|
311
|
+
"jsonc/key-spacing": ["error", {
|
|
312
|
+
afterColon: true,
|
|
313
|
+
beforeColon: false
|
|
314
|
+
}],
|
|
545
315
|
"jsonc/no-bigint-literals": "error",
|
|
546
316
|
"jsonc/no-binary-expression": "error",
|
|
547
317
|
"jsonc/no-binary-numeric-literals": "error",
|
|
@@ -565,17 +335,6 @@ async function jsonc(options) {
|
|
|
565
335
|
"jsonc/no-undefined-value": "error",
|
|
566
336
|
"jsonc/no-unicode-codepoint-escapes": "error",
|
|
567
337
|
"jsonc/no-useless-escape": "error",
|
|
568
|
-
"jsonc/space-unary-ops": "error",
|
|
569
|
-
"jsonc/valid-json-number": "error",
|
|
570
|
-
"jsonc/vue-custom-block/no-parsing-error": "error",
|
|
571
|
-
"jsonc/array-bracket-spacing": ["error", "never"],
|
|
572
|
-
"jsonc/comma-dangle": ["error", "never"],
|
|
573
|
-
"jsonc/comma-style": ["error", "last"],
|
|
574
|
-
"jsonc/indent": ["error", 2],
|
|
575
|
-
"jsonc/key-spacing": ["error", {
|
|
576
|
-
afterColon: true,
|
|
577
|
-
beforeColon: false
|
|
578
|
-
}],
|
|
579
338
|
"jsonc/object-curly-newline": ["error", {
|
|
580
339
|
consistent: true,
|
|
581
340
|
multiline: true
|
|
@@ -584,12 +343,15 @@ async function jsonc(options) {
|
|
|
584
343
|
"jsonc/object-property-newline": ["error", { allowAllPropertiesOnSameLine: true }],
|
|
585
344
|
"jsonc/quote-props": "error",
|
|
586
345
|
"jsonc/quotes": "error",
|
|
346
|
+
"jsonc/space-unary-ops": "error",
|
|
347
|
+
"jsonc/valid-json-number": "error",
|
|
348
|
+
"jsonc/vue-custom-block/no-parsing-error": "error",
|
|
587
349
|
...resolved.overrides
|
|
588
350
|
}
|
|
589
351
|
},
|
|
590
352
|
{
|
|
591
|
-
name: "favorodera/jsonc/sort/package-json",
|
|
592
353
|
files: [packageJsonGlob],
|
|
354
|
+
name: "favorodera/jsonc/sort/package-json",
|
|
593
355
|
rules: {
|
|
594
356
|
"jsonc/sort-array-values": ["error", {
|
|
595
357
|
order: { type: "asc" },
|
|
@@ -657,11 +419,11 @@ async function jsonc(options) {
|
|
|
657
419
|
},
|
|
658
420
|
{
|
|
659
421
|
order: { type: "asc" },
|
|
660
|
-
pathPattern:
|
|
422
|
+
pathPattern: String.raw`^workspaces\.catalog$`
|
|
661
423
|
},
|
|
662
424
|
{
|
|
663
425
|
order: { type: "asc" },
|
|
664
|
-
pathPattern:
|
|
426
|
+
pathPattern: String.raw`^workspaces\.catalogs\.[^.]+$`
|
|
665
427
|
},
|
|
666
428
|
{
|
|
667
429
|
order: [
|
|
@@ -691,8 +453,8 @@ async function jsonc(options) {
|
|
|
691
453
|
}
|
|
692
454
|
},
|
|
693
455
|
{
|
|
694
|
-
name: "favorodera/jsonc/sort/tsconfig-json",
|
|
695
456
|
files: tsConfigGlob,
|
|
457
|
+
name: "favorodera/jsonc/sort/tsconfig-json",
|
|
696
458
|
rules: { "jsonc/sort-keys": [
|
|
697
459
|
"error",
|
|
698
460
|
{
|
|
@@ -807,50 +569,434 @@ async function jsonc(options) {
|
|
|
807
569
|
];
|
|
808
570
|
}
|
|
809
571
|
//#endregion
|
|
810
|
-
//#region src/configs/
|
|
811
|
-
const
|
|
572
|
+
//#region src/configs/markdown.ts
|
|
573
|
+
const markdownDefaults = {
|
|
574
|
+
files: [mdGlob],
|
|
575
|
+
gfm: true
|
|
576
|
+
};
|
|
577
|
+
/**
|
|
578
|
+
* Constructs the flat config items for Markdown linting, extracting and linting
|
|
579
|
+
* embedded code blocks within the document according to specified rules.
|
|
580
|
+
* @param options Markdown configuration options.
|
|
581
|
+
* @returns Promise resolving to Markdown ESLint config items.
|
|
582
|
+
*/
|
|
583
|
+
async function markdown(options) {
|
|
584
|
+
const resolved = (0, defu.defu)(options, markdownDefaults);
|
|
585
|
+
const markdownPlugin = await importModule(import("@eslint/markdown"));
|
|
586
|
+
const baseRules = extractRules(markdownPlugin.configs.recommended);
|
|
587
|
+
return [
|
|
588
|
+
{
|
|
589
|
+
name: "favorodera/markdown/setup",
|
|
590
|
+
plugins: { md: markdownPlugin }
|
|
591
|
+
},
|
|
592
|
+
{
|
|
593
|
+
files: resolved.files,
|
|
594
|
+
ignores: [mdInMdGlob],
|
|
595
|
+
language: resolved.gfm ? "md/gfm" : "md/commonmark",
|
|
596
|
+
name: "favorodera/markdown/rules",
|
|
597
|
+
processor: (0, eslint_merge_processors.mergeProcessors)([markdownPlugin.processors?.markdown, eslint_merge_processors.processorPassThrough]),
|
|
598
|
+
rules: {
|
|
599
|
+
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { markdown: "md" }),
|
|
600
|
+
"md/fenced-code-language": "off",
|
|
601
|
+
"md/no-missing-label-refs": "off",
|
|
602
|
+
...resolved.overrides
|
|
603
|
+
}
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
files: [codeInMdGlob],
|
|
607
|
+
languageOptions: { parserOptions: { ecmaFeatures: { impliedStrict: true } } },
|
|
608
|
+
name: "favorodera/markdown/disables/code",
|
|
609
|
+
rules: {
|
|
610
|
+
"no-alert": "off",
|
|
611
|
+
"no-console": "off",
|
|
612
|
+
"no-labels": "off",
|
|
613
|
+
"no-lone-blocks": "off",
|
|
614
|
+
"no-restricted-syntax": "off",
|
|
615
|
+
"no-undef": "off",
|
|
616
|
+
"no-unused-expressions": "off",
|
|
617
|
+
"no-unused-labels": "off",
|
|
618
|
+
"no-unused-vars": "off",
|
|
619
|
+
"node/prefer-global/process": "off",
|
|
620
|
+
"style/comma-dangle": "off",
|
|
621
|
+
"style/eol-last": "off",
|
|
622
|
+
"style/padding-line-between-statements": "off",
|
|
623
|
+
"ts/consistent-type-imports": "off",
|
|
624
|
+
"ts/explicit-function-return-type": "off",
|
|
625
|
+
"ts/no-namespace": "off",
|
|
626
|
+
"ts/no-redeclare": "off",
|
|
627
|
+
"ts/no-require-imports": "off",
|
|
628
|
+
"ts/no-unused-expressions": "off",
|
|
629
|
+
"ts/no-unused-vars": "off",
|
|
630
|
+
"ts/no-use-before-define": "off",
|
|
631
|
+
"unicode-bom": "off",
|
|
632
|
+
"unused-imports/no-unused-imports": "off",
|
|
633
|
+
"unused-imports/no-unused-vars": "off"
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
];
|
|
637
|
+
}
|
|
638
|
+
//#endregion
|
|
639
|
+
//#region src/configs/node.ts
|
|
640
|
+
const nodeDefaults = { files: [
|
|
812
641
|
jsGlob,
|
|
813
642
|
tsGlob,
|
|
814
643
|
vueGlob
|
|
815
644
|
] };
|
|
816
645
|
/**
|
|
817
|
-
* Constructs the flat config items for
|
|
818
|
-
*
|
|
819
|
-
* @param options
|
|
820
|
-
* @returns Promise resolving to
|
|
646
|
+
* Constructs the flat config items for Node.js linting, providing rules
|
|
647
|
+
* to enforce best practices for Node.js environments.
|
|
648
|
+
* @param options Node configuration options.
|
|
649
|
+
* @returns Promise resolving to Node ESLint config items.
|
|
821
650
|
*/
|
|
822
|
-
async function
|
|
823
|
-
const resolved = (0, defu.defu)(options,
|
|
824
|
-
const
|
|
825
|
-
const baseRules = {
|
|
826
|
-
...jsdocPlugin.configs["flat/recommended-typescript-error"]?.rules,
|
|
827
|
-
...jsdocPlugin.configs["flat/stylistic-typescript-error"]?.rules
|
|
828
|
-
};
|
|
651
|
+
async function node(options) {
|
|
652
|
+
const resolved = (0, defu.defu)(options, nodeDefaults);
|
|
653
|
+
const nodePlugin = await importModule(import("eslint-plugin-n"));
|
|
654
|
+
const baseRules = nodePlugin.configs?.["flat/recommended"]?.rules || {};
|
|
829
655
|
return [{
|
|
830
|
-
name: "favorodera/
|
|
831
|
-
plugins: {
|
|
656
|
+
name: "favorodera/node/setup",
|
|
657
|
+
plugins: { node: nodePlugin }
|
|
658
|
+
}, {
|
|
659
|
+
files: resolved.files,
|
|
660
|
+
name: "favorodera/node/rules",
|
|
661
|
+
rules: {
|
|
662
|
+
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { n: "node" }),
|
|
663
|
+
"node/handle-callback-err": ["error", "^(err|error)$"],
|
|
664
|
+
"node/no-deprecated-api": "error",
|
|
665
|
+
"node/no-exports-assign": "error",
|
|
666
|
+
"node/no-missing-import": "off",
|
|
667
|
+
"node/no-new-require": "error",
|
|
668
|
+
"node/no-path-concat": "error",
|
|
669
|
+
"node/no-unpublished-import": "off",
|
|
670
|
+
"node/prefer-global/buffer": ["error", "never"],
|
|
671
|
+
"node/prefer-global/process": ["error", "never"],
|
|
672
|
+
"node/process-exit-as-throw": "error",
|
|
673
|
+
...resolved.overrides
|
|
674
|
+
}
|
|
675
|
+
}];
|
|
676
|
+
}
|
|
677
|
+
//#endregion
|
|
678
|
+
//#region src/configs/perfectionist.ts
|
|
679
|
+
const perfectionistDefaults = { files: [
|
|
680
|
+
jsGlob,
|
|
681
|
+
tsGlob,
|
|
682
|
+
vueGlob
|
|
683
|
+
] };
|
|
684
|
+
/**
|
|
685
|
+
* Constructs the flat config items for Perfectionist linting, providing rules
|
|
686
|
+
* to naturally sort objects, imports, classes, and other elements in your code.
|
|
687
|
+
* @param options Perfectionist configuration options.
|
|
688
|
+
* @returns Promise resolving to Perfectionist ESLint config items.
|
|
689
|
+
*/
|
|
690
|
+
async function perfectionist(options) {
|
|
691
|
+
const resolved = (0, defu.defu)(options, perfectionistDefaults);
|
|
692
|
+
const perfectionistPlugin = await importModule(import("eslint-plugin-perfectionist"));
|
|
693
|
+
const baseRules = perfectionistPlugin.configs["recommended-natural"]?.rules || {};
|
|
694
|
+
return [{
|
|
695
|
+
name: "favorodera/perfectionist/setup",
|
|
696
|
+
plugins: { perfectionist: perfectionistPlugin }
|
|
697
|
+
}, {
|
|
698
|
+
files: resolved.files,
|
|
699
|
+
name: "favorodera/perfectionist/rules",
|
|
700
|
+
rules: {
|
|
701
|
+
...baseRules,
|
|
702
|
+
"perfectionist/sort-exports": ["error", {
|
|
703
|
+
order: "asc",
|
|
704
|
+
type: "natural"
|
|
705
|
+
}],
|
|
706
|
+
"perfectionist/sort-imports": ["error", {
|
|
707
|
+
groups: [
|
|
708
|
+
"type-import",
|
|
709
|
+
[
|
|
710
|
+
"type-parent",
|
|
711
|
+
"type-sibling",
|
|
712
|
+
"type-index",
|
|
713
|
+
"type-internal"
|
|
714
|
+
],
|
|
715
|
+
"value-builtin",
|
|
716
|
+
"value-external",
|
|
717
|
+
"value-internal",
|
|
718
|
+
[
|
|
719
|
+
"value-parent",
|
|
720
|
+
"value-sibling",
|
|
721
|
+
"value-index"
|
|
722
|
+
],
|
|
723
|
+
"side-effect",
|
|
724
|
+
"ts-equals-import",
|
|
725
|
+
"unknown"
|
|
726
|
+
],
|
|
727
|
+
newlinesBetween: "ignore",
|
|
728
|
+
newlinesInside: "ignore",
|
|
729
|
+
order: "asc",
|
|
730
|
+
type: "natural"
|
|
731
|
+
}],
|
|
732
|
+
"perfectionist/sort-named-exports": ["error", {
|
|
733
|
+
order: "asc",
|
|
734
|
+
type: "natural"
|
|
735
|
+
}],
|
|
736
|
+
"perfectionist/sort-named-imports": ["error", {
|
|
737
|
+
order: "asc",
|
|
738
|
+
type: "natural"
|
|
739
|
+
}],
|
|
740
|
+
...resolved.overrides
|
|
741
|
+
}
|
|
742
|
+
}];
|
|
743
|
+
}
|
|
744
|
+
//#endregion
|
|
745
|
+
//#region src/configs/stylistic.ts
|
|
746
|
+
const stylisticDefaults = {
|
|
747
|
+
files: [
|
|
748
|
+
jsGlob,
|
|
749
|
+
tsGlob,
|
|
750
|
+
vueGlob
|
|
751
|
+
],
|
|
752
|
+
settings: {
|
|
753
|
+
experimental: false,
|
|
754
|
+
indent: 2,
|
|
755
|
+
jsx: false,
|
|
756
|
+
quotes: "single",
|
|
757
|
+
semi: false
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
/**
|
|
761
|
+
* Constructs the flat config items for Stylistic linting, applying customized
|
|
762
|
+
* formatting settings such as quotes, indentation, and spacing.
|
|
763
|
+
* @param options Stylistic configuration options.
|
|
764
|
+
* @returns Promise resolving to stylistic ESLint config items.
|
|
765
|
+
*/
|
|
766
|
+
async function stylistic(options) {
|
|
767
|
+
const resolved = (0, defu.defu)(options, stylisticDefaults);
|
|
768
|
+
const stylePlugin = await importModule(import("@stylistic/eslint-plugin"));
|
|
769
|
+
const baseRules = stylePlugin.configs.customize({
|
|
770
|
+
pluginName: "style",
|
|
771
|
+
...resolved.settings
|
|
772
|
+
})?.rules || {};
|
|
773
|
+
return [{
|
|
774
|
+
name: "favorodera/stylistic/setup",
|
|
775
|
+
plugins: { style: stylePlugin }
|
|
776
|
+
}, {
|
|
777
|
+
files: resolved.files,
|
|
778
|
+
name: "favorodera/stylistic/rules",
|
|
779
|
+
rules: {
|
|
780
|
+
...baseRules,
|
|
781
|
+
"style/brace-style": "off",
|
|
782
|
+
"style/generator-star-spacing": ["error", {
|
|
783
|
+
after: true,
|
|
784
|
+
before: false
|
|
785
|
+
}],
|
|
786
|
+
"style/no-multiple-empty-lines": ["error", {
|
|
787
|
+
max: 2,
|
|
788
|
+
maxBOF: 0,
|
|
789
|
+
maxEOF: 2
|
|
790
|
+
}],
|
|
791
|
+
"style/no-trailing-spaces": ["error", { skipBlankLines: true }],
|
|
792
|
+
"style/padded-blocks": "off",
|
|
793
|
+
"style/quotes": [
|
|
794
|
+
"error",
|
|
795
|
+
"single",
|
|
796
|
+
{ avoidEscape: true }
|
|
797
|
+
],
|
|
798
|
+
"style/yield-star-spacing": ["error", {
|
|
799
|
+
after: true,
|
|
800
|
+
before: false
|
|
801
|
+
}],
|
|
802
|
+
...resolved.overrides
|
|
803
|
+
}
|
|
804
|
+
}];
|
|
805
|
+
}
|
|
806
|
+
//#endregion
|
|
807
|
+
//#region src/configs/tailwind.ts
|
|
808
|
+
const tailwindDefaults = {
|
|
809
|
+
files: [
|
|
810
|
+
jsGlob,
|
|
811
|
+
tsGlob,
|
|
812
|
+
vueGlob
|
|
813
|
+
],
|
|
814
|
+
settings: { detectComponentClasses: true }
|
|
815
|
+
};
|
|
816
|
+
/**
|
|
817
|
+
* Constructs the flat config items for Tailwind CSS linting, providing custom settings
|
|
818
|
+
* to parse and lint utility classes, and enforcing consistent ordering.
|
|
819
|
+
* @param options Tailwind configuration options.
|
|
820
|
+
* @returns Promise resolving to Tailwind ESLint config items.
|
|
821
|
+
*/
|
|
822
|
+
async function tailwind(options) {
|
|
823
|
+
const resolved = (0, defu.defu)(options, tailwindDefaults);
|
|
824
|
+
const tailwindPlugin = await importModule(import("eslint-plugin-better-tailwindcss"));
|
|
825
|
+
const baseRules = {
|
|
826
|
+
...tailwindPlugin.configs["recommended-error"].rules,
|
|
827
|
+
...tailwindPlugin.configs["stylistic-error"].rules
|
|
828
|
+
};
|
|
829
|
+
return [{
|
|
830
|
+
name: "favorodera/tailwind/setup",
|
|
831
|
+
plugins: { tailwind: tailwindPlugin },
|
|
832
|
+
settings: { tailwindcss: resolved.settings }
|
|
832
833
|
}, {
|
|
834
|
+
files: resolved.files,
|
|
833
835
|
name: "favorodera/tailwind/rules",
|
|
836
|
+
rules: {
|
|
837
|
+
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { "better-tailwindcss": "tailwind" }),
|
|
838
|
+
"tailwind/enforce-consistent-line-wrapping": ["error", { group: "emptyLine" }],
|
|
839
|
+
"tailwind/no-unregistered-classes": "off",
|
|
840
|
+
...resolved.overrides
|
|
841
|
+
}
|
|
842
|
+
}];
|
|
843
|
+
}
|
|
844
|
+
//#endregion
|
|
845
|
+
//#region src/configs/typescript.ts
|
|
846
|
+
const typescriptDefaults = { files: [tsGlob] };
|
|
847
|
+
/**
|
|
848
|
+
* Constructs the flat config items for TypeScript linting, initializing the parser
|
|
849
|
+
* and extending the recommended and strict type-aware rule sets.
|
|
850
|
+
* @param options TypeScript configuration options.
|
|
851
|
+
* @returns Promise resolving to TypeScript ESLint config items.
|
|
852
|
+
*/
|
|
853
|
+
async function typescript(options) {
|
|
854
|
+
const resolved = (0, defu.defu)(options, typescriptDefaults);
|
|
855
|
+
const tsEsLint = await importModule(import("typescript-eslint"));
|
|
856
|
+
const baseRules = extractRules(tsEsLint.configs.recommended, tsEsLint.configs.strict);
|
|
857
|
+
return [{
|
|
858
|
+
name: "favorodera/typescript/setup",
|
|
859
|
+
plugins: { ts: tsEsLint.plugin }
|
|
860
|
+
}, {
|
|
834
861
|
files: resolved.files,
|
|
862
|
+
languageOptions: {
|
|
863
|
+
parser: tsEsLint.parser,
|
|
864
|
+
parserOptions: { sourceType: "module" }
|
|
865
|
+
},
|
|
866
|
+
name: "favorodera/typescript/rules",
|
|
835
867
|
rules: {
|
|
836
|
-
...baseRules
|
|
837
|
-
"
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
"
|
|
842
|
-
"
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
868
|
+
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { "@typescript-eslint": "ts" }),
|
|
869
|
+
"ts/array-type": ["error", {
|
|
870
|
+
default: "generic",
|
|
871
|
+
readonly: "generic"
|
|
872
|
+
}],
|
|
873
|
+
"ts/consistent-type-imports": ["error", { prefer: "type-imports" }],
|
|
874
|
+
"ts/no-empty-object-type": ["error", { allowInterfaces: "with-single-extends" }],
|
|
875
|
+
...resolved.overrides
|
|
876
|
+
}
|
|
877
|
+
}];
|
|
878
|
+
}
|
|
879
|
+
//#endregion
|
|
880
|
+
//#region src/configs/unicorn.ts
|
|
881
|
+
const unicornDefaults = { files: [
|
|
882
|
+
jsGlob,
|
|
883
|
+
tsGlob,
|
|
884
|
+
vueGlob
|
|
885
|
+
] };
|
|
886
|
+
/**
|
|
887
|
+
* Constructs the flat config items for Unicorn linting, providing a collection of
|
|
888
|
+
* awesome ESLint rules to improve code quality and enforce best practices.
|
|
889
|
+
* @param options Unicorn configuration options.
|
|
890
|
+
* @returns Promise resolving to Unicorn ESLint config items.
|
|
891
|
+
*/
|
|
892
|
+
async function unicorn(options) {
|
|
893
|
+
const resolved = (0, defu.defu)(options, unicornDefaults);
|
|
894
|
+
const unicornPlugin = await importModule(import("eslint-plugin-unicorn"));
|
|
895
|
+
const baseRules = unicornPlugin.configs["unopinionated"]?.rules || {};
|
|
896
|
+
return [{
|
|
897
|
+
name: "favorodera/unicorn/setup",
|
|
898
|
+
plugins: { unicorn: unicornPlugin }
|
|
899
|
+
}, {
|
|
900
|
+
files: resolved.files,
|
|
901
|
+
languageOptions: { globals: globals.default.builtin },
|
|
902
|
+
name: "favorodera/unicorn/rules",
|
|
903
|
+
rules: {
|
|
904
|
+
...baseRules,
|
|
905
|
+
"unicorn/consistent-empty-array-spread": "error",
|
|
906
|
+
"unicorn/error-message": "error",
|
|
907
|
+
"unicorn/escape-case": "error",
|
|
908
|
+
"unicorn/new-for-builtins": "error",
|
|
909
|
+
"unicorn/no-instanceof-builtins": "error",
|
|
910
|
+
"unicorn/no-new-array": "error",
|
|
911
|
+
"unicorn/no-new-buffer": "error",
|
|
912
|
+
"unicorn/number-literal-case": "error",
|
|
913
|
+
"unicorn/prefer-dom-node-text-content": "error",
|
|
914
|
+
"unicorn/prefer-includes": "error",
|
|
915
|
+
"unicorn/prefer-node-protocol": "error",
|
|
916
|
+
"unicorn/prefer-number-properties": "error",
|
|
917
|
+
"unicorn/prefer-string-starts-ends-with": "error",
|
|
918
|
+
"unicorn/prefer-type-error": "error",
|
|
919
|
+
"unicorn/throw-new-error": "error",
|
|
920
|
+
...resolved.overrides
|
|
921
|
+
}
|
|
922
|
+
}];
|
|
923
|
+
}
|
|
924
|
+
//#endregion
|
|
925
|
+
//#region src/configs/vue.ts
|
|
926
|
+
const sfcBlocksDefaults = { blocks: {
|
|
927
|
+
customBlocks: true,
|
|
928
|
+
styles: true,
|
|
929
|
+
template: false
|
|
930
|
+
} };
|
|
931
|
+
const vueDefaults = {
|
|
932
|
+
files: [vueGlob],
|
|
933
|
+
sfcBlocks: sfcBlocksDefaults
|
|
934
|
+
};
|
|
935
|
+
/**
|
|
936
|
+
* Constructs the flat config items for Vue linting, setting up the custom template parser,
|
|
937
|
+
* Vue block processors, and rules to enforce recommended component syntax.
|
|
938
|
+
* @param options Vue configuration options.
|
|
939
|
+
* @returns Promise resolving to Vue ESLint config items.
|
|
940
|
+
*/
|
|
941
|
+
async function vue(options) {
|
|
942
|
+
const resolved = (0, defu.defu)(options, vueDefaults);
|
|
943
|
+
const sfcBlocks = resolveOptions(resolved.sfcBlocks, sfcBlocksDefaults);
|
|
944
|
+
const [vuePlugin, vueParser, tsEsLint] = await Promise.all([
|
|
945
|
+
importModule(import("eslint-plugin-vue")),
|
|
946
|
+
importModule(import("vue-eslint-parser")),
|
|
947
|
+
importModule(import("typescript-eslint"))
|
|
948
|
+
]);
|
|
949
|
+
const baseRules = extractRules(vuePlugin.configs["flat/essential"], vuePlugin.configs["flat/strongly-recommended"], vuePlugin.configs["flat/recommended"]);
|
|
950
|
+
const processor = sfcBlocks === false ? vuePlugin.processors[".vue"] : (0, eslint_merge_processors.mergeProcessors)([vuePlugin.processors[".vue"], (0, eslint_processor_vue_blocks.default)(sfcBlocks)]);
|
|
951
|
+
return [{
|
|
952
|
+
languageOptions: { globals: {
|
|
953
|
+
computed: "readonly",
|
|
954
|
+
defineEmits: "readonly",
|
|
955
|
+
defineExpose: "readonly",
|
|
956
|
+
defineProps: "readonly",
|
|
957
|
+
onMounted: "readonly",
|
|
958
|
+
onUnmounted: "readonly",
|
|
959
|
+
reactive: "readonly",
|
|
960
|
+
ref: "readonly",
|
|
961
|
+
shallowReactive: "readonly",
|
|
962
|
+
shallowRef: "readonly",
|
|
963
|
+
toRef: "readonly",
|
|
964
|
+
toRefs: "readonly",
|
|
965
|
+
watch: "readonly",
|
|
966
|
+
watchEffect: "readonly"
|
|
967
|
+
} },
|
|
968
|
+
name: "favorodera/vue/setup",
|
|
969
|
+
plugins: { vue: vuePlugin }
|
|
970
|
+
}, {
|
|
971
|
+
files: resolved.files,
|
|
972
|
+
languageOptions: {
|
|
973
|
+
parser: vueParser,
|
|
974
|
+
parserOptions: {
|
|
975
|
+
extraFileExtensions: [".vue"],
|
|
976
|
+
parser: tsEsLint.parser,
|
|
977
|
+
sourceType: "module"
|
|
978
|
+
}
|
|
979
|
+
},
|
|
980
|
+
name: "favorodera/vue/rules",
|
|
981
|
+
processor,
|
|
982
|
+
rules: {
|
|
983
|
+
...baseRules,
|
|
984
|
+
"vue/block-order": ["error", { order: [
|
|
985
|
+
"script",
|
|
986
|
+
"template",
|
|
987
|
+
"style"
|
|
988
|
+
] }],
|
|
989
|
+
"vue/block-tag-newline": ["error", {
|
|
990
|
+
multiline: "ignore",
|
|
991
|
+
singleline: "ignore"
|
|
992
|
+
}],
|
|
993
|
+
"vue/component-name-in-template-casing": ["error", "PascalCase"],
|
|
994
|
+
"vue/component-options-name-casing": ["error", "PascalCase"],
|
|
995
|
+
"vue/multi-word-component-names": "off",
|
|
996
|
+
"vue/multiline-html-element-content-newline": ["error", {
|
|
997
|
+
allowEmptyLines: true,
|
|
998
|
+
ignores: ["pre", "textarea"]
|
|
999
|
+
}],
|
|
854
1000
|
...resolved.overrides
|
|
855
1001
|
}
|
|
856
1002
|
}];
|
|
@@ -864,18 +1010,20 @@ async function jsdoc(options) {
|
|
|
864
1010
|
* @returns A flat config composer instance that can be exported directly or further modified.
|
|
865
1011
|
*/
|
|
866
1012
|
function factory(options = {}) {
|
|
867
|
-
const configs = [];
|
|
868
|
-
configs.push(ignores(options.ignores));
|
|
1013
|
+
const configs = [ignores(options.ignores)];
|
|
869
1014
|
const configFunctions = {
|
|
870
|
-
vue,
|
|
871
|
-
typescript,
|
|
872
|
-
stylistic,
|
|
873
|
-
tailwind,
|
|
874
1015
|
imports,
|
|
875
|
-
markdown,
|
|
876
1016
|
javascript,
|
|
1017
|
+
jsdoc,
|
|
877
1018
|
jsonc,
|
|
878
|
-
|
|
1019
|
+
markdown,
|
|
1020
|
+
node,
|
|
1021
|
+
perfectionist,
|
|
1022
|
+
stylistic,
|
|
1023
|
+
tailwind,
|
|
1024
|
+
typescript,
|
|
1025
|
+
unicorn,
|
|
1026
|
+
vue
|
|
879
1027
|
};
|
|
880
1028
|
for (const [key, configFunction] of Object.entries(configFunctions)) {
|
|
881
1029
|
const configOption = options[key];
|
|
@@ -884,10 +1032,11 @@ function factory(options = {}) {
|
|
|
884
1032
|
}
|
|
885
1033
|
let composer = new eslint_flat_config_utils.FlatConfigComposer();
|
|
886
1034
|
composer = composer.append(...configs).renamePlugins({
|
|
887
|
-
"better-tailwindcss": "tailwind",
|
|
888
1035
|
"@typescript-eslint": "ts",
|
|
1036
|
+
"better-tailwindcss": "tailwind",
|
|
1037
|
+
"import-lite": "import",
|
|
889
1038
|
"markdown": "md",
|
|
890
|
-
"
|
|
1039
|
+
"n": "node"
|
|
891
1040
|
});
|
|
892
1041
|
return composer;
|
|
893
1042
|
}
|