diff --git a/.changeset/itchy-oranges-relate.md b/.changeset/itchy-oranges-relate.md new file mode 100644 index 000000000000..4d20d975fc82 --- /dev/null +++ b/.changeset/itchy-oranges-relate.md @@ -0,0 +1,5 @@ +--- +"@astrojs/vercel": minor +--- + +The special-case handling of `src/vercel-edge-middleware.js` file is now deprecated. This file allowed you to access the edge runtime's `RequestContext` object, and create the middleware `locals` from its fields. However, this object includes only one field - the `waitUntil()` function - which is now available directly as `ctx.locals.vercel.edge.waitUntil()`. diff --git a/packages/integrations/vercel/package.json b/packages/integrations/vercel/package.json index f2ab0f818afa..36e6d7fe182f 100644 --- a/packages/integrations/vercel/package.json +++ b/packages/integrations/vercel/package.json @@ -17,6 +17,7 @@ "bugs": "https://github.com/withastro/astro/issues", "homepage": "https://docs.astro.build/en/guides/integrations-guide/vercel/", "exports": { + ".": { "types": "./types.d.ts" }, "./serverless": "./dist/serverless/adapter.js", "./serverless/entrypoint": "./dist/serverless/entrypoint.js", "./static": "./dist/static/adapter.js", @@ -28,9 +29,6 @@ }, "typesVersions": { "*": { - "edge": [ - "dist/edge/adapter.d.ts" - ], "serverless": [ "dist/serverless/adapter.d.ts" ], @@ -40,7 +38,8 @@ } }, "files": [ - "dist" + "dist", + "types.d.ts" ], "scripts": { "build": "astro-scripts build \"src/**/*.ts\" && tsc", @@ -52,6 +51,7 @@ "dependencies": { "@astrojs/internal-helpers": "workspace:*", "@vercel/analytics": "^1.0.2", + "@vercel/edge": "^1.1.1", "@vercel/nft": "^0.26.4", "esbuild": "^0.19.6", "fast-glob": "^3.3.2", @@ -63,7 +63,6 @@ }, "devDependencies": { "@types/set-cookie-parser": "^2.4.6", - "@vercel/edge": "^1.1.1", "astro": "workspace:*", "astro-scripts": "workspace:*", "cheerio": "1.0.0-rc.12" diff --git a/packages/integrations/vercel/src/serverless/adapter.ts b/packages/integrations/vercel/src/serverless/adapter.ts index 2cb35a51773a..bb7d9f43738c 100644 --- a/packages/integrations/vercel/src/serverless/adapter.ts +++ b/packages/integrations/vercel/src/serverless/adapter.ts @@ -498,7 +498,8 @@ class VercelBuilder { entry, new URL(VERCEL_EDGE_MIDDLEWARE_FILE, this.config.srcDir), new URL('./middleware.mjs', functionFolder), - middlewareSecret + middlewareSecret, + this.logger ); await writeJson(new URL(`./.vc-config.json`, functionFolder), { diff --git a/packages/integrations/vercel/src/serverless/middleware.ts b/packages/integrations/vercel/src/serverless/middleware.ts index 1875cce00493..0518f6842d90 100644 --- a/packages/integrations/vercel/src/serverless/middleware.ts +++ b/packages/integrations/vercel/src/serverless/middleware.ts @@ -7,6 +7,7 @@ import { ASTRO_PATH_HEADER, NODE_PATH, } from './adapter.js'; +import type { AstroIntegrationLogger } from 'astro'; /** * It generates the Vercel Edge Middleware file. @@ -23,12 +24,14 @@ export async function generateEdgeMiddleware( astroMiddlewareEntryPointPath: URL, vercelEdgeMiddlewareHandlerPath: URL, outPath: URL, - middlewareSecret: string + middlewareSecret: string, + logger: AstroIntegrationLogger ): Promise { const code = edgeMiddlewareTemplate( astroMiddlewareEntryPointPath, vercelEdgeMiddlewareHandlerPath, - middlewareSecret + middlewareSecret, + logger ); // https://vercel.com/docs/concepts/functions/edge-middleware#create-edge-middleware const bundledFilePath = fileURLToPath(outPath); @@ -64,7 +67,8 @@ export async function generateEdgeMiddleware( function edgeMiddlewareTemplate( astroMiddlewareEntryPointPath: URL, vercelEdgeMiddlewareHandlerPath: URL, - middlewareSecret: string + middlewareSecret: string, + logger: AstroIntegrationLogger ) { const middlewarePath = JSON.stringify( fileURLToPath(astroMiddlewareEntryPointPath).replace(/\\/g, '/') @@ -73,6 +77,7 @@ function edgeMiddlewareTemplate( let handlerTemplateImport = ''; let handlerTemplateCall = '{}'; if (existsSync(filePathEdgeMiddleware + '.js') || existsSync(filePathEdgeMiddleware + '.ts')) { + logger.warn('Usage of `vercel-edge-middleware.js` is deprecated. You can now use the `waitUntil(promise)` function directly as `ctx.locals.waitUntil(promise)`.') const stringified = JSON.stringify(filePathEdgeMiddleware.replace(/\\/g, '/')); handlerTemplateImport = `import handler from ${stringified}`; handlerTemplateCall = `await handler({ request, context })`; @@ -87,17 +92,19 @@ export default async function middleware(request, context) { request, params: {} }); - ctx.locals = ${handlerTemplateCall}; + ctx.locals = { vercel: { edge: context }, ...${handlerTemplateCall} }; const { origin } = new URL(request.url); - const next = () => - fetch(new URL('/${NODE_PATH}', request.url), { + const next = () => { + const { vercel, ...locals } = ctx.locals; + return fetch(new URL('/${NODE_PATH}', request.url), { headers: { ...Object.fromEntries(request.headers.entries()), '${ASTRO_MIDDLEWARE_SECRET_HEADER}': '${middlewareSecret}', '${ASTRO_PATH_HEADER}': request.url.replace(origin, ''), - '${ASTRO_LOCALS_HEADER}': trySerializeLocals(ctx.locals) + '${ASTRO_LOCALS_HEADER}': trySerializeLocals(locals) } }) + } return onRequest(ctx, next); }`; diff --git a/packages/integrations/vercel/types.d.ts b/packages/integrations/vercel/types.d.ts new file mode 100644 index 000000000000..bde81aa7a0d3 --- /dev/null +++ b/packages/integrations/vercel/types.d.ts @@ -0,0 +1,5 @@ +export interface EdgeLocals { + vercel: { + edge: import("@vercel/edge").RequestContext; + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f520ad8430f3..177c099ed189 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4925,6 +4925,9 @@ importers: '@vercel/analytics': specifier: ^1.0.2 version: 1.2.2 + '@vercel/edge': + specifier: ^1.1.1 + version: 1.1.1 '@vercel/nft': specifier: ^0.26.4 version: 0.26.4 @@ -4944,9 +4947,6 @@ importers: '@types/set-cookie-parser': specifier: ^2.4.6 version: 2.4.7 - '@vercel/edge': - specifier: ^1.1.1 - version: 1.1.1 astro: specifier: workspace:* version: link:../../astro @@ -8357,7 +8357,7 @@ packages: /@vercel/edge@1.1.1: resolution: {integrity: sha512-NtKiIbn9Cq6HWGy+qRudz28mz5nxfOJWls5Pnckjw1yCfSX8rhXdvY/il3Sy3Zd5n/sKCM2h7VSCCpJF/oaDrQ==} - dev: true + dev: false /@vercel/nft@0.26.4: resolution: {integrity: sha512-j4jCOOXke2t8cHZCIxu1dzKLHLcFmYzC3yqAK6MfZznOL1QIJKd0xcFsXK3zcqzU7ScsE2zWkiMMNHGMHgp+FA==}