@pent4gon/fetch
Version:
A modern fetch wrapper with cookie support, written in TypeScript.
66 lines (65 loc) • 2.25 kB
JavaScript
import { CookieJar } from "tough-cookie";
import fetchcookie from "fetch-cookie";
export class MyFetchError extends Error {
constructor(status, finalUrl, responseBody) {
super(`fetch failed...
status: ${status}
finalUrl: ${finalUrl}
responseBody: ${responseBody}
`);
this.status = status;
this.finalUrl = finalUrl;
this.responseBody = responseBody;
}
}
export default class MyFetch {
constructor({ cookieJar = new CookieJar(), defaultHeaders = {} } = {}) {
this.cookieJar = cookieJar;
this.fetchCookie = fetchcookie(fetch, this.cookieJar);
this.defaultHeaders = defaultHeaders;
}
async fetch(url, init) {
try {
const mergedHeaders = new Headers(this.defaultHeaders);
if (init?.headers) {
new Headers(init.headers).forEach((value, key) => {
mergedHeaders.set(key, value);
});
}
const response = await this.fetchCookie(url, { ...init, headers: mergedHeaders });
if (!response.ok) {
throw new MyFetchError(response.status, response.url, await response.text());
}
return response;
}
catch (e) {
if (e instanceof MyFetchError) {
throw e;
}
else {
const errorMessage = e instanceof Error ? e.message : String(e);
throw new MyFetchError(1000, url.toString(), errorMessage);
}
}
}
static create({ cookieJar, defaultHeaders = {} } = {}) {
const instance = new MyFetch({ cookieJar, defaultHeaders });
const myFetch = instance.fetch.bind(instance);
Object.assign(myFetch, instance);
Object.setPrototypeOf(myFetch, MyFetch.prototype);
return myFetch;
}
getCookieJar() {
return this.cookieJar.serializeSync();
}
setCookieJar(cookieJar) {
this.cookieJar = cookieJar;
this.fetchCookie = fetchcookie(fetch, this.cookieJar);
}
getDefaultHeaders() {
return this.defaultHeaders;
}
setDefaultHeaders(defaultHeaders) {
this.defaultHeaders = defaultHeaders;
}
}