create-for-yeyu 3.2.1 → 3.4.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 +57 -0
  2. package/dist/index.js +200 -27
  3. package/package.json +1 -2
package/README.md CHANGED
@@ -49,6 +49,9 @@ npx create-for-yeyu my-project --template next-web-app
49
49
  # 使用 EVM DApp 模板
50
50
  npx create-for-yeyu my-project --template evm-dapp
51
51
 
52
+ # 使用 Hono App 模板
53
+ npx create-for-yeyu my-project --template hono
54
+
52
55
  # 使用 Vite 创建项目
53
56
  npx create-for-yeyu my-project --template vite
54
57
 
@@ -56,6 +59,56 @@ npx create-for-yeyu my-project --template vite
56
59
  npx create-for-yeyu my-project --template next
57
60
  ```
58
61
 
62
+ ### 常用选项
63
+
64
+ ```bash
65
+ # 查看版本
66
+ npx create-for-yeyu -v
67
+ npx create-for-yeyu --version
68
+
69
+ # 查看所有可用模板
70
+ npx create-for-yeyu --list-templates
71
+
72
+ # 使用默认值快速创建
73
+ # 默认项目名: my-project
74
+ # 默认模板: vite
75
+ npx create-for-yeyu --yes
76
+
77
+ # 目录已存在时直接覆盖
78
+ npx create-for-yeyu my-project --template next --force
79
+
80
+ # 关闭欢迎 Banner
81
+ npx create-for-yeyu my-project --template vite --no-banner
82
+
83
+ # Git 模板跳过 git 初始化
84
+ npx create-for-yeyu my-project --template nest --no-git
85
+ ```
86
+
87
+ ### 更新 CLI
88
+
89
+ ```bash
90
+ # 自动检测当前包管理器并更新到最新版本
91
+ create-for-yeyu update
92
+
93
+ # 指定包管理器更新
94
+ create-for-yeyu update --manager pnpm
95
+ create-for-yeyu update --manager npm
96
+ ```
97
+
98
+ ## 命令选项
99
+
100
+ | 选项 | 说明 |
101
+ | ---- | ---- |
102
+ | `-v, --version` | 显示当前 CLI 版本 |
103
+ | `-h, --help` | 显示帮助信息 |
104
+ | `-t, --template <template>` | 指定模板 |
105
+ | `-f, --force` | 目标目录已存在时直接覆盖 |
106
+ | `-y, --yes` | 尽可能使用默认值,跳过交互 |
107
+ | `--git` | Git 模板直接初始化仓库 |
108
+ | `--no-git` | Git 模板跳过仓库初始化 |
109
+ | `--list-templates` | 输出所有可用模板并退出 |
110
+ | `--no-banner` | 不显示欢迎 Banner |
111
+
59
112
  ## 可用模板
60
113
 
61
114
  | 模板名称 | 命令参数 | 说明 |
@@ -63,6 +116,7 @@ npx create-for-yeyu my-project --template next
63
116
  | NestJS Starter | `nest` | NestJS 应用启动模板 |
64
117
  | Next Web App Starter | `next-web-app` | Next Web App 启动模板 |
65
118
  | EVM DApp Starter | `evm-dapp` | EVM DApp 启动模板 |
119
+ | Hono App Starter | `hono` | Hono 应用启动模板 |
66
120
  | Vite | `vite` | 使用 Vite 官方模板 |
67
121
  | Next.js | `next` | 使用 Create Next App |
68
122
 
@@ -97,6 +151,9 @@ pnpm build
97
151
 
98
152
  # 本地测试运行
99
153
  pnpm start
154
+
155
+ # 查看帮助
156
+ pnpm start -- --help
100
157
  ```
101
158
 
102
159
  ## 项目结构
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
@@ -30,6 +31,13 @@ var templates = [
30
31
  type: "git",
31
32
  repo: "for-yeyu/evm-dapp-starter-for-yeyu"
32
33
  },
