1import * as Redacted from "effect/Redacted";
2
3/**
4 * The shape `Cloudflare.Hyperdrive` and other Postgres consumers accept
5 * as `origin`. Materialized on `Prisma.Connection` so callers can wire
6 * Prisma Postgres into Hyperdrive directly:
7 *
8 * ```typescript
9 * const connection = yield* Prisma.Connection("api", { database, name: "api" });
10 * const hd = yield* Cloudflare.Hyperdrive.Connection("api-hd", {
11 * origin: connection.origin.as<Prisma.PostgresOrigin>(),
12 * });
13 * ```
14 */
15export type PostgresOrigin = {
16 scheme: "postgres" | "postgresql";
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. Used to
26 * derive `connection.origin` / `connection.pooledOrigin` from the direct and
27 * pooled connection strings Prisma returns.
28 *
29 * Returns `undefined` for non-Postgres URIs (e.g. `prisma://` Accelerate
30 * connection strings) and malformed values.
31 */
32export const parsePostgresOrigin = (
33 uri: string,
34): PostgresOrigin | undefined => {
35 let url: URL;
36 try {
37 url = new URL(uri);
38 } catch {
39 return undefined;
40 }
41 if (url.protocol !== "postgres:" && url.protocol !== "postgresql:") {
42 return undefined;
43 }
44 return {
45 scheme: url.protocol === "postgresql:" ? "postgresql" : "postgres",
46 host: url.hostname,
47 port: url.port ? Number(url.port) : 5432,
48 database: url.pathname.replace(/^\//, ""),
49 user: decodeURIComponent(url.username),
50 password: Redacted.make(decodeURIComponent(url.password)),
51 };
52};