@whoj/eslint-config 2.2.2 → 2.3.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 (2) hide show
  1. package/dist/cli.js +171 -49
  2. package/package.json +4 -3
package/dist/cli.js CHANGED
@@ -1,16 +1,16 @@
1
1
  // src/cli/index.ts
2
2
  import yargs from "yargs";
3
- import c6 from "picocolors";
4
- import process5 from "node:process";
5
- import * as p5 from "@clack/prompts";
3
+ import c7 from "picocolors";
4
+ import process6 from "node:process";
5
+ import * as p6 from "@clack/prompts";
6
6
  import { hideBin } from "yargs/helpers";
7
7
 
8
8
  // src/cli/run.ts
9
- import fs3 from "node:fs";
10
- import c5 from "picocolors";
11
- import path4 from "node:path";
12
- import process4 from "node:process";
13
- import * as p4 from "@clack/prompts";
9
+ import fs4 from "node:fs";
10
+ import c6 from "picocolors";
11
+ import path5 from "node:path";
12
+ import process5 from "node:process";
13
+ import * as p5 from "@clack/prompts";
14
14
 
15
15
  // src/cli/utils.ts
16
16
  import { execSync } from "node:child_process";
@@ -22,15 +22,25 @@ function isGitClean() {
22
22
  return false;
23
23
  }
24
24
  }
25
+ function getJetbrainsEslintConfigContent(configFrom) {
26
+ return `
27
+ import { whoj } from '@whoj/eslint-config';
28
+ import _defaults from "${configFrom}";
29
+
30
+ export default whoj({
31
+ isInEditor: true
32
+ }).append(_defaults);
33
+ `.trimStart();
34
+ }
25
35
  function getEslintConfigContent(mainConfig, additionalConfigs) {
26
36
  return `
27
- import whoj from '@whoj/eslint-config'
37
+ import whoj from '@whoj/eslint-config';
28
38
 
29
39
  export default whoj({
30
40
  ${mainConfig}
31
41
  }${additionalConfigs?.map((config) => `,{
32
42
  ${config}
33
- }`)})
43
+ }`)});
34
44
  `.trimStart();
35
45
  }
36
46
 
@@ -85,6 +95,7 @@ async function updateEslintFiles(result) {
85
95
  });
86
96
  if (legacyConfig.length)
87
97
  p.note(`${c.dim(legacyConfig.join(", "))}`, "You can now remove those files manually");
98
+ return pathFlatConfig;
88
99
  }
89
100
 
90
101
  // src/cli/stages/update-package-json.ts
@@ -101,7 +112,7 @@ import c2 from "picocolors";
101
112
  var package_default = {
102
113
  name: "@whoj/eslint-config",
103
114
  type: "module",
104
- version: "2.2.2",
115
+ version: "2.3.1",
105
116
  packageManager: "pnpm@10.2.1",
106
117
  description: "ESLint config",
107
118
  license: "MIT",
@@ -163,7 +174,6 @@ var package_default = {
163
174
  "@clack/prompts": "^0.9.1",
164
175
  "@eslint-community/eslint-plugin-eslint-comments": "^4.4.1",
165
176
  "@eslint/markdown": "^6.2.2",
166
- "@nuxt/eslint-config": "^1.0.1",
167
177
  "@stylistic/eslint-plugin": "^3.0.1",
168
178
  "@typescript-eslint/eslint-plugin": "^8.22.0",
169
179
  "@typescript-eslint/parser": "^8.22.0",
@@ -186,6 +196,7 @@ var package_default = {
186
196
  "eslint-plugin-vue": "^9.32.0",
187
197
  "eslint-plugin-yml": "^1.16.0",
188
198
  "eslint-processor-vue-blocks": "^1.0.0",
199
+ "fast-xml-parser": "^4.5.1",
189
200
  globals: "^15.14.0",
190
201
  "jsonc-eslint-parser": "^2.4.0",
191
202
  "local-pkg": "^1.0.0",
@@ -200,6 +211,7 @@ var package_default = {
200
211
  "@antfu/ni": "^23.3.1",
201
212
  "@eslint-react/eslint-plugin": "^1.26.2",
202
213
  "@eslint/config-inspector": "^1.0.0",
214
+ "@nuxt/eslint-config": "^1.0.1",
203
215
  "@prettier/plugin-xml": "^3.4.1",
204
216
  "@stylistic/eslint-plugin-migrate": "^3.0.1",
205
217
  "@types/fs-extra": "^11.0.4",
@@ -256,6 +268,15 @@ var package_default = {
256
268
  };
257
269
 
258
270
  // src/cli/constants.ts
271
+ var jetbrainsSettingsObj = {
272
+ "?xml": { version: "1.0", encoding: "UTF-8" },
273
+ "project": { version: "4", component: {
274
+ "name": "EslintConfiguration",
275
+ "extra-options": { value: "--cache" },
276
+ "option": { value: "true", name: "fix-on-save" },
277
+ "custom-configuration-file": { used: "true", path: "$PROJECT_DIR$/eslint.config.js" }
278
+ } }
279
+ };
259
280
  var vscodeSettingsString = `
