From 0b587f4233daa08ac6aae23c09eef0c8f563bed9 Mon Sep 17 00:00:00 2001 From: Taku Amano Date: Thu, 31 Oct 2024 18:59:20 +0900 Subject: [PATCH] fix(utils): accept HeadersInit, null, undefined in buildOutgoingHttpHeaders --- src/utils.ts | 13 ++++----- test/utils.test.ts | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 test/utils.test.ts diff --git a/src/utils.ts b/src/utils.ts index d73e6fb..c704c93 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -42,24 +42,21 @@ export function writeFromReadableStream(stream: ReadableStream, writ } export const buildOutgoingHttpHeaders = ( - headers: Headers | Record + headers: Headers | HeadersInit | null | undefined ): OutgoingHttpHeaders => { const res: OutgoingHttpHeaders = {} + if (!(headers instanceof Headers)) { + headers = new Headers(headers ?? undefined) + } const cookies = [] - const entries = - headers instanceof Headers - ? headers.entries() - : Object.entries(headers).filter(([, value]) => value) - - for (const [k, v] of entries) { + for (const [k, v] of headers) { if (k === 'set-cookie') { cookies.push(v) } else { res[k] = v } } - if (cookies.length > 0) { res['set-cookie'] = cookies } diff --git a/test/utils.test.ts b/test/utils.test.ts new file mode 100644 index 0000000..3673c5f --- /dev/null +++ b/test/utils.test.ts @@ -0,0 +1,73 @@ +import { buildOutgoingHttpHeaders } from '../src/utils' + +describe('buildOutgoingHttpHeaders', () => { + it('original content-type is preserved', () => { + const headers = new Headers({ + a: 'b', + 'content-type': 'text/html; charset=UTF-8', + }) + const result = buildOutgoingHttpHeaders(headers) + expect(result).toEqual({ + a: 'b', + 'content-type': 'text/html; charset=UTF-8', + }) + }) + + it('multiple set-cookie', () => { + const headers = new Headers() + headers.append('set-cookie', 'a') + headers.append('set-cookie', 'b') + const result = buildOutgoingHttpHeaders(headers) + expect(result).toEqual({ + 'set-cookie': ['a', 'b'], + 'content-type': 'text/plain; charset=UTF-8', + }) + }) + + it('Headers', () => { + const headers = new Headers({ + a: 'b', + }) + const result = buildOutgoingHttpHeaders(headers) + expect(result).toEqual({ + a: 'b', + 'content-type': 'text/plain; charset=UTF-8', + }) + }) + + it('Record', () => { + const headers = { + a: 'b', + 'Set-Cookie': 'c', // case-insensitive + } + const result = buildOutgoingHttpHeaders(headers) + expect(result).toEqual({ + a: 'b', + 'set-cookie': ['c'], + 'content-type': 'text/plain; charset=UTF-8', + }) + }) + + it('Record[]', () => { + const headers: HeadersInit = [['a', 'b']] + const result = buildOutgoingHttpHeaders(headers) + expect(result).toEqual({ + a: 'b', + 'content-type': 'text/plain; charset=UTF-8', + }) + }) + + it('null', () => { + const result = buildOutgoingHttpHeaders(null) + expect(result).toEqual({ + 'content-type': 'text/plain; charset=UTF-8', + }) + }) + + it('undefined', () => { + const result = buildOutgoingHttpHeaders(undefined) + expect(result).toEqual({ + 'content-type': 'text/plain; charset=UTF-8', + }) + }) +})