@openreplay/tracker 5.0.5-beta.3 → 5.0.5-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/modules/axiosSpy.d.ts +1 -0
- package/cjs/modules/axiosSpy.js +16 -2
- package/cjs/modules/network.js +3 -0
- package/cjs/utils.d.ts +1 -0
- package/cjs/utils.js +21 -1
- package/lib/modules/axiosSpy.d.ts +1 -0
- package/lib/modules/axiosSpy.js +16 -2
- package/lib/modules/network.js +3 -0
- package/lib/utils.d.ts +1 -0
- package/lib/utils.js +19 -0
- package/package.json +1 -1
|
@@ -33,6 +33,7 @@ interface AxiosResponse<T = any> {
|
|
|
33
33
|
response?: AxiosRequestConfig;
|
|
34
34
|
}
|
|
35
35
|
export interface AxiosInstance extends Record<string, any> {
|
|
36
|
+
getUri: (config?: AxiosRequestConfig) => string;
|
|
36
37
|
interceptors: {
|
|
37
38
|
request: AxiosInterceptorManager<InternalAxiosRequestConfig>;
|
|
38
39
|
response: AxiosInterceptorManager<AxiosResponse>;
|
package/cjs/modules/axiosSpy.js
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const messages_gen_js_1 = require("../app/messages.gen.js");
|
|
4
4
|
const utils_js_1 = require("../utils.js");
|
|
5
|
+
const exception_js_1 = require("./exception.js");
|
|
5
6
|
function default_1(app, instance, opts, sanitize, stringify) {
|
|
6
7
|
app.debug.log('Openreplay: attaching axios spy to instance', instance);
|
|
7
8
|
function captureResponseData(axiosResponseObj) {
|
|
8
9
|
app.debug.log('Openreplay: capturing axios response data', axiosResponseObj);
|
|
9
|
-
const { headers: reqHs, data: reqData, method, url } = axiosResponseObj.config;
|
|
10
|
+
const { headers: reqHs, data: reqData, method, url, baseURL } = axiosResponseObj.config;
|
|
10
11
|
const { data: rData, headers: rHs, status: globStatus, response } = axiosResponseObj;
|
|
11
12
|
const { data: resData, headers: resHs, status: resStatus } = response || {};
|
|
12
13
|
const ihOpt = opts.ignoreHeaders;
|
|
@@ -65,6 +66,7 @@ function default_1(app, instance, opts, sanitize, stringify) {
|
|
|
65
66
|
}
|
|
66
67
|
const requestStart = axiosResponseObj.config.__openreplay_timing;
|
|
67
68
|
const duration = performance.now() - requestStart;
|
|
69
|
+
console.log(reqResInfo, 'finally');
|
|
68
70
|
app.send((0, messages_gen_js_1.NetworkRequest)('xhr', String(method), String(reqResInfo.url), stringify(reqResInfo.request), stringify(reqResInfo.response), reqResInfo.status, requestStart + (0, utils_js_1.getTimeOrigin)(), duration));
|
|
69
71
|
}
|
|
70
72
|
function getStartTime(config) {
|
|
@@ -88,7 +90,13 @@ function default_1(app, instance, opts, sanitize, stringify) {
|
|
|
88
90
|
return response;
|
|
89
91
|
}
|
|
90
92
|
function captureNetworkError(error) {
|
|
91
|
-
|
|
93
|
+
app.debug.log('Openreplay: capturing API request error', error);
|
|
94
|
+
if (isAxiosError(error)) {
|
|
95
|
+
captureResponseData(error.response);
|
|
96
|
+
}
|
|
97
|
+
else if (error instanceof Error) {
|
|
98
|
+
app.send((0, exception_js_1.getExceptionMessage)(error, []));
|
|
99
|
+
}
|
|
92
100
|
return Promise.reject(error);
|
|
93
101
|
}
|
|
94
102
|
function logRequestError(ev) {
|
|
@@ -107,3 +115,9 @@ function default_1(app, instance, opts, sanitize, stringify) {
|
|
|
107
115
|
});
|
|
108
116
|
}
|
|
109
117
|
exports.default = default_1;
|
|
118
|
+
function isAxiosError(payload) {
|
|
119
|
+
return isObject(payload) && payload.isAxiosError === true;
|
|
120
|
+
}
|
|
121
|
+
function isObject(thing) {
|
|
122
|
+
return thing !== null && typeof thing === 'object';
|
|
123
|
+
}
|
package/cjs/modules/network.js
CHANGED
|
@@ -165,6 +165,7 @@ function default_1(app, opts = {}) {
|
|
|
165
165
|
});
|
|
166
166
|
xhr.addEventListener('load', app.safe((e) => {
|
|
167
167
|
const { headers: reqHs, body: reqBody } = getXHRRequestDataObject(xhr);
|
|
168
|
+
app.debug.log('Openreplay: XHR load ', reqHs, reqBody, xhr, xhr.getAllResponseHeaders());
|
|
168
169
|
const duration = startTime > 0 ? e.timeStamp - startTime : 0;
|
|
169
170
|
const hString = ignoreHeaders ? '' : xhr.getAllResponseHeaders(); // might be null (though only if no response received though)
|
|
170
171
|
const resHs = hString
|
|
@@ -201,10 +202,12 @@ function default_1(app, opts = {}) {
|
|
|
201
202
|
XMLHttpRequest.prototype.send = function (body) {
|
|
202
203
|
const rdo = getXHRRequestDataObject(this);
|
|
203
204
|
rdo.body = body;
|
|
205
|
+
app.debug.log('Openreplay: ', 'XHR send', rdo, 'XHR Object', this);
|
|
204
206
|
return nativeSend.apply(this, arguments);
|
|
205
207
|
};
|
|
206
208
|
const nativeSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
|
|
207
209
|
XMLHttpRequest.prototype.setRequestHeader = function (name, value) {
|
|
210
|
+
app.debug.log('Openreplay: ', name, value, isHIgnored(name), getXHRRequestDataObject(this));
|
|
208
211
|
if (!isHIgnored(name)) {
|
|
209
212
|
const rdo = getXHRRequestDataObject(this);
|
|
210
213
|
rdo.headers[name] = value;
|
package/cjs/utils.d.ts
CHANGED
|
@@ -11,3 +11,4 @@ export declare const DOCS_HOST = "https://docs.openreplay.com";
|
|
|
11
11
|
export declare function deprecationWarn(nameOfFeature: string, useInstead: string, docsPath?: string): void;
|
|
12
12
|
export declare function getLabelAttribute(e: Element): string | null;
|
|
13
13
|
export declare function hasOpenreplayAttribute(e: Element, attr: string): boolean;
|
|
14
|
+
export declare function buildFullUrl(baseURL: string | undefined, requestedURL: string): string;
|
package/cjs/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.hasOpenreplayAttribute = exports.getLabelAttribute = exports.deprecationWarn = exports.DOCS_HOST = exports.isURL = exports.normSpaces = exports.stars = exports.now = exports.getTimeOrigin = exports.adjustTimeOrigin = exports.MAX_STR_LEN = exports.IS_FIREFOX = exports.IN_BROWSER = void 0;
|
|
3
|
+
exports.buildFullUrl = exports.hasOpenreplayAttribute = exports.getLabelAttribute = exports.deprecationWarn = exports.DOCS_HOST = exports.isURL = exports.normSpaces = exports.stars = exports.now = exports.getTimeOrigin = exports.adjustTimeOrigin = exports.MAX_STR_LEN = exports.IS_FIREFOX = exports.IN_BROWSER = void 0;
|
|
4
4
|
const DEPRECATED_ATTRS = { htmlmasked: 'hidden', masked: 'obscured' };
|
|
5
5
|
exports.IN_BROWSER = !(typeof window === 'undefined');
|
|
6
6
|
exports.IS_FIREFOX = exports.IN_BROWSER && navigator.userAgent.match(/firefox|fxios/i);
|
|
@@ -69,3 +69,23 @@ function hasOpenreplayAttribute(e, attr) {
|
|
|
69
69
|
return false;
|
|
70
70
|
}
|
|
71
71
|
exports.hasOpenreplayAttribute = hasOpenreplayAttribute;
|
|
72
|
+
// Copied from axios library because these functions haven't been exported.
|
|
73
|
+
// Why can't axios put constructed fullURL into the config object or in an additional meta information?
|
|
74
|
+
// TODO: axios feature request
|
|
75
|
+
function isAbsoluteURL(url) {
|
|
76
|
+
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
|
|
77
|
+
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
|
|
78
|
+
// by any combination of letters, digits, plus, period, or hyphen.
|
|
79
|
+
// eslint-disable-next-line no-useless-escape
|
|
80
|
+
return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
|
|
81
|
+
}
|
|
82
|
+
function combineURLs(baseURL, relativeURL) {
|
|
83
|
+
return relativeURL ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL;
|
|
84
|
+
}
|
|
85
|
+
function buildFullUrl(baseURL, requestedURL) {
|
|
86
|
+
if (baseURL && !isAbsoluteURL(requestedURL)) {
|
|
87
|
+
return combineURLs(baseURL, requestedURL);
|
|
88
|
+
}
|
|
89
|
+
return requestedURL;
|
|
90
|
+
}
|
|
91
|
+
exports.buildFullUrl = buildFullUrl;
|
|
@@ -33,6 +33,7 @@ interface AxiosResponse<T = any> {
|
|
|
33
33
|
response?: AxiosRequestConfig;
|
|
34
34
|
}
|
|
35
35
|
export interface AxiosInstance extends Record<string, any> {
|
|
36
|
+
getUri: (config?: AxiosRequestConfig) => string;
|
|
36
37
|
interceptors: {
|
|
37
38
|
request: AxiosInterceptorManager<InternalAxiosRequestConfig>;
|
|
38
39
|
response: AxiosInterceptorManager<AxiosResponse>;
|
package/lib/modules/axiosSpy.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { NetworkRequest } from '../app/messages.gen.js';
|
|
2
2
|
import { getTimeOrigin } from '../utils.js';
|
|
3
|
+
import { getExceptionMessage } from './exception.js';
|
|
3
4
|
export default function (app, instance, opts, sanitize, stringify) {
|
|
4
5
|
app.debug.log('Openreplay: attaching axios spy to instance', instance);
|
|
5
6
|
function captureResponseData(axiosResponseObj) {
|
|
6
7
|
app.debug.log('Openreplay: capturing axios response data', axiosResponseObj);
|
|
7
|
-
const { headers: reqHs, data: reqData, method, url } = axiosResponseObj.config;
|
|
8
|
+
const { headers: reqHs, data: reqData, method, url, baseURL } = axiosResponseObj.config;
|
|
8
9
|
const { data: rData, headers: rHs, status: globStatus, response } = axiosResponseObj;
|
|
9
10
|
const { data: resData, headers: resHs, status: resStatus } = response || {};
|
|
10
11
|
const ihOpt = opts.ignoreHeaders;
|
|
@@ -63,6 +64,7 @@ export default function (app, instance, opts, sanitize, stringify) {
|
|
|
63
64
|
}
|
|
64
65
|
const requestStart = axiosResponseObj.config.__openreplay_timing;
|
|
65
66
|
const duration = performance.now() - requestStart;
|
|
67
|
+
console.log(reqResInfo, 'finally');
|
|
66
68
|
app.send(NetworkRequest('xhr', String(method), String(reqResInfo.url), stringify(reqResInfo.request), stringify(reqResInfo.response), reqResInfo.status, requestStart + getTimeOrigin(), duration));
|
|
67
69
|
}
|
|
68
70
|
function getStartTime(config) {
|
|
@@ -86,7 +88,13 @@ export default function (app, instance, opts, sanitize, stringify) {
|
|
|
86
88
|
return response;
|
|
87
89
|
}
|
|
88
90
|
function captureNetworkError(error) {
|
|
89
|
-
|
|
91
|
+
app.debug.log('Openreplay: capturing API request error', error);
|
|
92
|
+
if (isAxiosError(error)) {
|
|
93
|
+
captureResponseData(error.response);
|
|
94
|
+
}
|
|
95
|
+
else if (error instanceof Error) {
|
|
96
|
+
app.send(getExceptionMessage(error, []));
|
|
97
|
+
}
|
|
90
98
|
return Promise.reject(error);
|
|
91
99
|
}
|
|
92
100
|
function logRequestError(ev) {
|
|
@@ -104,3 +112,9 @@ export default function (app, instance, opts, sanitize, stringify) {
|
|
|
104
112
|
(_d = (_c = instance.interceptors.response).eject) === null || _d === void 0 ? void 0 : _d.call(_c, resInt);
|
|
105
113
|
});
|
|
106
114
|
}
|
|
115
|
+
function isAxiosError(payload) {
|
|
116
|
+
return isObject(payload) && payload.isAxiosError === true;
|
|
117
|
+
}
|
|
118
|
+
function isObject(thing) {
|
|
119
|
+
return thing !== null && typeof thing === 'object';
|
|
120
|
+
}
|
package/lib/modules/network.js
CHANGED
|
@@ -163,6 +163,7 @@ export default function (app, opts = {}) {
|
|
|
163
163
|
});
|
|
164
164
|
xhr.addEventListener('load', app.safe((e) => {
|
|
165
165
|
const { headers: reqHs, body: reqBody } = getXHRRequestDataObject(xhr);
|
|
166
|
+
app.debug.log('Openreplay: XHR load ', reqHs, reqBody, xhr, xhr.getAllResponseHeaders());
|
|
166
167
|
const duration = startTime > 0 ? e.timeStamp - startTime : 0;
|
|
167
168
|
const hString = ignoreHeaders ? '' : xhr.getAllResponseHeaders(); // might be null (though only if no response received though)
|
|
168
169
|
const resHs = hString
|
|
@@ -199,10 +200,12 @@ export default function (app, opts = {}) {
|
|
|
199
200
|
XMLHttpRequest.prototype.send = function (body) {
|
|
200
201
|
const rdo = getXHRRequestDataObject(this);
|
|
201
202
|
rdo.body = body;
|
|
203
|
+
app.debug.log('Openreplay: ', 'XHR send', rdo, 'XHR Object', this);
|
|
202
204
|
return nativeSend.apply(this, arguments);
|
|
203
205
|
};
|
|
204
206
|
const nativeSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
|
|
205
207
|
XMLHttpRequest.prototype.setRequestHeader = function (name, value) {
|
|
208
|
+
app.debug.log('Openreplay: ', name, value, isHIgnored(name), getXHRRequestDataObject(this));
|
|
206
209
|
if (!isHIgnored(name)) {
|
|
207
210
|
const rdo = getXHRRequestDataObject(this);
|
|
208
211
|
rdo.headers[name] = value;
|
package/lib/utils.d.ts
CHANGED
|
@@ -11,3 +11,4 @@ export declare const DOCS_HOST = "https://docs.openreplay.com";
|
|
|
11
11
|
export declare function deprecationWarn(nameOfFeature: string, useInstead: string, docsPath?: string): void;
|
|
12
12
|
export declare function getLabelAttribute(e: Element): string | null;
|
|
13
13
|
export declare function hasOpenreplayAttribute(e: Element, attr: string): boolean;
|
|
14
|
+
export declare function buildFullUrl(baseURL: string | undefined, requestedURL: string): string;
|
package/lib/utils.js
CHANGED
|
@@ -59,3 +59,22 @@ export function hasOpenreplayAttribute(e, attr) {
|
|
|
59
59
|
}
|
|
60
60
|
return false;
|
|
61
61
|
}
|
|
62
|
+
// Copied from axios library because these functions haven't been exported.
|
|
63
|
+
// Why can't axios put constructed fullURL into the config object or in an additional meta information?
|
|
64
|
+
// TODO: axios feature request
|
|
65
|
+
function isAbsoluteURL(url) {
|
|
66
|
+
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
|
|
67
|
+
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
|
|
68
|
+
// by any combination of letters, digits, plus, period, or hyphen.
|
|
69
|
+
// eslint-disable-next-line no-useless-escape
|
|
70
|
+
return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
|
|
71
|
+
}
|
|
72
|
+
function combineURLs(baseURL, relativeURL) {
|
|
73
|
+
return relativeURL ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL;
|
|
74
|
+
}
|
|
75
|
+
export function buildFullUrl(baseURL, requestedURL) {
|
|
76
|
+
if (baseURL && !isAbsoluteURL(requestedURL)) {
|
|
77
|
+
return combineURLs(baseURL, requestedURL);
|
|
78
|
+
}
|
|
79
|
+
return requestedURL;
|
|
80
|
+
}
|