import fetch from "node-fetch"; import * as responses from "./responses"; import * as queryString from "qs"; export default class { readonly baseUrl: string; requestId: number; readonly baseHeaders: { [key: string]: string }; constructor(baseUrl: string) { this.baseUrl = baseUrl; this.requestId = 0; this.baseHeaders = { "Content-Type": "application/json; charset=utf-8", }; } buildHeaders() { return { ...this.baseHeaders, }; } async call(method: string, path: string, body?: string): Promise> { return this.callAny(method, path, body); } async callAny(method: string, path: string, body?: string) { const url = `${this.baseUrl}${path}`; const requestId = ++this.requestId; if (requestId) { // 警告回避用。requestIdはそのうちデバッグで使うかも程度 } const headers = this.buildHeaders(); const response = await fetch(url, { method, headers, body, }); // 403は"認可失敗"で、無効なトークン等でトークンの認可に失敗した場合に返ってくる仕様があり、 // 本仕様に準じて、これだけ専用エラーを発行 // TODO: 現状は401が返ってきてしまうこともあるようなので、まとめてトラップしてしまう if (response.status === 403 || response.status === 401) { const error = new responses.PermissionDeniedError(response); await error.tryParse(); throw error; } if (response.status < 200 || response.status >= 300) { const error = new responses.AkashicError(response); await error.tryParse(); throw error; } return response.json(); } qs( params: NodeJS.Dict< string | number | boolean | ReadonlyArray | ReadonlyArray | ReadonlyArray | null > ) { return queryString.stringify(params); } }