create-for-yeyu 3.2.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +53 -0
  2. package/dist/index.js +193 -27
  3. package/package.json +10 -11
package/README.md CHANGED
@@ -56,6 +56,56 @@ npx create-for-yeyu my-project --template vite
56
56
  npx create-for-yeyu my-project --template next
57
57
  ```
58
58
 
59
+ ### 常用选项
60
+
61
+ ```bash
62
+ # 查看版本
63
+ npx create-for-yeyu -v
64
+ npx create-for-yeyu --version
65
+
66
+ # 查看所有可用模板
67
+ npx create-for-yeyu --list-templates
68
+
69
+ # 使用默认值快速创建
70
+ # 默认项目名: my-project
71
+ # 默认模板: vite
72
+ npx create-for-yeyu --yes
73
+
74
+ # 目录已存在时直接覆盖
75
+ npx create-for-yeyu my-project --template next --force
76
+
77
+ # 关闭欢迎 Banner
78
+ npx create-for-yeyu my-project --template vite --no-banner
79
+
80
+ # Git 模板跳过 git 初始化
81
+ npx create-for-yeyu my-project --template nest --no-git
82
+ ```
83
+
84
+ ### 更新 CLI
85
+
86
+ ```bash
87
+ # 自动检测当前包管理器并更新到最新版本
88
+ create-for-yeyu update
89
+
90
+ # 指定包管理器更新
91
+ create-for-yeyu update --manager pnpm
92
+ create-for-yeyu update --manager npm
93
+ ```
94
+
95
+ ## 命令选项
96
+
97
+ | 选项 | 说明 |
98
+ | ---- | ---- |
99
+ | `-v, --version` | 显示当前 CLI 版本 |
100
+ | `-h, --help` | 显示帮助信息 |
101
+ | `-t, --template <template>` | 指定模板 |
102
+ | `-f, --force` | 目标目录已存在时直接覆盖 |
103
+ | `-y, --yes` | 尽可能使用默认值,跳过交互 |
104
+ | `--git` | Git 模板直接初始化仓库 |
105
+ | `--no-git` | Git 模板跳过仓库初始化 |
106
+ | `--list-templates` | 输出所有可用模板并退出 |
107
+ | `--no-banner` | 不显示欢迎 Banner |
108
+
59
109
  ## 可用模板
60
110
 
61
111
  | 模板名称 | 命令参数 | 说明 |
@@ -97,6 +147,9 @@ pnpm build
97
147
 
98
148
  # 本地测试运行
99
149
  pnpm start
150
+
151
+ # 查看帮助
152
+ pnpm start -- --help
100
153
  ```
101
154
 
102
155
  ## 项目结构
package/dist/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli.ts
4
- import { Command } from "commander";
4
+ import { createRequire } from "module";
5
+ import { Command, Option } from "commander";
5
6
  import chalk4 from "chalk";
6
7
 
7
8
  // src/prompts.ts
