import { get } from "lodash"; import { fromJS } from "immutable"; import { fileExtension } from "./path"; export const filterByPropExtension = (extension, propName) => arr => arr.filter(el => fileExtension(get(el, propName)) === extension); const catchFormatErrors = (format, formatter) => res => { try { return formatter(res); } catch (err) { throw new Error(`Response cannot be parsed into the expected format (${ format }): ${ err.message }`); } }; const responseFormatters = fromJS({ json: async res => { const contentType = res.headers.get("Content-Type"); if (!contentType.startsWith("application/json") && !contentType.startsWith("text/json")) { throw new Error(`${ contentType } is not a valid JSON Content-Type`); } return res.json(); }, text: async res => res.text(), blob: async res => res.blob(), }).mapEntries( ([format, formatter]) => [format, catchFormatErrors(format, formatter)] ); export const parseResponse = async (res, { expectingOk = true, format = "text" } = {}) => { if (expectingOk && !res.ok) { throw new Error(`Expected an ok response, but received an error status: ${ res.status }.`); } const formatter = responseFormatters.get(format, false); if (!formatter) { throw new Error(`${ format } is not a supported response format.`); } const body = await formatter(res); return body; }; export const responseParser = options => res => parseResponse(res, options);