UNPKG

everything-dev

Version:

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

131 lines (129 loc) 4.08 kB
const require_runtime = require('../_virtual/_rolldown/runtime.cjs'); let effect = require("effect"); let node_net = require("node:net"); //#region src/infra/preflight.ts function parseLocalUrl(url) { try { const match = url.match(/:\/\/([^:/]+):(\d+)/); if (!match) return null; const host = match[1]; const port = Number.parseInt(match[2], 10); if (Number.isNaN(port)) return null; if (host !== "localhost" && host !== "127.0.0.1") return null; return { host, port }; } catch { return null; } } function checkTcpReachable(host, port, timeoutMs = 2e3) { return effect.Effect.async((resume) => { const socket = (0, node_net.createConnection)({ host, port }); const timer = setTimeout(() => { socket.destroy(); resume(effect.Effect.succeed(false)); }, timeoutMs); socket.once("connect", () => { clearTimeout(timer); socket.destroy(); resume(effect.Effect.succeed(true)); }); socket.once("error", () => { clearTimeout(timer); socket.destroy(); resume(effect.Effect.succeed(false)); }); }); } function checkPgConnection(url) { return effect.Effect.gen(function* () { if (!(yield* checkTcpReachable(new URL(url).hostname, Number(new URL(url).port) || 5432, 4e3))) return false; try { const { Pool } = yield* effect.Effect.promise(() => Promise.resolve().then(() => require("../node_modules/pg/esm/index.cjs"))); const pool = new Pool({ connectionString: url, connectionTimeoutMillis: 3e3 }); const client = yield* effect.Effect.promise(() => pool.connect().then((c) => ({ client: c, pool }))); try { yield* effect.Effect.promise(() => client.client.query("SELECT 1")); return true; } finally { client.client.release(); yield* effect.Effect.promise(() => client.pool.end().catch(() => {})); } } catch { return false; } }); } function preflightTargetsFromEnv(env) { const targets = []; for (const [secret, value] of Object.entries(env)) { if (!value) continue; if (secret.endsWith("_DATABASE_URL")) { const parsed = parseLocalUrl(value); if (parsed) targets.push({ secret, host: parsed.host, port: parsed.port, kind: "postgres", url: value }); } else if (secret.endsWith("_REDIS_URL")) { const parsed = parseLocalUrl(value); if (parsed) targets.push({ secret, host: parsed.host, port: parsed.port, kind: "redis", url: value }); } } return targets; } function preflightLocalInfra(env, overrides) { const targets = preflightTargetsFromEnv(overrides ? { ...env, ...overrides } : env); if (targets.length === 0) return effect.Effect.succeed([]); return effect.Effect.forEach(targets, (target) => effect.Effect.gen(function* () { if (target.kind === "postgres") { if (yield* checkPgConnection(target.url)) return null; const tcpOk = yield* checkTcpReachable(target.host, target.port); const pluginContext = target.secret.endsWith("_DATABASE_URL") ? ` The plugin for ${target.secret} runs inside the local host process, so this DB must be reachable. Run \`docker compose up -d --wait\` to start local Postgres/Redis.` : ""; if (tcpOk) return { secret: target.secret, host: target.host, port: target.port, error: `${target.secret} at ${target.host}:${target.port} is reachable but Postgres connection failed. Check credentials and database name.${pluginContext}` }; return { secret: target.secret, host: target.host, port: target.port, error: `${target.secret} points to ${target.host}:${target.port} but nothing is listening.${pluginContext}` }; } if (yield* checkTcpReachable(target.host, target.port)) return null; return { secret: target.secret, host: target.host, port: target.port, error: `${target.secret} points to ${target.host}:${target.port} but nothing is listening` }; }), { concurrency: "unbounded" }).pipe(effect.Effect.map((results) => results.filter((r) => r !== null))); } //#endregion exports.preflightLocalInfra = preflightLocalInfra; //# sourceMappingURL=preflight.cjs.map