flu-cli 0.0.4 → 2.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.
Files changed (50) hide show
  1. package/CLI.md +349 -0
  2. package/README.md +59 -155
  3. package/config/dev.config.js +56 -0
  4. package/config/templates.js +147 -0
  5. package/index.js +128 -81
  6. package/lib/commands/add.js +472 -0
  7. package/lib/commands/cache.js +99 -0
  8. package/lib/commands/completion.js +94 -0
  9. package/lib/commands/generate.js +26 -0
  10. package/lib/commands/newClack.js +396 -0
  11. package/lib/commands/snippets.js +39 -0
  12. package/lib/commands/templates.js +84 -0
  13. package/lib/generators/component_generator.js +93 -0
  14. package/lib/generators/model_generator.js +303 -0
  15. package/lib/generators/module_generator.js +141 -0
  16. package/lib/generators/page_generator.js +322 -0
  17. package/lib/generators/project_generator.js +96 -0
  18. package/lib/generators/service_generator.js +408 -0
  19. package/lib/generators/state_manager_generator.js +402 -0
  20. package/lib/generators/viewmodel_generator.js +115 -0
  21. package/lib/generators/widget_generator.js +104 -0
  22. package/lib/templates/templateCopier.js +296 -0
  23. package/lib/templates/templateManager.js +191 -0
  24. package/lib/utils/config.js +99 -0
  25. package/lib/utils/flutterHelper.js +85 -0
  26. package/lib/utils/index_updater.js +69 -0
  27. package/lib/utils/logger.js +57 -0
  28. package/lib/utils/project_detector.js +227 -0
  29. package/lib/utils/snippet_loader.js +32 -0
  30. package/lib/utils/string_helper.js +56 -0
  31. package/lib/utils/templateSelectorEnquirer.js +200 -0
  32. package/package.json +31 -6
  33. package/release.sh +107 -0
  34. package/scripts/e2e-state-tests.js +116 -0
  35. package/scripts/sync-base-to-templates.js +108 -0
  36. package/scripts/workspace-clone-all.sh +101 -0
  37. package/scripts/workspace-status-all.sh +112 -0
  38. package/templates/README.md +138 -0
  39. package/templates/base_files/base_list_page.dart.template +174 -0
  40. package/templates/base_files/base_list_viewmodel.dart.template +134 -0
  41. package/templates/base_files/base_page.dart.template +251 -0
  42. package/templates/base_files/base_viewmodel.dart.template +77 -0
  43. package/templates/base_files/theme/status_views_theme.dart.template +46 -0
  44. package/templates/snippets/dart.code-snippets +487 -0
  45. package/lib/createProject.js +0 -220
  46. package/lib/flutterProjectCreator.js +0 -80
  47. package/lib/libCopier.js +0 -368
  48. package/lib/userInteraction.js +0 -274
  49. package/lib/utils.js +0 -200
  50. package/publish.sh +0 -29
