fix(vercel): support vercel.json redirects and rewrites

This commit is contained in:
Nate Moore 2023-03-13 14:13:10 -05:00
parent 87d5e96da4
commit 7dd7928003
6 changed files with 42 additions and 12 deletions

View file

@ -0,0 +1,5 @@
---
'@astrojs/vercel': minor
---
Support `vercel.json` redirects and rewrites using Build Output API

View file

@ -48,6 +48,7 @@
"@astrojs/webapi": "^2.1.0", "@astrojs/webapi": "^2.1.0",
"@vercel/analytics": "^0.1.8", "@vercel/analytics": "^0.1.8",
"@vercel/nft": "^0.22.1", "@vercel/nft": "^0.22.1",
"@vercel/routing-utils": "^2.1.10",
"fast-glob": "^3.2.11", "fast-glob": "^3.2.11",
"set-cookie-parser": "^2.5.1", "set-cookie-parser": "^2.5.1",
"web-vitals": "^3.1.1" "web-vitals": "^3.1.1"

View file

@ -11,6 +11,7 @@ import {
removeDir, removeDir,
writeJson, writeJson,
} from '../lib/fs.js'; } from '../lib/fs.js';
import { getRoutesFromVercelJSON } from '../lib/vercel-config.js';
import { getRedirects } from '../lib/redirects.js'; import { getRedirects } from '../lib/redirects.js';
const PACKAGE_NAME = '@astrojs/vercel/edge'; const PACKAGE_NAME = '@astrojs/vercel/edge';
@ -119,11 +120,14 @@ export default function vercelEdge({
entrypoint: relativePath(commonAncestor, entryPath), entrypoint: relativePath(commonAncestor, entryPath),
}); });
const userRoutes = await getRoutesFromVercelJSON(_config)
// Output configuration // Output configuration
// https://vercel.com/docs/build-output-api/v3#build-output-configuration // https://vercel.com/docs/build-output-api/v3#build-output-configuration
await writeJson(new URL(`./config.json`, _config.outDir), { await writeJson(new URL(`./config.json`, _config.outDir), {
version: 3, version: 3,
routes: [ routes: [
...userRoutes,
...getRedirects(routes, _config), ...getRedirects(routes, _config),
{ handle: 'filesystem' }, { handle: 'filesystem' },
{ src: '/.*', dest: 'render' }, { src: '/.*', dest: 'render' },

View file

@ -1,14 +1,5 @@
import type { AstroConfig, RouteData, RoutePart } from 'astro'; import type { AstroConfig, RouteData, RoutePart } from 'astro';
import type { Route as VercelRoute } from '@vercel/routing-utils';
// https://vercel.com/docs/project-configuration#legacy/routes
interface VercelRoute {
src: string;
methods?: string[];
dest?: string;
headers?: Record<string, string>;
status?: number;
continue?: boolean;
}
// Copied from /home/juanm04/dev/misc/astro/packages/astro/src/core/routing/manifest/create.ts // Copied from /home/juanm04/dev/misc/astro/packages/astro/src/core/routing/manifest/create.ts
// 2022-04-26 // 2022-04-26

View file

@ -0,0 +1,16 @@
import type { AstroConfig } from 'astro';
import type { Route as VercelRoute } from '@vercel/routing-utils';
import * as fs from "node:fs/promises";
import { getTransformedRoutes } from '@vercel/routing-utils';
export async function getRoutesFromVercelJSON(config: AstroConfig): Promise<VercelRoute[]> {
let vercelConfig: Record<string, any> | undefined;
try {
vercelConfig = await fs.readFile(new URL('./vercel.json', config.root), { encoding: 'utf-8' }).then(res => JSON.parse(res));
} catch (e) {}
if (!vercelConfig) return []
const { routes } = getTransformedRoutes(vercelConfig);
return routes ?? [];
}

View file

@ -3599,6 +3599,7 @@ importers:
'@types/set-cookie-parser': ^2.4.2 '@types/set-cookie-parser': ^2.4.2
'@vercel/analytics': ^0.1.8 '@vercel/analytics': ^0.1.8
'@vercel/nft': ^0.22.1 '@vercel/nft': ^0.22.1
'@vercel/routing-utils': ^2.1.10
astro: workspace:* astro: workspace:*
astro-scripts: workspace:* astro-scripts: workspace:*
chai: ^4.3.6 chai: ^4.3.6
@ -3610,6 +3611,7 @@ importers:
'@astrojs/webapi': link:../../webapi '@astrojs/webapi': link:../../webapi
'@vercel/analytics': 0.1.8 '@vercel/analytics': 0.1.8
'@vercel/nft': 0.22.6 '@vercel/nft': 0.22.6
'@vercel/routing-utils': 2.1.10
fast-glob: 3.2.12 fast-glob: 3.2.12
set-cookie-parser: 2.5.1 set-cookie-parser: 2.5.1
web-vitals: 3.1.1 web-vitals: 3.1.1
@ -8090,6 +8092,14 @@ packages:
- supports-color - supports-color
dev: false dev: false
/@vercel/routing-utils/2.1.10:
resolution: {integrity: sha512-eOde+TQBcGOpEMd5EVTE36rK5NQOewEepEUCX1jrSgwbf/vzYP5B82zwcGdtddxEwzWqJV4QjltS6H0GZOgf6A==}
dependencies:
path-to-regexp: 6.1.0
optionalDependencies:
ajv: 6.12.6
dev: false
/@vitejs/plugin-vue-jsx/3.0.0_vite@4.1.2+vue@3.2.47: /@vitejs/plugin-vue-jsx/3.0.0_vite@4.1.2+vue@3.2.47:
resolution: {integrity: sha512-vurkuzgac5SYuxd2HUZqAFAWGTF10diKBwJNbCvnWijNZfXd+7jMtqjPFbGt7idOJUn584fP1Ar9j/GN2jQ3Ew==} resolution: {integrity: sha512-vurkuzgac5SYuxd2HUZqAFAWGTF10diKBwJNbCvnWijNZfXd+7jMtqjPFbGt7idOJUn584fP1Ar9j/GN2jQ3Ew==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
@ -8346,7 +8356,6 @@ packages:
fast-json-stable-stringify: 2.1.0 fast-json-stable-stringify: 2.1.0
json-schema-traverse: 0.4.1 json-schema-traverse: 0.4.1
uri-js: 4.4.1 uri-js: 4.4.1
dev: true
/ajv/8.12.0: /ajv/8.12.0:
resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==}
@ -11778,7 +11787,6 @@ packages:
/json-schema-traverse/0.4.1: /json-schema-traverse/0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
dev: true
/json-schema-traverse/1.0.0: /json-schema-traverse/1.0.0:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
@ -13458,6 +13466,10 @@ packages:
/path-parse/1.0.7: /path-parse/1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
/path-to-regexp/6.1.0:
resolution: {integrity: sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw==}
dev: false
/path-to-regexp/6.2.1: /path-to-regexp/6.2.1:
resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==}
@ -15007,6 +15019,7 @@ packages:
/source-map/0.6.1: /source-map/0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
requiresBuild: true
/source-map/0.7.4: /source-map/0.7.4:
resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}