import { URL } from "node:url"; export function formatDatabaseTarget(parsedUrl, databaseName) { return `${parsedUrl.protocol}//${decodeURIComponent(parsedUrl.username)}@${parsedUrl.hostname}${parsedUrl.port ? `:${parsedUrl.port}` : ""}/${databaseName}`; } export function inspectDatabaseUrl(rawUrl, expectedDatabase = "capakraken") { if (!rawUrl) { throw new Error("DATABASE_URL is not configured."); } let parsedUrl; try { parsedUrl = new URL(rawUrl); } catch (error) { throw new Error(`DATABASE_URL is invalid: ${error instanceof Error ? error.message : String(error)}`); } const databaseName = parsedUrl.pathname.replace(/^\/+/, ""); const target = formatDatabaseTarget(parsedUrl, databaseName); if (!databaseName) { throw new Error(`DATABASE_URL does not contain a database name. Target=${target}`); } if (databaseName !== expectedDatabase) { throw new Error(`Unexpected database target '${databaseName}'. Expected '${expectedDatabase}'. Target=${target}`); } return { databaseName, expectedDatabase, target, }; } function collectPrismaCommandTokens(args) { const tokens = []; for (let index = 0; index < args.length; index += 1) { const arg = args[index]; if (arg === "--") { break; } if (arg === "--schema" || arg === "--url" || arg === "--telemetry-information") { index += 1; continue; } if (arg.startsWith("-")) { continue; } tokens.push(arg); } return tokens; } export function shouldGuardPrismaCommand(args) { if (args.includes("--help") || args.includes("-h")) { return false; } const [command, subcommand] = collectPrismaCommandTokens(args); if (!command) { return false; } if (command === "db") { return subcommand === "push" || subcommand === "pull" || subcommand === "execute"; } if (command === "migrate") { return true; } return command === "studio" || command === "introspect"; } export function getExpectedDatabaseName() { return process.env.CAPAKRAKEN_EXPECTED_DB_NAME?.trim() || "capakraken"; }