UNPKG

crm-sdk

Version:

Javasript Software Development Kit for Microsoft Dynamics CE Web API

182 lines (168 loc) 5.78 kB
const allowedRequestMethods = ["DELETE", "GET", "PATCH", "POST", "PUT"]; const requestJSON = (url, method = "GET", data, headers = {}) => { if (allowedRequestMethods.indexOf(method) === -1) { throw new Error(`Request method must be one of the following: ${allowedRequestMethods.join(", ")}`); } let requestData = null; if (data) { requestData = JSON.stringify(data); // when data is undefined IE sends undefined as a string } const totalHeaders = Object.assign({ "OData-MaxVersion": "4.0", "OData-Version": "4.0", "Accept": "application/json", "Content-Type": "application/json; charset=utf-8" }, headers); if (typeof XMLHttpRequest !== "undefined") { return requestXMLHttpRequest(url, method, requestData, totalHeaders); } else { return requestNodeHttpRequest(url, method, requestData, totalHeaders); } }; const requestXMLHttpRequest = (url, method, data, headers) => { return new Promise((resolve, reject) => { const request = new XMLHttpRequest(); request.open(method, encodeURI(url), true); for (const header in headers) { request.setRequestHeader(header, headers[header]); } request.onreadystatechange = () => { if (request.readyState === 4) { request.onreadystatechange = null; try { const response = handleXMLHttpsRequest(request); resolve(response); } catch(e) { reject(e); } } }; request.send(data); }); }; const handleXMLHttpsRequest = request => { const dataHandler = () => { let body = null; try { body = JSON.parse(request.response, dateReviver); } catch (ex) { throw new Error("JSON response can't be parsed"); } return { body: body, getResponseHeader: request.getResponseHeader.bind(request), statusCode: request.status }; }; const statusHandlers = { 200: () => { return dataHandler(); }, 201: () => { return dataHandler(); }, 204: () => { return { body: null, getResponseHeader: request.getResponseHeader.bind(request), statusCode: request.status }; } }; const statusHandler = statusHandlers[request.status]; if (statusHandler) { return statusHandler(); } else { const responseJSON = JSON.parse(request.response); throw new Error(responseJSON.error.message); } }; const requestNodeHttpRequest = (url, method, data, headers) => { return new Promise((resolve, reject) => { const https = eval("require")("https"), // hack for now: https://stackoverflow.com/questions/34828722/how-can-i-make-webpack-skip-an-require split = url.split("/"), hostname = split[2], path = "/" + split.slice(3, split.length).join("/"); if (method !== "GET") { headers["Content-Length"] = data.length; } const req = https.request({ hostname: hostname, port: 443, path: encodeURI(path), method: method, headers: headers }, response => { let body = ""; response.setEncoding("utf8"); response.on("data", chunk => body += chunk); response.on("end", () => { try { resolve(handleNodeHttpsResponse(response, body)); } catch(e) { reject(e); } }); }); req.on("error", error => { reject(error); }); if (method !== "GET") { req.write(data); } req.end(); }); }; const handleNodeHttpsResponse = (response, bodyString) => { const dataHandler = () => { let body = null; try { body = JSON.parse(bodyString, dateReviver); } catch (ex) { throw new Error("JSON response can't be parsed"); } return { body: body, getResponseHeader: function (headerName) { return response.headers[headerName]; }, statusCode: response.statusCode }; }; const statusHandlers = { 200: () => { return dataHandler(); }, 201: () => { return dataHandler(); }, 204: () => { return { body: null, getResponseHeader: function (headerName) { return response.headers[headerName]; }, statusCode: response.statusCode }; } }; const statusHandler = statusHandlers[response.statusCode]; if (statusHandler) { return statusHandler(); } else { if (response.statusCode === 401) { throw new Error("Unauthorized"); } throw new Error(`${response.statusCode}: ${response.statusMessage}\n ${bodyString}`); } }; const dateReviver = (key, value) => { if (typeof value === "string") { const d = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?::(\d*))?Z$/.exec(value); if (d) { return new Date(Date.UTC(+d[1], +d[2] - 1, +d[3], +d[4], +d[5], +d[6], +d[7] || 0)); } } return value; }; export default requestJSON;