everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
80 lines (78 loc) • 3.15 kB
JavaScript
let node_fs = require("node:fs");
let node_path = require("node:path");
let dotenv = require("dotenv");
//#region src/db/binding.ts
/**
* drizzle-kit subcommands that open a database connection. For everything
* else (generate, check) the connection string is parsed but never used, so a
* placeholder is safe.
*/
const DB_REQUIRING_COMMANDS = /* @__PURE__ */ new Set([
"push",
"pull",
"migrate",
"studio",
"up"
]);
/**
* Whether the current process is a drizzle-kit invocation whose command needs
* a live database. Mirrors drizzle-kit's CLI layout: `drizzle-kit <command> …`.
*/
function requiresDatabaseConnection(argv = process.argv) {
if (!(typeof argv[1] === "string" && argv[1].includes("drizzle-kit"))) return false;
const command = argv[2];
return typeof command === "string" && DB_REQUIRING_COMMANDS.has(command);
}
/**
* Materialize the environment a spawned tool needs to reach the binding's
* database: the canonical secret name mapped to the resolved URL. The process
* that resolves bindings (the CLI composition root) pushes this into spawned
* children so they never re-derive secrets from ambient state.
*/
function bindingEnv(binding) {
return { [binding.secretName]: binding.url };
}
function findEnvFile(startDir) {
if (!startDir) return void 0;
let current = startDir;
for (let i = 0; i < 15; i++) {
const candidate = (0, node_path.join)(current, ".env");
if ((0, node_fs.existsSync)(candidate)) return candidate;
const parent = (0, node_path.dirname)(current);
if (parent === current) return void 0;
current = parent;
}
}
/**
* Resolve the connection URL for a workspace identity.
*
* Resolution order:
* 1. the canonical secret in the provided environment
* 2. the canonical secret in the nearest `.env` walked up from the
* workspace directory (existing environment wins — values are not
* overridden, matching dotenv semantics)
* 3. loud failure when the drizzle-kit command needs a database
* 4. an in-memory pglite placeholder for commands that never connect
* (generate, check) and for non-drizzle-kit consumers
*
* This replaces the previous silent `pglite:` fallback that masked missing
* configuration as cryptic driver errors downstream.
*/
function resolveDatabaseUrl(identity, options = {}) {
const env = options.env ?? process.env;
const argv = options.argv ?? process.argv;
const direct = env[identity.secretName];
if (direct) return direct;
const envFile = findEnvFile(identity.workspaceDir);
if (envFile) try {
const fromFile = (0, dotenv.parse)((0, node_fs.readFileSync)(envFile, "utf-8"))[identity.secretName];
if (fromFile) return fromFile;
} catch {}
if (requiresDatabaseConnection(argv)) throw new Error(`Missing ${identity.secretName} for workspace "${identity.slug}" — required for "drizzle-kit ${argv[2]}". Add ${identity.secretName} to your .env (see .env.example) or run via \`bos db\`.`);
return `pglite:.bos/${identity.slug}/:memory:`;
}
//#endregion
exports.bindingEnv = bindingEnv;
exports.requiresDatabaseConnection = requiresDatabaseConnection;
exports.resolveDatabaseUrl = resolveDatabaseUrl;
//# sourceMappingURL=binding.cjs.map