securityos/node_modules/next/dist/server/web/spec-extension/adapters/headers.js

192 lines
7.3 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
ReadonlyHeadersError: null,
HeadersAdapter: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
ReadonlyHeadersError: function() {
return ReadonlyHeadersError;
},
HeadersAdapter: function() {
return HeadersAdapter;
}
});
const _reflect = require("./reflect");
class ReadonlyHeadersError extends Error {
constructor(){
super("Headers cannot be modified. Read more: https://nextjs.org/docs/app/api-reference/functions/headers");
}
static callable() {
throw new ReadonlyHeadersError();
}
}
class HeadersAdapter extends Headers {
constructor(headers){
// We've already overridden the methods that would be called, so we're just
// calling the super constructor to ensure that the instanceof check works.
super();
this.headers = new Proxy(headers, {
get (target, prop, receiver) {
// Because this is just an object, we expect that all "get" operations
// are for properties. If it's a "get" for a symbol, we'll just return
// the symbol.
if (typeof prop === "symbol") {
return _reflect.ReflectAdapter.get(target, prop, receiver);
}
const lowercased = prop.toLowerCase();
// Let's find the original casing of the key. This assumes that there is
// no mixed case keys (e.g. "Content-Type" and "content-type") in the
// headers object.
const original = Object.keys(headers).find((o)=>o.toLowerCase() === lowercased);
// If the original casing doesn't exist, return undefined.
if (typeof original === "undefined") return;
// If the original casing exists, return the value.
return _reflect.ReflectAdapter.get(target, original, receiver);
},
set (target, prop, value, receiver) {
if (typeof prop === "symbol") {
return _reflect.ReflectAdapter.set(target, prop, value, receiver);
}
const lowercased = prop.toLowerCase();
// Let's find the original casing of the key. This assumes that there is
// no mixed case keys (e.g. "Content-Type" and "content-type") in the
// headers object.
const original = Object.keys(headers).find((o)=>o.toLowerCase() === lowercased);
// If the original casing doesn't exist, use the prop as the key.
return _reflect.ReflectAdapter.set(target, original ?? prop, value, receiver);
},
has (target, prop) {
if (typeof prop === "symbol") return _reflect.ReflectAdapter.has(target, prop);
const lowercased = prop.toLowerCase();
// Let's find the original casing of the key. This assumes that there is
// no mixed case keys (e.g. "Content-Type" and "content-type") in the
// headers object.
const original = Object.keys(headers).find((o)=>o.toLowerCase() === lowercased);
// If the original casing doesn't exist, return false.
if (typeof original === "undefined") return false;
// If the original casing exists, return true.
return _reflect.ReflectAdapter.has(target, original);
},
deleteProperty (target, prop) {
if (typeof prop === "symbol") return _reflect.ReflectAdapter.deleteProperty(target, prop);
const lowercased = prop.toLowerCase();
// Let's find the original casing of the key. This assumes that there is
// no mixed case keys (e.g. "Content-Type" and "content-type") in the
// headers object.
const original = Object.keys(headers).find((o)=>o.toLowerCase() === lowercased);
// If the original casing doesn't exist, return true.
if (typeof original === "undefined") return true;
// If the original casing exists, delete the property.
return _reflect.ReflectAdapter.deleteProperty(target, original);
}
});
}
/**
* Seals a Headers instance to prevent modification by throwing an error when
* any mutating method is called.
*/ static seal(headers) {
return new Proxy(headers, {
get (target, prop, receiver) {
switch(prop){
case "append":
case "delete":
case "set":
return ReadonlyHeadersError.callable;
default:
return _reflect.ReflectAdapter.get(target, prop, receiver);
}
}
});
}
/**
* Merges a header value into a string. This stores multiple values as an
* array, so we need to merge them into a string.
*
* @param value a header value
* @returns a merged header value (a string)
*/ merge(value) {
if (Array.isArray(value)) return value.join(", ");
return value;
}
/**
* Creates a Headers instance from a plain object or a Headers instance.
*
* @param headers a plain object or a Headers instance
* @returns a headers instance
*/ static from(headers) {
if (headers instanceof Headers) return headers;
return new HeadersAdapter(headers);
}
append(name, value) {
const existing = this.headers[name];
if (typeof existing === "string") {
this.headers[name] = [
existing,
value
];
} else if (Array.isArray(existing)) {
existing.push(value);
} else {
this.headers[name] = value;
}
}
delete(name) {
delete this.headers[name];
}
get(name) {
const value = this.headers[name];
if (typeof value !== "undefined") return this.merge(value);
return null;
}
has(name) {
return typeof this.headers[name] !== "undefined";
}
set(name, value) {
this.headers[name] = value;
}
forEach(callbackfn, thisArg) {
for (const [name, value] of this.entries()){
callbackfn.call(thisArg, value, name, this);
}
}
*entries() {
for (const key of Object.keys(this.headers)){
const name = key.toLowerCase();
// We assert here that this is a string because we got it from the
// Object.keys() call above.
const value = this.get(name);
yield [
name,
value
];
}
}
*keys() {
for (const key of Object.keys(this.headers)){
const name = key.toLowerCase();
yield name;
}
}
*values() {
for (const key of Object.keys(this.headers)){
// We assert here that this is a string because we got it from the
// Object.keys() call above.
const value = this.get(key);
yield value;
}
}
[Symbol.iterator]() {
return this.entries();
}
}
//# sourceMappingURL=headers.js.map