diff --git a/packages/firebase-frameworks/src/next.js/index.ts b/packages/firebase-frameworks/src/next.js/index.ts index 5ab91c0c..47abeae5 100644 --- a/packages/firebase-frameworks/src/next.js/index.ts +++ b/packages/firebase-frameworks/src/next.js/index.ts @@ -1,41 +1,23 @@ import { parse } from "url"; import createNextServer from "next"; -import LRU from "lru-cache"; import type { Request } from "firebase-functions/v2/https"; import type { Response } from "express"; import type { NextServer } from "next/dist/server/next.js"; +import { incomingMessageFromExpress } from "../utils.js"; -const nextAppsLRU = new LRU({ - // TODO tune this - max: 3, - allowStale: true, - updateAgeOnGet: true, - dispose: (server) => { - server.close(); - }, +// @ts-expect-error - Next.js doesn't export the custom server function with proper types +// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment +const nextApp: NextServer = createNextServer({ + dev: false, + dir: process.cwd(), + hostname: "0.0.0.0", + port: 443, }); export const handle = async (req: Request, res: Response) => { - const { hostname, protocol, url } = req; - const port = protocol === "https" ? 443 : 80; - const key = [hostname, port].join(":"); - // I wish there was a better way to do this, but it seems like this is the - // way to go. Should investigate more if we can get hostname/port to be - // dynamic for middleware. - let nextApp = nextAppsLRU.get(key); - if (!nextApp) { - // @ts-expect-error - Next.js doesn't export the custom server function with proper types - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - nextApp = createNextServer({ - dev: false, - dir: process.cwd(), - hostname: "0.0.0.0", - port, - }); - nextAppsLRU.set(key, nextApp!); - } - await nextApp!.prepare(); - const parsedUrl = parse(url, true); - nextApp!.getRequestHandler()(req, res, parsedUrl); + await nextApp.prepare(); + const parsedUrl = parse(req.url, true); + const incomingMessage = incomingMessageFromExpress(req); + await nextApp.getRequestHandler()(incomingMessage, res, parsedUrl); }; diff --git a/packages/firebase-frameworks/src/utils.ts b/packages/firebase-frameworks/src/utils.ts index c53040c2..3f8ccba4 100644 --- a/packages/firebase-frameworks/src/utils.ts +++ b/packages/firebase-frameworks/src/utils.ts @@ -1,3 +1,7 @@ +import { Request } from "firebase-functions/v2/https"; +import { IncomingMessage } from "node:http"; +import { Socket } from "node:net"; + export async function isUsingFirebaseJsSdk() { if (!process.env.__FIREBASE_DEFAULTS__) return false; try { @@ -7,3 +11,25 @@ export async function isUsingFirebaseJsSdk() { return false; } } + +export function incomingMessageFromExpress(req: Request): IncomingMessage { + const socket = new Socket(); + const incomingMessage = new IncomingMessage(socket); + + incomingMessage.push(req.rawBody); + incomingMessage.push(null); + + incomingMessage.headers = req.headers; + incomingMessage.headersDistinct = req.headersDistinct; + incomingMessage.httpVersion = req.httpVersion; + incomingMessage.httpVersionMajor = req.httpVersionMajor; + incomingMessage.httpVersionMinor = req.httpVersionMinor; + incomingMessage.method = req.method; + incomingMessage.rawHeaders = req.rawHeaders; + incomingMessage.rawTrailers = req.rawTrailers; + incomingMessage.trailers = req.trailers; + incomingMessage.trailersDistinct = req.trailersDistinct; + incomingMessage.url = req.url; + + return incomingMessage; +}