EdgeAIG's picture
download
raw
8.35 kB
/**
* Models HTTP headers for the unstable HTTP client and server modules.
*
* `Headers` values are immutable maps keyed by lowercase header name. This
* module converts common header inputs into that shape, provides helpers for
* reading and updating header values, and redacts configured sensitive headers
* when values are inspected.
*
* @since 4.0.0
*/
import * as Context from "../../Context.js";
import * as Equal from "../../Equal.js";
import * as Equ from "../../Equivalence.js";
import { dual } from "../../Function.js";
import * as Hash from "../../Hash.js";
import * as Inspectable from "../../Inspectable.js";
import * as Option from "../../Option.js";
import * as Predicate from "../../Predicate.js";
import * as Record from "../../Record.js";
import * as Redactable from "../../Redactable.js";
import * as Redacted from "../../Redacted.js";
import * as Schema from "../../Schema.js";
import * as SchemaTransformation from "../../SchemaTransformation.js";
/**
* Runtime type identifier for `Headers` values.
*
* @category type IDs
* @since 4.0.0
*/
export const TypeId = /*#__PURE__*/Symbol.for("~effect/http/Headers");
/**
* Returns `true` if the provided value is a `Headers` value.
*
* @category refinements
* @since 4.0.0
*/
export const isHeaders = u => Predicate.hasProperty(u, TypeId);
// the properties are folded into the initializer (rather than a separate
// `Object.defineProperties(Proto, ...)` statement) so the whole definition
// is pure-annotated by the build and tree-shakable.
const Proto = /*#__PURE__*/Object.defineProperties(/*#__PURE__*/Object.create(null), {
[TypeId]: {
value: TypeId
},
[Redactable.symbolRedactable]: {
value(context) {
return redact(this, Context.get(context, CurrentRedactedNames));
}
},
toJSON: {
value() {
return Redactable.redact(this);
}
},
[Equal.symbol]: {
value(that) {
return Equivalence(this, that);
}
},
[Hash.symbol]: {
value() {
return Hash.structure(this);
}
},
toString: {
value: Inspectable.BaseProto.toString
},
[Inspectable.NodeInspectSymbol]: {
value: Inspectable.BaseProto[Inspectable.NodeInspectSymbol]
}
});
const make = input => Object.assign(Object.create(Proto), input);
/**
* Provides an `Equivalence` instance that compares `Headers` by header names
* and string values.
*
* @category instances
* @since 4.0.0
*/
export const Equivalence = /*#__PURE__*/Record.makeEquivalence(/*#__PURE__*/Equ.strictEqual());
/**
* Schema for `Headers` values encoded as records of string header values.
*
* **Details**
*
* Decoding normalizes header names through `fromInput`; encoding returns a plain record.
*
* @category schemas
* @since 4.0.0
*/
export const HeadersSchema = /*#__PURE__*/Schema.declare(isHeaders, {
typeConstructor: {
_tag: "effect/http/Headers"
},
generation: {
runtime: `Headers.HeadersSchema`,
Type: `Headers.Headers`,
Encoded: `typeof Headers.HeadersSchema["Encoded"]`,
importDeclaration: `import * as Headers from "effect/unstable/http/Headers"`
},
expected: "Headers",
toEquivalence: () => Equivalence,
toCodec: () => Schema.link()(Schema.Record(Schema.String, Schema.String), SchemaTransformation.transform({
decode: input => fromInput(input),
encode: headers => ({
...headers
})
}))
});
/**
* An empty `Headers` collection.
*
* @category constructors
* @since 4.0.0
*/
export const empty = /*#__PURE__*/Object.create(Proto);
/**
* Creates `Headers` from a record or iterable of header entries.
*
* **Details**
*
* Header names are normalized to lowercase. Array values in record input are joined with `", "`, and `undefined` values are omitted.
*
* @category constructors
* @since 4.0.0
*/
export const fromInput = input => {
if (input === undefined) {
return empty;
} else if (Symbol.iterator in input) {
const out = Object.create(Proto);
for (const [k, v] of input) {
out[k.toLowerCase()] = v;
}
return out;
}
const out = Object.create(Proto);
for (const [k, v] of Object.entries(input)) {
if (Array.isArray(v)) {
out[k.toLowerCase()] = v.join(", ");
} else if (v !== undefined) {
out[k.toLowerCase()] = v;
}
}
return out;
};
/**
* Treats an existing record as `Headers` unsafely.
*
* **Gotchas**
*
* This mutates the record's prototype and does not normalize header names; callers must provide the expected lowercase keys.
*
* @category constructors
* @since 4.0.0
*/
export const fromRecordUnsafe = input => Object.setPrototypeOf(input, Proto);
/**
* Returns `true` when a header with the given name is present.
*
* **Details**
*
* The lookup lowercases the provided header name.
*
* @category combinators
* @since 4.0.0
*/
export const has = /*#__PURE__*/dual(2, (self, key) => key.toLowerCase() in self);
/**
* Gets a header value by name safely.
*
* **Details**
*
* The lookup lowercases the provided header name and returns `Option.none()` when absent.
*
* @category combinators
* @since 4.0.0
*/
export const get = /*#__PURE__*/dual(2, (self, key) => Option.fromUndefinedOr(self[key.toLowerCase()]));
/**
* Returns a new `Headers` collection with the given header set.
*
* **Details**
*
* The header name is normalized to lowercase.
*
* @category combinators
* @since 4.0.0
*/
export const set = /*#__PURE__*/dual(3, (self, key, value) => {
const out = make(self);
out[key.toLowerCase()] = value;
return out;
});
/**
* Returns a new `Headers` collection with all provided headers set.
*
* **Details**
*
* Input headers are normalized with `fromInput` and override existing headers with the same lowercase name.
*
* @category combinators
* @since 4.0.0
*/
export const setAll = /*#__PURE__*/dual(2, (self, headers) => make({
...self,
...fromInput(headers)
}));
/**
* Returns a new `Headers` collection containing headers from both collections.
*
* **Details**
*
* Headers from the second collection override headers from the first collection with the same name.
*
* @category combinators
* @since 4.0.0
*/
export const merge = /*#__PURE__*/dual(2, (self, headers) => {
const out = make(self);
Object.assign(out, headers);
return out;
});
/**
* Returns a new `Headers` collection with the named header removed.
*
* **Details**
*
* The provided header name is normalized to lowercase before removal.
*
* @category combinators
* @since 4.0.0
*/
export const remove = /*#__PURE__*/dual(2, (self, key) => {
const out = make(self);
delete out[key.toLowerCase()];
return out;
});
/**
* Returns a new `Headers` collection with each named header removed.
*
* **Details**
*
* Each provided header name is normalized to lowercase before removal.
*
* @category combinators
* @since 4.0.0
*/
export const removeMany = /*#__PURE__*/dual(2, (self, keys) => {
const out = make(self);
for (const key of keys) {
delete out[key.toLowerCase()];
}
return out;
});
/**
* Returns a plain record with selected header values wrapped in `Redacted`.
*
* **Details**
*
* String keys are normalized to lowercase before matching; regular expressions are tested against the stored header names.
*
* @category combinators
* @since 4.0.0
*/
export const redact = /*#__PURE__*/dual(2, (self, key) => {
const out = {
...self
};
const modify = key => {
if (typeof key === "string") {
const k = key.toLowerCase();
if (k in self) {
out[k] = Redacted.make(self[k]);
}
} else {
for (const name in self) {
if (key.test(name)) {
out[name] = Redacted.make(self[name]);
}
}
}
};
if (Array.isArray(key)) {
for (let i = 0; i < key.length; i++) {
modify(key[i]);
}
} else {
modify(key);
}
return out;
});
/**
* Context reference listing header names or patterns that should be redacted when `Headers` are inspected or rendered.
*
* **Details**
*
* Defaults include `authorization`, `cookie`, `set-cookie`, and `x-api-key`.
*
* @category fiber refs
* @since 4.0.0
*/
export const CurrentRedactedNames = /*#__PURE__*/Context.Reference("effect/Headers/CurrentRedactedNames", {
defaultValue: () => ["authorization", "cookie", "set-cookie", "x-api-key"]
});
//# sourceMappingURL=Headers.js.map

Xet Storage Details

Size:
8.35 kB
·
Xet hash:
3c06167bccf2a559963013ef32ec3606c03c6443701ff97ec122edcd9d6425a8

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.