import { RequestBase, RequestOptionsBaseExtended } from "./RequestBase"; import { utils } from "../utils"; import { HEADER_NAMES } from "../constants"; import { SDKOptions, Token } from "../Sitefinity"; const XMLHttpRequestDone = 4; export class ExecutableRequest extends RequestBase { protected http: XMLHttpRequest; private token: Token; private enableUnlimitedChoices: boolean; private integrationMode: boolean; constructor(requestOptions: RequestOptionsBaseExtended, token: Token, sdkOptions: SDKOptions) { super(requestOptions); this.token = token; this.successCb = this.successCb || sdkOptions.handlers?.successCb; this.failureCb = this.failureCb || sdkOptions.handlers?.failureCb; this.enableUnlimitedChoices = sdkOptions.enableUnlimitedChoices; this.integrationMode = sdkOptions.integrationMode; } execute() { this.http = new XMLHttpRequest(); this.http.onreadystatechange = () => { if (this.http.readyState === XMLHttpRequestDone) { if (this.http.status > 0) { let data = this.parseResponse(this.http); if (this.http.status >= 200 && this.http.status <= 206) { if (this.successCb && utils.isFunction(this.successCb)) { this.successCb(data); } } else if (this.http.status >= 400) { // When the data is string, we save the string as message // and convert the data to normal object with message property if (utils.isString(data)) { data = { message: data }; } data.status = this.http.status; // in case of errors we would like there to be one handler for all of the errors if (this.failureCb && utils.isFunction(this.failureCb)) { this.failureCb(data); } } } } }; this.executeProgressEvent(); const method = this.getMethod(); const url = this.buildUrl(); this.http.open(method, url, true); this.setHeaders(this.http, this.getHeaders()); this.http.send(utils.serializeToJSON(this.getBody())); } protected executeProgressEvent() { if (this.http.upload) { this.http.upload.onprogress = (event) => { if (this.progressCb && utils.isFunction(this.progressCb)) { this.progressCb(event); } }; } } private setHeaders(http: XMLHttpRequest, headers: { [key: string]: string }) { const headerKeys = Object.keys(headers); for (let i = 0; i < headerKeys.length; i++) { const currentHeaderName = headerKeys[i]; http.setRequestHeader(currentHeaderName, headers[currentHeaderName]); } if (this.token) { if (typeof this.token === "string") { // for backward compatibility http.setRequestHeader(HEADER_NAMES.authorization, this.token); } else { http.setRequestHeader(HEADER_NAMES.authorization, this.token.type + " " + this.token.value); } } if (this.enableUnlimitedChoices) { http.setRequestHeader(HEADER_NAMES.choicesBinaryRepresentation, "true"); } if (this.integrationMode) { http.setRequestHeader(HEADER_NAMES.integrationMode, "true"); } // for backward compatibility http.setRequestHeader(HEADER_NAMES.serviceRequest, "true"); } } export interface ResponseHandlers { /** * The success handler. */ successCb?: Function; /** * The failure handler. */ failureCb?: Function; }