UNPKG

everything-dev

Version:

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

177 lines (174 loc) • 5.54 kB
const require_binding = require('./binding.cjs'); let node_fs = require("node:fs"); let node_path = require("node:path"); let effect = require("effect"); let node_child_process = require("node:child_process"); //#region src/db/drizzle-kit.ts var DrizzleKitError = class extends effect.Data.TaggedError("DrizzleKitError") {}; var DrizzleKit = class extends effect.Context.Service()("everything-dev/DrizzleKit") {}; /** * The single choke point for invoking drizzle-kit. Every child receives the * composition root's materialized environment (`bindingEnv`) so the config it * evaluates never has to re-derive credentials from ambient state. */ function spawnDrizzleKit(spec) { return effect.Effect.callback((resume) => { let stderr = ""; let settled = false; const settle = (effect$1) => { if (settled) return; settled = true; resume(effect$1); }; const child = (0, node_child_process.spawn)(process.platform === "win32" ? "npx.cmd" : "npx", [...spec.args], { cwd: spec.cwd, env: spec.env, stdio: spec.stdio }); if (spec.stdio === "pipe") child.stderr?.on("data", (data) => { stderr += data.toString(); }); child.on("error", (err) => { const hint = err.code === "ENOENT" ? "\"npx\" not found. Ensure Node.js is installed." : err.message; settle(effect.Effect.fail(new DrizzleKitError({ command: spec.command, message: hint, exitCode: void 0 }))); }); child.on("exit", (code) => { if (code === 0 || code === null) { settle(effect.Effect.void); return; } settle(effect.Effect.fail(new DrizzleKitError({ command: spec.command, message: `drizzle-kit ${spec.command} exited with code ${code}${stderr.trim() ? `: ${stderr.trim()}` : ""}`, exitCode: code }))); }); return effect.Effect.sync(() => { if (child.exitCode === null && !child.killed) child.kill(); }); }); } function childEnv(binding) { return { ...process.env, ...require_binding.bindingEnv({ secretName: binding.identity.secretName, url: binding.url }) }; } function workspaceConfigPath(binding) { const workspaceDir = binding.identity.workspaceDir; if (!workspaceDir) return void 0; const configPath = (0, node_path.join)(workspaceDir, "drizzle.config.ts"); return (0, node_fs.existsSync)(configPath) ? configPath : void 0; } function writeGeneratedConfig(binding, projectDir) { const dbDir = (0, node_path.resolve)(projectDir, ".bos", "db", binding.key); (0, node_fs.mkdirSync)(dbDir, { recursive: true }); const configPath = (0, node_path.join)(dbDir, "drizzle.config.ts"); const configContent = `import { defineConfig } from "drizzle-kit"; export default defineConfig({ schema: "./drizzle/schema.ts", out: "./drizzle", dialect: "postgresql", dbCredentials: { url: "${binding.url}", }, migrations: { schema: "${binding.identity.journal.schema}", table: "${binding.identity.journal.table}", }, verbose: true, strict: true, }); `; (0, node_fs.writeFileSync)(configPath, configContent); return dbDir; } const makeDrizzleKitLive = (options) => effect.Layer.succeed(DrizzleKit, { studio: (binding) => effect.Effect.gen(function* () { const localConfig = workspaceConfigPath(binding); if (localConfig && binding.identity.workspaceDir) { options.onLog?.(`Starting Drizzle Studio for ${binding.key} (local)...`); yield* spawnDrizzleKit({ args: [ "drizzle-kit", "studio", "--config", localConfig ], cwd: binding.identity.workspaceDir, env: childEnv(binding), command: "studio", stdio: "inherit" }); return; } if (binding.source === "local") return yield* new DrizzleKitError({ command: "studio", message: `No drizzle.config.ts found in ${binding.identity.workspaceDir ?? binding.key}. Run 'drizzle-kit init' first in the plugin workspace.`, exitCode: void 0 }); options.onLog?.(`Introspecting database schema for ${binding.key}...`); const dbDir = writeGeneratedConfig(binding, options.projectDir); yield* spawnDrizzleKit({ args: [ "drizzle-kit", "pull", "--config", (0, node_path.join)(dbDir, "drizzle.config.ts") ], cwd: dbDir, env: childEnv(binding), command: "pull", stdio: "inherit" }).pipe(effect.Effect.mapError((error) => new DrizzleKitError({ command: "pull", exitCode: error.exitCode, message: `Failed to introspect database for "${binding.key}". Check that ${binding.identity.secretName} is correct and the database is reachable. ` + error.message }))); options.onLog?.(`Starting Drizzle Studio for ${binding.key}...`); yield* spawnDrizzleKit({ args: [ "drizzle-kit", "studio", "--config", (0, node_path.join)(dbDir, "drizzle.config.ts") ], cwd: dbDir, env: childEnv(binding), command: "studio", stdio: "inherit" }); }), migrate: (binding) => { const configPath = workspaceConfigPath(binding); if (!configPath || !binding.identity.workspaceDir) return effect.Effect.fail(new DrizzleKitError({ command: "migrate", message: `No drizzle.config.ts found in ${binding.identity.workspaceDir ?? binding.key}.`, exitCode: void 0 })); return spawnDrizzleKit({ args: [ "drizzle-kit", "migrate", "--config", configPath ], cwd: binding.identity.workspaceDir, env: childEnv(binding), command: "migrate", stdio: "pipe" }); } }); //#endregion exports.DrizzleKit = DrizzleKit; exports.DrizzleKitError = DrizzleKitError; exports.makeDrizzleKitLive = makeDrizzleKitLive; //# sourceMappingURL=drizzle-kit.cjs.map