Skip to content

Commit

Permalink
feat: handle headers with arr values (#1007)
Browse files Browse the repository at this point in the history
  • Loading branch information
agerard-godaddy authored Jan 13, 2025
1 parent 00ad46c commit 6681179
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 7 deletions.
2 changes: 1 addition & 1 deletion packages/gasket-request/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { RequestLike } from '../internal.d.ts';
import type { Gasket } from '@gasket/core';

export type RequestLike = {
headers: Headers | Record<string, string>
headers: Headers | Record<string, string | string[]>
cookies?: CookieStore | Record<string, string>
query?: URLSearchParams | Record<string, string>
url?: string
Expand Down
23 changes: 17 additions & 6 deletions packages/gasket-request/lib/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,26 @@ export async function makeGasketRequest(requestLike) {
return requestLike;
}

const { headers, cookies = {} } = requestLike;
const { headers: rawHeaders, cookies = {} } = requestLike;

if (!headers) {
if (!rawHeaders) {
throw new Error('request argument must have headers');
}

if (!keeper.has(headers)) {
if (!keeper.has(rawHeaders)) {
const normalize = async () => {

// handle Headers objects
const headers = 'entries' in rawHeaders ? Object.fromEntries(rawHeaders.entries()) : rawHeaders;

// handle when header values are arrays
// https://nodejs.org/api/http.html#messageheadersdistinct
Object.entries(headers).forEach(([key, value]) => {
if (Array.isArray(value)) {
headers[key] = value.join(', ');
}
});

// handle Express Request objects
let query = requestLike.query;
let path = requestLike.path;
Expand All @@ -79,14 +90,14 @@ export async function makeGasketRequest(requestLike) {
path ??= '';

return new GasketRequest(Object.seal({
headers: 'entries' in headers ? Object.fromEntries(headers.entries()) : headers,
headers,
cookies: 'getAll' in cookies ? await objectFromCookieStore(cookies) : cookies,
query: query instanceof URLSearchParams ? objectFromSearchParams(query) : query,
path
}));
};

keeper.set(headers, normalize());
keeper.set(rawHeaders, normalize());
}
return keeper.get(headers);
return keeper.get(rawHeaders);
}
10 changes: 10 additions & 0 deletions packages/gasket-request/test/request.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,16 @@ describe('makeGasketRequest', () => {
expect(result.path).toEqual('/path/to/page');
});

it('handles IncomingMessage with headersDistinct shape (IncomingHttpHeaders)', async () => {
/** @type {IncomingHttpHeaders} */
const headers = { header1: 'value1', header2: ['value2'], header3: ['value3-1', 'value3-2'] };
const requestLike = { headers };

const result = await makeGasketRequest(requestLike);

expect(result.headers).toEqual({ header1: 'value1', header2: 'value2', header3: 'value3-1, value3-2' });
});

it('only processes url if query or path not set', async () => {
const query = {
query1: 'value1',
Expand Down

0 comments on commit 6681179

Please sign in to comment.