import firebase from "../lib/firebase" type ResponseType = "text" | "blob" interface RequestOptions extends RequestInit { requireJSON?: boolean } export default (firebase: any, log = console.log) => { // TODO: assign firebase type const token = async () => { return firebase.auth().currentUser?.getIdToken() } async function doRequest( url: string, options?: RequestOptions, responseType?: ResponseType ): Promise async function doRequest( url: string, options?: RequestOptions, responseType?: ResponseType ): Promise async function doRequest( url: string, options?: RequestOptions, responseType = "text" ) { log("request: fetching", url) const headers = new Headers() headers.append("Authorization", `Bearer ${await token()}`) headers.append("Content-Type", "application/json; charset=utf-8") let response try { response = await fetch(url, { headers, ...options, mode: 'cors' }) } catch (err) { log("request: network error making request", err) throw err } const result = await parseResponse( response, options?.requireJSON, responseType as ResponseType ) log("request: result", result) return result } async function parseResponse( res: Response, requireJSON?: boolean, responseType?: ResponseType ): Promise async function parseResponse( res: Response, requireJSON?: boolean, responseType?: ResponseType ): Promise async function parseResponse( res: Response, requireJSON?: boolean, responseType?: ResponseType ) { const text = await res[responseType as ResponseType]() log("response status: ", res.status, text) if (res.status >= 300) { throw new Error(`${res.status} ${text}`) } try { return JSON.parse(text as string) } catch (e) { if (requireJSON) { throw new Error(`${text}`) } } return text } return { token, doRequest, parseResponse } }