1import * as machines from "@distilled.cloud/fly-io/machines";
2import * as Fly from "@/Fly";
3import * as Test from "@/Test/Alchemy";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import { MinimumLogLevel } from "effect/References";
7import * as Schedule from "effect/Schedule";
8import * as pathe from "pathe";
9import { cloneFixture } from "../../Cloudflare/Utils/Fixture.ts";
10import { expectUrlContains } from "../../Cloudflare/Utils/Http.ts";
11
12const { test } = Test.make({ providers: Fly.providers() });
13
14const logLevel = Effect.provideService(
15 MinimumLogLevel,
16 process.env.DEBUG ? "Debug" : "Info",
17);
18
19const fixtureDir = pathe.resolve(
20 import.meta.dirname,
21 "../../AWS/Website/fixtures/nuxt-app",
22);
23const tempRoot = pathe.resolve(import.meta.dirname, "../../../.tmp");
24const fixtureEntries = [
25 ".gitignore",
26 "package.json",
27 "nuxt.config.ts",
28 "app",
29 "server",
30 "public",
31];
32
33const waitUntilGone = (appName: string) =>
34 machines.getApp({ app_name: appName }).pipe(
35 Effect.as("found" as const),
36 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
37 Effect.repeat({
38 schedule: Schedule.spaced("1 second"),
39 until: (status) => status === "gone",
40 times: 10,
41 }),
42 );
43
44test.provider(
45 "Nuxt: deploy, GET /, destroy, gone",
46 (stack) =>
47 Effect.gen(function* () {
48 yield* stack.destroy();
49
50 const rootDir = yield* cloneFixture(fixtureDir, {
51 prefix: "alchemy-nuxt-fly-",
52 tempRoot,
53 entries: fixtureEntries,
54 });
55
56 const deployed = yield* stack.deploy(
57 Effect.gen(function* () {
58 const site = yield* Fly.Website.Nuxt("Web", {
59 rootDir,
60 memo: {
61 include: [
62 "app/**",
63 "server/**",
64 "public/**",
65 "package.json",
66 "nuxt.config.ts",
67 ],
68 },
69 });
70 return { site };
71 }),
72 );
73
74 const url = deployed.site.url;
75 expect(url).toBeDefined();
76 expect(url).toMatch(/^https:\/\//);
77 expect(deployed.site.service).toBeDefined();
78 expect(deployed.site.app).toBeDefined();
79
80 yield* expectUrlContains(`${url!}/`, "NUXT_AWS_PAGE_MARKER", {
81 timeout: "90 seconds",
82 label: "home page",
83 });
84 yield* expectUrlContains(
85 `${url!}/api/hello?echo=roundtrip`,
86 "NUXT_AWS_API_MARKER",
87 {
88 timeout: "30 seconds",
89 label: "api route",
90 },
91 );
92 yield* expectUrlContains(
93 `${url!}/prerendered`,
94 "NUXT_AWS_PRERENDERED_MARKER",
95 {
96 timeout: "30 seconds",
97 label: "extra route",
98 },
99 );
100
101 const appName = deployed.site.app!.appName;
102 yield* stack.destroy();
103 const gone = yield* waitUntilGone(appName);
104 expect(gone).toEqual("gone");
105 }).pipe(logLevel),
106 {
107 tags: [
108 "provider:fly",
109 "provider:fly:machine",
110 "provider:fly:website",
111 "live",
112 ],
113 timeout: 240000,
114 },
115);