@@ -0,0 +1,147 @@
1
+ /**
2
+ * 模板配置文件
3
+ * 定义所有可用的项目模板
4
+ */
5
+
6
+ export const TEMPLATES = {
7
+ lite: {
8
+ name: 'Lite',
9
+ displayName: 'Lite - 精简版',
10
+ description: '最小依赖,单文件结构,适合小型项目和快速原型',
11
+ local: true,
12
+ repo: 'https://gitee.com/flu-cli/template-lite.git',
13
+ branch: 'main',
14
+ complexity: 1,
15
+ teamSize: '1 人',
16
+ codeSize: '< 5k 行',
17
+ features: [
18
+ '✅ 最小依赖',
19
+ '✅ 单文件结构',
20
+ '✅ Material 3 设计',
21
+ '✅ 快速启动'
22
+ ],
23
+ structure: `
24
+ lib/
25
+ ├── 📄 main.dart # 应用入口
26
+ ├── 📄 app.dart # 应用配置
27
+ ├── 📁 pages/ # 页面
28
+ ├── 📁 viewmodels/ # 视图模型
29
+ ├── 📁 widgets/ # 简单组件
30
+ ├── 📁 components/ # 复合组件
31
+ ├── 📁 services/ # 业务服务
32
+ ├── 📁 models/ # 数据模型
33
+ ├── 📁 config/ # 配置
34
+ └── 📁 utils/ # 工具类
35
+ `
36
+ },
37
+
38
+ modular: {
39
+ name: 'Modular',
40
+ displayName: 'Modular - 模块化版',
41
+ description: '模块化结构,功能分组,适合中型项目',
42
+ local: true,
43
+ repo: 'https://gitee.com/flu-cli/template-modular.git',
44
+ branch: 'main',
45
+ complexity: 3,
46
+ teamSize: '2-5 人',
47
+ codeSize: '5k-20k 行',
48
+ features: [
49
+ '✅ 模块化结构',
50
+ '✅ 路由配置独立',
51
+ '✅ 主题配置独立',
52
+ '✅ 功能分组'
53
+ ],
54
+ structure: `
55
+ lib/
56
+ ├── 📄 main.dart
57
+ ├── 📁 core/ # 核心基础设施
58
+ │ ├── theme/ # 主题系统
59
+ │ ├── router/ # 路由系统
60
+ │ ├── constants/ # 常量定义
61
+ │ └── base/ # 基础类(BaseViewModel, BasePage)
62
+ ├── 📁 shared/ # 跨模块共享
63
+ │ ├── widgets/ # 通用简单组件
64
+ │ ├── components/ # 通用复合组件
65
+ │ ├── models/ # 通用数据模型
66
+ │ └── utils/ # 通用工具类
67
+ └── 📁 features/ # 业务功能模块
68
+ ├── hoem/ # 用户模块
69
+ │ ├── pages/
70
+ │ ├── viewmodels/
71
+ │ ├── widgets/
72
+ │ ├── services/
73
+ └── └── models/
74
+ `
75
+ },
76
+
77
+ clean: {
78
+ name: 'Clean',
79
+ displayName: 'Clean - 分层版',
80
+ description: '严格分层架构,清晰的目录结构,适合大型项目',
81
+ local: true,
82
+ repo: 'https://gitee.com/flu-cli/template-clean.git',
83
+ branch: 'main',
84
+ complexity: 5,
85
+ teamSize: '5+ 人',
86
+ codeSize: '> 20k 行',
87
+ features: [
88
+ '✅ 严格分层架构',
89
+ '✅ 清晰的目录结构',
90
+ '✅ 易于扩展和维护',
91
+ '✅ 适合团队协作'
92
+ ],
93
+ structure: `
94
+ lib/
95
+ ├── 📄 main.dart # 应用入口
96
+ ├── 📄 app.dart # 应用配置
97
+ ├── 📁 core/ # 核心层(最内层)
98
+ │ ├── constants/ # 常量定义
99
+ │ ├── errors/ # 错误和异常
100
+ │ ├── usecases/ # UseCase 基类
101
+ │ ├── utils/ # 工具类
102
+ │ └── network/ # 网络配置
103
+ ├── 📁 features/ # 功能模块(按业务划分)
104
+ │ └── home/ # 示例:首页模块
105
+ │ ├── data/ # 数据层
106
+ │ │ ├── datasources/ # 数据源(API/本地)
107
+ │ │ ├── models/ # 数据模型(DTO)
108
+ │ │ └── repositories/ # Repository 实现
109
+ │ ├── domain/ # 领域层
110
+ │ │ ├── entities/ # 业务实体
111
+ │ │ ├── repositories/ # Repository 接口
112
+ │ │ └── usecases/ # 用例(业务逻辑)
113
+ │ └── presentation/ # 表现层
114
+ │ ├── pages/ # 页面
115
+ │ ├── widgets/ # 模块专用组件
116
+ │ └── viewmodels/ # 视图模型
117
+ ├── 📁 shared/ # 共享资源
118
+ │ ├── widgets/ # 通用组件
119
+ │ ├── components/ # 通用复合组件
120
+ │ └── extensions/ # 扩展方法
121
+ └── 📁 config/ # 配置层
122
+ ├── routes/ # 路由配置
123
+ └── theme/ # 主题配置
124
+ `
125
+ }
126
+ };
127
+
128
+ /**
129
+ * 获取模板配置
130
+ */
131
+ export function getTemplate (name) {
132
+ return TEMPLATES[name];
133
+ }
134
+
135
+ /**
136
+ * 获取所有模板
137
+ */
138
+ export function getAllTemplates () {
139
+ return Object.values(TEMPLATES);
140
+ }
141
+
142
+ /**
143
+ * 验证模板名称
144
+ */
145
+ export function isValidTemplate (name) {
146
+ return name in TEMPLATES;
147
+ }
package/index.js CHANGED
@@ -1,108 +1,155 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * 火之夜工作室 Flutter 项目创建工具
4
+ * flu-cli v2.0
5
+ * Flutter MVVM 脚手架工具
5
6
  *
