1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import { expect } from "alchemy-test";
4import * as Effect from "effect/Effect";
5import { cloneFixture } from "../../Cloudflare/Utils/Fixture.ts";
6import { expectUrlContains } from "../../Cloudflare/Utils/Http.ts";
7import { prepareNextjsFixture } from "../../Cloudflare/Website/TypeScriptCompat.ts";
8import { dockerAvailable } from "../bindingHost.ts";
9import {
10 assertSiteGone,
11 awsFixture,
12 cloudRunUrl,
13 liveOptions,
14 logLevel,
15 serviceIdentity,
16} from "./site.ts";
17
18const { test } = Test.make({ providers: GCP.providers() });
19
20const fixtureDir = awsFixture("nextjs-app");
21const fixtureEntries = [
22 ".gitignore",
23 "package.json",
24 "next.config.ts",
25 "tsconfig.json",
26 "app",
27 "public",
28];
29
30test.provider.skipIf(!dockerAvailable)(
31 "Nextjs: deploy, GET page, API and static routes, destroy, gone",
32 (stack) =>
33 Effect.gen(function* () {
34 yield* stack.destroy();
35
36 // Clone outside the repo: an in-workspace clone makes Next treat the
37 // monorepo as the workspace root and pick up the root's typescript.
38 const rootDir = yield* cloneFixture(fixtureDir, {
39 prefix: "alchemy-nextjs-gcp-",
40 entries: fixtureEntries,
41 });
42 yield* prepareNextjsFixture(rootDir);
43
44 const deployed = yield* stack.deploy(
45 Effect.gen(function* () {
46 const site = yield* GCP.Website.Nextjs("Web", {
47 rootDir,
48 memo: {
49 include: [
50 "app/**",
51 "public/**",
52 "package.json",
53 "next.config.ts",
54 "tsconfig.json",
55 ],
56 },
57 });
58 return { site };
59 }),
60 );
61
62 const url = deployed.site.url as string;
63 expect(url).toMatch(cloudRunUrl);
64 expect(deployed.site.service).toBeDefined();
65 const service = serviceIdentity(deployed.site.service!);
66
67 yield* expectUrlContains(`${url}/`, "NEXTJS_AWS_PAGE_MARKER", {
68 timeout: "180 seconds",
69 label: "Nextjs /",
70 });
71 yield* expectUrlContains(
72 `${url}/api/hello?echo=roundtrip`,
73 "NEXTJS_AWS_API_MARKER",
74 {
75 timeout: "30 seconds",
76 label: "Nextjs /api/hello?echo=roundtrip",
77 },
78 );
79 yield* expectUrlContains(`${url}/static`, "NEXTJS_AWS_STATIC_MARKER", {
80 timeout: "30 seconds",
81 label: "Nextjs /static",
82 });
83
84 yield* stack.destroy();
85 yield* assertSiteGone(service);
86 }).pipe(logLevel),
87 liveOptions(1_200_000),
88);