0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-23 21:53:55 -05:00
astro/packages/integrations/node/src/createOutgoingHttpHeaders.ts
Erika f14e48098a
nit: use node: prefix everywhere (#7692)
* nit: use `node:` prefix everywhere

* nit: fs/promises too

* test: workaround issue in node builtin detection
2023-07-18 02:17:59 +02:00

42 lines
1.5 KiB
TypeScript

import type { OutgoingHttpHeaders } from 'node: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;
}
// 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());
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;
}
}
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[];
}