6
- * 主入口文件,处理命令行参数并调用相应功能
7
+ * 支持多种架构模板和代码生成功能
7
8
  */
8
9
 
9
-
10
- import { program } from 'commander'
10
+ import { program } from 'commander';
11
11
  import chalk from 'chalk';
12
- import { createProject } from './lib/createProject.js';
13
12
  import { readFileSync } from 'fs';
14
13
  import { fileURLToPath } from 'url';
15
14
  import { dirname, join } from 'path';
15
+ import { newProjectWithClack } from './lib/commands/newClack.js';
16
+ import { addComponent } from './lib/commands/add.js';
17
+ import { listTemplates, showTemplateDetail } from './lib/commands/templates.js';
18
+ import { updateTemplates, cleanCache } from './lib/commands/cache.js';
19
+ import { generateStateManager } from './lib/commands/generate.js';
16
20
 
17
- // 获取package.json内容
21
+ // 获取 package.json
18
22
  const __dirname = dirname(fileURLToPath(import.meta.url));
19
23
  const packageJson = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8'));
20
24
 
21
- // 设置版本号和描述
25
+ // 设置版本和描述
22
26
  program
23
27
  .version(packageJson.version)
24
- .description(chalk.cyan('火之夜工作室 Flutter 项目创建工具'));
25
-
26
- //
28
+ .description(chalk.cyan('🚀 Flutter MVVM 脚手架工具'));
27
29
 
28
- // 创建项目命令
30
+ // ========== 创建项目命令(V1 已废弃) ==========
31
+ // V1 命令已移除,请使用 'flu new' 命令
29
32
  program
30
33
  .command('create')
