@luxass/eslint-config 4.11.0 → 4.12.1

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