@agile-team/robot-cli 1.0.6 → 1.0.8
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/bin/index.js +31 -2
- package/lib/download.js +132 -93
- package/lib/templates.js +22 -22
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -3,11 +3,40 @@
|
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
4
4
|
import { dirname, join, resolve } from 'path';
|
|
5
5
|
import { existsSync } from 'fs';
|
|
6
|
+
import { readFileSync } from 'fs';
|
|
6
7
|
|
|
7
8
|
// 获取当前文件的目录
|
|
8
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
10
|
const __dirname = dirname(__filename);
|
|
10
11
|
|
|
12
|
+
/**
|
|
13
|
+
* 获取包版本号
|
|
14
|
+
*/
|
|
15
|
+
function getPackageVersion() {
|
|
16
|
+
try {
|
|
17
|
+
// 尝试从多个位置读取 package.json
|
|
18
|
+
const possiblePaths = [
|
|
19
|
+
join(__dirname, '..', 'package.json'),
|
|
20
|
+
join(__dirname, 'package.json'),
|
|
21
|
+
join(__dirname, '..', '..', 'package.json')
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
for (const packagePath of possiblePaths) {
|
|
25
|
+
if (existsSync(packagePath)) {
|
|
26
|
+
const packageJson = JSON.parse(readFileSync(packagePath, 'utf8'));
|
|
27
|
+
return packageJson.version || '1.0.0';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return '1.0.0'; // 默认版本
|
|
32
|
+
} catch (error) {
|
|
33
|
+
return '1.0.0'; // 出错时返回默认版本
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 获取版本号
|
|
38
|
+
const PACKAGE_VERSION = getPackageVersion();
|
|
39
|
+
|
|
11
40
|
/**
|
|
12
41
|
* 智能路径解析 - 兼容不同包管理器的安装路径
|
|
13
42
|
*/
|
|
@@ -159,7 +188,7 @@ async function main() {
|
|
|
159
188
|
|
|
160
189
|
const titleBox = boxen(
|
|
161
190
|
logo + '\n\n' +
|
|
162
|
-
|
|
191
|
+
` 🤖 Robot 项目脚手架工具 v${PACKAGE_VERSION}\n` +
|
|
163
192
|
' 兼容 npm/yarn/pnpm/bun',
|
|
164
193
|
{
|
|
165
194
|
padding: { top: 1, bottom: 1, left: 2, right: 2 },
|
|
@@ -233,7 +262,7 @@ async function main() {
|
|
|
233
262
|
program
|
|
234
263
|
.name('robot')
|
|
235
264
|
.description('🤖 Robot 项目脚手架工具 - @agile-team/robot-cli')
|
|
236
|
-
.version(
|
|
265
|
+
.version(PACKAGE_VERSION) // 🎯 使用动态版本号
|
|
237
266
|
.hook('preAction', () => {
|
|
238
267
|
showWelcome();
|
|
239
268
|
});
|
package/lib/download.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// lib/download.js -
|
|
1
|
+
// lib/download.js - 真正简化版,解决实际问题
|
|
2
2
|
import fs from 'fs-extra';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import os from 'os';
|
|
@@ -14,10 +14,111 @@ const __dirname = path.dirname(__filename);
|
|
|
14
14
|
const CACHE_DIR = path.join(os.homedir(), '.robot-cli', 'cache');
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
* 解析仓库URL,构建下载链接
|
|
18
|
+
*/
|
|
19
|
+
function buildDownloadUrl(repoUrl) {
|
|
20
|
+
try {
|
|
21
|
+
const url = new URL(repoUrl);
|
|
22
|
+
const hostname = url.hostname;
|
|
23
|
+
const pathname = url.pathname;
|
|
24
|
+
|
|
25
|
+
if (hostname === 'github.com') {
|
|
26
|
+
// GitHub: https://github.com/user/repo -> /user/repo/archive/refs/heads/main.zip
|
|
27
|
+
return `${repoUrl}/archive/refs/heads/main.zip`;
|
|
28
|
+
} else if (hostname === 'gitee.com') {
|
|
29
|
+
// Gitee: https://gitee.com/user/repo -> /user/repo/repository/archive/master.zip
|
|
30
|
+
return `${repoUrl}/repository/archive/master.zip`;
|
|
31
|
+
} else if (hostname === 'gitlab.com') {
|
|
32
|
+
// GitLab: https://gitlab.com/user/repo -> /user/repo/-/archive/main/repo-main.zip
|
|
33
|
+
const repoName = pathname.split('/').pop();
|
|
34
|
+
return `${repoUrl}/-/archive/main/${repoName}-main.zip`;
|
|
35
|
+
} else {
|
|
36
|
+
// 其他平台,默认使用 GitHub 格式
|
|
37
|
+
return `${repoUrl}/archive/refs/heads/main.zip`;
|
|
38
|
+
}
|
|
39
|
+
} catch (error) {
|
|
40
|
+
// URL 解析失败,返回原始URL + 默认后缀
|
|
41
|
+
return `${repoUrl}/archive/refs/heads/main.zip`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 尝试下载 - 支持多平台
|
|
47
|
+
*/
|
|
48
|
+
async function tryDownload(repoUrl, spinner) {
|
|
49
|
+
const url = new URL(repoUrl);
|
|
50
|
+
const hostname = url.hostname;
|
|
51
|
+
|
|
52
|
+
// 根据平台选择镜像源
|
|
53
|
+
let mirrors = [];
|
|
54
|
+
|
|
55
|
+
if (hostname === 'github.com') {
|
|
56
|
+
mirrors = [
|
|
57
|
+
repoUrl, // 官方源
|
|
58
|
+
`https://ghproxy.com/${repoUrl}` // GitHub 代理
|
|
59
|
+
];
|
|
60
|
+
} else {
|
|
61
|
+
// 其他平台直接使用原始URL
|
|
62
|
+
mirrors = [repoUrl];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
for (let i = 0; i < mirrors.length; i++) {
|
|
66
|
+
const currentUrl = mirrors[i];
|
|
67
|
+
const isOriginal = currentUrl === repoUrl;
|
|
68
|
+
const sourceName = isOriginal ? `${hostname} 官方` : `${hostname} 镜像`;
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
if (spinner) {
|
|
72
|
+
spinner.text = `📦 尝试从 ${sourceName} 下载...`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const downloadUrl = buildDownloadUrl(currentUrl);
|
|
76
|
+
|
|
77
|
+
const response = await fetch(downloadUrl, {
|
|
78
|
+
timeout: isOriginal ? 15000 : 10000, // 官方源给更多时间
|
|
79
|
+
headers: {
|
|
80
|
+
'User-Agent': 'Robot-CLI/1.0.0'
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
if (response.status === 404) {
|
|
86
|
+
throw new Error(`仓库不存在: ${repoUrl}`);
|
|
87
|
+
}
|
|
88
|
+
throw new Error(`HTTP ${response.status}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (spinner) {
|
|
92
|
+
const contentLength = response.headers.get('content-length');
|
|
93
|
+
if (contentLength) {
|
|
94
|
+
const sizeInMB = (parseInt(contentLength) / 1024 / 1024).toFixed(1);
|
|
95
|
+
spinner.text = `📦 下载中... (${sizeInMB}MB from ${sourceName})`;
|
|
96
|
+
} else {
|
|
97
|
+
spinner.text = `📦 下载中... (from ${sourceName})`;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return { response, sourceName };
|
|
102
|
+
|
|
103
|
+
} catch (error) {
|
|
104
|
+
// 如果是最后一个源,抛出错误
|
|
105
|
+
if (i === mirrors.length - 1) {
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 否则继续尝试下一个源
|
|
110
|
+
if (spinner) {
|
|
111
|
+
spinner.text = `⚠️ ${sourceName} 访问失败,尝试其他源...`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 等待1秒再试下一个
|
|
115
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 下载模板 - 简化版
|
|
21
122
|
*/
|
|
22
123
|
export async function downloadTemplate(template, options = {}) {
|
|
23
124
|
const { useCache = true, spinner } = options;
|
|
@@ -27,12 +128,12 @@ export async function downloadTemplate(template, options = {}) {
|
|
|
27
128
|
throw new Error('模板参数不能为空');
|
|
28
129
|
}
|
|
29
130
|
|
|
30
|
-
if (!template.key && !template.
|
|
131
|
+
if (!template.key && !template.repoUrl) {
|
|
31
132
|
throw new Error(`模板配置无效: ${JSON.stringify(template)}`);
|
|
32
133
|
}
|
|
33
134
|
|
|
34
|
-
//
|
|
35
|
-
const cacheKey = template.key || template.
|
|
135
|
+
// 获取缓存键值
|
|
136
|
+
const cacheKey = template.key || template.repoUrl?.split('/').pop() || 'unknown-template';
|
|
36
137
|
const cachePath = path.join(CACHE_DIR, cacheKey);
|
|
37
138
|
|
|
38
139
|
// 检查缓存
|
|
@@ -57,69 +158,24 @@ export async function downloadTemplate(template, options = {}) {
|
|
|
57
158
|
}
|
|
58
159
|
}
|
|
59
160
|
|
|
60
|
-
//
|
|
61
|
-
if (template.localTest || !template.
|
|
161
|
+
// 如果是本地测试模板
|
|
162
|
+
if (template.localTest || !template.repoUrl) {
|
|
62
163
|
if (fs.existsSync(cachePath)) {
|
|
63
164
|
return cachePath;
|
|
64
165
|
} else {
|
|
65
|
-
throw new Error(
|
|
66
|
-
'本地测试模板不存在',
|
|
67
|
-
'',
|
|
68
|
-
chalk.red.bold('问题描述:'),
|
|
69
|
-
` 测试模板路径不存在: ${cachePath}`,
|
|
70
|
-
'',
|
|
71
|
-
chalk.green.bold('解决方案:'),
|
|
72
|
-
' 1. 运行测试环境设置: npm run test:setup',
|
|
73
|
-
' 2. 或创建测试缓存: npm run test',
|
|
74
|
-
' 3. 检查模板是否正确创建',
|
|
75
|
-
'',
|
|
76
|
-
chalk.blue.bold('可用命令:'),
|
|
77
|
-
' npm run test:setup --setup # 创建完整测试环境',
|
|
78
|
-
' npm run test:clean # 清理测试环境'
|
|
79
|
-
].join('\n'));
|
|
166
|
+
throw new Error(`本地测试模板不存在: ${cachePath}`);
|
|
80
167
|
}
|
|
81
168
|
}
|
|
82
169
|
|
|
83
170
|
// 下载远程模板
|
|
84
|
-
if (spinner) {
|
|
85
|
-
spinner.text = `🌐 连接到 GitHub (${template.repo})...`;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
171
|
try {
|
|
89
|
-
|
|
172
|
+
// 尝试从不同源下载
|
|
173
|
+
const { response, sourceName } = await tryDownload(template.repoUrl, spinner);
|
|
174
|
+
|
|
175
|
+
// 保存到临时文件
|
|
90
176
|
const tempZipPath = path.join(os.tmpdir(), cacheKey + '-' + Date.now() + '.zip');
|
|
91
177
|
const tempExtractPath = path.join(os.tmpdir(), cacheKey + '-extract-' + Date.now());
|
|
92
178
|
|
|
93
|
-
// 检查网络连接和获取文件信息
|
|
94
|
-
if (spinner) {
|
|
95
|
-
spinner.text = `🔗 检查仓库 ${template.repo} 可用性...`;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// 下载zip文件
|
|
99
|
-
const response = await fetch(downloadUrl, {
|
|
100
|
-
timeout: 60000, // 60秒超时,给大文件更多时间
|
|
101
|
-
headers: {
|
|
102
|
-
'User-Agent': 'Robot-CLI/1.0.4'
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
if (!response.ok) {
|
|
107
|
-
if (response.status === 404) {
|
|
108
|
-
throw new Error(`仓库不存在或私有: ${template.repo}\n请检查仓库地址是否正确且为公开仓库`);
|
|
109
|
-
}
|
|
110
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// 显示下载进度
|
|
114
|
-
const contentLength = response.headers.get('content-length');
|
|
115
|
-
if (spinner && contentLength) {
|
|
116
|
-
const totalSize = parseInt(contentLength);
|
|
117
|
-
const sizeInMB = (totalSize / 1024 / 1024).toFixed(1);
|
|
118
|
-
spinner.text = `📦 下载模板中... (${sizeInMB}MB)`;
|
|
119
|
-
} else if (spinner) {
|
|
120
|
-
spinner.text = '📦 下载模板中...';
|
|
121
|
-
}
|
|
122
|
-
|
|
123
179
|
const buffer = await response.buffer();
|
|
124
180
|
await fs.writeFile(tempZipPath, buffer);
|
|
125
181
|
|
|
@@ -130,14 +186,12 @@ export async function downloadTemplate(template, options = {}) {
|
|
|
130
186
|
// 解压文件
|
|
131
187
|
await extract(tempZipPath, { dir: tempExtractPath });
|
|
132
188
|
|
|
133
|
-
|
|
134
|
-
spinner.text = '🔍 查找项目结构...';
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// 找到解压后的项目目录 (通常是 reponame-main/)
|
|
189
|
+
// 查找项目目录
|
|
138
190
|
const extractedItems = await fs.readdir(tempExtractPath);
|
|
139
191
|
const projectDir = extractedItems.find(item =>
|
|
140
|
-
item.endsWith('-main') ||
|
|
192
|
+
item.endsWith('-main') ||
|
|
193
|
+
item.endsWith('-master') ||
|
|
194
|
+
item === template.repoUrl.split('/').pop()
|
|
141
195
|
);
|
|
142
196
|
|
|
143
197
|
if (!projectDir) {
|
|
@@ -146,34 +200,22 @@ export async function downloadTemplate(template, options = {}) {
|
|
|
146
200
|
|
|
147
201
|
const sourcePath = path.join(tempExtractPath, projectDir);
|
|
148
202
|
|
|
203
|
+
// 验证模板完整性
|
|
149
204
|
if (spinner) {
|
|
150
205
|
spinner.text = '✅ 验证模板完整性...';
|
|
151
206
|
}
|
|
152
207
|
|
|
153
|
-
// 验证模板完整性
|
|
154
208
|
const packageJsonPath = path.join(sourcePath, 'package.json');
|
|
155
209
|
if (!fs.existsSync(packageJsonPath)) {
|
|
156
|
-
throw new Error(`模板缺少 package.json
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// 读取并验证 package.json
|
|
160
|
-
try {
|
|
161
|
-
const packageJson = await fs.readJson(packageJsonPath);
|
|
162
|
-
if (!packageJson.name) {
|
|
163
|
-
console.log(chalk.yellow('⚠️ 模板 package.json 缺少 name 字段'));
|
|
164
|
-
}
|
|
165
|
-
} catch (error) {
|
|
166
|
-
throw new Error(`package.json 格式错误: ${error.message}`);
|
|
210
|
+
throw new Error(`模板缺少 package.json 文件`);
|
|
167
211
|
}
|
|
168
212
|
|
|
213
|
+
// 保存到缓存
|
|
169
214
|
if (spinner) {
|
|
170
215
|
spinner.text = '💾 保存到缓存...';
|
|
171
216
|
}
|
|
172
217
|
|
|
173
|
-
// 确保缓存目录存在
|
|
174
218
|
await fs.ensureDir(CACHE_DIR);
|
|
175
|
-
|
|
176
|
-
// 移动到缓存目录
|
|
177
219
|
if (fs.existsSync(cachePath)) {
|
|
178
220
|
await fs.remove(cachePath);
|
|
179
221
|
}
|
|
@@ -184,13 +226,13 @@ export async function downloadTemplate(template, options = {}) {
|
|
|
184
226
|
await fs.remove(tempExtractPath).catch(() => {});
|
|
185
227
|
|
|
186
228
|
if (spinner) {
|
|
187
|
-
spinner.text =
|
|
229
|
+
spinner.text = `🎉 模板下载完成 (via ${sourceName})`;
|
|
188
230
|
}
|
|
189
231
|
|
|
190
232
|
return cachePath;
|
|
191
233
|
|
|
192
234
|
} catch (error) {
|
|
193
|
-
//
|
|
235
|
+
// 清理临时文件
|
|
194
236
|
try {
|
|
195
237
|
const tempFiles = await fs.readdir(os.tmpdir());
|
|
196
238
|
const robotTempFiles = tempFiles.filter(file =>
|
|
@@ -204,17 +246,14 @@ export async function downloadTemplate(template, options = {}) {
|
|
|
204
246
|
// 忽略清理错误
|
|
205
247
|
}
|
|
206
248
|
|
|
207
|
-
//
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (error.code === 'ETIMEDOUT' || error.type === 'request-timeout') {
|
|
213
|
-
throw new Error(`下载超时: 模板文件较大或网络较慢\n请稍后重试或使用 --no-cache 选项`);
|
|
249
|
+
// 简单的错误处理
|
|
250
|
+
let errorMessage = `模板下载失败: ${error.message}`;
|
|
251
|
+
|
|
252
|
+
if (error.code === 'ENOTFOUND' || error.message.includes('网络')) {
|
|
253
|
+
errorMessage += '\n\n💡 建议:\n1. 检查网络连接\n2. 如果在国内,尝试使用科学上网\n3. 稍后重试';
|
|
214
254
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
throw new Error(`模板下载失败: ${error.message}`);
|
|
255
|
+
|
|
256
|
+
throw new Error(errorMessage);
|
|
218
257
|
}
|
|
219
258
|
}
|
|
220
259
|
|
package/lib/templates.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// lib/templates.js -
|
|
1
|
+
// lib/templates.js - 使用 repoUrl 配置
|
|
2
2
|
export const TEMPLATE_CATEGORIES = {
|
|
3
3
|
frontend: {
|
|
4
4
|
name: '🎨 前端项目',
|
|
@@ -12,14 +12,14 @@ export const TEMPLATE_CATEGORIES = {
|
|
|
12
12
|
'robot-admin': {
|
|
13
13
|
name: 'Robot Admin 完整版',
|
|
14
14
|
description: '包含30+完整示例、权限管理、图表组件、最佳实践等等',
|
|
15
|
-
|
|
15
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Admin',
|
|
16
16
|
features: ['Naive UI', 'Vue Router', 'Pinia', '权限管理', '动态路由', '图表组件', '性能优化等等'],
|
|
17
17
|
version: 'full'
|
|
18
18
|
},
|
|
19
19
|
'robot-admin-base': {
|
|
20
20
|
name: 'Robot Admin 精简版',
|
|
21
21
|
description: '基础架构、核心功能、快速启动',
|
|
22
|
-
|
|
22
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Admin_Base',
|
|
23
23
|
features: ['Naive UI', 'Vue Router', 'Pinia', '基础布局'],
|
|
24
24
|
version: 'base'
|
|
25
25
|
}
|
|
@@ -31,14 +31,14 @@ export const TEMPLATE_CATEGORIES = {
|
|
|
31
31
|
'robot-monorepo': {
|
|
32
32
|
name: 'Robot Monorepo 完整版',
|
|
33
33
|
description: 'bun workspace + 多包管理 + 共享组件库',
|
|
34
|
-
|
|
34
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Monorepo',
|
|
35
35
|
features: ['bun workspace', 'shared components', 'build tools', 'CI/CD'],
|
|
36
36
|
version: 'full'
|
|
37
37
|
},
|
|
38
38
|
'robot-monorepo-base': {
|
|
39
39
|
name: 'Robot Monorepo 精简版',
|
|
40
40
|
description: '基础 monorepo 结构 + 核心配置',
|
|
41
|
-
|
|
41
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Monorepo_Base',
|
|
42
42
|
features: ['bun workspace', 'basic structure'],
|
|
43
43
|
version: 'base'
|
|
44
44
|
}
|
|
@@ -50,14 +50,14 @@ export const TEMPLATE_CATEGORIES = {
|
|
|
50
50
|
'robot-micro': {
|
|
51
51
|
name: 'Robot微前端 完整版',
|
|
52
52
|
description: 'MicroApp + Vite插件模块联邦 + 多应用示例',
|
|
53
|
-
|
|
53
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Micro',
|
|
54
54
|
features: ['MicroApp', 'Vite模块联邦', '多应用', '路由共享'],
|
|
55
55
|
version: 'full'
|
|
56
56
|
},
|
|
57
57
|
'robot-micro-base': {
|
|
58
58
|
name: 'Robot微前端 精简版',
|
|
59
59
|
description: '基础 MicroApp 架构 + 主子应用',
|
|
60
|
-
|
|
60
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Micro_Base',
|
|
61
61
|
features: ['MicroApp', '基础配置'],
|
|
62
62
|
version: 'base'
|
|
63
63
|
}
|
|
@@ -74,14 +74,14 @@ export const TEMPLATE_CATEGORIES = {
|
|
|
74
74
|
'robot-react': {
|
|
75
75
|
name: 'Robot React 完整版',
|
|
76
76
|
description: 'Ant Design + 完整功能演示',
|
|
77
|
-
|
|
77
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_React',
|
|
78
78
|
features: ['Ant Design', 'React Router', 'Redux Toolkit'],
|
|
79
79
|
version: 'full'
|
|
80
80
|
},
|
|
81
81
|
'robot-react-base': {
|
|
82
82
|
name: 'Robot React 精简版',
|
|
83
83
|
description: '基础React + 核心功能',
|
|
84
|
-
|
|
84
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_React_Base',
|
|
85
85
|
features: ['React', 'React Router', '基础组件'],
|
|
86
86
|
version: 'base'
|
|
87
87
|
}
|
|
@@ -103,14 +103,14 @@ export const TEMPLATE_CATEGORIES = {
|
|
|
103
103
|
'robot-uniapp': {
|
|
104
104
|
name: 'Robot uni-app 完整版',
|
|
105
105
|
description: '多端适配 + 插件市场 + 完整示例',
|
|
106
|
-
|
|
106
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Uniapp',
|
|
107
107
|
features: ['多端发布', 'uView UI', '插件集成'],
|
|
108
108
|
version: 'full'
|
|
109
109
|
},
|
|
110
110
|
'robot-uniapp-base': {
|
|
111
111
|
name: 'Robot uni-app 精简版',
|
|
112
112
|
description: '基础框架 + 核心功能',
|
|
113
|
-
|
|
113
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Uniapp_Base',
|
|
114
114
|
features: ['基础框架', '路由配置'],
|
|
115
115
|
version: 'base'
|
|
116
116
|
}
|
|
@@ -127,7 +127,7 @@ export const TEMPLATE_CATEGORIES = {
|
|
|
127
127
|
'robot-tarao': {
|
|
128
128
|
name: 'Robot Tarao 完整版',
|
|
129
129
|
description: '原生性能 + 跨平台 + 完整功能(暂无,后续完善)',
|
|
130
|
-
|
|
130
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Tarao',
|
|
131
131
|
features: ['原生性能', '跨平台', '完整功能'],
|
|
132
132
|
version: 'full',
|
|
133
133
|
status: 'coming-soon'
|
|
@@ -135,7 +135,7 @@ export const TEMPLATE_CATEGORIES = {
|
|
|
135
135
|
'robot-tarao-base': {
|
|
136
136
|
name: 'Robot Tarao 精简版',
|
|
137
137
|
description: '基础 Tarao 框架(暂无,后续完善)',
|
|
138
|
-
|
|
138
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Tarao_Base',
|
|
139
139
|
features: ['基础框架', '核心功能'],
|
|
140
140
|
version: 'base',
|
|
141
141
|
status: 'coming-soon'
|
|
@@ -158,14 +158,14 @@ export const TEMPLATE_CATEGORIES = {
|
|
|
158
158
|
'robot-nest': {
|
|
159
159
|
name: 'Robot NestJS 完整版',
|
|
160
160
|
description: 'NestJS + TypeORM + JWT + Swagger + Redis + 完整生态',
|
|
161
|
-
|
|
161
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Nest',
|
|
162
162
|
features: ['NestJS', 'TypeORM', 'JWT认证', 'ApiFox文档', 'Redis', '微服务'],
|
|
163
163
|
version: 'full'
|
|
164
164
|
},
|
|
165
165
|
'robot-nest-base': {
|
|
166
166
|
name: 'Robot NestJS 精简版',
|
|
167
167
|
description: '基础 NestJS + 核心模块',
|
|
168
|
-
|
|
168
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Nest_Base',
|
|
169
169
|
features: ['NestJS', '基础路由', '错误处理'],
|
|
170
170
|
version: 'base'
|
|
171
171
|
}
|
|
@@ -177,7 +177,7 @@ export const TEMPLATE_CATEGORIES = {
|
|
|
177
177
|
'robot-nest-micro': {
|
|
178
178
|
name: 'Robot NestJS微服务版',
|
|
179
179
|
description: 'NestJS + 微服务架构 + gRPC + 服务发现',
|
|
180
|
-
|
|
180
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Nest_Micro',
|
|
181
181
|
features: ['NestJS', '微服务', 'gRPC', 'Redis', '服务发现'],
|
|
182
182
|
version: 'micro'
|
|
183
183
|
}
|
|
@@ -194,14 +194,14 @@ export const TEMPLATE_CATEGORIES = {
|
|
|
194
194
|
'robot-koa': {
|
|
195
195
|
name: 'Robot Koa3 完整版',
|
|
196
196
|
description: 'Koa3 + TypeScript + JWT + 数据库 + 中间件',
|
|
197
|
-
|
|
197
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Koa',
|
|
198
198
|
features: ['Koa3', 'TypeScript', 'JWT认证', 'MySQL', '中间件'],
|
|
199
199
|
version: 'full'
|
|
200
200
|
},
|
|
201
201
|
'robot-koa-base': {
|
|
202
202
|
name: 'Robot Koa3 精简版',
|
|
203
203
|
description: '基础Koa3 + 核心中间件',
|
|
204
|
-
|
|
204
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Koa_Base',
|
|
205
205
|
features: ['Koa3', '基础路由', '错误处理'],
|
|
206
206
|
version: 'base'
|
|
207
207
|
}
|
|
@@ -223,14 +223,14 @@ export const TEMPLATE_CATEGORIES = {
|
|
|
223
223
|
'robot-electron': {
|
|
224
224
|
name: 'Robot Electron 完整版',
|
|
225
225
|
description: 'Vue3 + Electron + 自动更新 + 原生能力',
|
|
226
|
-
|
|
226
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Electron',
|
|
227
227
|
features: ['Vue3', 'Electron', '自动更新', '原生API'],
|
|
228
228
|
version: 'full'
|
|
229
229
|
},
|
|
230
230
|
'robot-electron-base': {
|
|
231
231
|
name: 'Robot Electron 精简版',
|
|
232
232
|
description: '基础Electron + Vue框架',
|
|
233
|
-
|
|
233
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Electron_Base',
|
|
234
234
|
features: ['Vue3', 'Electron', '基础功能'],
|
|
235
235
|
version: 'base'
|
|
236
236
|
}
|
|
@@ -247,14 +247,14 @@ export const TEMPLATE_CATEGORIES = {
|
|
|
247
247
|
'robot-tauri': {
|
|
248
248
|
name: 'Robot Tauri 完整版',
|
|
249
249
|
description: 'Rust后端 + Vue前端 + 原生性能',
|
|
250
|
-
|
|
250
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Tauri',
|
|
251
251
|
features: ['Tauri', 'Vue3', 'Rust backend', '原生性能'],
|
|
252
252
|
version: 'full'
|
|
253
253
|
},
|
|
254
254
|
'robot-tauri-base': {
|
|
255
255
|
name: 'Robot Tauri 精简版',
|
|
256
256
|
description: '基础Tauri + Vue框架',
|
|
257
|
-
|
|
257
|
+
repoUrl: 'https://github.com/ChenyCHENYU/Robot_Tauri_Base',
|
|
258
258
|
features: ['Tauri', 'Vue3', '基础功能'],
|
|
259
259
|
version: 'base'
|
|
260
260
|
}
|