31
- .description('创建新的Flutter项目')
32
- .option('-t, --project-type <type>', '项目类型: app, module, package, plugin', 'app')
33
- .option('-m, --template-type <type>', '模板类型: only, min, normal, pro', 'normal')
34
- .option('-s, --state-manager <name>', '状态管理: state, GetX, Provider, MobX, Bloc, Riverpod', 'GetX')
35
- .option('-n, --project-name <name>', '项目名称')
36
- .option('-p, --package-name <name>', '包名(com.example.app)')
37
- .option('-d, --parent-dir <path>', '项目存放目录')
38
- .option('-i, --ide <type>', '使用的IDE: vscode, android_studio, open_folder , manual', 'vscode')
39
- .option('-f, --flutter-sdk <path>', '自定义Flutter SDK路径')
40
- .option('-h, --help', '显示创建命令帮助信息')
41
- .action((options) => {
42
- if (options.help) {
43
- console.log(chalk.bold.greenBright('flu-cli create - 创建新的Flutter项目'));
44
- console.log('用法: flu-cli create [选项]');
45
- console.log('选项:');
46
- console.log(' -t, --project-type <type> 项目类型 (app, module, package, plugin) [默认: app]');
47
- console.log(' -m, --template-type <type> 模板类型 (only, min, normal, pro) [默认: pro]');
48
- console.log(' -s, --state-manager <name> 状态管理方案 (state, GetX,) [默认: GetX]');
49
- console.log(' -n, --project-name <name> 项目名称 [默认: hzy_example_${项目类型}]');
50
- console.log(' -p, --package-name <name> 包名 [默认: com.example.${项目类型}]');
51
- console.log(' -d, --parent-dir <path> 项目存放目录 [默认: 当前目录]');
52
- console.log(' -i, --ide <choice> IDE选择 (vscode, android_studio, open_folder, manual) [默认: vscode]');
53
- console.log(' -f, --flutter-sdk <path> 自定义Flutter SDK路径 [默认: 系统环境变量中的flutter]');
54
- console.log(' -h, --help 显示本帮助信息');
55
- process.exit(0);
34
+ .description('⚠️ 已废弃:请使用 flu new 命令')
35
+ .action(() => {
36
+ console.log(chalk.yellow('\n⚠️ create 命令已在 V2 中废弃\n'));
37
+ console.log(chalk.cyan('请使用新命令:'));
38
+ console.log(chalk.green(' flu new <project-name>\n'));
39
+ console.log(chalk.gray('示例:'));
40
+ console.log(chalk.gray(' flu new my_app --template lite'));
41
+ console.log(chalk.gray(' flu new my_app --template modular'));
42
+ console.log(chalk.gray(' flu new my_app --template clean\n'));
43
+ console.log(chalk.blue('查看帮助:flu new --help\n'));
44
+ process.exit(0);
45
+ });
46
+
47
+ // ========== 新建项目命令(现代化交互式体验) ==========
48
+ program
49
+ .command('new [project-name]')
50
+ .alias('n')
51
+ .description('创建 Flutter 项目(实时模板预览)')
52
+ .option('-t, --template <type>', '模板类型: lite, modular, clean')
53
+ .option('-s, --state <type>', '状态管理器: default, provider, getx, riverpod', 'default')
54
+ .option('-d, --dir <path>', '项目存放目录', process.cwd())
55
+ .option('--no-cache', '不使用缓存,强制从 Git 拉取')
56
+ .option('--remote', '使用远程 Gitee 模板(默认使用本地模板)')
57
+ .action((projectName, options) => {
58
+ newProjectWithClack(projectName, options);
59
+ });
60
+
61
+ // ========== 添加组件命令 ==========
62
+ program
63
+ .command('add [type] [name]')
64
+ .alias('a')
65
+ .description('添加 Flutter 代码组件 (page/p, widget/w, component/c, ...)')
66
+ .option('-f, --feature <name>', '所属功能模块(仅 modular/clean 模式)')
67
+ .option('--stateful', '创建 StatefulWidget(默认 StatelessWidget)')
68
+ .option('--stateless', '强制创建 StatelessWidget(即使有 ViewModel,不推荐)')
69
+ .option('--list-page', '创建列表页 (BaseListPage)')
70
+ .option('--no-vm', '不生成 ViewModel(仅 page 类型)')
71
+ .option('--type <type>', 'Service 类型: api, storage, auth(仅 service 类型)', 'api')
72
+ .option('--json <file>', '从 JSON 文件生成(仅 model 类型)')
73
+ .option('--list', '查看支持的类型列表')
74
+ .action((type, name, options) => {
75
+ addComponent(type, name, options);
76
+ });
77
+
78
+ // ========== 模板管理命令 ==========
79
+ program
80
+ .command('templates [template-name]')
81
+ .alias('t')
82
+ .description('查看所有模板或指定模板详情')
83
+ .action((templateName) => {
84
+ if (templateName) {
85
+ showTemplateDetail(templateName);
86
+ } else {
87
+ listTemplates();
56
88
  }
89
+ });
57
90
 
58
- console.log(chalk.bold.greenBright('欢迎使用 火之夜工作室 Flutter 项目创建工具'));
59
-
60
- // 检查是否提供了命令行参数
61
- const hasCommandLineArgs = options.projectName ||
62
- options.packageName ||
63
- options.projectType !== 'app' ||
64
- options.templateType !== 'normal' ||
65
- options.stateManager !== 'GetX' ||
66
- options.parentDir || options.ide !== 'vscode' || options.flutterSdk;
67
-
68
- // 如果提供了命令行参数,则直接使用这些参数创建项目
69
- // 否则使用交互式方式获取参数
70
- createProject({
71
- useCommandLineArgs: hasCommandLineArgs,
72
- projectType: options.projectType,
73
- templateType: options.templateType,
74
- stateManager: options.stateManager,
75
- projectName: options.projectName,
76
- packageName: options.packageName,
77
- parentDir: options.parentDir,
78
- ideChoice: options.ide,
79
- flutterSdkPath: options.flutterSdk,
80
- });
91
+ program
92
+ .command('generate-sm <type>')
93
+ .alias('g')
94
+ .description('为现有项目生成状态管理适配与配置')
95
+ .option('-d, --dir <path>', '项目目录', process.cwd())
96
+ .option('-m, --module <name>', '模块名称(modular/clean 支持分模块适配器布局)')
97
+ .action((type, options) => {
98
+ generateStateManager(type, options);
81
99
  });
82
100
 
83
- // 全局帮助处理
84
- if (process.argv.includes('-h') || process.argv.includes('--help')) {
85
- if (process.argv.length <= 3) {
86
- console.log('flu-cli - 火之夜工作室Flutter项目创建工具');
87
- console.log('版本: ' + packageJson.version);
88
- console.log('用法: flu-cli [命令] [选项]\n');
89
- console.log('命令:');
90
- console.log(' create 创建新的Flutter项目\n');
91
- console.log('全局选项:');
92
- console.log(' -V, --version 显示版本号');
93
- console.log(' -h, --help 显示全局帮助信息\n');
94
- console.log('使用 "flu-cli [命令] --help" 查看特定命令的详细帮助');
95
- process.exit(0);
96
- }
97
- program.parse(process.argv);
98
- }
101
+ // ========== 缓存管理命令 ==========
102
+ program
103
+ .command('update-templates [template-name]')
104
+ .alias('update')
105
+ .alias('u')
106
+ .description('更新模板缓存')
107
+ .option('--force', '强制刷新并清理未跟踪文件')
108
+ .action((templateName, options) => {
109
+ updateTemplates(templateName, options);
110
+ });
111
+
112
+ program
113
+ .command('cache <action>')
114
+ .alias('c')
115
+ .description('缓存管理 (action: clean)')
116
+ .action((action) => {
117
+ if (action === 'clean') {
118
+ cleanCache();
119
+ } else {
120
+ console.log(chalk.red(`未知的操作: ${action}`));
121
+ console.log(chalk.yellow('支持的操作: clean'));
122
+ }
123
+ });
99
124
 
125
+ // ========== 代码片段管理 ==========
126
+ import { syncSnippets } from './lib/commands/snippets.js';
100
127
 
128
+ program
129
+ .command('sync-snippets')
130
+ .alias('sync')
131
+ .description('同步最新版本的标准代码片段到当前项目')
132
+ .action(() => {
133
+ syncSnippets();
134
+ });
101
135
 
102
- // 如果没有提供命令,默认执行创建项目
136
+ // ========== 自动补全 ==========
137
+ import { completion } from './lib/commands/completion.js';
138
+
139
+ program
140
+ .command('completion')
141
+ .alias('comp')
142
+ .description('生成 Shell 自动补全脚本 (bash/zsh)')
143
+ .action(() => {
144
+ completion();
145
+ });
146
+
147
+
148
+ // 解析命令行参数
149
+ program.parse(process.argv);
150
+
151
+ // 如果没有提供命令,显示帮助信息
103
152
  if (process.argv.length === 2) {
104
- console.log(chalk.bold.greenBright('欢迎使用 火之夜工作室 Flutter 项目创建工具\n'));
105
- createProject({});
106
- } else {
107
- program.parse(process.argv);
108
- }
153
+ console.log(chalk.bold.cyan('\n🚀 欢迎使用 flu-cli v2.0\n'));
154
+ program.help();
155
+ }