summaryrefslogtreecommitdiff
path: root/packages/integrations/vercel/src/serverless/request-transform.ts
diff options
context:
space:
mode:
authorGravatar Juan Martín Seery <me@juanm04.com> 2022-05-11 18:10:38 -0300
committerGravatar GitHub <noreply@github.com> 2022-05-11 15:10:38 -0600
commit114bf63e11f28299b13178ef1a412eed37ab7909 (patch)
tree80e3512af2a5ff86b662444f57994cfd5c25fc2c /packages/integrations/vercel/src/serverless/request-transform.ts
parent46cd8b9eb4c5e9b526a6cba288070630b8dcbbf5 (diff)
downloadastro-114bf63e11f28299b13178ef1a412eed37ab7909.tar.gz
astro-114bf63e11f28299b13178ef1a412eed37ab7909.tar.zst
astro-114bf63e11f28299b13178ef1a412eed37ab7909.zip
refactor(vercel): Build Output API v3 (#3216)
* Removed ignores * Migration to v3 * More changes * Remove legacy redirects * Fail when there is no ENABLE_VC_BUILD * Fix edge * Updated readme * Changeset * Added static mode * Updated documentation * Updated shim * Made edge work! * Updated changeset * Ensure empty dir * Fixed redirects for dynamic paths * Removed extra declaration * Splited imports * Updated readme * Fixed some urls * Deprecated shim! * [test]: Vercel NFT * Beautify * Edge bundle to node 14.19 Vercel runs 14.19.1 (I've checked it manually) * Re-added shim (#3304) * Added `node:` prefix * Use the same bundling as Deno for Edge * Remove esbuild * Fixed shim * Moved nft * Updated changeset * Added note about Edge * fix typo * Added support for Node 16 (vercel/vercel#7772)
Diffstat (limited to 'packages/integrations/vercel/src/serverless/request-transform.ts')
-rw-r--r--packages/integrations/vercel/src/serverless/request-transform.ts95
1 files changed, 95 insertions, 0 deletions
diff --git a/packages/integrations/vercel/src/serverless/request-transform.ts b/packages/integrations/vercel/src/serverless/request-transform.ts
new file mode 100644
index 000000000..7cdb2550a
--- /dev/null
+++ b/packages/integrations/vercel/src/serverless/request-transform.ts
@@ -0,0 +1,95 @@
+import { Readable } from 'node:stream';
+import type { IncomingMessage, ServerResponse } from 'node:http';
+
+/*
+ Credits to the SvelteKit team
+ https://github.com/sveltejs/kit/blob/69913e9fda054fa6a62a80e2bb4ee7dca1005796/packages/kit/src/node.js
+*/
+
+function get_raw_body(req: IncomingMessage) {
+ return new Promise<Uint8Array | null>((fulfil, reject) => {
+ const h = req.headers;
+
+ if (!h['content-type']) {
+ return fulfil(null);
+ }
+
+ req.on('error', reject);
+
+ const length = Number(h['content-length']);
+
+ // https://github.com/jshttp/type-is/blob/c1f4388c71c8a01f79934e68f630ca4a15fffcd6/index.js#L81-L95
+ if (isNaN(length) && h['transfer-encoding'] == null) {
+ return fulfil(null);
+ }
+
+ let data = new Uint8Array(length || 0);
+
+ if (length > 0) {
+ let offset = 0;
+ req.on('data', (chunk) => {
+ const new_len = offset + Buffer.byteLength(chunk);
+
+ if (new_len > length) {
+ return reject({
+ status: 413,
+ reason: 'Exceeded "Content-Length" limit',
+ });
+ }
+
+ data.set(chunk, offset);
+ offset = new_len;
+ });
+ } else {
+ req.on('data', (chunk) => {
+ const new_data = new Uint8Array(data.length + chunk.length);
+ new_data.set(data, 0);
+ new_data.set(chunk, data.length);
+ data = new_data;
+ });
+ }
+
+ req.on('end', () => {
+ fulfil(data);
+ });
+ });
+}
+
+export async function getRequest(base: string, req: IncomingMessage): Promise<Request> {
+ let headers = req.headers as Record<string, string>;
+ if (req.httpVersionMajor === 2) {
+ // we need to strip out the HTTP/2 pseudo-headers because node-fetch's
+ // Request implementation doesn't like them
+ headers = Object.assign({}, headers);
+ delete headers[':method'];
+ delete headers[':path'];
+ delete headers[':authority'];
+ delete headers[':scheme'];
+ }
+ return new Request(base + req.url, {
+ method: req.method,
+ headers,
+ body: await get_raw_body(req), // TODO stream rather than buffer
+ });
+}
+
+export async function setResponse(res: ServerResponse, response: Response): Promise<void> {
+ const headers = Object.fromEntries(response.headers);
+
+ if (response.headers.has('set-cookie')) {
+ // @ts-expect-error (headers.raw() is non-standard)
+ headers['set-cookie'] = response.headers.raw()['set-cookie'];
+ }
+
+ res.writeHead(response.status, headers);
+
+ if (response.body instanceof Readable) {
+ response.body.pipe(res);
+ } else {
+ if (response.body) {
+ res.write(await response.arrayBuffer());
+ }
+
+ res.end();
+ }
+}