1import { cloudflare } from "@octanejs/adapter-cloudflare";
2import { defineConfig, RenderRoute, ServerRoute } from "@octanejs/vite-plugin";
3
4/**
5 * The Cloudflare request context the adapter forwards as `context.platform`
6 * in production (`{ env, ctx }`). In dev, Octane's Vite middleware supplies
7 * no platform (upstream limitation), so handlers tolerate `undefined`.
8 */
9interface KvBinding {
10 get(key: string): Promise<string | null>;
11 put(key: string, value: string): Promise<void>;
12}
13
14interface Platform {
15 readonly env?: {
16 readonly TEST_BINDING?: string;
17 readonly SITE_KV?: KvBinding;
18 };
19 readonly ctx?: { readonly waitUntil?: unknown };
20}
21
22export default defineConfig({
23 adapter: cloudflare(),
24 router: {
25 routes: [
26 new ServerRoute({
27 path: "/api/hello",
28 methods: ["GET"],
29 handler: (context) => {
30 const platform = context.platform as Platform | undefined;
31 return Response.json({
32 marker: "api-route-ok",
33 binding: platform?.env?.TEST_BINDING ?? null,
34 hasWaitUntil: typeof platform?.ctx?.waitUntil === "function",
35 });
36 },
37 }),
38 new ServerRoute({
39 path: "/api/kv",
40 methods: ["GET", "PUT"],
41 handler: async (context) => {
42 const platform = context.platform as Platform | undefined;
43 const kv = platform?.env?.SITE_KV;
44 const key = context.url.searchParams.get("key") ?? "";
45 if (kv === undefined || key === "") {
46 return Response.json({ error: "no kv or key" }, { status: 500 });
47 }
48 if (context.request.method === "PUT") {
49 const value = context.url.searchParams.get("value") ?? "";
50 await kv.put(key, value);
51 return Response.json({ put: true, key });
52 }
53 return Response.json({ key, value: await kv.get(key) });
54 },
55 }),
56 new RenderRoute({ path: "/", entry: ["App", "/src/App.tsx"] }),
57 ],
58 },
59});