everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
1 lines • 4.81 kB
Source Map (JSON)
{"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"}