summaryrefslogtreecommitdiff
path: root/packages/integrations/node
diff options
context:
space:
mode:
authorGravatar natemoo-re <natemoo-re@users.noreply.github.com> 2023-06-06 15:11:47 +0000
committerGravatar fredkbot <fred+astrobot@astro.build> 2023-06-06 15:11:47 +0000
commita1144f7fec0cb93eb1fd549beb9f5bc91ee1f485 (patch)
tree1451b4462c572b88d409faa2e2a01439012afcf3 /packages/integrations/node
parent4929332c3210d1634b8607c7736d9049860a2079 (diff)
downloadastro-a1144f7fec0cb93eb1fd549beb9f5bc91ee1f485.tar.gz
astro-a1144f7fec0cb93eb1fd549beb9f5bc91ee1f485.tar.zst
astro-a1144f7fec0cb93eb1fd549beb9f5bc91ee1f485.zip
[ci] format
Diffstat (limited to 'packages/integrations/node')
-rw-r--r--packages/integrations/node/src/createOutgoingHttpHeaders.ts48
-rw-r--r--packages/integrations/node/src/http-server.ts4
-rw-r--r--packages/integrations/node/src/nodeMiddleware.ts14
-rw-r--r--packages/integrations/node/test/createOutgoingHttpHeaders.test.js128
-rw-r--r--packages/integrations/node/test/headers.test.js.js269
5 files changed, 231 insertions, 232 deletions
diff --git a/packages/integrations/node/src/createOutgoingHttpHeaders.ts b/packages/integrations/node/src/createOutgoingHttpHeaders.ts
index 5b99cfa4f..80269489e 100644
--- a/packages/integrations/node/src/createOutgoingHttpHeaders.ts
+++ b/packages/integrations/node/src/createOutgoingHttpHeaders.ts
@@ -3,38 +3,40 @@ import type { OutgoingHttpHeaders } from 'http';
/**
* Takes in a nullable WebAPI Headers object and produces a NodeJS OutgoingHttpHeaders object suitable for usage
* with ServerResponse.writeHead(..) or ServerResponse.setHeader(..)
- *
+ *
* @param webHeaders WebAPI Headers object
* @returns NodeJS OutgoingHttpHeaders object with multiple set-cookie handled as an array of values
*/
-export const createOutgoingHttpHeaders = (webHeaders: Headers | undefined | null): OutgoingHttpHeaders | undefined => {
- if (!webHeaders) {
- return undefined;
- }
+export const createOutgoingHttpHeaders = (
+ webHeaders: Headers | undefined | null
+): OutgoingHttpHeaders | undefined => {
+ if (!webHeaders) {
+ return undefined;
+ }
- // re-type to access Header.getSetCookie()
- const headers = webHeaders as HeadersWithGetSetCookie;
+ // re-type to access Header.getSetCookie()
+ const headers = webHeaders as HeadersWithGetSetCookie;
- // at this point, a multi-value'd set-cookie header is invalid (it was concatenated as a single CSV, which is not valid for set-cookie)
- const nodeHeaders: OutgoingHttpHeaders = Object.fromEntries(headers.entries());
+ // at this point, a multi-value'd set-cookie header is invalid (it was concatenated as a single CSV, which is not valid for set-cookie)
+ const nodeHeaders: OutgoingHttpHeaders = Object.fromEntries(headers.entries());
- if (Object.keys(nodeHeaders).length === 0) {
- return undefined;
- }
+ if (Object.keys(nodeHeaders).length === 0) {
+ return undefined;
+ }
- // if there is > 1 set-cookie header, we have to fix it to be an array of values
- if (headers.has('set-cookie')) {
- const cookieHeaders = headers.getSetCookie();
- if (cookieHeaders.length > 1) {
- // the Headers.entries() API already normalized all header names to lower case so we can safely index this as 'set-cookie'
- nodeHeaders['set-cookie'] = cookieHeaders;
- }
- }
+ // if there is > 1 set-cookie header, we have to fix it to be an array of values
+ if (headers.has('set-cookie')) {
+ const cookieHeaders = headers.getSetCookie();
+ if (cookieHeaders.length > 1) {
+ // the Headers.entries() API already normalized all header names to lower case so we can safely index this as 'set-cookie'
+ nodeHeaders['set-cookie'] = cookieHeaders;
+ }
+ }
- return nodeHeaders;
+ return nodeHeaders;
};
interface HeadersWithGetSetCookie extends Headers {
- // the @astrojs/webapi polyfill makes this available (as of undici@5.19.0), but tsc doesn't pick it up on the built-in Headers type from DOM lib
- getSetCookie(): string[];
+ // the @astrojs/webapi polyfill makes this available (as of undici@5.19.0), but tsc doesn't pick it up on the built-in Headers type from DOM lib
+ getSetCookie(): string[];
}
diff --git a/packages/integrations/node/src/http-server.ts b/packages/integrations/node/src/http-server.ts
index 9f8b3e891..8d463ba6f 100644
--- a/packages/integrations/node/src/http-server.ts
+++ b/packages/integrations/node/src/http-server.ts
@@ -60,9 +60,9 @@ export function createServer(
let location: string;
if (req.url!.includes('?')) {
const [url = '', search] = req.url!.split('?');
- location = `${url}/?${search}`
+ location = `${url}/?${search}`;
} else {
- location = req.url + '/'
+ location = req.url + '/';
}
res.statusCode = 301;
diff --git a/packages/integrations/node/src/nodeMiddleware.ts b/packages/integrations/node/src/nodeMiddleware.ts
index 492130daa..c0d439ba0 100644
--- a/packages/integrations/node/src/nodeMiddleware.ts
+++ b/packages/integrations/node/src/nodeMiddleware.ts
@@ -1,9 +1,9 @@
import type { NodeApp } from 'astro/app/node';
import type { IncomingMessage, ServerResponse } from 'http';
import type { Readable } from 'stream';
+import { createOutgoingHttpHeaders } from './createOutgoingHttpHeaders';
import { responseIterator } from './response-iterator';
import type { Options } from './types';
-import { createOutgoingHttpHeaders } from './createOutgoingHttpHeaders';
export default function (app: NodeApp, mode: Options['mode']) {
return async function (
@@ -45,16 +45,16 @@ async function writeWebResponse(app: NodeApp, res: ServerResponse, webResponse:
if (app.setCookieHeaders) {
const setCookieHeaders: Array<string> = Array.from(app.setCookieHeaders(webResponse));
-
+
if (setCookieHeaders.length) {
- for (const setCookieHeader of setCookieHeaders) {
- webResponse.headers.append('set-cookie', setCookieHeader);
- }
+ for (const setCookieHeader of setCookieHeaders) {
+ webResponse.headers.append('set-cookie', setCookieHeader);
+ }
}
}
- const nodeHeaders = createOutgoingHttpHeaders(headers);
- res.writeHead(status, nodeHeaders);
+ const nodeHeaders = createOutgoingHttpHeaders(headers);
+ res.writeHead(status, nodeHeaders);
if (webResponse.body) {
try {
for await (const chunk of responseIterator(webResponse) as unknown as Readable) {
diff --git a/packages/integrations/node/test/createOutgoingHttpHeaders.test.js b/packages/integrations/node/test/createOutgoingHttpHeaders.test.js
index 1876c9a00..2f7063b1c 100644
--- a/packages/integrations/node/test/createOutgoingHttpHeaders.test.js
+++ b/packages/integrations/node/test/createOutgoingHttpHeaders.test.js
@@ -3,76 +3,74 @@ import { expect } from 'chai';
import { createOutgoingHttpHeaders } from '../dist/createOutgoingHttpHeaders.js';
describe('createOutgoingHttpHeaders', () => {
+ it('undefined input headers', async () => {
+ const result = createOutgoingHttpHeaders(undefined);
+ expect(result).to.equal(undefined);
+ });
- it('undefined input headers', async () => {
- const result = createOutgoingHttpHeaders(undefined);
- expect(result).to.equal(undefined);
- });
+ it('null input headers', async () => {
+ const result = createOutgoingHttpHeaders(undefined);
+ expect(result).to.equal(undefined);
+ });
- it('null input headers', async () => {
- const result = createOutgoingHttpHeaders(undefined);
- expect(result).to.equal(undefined);
- });
+ it('Empty Headers', async () => {
+ const headers = new Headers();
+ const result = createOutgoingHttpHeaders(headers);
+ expect(result).to.equal(undefined);
+ });
- it('Empty Headers', async () => {
- const headers = new Headers();
- const result = createOutgoingHttpHeaders(headers);
- expect(result).to.equal(undefined);
- });
+ it('Headers with single key', async () => {
+ const headers = new Headers();
+ headers.append('x-test', 'hello world');
+ const result = createOutgoingHttpHeaders(headers);
+ expect(result).to.deep.equal({ 'x-test': 'hello world' });
+ });
- it('Headers with single key', async () => {
- const headers = new Headers();
- headers.append('x-test', 'hello world');
- const result = createOutgoingHttpHeaders(headers);
- expect(result).to.deep.equal({ 'x-test': 'hello world' });
- });
+ it('Headers with multiple keys', async () => {
+ const headers = new Headers();
+ headers.append('x-test1', 'hello');
+ headers.append('x-test2', 'world');
+ const result = createOutgoingHttpHeaders(headers);
+ expect(result).to.deep.equal({ 'x-test1': 'hello', 'x-test2': 'world' });
+ });
- it('Headers with multiple keys', async () => {
- const headers = new Headers();
- headers.append('x-test1', 'hello');
- headers.append('x-test2', 'world');
- const result = createOutgoingHttpHeaders(headers);
- expect(result).to.deep.equal({ 'x-test1': 'hello', 'x-test2': 'world' });
- });
+ it('Headers with multiple values (not set-cookie)', async () => {
+ const headers = new Headers();
+ headers.append('x-test', 'hello');
+ headers.append('x-test', 'world');
+ const result = createOutgoingHttpHeaders(headers);
+ expect(result).to.deep.equal({ 'x-test': 'hello, world' });
+ });
- it('Headers with multiple values (not set-cookie)', async () => {
- const headers = new Headers();
- headers.append('x-test', 'hello');
- headers.append('x-test', 'world');
- const result = createOutgoingHttpHeaders(headers);
- expect(result).to.deep.equal({ 'x-test': 'hello, world' });
- });
+ it('Headers with multiple values (set-cookie special case)', async () => {
+ const headers = new Headers();
+ headers.append('set-cookie', 'hello');
+ headers.append('set-cookie', 'world');
+ const result = createOutgoingHttpHeaders(headers);
+ expect(result).to.deep.equal({ 'set-cookie': ['hello', 'world'] });
+ });
- it('Headers with multiple values (set-cookie special case)', async () => {
- const headers = new Headers();
- headers.append('set-cookie', 'hello');
- headers.append('set-cookie', 'world');
- const result = createOutgoingHttpHeaders(headers);
- expect(result).to.deep.equal({ 'set-cookie': ['hello', 'world'] });
- });
+ it('Headers with multiple values (set-cookie case handling)', async () => {
+ const headers = new Headers();
+ headers.append('Set-cookie', 'hello');
+ headers.append('Set-Cookie', 'world');
+ const result = createOutgoingHttpHeaders(headers);
+ expect(result).to.deep.equal({ 'set-cookie': ['hello', 'world'] });
+ });
- it('Headers with multiple values (set-cookie case handling)', async () => {
- const headers = new Headers();
- headers.append('Set-cookie', 'hello');
- headers.append('Set-Cookie', 'world');
- const result = createOutgoingHttpHeaders(headers);
- expect(result).to.deep.equal({ 'set-cookie': ['hello', 'world'] });
- });
-
- it('Headers with all use cases', async () => {
- const headers = new Headers();
- headers.append('x-single', 'single');
- headers.append('x-triple', 'one');
- headers.append('x-triple', 'two');
- headers.append('x-triple', 'three');
- headers.append('Set-cookie', 'hello');
- headers.append('Set-Cookie', 'world');
- const result = createOutgoingHttpHeaders(headers);
- expect(result).to.deep.equal({
- 'x-single': 'single',
- 'x-triple': 'one, two, three',
- 'set-cookie': ['hello', 'world'],
- });
- });
-
-}); \ No newline at end of file
+ it('Headers with all use cases', async () => {
+ const headers = new Headers();
+ headers.append('x-single', 'single');
+ headers.append('x-triple', 'one');
+ headers.append('x-triple', 'two');
+ headers.append('x-triple', 'three');
+ headers.append('Set-cookie', 'hello');
+ headers.append('Set-Cookie', 'world');
+ const result = createOutgoingHttpHeaders(headers);
+ expect(result).to.deep.equal({
+ 'x-single': 'single',
+ 'x-triple': 'one, two, three',
+ 'set-cookie': ['hello', 'world'],
+ });
+ });
+});
diff --git a/packages/integrations/node/test/headers.test.js.js b/packages/integrations/node/test/headers.test.js.js
index 5b453dd56..17cfd3701 100644
--- a/packages/integrations/node/test/headers.test.js.js
+++ b/packages/integrations/node/test/headers.test.js.js
@@ -3,146 +3,145 @@ import { loadFixture, createRequestAndResponse } from './test-utils.js';
import { expect } from 'chai';
describe('Node Adapter Headers', () => {
- /** @type {import('./test-utils').Fixture} */
- let fixture;
-
- before(async () => {
- fixture = await loadFixture({
- root: './fixtures/headers/',
- output: 'server',
- adapter: nodejs({ mode: 'middleware' }),
- });
- await fixture.build();
- });
-
- it('Endpoint Simple Headers', async () => {
- await runTest('/endpoints/simple', {
- 'content-type': 'text/plain;charset=utf-8',
- 'x-hello': 'world',
- });
- });
-
- it('Endpoint Astro Single Cookie Header', async () => {
- await runTest('/endpoints/astro-cookies-single', {
- 'content-type': 'text/plain;charset=utf-8',
- 'set-cookie': 'from1=astro1',
- });
- });
-
- it('Endpoint Astro Multi Cookie Header', async () => {
- await runTest('/endpoints/astro-cookies-multi', {
- 'content-type': 'text/plain;charset=utf-8',
- 'set-cookie': ['from1=astro1', 'from2=astro2'],
- });
- });
-
- it('Endpoint Response Single Cookie Header', async () => {
- await runTest('/endpoints/response-cookies-single', {
- 'content-type': 'text/plain;charset=utf-8',
- 'set-cookie': 'hello1=world1',
- });
- });
-
- it('Endpoint Response Multi Cookie Header', async () => {
- await runTest('/endpoints/response-cookies-multi', {
- 'content-type': 'text/plain;charset=utf-8',
- 'set-cookie': ['hello1=world1', 'hello2=world2'],
- });
- });
-
- it('Endpoint Complex Headers Kitchen Sink', async () => {
- await runTest('/endpoints/kitchen-sink', {
- 'content-type': 'text/plain;charset=utf-8',
- 'x-single': 'single',
- 'x-triple': 'one, two, three',
- 'set-cookie': ['hello1=world1', 'hello2=world2'],
- });
- });
-
- it('Endpoint Astro and Response Single Cookie Header', async () => {
- await runTest('/endpoints/astro-response-cookie-single', {
- 'content-type': 'text/plain;charset=utf-8',
- 'set-cookie': ['from1=response1', 'from1=astro1'],
- });
- });
-
- it('Endpoint Astro and Response Multi Cookie Header', async () => {
- await runTest('/endpoints/astro-response-cookie-multi', {
- 'content-type': 'text/plain;charset=utf-8',
- 'set-cookie': ['from1=response1', 'from2=response2', 'from3=astro1', 'from4=astro2'],
- });
- });
-
- it('Endpoint Response Empty Headers Object', async () => {
- await runTest('/endpoints/response-empty-headers-object', {
- 'content-type': 'text/plain;charset=UTF-8',
- });
- });
-
- it('Endpoint Response undefined Headers Object', async () => {
- await runTest('/endpoints/response-undefined-headers-object', {
- 'content-type': 'text/plain;charset=UTF-8',
- });
- });
-
- it('Component Astro Single Cookie Header', async () => {
- await runTest('/astro/component-astro-cookies-single', {
- 'content-type': 'text/html',
- 'set-cookie': 'from1=astro1',
- });
- });
-
- it('Component Astro Multi Cookie Header', async () => {
- await runTest('/astro/component-astro-cookies-multi', {
- 'content-type': 'text/html',
- 'set-cookie': ['from1=astro1', 'from2=astro2'],
- });
- });
-
- it('Component Response Single Cookie Header', async () => {
- await runTest('/astro/component-response-cookies-single', {
- 'content-type': 'text/html',
- 'set-cookie': 'from1=value1',
- });
- });
-
- it('Component Response Multi Cookie Header', async () => {
- await runTest('/astro/component-response-cookies-multi', {
- 'content-type': 'text/html',
- 'set-cookie': ['from1=value1', 'from2=value2'],
- });
- });
-
- it('Component Astro and Response Single Cookie Header', async () => {
- await runTest('/astro/component-astro-response-cookie-single', {
- 'content-type': 'text/html',
- 'set-cookie': ['from1=response1', 'from1=astro1'],
- });
- });
-
- it('Component Astro and Response Multi Cookie Header', async () => {
- await runTest('/astro/component-astro-response-cookie-multi', {
- 'content-type': 'text/html',
- 'set-cookie': ['from1=response1', 'from2=response2', 'from3=astro1', 'from4=astro2'],
- });
- });
-
+ /** @type {import('./test-utils').Fixture} */
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/headers/',
+ output: 'server',
+ adapter: nodejs({ mode: 'middleware' }),
+ });
+ await fixture.build();
+ });
+
+ it('Endpoint Simple Headers', async () => {
+ await runTest('/endpoints/simple', {
+ 'content-type': 'text/plain;charset=utf-8',
+ 'x-hello': 'world',
+ });
+ });
+
+ it('Endpoint Astro Single Cookie Header', async () => {
+ await runTest('/endpoints/astro-cookies-single', {
+ 'content-type': 'text/plain;charset=utf-8',
+ 'set-cookie': 'from1=astro1',
+ });
+ });
+
+ it('Endpoint Astro Multi Cookie Header', async () => {
+ await runTest('/endpoints/astro-cookies-multi', {
+ 'content-type': 'text/plain;charset=utf-8',
+ 'set-cookie': ['from1=astro1', 'from2=astro2'],
+ });
+ });
+
+ it('Endpoint Response Single Cookie Header', async () => {
+ await runTest('/endpoints/response-cookies-single', {
+ 'content-type': 'text/plain;charset=utf-8',
+ 'set-cookie': 'hello1=world1',
+ });
+ });
+
+ it('Endpoint Response Multi Cookie Header', async () => {
+ await runTest('/endpoints/response-cookies-multi', {
+ 'content-type': 'text/plain;charset=utf-8',
+ 'set-cookie': ['hello1=world1', 'hello2=world2'],
+ });
+ });
+
+ it('Endpoint Complex Headers Kitchen Sink', async () => {
+ await runTest('/endpoints/kitchen-sink', {
+ 'content-type': 'text/plain;charset=utf-8',
+ 'x-single': 'single',
+ 'x-triple': 'one, two, three',
+ 'set-cookie': ['hello1=world1', 'hello2=world2'],
+ });
+ });
+
+ it('Endpoint Astro and Response Single Cookie Header', async () => {
+ await runTest('/endpoints/astro-response-cookie-single', {
+ 'content-type': 'text/plain;charset=utf-8',
+ 'set-cookie': ['from1=response1', 'from1=astro1'],
+ });
+ });
+
+ it('Endpoint Astro and Response Multi Cookie Header', async () => {
+ await runTest('/endpoints/astro-response-cookie-multi', {
+ 'content-type': 'text/plain;charset=utf-8',
+ 'set-cookie': ['from1=response1', 'from2=response2', 'from3=astro1', 'from4=astro2'],
+ });
+ });
+
+ it('Endpoint Response Empty Headers Object', async () => {
+ await runTest('/endpoints/response-empty-headers-object', {
+ 'content-type': 'text/plain;charset=UTF-8',
+ });
+ });
+
+ it('Endpoint Response undefined Headers Object', async () => {
+ await runTest('/endpoints/response-undefined-headers-object', {
+ 'content-type': 'text/plain;charset=UTF-8',
+ });
+ });
+
+ it('Component Astro Single Cookie Header', async () => {
+ await runTest('/astro/component-astro-cookies-single', {
+ 'content-type': 'text/html',
+ 'set-cookie': 'from1=astro1',
+ });
+ });
+
+ it('Component Astro Multi Cookie Header', async () => {
+ await runTest('/astro/component-astro-cookies-multi', {
+ 'content-type': 'text/html',
+ 'set-cookie': ['from1=astro1', 'from2=astro2'],
+ });
+ });
+
+ it('Component Response Single Cookie Header', async () => {
+ await runTest('/astro/component-response-cookies-single', {
+ 'content-type': 'text/html',
+ 'set-cookie': 'from1=value1',
+ });
+ });
+
+ it('Component Response Multi Cookie Header', async () => {
+ await runTest('/astro/component-response-cookies-multi', {
+ 'content-type': 'text/html',
+ 'set-cookie': ['from1=value1', 'from2=value2'],
+ });
+ });
+
+ it('Component Astro and Response Single Cookie Header', async () => {
+ await runTest('/astro/component-astro-response-cookie-single', {
+ 'content-type': 'text/html',
+ 'set-cookie': ['from1=response1', 'from1=astro1'],
+ });
+ });
+
+ it('Component Astro and Response Multi Cookie Header', async () => {
+ await runTest('/astro/component-astro-response-cookie-multi', {
+ 'content-type': 'text/html',
+ 'set-cookie': ['from1=response1', 'from2=response2', 'from3=astro1', 'from4=astro2'],
+ });
+ });
});
async function runTest(url, expectedHeaders) {
- const { handler } = await import('./fixtures/headers/dist/server/entry.mjs');
+ const { handler } = await import('./fixtures/headers/dist/server/entry.mjs');
- let { req, res, done } = createRequestAndResponse({
- method: 'GET',
- url,
- });
+ let { req, res, done } = createRequestAndResponse({
+ method: 'GET',
+ url,
+ });
- handler(req, res);
+ handler(req, res);
- req.send();
+ req.send();
- await done;
- const headers = res.getHeaders();
+ await done;
+ const headers = res.getHeaders();
- expect(headers).to.deep.equal(expectedHeaders);
-} \ No newline at end of file
+ expect(headers).to.deep.equal(expectedHeaders);
+}