summaryrefslogtreecommitdiff
path: root/packages/integrations/netlify/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/integrations/netlify/src')
-rw-r--r--packages/integrations/netlify/src/index.ts1
-rw-r--r--packages/integrations/netlify/src/integration-edge-functions.ts88
-rw-r--r--packages/integrations/netlify/src/integration-functions.ts22
-rw-r--r--packages/integrations/netlify/src/netlify-edge-functions.ts34
-rw-r--r--packages/integrations/netlify/src/netlify-functions.ts8
5 files changed, 24 insertions, 129 deletions
diff --git a/packages/integrations/netlify/src/index.ts b/packages/integrations/netlify/src/index.ts
index 510e560f1..a374020f9 100644
--- a/packages/integrations/netlify/src/index.ts
+++ b/packages/integrations/netlify/src/index.ts
@@ -1,3 +1,2 @@
-export { netlifyEdgeFunctions } from './integration-edge-functions.js';
export { netlifyFunctions as default, netlifyFunctions } from './integration-functions.js';
export { netlifyStatic } from './integration-static.js';
diff --git a/packages/integrations/netlify/src/integration-edge-functions.ts b/packages/integrations/netlify/src/integration-edge-functions.ts
deleted file mode 100644
index ac7c124fb..000000000
--- a/packages/integrations/netlify/src/integration-edge-functions.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import type { AstroAdapter, AstroConfig, AstroIntegration, RouteData } from 'astro';
-import {
- bundleServerEntry,
- createEdgeManifest,
- createRedirects,
- type NetlifyEdgeFunctionsOptions,
-} from './shared.js';
-
-export function getAdapter(): AstroAdapter {
- return {
- name: '@astrojs/netlify/edge-functions',
- serverEntrypoint: '@astrojs/netlify/netlify-edge-functions.js',
- exports: ['default'],
- };
-}
-
-export function netlifyEdgeFunctions({ dist }: NetlifyEdgeFunctionsOptions = {}): AstroIntegration {
- let _config: AstroConfig;
- let entryFile: string;
- let _buildConfig: AstroConfig['build'];
- let _vite: any;
- return {
- name: '@astrojs/netlify/edge-functions',
- hooks: {
- 'astro:config:setup': ({ config, updateConfig }) => {
- const outDir = dist ?? new URL('./dist/', config.root);
- updateConfig({
- outDir,
- build: {
- client: outDir,
- server: new URL('./.netlify/edge-functions/', config.root),
- // Netlify expects .js and will always interpret as ESM
- serverEntry: 'entry.js',
- },
- });
- },
- 'astro:config:done': ({ config, setAdapter }) => {
- setAdapter(getAdapter());
- _config = config;
- _buildConfig = config.build;
- entryFile = config.build.serverEntry.replace(/\.m?js/, '');
-
- if (config.output === 'static') {
- console.warn(
- `[@astrojs/netlify] \`output: "server"\` or \`output: "hybrid"\` is required to use this adapter.`
- );
- console.warn(
- `[@astrojs/netlify] Otherwise, this adapter is not required to deploy a static site to Netlify.`
- );
- }
- },
- 'astro:build:setup': ({ vite, target }) => {
- if (target === 'server') {
- _vite = vite;
- vite.resolve = vite.resolve || {};
- vite.resolve.alias = vite.resolve.alias || {};
-
- const aliases = [{ find: 'react-dom/server', replacement: 'react-dom/server.browser' }];
-
- if (Array.isArray(vite.resolve.alias)) {
- vite.resolve.alias = [...vite.resolve.alias, ...aliases];
- } else {
- for (const alias of aliases) {
- (vite.resolve.alias as Record<string, string>)[alias.find] = alias.replacement;
- }
- }
-
- vite.ssr = {
- noExternal: true,
- };
- }
- },
- 'astro:build:done': async ({ routes, dir }) => {
- const entryUrl = new URL(_buildConfig.serverEntry, _buildConfig.server);
- await bundleServerEntry(entryUrl, _buildConfig.server, _vite);
- await createEdgeManifest(routes, entryFile, _config.root);
- const dynamicTarget = `/.netlify/edge-functions/${entryFile}`;
- const map: [RouteData, string][] = routes.map((route) => {
- return [route, dynamicTarget];
- });
- const routeToDynamicTargetMap = new Map(Array.from(map));
- await createRedirects(_config, routeToDynamicTargetMap, dir);
- },
- },
- };
-}
-
-export { netlifyEdgeFunctions as default };
diff --git a/packages/integrations/netlify/src/integration-functions.ts b/packages/integrations/netlify/src/integration-functions.ts
index a950167e5..b8d56ad65 100644
--- a/packages/integrations/netlify/src/integration-functions.ts
+++ b/packages/integrations/netlify/src/integration-functions.ts
@@ -8,12 +8,26 @@ import { createRedirects } from './shared.js';
export const NETLIFY_EDGE_MIDDLEWARE_FILE = 'netlify-edge-middleware';
export const ASTRO_LOCALS_HEADER = 'x-astro-locals';
-export function getAdapter(args: Args = {}): AstroAdapter {
+export function getAdapter({ functionPerRoute, edgeMiddleware, ...args }: Args): AstroAdapter {
return {
name: '@astrojs/netlify/functions',
serverEntrypoint: '@astrojs/netlify/netlify-functions.js',
exports: ['handler'],
args,
+ adapterFeatures: {
+ functionPerRoute,
+ edgeMiddleware,
+ },
+ supportedAstroFeatures: {
+ hybridOutput: 'stable',
+ staticOutput: 'stable',
+ serverOutput: 'stable',
+ assets: {
+ supportKind: 'stable',
+ isSharpCompatible: true,
+ isSquooshCompatible: true,
+ },
+ },
};
}
@@ -21,12 +35,16 @@ interface NetlifyFunctionsOptions {
dist?: URL;
builders?: boolean;
binaryMediaTypes?: string[];
+ edgeMiddleware?: boolean;
+ functionPerRoute?: boolean;
}
function netlifyFunctions({
dist,
builders,
binaryMediaTypes,
+ functionPerRoute = false,
+ edgeMiddleware = false,
}: NetlifyFunctionsOptions = {}): AstroIntegration {
let _config: AstroConfig;
let _entryPoints: Map<RouteData, URL>;
@@ -53,7 +71,7 @@ function netlifyFunctions({
_entryPoints = entryPoints;
},
'astro:config:done': ({ config, setAdapter }) => {
- setAdapter(getAdapter({ binaryMediaTypes, builders }));
+ setAdapter(getAdapter({ binaryMediaTypes, builders, functionPerRoute, edgeMiddleware }));
_config = config;
ssrEntryFile = config.build.serverEntry.replace(/\.m?js/, '');
diff --git a/packages/integrations/netlify/src/netlify-edge-functions.ts b/packages/integrations/netlify/src/netlify-edge-functions.ts
deleted file mode 100644
index 5e95035a6..000000000
--- a/packages/integrations/netlify/src/netlify-edge-functions.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import type { Context } from '@netlify/edge-functions';
-import type { SSRManifest } from 'astro';
-import { App } from 'astro/app';
-
-const clientAddressSymbol = Symbol.for('astro.clientAddress');
-
-export function createExports(manifest: SSRManifest) {
- const app = new App(manifest);
-
- const handler = async (request: Request, context: Context): Promise<Response | void> => {
- const url = new URL(request.url);
-
- // If this matches a static asset, just return and Netlify will forward it
- // to its static asset handler.
- if (manifest.assets.has(url.pathname)) {
- return;
- }
- const routeData = app.match(request);
- const ip =
- request.headers.get('x-nf-client-connection-ip') ||
- context?.ip ||
- (context as any)?.remoteAddr?.hostname;
- Reflect.set(request, clientAddressSymbol, ip);
- const response = await app.render(request, routeData);
- if (app.setCookieHeaders) {
- for (const setCookieHeader of app.setCookieHeaders(response)) {
- response.headers.append('Set-Cookie', setCookieHeader);
- }
- }
- return response;
- };
-
- return { default: handler };
-}
diff --git a/packages/integrations/netlify/src/netlify-functions.ts b/packages/integrations/netlify/src/netlify-functions.ts
index c45c1b9ef..8c051d9f6 100644
--- a/packages/integrations/netlify/src/netlify-functions.ts
+++ b/packages/integrations/netlify/src/netlify-functions.ts
@@ -1,16 +1,16 @@
-import { polyfill } from '@astrojs/webapi';
import { builder, type Handler } from '@netlify/functions';
import type { SSRManifest } from 'astro';
import { App } from 'astro/app';
+import { applyPolyfills } from 'astro/app/node';
import { ASTRO_LOCALS_HEADER } from './integration-functions.js';
-polyfill(globalThis, {
- exclude: 'window document',
-});
+applyPolyfills();
export interface Args {
builders?: boolean;
binaryMediaTypes?: string[];
+ edgeMiddleware: boolean;
+ functionPerRoute: boolean;
}
function parseContentType(header?: string) {