UNPKG

@multiplayer-app/session-recorder-browser

Version:
107 lines 4.12 kB
import { isDocument, isFormData, isNullish, isObject, isString, } from '../utils/type-utils'; import { formDataToQuery } from '../utils/request-utils'; import { configs } from './configs'; function _tryReadXHRBody({ body, url, }) { if (isNullish(body)) { return null; } if (isString(body)) { return body; } if (isDocument(body)) { return body.textContent; } if (isFormData(body)) { return formDataToQuery(body); } if (isObject(body)) { try { return JSON.stringify(body); } catch (_a) { return '[XHR] Failed to stringify response object'; } } return `[XHR] Cannot read body of type ${toString.call(body)}`; } function _isWithinPayloadLimit(payload) { try { if (typeof Blob !== 'undefined') { return new Blob([payload]).size <= configs.maxCapturingHttpPayloadSize; } } catch (_a) { // ignore and fallback to string length } return payload.length <= configs.maxCapturingHttpPayloadSize; } // Only patch XHR in environments where it exists (avoid SSR/Node) if (typeof XMLHttpRequest !== 'undefined') { (function (xhr) { // Idempotency guard: avoid double-patching // @ts-ignore if (xhr.__mp_session_recorder_patched__) { return; } // @ts-ignore ; xhr.__mp_session_recorder_patched__ = true; const originalOpen = xhr.open; xhr.open = function (method, url, async = true, username, password) { const xhr = this; const networkRequest = {}; // @ts-ignore const requestHeaders = {}; const originalSetRequestHeader = xhr.setRequestHeader.bind(xhr); xhr.setRequestHeader = (header, value) => { requestHeaders[header] = value; return originalSetRequestHeader(header, value); }; if (configs.recordRequestHeaders) { networkRequest.requestHeaders = requestHeaders; } const originalSend = xhr.send.bind(xhr); xhr.send = (body) => { if (configs.shouldRecordBody) { const requestBody = _tryReadXHRBody({ body, url }); if ((requestBody === null || requestBody === void 0 ? void 0 : requestBody.length) && _isWithinPayloadLimit(requestBody)) { networkRequest.requestBody = requestBody; } } return originalSend(body); }; xhr.addEventListener('readystatechange', () => { if (xhr.readyState !== xhr.DONE) { return; } // @ts-ignore const responseHeaders = {}; const rawHeaders = xhr.getAllResponseHeaders(); const headers = rawHeaders.trim().split(/[\r\n]+/); headers.forEach((line) => { const parts = line.split(': '); const header = parts.shift(); const value = parts.join(': '); if (header) { responseHeaders[header] = value; } }); if (configs.recordResponseHeaders) { networkRequest.responseHeaders = responseHeaders; } if (configs.shouldRecordBody) { const responseBody = _tryReadXHRBody({ body: xhr.response, url }); if ((responseBody === null || responseBody === void 0 ? void 0 : responseBody.length) && _isWithinPayloadLimit(responseBody)) { networkRequest.responseBody = responseBody; } } }); // @ts-ignore xhr.networkRequest = networkRequest; originalOpen.call(xhr, method, url, async, username, password); }; })(XMLHttpRequest.prototype); } //# sourceMappingURL=xhr.js.map