Skip to content

Instantly share code, notes, and snippets.

@lokshunhung
Last active September 19, 2023 04:49
Show Gist options
  • Save lokshunhung/06f3ea51c5e33e855174abf57c4f092c to your computer and use it in GitHub Desktop.
Save lokshunhung/06f3ea51c5e33e855174abf57c4f092c to your computer and use it in GitHub Desktop.
Serialize browser fetch Request
// @ts-check
"use strict";
/** @param {*} value @returns {value is string} */
const isString = value => typeof value === "string";
/** @param {*} value @returns {value is RegExp} */
const isRegExp = value => value instanceof RegExp;
class Santinizer {
#redactStr;
#redactRe;
/** @param {{ redact: Array<string | RegExp> }} _ */
constructor({ redact }) {
this.#redactStr = new Set(redact.filter(isString));
this.#redactRe = redact.filter(isRegExp);
}
/**
* @template {URLSearchParams | Headers | object} T
* @param {T} target
* @returns {Promise<T>}
*/
async redact(target) {
if (target instanceof URLSearchParams) {
target.forEach((value, key, dict) => {
if (this.#redactStr.has(key) || this.#redactRe.some(re => re.test(key))) {
dict.set(key, "--REDACTED--");
}
});
return target;
}
if (target instanceof Headers) {
target.forEach((value, key, dict) => {
if (this.#redactStr.has(key) || this.#redactRe.some(re => re.test(key))) {
dict.set(key, "--REDACTED--");
}
});
return target;
}
return this.#redactObject(target);
}
#redactObject(target) {
if (target && typeof target === "object") {
Object.keys(target).forEach(key => {
if (this.#redactStr.has(key) || this.#redactRe.some(re => re.test(key))) {
target[key] = "--REDACTED--";
} else {
this.#redactObject(target[key]);
}
});
}
return target;
}
}
/** @param {Request} request @param {{ redact?: Array<string | RegExp> }} _ @returns {Promise<object>} */
async function serializeRequest(request, { redact = [] } = {}) {
const santinizer = new Santinizer({ redact });
const url = new URL(request.url);
santinizer.redact(url.searchParams);
const headers = new Headers(request.headers);
santinizer.redact(headers);
let body = "--UNKNOWN--";
if (request.headers.get("content-type") === "application/json") {
body = await request.clone().json();
santinizer.redact(body);
}
return {
method: request.method,
url: url.toString(),
headers: Array.from(headers.entries()),
body,
};
}
module.exports = {
serializeRequest,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment