UNPKG

masto

Version:

Mastodon API client for JavaScript, TypeScript, Node.js, browsers

82 lines (81 loc) 3.2 kB
import { MastoHttpError, MastoTimeoutError, MastoUnexpectedError, } from "../errors/index.js"; import { BaseHttp } from "./base-http.js"; import { getEncoding } from "./get-encoding.js"; export class HttpNativeImpl extends BaseHttp { serializer; config; logger; constructor(serializer, config, logger) { super(); this.serializer = serializer; this.config = config; this.logger = logger; } async request(params) { const request = this.createRequest(params); try { this.logger?.log("info", `↑ ${request.method} ${request.url}`); this.logger?.log("debug", "\tbody", { encoding: params.encoding, body: params.body, }); const response = await fetch(request); if (!response.ok) { throw response; } const text = await response.text(); const encoding = getEncoding(response.headers); if (!encoding) { throw new MastoUnexpectedError("The server returned data with an unknown encoding."); } const data = this.serializer.deserialize(encoding, text); this.logger?.log("info", `↓ ${request.method} ${request.url}`); this.logger?.log("debug", "\tbody", text); return { headers: response.headers, data: data, }; } catch (error) { this.logger?.log("debug", `HTTP failed`, error); throw await this.createError(error); } } createRequest(params) { const { method, path, search, encoding = "json", requestInit = {}, } = params; const url = this.config.resolvePath(path, search); const body = this.serializer.serialize(encoding, params.body); const init = this.config.mergeRequestInitWithDefaults(requestInit); const request = new Request(url, { method, body, ...init, }); if (typeof body === "string" && encoding === "json") { request.headers.set("Content-Type", "application/json"); } return request; } async createError(error) { if (error instanceof Response) { const encoding = getEncoding(error.headers); if (!encoding) { throw new MastoUnexpectedError("The server returned data with an unknown encoding. The server may be down."); } const data = this.serializer.deserialize(encoding, await error.text()); const { error: message, errorDescription, details, ...additionalProperties } = data; return new MastoHttpError({ statusCode: error.status, message: message, description: errorDescription, details: details, additionalProperties, }, { cause: error }); } if (error instanceof DOMException && error.name === "TimeoutError") { return new MastoTimeoutError(`Request timed out`, { cause: error }); } /* c8 ignore next */ return error; } }