@favorodera/eslint-config 0.0.2 → 0.0.4
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 +144 -1
- package/dist/index.cjs +530 -91
- package/dist/index.d.cts +1382 -44
- package/dist/index.d.mts +1382 -44
- package/dist/index.mjs +530 -91
- package/package.json +32 -28
package/dist/index.mjs
CHANGED
|
@@ -4,17 +4,31 @@ import { mergeProcessors, processorPassThrough } from "eslint-merge-processors";
|
|
|
4
4
|
import vueBlocksProcessor from "eslint-processor-vue-blocks";
|
|
5
5
|
import globals from "globals";
|
|
6
6
|
//#region src/globs.ts
|
|
7
|
-
/** Glob pattern for JavaScript
|
|
7
|
+
/** Glob pattern for matching JavaScript files */
|
|
8
8
|
const jsGlob = "**/*.{js,cjs,mjs}";
|
|
9
|
-
/** Glob pattern for TypeScript
|
|
9
|
+
/** Glob pattern for matching TypeScript files */
|
|
10
10
|
const tsGlob = "**/*.{ts,cts,mts}";
|
|
11
|
-
/** Glob pattern for Vue
|
|
11
|
+
/** Glob pattern for matching Vue single-file components */
|
|
12
12
|
const vueGlob = "**/*.vue";
|
|
13
|
-
/** Glob pattern for Markdown
|
|
13
|
+
/** Glob pattern for matching Markdown files */
|
|
14
14
|
const mdGlob = "**/*.md";
|
|
15
|
+
/** Glob pattern for matching virtual files extracted from Markdown */
|
|
16
|
+
const mdInMdGlob = "**/*.md/*.md";
|
|
17
|
+
/** Glob pattern for matching code blocks embedded in Markdown files */
|
|
18
|
+
const codeInMdGlob = "**/*.md/**/*.{js,cjs,mjs,ts,cts,mts,vue}";
|
|
19
|
+
/** Glob pattern for matching JSON files */
|
|
20
|
+
const jsonGlob = "**/*.json";
|
|
21
|
+
/** Glob pattern for matching JSON5 files */
|
|
22
|
+
const json5Glob = "**/*.json5";
|
|
23
|
+
/** Glob pattern for matching JSON with Comments files */
|
|
24
|
+
const jsoncGlob = "**/*.jsonc";
|
|
25
|
+
/** Glob patterns for matching TypeScript configuration files */
|
|
26
|
+
const tsConfigGlob = ["**/tsconfig.json", "**/tsconfig.*.json"];
|
|
27
|
+
/** Glob pattern for matching package.json files */
|
|
28
|
+
const packageJsonGlob = "**/package.json";
|
|
15
29
|
/**
|
|
16
|
-
*
|
|
17
|
-
* Includes
|
|
30
|
+
* Common glob patterns for files and directories that should be ignored by ESLint.
|
|
31
|
+
* Includes node_modules, build outputs, lock files, temporary files, and tool-specific caches.
|
|
18
32
|
*/
|
|
19
33
|
const ignoresGlob = [
|
|
20
34
|
"**/node_modules/**",
|
|
@@ -61,9 +75,9 @@ const ignoresGlob = [
|
|
|
61
75
|
*
|
|
62
76
|
* Handles both ESM modules (which wrap exports under `.default`) and
|
|
63
77
|
* CJS / plain-object modules uniformly.
|
|
64
|
-
*
|
|
65
|
-
* @param module
|
|
66
|
-
* @returns The `.default` export if it exists, otherwise the module itself
|
|
78
|
+
* @template TModule The type of the module being imported.
|
|
79
|
+
* @param module A module or a promise that resolves to one.
|
|
80
|
+
* @returns The `.default` export if it exists, otherwise the module itself.
|
|
67
81
|
*/
|
|
68
82
|
async function importModule(module) {
|
|
69
83
|
const resolved = await module;
|
|
@@ -73,15 +87,23 @@ async function importModule(module) {
|
|
|
73
87
|
/**
|
|
74
88
|
* Normalize boolean or options value into merged options or null.
|
|
75
89
|
* Returns null when the input is false or undefined.
|
|
76
|
-
*
|
|
77
|
-
* @param value
|
|
78
|
-
* @param defaults
|
|
79
|
-
* @returns merged options or false
|
|
90
|
+
* @template TOptions The type of the options object.
|
|
91
|
+
* @param value The configuration value, which can be a boolean, an options object, or undefined.
|
|
92
|
+
* @param defaults The default options to merge with if `value` is true or an object.
|
|
93
|
+
* @returns The merged options object, or false if the feature is disabled.
|
|
80
94
|
*/
|
|
81
95
|
function resolveOptions(value, defaults) {
|
|
82
96
|
if (!value) return false;
|
|
83
97
|
return defu(value === true ? {} : value, defaults);
|
|
84
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Extracts and merges the rules from multiple ESLint configuration arrays.
|
|
101
|
+
* @param configArrays Rest parameter representing multiple arrays of ESLint flat config items.
|
|
102
|
+
* @returns A single object containing all the merged rules from the provided configurations.
|
|
103
|
+
*/
|
|
104
|
+
function extractRules(...configArrays) {
|
|
105
|
+
return Object.assign({}, ...configArrays.flat().map((config) => config?.rules || {}));
|
|
106
|
+
}
|
|
85
107
|
//#endregion
|
|
86
108
|
//#region src/configs/vue.ts
|
|
87
109
|
const sfcBlocksDefaults = { blocks: {
|
|
@@ -93,6 +115,12 @@ const vueDefaults = {
|
|
|
93
115
|
files: [vueGlob],
|
|
94
116
|
sfcBlocks: sfcBlocksDefaults
|
|
95
117
|
};
|
|
118
|
+
/**
|
|
119
|
+
* Constructs the flat config items for Vue linting, setting up the custom template parser,
|
|
120
|
+
* Vue block processors, and rules to enforce recommended component syntax.
|
|
121
|
+
* @param options Vue configuration options.
|
|
122
|
+
* @returns Promise resolving to Vue ESLint config items.
|
|
123
|
+
*/
|
|
96
124
|
async function vue(options) {
|
|
97
125
|
const resolved = defu(options, vueDefaults);
|
|
98
126
|
const sfcBlocks = resolveOptions(resolved.sfcBlocks, sfcBlocksDefaults);
|
|
@@ -101,32 +129,31 @@ async function vue(options) {
|
|
|
101
129
|
importModule(import("vue-eslint-parser")),
|
|
102
130
|
importModule(import("typescript-eslint"))
|
|
103
131
|
]);
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
...vuePlugin.configs["flat/strongly-recommended"],
|
|
107
|
-
...vuePlugin.configs["flat/recommended"]
|
|
108
|
-
].map((config) => config?.rules || {}));
|
|
132
|
+
const baseRules = extractRules(vuePlugin.configs["flat/essential"], vuePlugin.configs["flat/strongly-recommended"], vuePlugin.configs["flat/recommended"]);
|
|
133
|
+
const processor = sfcBlocks === false ? vuePlugin.processors[".vue"] : mergeProcessors([vuePlugin.processors[".vue"], vueBlocksProcessor(sfcBlocks)]);
|
|
109
134
|
return [{
|
|
110
|
-
name: "favorodera/vue",
|
|
135
|
+
name: "favorodera/vue/setup",
|
|
111
136
|
plugins: { vue: vuePlugin },
|
|
137
|
+
languageOptions: { globals: {
|
|
138
|
+
computed: "readonly",
|
|
139
|
+
defineEmits: "readonly",
|
|
140
|
+
defineExpose: "readonly",
|
|
141
|
+
defineProps: "readonly",
|
|
142
|
+
onMounted: "readonly",
|
|
143
|
+
onUnmounted: "readonly",
|
|
144
|
+
reactive: "readonly",
|
|
145
|
+
ref: "readonly",
|
|
146
|
+
shallowReactive: "readonly",
|
|
147
|
+
shallowRef: "readonly",
|
|
148
|
+
toRef: "readonly",
|
|
149
|
+
toRefs: "readonly",
|
|
150
|
+
watch: "readonly",
|
|
151
|
+
watchEffect: "readonly"
|
|
152
|
+
} }
|
|
153
|
+
}, {
|
|
154
|
+
name: "favorodera/vue/rules",
|
|
112
155
|
files: resolved.files,
|
|
113
156
|
languageOptions: {
|
|
114
|
-
globals: {
|
|
115
|
-
computed: "readonly",
|
|
116
|
-
defineEmits: "readonly",
|
|
117
|
-
defineExpose: "readonly",
|
|
118
|
-
defineProps: "readonly",
|
|
119
|
-
onMounted: "readonly",
|
|
120
|
-
onUnmounted: "readonly",
|
|
121
|
-
reactive: "readonly",
|
|
122
|
-
ref: "readonly",
|
|
123
|
-
shallowReactive: "readonly",
|
|
124
|
-
shallowRef: "readonly",
|
|
125
|
-
toRef: "readonly",
|
|
126
|
-
toRefs: "readonly",
|
|
127
|
-
watch: "readonly",
|
|
128
|
-
watchEffect: "readonly"
|
|
129
|
-
},
|
|
130
157
|
parser: vueParser,
|
|
131
158
|
parserOptions: {
|
|
132
159
|
parser: tsEsLint.parser,
|
|
@@ -134,9 +161,9 @@ async function vue(options) {
|
|
|
134
161
|
sourceType: "module"
|
|
135
162
|
}
|
|
136
163
|
},
|
|
137
|
-
processor
|
|
164
|
+
processor,
|
|
138
165
|
rules: {
|
|
139
|
-
...
|
|
166
|
+
...baseRules,
|
|
140
167
|
"vue/block-order": ["error", { order: [
|
|
141
168
|
"script",
|
|
142
169
|
"template",
|
|
@@ -162,7 +189,7 @@ async function vue(options) {
|
|
|
162
189
|
const defaultPatterns = ignoresGlob;
|
|
163
190
|
/**
|
|
164
191
|
* Globs for ignoring files and directories from ESLint scanning.
|
|
165
|
-
* @param patterns
|
|
192
|
+
* @param patterns Additional ignore patterns or a function to modify the defaults.
|
|
166
193
|
* @returns An array containing the ignore flat config item.
|
|
167
194
|
*/
|
|
168
195
|
function ignores(patterns = []) {
|
|
@@ -178,19 +205,27 @@ const importsDefaults = { files: [
|
|
|
178
205
|
tsGlob,
|
|
179
206
|
vueGlob
|
|
180
207
|
] };
|
|
208
|
+
/**
|
|
209
|
+
* Constructs the flat config items for imports linting, providing plugin setup and
|
|
210
|
+
* specific rules to enforce consistent import ordering and unused variable checks.
|
|
211
|
+
* @param options Configuration options for imports linting.
|
|
212
|
+
* @returns Promise resolving to imports ESLint config items.
|
|
213
|
+
*/
|
|
181
214
|
async function imports(options) {
|
|
182
215
|
const resolved = defu(options, importsDefaults);
|
|
183
216
|
const [importPlugin, unusedImportsPlugin] = await Promise.all([importModule(import("eslint-plugin-import-lite")), importModule(import("eslint-plugin-unused-imports"))]);
|
|
184
|
-
const
|
|
217
|
+
const baseRules = importPlugin.configs.recommended?.rules || {};
|
|
185
218
|
return [{
|
|
186
|
-
name: "favorodera/imports",
|
|
187
|
-
files: resolved.files,
|
|
219
|
+
name: "favorodera/imports/setup",
|
|
188
220
|
plugins: {
|
|
189
221
|
"import": importPlugin,
|
|
190
222
|
"unused-imports": unusedImportsPlugin
|
|
191
|
-
}
|
|
223
|
+
}
|
|
224
|
+
}, {
|
|
225
|
+
name: "favorodera/imports/rules",
|
|
226
|
+
files: resolved.files,
|
|
192
227
|
rules: {
|
|
193
|
-
...renamePluginsInRules(
|
|
228
|
+
...renamePluginsInRules(baseRules, { "import-lite": "import" }),
|
|
194
229
|
"import/consistent-type-specifier-style": ["error", "top-level"],
|
|
195
230
|
"import/first": "error",
|
|
196
231
|
"import/no-duplicates": "error",
|
|
@@ -217,16 +252,16 @@ const javascriptDefaults = { files: [
|
|
|
217
252
|
vueGlob
|
|
218
253
|
] };
|
|
219
254
|
/**
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
* @
|
|
255
|
+
* Constructs the flat config items for core JavaScript linting, setting up the required
|
|
256
|
+
* language options, globals, and recommended baseline rules.
|
|
257
|
+
* @param options Javascript configuration options.
|
|
258
|
+
* @returns Promise resolving to javascript ESLint config items.
|
|
223
259
|
*/
|
|
224
260
|
async function javascript(options) {
|
|
225
261
|
const resolved = defu(options, javascriptDefaults);
|
|
226
|
-
const
|
|
262
|
+
const baseRules = (await importModule(import("@eslint/js"))).configs.recommended.rules;
|
|
227
263
|
return [{
|
|
228
|
-
name: "favorodera/javascript",
|
|
229
|
-
files: resolved.files,
|
|
264
|
+
name: "favorodera/javascript/setup",
|
|
230
265
|
languageOptions: {
|
|
231
266
|
ecmaVersion: "latest",
|
|
232
267
|
sourceType: "module",
|
|
@@ -239,9 +274,12 @@ async function javascript(options) {
|
|
|
239
274
|
window: "readonly"
|
|
240
275
|
}
|
|
241
276
|
},
|
|
242
|
-
linterOptions: { reportUnusedDisableDirectives: true }
|
|
277
|
+
linterOptions: { reportUnusedDisableDirectives: true }
|
|
278
|
+
}, {
|
|
279
|
+
name: "favorodera/javascript/rules",
|
|
280
|
+
files: resolved.files,
|
|
243
281
|
rules: {
|
|
244
|
-
...
|
|
282
|
+
...baseRules,
|
|
245
283
|
"accessor-pairs": ["error", {
|
|
246
284
|
enforceForClassMembers: true,
|
|
247
285
|
setWithoutGet: true
|
|
@@ -258,23 +296,66 @@ const markdownDefaults = {
|
|
|
258
296
|
files: [mdGlob],
|
|
259
297
|
gfm: true
|
|
260
298
|
};
|
|
299
|
+
/**
|
|
300
|
+
* Constructs the flat config items for Markdown linting, extracting and linting
|
|
301
|
+
* embedded code blocks within the document according to specified rules.
|
|
302
|
+
* @param options Markdown configuration options.
|
|
303
|
+
* @returns Promise resolving to Markdown ESLint config items.
|
|
304
|
+
*/
|
|
261
305
|
async function markdown(options) {
|
|
262
306
|
const resolved = defu(options, markdownDefaults);
|
|
263
307
|
const markdownPlugin = await importModule(import("@eslint/markdown"));
|
|
264
|
-
const
|
|
265
|
-
return [
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
"md/
|
|
274
|
-
|
|
275
|
-
|
|
308
|
+
const baseRules = extractRules(markdownPlugin.configs.recommended);
|
|
309
|
+
return [
|
|
310
|
+
{
|
|
311
|
+
name: "favorodera/markdown/setup",
|
|
312
|
+
plugins: { md: markdownPlugin }
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
name: "favorodera/markdown/rules",
|
|
316
|
+
files: resolved.files,
|
|
317
|
+
language: resolved.gfm ? "md/gfm" : "md/commonmark",
|
|
318
|
+
ignores: [mdInMdGlob],
|
|
319
|
+
processor: mergeProcessors([markdownPlugin.processors?.markdown, processorPassThrough]),
|
|
320
|
+
rules: {
|
|
321
|
+
...renamePluginsInRules(baseRules, { markdown: "md" }),
|
|
322
|
+
"md/fenced-code-language": "off",
|
|
323
|
+
"md/no-missing-label-refs": "off",
|
|
324
|
+
...resolved.overrides
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
name: "favorodera/markdown/disables/code",
|
|
329
|
+
files: [codeInMdGlob],
|
|
330
|
+
languageOptions: { parserOptions: { ecmaFeatures: { impliedStrict: true } } },
|
|
331
|
+
rules: {
|
|
332
|
+
"no-alert": "off",
|
|
333
|
+
"no-console": "off",
|
|
334
|
+
"no-labels": "off",
|
|
335
|
+
"no-lone-blocks": "off",
|
|
336
|
+
"no-restricted-syntax": "off",
|
|
337
|
+
"no-undef": "off",
|
|
338
|
+
"no-unused-expressions": "off",
|
|
339
|
+
"no-unused-labels": "off",
|
|
340
|
+
"no-unused-vars": "off",
|
|
341
|
+
"node/prefer-global/process": "off",
|
|
342
|
+
"style/comma-dangle": "off",
|
|
343
|
+
"style/eol-last": "off",
|
|
344
|
+
"style/padding-line-between-statements": "off",
|
|
345
|
+
"ts/consistent-type-imports": "off",
|
|
346
|
+
"ts/explicit-function-return-type": "off",
|
|
347
|
+
"ts/no-namespace": "off",
|
|
348
|
+
"ts/no-redeclare": "off",
|
|
349
|
+
"ts/no-require-imports": "off",
|
|
350
|
+
"ts/no-unused-expressions": "off",
|
|
351
|
+
"ts/no-unused-vars": "off",
|
|
352
|
+
"ts/no-use-before-define": "off",
|
|
353
|
+
"unicode-bom": "off",
|
|
354
|
+
"unused-imports/no-unused-imports": "off",
|
|
355
|
+
"unused-imports/no-unused-vars": "off"
|
|
356
|
+
}
|
|
276
357
|
}
|
|
277
|
-
|
|
358
|
+
];
|
|
278
359
|
}
|
|
279
360
|
//#endregion
|
|
280
361
|
//#region src/configs/stylistic.ts
|
|
@@ -292,19 +373,27 @@ const stylisticDefaults = {
|
|
|
292
373
|
vueGlob
|
|
293
374
|
]
|
|
294
375
|
};
|
|
376
|
+
/**
|
|
377
|
+
* Constructs the flat config items for Stylistic linting, applying customized
|
|
378
|
+
* formatting settings such as quotes, indentation, and spacing.
|
|
379
|
+
* @param options Stylistic configuration options.
|
|
380
|
+
* @returns Promise resolving to stylistic ESLint config items.
|
|
381
|
+
*/
|
|
295
382
|
async function stylistic(options) {
|
|
296
383
|
const resolved = defu(options, stylisticDefaults);
|
|
297
|
-
const
|
|
384
|
+
const stylePlugin = await importModule(import("@stylistic/eslint-plugin"));
|
|
385
|
+
const baseRules = stylePlugin.configs.customize({
|
|
298
386
|
pluginName: "style",
|
|
299
387
|
...resolved.settings
|
|
300
|
-
});
|
|
301
|
-
const inheritedRules = config?.rules || {};
|
|
388
|
+
})?.rules || {};
|
|
302
389
|
return [{
|
|
303
|
-
|
|
304
|
-
|
|
390
|
+
name: "favorodera/stylistic/setup",
|
|
391
|
+
plugins: { style: stylePlugin }
|
|
392
|
+
}, {
|
|
393
|
+
name: "favorodera/stylistic/rules",
|
|
305
394
|
files: resolved.files,
|
|
306
395
|
rules: {
|
|
307
|
-
...
|
|
396
|
+
...baseRules,
|
|
308
397
|
"style/quotes": [
|
|
309
398
|
"error",
|
|
310
399
|
"single",
|
|
@@ -341,24 +430,27 @@ const tailwindDefaults = {
|
|
|
341
430
|
settings: { detectComponentClasses: true }
|
|
342
431
|
};
|
|
343
432
|
/**
|
|
344
|
-
* Tailwind linting
|
|
345
|
-
*
|
|
346
|
-
* @
|
|
433
|
+
* Constructs the flat config items for Tailwind CSS linting, providing custom settings
|
|
434
|
+
* to parse and lint utility classes, and enforcing consistent ordering.
|
|
435
|
+
* @param options Tailwind configuration options.
|
|
436
|
+
* @returns Promise resolving to Tailwind ESLint config items.
|
|
347
437
|
*/
|
|
348
438
|
async function tailwind(options) {
|
|
349
439
|
const resolved = defu(options, tailwindDefaults);
|
|
350
440
|
const tailwindPlugin = await importModule(import("eslint-plugin-better-tailwindcss"));
|
|
351
|
-
const
|
|
441
|
+
const baseRules = {
|
|
352
442
|
...tailwindPlugin.configs["recommended-error"].rules,
|
|
353
443
|
...tailwindPlugin.configs["stylistic-error"].rules
|
|
354
444
|
};
|
|
355
445
|
return [{
|
|
356
|
-
name: "favorodera/tailwind",
|
|
357
|
-
files: resolved.files,
|
|
446
|
+
name: "favorodera/tailwind/setup",
|
|
358
447
|
plugins: { tailwind: tailwindPlugin },
|
|
359
|
-
settings: { tailwindcss: resolved.settings }
|
|
448
|
+
settings: { tailwindcss: resolved.settings }
|
|
449
|
+
}, {
|
|
450
|
+
name: "favorodera/tailwind/rules",
|
|
451
|
+
files: resolved.files,
|
|
360
452
|
rules: {
|
|
361
|
-
...renamePluginsInRules(
|
|
453
|
+
...renamePluginsInRules(baseRules, { "better-tailwindcss": "tailwind" }),
|
|
362
454
|
"tailwind/no-unregistered-classes": "off",
|
|
363
455
|
"tailwind/enforce-consistent-line-wrapping": ["error", { group: "emptyLine" }],
|
|
364
456
|
...resolved.overrides
|
|
@@ -369,27 +461,371 @@ async function tailwind(options) {
|
|
|
369
461
|
//#region src/configs/typescript.ts
|
|
370
462
|
const typescriptDefaults = { files: [tsGlob] };
|
|
371
463
|
/**
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
* @
|
|
464
|
+
* Constructs the flat config items for TypeScript linting, initializing the parser
|
|
465
|
+
* and extending the recommended and strict type-aware rule sets.
|
|
466
|
+
* @param options TypeScript configuration options.
|
|
467
|
+
* @returns Promise resolving to TypeScript ESLint config items.
|
|
375
468
|
*/
|
|
376
469
|
async function typescript(options) {
|
|
377
470
|
const resolved = defu(options, typescriptDefaults);
|
|
378
471
|
const tsEsLint = await importModule(import("typescript-eslint"));
|
|
379
|
-
const
|
|
472
|
+
const baseRules = extractRules(tsEsLint.configs.recommended, tsEsLint.configs.strict);
|
|
380
473
|
return [{
|
|
381
|
-
name: "favorodera/typescript",
|
|
382
|
-
plugins: { ts: tsEsLint.plugin }
|
|
474
|
+
name: "favorodera/typescript/setup",
|
|
475
|
+
plugins: { ts: tsEsLint.plugin }
|
|
476
|
+
}, {
|
|
477
|
+
name: "favorodera/typescript/rules",
|
|
478
|
+
files: resolved.files,
|
|
383
479
|
languageOptions: {
|
|
384
480
|
parser: tsEsLint.parser,
|
|
385
481
|
parserOptions: { sourceType: "module" }
|
|
386
482
|
},
|
|
387
|
-
files: resolved.files,
|
|
388
483
|
rules: {
|
|
389
|
-
...renamePluginsInRules(
|
|
484
|
+
...renamePluginsInRules(baseRules, { "@typescript-eslint": "ts" }),
|
|
390
485
|
"ts/consistent-type-imports": ["error", { prefer: "type-imports" }],
|
|
391
486
|
"ts/no-empty-object-type": ["error", { allowInterfaces: "with-single-extends" }],
|
|
392
|
-
"ts/array-type": ["error", {
|
|
487
|
+
"ts/array-type": ["error", {
|
|
488
|
+
default: "generic",
|
|
489
|
+
readonly: "generic"
|
|
490
|
+
}],
|
|
491
|
+
...resolved.overrides
|
|
492
|
+
}
|
|
493
|
+
}];
|
|
494
|
+
}
|
|
495
|
+
//#endregion
|
|
496
|
+
//#region src/configs/jsonc.ts
|
|
497
|
+
const jsoncDefaults = { files: [
|
|
498
|
+
json5Glob,
|
|
499
|
+
jsoncGlob,
|
|
500
|
+
jsonGlob
|
|
501
|
+
] };
|
|
502
|
+
/**
|
|
503
|
+
* Constructs the flat config items for JSON, JSON5, and JSONC linting, setting up
|
|
504
|
+
* the custom parser, rule validations, and sorting rules for package.json/tsconfig.json.
|
|
505
|
+
* @param options JSONC configuration options.
|
|
506
|
+
* @returns Promise resolving to JSONC ESLint config items.
|
|
507
|
+
*/
|
|
508
|
+
async function jsonc(options) {
|
|
509
|
+
const resolved = defu(options, jsoncDefaults);
|
|
510
|
+
return [
|
|
511
|
+
{
|
|
512
|
+
name: "favorodera/jsonc/setup",
|
|
513
|
+
plugins: { jsonc: await importModule(import("eslint-plugin-jsonc")) }
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
name: "favorodera/jsonc/rules",
|
|
517
|
+
files: resolved.files,
|
|
518
|
+
language: "jsonc/x",
|
|
519
|
+
rules: {
|
|
520
|
+
"jsonc/no-bigint-literals": "error",
|
|
521
|
+
"jsonc/no-binary-expression": "error",
|
|
522
|
+
"jsonc/no-binary-numeric-literals": "error",
|
|
523
|
+
"jsonc/no-dupe-keys": "error",
|
|
524
|
+
"jsonc/no-escape-sequence-in-identifier": "error",
|
|
525
|
+
"jsonc/no-floating-decimal": "error",
|
|
526
|
+
"jsonc/no-hexadecimal-numeric-literals": "error",
|
|
527
|
+
"jsonc/no-infinity": "error",
|
|
528
|
+
"jsonc/no-multi-str": "error",
|
|
529
|
+
"jsonc/no-nan": "error",
|
|
530
|
+
"jsonc/no-number-props": "error",
|
|
531
|
+
"jsonc/no-numeric-separators": "error",
|
|
532
|
+
"jsonc/no-octal": "error",
|
|
533
|
+
"jsonc/no-octal-escape": "error",
|
|
534
|
+
"jsonc/no-octal-numeric-literals": "error",
|
|
535
|
+
"jsonc/no-parenthesized": "error",
|
|
536
|
+
"jsonc/no-plus-sign": "error",
|
|
537
|
+
"jsonc/no-regexp-literals": "error",
|
|
538
|
+
"jsonc/no-sparse-arrays": "error",
|
|
539
|
+
"jsonc/no-template-literals": "error",
|
|
540
|
+
"jsonc/no-undefined-value": "error",
|
|
541
|
+
"jsonc/no-unicode-codepoint-escapes": "error",
|
|
542
|
+
"jsonc/no-useless-escape": "error",
|
|
543
|
+
"jsonc/space-unary-ops": "error",
|
|
544
|
+
"jsonc/valid-json-number": "error",
|
|
545
|
+
"jsonc/vue-custom-block/no-parsing-error": "error",
|
|
546
|
+
"jsonc/array-bracket-spacing": ["error", "never"],
|
|
547
|
+
"jsonc/comma-dangle": ["error", "never"],
|
|
548
|
+
"jsonc/comma-style": ["error", "last"],
|
|
549
|
+
"jsonc/indent": ["error", 2],
|
|
550
|
+
"jsonc/key-spacing": ["error", {
|
|
551
|
+
afterColon: true,
|
|
552
|
+
beforeColon: false
|
|
553
|
+
}],
|
|
554
|
+
"jsonc/object-curly-newline": ["error", {
|
|
555
|
+
consistent: true,
|
|
556
|
+
multiline: true
|
|
557
|
+
}],
|
|
558
|
+
"jsonc/object-curly-spacing": ["error", "always"],
|
|
559
|
+
"jsonc/object-property-newline": ["error", { allowAllPropertiesOnSameLine: true }],
|
|
560
|
+
"jsonc/quote-props": "error",
|
|
561
|
+
"jsonc/quotes": "error",
|
|
562
|
+
...resolved.overrides
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
name: "favorodera/jsonc/sort/package-json",
|
|
567
|
+
files: [packageJsonGlob],
|
|
568
|
+
rules: {
|
|
569
|
+
"jsonc/sort-array-values": ["error", {
|
|
570
|
+
order: { type: "asc" },
|
|
571
|
+
pathPattern: "^files$"
|
|
572
|
+
}],
|
|
573
|
+
"jsonc/sort-keys": [
|
|
574
|
+
"error",
|
|
575
|
+
{
|
|
576
|
+
order: [
|
|
577
|
+
"publisher",
|
|
578
|
+
"name",
|
|
579
|
+
"displayName",
|
|
580
|
+
"type",
|
|
581
|
+
"version",
|
|
582
|
+
"private",
|
|
583
|
+
"packageManager",
|
|
584
|
+
"description",
|
|
585
|
+
"author",
|
|
586
|
+
"contributors",
|
|
587
|
+
"license",
|
|
588
|
+
"funding",
|
|
589
|
+
"homepage",
|
|
590
|
+
"repository",
|
|
591
|
+
"bugs",
|
|
592
|
+
"keywords",
|
|
593
|
+
"categories",
|
|
594
|
+
"sideEffects",
|
|
595
|
+
"imports",
|
|
596
|
+
"exports",
|
|
597
|
+
"main",
|
|
598
|
+
"module",
|
|
599
|
+
"unpkg",
|
|
600
|
+
"jsdelivr",
|
|
601
|
+
"types",
|
|
602
|
+
"typesVersions",
|
|
603
|
+
"bin",
|
|
604
|
+
"icon",
|
|
605
|
+
"files",
|
|
606
|
+
"engines",
|
|
607
|
+
"activationEvents",
|
|
608
|
+
"contributes",
|
|
609
|
+
"scripts",
|
|
610
|
+
"peerDependencies",
|
|
611
|
+
"peerDependenciesMeta",
|
|
612
|
+
"dependencies",
|
|
613
|
+
"optionalDependencies",
|
|
614
|
+
"devDependencies",
|
|
615
|
+
"pnpm",
|
|
616
|
+
"overrides",
|
|
617
|
+
"resolutions",
|
|
618
|
+
"husky",
|
|
619
|
+
"simple-git-hooks",
|
|
620
|
+
"lint-staged",
|
|
621
|
+
"eslintConfig"
|
|
622
|
+
],
|
|
623
|
+
pathPattern: "^$"
|
|
624
|
+
},
|
|
625
|
+
{
|
|
626
|
+
order: { type: "asc" },
|
|
627
|
+
pathPattern: "^(?:dev|peer|optional|bundled)?[Dd]ependencies(Meta)?$"
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
order: { type: "asc" },
|
|
631
|
+
pathPattern: "^(?:resolutions|overrides|pnpm.overrides)$"
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
order: { type: "asc" },
|
|
635
|
+
pathPattern: "^workspaces\\.catalog$"
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
order: { type: "asc" },
|
|
639
|
+
pathPattern: "^workspaces\\.catalogs\\.[^.]+$"
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
order: [
|
|
643
|
+
"types",
|
|
644
|
+
"import",
|
|
645
|
+
"require",
|
|
646
|
+
"default"
|
|
647
|
+
],
|
|
648
|
+
pathPattern: "^exports.*$"
|
|
649
|
+
},
|
|
650
|
+
{
|
|
651
|
+
order: [
|
|
652
|
+
"pre-commit",
|
|
653
|
+
"prepare-commit-msg",
|
|
654
|
+
"commit-msg",
|
|
655
|
+
"post-commit",
|
|
656
|
+
"pre-rebase",
|
|
657
|
+
"post-rewrite",
|
|
658
|
+
"post-checkout",
|
|
659
|
+
"post-merge",
|
|
660
|
+
"pre-push",
|
|
661
|
+
"pre-auto-gc"
|
|
662
|
+
],
|
|
663
|
+
pathPattern: "^(?:gitHooks|husky|simple-git-hooks)$"
|
|
664
|
+
}
|
|
665
|
+
]
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
name: "favorodera/jsonc/sort/tsconfig-json",
|
|
670
|
+
files: tsConfigGlob,
|
|
671
|
+
rules: { "jsonc/sort-keys": [
|
|
672
|
+
"error",
|
|
673
|
+
{
|
|
674
|
+
order: [
|
|
675
|
+
"extends",
|
|
676
|
+
"compilerOptions",
|
|
677
|
+
"references",
|
|
678
|
+
"files",
|
|
679
|
+
"include",
|
|
680
|
+
"exclude"
|
|
681
|
+
],
|
|
682
|
+
pathPattern: "^$"
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
order: [
|
|
686
|
+
"incremental",
|
|
687
|
+
"composite",
|
|
688
|
+
"tsBuildInfoFile",
|
|
689
|
+
"disableSourceOfProjectReferenceRedirect",
|
|
690
|
+
"disableSolutionSearching",
|
|
691
|
+
"disableReferencedProjectLoad",
|
|
692
|
+
"target",
|
|
693
|
+
"jsx",
|
|
694
|
+
"jsxFactory",
|
|
695
|
+
"jsxFragmentFactory",
|
|
696
|
+
"jsxImportSource",
|
|
697
|
+
"lib",
|
|
698
|
+
"moduleDetection",
|
|
699
|
+
"noLib",
|
|
700
|
+
"reactNamespace",
|
|
701
|
+
"useDefineForClassFields",
|
|
702
|
+
"emitDecoratorMetadata",
|
|
703
|
+
"experimentalDecorators",
|
|
704
|
+
"libReplacement",
|
|
705
|
+
"baseUrl",
|
|
706
|
+
"rootDir",
|
|
707
|
+
"rootDirs",
|
|
708
|
+
"customConditions",
|
|
709
|
+
"module",
|
|
710
|
+
"moduleResolution",
|
|
711
|
+
"moduleSuffixes",
|
|
712
|
+
"noResolve",
|
|
713
|
+
"paths",
|
|
714
|
+
"resolveJsonModule",
|
|
715
|
+
"resolvePackageJsonExports",
|
|
716
|
+
"resolvePackageJsonImports",
|
|
717
|
+
"typeRoots",
|
|
718
|
+
"types",
|
|
719
|
+
"allowArbitraryExtensions",
|
|
720
|
+
"allowImportingTsExtensions",
|
|
721
|
+
"allowUmdGlobalAccess",
|
|
722
|
+
"allowJs",
|
|
723
|
+
"checkJs",
|
|
724
|
+
"maxNodeModuleJsDepth",
|
|
725
|
+
"strict",
|
|
726
|
+
"strictBindCallApply",
|
|
727
|
+
"strictFunctionTypes",
|
|
728
|
+
"strictNullChecks",
|
|
729
|
+
"strictPropertyInitialization",
|
|
730
|
+
"allowUnreachableCode",
|
|
731
|
+
"allowUnusedLabels",
|
|
732
|
+
"alwaysStrict",
|
|
733
|
+
"exactOptionalPropertyTypes",
|
|
734
|
+
"noFallthroughCasesInSwitch",
|
|
735
|
+
"noImplicitAny",
|
|
736
|
+
"noImplicitOverride",
|
|
737
|
+
"noImplicitReturns",
|
|
738
|
+
"noImplicitThis",
|
|
739
|
+
"noPropertyAccessFromIndexSignature",
|
|
740
|
+
"noUncheckedIndexedAccess",
|
|
741
|
+
"noUnusedLocals",
|
|
742
|
+
"noUnusedParameters",
|
|
743
|
+
"useUnknownInCatchVariables",
|
|
744
|
+
"declaration",
|
|
745
|
+
"declarationDir",
|
|
746
|
+
"declarationMap",
|
|
747
|
+
"downlevelIteration",
|
|
748
|
+
"emitBOM",
|
|
749
|
+
"emitDeclarationOnly",
|
|
750
|
+
"importHelpers",
|
|
751
|
+
"importsNotUsedAsValues",
|
|
752
|
+
"inlineSourceMap",
|
|
753
|
+
"inlineSources",
|
|
754
|
+
"mapRoot",
|
|
755
|
+
"newLine",
|
|
756
|
+
"noEmit",
|
|
757
|
+
"noEmitHelpers",
|
|
758
|
+
"noEmitOnError",
|
|
759
|
+
"outDir",
|
|
760
|
+
"outFile",
|
|
761
|
+
"preserveConstEnums",
|
|
762
|
+
"preserveValueImports",
|
|
763
|
+
"removeComments",
|
|
764
|
+
"sourceMap",
|
|
765
|
+
"sourceRoot",
|
|
766
|
+
"stripInternal",
|
|
767
|
+
"allowSyntheticDefaultImports",
|
|
768
|
+
"esModuleInterop",
|
|
769
|
+
"forceConsistentCasingInFileNames",
|
|
770
|
+
"isolatedDeclarations",
|
|
771
|
+
"isolatedModules",
|
|
772
|
+
"preserveSymlinks",
|
|
773
|
+
"verbatimModuleSyntax",
|
|
774
|
+
"erasableSyntaxOnly",
|
|
775
|
+
"skipDefaultLibCheck",
|
|
776
|
+
"skipLibCheck"
|
|
777
|
+
],
|
|
778
|
+
pathPattern: "^compilerOptions$"
|
|
779
|
+
}
|
|
780
|
+
] }
|
|
781
|
+
}
|
|
782
|
+
];
|
|
783
|
+
}
|
|
784
|
+
//#endregion
|
|
785
|
+
//#region src/configs/jsdoc.ts
|
|
786
|
+
const jsdocDefaults = { files: [
|
|
787
|
+
jsGlob,
|
|
788
|
+
tsGlob,
|
|
789
|
+
vueGlob
|
|
790
|
+
] };
|
|
791
|
+
/**
|
|
792
|
+
* Constructs the flat config items for JSDoc linting, ensuring comments follow
|
|
793
|
+
* proper styling, parameter checks, and types alignment.
|
|
794
|
+
* @param options JSDoc configuration options.
|
|
795
|
+
* @returns Promise resolving to JSDoc ESLint config items.
|
|
796
|
+
*/
|
|
797
|
+
async function jsdoc(options) {
|
|
798
|
+
const resolved = defu(options, jsdocDefaults);
|
|
799
|
+
const jsdocPlugin = await importModule(import("eslint-plugin-jsdoc"));
|
|
800
|
+
const baseRules = {
|
|
801
|
+
...jsdocPlugin.configs["flat/recommended-typescript-error"]?.rules,
|
|
802
|
+
...jsdocPlugin.configs["flat/stylistic-typescript-error"]?.rules
|
|
803
|
+
};
|
|
804
|
+
return [{
|
|
805
|
+
name: "favorodera/jsdoc/setup",
|
|
806
|
+
plugins: { jsdoc: jsdocPlugin }
|
|
807
|
+
}, {
|
|
808
|
+
name: "favorodera/tailwind/rules",
|
|
809
|
+
files: resolved.files,
|
|
810
|
+
rules: {
|
|
811
|
+
...baseRules || {},
|
|
812
|
+
"jsdoc/check-access": "warn",
|
|
813
|
+
"jsdoc/check-param-names": "warn",
|
|
814
|
+
"jsdoc/check-property-names": "warn",
|
|
815
|
+
"jsdoc/check-types": "warn",
|
|
816
|
+
"jsdoc/empty-tags": "warn",
|
|
817
|
+
"jsdoc/implements-on-classes": "warn",
|
|
818
|
+
"jsdoc/no-defaults": "warn",
|
|
819
|
+
"jsdoc/no-multi-asterisks": "warn",
|
|
820
|
+
"jsdoc/require-param-name": "warn",
|
|
821
|
+
"jsdoc/require-property": "warn",
|
|
822
|
+
"jsdoc/require-property-description": "warn",
|
|
823
|
+
"jsdoc/require-property-name": "warn",
|
|
824
|
+
"jsdoc/require-returns-check": "warn",
|
|
825
|
+
"jsdoc/require-returns-description": "warn",
|
|
826
|
+
"jsdoc/require-yields-check": "warn",
|
|
827
|
+
"jsdoc/check-alignment": "warn",
|
|
828
|
+
"jsdoc/multiline-blocks": "warn",
|
|
393
829
|
...resolved.overrides
|
|
394
830
|
}
|
|
395
831
|
}];
|
|
@@ -397,9 +833,10 @@ async function typescript(options) {
|
|
|
397
833
|
//#endregion
|
|
398
834
|
//#region src/factory.ts
|
|
399
835
|
/**
|
|
400
|
-
* Factory to create a flat ESLint config
|
|
401
|
-
*
|
|
402
|
-
* @
|
|
836
|
+
* Factory to create a flat ESLint config.
|
|
837
|
+
* It builds an ESLint config by sequentially adding sub-configs based on the provided options.
|
|
838
|
+
* @param options Configuration options for enabling/disabling or configuring specific rule sets.
|
|
839
|
+
* @returns A flat config composer instance that can be exported directly or further modified.
|
|
403
840
|
*/
|
|
404
841
|
function factory(options = {}) {
|
|
405
842
|
const configs = [];
|
|
@@ -411,7 +848,9 @@ function factory(options = {}) {
|
|
|
411
848
|
tailwind,
|
|
412
849
|
imports,
|
|
413
850
|
markdown,
|
|
414
|
-
javascript
|
|
851
|
+
javascript,
|
|
852
|
+
jsonc,
|
|
853
|
+
jsdoc
|
|
415
854
|
};
|
|
416
855
|
for (const [key, configFunction] of Object.entries(configFunctions)) {
|
|
417
856
|
const configOption = options[key];
|