@syzlm/scaffold-cli 1.0.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/dist/git.js ADDED
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.cloneGitTemplate = cloneGitTemplate;
7
+ const simple_git_1 = require("simple-git");
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const path_1 = __importDefault(require("path"));
10
+ async function cloneGitTemplate(gitUrl, targetDir) {
11
+ // 检查目标目录是否存在
12
+ if (fs_extra_1.default.existsSync(targetDir)) {
13
+ throw new Error(`目录 ${targetDir} 已存在,请选择其他目录或删除现有目录`);
14
+ }
15
+ try {
16
+ console.log(`正在从 ${gitUrl} 克隆模板...`);
17
+ // 创建临时目录用于克隆
18
+ const tempDir = path_1.default.join(targetDir, ".git-template-temp");
19
+ fs_extra_1.default.mkdirpSync(tempDir);
20
+ // 克隆仓库
21
+ await (0, simple_git_1.simpleGit)(tempDir).clone(gitUrl, tempDir, {
22
+ "--depth": "1", // 只克隆最新版本,减少下载时间
23
+ });
24
+ // 移动文件到目标目录,排除.git目录
25
+ const tempFiles = fs_extra_1.default.readdirSync(tempDir);
26
+ fs_extra_1.default.mkdirpSync(targetDir);
27
+ for (const file of tempFiles) {
28
+ if (file !== ".git") {
29
+ const sourcePath = path_1.default.join(tempDir, file);
30
+ const destPath = path_1.default.join(targetDir, file);
31
+ fs_extra_1.default.moveSync(sourcePath, destPath);
32
+ }
33
+ }
34
+ // 删除临时目录
35
+ fs_extra_1.default.removeSync(tempDir);
36
+ console.log("模板克隆成功!");
37
+ }
38
+ catch (error) {
39
+ console.error("Git克隆失败:", error);
40
+ throw error;
41
+ }
42
+ }
package/dist/index.js ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const child_process_1 = require("child_process");
8
+ const path_1 = __importDefault(require("path"));
9
+ const process_1 = __importDefault(require("process"));
10
+ // 1. 获取子命令(即命令行中 syzlm 后面的第一个参数,此处为 scaffold)
11
+ const subCommand = process_1.default.argv[2];
12
+ // 2. 剩余参数(传递给子命令)
13
+ const subCommandArgs = process_1.default.argv.slice(3);
14
+ // 3. 校验子命令是否存在
15
+ const subCommandPath = path_1.default.resolve(__dirname, `syzlm/${subCommand}.js`);
16
+ try {
17
+ // 4. 调用子命令(用 child_process.spawn 执行子命令文件,继承终端输入输出)
18
+ const childProcess = (0, child_process_1.spawn)("node", [subCommandPath, ...subCommandArgs], {
19
+ stdio: "inherit", // 关键:让子命令的日志、交互直接输出到终端
20
+ cwd: process_1.default.cwd(), // 保持当前工作目录不变
21
+ });
22
+ // 5. 监听子命令执行结束
23
+ childProcess.on("close", (code) => {
24
+ process_1.default.exit(code);
25
+ });
26
+ }
27
+ catch (er) {
28
+ console.error(`错误:不存在子命令 "${subCommand}",仅支持 scaffold 命令`);
29
+ process_1.default.exit(1);
30
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.installDependencies = installDependencies;
7
+ const execa_1 = require("execa");
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const path_1 = __importDefault(require("path"));
10
+ async function installDependencies(projectDir) {
11
+ // 检查是否存在package.json文件
12
+ const packageJsonPath = path_1.default.join(projectDir, 'package.json');
13
+ if (!fs_extra_1.default.existsSync(packageJsonPath)) {
14
+ console.log('未找到package.json文件,跳过依赖安装');
15
+ return;
16
+ }
17
+ try {
18
+ console.log('正在安装依赖...');
19
+ // 检测pnpm是否可用
20
+ let hasPnpm = false;
21
+ try {
22
+ await (0, execa_1.execa)('pnpm', ['--version'], { stdio: 'ignore' });
23
+ hasPnpm = true;
24
+ }
25
+ catch {
26
+ hasPnpm = false;
27
+ }
28
+ // 执行安装命令
29
+ if (hasPnpm) {
30
+ console.log('使用pnpm安装依赖...');
31
+ await (0, execa_1.execa)('pnpm', ['install'], {
32
+ cwd: projectDir,
33
+ stdio: 'inherit'
34
+ });
35
+ }
36
+ else {
37
+ console.log('pnpm不可用,使用npm安装依赖...');
38
+ await (0, execa_1.execa)('npm', ['install'], {
39
+ cwd: projectDir,
40
+ stdio: 'inherit'
41
+ });
42
+ }
43
+ console.log('依赖安装完成!');
44
+ }
45
+ catch (error) {
46
+ console.error('依赖安装失败:', error);
47
+ throw error;
48
+ }
49
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.interactivePrompt = interactivePrompt;
7
+ const inquirer_1 = __importDefault(require("inquirer"));
8
+ async function interactivePrompt() {
9
+ const answers = await inquirer_1.default.prompt([
10
+ {
11
+ type: "input",
12
+ name: "projectName",
13
+ message: "请输入项目名称:",
14
+ default: "my-project",
15
+ validate: (value) => {
16
+ if (value.trim() === "") {
17
+ return "项目名称不能为空";
18
+ }
19
+ return true;
20
+ },
21
+ },
22
+ {
23
+ type: "input",
24
+ name: "gitUrl",
25
+ message: "请输入Git模板仓库地址:",
26
+ validate: (value) => {
27
+ if (value.trim() === "") {
28
+ return "Git地址不能为空";
29
+ }
30
+ return true;
31
+ },
32
+ default: "https://gitee.com/xunyu/mini-program-scaffold.git",
33
+ },
34
+ {
35
+ type: "input",
36
+ name: "description",
37
+ message: "请输入项目描述:",
38
+ default: "我的小程序",
39
+ },
40
+ {
41
+ type: "input",
42
+ name: "appid",
43
+ message: "请输入小程序appid:",
44
+ default: "wx745e1806f98fbee9",
45
+ },
46
+ {
47
+ type: "confirm",
48
+ name: "installDependencies",
49
+ message: "是否自动安装依赖?",
50
+ default: true,
51
+ },
52
+ ]);
53
+ return answers;
54
+ }
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const path_1 = __importDefault(require("path"));
8
+ const interactive_1 = require("./interactive");
9
+ const git_1 = require("./git");
10
+ const template_1 = require("./template");
11
+ const installer_1 = require("./installer");
12
+ const dayjs_1 = __importDefault(require("dayjs"));
13
+ async function main() {
14
+ console.log("============================================");
15
+ console.log("欢迎使用 @syzlm/scaffold-cli 脚手架工具");
16
+ console.log("============================================");
17
+ try {
18
+ // 获取用户输入
19
+ const options = await (0, interactive_1.interactivePrompt)();
20
+ // 计算项目目录路径
21
+ const projectDir = path_1.default.join(process.cwd(), options.projectName);
22
+ // 克隆Git模板
23
+ await (0, git_1.cloneGitTemplate)(options.gitUrl, projectDir);
24
+ // 处理模板变量
25
+ const templateVariables = {
26
+ projectName: options.projectName,
27
+ description: options.description,
28
+ appid: options.appid,
29
+ date: (0, dayjs_1.default)().format("YYYY-MM-DD"),
30
+ };
31
+ await (0, template_1.processTemplateFiles)(projectDir, templateVariables);
32
+ // 安装依赖
33
+ if (options.installDependencies) {
34
+ await (0, installer_1.installDependencies)(projectDir);
35
+ }
36
+ console.log("============================================");
37
+ console.log("项目创建成功!");
38
+ console.log(`项目目录: ${projectDir}`);
39
+ console.log("============================================");
40
+ console.log("您可以使用以下命令启动项目:");
41
+ console.log(`cd ${options.projectName}`);
42
+ console.log("pnpm dev");
43
+ }
44
+ catch (error) {
45
+ console.error("============================================");
46
+ console.error("项目创建失败:", error);
47
+ console.error("============================================");
48
+ process.exit(1);
49
+ }
50
+ }
51
+ // 执行主函数
52
+ main();
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.processTemplateFiles = processTemplateFiles;
7
+ const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const ejs_1 = __importDefault(require("ejs"));
10
+ // 需要进行模板替换的文件扩展名
11
+ const TEMPLATE_EXTENSIONS = [
12
+ ".json",
13
+ ".ts",
14
+ ".js",
15
+ ".tsx",
16
+ ".md",
17
+ ".html",
18
+ ".css",
19
+ ".scss",
20
+ ".yaml",
21
+ ".yml",
22
+ ];
23
+ // 需要忽略的文件和目录
24
+ const IGNORE_PATTERNS = [
25
+ "node_modules",
26
+ ".git",
27
+ ".gitignore",
28
+ ".DS_Store",
29
+ "dist",
30
+ "build",
31
+ ];
32
+ async function processTemplateFiles(directory, variables) {
33
+ console.log("正在处理模板变量...");
34
+ async function processFile(filePath) {
35
+ const ext = path_1.default.extname(filePath);
36
+ // 检查文件扩展名是否需要处理
37
+ if (TEMPLATE_EXTENSIONS.includes(ext)) {
38
+ try {
39
+ const content = await fs_extra_1.default.readFile(filePath, "utf-8");
40
+ const processedContent = ejs_1.default.render(content, variables, {
41
+ delimiter: "%",
42
+ escape: (str) => str,
43
+ });
44
+ await fs_extra_1.default.writeFile(filePath, processedContent, "utf-8");
45
+ console.log(`已处理文件: ${filePath}`);
46
+ }
47
+ catch (error) {
48
+ console.error(`处理文件 ${filePath} 时出错:`, error);
49
+ }
50
+ }
51
+ }
52
+ async function processDirectory(dirPath) {
53
+ const entries = await fs_extra_1.default.readdir(dirPath, { withFileTypes: true });
54
+ for (const entry of entries) {
55
+ const fullPath = path_1.default.join(dirPath, entry.name);
56
+ // 检查是否需要忽略
57
+ if (IGNORE_PATTERNS.includes(entry.name)) {
58
+ continue;
59
+ }
60
+ if (entry.isDirectory()) {
61
+ await processDirectory(fullPath);
62
+ }
63
+ else {
64
+ await processFile(fullPath);
65
+ }
66
+ }
67
+ }
68
+ await processDirectory(directory);
69
+ console.log("模板变量处理完成!");
70
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@syzlm/scaffold-cli",
3
+ "version": "1.0.0",
4
+ "main": "dist/index.js",
5
+ "bin": {
6
+ "syzlm": "dist/index.js"
7
+ },
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "dev": "ts-node src/index.ts",
11
+ "lint": "eslint src --ext .ts",
12
+ "format": "prettier --write src",
13
+ "test": "echo \"Error: no test specified\" && exit 1"
14
+ },
15
+ "keywords": [
16
+ "scaffold",
17
+ "cli",
18
+ "template",
19
+ "typescript"
20
+ ],
21
+ "files": [
22
+ "dist",
23
+ "package.json"
24
+ ],
25
+ "author": "",
26
+ "license": "ISC",
27
+ "description": "A scaffold tool for quickly creating Node.js + TypeScript projects",
28
+ "type": "commonjs",
29
+ "dependencies": {
30
+ "dayjs": "^1.11.19",
31
+ "ejs": "^3.1.10",
32
+ "execa": "^9.6.1",
33
+ "fs-extra": "^11.3.3",
34
+ "inquirer": "^13.1.0",
35
+ "simple-git": "^3.30.0"
36
+ },
37
+ "devDependencies": {
38
+ "@eslint/js": "^9.39.2",
39
+ "@types/ejs": "^3.1.5",
40
+ "@types/fs-extra": "^11.0.4",
41
+ "@types/inquirer": "^9.0.9",
42
+ "@types/node": "^25.0.3",
43
+ "@typescript-eslint/eslint-plugin": "^8.52.0",
44
+ "@typescript-eslint/parser": "^8.52.0",
45
+ "eslint": "^9.39.2",
46
+ "eslint-config-prettier": "^10.1.8",
47
+ "eslint-plugin-prettier": "^5.5.4",
48
+ "globals": "^17.0.0",
49
+ "jiti": "^2.6.1",
50
+ "prettier": "^3.7.4",
51
+ "ts-node": "^10.9.2",
52
+ "typescript": "^5.9.3",
53
+ "typescript-eslint": "^8.52.0"
54
+ }
55
+ }