@luxass/eslint-config 4.11.0 → 4.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (6) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs +1882 -1789
  3. package/dist/index.d.cts +14001 -13262
  4. package/dist/index.d.ts +14001 -13262
  5. package/dist/index.js +1873 -1789
  6. package/package.json +36 -29
package/dist/index.js CHANGED
@@ -1,86 +1,6 @@
1
1
  // src/factory.ts
2
- import process3 from "node:process";
3
- import { existsSync } from "node:fs";
4
- import { isPackageExists as isPackageExists4 } from "local-pkg";
5
2
  import { FlatConfigComposer } from "eslint-flat-config-utils";
6
-
7
- // src/configs/comments.ts
8
- import eslintCommentsPlugin from "@eslint-community/eslint-plugin-eslint-comments";
9
- async function comments() {
10
- return [
11
- {
12
- name: "luxass/eslint-comments",
13
- plugins: {
14
- "eslint-comments": eslintCommentsPlugin
15
- },
16
- rules: {
17
- // https://github.com/eslint-community/eslint-plugin-eslint-comments/blob/main/docs/rules/no-aggregating-enable.md
18
- "eslint-comments/no-aggregating-enable": "error",
19
- // https://github.com/eslint-community/eslint-plugin-eslint-comments/blob/main/docs/rules/no-duplicate-disable.md
20
- "eslint-comments/no-duplicate-disable": "error",
21
- // https://github.com/eslint-community/eslint-plugin-eslint-comments/blob/main/docs/rules/no-unlimited-disable.md
22
- "eslint-comments/no-unlimited-disable": "error",
23
- // Deprecated in favor of official reportUnusedDisableDirectives
24
- // https://github.com/eslint-community/eslint-plugin-eslint-comments/issues/133
25
- "eslint-comments/no-unused-enable": "off"
26
- }
27
- }
28
- ];
29
- }
30
-
31
- // src/configs/unicorn.ts
32
- import pluginUnicorn from "eslint-plugin-unicorn";
33
- function unicorn() {
34
- return [
35
- {
36
- name: "luxass/unicorn",
37
- plugins: {
38
- unicorn: pluginUnicorn
39
- },
40
- rules: {
41
- // Pass error message when throwing errors
42
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/error-message.md
43
- "unicorn/error-message": "error",
44
- // Uppercase regex escapes
45
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/escape-case.md
46
- "unicorn/escape-case": "error",
47
- // Array.isArray instead of instanceof
48
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-instanceof-array.md
49
- "unicorn/no-instanceof-array": "error",
50
- // Ban `new Array` as `Array` constructor's params are ambiguous
51
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-new-array.md
52
- "unicorn/no-new-array": "error",
53
- // Prevent deprecated `new Buffer()`
54
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-new-buffer.md
55
- "unicorn/no-new-buffer": "error",
56
- // Lowercase number formatting for octal, hex, binary (0x1'error' instead of 0X1'error')
57
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/number-literal-case.md
58
- "unicorn/number-literal-case": "error",
59
- // textContent instead of innerText
60
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-text-content.md
61
- "unicorn/prefer-dom-node-text-content": "error",
62
- // includes over indexOf when checking for existence
63
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-includes.md
64
- "unicorn/prefer-includes": "error",
65
- // Prefer using the node: protocol
66
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-node-protocol.md
67
- "unicorn/prefer-node-protocol": "error",
68
- // Prefer using number properties like `Number.isNaN` rather than `isNaN`
69
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-number-properties.md
70
- "unicorn/prefer-number-properties": "error",
71
- // String methods startsWith/endsWith instead of more complicated stuff
72
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-starts-ends-with.md
73
- "unicorn/prefer-string-starts-ends-with": "error",
74
- // Enforce throwing type error when throwing error while checking typeof
75
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-type-error.md
76
- "unicorn/prefer-type-error": "error",
77
- // Use new when throwing error
78
- // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/throw-new-error.md
79
- "unicorn/throw-new-error": "error"
80
- }
81
- }
82
- ];
83
- }
3
+ import { isPackageExists as isPackageExists3 } from "local-pkg";
84
4
 
85
5
  // src/globs.ts
86
6
  var GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
@@ -166,1956 +86,2138 @@ var GLOB_EXCLUDE = [
166
86
  "**/components.d.ts"
167
87
  ];
168
88
 
