mvframe 1.1.30 → 1.1.32

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.cn.md CHANGED
@@ -268,6 +268,21 @@ await notify("需要发送到钉钉的消息");
268
268
 
269
269
  ---
270
270
 
271
+ ## 命令行:宿主项目打包
272
+
273
+ 在宿主项目 `package.json` 中增加 `"b": "mvframe-b"`。该命令会执行宿主 Vite 构建、复制 MVFrame 国旗资源,并写入 `serve.json`。项目名自动取执行命令时所在项目的文件夹名,并通过 `MVFRAME_PROJECT_NAME` 传给 Vite。
274
+
275
+ ```bash
276
+ yarn b # mode=development,输出 dev/
277
+ yarn b pre # mode=pre,输出 pre/,加载 .env.pre*
278
+ yarn b pd # mode=production,输出 pd/,加载 .env.production*
279
+ yarn b --mode staging --outDir release
280
+ ```
281
+
282
+ `--pre`、`--pd` 分别等价于 `pre`、`pd` 快捷命令。旧的 `-t`(`test/test`)、`-p`(`production/pre`)以及单个位置参数自定义输出目录仍然兼容。
283
+
284
+ ---
285
+
271
286
  ## 命令行:项目目录雏形(推荐)
272
287
 
273
288
  在**空目录或已有 Vite 工程根目录**执行,生成 `src/views`、`src/component`、`src/api`、`src/assets/img`、`src/assets/style`、`src/router`、`src/pinia/chip`、`src/config` 及示例 `main.js` / `App.vue`(已 `app.use(mvframe, …)` 挂好路由、Pinia `storeChips`、config,并写入 `components.async: ["VTable"]`),同时写入/更新宿主项目 **`AGENTS.md`** 的 MVFrame Codex 规则,其中包含 **每次 AI 完成开发后执行 `yarn exec mvframe-notify --once --message "..."` 发送完成通知** 的要求,并复制 **`/.cursor/rules/*.mdc`**(与 mvframe 仓库内 Cursor 规则一致)。若不存在则附带 `index.html` 与 `vite.config.js`。会**合并** `package.json` 的 `scripts` / `dependencies` / `devDependencies`(与 Vite 模板一致;**同名脚本和包保留你原有值**),初始化 `.env.mvframe-notify.example` / `.env.local.example` 与 `config.notify`,并自动执行 **`yarn install`**,最后请执行 **`yarn dev`**;需要同时启动通知服务时显式执行 **`yarn exec mvframe-d -n`**。加 `--no-package-json` 可不改动 `package.json` 且跳过安装。
package/README.md CHANGED
@@ -253,6 +253,21 @@ The floating label shell is implemented centrally in `src/style/chip/element.scs
253
253
 
254
254
  ---
255
255
 
256
+ ## CLI: host application build
257
+
258
+ Add `"b": "mvframe-b"` to the host application's `package.json`. The command runs the host Vite build, copies MVFrame flag assets, and writes `serve.json`. The host project name is derived from the current project folder and passed to Vite as `MVFRAME_PROJECT_NAME`.
259
+
260
+ ```bash
261
+ yarn b # mode=development, outDir=dev
262
+ yarn b pre # mode=pre, outDir=pre; loads .env.pre*
263
+ yarn b pd # mode=production, outDir=pd; loads .env.production*
264
+ yarn b --mode staging --outDir release
265
+ ```
266
+
267
+ `--pre` and `--pd` are equivalent to the `pre` and `pd` shortcuts. The legacy `-t` (`test/test`), `-p` (`production/pre`), and single positional output-directory forms remain supported.
268
+
269
+ ---
270
+
256
271
  ## CLI: project skeleton
257
272
 
258
273
  From an **empty folder or existing Vite root**, generates `src/views`, `src/component`, `src/api`, `src/assets/img`, `src/assets/style`, `src/router`, `src/pinia/chip`, `src/config`, plus starter `main.js` / `App.vue` with `app.use(mvframe, …)` (routes, Pinia `storeChips`, config, and `components.async: ["VTable"]`). It also writes/updates host-project **`AGENTS.md`** with MVFrame Codex rules, including a requirement that AI send a completion message with `yarn exec mvframe-notify --once --message "..."` after each finished development task, and copies **`/.cursor/rules/*.mdc`** from the package (same as this repo’s Cursor rules). Adds `index.html` and `vite.config.js` only if missing (use `--force` to overwrite). **Merges** `scripts` / `dependencies` / `devDependencies` into `package.json` (existing values win for shared keys), initializes `.env.mvframe-notify.example` / `.env.local.example` and `config.notify`, then runs **`yarn install`**; use `--no-package-json` to skip package changes and install. Then run **`yarn dev`** or explicitly run **`yarn exec mvframe-d -n`** to start Vite with the notify service.
package/dist/vendor.js CHANGED
@@ -6084,7 +6084,7 @@ const Gl = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
6084
6084
  {
6085
6085
  id: "143598",
6086
6086
  code: "st",
6087
- label: "Sao",
6087
+ label: "Sao Tome and Principe",
6088
6088
  hide: !1
6089
6089
  },
6090
6090
  {
@@ -13958,7 +13958,7 @@ const Wr = (a, o = {}) => {
13958
13958
  }, qr = {
13959
13959
  name: "Matt Avias Frame",
13960
13960
  copyright: "©2026",
13961
- version: "1.1.30",
13961
+ version: "1.1.32",
13962
13962
  author: "Matt Avias",
13963
13963
  date: "2026-02-26",
13964
13964
  /** 默认语言 key,与 `$getLang`、localStorage `lang` 一致;业务在 app.use(mvframe, { config }) 里覆盖 */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mvframe",
