create-for-yeyu 3.2.1 → 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.
- package/README.md +53 -0
- package/dist/index.js +193 -27
- package/package.json +1 -2
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 {
|
|
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
|
|
465
|
+
const packageJson2 = JSON.parse(packageJsonContent);
|
|
465
466
|
const newPackageJson = {
|
|
466
467
|
name: projectName
|
|
467
468
|
};
|
|
468
|
-
for (const [key, value] of Object.entries(
|
|
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
|
|
622
|
-
|
|
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(
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
).
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
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
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
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
|
|
678
|
-
|
|
679
|
-
|
|
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
|
-
|
|
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.
|
|
3
|
+
"version": "3.3.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",
|