muddle/adapters/cloudflare-wrangler.ts
2026-10-23 08:53:07 -04:00

53 lines
1.6 KiB
TypeScript

import type { App } from "../core/app.ts";
import { existsSync } from "node:fs";
import { writeFile } from "node:fs/promises";
import { join, resolve } from "node:path";
export interface WorkerEnv {
[key: string]: unknown;
}
export interface WorkerContext {
waitUntil(promise: Promise<unknown>): void;
passThroughOnException?(): void;
}
export interface WorkerOptions {
/** Builds the application from the bindings of the worker. */
create?: (env: WorkerEnv) => App | Promise<App>;
}
export interface WranglerSetupOptions {
name?: string;
main?: string;
compatibilityDate?: string;
}
/** Creates a minimal Wrangler config when a project has not supplied one. */
export async function setupWrangler(root: string, options: WranglerSetupOptions = {}): Promise<string> {
const path = join(resolve(root), "wrangler.jsonc");
if (existsSync(path)) return path;
const source = JSON.stringify({ name: options.name ?? "muddle-app", main: options.main ?? "src/worker.ts", compatibility_date: options.compatibilityDate ?? "2026-10-22" }, null, 2).concat("\n");
await writeFile(path, source, "utf8");
return path;
}
/** Creates the fetch handler of a worker. */
export function createWorker(app: App | WorkerOptions["create"]): {
fetch(
request: Request,
env: WorkerEnv,
ctx: WorkerContext,
): Promise<Response>;
} {
let instance: App | undefined = typeof app === "function" ? undefined : app;
return {
async fetch(request: Request, env: WorkerEnv, _ctx: WorkerContext) {
if (!instance) {
instance = await (app as (env: WorkerEnv) => Promise<App>)(env);
}
return instance.fetch(request);
},
};
}