@stuntman/shared
Version:
Stuntman - HTTP proxy / mock shared types and utils
106 lines • 3.6 kB
JavaScript
export class RawHeaders extends Array {
get(name) {
const headers = this.toHeaderPairs();
const matchingHeaders = headers.filter((h) => h[0].toLowerCase() === name.toLowerCase());
if (matchingHeaders.length === 0) {
return undefined;
}
if (matchingHeaders.length === 1) {
return matchingHeaders[0][1];
}
throw new Error('Multiple headers with same name. Manipulate rawHeaders instead');
}
has(name, value) {
const foundValue = this.get(name);
if (value === undefined) {
return foundValue !== undefined;
}
return foundValue === value;
}
set(name, value) {
let foundIndex = -1;
for (let headerIndex = 0; headerIndex < this.length; headerIndex += 2) {
if (this[headerIndex].toLowerCase() === name.toLowerCase()) {
if (foundIndex !== -1) {
throw new Error('Multiple headers with same name. Manipulate rawHeaders instead');
}
foundIndex = headerIndex;
}
}
if (foundIndex === -1) {
this.add(name, value);
return;
}
this[foundIndex + 1] = value;
}
add(name, value) {
this.push(name);
this.push(value);
}
remove(name) {
const headersCopy = [...this];
let foundIndex = -1;
for (let headerIndex = 0; headerIndex < headersCopy.length; headerIndex += 2) {
if (this[headerIndex].toLowerCase() === name.toLowerCase()) {
if (foundIndex !== -1) {
throw new Error('Multiple headers with same name. Manipulate rawHeaders instead');
}
foundIndex = headerIndex;
}
}
if (foundIndex === -1) {
return;
}
this.splice(foundIndex, 2);
}
toHeaderPairs() {
return RawHeaders.toHeaderPairs(this);
}
toHeadersRecord() {
return RawHeaders.toHeadersRecord(this);
}
static fromHeaderPairs(headerPairs) {
return new RawHeaders(...headerPairs.flatMap((x) => x));
}
static fromHeadersRecord(headersRecord) {
const output = new RawHeaders();
for (const [key, value] of Object.entries(headersRecord)) {
if (typeof value === 'string' || value === undefined) {
output.add(key, value ?? '');
continue;
}
for (const subValue of value) {
output.add(key, subValue);
}
}
return output;
}
static toHeadersRecord(rawHeaders) {
const output = {};
const headerPairs = RawHeaders.toHeaderPairs(rawHeaders);
for (const [key, value] of headerPairs) {
if (!output[key]) {
output[key] = value;
continue;
}
else if (typeof output[key] === 'string') {
output[key] = [output[key], value];
}
else if (Array.isArray(output[key])) {
output[key].push(value);
}
else {
throw new Error('unexpected error');
}
}
return output;
}
static toHeaderPairs(rawHeaders) {
const headers = new Array();
for (let headerIndex = 0; headerIndex < rawHeaders.length; headerIndex += 2) {
headers.push([rawHeaders[headerIndex], rawHeaders[headerIndex + 1]]);
}
return headers;
}
}
//# sourceMappingURL=rawHeaders.js.map