@openreplay/tracker 14.0.7 → 14.0.8

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.
Files changed (39) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/bun.lockb +0 -0
  3. package/cjs/app/index.js +5 -1
  4. package/cjs/index.js +1 -1
  5. package/cjs/modules/network.js +4 -2
  6. package/lib/app/index.js +5 -1
  7. package/lib/common/tsconfig.tsbuildinfo +1 -1
  8. package/lib/index.js +1 -1
  9. package/lib/modules/network.js +4 -2
  10. package/package.json +2 -1
  11. package/tsconfig-base.json +2 -2
  12. package/cjs/modules/Network/beaconProxy.d.ts +0 -16
  13. package/cjs/modules/Network/beaconProxy.js +0 -87
  14. package/cjs/modules/Network/fetchProxy.d.ts +0 -34
  15. package/cjs/modules/Network/fetchProxy.js +0 -309
  16. package/cjs/modules/Network/index.d.ts +0 -3
  17. package/cjs/modules/Network/index.js +0 -28
  18. package/cjs/modules/Network/networkMessage.d.ts +0 -49
  19. package/cjs/modules/Network/networkMessage.js +0 -87
  20. package/cjs/modules/Network/types.d.ts +0 -13
  21. package/cjs/modules/Network/types.js +0 -3
  22. package/cjs/modules/Network/utils.d.ts +0 -11
  23. package/cjs/modules/Network/utils.js +0 -216
  24. package/cjs/modules/Network/xhrProxy.d.ts +0 -39
  25. package/cjs/modules/Network/xhrProxy.js +0 -249
  26. package/lib/modules/Network/beaconProxy.d.ts +0 -16
  27. package/lib/modules/Network/beaconProxy.js +0 -79
  28. package/lib/modules/Network/fetchProxy.d.ts +0 -34
  29. package/lib/modules/Network/fetchProxy.js +0 -280
  30. package/lib/modules/Network/index.d.ts +0 -3
  31. package/lib/modules/Network/index.js +0 -22
  32. package/lib/modules/Network/networkMessage.d.ts +0 -49
  33. package/lib/modules/Network/networkMessage.js +0 -83
  34. package/lib/modules/Network/types.d.ts +0 -13
  35. package/lib/modules/Network/types.js +0 -2
  36. package/lib/modules/Network/utils.d.ts +0 -11
  37. package/lib/modules/Network/utils.js +0 -204
  38. package/lib/modules/Network/xhrProxy.d.ts +0 -39
  39. package/lib/modules/Network/xhrProxy.js +0 -221
