Unified · Split
| @@ -39,6 +39,48 @@ const trim = (value: string | undefined): string | undefined => { · 38 unmodified lines | |||
| 39 | return candidate && candidate.length > 0 ? candidate : undefined; | 39 | return candidate && candidate.length > 0 ? candidate : undefined; |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | const isPlanetScalePostgresUrl = (value: string): boolean => { | ||
| 43 | try { | ||
| 44 | const parsed = new URL(value); | ||
| 45 | return ( | ||
| 46 | (parsed.protocol === "postgres:" || parsed.protocol === "postgresql:") | ||
| 47 | && parsed.hostname.endsWith(".pg.psdb.cloud") | ||
| 48 | ); | ||
| 49 | } catch { | ||
| 50 | return false; | ||
| 51 | } | ||
| 52 | }; | ||
| 53 | |||
| 54 | const deriveRuntimeDatabaseUrl = (value: string): string => { | ||
| 55 | const configuredTarget = trim(process.env.CONTROL_PLANE_POSTGRES_CONNECTION_TARGET)?.toLowerCase(); | ||
| 56 | |||
| 57 | if (configuredTarget === "direct") { | ||
| 58 | return value; | ||
| 59 | } | ||
| 60 | |||
| 61 | const shouldPreferPgbouncer = | ||
| 62 | configuredTarget === "pgbouncer" | ||
| 63 | || (configuredTarget === undefined && process.env.NODE_ENV === "production"); | ||
| 64 | |||
| 65 | if (!shouldPreferPgbouncer || !isPlanetScalePostgresUrl(value)) { | ||
| 66 | return value; | ||
| 67 | } | ||
| 68 | |||
| 69 | try { | ||
| 70 | const parsed = new URL(value); | ||
| 71 | const port = parsed.port.length > 0 ? parsed.port : "5432"; | ||
| 72 | |||
| 73 | if (port !== "5432") { | ||
| 74 | return value; | ||
| 75 | } | ||
| 76 | |||
| 77 | parsed.port = "6432"; | ||
| 78 | return parsed.toString(); | ||
| 79 | } catch { | ||
| 80 | return value; | ||
| 81 | } | ||
| 82 | }; | ||
| 83 | |||
| 42 | const defaultControlPlaneStateRootDir = ".executor-v2/web-state"; | 84 | const defaultControlPlaneStateRootDir = ".executor-v2/web-state"; |
| 43 | const defaultControlPlaneDataDir = `${defaultControlPlaneStateRootDir}/control-plane-pgdata`; | 85 | const defaultControlPlaneDataDir = `${defaultControlPlaneStateRootDir}/control-plane-pgdata`; |
| 44 | 86 | ||
| @@ -75,16 +117,17 @@ const toAccountScopedIds = (subject: string) => { · 30 unmodified lines | |||
| 75 | }; | 117 | }; |
| 76 | 118 | ||
| 77 | const resolveDatabaseUrl = (): string | undefined => { | 119 | const resolveDatabaseUrl = (): string | undefined => { |
| 78 | const candidates = [ | 120 | const override = trim(process.env.CONTROL_PLANE_DATABASE_URL); |
| 79 | process.env.CONTROL_PLANE_DATABASE_URL, | 121 | if (override) { |
| 80 | process.env.DATABASE_URL, | 122 | return override; |
| 81 | process.env.POSTGRES_URL, | 123 | } |
| 82 | ]; | 124 | |
| 125 | const candidates = [process.env.DATABASE_URL, process.env.POSTGRES_URL]; | ||
| 83 | 126 | ||
| 84 | for (const candidate of candidates) { | 127 | for (const candidate of candidates) { |
| 85 | const value = trim(candidate); | 128 | const value = trim(candidate); |
| 86 | if (value) { | 129 | if (value) { |
| 87 | return value; | 130 | return deriveRuntimeDatabaseUrl(value); |
| 88 | } | 131 | } |
| 89 | } | 132 | } |
| 90 | 133 | ||