首次提交:脑晴测 H5 项目
包含前端源码、预构建产物(dist/)、零依赖 Node.js 服务器(server.mjs)、 Cloudflare Worker 版本(worker/)、部署文档(DEPLOY.md)和交接文档。 技术总监可直接 clone 后运行 node server.mjs 启动,无需安装 React 或 build。 DEEPSEEK_API_KEY 通过环境变量注入,未纳入仓库。
This commit is contained in:
33
brain-h5/scripts/check-mobile-runtime.mjs
Normal file
33
brain-h5/scripts/check-mobile-runtime.mjs
Normal file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env node
|
||||
import { createHash } from "node:crypto";
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const lockPath = path.join(root, "mobile-runtime.lock.json");
|
||||
const lockedFiles = JSON.parse(readFileSync(lockPath, "utf8"));
|
||||
const failures = [];
|
||||
|
||||
for (const [relativePath, expectedHash] of Object.entries(lockedFiles)) {
|
||||
const filePath = path.join(root, relativePath);
|
||||
|
||||
if (!existsSync(filePath)) {
|
||||
failures.push(`${relativePath} is missing`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const actualHash = createHash("sha256").update(readFileSync(filePath)).digest("hex");
|
||||
if (actualHash !== expectedHash) {
|
||||
failures.push(`${relativePath} was modified`);
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.length > 0) {
|
||||
console.error("Mobile runtime integrity check failed:\n");
|
||||
for (const failure of failures) console.error(`- ${failure}`);
|
||||
console.error("\nRestore the protected runtime. Put app UI in src/Prototype.tsx and src/prototype.css.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Mobile runtime integrity check passed (${Object.keys(lockedFiles).length} protected files).`);
|
||||
Reference in New Issue
Block a user