@scenemesh/entity-engine
Version:
一个“元数据驱动 + 组件适配 + 动态关系 + 视图管线”式的实体引擎。以 **Model + View + FieldType + SuiteAdapter + DataSource** 为五大支点,统一 CRUD / 查询 / 引用管理 / 视图渲染 / 扩展注册,支持在运行期无侵入拼装出 **表单、网格、主从、看板、仪表盘、流程/树形视图** 等多形态界面。
125 lines (124 loc) • 5.24 kB
JavaScript
// src/scripts/cli.ts
import fs from "fs";
import path from "path";
import readline from "readline";
import { promisify } from "util";
import { exec } from "child_process";
var execPromise = promisify(exec);
var log = {
info: (msg) => console.log(`\x1B[34m[info]\x1B[0m ${msg}`),
success: (msg) => console.log(`\x1B[32m[success]\x1B[0m ${msg}`),
error: (msg) => console.error(`\x1B[31m[error]\x1B[0m ${msg}`),
warn: (msg) => console.warn(`\x1B[33m[warn]\x1B[0m ${msg}`)
};
async function runCommand(command) {
try {
const { stdout, stderr } = await execPromise(command);
if (stdout) console.log(stdout);
if (stderr) console.error(stderr);
} catch (error) {
log.error(`Failed to execute command: ${command}`);
throw error;
}
}
async function main() {
log.info("Setting up @scenemesh/entity-engine...");
const userSchemaPath = path.join(process.cwd(), "prisma", "schema.prisma");
const packageSchemaPath = path.join(__dirname, "..", "prisma", "schema.prisma");
let generateCommand = "npx prisma generate";
if (fs.existsSync(userSchemaPath)) {
log.info("Existing prisma/schema.prisma found. Merging models...");
const existingSchema = fs.readFileSync(userSchemaPath, "utf-8");
if (existingSchema.includes("model EntityObject")) {
log.info(
"Entity Engine models already exist in your schema. Skipping schema modification."
);
} else {
let modelsToAdd = fs.readFileSync(packageSchemaPath, "utf-8");
const modelStartIndex = modelsToAdd.indexOf("model EntityObject");
if (modelStartIndex !== -1) {
modelsToAdd = "\n\n" + modelsToAdd.substring(modelStartIndex);
fs.appendFileSync(userSchemaPath, modelsToAdd);
log.success("Entity Engine models have been added to your prisma/schema.prisma.");
}
}
} else {
log.warn("No prisma/schema.prisma found in your project.");
log.info("Generating a temporary Prisma Client based on the Entity Engine schema.");
generateCommand = `npx prisma generate --schema=${packageSchemaPath}`;
}
try {
log.info(`Running command: ${generateCommand}`);
await runCommand(generateCommand);
log.success("Prisma Client has been successfully generated.");
} catch {
log.error("Prisma Client generation failed. Please run it manually.");
process.exit(1);
}
if (fs.existsSync(userSchemaPath)) {
log.info("Next step: Run 'npx prisma migrate dev' to update your database.");
await maybeRunInteractive(async () => {
const doMigrate = await promptYesNo("\u662F\u5426\u73B0\u5728\u6267\u884C\u6570\u636E\u5E93\u8FC1\u79FB\u4EE5\u521B\u5EFA/\u66F4\u65B0\u8868\u7ED3\u6784? (y/N): ");
if (doMigrate) {
try {
log.info("Running: npx prisma migrate dev");
await runCommand("npx prisma migrate dev");
log.success("\u6570\u636E\u5E93\u8FC1\u79FB\u5DF2\u5B8C\u6210\u3002");
} catch (err) {
log.error("\u6267\u884C prisma migrate dev \u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u68C0\u67E5\u3002");
if (err instanceof Error) log.error(err.message);
}
} else {
log.info("\u5DF2\u8DF3\u8FC7\u6570\u636E\u5E93\u8FC1\u79FB\u3002");
}
});
} else {
log.warn(
"Important: The generated client is temporary and only contains Entity Engine models."
);
log.warn(
"Once you create your own 'prisma/schema.prisma' and run 'npx prisma generate', this client will be overwritten."
);
log.warn(
"To integrate properly, run 'npx prisma init' and then run this setup script again."
);
await maybeRunInteractive(async () => {
const doPush = await promptYesNo(
"\u5F53\u524D\u6CA1\u6709\u672C\u5730 schema\uFF0C\u662F\u5426\u57FA\u4E8E\u5305\u5185\u4E34\u65F6 schema \u7ACB\u5373\u521B\u5EFA\u6570\u636E\u5E93\u7ED3\u6784 (prisma db push)? (y/N): "
);
if (doPush) {
try {
const cmd = `npx prisma db push --schema=${packageSchemaPath}`;
log.info(`Running: ${cmd}`);
await runCommand(cmd);
log.success("\u5DF2\u6839\u636E\u4E34\u65F6 schema \u521B\u5EFA/\u540C\u6B65\u6570\u636E\u5E93\u7ED3\u6784\u3002");
} catch (err) {
log.error("\u6267\u884C prisma db push \u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u68C0\u67E5\u3002");
if (err instanceof Error) log.error(err.message);
}
} else {
log.info("\u5DF2\u8DF3\u8FC7\u4E34\u65F6 schema \u7684\u6570\u636E\u5E93\u7ED3\u6784\u521B\u5EFA\u3002");
}
});
}
}
main();
function promptYesNo(question) {
return new Promise((resolve) => {
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
rl.question(question, (answer) => {
rl.close();
const normalized = (answer || "").trim().toLowerCase();
resolve(normalized === "y" || normalized === "yes");
});
});
}
async function maybeRunInteractive(fn) {
if (!process.stdout.isTTY) {
log.info("\u68C0\u6D4B\u5230\u975E\u4EA4\u4E92\u5F0F\u73AF\u5883\uFF0C\u81EA\u52A8\u8DF3\u8FC7\u53EF\u9009\u7684\u6570\u636E\u5E93\u7ED3\u6784\u521B\u5EFA\u6B65\u9AA4\u3002");
return;
}
await fn();
}
//# sourceMappingURL=cli.mjs.map