flu-cli 2.0.0 → 2.0.2
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/CLI.md +226 -63
- package/README.md +56 -29
- package/index.js +61 -12
- package/lib/commands/add.js +177 -54
- package/lib/commands/completion.js +0 -2
- package/lib/commands/config.js +70 -0
- package/lib/commands/newClack.js +9 -6
- package/lib/commands/template.js +113 -0
- package/lib/utils/templateSelectorEnquirer.js +13 -10
- package/package.json +5 -3
- package/templates/snippets/dart.code-snippets +168 -263
- package/lib/commands/generate.js +0 -26
- package/lib/generators/component_generator.js +0 -93
- package/lib/generators/module_generator.js +0 -141
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { ConfigManager } from '@flu-cli/core';
|
|
3
|
+
import { getAllTemplates } from '../../config/templates.js';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
import { existsSync } from 'fs';
|
|
6
|
+
import { getTemplateCachePath } from '../templates/templateManager.js';
|
|
7
|
+
import { format } from 'date-fns'; // 需要检查是否已安装 date-fns,如果没有可以用原生 Date
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 格式化日期
|
|
11
|
+
*/
|
|
12
|
+
function formatDate (timestamp) {
|
|
13
|
+
if (!timestamp) return '从未';
|
|
14
|
+
return new Date(timestamp).toLocaleString('zh-CN');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 列出所有模板(内置 + 自定义)
|
|
19
|
+
*/
|
|
20
|
+
export function listAllTemplates () {
|
|
21
|
+
logger.title('📦 可用的项目模板');
|
|
22
|
+
|
|
23
|
+
// 1. 内置模板
|
|
24
|
+
console.log(chalk.bold.cyan('📌 内置模板'));
|
|
25
|
+
const builtinTemplates = getAllTemplates();
|
|
26
|
+
builtinTemplates.forEach((template) => {
|
|
27
|
+
const cachePath = getTemplateCachePath(template.name);
|
|
28
|
+
const isCached = existsSync(cachePath);
|
|
29
|
+
const status = isCached ? chalk.green('已缓存') : chalk.gray('未缓存');
|
|
30
|
+
|
|
31
|
+
console.log(chalk.bold(` • ${template.name} (${template.displayName})`) + ` [${status}]`);
|
|
32
|
+
console.log(chalk.gray(` ${template.description}`));
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// 2. 自定义模板
|
|
36
|
+
const configManager = ConfigManager.getInstance();
|
|
37
|
+
const customTemplates = configManager.getTemplates();
|
|
38
|
+
|
|
39
|
+
if (customTemplates.length > 0) {
|
|
40
|
+
logger.newLine();
|
|
41
|
+
console.log(chalk.bold.cyan('🔧 自定义模板'));
|
|
42
|
+
customTemplates.forEach((template) => {
|
|
43
|
+
const source = template.type === 'git' ? template.url : template.path;
|
|
44
|
+
let status = '';
|
|
45
|
+
let updateInfo = '';
|
|
46
|
+
|
|
47
|
+
if (template.type === 'git') {
|
|
48
|
+
const cachePath = getTemplateCachePath(template.id);
|
|
49
|
+
const isCached = existsSync(cachePath);
|
|
50
|
+
status = isCached ? chalk.green('已缓存') : chalk.gray('未缓存');
|
|
51
|
+
if (template.lastUsedAt) {
|
|
52
|
+
updateInfo = chalk.gray(` (上次使用: ${formatDate(template.lastUsedAt)})`);
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
status = chalk.blue('本地链接');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.log(chalk.bold(` • ${template.id} (${template.name})`) + ` [${status}]` + updateInfo);
|
|
59
|
+
console.log(chalk.gray(` ${template.description || '无描述'}`));
|
|
60
|
+
console.log(chalk.gray(` 来源: [${template.type}] ${source}`));
|
|
61
|
+
if (template.branch) {
|
|
62
|
+
console.log(chalk.gray(` 分支: ${template.branch}`));
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
logger.newLine();
|
|
67
|
+
console.log(chalk.gray(' (暂无自定义模板)'));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
logger.newLine();
|
|
71
|
+
logger.info('使用 "flu template add" 添加自定义模板');
|
|
72
|
+
logger.info('使用 "flu new <name> -t <template>" 创建项目');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 添加自定义模板
|
|
77
|
+
*/
|
|
78
|
+
export function addTemplate (name, source, options) {
|
|
79
|
+
const configManager = ConfigManager.getInstance();
|
|
80
|
+
const existing = configManager.getTemplate(name);
|
|
81
|
+
|
|
82
|
+
if (existing && !options.force) {
|
|
83
|
+
logger.error(`模板 "${name}" 已存在`);
|
|
84
|
+
logger.info('使用 --force 覆盖,或使用 "flu template remove" 删除');
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const isLocal = options.local;
|
|
89
|
+
const template = {
|
|
90
|
+
id: name,
|
|
91
|
+
name: options.name || name,
|
|
92
|
+
type: isLocal ? 'local' : 'git',
|
|
93
|
+
description: options.description || '自定义模板',
|
|
94
|
+
...(isLocal ? { path: source } : { url: source, branch: options.branch || 'main' })
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
configManager.addTemplate(template);
|
|
98
|
+
logger.success(`✅ 模板 "${name}" 添加成功`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* 删除自定义模板
|
|
103
|
+
*/
|
|
104
|
+
export function removeTemplate (name) {
|
|
105
|
+
const configManager = ConfigManager.getInstance();
|
|
106
|
+
const success = configManager.removeTemplate(name);
|
|
107
|
+
|
|
108
|
+
if (success) {
|
|
109
|
+
logger.success(`🗑️ 模板 "${name}" 已删除`);
|
|
110
|
+
} else {
|
|
111
|
+
logger.error(`模板 "${name}" 不存在`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -8,7 +8,8 @@ import chalk from 'chalk';
|
|
|
8
8
|
import { existsSync } from 'fs';
|
|
9
9
|
import { basename } from 'path';
|
|
10
10
|
import { getAllTemplates } from '../../config/templates.js';
|
|
11
|
-
import {
|
|
11
|
+
import { ConfigManager } from '@flu-cli/core';
|
|
12
|
+
import { getDefaultTemplate, saveDefaultTemplate } from '../utils/config.js';
|
|
12
13
|
|
|
13
14
|
const { Select } = enquirer;
|
|
14
15
|
|
|
@@ -17,7 +18,8 @@ const { Select } = enquirer;
|
|
|
17
18
|
*/
|
|
18
19
|
export async function selectTemplateWithEnquirer () {
|
|
19
20
|
const templates = getAllTemplates();
|
|
20
|
-
const
|
|
21
|
+
const configManager = ConfigManager.getInstance();
|
|
22
|
+
const customTemplates = configManager.getTemplates();
|
|
21
23
|
const defaultTpl = getDefaultTemplate();
|
|
22
24
|
|
|
23
25
|
// 创建自定义的 Select prompt
|
|
@@ -85,7 +87,7 @@ export async function selectTemplateWithEnquirer () {
|
|
|
85
87
|
const customChoices = customTemplates.map(ct => ({
|
|
86
88
|
name: `custom:${ct.id}`,
|
|
87
89
|
message: `自定义:${ct.name}`,
|
|
88
|
-
hint: ct.type === 'git' ? ct.
|
|
90
|
+
hint: ct.type === 'git' ? ct.url : `本地: ${ct.path}`
|
|
89
91
|
}));
|
|
90
92
|
const addCustomChoice = { name: '__add_custom__', message: chalk.yellow('➕ 新增自定义模板(本地或 Git)') };
|
|
91
93
|
|
|
@@ -158,17 +160,18 @@ export async function selectTemplateWithEnquirer () {
|
|
|
158
160
|
: basename(pathOrUrl);
|
|
159
161
|
const id = `${nameGuess.replace(/\W+/g, '-').toLowerCase()}-${Date.now()}`;
|
|
160
162
|
|
|
161
|
-
const
|
|
163
|
+
const newTemplate = {
|
|
162
164
|
id,
|
|
163
165
|
name: nameGuess,
|
|
164
166
|
type: sourceType,
|
|
165
|
-
pathOrUrl,
|
|
166
|
-
|
|
167
|
-
|
|
167
|
+
...(sourceType === 'git' ? { url: pathOrUrl, branch } : { path: pathOrUrl })
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
configManager.addTemplate(newTemplate);
|
|
168
171
|
|
|
169
|
-
console.log(chalk.green('✓ 已保存自定义模板:'), chalk.cyan.bold(
|
|
170
|
-
saveDefaultTemplate({ type: 'custom', idOrName:
|
|
171
|
-
return { kind: 'custom', id:
|
|
172
|
+
console.log(chalk.green('✓ 已保存自定义模板:'), chalk.cyan.bold(newTemplate.name));
|
|
173
|
+
saveDefaultTemplate({ type: 'custom', idOrName: newTemplate.id });
|
|
174
|
+
return { kind: 'custom', id: newTemplate.id };
|
|
172
175
|
}
|
|
173
176
|
|
|
174
177
|
if (answer.startsWith('builtin:')) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flu-cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Flutter MVVM 脚手架工具 - V2",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"scripts": {
|
|
14
14
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
15
15
|
"start": "node ./index.js",
|
|
16
|
-
"dev": "NODE_ENV=development node ./index.js",
|
|
16
|
+
"dev": "NODE_ENV=development node ./index.js --",
|
|
17
17
|
"prod": "NODE_ENV=production node ./index.js",
|
|
18
18
|
"prepublishOnly": "NODE_ENV=production"
|
|
19
19
|
},
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"template",
|
|
27
27
|
"generator"
|
|
28
28
|
],
|
|
29
|
-
"author": "
|
|
29
|
+
"author": "火叶工作室",
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|
|
@@ -38,8 +38,10 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@clack/prompts": "^0.11.0",
|
|
41
|
+
"@flu-cli/core": "file:../core",
|
|
41
42
|
"chalk": "^4.1.2",
|
|
42
43
|
"commander": "^11.1.0",
|
|
44
|
+
"date-fns": "^4.1.0",
|
|
43
45
|
"enquirer": "^2.4.1",
|
|
44
46
|
"fs-extra": "^11.2.0",
|
|
45
47
|
"handlebars": "^4.7.8",
|