3
3
  "packageManager": "yarn@4.4.1",
4
- "version": "1.1.30",
4
+ "version": "1.1.32",
5
5
  "author": "matt avis",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -3,17 +3,34 @@
3
3
  * 宿主 Vite 工程:打包后写入与 mstar 一致的 `serve.json`(SPA 回写 index.html)。
4
4
  *
5
5
  * 在宿主 `package.json` 中增加:`"b": "mvframe-b"`
6
- * 然后执行 `yarn b` `yarn b [outDir] [-t|-p]`。
6
+ * 然后执行 `yarn b`、`yarn b pre`、`yarn b pd`,或传入自定义 mode / outDir
7
7
  *
8
8
  * - 默认:--mode development,输出目录 `dev`
9
9
  * - `-t`:--mode test,输出 `test`
10
- * - `-p`:--mode production,输出 `pre`(Vite 环境为 production,对应 .env.production*)
11
- * - 一个位置参数:自定义输出目录(与 -t / -p 同用时,以 -t / -p 为准)
10
+ * - `-p`:兼容旧行为,--mode production,输出 `pre`
11
+ * - `pre` / `--pre`:--mode pre,输出 `pre`,加载 `.env.pre*`
12
+ * - `pd` / `--pd`:--mode production,输出 `pd`,加载 `.env.production*`
13
+ * - `--mode <mode>` / `--outDir <dir>`:自定义 Vite mode 与输出目录
14
+ * - 一个普通位置参数:兼容旧行为,作为自定义输出目录
12
15
  */
13
16
  const { spawnSync } = require("child_process");
14
17
  const fs = require("fs");
15
18
  const path = require("path");
16
19
  const { copyFlagAssetsTo } = require("./flag-assets.js");
20
+ const USAGE = `用法:
21
+ mvframe-b
22
+ mvframe-b pre | --pre
23
+ mvframe-b pd | --pd
24
+ mvframe-b [outDir] [-t|-p]
25
+ mvframe-b [--mode <mode>] [--outDir <dir>]
26
+
27
+ 快捷模式:
28
+ pre / --pre mode=pre, outDir=pre
29
+ pd / --pd mode=production, outDir=pd
30
+
31
+ 兼容模式:
32
+ -t mode=test, outDir=test
33
+ -p mode=production, outDir=pre`;
17
34
  const SERVE_JSON = `{
18
35
  "rewrites": [{
19
36
  "source": "**",
@@ -21,48 +38,88 @@ const SERVE_JSON = `{
21
38
  }]
