mvframe 1.1.15 → 1.1.16
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/dist/vendor.js +1 -1
- package/package.json +3 -1
- package/scripts/build-host.js +9 -0
- package/scripts/dev-vite-server.js +200 -0
- package/scripts/dev-with-notify.js +2 -34
- package/scripts/flag-assets.js +85 -0
package/dist/vendor.js
CHANGED
|
@@ -13917,7 +13917,7 @@ const Hr = (a, o = {}) => {
|
|
|
13917
13917
|
}, Jr = {
|
|
13918
13918
|
name: "Matt Avias Frame",
|
|
13919
13919
|
copyright: "©2026",
|
|
13920
|
-
version: "1.1.
|
|
13920
|
+
version: "1.1.16",
|
|
13921
13921
|
author: "Matt Avias",
|
|
13922
13922
|
date: "2026-02-26",
|
|
13923
13923
|
/** 默认语言 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.
|
|
4
|
+
"version": "1.1.16",
|
|
5
5
|
"author": "matt avis",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.js",
|
|
@@ -67,7 +67,9 @@
|
|
|
67
67
|
"dist/assets/*",
|
|
68
68
|
"src/style/chip/mixin.scss",
|
|
69
69
|
"scripts/build-host.js",
|
|
70
|
+
"scripts/dev-vite-server.js",
|
|
70
71
|
"scripts/dev-with-notify.js",
|
|
72
|
+
"scripts/flag-assets.js",
|
|
71
73
|
"scripts/init-rules.js",
|
|
72
74
|
"scripts/install-codex-agents.js",
|
|
73
75
|
"scripts/copy-flag-assets.js",
|
package/scripts/build-host.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
const { spawnSync } = require("child_process");
|
|
14
14
|
const fs = require("fs");
|
|
15
15
|
const path = require("path");
|
|
16
|
+
const { copyFlagAssetsTo } = require("./flag-assets.js");
|
|
16
17
|
const SERVE_JSON = `{
|
|
17
18
|
"rewrites": [{
|
|
18
19
|
"source": "**",
|
|
@@ -85,6 +86,13 @@ function resolveViteCli(cwd) {
|
|
|
85
86
|
);
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
function copyFlagAssets(outAbs) {
|
|
90
|
+
const dest = path.join(outAbs, "assets", "flags");
|
|
91
|
+
|
|
92
|
+
copyFlagAssetsTo(dest);
|
|
93
|
+
console.log(`[mvframe-b] 已复制 ${path.relative(outAbs, dest)}`);
|
|
94
|
+
}
|
|
95
|
+
|
|
88
96
|
function main() {
|
|
89
97
|
const cwd = process.cwd();
|
|
90
98
|
const { mode, outDir } = parseArgs(process.argv);
|
|
@@ -100,6 +108,7 @@ function main() {
|
|
|
100
108
|
}
|
|
101
109
|
const outAbs = path.resolve(cwd, outDir);
|
|
102
110
|
fs.mkdirSync(outAbs, { recursive: true });
|
|
111
|
+
copyFlagAssets(outAbs);
|
|
103
112
|
const servePath = path.join(outAbs, "serve.json");
|
|
104
113
|
fs.writeFileSync(servePath, `${SERVE_JSON}\n`, "utf8");
|
|
105
114
|
console.log(`[mvframe-b] 已写入 ${path.relative(cwd, servePath)}`);
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { spawn } = require("child_process");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const { pathToFileURL } = require("url");
|
|
6
|
+
const { createRequire } = require("module");
|
|
7
|
+
const { createTempFlagAssets } = require("./flag-assets.js");
|
|
8
|
+
|
|
9
|
+
let child = null;
|
|
10
|
+
let cleanupTemp = null;
|
|
11
|
+
let shuttingDown = false;
|
|
12
|
+
|
|
13
|
+
function resolveViteCli(cwd) {
|
|
14
|
+
let vpkg = "";
|
|
15
|
+
try {
|
|
16
|
+
const projectRequire = createRequire(path.join(cwd, "package.json"));
|
|
17
|
+
vpkg = projectRequire.resolve("vite/package.json");
|
|
18
|
+
} catch {
|
|
19
|
+
// Fall back to node_modules for non-PnP projects.
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!vpkg) {
|
|
23
|
+
vpkg = path.join(cwd, "node_modules", "vite", "package.json");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (fs.existsSync(vpkg)) {
|
|
27
|
+
const p = require(vpkg);
|
|
28
|
+
const bin = typeof p.bin === "string" ? p.bin : p.bin && p.bin.vite;
|
|
29
|
+
if (bin) {
|
|
30
|
+
const cli = path.join(path.dirname(vpkg), bin);
|
|
31
|
+
if (fs.existsSync(cli)) return cli;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
throw new Error(
|
|
35
|
+
"未在当前项目找到 Vite(请先安装依赖;宿主项目可执行 yarn install 后再运行 mvframe-d)",
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function resolvePackageManager(cwd) {
|
|
40
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
41
|
+
if (fs.existsSync(pkgPath)) {
|
|
42
|
+
const pkg = require(pkgPath);
|
|
43
|
+
const packageManager = String(pkg.packageManager || "");
|
|
44
|
+
if (packageManager.startsWith("pnpm@")) return "pnpm";
|
|
45
|
+
if (packageManager.startsWith("npm@")) return "npx";
|
|
46
|
+
return "yarn";
|
|
47
|
+
}
|
|
48
|
+
return "yarn";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function findHostViteConfig(cwd) {
|
|
52
|
+
const names = [
|
|
53
|
+
"vite.config.ts",
|
|
54
|
+
"vite.config.mts",
|
|
55
|
+
"vite.config.js",
|
|
56
|
+
"vite.config.mjs",
|
|
57
|
+
"vite.config.cjs",
|
|
58
|
+
"vite.config.cts",
|
|
59
|
+
];
|
|
60
|
+
return names.map((name) => path.join(cwd, name)).find(fs.existsSync) || "";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function createWrapperConfig({ cwd, flagsRoot, tmpRoot }) {
|
|
64
|
+
const hostConfig = findHostViteConfig(cwd);
|
|
65
|
+
const hostImport = hostConfig
|
|
66
|
+
? `import hostConfig from ${JSON.stringify(pathToFileURL(hostConfig).href)};`
|
|
67
|
+
: "const hostConfig = {};";
|
|
68
|
+
const source = `
|
|
69
|
+
import fs from "node:fs";
|
|
70
|
+
import path from "node:path";
|
|
71
|
+
${hostImport}
|
|
72
|
+
|
|
73
|
+
function createFlagAssetsPlugin(flagsRoot) {
|
|
74
|
+
return {
|
|
75
|
+
name: "mvframe-host-flag-assets",
|
|
76
|
+
configureServer(server) {
|
|
77
|
+
server.middlewares.use((req, res, next) => {
|
|
78
|
+
const pathname = req.url?.split("?")[0] || "";
|
|
79
|
+
if (!pathname.startsWith("/assets/flags/")) {
|
|
80
|
+
next();
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const relativePath = decodeURIComponent(
|
|
85
|
+
pathname.replace(/^\\/assets\\/flags\\//, ""),
|
|
86
|
+
);
|
|
87
|
+
const normalized = path.posix.normalize(relativePath);
|
|
88
|
+
if (
|
|
89
|
+
normalized.startsWith("../") ||
|
|
90
|
+
!/^(1x1|4x3)\\/[a-z0-9-]+\\.svg$/.test(normalized)
|
|
91
|
+
) {
|
|
92
|
+
res.statusCode = 404;
|
|
93
|
+
res.end();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const filePath = path.join(flagsRoot, normalized);
|
|
98
|
+
fs.readFile(filePath, (err, content) => {
|
|
99
|
+
if (err) {
|
|
100
|
+
res.statusCode = 404;
|
|
101
|
+
res.end();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
res.setHeader("Content-Type", "image/svg+xml");
|
|
105
|
+
res.end(content);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function toArray(value) {
|
|
113
|
+
if (!value) return [];
|
|
114
|
+
return Array.isArray(value) ? value : [value];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export default async function mvframeWrappedConfig(configEnv) {
|
|
118
|
+
const loaded =
|
|
119
|
+
typeof hostConfig === "function" ? await hostConfig(configEnv) : hostConfig;
|
|
120
|
+
const base = loaded || {};
|
|
121
|
+
const server = { ...(base.server || {}) };
|
|
122
|
+
if (server.host == null) {
|
|
123
|
+
server.host = "0.0.0.0";
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
...base,
|
|
128
|
+
root: base.root || ${JSON.stringify(cwd)},
|
|
129
|
+
server,
|
|
130
|
+
plugins: [
|
|
131
|
+
...toArray(base.plugins),
|
|
132
|
+
createFlagAssetsPlugin(${JSON.stringify(flagsRoot)}),
|
|
133
|
+
],
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
`;
|
|
137
|
+
const configPath = path.join(tmpRoot, "mvframe-vite.config.mjs");
|
|
138
|
+
fs.writeFileSync(configPath, source, "utf8");
|
|
139
|
+
return configPath;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function shutdown(code = 0) {
|
|
143
|
+
if (shuttingDown) return;
|
|
144
|
+
shuttingDown = true;
|
|
145
|
+
if (child && !child.killed) {
|
|
146
|
+
child.kill("SIGTERM");
|
|
147
|
+
}
|
|
148
|
+
if (cleanupTemp) {
|
|
149
|
+
cleanupTemp();
|
|
150
|
+
}
|
|
151
|
+
setTimeout(() => process.exit(code), 200);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
process.on("SIGINT", () => shutdown(0));
|
|
155
|
+
process.on("SIGTERM", () => shutdown(0));
|
|
156
|
+
|
|
157
|
+
function main() {
|
|
158
|
+
const cwd = process.cwd();
|
|
159
|
+
const viteEntry = resolveViteCli(cwd);
|
|
160
|
+
const tempFlags = createTempFlagAssets();
|
|
161
|
+
cleanupTemp = tempFlags.cleanup;
|
|
162
|
+
const configPath = createWrapperConfig({
|
|
163
|
+
cwd,
|
|
164
|
+
flagsRoot: tempFlags.flagsRoot,
|
|
165
|
+
tmpRoot: tempFlags.tmpRoot,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
child = spawn(
|
|
169
|
+
viteEntry.includes(".zip/") ? resolvePackageManager(cwd) : process.execPath,
|
|
170
|
+
viteEntry.includes(".zip/")
|
|
171
|
+
? ["vite", "--host", "0.0.0.0", "--config", configPath]
|
|
172
|
+
: [viteEntry, "--host", "0.0.0.0", "--config", configPath],
|
|
173
|
+
{
|
|
174
|
+
cwd,
|
|
175
|
+
env: process.env,
|
|
176
|
+
stdio: "inherit",
|
|
177
|
+
shell: false,
|
|
178
|
+
},
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
child.on("exit", (code, signal) => {
|
|
182
|
+
if (shuttingDown) return;
|
|
183
|
+
if (cleanupTemp) {
|
|
184
|
+
cleanupTemp();
|
|
185
|
+
}
|
|
186
|
+
process.exit(code === null ? (signal ? 1 : 0) : code);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
child.on("error", (error) => {
|
|
190
|
+
console.error(`[mvframe-d] failed to start vite: ${error.message}`);
|
|
191
|
+
shutdown(1);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
try {
|
|
196
|
+
main();
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error(`[mvframe-d] failed to start vite: ${error.message}`);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
const { spawn } = require("child_process");
|
|
8
8
|
const path = require("path");
|
|
9
|
-
const fs = require("fs");
|
|
10
|
-
const { createRequire } = require("module");
|
|
11
9
|
|
|
12
10
|
const children = new Set();
|
|
13
11
|
let shuttingDown = false;
|
|
@@ -56,37 +54,7 @@ process.on("SIGTERM", () => shutdown(0));
|
|
|
56
54
|
|
|
57
55
|
const notifyArgs = process.argv.slice(2);
|
|
58
56
|
const notifyScript = path.join(__dirname, "notify-server.js");
|
|
59
|
-
|
|
60
|
-
function resolveViteCli(cwd) {
|
|
61
|
-
let vpkg = "";
|
|
62
|
-
try {
|
|
63
|
-
const projectRequire = createRequire(path.join(cwd, "package.json"));
|
|
64
|
-
vpkg = projectRequire.resolve("vite/package.json");
|
|
65
|
-
} catch {
|
|
66
|
-
// Fall back to node_modules for non-PnP projects.
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (!vpkg) {
|
|
70
|
-
vpkg = path.join(cwd, "node_modules", "vite", "package.json");
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (fs.existsSync(vpkg)) {
|
|
74
|
-
const p = require(vpkg);
|
|
75
|
-
const bin = typeof p.bin === "string" ? p.bin : p.bin && p.bin.vite;
|
|
76
|
-
if (bin) {
|
|
77
|
-
const cli = path.join(path.dirname(vpkg), bin);
|
|
78
|
-
if (fs.existsSync(cli)) return cli;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
throw new Error(
|
|
82
|
-
"未在当前项目找到 Vite(请先安装依赖;宿主项目可执行 yarn install 后再运行 mvframe-d)",
|
|
83
|
-
);
|
|
84
|
-
}
|
|
57
|
+
const viteScript = path.join(__dirname, "dev-vite-server.js");
|
|
85
58
|
|
|
86
59
|
spawnChild("notify", process.execPath, [notifyScript, ...notifyArgs]);
|
|
87
|
-
|
|
88
|
-
const viteEntry = resolveViteCli(process.cwd());
|
|
89
|
-
spawnChild("vite", process.execPath, [viteEntry, "--host", "0.0.0.0"]);
|
|
90
|
-
} catch {
|
|
91
|
-
spawnChild("vite", "yarn", ["vite", "--host", "0.0.0.0"]);
|
|
92
|
-
}
|
|
60
|
+
spawnChild("vite", process.execPath, [viteScript]);
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const { execFileSync } = require("child_process");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const os = require("os");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const { createRequire } = require("module");
|
|
6
|
+
|
|
7
|
+
const root = path.resolve(__dirname, "..");
|
|
8
|
+
const pnpPath = path.join(root, ".pnp.cjs");
|
|
9
|
+
|
|
10
|
+
if (fs.existsSync(pnpPath)) {
|
|
11
|
+
require(pnpPath).setup();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function resolveFlagSource() {
|
|
15
|
+
const projectRequire = createRequire(path.join(root, "package.json"));
|
|
16
|
+
const flagPackagePath = projectRequire.resolve("flag-icons/package.json");
|
|
17
|
+
const flagRoot = path.dirname(flagPackagePath);
|
|
18
|
+
return path.join(flagRoot, "flags");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function copyFromZip(zipBackedPath, target, tmpParent) {
|
|
22
|
+
const marker = ".zip/";
|
|
23
|
+
const splitAt = zipBackedPath.indexOf(marker);
|
|
24
|
+
if (splitAt < 0) return false;
|
|
25
|
+
|
|
26
|
+
const zipPath = zipBackedPath.slice(0, splitAt + ".zip".length);
|
|
27
|
+
const innerPath = zipBackedPath.slice(splitAt + marker.length);
|
|
28
|
+
const tmp = fs.mkdtempSync(path.join(tmpParent, ".tmp-flag-icons-"));
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
execFileSync("unzip", ["-q", zipPath, `${innerPath}/*`, "-d", tmp], {
|
|
32
|
+
stdio: "ignore",
|
|
33
|
+
});
|
|
34
|
+
const extracted = path.join(tmp, innerPath);
|
|
35
|
+
fs.cpSync(extracted, target, { recursive: true });
|
|
36
|
+
} finally {
|
|
37
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function copyFlagAssetsTo(dest, options = {}) {
|
|
44
|
+
const src = resolveFlagSource();
|
|
45
|
+
const clean = options.clean !== false;
|
|
46
|
+
const tmpParent = options.tmpParent || path.dirname(dest);
|
|
47
|
+
|
|
48
|
+
if (clean) {
|
|
49
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
50
|
+
}
|
|
51
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
52
|
+
fs.mkdirSync(tmpParent, { recursive: true });
|
|
53
|
+
|
|
54
|
+
if (src.includes(".zip/")) {
|
|
55
|
+
copyFromZip(src, dest, tmpParent);
|
|
56
|
+
} else if (fs.existsSync(src)) {
|
|
57
|
+
fs.cpSync(src, dest, { recursive: true });
|
|
58
|
+
} else {
|
|
59
|
+
throw new Error(`[flag-assets] flag-icons assets not found: ${src}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return dest;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function createTempFlagAssets() {
|
|
66
|
+
const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), "mvframe-flags-"));
|
|
67
|
+
const flagsRoot = path.join(tmpRoot, "flags");
|
|
68
|
+
|
|
69
|
+
copyFlagAssetsTo(flagsRoot, {
|
|
70
|
+
tmpParent: tmpRoot,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
flagsRoot,
|
|
75
|
+
tmpRoot,
|
|
76
|
+
cleanup() {
|
|
77
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = {
|
|
83
|
+
copyFlagAssetsTo,
|
|
84
|
+
createTempFlagAssets,
|
|
85
|
+
};
|