@qingtian/qtcli 1.0.5 → 1.0.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qingtian/qtcli",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "QTCli是一款基于node的前端工程化底座",
5
5
  "homepage": "https://gitee.com/fengrengame/qtnode#readme",
6
6
  "bugs": {
@@ -45,6 +45,8 @@ var inquirer_1 = __importDefault(require("inquirer"));
45
45
  var context_1 = require("../cores/context");
46
46
  var contextModel_1 = require("../types/contextModel");
47
47
  var logger_1 = require("../utils/logger");
48
+ var printer_1 = require("../utils/printer");
49
+ var templates_1 = require("../config/templates");
48
50
  exports.default = (function () {
49
51
  var heat = new commander_1.default.Command('init');
50
52
  heat
@@ -52,37 +54,23 @@ exports.default = (function () {
52
54
  .option('-n, --name <type>', '项目名字')
53
55
  .option('-t, --template <type>', '模板名字')
54
56
  .action(function (options, cmd) { return __awaiter(void 0, void 0, void 0, function () {
55
- var promptList, c, defaultTarName, promptList, c, cm;
57
+ var choices, promptList, c, defaultTarName, promptList, c, cm;
56
58
  return __generator(this, function (_a) {
57
59
  switch (_a.label) {
58
60
  case 0:
59
61
  if (!!options.template) return [3 /*break*/, 2];
62
+ choices = templates_1.templates.map(function (t, i) { return ({
63
+ key: "".concat(i + 1),
64
+ name: "".concat(t.name, " \u300C").concat(t.description, "\u300D [").concat(t.techStack.join(' + '), "]"),
65
+ value: t.name,
66
+ }); });
60
67
  promptList = [
61
68
  {
62
69
  type: 'list',
63
70
  message: '请选择模板',
64
71
  name: 'template',
65
72
  default: '1',
66
- choices: [
67
- {
68
- key: '1',
69
- name: 'react 「一个标准的React工程模板」',
70
- value: 'react',
71
- },
72
- {
73
- key: '2',
74
- name: 'Commponent 「一个标准的创建组件的工程模板」',
75
- value: 'Commponent',
76
- },
77
- {
78
- key: '3',
79
- name: 'Library 「一个标准的创建库工程模板」',
80
- value: 'Library',
81
- },
82
- ],
83
- filter: function (val) {
84
- return val.toLowerCase();
85
- },
73
+ choices: choices,
86
74
  },
87
75
  ];
88
76
  (0, logger_1.logStart)();
@@ -102,6 +90,12 @@ exports.default = (function () {
102
90
  message: '请输入项目的名称',
103
91
  name: 'name',
104
92
  default: defaultTarName,
93
+ validate: function (val) {
94
+ if (!/^[a-zA-Z0-9_-]+$/.test(val)) {
95
+ return '项目名只能包含字母、数字、连字符(-)和下划线(_)';
96
+ }
97
+ return true;
98
+ },
105
99
  filter: function (val) {
106
100
  return val.toLowerCase();
107
101
  },
@@ -115,6 +109,11 @@ exports.default = (function () {
115
109
  options.name = c;
116
110
  _a.label = 4;
117
111
  case 4:
112
+ // 通过命令行参数传入的名称也需要校验
113
+ if (!/^[a-zA-Z0-9_-]+$/.test(options.name)) {
114
+ printer_1.printer.error('项目名只能包含字母、数字、连字符(-)和下划线(_)');
115
+ return [2 /*return*/];
116
+ }
118
117
  cm = new contextModel_1.ContextModel();
119
118
  cm.cmd = cmd.name();
120
119
  cm.proxy = cmd.name();
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.templates = void 0;
4
+ exports.templates = [
5
+ {
6
+ name: 'react',
7
+ description: '一个标准的React工程模板',
8
+ techStack: ['typescript', 'react'],
9
+ source: 'react.zip',
10
+ },
11
+ {
12
+ name: 'component',
13
+ description: '一个标准的创建组件的工程模板',
14
+ techStack: ['typescript', 'react'],
15
+ source: 'component.zip',
16
+ },
17
+ {
18
+ name: 'library',
19
+ description: '一个标准的创建库工程模板',
20
+ techStack: ['typescript'],
21
+ source: 'library.zip',
22
+ },
23
+ ];
@@ -41,47 +41,145 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
42
  var printer_1 = require("../../utils/printer");
43
43
  var childProcess_1 = require("../../utils/childProcess");
44
+ var formatOutput_1 = require("../../utils/formatOutput");
44
45
  var fileUtils_1 = require("../../utils/fileUtils");
46
+ var inquirer_1 = __importDefault(require("inquirer"));
45
47
  var path_1 = __importDefault(require("path"));
48
+ var fs_1 = __importDefault(require("fs"));
49
+ var templates_1 = require("../../config/templates");
46
50
  var fun = function (opts) { return __awaiter(void 0, void 0, void 0, function () {
47
51
  return __generator(this, function (_a) {
48
52
  return [2 /*return*/, new Promise(function (resolve, reject) { return __awaiter(void 0, void 0, void 0, function () {
49
- var _a, template, name_1, zipPath, targetPath, c, err_1;
53
+ var _a, template_1, name_1, tplConfig, zipPath, targetPath, projectInfo, pkgPath, pkgContent, guideContent, err_1;
50
54
  return __generator(this, function (_b) {
51
55
  switch (_b.label) {
52
56
  case 0:
53
57
  if (opts.config) {
54
58
  printer_1.printer.error("\u5F53\u524D\u76EE\u5F55\u4E0D\u53EF\u6267\u884C\u300Cinit\u300D\uFF08".concat(process.cwd(), "\uFF09"));
55
59
  reject(new Error("\u5F53\u524D\u76EE\u5F55\u4E0D\u53EF\u6267\u884C\u300Cinit\u300D(".concat(process.cwd(), ")")));
60
+ return [2 /*return*/];
56
61
  }
57
62
  _b.label = 1;
58
63
  case 1:
59
- _b.trys.push([1, 5, , 6]);
60
- _a = opts === null || opts === void 0 ? void 0 : opts.argsCmd, template = _a.template, name_1 = _a.name;
61
- printer_1.printer.info("\u6B63\u5728\u521B\u5EFA\u4EE5\u300C".concat(template, "\u300D\u4E3A\u6A21\u677F\u7684\u9879\u76EE\u300C").concat(name_1, "\u300D..."));
62
- zipPath = "".concat(path_1.default.join(__dirname, "../../statics/".concat(template, ".zip")));
63
- targetPath = "".concat(path_1.default.join(opts.rootDir, "./".concat(name_1)));
64
+ _b.trys.push([1, 10, , 11]);
65
+ _a = opts === null || opts === void 0 ? void 0 : opts.argsCmd, template_1 = _a.template, name_1 = _a.name;
66
+ tplConfig = templates_1.templates.find(function (t) { return t.name === template_1; });
67
+ if (!tplConfig) {
68
+ printer_1.printer.error("\u672A\u627E\u5230\u6A21\u677F\u300C".concat(template_1, "\u300D\u7684\u914D\u7F6E"));
69
+ reject(new Error("\u672A\u627E\u5230\u6A21\u677F\u914D\u7F6E: ".concat(template_1)));
70
+ return [2 /*return*/];
71
+ }
72
+ zipPath = path_1.default.join(__dirname, "../../statics/".concat(tplConfig.source));
73
+ targetPath = path_1.default.join(opts.rootDir, "./".concat(name_1));
74
+ // 检查目标目录是否已存在
75
+ if (fs_1.default.existsSync(targetPath)) {
76
+ printer_1.printer.error("\u76EE\u6807\u76EE\u5F55\u300C".concat(targetPath, "\u300D\u5DF2\u5B58\u5728\uFF0C\u8BF7\u66F4\u6362\u9879\u76EE\u540D\u79F0\u6216\u5220\u9664\u5DF2\u6709\u76EE\u5F55"));
77
+ reject(new Error("\u76EE\u6807\u76EE\u5F55\u5DF2\u5B58\u5728: ".concat(targetPath)));
78
+ return [2 /*return*/];
79
+ }
80
+ // 创建项目
81
+ console.log((0, formatOutput_1.formatNode)({
82
+ type: 'process',
83
+ title: '创建项目',
84
+ content: "\u6B63\u5728\u521B\u5EFA\u4EE5\u300C".concat(template_1, "\u300D\u4E3A\u6A21\u677F\u7684\u9879\u76EE\u300C").concat(name_1, "\u300D..."),
85
+ }));
64
86
  return [4 /*yield*/, (0, fileUtils_1.unzip)(zipPath, targetPath)];
65
87
  case 2:
66
88
  _b.sent();
67
- printer_1.printer.info('创建完成!');
68
- printer_1.printer.info("\u521D\u59CB\u5316...");
69
- return [4 /*yield*/, (0, childProcess_1.execPromise)("which npm ", {}, false)];
89
+ return [4 /*yield*/, inquirer_1.default.prompt([
90
+ {
91
+ type: 'input',
92
+ name: 'description',
93
+ message: '请输入项目描述(直接回车跳过)',
94
+ },
95
+ {
96
+ type: 'input',
97
+ name: 'author',
98
+ message: '请输入作者名称(直接回车跳过)',
99
+ },
100
+ {
101
+ type: 'input',
102
+ name: 'email',
103
+ message: '请输入作者邮箱(直接回车跳过)',
104
+ },
105
+ {
106
+ type: 'input',
107
+ name: 'gitUrl',
108
+ message: '请输入 Git 远程仓库地址(直接回车跳过)',
109
+ },
110
+ ])];
70
111
  case 3:
71
- c = _b.sent();
72
- return [4 /*yield*/, (0, childProcess_1.forkPromise)("".concat(path_1.default.resolve(c, '../npm')), ['i'], {
73
- cwd: path_1.default.resolve(targetPath, './'),
74
- })];
112
+ projectInfo = _b.sent();
113
+ pkgPath = path_1.default.join(targetPath, 'package.json');
114
+ if (fs_1.default.existsSync(pkgPath)) {
115
+ pkgContent = JSON.parse(fs_1.default.readFileSync(pkgPath, 'utf-8'));
116
+ pkgContent.name = name_1;
117
+ if (projectInfo.description) {
118
+ pkgContent.description = projectInfo.description;
119
+ }
120
+ if (projectInfo.author || projectInfo.email) {
121
+ pkgContent.author = projectInfo.email
122
+ ? "".concat(projectInfo.author, " <").concat(projectInfo.email, ">")
123
+ : projectInfo.author;
124
+ }
125
+ if (projectInfo.gitUrl) {
126
+ pkgContent.repository = {
127
+ type: 'git',
128
+ url: projectInfo.gitUrl,
129
+ };
130
+ }
131
+ fs_1.default.writeFileSync(pkgPath, JSON.stringify(pkgContent, null, 2) + '\n', 'utf-8');
132
+ }
133
+ // 安装依赖
134
+ console.log((0, formatOutput_1.formatNode)({
135
+ type: 'process',
136
+ title: '安装依赖',
137
+ content: '正在执行 npm install ...',
138
+ }));
139
+ return [4 /*yield*/, (0, childProcess_1.execPromise)('npm install', { cwd: targetPath }, !!opts.debug)];
75
140
  case 4:
76
141
  _b.sent();
77
- printer_1.printer.info('初始化完成!');
78
- resolve(true);
79
- return [3 /*break*/, 6];
142
+ if (!projectInfo.gitUrl) return [3 /*break*/, 9];
143
+ console.log((0, formatOutput_1.formatNode)({
144
+ type: 'process',
145
+ title: 'Git初始化',
146
+ content: '正在初始化 Git 仓库并绑定远程地址...',
147
+ }));
148
+ return [4 /*yield*/, (0, childProcess_1.execPromise)('git init', { cwd: targetPath }, false)];
80
149
  case 5:
150
+ _b.sent();
151
+ return [4 /*yield*/, (0, childProcess_1.execPromise)("git remote add origin ".concat(projectInfo.gitUrl), { cwd: targetPath }, false)];
152
+ case 6:
153
+ _b.sent();
154
+ return [4 /*yield*/, (0, childProcess_1.execPromise)('git add -A', { cwd: targetPath }, false)];
155
+ case 7:
156
+ _b.sent();
157
+ return [4 /*yield*/, (0, childProcess_1.execPromise)('git commit -m "feat: init project"', { cwd: targetPath }, false)];
158
+ case 8:
159
+ _b.sent();
160
+ _b.label = 9;
161
+ case 9:
162
+ guideContent = [
163
+ '开始开发:',
164
+ " cd ".concat(name_1),
165
+ ' npm run dev',
166
+ '',
167
+ '构建生产版本:',
168
+ ' npm run build',
169
+ ].join('\n');
170
+ console.log((0, formatOutput_1.formatNode)({
171
+ type: 'success',
172
+ title: '项目初始化完成',
173
+ content: guideContent,
174
+ status: 'success',
175
+ }));
176
+ resolve(true);
177
+ return [3 /*break*/, 11];
178
+ case 10:
81
179
  err_1 = _b.sent();
82
180
  reject(err_1);
83
- return [3 /*break*/, 6];
84
- case 6: return [2 /*return*/];
181
+ return [3 /*break*/, 11];
182
+ case 11: return [2 /*return*/];
85
183
  }
86
184
  });
87
185
  }); })];