1import * as Fly from "@/Fly";
2import * as Test from "@/Test/Alchemy";
3import { describe, expect } from "alchemy-test";
4import * as Effect from "effect/Effect";
5import * as pathe from "pathe";
6import { prepareNextjsFixture } from "../../Cloudflare/Website/TypeScriptCompat.ts";
7import { cloneFixture } from "../../Cloudflare/Utils/Fixture.ts";
8import { expectUrlContains } from "../../Cloudflare/Utils/Http.ts";
9
10const { test } = Test.make({ providers: Fly.providers(), dev: true });
11
12const fixtureDir = pathe.resolve(
13 import.meta.dirname,
14 "../../AWS/Website/fixtures/nextjs-app",
15);
16const fixtureEntries = [
17 ".gitignore",
18 "package.json",
19 "next.config.ts",
20 "tsconfig.json",
21 "app",
22 "public",
23];
24
25describe(
26 "Fly.Website.Nextjs local",
27 { tags: ["provider:fly", "provider:fly:website", "local"] },
28 () => {
29 test.provider(
30 "dev runs the framework server with no cloud resources",
31 (stack) =>
32 Effect.gen(function* () {
33 yield* stack.destroy();
34
35 // Clone OUTSIDE the repo (OS temp dir): an in-workspace clone makes
36 // Next treat the alchemy monorepo as the workspace root and look up
37 // the root's typescript (catalog:build = tsgo).
38 const rootDir = yield* cloneFixture(fixtureDir, {
39 prefix: "alchemy-nextjs-fly-local-",
40 entries: fixtureEntries,
41 });
42 yield* prepareNextjsFixture(rootDir);
43
44 const deployed = yield* stack.deploy(
45 Effect.gen(function* () {
46 const site = yield* Fly.Website.Nextjs("Web", {
47 rootDir,
48 });
49 return { site };
50 }),
51 );
52
53 const url = deployed.site.url;
54 expect(url).toMatch(/^http:\/\/(localhost|127\.0\.0\.1):\d+\/?$/);
55 expect(deployed.site.service).toBeUndefined();
56 expect(deployed.site.app).toBeUndefined();
57 expect(deployed.site.ip).toBeUndefined();
58
59 yield* expectUrlContains(`${url}/`, "NEXTJS_AWS_PAGE_MARKER", {
60 timeout: "180 seconds",
61 label: "dev home page",
62 });
63 yield* expectUrlContains(
64 `${url}/api/hello?echo=roundtrip`,
65 "NEXTJS_AWS_API_MARKER",
66 { label: "api route (dev)" },
67 );
68 yield* expectUrlContains(
69 `${url}/static`,
70 "NEXTJS_AWS_STATIC_MARKER",
71 {
72 label: "extra route (dev)",
73 },
74 );
75
76 yield* stack.destroy();
77 }),
78 { timeout: 600_000 },
79 );
80 },
81);