1import * as Effect from "effect/Effect";
2import * as HttpClient from "effect/http/HttpClient";
3import * as HttpClientRequest from "effect/http/HttpClientRequest";
4import { exportDatabase } from "./ExportDatabase.ts";
5import { importD1Database } from "./ImportDatabase.ts";
6
7export interface CloneDatabaseOptions {
8 accountId: string;
9 sourceDatabaseId: string;
10 targetDatabaseId: string;
11}
12
13/**
14 * Clone a D1 database by exporting from the source and importing into the
15 * target. Fetches the SQL dump from the export's signed URL and streams the
16 * payload through the import flow.
17 */
18export const cloneDatabase = (options: CloneDatabaseOptions) =>
19 Effect.gen(function* () {
20 const exportResult = yield* exportDatabase({
21 accountId: options.accountId,
22 databaseId: options.sourceDatabaseId,
23 });
24
25 const client = yield* HttpClient.HttpClient;
26 const dumpRes = yield* client
27 .execute(HttpClientRequest.get(exportResult.signedUrl))
28 .pipe(Effect.orDie);
29 if (dumpRes.status < 200 || dumpRes.status >= 300) {
30 return yield* Effect.die(
31 `Failed to fetch D1 export dump (${dumpRes.status})`,
32 );
33 }
34 const sqlData = yield* dumpRes.text.pipe(Effect.orDie);
35
36 return yield* importD1Database({
37 accountId: options.accountId,
38 databaseId: options.targetDatabaseId,
39 sqlData,
40 filename: exportResult.filename,
41 });
42 });