34
+ {
35
+ name: "Hono App Starter",
36
+ value: "hono",
37
+ description: "Hono application starter template",
38
+ type: "git",
39
+ repo: "for-yeyu/hono-app-starter-for-yeyu"
40
+ },
33
41
  {
34
42
  name: "Vite",
35
43
  value: "vite",
@@ -461,11 +469,11 @@ async function updatePackageJsonName(targetPath, projectName) {
461
469
  try {
462
470
  const packageJsonPath = path2.join(targetPath, "package.json");
463
471
  const packageJsonContent = await fsExtra.readFile(packageJsonPath, "utf-8");
464
- const packageJson = JSON.parse(packageJsonContent);
472
+ const packageJson2 = JSON.parse(packageJsonContent);
465
473
  const newPackageJson = {
466
474
  name: projectName
467
475
  };
468
- for (const [key, value] of Object.entries(packageJson)) {
476
+ for (const [key, value] of Object.entries(packageJson2)) {
469
477
  if (key !== "name") {
470
478
  newPackageJson[key] = value;
471
479
  }
@@ -554,6 +562,78 @@ async function createNextProject(projectName) {
554
562
  }
555
563
  }
556
564
 
565
+ // src/actions/update-cli.ts
566
+ import { execa as execa4 } from "execa";
567
+ var SUPPORTED_PACKAGE_MANAGERS = ["npm", "pnpm", "yarn", "bun"];
568
+ function getSupportedPackageManagers() {
569
+ return SUPPORTED_PACKAGE_MANAGERS;
570
+ }
571
+ function isPackageManager(value) {
572
+ return SUPPORTED_PACKAGE_MANAGERS.includes(value);
573
+ }
574
+ function normalizePackageManager(value) {
575
+ const normalized = value.trim().toLowerCase();
576
+ if (!isPackageManager(normalized)) {
577
+ throw new Error(
578
+ `Unsupported package manager: ${value}. Use one of: ${SUPPORTED_PACKAGE_MANAGERS.join(", ")}`
579
+ );
580
+ }
581
+ return normalized;
582
+ }
583
+ function detectPackageManager() {
584
+ const userAgent = process.env.npm_config_user_agent ?? "";
585
+ if (userAgent.startsWith("pnpm")) {
586
+ return "pnpm";
587
+ }
588
+ if (userAgent.startsWith("yarn")) {
589
+ return "yarn";
590
+ }
591
+ if (userAgent.startsWith("bun")) {
592
+ return "bun";
593
+ }
594
+ return "npm";
595
+ }
596
+ function getUpdateCommand(packageName, packageManager) {
597
+ switch (packageManager) {
598
+ case "pnpm":
599
+ return {
600
+ command: "pnpm",
601
+ args: ["add", "-g", `${packageName}@latest`]
602
+ };
603
+ case "yarn":
604
+ return {
605
+ command: "yarn",
606
+ args: ["global", "add", `${packageName}@latest`]
607
+ };
608
+ case "bun":
609
+ return {
610
+ command: "bun",
611
+ args: ["add", "-g", `${packageName}@latest`]
612
+ };
613
+ case "npm":
614
+ default:
615
+ return {
616
+ command: "npm",
617
+ args: ["install", "-g", `${packageName}@latest`]
618
+ };
619
+ }
620
+ }
621
+ async function updateCLI(packageName, preferredManager) {
622
+ const packageManager = preferredManager ? normalizePackageManager(preferredManager) : detectPackageManager();
623
+ const { command, args } = getUpdateCommand(packageName, packageManager);
624
+ logger.info(`Updating ${packageName} with ${packageManager}...`);
625
+ logger.log("");
626
+ try {
627
+ await execa4(command, args, {
628
+ cwd: process.cwd(),
629
+ stdio: "inherit"
630
+ });
631
+ logger.success(`${packageName} has been updated to the latest version`);
632
+ } catch (error) {
633
+ throw error;
634
+ }
635
+ }
636
+
557
637
  // src/utils/cats.ts
558
638
  import os from "os";
559
639
  var cats = [
@@ -618,8 +698,22 @@ Today is ${date}`;
618
698
  }
619
699
 
620
700
  // src/cli.ts
621
- var VERSION = "1.0.0";
622
- async function executeTemplate(template, projectName, shouldOverwrite) {
701
+ var require2 = createRequire(import.meta.url);
702
+ var packageJson = require2("../package.json");
703
+ var PACKAGE_NAME = packageJson.name;
704
+ var VERSION = packageJson.version;
705
+ var DEFAULT_PROJECT_NAME = "my-project";
706
+ var DEFAULT_TEMPLATE = "vite";
707
+ var AVAILABLE_TEMPLATES = templates.map((template) => template.value);
708
+ function resolveGitOption(argv = process.argv) {
709
+ const gitIndex = argv.lastIndexOf("--git");
710
+ const noGitIndex = argv.lastIndexOf("--no-git");
711
+ if (gitIndex === -1 && noGitIndex === -1) {
712
+ return void 0;
713
+ }
714
+ return gitIndex > noGitIndex;
715
+ }
716
+ async function executeTemplate(template, projectName, shouldOverwrite, options) {
623
717
  if (shouldOverwrite) {
624
718
  logger.info(`Removing existing directory ${projectName}...`);
625
719
  await removeDirectory(projectName);
@@ -629,12 +723,18 @@ async function executeTemplate(template, projectName, shouldOverwrite) {
629
723
  logger.error("Template repository not configured");
630
724
  process.exit(1);
631
725
  }
632
- const initGit = await promptInitGit();
726
+ const initGit = options.git ?? (options.yes ? true : await promptInitGit());
633
727
  await cloneRepo(template.repo, projectName, { initGit });
634
728
  printSuccessMessage(projectName);
635
729
  } else if (template.type === "vite") {
730
+ if (options.git !== void 0) {
731
+ logger.warning("`--git` and `--no-git` only apply to Git starter templates");
732
+ }
636
733
  await createViteProject(projectName);
637
734
  } else if (template.type === "next") {
735
+ if (options.git !== void 0) {
736
+ logger.warning("`--git` and `--no-git` only apply to Git starter templates");
737
+ }
638
738
  await createNextProject(projectName);
639
739
  }
640
740
  }
@@ -653,32 +753,105 @@ function printBanner() {
653
753
  console.log(chalk4.cyan(catSay(getGreetingMessage())));
654
754
  console.log();
655
755
  }
756
+ function printTemplateList() {
757
+ logger.log(chalk4.cyan("Available templates:"));
758
+ logger.log("");
759
+ for (const template of templates) {
760
+ logger.log(
761
+ ` ${chalk4.yellow(template.value.padEnd(14))} ${template.name.padEnd(22)} ${template.description}`
762
+ );
763
+ }
764
+ logger.log("");
765
+ }
766
+ function getDefaultTemplate() {
767
+ const template = getTemplateByValue(DEFAULT_TEMPLATE);
768
+ if (!template) {
769
+ throw new Error(`Default template not found: ${DEFAULT_TEMPLATE}`);
770
+ }
771
+ return template;
772
+ }
773
+ async function resolveProjectTarget(projectName, options) {
774
+ if (!checkDirectoryExists(projectName)) {
775
+ return {
776
+ projectName,
777
+ shouldOverwrite: false
778
+ };
779
+ }
780
+ if (options.force) {
781
+ return {
782
+ projectName,
783
+ shouldOverwrite: true
784
+ };
785
+ }
786
+ if (options.yes) {
787
+ return {
788
+ projectName: generateUniqueProjectName(projectName),
789
+ shouldOverwrite: false
790
+ };
791
+ }
792
+ return resolveProjectName(projectName);
793
+ }
656
794
  async function run() {
657
795
  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();
796
+ 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({
797
+ sortOptions: true,
798
+ sortSubcommands: true
799
+ }).addHelpText(
800
+ "after",
801
+ `
802
+ Examples:
803
+ $ ${PACKAGE_NAME} my-app --template vite
804
+ $ ${PACKAGE_NAME} my-app --template next-web-app --no-git
805
+ $ ${PACKAGE_NAME} --list-templates
806
+ $ ${PACKAGE_NAME} update --manager pnpm
807
+ `
808
+ ).argument("[project-name]", "Project name").addOption(
809
+ new Option("-t, --template <template>", "Specify template").choices(
810
+ AVAILABLE_TEMPLATES
811
+ )
812
+ ).option("-f, --force", "Overwrite an existing directory without prompting").option("--git", "Always initialize git when the selected template supports it").option(
813
+ "--no-git",
814
+ "Skip git initialization when the selected template supports it"
815
+ ).option(
816
+ "-y, --yes",
817
+ `Use defaults when possible (${DEFAULT_PROJECT_NAME}, ${DEFAULT_TEMPLATE})`
818
+ ).option("--list-templates", "Print available templates and exit").option("--no-banner", "Disable the welcome banner").action(
819
+ async (projectName, options) => {
820
+ if (options.listTemplates) {
821
+ printTemplateList();
822
+ return;
668
823
  }
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);
824
+ if (options.banner) {
825
+ printBanner();
826
+ }
827
+ try {
828
+ const gitOption = resolveGitOption(process.argv);
829
+ const inputProjectName = projectName ?? (options.yes ? DEFAULT_PROJECT_NAME : await promptProjectName());
830
+ const { projectName: resolvedName, shouldOverwrite } = await resolveProjectTarget(inputProjectName, options);
831
+ const template = options.template !== void 0 ? getTemplateByValue(options.template) : options.yes ? getDefaultTemplate() : await promptTemplate();
832
+ if (!template) {
833
+ throw new Error("Selected template is not available");
676
834
  }
677
- template = foundTemplate;
678
- } else {
679
- template = await promptTemplate();
835
+ await executeTemplate(template, resolvedName, shouldOverwrite, {
836
+ git: gitOption,
837
+ yes: options.yes ?? false
838
+ });
839
+ } catch (error) {
840
+ if (error instanceof Error) {
841
+ logger.error(error.message);
842
+ }
843
+ process.exit(1);
680
844
  }
681
- await executeTemplate(template, resolvedName, shouldOverwrite);
845
+ }
846
+ );
847
+ program.command("update").description(`Update ${PACKAGE_NAME} to the latest version`).addOption(
848
+ new Option(
849
+ "-m, --manager <manager>",
850
+ "Package manager to use for the update"
851
+ ).choices(getSupportedPackageManagers())
852
+ ).action(async (options) => {
853
+ try {
854
+ await updateCLI(PACKAGE_NAME, options.manager);
682
855
  } catch (error) {
683
856
  if (error instanceof Error) {
684
857
  logger.error(error.message);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-for-yeyu",
3
- "version": "3.2.1",
3
+ "version": "3.4.0",
4
4
  "description": "A CLI tool to scaffold projects from templates",
5
5
  "type": "module",
6
6
  "bin": {
@@ -29,7 +29,6 @@
29
29
  },
30
30
  "devDependencies": {
31
31
  "@changesets/cli": "^2.30.0",
32
- "@types/chalk": "^2.2.4",
33
32
  "@types/degit": "^2.8.6",
34
33
  "@types/fs-extra": "^11.0.4",
35
34
  "@types/node": "^25.5.2",