1import * as Fly from "@/Fly";
2import { describe, expect, it } from "alchemy-test";
3
4/**
5 * Compile-time pins for Fly.Website prop surfaces. Fail the build if
6 * dissolved 1353 bags sneak back in as flat keys, or if `spa`/`errorPage`
7 * sugar returns.
8 */
9describe(
10 "Fly.Website prop surfaces",
11 { tags: ["unit", "provider:fly", "provider:fly:website", "local"] },
12 () => {
13 const _pins = [
14 () =>
15 Fly.Website.Vinext("Vinext", {
16 rootDir: "./app",
17 env: { GREETING: "Hello" },
18 memo: { lockfile: true },
19 assets: { notFoundHandling: "404-page" },
20 dev: {},
21 domain: "app.example.com",
22 }),
23 () =>
24 Fly.Website.Vite("V", {
25 deploy: { strategy: "bluegreen", healthTimeout: "90 seconds" },
26 shutdown: { timeout: "30 seconds" },
27 checks: { ready: { type: "http", port: 3000, path: "/health" } },
28 services: [],
29 assets: { notFoundHandling: "single-page-application" },
30 vite: { outDir: "build", base: "/docs/" },
31 }),
32 () =>
33 Fly.Website.Vite("V", {
34 // @ts-expect-error spa sugar replaced by assets.notFoundHandling
35 spa: true,
36 }),
37 () =>
38 Fly.Website.Vite("V", {
39 // @ts-expect-error outDir lives on the vite bag
40 outDir: "build",
41 }),
42 () =>
43 Fly.Website.Waku("W", {
44 waku: { srcDir: "app", distDir: "build", basePath: "/docs/" },
45 }),
46 () =>
47 Fly.Website.Waku("W", {
48 // @ts-expect-error srcDir lives on the waku bag
49 srcDir: "app",
50 }),
51 () =>
52 Fly.Website.Astro("A", {
53 astro: { output: "static" },
54 assets: { notFoundHandling: "404-page" },
55 }),
56 () =>
57 Fly.Website.Astro("A", {
58 // @ts-expect-error spa sugar replaced by assets.notFoundHandling
59 spa: true,
60 }),
61 () =>
62 Fly.Website.Nuxt("N", {
63 nuxt: { app: { baseURL: "/docs/" } },
64 }),
65 () =>
66 Fly.Website.SvelteKit("S", {
67 kit: { paths: { base: "/docs" } },
68 deploy: { strategy: "bluegreen", healthTimeout: "90 seconds" },
69 shutdown: { signal: "SIGINT", timeout: "60 seconds" },
70 checks: { ready: { type: "http", port: 3000, path: "/ready" } },
71 services: [],
72 }),
73 () =>
74 Fly.Website.Nextjs("N", {
75 deploy: { strategy: "rolling" },
76 shutdown: { signal: "SIGTERM", timeout: "10 seconds" },
77 checks: { ready: { type: "http", port: 3000, path: "/ready" } },
78 services: [],
79 }),
80 () =>
81 Fly.Website.SolidStart("So", {
82 nitro: { prerender: { routes: ["/"] } },
83 }),
84 () => Fly.Website.ReactRouter("R", {}),
85 () => Fly.Website.TanStackStart("T", {}),
86 () =>
87 Fly.Website.Foldkit("F", {
88 assets: { notFoundHandling: "404-page" },
89 }),
90 () =>
91 Fly.Website.StaticSite("St", {
92 build: { command: "hugo --minify", output: "public" },
93 deploy: { strategy: "bluegreen" },
94 shutdown: { signal: "SIGTERM" },
95 checks: { ready: { type: "tcp", port: 3000 } },
96 services: [],
97 assets: { notFoundHandling: "single-page-application" },
98 }),
99 () =>
100 Fly.Website.StaticSite("St", {
101 build: { command: "npm run build", output: "dist" },
102 // @ts-expect-error command is nested under build
103 command: "npm run build",
104 }),
105 ];
106
107 it("rejects dissolved 1353 props at the type level", () => {
108 expect(_pins.length).toBeGreaterThan(0);
109 });
110 },
111);