import FetchArrayProxy from "../fetch-array-proxy"; import 'whatwg-fetch'; let KinisiteRemoteFormatters = { /** * Fetch an object from a remote URL. This returns a structured object much like the response from a Javascript FETCH * { * "response": The raw response as a string * "status": The status code of the response e.g. 200 * "statusText": The text of the status returned if set * "headers": An object with keys for each returned header and values for the header value. * } * * This uses the primary argument as the url * and accepts an HTTP method as the second argument. The arguments * following this can vary according to the following rules * * 1) If a single additional argument is supplied and method is POST,PUT,PATCH,DELETE this is assumed to be the Payload for the method * 2) If pairs of additional arguments are supplied these will be treated as Key/Value parameters to the call. If the key is prefixed * with the string header: it will be assumed to be a HTTP request header instead of a parameter. * * @param url * @param method */ fetch: function (url: any, method = "GET") { let response: any = { "response": null, "status": null, "statusText": null, "headers": null }; KinisiteRemoteFormatters._doFetch(url, method, Array.prototype.slice.call(arguments, 2)).then((fetchResponse: any) => { // Gather fetch headers as key/value let fetchHeaders = (fetchResponse.headers).entries(); let headers: any = {}; let value = null; while (value = fetchHeaders.next().value) { headers[value[0]] = value[1]; } response.headers = headers; response.status = fetchResponse.status; response.statusText = fetchResponse.statusText; fetchResponse.text().then((text: any) => { response.response = text; }); }); return response; }, /** * Convenience wrapper to above fetch method where we are expecting a single JSON object * return value and are not concerned with the raw value / headers etc. * * @param url * @param method */ fetchObject: function (url: any, method = "GET") { let object = {}; KinisiteRemoteFormatters._doFetch(url, method, Array.prototype.slice.call(arguments, 2)).then(fetchResponse => { fetchResponse.json().then((jsonValue: any) => { Object.assign(object, jsonValue); }); }); return object; }, /** * Convenience wrapper to fetch where we are expecting an array of JSON objects and * are not concerned with the raw value / headers etc. * * @param url * @param method */ fetchArray: function (url: any, method = "GET") { let fetchInstance = KinisiteRemoteFormatters._doFetch(url, method, Array.prototype.slice.call(arguments, 2)); return new FetchArrayProxy(fetchInstance); }, /** * Internal do fetch method used by above wrappers. * * @param url * @param method * @param params */ _doFetch(url: any, method: any, params: any[]): Promise { let init: any = { method }; // If 3 args assume 3rd argument is payload if not a GET request if (params.length == 1 && method != 'GET') { init["body"] = JSON.stringify(params[0]); } else if (params.length > 0) { let requestParams: any = {}; init["headers"] = new Headers(); for (var i = 0; i < params.length; i += 2) { if (i + 1 < params.length) { if (params[i].startsWith("header:")) init["headers"].append(params[i].substr(7), params[i + 1]); else requestParams[params[i]] = params[i + 1]; } } if (method == "GET") { url += (url.includes("?") ? "&" : "?") + new URLSearchParams(requestParams).toString(); } else { init["body"] = new URLSearchParams(requestParams); } } // Do the fetch and update the object return fetch(url, init); } }; export default KinisiteRemoteFormatters;