@clickup/rest-client
Version:
A syntax sugar tool around Node fetch() API, tailored to work with TypeScript and response validators
34 lines (31 loc) • 1.55 kB
text/typescript
import type { Response } from "node-fetch";
const CHARSET_RE =
/(?:charset|encoding)\s{0,10}=\s{0,10}['"]? {0,10}([-\w]{1,100})/i;
const BUFFER_ENCODINGS = ["ascii", "utf8", "utf-8", "utf16le", "ucs2", "ucs-2"];
/**
* Tries its best to infer the encoding of the Response, falling back to UTF-8
* as an opinionated default value on failure.
*/
export default function inferResBodyEncoding(res: Response): BufferEncoding {
const contentType = res.headers.get("content-type")?.toLowerCase();
const charset = contentType?.match(CHARSET_RE)
? RegExp.$1.toLowerCase()
: undefined;
return contentType?.startsWith("application/octet-stream")
? // It's a binary Content-Type.
"binary"
: charset && !BUFFER_ENCODINGS.includes(charset)
? // The charset is provided in Content-Type, but unknown by Buffer.
"binary"
: charset && BUFFER_ENCODINGS.includes(charset)
? // Charset is provided in Content-Type header, and Buffer knows
// how to decode it.
(charset as BufferEncoding)
: // An opinionated choice is made here to always default-decode the
// response stream as UTF-8. This is because JSON is by definition a UTF-8
// stream, and people often time respond with JSONs forgetting to provide
// "; charset=utf-8" part of the Content-Type header (or they forget
// Content-Type header at all, or put some wrong value as "text/plain"
// there; there is an endless list of mistake variations here).
"utf-8";
}