@favorodera/eslint-config 0.0.4 → 0.0.6
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/LICENSE +21 -0
- package/README.md +13 -8
- package/dist/index.cjs +945 -406
- package/dist/index.d.cts +8313 -3019
- package/dist/index.d.mts +8315 -3021
- package/dist/index.mjs +945 -407
- package/package.json +11 -2
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}";
|
|
@@ -41,6 +41,8 @@ const mdGlob = "**/*.md";
|
|
|
41
41
|
const mdInMdGlob = "**/*.md/*.md";
|
|
42
42
|
/** Glob pattern for matching code blocks embedded in Markdown files */
|
|
43
43
|
const codeInMdGlob = "**/*.md/**/*.{js,cjs,mjs,ts,cts,mts,vue}";
|
|
44
|
+
/** Glob pattern for matching test files */
|
|
45
|
+
const testsGlob = ["**/*.{tests,specs,benchmark,bench}.{js,cjs,mjs,ts,cts,mts}", "**/__tests__/**/*.{js,cjs,mjs,ts,cts,mts}"];
|
|
44
46
|
/** Glob pattern for matching JSON files */
|
|
45
47
|
const jsonGlob = "**/*.json";
|
|
46
48
|
/** Glob pattern for matching JSON5 files */
|
|
@@ -49,13 +51,15 @@ const json5Glob = "**/*.json5";
|
|
|
49
51
|
const jsoncGlob = "**/*.jsonc";
|
|
50
52
|
/** Glob patterns for matching TypeScript configuration files */
|
|
51
53
|
const tsConfigGlob = ["**/tsconfig.json", "**/tsconfig.*.json"];
|
|
54
|
+
/** Glob pattern for matching YAML files */
|
|
55
|
+
const yamlGlob = "**/*.{yml,yaml}";
|
|
56
|
+
/** Glob pattern for matching pnpm-workspace.yaml file */
|
|
57
|
+
const pnpmWorkspaceGlob = "pnpm-workspace.yaml";
|
|
52
58
|
/** Glob pattern for matching package.json files */
|
|
53
59
|
const packageJsonGlob = "**/package.json";
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
*/
|
|
58
|
-
const ignoresGlob = [
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/configs/ignores.ts
|
|
62
|
+
const defaultPatterns = [
|
|
59
63
|
"**/node_modules/**",
|
|
60
64
|
"**/dist/**",
|
|
61
65
|
"**/package-lock.json",
|
|
@@ -92,9 +96,28 @@ const ignoresGlob = [
|
|
|
92
96
|
"**/.agents",
|
|
93
97
|
"**/.*/skills"
|
|
94
98
|
];
|
|
99
|
+
/**
|
|
100
|
+
* Globs for ignoring files and directories from ESLint scanning.
|
|
101
|
+
* @param patterns Additional ignore patterns or a function to modify the defaults.
|
|
102
|
+
* @returns An array containing the ignore flat config item.
|
|
103
|
+
*/
|
|
104
|
+
function ignores(patterns = []) {
|
|
105
|
+
return [{
|
|
106
|
+
ignores: typeof patterns === "function" ? patterns(defaultPatterns) : [...defaultPatterns, ...patterns],
|
|
107
|
+
name: "favorodera/ignores"
|
|
108
|
+
}];
|
|
109
|
+
}
|
|
95
110
|
//#endregion
|
|
96
111
|
//#region src/utils.ts
|
|
97
112
|
/**
|
|
113
|
+
* Extracts and merges the rules from multiple ESLint configuration arrays.
|
|
114
|
+
* @param configArrays Rest parameter representing multiple arrays of ESLint flat config items.
|
|
115
|
+
* @returns A single object containing all the merged rules from the provided configurations.
|
|
116
|
+
*/
|
|
117
|
+
function extractRules(...configArrays) {
|
|
118
|
+
return Object.assign({}, ...configArrays.flat().map((config) => config?.rules || {}));
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
98
121
|
* Resolves a module (or a promise of one) and returns its default export
|
|
99
122
|
* if present, otherwise returns the module itself.
|
|
100
123
|
*
|
|
@@ -121,108 +144,6 @@ function resolveOptions(value, defaults) {
|
|
|
121
144
|
if (!value) return false;
|
|
122
145
|
return (0, defu.defu)(value === true ? {} : value, defaults);
|
|
123
146
|
}
|
|
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
147
|
//#endregion
|
|
227
148
|
//#region src/configs/imports.ts
|
|
228
149
|
const importsDefaults = { files: [
|
|
@@ -247,16 +168,16 @@ async function imports(options) {
|
|
|
247
168
|
"unused-imports": unusedImportsPlugin
|
|
248
169
|
}
|
|
249
170
|
}, {
|
|
250
|
-
name: "favorodera/imports/rules",
|
|
251
171
|
files: resolved.files,
|
|
172
|
+
name: "favorodera/imports/rules",
|
|
252
173
|
rules: {
|
|
253
174
|
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { "import-lite": "import" }),
|
|
254
|
-
"import/consistent-type-specifier-style": ["error", "top-level"],
|
|
175
|
+
"import/consistent-type-specifier-style": ["error", "prefer-top-level"],
|
|
255
176
|
"import/first": "error",
|
|
177
|
+
"import/newline-after-import": ["error", { count: 1 }],
|
|
256
178
|
"import/no-duplicates": "error",
|
|
257
179
|
"import/no-mutable-exports": "error",
|
|
258
180
|
"import/no-named-default": "error",
|
|
259
|
-
"import/newline-after-import": ["error", { count: 1 }],
|
|
260
181
|
"unused-imports/no-unused-imports": "error",
|
|
261
182
|
"unused-imports/no-unused-vars": ["error", {
|
|
262
183
|
args: "after-used",
|
|
@@ -286,10 +207,8 @@ async function javascript(options) {
|
|
|
286
207
|
const resolved = (0, defu.defu)(options, javascriptDefaults);
|
|
287
208
|
const baseRules = (await importModule(import("@eslint/js"))).configs.recommended.rules;
|
|
288
209
|
return [{
|
|
289
|
-
name: "favorodera/javascript/setup",
|
|
290
210
|
languageOptions: {
|
|
291
211
|
ecmaVersion: "latest",
|
|
292
|
-
sourceType: "module",
|
|
293
212
|
globals: {
|
|
294
213
|
...globals.default.browser,
|
|
295
214
|
...globals.default.es2021,
|
|
@@ -297,251 +216,278 @@ async function javascript(options) {
|
|
|
297
216
|
document: "readonly",
|
|
298
217
|
navigator: "readonly",
|
|
299
218
|
window: "readonly"
|
|
300
|
-
}
|
|
219
|
+
},
|
|
220
|
+
sourceType: "module"
|
|
301
221
|
},
|
|
302
|
-
linterOptions: { reportUnusedDisableDirectives: true }
|
|
222
|
+
linterOptions: { reportUnusedDisableDirectives: true },
|
|
223
|
+
name: "favorodera/javascript/setup"
|
|
303
224
|
}, {
|
|
304
|
-
name: "favorodera/javascript/rules",
|
|
305
225
|
files: resolved.files,
|
|
226
|
+
name: "favorodera/javascript/rules",
|
|
306
227
|
rules: {
|
|
307
228
|
...baseRules,
|
|
308
|
-
"accessor-pairs": ["error", {
|
|
309
|
-
enforceForClassMembers: true,
|
|
310
|
-
setWithoutGet: true
|
|
311
|
-
}],
|
|
312
229
|
"array-callback-return": "error",
|
|
313
230
|
"block-scoped-var": "error",
|
|
231
|
+
"constructor-super": "error",
|
|
232
|
+
"default-case-last": "error",
|
|
233
|
+
"dot-notation": ["error", { allowKeywords: true }],
|
|
234
|
+
"eqeqeq": ["error", "smart"],
|
|
235
|
+
"new-cap": ["error", {
|
|
236
|
+
capIsNew: false,
|
|
237
|
+
newIsCap: true,
|
|
238
|
+
properties: true
|
|
239
|
+
}],
|
|
240
|
+
"no-alert": "error",
|
|
241
|
+
"no-array-constructor": "error",
|
|
242
|
+
"no-async-promise-executor": "error",
|
|
243
|
+
"no-caller": "error",
|
|
244
|
+
"no-case-declarations": "error",
|
|
245
|
+
"no-class-assign": "error",
|
|
246
|
+
"no-compare-neg-zero": "error",
|
|
247
|
+
"no-cond-assign": ["error", "always"],
|
|
248
|
+
"no-console": ["error", { allow: ["warn", "error"] }],
|
|
249
|
+
"no-const-assign": "error",
|
|
250
|
+
"no-control-regex": "error",
|
|
251
|
+
"no-debugger": "error",
|
|
252
|
+
"no-delete-var": "error",
|
|
253
|
+
"no-dupe-args": "error",
|
|
254
|
+
"no-dupe-class-members": "error",
|
|
255
|
+
"no-dupe-keys": "error",
|
|
256
|
+
"no-duplicate-case": "error",
|
|
257
|
+
"no-empty": ["error", { allowEmptyCatch: true }],
|
|
258
|
+
"no-empty-character-class": "error",
|
|
259
|
+
"no-empty-pattern": "error",
|
|
260
|
+
"no-eval": "error",
|
|
261
|
+
"no-ex-assign": "error",
|
|
262
|
+
"no-extend-native": "error",
|
|
263
|
+
"no-extra-bind": "error",
|
|
264
|
+
"no-extra-boolean-cast": "error",
|
|
265
|
+
"no-fallthrough": "error",
|
|
266
|
+
"no-func-assign": "error",
|
|
267
|
+
"no-global-assign": "error",
|
|
268
|
+
"no-implied-eval": "error",
|
|
269
|
+
"no-import-assign": "error",
|
|
270
|
+
"no-invalid-regexp": "error",
|
|
271
|
+
"no-irregular-whitespace": "error",
|
|
272
|
+
"no-iterator": "error",
|
|
273
|
+
"no-labels": ["error", {
|
|
274
|
+
allowLoop: false,
|
|
275
|
+
allowSwitch: false
|
|
276
|
+
}],
|
|
277
|
+
"no-lone-blocks": "error",
|
|
278
|
+
"no-loss-of-precision": "error",
|
|
279
|
+
"no-misleading-character-class": "error",
|
|
280
|
+
"no-multi-str": "error",
|
|
281
|
+
"no-new": "error",
|
|
282
|
+
"no-new-func": "error",
|
|
283
|
+
"no-new-native-nonconstructor": "error",
|
|
284
|
+
"no-new-wrappers": "error",
|
|
285
|
+
"no-obj-calls": "error",
|
|
286
|
+
"no-octal": "error",
|
|
287
|
+
"no-octal-escape": "error",
|
|
288
|
+
"no-proto": "error",
|
|
289
|
+
"no-prototype-builtins": "error",
|
|
290
|
+
"no-redeclare": ["error", { builtinGlobals: false }],
|
|
291
|
+
"no-regex-spaces": "error",
|
|
292
|
+
"no-restricted-globals": [
|
|
293
|
+
"error",
|
|
294
|
+
{
|
|
295
|
+
message: "Use `globalThis` instead.",
|
|
296
|
+
name: "global"
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
message: "Use `globalThis` instead.",
|
|
300
|
+
name: "self"
|
|
301
|
+
}
|
|
302
|
+
],
|
|
303
|
+
"no-restricted-properties": [
|
|
304
|
+
"error",
|
|
305
|
+
{
|
|
306
|
+
message: "Use `Object.getPrototypeOf` or `Object.setPrototypeOf` instead.",
|
|
307
|
+
property: "__proto__"
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
message: "Use `Object.defineProperty` instead.",
|
|
311
|
+
property: "__defineGetter__"
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
message: "Use `Object.defineProperty` instead.",
|
|
315
|
+
property: "__defineSetter__"
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
message: "Use `Object.getOwnPropertyDescriptor` instead.",
|
|
319
|
+
property: "__lookupGetter__"
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
message: "Use `Object.getOwnPropertyDescriptor` instead.",
|
|
323
|
+
property: "__lookupSetter__"
|
|
324
|
+
}
|
|
325
|
+
],
|
|
326
|
+
"no-restricted-syntax": [
|
|
327
|
+
"error",
|
|
328
|
+
"TSEnumDeclaration[const=true]",
|
|
329
|
+
"TSExportAssignment"
|
|
330
|
+
],
|
|
331
|
+
"no-self-assign": ["error", { props: true }],
|
|
332
|
+
"no-self-compare": "error",
|
|
333
|
+
"no-sequences": "error",
|
|
334
|
+
"no-shadow-restricted-names": "error",
|
|
335
|
+
"no-sparse-arrays": "error",
|
|
336
|
+
"no-template-curly-in-string": "error",
|
|
337
|
+
"no-this-before-super": "error",
|
|
338
|
+
"no-throw-literal": "error",
|
|
339
|
+
"no-undef": "error",
|
|
340
|
+
"no-undef-init": "error",
|
|
341
|
+
"no-unexpected-multiline": "error",
|
|
342
|
+
"no-unmodified-loop-condition": "error",
|
|
343
|
+
"no-unneeded-ternary": ["error", { defaultAssignment: false }],
|
|
344
|
+
"no-unreachable": "error",
|
|
345
|
+
"no-unreachable-loop": "error",
|
|
346
|
+
"no-unsafe-finally": "error",
|
|
347
|
+
"no-unsafe-negation": "error",
|
|
348
|
+
"no-unused-expressions": ["error", {
|
|
349
|
+
allowShortCircuit: true,
|
|
350
|
+
allowTaggedTemplates: true,
|
|
351
|
+
allowTernary: true
|
|
352
|
+
}],
|
|
353
|
+
"no-unused-vars": ["error", {
|
|
354
|
+
args: "none",
|
|
355
|
+
caughtErrors: "none",
|
|
356
|
+
ignoreRestSiblings: true,
|
|
357
|
+
vars: "all"
|
|
358
|
+
}],
|
|
359
|
+
"no-use-before-define": ["error", {
|
|
360
|
+
classes: false,
|
|
361
|
+
functions: false,
|
|
362
|
+
variables: true
|
|
363
|
+
}],
|
|
364
|
+
"no-useless-backreference": "error",
|
|
365
|
+
"no-useless-call": "error",
|
|
366
|
+
"no-useless-catch": "error",
|
|
367
|
+
"no-useless-computed-key": "error",
|
|
368
|
+
"no-useless-constructor": "error",
|
|
369
|
+
"no-useless-rename": "error",
|
|
370
|
+
"no-useless-return": "error",
|
|
371
|
+
"no-var": "error",
|
|
372
|
+
"no-with": "error",
|
|
373
|
+
"object-shorthand": [
|
|
374
|
+
"error",
|
|
375
|
+
"always",
|
|
376
|
+
{
|
|
377
|
+
avoidQuotes: true,
|
|
378
|
+
ignoreConstructors: false
|
|
379
|
+
}
|
|
380
|
+
],
|
|
381
|
+
"one-var": ["error", { initialized: "never" }],
|
|
382
|
+
"prefer-arrow-callback": ["error", {
|
|
383
|
+
allowNamedFunctions: false,
|
|
384
|
+
allowUnboundThis: true
|
|
385
|
+
}],
|
|
386
|
+
"prefer-const": ["error", {
|
|
387
|
+
destructuring: "all",
|
|
388
|
+
ignoreReadBeforeAssign: true
|
|
389
|
+
}],
|
|
390
|
+
"prefer-exponentiation-operator": "error",
|
|
391
|
+
"prefer-promise-reject-errors": "error",
|
|
392
|
+
"prefer-regex-literals": ["error", { disallowRedundantWrapping: true }],
|
|
393
|
+
"prefer-rest-params": "error",
|
|
394
|
+
"prefer-spread": "error",
|
|
395
|
+
"prefer-template": "error",
|
|
396
|
+
"symbol-description": "error",
|
|
397
|
+
"unicode-bom": ["error", "never"],
|
|
398
|
+
"use-isnan": ["error", {
|
|
399
|
+
enforceForIndexOf: true,
|
|
400
|
+
enforceForSwitchCase: true
|
|
401
|
+
}],
|
|
402
|
+
"valid-typeof": ["error", { requireStringLiterals: true }],
|
|
403
|
+
"vars-on-top": "error",
|
|
404
|
+
"yoda": ["error", "never"],
|
|
314
405
|
...resolved.overrides
|
|
315
406
|
}
|
|
316
407
|
}];
|
|
317
408
|
}
|
|
318
409
|
//#endregion
|
|
319
|
-
//#region src/configs/
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
410
|
+
//#region src/configs/jsdoc.ts
|
|
411
|
+
const jsdocDefaults = { files: [
|
|
412
|
+
jsGlob,
|
|
413
|
+
tsGlob,
|
|
414
|
+
vueGlob
|
|
415
|
+
] };
|
|
324
416
|
/**
|
|
325
|
-
* Constructs the flat config items for
|
|
326
|
-
*
|
|
327
|
-
* @param options
|
|
328
|
-
* @returns Promise resolving to
|
|
417
|
+
* Constructs the flat config items for JSDoc linting, ensuring comments follow
|
|
418
|
+
* proper styling, parameter checks, and types alignment.
|
|
419
|
+
* @param options JSDoc configuration options.
|
|
420
|
+
* @returns Promise resolving to JSDoc ESLint config items.
|
|
329
421
|
*/
|
|
330
|
-
async function
|
|
331
|
-
const resolved = (0, defu.defu)(options,
|
|
332
|
-
const
|
|
333
|
-
const baseRules =
|
|
422
|
+
async function jsdoc(options) {
|
|
423
|
+
const resolved = (0, defu.defu)(options, jsdocDefaults);
|
|
424
|
+
const jsdocPlugin = await importModule(import("eslint-plugin-jsdoc"));
|
|
425
|
+
const baseRules = {
|
|
426
|
+
...jsdocPlugin.configs["flat/recommended-typescript-error"]?.rules,
|
|
427
|
+
...jsdocPlugin.configs["flat/stylistic-typescript-error"]?.rules
|
|
428
|
+
};
|
|
429
|
+
return [{
|
|
430
|
+
name: "favorodera/jsdoc/setup",
|
|
431
|
+
plugins: { jsdoc: jsdocPlugin }
|
|
432
|
+
}, {
|
|
433
|
+
files: resolved.files,
|
|
434
|
+
name: "favorodera/jsdoc/rules",
|
|
435
|
+
rules: {
|
|
436
|
+
...baseRules,
|
|
437
|
+
"jsdoc/check-access": "warn",
|
|
438
|
+
"jsdoc/check-alignment": "warn",
|
|
439
|
+
"jsdoc/check-param-names": "warn",
|
|
440
|
+
"jsdoc/check-property-names": "warn",
|
|
441
|
+
"jsdoc/check-types": "warn",
|
|
442
|
+
"jsdoc/empty-tags": "warn",
|
|
443
|
+
"jsdoc/implements-on-classes": "warn",
|
|
444
|
+
"jsdoc/multiline-blocks": "warn",
|
|
445
|
+
"jsdoc/no-defaults": "warn",
|
|
446
|
+
"jsdoc/no-multi-asterisks": "warn",
|
|
447
|
+
"jsdoc/require-param-name": "warn",
|
|
448
|
+
"jsdoc/require-property": "warn",
|
|
449
|
+
"jsdoc/require-property-description": "warn",
|
|
450
|
+
"jsdoc/require-property-name": "warn",
|
|
451
|
+
"jsdoc/require-returns-check": "warn",
|
|
452
|
+
"jsdoc/require-returns-description": "warn",
|
|
453
|
+
"jsdoc/require-yields-check": "warn",
|
|
454
|
+
...resolved.overrides
|
|
455
|
+
}
|
|
456
|
+
}];
|
|
457
|
+
}
|
|
458
|
+
//#endregion
|
|
459
|
+
//#region src/configs/jsonc.ts
|
|
460
|
+
const jsoncDefaults = { files: [
|
|
461
|
+
json5Glob,
|
|
462
|
+
jsoncGlob,
|
|
463
|
+
jsonGlob
|
|
464
|
+
] };
|
|
465
|
+
/**
|
|
466
|
+
* Constructs the flat config items for JSON, JSON5, and JSONC linting, setting up
|
|
467
|
+
* the custom parser, rule validations, and sorting rules for package.json/tsconfig.json.
|
|
468
|
+
* @param options JSONC configuration options.
|
|
469
|
+
* @returns Promise resolving to JSONC ESLint config items.
|
|
470
|
+
*/
|
|
471
|
+
async function jsonc(options) {
|
|
472
|
+
const resolved = (0, defu.defu)(options, jsoncDefaults);
|
|
334
473
|
return [
|
|
335
474
|
{
|
|
336
|
-
name: "favorodera/
|
|
337
|
-
plugins: {
|
|
475
|
+
name: "favorodera/jsonc/setup",
|
|
476
|
+
plugins: { jsonc: await importModule(import("eslint-plugin-jsonc")) }
|
|
338
477
|
},
|
|
339
478
|
{
|
|
340
|
-
name: "favorodera/markdown/rules",
|
|
341
479
|
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",
|
|
480
|
+
language: "jsonc/x",
|
|
481
|
+
name: "favorodera/jsonc/rules",
|
|
544
482
|
rules: {
|
|
483
|
+
"jsonc/array-bracket-spacing": ["error", "never"],
|
|
484
|
+
"jsonc/comma-dangle": ["error", "never"],
|
|
485
|
+
"jsonc/comma-style": ["error", "last"],
|
|
486
|
+
"jsonc/indent": ["error", 2],
|
|
487
|
+
"jsonc/key-spacing": ["error", {
|
|
488
|
+
afterColon: true,
|
|
489
|
+
beforeColon: false
|
|
490
|
+
}],
|
|
545
491
|
"jsonc/no-bigint-literals": "error",
|
|
546
492
|
"jsonc/no-binary-expression": "error",
|
|
547
493
|
"jsonc/no-binary-numeric-literals": "error",
|
|
@@ -565,17 +511,6 @@ async function jsonc(options) {
|
|
|
565
511
|
"jsonc/no-undefined-value": "error",
|
|
566
512
|
"jsonc/no-unicode-codepoint-escapes": "error",
|
|
567
513
|
"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
514
|
"jsonc/object-curly-newline": ["error", {
|
|
580
515
|
consistent: true,
|
|
581
516
|
multiline: true
|
|
@@ -584,12 +519,15 @@ async function jsonc(options) {
|
|
|
584
519
|
"jsonc/object-property-newline": ["error", { allowAllPropertiesOnSameLine: true }],
|
|
585
520
|
"jsonc/quote-props": "error",
|
|
586
521
|
"jsonc/quotes": "error",
|
|
522
|
+
"jsonc/space-unary-ops": "error",
|
|
523
|
+
"jsonc/valid-json-number": "error",
|
|
524
|
+
"jsonc/vue-custom-block/no-parsing-error": "error",
|
|
587
525
|
...resolved.overrides
|
|
588
526
|
}
|
|
589
527
|
},
|
|
590
528
|
{
|
|
591
|
-
name: "favorodera/jsonc/sort/package-json",
|
|
592
529
|
files: [packageJsonGlob],
|
|
530
|
+
name: "favorodera/jsonc/sort/package-json",
|
|
593
531
|
rules: {
|
|
594
532
|
"jsonc/sort-array-values": ["error", {
|
|
595
533
|
order: { type: "asc" },
|
|
@@ -657,11 +595,11 @@ async function jsonc(options) {
|
|
|
657
595
|
},
|
|
658
596
|
{
|
|
659
597
|
order: { type: "asc" },
|
|
660
|
-
pathPattern:
|
|
598
|
+
pathPattern: String.raw`^workspaces\.catalog$`
|
|
661
599
|
},
|
|
662
600
|
{
|
|
663
601
|
order: { type: "asc" },
|
|
664
|
-
pathPattern:
|
|
602
|
+
pathPattern: String.raw`^workspaces\.catalogs\.[^.]+$`
|
|
665
603
|
},
|
|
666
604
|
{
|
|
667
605
|
order: [
|
|
@@ -691,8 +629,8 @@ async function jsonc(options) {
|
|
|
691
629
|
}
|
|
692
630
|
},
|
|
693
631
|
{
|
|
694
|
-
name: "favorodera/jsonc/sort/tsconfig-json",
|
|
695
632
|
files: tsConfigGlob,
|
|
633
|
+
name: "favorodera/jsonc/sort/tsconfig-json",
|
|
696
634
|
rules: { "jsonc/sort-keys": [
|
|
697
635
|
"error",
|
|
698
636
|
{
|
|
@@ -807,55 +745,647 @@ async function jsonc(options) {
|
|
|
807
745
|
];
|
|
808
746
|
}
|
|
809
747
|
//#endregion
|
|
810
|
-
//#region src/configs/
|
|
811
|
-
const
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
] };
|
|
748
|
+
//#region src/configs/markdown.ts
|
|
749
|
+
const markdownDefaults = {
|
|
750
|
+
files: [mdGlob],
|
|
751
|
+
gfm: true
|
|
752
|
+
};
|
|
816
753
|
/**
|
|
817
|
-
* Constructs the flat config items for
|
|
818
|
-
*
|
|
819
|
-
* @param options
|
|
820
|
-
* @returns Promise resolving to
|
|
754
|
+
* Constructs the flat config items for Markdown linting, extracting and linting
|
|
755
|
+
* embedded code blocks within the document according to specified rules.
|
|
756
|
+
* @param options Markdown configuration options.
|
|
757
|
+
* @returns Promise resolving to Markdown ESLint config items.
|
|
821
758
|
*/
|
|
822
|
-
async function
|
|
823
|
-
const resolved = (0, defu.defu)(options,
|
|
824
|
-
const
|
|
825
|
-
const baseRules =
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
"
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
759
|
+
async function markdown(options) {
|
|
760
|
+
const resolved = (0, defu.defu)(options, markdownDefaults);
|
|
761
|
+
const markdownPlugin = await importModule(import("@eslint/markdown"));
|
|
762
|
+
const baseRules = extractRules(markdownPlugin.configs.recommended);
|
|
763
|
+
return [
|
|
764
|
+
{
|
|
765
|
+
name: "favorodera/markdown/setup",
|
|
766
|
+
plugins: { md: markdownPlugin }
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
files: resolved.files,
|
|
770
|
+
ignores: [mdInMdGlob],
|
|
771
|
+
language: resolved.gfm ? "md/gfm" : "md/commonmark",
|
|
772
|
+
name: "favorodera/markdown/rules",
|
|
773
|
+
processor: (0, eslint_merge_processors.mergeProcessors)([markdownPlugin.processors?.markdown, eslint_merge_processors.processorPassThrough]),
|
|
774
|
+
rules: {
|
|
775
|
+
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { markdown: "md" }),
|
|
776
|
+
"md/fenced-code-language": "off",
|
|
777
|
+
"md/no-missing-label-refs": "off",
|
|
778
|
+
...resolved.overrides
|
|
779
|
+
}
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
files: [codeInMdGlob],
|
|
783
|
+
languageOptions: { parserOptions: { ecmaFeatures: { impliedStrict: true } } },
|
|
784
|
+
name: "favorodera/markdown/code-in-md/disables",
|
|
785
|
+
rules: {
|
|
786
|
+
"no-alert": "off",
|
|
787
|
+
"no-console": "off",
|
|
788
|
+
"no-labels": "off",
|
|
789
|
+
"no-lone-blocks": "off",
|
|
790
|
+
"no-restricted-syntax": "off",
|
|
791
|
+
"no-undef": "off",
|
|
792
|
+
"no-unused-expressions": "off",
|
|
793
|
+
"no-unused-labels": "off",
|
|
794
|
+
"no-unused-vars": "off",
|
|
795
|
+
"node/prefer-global/process": "off",
|
|
796
|
+
"style/comma-dangle": "off",
|
|
797
|
+
"style/eol-last": "off",
|
|
798
|
+
"style/padding-line-between-statements": "off",
|
|
799
|
+
"ts/consistent-type-imports": "off",
|
|
800
|
+
"ts/explicit-function-return-type": "off",
|
|
801
|
+
"ts/no-namespace": "off",
|
|
802
|
+
"ts/no-redeclare": "off",
|
|
803
|
+
"ts/no-require-imports": "off",
|
|
804
|
+
"ts/no-unused-expressions": "off",
|
|
805
|
+
"ts/no-unused-vars": "off",
|
|
806
|
+
"ts/no-use-before-define": "off",
|
|
807
|
+
"unicode-bom": "off",
|
|
808
|
+
"unused-imports/no-unused-imports": "off",
|
|
809
|
+
"unused-imports/no-unused-vars": "off"
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
];
|
|
813
|
+
}
|
|
814
|
+
//#endregion
|
|
815
|
+
//#region src/configs/node.ts
|
|
816
|
+
const nodeDefaults = { files: [
|
|
817
|
+
jsGlob,
|
|
818
|
+
tsGlob,
|
|
819
|
+
vueGlob
|
|
820
|
+
] };
|
|
821
|
+
/**
|
|
822
|
+
* Constructs the flat config items for Node.js linting, providing rules
|
|
823
|
+
* to enforce best practices for Node.js environments.
|
|
824
|
+
* @param options Node configuration options.
|
|
825
|
+
* @returns Promise resolving to Node ESLint config items.
|
|
826
|
+
*/
|
|
827
|
+
async function node(options) {
|
|
828
|
+
const resolved = (0, defu.defu)(options, nodeDefaults);
|
|
829
|
+
const nodePlugin = await importModule(import("eslint-plugin-n"));
|
|
830
|
+
const baseRules = nodePlugin.configs?.["flat/recommended"]?.rules || {};
|
|
831
|
+
return [{
|
|
832
|
+
name: "favorodera/node/setup",
|
|
833
|
+
plugins: { node: nodePlugin }
|
|
834
|
+
}, {
|
|
835
|
+
files: resolved.files,
|
|
836
|
+
name: "favorodera/node/rules",
|
|
837
|
+
rules: {
|
|
838
|
+
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { n: "node" }),
|
|
839
|
+
"node/handle-callback-err": ["error", "^(err|error)$"],
|
|
840
|
+
"node/no-deprecated-api": "error",
|
|
841
|
+
"node/no-exports-assign": "error",
|
|
842
|
+
"node/no-missing-import": "off",
|
|
843
|
+
"node/no-new-require": "error",
|
|
844
|
+
"node/no-path-concat": "error",
|
|
845
|
+
"node/no-unpublished-import": "off",
|
|
846
|
+
"node/prefer-global/buffer": ["error", "never"],
|
|
847
|
+
"node/prefer-global/process": ["error", "never"],
|
|
848
|
+
"node/process-exit-as-throw": "error",
|
|
849
|
+
...resolved.overrides
|
|
850
|
+
}
|
|
851
|
+
}];
|
|
852
|
+
}
|
|
853
|
+
//#endregion
|
|
854
|
+
//#region src/configs/perfectionist.ts
|
|
855
|
+
const perfectionistDefaults = { files: [
|
|
856
|
+
jsGlob,
|
|
857
|
+
tsGlob,
|
|
858
|
+
vueGlob
|
|
859
|
+
] };
|
|
860
|
+
/**
|
|
861
|
+
* Constructs the flat config items for Perfectionist linting, providing rules
|
|
862
|
+
* to naturally sort objects, imports, classes, and other elements in your code.
|
|
863
|
+
* @param options Perfectionist configuration options.
|
|
864
|
+
* @returns Promise resolving to Perfectionist ESLint config items.
|
|
865
|
+
*/
|
|
866
|
+
async function perfectionist(options) {
|
|
867
|
+
const resolved = (0, defu.defu)(options, perfectionistDefaults);
|
|
868
|
+
const perfectionistPlugin = await importModule(import("eslint-plugin-perfectionist"));
|
|
869
|
+
const baseRules = perfectionistPlugin.configs["recommended-natural"]?.rules || {};
|
|
870
|
+
return [{
|
|
871
|
+
name: "favorodera/perfectionist/setup",
|
|
872
|
+
plugins: { perfectionist: perfectionistPlugin }
|
|
873
|
+
}, {
|
|
874
|
+
files: resolved.files,
|
|
875
|
+
name: "favorodera/perfectionist/rules",
|
|
876
|
+
rules: {
|
|
877
|
+
...baseRules,
|
|
878
|
+
"perfectionist/sort-exports": ["error", {
|
|
879
|
+
order: "asc",
|
|
880
|
+
type: "natural"
|
|
881
|
+
}],
|
|
882
|
+
"perfectionist/sort-imports": ["error", {
|
|
883
|
+
groups: [
|
|
884
|
+
"type-import",
|
|
885
|
+
[
|
|
886
|
+
"type-parent",
|
|
887
|
+
"type-sibling",
|
|
888
|
+
"type-index",
|
|
889
|
+
"type-internal"
|
|
890
|
+
],
|
|
891
|
+
"value-builtin",
|
|
892
|
+
"value-external",
|
|
893
|
+
"value-internal",
|
|
894
|
+
[
|
|
895
|
+
"value-parent",
|
|
896
|
+
"value-sibling",
|
|
897
|
+
"value-index"
|
|
898
|
+
],
|
|
899
|
+
"side-effect",
|
|
900
|
+
"ts-equals-import",
|
|
901
|
+
"unknown"
|
|
902
|
+
],
|
|
903
|
+
newlinesBetween: "ignore",
|
|
904
|
+
newlinesInside: "ignore",
|
|
905
|
+
order: "asc",
|
|
906
|
+
type: "natural"
|
|
907
|
+
}],
|
|
908
|
+
"perfectionist/sort-named-exports": ["error", {
|
|
909
|
+
order: "asc",
|
|
910
|
+
type: "natural"
|
|
911
|
+
}],
|
|
912
|
+
"perfectionist/sort-named-imports": ["error", {
|
|
913
|
+
order: "asc",
|
|
914
|
+
type: "natural"
|
|
915
|
+
}],
|
|
916
|
+
...resolved.overrides
|
|
917
|
+
}
|
|
918
|
+
}];
|
|
919
|
+
}
|
|
920
|
+
//#endregion
|
|
921
|
+
//#region src/configs/pnpm.ts
|
|
922
|
+
/**
|
|
923
|
+
* Constructs the flat config items for pnpm linting.
|
|
924
|
+
* @returns Promise resolving to pnpm ESLint config items.
|
|
925
|
+
*/
|
|
926
|
+
async function pnpm() {
|
|
927
|
+
const [pnpmPlugin, yamlParser] = await Promise.all([importModule(import("eslint-plugin-pnpm")), importModule(import("yaml-eslint-parser"))]);
|
|
928
|
+
return [
|
|
929
|
+
{
|
|
930
|
+
name: "favorodera/pnpm/setup",
|
|
931
|
+
plugins: { pnpm: pnpmPlugin }
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
files: [packageJsonGlob],
|
|
935
|
+
language: "jsonc/x",
|
|
936
|
+
name: "favorodera/pnpm/package-json",
|
|
937
|
+
rules: {
|
|
938
|
+
"pnpm/json-enforce-catalog": ["error", {
|
|
939
|
+
autofix: true,
|
|
940
|
+
ignores: ["@types/vscode"]
|
|
941
|
+
}],
|
|
942
|
+
"pnpm/json-prefer-workspace-settings": ["error", { autofix: true }],
|
|
943
|
+
"pnpm/json-valid-catalog": ["error", { autofix: true }]
|
|
944
|
+
}
|
|
945
|
+
},
|
|
946
|
+
{
|
|
947
|
+
files: [pnpmWorkspaceGlob],
|
|
948
|
+
languageOptions: { parser: yamlParser },
|
|
949
|
+
name: "favorodera/pnpm/pnpm-workspace-yaml",
|
|
950
|
+
rules: {
|
|
951
|
+
"pnpm/yaml-enforce-settings": ["error", { settings: {
|
|
952
|
+
shellEmulator: true,
|
|
953
|
+
trustPolicy: "no-downgrade"
|
|
954
|
+
} }],
|
|
955
|
+
"pnpm/yaml-no-duplicate-catalog-item": ["error", { checkDuplicates: "exact-version" }],
|
|
956
|
+
"pnpm/yaml-no-unused-catalog-item": "error"
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
];
|
|
960
|
+
}
|
|
961
|
+
//#endregion
|
|
962
|
+
//#region src/configs/stylistic.ts
|
|
963
|
+
const stylisticDefaults = {
|
|
964
|
+
files: [
|
|
965
|
+
jsGlob,
|
|
966
|
+
tsGlob,
|
|
967
|
+
vueGlob
|
|
968
|
+
],
|
|
969
|
+
settings: {
|
|
970
|
+
experimental: false,
|
|
971
|
+
indent: 2,
|
|
972
|
+
jsx: false,
|
|
973
|
+
quotes: "single",
|
|
974
|
+
semi: false
|
|
975
|
+
}
|
|
976
|
+
};
|
|
977
|
+
/**
|
|
978
|
+
* Constructs the flat config items for Stylistic linting, applying customized
|
|
979
|
+
* formatting settings such as quotes, indentation, and spacing.
|
|
980
|
+
* @param options Stylistic configuration options.
|
|
981
|
+
* @returns Promise resolving to stylistic ESLint config items.
|
|
982
|
+
*/
|
|
983
|
+
async function stylistic(options) {
|
|
984
|
+
const resolved = (0, defu.defu)(options, stylisticDefaults);
|
|
985
|
+
const stylePlugin = await importModule(import("@stylistic/eslint-plugin"));
|
|
986
|
+
const baseRules = stylePlugin.configs.customize({
|
|
987
|
+
pluginName: "style",
|
|
988
|
+
...resolved.settings
|
|
989
|
+
})?.rules || {};
|
|
990
|
+
return [{
|
|
991
|
+
name: "favorodera/stylistic/setup",
|
|
992
|
+
plugins: { style: stylePlugin }
|
|
993
|
+
}, {
|
|
994
|
+
files: resolved.files,
|
|
995
|
+
name: "favorodera/stylistic/rules",
|
|
996
|
+
rules: {
|
|
997
|
+
...baseRules,
|
|
998
|
+
"style/brace-style": "off",
|
|
999
|
+
"style/generator-star-spacing": ["error", {
|
|
1000
|
+
after: true,
|
|
1001
|
+
before: false
|
|
1002
|
+
}],
|
|
1003
|
+
"style/no-multiple-empty-lines": ["error", {
|
|
1004
|
+
max: 2,
|
|
1005
|
+
maxBOF: 0,
|
|
1006
|
+
maxEOF: 2
|
|
1007
|
+
}],
|
|
1008
|
+
"style/no-trailing-spaces": ["error", { skipBlankLines: true }],
|
|
1009
|
+
"style/padded-blocks": "off",
|
|
1010
|
+
"style/quotes": [
|
|
1011
|
+
"error",
|
|
1012
|
+
"single",
|
|
1013
|
+
{ avoidEscape: true }
|
|
1014
|
+
],
|
|
1015
|
+
"style/yield-star-spacing": ["error", {
|
|
1016
|
+
after: true,
|
|
1017
|
+
before: false
|
|
1018
|
+
}],
|
|
854
1019
|
...resolved.overrides
|
|
855
1020
|
}
|
|
856
1021
|
}];
|
|
857
1022
|
}
|
|
858
1023
|
//#endregion
|
|
1024
|
+
//#region src/configs/tailwind.ts
|
|
1025
|
+
const tailwindDefaults = {
|
|
1026
|
+
files: [
|
|
1027
|
+
jsGlob,
|
|
1028
|
+
tsGlob,
|
|
1029
|
+
vueGlob
|
|
1030
|
+
],
|
|
1031
|
+
settings: { detectComponentClasses: true }
|
|
1032
|
+
};
|
|
1033
|
+
/**
|
|
1034
|
+
* Constructs the flat config items for Tailwind CSS linting, providing custom settings
|
|
1035
|
+
* to parse and lint utility classes, and enforcing consistent ordering.
|
|
1036
|
+
* @param options Tailwind configuration options.
|
|
1037
|
+
* @returns Promise resolving to Tailwind ESLint config items.
|
|
1038
|
+
*/
|
|
1039
|
+
async function tailwind(options) {
|
|
1040
|
+
const resolved = (0, defu.defu)(options, tailwindDefaults);
|
|
1041
|
+
const tailwindPlugin = await importModule(import("eslint-plugin-better-tailwindcss"));
|
|
1042
|
+
const baseRules = {
|
|
1043
|
+
...tailwindPlugin.configs["recommended-error"].rules,
|
|
1044
|
+
...tailwindPlugin.configs["stylistic-error"].rules
|
|
1045
|
+
};
|
|
1046
|
+
return [{
|
|
1047
|
+
name: "favorodera/tailwind/setup",
|
|
1048
|
+
plugins: { tailwind: tailwindPlugin },
|
|
1049
|
+
settings: { tailwindcss: resolved.settings }
|
|
1050
|
+
}, {
|
|
1051
|
+
files: resolved.files,
|
|
1052
|
+
name: "favorodera/tailwind/rules",
|
|
1053
|
+
rules: {
|
|
1054
|
+
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { "better-tailwindcss": "tailwind" }),
|
|
1055
|
+
"tailwind/enforce-consistent-line-wrapping": ["error", { group: "emptyLine" }],
|
|
1056
|
+
...resolved.overrides
|
|
1057
|
+
}
|
|
1058
|
+
}];
|
|
1059
|
+
}
|
|
1060
|
+
//#endregion
|
|
1061
|
+
//#region src/configs/test.ts
|
|
1062
|
+
const testDefaults = { files: testsGlob };
|
|
1063
|
+
/**
|
|
1064
|
+
* Constructs the flat config items for test linting, extending
|
|
1065
|
+
* the recommended Vitest rule sets.
|
|
1066
|
+
* @param options Test configuration options.
|
|
1067
|
+
* @returns Promise resolving to test ESLint config items.
|
|
1068
|
+
*/
|
|
1069
|
+
async function test(options) {
|
|
1070
|
+
const resolved = (0, defu.defu)(options, testDefaults);
|
|
1071
|
+
const testPlugin = await importModule(import("@vitest/eslint-plugin"));
|
|
1072
|
+
const baseRules = extractRules(testPlugin.configs.recommended);
|
|
1073
|
+
return [
|
|
1074
|
+
{
|
|
1075
|
+
name: "favorodera/test/setup",
|
|
1076
|
+
plugins: { test: testPlugin }
|
|
1077
|
+
},
|
|
1078
|
+
{
|
|
1079
|
+
files: resolved.files,
|
|
1080
|
+
name: "favorodera/test/rules",
|
|
1081
|
+
rules: {
|
|
1082
|
+
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { vitest: "test" }),
|
|
1083
|
+
"test/consistent-test-it": ["error", {
|
|
1084
|
+
fn: "it",
|
|
1085
|
+
withinDescribe: "it"
|
|
1086
|
+
}],
|
|
1087
|
+
"test/no-identical-title": "error",
|
|
1088
|
+
"test/no-import-node-test": "error",
|
|
1089
|
+
"test/prefer-hooks-in-order": "error",
|
|
1090
|
+
"test/prefer-lowercase-title": "error",
|
|
1091
|
+
...resolved.overrides
|
|
1092
|
+
}
|
|
1093
|
+
},
|
|
1094
|
+
{
|
|
1095
|
+
files: resolved.files,
|
|
1096
|
+
name: "favorodera/test/disables",
|
|
1097
|
+
rules: {
|
|
1098
|
+
"no-unused-expressions": "off",
|
|
1099
|
+
"node/prefer-global/process": "off"
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
];
|
|
1103
|
+
}
|
|
1104
|
+
//#endregion
|
|
1105
|
+
//#region src/configs/typescript.ts
|
|
1106
|
+
const typescriptDefaults = { files: [tsGlob] };
|
|
1107
|
+
/**
|
|
1108
|
+
* Constructs the flat config items for TypeScript linting, initializing the parser
|
|
1109
|
+
* and extending the recommended and strict type-aware rule sets.
|
|
1110
|
+
* @param options TypeScript configuration options.
|
|
1111
|
+
* @returns Promise resolving to TypeScript ESLint config items.
|
|
1112
|
+
*/
|
|
1113
|
+
async function typescript(options) {
|
|
1114
|
+
const resolved = (0, defu.defu)(options, typescriptDefaults);
|
|
1115
|
+
const tsEsLint = await importModule(import("typescript-eslint"));
|
|
1116
|
+
const baseRules = extractRules(tsEsLint.configs.recommended, tsEsLint.configs.strict);
|
|
1117
|
+
return [{
|
|
1118
|
+
name: "favorodera/typescript/setup",
|
|
1119
|
+
plugins: { ts: tsEsLint.plugin }
|
|
1120
|
+
}, {
|
|
1121
|
+
files: resolved.files,
|
|
1122
|
+
languageOptions: {
|
|
1123
|
+
parser: tsEsLint.parser,
|
|
1124
|
+
parserOptions: { sourceType: "module" }
|
|
1125
|
+
},
|
|
1126
|
+
name: "favorodera/typescript/rules",
|
|
1127
|
+
rules: {
|
|
1128
|
+
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { "@typescript-eslint": "ts" }),
|
|
1129
|
+
"ts/array-type": ["error", {
|
|
1130
|
+
default: "generic",
|
|
1131
|
+
readonly: "generic"
|
|
1132
|
+
}],
|
|
1133
|
+
"ts/consistent-type-imports": ["error", { prefer: "type-imports" }],
|
|
1134
|
+
"ts/no-empty-object-type": ["error", { allowInterfaces: "with-single-extends" }],
|
|
1135
|
+
...resolved.overrides
|
|
1136
|
+
}
|
|
1137
|
+
}];
|
|
1138
|
+
}
|
|
1139
|
+
//#endregion
|
|
1140
|
+
//#region src/configs/unicorn.ts
|
|
1141
|
+
const unicornDefaults = { files: [
|
|
1142
|
+
jsGlob,
|
|
1143
|
+
tsGlob,
|
|
1144
|
+
vueGlob
|
|
1145
|
+
] };
|
|
1146
|
+
/**
|
|
1147
|
+
* Constructs the flat config items for Unicorn linting, providing a collection of
|
|
1148
|
+
* awesome ESLint rules to improve code quality and enforce best practices.
|
|
1149
|
+
* @param options Unicorn configuration options.
|
|
1150
|
+
* @returns Promise resolving to Unicorn ESLint config items.
|
|
1151
|
+
*/
|
|
1152
|
+
async function unicorn(options) {
|
|
1153
|
+
const resolved = (0, defu.defu)(options, unicornDefaults);
|
|
1154
|
+
const unicornPlugin = await importModule(import("eslint-plugin-unicorn"));
|
|
1155
|
+
const baseRules = unicornPlugin.configs.unopinionated?.rules || {};
|
|
1156
|
+
return [{
|
|
1157
|
+
name: "favorodera/unicorn/setup",
|
|
1158
|
+
plugins: { unicorn: unicornPlugin }
|
|
1159
|
+
}, {
|
|
1160
|
+
files: resolved.files,
|
|
1161
|
+
languageOptions: { globals: globals.default.builtin },
|
|
1162
|
+
name: "favorodera/unicorn/rules",
|
|
1163
|
+
rules: {
|
|
1164
|
+
...baseRules,
|
|
1165
|
+
"unicorn/consistent-empty-array-spread": "error",
|
|
1166
|
+
"unicorn/error-message": "error",
|
|
1167
|
+
"unicorn/escape-case": "error",
|
|
1168
|
+
"unicorn/new-for-builtins": "error",
|
|
1169
|
+
"unicorn/no-instanceof-builtins": "error",
|
|
1170
|
+
"unicorn/no-new-array": "error",
|
|
1171
|
+
"unicorn/no-new-buffer": "error",
|
|
1172
|
+
"unicorn/number-literal-case": "error",
|
|
1173
|
+
"unicorn/prefer-dom-node-text-content": "error",
|
|
1174
|
+
"unicorn/prefer-includes": "error",
|
|
1175
|
+
"unicorn/prefer-node-protocol": "error",
|
|
1176
|
+
"unicorn/prefer-number-properties": "error",
|
|
1177
|
+
"unicorn/prefer-string-starts-ends-with": "error",
|
|
1178
|
+
"unicorn/prefer-type-error": "error",
|
|
1179
|
+
"unicorn/throw-new-error": "error",
|
|
1180
|
+
...resolved.overrides
|
|
1181
|
+
}
|
|
1182
|
+
}];
|
|
1183
|
+
}
|
|
1184
|
+
//#endregion
|
|
1185
|
+
//#region src/configs/vue.ts
|
|
1186
|
+
const sfcBlocksDefaults = { blocks: {
|
|
1187
|
+
customBlocks: true,
|
|
1188
|
+
styles: true,
|
|
1189
|
+
template: false
|
|
1190
|
+
} };
|
|
1191
|
+
const vueDefaults = {
|
|
1192
|
+
files: [vueGlob],
|
|
1193
|
+
sfcBlocks: sfcBlocksDefaults
|
|
1194
|
+
};
|
|
1195
|
+
/**
|
|
1196
|
+
* Constructs the flat config items for Vue linting, setting up the custom template parser,
|
|
1197
|
+
* Vue block processors, and rules to enforce recommended component syntax.
|
|
1198
|
+
* @param options Vue configuration options.
|
|
1199
|
+
* @returns Promise resolving to Vue ESLint config items.
|
|
1200
|
+
*/
|
|
1201
|
+
async function vue(options) {
|
|
1202
|
+
const resolved = (0, defu.defu)(options, vueDefaults);
|
|
1203
|
+
const sfcBlocks = resolveOptions(resolved.sfcBlocks, sfcBlocksDefaults);
|
|
1204
|
+
const [vuePlugin, vueParser, tsEsLint] = await Promise.all([
|
|
1205
|
+
importModule(import("eslint-plugin-vue")),
|
|
1206
|
+
importModule(import("vue-eslint-parser")),
|
|
1207
|
+
importModule(import("typescript-eslint"))
|
|
1208
|
+
]);
|
|
1209
|
+
const baseRules = extractRules(vuePlugin.configs["flat/essential"], vuePlugin.configs["flat/strongly-recommended"], vuePlugin.configs["flat/recommended"]);
|
|
1210
|
+
const processor = sfcBlocks === false ? vuePlugin.processors[".vue"] : (0, eslint_merge_processors.mergeProcessors)([vuePlugin.processors[".vue"], (0, eslint_processor_vue_blocks.default)(sfcBlocks)]);
|
|
1211
|
+
return [{
|
|
1212
|
+
languageOptions: { globals: {
|
|
1213
|
+
computed: "readonly",
|
|
1214
|
+
defineEmits: "readonly",
|
|
1215
|
+
defineExpose: "readonly",
|
|
1216
|
+
defineProps: "readonly",
|
|
1217
|
+
onMounted: "readonly",
|
|
1218
|
+
onUnmounted: "readonly",
|
|
1219
|
+
reactive: "readonly",
|
|
1220
|
+
ref: "readonly",
|
|
1221
|
+
shallowReactive: "readonly",
|
|
1222
|
+
shallowRef: "readonly",
|
|
1223
|
+
toRef: "readonly",
|
|
1224
|
+
toRefs: "readonly",
|
|
1225
|
+
watch: "readonly",
|
|
1226
|
+
watchEffect: "readonly"
|
|
1227
|
+
} },
|
|
1228
|
+
name: "favorodera/vue/setup",
|
|
1229
|
+
plugins: { vue: vuePlugin }
|
|
1230
|
+
}, {
|
|
1231
|
+
files: resolved.files,
|
|
1232
|
+
languageOptions: {
|
|
1233
|
+
parser: vueParser,
|
|
1234
|
+
parserOptions: {
|
|
1235
|
+
extraFileExtensions: [".vue"],
|
|
1236
|
+
parser: tsEsLint.parser,
|
|
1237
|
+
sourceType: "module"
|
|
1238
|
+
}
|
|
1239
|
+
},
|
|
1240
|
+
name: "favorodera/vue/rules",
|
|
1241
|
+
processor,
|
|
1242
|
+
rules: {
|
|
1243
|
+
...baseRules,
|
|
1244
|
+
"vue/block-order": ["error", { order: [
|
|
1245
|
+
"script",
|
|
1246
|
+
"template",
|
|
1247
|
+
"style"
|
|
1248
|
+
] }],
|
|
1249
|
+
"vue/block-tag-newline": ["error", {
|
|
1250
|
+
multiline: "ignore",
|
|
1251
|
+
singleline: "ignore"
|
|
1252
|
+
}],
|
|
1253
|
+
"vue/component-name-in-template-casing": ["error", "PascalCase"],
|
|
1254
|
+
"vue/component-options-name-casing": ["error", "PascalCase"],
|
|
1255
|
+
"vue/multi-word-component-names": "off",
|
|
1256
|
+
"vue/multiline-html-element-content-newline": ["error", {
|
|
1257
|
+
allowEmptyLines: true,
|
|
1258
|
+
ignores: ["pre", "textarea"]
|
|
1259
|
+
}],
|
|
1260
|
+
...resolved.overrides
|
|
1261
|
+
}
|
|
1262
|
+
}];
|
|
1263
|
+
}
|
|
1264
|
+
//#endregion
|
|
1265
|
+
//#region src/configs/yaml.ts
|
|
1266
|
+
const yamlDefaults = { files: [yamlGlob] };
|
|
1267
|
+
/**
|
|
1268
|
+
* Constructs the flat config items for YAML linting, setting up
|
|
1269
|
+
* the custom parser and rule validations.
|
|
1270
|
+
* @param options YAML configuration options.
|
|
1271
|
+
* @returns Promise resolving to YAML ESLint config items.
|
|
1272
|
+
*/
|
|
1273
|
+
async function yaml(options) {
|
|
1274
|
+
const resolved = (0, defu.defu)(options, yamlDefaults);
|
|
1275
|
+
const [yamlPlugin, yamlParser] = await Promise.all([importModule(import("eslint-plugin-yml")), importModule(import("yaml-eslint-parser"))]);
|
|
1276
|
+
const baseRules = extractRules(yamlPlugin.configs.recommended);
|
|
1277
|
+
return [
|
|
1278
|
+
{
|
|
1279
|
+
name: "favorodera/yaml/setup",
|
|
1280
|
+
plugins: { yaml: yamlPlugin }
|
|
1281
|
+
},
|
|
1282
|
+
{
|
|
1283
|
+
files: resolved.files,
|
|
1284
|
+
languageOptions: { parser: yamlParser },
|
|
1285
|
+
name: "favorodera/yaml/rules",
|
|
1286
|
+
rules: {
|
|
1287
|
+
...(0, eslint_flat_config_utils.renamePluginsInRules)(baseRules, { yml: "yaml" }),
|
|
1288
|
+
"style/spaced-comment": "off",
|
|
1289
|
+
"yaml/block-mapping": "error",
|
|
1290
|
+
"yaml/block-mapping-question-indicator-newline": "error",
|
|
1291
|
+
"yaml/block-sequence": "error",
|
|
1292
|
+
"yaml/block-sequence-hyphen-indicator-newline": "error",
|
|
1293
|
+
"yaml/flow-mapping-curly-newline": "error",
|
|
1294
|
+
"yaml/flow-mapping-curly-spacing": "error",
|
|
1295
|
+
"yaml/flow-sequence-bracket-newline": "error",
|
|
1296
|
+
"yaml/flow-sequence-bracket-spacing": "error",
|
|
1297
|
+
"yaml/indent": ["error", 2],
|
|
1298
|
+
"yaml/key-spacing": "error",
|
|
1299
|
+
"yaml/no-empty-key": "error",
|
|
1300
|
+
"yaml/no-empty-sequence-entry": "error",
|
|
1301
|
+
"yaml/no-irregular-whitespace": "error",
|
|
1302
|
+
"yaml/no-tab-indent": "error",
|
|
1303
|
+
"yaml/plain-scalar": "error",
|
|
1304
|
+
"yaml/quotes": ["error", {
|
|
1305
|
+
avoidEscape: true,
|
|
1306
|
+
prefer: "single"
|
|
1307
|
+
}],
|
|
1308
|
+
"yaml/spaced-comment": "error",
|
|
1309
|
+
"yaml/vue-custom-block/no-parsing-error": "error",
|
|
1310
|
+
...resolved.overrides
|
|
1311
|
+
}
|
|
1312
|
+
},
|
|
1313
|
+
{
|
|
1314
|
+
files: [pnpmWorkspaceGlob],
|
|
1315
|
+
languageOptions: { parser: yamlParser },
|
|
1316
|
+
name: "favorodera/yaml/sort/pnpm-workspace-yaml",
|
|
1317
|
+
rules: { "yaml/sort-keys": [
|
|
1318
|
+
"error",
|
|
1319
|
+
{
|
|
1320
|
+
order: [
|
|
1321
|
+
"cacheDir",
|
|
1322
|
+
"catalogMode",
|
|
1323
|
+
"cleanupUnusedCatalogs",
|
|
1324
|
+
"dedupeDirectDeps",
|
|
1325
|
+
"deployAllFiles",
|
|
1326
|
+
"enablePrePostScripts",
|
|
1327
|
+
"engineStrict",
|
|
1328
|
+
"extendNodePath",
|
|
1329
|
+
"hoist",
|
|
1330
|
+
"hoistPattern",
|
|
1331
|
+
"hoistWorkspacePackages",
|
|
1332
|
+
"ignoreCompatibilityDb",
|
|
1333
|
+
"ignoreDepScripts",
|
|
1334
|
+
"ignoreScripts",
|
|
1335
|
+
"ignoreWorkspaceRootCheck",
|
|
1336
|
+
"managePackageManagerVersions",
|
|
1337
|
+
"minimumReleaseAge",
|
|
1338
|
+
"minimumReleaseAgeExclude",
|
|
1339
|
+
"modulesDir",
|
|
1340
|
+
"nodeLinker",
|
|
1341
|
+
"nodeVersion",
|
|
1342
|
+
"optimisticRepeatInstall",
|
|
1343
|
+
"packageManagerStrict",
|
|
1344
|
+
"packageManagerStrictVersion",
|
|
1345
|
+
"preferSymlinkedExecutables",
|
|
1346
|
+
"preferWorkspacePackages",
|
|
1347
|
+
"publicHoistPattern",
|
|
1348
|
+
"registrySupportsTimeField",
|
|
1349
|
+
"requiredScripts",
|
|
1350
|
+
"resolutionMode",
|
|
1351
|
+
"savePrefix",
|
|
1352
|
+
"scriptShell",
|
|
1353
|
+
"shamefullyHoist",
|
|
1354
|
+
"shellEmulator",
|
|
1355
|
+
"stateDir",
|
|
1356
|
+
"supportedArchitectures",
|
|
1357
|
+
"symlink",
|
|
1358
|
+
"tag",
|
|
1359
|
+
"trustPolicy",
|
|
1360
|
+
"trustPolicyExclude",
|
|
1361
|
+
"updateNotifier",
|
|
1362
|
+
"packages",
|
|
1363
|
+
"overrides",
|
|
1364
|
+
"patchedDependencies",
|
|
1365
|
+
"catalog",
|
|
1366
|
+
"catalogs",
|
|
1367
|
+
"allowedDeprecatedVersions",
|
|
1368
|
+
"allowNonAppliedPatches",
|
|
1369
|
+
"configDependencies",
|
|
1370
|
+
"ignoredBuiltDependencies",
|
|
1371
|
+
"ignoredOptionalDependencies",
|
|
1372
|
+
"neverBuiltDependencies",
|
|
1373
|
+
"onlyBuiltDependencies",
|
|
1374
|
+
"onlyBuiltDependenciesFile",
|
|
1375
|
+
"packageExtensions",
|
|
1376
|
+
"peerDependencyRules"
|
|
1377
|
+
],
|
|
1378
|
+
pathPattern: "^$"
|
|
1379
|
+
},
|
|
1380
|
+
{
|
|
1381
|
+
order: { type: "asc" },
|
|
1382
|
+
pathPattern: ".*"
|
|
1383
|
+
}
|
|
1384
|
+
] }
|
|
1385
|
+
}
|
|
1386
|
+
];
|
|
1387
|
+
}
|
|
1388
|
+
//#endregion
|
|
859
1389
|
//#region src/factory.ts
|
|
860
1390
|
/**
|
|
861
1391
|
* Factory to create a flat ESLint config.
|
|
@@ -864,18 +1394,23 @@ async function jsdoc(options) {
|
|
|
864
1394
|
* @returns A flat config composer instance that can be exported directly or further modified.
|
|
865
1395
|
*/
|
|
866
1396
|
function factory(options = {}) {
|
|
867
|
-
const configs = [];
|
|
868
|
-
configs.push(ignores(options.ignores));
|
|
1397
|
+
const configs = [ignores(options.ignores)];
|
|
869
1398
|
const configFunctions = {
|
|
870
|
-
vue,
|
|
871
|
-
typescript,
|
|
872
|
-
stylistic,
|
|
873
|
-
tailwind,
|
|
874
1399
|
imports,
|
|
875
|
-
markdown,
|
|
876
1400
|
javascript,
|
|
1401
|
+
jsdoc,
|
|
877
1402
|
jsonc,
|
|
878
|
-
|
|
1403
|
+
markdown,
|
|
1404
|
+
node,
|
|
1405
|
+
perfectionist,
|
|
1406
|
+
pnpm,
|
|
1407
|
+
stylistic,
|
|
1408
|
+
tailwind,
|
|
1409
|
+
test,
|
|
1410
|
+
typescript,
|
|
1411
|
+
unicorn,
|
|
1412
|
+
vue,
|
|
1413
|
+
yaml
|
|
879
1414
|
};
|
|
880
1415
|
for (const [key, configFunction] of Object.entries(configFunctions)) {
|
|
881
1416
|
const configOption = options[key];
|
|
@@ -884,13 +1419,17 @@ function factory(options = {}) {
|
|
|
884
1419
|
}
|
|
885
1420
|
let composer = new eslint_flat_config_utils.FlatConfigComposer();
|
|
886
1421
|
composer = composer.append(...configs).renamePlugins({
|
|
887
|
-
"better-tailwindcss": "tailwind",
|
|
888
1422
|
"@typescript-eslint": "ts",
|
|
1423
|
+
"better-tailwindcss": "tailwind",
|
|
1424
|
+
"import-lite": "import",
|
|
889
1425
|
"markdown": "md",
|
|
890
|
-
"
|
|
1426
|
+
"n": "node",
|
|
1427
|
+
"vitest": "test",
|
|
1428
|
+
"yml": "yaml"
|
|
891
1429
|
});
|
|
892
1430
|
return composer;
|
|
893
1431
|
}
|
|
894
1432
|
//#endregion
|
|
1433
|
+
exports.extractRules = extractRules;
|
|
895
1434
|
exports.factory = factory;
|
|
896
1435
|
exports.importModule = importModule;
|