everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
123 lines (120 loc) • 4.45 kB
JavaScript
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
let node_fs = require("node:fs");
let node_path = require("node:path");
let _clack_prompts = require("@clack/prompts");
_clack_prompts = require_runtime.__toESM(_clack_prompts, 1);
let node_child_process = require("node:child_process");
//#region src/cli/db-studio.ts
function resolvePluginDbInfo(pluginKey, runtimeConfig, projectDir) {
let source;
let section;
let secrets;
let localPath;
let key;
if (pluginKey === "api" && runtimeConfig.api) {
source = runtimeConfig.api.source;
section = "app.api";
secrets = runtimeConfig.api.secrets;
localPath = runtimeConfig.api.localPath;
key = "api";
} else if (pluginKey === "auth" && runtimeConfig.auth) {
source = runtimeConfig.auth.source;
section = "app.auth";
secrets = runtimeConfig.auth.secrets;
localPath = runtimeConfig.auth.localPath;
key = "auth";
} else if (runtimeConfig.plugins?.[pluginKey]) {
const plugin = runtimeConfig.plugins[pluginKey];
source = plugin.source;
section = "plugins";
secrets = plugin.secrets;
localPath = plugin.localPath;
key = pluginKey;
} else throw new Error(`Plugin "${pluginKey}" not found in app.api, app.auth, or plugins. Available: ${[
"api",
...runtimeConfig.auth ? ["auth"] : [],
...Object.keys(runtimeConfig.plugins ?? {})
].join(", ")}`);
const dbSecret = secrets?.find((s) => s.endsWith("_DATABASE_URL"));
if (!dbSecret) throw new Error(`Plugin "${pluginKey}" has no database secret (no secret ending in _DATABASE_URL). Secrets: ${(secrets ?? []).join(", ") || "none"}`);
const dbUrl = process.env[dbSecret];
if (!dbUrl) throw new Error(`.env missing ${dbSecret} for plugin "${pluginKey}". Add it to your .env file (see .env.example).`);
return {
key,
source: source ?? "remote",
section,
databaseSecret: dbSecret,
databaseUrl: dbUrl,
workspaceDir: localPath,
projectDir
};
}
async function runStudioLocal(info) {
const workspaceRoot = info.workspaceDir ? (0, node_path.resolve)(info.projectDir, info.workspaceDir) : (0, node_path.resolve)(info.projectDir, info.key);
const configPath = (0, node_path.join)(workspaceRoot, "drizzle.config.ts");
if (!(0, node_fs.existsSync)(configPath)) throw new Error(`No drizzle.config.ts found in ${workspaceRoot}. Run 'drizzle-kit init' first in the plugin workspace.`);
_clack_prompts.log.info(`Starting Drizzle Studio for ${info.key} (local)...`);
await spawnAsync("npx", [
"drizzle-kit",
"studio",
"--config",
configPath
], { cwd: workspaceRoot });
}
async function runStudioRemote(info) {
const dbDir = (0, node_path.resolve)(info.projectDir, ".bos", "db", info.key);
(0, node_fs.mkdirSync)(dbDir, { recursive: true });
const configPath = (0, node_path.join)(dbDir, "drizzle.config.ts");
(0, node_fs.writeFileSync)(configPath, `import { defineConfig } from "drizzle-kit";
export default defineConfig({
schema: "./drizzle/schema.ts",
out: "./drizzle",
dialect: "postgresql",
dbCredentials: {
url: "${info.databaseUrl}",
},
verbose: true,
strict: true,
});
`);
_clack_prompts.log.info(`Introspecting database schema for ${info.key}...`);
try {
await spawnAsync("npx", [
"drizzle-kit",
"pull",
"--config",
configPath
], { cwd: dbDir });
} catch {
throw new Error(`Failed to introspect database for "${info.key}". Check that ${info.databaseSecret} is correct and the database is reachable.`);
}
_clack_prompts.log.info(`Starting Drizzle Studio for ${info.key}...`);
await spawnAsync("npx", [
"drizzle-kit",
"studio",
"--config",
configPath
], { cwd: dbDir });
}
function spawnAsync(cmd, args, options) {
return new Promise((resolvePromise, reject) => {
const child = (0, node_child_process.spawn)(cmd, args, {
cwd: options.cwd,
stdio: "inherit",
shell: true
});
child.on("error", (err) => {
if (err.code === "ENOENT") reject(/* @__PURE__ */ new Error(`"${cmd}" not found. Ensure it is installed (e.g. 'npm install -g drizzle-kit').`));
else reject(/* @__PURE__ */ new Error(`Failed to start ${cmd}: ${err.message}`));
});
child.on("exit", (code) => {
if (code === 0 || code === null) resolvePromise();
else reject(/* @__PURE__ */ new Error(`"${cmd}" exited with code ${code}`));
});
});
}
//#endregion
exports.resolvePluginDbInfo = resolvePluginDbInfo;
exports.runStudioLocal = runStudioLocal;
exports.runStudioRemote = runStudioRemote;
//# sourceMappingURL=db-studio.cjs.map