1import * as Cloudflare from "@/Cloudflare/index.ts";
2import * as Planetscale from "@/Planetscale/index.ts";
3import * as Effect from "effect/Effect";
4import path from "node:path";
5import { fileURLToPath } from "node:url";
6
7/**
8 * Shared PlanetScale + Cloudflare wiring used by the MySQL Hyperdrive
9 * fixture worker. A long-lived staging MySQL database (named
10 * deterministically so reruns adopt the same resource) owns a feature
11 * branch (which applies the fixture migrations) + password. The Hyperdrive
12 * config points at the password's origin.
13 */
14// This module is bundled into the worker (hyperdrive-worker.ts imports it),
15// so this also evaluates at worker startup, where the bundler leaves
16// `import.meta.url` undefined. The fallback is never read there — resource
17// props are only consumed at deploy time.
18const migrationsDir = import.meta.url
19 ? path.join(fileURLToPath(import.meta.url), "..", "migrations")
20 : ".";
21
22export const PlanetscaleDb = Effect.gen(function* () {
23 const database = yield* Planetscale.MySQLDatabase("MySQLHyperdriveTestDb", {
24 name: "alchemy-mysql-hyperdrive",
25 region: { slug: "us-east" },
26 clusterSize: "PS_10",
27 });
28
29 const branch = yield* Planetscale.MySQLBranch("MySQLHyperdriveTestBranch", {
30 database,
31 parentBranch: "main",
32 isProduction: false,
33 migrations: migrationsDir,
34 });
35
36 const password = yield* Planetscale.MySQLPassword(
37 "MySQLHyperdriveTestPassword",
38 {
39 database,
40 branch,
41 role: "admin",
42 },
43 );
44
45 return { database, branch, password };
46});
47
48export const Hyperdrive = Effect.gen(function* () {
49 const { password } = yield* PlanetscaleDb;
50 return yield* Cloudflare.Hyperdrive.Connection("MySQLHyperdriveTestEdge", {
51 origin: password.origin,
52 // The test asserts read-your-writes across separate HTTP requests;
53 // Hyperdrive's query cache (60s default) would serve stale SELECTs.
54 caching: { disabled: true },
55 });
56});