diff --git a/src/presets/cloudflare/runtime/cloudflare-module.ts b/src/presets/cloudflare/runtime/cloudflare-module.ts index 4cf420823b..910f21fc93 100644 --- a/src/presets/cloudflare/runtime/cloudflare-module.ts +++ b/src/presets/cloudflare/runtime/cloudflare-module.ts @@ -13,6 +13,8 @@ import { mapRequestToAsset, } from "@cloudflare/kv-asset-handler"; +import type { CloudflareEmailContext, CloudflareMessageBatch } from "../types"; + // @ts-ignore Bundled by Wrangler // See https://github.com/cloudflare/kv-asset-handler#asset_manifest-required-for-es-modules import manifest from "__STATIC_CONTENT_MANIFEST"; @@ -99,6 +101,28 @@ export default { ); } }, + + email( + event: CloudflareEmailContext, + env: CFModuleEnv, + context: ExecutionContext + ) { + (globalThis as any).__env__ = env; + context.waitUntil( + nitroApp.hooks.callHook("cloudflare:email", { event, env, context }) + ); + }, + + queue( + event: CloudflareEmailContext, + env: CFModuleEnv, + context: ExecutionContext + ) { + (globalThis as any).__env__ = env; + context.waitUntil( + nitroApp.hooks.callHook("cloudflare:queue", { event, env, context }) + ); + }, }; function assetsCacheControl(_request: Request) { diff --git a/src/presets/cloudflare/types.ts b/src/presets/cloudflare/types.ts index 25a70665e2..b8176c30e0 100644 --- a/src/presets/cloudflare/types.ts +++ b/src/presets/cloudflare/types.ts @@ -1,4 +1,5 @@ import type { Config as WranglerConfig } from "./types.wrangler"; +import type { ExecutionContext } from "@cloudflare/workers-types"; /** * https://developers.cloudflare.com/pages/platform/functions/routing/#functions-invocation-routes @@ -50,3 +51,50 @@ export interface CloudflareOptions { defaultRoutes?: boolean; }; } + +/** @experimental */ +export interface CloudflareEmailContext { + readonly from?: string; + readonly to?: string; + readonly headers?: Headers; + readonly raw?: ReadableStream; + readonly rawSize?: number; + + setReject?(reason: string): void; + forward?(rcptTo: string, headers?: Headers): Promise; + reply?(message: CloudflareEmailContext): Promise; +} + +export interface CloudflareQueueRetryOptions { + delaySeconds?: number; +} + +export interface CloudflareMessageBody { + readonly id: string; + readonly timestamp: Date; + readonly body: Body; + adk(): void; + retry(options?: CloudflareQueueRetryOptions): void; +} + +export interface CloudflareMessageBatch { + readonly queue: string; + readonly messages: CloudflareMessageBody[]; + ackAll(): void; + retryAll(options?: CloudflareQueueRetryOptions): void; +} + +declare module "nitropack/types" { + export interface NitroRuntimeHooks { + "cloudflare:email": (_: { + event: CloudflareEmailContext; + env: any; + context: ExecutionContext; + }) => void; + "cloudflare:queue": (_: { + event: CloudflareEmailContext; + env: any; + context: ExecutionContext; + }) => void; + } +}