UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

119 lines (116 loc) 4.08 kB
import { existsSync, mkdirSync, writeFileSync } from "node:fs"; import { join, resolve } from "node:path"; import * as p from "@clack/prompts"; import { spawn } from "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 ? resolve(info.projectDir, info.workspaceDir) : resolve(info.projectDir, info.key); const configPath = join(workspaceRoot, "drizzle.config.ts"); if (!existsSync(configPath)) throw new Error(`No drizzle.config.ts found in ${workspaceRoot}. Run 'drizzle-kit init' first in the plugin workspace.`); p.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 = resolve(info.projectDir, ".bos", "db", info.key); mkdirSync(dbDir, { recursive: true }); const configPath = join(dbDir, "drizzle.config.ts"); 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, }); `); p.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.`); } p.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 = 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 export { resolvePluginDbInfo, runStudioLocal, runStudioRemote }; //# sourceMappingURL=db-studio.mjs.map