flu-cli-core 1.0.2 → 1.0.3
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/README.md +84 -38
- package/dist/chunk-3RG5ZIWI.js +10 -0
- package/dist/{chunk-FOMWV2YP.js → chunk-ANN4MX7M.js} +25 -15
- package/dist/{factory-6DDXZYQP.js → factory-W73G7NBW.js} +2 -1
- package/dist/index.cjs +5268 -786
- package/dist/index.d.cts +122 -61
- package/dist/index.d.ts +122 -61
- package/dist/index.js +5171 -725
- package/dist/{upgrade_snippets-XFR7Q444.js → upgrade_snippets-J7SRI6M5.js} +1 -0
- package/locales/en-US.json +1 -1
- package/locales/zh-CN.json +2 -2
- package/package.json +56 -49
- package/templates/core_files/network/app_error_code.dart.template +6 -6
- package/templates/core_files/network/app_http.dart.template +4 -4
- package/templates/core_files/network/app_response.dart.template +2 -2
- package/templates/core_files/utils/loading_util.dart.template +13 -4
- package/templates/snippets/flu-cli.code-snippets +26 -36
- package/templates/request_helper.dart.template +0 -59
package/README.md
CHANGED
|
@@ -1,64 +1,110 @@
|
|
|
1
|
-
#
|
|
1
|
+
# flu-cli-core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
核心逻辑库,支持 Flutter 项目全生命周期管理:代码生成、项目初始化、资源管理、构建、以及多平台应用商店上传。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 🎯 核心功能
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
### 1. 项目生成与初始化 (Task Pipeline)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
采用 **原子化任务流水线** 架构,支持 4 种模板:Lite、Modular、Clean、Native。
|
|
10
10
|
|
|
11
|
-
`ProjectGenerator`
|
|
11
|
+
`ProjectGenerator` 作为 **Orchestrator (指挥官)**,通过 `ProjectPipeline` 编排一系列 `IProjectTask`:
|
|
12
12
|
|
|
13
|
-
```mermaid
|
|
14
|
-
graph LR
|
|
15
|
-
A[ProjectGenerator] --> B(ProjectPipeline)
|
|
16
|
-
B --> T1[FlutterInitTask]
|
|
17
|
-
B --> T2[TemplateCopyTask]
|
|
18
|
-
B --> T3[VariablesReplaceTask]
|
|
19
|
-
B --> T4[NetworkEnrichTask]
|
|
20
|
-
B --> T5[RouteMappingTask]
|
|
21
|
-
B --> T6[HomePatchTask]
|
|
22
|
-
B --> T7[CleanupTask]
|
|
23
13
|
```
|
|
14
|
+
ProjectGenerator
|
|
15
|
+
├─ FlutterInitTask (确保环境就绪)
|
|
16
|
+
├─ TemplateCopyTask (智能模板复制)
|
|
17
|
+
├─ VariablesReplaceTask (变量替换)
|
|
18
|
+
├─ NetworkEnrichTask (网络层注入)
|
|
19
|
+
├─ RouteMappingTask (路由自动扫描)
|
|
20
|
+
├─ HomePatchTask (首页示例注入)
|
|
21
|
+
└─ CleanupTask (清理冗余)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 2. 多平台应用商店上传 ✨
|
|
25
|
+
|
|
26
|
+
独立的 **@huoye/app-ship** 上传引擎,**8 个平台全部实测通过**:
|
|
27
|
+
|
|
28
|
+
- ✅ 蒲公英 (Pgyer) — 内测分发
|
|
29
|
+
- ✅ 华为 AppGallery — 国内商店
|
|
30
|
+
- ✅ 小米应用商店 — RSA 签名认证
|
|
31
|
+
- ✅ OPPO 应用商店 — HMAC-SHA256
|
|
32
|
+
- ✅ vivo 应用商店 — 一站式直传
|
|
33
|
+
- ✅ 腾讯应用宝 — COS 直传
|
|
34
|
+
- ✅ App Store — Transporter/altool
|
|
35
|
+
- ✅ 鸿蒙应用市场 — 华为 API 复用
|
|
36
|
+
|
|
37
|
+
详见 [@huoye/app-ship 文档](https://gitee.com/flu-cli/flu-cli/blob/main/packages/app-ship/README.md)。
|
|
38
|
+
|
|
39
|
+
### 3. 代码生成
|
|
40
|
+
|
|
41
|
+
支持 7 种代码生成器:
|
|
42
|
+
|
|
43
|
+
- **Page** — 页面生成
|
|
44
|
+
- **ViewModel** — 状态管理类
|
|
45
|
+
- **Widget** — 组件
|
|
46
|
+
- **Component** — 复用组件
|
|
47
|
+
- **Service** — 服务层
|
|
48
|
+
- **Model** — 数据模型
|
|
49
|
+
- **Module** — 功能模块
|
|
50
|
+
|
|
51
|
+
### 4. 应用资源管理
|
|
52
|
+
|
|
53
|
+
- **App Icon** — 一张图自动适配全平台(iOS、Android、Harmony)
|
|
54
|
+
- **启动图** — Logo + 背景色,自动配置 `flutter_native_splash`
|
|
55
|
+
|
|
56
|
+
### 5. 构建管理
|
|
57
|
+
|
|
58
|
+
- **Android**: APK / AAB 自动构建
|
|
59
|
+
- **iOS**: IPA 自动构建
|
|
60
|
+
|
|
61
|
+
## 💡 架构优势
|
|
62
|
+
|
|
63
|
+
- **极简核心** — `ProjectGenerator.ts` 从 1500 行精简至 100 行
|
|
64
|
+
- **高可扩展** — 新增功能只需实现 `IProjectTask` 并加入流水线
|
|
65
|
+
- **高度解耦** — 各 Task 职责单一,互不干扰
|
|
66
|
+
- **声明式** — 清晰可见每一个项目生成步骤
|
|
24
67
|
|
|
25
|
-
|
|
68
|
+
## 📦 三种使用方式
|
|
26
69
|
|
|
27
|
-
|
|
28
|
-
|
|
70
|
+
| 方式 | 工具 | 用途 |
|
|
71
|
+
| ---------- | ------------ | ----------------- |
|
|
72
|
+
| **命令行** | flu-cli (v2) | CI/CD、自动化发版 |
|
|
73
|
+
| **可视化** | VSCode 插件 | IDE 内点击操作 |
|
|
74
|
+
| **编程** | @huoye/app-ship npm | 自建发布系统 |
|
|
29
75
|
|
|
30
|
-
##
|
|
76
|
+
## 🔗 相关资源
|
|
31
77
|
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
78
|
+
- [@huoye/app-ship 独立上传库](https://gitee.com/flu-cli/flu-cli/blob/main/packages/app-ship/README.md) — 多平台上传引擎
|
|
79
|
+
- [VSCode 扩展](https://gitee.com/flu-cli/flu-cli/blob/main/packages/vscode-extension/README.md) — 可视化发布中心
|
|
80
|
+
- [CLI v2](https://gitee.com/flu-cli/flu-cli/blob/main/packages/v2/README.md) — 命令行工具
|
|
81
|
+
- [官方文档](http://huozhiye.cn/flu-cli/) — 完整指南
|
|
36
82
|
|
|
37
83
|
## 🚀 核心组件
|
|
38
84
|
|
|
39
|
-
### 生成器
|
|
85
|
+
### 生成器
|
|
40
86
|
|
|
41
|
-
- **ProjectGenerator
|
|
42
|
-
- **Page/ViewModel/Model Generator
|
|
43
|
-
- **Service Generator
|
|
87
|
+
- **ProjectGenerator** — Pipeline 模式的项目实例化引擎
|
|
88
|
+
- **Page/ViewModel/Model Generator** — 针对不同架构的代码生成
|
|
89
|
+
- **Service Generator** — 智能服务层生成,支持网络层检测
|
|
44
90
|
|
|
45
|
-
### 任务体系
|
|
91
|
+
### 任务体系
|
|
46
92
|
|
|
47
|
-
- `FlutterInitTask
|
|
48
|
-
- `TemplateCopyTask
|
|
49
|
-
- `NetworkEnrichTask
|
|
50
|
-
- `RouteMappingTask
|
|
51
|
-
- `HomePatchTask
|
|
93
|
+
- `FlutterInitTask` — 确保原生 Flutter 环境就绪
|
|
94
|
+
- `TemplateCopyTask` — 智能处理模板复制与冗余清理
|
|
95
|
+
- `NetworkEnrichTask` — 声明式注入网络层基础设施
|
|
96
|
+
- `RouteMappingTask` — 自动扫描业务路径并注册路由表
|
|
97
|
+
- `HomePatchTask` — 自动化首页示例入口
|
|
52
98
|
|
|
53
99
|
## 🛠 开发与扩展
|
|
54
100
|
|
|
55
|
-
###
|
|
101
|
+
### 添加新任务
|
|
56
102
|
|
|
57
|
-
1. 在 `src/generators/tasks/` 创建实现 `IProjectTask`
|
|
58
|
-
2. 在 `ProjectGenerator.generate` 中通过 `.addTask()`
|
|
103
|
+
1. 在 `src/generators/tasks/` 创建实现 `IProjectTask` 的类
|
|
104
|
+
2. 在 `ProjectGenerator.generate` 中通过 `.addTask()` 链式调用
|
|
59
105
|
|
|
60
106
|
```typescript
|
|
61
|
-
pipeline.addTask(new YourAwesomeTask())
|
|
107
|
+
pipeline.addTask(new YourAwesomeTask())
|
|
62
108
|
```
|
|
63
109
|
|
|
64
110
|
## 📜 许可证
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
__require
|
|
10
|
+
};
|
|
@@ -18,10 +18,7 @@ var ProviderAdapter = class {
|
|
|
18
18
|
}
|
|
19
19
|
getImports(relativeCorePath) {
|
|
20
20
|
if (this.name === "provider") {
|
|
21
|
-
return [
|
|
22
|
-
`import 'package:provider/provider.dart';`,
|
|
23
|
-
`import '${relativeCorePath}';`
|
|
24
|
-
];
|
|
21
|
+
return [`import 'package:provider/provider.dart';`, `import '${relativeCorePath}';`];
|
|
25
22
|
}
|
|
26
23
|
return [`import '${relativeCorePath}';`];
|
|
27
24
|
}
|
|
@@ -143,9 +140,7 @@ class BaseViewModel extends GetxController {
|
|
|
143
140
|
return isListPage ? "BaseListViewModel" : "BaseViewModel";
|
|
144
141
|
}
|
|
145
142
|
getImports(relativeCorePath) {
|
|
146
|
-
return [
|
|
147
|
-
`import '${relativeCorePath}';`
|
|
148
|
-
];
|
|
143
|
+
return [`import '${relativeCorePath}';`];
|
|
149
144
|
}
|
|
150
145
|
/**
|
|
151
146
|
* 修改 app.dart
|
|
@@ -173,7 +168,10 @@ class BaseViewModel extends GetxController {
|
|
|
173
168
|
raw = raw.replace(/navigatorKey:\s*NavigatorUtil\.navigatorKey\s*,?/g, "");
|
|
174
169
|
}
|
|
175
170
|
if (raw.includes("scaffoldMessengerKey: NavigatorUtil.scaffoldMessengerKey")) {
|
|
176
|
-
raw = raw.replace(
|
|
171
|
+
raw = raw.replace(
|
|
172
|
+
/scaffoldMessengerKey:\s*NavigatorUtil\.scaffoldMessengerKey\s*,?\s*\n?/g,
|
|
173
|
+
""
|
|
174
|
+
);
|
|
177
175
|
}
|
|
178
176
|
return raw;
|
|
179
177
|
}
|
|
@@ -268,8 +266,13 @@ var RiverpodAdapter = class {
|
|
|
268
266
|
const { projectPath } = context;
|
|
269
267
|
const baseDir = join(projectPath, "lib", "core", "base");
|
|
270
268
|
await fsx.ensureDir(baseDir);
|
|
271
|
-
await fsx.writeFile(
|
|
272
|
-
|
|
269
|
+
await fsx.writeFile(
|
|
270
|
+
join(baseDir, "view_state.dart"),
|
|
271
|
+
"enum ViewState { idle, loading, success, error }\n"
|
|
272
|
+
);
|
|
273
|
+
await fsx.writeFile(
|
|
274
|
+
join(baseDir, "base_state.dart"),
|
|
275
|
+
`
|
|
273
276
|
import 'view_state.dart';
|
|
274
277
|
|
|
275
278
|
class BaseState {
|
|
@@ -296,8 +299,11 @@ class BaseState {
|
|
|
296
299
|
bool get isError => state == ViewState.error;
|
|
297
300
|
bool get isIdle => state == ViewState.idle;
|
|
298
301
|
}
|
|
299
|
-
`
|
|
300
|
-
|
|
302
|
+
`
|
|
303
|
+
);
|
|
304
|
+
await fsx.writeFile(
|
|
305
|
+
join(baseDir, "base_notifier.dart"),
|
|
306
|
+
`
|
|
301
307
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
302
308
|
import 'view_state.dart';
|
|
303
309
|
import 'base_state.dart';
|
|
@@ -322,8 +328,11 @@ abstract class BaseNotifier<T extends BaseState> extends Notifier<T> {
|
|
|
322
328
|
}
|
|
323
329
|
}
|
|
324
330
|
}
|
|
325
|
-
`
|
|
326
|
-
|
|
331
|
+
`
|
|
332
|
+
);
|
|
333
|
+
await fsx.writeFile(
|
|
334
|
+
join(baseDir, "base_page_riverpod.dart"),
|
|
335
|
+
`
|
|
327
336
|
import 'package:flutter/material.dart';
|
|
328
337
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
329
338
|
import 'base_state.dart';
|
|
@@ -353,7 +362,8 @@ class BasePageRiverpod<TState extends BaseState, TNotifier extends Notifier<TSta
|
|
|
353
362
|
);
|
|
354
363
|
}
|
|
355
364
|
}
|
|
356
|
-
`
|
|
365
|
+
`
|
|
366
|
+
);
|
|
357
367
|
}
|
|
358
368
|
};
|
|
359
369
|
|