169
- // src/configs/ignores.ts
170
- function ignores() {
89
+ // src/utils.ts
90
+ import process from "node:process";
91
+ import { fileURLToPath } from "node:url";
92
+ import { isPackageExists } from "local-pkg";
93
+ var scopeUrl = fileURLToPath(new URL(".", import.meta.url));
94
+ var isCwdInScope = isPackageExists("@luxass/eslint-config");
95
+ var parserPlain = {
96
+ meta: {
97
+ name: "parser-plain"
98
+ },
99
+ parseForESLint: (code) => ({
100
+ ast: {
101
+ body: [],
102
+ comments: [],
103
+ loc: { end: code.length, start: 0 },
104
+ range: [0, code.length],
105
+ tokens: [],
106
+ type: "Program"
107
+ },
108
+ scopeManager: null,
109
+ services: { isPlain: true },
110
+ visitorKeys: {
111
+ Program: []
112
+ }
113
+ })
114
+ };
115
+ async function combine(...configs2) {
116
+ const resolved = await Promise.all(configs2);
117
+ return resolved.flat();
118
+ }
119
+ function renameRules(rules, map) {
120
+ return Object.fromEntries(
121
+ Object.entries(rules).map(([key, value]) => {
122
+ for (const [from, to] of Object.entries(map)) {
123
+ if (key.startsWith(`${from}/`)) {
124
+ return [to + key.slice(from.length), value];
125
+ }
126
+ }
127
+ return [key, value];
128
+ })
129
+ );
130
+ }
131
+ function renamePluginInConfigs(configs2, map) {
132
+ return configs2.map((i) => {
133
+ const clone = { ...i };
134
+ if (clone.rules) {
135
+ clone.rules = renameRules(clone.rules, map);
136
+ }
137
+ if (clone.plugins) {
138
+ clone.plugins = Object.fromEntries(
139
+ Object.entries(clone.plugins).map(([key, value]) => {
140
+ if (key in map) {
141
+ return [map[key], value];
142
+ }
143
+ return [key, value];
144
+ })
145
+ );
146
+ }
147
+ return clone;
148
+ });
149
+ }
150
+ function toArray(value) {
151
+ return Array.isArray(value) ? value : [value];
152
+ }
153
+ async function interop(m) {
154
+ const resolved = await m;
155
+ return resolved.default || resolved;
156
+ }
157
+ async function ensure(packages) {
158
+ if (process.env.CI || process.stdout.isTTY === false || isCwdInScope === false) {
159
+ return;
160
+ }
161
+ ;
162
+ const nonExistingPackages = packages.filter((i) => i && !isPackageInScope(i));
163
+ if (nonExistingPackages.length === 0) {
164
+ return;
165
+ }
166
+ const p = await import("@clack/prompts");
167
+ const result = await p.confirm({
168
+ message: `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?`
169
+ });
170
+ if (result) {
171
+ await import("@antfu/install-pkg").then((i) => i.installPackage(nonExistingPackages, { dev: true }));
172
+ }
173
+ }
174
+ function resolveSubOptions(options, key) {
175
+ return typeof options[key] === "boolean" ? {} : options[key] || {};
176
+ }
177
+ function getOverrides(options, key) {
178
+ const sub = resolveSubOptions(options, key);
179
+ return {
180
+ ..."overrides" in sub ? sub.overrides : {}
181
+ };
182
+ }
183
+ function isPackageInScope(name) {
184
+ return isPackageExists(name, { paths: [scopeUrl] });
185
+ }
186
+ function isInEditorEnv() {
187
+ if (process.env.CI) {
188
+ return false;
189
+ }
190
+ if (isInGitHooksOrLintStaged()) {
191
+ return false;
192
+ }
193
+ return !!(process.env.VSCODE_PID || process.env.VSCODE_CWD || process.env.JETBRAINS_IDE || process.env.VIM || process.env.NVIM);
194
+ }
195
+ function isInGitHooksOrLintStaged() {
196
+ return !!(process.env.GIT_PARAMS || process.env.VSCODE_GIT_COMMAND || process.env.npm_lifecycle_script?.startsWith("lint-staged"));
197
+ }
198
+
199
+ // src/configs/astro.ts
200
+ async function astro(options = {}) {
201
+ const {
202
+ files = [GLOB_ASTRO],
203
+ overrides = {},
204
+ stylistic: stylistic2 = true
205
+ } = options;
206
+ await ensure([
207
+ "eslint-plugin-astro",
208
+ "astro-eslint-parser"
209
+ ]);
210
+ const [
211
+ pluginAstro,
212
+ parserAstro,
213
+ parserTs
214
+ ] = await Promise.all([
215
+ interop(import("eslint-plugin-astro")),
216
+ interop(import("astro-eslint-parser")),
217
+ interop(import("@typescript-eslint/parser"))
218
+ ]);
171
219
  return [
172
220
  {
173
- ignores: GLOB_EXCLUDE
221
+ name: "luxass/astro/setup",
222
+ plugins: {
223
+ astro: pluginAstro
224
+ }
225
+ },
226
+ {
227
+ name: "luxass/astro/rules",
228
+ files,
229
+ languageOptions: {
230
+ globals: pluginAstro.environments.astro.globals,
231
+ parser: parserAstro,
232
+ parserOptions: {
233
+ extraFileExtensions: [".astro"],
234
+ parser: parserTs
235
+ },
236
+ sourceType: "module"
237
+ },
238
+ processor: "astro/client-side-ts",
239
+ rules: {
240
+ "astro/missing-client-only-directive-value": "error",
241
+ "astro/no-conflict-set-directives": "error",
242
+ "astro/no-deprecated-astro-canonicalurl": "error",
243
+ "astro/no-deprecated-astro-fetchcontent": "error",
244
+ "astro/no-deprecated-astro-resolve": "error",
245
+ "astro/no-deprecated-getentrybyslug": "error",
246
+ "astro/no-set-html-directive": "off",
247
+ "astro/no-unused-define-vars-in-style": "error",
248
+ "astro/semi": "error",
249
+ "astro/valid-compile": "error",
250
+ ...stylistic2 ? {
251
+ "style/indent": "off",
252
+ "style/jsx-closing-tag-location": "off",
253
+ "style/jsx-indent": "off",
254
+ "style/jsx-one-expression-per-line": "off",
255
+ "style/no-multiple-empty-lines": "off"
256
+ } : {},
257
+ ...overrides
258
+ }
174
259
  }
175
260
  ];
176
261
  }
177
262
 
178
- // src/configs/node.ts
179
- import pluginNode from "eslint-plugin-n";
180
- function node() {
263
+ // src/configs/comments.ts
264
+ import eslintCommentsPlugin from "@eslint-community/eslint-plugin-eslint-comments";
265
+ async function comments() {
181
266
  return [
182
267
  {
183
- name: "luxass/node",
268
+ name: "luxass/eslint-comments",
184
269
  plugins: {
185
- node: pluginNode
270
+ "eslint-comments": eslintCommentsPlugin
186
271
  },
187
272
  rules: {
188
- "node/handle-callback-err": ["error", "^(err|error)$"],
189
- "node/no-deprecated-api": "error",
190
- "node/no-exports-assign": "error",
191
- "node/no-new-require": "error",
192
- "node/no-path-concat": "error",
193
- "node/prefer-global/buffer": ["error", "never"],
194
- "node/prefer-global/process": ["error", "never"],
195
- "node/process-exit-as-throw": "error"
273
+ // https://github.com/eslint-community/eslint-plugin-eslint-comments/blob/main/docs/rules/no-aggregating-enable.md
274
+ "eslint-comments/no-aggregating-enable": "error",
275
+ // https://github.com/eslint-community/eslint-plugin-eslint-comments/blob/main/docs/rules/no-duplicate-disable.md
276
+ "eslint-comments/no-duplicate-disable": "error",
277
+ // https://github.com/eslint-community/eslint-plugin-eslint-comments/blob/main/docs/rules/no-unlimited-disable.md
278
+ "eslint-comments/no-unlimited-disable": "error",
279
+ // Deprecated in favor of official reportUnusedDisableDirectives
280
+ // https://github.com/eslint-community/eslint-plugin-eslint-comments/issues/133
281
+ "eslint-comments/no-unused-enable": "off"
196
282
  }
197
283
  }
198
284
  ];
199
285
  }
200
286
 
201
- // src/configs/sort.ts
202
- function sortPackageJson() {
287
+ // src/configs/disables.ts
288
+ async function disables() {
203
289
  return [
204
290
  {
205
- name: "luxass/sort/package-json",
206
- files: ["**/package.json"],
291
+ files: [`scripts/${GLOB_SRC}`],
292
+ name: "luxass/disables/scripts",
207
293
  rules: {
208
- "jsonc/sort-array-values": [
209
- "error",
210
- {
211
- order: { type: "asc" },
212
- pathPattern: "^files$"
213
- }
214
- ],
215
- "jsonc/sort-keys": [
216
- "error",
217
- {
218
- order: [
219
- "name",
220
- "displayName",
221
- "version",
222
- "description",
223
- "type",
224
- "private",
225
- "author",
226
- "contributors",
227
- "publisher",
228
- "packageManager",
229
- "license",
230
- "funding",
231
- "homepage",
232
- "repository",
233
- "bugs",
234
- "keywords",
235
- "categories",
236
- "sideEffects",
237
- "exports",
238
- "main",
239
- "module",
240
- "unpkg",
241
- "jsdelivr",
242
- "types",
243
- "typesVersions",
244
- "bin",
245
- "icon",
246
- "files",
247
- "engines",
248
- "activationEvents",
249
- "contributes",
250
- "scripts",
251
- "peerDependencies",
252
- "peerDependenciesMeta",
253
- "dependencies",
254
- "optionalDependencies",
255
- "devDependencies",
256
- "pnpm",
257
- "overrides",
258
- "resolutions",
259
- "husky",
260
- "simple-git-hooks",
261
- "lint-staged",
262
- "eslintConfig"
263
- ],
264
- pathPattern: "^$"
265
- },
266
- {
267
- order: { type: "asc" },
268
- pathPattern: "^(?:dev|peer|optional|bundled)?[Dd]ependencies$"
269
- },
270
- {
271
- order: { type: "asc" },
272
- pathPattern: "^resolutions$"
273
- },
274
- {
275
- order: { type: "asc" },
276
- pathPattern: "^pnpm.overrides$"
277
- },
278
- {
279
- order: ["types", "import", "require", "default"],
280
- pathPattern: "^exports.*$"
281
- },
282
- {
283
- order: [
284
- // client hooks only
285
- "pre-commit",
286
- "prepare-commit-msg",
287
- "commit-msg",
288
- "post-commit",
289
- "pre-rebase",
290
- "post-rewrite",
291
- "post-checkout",
292
- "post-merge",
293
- "pre-push",
294
- "pre-auto-gc"
295
- ],
296
- pathPattern: "^(?:gitHooks|husky|simple-git-hooks)$"
297
- }
298
- ]
299
- }
300
- }
301
- ];
302
- }
303
- function sortTsconfig() {
304
- return [
305
- {
306
- name: "luxass/sort/tsconfig",
307
- files: ["**/tsconfig.json", "**/tsconfig.*.json"],
308
- rules: {
309
- "jsonc/sort-keys": [
310
- "error",
311
- {
312
- order: [
313
- "extends",
314
- "compilerOptions",
315
- "references",
316
- "files",
317
- "include",
318
- "exclude"
319
- ],
320
- pathPattern: "^$"
321
- },
322
- {
323
- order: [
324
- /* Projects */
325
- "incremental",
326
- "composite",
327
- "tsBuildInfoFile",
328
- "disableSourceOfProjectReferenceRedirect",
329
- "disableSolutionSearching",
330
- "disableReferencedProjectLoad",
331
- /* Language and Environment */
332
- "target",
333
- "jsx",
334
- "jsxFactory",
335
- "jsxFragmentFactory",
336
- "jsxImportSource",
337
- "lib",
338
- "moduleDetection",
339
- "noLib",
340
- "reactNamespace",
341
- "useDefineForClassFields",
342
- "emitDecoratorMetadata",
343
- "experimentalDecorators",
344
- /* Modules */
345
- "baseUrl",
346
- "rootDir",
347
- "rootDirs",
348
- "customConditions",
349
- "module",
350
- "moduleResolution",
351
- "moduleSuffixes",
352
- "noResolve",
353
- "paths",
354
- "resolveJsonModule",
355
- "resolvePackageJsonExports",
356
- "resolvePackageJsonImports",
357
- "typeRoots",
358
- "types",
359
- "allowArbitraryExtensions",
360
- "allowImportingTsExtensions",
361
- "allowUmdGlobalAccess",
362
- /* JavaScript Support */
363
- "allowJs",
364
- "checkJs",
365
- "maxNodeModuleJsDepth",
366
- /* Type Checking */
367
- "strict",
368
- "strictBindCallApply",
369
- "strictFunctionTypes",
370
- "strictNullChecks",
371
- "strictPropertyInitialization",
372
- "allowUnreachableCode",
373
- "allowUnusedLabels",
374
- "alwaysStrict",
375
- "exactOptionalPropertyTypes",
376
- "noFallthroughCasesInSwitch",
377
- "noImplicitAny",
378
- "noImplicitOverride",
379
- "noImplicitReturns",
380
- "noImplicitThis",
381
- "noPropertyAccessFromIndexSignature",
382
- "noUncheckedIndexedAccess",
383
- "noUnusedLocals",
384
- "noUnusedParameters",
385
- "useUnknownInCatchVariables",
386
- /* Emit */
387
- "declaration",
388
- "declarationDir",
389
- "declarationMap",
390
- "downlevelIteration",
391
- "emitBOM",
392
- "emitDeclarationOnly",
393
- "importHelpers",
394
- "importsNotUsedAsValues",
395
- "inlineSourceMap",
396
- "inlineSources",
397
- "mapRoot",
398
- "newLine",
399
- "noEmit",
400
- "noEmitHelpers",
401
- "noEmitOnError",
402
- "outDir",
403
- "outFile",
404
- "preserveConstEnums",
405
- "preserveValueImports",
406
- "removeComments",
407
- "sourceMap",
408
- "sourceRoot",
409
- "stripInternal",
410
- /* Interop Constraints */
411
- "allowSyntheticDefaultImports",
412
- "esModuleInterop",
413
- "forceConsistentCasingInFileNames",
414
- "isolatedDeclarations",
415
- "isolatedModules",
416
- "preserveSymlinks",
417
- "verbatimModuleSyntax",
418
- /* Completeness */
419
- "skipDefaultLibCheck",
420
- "skipLibCheck"
421
- ],
422
- pathPattern: "^compilerOptions$"
423
- }
424
- ]
294
+ "no-console": "off",
295
+ "ts/explicit-function-return-type": "off"
425
296
  }
426
- }
427
- ];
428
- }
429
-
430
- // src/configs/imports.ts
431
- import pluginImport from "eslint-plugin-import-x";
432
- import pluginAntfu from "eslint-plugin-antfu";
433
- async function imports(options = {}) {
434
- const {
435
- stylistic: stylistic2 = true
436
- } = options;
437
- return [
297
+ },
438
298
  {
439
- name: "luxass/imports",
440
- plugins: {
441
- antfu: pluginAntfu,
442
- import: pluginImport
443
- },
299
+ files: [`cli/${GLOB_SRC}`, `cli.${GLOB_SRC_EXT}`],
300
+ name: "luxass/disables/cli",
444
301
  rules: {
445
- "antfu/import-dedupe": "error",
446
- "antfu/no-import-dist": "error",
447
- "antfu/no-import-node-modules-by-path": "error",
448
- "import/first": "error",
449
- "import/no-duplicates": "error",
450
- "import/no-mutable-exports": "error",
451
- "import/no-named-default": "error",
452
- "import/no-self-import": "error",
453
- "import/no-webpack-loader-syntax": "error",
454
- "import/order": "error",
455
- ...stylistic2 ? {
456
- "import/newline-after-import": ["error", { count: 1 }]
457
- } : {}
302
+ "no-console": "off"
458
303
  }
459
304
  },
460
305
  {
461
- name: "luxass/disables/imports-bin",
462
306
  files: ["**/bin/**/*", `**/bin.${GLOB_SRC_EXT}`],
307
+ name: "luxass/disables/bin",
463
308
  rules: {
464
309
  "antfu/no-import-dist": "off",
465
310
  "antfu/no-import-node-modules-by-path": "off"
466
311
  }
467
- }
468
- ];
469
- }
470
-
471
- // src/configs/javascript.ts
472
- import globals from "globals";
473
- import pluginUnusedImports from "eslint-plugin-unused-imports";
474
- import pluginAntfu2 from "eslint-plugin-antfu";
475
- async function javascript(options = {}) {
476
- const {
477
- editor = false,
478
- overrides = {}
479
- } = options;
480
- return [
481
- {
482
- name: "luxass/javascript/setup",
483
- languageOptions: {
484
- ecmaVersion: 2022,
485
- globals: {
486
- ...globals.browser,
487
- ...globals.es2021,
488
- ...globals.node,
489
- document: "readonly",
490
- navigator: "readonly",
491
- window: "readonly"
492
- },
493
- parserOptions: {
494
- ecmaFeatures: {
495
- jsx: true
496
- },
497
- ecmaVersion: 2022,
498
- sourceType: "module"
499
- },
500
- sourceType: "module"
501
- },
502
- linterOptions: {
503
- reportUnusedDisableDirectives: true
504
- }
505
312
  },
506
313
  {
507
- name: "luxass/javascript/rules",
508
- plugins: {
509
- "antfu": pluginAntfu2,
510
- "unused-imports": pluginUnusedImports
511
- },
512
- rules: {
513
- "accessor-pairs": [
514
- "error",
515
- { enforceForClassMembers: true, setWithoutGet: true }
516
- ],
517
- "array-callback-return": "error",
518
- "block-scoped-var": "error",
519
- "constructor-super": "error",
520
- "default-case-last": "error",
521
- "dot-notation": ["error", { allowKeywords: true }],
522
- "eqeqeq": ["error", "smart"],
523
- "new-cap": [
524
- "error",
525
- { capIsNew: false, newIsCap: true, properties: true }
526
- ],
527
- "no-alert": "error",
528
- "no-array-constructor": "error",
529
- "no-async-promise-executor": "error",
530
- "no-caller": "error",
531
- "no-case-declarations": "error",
532
- "no-class-assign": "error",
533
- "no-compare-neg-zero": "error",
534
- "no-cond-assign": ["error", "always"],
535
- "no-console": ["error", { allow: ["warn", "error"] }],
536
- "no-const-assign": "error",
537
- "no-control-regex": "error",
538
- "no-debugger": "error",
539
- "no-delete-var": "error",
540
- "no-dupe-args": "error",
541
- "no-dupe-class-members": "error",
542
- "no-dupe-keys": "error",
543
- "no-duplicate-case": "error",
544
- "no-empty": ["error", { allowEmptyCatch: true }],
545
- "no-empty-character-class": "error",
546
- "no-empty-pattern": "error",
547
- "no-eval": "error",
548
- "no-ex-assign": "error",
549
- "no-extend-native": "error",
550
- "no-extra-bind": "error",
551
- "no-extra-boolean-cast": "error",
552
- "no-fallthrough": "error",
553
- "no-func-assign": "error",
554
- "no-global-assign": "error",
555
- "no-implied-eval": "error",
556
- "no-import-assign": "error",
557
- "no-invalid-regexp": "error",
558
- "no-invalid-this": "error",
559
- "no-irregular-whitespace": "error",
560
- "no-iterator": "error",
561
- "no-labels": ["error", { allowLoop: false, allowSwitch: false }],
562
- "no-lone-blocks": "error",
563
- "no-loss-of-precision": "error",
564
- "no-misleading-character-class": "error",
565
- "no-multi-str": "error",
566
- "no-new": "error",
567
- "no-new-func": "error",
568
- "no-new-native-nonconstructor": "error",
569
- "no-new-wrappers": "error",
570
- "no-obj-calls": "error",
571
- "no-octal": "error",
572
- "no-octal-escape": "error",
573
- "no-proto": "error",
574
- "no-prototype-builtins": "error",
575
- "no-redeclare": ["error", { builtinGlobals: false }],
576
- "no-regex-spaces": "error",
577
- "no-restricted-globals": [
578
- "error",
579
- { name: "global", message: "Use `globalThis` instead." },
580
- { name: "self", message: "Use `globalThis` instead." }
581
- ],
582
- "no-restricted-properties": [
583
- "error",
584
- {
585
- message: "Use `Object.getPrototypeOf` or `Object.setPrototypeOf` instead.",
586
- property: "__proto__"
587
- },
588
- {
589
- message: "Use `Object.defineProperty` instead.",
590
- property: "__defineGetter__"
591
- },
592
- {
593
- message: "Use `Object.defineProperty` instead.",
594
- property: "__defineSetter__"
595
- },
596
- {
597
- message: "Use `Object.getOwnPropertyDescriptor` instead.",
598
- property: "__lookupGetter__"
599
- },
600
- {
601
- message: "Use `Object.getOwnPropertyDescriptor` instead.",
602
- property: "__lookupSetter__"
603
- }
604
- ],
605
- "no-restricted-syntax": [
606
- "error",
607
- "DebuggerStatement",
608
- "LabeledStatement",
609
- "WithStatement",
610
- "TSEnumDeclaration[const=true]",
611
- "TSExportAssignment"
612
- ],
613
- "no-self-assign": ["error", { props: true }],
614
- "no-self-compare": "error",
615
- "no-sequences": "error",
616
- "no-shadow-restricted-names": "error",
617
- "no-sparse-arrays": "error",
618
- "no-template-curly-in-string": "error",
619
- "no-this-before-super": "error",
620
- "no-throw-literal": "error",
621
- "no-undef": "error",
622
- "no-undef-init": "error",
623
- "no-unexpected-multiline": "error",
624
- "no-unmodified-loop-condition": "error",
625
- "no-unneeded-ternary": ["error", { defaultAssignment: false }],
626
- "no-unreachable": "error",
627
- "no-unreachable-loop": "error",
628
- "no-unsafe-finally": "error",
629
- "no-unsafe-negation": "error",
630
- "no-unused-expressions": [
631
- "error",
632
- {
633
- allowShortCircuit: true,
634
- allowTaggedTemplates: true,
635
- allowTernary: true
636
- }
637
- ],
638
- "no-unused-vars": [
639
- "error",
640
- {
641
- args: "none",
642
- caughtErrors: "none",
643
- ignoreRestSiblings: true,
644
- vars: "all"
645
- }
646
- ],
647
- "no-use-before-define": [
648
- "error",
649
- { classes: false, functions: false, variables: true }
650
- ],
651
- "no-useless-backreference": "error",
652
- "no-useless-call": "error",
653
- "no-useless-catch": "error",
654
- "no-useless-computed-key": "error",
655
- "no-useless-constructor": "error",
656
- "no-useless-rename": "error",
657
- "no-useless-return": "error",
658
- "no-var": "error",
659
- "no-with": "error",
660
- "object-shorthand": [
661
- "error",
662
- "always",
663
- {
664
- avoidQuotes: true,
665
- ignoreConstructors: false
666
- }
667
- ],
668
- "one-var": ["error", { initialized: "never" }],
669
- "prefer-arrow-callback": [
670
- "error",
671
- {
672
- allowNamedFunctions: false,
673
- allowUnboundThis: true
674
- }
675
- ],
676
- "prefer-const": [
677
- "error",
678
- {
679
- destructuring: "all",
680
- ignoreReadBeforeAssign: true
681
- }
682
- ],
683
- "prefer-exponentiation-operator": "error",
684
- "prefer-promise-reject-errors": "error",
685
- "prefer-regex-literals": ["error", { disallowRedundantWrapping: true }],
686
- "prefer-rest-params": "error",
687
- "prefer-spread": "error",
688
- "prefer-template": "error",
689
- "sort-imports": [
690
- "error",
691
- {
692
- allowSeparatedGroups: false,
693
- ignoreCase: false,
694
- ignoreDeclarationSort: true,
695
- ignoreMemberSort: false,
696
- memberSyntaxSortOrder: ["none", "all", "multiple", "single"]
697
- }
698
- ],
699
- "symbol-description": "error",
700
- "unicode-bom": ["error", "never"],
701
- "unused-imports/no-unused-imports": editor ? "off" : "error",
702
- "unused-imports/no-unused-vars": [
703
- "error",
704
- {
705
- args: "after-used",
706
- argsIgnorePattern: "^_",
707
- vars: "all",
708
- varsIgnorePattern: "^_"
709
- }
710
- ],
711
- "use-isnan": [
712
- "error",
713
- { enforceForIndexOf: true, enforceForSwitchCase: true }
714
- ],
715
- "valid-typeof": ["error", { requireStringLiterals: true }],
716
- "vars-on-top": "error",
717
- "yoda": ["error", "never"],
718
- ...overrides
719
- }
720
- },
721
- {
722
- name: "luxass/disables/cli",
723
- files: [
724
- `scripts/${GLOB_SRC}`,
725
- `cli.${GLOB_SRC_EXT}`,
726
- `**/playground.${GLOB_SRC_EXT}`
727
- ],
728
- rules: {
729
- "no-console": "off"
730
- }
731
- }
732
- ];
733
- }
734
-
735
- // src/utils.ts
736
- import process from "node:process";
737
- import { isPackageExists } from "local-pkg";
738
- var parserPlain = {
739
- meta: {
740
- name: "parser-plain"
741
- },
742
- parseForESLint: (code) => ({
743
- ast: {
744
- body: [],
745
- comments: [],
746
- loc: { end: code.length, start: 0 },
747
- range: [0, code.length],
748
- tokens: [],
749
- type: "Program"
750
- },
751
- scopeManager: null,
752
- services: { isPlain: true },
753
- visitorKeys: {
754
- Program: []
755
- }
756
- })
757
- };
758
- async function combine(...configs2) {
759
- const resolved = await Promise.all(configs2);
760
- return resolved.flat();
761
- }
762
- function renameRules(rules, map) {
763
- return Object.fromEntries(
764
- Object.entries(rules).map(([key, value]) => {
765
- for (const [from, to] of Object.entries(map)) {
766
- if (key.startsWith(`${from}/`)) {
767
- return [to + key.slice(from.length), value];
768
- }
769
- }
770
- return [key, value];
771
- })
772
- );
773
- }
774
- function renamePluginInConfigs(configs2, map) {
775
- return configs2.map((i) => {
776
- const clone = { ...i };
777
- if (clone.rules) {
778
- clone.rules = renameRules(clone.rules, map);
779
- }
780
- if (clone.plugins) {
781
- clone.plugins = Object.fromEntries(
782
- Object.entries(clone.plugins).map(([key, value]) => {
783
- if (key in map) {
784
- return [map[key], value];
785
- }
786
- return [key, value];
787
- })
788
- );
789
- }
790
- return clone;
791
- });
792
- }
793
- function toArray(value) {
794
- return Array.isArray(value) ? value : [value];
795
- }
796
- async function interop(m) {
797
- const resolved = await m;
798
- return resolved.default || resolved;
799
- }
800
- async function ensure(packages) {
801
- if (process.env.CI || process.stdout.isTTY === false) {
802
- return;
803
- }
804
- ;
805
- const nonExistingPackages = packages.filter((i) => i && !isPackageExists(i));
806
- if (nonExistingPackages.length === 0) {
807
- return;
808
- }
809
- const p = await import("@clack/prompts");
810
- const result = await p.confirm({
811
- message: `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?`
812
- });
813
- if (result) {
814
- await import("@antfu/install-pkg").then((i) => i.installPackage(nonExistingPackages, { dev: true }));
815
- }
816
- }
817
- function resolveSubOptions(options, key) {
818
- return typeof options[key] === "boolean" ? {} : options[key] || {};
819
- }
820
- function getOverrides(options, key) {
821
- const sub = resolveSubOptions(options, key);
822
- return {
823
- ..."overrides" in sub ? sub.overrides : {}
824
- };
825
- }
826
-
827
- // src/configs/jsdoc.ts
828
- async function jsdoc(options = {}) {
829
- const {
830
- overrides,
831
- stylistic: stylistic2 = true
832
- } = options;
833
- return [
834
- {
835
- name: "luxass/jsdoc/rules",
836
- plugins: {
837
- jsdoc: await interop(import("eslint-plugin-jsdoc"))
838
- },
314
+ files: ["**/*.d.?([cm])ts"],
315
+ name: "luxass/disables/dts",
839
316
  rules: {
840
- "jsdoc/check-access": "warn",
841
- "jsdoc/check-param-names": "warn",
842
- "jsdoc/check-property-names": "warn",
843
- "jsdoc/check-types": "warn",
844
- "jsdoc/empty-tags": "warn",
845
- "jsdoc/implements-on-classes": "warn",
846
- "jsdoc/no-defaults": "warn",
847
- "jsdoc/no-multi-asterisks": "warn",
848
- "jsdoc/require-param-name": "warn",
849
- "jsdoc/require-property": "warn",
850
- "jsdoc/require-property-description": "warn",
851
- "jsdoc/require-property-name": "warn",
852
- "jsdoc/require-returns-check": "warn",
853
- "jsdoc/require-returns-description": "warn",
854
- "jsdoc/require-yields-check": "warn",
855
- ...stylistic2 ? {
856
- "jsdoc/check-alignment": "warn",
857
- "jsdoc/multiline-blocks": "warn"
858
- } : {},
859
- ...overrides
860
- }
861
- }
862
- ];
863
- }
864
-
865
- // src/configs/json.ts
866
- async function jsonc(options = {}) {
867
- const {
868
- files = [GLOB_JSON, GLOB_JSON5, GLOB_JSONC],
869
- overrides = {},
870
- stylistic: stylistic2 = true
871
- } = options;
872
- const {
873
- indent = 2
874
- } = typeof stylistic2 === "boolean" ? {} : stylistic2;
875
- const [
876
- pluginJsonc,
877
- parserJsonc
878
- ] = await Promise.all([
879
- interop(import("eslint-plugin-jsonc")),
880
- interop(import("jsonc-eslint-parser"))
881
- ]);
882
- return [
317
+ "eslint-comments/no-unlimited-disable": "off",
318
+ "import/no-duplicates": "off",
319
+ "no-restricted-syntax": "off",
320
+ "unused-imports/no-unused-vars": "off"
321
+ }
322
+ },
883
323
  {
884
- name: "luxass/jsonc/setup",
885
- plugins: {
886
- jsonc: pluginJsonc
324
+ files: ["**/*.{test,spec}.([tj])s?(x)"],
325
+ name: "luxass/disables/test",
326
+ rules: {
327
+ "no-unused-expressions": "off"
887
328
  }
888
329
  },
889
330
  {
890
- name: "luxass/jsonc/rules",
891
- files,
892
- languageOptions: {
893
- parser: parserJsonc
894
- },
331
+ files: ["**/*.js", "**/*.cjs"],
332
+ name: "luxass/disables/cjs",
895
333
  rules: {
896
- "jsonc/no-bigint-literals": "error",
897
- "jsonc/no-binary-expression": "error",
898
- "jsonc/no-binary-numeric-literals": "error",
899
- "jsonc/no-dupe-keys": "error",
900
- "jsonc/no-escape-sequence-in-identifier": "error",
901
- "jsonc/no-floating-decimal": "error",
902
- "jsonc/no-hexadecimal-numeric-literals": "error",
903
- "jsonc/no-infinity": "error",
904
- "jsonc/no-multi-str": "error",
905
- "jsonc/no-nan": "error",
906
- "jsonc/no-number-props": "error",
907
- "jsonc/no-numeric-separators": "error",
908
- "jsonc/no-octal": "error",
909
- "jsonc/no-octal-escape": "error",
910
- "jsonc/no-octal-numeric-literals": "error",
911
- "jsonc/no-parenthesized": "error",
912
- "jsonc/no-plus-sign": "error",
913
- "jsonc/no-regexp-literals": "error",
914
- "jsonc/no-sparse-arrays": "error",
915
- "jsonc/no-template-literals": "error",
916
- "jsonc/no-undefined-value": "error",
917
- "jsonc/no-unicode-codepoint-escapes": "error",
918
- "jsonc/no-useless-escape": "error",
919
- "jsonc/space-unary-ops": "error",
920
- "jsonc/valid-json-number": "error",
921
- "jsonc/vue-custom-block/no-parsing-error": "error",
922
- ...stylistic2 ? {
923
- "jsonc/array-bracket-spacing": ["error", "never"],
924
- "jsonc/comma-dangle": ["error", "never"],
925
- "jsonc/comma-style": ["error", "last"],
926
- "jsonc/indent": ["error", indent],
927
- "jsonc/key-spacing": [
928
- "error",
929
- { afterColon: true, beforeColon: false }
930
- ],
931
- "jsonc/object-curly-newline": [
932
- "error",
933
- { consistent: true, multiline: true }
934
- ],
935
- "jsonc/object-curly-spacing": ["error", "always"],
936
- "jsonc/object-property-newline": [
937
- "error",
938
- { allowMultiplePropertiesPerLine: true }
939
- ],
940
- "jsonc/quote-props": "error",
941
- "jsonc/quotes": "error"
942
- } : {},
943
- ...overrides
334
+ "ts/no-require-imports": "off"
944
335
  }
945
336
  }
946
337
  ];
947
338
  }
948
339
 
949
- // src/configs/markdown.ts
950
- import { mergeProcessors, processorPassThrough } from "eslint-merge-processors";
951
- async function markdown(options = {}) {
340
+ // src/configs/stylistic.ts
341
+ import pluginAntfu from "eslint-plugin-antfu";
342
+ var StylisticConfigDefaults = {
343
+ indent: 2,
344
+ jsx: true,
345
+ quotes: "double",
346
+ semi: true
347
+ };
348
+ async function stylistic(options = {}) {
952
349
  const {
953
- exts = [],
954
- files = [GLOB_MARKDOWN],
955
- overrides = {}
956
- } = options;
957
- const markdown2 = await interop(import("eslint-plugin-markdown"));
350
+ indent,
351
+ jsx: jsx2,
352
+ overrides = {},
353
+ quotes,
354
+ semi
355
+ } = {
356
+ ...StylisticConfigDefaults,
357
+ ...options
358
+ };
359
+ const pluginStylistic = await interop(import("@stylistic/eslint-plugin"));
360
+ const config = pluginStylistic.configs.customize({
361
+ flat: true,
362
+ indent,
363
+ jsx: jsx2,
364
+ pluginName: "style",
365
+ quotes,
366
+ semi
367
+ });
958
368
  return [
959
369
  {
960
- name: "luxass/markdown/setup",
370
+ name: "luxass/stylistic",
961
371
  plugins: {
962
- markdown: markdown2
372
+ antfu: pluginAntfu,
373
+ style: pluginStylistic
374
+ },
375
+ rules: {
376
+ ...config.rules,
377
+ "antfu/consistent-list-newline": "error",
378
+ "antfu/if-newline": "off",
379
+ "antfu/top-level-function": "error",
380
+ "curly": ["error", "multi-line", "consistent"],
381
+ "style/arrow-parens": ["error", "always", { requireForBlockBody: true }],
382
+ "style/brace-style": ["error", "1tbs", { allowSingleLine: true }],
383
+ ...overrides
963
384
  }
385
+ }
386
+ ];
387
+ }
388
+
389
+ // src/configs/formatters.ts
390
+ async function formatters(options = {}, stylistic2 = {}) {
391
+ if (options === true) {
392
+ options = {
393
+ astro: isPackageInScope("astro"),
394
+ css: true,
395
+ graphql: true,
396
+ html: true,
397
+ markdown: true
398
+ };
399
+ }
400
+ await ensure([
401
+ "eslint-plugin-format",
402
+ options.astro ? "prettier-plugin-astro" : void 0
403
+ ]);
404
+ const {
405
+ indent,
406
+ quotes,
407
+ semi
408
+ } = {
409
+ ...StylisticConfigDefaults,
410
+ ...stylistic2
411
+ };
412
+ const prettierOptions = Object.assign(
413
+ {
414
+ endOfLine: "auto",
415
+ printWidth: 120,
416
+ semi,
417
+ singleQuote: quotes === "single",
418
+ tabWidth: typeof indent === "number" ? indent : 2,
419
+ trailingComma: "all",
420
+ useTabs: indent === "tab"
964
421
  },
422
+ options.prettierOptions || {}
423
+ );
424
+ const dprintOptions = Object.assign(
965
425
  {
966
- name: "luxass/markdown/processor",
967
- files,
968
- ignores: [GLOB_MARKDOWN_IN_MARKDOWN],
969
- // `eslint-plugin-markdown` only creates virtual files for code blocks,
970
- // but not the markdown file itself. We use `eslint-merge-processors` to
971
- // add a pass-through processor for the markdown file itself.
972
- processor: mergeProcessors([
973
- markdown2.processors.markdown,
974
- processorPassThrough
975
- ])
426
+ indentWidth: typeof indent === "number" ? indent : 2,
427
+ quoteStyle: quotes === "single" ? "preferSingle" : "preferDouble",
428
+ useTabs: indent === "tab"
976
429
  },
430
+ options.dprintOptions || {}
431
+ );
432
+ const pluginFormat = await interop(import("eslint-plugin-format"));
433
+ const configs2 = [
977
434
  {
978
- name: "luxass/markdown/parser",
979
- files,
435
+ name: "luxass/formatter/setup",
436
+ plugins: {
437
+ format: pluginFormat
438
+ }
439
+ }
440
+ ];
441
+ if (options.css) {
442
+ configs2.push(
443
+ {
444
+ name: "luxass/formatter/css",
445
+ files: [GLOB_CSS, GLOB_POSTCSS],
446
+ languageOptions: {
447
+ parser: parserPlain
448
+ },
449
+ rules: {
450
+ "format/prettier": [
451
+ "error",
452
+ {
453
+ ...prettierOptions,
454
+ parser: "css"
455
+ }
456
+ ]
457
+ }
458
+ },
459
+ {
460
+ name: "luxass/formatter/scss",
461
+ files: [GLOB_SCSS],
462
+ languageOptions: {
463
+ parser: parserPlain
464
+ },
465
+ rules: {
466
+ "format/prettier": [
467
+ "error",
468
+ {
469
+ ...prettierOptions,
470
+ parser: "scss"
471
+ }
472
+ ]
473
+ }
474
+ },
475
+ {
476
+ name: "luxass/formatter/less",
477
+ files: [GLOB_LESS],
478
+ languageOptions: {
479
+ parser: parserPlain
480
+ },
481
+ rules: {
482
+ "format/prettier": [
483
+ "error",
484
+ {
485
+ ...prettierOptions,
486
+ parser: "less"
487
+ }
488
+ ]
489
+ }
490
+ }
491
+ );
492
+ }
493
+ if (options.html) {
494
+ configs2.push({
495
+ name: "luxass/formatter/html",
496
+ files: [GLOB_HTML],
497
+ languageOptions: {
498
+ parser: parserPlain
499
+ },
500
+ rules: {
501
+ "format/prettier": [
502
+ "error",
503
+ {
504
+ ...prettierOptions,
505
+ parser: "html"
506
+ }
507
+ ]
508
+ }
509
+ });
510
+ }
511
+ if (options.markdown) {
512
+ const formater = options.markdown === true ? "prettier" : options.markdown;
513
+ configs2.push({
514
+ name: "luxass/formatter/markdown",
515
+ files: [GLOB_MARKDOWN],
516
+ languageOptions: {
517
+ parser: parserPlain
518
+ },
519
+ rules: {
520
+ [`format/${formater}`]: [
521
+ "error",
522
+ formater === "prettier" ? {
523
+ ...prettierOptions,
524
+ embeddedLanguageFormatting: "off",
525
+ parser: "markdown"
526
+ } : {
527
+ ...dprintOptions,
528
+ language: "markdown"
529
+ }
530
+ ]
531
+ }
532
+ });
533
+ }
534
+ if (options.astro) {
535
+ configs2.push({
536
+ name: "luxass/formatter/astro",
537
+ files: [GLOB_ASTRO],
980
538
  languageOptions: {
981
539
  parser: parserPlain
540
+ },
541
+ rules: {
542
+ "format/prettier": [
543
+ "error",
544
+ {
545
+ ...prettierOptions,
546
+ parser: "astro",
547
+ plugins: [
548
+ "prettier-plugin-astro"
549
+ ]
550
+ }
551
+ ]
982
552
  }
983
- },
984
- {
985
- name: "luxass/markdown/disables",
986
- files: [
987
- GLOB_MARKDOWN_CODE,
988
- ...exts.map((ext) => `${GLOB_MARKDOWN}/**/*.${ext}`)
989
- ],
553
+ });
554
+ }
555
+ if (options.graphql) {
556
+ configs2.push({
557
+ name: "luxass/formatter/graphql",
558
+ files: [GLOB_GRAPHQL],
990
559
  languageOptions: {
991
- parserOptions: {
992
- ecmaFeatures: {
993
- impliedStrict: true
994
- }
995
- }
560
+ parser: parserPlain
996
561
  },
997
562
  rules: {
998
- "import/newline-after-import": "off",
999
- "no-alert": "off",
1000
- "no-console": "off",
1001
- "no-labels": "off",
1002
- "no-lone-blocks": "off",
1003
- "no-restricted-syntax": "off",
1004
- "no-undef": "off",
1005
- "no-unused-expressions": "off",
1006
- "no-unused-labels": "off",
1007
- "no-unused-vars": "off",
1008
- "node/prefer-global/process": "off",
1009
- "style/comma-dangle": "off",
1010
- "style/eol-last": "off",
1011
- "ts/consistent-type-imports": "off",
1012
- "ts/no-namespace": "off",
1013
- "ts/no-redeclare": "off",
1014
- "ts/no-require-imports": "off",
1015
- "ts/no-unused-expressions": "off",
1016
- "ts/no-unused-vars": "off",
1017
- "ts/no-use-before-define": "off",
1018
- "ts/no-var-requires": "off",
1019
- "unicode-bom": "off",
1020
- "unused-imports/no-unused-imports": "off",
1021
- "unused-imports/no-unused-vars": "off",
1022
- ...overrides
563
+ "format/prettier": [
564
+ "error",
565
+ {
566
+ ...prettierOptions,
567
+ parser: "graphql"
568
+ }
569
+ ]
1023
570
  }
571
+ });
572
+ }
573
+ return configs2;
574
+ }
575
+
576
+ // src/configs/ignores.ts
577
+ async function ignores(userIgnores = []) {
578
+ return [
579
+ {
580
+ ignores: [
581
+ ...GLOB_EXCLUDE,
582
+ ...userIgnores
583
+ ],
584
+ name: "luxass/ignores"
1024
585
  }
1025
586
  ];
1026
587
  }
1027
588
 
1028
- // src/configs/stylistic.ts
1029
- import pluginAntfu3 from "eslint-plugin-antfu";
1030
- var StylisticConfigDefaults = {
1031
- indent: 2,
1032
- jsx: true,
1033
- quotes: "double",
1034
- semi: true
1035
- };
1036
- async function stylistic(options = {}) {
589
+ // src/configs/imports.ts
590
+ import pluginAntfu2 from "eslint-plugin-antfu";
591
+ import pluginImport from "eslint-plugin-import-x";
592
+ async function imports(options = {}) {
1037
593
  const {
1038
- indent,
1039
- jsx: jsx2,
1040
- overrides = {},
1041
- quotes,
1042
- semi
1043
- } = {
1044
- ...StylisticConfigDefaults,
1045
- ...options
1046
- };
1047
- const pluginStylistic = await interop(import("@stylistic/eslint-plugin"));
1048
- const config = pluginStylistic.configs.customize({
1049
- flat: true,
1050
- indent,
1051
- jsx: jsx2,
1052
- pluginName: "style",
1053
- quotes,
1054
- semi
1055
- });
594
+ stylistic: stylistic2 = true
595
+ } = options;
1056
596
  return [
1057
597
  {
1058
- name: "luxass/stylistic",
598
+ name: "luxass/imports",
1059
599
  plugins: {
1060
- antfu: pluginAntfu3,
1061
- style: pluginStylistic
600
+ antfu: pluginAntfu2,
601
+ import: pluginImport
1062
602
  },
1063
603
  rules: {
1064
- ...config.rules,
1065
- "antfu/consistent-list-newline": "error",
1066
- "antfu/if-newline": "off",
1067
- "antfu/top-level-function": "error",
1068
- "curly": ["error", "multi-line", "consistent"],
1069
- "style/arrow-parens": ["error", "always", { requireForBlockBody: true }],
1070
- "style/brace-style": ["error", "1tbs", { allowSingleLine: true }],
1071
- ...overrides
604
+ "antfu/import-dedupe": "error",
605
+ "antfu/no-import-dist": "error",
606
+ "antfu/no-import-node-modules-by-path": "error",
607
+ "import/first": "error",
608
+ "import/no-duplicates": "error",
609
+ "import/no-mutable-exports": "error",
610
+ "import/no-named-default": "error",
611
+ "import/no-self-import": "error",
612
+ "import/no-webpack-loader-syntax": "error",
613
+ ...stylistic2 ? {
614
+ "import/newline-after-import": ["error", { count: 1 }]
615
+ } : {}
1072
616
  }
1073
617
  }
1074
618
  ];
1075
619
  }
1076
620
 
1077
- // src/configs/typescript.ts
1078
- import process2 from "node:process";
1079
- import pluginAntfu4 from "eslint-plugin-antfu";
1080
- async function typescript(options = {}) {
621
+ // src/configs/javascript.ts
622
+ import pluginAntfu3 from "eslint-plugin-antfu";
623
+ import pluginUnusedImports from "eslint-plugin-unused-imports";
624
+ import globals from "globals";
625
+ async function javascript(options = {}) {
1081
626
  const {
1082
- exts = [],
1083
- overrides = {},
1084
- parserOptions = {},
1085
- type = "app"
1086
- } = options ?? {};
1087
- const files = options.files ?? [
1088
- GLOB_TS,
1089
- GLOB_TSX,
1090
- ...exts.map((ext) => `**/*.${ext}`)
1091
- ];
1092
- const filesTypeAware = options.filesTypeAware ?? [GLOB_TS, GLOB_TSX];
1093
- const ignoresTypeAware = options.ignoresTypeAware ?? [
1094
- `${GLOB_MARKDOWN}/**`,
1095
- GLOB_ASTRO_TS
1096
- ];
1097
- const tsconfigPath = options?.tsconfigPath ? options.tsconfigPath : void 0;
1098
- const isTypeAware = !!tsconfigPath;
1099
- const typeAwareRules = {
1100
- "dot-notation": "off",
1101
- "no-implied-eval": "off",
1102
- "ts/await-thenable": "error",
1103
- "ts/dot-notation": ["error", { allowKeywords: true }],
1104
- "ts/no-floating-promises": "error",
1105
- "ts/no-for-in-array": "error",
1106
- "ts/no-implied-eval": "error",
1107
- "ts/no-misused-promises": "error",
1108
- "ts/no-unnecessary-type-assertion": "error",
1109
- "ts/no-unsafe-argument": "error",
1110
- "ts/no-unsafe-assignment": "error",
1111
- "ts/no-unsafe-call": "error",
1112
- "ts/no-unsafe-member-access": "error",
1113
- "ts/no-unsafe-return": "error",
1114
- "ts/promise-function-async": "error",
1115
- "ts/restrict-plus-operands": "error",
1116
- "ts/restrict-template-expressions": "error",
1117
- "ts/return-await": ["error", "in-try-catch"],
1118
- "ts/strict-boolean-expressions": ["error", { allowNullableBoolean: true, allowNullableObject: true }],
1119
- "ts/switch-exhaustiveness-check": "error",
1120
- "ts/unbound-method": "error"
1121
- };
1122
- const [
1123
- pluginTs,
1124
- parserTs
1125
- ] = await Promise.all([
1126
- interop(import("@typescript-eslint/eslint-plugin")),
1127
- interop(import("@typescript-eslint/parser"))
1128
- ]);
1129
- function makeParser(typeAware, files2, ignores2) {
1130
- return {
1131
- files: files2,
1132
- ...ignores2 ? { ignores: ignores2 } : {},
1133
- name: `luxass/typescript/${typeAware ? "type-aware-parser" : "parser"}`,
1134
- languageOptions: {
1135
- parser: parserTs,
1136
- parserOptions: {
1137
- extraFileExtensions: exts.map((ext) => `.${ext}`),
1138
- sourceType: "module",
1139
- ...typeAware ? {
1140
- projectService: {
1141
- allowDefaultProject: ["./*.js"],
1142
- defaultProject: tsconfigPath
1143
- },
1144
- tsconfigRootDir: process2.cwd()
1145
- } : {},
1146
- ...parserOptions
1147
- }
1148
- }
1149
- };
1150
- }
627
+ isInEditor = false,
628
+ overrides = {}
629
+ } = options;
1151
630
  return [
1152
631
  {
1153
- // Install the plugins without globs, so they can be configured separately.
1154
- name: "luxass/typescript/setup",
1155
- plugins: {
1156
- antfu: pluginAntfu4,
1157
- ts: pluginTs
1158
- }
1159
- },
1160
- ...isTypeAware ? [
1161
- makeParser(true, filesTypeAware, ignoresTypeAware),
1162
- makeParser(false, files, filesTypeAware)
1163
- ] : [makeParser(false, files)],
632
+ name: "luxass/javascript/setup",
633
+ languageOptions: {
634
+ ecmaVersion: 2022,
635
+ globals: {
636
+ ...globals.browser,
637
+ ...globals.es2021,
638
+ ...globals.node,
639
+ document: "readonly",
640
+ navigator: "readonly",
641
+ window: "readonly"
642
+ },
643
+ parserOptions: {
644
+ ecmaFeatures: {
645
+ jsx: true
646
+ },
647
+ ecmaVersion: 2022,
648
+ sourceType: "module"
649
+ },
650
+ sourceType: "module"
651
+ },
652
+ linterOptions: {
653
+ reportUnusedDisableDirectives: true
654
+ }
655
+ },
1164
656
  {
1165
- name: "luxass/typescript/rules",
1166
- files,
657
+ name: "luxass/javascript/rules",
658
+ plugins: {
659
+ "antfu": pluginAntfu3,
660
+ "unused-imports": pluginUnusedImports
661
+ },
1167
662
  rules: {
1168
- ...renameRules(
1169
- pluginTs.configs["eslint-recommended"].overrides[0].rules,
663
+ "accessor-pairs": [
664
+ "error",
665
+ { enforceForClassMembers: true, setWithoutGet: true }
666
+ ],
667
+ "array-callback-return": "error",
668
+ "block-scoped-var": "error",
669
+ "constructor-super": "error",
670
+ "default-case-last": "error",
671
+ "dot-notation": ["error", { allowKeywords: true }],
672
+ "eqeqeq": ["error", "smart"],
673
+ "new-cap": [
674
+ "error",
675
+ { capIsNew: false, newIsCap: true, properties: true }
676
+ ],
677
+ "no-alert": "error",
678
+ "no-array-constructor": "error",
679
+ "no-async-promise-executor": "error",
680
+ "no-caller": "error",
681
+ "no-case-declarations": "error",
682
+ "no-class-assign": "error",
683
+ "no-compare-neg-zero": "error",
684
+ "no-cond-assign": ["error", "always"],
685
+ "no-console": ["error", { allow: ["warn", "error"] }],
686
+ "no-const-assign": "error",
687
+ "no-control-regex": "error",
688
+ "no-debugger": "error",
689
+ "no-delete-var": "error",
690
+ "no-dupe-args": "error",
691
+ "no-dupe-class-members": "error",
692
+ "no-dupe-keys": "error",
693
+ "no-duplicate-case": "error",
694
+ "no-empty": ["error", { allowEmptyCatch: true }],
695
+ "no-empty-character-class": "error",
696
+ "no-empty-pattern": "error",
697
+ "no-eval": "error",
698
+ "no-ex-assign": "error",
699
+ "no-extend-native": "error",
700
+ "no-extra-bind": "error",
701
+ "no-extra-boolean-cast": "error",
702
+ "no-fallthrough": "error",
703
+ "no-func-assign": "error",
704
+ "no-global-assign": "error",
705
+ "no-implied-eval": "error",
706
+ "no-import-assign": "error",
707
+ "no-invalid-regexp": "error",
708
+ "no-invalid-this": "error",
709
+ "no-irregular-whitespace": "error",
710
+ "no-iterator": "error",
711
+ "no-labels": ["error", { allowLoop: false, allowSwitch: false }],
712
+ "no-lone-blocks": "error",
713
+ "no-loss-of-precision": "error",
714
+ "no-misleading-character-class": "error",
715
+ "no-multi-str": "error",
716
+ "no-new": "error",
717
+ "no-new-func": "error",
718
+ "no-new-native-nonconstructor": "error",
719
+ "no-new-wrappers": "error",
720
+ "no-obj-calls": "error",
721
+ "no-octal": "error",
722
+ "no-octal-escape": "error",
723
+ "no-proto": "error",
724
+ "no-prototype-builtins": "error",
725
+ "no-redeclare": ["error", { builtinGlobals: false }],
726
+ "no-regex-spaces": "error",
727
+ "no-restricted-globals": [
728
+ "error",
729
+ { name: "global", message: "Use `globalThis` instead." },
730
+ { name: "self", message: "Use `globalThis` instead." }
731
+ ],
732
+ "no-restricted-properties": [
733
+ "error",
1170
734
  {
1171
- "@typescript-eslint": "ts"
1172
- }
1173
- ),
1174
- ...renameRules(
1175
- pluginTs.configs.strict.rules,
735
+ message: "Use `Object.getPrototypeOf` or `Object.setPrototypeOf` instead.",
736
+ property: "__proto__"
737
+ },
1176
738
  {
1177
- "@typescript-eslint": "ts"
739
+ message: "Use `Object.defineProperty` instead.",
740
+ property: "__defineGetter__"
741
+ },
742
+ {
743
+ message: "Use `Object.defineProperty` instead.",
744
+ property: "__defineSetter__"
745
+ },
746
+ {
747
+ message: "Use `Object.getOwnPropertyDescriptor` instead.",
748
+ property: "__lookupGetter__"
749
+ },
750
+ {
751
+ message: "Use `Object.getOwnPropertyDescriptor` instead.",
752
+ property: "__lookupSetter__"
1178
753
  }
1179
- ),
1180
- "no-dupe-class-members": "off",
1181
- "no-invalid-this": "off",
1182
- "no-loss-of-precision": "error",
1183
- "no-redeclare": "off",
1184
- "no-use-before-define": "off",
1185
- "no-useless-constructor": "off",
1186
- "ts/ban-ts-comment": [
754
+ ],
755
+ "no-restricted-syntax": [
756
+ "error",
757
+ "DebuggerStatement",
758
+ "LabeledStatement",
759
+ "WithStatement",
760
+ "TSEnumDeclaration[const=true]",
761
+ "TSExportAssignment"
762
+ ],
763
+ "no-self-assign": ["error", { props: true }],
764
+ "no-self-compare": "error",
765
+ "no-sequences": "error",
766
+ "no-shadow-restricted-names": "error",
767
+ "no-sparse-arrays": "error",
768
+ "no-template-curly-in-string": "error",
769
+ "no-this-before-super": "error",
770
+ "no-throw-literal": "error",
771
+ "no-undef": "error",
772
+ "no-undef-init": "error",
773
+ "no-unexpected-multiline": "error",
774
+ "no-unmodified-loop-condition": "error",
775
+ "no-unneeded-ternary": ["error", { defaultAssignment: false }],
776
+ "no-unreachable": "error",
777
+ "no-unreachable-loop": "error",
778
+ "no-unsafe-finally": "error",
779
+ "no-unsafe-negation": "error",
780
+ "no-unused-expressions": [
1187
781
  "error",
1188
782
  {
1189
- "ts-ignore": "allow-with-description",
1190
- "ts-expect-error": "allow-with-description"
783
+ allowShortCircuit: true,
784
+ allowTaggedTemplates: true,
785
+ allowTernary: true
1191
786
  }
1192
787
  ],
1193
- "ts/consistent-type-definitions": ["error", "interface"],
1194
- "ts/consistent-type-imports": [
788
+ "no-unused-vars": [
1195
789
  "error",
1196
- { disallowTypeAnnotations: false, prefer: "type-imports" }
790
+ {
791
+ args: "none",
792
+ caughtErrors: "none",
793
+ ignoreRestSiblings: true,
794
+ vars: "all"
795
+ }
1197
796
  ],
1198
- "ts/method-signature-style": ["error", "property"],
1199
- // https://www.totaltypescript.com/method-shorthand-syntax-considered-harmful
1200
- "ts/no-dupe-class-members": "error",
1201
- "ts/no-dynamic-delete": "off",
1202
- "ts/no-empty-object-type": "error",
1203
- "ts/no-explicit-any": "off",
1204
- "ts/no-extraneous-class": "off",
1205
- "ts/no-import-type-side-effects": "error",
1206
- "ts/no-invalid-this": "error",
1207
- "ts/no-invalid-void-type": "off",
1208
- "ts/no-non-null-assertion": "off",
1209
- "ts/no-redeclare": "error",
1210
- "ts/no-require-imports": "error",
1211
- "ts/no-unused-vars": "off",
1212
- "ts/no-use-before-define": [
797
+ "no-use-before-define": [
1213
798
  "error",
1214
799
  { classes: false, functions: false, variables: true }
1215
800
  ],
1216
- "ts/no-useless-constructor": "off",
1217
- "ts/no-wrapper-object-types": "error",
1218
- "ts/triple-slash-reference": "off",
1219
- "ts/unified-signatures": "off",
1220
- ...type === "lib" ? {
1221
- "ts/explicit-function-return-type": ["error", {
1222
- allowExpressions: true,
1223
- allowHigherOrderFunctions: true,
1224
- allowIIFEs: true
1225
- }]
1226
- } : {},
801
+ "no-useless-backreference": "error",
802
+ "no-useless-call": "error",
803
+ "no-useless-catch": "error",
804
+ "no-useless-computed-key": "error",
805
+ "no-useless-constructor": "error",
806
+ "no-useless-rename": "error",
807
+ "no-useless-return": "error",
808
+ "no-var": "error",
809
+ "no-with": "error",
810
+ "object-shorthand": [
811
+ "error",
812
+ "always",
813
+ {
814
+ avoidQuotes: true,
815
+ ignoreConstructors: false
816
+ }
817
+ ],
818
+ "one-var": ["error", { initialized: "never" }],
819
+ "prefer-arrow-callback": [
820
+ "error",
821
+ {
822
+ allowNamedFunctions: false,
823
+ allowUnboundThis: true
824
+ }
825
+ ],
826
+ "prefer-const": [
827
+ "error",
828
+ {
829
+ destructuring: "all",
830
+ ignoreReadBeforeAssign: true
831
+ }
832
+ ],
833
+ "prefer-exponentiation-operator": "error",
834
+ "prefer-promise-reject-errors": "error",
835
+ "prefer-regex-literals": ["error", { disallowRedundantWrapping: true }],
836
+ "prefer-rest-params": "error",
837
+ "prefer-spread": "error",
838
+ "prefer-template": "error",
839
+ "symbol-description": "error",
840
+ "unicode-bom": ["error", "never"],
841
+ "unused-imports/no-unused-imports": isInEditor ? "off" : "error",
842
+ "unused-imports/no-unused-vars": [
843
+ "error",
844
+ {
845
+ args: "after-used",
846
+ argsIgnorePattern: "^_",
847
+ vars: "all",
848
+ varsIgnorePattern: "^_"
849
+ }
850
+ ],
851
+ "use-isnan": [
852
+ "error",
853
+ { enforceForIndexOf: true, enforceForSwitchCase: true }
854
+ ],
855
+ "valid-typeof": ["error", { requireStringLiterals: true }],
856
+ "vars-on-top": "error",
857
+ "yoda": ["error", "never"],
1227
858
  ...overrides
1228
859
  }
1229
860
  },
1230
- ...isTypeAware ? [{
1231
- files: filesTypeAware,
1232
- ignores: ignoresTypeAware,
1233
- name: "luxass/typescript/rules-type-aware",
1234
- rules: typeAwareRules
1235
- }] : [],
1236
- {
1237
- name: "luxass/typescript/disables/dts",
1238
- files: ["**/*.d.?([cm])ts"],
1239
- rules: {
1240
- "eslint-comments/no-unlimited-disable": "off",
1241
- "import/no-duplicates": "off",
1242
- "no-restricted-syntax": "off",
1243
- "unused-imports/no-unused-vars": "off"
1244
- }
1245
- },
1246
861
  {
1247
- files: ["**/*.{test,spec}.ts?(x)"],
1248
- name: "luxass/typescript/disables/test",
862
+ name: "luxass/disables/cli",
863
+ files: [
864
+ `scripts/${GLOB_SRC}`,
865
+ `cli.${GLOB_SRC_EXT}`,
866
+ `**/playground.${GLOB_SRC_EXT}`
867
+ ],
1249
868
  rules: {
1250
- "no-unused-expressions": "off"
869
+ "no-console": "off"
1251
870
  }
1252
- },
871
+ }
872
+ ];
873
+ }
874
+
875
+ // src/configs/jsdoc.ts
876
+ async function jsdoc(options = {}) {
877
+ const {
878
+ overrides,
879
+ stylistic: stylistic2 = true
880
+ } = options;
881
+ return [
1253
882
  {
1254
- name: "luxass/typescript/disables/cjs",
1255
- files: ["**/*.js", "**/*.cjs"],
883
+ name: "luxass/jsdoc/rules",
884
+ plugins: {
885
+ jsdoc: await interop(import("eslint-plugin-jsdoc"))
886
+ },
1256
887
  rules: {
1257
- "ts/no-require-imports": "off",
1258
- "ts/no-var-requires": "off"
888
+ "jsdoc/check-access": "warn",
889
+ "jsdoc/check-param-names": "warn",
890
+ "jsdoc/check-property-names": "warn",
891
+ "jsdoc/check-types": "warn",
892
+ "jsdoc/empty-tags": "warn",
893
+ "jsdoc/implements-on-classes": "warn",
894
+ "jsdoc/no-defaults": "warn",
895
+ "jsdoc/no-multi-asterisks": "warn",
896
+ "jsdoc/require-param-name": "warn",
897
+ "jsdoc/require-property": "warn",
898
+ "jsdoc/require-property-description": "warn",
899
+ "jsdoc/require-property-name": "warn",
900
+ "jsdoc/require-returns-check": "warn",
901
+ "jsdoc/require-returns-description": "warn",
902
+ "jsdoc/require-yields-check": "warn",
903
+ ...stylistic2 ? {
904
+ "jsdoc/check-alignment": "warn",
905
+ "jsdoc/multiline-blocks": "warn"
906
+ } : {},
907
+ ...overrides
1259
908
  }
1260
909
  }
1261
910
  ];
1262
911
  }
1263
912
 
1264
- // src/configs/vue.ts
1265
- import { mergeProcessors as mergeProcessors2 } from "eslint-merge-processors";
1266
- async function vue(options = {}) {
913
+ // src/configs/json.ts
914
+ async function jsonc(options = {}) {
1267
915
  const {
1268
- files = [GLOB_VUE],
916
+ files = [GLOB_JSON, GLOB_JSON5, GLOB_JSONC],
1269
917
  overrides = {},
1270
918
  stylistic: stylistic2 = true
1271
919
  } = options;
1272
- const [
1273
- pluginVue,
1274
- parserVue,
1275
- processorVueBlocks
1276
- ] = await Promise.all([
1277
- interop(import("eslint-plugin-vue")),
1278
- interop(import("vue-eslint-parser")),
1279
- interop(import("eslint-processor-vue-blocks"))
1280
- ]);
1281
- const sfcBlocks = options.sfcBlocks === true ? {} : options.sfcBlocks ?? {};
1282
920
  const {
1283
921
  indent = 2
1284
922
  } = typeof stylistic2 === "boolean" ? {} : stylistic2;
923
+ const [
924
+ pluginJsonc,
925
+ parserJsonc
926
+ ] = await Promise.all([
927
+ interop(import("eslint-plugin-jsonc")),
928
+ interop(import("jsonc-eslint-parser"))
929
+ ]);
1285
930
  return [
1286
931
  {
1287
- name: "luxass/vue/setup",
1288
- // This allows Vue plugin to work with auto imports
1289
- // https://github.com/vuejs/eslint-plugin-vue/pull/2422
932
+ name: "luxass/jsonc/setup",
933
+ plugins: {
934
+ jsonc: pluginJsonc
935
+ }
936
+ },
937
+ {
938
+ name: "luxass/jsonc/rules",
939
+ files,
1290
940
  languageOptions: {
1291
- globals: {
1292
- computed: "readonly",
1293
- defineEmits: "readonly",
1294
- defineExpose: "readonly",
1295
- defineProps: "readonly",
1296
- onMounted: "readonly",
1297
- onUnmounted: "readonly",
1298
- reactive: "readonly",
1299
- ref: "readonly",
1300
- shallowReactive: "readonly",
1301
- shallowRef: "readonly",
1302
- toRef: "readonly",
1303
- toRefs: "readonly",
1304
- watch: "readonly",
1305
- watchEffect: "readonly"
1306
- }
941
+ parser: parserJsonc
1307
942
  },
943
+ rules: {
944
+ "jsonc/no-bigint-literals": "error",
945
+ "jsonc/no-binary-expression": "error",
946
+ "jsonc/no-binary-numeric-literals": "error",
947
+ "jsonc/no-dupe-keys": "error",
948
+ "jsonc/no-escape-sequence-in-identifier": "error",
949
+ "jsonc/no-floating-decimal": "error",
950
+ "jsonc/no-hexadecimal-numeric-literals": "error",
951
+ "jsonc/no-infinity": "error",
952
+ "jsonc/no-multi-str": "error",
953
+ "jsonc/no-nan": "error",
954
+ "jsonc/no-number-props": "error",
955
+ "jsonc/no-numeric-separators": "error",
956
+ "jsonc/no-octal": "error",
957
+ "jsonc/no-octal-escape": "error",
958
+ "jsonc/no-octal-numeric-literals": "error",
959
+ "jsonc/no-parenthesized": "error",
960
+ "jsonc/no-plus-sign": "error",
961
+ "jsonc/no-regexp-literals": "error",
962
+ "jsonc/no-sparse-arrays": "error",
963
+ "jsonc/no-template-literals": "error",
964
+ "jsonc/no-undefined-value": "error",
965
+ "jsonc/no-unicode-codepoint-escapes": "error",
966
+ "jsonc/no-useless-escape": "error",
967
+ "jsonc/space-unary-ops": "error",
968
+ "jsonc/valid-json-number": "error",
969
+ "jsonc/vue-custom-block/no-parsing-error": "error",
970
+ ...stylistic2 ? {
971
+ "jsonc/array-bracket-spacing": ["error", "never"],
972
+ "jsonc/comma-dangle": ["error", "never"],
973
+ "jsonc/comma-style": ["error", "last"],
974
+ "jsonc/indent": ["error", indent],
975
+ "jsonc/key-spacing": [
976
+ "error",
977
+ { afterColon: true, beforeColon: false }
978
+ ],
979
+ "jsonc/object-curly-newline": [
980
+ "error",
981
+ { consistent: true, multiline: true }
982
+ ],
983
+ "jsonc/object-curly-spacing": ["error", "always"],
984
+ "jsonc/object-property-newline": [
985
+ "error",
986
+ { allowMultiplePropertiesPerLine: true }
987
+ ],
988
+ "jsonc/quote-props": "error",
989
+ "jsonc/quotes": "error"
990
+ } : {},
991
+ ...overrides
992
+ }
993
+ }
994
+ ];
995
+ }
996
+
997
+ // src/configs/jsx.ts
998
+ async function jsx() {
999
+ return [
1000
+ {
1001
+ name: "luxass/jsx/setup",
1002
+ files: [GLOB_JSX, GLOB_TSX],
1003
+ languageOptions: {
1004
+ parserOptions: {
1005
+ ecmaFeatures: {
1006
+ jsx: true
1007
+ }
1008
+ }
1009
+ }
1010
+ }
1011
+ ];
1012
+ }
1013
+
1014
+ // src/configs/markdown.ts
1015
+ import { mergeProcessors, processorPassThrough } from "eslint-merge-processors";
1016
+ async function markdown(options = {}) {
1017
+ const {
1018
+ exts = [],
1019
+ files = [GLOB_MARKDOWN],
1020
+ overrides = {}
1021
+ } = options;
1022
+ const markdown2 = await interop(import("@eslint/markdown"));
1023
+ return [
1024
+ {
1025
+ name: "luxass/markdown/setup",
1308
1026
  plugins: {
1309
- vue: pluginVue
1027
+ markdown: markdown2
1310
1028
  }
1311
1029
  },
1312
1030
  {
1313
- name: "luxass/vue/rules",
1031
+ name: "luxass/markdown/processor",
1032
+ files,
1033
+ ignores: [GLOB_MARKDOWN_IN_MARKDOWN],
1034
+ // `eslint-plugin-markdown` only creates virtual files for code blocks,
1035
+ // but not the markdown file itself. We use `eslint-merge-processors` to
1036
+ // add a pass-through processor for the markdown file itself.
1037
+ processor: mergeProcessors([
1038
+ markdown2.processors.markdown,
1039
+ processorPassThrough
1040
+ ])
1041
+ },
1042
+ {
1043
+ name: "luxass/markdown/parser",
1314
1044
  files,
1315
1045
  languageOptions: {
1316
- parser: parserVue,
1046
+ parser: parserPlain
1047
+ }
1048
+ },
1049
+ {
1050
+ name: "luxass/markdown/disables",
1051
+ files: [
1052
+ GLOB_MARKDOWN_CODE,
1053
+ ...exts.map((ext) => `${GLOB_MARKDOWN}/**/*.${ext}`)
1054
+ ],
1055
+ languageOptions: {
1317
1056
  parserOptions: {
1318
1057
  ecmaFeatures: {
1319
- jsx: true
1320
- },
1321
- extraFileExtensions: [".vue"],
1322
- parser: options.typescript ? await interop(import("@typescript-eslint/parser")) : null,
1323
- sourceType: "module"
1058
+ impliedStrict: true
1059
+ }
1324
1060
  }
1325
1061
  },
1326
- processor: sfcBlocks === false ? pluginVue.processors[".vue"] : mergeProcessors2([
1327
- pluginVue.processors[".vue"],
1328
- processorVueBlocks({
1329
- ...sfcBlocks,
1330
- blocks: {
1331
- styles: true,
1332
- ...sfcBlocks.blocks
1333
- }
1334
- })
1335
- ]),
1336
1062
  rules: {
1337
- ...pluginVue.configs.base.rules,
1338
- ...pluginVue.configs["vue3-essential"].rules,
1339
- ...pluginVue.configs["vue3-strongly-recommended"].rules,
1340
- ...pluginVue.configs["vue3-recommended"].rules,
1341
- "node/prefer-global/process": "off",
1342
- "vue/block-order": [
1343
- "error",
1344
- {
1345
- order: ["script", "template", "style"]
1346
- }
1347
- ],
1348
- "vue/component-name-in-template-casing": ["error", "PascalCase"],
1349
- "vue/component-options-name-casing": ["error", "PascalCase"],
1350
- // this is deprecated
1351
- "vue/component-tags-order": "off",
1352
- "vue/custom-event-name-casing": ["error", "camelCase"],
1353
- "vue/define-macros-order": [
1354
- "error",
1355
- {
1356
- order: [
1357
- "defineOptions",
1358
- "defineProps",
1359
- "defineEmits",
1360
- "defineSlots"
1361
- ]
1362
- }
1363
- ],
1364
- "vue/dot-location": ["error", "property"],
1365
- "vue/dot-notation": ["error", { allowKeywords: true }],
1366
- "vue/eqeqeq": ["error", "smart"],
1367
- "vue/html-indent": ["error", indent],
1368
- "vue/html-quotes": ["error", "double"],
1369
- "vue/max-attributes-per-line": "off",
1370
- "vue/multi-word-component-names": "off",
1371
- "vue/no-dupe-keys": "off",
1372
- "vue/no-empty-pattern": "error",
1373
- "vue/no-irregular-whitespace": "error",
1374
- "vue/no-loss-of-precision": "error",
1375
- "vue/no-restricted-syntax": [
1376
- "error",
1377
- "DebuggerStatement",
1378
- "LabeledStatement",
1379
- "WithStatement"
1380
- ],
1381
- "vue/no-restricted-v-bind": ["error", "/^v-/"],
1382
- "vue/no-setup-props-reactivity-loss": "off",
1383
- "vue/no-sparse-arrays": "error",
1384
- "vue/no-unused-refs": "error",
1385
- "vue/no-useless-v-bind": "error",
1386
- "vue/no-v-html": "off",
1387
- "vue/object-shorthand": [
1388
- "error",
1389
- "always",
1390
- {
1391
- avoidQuotes: true,
1392
- ignoreConstructors: false
1393
- }
1394
- ],
1395
- "vue/prefer-separate-static-class": "error",
1396
- "vue/prefer-template": "error",
1397
- "vue/prop-name-casing": ["error", "camelCase"],
1398
- "vue/require-default-prop": "off",
1399
- "vue/require-prop-types": "off",
1400
- "vue/space-infix-ops": "error",
1401
- "vue/space-unary-ops": ["error", { nonwords: false, words: true }],
1402
- ...stylistic2 ? {
1403
- "vue/array-bracket-spacing": ["error", "never"],
1404
- "vue/arrow-spacing": ["error", { after: true, before: true }],
1405
- "vue/block-spacing": ["error", "always"],
1406
- "vue/block-tag-newline": [
1407
- "error",
1408
- {
1409
- multiline: "always",
1410
- singleline: "always"
1411
- }
1063
+ "import/newline-after-import": "off",
1064
+ "no-alert": "off",
1065
+ "no-console": "off",
1066
+ "no-labels": "off",
1067
+ "no-lone-blocks": "off",
1068
+ "no-restricted-syntax": "off",
1069
+ "no-undef": "off",
1070
+ "no-unused-expressions": "off",
1071
+ "no-unused-labels": "off",
1072
+ "no-unused-vars": "off",
1073
+ "node/prefer-global/process": "off",
1074
+ "style/comma-dangle": "off",
1075
+ "style/eol-last": "off",
1076
+ "ts/consistent-type-imports": "off",
1077
+ "ts/no-namespace": "off",
1078
+ "ts/no-redeclare": "off",
1079
+ "ts/no-require-imports": "off",
1080
+ "ts/no-unused-expressions": "off",
1081
+ "ts/no-unused-vars": "off",
1082
+ "ts/no-use-before-define": "off",
1083
+ "ts/no-var-requires": "off",
1084
+ "unicode-bom": "off",
1085
+ "unused-imports/no-unused-imports": "off",
1086
+ "unused-imports/no-unused-vars": "off",
1087
+ ...overrides
1088
+ }
1089
+ }
1090
+ ];
1091
+ }
1092
+
1093
+ // src/configs/node.ts
1094
+ import pluginNode from "eslint-plugin-n";
1095
+ function node() {
1096
+ return [
1097
+ {
1098
+ name: "luxass/node",
1099
+ plugins: {
1100
+ node: pluginNode
1101
+ },
1102
+ rules: {
1103
+ "node/handle-callback-err": ["error", "^(err|error)$"],
1104
+ "node/no-deprecated-api": "error",
1105
+ "node/no-exports-assign": "error",
1106
+ "node/no-new-require": "error",
1107
+ "node/no-path-concat": "error",
1108
+ "node/prefer-global/buffer": ["error", "never"],
1109
+ "node/prefer-global/process": ["error", "never"],
1110
+ "node/process-exit-as-throw": "error"
1111
+ }
1112
+ }
1113
+ ];
1114
+ }
1115
+
1116
+ // src/configs/perfectionist.ts
1117
+ import pluginPerfectionist from "eslint-plugin-perfectionist";
1118
+ async function perfectionist() {
1119
+ return [
1120
+ {
1121
+ name: "luxass/perfectionist/setup",
1122
+ plugins: {
1123
+ perfectionist: pluginPerfectionist
1124
+ },
1125
+ rules: {
1126
+ "perfectionist/sort-exports": ["error", { order: "asc", type: "natural" }],
1127
+ "perfectionist/sort-imports": ["error", {
1128
+ groups: [
1129
+ "builtin",
1130
+ "external",
1131
+ "type",
1132
+ ["internal", "internal-type"],
1133
+ ["parent", "sibling", "index"],
1134
+ ["parent-type", "sibling-type", "index-type"],
1135
+ "side-effect",
1136
+ "object",
1137
+ "unknown"
1412
1138
  ],
1413
- "vue/brace-style": [
1414
- "error",
1415
- "stroustrup",
1416
- { allowSingleLine: true }
1417
- ],
1418
- "vue/comma-dangle": ["error", "always-multiline"],
1419
- "vue/comma-spacing": ["error", { after: true, before: false }],
1420
- "vue/comma-style": ["error", "last"],
1421
- "vue/html-comment-content-spacing": [
1422
- "error",
1423
- "always",
1424
- {
1425
- exceptions: ["-"]
1426
- }
1427
- ],
1428
- "vue/key-spacing": [
1429
- "error",
1430
- { afterColon: true, beforeColon: false }
1431
- ],
1432
- "vue/keyword-spacing": ["error", { after: true, before: true }],
1433
- "vue/object-curly-newline": "off",
1434
- "vue/object-curly-spacing": ["error", "always"],
1435
- "vue/object-property-newline": [
1436
- "error",
1437
- { allowMultiplePropertiesPerLine: true }
1438
- ],
1439
- "vue/operator-linebreak": ["error", "before"],
1440
- "vue/padding-line-between-blocks": ["error", "always"],
1441
- "vue/quote-props": ["error", "consistent-as-needed"],
1442
- "vue/space-in-parens": ["error", "never"],
1443
- "vue/template-curly-spacing": "error"
1444
- } : {},
1445
- ...overrides
1139
+ newlinesBetween: "ignore",
1140
+ order: "asc",
1141
+ type: "natural"
1142
+ }],
1143
+ "perfectionist/sort-named-exports": ["error", { order: "asc", type: "natural" }],
1144
+ "perfectionist/sort-named-imports": ["error", { order: "asc", type: "natural" }]
1446
1145
  }
1447
1146
  }
1448
1147
  ];
1449
1148
  }
1450
1149
 
1451
- // src/configs/yaml.ts
1452
- async function yaml(options = {}) {
1150
+ // src/configs/react.ts
1151
+ import { isPackageExists as isPackageExists2 } from "local-pkg";
1152
+ var ReactRefreshAllowConstantExportPackages = [
1153
+ "vite"
1154
+ ];
1155
+ var RemixPackages = [
1156
+ "@remix-run/node",
1157
+ "@remix-run/react",
1158
+ "@remix-run/serve",
1159
+ "@remix-run/dev"
1160
+ ];
1161
+ async function react(options = {}) {
1453
1162
  const {
1454
- files = [GLOB_YAML],
1455
- overrides = {},
1456
- stylistic: stylistic2 = true
1163
+ files = [GLOB_JS, GLOB_JSX, GLOB_TS, GLOB_TSX],
1164
+ overrides = {}
1457
1165
  } = options;
1166
+ await ensure([
1167
+ "@eslint-react/eslint-plugin",
1168
+ "eslint-plugin-react-hooks",
1169
+ "eslint-plugin-react-refresh"
1170
+ ]);
1171
+ const tsconfigPath = options?.tsconfigPath ? toArray(options.tsconfigPath) : void 0;
1172
+ const isTypeAware = !!tsconfigPath;
1458
1173
  const [
1459
- pluginYaml,
1460
- parserYaml
1174
+ pluginReact,
1175
+ pluginReactHooks,
1176
+ pluginReactRefresh,
1177
+ parserTs
1461
1178
  ] = await Promise.all([
1462
- interop(import("eslint-plugin-yml")),
1463
- interop(import("yaml-eslint-parser"))
1179
+ interop(import("@eslint-react/eslint-plugin")),
1180
+ interop(import("eslint-plugin-react-hooks")),
1181
+ interop(import("eslint-plugin-react-refresh")),
1182
+ interop(import("@typescript-eslint/parser"))
1464
1183
  ]);
1465
- const {
1466
- indent = 2,
1467
- quotes = "double"
1468
- } = typeof stylistic2 === "boolean" ? {} : stylistic2;
1184
+ const isAllowConstantExport = ReactRefreshAllowConstantExportPackages.some(
1185
+ (i) => isPackageExists2(i)
1186
+ );
1187
+ const isUsingRemix = RemixPackages.some((i) => isPackageExists2(i));
1188
+ const isUsingNext = isPackageExists2("next");
1189
+ const plugins = pluginReact.configs.all.plugins;
1469
1190
  return [
1470
1191
  {
1471
- name: "luxass/yaml/setup",
1192
+ name: "luxass/react/setup",
1472
1193
  plugins: {
1473
- yaml: pluginYaml
1194
+ "react": plugins["@eslint-react"],
1195
+ "react-dom": plugins["@eslint-react/dom"],
1196
+ "react-hooks": pluginReactHooks,
1197
+ "react-hooks-extra": plugins["@eslint-react/hooks-extra"],
1198
+ "react-naming-convention": plugins["@eslint-react/naming-convention"],
1199
+ "react-refresh": pluginReactRefresh
1474
1200
  }
1475
1201
  },
1476
1202
  {
1477
- name: "luxass/yaml/rules",
1203
+ name: "luxass/react/rules",
1478
1204
  files,
1479
1205
  languageOptions: {
1480
- parser: parserYaml
1206
+ parser: parserTs,
1207
+ parserOptions: {
1208
+ ecmaFeatures: {
1209
+ jsx: true
1210
+ },
1211
+ ...isTypeAware ? { project: tsconfigPath } : {}
1212
+ },
1213
+ sourceType: "module"
1481
1214
  },
1482
1215
  rules: {
1483
- "style/spaced-comment": "off",
1484
- "yaml/block-mapping": "error",
1485
- "yaml/block-sequence": "error",
1486
- "yaml/no-empty-key": "error",
1487
- "yaml/no-empty-mapping-value": "error",
1488
- "yaml/no-empty-sequence-entry": "error",
1489
- "yaml/no-irregular-whitespace": "error",
1490
- "yaml/plain-scalar": "error",
1491
- "yaml/vue-custom-block/no-parsing-error": "error",
1492
- ...stylistic2 ? {
1493
- "yaml/block-mapping-question-indicator-newline": "error",
1494
- "yaml/block-sequence-hyphen-indicator-newline": "error",
1495
- "yaml/flow-mapping-curly-newline": "error",
1496
- "yaml/flow-mapping-curly-spacing": "error",
1497
- "yaml/flow-sequence-bracket-newline": "error",
1498
- "yaml/flow-sequence-bracket-spacing": "error",
1499
- "yaml/indent": ["error", indent === "tab" ? 2 : indent],
1500
- "yaml/key-spacing": "error",
1501
- "yaml/no-tab-indent": "error",
1502
- "yaml/quotes": [
1503
- "error",
1504
- { avoidEscape: false, prefer: quotes }
1505
- ],
1506
- "yaml/spaced-comment": "error"
1216
+ // recommended rules from @eslint-react/dom
1217
+ "react-dom/no-children-in-void-dom-elements": "warn",
1218
+ "react-dom/no-dangerously-set-innerhtml": "warn",
1219
+ "react-dom/no-dangerously-set-innerhtml-with-children": "error",
1220
+ "react-dom/no-find-dom-node": "error",
1221
+ "react-dom/no-missing-button-type": "warn",
1222
+ "react-dom/no-missing-iframe-sandbox": "warn",
1223
+ "react-dom/no-namespace": "error",
1224
+ "react-dom/no-render-return-value": "error",
1225
+ "react-dom/no-script-url": "warn",
1226
+ "react-dom/no-unsafe-iframe-sandbox": "warn",
1227
+ "react-dom/no-unsafe-target-blank": "warn",
1228
+ // recommended rules react-hooks
1229
+ "react-hooks/exhaustive-deps": "warn",
1230
+ "react-hooks/rules-of-hooks": "error",
1231
+ // react refresh
1232
+ "react-refresh/only-export-components": [
1233
+ "warn",
1234
+ {
1235
+ allowConstantExport: isAllowConstantExport,
1236
+ allowExportNames: [
1237
+ ...isUsingNext ? [
1238
+ "config",
1239
+ "runtime",
1240
+ "generateStaticParams",
1241
+ "metadata",
1242
+ "generateMetadata",
1243
+ "viewport",
1244
+ "generateViewport"
1245
+ ] : [],
1246
+ ...isUsingRemix ? [
1247
+ "meta",
1248
+ "links",
1249
+ "headers",
1250
+ "loader",
1251
+ "action"
1252
+ ] : []
1253
+ ]
1254
+ }
1255
+ ],
1256
+ // recommended rules from @eslint-react
1257
+ "react/ensure-forward-ref-using-ref": "warn",
1258
+ "react/no-access-state-in-setstate": "error",
1259
+ "react/no-array-index-key": "warn",
1260
+ "react/no-children-count": "warn",
1261
+ "react/no-children-for-each": "warn",
1262
+ "react/no-children-map": "warn",
1263
+ "react/no-children-only": "warn",
1264
+ "react/no-children-prop": "warn",
1265
+ "react/no-children-to-array": "warn",
1266
+ "react/no-clone-element": "warn",
1267
+ "react/no-comment-textnodes": "warn",
1268
+ "react/no-component-will-mount": "error",
1269
+ "react/no-component-will-receive-props": "error",
1270
+ "react/no-component-will-update": "error",
1271
+ "react/no-create-ref": "error",
1272
+ "react/no-direct-mutation-state": "error",
1273
+ "react/no-duplicate-key": "error",
1274
+ "react/no-implicit-key": "error",
1275
+ "react/no-missing-key": "error",
1276
+ "react/no-nested-components": "warn",
1277
+ "react/no-redundant-should-component-update": "error",
1278
+ "react/no-set-state-in-component-did-mount": "warn",
1279
+ "react/no-set-state-in-component-did-update": "warn",
1280
+ "react/no-set-state-in-component-will-update": "warn",
1281
+ "react/no-string-refs": "error",
1282
+ "react/no-unsafe-component-will-mount": "warn",
1283
+ "react/no-unsafe-component-will-receive-props": "warn",
1284
+ "react/no-unsafe-component-will-update": "warn",
1285
+ "react/no-unstable-context-value": "error",
1286
+ "react/no-unstable-default-props": "error",
1287
+ "react/no-unused-class-component-members": "warn",
1288
+ "react/no-unused-state": "warn",
1289
+ "react/no-useless-fragment": "warn",
1290
+ "react/prefer-destructuring-assignment": "warn",
1291
+ "react/prefer-shorthand-boolean": "warn",
1292
+ "react/prefer-shorthand-fragment": "warn",
1293
+ ...isTypeAware ? {
1294
+ "react/no-leaked-conditional-rendering": "warn"
1507
1295
  } : {},
1296
+ // overrides
1508
1297
  ...overrides
1509
1298
  }
1510
- },
1299
+ }
1300
+ ];
1301
+ }
1302
+
1303
+ // src/configs/regexp.ts
1304
+ import { configs } from "eslint-plugin-regexp";
1305
+ async function regexp(options = {}) {
1306
+ const config = configs["flat/recommended"];
1307
+ const rules = {
1308
+ ...config.rules
1309
+ };
1310
+ if (options.level === "warn") {
1311
+ for (const key in rules) {
1312
+ if (rules[key] === "error") {
1313
+ rules[key] = "warn";
1314
+ }
1315
+ }
1316
+ }
1317
+ return [
1511
1318
  {
1512
- name: "luxass/yaml/github-actions",
1513
- files: ["**/.github/workflows/*.{yml,yaml}"],
1319
+ ...config,
1320
+ name: "luxass/regexp/rules",
1514
1321
  rules: {
1515
- // GitHub Actions supports empty values to enable features
1516
- "yaml/no-empty-mapping-value": "off"
1322
+ ...rules,
1323
+ ...options.overrides
1517
1324
  }
1518
1325
  }
1519
1326
  ];
1520
1327
  }
1521
1328
 
1522
- // src/configs/test.ts
1523
- var _pluginTest;
1524
- async function test(options = {}) {
1525
- const {
1526
- editor = false,
1527
- files = GLOB_TESTS,
1528
- overrides = {}
1529
- } = options;
1530
- const [
1531
- pluginVitest
1532
- ] = await Promise.all([
1533
- interop(import("@vitest/eslint-plugin"))
1534
- ]);
1535
- _pluginTest = _pluginTest || pluginVitest;
1329
+ // src/configs/sort.ts
1330
+ function sortPackageJson() {
1536
1331
  return [
1537
1332
  {
1538
- name: "luxass/test/setup",
1539
- plugins: {
1540
- test: _pluginTest
1333
+ name: "luxass/sort/package-json",
1334
+ files: ["**/package.json"],
1335
+ rules: {
1336
+ "jsonc/sort-array-values": [
1337
+ "error",
1338
+ {
1339
+ order: { type: "asc" },
1340
+ pathPattern: "^files$"
1341
+ }
1342
+ ],
1343
+ "jsonc/sort-keys": [
1344
+ "error",
1345
+ {
1346
+ order: [
1347
+ "name",
1348
+ "displayName",
1349
+ "version",
1350
+ "description",
1351
+ "type",
1352
+ "private",
1353
+ "author",
1354
+ "contributors",
1355
+ "publisher",
1356
+ "packageManager",
1357
+ "license",
1358
+ "funding",
1359
+ "homepage",
1360
+ "repository",
1361
+ "bugs",
1362
+ "keywords",
1363
+ "categories",
1364
+ "sideEffects",
1365
+ "exports",
1366
+ "main",
1367
+ "module",
1368
+ "unpkg",
1369
+ "jsdelivr",
1370
+ "types",
1371
+ "typesVersions",
1372
+ "bin",
1373
+ "icon",
1374
+ "files",
1375
+ "engines",
1376
+ "activationEvents",
1377
+ "contributes",
1378
+ "scripts",
1379
+ "peerDependencies",
1380
+ "peerDependenciesMeta",
1381
+ "dependencies",
1382
+ "optionalDependencies",
1383
+ "devDependencies",
1384
+ "pnpm",
1385
+ "overrides",
1386
+ "resolutions",
1387
+ "husky",
1388
+ "simple-git-hooks",
1389
+ "lint-staged",
1390
+ "eslintConfig"
1391
+ ],
1392
+ pathPattern: "^$"
1393
+ },
1394
+ {
1395
+ order: { type: "asc" },
1396
+ pathPattern: "^(?:dev|peer|optional|bundled)?[Dd]ependencies$"
1397
+ },
1398
+ {
1399
+ order: { type: "asc" },
1400
+ pathPattern: "^resolutions$"
1401
+ },
1402
+ {
1403
+ order: { type: "asc" },
1404
+ pathPattern: "^pnpm.overrides$"
1405
+ },
1406
+ {
1407
+ order: ["types", "import", "require", "default"],
1408
+ pathPattern: "^exports.*$"
1409
+ },
1410
+ {
1411
+ order: [
1412
+ // client hooks only
1413
+ "pre-commit",
1414
+ "prepare-commit-msg",
1415
+ "commit-msg",
1416
+ "post-commit",
1417
+ "pre-rebase",
1418
+ "post-rewrite",
1419
+ "post-checkout",
1420
+ "post-merge",
1421
+ "pre-push",
1422
+ "pre-auto-gc"
1423
+ ],
1424
+ pathPattern: "^(?:gitHooks|husky|simple-git-hooks)$"
1425
+ }
1426
+ ]
1541
1427
  }
1542
- },
1428
+ }
1429
+ ];
1430
+ }
1431
+ function sortTsconfig() {
1432
+ return [
1543
1433
  {
1544
- name: "luxass/test/rules",
1545
- files,
1434
+ name: "luxass/sort/tsconfig",
1435
+ files: ["**/tsconfig.json", "**/tsconfig.*.json"],
1546
1436
  rules: {
1547
- "node/prefer-global/process": "off",
1548
- "test/consistent-test-it": [
1437
+ "jsonc/sort-keys": [
1549
1438
  "error",
1550
- { fn: "it", withinDescribe: "it" }
1551
- ],
1552
- "test/no-identical-title": "error",
1553
- "test/no-import-node-test": "error",
1554
- "test/no-focused-tests": editor ? "off" : ["error", { fixable: true }],
1555
- "test/prefer-hooks-in-order": "error",
1556
- "test/prefer-lowercase-title": "error",
1557
- "ts/explicit-function-return-type": "off",
1558
- ...overrides
1439
+ {
1440
+ order: [
1441
+ "extends",
1442
+ "compilerOptions",
1443
+ "references",
1444
+ "files",
1445
+ "include",
1446
+ "exclude"
1447
+ ],
1448
+ pathPattern: "^$"
1449
+ },
1450
+ {
1451
+ order: [
1452
+ /* Projects */
1453
+ "incremental",
1454
+ "composite",
1455
+ "tsBuildInfoFile",
1456
+ "disableSourceOfProjectReferenceRedirect",
1457
+ "disableSolutionSearching",
1458
+ "disableReferencedProjectLoad",
1459
+ /* Language and Environment */
1460
+ "target",
1461
+ "jsx",
1462
+ "jsxFactory",
1463
+ "jsxFragmentFactory",
1464
+ "jsxImportSource",
1465
+ "lib",
1466
+ "moduleDetection",
1467
+ "noLib",
1468
+ "reactNamespace",
1469
+ "useDefineForClassFields",
1470
+ "emitDecoratorMetadata",
1471
+ "experimentalDecorators",
1472
+ /* Modules */
1473
+ "baseUrl",
1474
+ "rootDir",
1475
+ "rootDirs",
1476
+ "customConditions",
1477
+ "module",
1478
+ "moduleResolution",
1479
+ "moduleSuffixes",
1480
+ "noResolve",
1481
+ "paths",
1482
+ "resolveJsonModule",
1483
+ "resolvePackageJsonExports",
1484
+ "resolvePackageJsonImports",
1485
+ "typeRoots",
1486
+ "types",
1487
+ "allowArbitraryExtensions",
1488
+ "allowImportingTsExtensions",
1489
+ "allowUmdGlobalAccess",
1490
+ /* JavaScript Support */
1491
+ "allowJs",
1492
+ "checkJs",
1493
+ "maxNodeModuleJsDepth",
1494
+ /* Type Checking */
1495
+ "strict",
1496
+ "strictBindCallApply",
1497
+ "strictFunctionTypes",
1498
+ "strictNullChecks",
1499
+ "strictPropertyInitialization",
1500
+ "allowUnreachableCode",
1501
+ "allowUnusedLabels",
1502
+ "alwaysStrict",
1503
+ "exactOptionalPropertyTypes",
1504
+ "noFallthroughCasesInSwitch",
1505
+ "noImplicitAny",
1506
+ "noImplicitOverride",
1507
+ "noImplicitReturns",
1508
+ "noImplicitThis",
1509
+ "noPropertyAccessFromIndexSignature",
1510
+ "noUncheckedIndexedAccess",
1511
+ "noUnusedLocals",
1512
+ "noUnusedParameters",
1513
+ "useUnknownInCatchVariables",
1514
+ /* Emit */
1515
+ "declaration",
1516
+ "declarationDir",
1517
+ "declarationMap",
1518
+ "downlevelIteration",
1519
+ "emitBOM",
1520
+ "emitDeclarationOnly",
1521
+ "importHelpers",
1522
+ "importsNotUsedAsValues",
1523
+ "inlineSourceMap",
1524
+ "inlineSources",
1525
+ "mapRoot",
1526
+ "newLine",
1527
+ "noEmit",
1528
+ "noEmitHelpers",
1529
+ "noEmitOnError",
1530
+ "outDir",
1531
+ "outFile",
1532
+ "preserveConstEnums",
1533
+ "preserveValueImports",
1534
+ "removeComments",
1535
+ "sourceMap",
1536
+ "sourceRoot",
1537
+ "stripInternal",
1538
+ /* Interop Constraints */
1539
+ "allowSyntheticDefaultImports",
1540
+ "esModuleInterop",
1541
+ "forceConsistentCasingInFileNames",
1542
+ "isolatedDeclarations",
1543
+ "isolatedModules",
1544
+ "preserveSymlinks",
1545
+ "verbatimModuleSyntax",
1546
+ /* Completeness */
1547
+ "skipDefaultLibCheck",
1548
+ "skipLibCheck"
1549
+ ],
1550
+ pathPattern: "^compilerOptions$"
1551
+ }
1552
+ ]
1559
1553
  }
1560
1554
  }
1561
1555
  ];
1562
1556
  }
1563
1557
 
1564
- // src/configs/unocss.ts
1565
- async function unocss(options = {}) {
1558
+ // src/configs/tailwindcss.ts
1559
+ async function tailwindcss(options = {}) {
1566
1560
  const {
1567
- attributify = true,
1568
1561
  overrides,
1569
- strict = false,
1570
1562
  configPath
1571
1563
  } = options;
1572
1564
  await ensure([
1573
- "@unocss/eslint-plugin"
1565
+ "eslint-plugin-tailwindcss"
1574
1566
  ]);
1575
1567
  const [
1576
- pluginUnoCSS
1568
+ pluginTailwindCSS
1577
1569
  ] = await Promise.all([
1578
- interop(import("@unocss/eslint-plugin"))
1570
+ interop(import("eslint-plugin-tailwindcss"))
1579
1571
  ]);
1580
1572
  return [
1581
1573
  {
1582
- name: "luxass/unocss",
1583
- plugins: {
1584
- unocss: pluginUnoCSS
1574
+ name: "luxass/tailwindcss",
1575
+ languageOptions: {
1576
+ parserOptions: {
1577
+ ecmaFeatures: {
1578
+ jsx: true
1579
+ }
1580
+ }
1585
1581
  },
1586
1582
  settings: {
1587
1583
  ...configPath != null ? {
1588
- unocss: {
1589
- configPath
1584
+ tailwindcss: {
1585
+ config: configPath
1590
1586
  }
1591
1587
  } : {}
1592
1588
  },
1589
+ plugins: {
1590
+ tailwindcss: pluginTailwindCSS
1591
+ },
1593
1592
  rules: {
1594
- "unocss/order": "warn",
1595
- ...attributify ? {
1596
- "unocss/order-attributify": "warn"
1597
- } : {},
1598
- ...strict ? {
1599
- "unocss/blocklist": "error"
1600
- } : {},
1593
+ // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/classnames-order.md
1594
+ "tailwindcss/classnames-order": "warn",
1595
+ // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/enforces-negative-arbitrary-values.md
1596
+ "tailwindcss/enforces-negative-arbitrary-values": "warn",
1597
+ // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/enforces-shorthand.md
1598
+ "tailwindcss/enforces-shorthand": "warn",
1599
+ // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/migration-from-tailwind-2.md
1600
+ "tailwindcss/migration-from-tailwind-2": "warn",
1601
+ // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/no-arbitrary-value.md
1602
+ "tailwindcss/no-arbitrary-value": "off",
1603
+ // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/no-contradicting-classname.md
1604
+ "tailwindcss/no-contradicting-classname": "error",
1605
+ // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/no-custom-classname.md
1606
+ "tailwindcss/no-custom-classname": "warn",
1601
1607
  ...overrides
1602
1608
  }
1603
1609
  }
1604
1610
  ];
1605
1611
  }
1606
1612
 
1607
- // src/configs/react.ts
1608
- import { isPackageExists as isPackageExists2 } from "local-pkg";
1609
- var ReactRefreshAllowConstantExportPackages = [
1610
- "vite"
1611
- ];
1612
- var RemixPackages = [
1613
- "@remix-run/node",
1614
- "@remix-run/react",
1615
- "@remix-run/serve",
1616
- "@remix-run/dev"
1617
- ];
1618
- async function react(options = {}) {
1613
+ // src/configs/test.ts
1614
+ var _pluginTest;
1615
+ async function test(options = {}) {
1619
1616
  const {
1620
- files = [GLOB_JS, GLOB_JSX, GLOB_TS, GLOB_TSX],
1617
+ isInEditor = false,
1618
+ files = GLOB_TESTS,
1621
1619
  overrides = {}
1622
1620
  } = options;
1623
- await ensure([
1624
- "@eslint-react/eslint-plugin",
1625
- "eslint-plugin-react-hooks",
1626
- "eslint-plugin-react-refresh"
1627
- ]);
1628
- const tsconfigPath = options?.tsconfigPath ? toArray(options.tsconfigPath) : void 0;
1629
- const isTypeAware = !!tsconfigPath;
1630
1621
  const [
1631
- pluginReact,
1632
- pluginReactHooks,
1633
- pluginReactRefresh,
1634
- parserTs
1622
+ pluginVitest
1635
1623
  ] = await Promise.all([
1636
- interop(import("@eslint-react/eslint-plugin")),
1637
- interop(import("eslint-plugin-react-hooks")),
1638
- interop(import("eslint-plugin-react-refresh")),
1639
- interop(import("@typescript-eslint/parser"))
1624
+ interop(import("@vitest/eslint-plugin"))
1640
1625
  ]);
1641
- const isAllowConstantExport = ReactRefreshAllowConstantExportPackages.some(
1642
- (i) => isPackageExists2(i)
1643
- );
1644
- const isUsingRemix = RemixPackages.some((i) => isPackageExists2(i));
1645
- const isUsingNext = isPackageExists2("next");
1646
- const plugins = pluginReact.configs.all.plugins;
1626
+ _pluginTest = _pluginTest || pluginVitest;
1647
1627
  return [
1648
1628
  {
1649
- name: "luxass/react/setup",
1629
+ name: "luxass/test/setup",
1650
1630
  plugins: {
1651
- "react": plugins["@eslint-react"],
1652
- "react-dom": plugins["@eslint-react/dom"],
1653
- "react-hooks": pluginReactHooks,
1654
- "react-hooks-extra": plugins["@eslint-react/hooks-extra"],
1655
- "react-naming-convention": plugins["@eslint-react/naming-convention"],
1656
- "react-refresh": pluginReactRefresh
1631
+ test: _pluginTest
1657
1632
  }
1658
- },
1659
- {
1660
- name: "luxass/react/rules",
1661
- files,
1662
- languageOptions: {
1663
- parser: parserTs,
1664
- parserOptions: {
1665
- ecmaFeatures: {
1666
- jsx: true
1667
- },
1668
- ...isTypeAware ? { project: tsconfigPath } : {}
1669
- },
1670
- sourceType: "module"
1671
- },
1672
- rules: {
1673
- // recommended rules from @eslint-react/dom
1674
- "react-dom/no-children-in-void-dom-elements": "warn",
1675
- "react-dom/no-dangerously-set-innerhtml": "warn",
1676
- "react-dom/no-dangerously-set-innerhtml-with-children": "error",
1677
- "react-dom/no-find-dom-node": "error",
1678
- "react-dom/no-missing-button-type": "warn",
1679
- "react-dom/no-missing-iframe-sandbox": "warn",
1680
- "react-dom/no-namespace": "error",
1681
- "react-dom/no-render-return-value": "error",
1682
- "react-dom/no-script-url": "warn",
1683
- "react-dom/no-unsafe-iframe-sandbox": "warn",
1684
- "react-dom/no-unsafe-target-blank": "warn",
1685
- // recommended rules react-hooks
1686
- "react-hooks/exhaustive-deps": "warn",
1687
- "react-hooks/rules-of-hooks": "error",
1688
- // react refresh
1689
- "react-refresh/only-export-components": [
1690
- "warn",
1691
- {
1692
- allowConstantExport: isAllowConstantExport,
1693
- allowExportNames: [
1694
- ...isUsingNext ? [
1695
- "config",
1696
- "runtime",
1697
- "generateStaticParams",
1698
- "metadata",
1699
- "generateMetadata",
1700
- "viewport",
1701
- "generateViewport"
1702
- ] : [],
1703
- ...isUsingRemix ? [
1704
- "meta",
1705
- "links",
1706
- "headers",
1707
- "loader",
1708
- "action"
1709
- ] : []
1710
- ]
1711
- }
1712
- ],
1713
- // recommended rules from @eslint-react
1714
- "react/ensure-forward-ref-using-ref": "warn",
1715
- "react/no-access-state-in-setstate": "error",
1716
- "react/no-array-index-key": "warn",
1717
- "react/no-children-count": "warn",
1718
- "react/no-children-for-each": "warn",
1719
- "react/no-children-map": "warn",
1720
- "react/no-children-only": "warn",
1721
- "react/no-children-prop": "warn",
1722
- "react/no-children-to-array": "warn",
1723
- "react/no-clone-element": "warn",
1724
- "react/no-comment-textnodes": "warn",
1725
- "react/no-component-will-mount": "error",
1726
- "react/no-component-will-receive-props": "error",
1727
- "react/no-component-will-update": "error",
1728
- "react/no-create-ref": "error",
1729
- "react/no-direct-mutation-state": "error",
1730
- "react/no-duplicate-key": "error",
1731
- "react/no-implicit-key": "error",
1732
- "react/no-missing-key": "error",
1733
- "react/no-nested-components": "warn",
1734
- "react/no-redundant-should-component-update": "error",
1735
- "react/no-set-state-in-component-did-mount": "warn",
1736
- "react/no-set-state-in-component-did-update": "warn",
1737
- "react/no-set-state-in-component-will-update": "warn",
1738
- "react/no-string-refs": "error",
1739
- "react/no-unsafe-component-will-mount": "warn",
1740
- "react/no-unsafe-component-will-receive-props": "warn",
1741
- "react/no-unsafe-component-will-update": "warn",
1742
- "react/no-unstable-context-value": "error",
1743
- "react/no-unstable-default-props": "error",
1744
- "react/no-unused-class-component-members": "warn",
1745
- "react/no-unused-state": "warn",
1746
- "react/no-useless-fragment": "warn",
1747
- "react/prefer-destructuring-assignment": "warn",
1748
- "react/prefer-shorthand-boolean": "warn",
1749
- "react/prefer-shorthand-fragment": "warn",
1750
- ...isTypeAware ? {
1751
- "react/no-leaked-conditional-rendering": "warn"
1752
- } : {},
1753
- // overrides
1633
+ },
1634
+ {
1635
+ name: "luxass/test/rules",
1636
+ files,
1637
+ rules: {
1638
+ "node/prefer-global/process": "off",
1639
+ "test/consistent-test-it": [
1640
+ "error",
1641
+ { fn: "it", withinDescribe: "it" }
1642
+ ],
1643
+ "test/no-identical-title": "error",
1644
+ "test/no-import-node-test": "error",
1645
+ "test/no-focused-tests": isInEditor ? "off" : ["error", { fixable: true }],
1646
+ "test/prefer-hooks-in-order": "error",
1647
+ "test/prefer-lowercase-title": "error",
1648
+ "ts/explicit-function-return-type": "off",
1754
1649
  ...overrides
1755
1650
  }
1756
1651
  }
1757
1652
  ];
1758
1653
  }
1759
1654
 
1760
- // src/configs/astro.ts
1761
- async function astro(options = {}) {
1655
+ // src/configs/toml.ts
1656
+ async function toml(options = {}) {
1762
1657
  const {
1763
- files = [GLOB_ASTRO],
1658
+ files = [GLOB_TOML],
1764
1659
  overrides = {},
1765
1660
  stylistic: stylistic2 = true
1766
1661
  } = options;
1767
- await ensure([
1768
- "eslint-plugin-astro",
1769
- "astro-eslint-parser"
1770
- ]);
1662
+ const {
1663
+ indent = 2
1664
+ } = typeof stylistic2 === "boolean" ? {} : stylistic2;
1771
1665
  const [
1772
- pluginAstro,
1773
- parserAstro,
1774
- parserTs
1666
+ pluginToml,
1667
+ parserToml
1775
1668
  ] = await Promise.all([
1776
- interop(import("eslint-plugin-astro")),
1777
- interop(import("astro-eslint-parser")),
1778
- interop(import("@typescript-eslint/parser"))
1669
+ interop(import("eslint-plugin-toml")),
1670
+ interop(import("toml-eslint-parser"))
1779
1671
  ]);
1780
1672
  return [
1781
1673
  {
1782
- name: "luxass/astro/setup",
1674
+ name: "luxass/toml/setup",
1783
1675
  plugins: {
1784
- astro: pluginAstro
1676
+ toml: pluginToml
1785
1677
  }
1786
1678
  },
1787
1679
  {
1788
- name: "luxass/astro/rules",
1680
+ name: "luxass/toml/rules",
1789
1681
  files,
1790
1682
  languageOptions: {
1791
- globals: pluginAstro.environments.astro.globals,
1792
- parser: parserAstro,
1793
- parserOptions: {
1794
- extraFileExtensions: [".astro"],
1795
- parser: parserTs
1796
- },
1797
- sourceType: "module"
1683
+ parser: parserToml
1798
1684
  },
1799
- processor: "astro/client-side-ts",
1800
1685
  rules: {
1801
- "astro/missing-client-only-directive-value": "error",
1802
- "astro/no-conflict-set-directives": "error",
1803
- "astro/no-deprecated-astro-canonicalurl": "error",
1804
- "astro/no-deprecated-astro-fetchcontent": "error",
1805
- "astro/no-deprecated-astro-resolve": "error",
1806
- "astro/no-deprecated-getentrybyslug": "error",
1807
- "astro/no-set-html-directive": "off",
1808
- "astro/no-unused-define-vars-in-style": "error",
1809
- "astro/semi": "error",
1810
- "astro/valid-compile": "error",
1686
+ "style/spaced-comment": "off",
1687
+ "toml/comma-style": "error",
1688
+ "toml/keys-order": "error",
1689
+ "toml/no-space-dots": "error",
1690
+ "toml/no-unreadable-number-separator": "error",
1691
+ "toml/precision-of-fractional-seconds": "error",
1692
+ "toml/precision-of-integer": "error",
1693
+ "toml/tables-order": "error",
1694
+ "toml/vue-custom-block/no-parsing-error": "error",
1811
1695
  ...stylistic2 ? {
1812
- "style/indent": "off",
1813
- "style/jsx-closing-tag-location": "off",
1814
- "style/jsx-indent": "off",
1815
- "style/jsx-one-expression-per-line": "off",
1816
- "style/no-multiple-empty-lines": "off"
1696
+ "toml/array-bracket-newline": "error",
1697
+ "toml/array-bracket-spacing": "error",
1698
+ "toml/array-element-newline": "error",
1699
+ "toml/indent": ["error", indent === "tab" ? 2 : indent],
1700
+ "toml/inline-table-curly-spacing": "error",
1701
+ "toml/key-spacing": "error",
1702
+ "toml/padding-line-between-pairs": "error",
1703
+ "toml/padding-line-between-tables": "error",
1704
+ "toml/quoted-keys": "error",
1705
+ "toml/spaced-comment": "error",
1706
+ "toml/table-bracket-spacing": "error"
1707
+ } : {},
1708
+ ...overrides
1709
+ }
1710
+ }
1711
+ ];
1712
+ }
1713
+
1714
+ // src/configs/typescript.ts
1715
+ import process2 from "node:process";
1716
+ import pluginAntfu4 from "eslint-plugin-antfu";
1717
+ async function typescript(options = {}) {
1718
+ const {
1719
+ exts = [],
1720
+ overrides = {},
1721
+ parserOptions = {},
1722
+ type = "app"
1723
+ } = options ?? {};
1724
+ const files = options.files ?? [
1725
+ GLOB_TS,
1726
+ GLOB_TSX,
1727
+ ...exts.map((ext) => `**/*.${ext}`)
1728
+ ];
1729
+ const filesTypeAware = options.filesTypeAware ?? [GLOB_TS, GLOB_TSX];
1730
+ const ignoresTypeAware = options.ignoresTypeAware ?? [
1731
+ `${GLOB_MARKDOWN}/**`,
1732
+ GLOB_ASTRO_TS
1733
+ ];
1734
+ const tsconfigPath = options?.tsconfigPath ? options.tsconfigPath : void 0;
1735
+ const isTypeAware = !!tsconfigPath;
1736
+ const typeAwareRules = {
1737
+ "dot-notation": "off",
1738
+ "no-implied-eval": "off",
1739
+ "ts/await-thenable": "error",
1740
+ "ts/dot-notation": ["error", { allowKeywords: true }],
1741
+ "ts/no-floating-promises": "error",
1742
+ "ts/no-for-in-array": "error",
1743
+ "ts/no-implied-eval": "error",
1744
+ "ts/no-misused-promises": "error",
1745
+ "ts/no-unnecessary-type-assertion": "error",
1746
+ "ts/no-unsafe-argument": "error",
1747
+ "ts/no-unsafe-assignment": "error",
1748
+ "ts/no-unsafe-call": "error",
1749
+ "ts/no-unsafe-member-access": "error",
1750
+ "ts/no-unsafe-return": "error",
1751
+ "ts/promise-function-async": "error",
1752
+ "ts/restrict-plus-operands": "error",
1753
+ "ts/restrict-template-expressions": "error",
1754
+ "ts/return-await": ["error", "in-try-catch"],
1755
+ "ts/strict-boolean-expressions": ["error", { allowNullableBoolean: true, allowNullableObject: true }],
1756
+ "ts/switch-exhaustiveness-check": "error",
1757
+ "ts/unbound-method": "error"
1758
+ };
1759
+ const [
1760
+ pluginTs,
1761
+ parserTs
1762
+ ] = await Promise.all([
1763
+ interop(import("@typescript-eslint/eslint-plugin")),
1764
+ interop(import("@typescript-eslint/parser"))
1765
+ ]);
1766
+ function makeParser(typeAware, files2, ignores2) {
1767
+ return {
1768
+ files: files2,
1769
+ ...ignores2 ? { ignores: ignores2 } : {},
1770
+ name: `luxass/typescript/${typeAware ? "type-aware-parser" : "parser"}`,
1771
+ languageOptions: {
1772
+ parser: parserTs,
1773
+ parserOptions: {
1774
+ extraFileExtensions: exts.map((ext) => `.${ext}`),
1775
+ sourceType: "module",
1776
+ ...typeAware ? {
1777
+ projectService: {
1778
+ allowDefaultProject: ["./*.js"],
1779
+ defaultProject: tsconfigPath
1780
+ },
1781
+ tsconfigRootDir: process2.cwd()
1782
+ } : {},
1783
+ ...parserOptions
1784
+ }
1785
+ }
1786
+ };
1787
+ }
1788
+ return [
1789
+ {
1790
+ // Install the plugins without globs, so they can be configured separately.
1791
+ name: "luxass/typescript/setup",
1792
+ plugins: {
1793
+ antfu: pluginAntfu4,
1794
+ ts: pluginTs
1795
+ }
1796
+ },
1797
+ ...isTypeAware ? [
1798
+ makeParser(true, filesTypeAware, ignoresTypeAware),
1799
+ makeParser(false, files, filesTypeAware)
1800
+ ] : [makeParser(false, files)],
1801
+ {
1802
+ name: "luxass/typescript/rules",
1803
+ files,
1804
+ rules: {
1805
+ ...renameRules(
1806
+ pluginTs.configs["eslint-recommended"].overrides[0].rules,
1807
+ {
1808
+ "@typescript-eslint": "ts"
1809
+ }
1810
+ ),
1811
+ ...renameRules(
1812
+ pluginTs.configs.strict.rules,
1813
+ {
1814
+ "@typescript-eslint": "ts"
1815
+ }
1816
+ ),
1817
+ "no-dupe-class-members": "off",
1818
+ "no-invalid-this": "off",
1819
+ "no-loss-of-precision": "error",
1820
+ "no-redeclare": "off",
1821
+ "no-use-before-define": "off",
1822
+ "no-useless-constructor": "off",
1823
+ "ts/ban-ts-comment": [
1824
+ "error",
1825
+ {
1826
+ "ts-ignore": "allow-with-description",
1827
+ "ts-expect-error": "allow-with-description"
1828
+ }
1829
+ ],
1830
+ "ts/consistent-type-definitions": ["error", "interface"],
1831
+ "ts/consistent-type-imports": [
1832
+ "error",
1833
+ { disallowTypeAnnotations: false, prefer: "type-imports" }
1834
+ ],
1835
+ "ts/method-signature-style": ["error", "property"],
1836
+ // https://www.totaltypescript.com/method-shorthand-syntax-considered-harmful
1837
+ "ts/no-dupe-class-members": "error",
1838
+ "ts/no-dynamic-delete": "off",
1839
+ "ts/no-empty-object-type": "error",
1840
+ "ts/no-explicit-any": "off",
1841
+ "ts/no-extraneous-class": "off",
1842
+ "ts/no-import-type-side-effects": "error",
1843
+ "ts/no-invalid-this": "error",
1844
+ "ts/no-invalid-void-type": "off",
1845
+ "ts/no-non-null-assertion": "off",
1846
+ "ts/no-redeclare": "error",
1847
+ "ts/no-require-imports": "error",
1848
+ "ts/no-unused-vars": "off",
1849
+ "ts/no-use-before-define": [
1850
+ "error",
1851
+ { classes: false, functions: false, variables: true }
1852
+ ],
1853
+ "ts/no-useless-constructor": "off",
1854
+ "ts/no-wrapper-object-types": "error",
1855
+ "ts/triple-slash-reference": "off",
1856
+ "ts/unified-signatures": "off",
1857
+ ...type === "lib" ? {
1858
+ "ts/explicit-function-return-type": ["error", {
1859
+ allowExpressions: true,
1860
+ allowHigherOrderFunctions: true,
1861
+ allowIIFEs: true
1862
+ }]
1817
1863
  } : {},
1818
1864
  ...overrides
1819
1865
  }
1866
+ },
1867
+ ...isTypeAware ? [{
1868
+ files: filesTypeAware,
1869
+ ignores: ignoresTypeAware,
1870
+ name: "luxass/typescript/rules-type-aware",
1871
+ rules: typeAwareRules
1872
+ }] : []
1873
+ ];
1874
+ }
1875
+
1876
+ // src/configs/unicorn.ts
1877
+ import pluginUnicorn from "eslint-plugin-unicorn";
1878
+ async function unicorn(options = {}) {
1879
+ if (options.allRecommended && pluginUnicorn.configs == null) {
1880
+ throw new Error("The `allRecommended` option requires `eslint-plugin-unicorn` to be installed.");
1881
+ }
1882
+ return [
1883
+ {
1884
+ name: "luxass/unicorn/rules",
1885
+ plugins: {
1886
+ unicorn: pluginUnicorn
1887
+ },
1888
+ rules: {
1889
+ ...options.allRecommended ? pluginUnicorn.configs["flat/recommended"].rules : {
1890
+ // Pass error message when throwing errors
1891
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/error-message.md
1892
+ "unicorn/error-message": "error",
1893
+ // Uppercase regex escapes
1894
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/escape-case.md
1895
+ "unicorn/escape-case": "error",
1896
+ // Array.isArray instead of instanceof
1897
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-instanceof-array.md
1898
+ "unicorn/no-instanceof-array": "error",
1899
+ // Ban `new Array` as `Array` constructor's params are ambiguous
1900
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-new-array.md
1901
+ "unicorn/no-new-array": "error",
1902
+ // Prevent deprecated `new Buffer()`
1903
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-new-buffer.md
1904
+ "unicorn/no-new-buffer": "error",
1905
+ // Lowercase number formatting for octal, hex, binary (0x1'error' instead of 0X1'error')
1906
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/number-literal-case.md
1907
+ "unicorn/number-literal-case": "error",
1908
+ // textContent instead of innerText
1909
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-text-content.md
1910
+ "unicorn/prefer-dom-node-text-content": "error",
1911
+ // includes over indexOf when checking for existence
1912
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-includes.md
1913
+ "unicorn/prefer-includes": "error",
1914
+ // Prefer using the node: protocol
1915
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-node-protocol.md
1916
+ "unicorn/prefer-node-protocol": "error",
1917
+ // Prefer using number properties like `Number.isNaN` rather than `isNaN`
1918
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-number-properties.md
1919
+ "unicorn/prefer-number-properties": "error",
1920
+ // String methods startsWith/endsWith instead of more complicated stuff
1921
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-starts-ends-with.md
1922
+ "unicorn/prefer-string-starts-ends-with": "error",
1923
+ // Enforce throwing type error when throwing error while checking typeof
1924
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-type-error.md
1925
+ "unicorn/prefer-type-error": "error",
1926
+ // Use new when throwing error
1927
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/throw-new-error.md
1928
+ "unicorn/throw-new-error": "error"
1929
+ }
1930
+ }
1820
1931
  }
1821
1932
  ];
1822
1933
  }
1823
1934
 
1824
- // src/configs/tailwindcss.ts
1825
- async function tailwindcss(options = {}) {
1935
+ // src/configs/unocss.ts
1936
+ async function unocss(options = {}) {
1826
1937
  const {
1938
+ attributify = true,
1827
1939
  overrides,
1940
+ strict = false,
1828
1941
  configPath
1829
1942
  } = options;
1830
1943
  await ensure([
1831
- "eslint-plugin-tailwindcss"
1944
+ "@unocss/eslint-plugin"
1832
1945
  ]);
1833
1946
  const [
1834
- pluginTailwindCSS
1947
+ pluginUnoCSS
1835
1948
  ] = await Promise.all([
1836
- interop(import("eslint-plugin-tailwindcss"))
1949
+ interop(import("@unocss/eslint-plugin"))
1837
1950
  ]);
1838
1951
  return [
1839
1952
  {
1840
- name: "luxass/tailwindcss",
1841
- languageOptions: {
1842
- parserOptions: {
1843
- ecmaFeatures: {
1844
- jsx: true
1845
- }
1846
- }
1953
+ name: "luxass/unocss",
1954
+ plugins: {
1955
+ unocss: pluginUnoCSS
1847
1956
  },
1848
1957
  settings: {
1849
1958
  ...configPath != null ? {
1850
- tailwindcss: {
1851
- config: configPath
1959
+ unocss: {
1960
+ configPath
1852
1961
  }
1853
1962
  } : {}
1854
1963
  },
1855
- plugins: {
1856
- tailwindcss: pluginTailwindCSS
1857
- },
1858
1964
  rules: {
1859
- // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/classnames-order.md
1860
- "tailwindcss/classnames-order": "warn",
1861
- // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/enforces-negative-arbitrary-values.md
1862
- "tailwindcss/enforces-negative-arbitrary-values": "warn",
1863
- // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/enforces-shorthand.md
1864
- "tailwindcss/enforces-shorthand": "warn",
1865
- // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/migration-from-tailwind-2.md
1866
- "tailwindcss/migration-from-tailwind-2": "warn",
1867
- // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/no-arbitrary-value.md
1868
- "tailwindcss/no-arbitrary-value": "off",
1869
- // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/no-contradicting-classname.md
1870
- "tailwindcss/no-contradicting-classname": "error",
1871
- // https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/docs/rules/no-custom-classname.md
1872
- "tailwindcss/no-custom-classname": "warn",
1965
+ "unocss/order": "warn",
1966
+ ...attributify ? {
1967
+ "unocss/order-attributify": "warn"
1968
+ } : {},
1969
+ ...strict ? {
1970
+ "unocss/blocklist": "error"
1971
+ } : {},
1873
1972
  ...overrides
1874
1973
  }
1875
1974
  }
1876
1975
  ];
1877
1976
  }
1878
1977
 
1879
- // src/configs/formatters.ts
1880
- import { isPackageExists as isPackageExists3 } from "local-pkg";
1881
- async function formatters(options = {}, stylistic2 = {}) {
1882
- if (options === true) {
1883
- options = {
1884
- astro: isPackageExists3("astro"),
1885
- css: true,
1886
- graphql: true,
1887
- html: true,
1888
- markdown: true
1889
- };
1890
- }
1891
- await ensure([
1892
- "eslint-plugin-format",
1893
- options.astro ? "prettier-plugin-astro" : void 0
1978
+ // src/configs/vue.ts
1979
+ import { mergeProcessors as mergeProcessors2 } from "eslint-merge-processors";
1980
+ async function vue(options = {}) {
1981
+ const {
1982
+ files = [GLOB_VUE],
1983
+ overrides = {},
1984
+ stylistic: stylistic2 = true
1985
+ } = options;
1986
+ const [
1987
+ pluginVue,
1988
+ parserVue,
1989
+ processorVueBlocks
1990
+ ] = await Promise.all([
1991
+ interop(import("eslint-plugin-vue")),
1992
+ interop(import("vue-eslint-parser")),
1993
+ interop(import("eslint-processor-vue-blocks"))
1894
1994
  ]);
1995
+ const sfcBlocks = options.sfcBlocks === true ? {} : options.sfcBlocks ?? {};
1895
1996
  const {
1896
- indent,
1897
- quotes,
1898
- semi
1899
- } = {
1900
- ...StylisticConfigDefaults,
1901
- ...stylistic2
1902
- };
1903
- const prettierOptions = Object.assign(
1904
- {
1905
- endOfLine: "auto",
1906
- semi,
1907
- singleQuote: quotes === "single",
1908
- tabWidth: typeof indent === "number" ? indent : 2,
1909
- trailingComma: "all",
1910
- useTabs: indent === "tab",
1911
- printWidth: 120
1912
- },
1913
- options.prettierOptions || {}
1914
- );
1915
- const dprintOptions = Object.assign(
1916
- {
1917
- indentWidth: typeof indent === "number" ? indent : 2,
1918
- quoteStyle: quotes === "single" ? "preferSingle" : "preferDouble",
1919
- useTabs: indent === "tab"
1920
- },
1921
- options.dprintOptions || {}
1922
- );
1923
- const pluginFormat = await interop(import("eslint-plugin-format"));
1924
- const configs2 = [
1997
+ indent = 2
1998
+ } = typeof stylistic2 === "boolean" ? {} : stylistic2;
1999
+ return [
1925
2000
  {
1926
- name: "luxass/formatter/setup",
1927
- plugins: {
1928
- format: pluginFormat
1929
- }
1930
- }
1931
- ];
1932
- if (options.css) {
1933
- configs2.push(
1934
- {
1935
- name: "luxass/formatter/css",
1936
- files: [GLOB_CSS, GLOB_POSTCSS],
1937
- languageOptions: {
1938
- parser: parserPlain
1939
- },
1940
- rules: {
1941
- "format/prettier": [
1942
- "error",
1943
- {
1944
- ...prettierOptions,
1945
- parser: "css"
1946
- }
1947
- ]
1948
- }
1949
- },
1950
- {
1951
- name: "luxass/formatter/scss",
1952
- files: [GLOB_SCSS],
1953
- languageOptions: {
1954
- parser: parserPlain
1955
- },
1956
- rules: {
1957
- "format/prettier": [
1958
- "error",
1959
- {
1960
- ...prettierOptions,
1961
- parser: "scss"
1962
- }
1963
- ]
1964
- }
1965
- },
1966
- {
1967
- name: "luxass/formatter/less",
1968
- files: [GLOB_LESS],
1969
- languageOptions: {
1970
- parser: parserPlain
1971
- },
1972
- rules: {
1973
- "format/prettier": [
1974
- "error",
1975
- {
1976
- ...prettierOptions,
1977
- parser: "less"
1978
- }
1979
- ]
1980
- }
1981
- }
1982
- );
1983
- }
1984
- if (options.html) {
1985
- configs2.push({
1986
- name: "luxass/formatter/html",
1987
- files: [GLOB_HTML],
1988
- languageOptions: {
1989
- parser: parserPlain
1990
- },
1991
- rules: {
1992
- "format/prettier": [
1993
- "error",
1994
- {
1995
- ...prettierOptions,
1996
- parser: "html"
1997
- }
1998
- ]
1999
- }
2000
- });
2001
- }
2002
- if (options.markdown) {
2003
- const formater = options.markdown === true ? "prettier" : options.markdown;
2004
- configs2.push({
2005
- name: "luxass/formatter/markdown",
2006
- files: [GLOB_MARKDOWN],
2001
+ name: "luxass/vue/setup",
2002
+ // This allows Vue plugin to work with auto imports
2003
+ // https://github.com/vuejs/eslint-plugin-vue/pull/2422
2007
2004
  languageOptions: {
2008
- parser: parserPlain
2005
+ globals: {
2006
+ computed: "readonly",
2007
+ defineEmits: "readonly",
2008
+ defineExpose: "readonly",
2009
+ defineProps: "readonly",
2010
+ onMounted: "readonly",
2011
+ onUnmounted: "readonly",
2012
+ reactive: "readonly",
2013
+ ref: "readonly",
2014
+ shallowReactive: "readonly",
2015
+ shallowRef: "readonly",
2016
+ toRef: "readonly",
2017
+ toRefs: "readonly",
2018
+ watch: "readonly",
2019
+ watchEffect: "readonly"
2020
+ }
2009
2021
  },
2010
- rules: {
2011
- [`format/${formater}`]: [
2012
- "error",
2013
- formater === "prettier" ? {
2014
- ...prettierOptions,
2015
- embeddedLanguageFormatting: "off",
2016
- parser: "markdown"
2017
- } : {
2018
- ...dprintOptions,
2019
- language: "markdown"
2020
- }
2021
- ]
2022
+ plugins: {
2023
+ vue: pluginVue
2022
2024
  }
2023
- });
2024
- }
2025
- if (options.astro) {
2026
- configs2.push({
2027
- name: "luxass/formatter/astro",
2028
- files: [GLOB_ASTRO],
2025
+ },
2026
+ {
2027
+ name: "luxass/vue/rules",
2028
+ files,
2029
2029
  languageOptions: {
2030
- parser: parserPlain
2030
+ parser: parserVue,
2031
+ parserOptions: {
2032
+ ecmaFeatures: {
2033
+ jsx: true
2034
+ },
2035
+ extraFileExtensions: [".vue"],
2036
+ parser: options.typescript ? await interop(import("@typescript-eslint/parser")) : null,
2037
+ sourceType: "module"
2038
+ }
2031
2039
  },
2040
+ processor: sfcBlocks === false ? pluginVue.processors[".vue"] : mergeProcessors2([
2041
+ pluginVue.processors[".vue"],
2042
+ processorVueBlocks({
2043
+ ...sfcBlocks,
2044
+ blocks: {
2045
+ styles: true,
2046
+ ...sfcBlocks.blocks
2047
+ }
2048
+ })
2049
+ ]),
2032
2050
  rules: {
2033
- "format/prettier": [
2051
+ ...pluginVue.configs.base.rules,
2052
+ ...pluginVue.configs["vue3-essential"].rules,
2053
+ ...pluginVue.configs["vue3-strongly-recommended"].rules,
2054
+ ...pluginVue.configs["vue3-recommended"].rules,
2055
+ "node/prefer-global/process": "off",
2056
+ "vue/block-order": [
2034
2057
  "error",
2035
2058
  {
2036
- ...prettierOptions,
2037
- parser: "astro",
2038
- plugins: [
2039
- "prettier-plugin-astro"
2059
+ order: ["script", "template", "style"]
2060
+ }
2061
+ ],
2062
+ "vue/component-name-in-template-casing": ["error", "PascalCase"],
2063
+ "vue/component-options-name-casing": ["error", "PascalCase"],
2064
+ // this is deprecated
2065
+ "vue/component-tags-order": "off",
2066
+ "vue/custom-event-name-casing": ["error", "camelCase"],
2067
+ "vue/define-macros-order": [
2068
+ "error",
2069
+ {
2070
+ order: [
2071
+ "defineOptions",
2072
+ "defineProps",
2073
+ "defineEmits",
2074
+ "defineSlots"
2040
2075
  ]
2041
2076
  }
2042
- ]
2043
- }
2044
- });
2045
- }
2046
- if (options.graphql) {
2047
- configs2.push({
2048
- name: "luxass/formatter/graphql",
2049
- files: [GLOB_GRAPHQL],
2050
- languageOptions: {
2051
- parser: parserPlain
2052
- },
2053
- rules: {
2054
- "format/prettier": [
2077
+ ],
2078
+ "vue/dot-location": ["error", "property"],
2079
+ "vue/dot-notation": ["error", { allowKeywords: true }],
2080
+ "vue/eqeqeq": ["error", "smart"],
2081
+ "vue/html-indent": ["error", indent],
2082
+ "vue/html-quotes": ["error", "double"],
2083
+ "vue/max-attributes-per-line": "off",
2084
+ "vue/multi-word-component-names": "off",
2085
+ "vue/no-dupe-keys": "off",
2086
+ "vue/no-empty-pattern": "error",
2087
+ "vue/no-irregular-whitespace": "error",
2088
+ "vue/no-loss-of-precision": "error",
2089
+ "vue/no-restricted-syntax": [
2090
+ "error",
2091
+ "DebuggerStatement",
2092
+ "LabeledStatement",
2093
+ "WithStatement"
2094
+ ],
2095
+ "vue/no-restricted-v-bind": ["error", "/^v-/"],
2096
+ "vue/no-setup-props-reactivity-loss": "off",
2097
+ "vue/no-sparse-arrays": "error",
2098
+ "vue/no-unused-refs": "error",
2099
+ "vue/no-useless-v-bind": "error",
2100
+ "vue/no-v-html": "off",
2101
+ "vue/object-shorthand": [
2055
2102
  "error",
2103
+ "always",
2056
2104
  {
2057
- ...prettierOptions,
2058
- parser: "graphql"
2105
+ avoidQuotes: true,
2106
+ ignoreConstructors: false
2059
2107
  }
2060
- ]
2108
+ ],
2109
+ "vue/prefer-separate-static-class": "error",
2110
+ "vue/prefer-template": "error",
2111
+ "vue/prop-name-casing": ["error", "camelCase"],
2112
+ "vue/require-default-prop": "off",
2113
+ "vue/require-prop-types": "off",
2114
+ "vue/space-infix-ops": "error",
2115
+ "vue/space-unary-ops": ["error", { nonwords: false, words: true }],
2116
+ ...stylistic2 ? {
2117
+ "vue/array-bracket-spacing": ["error", "never"],
2118
+ "vue/arrow-spacing": ["error", { after: true, before: true }],
2119
+ "vue/block-spacing": ["error", "always"],
2120
+ "vue/block-tag-newline": [
2121
+ "error",
2122
+ {
2123
+ multiline: "always",
2124
+ singleline: "always"
2125
+ }
2126
+ ],
2127
+ "vue/brace-style": [
2128
+ "error",
2129
+ "stroustrup",
2130
+ { allowSingleLine: true }
2131
+ ],
2132
+ "vue/comma-dangle": ["error", "always-multiline"],
2133
+ "vue/comma-spacing": ["error", { after: true, before: false }],
2134
+ "vue/comma-style": ["error", "last"],
2135
+ "vue/html-comment-content-spacing": [
2136
+ "error",
2137
+ "always",
2138
+ {
2139
+ exceptions: ["-"]
2140
+ }
2141
+ ],
2142
+ "vue/key-spacing": [
2143
+ "error",
2144
+ { afterColon: true, beforeColon: false }
2145
+ ],
2146
+ "vue/keyword-spacing": ["error", { after: true, before: true }],
2147
+ "vue/object-curly-newline": "off",
2148
+ "vue/object-curly-spacing": ["error", "always"],
2149
+ "vue/object-property-newline": [
2150
+ "error",
2151
+ { allowMultiplePropertiesPerLine: true }
2152
+ ],
2153
+ "vue/operator-linebreak": ["error", "before"],
2154
+ "vue/padding-line-between-blocks": ["error", "always"],
2155
+ "vue/quote-props": ["error", "consistent-as-needed"],
2156
+ "vue/space-in-parens": ["error", "never"],
2157
+ "vue/template-curly-spacing": "error"
2158
+ } : {},
2159
+ ...overrides
2061
2160
  }
2062
- });
2063
- }
2064
- return configs2;
2161
+ }
2162
+ ];
2065
2163
  }
2066
2164
 
2067
- // src/configs/toml.ts
2068
- async function toml(options = {}) {
2165
+ // src/configs/yaml.ts
2166
+ async function yaml(options = {}) {
2069
2167
  const {
2070
- files = [GLOB_TOML],
2168
+ files = [GLOB_YAML],
2071
2169
  overrides = {},
2072
2170
  stylistic: stylistic2 = true
2073
2171
  } = options;
2074
- const {
2075
- indent = 2
2076
- } = typeof stylistic2 === "boolean" ? {} : stylistic2;
2077
2172
  const [
2078
- pluginToml,
2079
- parserToml
2173
+ pluginYaml,
2174
+ parserYaml
2080
2175
  ] = await Promise.all([
2081
- interop(import("eslint-plugin-toml")),
2082
- interop(import("toml-eslint-parser"))
2176
+ interop(import("eslint-plugin-yml")),
2177
+ interop(import("yaml-eslint-parser"))
2083
2178
  ]);
2179
+ const {
2180
+ indent = 2,
2181
+ quotes = "double"
2182
+ } = typeof stylistic2 === "boolean" ? {} : stylistic2;
2084
2183
  return [
2085
2184
  {
2086
- name: "luxass/toml/setup",
2185
+ name: "luxass/yaml/setup",
2087
2186
  plugins: {
2088
- toml: pluginToml
2187
+ yaml: pluginYaml
2089
2188
  }
2090
2189
  },
2091
2190
  {
2092
- name: "luxass/toml/rules",
2191
+ name: "luxass/yaml/rules",
2093
2192
  files,
2094
2193
  languageOptions: {
2095
- parser: parserToml
2194
+ parser: parserYaml
2096
2195
  },
2097
2196
  rules: {
2098
2197
  "style/spaced-comment": "off",
2099
- "toml/comma-style": "error",
2100
- "toml/keys-order": "error",
2101
- "toml/no-space-dots": "error",
2102
- "toml/no-unreadable-number-separator": "error",
2103
- "toml/precision-of-fractional-seconds": "error",
2104
- "toml/precision-of-integer": "error",
2105
- "toml/tables-order": "error",
2106
- "toml/vue-custom-block/no-parsing-error": "error",
2198
+ "yaml/block-mapping": "error",
2199
+ "yaml/block-sequence": "error",
2200
+ "yaml/no-empty-key": "error",
2201
+ "yaml/no-empty-mapping-value": "error",
2202
+ "yaml/no-empty-sequence-entry": "error",
2203
+ "yaml/no-irregular-whitespace": "error",
2204
+ "yaml/plain-scalar": "error",
2205
+ "yaml/vue-custom-block/no-parsing-error": "error",
2107
2206
  ...stylistic2 ? {
2108
- "toml/array-bracket-newline": "error",
2109
- "toml/array-bracket-spacing": "error",
2110
- "toml/array-element-newline": "error",
2111
- "toml/indent": ["error", indent === "tab" ? 2 : indent],
2112
- "toml/inline-table-curly-spacing": "error",
2113
- "toml/key-spacing": "error",
2114
- "toml/padding-line-between-pairs": "error",
2115
- "toml/padding-line-between-tables": "error",
2116
- "toml/quoted-keys": "error",
2117
- "toml/spaced-comment": "error",
2118
- "toml/table-bracket-spacing": "error"
2207
+ "yaml/block-mapping-question-indicator-newline": "error",
2208
+ "yaml/block-sequence-hyphen-indicator-newline": "error",
2209
+ "yaml/flow-mapping-curly-newline": "error",
2210
+ "yaml/flow-mapping-curly-spacing": "error",
2211
+ "yaml/flow-sequence-bracket-newline": "error",
2212
+ "yaml/flow-sequence-bracket-spacing": "error",
2213
+ "yaml/indent": ["error", indent === "tab" ? 2 : indent],
2214
+ "yaml/key-spacing": "error",
2215
+ "yaml/no-tab-indent": "error",
2216
+ "yaml/quotes": [
2217
+ "error",
2218
+ { avoidEscape: false, prefer: quotes }
2219
+ ],
2220
+ "yaml/spaced-comment": "error"
2119
2221
  } : {},
2120
2222
  ...overrides
2121
2223
  }
@@ -2123,49 +2225,6 @@ async function toml(options = {}) {
2123
2225
  ];
2124
2226
  }
2125
2227
 
2126
- // src/configs/regexp.ts
2127
- import { configs } from "eslint-plugin-regexp";
2128
- async function regexp(options = {}) {
2129
- const config = configs["flat/recommended"];
2130
- const rules = {
2131
- ...config.rules
2132
- };
2133
- if (options.level === "warn") {
2134
- for (const key in rules) {
2135
- if (rules[key] === "error") {
2136
- rules[key] = "warn";
2137
- }
2138
- }
2139
- }
2140
- return [
2141
- {
2142
- ...config,
2143
- name: "luxass/regexp/rules",
2144
- rules: {
2145
- ...rules,
2146
- ...options.overrides
2147
- }
2148
- }
2149
- ];
2150
- }
2151
-
2152
- // src/configs/jsx.ts
2153
- async function jsx() {
2154
- return [
2155
- {
2156
- name: "luxass/jsx/setup",
2157
- files: [GLOB_JSX, GLOB_TSX],
2158
- languageOptions: {
2159
- parserOptions: {
2160
- ecmaFeatures: {
2161
- jsx: true
2162
- }
2163
- }
2164
- }
2165
- }
2166
- ];
2167
- }
2168
-
2169
2228
  // src/factory.ts
2170
2229
  var FLAT_CONFIG_PROPS = [
2171
2230
  "name",
@@ -2202,16 +2261,23 @@ function luxass(options = {}, ...userConfigs) {
2202
2261
  autoRenamePlugins = true,
2203
2262
  exts = [],
2204
2263
  gitignore: enableGitignore = true,
2205
- editor = !!((process3.env.VSCODE_PID || process3.env.JETBRAINS_IDE || process3.env.VIM) && !process3.env.CI),
2206
2264
  jsx: enableJsx = true,
2207
2265
  react: enableReact = false,
2208
2266
  regexp: enableRegexp = true,
2209
- typescript: enableTypeScript = isPackageExists4("typescript"),
2267
+ typescript: enableTypeScript = isPackageExists3("typescript"),
2268
+ unicorn: enableUnicorn = true,
2210
2269
  unocss: enableUnoCSS = false,
2211
2270
  tailwindcss: enableTailwindCSS = false,
2212
- vue: enableVue = VuePackages.some((i) => isPackageExists4(i)),
2271
+ vue: enableVue = VuePackages.some((i) => isPackageExists3(i)),
2213
2272
  type: projectType = "app"
2214
2273
  } = options;
2274
+ let isInEditor = options.isInEditor;
2275
+ if (isInEditor == null) {
2276
+ isInEditor = isInEditorEnv();
2277
+ if (isInEditor) {
2278
+ console.log("[@luxass/eslint-config] Detected running in editor, some rules are disabled.");
2279
+ }
2280
+ }
2215
2281
  const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
2216
2282
  if (stylisticOptions && !("jsx" in stylisticOptions)) {
2217
2283
  stylisticOptions.jsx = enableJsx;
@@ -2219,11 +2285,15 @@ function luxass(options = {}, ...userConfigs) {
2219
2285
  const configs2 = [];
2220
2286
  if (enableGitignore) {
2221
2287
  if (typeof enableGitignore !== "boolean") {
2222
- configs2.push(interop(import("eslint-config-flat-gitignore")).then((plugin) => [plugin(enableGitignore)]));
2288
+ configs2.push(interop(import("eslint-config-flat-gitignore")).then((r) => [r({
2289
+ name: "luxass/gitignore",
2290
+ ...enableGitignore
2291
+ })]));
2223
2292
  } else {
2224
- if (existsSync(".gitignore")) {
2225
- configs2.push(interop(import("eslint-config-flat-gitignore")).then((plugin) => [plugin()]));
2226
- }
2293
+ configs2.push(interop(import("eslint-config-flat-gitignore")).then((r) => [r({
2294
+ name: "luxass/gitignore",
2295
+ strict: false
2296
+ })]));
2227
2297
  }
2228
2298
  }
2229
2299
  const typescriptOptions = resolveSubOptions(options, "typescript");
@@ -2231,7 +2301,7 @@ function luxass(options = {}, ...userConfigs) {
2231
2301
  configs2.push(
2232
2302
  ignores(),
2233
2303
  javascript({
2234
- editor,
2304
+ isInEditor,
2235
2305
  overrides: getOverrides(options, "javascript")
2236
2306
  }),
2237
2307
  comments(),
@@ -2242,8 +2312,11 @@ function luxass(options = {}, ...userConfigs) {
2242
2312
  imports({
2243
2313
  stylistic: stylisticOptions
2244
2314
  }),
2245
- unicorn()
2315
+ perfectionist()
2246
2316
  );
2317
+ if (enableUnicorn) {
2318
+ configs2.push(unicorn(enableUnicorn === true ? {} : enableUnicorn));
2319
+ }
2247
2320
  if (enableVue) {
2248
2321
  exts.push("vue");
2249
2322
  }
@@ -2272,7 +2345,7 @@ function luxass(options = {}, ...userConfigs) {
2272
2345
  }
2273
2346
  if (options.test ?? true) {
2274
2347
  configs2.push(test({
2275
- editor,
2348
+ isInEditor,
2276
2349
  overrides: getOverrides(options, "test")
2277
2350
  }));
2278
2351
  }
@@ -2349,6 +2422,12 @@ function luxass(options = {}, ...userConfigs) {
2349
2422
  typeof stylisticOptions === "boolean" ? {} : stylisticOptions
2350
2423
  ));
2351
2424
  }
2425
+ configs2.push(
2426
+ disables()
2427
+ );
2428
+ if ("files" in options) {
2429
+ throw new Error('[@luxass/eslint-config] The first argument should not contain the "files" property as the options are supposed to be global. Place it in the second or later config instead.');
2430
+ }
2352
2431
  const fusedConfig = FLAT_CONFIG_PROPS.reduce((acc, key) => {
2353
2432
  if (key in options) {
2354
2433
  acc[key] = options[key];
@@ -2405,12 +2484,16 @@ export {
2405
2484
  combine,
2406
2485
  comments,
2407
2486
  src_default as default,
2487
+ disables,
2408
2488
  ensure,
2409
2489
  formatters,
2410
2490
  getOverrides,
2411
2491
  ignores,
2412
2492
  imports,
2413
2493
  interop,
2494
+ isInEditorEnv,
2495
+ isInGitHooksOrLintStaged,
2496
+ isPackageInScope,
2414
2497
  javascript,
2415
2498
  jsdoc,
2416
2499
  jsonc,
@@ -2419,6 +2502,7 @@ export {
2419
2502
  markdown,
2420
2503
  node,
2421
2504
  parserPlain,
2505
+ perfectionist,
2422
2506
  react,
2423
2507
  regexp,
2424
2508
  renamePluginInConfigs,