260
281
  // Disable the default formatter, use eslint instead
261
282
  "prettier.enable": false,
@@ -312,6 +333,10 @@ var frameworkOptions = [
312
333
  value: "vue",
313
334
  label: c2.green("Vue")
314
335
  },
336
+ {
337
+ value: "nuxt",
338
+ label: c2.green("Nuxt")
339
+ },
315
340
  {
316
341
  value: "react",
317
342
  label: c2.cyan("React")
@@ -348,6 +373,9 @@ var extraOptions = [
348
373
  var extra = extraOptions.map(({ value }) => value);
349
374
  var dependenciesMap = {
350
375
  vue: [],
376
+ nuxt: [
377
+ "@nuxt/eslint-config"
378
+ ],
351
379
  solid: [
352
380
  "eslint-plugin-solid"
353
381
  ],
@@ -420,57 +448,129 @@ async function updatePackageJson(result) {
420
448
  p2.log.success(c3.green("Changes wrote to package.json"));
421
449
  }
422
450
 
423
- // src/cli/stages/update-vscode-settings.ts
451
+ // src/cli/stages/update-jetbrains-idea.ts
424
452
  import fs2 from "node:fs";
425
453
  import c4 from "picocolors";
426
454
  import path3 from "node:path";
427
455
  import fsp3 from "node:fs/promises";
428
456
  import process3 from "node:process";
429
457
  import * as p3 from "@clack/prompts";
430
- async function updateVscodeSettings(result) {
458
+ import { deepMergeWithArray } from "@antfu/utils";
459
+ import { XMLParser, XMLBuilder } from "fast-xml-parser";
460
+ async function updateJetbrainsIdea(result, flatConfigPath) {
431
461
  const cwd = process3.cwd();
432
- if (!result.updateVscodeSettings)
462
+ if (!result.updateJetbrainsIdea)
433
463
  return;
434
- const dotVscodePath = path3.join(cwd, ".vscode");
435
- const settingsPath = path3.join(dotVscodePath, "settings.json");
436
- if (!fs2.existsSync(dotVscodePath))
437
- await fsp3.mkdir(dotVscodePath, { recursive: true });
464
+ const dotIdeaPath = path3.join(cwd, ".idea/jsLinters");
465
+ const settingsPath = path3.join(dotIdeaPath, "eslint.xml");
466
+ const ideaFlatConfigPath = path3.join(dotIdeaPath, path3.basename(flatConfigPath));
467
+ const xmlParserOptions = {
468
+ attributeNamePrefix: "",
469
+ ignoreAttributes: false,
470
+ unpairedTags: [
471
+ "option",
472
+ "extra-options",
473
+ "work-dir-patterns",
474
+ "additional-rules-dir",
475
+ "custom-configuration-file"
476
+ ]
477
+ };
478
+ const xmlBuilderOptions = {
479
+ format: true,
480
+ ...xmlParserOptions,
481
+ suppressUnpairedNode: false,
482
+ suppressBooleanAttributes: false
483
+ };
484
+ const builder = new XMLBuilder(xmlBuilderOptions);
485
+ if (!fs2.existsSync(dotIdeaPath)) {
486
+ await fsp3.mkdir(dotIdeaPath, { recursive: true });
487
+ }
488
+ await fsp3.writeFile(
489
+ ideaFlatConfigPath,
490
+ getJetbrainsEslintConfigContent(flatConfigPath),
491
+ "utf8"
492
+ );
493
+ p3.log.success(c4.green(`Created ${path3.relative(cwd, ideaFlatConfigPath)}`));
494
+ const ideaSettingsObject = deepMergeWithArray(
495
+ jetbrainsSettingsObj,
496
+ {
497
+ project: {
498
+ component: {
499
+ "custom-configuration-file": {
500
+ used: "true",
501
+ path: `$PROJECT_DIR$/.idea/jsLinters/${path3.basename(flatConfigPath)}`
502
+ }
503
+ }
504
+ }
505
+ }
506
+ );
438
507
  if (!fs2.existsSync(settingsPath)) {
439
- await fsp3.writeFile(settingsPath, `{${vscodeSettingsString}}
508
+ await fsp3.writeFile(settingsPath, builder.build(ideaSettingsObject), "utf8");
509
+ p3.log.success(c4.green("Created .idea/jsLinters/eslint.xml"));
510
+ } else {
511
+ const ideaSettingsContent = await fsp3.readFile(settingsPath, "utf8");
512
+ const parser = new XMLParser(xmlParserOptions);
513
+ const ideaXml = deepMergeWithArray(
514
+ parser.parse(ideaSettingsContent),
515
+ jetbrainsSettingsObj
516
+ );
517
+ await fsp3.writeFile(settingsPath, builder.build(ideaXml), "utf8");
518
+ p3.log.success(c4.green("Updated .idea/jsLinters/eslint.xml"));
519
+ }
520
+ }
521
+
522
+ // src/cli/stages/update-vscode-settings.ts
523
+ import fs3 from "node:fs";
524
+ import c5 from "picocolors";
525
+ import path4 from "node:path";
526
+ import fsp4 from "node:fs/promises";
527
+ import process4 from "node:process";
528
+ import * as p4 from "@clack/prompts";
529
+ async function updateVscodeSettings(result) {
530
+ const cwd = process4.cwd();
531
+ if (!result.updateVscodeSettings)
532
+ return;
533
+ const dotVscodePath = path4.join(cwd, ".vscode");
534
+ const settingsPath = path4.join(dotVscodePath, "settings.json");
535
+ if (!fs3.existsSync(dotVscodePath))
536
+ await fsp4.mkdir(dotVscodePath, { recursive: true });
537
+ if (!fs3.existsSync(settingsPath)) {
538
+ await fsp4.writeFile(settingsPath, `{${vscodeSettingsString}}
440
539
  `, "utf-8");
441
- p3.log.success(c4.green("Created .vscode/settings.json"));
540
+ p4.log.success(c5.green("Created .vscode/settings.json"));
442
541
  } else {
443
- let settingsContent = await fsp3.readFile(settingsPath, "utf8");
542
+ let settingsContent = await fsp4.readFile(settingsPath, "utf8");
444
543
  settingsContent = settingsContent.trim().replace(/\s*\}$/, "");
445
544
  settingsContent += settingsContent.endsWith(",") || settingsContent.endsWith("{") ? "" : ",";
446
545
  settingsContent += `${vscodeSettingsString}}
447
546
  `;
448
- await fsp3.writeFile(settingsPath, settingsContent, "utf-8");
449
- p3.log.success(c4.green("Updated .vscode/settings.json"));
547
+ await fsp4.writeFile(settingsPath, settingsContent, "utf-8");
548
+ p4.log.success(c5.green("Updated .vscode/settings.json"));
450
549
  }
451
550
  }
452
551
 
453
552
  // src/cli/run.ts
454
- async function run(options = {}) {
455
- const argSkipPrompt = !!process4.env.SKIP_PROMPT || options.yes;
553
+ async function run({ jetbrains, vscode, ...options } = {}) {
554
+ const argSkipPrompt = !!process5.env.SKIP_PROMPT || options.yes;
456
555
  const argTemplate = options.frameworks?.map((m) => m.trim());
457
556
  const argExtra = options.extra?.map((m) => m.trim());
458
- if (fs3.existsSync(path4.join(process4.cwd(), "eslint.config.js"))) {
459
- p4.log.warn(c5.yellow("eslint.config.js already exists, migration wizard exited."));
460
- return process4.exit(1);
557
+ if (fs4.existsSync(path5.join(process5.cwd(), "eslint.config.js"))) {
558
+ p5.log.warn(c6.yellow("eslint.config.js already exists, migration wizard exited."));
559
+ return process5.exit(1);
461
560
  }
462
561
  let result = {
463
562
  extra: argExtra ?? [],
464
563
  frameworks: argTemplate ?? [],
465
564
  uncommittedConfirmed: false,
466
- updateVscodeSettings: true
565
+ updateVscodeSettings: vscode ?? true,
566
+ updateJetbrainsIdea: jetbrains ?? true
467
567
  };
468
568
  if (!argSkipPrompt) {
469
- result = await p4.group({
569
+ result = await p5.group({
470
570
  uncommittedConfirmed: () => {
471
571
  if (argSkipPrompt || isGitClean())
472
572
  return Promise.resolve(true);
473
- return p4.confirm({
573
+ return p5.confirm({
474
574
  initialValue: false,
475
575
  message: "There are uncommitted changes in the current repository, are you sure to continue?"
476
576
  });
@@ -480,8 +580,8 @@ async function run(options = {}) {
480
580
  if (!results.uncommittedConfirmed || isArgTemplateValid)
481
581
  return;
482
582
  const message = !isArgTemplateValid && argTemplate ? `"${argTemplate}" isn't a valid template. Please choose from below: ` : "Select a framework:";
483
- return p4.multiselect({
484
- message: c5.reset(message),
583
+ return p5.multiselect({
584
+ message: c6.reset(message),
485
585
  options: frameworkOptions,
486
586
  required: false
487
587
  });
@@ -491,53 +591,75 @@ async function run(options = {}) {
491
591
  if (!results.uncommittedConfirmed || isArgExtraValid)
492
592
  return;
493
593
  const message = !isArgExtraValid && argExtra ? `"${argExtra}" isn't a valid extra util. Please choose from below: ` : "Select a extra utils:";
494
- return p4.multiselect({
495
- message: c5.reset(message),
594
+ return p5.multiselect({
595
+ message: c6.reset(message),
496
596
  options: extraOptions,
497
597
  required: false
498
598
  });
499
599
  },
600
+ updateJetbrainsIdea: ({ results }) => {
601
+ if (!results.uncommittedConfirmed)
602
+ return;
603
+ return p5.confirm({
604
+ initialValue: true,
605
+ message: "Update JetBrain IDE's eslint configuration for better experience WebStorm / PhpStorm?"
606
+ });
607
+ },
500
608
  updateVscodeSettings: ({ results }) => {
501
609
  if (!results.uncommittedConfirmed)
502
610
  return;
503
- return p4.confirm({
611
+ return p5.confirm({
504
612
  initialValue: true,
505
613
  message: "Update .vscode/settings.json for better VS Code experience?"
506
614
  });
507
615
  }
508
616
  }, {
509
617
  onCancel: () => {
510
- p4.cancel("Operation cancelled.");
511
- process4.exit(0);
618
+ p5.cancel("Operation cancelled.");
619
+ process5.exit(0);
512
620
  }
513
621
  });
514
622
  if (!result.uncommittedConfirmed)
515
- return process4.exit(1);
623
+ return process5.exit(1);
516
624
  }
517
625
  await updatePackageJson(result);
518
- await updateEslintFiles(result);
626
+ const configFileName = await updateEslintFiles(result);
627
+ await updateJetbrainsIdea(
628
+ result,
629
+ configFileName
630
+ );
519
631
  await updateVscodeSettings(result);
520
- p4.log.success(c5.green("Setup completed"));
521
- p4.outro(`Now you can update the dependencies by run ${c5.blue("pnpm install")} and run ${c5.blue("eslint . --fix")}
632
+ p5.log.success(c6.green("Setup completed"));
633
+ p5.outro(`Now you can update the dependencies by run ${c6.blue("pnpm install")} and run ${c6.blue("eslint . --fix")}
522
634
  `);
523
635
  }
524
636
 
525
637
  // src/cli/index.ts
526
638
  function header() {
527
639
  console.log("\n");
528
- p5.intro(`${c6.green("@whoj/eslint-config ")}${c6.dim(`v${package_default.version}`)}`);
640
+ p6.intro(`${c7.green("@whoj/eslint-config ")}${c7.dim(`v${package_default.version}`)}`);
529
641
  }
530
- var instance = yargs(hideBin(process5.argv)).scriptName("@whoj/eslint-config").usage("").command(
642
+ var instance = yargs(hideBin(process6.argv)).scriptName("@whoj/eslint-config").usage("").command(
531
643
  "*",
532
644
  "Run the initialization or migration",
533
645
  (args) => args.option("yes", {
534
646
  alias: "y",
535
647
  type: "boolean",
536
648
  description: "Skip prompts and use default values"
649
+ }).option("jetbrains", {
650
+ default: true,
651
+ type: "boolean",
652
+ alias: ["idea", "j"],
653
+ description: "Configure eslint settings for better Jetbrains IDE. (WebStorm / PhpStorm) experience."
654
+ }).option("vscode", {
655
+ default: true,
656
+ type: "boolean",
657
+ alias: ["c", "code"],
658
+ description: "Add/Update .vscode/settings.json for better VS Code experience."
537
659
  }).option("template", {
538
660
  alias: "t",
539
661
  type: "string",
540
- description: "Use the framework template for optimal customization: vue / react / svelte / astro"
662
+ description: "Use the framework template for optimal customization: vue / nuxt / react / svelte / astro"
541
663
  }).option("extra", {
542
664
  alias: "e",
543
665
  array: true,
@@ -549,9 +671,9 @@ var instance = yargs(hideBin(process5.argv)).scriptName("@whoj/eslint-config").u
549
671
  try {
550
672
  await run(args);
551
673
  } catch (error) {
552
- p5.log.error(c6.inverse(c6.red(" Failed to migrate ")));
553
- p5.log.error(c6.red(`\u2718 ${String(error)}`));
554
- process5.exit(1);
674
+ p6.log.error(c7.inverse(c7.red(" Failed to migrate ")));
675
+ p6.log.error(c7.red(`\u2718 ${String(error)}`));
676
+ process6.exit(1);
555
677
  }
556
678
  }
557
679
  ).showHelpOnFail(false).alias("h", "help").version("version", package_default.version).alias("v", "version");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@whoj/eslint-config",
3
3
  "type": "module",
4
- "version": "2.2.2",
4
+ "version": "2.3.1",
5
5
  "description": "ESLint config",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/who-jonson/eslint-config",
@@ -47,7 +47,6 @@
47
47
  "@clack/prompts": "^0.9.1",
48
48
  "@eslint-community/eslint-plugin-eslint-comments": "^4.4.1",
49
49
  "@eslint/markdown": "^6.2.2",
50
- "@nuxt/eslint-config": "^1.0.1",
51
50
  "@stylistic/eslint-plugin": "^3.0.1",
52
51
  "@typescript-eslint/eslint-plugin": "^8.22.0",
53
52
  "@typescript-eslint/parser": "^8.22.0",
@@ -70,6 +69,7 @@
70
69
  "eslint-plugin-vue": "^9.32.0",
71
70
  "eslint-plugin-yml": "^1.16.0",
72
71
  "eslint-processor-vue-blocks": "^1.0.0",
72
+ "fast-xml-parser": "^4.5.1",
73
73
  "globals": "^15.14.0",
74
74
  "jsonc-eslint-parser": "^2.4.0",
75
75
  "local-pkg": "^1.0.0",
@@ -84,6 +84,7 @@
84
84
  "@antfu/ni": "^23.3.1",
85
85
  "@eslint-react/eslint-plugin": "^1.26.2",
86
86
  "@eslint/config-inspector": "^1.0.0",
87
+ "@nuxt/eslint-config": "^1.0.1",
87
88
  "@prettier/plugin-xml": "^3.4.1",
88
89
  "@stylistic/eslint-plugin-migrate": "^3.0.1",
89
90
  "@types/fs-extra": "^11.0.4",
@@ -117,7 +118,7 @@
117
118
  "typescript": "^5.7.3",
118
119
  "vitest": "^3.0.4",
119
120
  "vue": "^3.5.13",
120
- "@whoj/eslint-config": "2.2.2"
121
+ "@whoj/eslint-config": "2.3.1"
121
122
  },
122
123
  "resolutions": {
123
124
  "@eslint-community/eslint-utils": "^4.4.1",