/** Cloudflare Worker entry point for the vinext-starter template. */ import { handleImageOptimization, DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES } from "vinext/server/image-optimization"; import handler from "vinext/server/app-router-entry"; import { backfillAccountProfiles } from "../lib/account-enrichment-service"; import { ensureSchema } from "../lib/mvp-db"; import { runScheduledCollections } from "../lib/collection-service"; import { resolveCollectionMcpConfig, type CollectionMcpBindings, } from "../lib/mcp-collection-client"; import type { FeishuBindings } from "../lib/feishu-client"; interface Env extends CollectionMcpBindings, FeishuBindings { ASSETS: Fetcher; DB: D1Database; UPLOADS: R2Bucket; IMAGES: { input(stream: ReadableStream): { transform(options: Record): { output(options: { format: string; quality: number }): Promise<{ response(): Response }>; }; }; }; } interface ExecutionContext { waitUntil(promise: Promise): void; passThroughOnException(): void; } interface ScheduledController { scheduledTime: number; cron: string; noRetry(): void; } // Image security config. SVG sources with .svg extension auto-skip the // optimization endpoint on the client side (served directly, no proxy). // To route SVGs through the optimizer (with security headers), set // dangerouslyAllowSVG: true in next.config.js and uncomment below: // const imageConfig: ImageConfig = { dangerouslyAllowSVG: true }; const worker = { async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise { const url = new URL(request.url); if (url.pathname === "/_vinext/image") { const allowedWidths = [...DEFAULT_DEVICE_SIZES, ...DEFAULT_IMAGE_SIZES]; return handleImageOptimization(request, { fetchAsset: (path) => env.ASSETS.fetch(new Request(new URL(path, request.url))), transformImage: async (body, { width, format, quality }) => { const result = await env.IMAGES.input(body).transform(width > 0 ? { width } : {}).output({ format, quality }); return result.response(); }, }, allowedWidths); } return handler.fetch(request, env, ctx); }, async scheduled( controller: ScheduledController, env: Env, ctx: ExecutionContext, ) { ctx.waitUntil( (async () => { await ensureSchema(env.DB); const mcpConfig = resolveCollectionMcpConfig(env); await runScheduledCollections( env.DB, controller.scheduledTime, mcpConfig, ); const accountBackfill = await backfillAccountProfiles( env.DB, mcpConfig, 10, ); console.info("KOC scheduled account backfill completed", accountBackfill); })(), ); }, }; export default worker;