summaryrefslogtreecommitdiff
path: root/packages/integrations/netlify/src/netlify-functions.ts
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@skypack.dev> 2023-09-28 04:48:26 +0800
committerGravatar GitHub <noreply@github.com> 2023-09-27 16:48:26 -0400
commit4ed410db507723d8f8edd70aec508415d77ad2f5 (patch)
treedd876939fc708358d0675ba159e0a1d9af0fcd79 /packages/integrations/netlify/src/netlify-functions.ts
parenta10a798c18512796d2c8b8ed49924dafd884e04c (diff)
downloadastro-4ed410db507723d8f8edd70aec508415d77ad2f5.tar.gz
astro-4ed410db507723d8f8edd70aec508415d77ad2f5.tar.zst
astro-4ed410db507723d8f8edd70aec508415d77ad2f5.zip
Remove Netlify adapter from core (#8574)
* New link * More explicit * Add placeholder package.json * lockfile * add keyworkds
Diffstat (limited to 'packages/integrations/netlify/src/netlify-functions.ts')
-rw-r--r--packages/integrations/netlify/src/netlify-functions.ts225
1 files changed, 0 insertions, 225 deletions
diff --git a/packages/integrations/netlify/src/netlify-functions.ts b/packages/integrations/netlify/src/netlify-functions.ts
deleted file mode 100644
index 8c051d9f6..000000000
--- a/packages/integrations/netlify/src/netlify-functions.ts
+++ /dev/null
@@ -1,225 +0,0 @@
-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';
-
-applyPolyfills();
-
-export interface Args {
- builders?: boolean;
- binaryMediaTypes?: string[];
- edgeMiddleware: boolean;
- functionPerRoute: boolean;
-}
-
-function parseContentType(header?: string) {
- return header?.split(';')[0] ?? '';
-}
-
-const clientAddressSymbol = Symbol.for('astro.clientAddress');
-
-export const createExports = (manifest: SSRManifest, args: Args) => {
- const app = new App(manifest);
-
- const builders = args.builders ?? false;
- const binaryMediaTypes = args.binaryMediaTypes ?? [];
- const knownBinaryMediaTypes = new Set([
- 'audio/3gpp',
- 'audio/3gpp2',
- 'audio/aac',
- 'audio/midi',
- 'audio/mpeg',
- 'audio/ogg',
- 'audio/opus',
- 'audio/wav',
- 'audio/webm',
- 'audio/x-midi',
- 'image/avif',
- 'image/bmp',
- 'image/gif',
- 'image/vnd.microsoft.icon',
- 'image/heif',
- 'image/jpeg',
- 'image/png',
- 'image/svg+xml',
- 'image/tiff',
- 'image/webp',
- 'video/3gpp',
- 'video/3gpp2',
- 'video/mp2t',
- 'video/mp4',
- 'video/mpeg',
- 'video/ogg',
- 'video/x-msvideo',
- 'video/webm',
- ...binaryMediaTypes,
- ]);
-
- const myHandler: Handler = async (event) => {
- const { httpMethod, headers, rawUrl, body: requestBody, isBase64Encoded } = event;
- const init: RequestInit = {
- method: httpMethod,
- headers: new Headers(headers as any),
- };
- // Attach the event body the request, with proper encoding.
- if (httpMethod !== 'GET' && httpMethod !== 'HEAD') {
- const encoding = isBase64Encoded ? 'base64' : 'utf-8';
- init.body =
- typeof requestBody === 'string' ? Buffer.from(requestBody, encoding) : requestBody;
- }
-
- const request = new Request(rawUrl, init);
-
- const routeData = app.match(request);
- const ip = headers['x-nf-client-connection-ip'];
- Reflect.set(request, clientAddressSymbol, ip);
-
- let locals: Record<string, unknown> = {};
-
- if (request.headers.has(ASTRO_LOCALS_HEADER)) {
- let localsAsString = request.headers.get(ASTRO_LOCALS_HEADER);
- if (localsAsString) {
- locals = JSON.parse(localsAsString);
- }
- }
-
- let responseTtl = undefined;
-
- locals.runtime = builders
- ? {
- setBuildersTtl(ttl: number) {
- responseTtl = ttl;
- },
- }
- : {};
-
- const response: Response = await app.render(request, routeData, locals);
- const responseHeaders = Object.fromEntries(response.headers.entries());
-
- const responseContentType = parseContentType(responseHeaders['content-type']);
- const responseIsBase64Encoded = knownBinaryMediaTypes.has(responseContentType);
-
- let responseBody: string;
- if (responseIsBase64Encoded) {
- const ab = await response.arrayBuffer();
- responseBody = Buffer.from(ab).toString('base64');
- } else {
- responseBody = await response.text();
- }
-
- const fnResponse: any = {
- statusCode: response.status,
- headers: responseHeaders,
- body: responseBody,
- isBase64Encoded: responseIsBase64Encoded,
- ttl: responseTtl,
- };
-
- const cookies = response.headers.get('set-cookie');
- if (cookies) {
- fnResponse.multiValueHeaders = {
- 'set-cookie': Array.isArray(cookies) ? cookies : splitCookiesString(cookies),
- };
- }
-
- // Apply cookies set via Astro.cookies.set/delete
- if (app.setCookieHeaders) {
- const setCookieHeaders = Array.from(app.setCookieHeaders(response));
- fnResponse.multiValueHeaders = fnResponse.multiValueHeaders || {};
- if (!fnResponse.multiValueHeaders['set-cookie']) {
- fnResponse.multiValueHeaders['set-cookie'] = [];
- }
- fnResponse.multiValueHeaders['set-cookie'].push(...setCookieHeaders);
- }
-
- return fnResponse;
- };
-
- const handler = builders ? builder(myHandler) : myHandler;
-
- return { handler };
-};
-
-/*
- From: https://github.com/nfriedly/set-cookie-parser/blob/5cae030d8ef0f80eec58459e3583d43a07b984cb/lib/set-cookie.js#L144
- Set-Cookie header field-values are sometimes comma joined in one string. This splits them without choking on commas
- that are within a single set-cookie field-value, such as in the Expires portion.
- This is uncommon, but explicitly allowed - see https://tools.ietf.org/html/rfc2616#section-4.2
- Node.js does this for every header *except* set-cookie - see https://github.com/nodejs/node/blob/d5e363b77ebaf1caf67cd7528224b651c86815c1/lib/_http_incoming.js#L128
- React Native's fetch does this for *every* header, including set-cookie.
- Based on: https://github.com/google/j2objc/commit/16820fdbc8f76ca0c33472810ce0cb03d20efe25
- Credits to: https://github.com/tomball for original and https://github.com/chrusart for JavaScript implementation
-*/
-function splitCookiesString(cookiesString: string): string[] {
- if (Array.isArray(cookiesString)) {
- return cookiesString;
- }
- if (typeof cookiesString !== 'string') {
- return [];
- }
-
- let cookiesStrings = [];
- let pos = 0;
- let start;
- let ch;
- let lastComma;
- let nextStart;
- let cookiesSeparatorFound;
-
- function skipWhitespace() {
- while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) {
- pos += 1;
- }
- return pos < cookiesString.length;
- }
-
- function notSpecialChar() {
- ch = cookiesString.charAt(pos);
-
- return ch !== '=' && ch !== ';' && ch !== ',';
- }
-
- while (pos < cookiesString.length) {
- start = pos;
- cookiesSeparatorFound = false;
-
- while (skipWhitespace()) {
- ch = cookiesString.charAt(pos);
- if (ch === ',') {
- // ',' is a cookie separator if we have later first '=', not ';' or ','
- lastComma = pos;
- pos += 1;
-
- skipWhitespace();
- nextStart = pos;
-
- while (pos < cookiesString.length && notSpecialChar()) {
- pos += 1;
- }
-
- // currently special character
- if (pos < cookiesString.length && cookiesString.charAt(pos) === '=') {
- // we found cookies separator
- cookiesSeparatorFound = true;
- // pos is inside the next cookie, so back up and return it.
- pos = nextStart;
- cookiesStrings.push(cookiesString.substring(start, lastComma));
- start = pos;
- } else {
- // in param ',' or param separator ';',
- // we continue from that comma
- pos = lastComma + 1;
- }
- } else {
- pos += 1;
- }
- }
-
- if (!cookiesSeparatorFound || pos >= cookiesString.length) {
- cookiesStrings.push(cookiesString.substring(start, cookiesString.length));
- }
- }
-
- return cookiesStrings;
-}