22
39
  }`;
23
40
 
24
- function parseArgs(argv) {
41
+ function argumentError(message) {
42
+ const error = new Error(`${message}\n\n${USAGE}`);
43
+ error.name = "MvframeBuildArgumentError";
44
+ return error;
45
+ }
46
+
47
+ function readOptionValue(args, index, option) {
48
+ const value = args[index + 1];
49
+ if (!value || value.startsWith("-")) {
50
+ throw argumentError(`[mvframe-b] ${option} 缺少参数值`);
51
+ }
52
+ return value;
53
+ }
54
+
55
+ function parseArgs(argv, logger = console) {
25
56
  const args = argv.slice(2);
26
57
  let mode = "development";
27
58
  let outDir = "dev";
28
- let preset = false;
59
+ let preset = "";
60
+ let explicitOutDir = false;
61
+ let help = false;
29
62
  const positional = [];
30
63
 
31
- for (const a of args) {
32
- if (a === "-t") {
64
+ for (let index = 0; index < args.length; index += 1) {
65
+ const arg = args[index];
66
+
67
+ if (arg === "-h" || arg === "--help") {
68
+ help = true;
69
+ } else if (arg === "-t") {
33
70
  mode = "test";
34
71
  outDir = "test";
35
- preset = true;
36
- } else if (a === "-p") {
72
+ preset = "-t";
73
+ } else if (arg === "-p") {
37
74
  mode = "production";
38
75
  outDir = "pre";
39
- preset = true;
40
- } else if (a.startsWith("-")) {
41
- console.error(`[mvframe-b] 未知参数: ${a}`);
42
- process.exit(1);
76
+ preset = "-p";
77
+ } else if (arg === "pre" || arg === "--pre") {
78
+ mode = "pre";
79
+ outDir = "pre";
80
+ preset = "pre";
81
+ } else if (arg === "pd" || arg === "--pd") {
82
+ mode = "production";
83
+ outDir = "pd";
84
+ preset = "pd";
85
+ } else if (arg === "--mode") {
86
+ mode = readOptionValue(args, index, "--mode");
87
+ index += 1;
88
+ } else if (arg.startsWith("--mode=")) {
89
+ mode = arg.slice("--mode=".length);
90
+ if (!mode) throw argumentError("[mvframe-b] --mode 缺少参数值");
91
+ } else if (arg === "--outDir" || arg === "--out-dir") {
92
+ outDir = readOptionValue(args, index, arg);
93
+ explicitOutDir = true;
94
+ index += 1;
95
+ } else if (arg.startsWith("--outDir=") || arg.startsWith("--out-dir=")) {
96
+ outDir = arg.slice(arg.indexOf("=") + 1);
97
+ if (!outDir) throw argumentError("[mvframe-b] --outDir 缺少参数值");
98
+ explicitOutDir = true;
99
+ } else if (arg.startsWith("-")) {
100
+ throw argumentError(`[mvframe-b] 未知参数: ${arg}`);
43
101
  } else {
44
- positional.push(a);
102
+ positional.push(arg);
45
103
  }
46
104
  }
47
105
 
48
106
  if (positional.length > 1) {
49
- console.error(
50
- "[mvframe-b] 用法: yarn b [outDir] [-t|-p]\n 默认: outDir=dev, mode=development; -t: test/test; -p: pre/production",
107
+ throw argumentError(
108
+ `[mvframe-b] 最多只能传入一个自定义输出目录: ${positional.join(" ")}`,
51
109
  );
52
- process.exit(1);
53
110
  }
54
111
 
55
112
  if (positional.length === 1) {
56
- if (preset) {
57
- console.warn(
58
- `[mvframe-b] 已使用 -t/-p,忽略输出目录参数 "${positional[0]}",实际输出: ${outDir}`,
113
+ if (preset || explicitOutDir) {
114
+ logger.warn(
115
+ `[mvframe-b] 已指定 ${preset || "--outDir"},忽略输出目录参数 "${positional[0]}",实际输出: ${outDir}`,
59
116
  );
60
117
  } else {
61
118
  outDir = positional[0];
62
119
  }
63
120
  }
64
121
 
65
- return { mode, outDir };
122
+ return { mode, outDir, help };
66
123
  }
67
124
 
68
125
  /**
@@ -93,11 +150,39 @@ function copyFlagAssets(outAbs) {
93
150
  console.log(`[mvframe-b] 已复制 ${path.relative(outAbs, dest)}`);
94
151
  }
95
152
 
153
+ function projectNameFrom(cwd) {
154
+ return path.basename(path.resolve(cwd));
155
+ }
156
+
96
157
  function main() {
97
158
  const cwd = process.cwd();
98
- const { mode, outDir } = parseArgs(process.argv);
159
+ let options;
160
+
161
+ try {
162
+ options = parseArgs(process.argv);
163
+ } catch (error) {
164
+ if (error?.name === "MvframeBuildArgumentError") {
165
+ console.error(error.message);
166
+ process.exit(1);
167
+ }
168
+ throw error;
169
+ }
170
+
171
+ if (options.help) {
172
+ console.log(USAGE);
173
+ return;
174
+ }
175
+
176
+ const { mode, outDir } = options;
177
+ const projectName = projectNameFrom(cwd);
99
178
  const viteEntry = resolveViteCli(cwd);
100
- const env = { ...process.env, NODE_ENV: "production" };
179
+ const env = {
180
+ ...process.env,
181
+ NODE_ENV: "production",
182
+ MVFRAME_PROJECT_NAME: projectName,
183
+ };
184
+
185
+ console.log(`[mvframe-b] 项目: ${projectName}; mode: ${mode}; outDir: ${outDir}`);
101
186
  const child = spawnSync(
102
187
  process.execPath,
103
188
  [viteEntry, "build", "--outDir", outDir, "--mode", mode],
@@ -114,4 +199,10 @@ function main() {
114
199
  console.log(`[mvframe-b] 已写入 ${path.relative(cwd, servePath)}`);
115
200
  }
116
201
 
117
- main();
202
+ if (require.main === module) main();
203
+
204
+ module.exports = {
205
+ parseArgs,
206
+ projectNameFrom,
207
+ USAGE,
208
+ };