flu-cli 2.0.5 → 2.1.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/CHANGELOG.md +23 -0
- package/README.md +17 -4
- package/config/dev.config.js +11 -11
- package/config/templates.js +10 -10
- package/index.js +554 -102
- package/lib/commands/add.js +365 -266
- package/lib/commands/assets.js +77 -78
- package/lib/commands/cache.js +29 -52
- package/lib/commands/completion.js +13 -11
- package/lib/commands/config.js +150 -44
- package/lib/commands/init-ai-base.js +89 -0
- package/lib/commands/newClack.js +269 -178
- package/lib/commands/snippets.js +58 -43
- package/lib/commands/template.js +98 -58
- package/lib/commands/templates.js +101 -57
- package/lib/commands/upload.js +313 -0
- package/lib/commands/vnext-options.js +206 -0
- package/lib/generators/model_generator.js +91 -88
- package/lib/generators/page_generator.js +100 -93
- package/lib/generators/service_generator.js +44 -39
- package/lib/generators/viewmodel_generator.js +25 -29
- package/lib/generators/widget_generator.js +30 -35
- package/lib/templates/templateCopier.js +14 -15
- package/lib/templates/templateManager.js +22 -21
- package/lib/utils/config.js +37 -20
- package/lib/utils/flutterHelper.js +2 -2
- package/lib/utils/i18n.js +3 -3
- package/lib/utils/index_updater.js +22 -23
- package/lib/utils/json-output.js +59 -0
- package/lib/utils/logger.js +17 -17
- package/lib/utils/project_detector.js +66 -66
- package/lib/utils/snippet_loader.js +21 -19
- package/lib/utils/string_helper.js +13 -13
- package/lib/utils/templateSelectorEnquirer.js +94 -108
- package/locales/en-US.json +1 -1
- package/locales/zh-CN.json +2 -2
- package/package.json +60 -57
- package/scripts/smoke-vnext-generate.mjs +1934 -0
- package/scripts/smoke-vnext-params.mjs +92 -0
- package/CLI.md +0 -513
- package/release.sh +0 -529
- package/scripts/e2e-state-tests.js +0 -116
- package/scripts/sync-base-to-templates.js +0 -108
- package/scripts/workspace-clone-all.sh +0 -101
- package/scripts/workspace-status-all.sh +0 -112
|
@@ -4,112 +4,109 @@
|
|
|
4
4
|
* 该文件从 flu-cli-core 迁移回来,以保持 core 的 Headless 纯净。
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import enquirer from 'enquirer'
|
|
8
|
-
import chalk from 'chalk'
|
|
9
|
-
import { existsSync } from 'fs'
|
|
10
|
-
import { basename } from 'path'
|
|
11
|
-
import { BUILTIN_TEMPLATES, ConfigManager } from 'flu-cli-core'
|
|
7
|
+
import enquirer from 'enquirer'
|
|
8
|
+
import chalk from 'chalk'
|
|
9
|
+
import { existsSync } from 'fs'
|
|
10
|
+
import { basename } from 'path'
|
|
11
|
+
import { BUILTIN_TEMPLATES, ConfigManager } from 'flu-cli-core'
|
|
12
12
|
|
|
13
|
-
const { Select } = enquirer
|
|
13
|
+
const { Select } = enquirer
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* 选择模板(带实时预览 - Enquirer 版本)
|
|
17
17
|
*/
|
|
18
|
-
export async function selectTemplateWithEnquirer
|
|
19
|
-
const builtinTemplates = Object.values(BUILTIN_TEMPLATES)
|
|
20
|
-
const configManager = ConfigManager.getInstance()
|
|
21
|
-
const customTemplates = configManager.getTemplates()
|
|
22
|
-
const defaultTpl = configManager.getDefaultTemplate()
|
|
18
|
+
export async function selectTemplateWithEnquirer() {
|
|
19
|
+
const builtinTemplates = Object.values(BUILTIN_TEMPLATES)
|
|
20
|
+
const configManager = ConfigManager.getInstance()
|
|
21
|
+
const customTemplates = configManager.getTemplates()
|
|
22
|
+
const defaultTpl = configManager.getDefaultTemplate()
|
|
23
23
|
|
|
24
24
|
// 创建自定义的 Select prompt
|
|
25
25
|
class TemplateSelect extends Select {
|
|
26
26
|
constructor(options) {
|
|
27
|
-
super(options)
|
|
27
|
+
super(options)
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
async render
|
|
31
|
-
const { size } = this.state
|
|
32
|
-
const index = this.index
|
|
30
|
+
async render() {
|
|
31
|
+
const { size } = this.state
|
|
32
|
+
const index = this.index
|
|
33
33
|
// 选择项与模板索引可能不一致,安全获取
|
|
34
|
-
const choice = this.choices[index]
|
|
35
|
-
const isBuiltin = choice?.name?.startsWith('builtin:')
|
|
36
|
-
const builtinKey = isBuiltin ? choice.name.split(':')[1] : ''
|
|
37
|
-
const template = isBuiltin ? BUILTIN_TEMPLATES[builtinKey] : null
|
|
34
|
+
const choice = this.choices[index]
|
|
35
|
+
const isBuiltin = choice?.name?.startsWith('builtin:')
|
|
36
|
+
const builtinKey = isBuiltin ? choice.name.split(':')[1] : ''
|
|
37
|
+
const template = isBuiltin ? BUILTIN_TEMPLATES[builtinKey] : null
|
|
38
38
|
|
|
39
|
-
let prompt = ''
|
|
40
|
-
let prefix = await this.prefix()
|
|
41
|
-
let separator = await this.separator()
|
|
42
|
-
let message = await this.message()
|
|
39
|
+
let prompt = ''
|
|
40
|
+
let prefix = await this.prefix()
|
|
41
|
+
let separator = await this.separator()
|
|
42
|
+
let message = await this.message()
|
|
43
43
|
|
|
44
44
|
if (this.options.promptLine !== false) {
|
|
45
|
-
prompt = [prefix, message, separator].filter(Boolean).join(' ')
|
|
46
|
-
this.state.prompt = prompt
|
|
45
|
+
prompt = [prefix, message, separator].filter(Boolean).join(' ')
|
|
46
|
+
this.state.prompt = prompt
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
let output = prompt + '\n\n'
|
|
49
|
+
let output = prompt + '\n\n'
|
|
50
50
|
|
|
51
51
|
// 显示选项列表
|
|
52
52
|
for (let i = 0; i < this.choices.length; i++) {
|
|
53
|
-
const choice = this.choices[i]
|
|
54
|
-
const isSelected = i === index
|
|
55
|
-
const prefixStr = isSelected ? chalk.cyan('❯') : ' '
|
|
56
|
-
const style = isSelected ? chalk.cyan : chalk.gray
|
|
57
|
-
output += `${prefixStr} ${style(choice.message)}\n
|
|
53
|
+
const choice = this.choices[i]
|
|
54
|
+
const isSelected = i === index
|
|
55
|
+
const prefixStr = isSelected ? chalk.cyan('❯') : ' '
|
|
56
|
+
const style = isSelected ? chalk.cyan : chalk.gray
|
|
57
|
+
output += `${prefixStr} ${style(choice.message)}\n`
|
|
58
58
|
if (choice.hint) {
|
|
59
|
-
output += ` ${chalk.gray(choice.hint)}\n
|
|
59
|
+
output += ` ${chalk.gray(choice.hint)}\n`
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
// 显示当前模板的结构预览(仅内置模板)
|
|
64
|
-
output += '\n' + chalk.cyan('─'.repeat(70)) + '\n'
|
|
64
|
+
output += '\n' + chalk.cyan('─'.repeat(70)) + '\n'
|
|
65
65
|
if (template) {
|
|
66
|
-
output += chalk.yellow('📁 项目结构预览:\n\n')
|
|
67
|
-
const structureLines = template.structure.trim().split('\n')
|
|
66
|
+
output += chalk.yellow('📁 项目结构预览:\n\n')
|
|
67
|
+
const structureLines = template.structure.trim().split('\n')
|
|
68
68
|
structureLines.forEach((line) => {
|
|
69
|
-
output += chalk.gray(line) + '\n'
|
|
70
|
-
})
|
|
71
|
-
output += '\n'
|
|
72
|
-
output += chalk.cyan('✨ 特性: ') + chalk.gray(template.features.join(', ')) + '\n'
|
|
73
|
-
output +=
|
|
69
|
+
output += chalk.gray(line) + '\n'
|
|
70
|
+
})
|
|
71
|
+
output += '\n'
|
|
72
|
+
output += chalk.cyan('✨ 特性: ') + chalk.gray(template.features.join(', ')) + '\n'
|
|
73
|
+
output +=
|
|
74
|
+
chalk.cyan('📊 适用: ') + chalk.gray(`${template.teamSize}, ${template.codeSize}`) + '\n'
|
|
74
75
|
} else {
|
|
75
|
-
output += chalk.yellow('自定义模板:不提供结构预览') + '\n'
|
|
76
|
+
output += chalk.yellow('自定义模板:不提供结构预览') + '\n'
|
|
76
77
|
}
|
|
77
|
-
output += chalk.cyan('─'.repeat(70))
|
|
78
|
+
output += chalk.cyan('─'.repeat(70))
|
|
78
79
|
|
|
79
|
-
this.clear(size)
|
|
80
|
-
this.write(output)
|
|
80
|
+
this.clear(size)
|
|
81
|
+
this.write(output)
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
// 构建选择项:内置模板 + 自定义模板 + 新增自定义入口
|
|
85
|
-
const builtinChoices = builtinTemplates.map(t => ({
|
|
86
|
+
const builtinChoices = builtinTemplates.map((t) => ({
|
|
86
87
|
name: `builtin:${t.name.toLowerCase()}`,
|
|
87
88
|
message: `${t.displayName}`,
|
|
88
|
-
}))
|
|
89
|
-
const customChoices = customTemplates.map(ct => ({
|
|
89
|
+
}))
|
|
90
|
+
const customChoices = customTemplates.map((ct) => ({
|
|
90
91
|
name: `custom:${ct.id}`,
|
|
91
92
|
message: `自定义:${ct.name}`,
|
|
92
93
|
hint: ct.type === 'git' ? ct.url : `本地: ${ct.path}`,
|
|
93
|
-
}))
|
|
94
|
+
}))
|
|
94
95
|
const addCustomChoice = {
|
|
95
96
|
name: '__add_custom__',
|
|
96
97
|
message: chalk.yellow('➕ 新增自定义模板(本地或 Git)'),
|
|
97
|
-
}
|
|
98
|
+
}
|
|
98
99
|
|
|
99
|
-
const allChoices = [...builtinChoices, ...customChoices, addCustomChoice]
|
|
100
|
+
const allChoices = [...builtinChoices, ...customChoices, addCustomChoice]
|
|
100
101
|
|
|
101
102
|
// 计算默认选中索引
|
|
102
|
-
let initialIndex = 0
|
|
103
|
+
let initialIndex = 0
|
|
103
104
|
if (defaultTpl && defaultTpl.type === 'builtin') {
|
|
104
|
-
const idx = allChoices.findIndex(
|
|
105
|
-
|
|
106
|
-
);
|
|
107
|
-
if (idx >= 0) initialIndex = idx;
|
|
105
|
+
const idx = allChoices.findIndex((c) => c.name === `builtin:${defaultTpl.idOrName}`)
|
|
106
|
+
if (idx >= 0) initialIndex = idx
|
|
108
107
|
} else if (defaultTpl && defaultTpl.type === 'custom') {
|
|
109
|
-
const idx = allChoices.findIndex(
|
|
110
|
-
|
|
111
|
-
);
|
|
112
|
-
if (idx >= 0) initialIndex = idx;
|
|
108
|
+
const idx = allChoices.findIndex((c) => c.name === `custom:${defaultTpl.idOrName}`)
|
|
109
|
+
if (idx >= 0) initialIndex = idx
|
|
113
110
|
}
|
|
114
111
|
|
|
115
112
|
const templatePrompt = new TemplateSelect({
|
|
@@ -117,13 +114,13 @@ export async function selectTemplateWithEnquirer () {
|
|
|
117
114
|
message: '选择项目模板(使用 ↑↓ 键切换,实时查看结构)',
|
|
118
115
|
choices: allChoices,
|
|
119
116
|
initial: initialIndex,
|
|
120
|
-
})
|
|
117
|
+
})
|
|
121
118
|
|
|
122
119
|
try {
|
|
123
|
-
const answer = await templatePrompt.run()
|
|
120
|
+
const answer = await templatePrompt.run()
|
|
124
121
|
|
|
125
122
|
// 清除屏幕上的大量输出,只保留简洁的确认信息
|
|
126
|
-
console.clear()
|
|
123
|
+
console.clear()
|
|
127
124
|
|
|
128
125
|
// 显示选中确认
|
|
129
126
|
if (answer === '__add_custom__') {
|
|
@@ -135,8 +132,8 @@ export async function selectTemplateWithEnquirer () {
|
|
|
135
132
|
{ name: 'local', message: '本地目录' },
|
|
136
133
|
{ name: 'git', message: 'Git 仓库' },
|
|
137
134
|
],
|
|
138
|
-
})
|
|
139
|
-
const sourceType = await typePrompt.run()
|
|
135
|
+
})
|
|
136
|
+
const sourceType = await typePrompt.run()
|
|
140
137
|
|
|
141
138
|
// 输入路径或 URL
|
|
142
139
|
const inputPrompt = new enquirer.Input({
|
|
@@ -145,86 +142,75 @@ export async function selectTemplateWithEnquirer () {
|
|
|
145
142
|
sourceType === 'git'
|
|
146
143
|
? '请输入 Git 仓库地址(如 https://... 或 git@...)'
|
|
147
144
|
: '请输入本地模板目录绝对路径',
|
|
148
|
-
})
|
|
149
|
-
const pathOrUrl = await inputPrompt.run()
|
|
145
|
+
})
|
|
146
|
+
const pathOrUrl = await inputPrompt.run()
|
|
150
147
|
|
|
151
148
|
// 分支(Git)
|
|
152
|
-
let branch = 'main'
|
|
149
|
+
let branch = 'main'
|
|
153
150
|
if (sourceType === 'git') {
|
|
154
151
|
const branchPrompt = new enquirer.Input({
|
|
155
152
|
name: 'branch',
|
|
156
153
|
message: '请输入分支名称(默认 main)',
|
|
157
154
|
initial: 'main',
|
|
158
|
-
})
|
|
159
|
-
branch = await branchPrompt.run()
|
|
160
|
-
if (!branch) branch = 'main'
|
|
155
|
+
})
|
|
156
|
+
branch = await branchPrompt.run()
|
|
157
|
+
if (!branch) branch = 'main'
|
|
161
158
|
}
|
|
162
159
|
|
|
163
160
|
// 基本校验
|
|
164
161
|
if (sourceType === 'local' && !existsSync(pathOrUrl)) {
|
|
165
|
-
console.log(chalk.red('本地目录不存在:'), pathOrUrl)
|
|
166
|
-
process.exit(1)
|
|
162
|
+
console.log(chalk.red('本地目录不存在:'), pathOrUrl)
|
|
163
|
+
process.exit(1)
|
|
167
164
|
}
|
|
168
165
|
|
|
169
166
|
// 生成 id 与名称
|
|
170
167
|
const nameGuess =
|
|
171
168
|
sourceType === 'git'
|
|
172
169
|
? pathOrUrl.split('/').pop()?.replace('.git', '') || 'custom'
|
|
173
|
-
: basename(pathOrUrl)
|
|
174
|
-
const id = `${nameGuess
|
|
175
|
-
.replace(/\W+/g, '-')
|
|
176
|
-
.toLowerCase()}-${Date.now()}`;
|
|
170
|
+
: basename(pathOrUrl)
|
|
171
|
+
const id = `${nameGuess.replace(/\W+/g, '-').toLowerCase()}-${Date.now()}`
|
|
177
172
|
|
|
178
173
|
const newTemplate = {
|
|
179
174
|
id,
|
|
180
175
|
name: nameGuess,
|
|
181
176
|
type: sourceType,
|
|
182
177
|
...(sourceType === 'git' ? { url: pathOrUrl, branch } : { path: pathOrUrl }),
|
|
183
|
-
}
|
|
178
|
+
}
|
|
184
179
|
|
|
185
|
-
configManager.addTemplate(newTemplate)
|
|
180
|
+
configManager.addTemplate(newTemplate)
|
|
186
181
|
|
|
187
|
-
console.log(
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
);
|
|
191
|
-
configManager.setDefaultTemplate('custom', newTemplate.id);
|
|
192
|
-
return { kind: 'custom', id: newTemplate.id };
|
|
182
|
+
console.log(chalk.green('✓ 已保存自定义模板:'), chalk.cyan.bold(newTemplate.name))
|
|
183
|
+
configManager.setDefaultTemplate('custom', newTemplate.id)
|
|
184
|
+
return { kind: 'custom', id: newTemplate.id }
|
|
193
185
|
}
|
|
194
186
|
|
|
195
187
|
if (answer.startsWith('builtin:')) {
|
|
196
|
-
const name = answer.split(':')[1]
|
|
197
|
-
const selectedTemplate = BUILTIN_TEMPLATES[name]
|
|
198
|
-
console.log(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
);
|
|
202
|
-
configManager.setDefaultTemplate('builtin', name);
|
|
203
|
-
return { kind: 'builtin', name };
|
|
188
|
+
const name = answer.split(':')[1]
|
|
189
|
+
const selectedTemplate = BUILTIN_TEMPLATES[name]
|
|
190
|
+
console.log(chalk.green('✓ 已选择:'), chalk.cyan.bold(selectedTemplate.displayName))
|
|
191
|
+
configManager.setDefaultTemplate('builtin', name)
|
|
192
|
+
return { kind: 'builtin', name }
|
|
204
193
|
}
|
|
205
194
|
|
|
206
195
|
if (answer.startsWith('custom:')) {
|
|
207
|
-
const id = answer.split(':')[1]
|
|
208
|
-
const ct = customTemplates.find(t => t.id === id)
|
|
209
|
-
console.log(
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
);
|
|
213
|
-
configManager.setDefaultTemplate('custom', id);
|
|
214
|
-
return { kind: 'custom', id };
|
|
196
|
+
const id = answer.split(':')[1]
|
|
197
|
+
const ct = customTemplates.find((t) => t.id === id)
|
|
198
|
+
console.log(chalk.green('✓ 已选择自定义:'), chalk.cyan.bold(ct?.name || id))
|
|
199
|
+
configManager.setDefaultTemplate('custom', id)
|
|
200
|
+
return { kind: 'custom', id }
|
|
215
201
|
}
|
|
216
202
|
|
|
217
203
|
// 兜底(保持兼容)
|
|
218
|
-
const nameFallback = answer
|
|
219
|
-
configManager.setDefaultTemplate('builtin', nameFallback)
|
|
220
|
-
const selectedTemplate = BUILTIN_TEMPLATES[nameFallback]
|
|
204
|
+
const nameFallback = answer
|
|
205
|
+
configManager.setDefaultTemplate('builtin', nameFallback)
|
|
206
|
+
const selectedTemplate = BUILTIN_TEMPLATES[nameFallback]
|
|
221
207
|
console.log(
|
|
222
208
|
chalk.green('✓ 已选择:'),
|
|
223
|
-
chalk.cyan.bold(selectedTemplate?.displayName || nameFallback)
|
|
224
|
-
)
|
|
225
|
-
return { kind: 'builtin', name: nameFallback }
|
|
209
|
+
chalk.cyan.bold(selectedTemplate?.displayName || nameFallback),
|
|
210
|
+
)
|
|
211
|
+
return { kind: 'builtin', name: nameFallback }
|
|
226
212
|
} catch (error) {
|
|
227
|
-
console.log(chalk.yellow('\n操作已取消'))
|
|
228
|
-
process.exit(0)
|
|
213
|
+
console.log(chalk.yellow('\n操作已取消'))
|
|
214
|
+
process.exit(0)
|
|
229
215
|
}
|
|
230
216
|
}
|
package/locales/en-US.json
CHANGED
|
@@ -56,4 +56,4 @@
|
|
|
56
56
|
"snippets.sync_success": "✅ Code snippets synced successfully!",
|
|
57
57
|
"snippets.detect_config": "ℹ️ Project config detected, filtering snippets...",
|
|
58
58
|
"snippets.applied_filter": "Architecture-aware filtering applied (BasePage: {basePage}, ViewModel: {viewModel})"
|
|
59
|
-
}
|
|
59
|
+
}
|
package/locales/zh-CN.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"cli.description": "🚀 Flutter
|
|
2
|
+
"cli.description": "🚀 Flutter 全流程效率工具链",
|
|
3
3
|
"cmd.new.desc": "创建 Flutter 项目(实时模板预览)",
|
|
4
4
|
"cmd.new.opt.template": "模板类型: lite, modular, clean",
|
|
5
5
|
"cmd.new.opt.state": "状态管理器: default, provider, getx",
|
|
@@ -56,4 +56,4 @@
|
|
|
56
56
|
"snippets.sync_success": "✅ 代码片段同步成功!",
|
|
57
57
|
"snippets.detect_config": "ℹ️ 检测到项目配置,正在按需过滤代码片段...",
|
|
58
58
|
"snippets.applied_filter": "已应用架构感知过滤 (BasePage: {basePage}, ViewModel: {viewModel})"
|
|
59
|
-
}
|
|
59
|
+
}
|
package/package.json
CHANGED
|
@@ -1,59 +1,62 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
2
|
+
"name": "flu-cli",
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Flutter 全流程效率工具链",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"flu-cli": "./index.js"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"tag": "latest"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"start": "node ./index.js",
|
|
15
|
+
"dev": "NODE_ENV=development node ./index.js --",
|
|
16
|
+
"prod": "NODE_ENV=production node ./index.js",
|
|
17
|
+
"build": "node -e \"console.log('flu-cli: no build step')\"",
|
|
18
|
+
"smoke:vnext-params": "node scripts/smoke-vnext-params.mjs",
|
|
19
|
+
"smoke:vnext-generate": "node scripts/smoke-vnext-generate.mjs",
|
|
20
|
+
"prepublishOnly": "NODE_ENV=production"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"flutter",
|
|
24
|
+
"cli",
|
|
25
|
+
"v2",
|
|
26
|
+
"scaffold",
|
|
27
|
+
"mvvm",
|
|
28
|
+
"template",
|
|
29
|
+
"generator"
|
|
30
|
+
],
|
|
31
|
+
"author": "火叶工作室",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://gitee.com/flu-cli/flu-cli.git"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "http://huozhiye.cn/flu-cli",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://gitee.com/flu-cli/flu-cli/issues"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@clack/prompts": "^0.11.0",
|
|
43
|
+
"flu-cli-core": "^1.0.6",
|
|
44
|
+
"chalk": "^4.1.2",
|
|
45
|
+
"commander": "^11.1.0",
|
|
46
|
+
"date-fns": "^4.1.0",
|
|
47
|
+
"enquirer": "^2.4.1",
|
|
48
|
+
"fs-extra": "^11.2.0",
|
|
49
|
+
"handlebars": "^4.7.8",
|
|
50
|
+
"inquirer": "^8.2.6",
|
|
51
|
+
"json5": "^2.2.3",
|
|
52
|
+
"ora": "^5.4.1",
|
|
53
|
+
"simple-git": "^3.20.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/fs-extra": "^11.0.4",
|
|
57
|
+
"@types/inquirer": "^9.0.7"
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=14.0.0"
|
|
61
|
+
}
|
|
59
62
|
}
|