UNPKG

react-native-gleapsdk

Version:

Know exactly why and how a bug happened. Get reports with screenshots, live action replays and all of the important metadata every time.

373 lines (323 loc) 9.85 kB
/* eslint-disable @typescript-eslint/no-unused-vars */ class GleapNetworkIntercepter { requestId = 0; requests: any = {}; maxRequests = 25; stopped = false; updatedCallback: any = null; setUpdatedCallback(updatedCallback: any) { this.updatedCallback = updatedCallback; } getRequests() { return Object.values(this.requests); } setMaxRequests(maxRequests: number) { this.maxRequests = maxRequests; } setStopped(stopped: boolean) { this.stopped = stopped; } cleanRequests() { var keys = Object.keys(this.requests); if (keys.length > this.maxRequests) { var keysToRemove = keys.slice(0, keys.length - this.maxRequests); for (var i = 0; i < keysToRemove.length; i++) { delete this.requests[keysToRemove[i]]; } } if (this.updatedCallback) { this.updatedCallback(); } } calcRequestTime(gleapRequestId: string | number) { if (!this.requests[gleapRequestId]) { return; } var startDate = this.requests[gleapRequestId].date; if ( startDate && typeof startDate.getTime === 'function' && !Object.isFrozen(this.requests[gleapRequestId]) ) { this.requests[gleapRequestId].duration = new Date().getTime() - startDate.getTime(); this.requests[gleapRequestId].date = this.requests[gleapRequestId].date.toString(); } } getTextContentSizeOk(text: string) { if (text && text.length) { const size = text.length * 16; const kiloBytes = size / 1024; const megaBytes = kiloBytes / 1024; if (megaBytes < 0.2) { return true; } } return false; } prepareContent(text: string) { if (!this.getTextContentSizeOk(text)) { return '<content_too_large>'; } return text; } cleanupPayload(payload: any) { if (payload === undefined || payload === null) { return '{}'; } try { if (ArrayBuffer.isView(payload)) { return `{ type: "binary", length: ${payload.byteLength} }`; } } catch (exp) {} return payload; } preparePayload(payload: any) { var payloadText = this.cleanupPayload(payload); return this.prepareContent(payloadText); } start() { this.setStopped(false); this.interceptNetworkRequests({ onFetch: (params: any[], gleapRequestId: any) => { if (this.stopped || params.length === 0) { return; } if (params.length >= 2 && params[1] !== undefined) { var method = params[1].method ? params[1].method : 'GET'; this.requests[gleapRequestId] = { request: { payload: this.preparePayload(params[1].body), headers: params[1].headers, }, type: method, url: params[0], date: new Date(), }; } else { this.requests[gleapRequestId] = { request: {}, url: params[0], type: 'GET', date: new Date(), }; } this.cleanRequests(); }, onFetchLoad: (req: any, gleapRequestId: any) => { if ( this.stopped || !gleapRequestId || !this.requests || !this.requests[gleapRequestId] ) { return; } try { this.requests[gleapRequestId].success = true; this.requests[gleapRequestId].response = { status: req.status, statusText: '', responseText: '<request_still_open>', }; this.calcRequestTime(gleapRequestId); } catch (exp) {} req .text() .then((responseText: any) => { if (this.requests && this.requests[gleapRequestId]) { this.requests[gleapRequestId].success = true; this.requests[gleapRequestId].response = { status: req.status, statusText: req.statusText, responseText: this.prepareContent(responseText), }; this.calcRequestTime(gleapRequestId); this.cleanRequests(); } }) .catch((_err: any) => { if (this) { this.cleanRequests(); } }); }, onFetchFailed: (_err: any, gleapRequestId: any) => { if (this.stopped || !gleapRequestId) { return; } if (this.requests && this.requests[gleapRequestId]) { this.requests[gleapRequestId].success = false; this.calcRequestTime(gleapRequestId); } this.cleanRequests(); }, onOpen: (request: any, args: string | any[]) => { if (this.stopped) { return; } if ( request && request.gleapRequestId && args.length >= 2 && this.requests ) { this.requests[request.gleapRequestId] = { type: args[0], url: args[1], date: new Date(), }; } this.cleanRequests(); }, onSend: (request: any, args: string | any[]) => { if (this.stopped) { return; } if ( request && request.gleapRequestId && this.requests && this.requests[request.gleapRequestId] ) { this.requests[request.gleapRequestId].request = { payload: this.preparePayload(args.length > 0 ? args[0] : ''), headers: request.requestHeaders, }; } this.cleanRequests(); }, onError: (request: any) => { if ( !this.stopped && this.requests && request && request.gleapRequestId && this.requests[request.gleapRequestId] ) { this.requests[request.gleapRequestId].success = false; this.calcRequestTime(request.gleapRequestId); } this.cleanRequests(); }, onLoad: (request: any) => { if (this.stopped) { return; } if ( request && request.gleapRequestId && this.requests && this.requests[request.gleapRequestId] ) { const contentType = request.getResponseHeader('content-type'); const isTextOrJSON = contentType && (contentType.includes('json') || contentType.includes('text')); var responseText = '<' + contentType + '>'; if (request.responseType === '' || request.responseType === 'text') { responseText = request.responseText; } if (request._response && isTextOrJSON) { responseText = request._response; } this.requests[request.gleapRequestId].success = true; this.requests[request.gleapRequestId].response = { status: request.status, responseText: this.prepareContent(responseText), }; this.calcRequestTime(request.gleapRequestId); } this.cleanRequests(); }, }); } interceptNetworkRequests(callback: any) { // eslint-disable-next-line consistent-this var self = this; // @ts-ignore if (XMLHttpRequest.prototype.gleapTouched) { return; } // @ts-ignore XMLHttpRequest.prototype.gleapTouched = true; // XMLHttpRequest const open = XMLHttpRequest.prototype.open; const send = XMLHttpRequest.prototype.send; // @ts-ignore XMLHttpRequest.prototype.wrappedSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader; XMLHttpRequest.prototype.setRequestHeader = function (header, value) { // @ts-ignore if (!this.requestHeaders) { // @ts-ignore this.requestHeaders = {}; } // @ts-ignore if (this.requestHeaders && this.requestHeaders.hasOwnProperty(header)) { return; } // @ts-ignore if (!this.requestHeaders[header]) { // @ts-ignore this.requestHeaders[header] = []; } // @ts-ignore this.requestHeaders[header].push(value); // @ts-ignore this.wrappedSetRequestHeader(header, value); }; XMLHttpRequest.prototype.open = function () { (this as any).gleapRequestId = ++self.requestId; callback.onOpen && callback.onOpen(this, arguments); if (callback.onLoad) { this.addEventListener('load', function () { // @ts-ignore callback.onLoad(this); }); } if (callback.onError) { this.addEventListener('error', function () { // @ts-ignore callback.onError(this); }); } // @ts-ignore return open.apply(this, arguments); }; XMLHttpRequest.prototype.send = function () { callback.onSend && callback.onSend(this, arguments); // @ts-ignore return send.apply(this, arguments); }; // Fetch if (global) { (function () { var originalFetch = global.fetch; global.fetch = function () { var gleapRequestId = ++self.requestId; callback.onFetch(arguments, gleapRequestId); return ( originalFetch // @ts-ignore .apply(this, arguments) .then(function (response) { if (response && typeof response.clone === 'function') { const data = response.clone(); callback.onFetchLoad(data, gleapRequestId); } return response; }) .catch((err) => { callback.onFetchFailed(err, gleapRequestId); throw err; }) ); }; })(); } return callback; } } export default GleapNetworkIntercepter;