@@ -1,216 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getURL = exports.formatByteSize = exports.isIterable = exports.isPureObject = exports.genFormattedBody = exports.genGetDataByUrl = exports.genStringBody = exports.getStringResponseByType = exports.genResponseByType = void 0;
4
- const genResponseByType = (responseType, response) => {
5
- let result = '';
6
- switch (responseType) {
7
- case '':
8
- case 'text':
9
- case 'json':
10
- if (typeof response == 'string') {
11
- try {
12
- result = JSON.parse(response);
13
- }
14
- catch (e) {
15
- // not a JSON string
16
- result = response.slice(0, 10000);
17
- }
18
- }
19
- else if (isPureObject(response) || Array.isArray(response)) {
20
- result = JSON.stringify(response);
21
- }
22
- else if (typeof response !== 'undefined') {
23
- result = Object.prototype.toString.call(response);
24
- }
25
- break;
26
- case 'blob':
27
- case 'document':
28
- case 'arraybuffer':
29
- default:
30
- if (typeof response !== 'undefined') {
31
- result = Object.prototype.toString.call(response);
32
- }
33
- break;
34
- }
35
- return result;
36
- };
37
- exports.genResponseByType = genResponseByType;
38
- const getStringResponseByType = (responseType, response) => {
39
- let result = '';
40
- switch (responseType) {
41
- case '':
42
- case 'text':
43
- case 'json':
44
- if (typeof response == 'string') {
45
- result = response;
46
- }
47
- else if (isPureObject(response) || Array.isArray(response)) {
48
- result = JSON.stringify(response);
49
- }
50
- else if (typeof response !== 'undefined') {
51
- result = Object.prototype.toString.call(response);
52
- }
53
- break;
54
- case 'blob':
55
- case 'document':
56
- case 'arraybuffer':
57
- default:
58
- if (typeof response !== 'undefined') {
59
- result = Object.prototype.toString.call(response);
60
- }
61
- break;
62
- }
63
- return result;
64
- };
65
- exports.getStringResponseByType = getStringResponseByType;
66
- const genStringBody = (body) => {
67
- if (!body) {
68
- return null;
69
- }
70
- let result;
71
- if (typeof body === 'string') {
72
- if (body[0] === '{' || body[0] === '[') {
73
- result = body;
74
- }
75
- // 'a=1&b=2' => try to parse as query
76
- const arr = body.split('&');
77
- if (arr.length === 1) {
78
- // not a query, parse as original string
79
- result = body;
80
- }
81
- else {
82
- // 'a=1&b=2&c' => parse as query
83
- result = arr.join(',');
84
- }
85
- }
86
- else if (isIterable(body)) {
87
- // FormData or URLSearchParams or Array
88
- const arr = [];
89
- for (const [key, value] of body) {
90
- arr.push(`${key}=${typeof value === 'string' ? value : '[object Object]'}`);
91
- }
92
- result = arr.join(',');
93
- }
94
- else if (body instanceof Blob ||
95
- body instanceof ReadableStream ||
96
- body instanceof ArrayBuffer) {
97
- result = 'byte data';
98
- }
99
- else if (isPureObject(body)) {
100
- // overriding ArrayBufferView which is not convertable to string
101
- result = body;
102
- }
103
- else {
104
- result = `can't parse body ${typeof body}`;
105
- }
106
- return result;
107
- };
108
- exports.genStringBody = genStringBody;
109
- const genGetDataByUrl = (url, getData = {}) => {
110
- if (!isPureObject(getData)) {
111
- getData = {};
112
- }
113
- let query = url ? url.split('?') : []; // a.php?b=c&d=?e => ['a.php', 'b=c&d=', 'e']
114
- query.shift(); // => ['b=c&d=', 'e']
115
- if (query.length > 0) {
116
- query = query.join('?').split('&'); // => 'b=c&d=?e' => ['b=c', 'd=?e']
117
- for (const q of query) {
118
- const kv = q.split('=');
119
- try {
120
- getData[kv[0]] = decodeURIComponent(kv[1]);
121
- }
122
- catch (e) {
123
- // "URIError: URI malformed" will be thrown when `kv[1]` contains "%", so just use raw data
124
- // @issue #470
125
- // @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Malformed_URI
126
- getData[kv[0]] = kv[1];
127
- }
128
- }
129
- }
130
- return getData;
131
- };
132
- exports.genGetDataByUrl = genGetDataByUrl;
133
- const genFormattedBody = (body) => {
134
- if (!body) {
135
- return null;
136
- }
137
- let result;
138
- if (typeof body === 'string') {
139
- try {
140
- // '{a:1}' =>
141
- result = JSON.parse(body);
142
- }
143
- catch (e) {
144
- // 'a=1&b=2' => try to parse as query
145
- const arr = body.split('&');
146
- result = {};
147
- // eslint-disable-next-line
148
- for (let q of arr) {
149
- const kv = q.split('=');
150
- result[kv[0]] = kv[1] === undefined ? 'undefined' : kv[1];
151
- }
152
- }
153
- }
154
- else if (isIterable(body)) {
155
- // FormData or URLSearchParams or Array
156
- result = {};
157
- for (const [key, value] of body) {
158
- result[key] = typeof value === 'string' ? value : '[object Object]';
159
- }
160
- }
161
- else if (ArrayBuffer.isView(body) ||
162
- body instanceof Blob ||
163
- body instanceof ReadableStream ||
164
- body instanceof ArrayBuffer) {
165
- result = '[byte data]';
166
- }
167
- else if (isPureObject(body)) {
168
- result = body;
169
- }
170
- else {
171
- result = `can't parse body ${typeof body}`;
172
- }
173
- return result;
174
- };
175
- exports.genFormattedBody = genFormattedBody;
176
- function isPureObject(input) {
177
- return null !== input && typeof input === 'object';
178
- }
179
- exports.isPureObject = isPureObject;
180
- function isIterable(value) {
181
- if (value === null || value === undefined) {
182
- return false;
183
- }
184
- if (ArrayBuffer.isView(value)) {
185
- return false;
186
- }
187
- return typeof Symbol !== 'undefined' && typeof value[Symbol.iterator] === 'function';
188
- }
189
- exports.isIterable = isIterable;
190
- function formatByteSize(bytes) {
191
- if (bytes <= 0) {
192
- // shouldn't happen?
193
- return '';
194
- }
195
- if (bytes >= 1000 * 1000) {
196
- return (bytes / 1000 / 1000).toFixed(1) + ' MB';
197
- }
198
- if (bytes >= 1000) {
199
- return (bytes / 1000).toFixed(1) + ' KB';
200
- }
201
- return `${bytes}B`;
202
- }
203
- exports.formatByteSize = formatByteSize;
204
- const getURL = (urlString) => {
205
- if (urlString.startsWith('//')) {
206
- const baseUrl = new URL(window.location.href);
207
- urlString = `${baseUrl.protocol}${urlString}`;
208
- }
209
- if (urlString.startsWith('http')) {
210
- return new URL(urlString);
211
- }
212
- else {
213
- return new URL(urlString, window.location.href);
214
- }
215
- };
216
- exports.getURL = getURL;
@@ -1,39 +0,0 @@
1
- /**
2
- * I took inspiration in few stack exchange posts
3
- * and Tencent vConsole library (MIT)
4
- * by wrapping the XMLHttpRequest object in a Proxy
5
- * we can intercept the network requests
6
- * in not-so-hacky way
7
- * */
8
- import NetworkMessage from './networkMessage.js';
9
- import { RequestResponseData } from './types.js';
10
- import { NetworkRequest } from '../../common/messages.gen.js';
11
- export declare class XHRProxyHandler<T extends XMLHttpRequest> implements ProxyHandler<T> {
12
- private readonly ignoredHeaders;
13
- private readonly setSessionTokenHeader;
14
- private readonly sanitize;
15
- private readonly sendMessage;
16
- private readonly isServiceUrl;
17
- private readonly tokenUrlMatcher?;
18
- XMLReq: XMLHttpRequest;
19
- item: NetworkMessage;
20
- constructor(XMLReq: XMLHttpRequest, ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData | null, sendMessage: (message: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: ((url: string) => boolean) | undefined);
21
- get(target: T, key: string): any;
22
- set(target: T, key: string, value: (args: any[]) => any): boolean;
23
- onReadyStateChange(): void;
24
- onAbort(): void;
25
- onTimeout(): void;
26
- protected getOpen(target: T): (...args: any[]) => any;
27
- protected getSend(target: T): (...args: any[]) => any;
28
- protected getSetRequestHeader(target: T): (...args: any[]) => any;
29
- protected setOnReadyStateChange(target: T, key: string, orscFunction: (args: any[]) => any): boolean;
30
- protected setOnAbort(target: T, key: string, oaFunction: (args: any[]) => any): boolean;
31
- protected setOnTimeout(target: T, key: string, otFunction: (args: any[]) => any): boolean;
32
- /**
33
- * Update item's properties according to readyState.
34
- */
35
- protected updateItemByReadyState(): void;
36
- }
37
- export default class XHRProxy {
38
- static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData | null, sendMessage: (data: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: (url: string) => boolean): any;
39
- }
@@ -1,249 +0,0 @@
1
- "use strict";
2
- /**
3
- * I took inspiration in few stack exchange posts
4
- * and Tencent vConsole library (MIT)
5
- * by wrapping the XMLHttpRequest object in a Proxy
6
- * we can intercept the network requests
7
- * in not-so-hacky way
8
- * */
9
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- var desc = Object.getOwnPropertyDescriptor(m, k);
12
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
- desc = { enumerable: true, get: function() { return m[k]; } };
14
- }
15
- Object.defineProperty(o, k2, desc);
16
- }) : (function(o, m, k, k2) {
17
- if (k2 === undefined) k2 = k;
18
- o[k2] = m[k];
19
- }));
20
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
- Object.defineProperty(o, "default", { enumerable: true, value: v });
22
- }) : function(o, v) {
23
- o["default"] = v;
24
- });
25
- var __importStar = (this && this.__importStar) || function (mod) {
26
- if (mod && mod.__esModule) return mod;
27
- var result = {};
28
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
29
- __setModuleDefault(result, mod);
30
- return result;
31
- };
32
- Object.defineProperty(exports, "__esModule", { value: true });
33
- exports.XHRProxyHandler = void 0;
34
- const networkMessage_js_1 = __importStar(require("./networkMessage.js"));
35
- const utils_js_1 = require("./utils.js");
36
- class XHRProxyHandler {
37
- constructor(XMLReq, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher) {
38
- this.ignoredHeaders = ignoredHeaders;
39
- this.setSessionTokenHeader = setSessionTokenHeader;
40
- this.sanitize = sanitize;
41
- this.sendMessage = sendMessage;
42
- this.isServiceUrl = isServiceUrl;
43
- this.tokenUrlMatcher = tokenUrlMatcher;
44
- this.XMLReq = XMLReq;
45
- this.XMLReq.onreadystatechange = () => {
46
- this.onReadyStateChange();
47
- };
48
- this.XMLReq.onabort = () => {
49
- this.onAbort();
50
- };
51
- this.XMLReq.ontimeout = () => {
52
- this.onTimeout();
53
- };
54
- this.item = new networkMessage_js_1.default(ignoredHeaders, setSessionTokenHeader, sanitize);
55
- this.item.requestType = 'xhr';
56
- }
57
- get(target, key) {
58
- switch (key) {
59
- case 'open':
60
- return this.getOpen(target);
61
- case 'send':
62
- this.setSessionTokenHeader((name, value) => {
63
- if (this.tokenUrlMatcher !== undefined) {
64
- if (!this.tokenUrlMatcher(this.item.url)) {
65
- return;
66
- }
67
- }
68
- target.setRequestHeader(name, value);
69
- });
70
- return this.getSend(target);
71
- case 'setRequestHeader':
72
- return this.getSetRequestHeader(target);
73
- default:
74
- // eslint-disable-next-line no-case-declarations
75
- const value = Reflect.get(target, key);
76
- if (typeof value === 'function') {
77
- return value.bind(target);
78
- }
79
- else {
80
- return value;
81
- }
82
- }
83
- }
84
- set(target, key, value) {
85
- switch (key) {
86
- case 'onreadystatechange':
87
- return this.setOnReadyStateChange(target, key, value);
88
- case 'onabort':
89
- return this.setOnAbort(target, key, value);
90
- case 'ontimeout':
91
- return this.setOnTimeout(target, key, value);
92
- default:
93
- // not tracked methods
94
- }
95
- return Reflect.set(target, key, value);
96
- }
97
- onReadyStateChange() {
98
- if (this.item.url && this.isServiceUrl(this.item.url))
99
- return;
100
- this.item.readyState = this.XMLReq.readyState;
101
- this.item.responseType = this.XMLReq.responseType;
102
- this.item.endTime = performance.now();
103
- this.item.duration = this.item.endTime - this.item.startTime;
104
- this.updateItemByReadyState();
105
- setTimeout(() => {
106
- this.item.response = (0, utils_js_1.getStringResponseByType)(this.item.responseType, this.item.response);
107
- }, 0);
108
- if (this.XMLReq.readyState === networkMessage_js_1.RequestState.DONE) {
109
- const msg = this.item.getMessage();
110
- if (msg) {
111
- this.sendMessage(msg);
112
- }
113
- }
114
- }
115
- onAbort() {
116
- this.item.cancelState = 1;
117
- this.item.statusText = 'Abort';
118
- const msg = this.item.getMessage();
119
- if (msg) {
120
- this.sendMessage(msg);
121
- }
122
- }
123
- onTimeout() {
124
- this.item.cancelState = 3;
125
- this.item.statusText = 'Timeout';
126
- const msg = this.item.getMessage();
127
- if (msg) {
128
- this.sendMessage(msg);
129
- }
130
- }
131
- getOpen(target) {
132
- const targetFunction = Reflect.get(target, 'open');
133
- return (...args) => {
134
- const method = args[0];
135
- const url = args[1];
136
- this.item.method = method ? method.toUpperCase() : 'GET';
137
- this.item.url = url.toString?.() || '';
138
- this.item.name = this.item.url?.replace(new RegExp('/*$'), '').split('/').pop() ?? '';
139
- this.item.getData = (0, utils_js_1.genGetDataByUrl)(this.item.url, {});
140
- return targetFunction.apply(target, args);
141
- };
142
- }
143
- getSend(target) {
144
- const targetFunction = Reflect.get(target, 'send');
145
- return (...args) => {
146
- const data = args[0];
147
- this.item.requestData = (0, utils_js_1.genStringBody)(data);
148
- return targetFunction.apply(target, args);
149
- };
150
- }
151
- getSetRequestHeader(target) {
152
- const targetFunction = Reflect.get(target, 'setRequestHeader');
153
- return (...args) => {
154
- if (!this.item.requestHeader) {
155
- this.item.requestHeader = {};
156
- }
157
- // @ts-ignore
158
- this.item.requestHeader[args[0]] = args[1];
159
- return targetFunction.apply(target, args);
160
- };
161
- }
162
- setOnReadyStateChange(target, key, orscFunction) {
163
- return Reflect.set(target, key, (...args) => {
164
- this.onReadyStateChange();
165
- orscFunction?.apply(target, args);
166
- });
167
- }
168
- setOnAbort(target, key, oaFunction) {
169
- return Reflect.set(target, key, (...args) => {
170
- this.onAbort();
171
- oaFunction.apply(target, args);
172
- });
173
- }
174
- setOnTimeout(target, key, otFunction) {
175
- return Reflect.set(target, key, (...args) => {
176
- this.onTimeout();
177
- otFunction.apply(target, args);
178
- });
179
- }
180
- /**
181
- * Update item's properties according to readyState.
182
- */
183
- updateItemByReadyState() {
184
- switch (this.XMLReq.readyState) {
185
- case networkMessage_js_1.RequestState.UNSENT:
186
- case networkMessage_js_1.RequestState.OPENED:
187
- this.item.status = networkMessage_js_1.RequestState.UNSENT;
188
- this.item.statusText = 'Pending';
189
- if (!this.item.startTime) {
190
- this.item.startTime = performance.now();
191
- }
192
- break;
193
- case networkMessage_js_1.RequestState.HEADERS_RECEIVED:
194
- this.item.status = this.XMLReq.status;
195
- this.item.statusText = 'Loading';
196
- this.item.header = {};
197
- // eslint-disable-next-line no-case-declarations
198
- const header = this.XMLReq.getAllResponseHeaders() || '', headerArr = header.split('\n');
199
- // extract plain text to key-value format
200
- for (let i = 0; i < headerArr.length; i++) {
201
- const line = headerArr[i];
202
- if (!line) {
203
- continue;
204
- }
205
- const arr = line.split(': ');
206
- const key = arr[0];
207
- this.item.header[key] = arr.slice(1).join(': ');
208
- }
209
- break;
210
- case networkMessage_js_1.RequestState.LOADING:
211
- this.item.status = this.XMLReq.status;
212
- this.item.statusText = 'Loading';
213
- if (!!this.XMLReq.response && this.XMLReq.response.length) {
214
- this.item.responseSize = this.XMLReq.response.length;
215
- this.item.responseSizeText = (0, utils_js_1.formatByteSize)(this.item.responseSize);
216
- }
217
- break;
218
- case networkMessage_js_1.RequestState.DONE:
219
- // `XMLReq.abort()` will change `status` from 200 to 0, so use previous value in this case
220
- this.item.status = this.XMLReq.status || this.item.status || 0;
221
- // show status code when request completed
222
- this.item.statusText = String(this.item.status);
223
- this.item.endTime = performance.now();
224
- this.item.duration = this.item.endTime - (this.item.startTime || this.item.endTime);
225
- this.item.response = this.XMLReq.response;
226
- if (!!this.XMLReq.response && this.XMLReq.response.length) {
227
- this.item.responseSize = this.XMLReq.response.length;
228
- this.item.responseSizeText = (0, utils_js_1.formatByteSize)(this.item.responseSize);
229
- }
230
- break;
231
- default:
232
- this.item.status = this.XMLReq.status;
233
- this.item.statusText = 'Unknown';
234
- break;
235
- }
236
- }
237
- }
238
- exports.XHRProxyHandler = XHRProxyHandler;
239
- class XHRProxy {
240
- static create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher) {
241
- return new Proxy(XMLHttpRequest, {
242
- construct(original) {
243
- const XMLReq = new original();
244
- return new Proxy(XMLReq, new XHRProxyHandler(XMLReq, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher));
245
- },
246
- });
247
- }
248
- }
249
- exports.default = XHRProxy;
@@ -1,16 +0,0 @@
1
- import { NetworkRequest } from '../../common/messages.gen.js';
2
- import { RequestResponseData } from './types.js';
3
- export declare class BeaconProxyHandler<T extends typeof navigator.sendBeacon> implements ProxyHandler<T> {
4
- private readonly ignoredHeaders;
5
- private readonly setSessionTokenHeader;
6
- private readonly sanitize;
7
- private readonly sendMessage;
8
- private readonly isServiceUrl;
9
- constructor(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData | null, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean);
10
- apply(target: T, thisArg: T, argsList: any[]): any;
11
- }
12
- export default class BeaconProxy {
13
- static origSendBeacon: (url: string | URL, data?: BodyInit | null | undefined) => boolean;
14
- static hasSendBeacon(): boolean;
15
- static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData | null, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean): any;
16
- }
@@ -1,79 +0,0 @@
1
- import NetworkMessage from './networkMessage.js';
2
- import { genStringBody, getURL } from './utils.js';
3
- // https://fetch.spec.whatwg.org/#concept-bodyinit-extract
4
- const getContentType = (data) => {
5
- if (data instanceof Blob) {
6
- return data.type;
7
- }
8
- if (data instanceof FormData) {
9
- return 'multipart/form-data';
10
- }
11
- if (data instanceof URLSearchParams) {
12
- return 'application/x-www-form-urlencoded;charset=UTF-8';
13
- }
14
- return 'text/plain;charset=UTF-8';
15
- };
16
- export class BeaconProxyHandler {
17
- constructor(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
18
- this.ignoredHeaders = ignoredHeaders;
19
- this.setSessionTokenHeader = setSessionTokenHeader;
20
- this.sanitize = sanitize;
21
- this.sendMessage = sendMessage;
22
- this.isServiceUrl = isServiceUrl;
23
- }
24
- apply(target, thisArg, argsList) {
25
- const urlString = argsList[0];
26
- const data = argsList[1];
27
- const item = new NetworkMessage(this.ignoredHeaders, this.setSessionTokenHeader, this.sanitize);
28
- if (this.isServiceUrl(urlString)) {
29
- return target.apply(thisArg, argsList);
30
- }
31
- const url = getURL(urlString);
32
- item.method = 'POST';
33
- item.url = urlString;
34
- item.name = (url.pathname.split('/').pop() || '') + url.search;
35
- item.requestType = 'beacon';
36
- item.requestHeader = { 'Content-Type': getContentType(data) };
37
- item.status = 0;
38
- item.statusText = 'Pending';
39
- if (url.search && url.searchParams) {
40
- item.getData = {};
41
- for (const [key, value] of url.searchParams) {
42
- item.getData[key] = value;
43
- }
44
- }
45
- item.requestData = genStringBody(data);
46
- if (!item.startTime) {
47
- item.startTime = performance.now();
48
- }
49
- const isSuccess = target.apply(thisArg, argsList);
50
- if (isSuccess) {
51
- item.endTime = performance.now();
52
- item.duration = item.endTime - (item.startTime || item.endTime);
53
- item.status = 0;
54
- item.statusText = 'Sent';
55
- item.readyState = 4;
56
- }
57
- else {
58
- item.status = 500;
59
- item.statusText = 'Unknown';
60
- }
61
- const msg = item.getMessage();
62
- if (msg) {
63
- this.sendMessage(msg);
64
- }
65
- return isSuccess;
66
- }
67
- }
68
- export default class BeaconProxy {
69
- static hasSendBeacon() {
70
- return !!BeaconProxy.origSendBeacon;
71
- }
72
- static create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
73
- if (!BeaconProxy.hasSendBeacon()) {
74
- return undefined;
75
- }
76
- return new Proxy(BeaconProxy.origSendBeacon, new BeaconProxyHandler(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl));
77
- }
78
- }
79
- BeaconProxy.origSendBeacon = window?.navigator?.sendBeacon;
@@ -1,34 +0,0 @@
1
- /**
2
- * I took inspiration in few stack exchange posts
3
- * and Tencent vConsole library (MIT)
4
- * by wrapping the XMLHttpRequest object in a Proxy
5
- * we can intercept the network requests
6
- * in not-so-hacky way
7
- * */
8
- import NetworkMessage from './networkMessage.js';
9
- import { RequestResponseData } from './types.js';
10
- import { NetworkRequest } from '../../common/messages.gen.js';
11
- export declare class ResponseProxyHandler<T extends Response> implements ProxyHandler<T> {
12
- resp: Response;
13
- item: NetworkMessage;
14
- constructor(resp: T, item: NetworkMessage);
15
- set(target: T, key: string, value: (args: any[]) => any): boolean;
16
- get(target: T, key: string): any;
17
- protected mockReader(): void;
18
- }
19
- export declare class FetchProxyHandler<T extends typeof fetch> implements ProxyHandler<T> {
20
- private readonly ignoredHeaders;
21
- private readonly setSessionTokenHeader;
22
- private readonly sanitize;
23
- private readonly sendMessage;
24
- private readonly isServiceUrl;
25
- private readonly tokenUrlMatcher?;
26
- constructor(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData | null, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: ((url: string) => boolean) | undefined);
27
- apply(target: T, _: typeof window, argsList: [RequestInfo | URL, RequestInit]): any;
28
- protected beforeFetch(item: NetworkMessage, input: RequestInfo | string, init?: RequestInit): void;
29
- protected afterFetch(item: NetworkMessage): (resp: Response) => Response;
30
- protected handleResponseBody(resp: Response, item: NetworkMessage): Promise<string> | Promise<ArrayBuffer>;
31
- }
32
- export default class FetchProxy {
33
- static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData | null, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: (url: string) => boolean): typeof fetch;
34
- }