const _get = require('lodash.get'); import { Response } from 'node-fetch'; import { FetchRequestOptions } from '../types/options'; import { InvalidResponseError } from '../errors'; import { responseError } from '../helpers/response-error'; import { isResponseEmpty } from '../helpers/is-response-empty'; export async function makeRequest(url: string, options: FetchRequestOptions, fetch: Function, targetApiSystemCode?: string, expectEmptyResponse?: boolean): Promise { const response: Response = await fetch(url, options); // Handle all error situations first if (!response.ok) { const request = { url, method: options.method, body: options.body, headers: options.headers }; throw await responseError(response, request, targetApiSystemCode); } // Handle 204s and 201s with empty body if (expectEmptyResponse || isResponseEmpty(response)) { return { status: response.status, headers: response.headers, ok: response.ok }; } const fetchHeaders = options.headers || ''; const acceptHeader = fetchHeaders['Accept'] || ''; if (acceptHeader === 'application/pdf') { return Buffer.from(await response.arrayBuffer()); } if (acceptHeader === 'text/plain' || response.headers.get('content-length') === '0') { return await response.text(); } // Attempt to return the response data try { const parsed = await response.json(); if ( typeof response.status === 'number' && parsed && typeof parsed === 'object' ) { parsed.status = response.status; } return parsed; } catch (error) { throw new InvalidResponseError('Invalid JSON returned', { raw: _get(error, 'message') }); } }