@@ -461,11 +462,11 @@ async function updatePackageJsonName(targetPath, projectName) {
461
462
  try {
462
463
  const packageJsonPath = path2.join(targetPath, "package.json");
463
464
  const packageJsonContent = await fsExtra.readFile(packageJsonPath, "utf-8");
464
- const packageJson = JSON.parse(packageJsonContent);
465
+ const packageJson2 = JSON.parse(packageJsonContent);
465
466
  const newPackageJson = {
466
467
  name: projectName
467
468
  };
468
- for (const [key, value] of Object.entries(packageJson)) {
469
+ for (const [key, value] of Object.entries(packageJson2)) {
469
470
  if (key !== "name") {
470
471
  newPackageJson[key] = value;
471
472
  }
@@ -554,6 +555,78 @@ async function createNextProject(projectName) {
554
555
  }
555
556
  }
556
557
 
558
+ // src/actions/update-cli.ts
559
+ import { execa as execa4 } from "execa";
560
+ var SUPPORTED_PACKAGE_MANAGERS = ["npm", "pnpm", "yarn", "bun"];
561
+ function getSupportedPackageManagers() {
562
+ return SUPPORTED_PACKAGE_MANAGERS;
563
+ }
564
+ function isPackageManager(value) {
565
+ return SUPPORTED_PACKAGE_MANAGERS.includes(value);
566
+ }
567
+ function normalizePackageManager(value) {
568
+ const normalized = value.trim().toLowerCase();
569
+ if (!isPackageManager(normalized)) {
570
+ throw new Error(
571
+ `Unsupported package manager: ${value}. Use one of: ${SUPPORTED_PACKAGE_MANAGERS.join(", ")}`
572
+ );
573
+ }
574
+ return normalized;
575
+ }
576
+ function detectPackageManager() {
577
+ const userAgent = process.env.npm_config_user_agent ?? "";
578
+ if (userAgent.startsWith("pnpm")) {
579
+ return "pnpm";
580
+ }
581
+ if (userAgent.startsWith("yarn")) {
582
+ return "yarn";
583
+ }
584
+ if (userAgent.startsWith("bun")) {
585
+ return "bun";
586
+ }
587
+ return "npm";
588
+ }
589
+ function getUpdateCommand(packageName, packageManager) {
590
+ switch (packageManager) {
591
+ case "pnpm":
592
+ return {
593
+ command: "pnpm",
594
+ args: ["add", "-g", `${packageName}@latest`]
595
+ };
596
+ case "yarn":
597
+ return {
598
+ command: "yarn",
599
+ args: ["global", "add", `${packageName}@latest`]
600
+ };
601
+ case "bun":
602
+ return {
603
+ command: "bun",
604
+ args: ["add", "-g", `${packageName}@latest`]
605
+ };
606
+ case "npm":
607
+ default:
608
+ return {
609
+ command: "npm",
610
+ args: ["install", "-g", `${packageName}@latest`]
611
+ };
612
+ }
613
+ }
614
+ async function updateCLI(packageName, preferredManager) {
615
+ const packageManager = preferredManager ? normalizePackageManager(preferredManager) : detectPackageManager();
616
+ const { command, args } = getUpdateCommand(packageName, packageManager);
617
+ logger.info(`Updating ${packageName} with ${packageManager}...`);
618
+ logger.log("");
619
+ try {
620
+ await execa4(command, args, {
621
+ cwd: process.cwd(),
622
+ stdio: "inherit"
623
+ });
624
+ logger.success(`${packageName} has been updated to the latest version`);
625
+ } catch (error) {
626
+ throw error;
627
+ }
628
+ }
629
+
557
630
  // src/utils/cats.ts
558
631
  import os from "os";
559
632
  var cats = [
@@ -618,8 +691,22 @@ Today is ${date}`;
618
691
  }
619
692
 
620
693
  // src/cli.ts
621
- var VERSION = "1.0.0";
622
- async function executeTemplate(template, projectName, shouldOverwrite) {
694
+ var require2 = createRequire(import.meta.url);
695
+ var packageJson = require2("../package.json");
696
+ var PACKAGE_NAME = packageJson.name;
697
+ var VERSION = packageJson.version;
698
+ var DEFAULT_PROJECT_NAME = "my-project";
699
+ var DEFAULT_TEMPLATE = "vite";
700
+ var AVAILABLE_TEMPLATES = templates.map((template) => template.value);
701
+ function resolveGitOption(argv = process.argv) {
702
+ const gitIndex = argv.lastIndexOf("--git");
703
+ const noGitIndex = argv.lastIndexOf("--no-git");
704
+ if (gitIndex === -1 && noGitIndex === -1) {
705
+ return void 0;
706
+ }
707
+ return gitIndex > noGitIndex;
708
+ }
709
+ async function executeTemplate(template, projectName, shouldOverwrite, options) {
623
710
  if (shouldOverwrite) {
624
711
  logger.info(`Removing existing directory ${projectName}...`);
625
712
  await removeDirectory(projectName);
@@ -629,12 +716,18 @@ async function executeTemplate(template, projectName, shouldOverwrite) {
629
716
  logger.error("Template repository not configured");
630
717
  process.exit(1);
631
718
  }
632
- const initGit = await promptInitGit();
719
+ const initGit = options.git ?? (options.yes ? true : await promptInitGit());
633
720
  await cloneRepo(template.repo, projectName, { initGit });
634
721
  printSuccessMessage(projectName);
635
722
  } else if (template.type === "vite") {
723
+ if (options.git !== void 0) {
724
+ logger.warning("`--git` and `--no-git` only apply to Git starter templates");
725
+ }
636
726
  await createViteProject(projectName);
637
727
  } else if (template.type === "next") {
728
+ if (options.git !== void 0) {
729
+ logger.warning("`--git` and `--no-git` only apply to Git starter templates");
730
+ }
638
731
  await createNextProject(projectName);
639
732
  }
640
733
  }
@@ -653,32 +746,105 @@ function printBanner() {
653
746
  console.log(chalk4.cyan(catSay(getGreetingMessage())));
654
747
  console.log();
655
748
  }
749
+ function printTemplateList() {
750
+ logger.log(chalk4.cyan("Available templates:"));
751
+ logger.log("");
752
+ for (const template of templates) {
753
+ logger.log(
754
+ ` ${chalk4.yellow(template.value.padEnd(14))} ${template.name.padEnd(22)} ${template.description}`
755
+ );
756
+ }
757
+ logger.log("");
758
+ }
759
+ function getDefaultTemplate() {
760
+ const template = getTemplateByValue(DEFAULT_TEMPLATE);
761
+ if (!template) {
762
+ throw new Error(`Default template not found: ${DEFAULT_TEMPLATE}`);
763
+ }
764
+ return template;
765
+ }
766
+ async function resolveProjectTarget(projectName, options) {
767
+ if (!checkDirectoryExists(projectName)) {
768
+ return {
769
+ projectName,
770
+ shouldOverwrite: false
771
+ };
772
+ }
773
+ if (options.force) {
774
+ return {
775
+ projectName,
776
+ shouldOverwrite: true
777
+ };
778
+ }
779
+ if (options.yes) {
780
+ return {
781
+ projectName: generateUniqueProjectName(projectName),
782
+ shouldOverwrite: false
783
+ };
784
+ }
785
+ return resolveProjectName(projectName);
786
+ }
656
787
  async function run() {
657
788
  const program = new Command();
658
- program.name("create-for-yeyu").description("A CLI tool to scaffold projects from templates").version(VERSION).argument("[project-name]", "Project name").option(
659
- "-t, --template <template>",
660
- "Specify template (nest, evm-dapp, vite, next)"
661
- ).action(async (projectName, options) => {
662
- printBanner();
663
- try {
664
- let inputProjectName = projectName;
665
- let template;
666
- if (!inputProjectName) {
667
- inputProjectName = await promptProjectName();
789
+ program.name(PACKAGE_NAME).description("A CLI tool to scaffold projects from templates").version(VERSION, "-v, --version", "Display the current version").helpOption("-h, --help", "Display help for command").showHelpAfterError().showSuggestionAfterError().configureHelp({
790
+ sortOptions: true,
791
+ sortSubcommands: true
792
+ }).addHelpText(
793
+ "after",
794
+ `
795
+ Examples:
796
+ $ ${PACKAGE_NAME} my-app --template vite
797
+ $ ${PACKAGE_NAME} my-app --template next-web-app --no-git
798
+ $ ${PACKAGE_NAME} --list-templates
799
+ $ ${PACKAGE_NAME} update --manager pnpm
800
+ `
801
+ ).argument("[project-name]", "Project name").addOption(
802
+ new Option("-t, --template <template>", "Specify template").choices(
803
+ AVAILABLE_TEMPLATES
804
+ )
805
+ ).option("-f, --force", "Overwrite an existing directory without prompting").option("--git", "Always initialize git when the selected template supports it").option(
806
+ "--no-git",
807
+ "Skip git initialization when the selected template supports it"
808
+ ).option(
809
+ "-y, --yes",
810
+ `Use defaults when possible (${DEFAULT_PROJECT_NAME}, ${DEFAULT_TEMPLATE})`
811
+ ).option("--list-templates", "Print available templates and exit").option("--no-banner", "Disable the welcome banner").action(
812
+ async (projectName, options) => {
813
+ if (options.listTemplates) {
814
+ printTemplateList();
815
+ return;
668
816
  }
669
- const { projectName: resolvedName, shouldOverwrite } = await resolveProjectName(inputProjectName);
670
- if (options.template) {
671
- const foundTemplate = getTemplateByValue(options.template);
672
- if (!foundTemplate) {
673
- logger.error(`Template not found: ${options.template}`);
674
- logger.info("Available templates: nest, evm-dapp, vite, next");
675
- process.exit(1);
817
+ if (options.banner) {
818
+ printBanner();
819
+ }
820
+ try {
821
+ const gitOption = resolveGitOption(process.argv);
822
+ const inputProjectName = projectName ?? (options.yes ? DEFAULT_PROJECT_NAME : await promptProjectName());
823
+ const { projectName: resolvedName, shouldOverwrite } = await resolveProjectTarget(inputProjectName, options);
824
+ const template = options.template !== void 0 ? getTemplateByValue(options.template) : options.yes ? getDefaultTemplate() : await promptTemplate();
825
+ if (!template) {
826
+ throw new Error("Selected template is not available");
676
827
  }
677
- template = foundTemplate;
678
- } else {
679
- template = await promptTemplate();
828
+ await executeTemplate(template, resolvedName, shouldOverwrite, {
829
+ git: gitOption,
830
+ yes: options.yes ?? false
831
+ });
832
+ } catch (error) {
833
+ if (error instanceof Error) {
834
+ logger.error(error.message);
835
+ }
836
+ process.exit(1);
680
837
  }
681
- await executeTemplate(template, resolvedName, shouldOverwrite);
838
+ }
839
+ );
840
+ program.command("update").description(`Update ${PACKAGE_NAME} to the latest version`).addOption(
841
+ new Option(
842
+ "-m, --manager <manager>",
843
+ "Package manager to use for the update"
844
+ ).choices(getSupportedPackageManagers())
845
+ ).action(async (options) => {
846
+ try {
847
+ await updateCLI(PACKAGE_NAME, options.manager);
682
848
  } catch (error) {
683
849
  if (error instanceof Error) {
684
850
  logger.error(error.message);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-for-yeyu",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "A CLI tool to scaffold projects from templates",
5
5
  "type": "module",
6
6
  "bin": {
@@ -17,24 +17,23 @@
17
17
  "author": "yeyu",
18
18
  "license": "MIT",
19
19
  "dependencies": {
20
- "@inquirer/core": "^11.1.1",
21
- "@inquirer/prompts": "^7.2.1",
22
- "@inquirer/type": "^4.0.3",
20
+ "@inquirer/core": "^11.1.8",
21
+ "@inquirer/prompts": "^8.4.1",
22
+ "@inquirer/type": "^4.0.5",
23
23
  "chalk": "^5.3.0",
24
- "commander": "^14.0.2",
24
+ "commander": "^14.0.3",
25
25
  "degit": "^2.8.4",
26
26
  "execa": "^9.6.1",
27
- "fs-extra": "^11.2.0",
28
- "ora": "^9.0.0"
27
+ "fs-extra": "^11.3.4",
28
+ "ora": "^9.3.0"
29
29
  },
30
30
  "devDependencies": {
31
- "@changesets/cli": "^2.29.8",
32
- "@types/chalk": "^2.2.4",
31
+ "@changesets/cli": "^2.30.0",
33
32
  "@types/degit": "^2.8.6",
34
33
  "@types/fs-extra": "^11.0.4",
35
- "@types/node": "^20.11.0",
34
+ "@types/node": "^25.5.2",
36
35
  "tsup": "^8.0.1",
37
- "typescript": "^5.3.3"
36
+ "typescript": "^6.0.2"
38
37
  },
39
38
  "engines": {
40
39
  "node": ">=18"