summaryrefslogtreecommitdiff
path: root/packages/integrations/vercel/src/serverless/adapter.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/integrations/vercel/src/serverless/adapter.ts')
-rw-r--r--packages/integrations/vercel/src/serverless/adapter.ts78
1 files changed, 78 insertions, 0 deletions
diff --git a/packages/integrations/vercel/src/serverless/adapter.ts b/packages/integrations/vercel/src/serverless/adapter.ts
new file mode 100644
index 000000000..babda1f84
--- /dev/null
+++ b/packages/integrations/vercel/src/serverless/adapter.ts
@@ -0,0 +1,78 @@
+import type { AstroAdapter, AstroConfig, AstroIntegration } from 'astro';
+
+import { writeJson, getVercelOutput } from '../lib/fs.js';
+import { copyDependenciesToFunction } from '../lib/nft.js';
+import { getRedirects } from '../lib/redirects.js';
+
+const PACKAGE_NAME = '@astrojs/vercel/serverless';
+
+function getAdapter(): AstroAdapter {
+ return {
+ name: PACKAGE_NAME,
+ serverEntrypoint: `${PACKAGE_NAME}/entrypoint`,
+ exports: ['default'],
+ };
+}
+
+export interface Options {
+ nodeVersion?: '12.x' | '14.x' | '16.x';
+}
+
+export default function vercelEdge({ nodeVersion = '16.x' }: Options = {}): AstroIntegration {
+ let _config: AstroConfig;
+ let functionFolder: URL;
+ let serverEntry: string;
+
+ return {
+ name: PACKAGE_NAME,
+ hooks: {
+ 'astro:config:setup': ({ config }) => {
+ config.outDir = getVercelOutput(config.root);
+ },
+ 'astro:config:done': ({ setAdapter, config }) => {
+ setAdapter(getAdapter());
+ _config = config;
+ },
+ 'astro:build:start': async ({ buildConfig }) => {
+ if (String(process.env.ENABLE_VC_BUILD) !== '1') {
+ throw new Error(
+ `The enviroment variable "ENABLE_VC_BUILD" was not found. Make sure you have it set to "1" in your Vercel project.\nLearn how to set enviroment variables here: https://vercel.com/docs/concepts/projects/environment-variables`
+ );
+ }
+
+ buildConfig.serverEntry = serverEntry = 'entry.js';
+ buildConfig.client = new URL('./static/', _config.outDir);
+ buildConfig.server = functionFolder = new URL('./functions/render.func/', _config.outDir);
+ },
+ 'astro:build:done': async ({ routes }) => {
+ // Copy necessary files (e.g. node_modules/)
+ await copyDependenciesToFunction(_config.root, functionFolder, serverEntry);
+
+ // Enable ESM
+ // https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/
+ await writeJson(new URL(`./package.json`, functionFolder), {
+ type: 'module',
+ });
+
+ // Serverless function config
+ // https://vercel.com/docs/build-output-api/v3#vercel-primitives/serverless-functions/configuration
+ await writeJson(new URL(`./.vc-config.json`, functionFolder), {
+ runtime: `nodejs${nodeVersion}`,
+ handler: serverEntry,
+ launcherType: 'Nodejs',
+ });
+
+ // Output configuration
+ // https://vercel.com/docs/build-output-api/v3#build-output-configuration
+ await writeJson(new URL(`./config.json`, _config.outDir), {
+ version: 3,
+ routes: [
+ ...getRedirects(routes, _config),
+ { handle: 'filesystem' },
+ { src: '/.*', dest: 'render' },
+ ],
+ });
+ },
+ },
+ };
+}