@ynight/cli 0.0.0-stage → 0.0.1

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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +251 -2
  3. package/config/client.json +14 -0
  4. package/config/server.json +16 -0
  5. package/dist/bin.d.ts +26 -0
  6. package/dist/bin.d.ts.map +1 -0
  7. package/dist/bin.js +114 -0
  8. package/dist/bin.js.map +1 -0
  9. package/dist/commands.d.ts +38 -0
  10. package/dist/commands.d.ts.map +1 -0
  11. package/dist/commands.js +225 -0
  12. package/dist/commands.js.map +1 -0
  13. package/dist/dev-entry.d.ts +2 -0
  14. package/dist/dev-entry.d.ts.map +1 -0
  15. package/dist/dev-entry.js +348 -0
  16. package/dist/dev-entry.js.map +1 -0
  17. package/dist/dev-proxy.d.ts +21 -0
  18. package/dist/dev-proxy.d.ts.map +1 -0
  19. package/dist/dev-proxy.js +98 -0
  20. package/dist/dev-proxy.js.map +1 -0
  21. package/dist/dev-watcher.d.ts +24 -0
  22. package/dist/dev-watcher.d.ts.map +1 -0
  23. package/dist/dev-watcher.js +242 -0
  24. package/dist/dev-watcher.js.map +1 -0
  25. package/dist/generate-types.d.ts +14 -0
  26. package/dist/generate-types.d.ts.map +1 -0
  27. package/dist/generate-types.js +190 -0
  28. package/dist/generate-types.js.map +1 -0
  29. package/dist/output-safety.d.ts +47 -0
  30. package/dist/output-safety.d.ts.map +1 -0
  31. package/dist/output-safety.js +145 -0
  32. package/dist/output-safety.js.map +1 -0
  33. package/dist/project-config.d.ts +72 -0
  34. package/dist/project-config.d.ts.map +1 -0
  35. package/dist/project-config.js +221 -0
  36. package/dist/project-config.js.map +1 -0
  37. package/dist/types.d.ts +29 -0
  38. package/dist/types.d.ts.map +1 -0
  39. package/dist/types.js +3 -0
  40. package/dist/types.js.map +1 -0
  41. package/dist/utils.d.ts +84 -0
  42. package/dist/utils.d.ts.map +1 -0
  43. package/dist/utils.js +176 -0
  44. package/dist/utils.js.map +1 -0
  45. package/dist/webpack-build.d.ts +87 -0
  46. package/dist/webpack-build.d.ts.map +1 -0
  47. package/dist/webpack-build.js +475 -0
  48. package/dist/webpack-build.js.map +1 -0
  49. package/package.json +64 -3
  50. package/tsconfig/client.json +3 -0
  51. package/tsconfig/server.json +3 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 diaogroup
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,252 @@
1
- # Temporary Holding Version
1
+ # @ynight/cli
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ > Elpis 业务工程 CLI —— 把框架装成可运行的业务项目入口
4
+
5
+ ## 概述
6
+
7
+ `@ynight/cli` 是 Elpis 框架**业务工程**的入口工具,对外暴露 `elpis` 命令。通过 `elpis dev`、`elpis build`、`elpis type-check` 等命令,业务开发者可以一键启动前后端开发服务器、生产构建和类型检查。
8
+
9
+ CLI 在内部负责:
10
+
11
+ - 加载并合并 `elpis.config.ts` 与命令行覆盖项
12
+ - 用 Webpack 5 构建前端(Vue 3 + Element Plus + Pinia)
13
+ - 用 ts-node / tsc 编译并运行后端
14
+ - 通过 Express + webpack-dev-middleware 把前端 HMR 与 Koa 挂到同一 HTTP 端口
15
+ - 把构建产物(前端资源 + 后端编译产物)组装到 `server/dist`,供 `@ynight/server` 启动
16
+ - 扫描业务模块生成 application 类型供编辑器使用
17
+ - 在写入任何文件前做路径安全校验(output-safety),避免覆盖源码目录
18
+
19
+ `@ynight/cli` 不发布业务源码,只发布 `dist`、`config`、`tsconfig` 三个目录以及 README 与 LICENSE。
20
+
21
+ ## 子导出与发布产物
22
+
23
+ 包内 `package.json` 仅声明两个子路径导出:
24
+
25
+ | 子路径 | 指向 |
26
+ | ---------------------------------- | -------------------- |
27
+ | `@ynight/cli/tsconfig/server.json` | `config/server.json` |
28
+ | `@ynight/cli/tsconfig/client.json` | `config/client.json` |
29
+
30
+ **重要:** 包内同时保留 `tsconfig/` 目录作为转接文件,**业务工程不要删除或重命名 `tsconfig/`**,因为 `ts-node` 10 对 TypeScript `extends` 的解析依赖这些文件直接落在发布产物中——仅保留 `exports` 映射是不够的。
31
+
32
+ ## 安装
33
+
34
+ 在 Elpis 业务工程中:
35
+
36
+ ```bash
37
+ pnpm add -D @ynight/cli
38
+ ```
39
+
40
+ `bin` 字段会注册 `elpis` 可执行命令。
41
+
42
+ ## 命令
43
+
44
+ ### `elpis dev`
45
+
46
+ 启动开发服务器。
47
+
48
+ - 解析 `elpis.config.ts` 与 CLI 覆盖项
49
+ - 启动 Webpack dev server(HMR)并把它挂到与 Koa 同一 HTTP 端口
50
+ - 用 ts-node 即时编译并运行 `server/app.ts`
51
+ - 监听业务模块变更:增量切换 `app/` 目录、保留失败产物供诊断、自动清理旧实例
52
+
53
+ ```bash
54
+ elpis dev
55
+ elpis dev --port 4000
56
+ elpis dev --elpis-config ./elpis.config.ts
57
+ ```
58
+
59
+ ### `elpis build`
60
+
61
+ 生产构建。
62
+
63
+ - 前端走 Webpack 5,产物输出到 `server/dist/public`
64
+ - 后端编译为 JavaScript 并组装到 `server/dist`
65
+ - 生成最小生产启动器(`server/dist/index.js`),写入 `manifest.json` 描述内置页面与资源映射
66
+ - 在写入前调用 `output-safety` 检查目标路径,不在 `node_modules / server / model / .git` 等敏感目录下
67
+
68
+ ```bash
69
+ elpis build
70
+ elpis build --out ./build
71
+ ```
72
+
73
+ ### `elpis type-check`
74
+
75
+ 运行前后端 TypeScript 类型检查(同步执行应用类型生成)。
76
+
77
+ - 生成 `types/application.ts` 后再用 `tsc --noEmit` 校验服务端
78
+ - 用 `vue-tsc --noEmit` 校验前端(包含 Vue SFC)
79
+
80
+ ```bash
81
+ elpis type-check
82
+ ```
83
+
84
+ ### `elpis generate-types`(被 type-check 调用,也可单独运行)
85
+
86
+ 扫描 `server/controller`、`server/service`、`server/middleware`、`server/router-schema`,按目录命名生成 `types/application.ts`。
87
+
88
+ ```bash
89
+ elpis generate-types
90
+ elpis generate:types:check # 仅校验已生成的文件是否最新
91
+ ```
92
+
93
+ ## 配置文件
94
+
95
+ ### `elpis.config.ts`
96
+
97
+ 工程根目录的 Elpis 配置入口,由 `project-config.ts` 加载并合并 CLI 参数覆盖项。
98
+
99
+ ```ts
100
+ import { defineConfig } from '@ynight/framework';
101
+
102
+ export default defineConfig({
103
+ name: 'my-app',
104
+ server: { host: '127.0.0.1', port: 3000 },
105
+ model: { dir: 'model' },
106
+ client: { dashboardBase: '/' },
107
+ });
108
+ ```
109
+
110
+ CLI 参数会合并到最终配置:
111
+
112
+ | CLI 参数 | 覆盖字段 |
113
+ | ----------------------- | ------------------ |
114
+ | `--port` | `server.port` |
115
+ | `--host` | `server.host` |
116
+ | `--out` | 构建输出目录 |
117
+ | `--elpis-config <path>` | 自定义配置文件路径 |
118
+
119
+ ### TypeScript 配置预设
120
+
121
+ 业务工程在自己的 `tsconfig.json` 中继承 CLI 提供的预设:
122
+
123
+ ```json
124
+ {
125
+ "extends": "@ynight/cli/tsconfig/server.json"
126
+ }
127
+ ```
128
+
129
+ ```json
130
+ {
131
+ "extends": "@ynight/cli/tsconfig/client.json"
132
+ }
133
+ ```
134
+
135
+ 这两份预设包含了构建/运行所需的路径映射、JSX、装饰器、严格模式等选项。
136
+
137
+ ### 目录约定(CLI 视角)
138
+
139
+ | 路径 | 角色 |
140
+ | --------------------------------------------- | ---------------------------------------------- |
141
+ | `elpis.config.ts` | 工程配置入口 |
142
+ | `server/app.ts` | `defineServer` 入口,被 `elpis dev` 编译并运行 |
143
+ | `server/controller/<name>.ts` | 业务 Controller |
144
+ | `server/service/<name>.ts` | 业务 Service |
145
+ | `server/router/<name>.ts` | 业务路由定义 |
146
+ | `server/middleware/<name>.ts` | 业务 Koa 中间件 |
147
+ | `server/router-schema/<name>.ts` | 路由请求参数 AJV schema |
148
+ | `model/<modelKey>/model.<ext>` | 基础模型 |
149
+ | `model/<modelKey>/project/<projectKey>.<ext>` | 项目配置 |
150
+ | `client/` | 自定义 Vue 组件 / 页面 / 扩展(可选) |
151
+ | `types/empty-client.ts` | 前端无自定义控件/页面时的占位 |
152
+ | `public/` | 静态资源(含 help.html) |
153
+
154
+ ## 前端构建
155
+
156
+ CLI 在 `webpack-build.ts` 中基于 Webpack 5 + `vue-loader` + `esbuild-loader` + `less-loader` 装配前端:
157
+
158
+ - `HtmlWebpackPlugin` 注入入口,`publicPath` 默认为 `/`
159
+ - `PAGE_NAMES` 与 `@ynight/framework/assets` 协同,把框架内置页面(project-list、dashboard、error)注入构建
160
+ - 生产构建通过 `mini-css-extract-plugin` 抽取样式,开发模式用 `style-loader` 注入 HMR
161
+ - 入口文件生成后会写入 `manifest.json`,运行时按页面名解析入口 HTML
162
+
163
+ `createFrontendOptions` 暴露前端构建选项;`pageOutputPaths` 提供构建产物的最终路径映射,便于服务端在 History 兜底时定位页面。
164
+
165
+ ## 开发代理
166
+
167
+ `dev-proxy.ts` 把 Express + `webpack-dev-middleware` + `webpack-hot-middleware` 装到 Koa 同一 HTTP 实例:
168
+
169
+ - API 请求由 Koa 处理
170
+ - `/__webpack_dev_server__/*` 与热更新 socket 由 Webpack 中间件处理
171
+ - 静态资源命中后由 Koa 静态文件中间件兜底
172
+ - 业务资源(`*.js` / `*.css` / `*.png` 等)需经 Koa 的 `public:read` 授权(由 `@ynight/framework` 的 AuthAdapter 决定)
173
+
174
+ 生产构建完成后,`server/dist/public` 被 Koa 直接托管,不再需要 dev proxy。
175
+
176
+ ## 开发文件监听
177
+
178
+ `dev-entry.ts` 使用 `chokidar` 订阅操作系统文件事件,不通过固定时间间隔递归扫描项目目录:
179
+
180
+ - 启动时先生成一次业务类型并完成后端编译;
181
+ - 业务目录、模型目录、共享目录和关键配置文件发生 `add`、`change`、`unlink` 时触发更新;
182
+ - 连续保存会合并为一次更新,默认防抖 200ms;
183
+ - 更新过程串行执行,新的文件事件不会被丢弃;
184
+ - 配置改变后会刷新监听范围,退出时关闭 watcher 并释放文件句柄;
185
+ - `.elpis`、`dist`、`node_modules` 和日志目录会被排除,避免生成文件触发自循环。
186
+
187
+ ## 类型生成
188
+
189
+ `generate-types.ts` 扫描业务模块目录,按嵌套命名空间生成 `types/application.ts`:
190
+
191
+ - 叶子节点(class / handler)的导出名映射到 `<model>.<service|controller|middleware>` 等路径
192
+ - 中间节点(目录)形成命名空间,路径冲突会抛错
193
+ - 生成结果参与 `type-check` 流水线,确保编辑器与 CI 看到的类型一致
194
+
195
+ ## 路径安全
196
+
197
+ `output-safety.ts` 在所有写入操作前做路径校验:
198
+
199
+ - `within(root, candidate)`:确认目标路径在允许根目录之内
200
+ - `safeGeneratedPath`:校验生成文件(如 `types/application.ts`)不会被写入源码目录
201
+ - `safeOutputRoot`:禁止 `outDir` 落在 `node_modules / server / model / .git` 等敏感目录
202
+ - `replaceDirectoryAtomically`:原子替换目录,先写入临时目录再 rename,避免半成品
203
+
204
+ 构建、类型生成、应用启动前都会调用这些守卫。
205
+
206
+ ## 工具与类型
207
+
208
+ `utils.ts` 提供:
209
+
210
+ - `findFiles(root, predicate)`、`hasSourceFiles(root)`:业务目录扫描
211
+ - `camelCase`:路径片段命名转换(kebab-case / snake_case → camelCase)
212
+ - `runNodeScript(scriptPath, args)`:派生 Node 子进程并转发 stdout/stderr
213
+ - `resolveTsc` / `resolveVueTsc` / `runTsc` / `runVueTsc`:定位并运行类型检查器
214
+ - `copyDirectory(src, dest)`:安全拷贝目录(保留权限)
215
+
216
+ `types.ts` 暴露:
217
+
218
+ - `CliOptions`:CLI 接受的覆盖项结构
219
+ - `ParsedArgs`:参数解析后的结果
220
+
221
+ ## 集成测试
222
+
223
+ - `pnpm test`:构建后用 `node --test` 运行单元测试(`test/*.test.mjs`)
224
+ - `pnpm test:integration`:使用 Playwright 启动 `elpis dev` 并端到端校验页面与 API
225
+
226
+ ## 相关包
227
+
228
+ - [@ynight/framework](../framework) — 框架运行时,被本 CLI 组装
229
+ - [@ynight/create-app](../create-app) — 用本 CLI 初始化新的业务工程
230
+ - [@ynight/core](../core) — 底层引擎
231
+ - [@ynight/contracts](../contracts) — DSL 与协议类型
232
+ - [@ynight/model-runtime](../model-runtime) — 模型加载与校验
233
+
234
+ ## 脚本
235
+
236
+ | 命令 | 说明 |
237
+ | ----------------------- | ------------------------- |
238
+ | `pnpm clean` | 清理 `dist` |
239
+ | `pnpm build` | 编译 TypeScript 到 `dist` |
240
+ | `pnpm type-check` | 类型检查(不产出) |
241
+ | `pnpm test` | 单元测试(需先 build) |
242
+ | `pnpm test:integration` | Playwright 集成测试 |
243
+ | `pnpm lint` | ESLint |
244
+
245
+ ## 引擎要求
246
+
247
+ - Node.js `>=22.0.0`
248
+ - pnpm `10.16.0`
249
+
250
+ ## 许可证
251
+
252
+ MIT
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "strict": true,
8
+ "isolatedModules": true,
9
+ "jsx": "preserve",
10
+ "allowJs": false,
11
+ "skipLibCheck": false,
12
+ "types": ["node"]
13
+ }
14
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022"],
5
+ "module": "Node16",
6
+ "moduleResolution": "Node16",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "allowSyntheticDefaultImports": true,
10
+ "resolveJsonModule": true,
11
+ "declaration": false,
12
+ "sourceMap": true,
13
+ "skipLibCheck": false,
14
+ "types": ["node"]
15
+ }
16
+ }
package/dist/bin.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ import type { ParsedArgs } from './types';
3
+ /**
4
+ * 把 `process.argv.slice(2)` 解析为结构化的 `{ command, options }`。
5
+ *
6
+ * 支持的子命令:
7
+ * - `dev` / `build` / `type-check` / `generate:types`:实际工作命令;
8
+ * - `--help` / `-h`:等价于 `help`,只打印帮助;
9
+ * - `--version` / `-v`:等价于 `version`,只打印版本号。
10
+ *
11
+ * 支持的参数:
12
+ * - `--root <path>`:业务工程根目录,默认 `process.cwd()`;
13
+ * - `--port <n>`:后端 Koa 端口(仅 `dev`);
14
+ * - `--web-port <n>`:前端 dev server 端口(仅 `dev`);
15
+ * - `--check`:仅 `generate:types` 支持,启用新鲜度校验模式。
16
+ *
17
+ * @throws 当首个参数不是已知子命令或后续参数不识别时抛出。
18
+ */
19
+ export declare function parseArgs(argv: string[]): ParsedArgs;
20
+ /**
21
+ * CLI 主入口:解析参数 → 分发到对应命令函数。
22
+ *
23
+ * @param argv 默认取 `process.argv.slice(2)`,便于测试时显式注入。
24
+ */
25
+ export declare function main(argv?: string[]): Promise<void>;
26
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAkB1C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAgCpD;AAED;;;;GAIG;AACH,wBAAsB,IAAI,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBtE"}
package/dist/bin.js ADDED
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.parseArgs = parseArgs;
5
+ exports.main = main;
6
+ const tslib_1 = require("tslib");
7
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
8
+ const commands_1 = require("./commands");
9
+ const generate_types_1 = require("./generate-types");
10
+ /**
11
+ * 解析并校验 CLI 中的端口号参数。
12
+ *
13
+ * @param value 原始字符串(来自 `argv`)。
14
+ * @param name 参数名(如 `--port`),仅用于错误提示。
15
+ * @returns 合法端口号(整数)。
16
+ * @throws 当 value 不是合法整数或不在 1-65535 范围内时抛出。
17
+ */
18
+ function parsePort(value, name) {
19
+ const port = Number(value);
20
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
21
+ throw new Error(`${name} 必须是 1-65535 的整数`);
22
+ }
23
+ return port;
24
+ }
25
+ /**
26
+ * 把 `process.argv.slice(2)` 解析为结构化的 `{ command, options }`。
27
+ *
28
+ * 支持的子命令:
29
+ * - `dev` / `build` / `type-check` / `generate:types`:实际工作命令;
30
+ * - `--help` / `-h`:等价于 `help`,只打印帮助;
31
+ * - `--version` / `-v`:等价于 `version`,只打印版本号。
32
+ *
33
+ * 支持的参数:
34
+ * - `--root <path>`:业务工程根目录,默认 `process.cwd()`;
35
+ * - `--port <n>`:后端 Koa 端口(仅 `dev`);
36
+ * - `--web-port <n>`:前端 dev server 端口(仅 `dev`);
37
+ * - `--check`:仅 `generate:types` 支持,启用新鲜度校验模式。
38
+ *
39
+ * @throws 当首个参数不是已知子命令或后续参数不识别时抛出。
40
+ */
41
+ function parseArgs(argv) {
42
+ const first = argv[0];
43
+ // 没有任何参数或显式 --help / -h:进入帮助分支。
44
+ if (!first || first === '--help' || first === '-h') {
45
+ return { command: 'help', options: { root: process.cwd() } };
46
+ }
47
+ if (first === '--version' || first === '-v') {
48
+ return { command: 'version', options: { root: process.cwd() } };
49
+ }
50
+ // 仅识别白名单内的子命令,避免误把业务参数当成命令执行。
51
+ const known = new Set(['dev', 'build', 'type-check', 'generate:types']);
52
+ if (!known.has(first)) {
53
+ throw new Error(`未知命令: ${first}`);
54
+ }
55
+ // 默认根目录 = 当前工作目录,子命令可以再通过 --root 覆盖。
56
+ const options = { root: process.cwd() };
57
+ for (let index = 1; index < argv.length; index += 1) {
58
+ const arg = argv[index];
59
+ if (arg === '--root') {
60
+ // path.resolve 支持绝对路径与相对路径(含 `..`)。
61
+ options.root = node_path_1.default.resolve(argv[++index] ?? '');
62
+ }
63
+ else if (arg === '--port') {
64
+ options.port = parsePort(argv[++index] ?? '', '--port');
65
+ }
66
+ else if (arg === '--web-port') {
67
+ options.webPort = parsePort(argv[++index] ?? '', '--web-port');
68
+ }
69
+ else if (arg === '--check' && first === 'generate:types') {
70
+ options.check = true;
71
+ }
72
+ else {
73
+ throw new Error(`未知参数: ${arg}`);
74
+ }
75
+ }
76
+ return { command: first, options };
77
+ }
78
+ /**
79
+ * CLI 主入口:解析参数 → 分发到对应命令函数。
80
+ *
81
+ * @param argv 默认取 `process.argv.slice(2)`,便于测试时显式注入。
82
+ */
83
+ async function main(argv = process.argv.slice(2)) {
84
+ const parsed = parseArgs(argv);
85
+ if (parsed.command === 'help') {
86
+ console.log(commands_1.HELP);
87
+ return;
88
+ }
89
+ if (parsed.command === 'version') {
90
+ console.log(commands_1.CLI_VERSION);
91
+ return;
92
+ }
93
+ if (parsed.command === 'generate:types') {
94
+ (0, generate_types_1.generateTypes)(parsed.options.root, parsed.options.check);
95
+ console.log(parsed.options.check ? '生成类型检查通过' : '生成类型已更新');
96
+ return;
97
+ }
98
+ if (parsed.command === 'type-check') {
99
+ (0, commands_1.typeCheck)(parsed.options);
100
+ return;
101
+ }
102
+ if (parsed.command === 'build') {
103
+ await (0, commands_1.build)(parsed.options);
104
+ return;
105
+ }
106
+ // 兜底:唯一剩下的命令就是 dev。
107
+ await (0, commands_1.dev)(parsed.options);
108
+ }
109
+ // 顶层错误捕获:所有命令最终统一收敛到这里,便于给出统一的退出码。
110
+ main().catch(error => {
111
+ console.error(`Elpis 执行失败: ${error instanceof Error ? error.message : error}`);
112
+ process.exitCode = 1;
113
+ });
114
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { CliOptions } from './types';
2
+ export declare const CLI_VERSION: string;
3
+ /**
4
+ * CLI 帮助文本:列出所有子命令与参数;保持简洁,便于直接打印。
5
+ *
6
+ * 注意:每个子命令的实际解析在 `bin.ts::parseArgs` 中。
7
+ */
8
+ export declare const HELP: string;
9
+ /**
10
+ * 同步执行完整类型检查:
11
+ * 1. 校验配置文件;
12
+ * 2. 重新生成业务模块声明文件;
13
+ * 3. 使用 `tsc --noEmit` 检查服务端代码;
14
+ * 4. 调用 `vue-tsc` 检查客户端代码。
15
+ */
16
+ export declare function typeCheck(options: CliOptions): void;
17
+ /**
18
+ * 生产构建主流程:
19
+ * 1. 校验配置与输出目录安全;
20
+ * 2. 重新生成类型声明;
21
+ * 3. 在 `.elpis/build/{buildId}` 下构建 staging 产物;
22
+ * 4. 校验页面模板齐全;
23
+ * 5. 写入 manifest;
24
+ * 6. 原子替换到正式输出目录。
25
+ *
26
+ * 任何步骤失败都会在 catch 中打印消息并向上抛出,调用方决定是否回滚。
27
+ */
28
+ export declare function build(options: CliOptions): Promise<void>;
29
+ /**
30
+ * 开发模式入口(spawn 当前 CLI 重新跑 dev-entry.ts)。
31
+ *
32
+ * 这里采用子进程模式的原因:
33
+ * - dev-entry 维护大量长生命周期资源(koa server / webpack-dev-server / tsc 子进程 / 定时器),
34
+ * 用独立子进程可借助 OS 进程隔离避免污染父进程;
35
+ * - 父进程仅负责把 SIGINT / SIGTERM 透传给子进程,简化资源回收。
36
+ */
37
+ export declare function dev(options: CliOptions): Promise<void>;
38
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAM1C,eAAO,MAAM,WAAW,QAA0B,CAAC;AAEnD;;;;GAIG;AACH,eAAO,MAAM,IAAI,QAOU,CAAC;AAkD5B;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAMnD;AA2CD;;;;;;;;;;GAUG;AACH,wBAAsB,KAAK,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkD9D;AAED;;;;;;;GAOG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA2C5D"}