diff --git a/apps/api/src/app/api/electric/[...path]/route.ts b/apps/api/src/app/api/electric/[...path]/route.ts index 352c60b5de9..c1cef4813c4 100644 --- a/apps/api/src/app/api/electric/[...path]/route.ts +++ b/apps/api/src/app/api/electric/[...path]/route.ts @@ -24,8 +24,23 @@ export async function GET(request: Request): Promise { return new Response("Not a member of this organization", { status: 403 }); } - const originUrl = new URL(env.ELECTRIC_URL); - originUrl.searchParams.set("secret", env.ELECTRIC_SECRET); + const useCloud = + request.headers.get("x-electric-backend") === "cloud" && + env.ELECTRIC_SOURCE_ID && + env.ELECTRIC_SOURCE_SECRET; + + const originUrl = useCloud + ? new URL("/v1/shape", "https://api.electric-sql.cloud") + : new URL(env.ELECTRIC_URL); + + if (useCloud) { + // biome-ignore lint/style/noNonNullAssertion: guarded by useCloud check above + originUrl.searchParams.set("source_id", env.ELECTRIC_SOURCE_ID!); + // biome-ignore lint/style/noNonNullAssertion: guarded by useCloud check above + originUrl.searchParams.set("source_secret", env.ELECTRIC_SOURCE_SECRET!); + } else { + originUrl.searchParams.set("secret", env.ELECTRIC_SECRET); + } url.searchParams.forEach((value, key) => { if (ELECTRIC_PROTOCOL_QUERY_PARAMS.includes(key)) { @@ -63,7 +78,7 @@ export async function GET(request: Request): Promise { const response = await fetch(originUrl.toString()); const headers = new Headers(response.headers); - headers.append("Vary", "Authorization"); + headers.append("Vary", "Authorization, X-Electric-Backend"); if (headers.get("content-encoding")) { headers.delete("content-encoding"); diff --git a/apps/api/src/env.ts b/apps/api/src/env.ts index 7c57e9ae99f..eb14866458b 100644 --- a/apps/api/src/env.ts +++ b/apps/api/src/env.ts @@ -12,6 +12,8 @@ export const env = createEnv({ DATABASE_URL_UNPOOLED: z.string(), ELECTRIC_URL: z.string().url(), ELECTRIC_SECRET: z.string().min(16), + ELECTRIC_SOURCE_ID: z.string().optional(), + ELECTRIC_SOURCE_SECRET: z.string().optional(), BLOB_READ_WRITE_TOKEN: z.string(), GOOGLE_CLIENT_ID: z.string().min(1), GOOGLE_CLIENT_SECRET: z.string().min(1), diff --git a/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts b/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts index 0c3d9776fe8..b042e87e549 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts +++ b/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts @@ -71,6 +71,7 @@ const electricHeaders = { const token = getAuthToken(); return token ? `Bearer ${token}` : ""; }, + "X-Electric-Backend": "cloud", }; const organizationsCollection = createCollection(