UNPKG

@aziontech/opennextjs-azion

Version:
93 lines (92 loc) 3.98 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ /** * This code was originally copied and modified from the @opennextjs/cloudflare repository. * Significant changes have been made to adapt it for use with Azion. */ //@ts-expect-error: Will be resolved by wrangler build import { runWithAzionRequestContext } from "./azion/init.js"; // Azion Storage API // TODO: future receive from azion env const bucketName = globalThis?.AZION_BUCKET_NAME ?? ""; const bucketPrefix = globalThis?.AZION_BUCKET_PREFIX ?? ""; const InstanceStorage = new globalThis.Azion.Storage(bucketName); export default { async fetch(request, env, ctx) { // SET env env = { ...env, AZION: { BUCKET_NAME: bucketName, BUCKET_PREFIX: bucketPrefix, CACHE_API_STORAGE_NAME: globalThis.AZION_CACHE_API_STORAGE_NAME ?? "nextjs_cache", Storage: InstanceStorage, }, // TODO: future receive from azion env ASSETS: { fetch: getStorageAsset, }, WORKER_SELF_REFERENCE: { fetch: async (url, options) => { const requestRef = new Request(url, options); return requestHandler(requestRef, env, ctx); }, }, }; return runWithAzionRequestContext(request, env, ctx, async () => { return requestHandler(request, env, ctx); }); }, }; const requestHandler = async (request, env, ctx) => { const url = new URL(request.url); // Serve images in development. // Note: "/data-cache/image/..." requests do not reach production workers. // TODO: make support for this if (url.pathname.startsWith("/data-cache/image/")) { const m = url.pathname.match(/\/data-cache\/image\/.+?\/(?<url>.+)$/); if (m === null) { return new Response("Not Found!", { status: 404 }); } const imageUrl = m.groups.url; return imageUrl.match(/^https?:\/\//) ? fetch(imageUrl) : env.ASSETS?.fetch(new URL(`/${imageUrl}`, url)); } // Fallback for the Next default image loader. if (url.pathname === "/_next/image") { const imageUrl = url.searchParams.get("url") ?? ""; return imageUrl.startsWith("/") ? env.ASSETS?.fetch(new URL(imageUrl, request.url)) : fetch(imageUrl); } // static assets if (url.pathname.startsWith("/_next/")) { return env.ASSETS?.fetch(request); } // This necessary to local server const assetRegex = /\.(css|js|ttf|woff|woff2|otf|eot|svg|jpg|jpeg|gif|bmp|png|ico|webp|avif|heic|heif|tiff|tif|mp4|webm|avi|mov|wmv|flv|m4v|mkv|ogv|mp3|wav|ogg|m4a|aac|flac|opus|pdf|json|xml|zip|rar|tar|gz)$/; if (url.pathname.match(assetRegex)) { if (url.pathname.includes(".devtools.json")) { return new Response("ok", { status: 200 }); } return env.ASSETS?.fetch(request); } // - `Request`s are handled by the Next server // @ts-expect-error: resolved by bundler build const { handler: middlewareModule } = await import("./middleware/handler.mjs"); const cloneRequest = request.clone(); const reqOrResp = await middlewareModule(cloneRequest, env, ctx); if (reqOrResp instanceof Response) { return reqOrResp; } // @ts-expect-error: resolved by bundler build const { handler } = await import("./server-functions/default/handler.mjs"); return handler(reqOrResp, env, ctx); }; const getStorageAsset = async (request) => { try { const urlString = request instanceof Request ? request.url : request.toString(); const requestPath = decodeURIComponent(new URL(urlString).pathname); const assetUrl = new URL(requestPath === "/" ? "index.html" : requestPath, "file://"); return fetch(assetUrl); } catch (e) { return new Response(e.message || e.toString(), { status: 404 }); } };