2022-05-11 21:10:38 +00:00
|
|
|
import type { AstroAdapter, AstroConfig, AstroIntegration } from 'astro';
|
|
|
|
|
2022-10-10 15:37:03 +00:00
|
|
|
import { getVercelOutput, removeDir, writeJson } from '../lib/fs.js';
|
2022-05-11 21:10:38 +00:00
|
|
|
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'],
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-05-16 18:34:46 +00:00
|
|
|
export default function vercelEdge(): AstroIntegration {
|
2022-05-11 21:10:38 +00:00
|
|
|
let _config: AstroConfig;
|
2022-10-10 15:37:03 +00:00
|
|
|
let buildTempFolder: URL;
|
2022-05-11 21:10:38 +00:00
|
|
|
let functionFolder: URL;
|
|
|
|
let serverEntry: string;
|
2022-10-12 21:25:51 +00:00
|
|
|
let needsBuildConfig = false;
|
2022-05-11 21:10:38 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
name: PACKAGE_NAME,
|
|
|
|
hooks: {
|
2022-10-12 21:25:51 +00:00
|
|
|
'astro:config:setup': ({ config, updateConfig }) => {
|
|
|
|
needsBuildConfig = !config.build.client;
|
|
|
|
const outDir = getVercelOutput(config.root);
|
|
|
|
updateConfig({
|
|
|
|
outDir,
|
|
|
|
build: {
|
|
|
|
serverEntry: 'entry.js',
|
|
|
|
client: new URL('./static/', outDir),
|
|
|
|
server: new URL('./dist/', config.root),
|
2022-10-12 21:27:56 +00:00
|
|
|
},
|
2022-10-12 21:25:51 +00:00
|
|
|
});
|
2022-05-11 21:10:38 +00:00
|
|
|
},
|
|
|
|
'astro:config:done': ({ setAdapter, config }) => {
|
|
|
|
setAdapter(getAdapter());
|
|
|
|
_config = config;
|
2022-10-12 21:25:51 +00:00
|
|
|
buildTempFolder = config.build.server;
|
|
|
|
functionFolder = new URL('./functions/render.func/', config.outDir);
|
|
|
|
serverEntry = config.build.serverEntry;
|
2022-07-27 15:50:48 +00:00
|
|
|
|
2022-07-27 15:52:44 +00:00
|
|
|
if (config.output === 'static') {
|
|
|
|
throw new Error(`
|
2022-07-27 15:50:48 +00:00
|
|
|
[@astrojs/vercel] \`output: "server"\` is required to use the serverless adapter.
|
|
|
|
|
|
|
|
`);
|
|
|
|
}
|
2022-05-11 21:10:38 +00:00
|
|
|
},
|
2022-10-12 21:25:51 +00:00
|
|
|
'astro:build:start': ({ buildConfig }) => {
|
2022-10-12 21:27:56 +00:00
|
|
|
if (needsBuildConfig) {
|
2022-10-12 21:25:51 +00:00
|
|
|
buildConfig.client = new URL('./static/', _config.outDir);
|
|
|
|
buildTempFolder = buildConfig.server = new URL('./dist/', _config.root);
|
|
|
|
serverEntry = buildConfig.serverEntry = 'entry.js';
|
|
|
|
}
|
2022-05-11 21:10:38 +00:00
|
|
|
},
|
|
|
|
'astro:build:done': async ({ routes }) => {
|
|
|
|
// Copy necessary files (e.g. node_modules/)
|
2022-10-10 15:37:03 +00:00
|
|
|
const { handler } = await copyDependenciesToFunction(
|
|
|
|
new URL(serverEntry, buildTempFolder),
|
|
|
|
functionFolder
|
|
|
|
);
|
|
|
|
|
|
|
|
// Remove temporary folder
|
|
|
|
await removeDir(buildTempFolder);
|
2022-05-11 21:10:38 +00:00
|
|
|
|
|
|
|
// 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), {
|
2022-05-16 18:34:46 +00:00
|
|
|
runtime: getRuntime(),
|
2022-10-10 15:37:03 +00:00
|
|
|
handler,
|
2022-05-11 21:10:38 +00:00
|
|
|
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' },
|
|
|
|
],
|
|
|
|
});
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
2022-05-16 18:34:46 +00:00
|
|
|
|
|
|
|
function getRuntime() {
|
|
|
|
const version = process.version.slice(1); // 'v16.5.0' --> '16.5.0'
|
|
|
|
const major = version.split('.')[0]; // '16.5.0' --> '16'
|
|
|
|
return `nodejs${major}.x`;
|
|
|
|
}
|