1import * as Redacted from "effect/Redacted";
2
3/**
4 * The shape `Cloudflare.Hyperdrive` and other Postgres consumers accept
5 * as `origin`. Materialized on `Neon.Project` and `Neon.Branch` so callers
6 * can wire databases into Hyperdrive directly:
7 *
8 * ```typescript
9 * const branch = yield* Neon.Branch("preview", { project });
10 * const hd = yield* Cloudflare.Hyperdrive.Connection("preview-hd", {
11 * origin: branch.origin,
12 * });
13 * ```
14 */
15export type PostgresOrigin = {
16 scheme: "postgres" | "postgresql" | "mysql";
17 host: string;
18 port: number;
19 database: string;
20 user: string;
21 password: Redacted.Redacted<string>;
22};
23
24/**
25 * Parse a Postgres connection URI into the structured origin shape.
26 * Used to derive `branch.origin` / `project.origin` from the API
27 * response's `connectionUri`.
28 */
29export const parsePostgresOrigin = (uri: string): PostgresOrigin => {
30 const url = new URL(uri);
31 const scheme: PostgresOrigin["scheme"] =
32 url.protocol === "postgresql:" ? "postgresql" : "postgres";
33 return {
34 scheme,
35 host: url.hostname,
36 port: url.port ? Number(url.port) : 5432,
37 database: url.pathname.replace(/^\//, ""),
38 user: decodeURIComponent(url.username),
39 password: Redacted.make(decodeURIComponent(url.password)),
40 };
41};