{"version":3,"file":"binding.mjs","names":["parseDotenv"],"sources":["../../src/db/binding.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { parse as parseDotenv } from \"dotenv\";\nimport type { WorkspaceIdentity } from \"./identity\";\n\n/**\n * drizzle-kit subcommands that open a database connection. For everything\n * else (generate, check) the connection string is parsed but never used, so a\n * placeholder is safe.\n */\nconst DB_REQUIRING_COMMANDS: ReadonlySet<string> = new Set([\n  \"push\",\n  \"pull\",\n  \"migrate\",\n  \"studio\",\n  \"up\",\n]);\n\n/**\n * Whether the current process is a drizzle-kit invocation whose command needs\n * a live database. Mirrors drizzle-kit's CLI layout: `drizzle-kit <command> …`.\n */\nexport function requiresDatabaseConnection(argv: readonly string[] = process.argv): boolean {\n  const isDrizzleKit = typeof argv[1] === \"string\" && argv[1].includes(\"drizzle-kit\");\n  if (!isDrizzleKit) return false;\n  const command = argv[2];\n  return typeof command === \"string\" && DB_REQUIRING_COMMANDS.has(command);\n}\n\n/**\n * Materialize the environment a spawned tool needs to reach the binding's\n * database: the canonical secret name mapped to the resolved URL. The process\n * that resolves bindings (the CLI composition root) pushes this into spawned\n * children so they never re-derive secrets from ambient state.\n */\nexport function bindingEnv(binding: { secretName: string; url: string }): Record<string, string> {\n  return { [binding.secretName]: binding.url };\n}\n\nfunction findEnvFile(startDir: string | undefined): string | undefined {\n  if (!startDir) return undefined;\n  let current = startDir;\n  for (let i = 0; i < 15; i++) {\n    const candidate = join(current, \".env\");\n    if (existsSync(candidate)) return candidate;\n    const parent = dirname(current);\n    if (parent === current) return undefined;\n    current = parent;\n  }\n  return undefined;\n}\n\n/**\n * Resolve the connection URL for a workspace identity.\n *\n * Resolution order:\n *   1. the canonical secret in the provided environment\n *   2. the canonical secret in the nearest `.env` walked up from the\n *      workspace directory (existing environment wins — values are not\n *      overridden, matching dotenv semantics)\n *   3. loud failure when the drizzle-kit command needs a database\n *   4. an in-memory pglite placeholder for commands that never connect\n *      (generate, check) and for non-drizzle-kit consumers\n *\n * This replaces the previous silent `pglite:` fallback that masked missing\n * configuration as cryptic driver errors downstream.\n */\nexport function resolveDatabaseUrl(\n  identity: WorkspaceIdentity,\n  options: {\n    env?: Record<string, string | undefined>;\n    argv?: readonly string[];\n  } = {},\n): string {\n  const env = options.env ?? process.env;\n  const argv = options.argv ?? process.argv;\n\n  const direct = env[identity.secretName];\n  if (direct) return direct;\n\n  const envFile = findEnvFile(identity.workspaceDir);\n  if (envFile) {\n    try {\n      const parsed = parseDotenv(readFileSync(envFile, \"utf-8\"));\n      const fromFile = parsed[identity.secretName];\n      if (fromFile) return fromFile;\n    } catch {\n      // unreadable .env — fall through to loud failure / placeholder\n    }\n  }\n\n  if (requiresDatabaseConnection(argv)) {\n    throw new Error(\n      `Missing ${identity.secretName} for workspace \"${identity.slug}\" — ` +\n        `required for \"drizzle-kit ${argv[2]}\". ` +\n        `Add ${identity.secretName} to your .env (see .env.example) or run via \\`bos db\\`.`,\n    );\n  }\n\n  return `pglite:.bos/${identity.slug}/:memory:`;\n}\n"],"mappings":";;;;;;;;;;AAUA,MAAM,wCAA6C,IAAI,IAAI;CACzD;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;AAMD,SAAgB,2BAA2B,OAA0B,QAAQ,MAAe;CAE1F,IAAI,EADiB,OAAO,KAAK,OAAO,YAAY,KAAK,EAAE,CAAC,SAAS,aAAa,IAC/D,OAAO;CAC1B,MAAM,UAAU,KAAK;CACrB,OAAO,OAAO,YAAY,YAAY,sBAAsB,IAAI,OAAO;AACzE;;;;;;;AAQA,SAAgB,WAAW,SAAsE;CAC/F,OAAO,GAAG,QAAQ,aAAa,QAAQ,IAAI;AAC7C;AAEA,SAAS,YAAY,UAAkD;CACrE,IAAI,CAAC,UAAU,OAAO;CACtB,IAAI,UAAU;CACd,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;EAC3B,MAAM,YAAY,KAAK,SAAS,MAAM;EACtC,IAAI,WAAW,SAAS,GAAG,OAAO;EAClC,MAAM,SAAS,QAAQ,OAAO;EAC9B,IAAI,WAAW,SAAS,OAAO;EAC/B,UAAU;CACZ;AAEF;;;;;;;;;;;;;;;;AAiBA,SAAgB,mBACd,UACA,UAGI,CAAC,GACG;CACR,MAAM,MAAM,QAAQ,OAAO,QAAQ;CACnC,MAAM,OAAO,QAAQ,QAAQ,QAAQ;CAErC,MAAM,SAAS,IAAI,SAAS;CAC5B,IAAI,QAAQ,OAAO;CAEnB,MAAM,UAAU,YAAY,SAAS,YAAY;CACjD,IAAI,SACF,IAAI;EAEF,MAAM,WADSA,MAAY,aAAa,SAAS,OAAO,CAClC,CAAC,CAAC,SAAS;EACjC,IAAI,UAAU,OAAO;CACvB,QAAQ,CAER;CAGF,IAAI,2BAA2B,IAAI,GACjC,MAAM,IAAI,MACR,WAAW,SAAS,WAAW,kBAAkB,SAAS,KAAK,gCAChC,KAAK,GAAG,SAC9B,SAAS,WAAW,wDAC/B;CAGF,OAAO,eAAe,SAAS,KAAK;AACtC"}