@cuiqg/eslint-config 2.8.0 → 2.8.2

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 (2) hide show
  1. package/dist/index.mjs +162 -46
  2. package/package.json +3 -6
package/dist/index.mjs CHANGED
@@ -1,7 +1,8 @@
1
1
  import { FlatConfigComposer } from "eslint-flat-config-utils";
2
+ import { fileURLToPath } from "node:url";
3
+ import { isPackageExists } from "local-pkg";
2
4
  import globals from "globals";
3
5
  import process from "node:process";
4
- import { isPackageExists } from "local-pkg";
5
6
 
6
7
  //#region src/globs.js
7
8
  const GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
@@ -26,6 +27,8 @@ const GLOB_TOML = "**/*.toml";
26
27
  const GLOB_XML = "**/*.xml";
27
28
  const GLOB_SVG = "**/*.svg";
28
29
  const GLOB_HTML = "**/*.htm?(l)";
30
+ const GLOB_GRAPHQL = "**/*.{g,graph}ql";
31
+ const GLOB_PHP = "**/*.php";
29
32
  const GLOB_EXCLUDE = [
30
33
  "**/node_modules",
31
34
  "**/dist",
@@ -69,6 +72,26 @@ const GLOB_EXCLUDE = [
69
72
 
70
73
  //#endregion
71
74
  //#region src/utils.js
75
+ const scopeUrl = fileURLToPath(new URL(".", import.meta.url));
76
+ const parserPlain = {
77
+ meta: { name: "parser-plain" },
78
+ parseForESLint: (code) => ({
79
+ ast: {
80
+ body: [],
81
+ comments: [],
82
+ loc: {
83
+ end: code.length,
84
+ start: 0
85
+ },
86
+ range: [0, code.length],
87
+ tokens: [],
88
+ type: "Program"
89
+ },
90
+ scopeManager: null,
91
+ services: { isPlain: true },
92
+ visitorKeys: { Program: [] }
93
+ })
94
+ };
72
95
  async function interopDefault(module) {
73
96
  try {
74
97
  let resolved = await module;
@@ -77,6 +100,9 @@ async function interopDefault(module) {
77
100
  throw new Error(`Cannot import module: ${String(error)}`);
78
101
  }
79
102
  }
103
+ function isPackageInScope(name) {
104
+ return isPackageExists(name, { paths: [scopeUrl] });
105
+ }
80
106
  function renameRules(rules, map) {
81
107
  return Object.fromEntries(Object.entries(rules).map(([key, value]) => {
82
108
  for (const [from, to] of Object.entries(map)) if (key.startsWith(`${from}/`)) return [to + key.slice(from.length), value];
@@ -190,6 +216,13 @@ async function prettier() {
190
216
 
191
217
  //#endregion
192
218
  //#region src/configs/stylistic.js
219
+ const stylisticConfigDefaults = {
220
+ indent: 2,
221
+ jsx: true,
222
+ quotes: "single",
223
+ semi: false,
224
+ commaDangle: "never"
225
+ };
193
226
  async function stylistic() {
194
227
  const pluginStylistic = await interopDefault(import("@stylistic/eslint-plugin"));
195
228
  const config = pluginStylistic.configs.customize({
@@ -197,7 +230,8 @@ async function stylistic() {
197
230
  indent: 2,
198
231
  pluginName: "style",
199
232
  quotes: "single",
200
- semi: false
233
+ semi: false,
234
+ ...stylisticConfigDefaults
201
235
  });
202
236
  return [{
203
237
  name: "cuiqg/stylistic",
@@ -363,51 +397,125 @@ async function vue() {
363
397
  }
364
398
 
365
399
  //#endregion
366
- //#region src/configs/compat.js
367
- async function compat() {
368
- const pluginCompat = await interopDefault(import("eslint-plugin-compat"));
400
+ //#region src/configs/tailwindcss.js
401
+ async function tailwindcss() {
402
+ const pluginTailwindcss = await interopDefault(import("eslint-plugin-tailwindcss"));
369
403
  return [{
370
- name: "cuiqg/compat",
371
- plugins: { compat: pluginCompat },
372
- rules: { ...pluginCompat.configs.recommended.rules }
404
+ name: "cuiqg/tailwindcss",
405
+ plugins: { tailwindcss: pluginTailwindcss },
406
+ languageOptions: { parserOptions: { ecmaFeatures: { jsx: true } } },
407
+ rules: { ...pluginTailwindcss.configs["flat/recommended"][1].rules }
373
408
  }];
374
409
  }
375
410
 
376
411
  //#endregion
377
- //#region src/configs/unicorn.js
378
- async function unicorn() {
379
- const pluginUnicorn = await interopDefault(import("eslint-plugin-unicorn"));
380
- return [{
381
- name: "cuiqg/unicorn",
382
- plugins: { unicorn: pluginUnicorn },
383
- rules: { ...pluginUnicorn.configs?.recommended?.rules }
384
- }];
412
+ //#region src/configs/formatters.js
413
+ function mergePrettierOptions(options, overrides = {}) {
414
+ return {
415
+ ...options,
416
+ ...overrides,
417
+ plugins: [...overrides.plugins || [], ...options.plugins || []]
418
+ };
385
419
  }
386
-
387
- //#endregion
388
- //#region src/configs/promise.js
389
- async function promise() {
390
- return [{
391
- ...(await interopDefault(import("eslint-plugin-promise"))).configs["flat/recommended"],
392
- name: "cuiqg/promise"
393
- }];
394
- }
395
-
396
- //#endregion
397
- //#region src/configs/imports.js
398
- async function imports() {
399
- return [{
400
- name: "cuiqg/imports",
401
- plugins: { import: await interopDefault(import("eslint-plugin-import-lite")) },
402
- rules: {
403
- "import/consistent-type-specifier-style": ["error", "top-level"],
404
- "import/first": "error",
405
- "import/no-duplicates": "error",
406
- "import/no-mutable-exports": "error",
407
- "import/no-named-default": "error",
408
- "import/newline-after-import": ["error", { count: 1 }]
409
- }
420
+ async function formatters(options = {}) {
421
+ const isPrettierPluginXmlScope = isPackageInScope("@prettier/plugin-xml");
422
+ const isPrettierPluginPhpScope = isPackageInScope("@prettier/plugin-php");
423
+ const { config = {}, css = true, html = true, graphql = true, svg = isPrettierPluginXmlScope, xml = isPrettierPluginXmlScope, php = isPrettierPluginPhpScope } = options;
424
+ const pluginFormat = await interopDefault(import("eslint-plugin-format"));
425
+ const { indent, quotes, semi } = { ...stylisticConfigDefaults };
426
+ const prettierOptions = Object.assign({
427
+ endOfLine: "auto",
428
+ printWidth: 120,
429
+ semi,
430
+ singleQuote: quotes === "single",
431
+ tabWidth: typeof indent === "number" ? indent : 2,
432
+ trailingComma: "all",
433
+ useTabs: indent === "tab"
434
+ }, config || {});
435
+ const prettierXmlOptions = {
436
+ bracketSameLine: true,
437
+ singleAttributePerLine: false,
438
+ tabWidth: 80,
439
+ xmlQuoteAttributes: "double",
440
+ xmlSelfClosingSpace: true,
441
+ xmlSortAttributesByKey: false,
442
+ xmlWhitespaceSensitivity: "ignore"
443
+ };
444
+ const prettierPhpOptions = {
445
+ phpVersion: "auto",
446
+ printWidth: 80,
447
+ tabWidth: 4,
448
+ useTabs: false,
449
+ singleQuote: false,
450
+ trailingCommaPHP: true,
451
+ braceStyle: "per-cs",
452
+ requirePragma: false,
453
+ insertPragma: false
454
+ };
455
+ const configs = [{
456
+ name: "cuiqg/formatter/setup",
457
+ plugins: { format: pluginFormat }
410
458
  }];
459
+ if (css) configs.push({
460
+ name: "cuiqg/formatter/css",
461
+ files: [GLOB_CSS, GLOB_POSTCSS],
462
+ plugins: { format: parserPlain },
463
+ rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "css" })] }
464
+ }, {
465
+ files: [GLOB_SCSS],
466
+ languageOptions: { parser: parserPlain },
467
+ name: "cuiqg/formatter/scss",
468
+ rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "scss" })] }
469
+ });
470
+ if (html) configs.push({
471
+ files: [GLOB_HTML],
472
+ languageOptions: { parser: parserPlain },
473
+ name: "cuiqg/formatter/html",
474
+ rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "html" })] }
475
+ });
476
+ if (xml) configs.push({
477
+ files: [GLOB_XML],
478
+ languageOptions: { parser: parserPlain },
479
+ name: "cuiqg/formatter/xml",
480
+ rules: { "format/prettier": ["error", mergePrettierOptions({
481
+ ...prettierXmlOptions,
482
+ ...prettierOptions
483
+ }, {
484
+ parser: "xml",
485
+ plugins: ["@prettier/plugin-xml"]
486
+ })] }
487
+ });
488
+ if (svg) configs.push({
489
+ files: [GLOB_SVG],
490
+ languageOptions: { parser: parserPlain },
491
+ name: "cuiqg/formatter/svg",
492
+ rules: { "format/prettier": ["error", mergePrettierOptions({
493
+ ...prettierXmlOptions,
494
+ ...prettierOptions
495
+ }, {
496
+ parser: "xml",
497
+ plugins: ["@prettier/plugin-xml"]
498
+ })] }
499
+ });
500
+ if (graphql) configs.push({
501
+ files: [GLOB_GRAPHQL],
502
+ languageOptions: { parser: parserPlain },
503
+ name: "cuiqg/formatter/graphql",
504
+ rules: { "format/prettier": ["error", mergePrettierOptions(prettierOptions, { parser: "graphql" })] }
505
+ });
506
+ if (php) configs.push({
507
+ files: [GLOB_PHP],
508
+ languageOptions: { parser: parserPlain },
509
+ name: "cuiqg/formatter/php",
510
+ rules: { "format/prettier": ["error", mergePrettierOptions({
511
+ ...prettierPhpOptions,
512
+ ...prettierOptions
513
+ }, {
514
+ parser: "php",
515
+ plugins: ["@prettier/plugin-php"]
516
+ })] }
517
+ });
518
+ return configs;
411
519
  }
412
520
 
413
521
  //#endregion
@@ -427,7 +535,8 @@ const hasVue = () => [
427
535
  "@slidev/cli"
428
536
  ].some((i) => isPackageExists(i));
429
537
  const hasTypeScript = () => isPackageExists("typescript");
430
- const hasUnoCss = () => isPackageExists("unocss");
538
+ const hasUnocss = () => isPackageExists("unocss");
539
+ const hasTailwindcss = () => isPackageExists("tailwindcss");
431
540
 
432
541
  //#endregion
433
542
  //#region src/presets.js
@@ -438,16 +547,23 @@ const defaultPluginRenaming = {
438
547
  /**
439
548
  *
440
549
  * @param {object} options - 设置选项
441
- * @param {...any} userConfigs - 用户配置
442
- * @returns {Promise<any[]>} 合并后的配置
550
+ * @param {boolean} [options.prettier=false] - 是否启用 prettier 格式化
551
+ * @param {boolean} [options.unocss] - 是否启用 unocss 格式化
552
+ * @param {boolean} [options.tailwindcss] - 是否启用 tailwindcss 格式化
553
+ * @param {boolean} [options.vue] - 是否启用 vue 格式化
554
+ * @param {boolean|object} [options.formatter=true] - 是否启用格式化
555
+ * @param {...Object} userConfigs - 用户配置
556
+ * @returns {Promise<Object[]>} 合并后的配置
443
557
  */
444
558
  function cuiqg(options = {}, ...userConfigs) {
445
- const { prettier: enablePrettier = false, unocss: enableUnocss = hasUnoCss(), vue: enableVue = hasVue() } = options;
559
+ const { prettier: enablePrettier = false, unocss: enableUnocss = hasUnocss(), tailwindcss: enableTailwindcss = hasTailwindcss(), vue: enableVue = hasVue(), formatter: enableFormatter = true } = options;
446
560
  const configs = [];
447
- configs.push(compat(), ignores(), javascript(), imports(), jsdoc(), stylistic(), packageJson(), unicorn(), promise());
561
+ configs.push(ignores(), javascript(), jsdoc(), stylistic(), packageJson());
448
562
  if (enableVue) configs.push(vue(), macros());
449
563
  if (enableUnocss) configs.push(unocss());
564
+ if (enableTailwindcss) configs.push(tailwindcss());
450
565
  if (enablePrettier) configs.push(prettier());
566
+ if (enableFormatter) configs.push(formatters(typeof enableFormatter === "object" ? enableFormatter : {}));
451
567
  let composer = new FlatConfigComposer();
452
568
  composer = composer.append(...configs, ...userConfigs).renamePlugins(defaultPluginRenaming);
453
569
  return composer;
@@ -458,4 +574,4 @@ function cuiqg(options = {}, ...userConfigs) {
458
574
  var src_default = cuiqg;
459
575
 
460
576
  //#endregion
461
- export { GLOB_CSS, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_STYLUS, GLOB_SVG, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, compat, cuiqg, src_default as default, defaultPluginRenaming, hasTypeScript, hasUnoCss, hasVue, ignores, imports, isInEditor, isInGitHookOrLintStaged, javascript, jsdoc, macros, packageJson, prettier, promise, stylistic, unicorn, unocss, vue };
577
+ export { GLOB_CSS, GLOB_EXCLUDE, GLOB_GRAPHQL, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_PHP, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_STYLUS, GLOB_SVG, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, cuiqg, src_default as default, defaultPluginRenaming, formatters, hasTailwindcss, hasTypeScript, hasUnocss, hasVue, ignores, isInEditor, isInGitHookOrLintStaged, javascript, jsdoc, macros, packageJson, prettier, stylistic, stylisticConfigDefaults, tailwindcss, unocss, vue };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cuiqg/eslint-config",
3
- "version": "2.8.0",
3
+ "version": "2.8.2",
4
4
  "description": "Eslint config for @cuiqg",
5
5
  "keywords": [
6
6
  "eslint-config"
@@ -42,14 +42,11 @@
42
42
  "eslint-config-flat-gitignore": "^2.1.0",
43
43
  "eslint-config-prettier": "^10.1.8",
44
44
  "eslint-flat-config-utils": "^2.1.4",
45
- "eslint-plugin-compat": "^6.0.2",
46
- "eslint-plugin-import-lite": "^0.3.0",
45
+ "eslint-plugin-format": "^1.0.2",
47
46
  "eslint-plugin-jsdoc": "^61.4.1",
48
47
  "eslint-plugin-package-json": "^0.85.0",
49
- "eslint-plugin-perfectionist": "^4.15.1",
50
48
  "eslint-plugin-prettier": "^5.5.4",
51
- "eslint-plugin-promise": "^7.2.1",
52
- "eslint-plugin-unicorn": "^62.0.0",
49
+ "eslint-plugin-tailwindcss": "4.0.0-beta.0",
53
50
  "eslint-plugin-vue": "^10.6.2",
54
51
  "globals": "^16.5.0",
55
52
  "jsonc-eslint-parser": "^2.4.1",