summaryrefslogtreecommitdiff
path: root/packages/integrations/netlify/src/shared.ts
diff options
context:
space:
mode:
authorGravatar Emanuele Stoppa <my.burning@gmail.com> 2023-07-17 15:53:10 +0100
committerGravatar GitHub <noreply@github.com> 2023-07-17 15:53:10 +0100
commit4c93bd8154c210ebce6ad2889bd8bfdf4c349a78 (patch)
treee0b9fb9474845411b35f177260408f444d0631ff /packages/integrations/netlify/src/shared.ts
parentcc8e9de88179d2ed4b70980c60b41448db393429 (diff)
downloadastro-4c93bd8154c210ebce6ad2889bd8bfdf4c349a78.tar.gz
astro-4c93bd8154c210ebce6ad2889bd8bfdf4c349a78.tar.zst
astro-4c93bd8154c210ebce6ad2889bd8bfdf4c349a78.zip
feat(@astrojs/netlify): edge middleware support (#7632)
Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com> Co-authored-by: Yan Thomas <61414485+Yan-Thomas@users.noreply.github.com>
Diffstat (limited to 'packages/integrations/netlify/src/shared.ts')
-rw-r--r--packages/integrations/netlify/src/shared.ts91
1 files changed, 91 insertions, 0 deletions
diff --git a/packages/integrations/netlify/src/shared.ts b/packages/integrations/netlify/src/shared.ts
index ca45dc752..c0ed9ec17 100644
--- a/packages/integrations/netlify/src/shared.ts
+++ b/packages/integrations/netlify/src/shared.ts
@@ -1,6 +1,37 @@
import { createRedirectsFromAstroRoutes } from '@astrojs/underscore-redirects';
import type { AstroConfig, RouteData } from 'astro';
import fs from 'node:fs';
+import { fileURLToPath } from 'url';
+import esbuild from 'esbuild';
+import npath from 'path';
+
+export const DENO_SHIM = `globalThis.process = {
+ argv: [],
+ env: Deno.env.toObject(),
+};`;
+
+export interface NetlifyEdgeFunctionsOptions {
+ dist?: URL;
+}
+
+export interface NetlifyEdgeFunctionManifestFunctionPath {
+ function: string;
+ path: string;
+}
+
+export interface NetlifyEdgeFunctionManifestFunctionPattern {
+ function: string;
+ pattern: string;
+}
+
+export type NetlifyEdgeFunctionManifestFunction =
+ | NetlifyEdgeFunctionManifestFunctionPath
+ | NetlifyEdgeFunctionManifestFunctionPattern;
+
+export interface NetlifyEdgeFunctionManifest {
+ functions: NetlifyEdgeFunctionManifestFunction[];
+ version: 1;
+}
export async function createRedirects(
config: AstroConfig,
@@ -21,3 +52,63 @@ export async function createRedirects(
// If the file does not exist yet, appendFile() automatically creates it.
await fs.promises.appendFile(_redirectsURL, content, 'utf-8');
}
+
+export async function createEdgeManifest(routes: RouteData[], entryFile: string, dir: URL) {
+ const functions: NetlifyEdgeFunctionManifestFunction[] = [];
+ for (const route of routes) {
+ if (route.pathname) {
+ functions.push({
+ function: entryFile,
+ path: route.pathname,
+ });
+ } else {
+ functions.push({
+ function: entryFile,
+ // Make route pattern serializable to match expected
+ // Netlify Edge validation format. Mirrors Netlify's own edge bundler:
+ // https://github.com/netlify/edge-bundler/blob/main/src/manifest.ts#L34
+ pattern: route.pattern.source.replace(/\\\//g, '/').toString(),
+ });
+ }
+ }
+
+ const manifest: NetlifyEdgeFunctionManifest = {
+ functions,
+ version: 1,
+ };
+
+ const baseDir = new URL('./.netlify/edge-functions/', dir);
+ await fs.promises.mkdir(baseDir, { recursive: true });
+
+ const manifestURL = new URL('./manifest.json', baseDir);
+ const _manifest = JSON.stringify(manifest, null, ' ');
+ await fs.promises.writeFile(manifestURL, _manifest, 'utf-8');
+}
+
+export async function bundleServerEntry(entryUrl: URL, serverUrl?: URL, vite?: any | undefined) {
+ const pth = fileURLToPath(entryUrl);
+ await esbuild.build({
+ target: 'es2020',
+ platform: 'browser',
+ entryPoints: [pth],
+ outfile: pth,
+ allowOverwrite: true,
+ format: 'esm',
+ bundle: true,
+ external: ['@astrojs/markdown-remark', 'astro/middleware'],
+ banner: {
+ js: DENO_SHIM,
+ },
+ });
+
+ // Remove chunks, if they exist. Since we have bundled via esbuild these chunks are trash.
+ if (vite && serverUrl) {
+ try {
+ const chunkFileNames =
+ vite?.build?.rollupOptions?.output?.chunkFileNames ?? `chunks/chunk.[hash].mjs`;
+ const chunkPath = npath.dirname(chunkFileNames);
+ const chunksDirUrl = new URL(chunkPath + '/', serverUrl);
+ await fs.promises.rm(chunksDirUrl, { recursive: true, force: true });
+ } catch {}
+ }
+}