1import * as Prisma from "@/Prisma/index.ts";
2import * as Test from "@/Test/Alchemy.ts";
3import { getProject, getService } from "@distilled.cloud/prisma/management";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import * as FileSystem from "effect/FileSystem";
7import * as Path from "effect/Path";
8import * as HttpClient from "effect/http/HttpClient";
9import { bodyContaining, copyViteFixture } from "./Fixture.ts";
10
11const { test } = Test.make({ providers: Prisma.providers() });
12
13test.provider.skipIf(process.env.ALCHEMY_RUN_LIVE_PRISMA_TESTS !== "true")(
14 "Vite publishes real builds, memoizes unchanged content, updates in place, and cleans up",
15 (stack) =>
16 Effect.gen(function* () {
17 yield* stack.destroy();
18 const fs = yield* FileSystem.FileSystem;
19 const path = yield* Path.Path;
20 const rootDir = yield* copyViteFixture;
21 const deploy = (
22 fallback:
23 | "single-page-application"
24 | "none" = "single-page-application",
25 ) =>
26 stack.deploy(
27 Prisma.Website.Vite("Web", {
28 rootDir,
29 assets: { notFoundHandling: fallback },
30 vite: { outDir: "build" },
31 memo: { include: ["index.html", "main.ts", "package.json"] },
32 }).pipe(Effect.map((site) => ({ site }))),
33 );
34 const initial = (yield* deploy()).site;
35 expect(initial.url).toMatch(/^https:\/\//);
36 const projectId = initial.compute!.projectId;
37 const appId = initial.compute!.appId;
38 yield* bodyContaining(
39 `${initial.url}/client/route`,
40 "Prisma Website fixture",
41 );
42 yield* bodyContaining(`${initial.url}/health`, "ok");
43 const unchanged = (yield* deploy()).site;
44 expect(unchanged.compute!.deploymentId).toBe(
45 initial.compute!.deploymentId,
46 );
47 const indexPath = path.join(rootDir, "index.html");
48 const index = yield* fs.readFileString(indexPath);
49 yield* fs.writeFileString(
50 indexPath,
51 index.replaceAll("Prisma Website fixture", "Prisma Website updated"),
52 );
53 const updated = (yield* deploy("none")).site;
54 expect(updated.compute!.appId).toBe(appId);
55 expect(updated.compute!.projectId).toBe(projectId);
56 expect(updated.compute!.deploymentId).not.toBe(
57 initial.compute!.deploymentId,
58 );
59 yield* bodyContaining(`${updated.url}/`, "Prisma Website updated");
60 const missing = yield* HttpClient.get(
61 `${updated.url}/missing-client-route`,
62 );
63 expect(missing.status).toBe(404);
64 yield* stack.destroy();
65 expect(
66 yield* getService({ serviceId: appId }).pipe(
67 Effect.as(false),
68 Effect.catchTag("NotFound", () => Effect.succeed(true)),
69 ),
70 ).toBe(true);
71 expect(
72 yield* getProject({ id: projectId }).pipe(
73 Effect.as(false),
74 Effect.catchTag("NotFound", () => Effect.succeed(true)),
75 ),
76 ).toBe(true);
77 }).pipe(Effect.scoped),
78 {
79 tags: ["provider:prisma", "provider:prisma:website", "live"],
80 timeout: 120_000,
81 },
82);