@wutiange/log-listener-plugin 2.0.1 → 2.0.2-alpha.2

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 (65) hide show
  1. package/README.md +166 -163
  2. package/dist/index.cjs.js +7 -0
  3. package/dist/index.cjs.js.map +1 -0
  4. package/dist/index.d.ts +34 -2
  5. package/dist/index.esm.js +5 -0
  6. package/dist/index.esm.js.map +1 -0
  7. package/index.ts +3 -3
  8. package/package.json +52 -59
  9. package/src/HTTPInterceptor.ts +340 -340
  10. package/src/Server.ts +174 -178
  11. package/src/__mocks__/react-native/Libraries/Blob/FileReader.js +44 -44
  12. package/src/__mocks__/react-native/Libraries/Network/XHRInterceptor.js +39 -39
  13. package/src/__tests__/HTTPInterceptor.test.ts +322 -322
  14. package/src/__tests__/Server.test.ts +150 -150
  15. package/src/__tests__/utils.test.ts +114 -114
  16. package/src/common.ts +57 -57
  17. package/src/logPlugin.ts +238 -231
  18. package/src/logger.ts +15 -15
  19. package/src/utils.ts +135 -112
  20. package/LICENSE +0 -201
  21. package/dist/console.d.ts +0 -1
  22. package/dist/console.js +0 -20
  23. package/dist/console.js.map +0 -1
  24. package/dist/fetch.d.ts +0 -1
  25. package/dist/fetch.js +0 -48
  26. package/dist/fetch.js.map +0 -1
  27. package/dist/index.js +0 -8
  28. package/dist/index.js.map +0 -1
  29. package/dist/src/HTTPInterceptor.d.ts +0 -50
  30. package/dist/src/HTTPInterceptor.js +0 -227
  31. package/dist/src/HTTPInterceptor.js.map +0 -1
  32. package/dist/src/__mocks__/react-native/Libraries/Blob/FileReader.d.ts +0 -14
  33. package/dist/src/__mocks__/react-native/Libraries/Blob/FileReader.js +0 -41
  34. package/dist/src/__mocks__/react-native/Libraries/Blob/FileReader.js.map +0 -1
  35. package/dist/src/__mocks__/react-native/Libraries/Network/XHRInterceptor.d.ts +0 -17
  36. package/dist/src/__mocks__/react-native/Libraries/Network/XHRInterceptor.js +0 -34
  37. package/dist/src/__mocks__/react-native/Libraries/Network/XHRInterceptor.js.map +0 -1
  38. package/dist/src/__tests__/HTTPInterceptor.test.d.ts +0 -9
  39. package/dist/src/__tests__/HTTPInterceptor.test.js +0 -281
  40. package/dist/src/__tests__/HTTPInterceptor.test.js.map +0 -1
  41. package/dist/src/__tests__/Server.test.d.ts +0 -1
  42. package/dist/src/__tests__/Server.test.js +0 -116
  43. package/dist/src/__tests__/Server.test.js.map +0 -1
  44. package/dist/src/__tests__/console.test.d.ts +0 -1
  45. package/dist/src/__tests__/console.test.js +0 -29
  46. package/dist/src/__tests__/console.test.js.map +0 -1
  47. package/dist/src/__tests__/utils.test.d.ts +0 -1
  48. package/dist/src/__tests__/utils.test.js +0 -112
  49. package/dist/src/__tests__/utils.test.js.map +0 -1
  50. package/dist/src/common.d.ts +0 -14
  51. package/dist/src/common.js +0 -54
  52. package/dist/src/common.js.map +0 -1
  53. package/dist/src/logPlugin.d.ts +0 -35
  54. package/dist/src/logPlugin.js +0 -188
  55. package/dist/src/logPlugin.js.map +0 -1
  56. package/dist/src/logger.d.ts +0 -6
  57. package/dist/src/logger.js +0 -16
  58. package/dist/src/logger.js.map +0 -1
  59. package/dist/src/server.d.ts +0 -21
  60. package/dist/src/server.js +0 -178
  61. package/dist/src/server.js.map +0 -1
  62. package/dist/src/utils.d.ts +0 -6
  63. package/dist/src/utils.js +0 -106
  64. package/dist/src/utils.js.map +0 -1
  65. package/tsconfig.json +0 -27
@@ -1,340 +1,340 @@
1
- import XHRInterceptor from 'react-native/Libraries/Network/XHRInterceptor';
2
- import BlobFileReader from 'react-native/Libraries/Blob/FileReader';
3
- import {Blob} from 'buffer';
4
- import { createClassWithErrorHandling, formDataToString } from './utils';
5
- import logger from './logger';
6
-
7
- type StartNetworkLoggingOptions = {
8
- /** List of hosts to ignore, e.g. `services.test.com` */
9
- ignoredHosts?: string[];
10
- /** List of urls to ignore, e.g. `https://services.test.com/test` */
11
- ignoredUrls?: string[];
12
- /**
13
- * List of url patterns to ignore, e.g. `/^GET https://test.com\/pages\/.*$/`
14
- *
15
- * Url to match with is in the format: `${method} ${url}`, e.g. `GET https://test.com/pages/123`
16
- */
17
- ignoredPatterns?: RegExp[];
18
- /**
19
- * Force the network logger to start even if another program is using the network interceptor
20
- * e.g. a dev/debuging program
21
- */
22
- forceEnable?: boolean;
23
- };
24
-
25
- interface HttpRequestInfo {
26
- id: string;
27
- method: RequestMethod;
28
- url: string;
29
- timeout: number;
30
- requestHeaders: Record<string, string>;
31
- requestData: any | null;
32
- startTime: number;
33
- endTime: number;
34
- responseHeaders: Headers;
35
- responseData: any | null;
36
- status: number;
37
- duration: number;
38
- responseContentType: string;
39
- responseSize: number;
40
- responseURL: string;
41
- responseType: string;
42
- }
43
-
44
- type RequestMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
45
-
46
- type XHR = {
47
- uniqueId: string;
48
- responseHeaders?: Headers;
49
- };
50
-
51
- type EventName =
52
- | 'open'
53
- | 'requestHeader'
54
- | 'headerReceived'
55
- | 'send'
56
- | 'response';
57
-
58
- const extractHost = (url: string) => {
59
- const host = url.split('//')[1]?.split(':')[0]?.split('/')[0] || undefined;
60
-
61
- return host;
62
- };
63
-
64
- const generateUniqueId = () => {
65
- return Date.now().toString(36) + Math.random().toString(36).substr(2);
66
- };
67
-
68
- const parseResponseBlob = async (response: Blob) => {
69
- const blobReader = new BlobFileReader();
70
- blobReader.readAsText(response);
71
-
72
- return await new Promise<string>((resolve, reject) => {
73
- const handleError = () => reject(blobReader.error);
74
-
75
- blobReader.addEventListener('load', () => {
76
- resolve(blobReader.result);
77
- });
78
- blobReader.addEventListener('error', handleError);
79
- blobReader.addEventListener('abort', handleError);
80
- });
81
- };
82
-
83
- const getResponseBody = async (responseType: string, response: any) => {
84
- try {
85
- if (responseType === 'blob' && response) {
86
- return await parseResponseBlob(response as unknown as Blob);
87
- }
88
- return response ?? null;
89
- } catch (error) {
90
- logger.warn("getResponseBody---error---", error)
91
- return null;
92
- }
93
- };
94
-
95
- class HTTPInterceptor {
96
- private static _index = 0;
97
- private ignoredHosts: Set<string> | undefined;
98
- private ignoredUrls: Set<string> | undefined;
99
- private ignoredPatterns: RegExp[] | undefined;
100
- // 只保存正在请求中的
101
- private allRequests = new Map<string, Partial<HttpRequestInfo>>();
102
-
103
- private userListeners: [
104
- EventName,
105
- (data: Partial<HttpRequestInfo>) => Promise<void> | void,
106
- ][] = [];
107
-
108
- private enabled = false;
109
-
110
- addListener = (
111
- eventName: EventName,
112
- listener: (data: Partial<HttpRequestInfo>) => Promise<void> | void,
113
- ) => {
114
- // 如果之前已经订阅过了就过滤掉
115
- if (
116
- this.userListeners.find(
117
- ([name, tempListener]) =>
118
- name === eventName && tempListener === listener,
119
- )
120
- ) {
121
- return;
122
- }
123
- this.userListeners.push([eventName, listener]);
124
-
125
- return () => {
126
- this.userListeners = this.userListeners.filter(
127
- ([name, tempListener]) =>
128
- name !== eventName || tempListener !== listener,
129
- );
130
- };
131
- };
132
-
133
- removeListener = (
134
- eventName: EventName,
135
- listener: (data: Partial<HttpRequestInfo>) => Promise<void> | void,
136
- ) => {
137
- this.userListeners = this.userListeners.filter(
138
- ([name, tempListener]) => name !== eventName || tempListener !== listener,
139
- );
140
- };
141
-
142
- removeAllListener() {
143
- this.userListeners = [];
144
- }
145
-
146
- private listenerHandle = (
147
- eventName: EventName,
148
- data: Partial<HttpRequestInfo>,
149
- ) => {
150
- this.userListeners.forEach(async ([name, listener]) => {
151
- try {
152
- if (name === eventName) {
153
- await listener(data);
154
- }
155
- } catch (error: any) {
156
- console.warn(`eventName=${eventName}, error=${error?.message}`)
157
- }
158
- });
159
- };
160
-
161
- private openHandle = (method: RequestMethod, url: string, xhr: XHR) => {
162
- if (this.ignoredHosts) {
163
- const host = extractHost(url);
164
- if (host && this.ignoredHosts.has(host)) {
165
- return;
166
- }
167
- }
168
- if (this.ignoredUrls && this.ignoredUrls.has(url)) {
169
- return;
170
- }
171
-
172
- if (this.ignoredPatterns) {
173
- if (
174
- this.ignoredPatterns.some(pattern => pattern.test(`${method} ${url}`))
175
- ) {
176
- return;
177
- }
178
- }
179
- xhr.uniqueId = HTTPInterceptor._index + generateUniqueId();
180
- const newRequest = {
181
- id: xhr.uniqueId,
182
- method,
183
- url,
184
- };
185
- this.allRequests.set(xhr.uniqueId, newRequest);
186
- this.listenerHandle('open', newRequest);
187
- };
188
-
189
- private requestHeaderHandle = (header: string, value: string, xhr: XHR) => {
190
- const currentRequest = this.allRequests.get(xhr.uniqueId);
191
- if (!currentRequest) {
192
- return;
193
- }
194
- if (!currentRequest.requestHeaders) {
195
- currentRequest.requestHeaders = {};
196
- }
197
- currentRequest.requestHeaders[header] = value;
198
- this.listenerHandle('requestHeader', currentRequest);
199
- };
200
-
201
- private headerReceivedHandle = (
202
- responseContentType: string,
203
- responseSize: number,
204
- responseHeaders: Headers,
205
- xhr: XHR,
206
- ) => {
207
- const currentRequest = this.allRequests.get(xhr.uniqueId);
208
- if (!currentRequest) {
209
- return;
210
- }
211
- currentRequest.responseContentType = responseContentType;
212
- currentRequest.responseSize = responseSize;
213
- currentRequest.responseHeaders = xhr.responseHeaders;
214
- this.listenerHandle('headerReceived', currentRequest);
215
- };
216
-
217
- private responseHandle = async (
218
- status: number,
219
- timeout: number,
220
- response: any,
221
- responseURL: string,
222
- responseType: string,
223
- xhr: XHR,
224
- ) => {
225
- const currentRequest = this.allRequests.get(xhr.uniqueId);
226
- if (!currentRequest) {
227
- return;
228
- }
229
- currentRequest.endTime = Date.now();
230
- currentRequest.status = status;
231
- currentRequest.timeout = timeout;
232
- currentRequest.responseData = await getResponseBody(responseType, response);
233
- currentRequest.responseURL = responseURL;
234
- currentRequest.responseType = responseType;
235
- currentRequest.duration =
236
- currentRequest.endTime - (currentRequest.startTime ?? 0);
237
- this.listenerHandle('response', currentRequest);
238
- this.allRequests.delete(xhr.uniqueId);
239
- };
240
-
241
- private sendHandle = (data: any, xhr: XHR) => {
242
- const currentRequest = this.allRequests.get(xhr.uniqueId);
243
- if (!currentRequest) {
244
- return;
245
- }
246
- try {
247
- if (data && typeof data === 'object' && data instanceof FormData) {
248
- currentRequest.requestData = formDataToString(data);
249
- } else {
250
- currentRequest.requestData = JSON.parse(data);
251
- }
252
- } catch (error) {
253
- currentRequest.requestData = null;
254
- }
255
- currentRequest.startTime = Date.now();
256
- this.listenerHandle('send', currentRequest);
257
- };
258
-
259
- setIgnoredUrls = (ignoredUrls: string[]) => {
260
- if (ignoredUrls?.length) {
261
- if (
262
- !Array.isArray(ignoredUrls) ||
263
- typeof ignoredUrls[0] !== 'string'
264
- ) {
265
- console.warn(
266
- 'ignoredUrls must be an array of strings. The logger has not been started.',
267
- );
268
- return;
269
- }
270
- this.ignoredUrls = new Set(ignoredUrls);
271
- }
272
- }
273
-
274
- enable = (options?: StartNetworkLoggingOptions) => {
275
- try {
276
- if (
277
- this.enabled ||
278
- (XHRInterceptor.isInterceptorEnabled() && !options?.forceEnable)
279
- ) {
280
- if (!this.enabled) {
281
- console.warn(
282
- 'network interceptor has not been enabled as another interceptor is already running (e.g. another debugging program). Use option `forceEnable: true` to override this behaviour.',
283
- );
284
- }
285
- return;
286
- }
287
-
288
- if (options?.ignoredHosts) {
289
- if (
290
- !Array.isArray(options.ignoredHosts) ||
291
- typeof options.ignoredHosts[0] !== 'string'
292
- ) {
293
- console.warn(
294
- 'ignoredHosts must be an array of strings. The logger has not been started.',
295
- );
296
- return;
297
- }
298
- this.ignoredHosts = new Set(options.ignoredHosts);
299
- }
300
-
301
- if (options?.ignoredPatterns) {
302
- this.ignoredPatterns = options.ignoredPatterns;
303
- }
304
- this.setIgnoredUrls(options?.ignoredUrls)
305
- XHRInterceptor.setOpenCallback(this.openHandle);
306
- XHRInterceptor.setRequestHeaderCallback(this.requestHeaderHandle);
307
- XHRInterceptor.setHeaderReceivedCallback(this.headerReceivedHandle);
308
- XHRInterceptor.setSendCallback(this.sendHandle);
309
- XHRInterceptor.setResponseCallback(this.responseHandle);
310
- XHRInterceptor.enableInterception();
311
- this.enabled = true;
312
- } catch (error) {}
313
- };
314
-
315
- disable = () => {
316
- if (!this.enabled) {
317
- return;
318
- }
319
- XHRInterceptor.disableInterception();
320
- this.enabled = false;
321
- };
322
-
323
- reset = () => {
324
- this.disable();
325
- this.removeAllListener();
326
- this.ignoredHosts = undefined;
327
- this.ignoredUrls = undefined;
328
- this.ignoredPatterns = undefined;
329
- this.allRequests.clear();
330
- };
331
- }
332
-
333
- const SafeHTTPInterceptor = createClassWithErrorHandling(HTTPInterceptor)
334
- const httpInterceptor = new SafeHTTPInterceptor();
335
- export {
336
- type StartNetworkLoggingOptions,
337
- httpInterceptor,
338
- type EventName,
339
- type RequestMethod,
340
- };
1
+ import XHRInterceptor from 'react-native/Libraries/Network/XHRInterceptor';
2
+ import BlobFileReader from 'react-native/Libraries/Blob/FileReader';
3
+ import {Blob} from 'buffer';
4
+ import { createClassWithErrorHandling, formDataToString } from './utils';
5
+ import logger from './logger';
6
+
7
+ type StartNetworkLoggingOptions = {
8
+ /** List of hosts to ignore, e.g. `services.test.com` */
9
+ ignoredHosts?: string[];
10
+ /** List of urls to ignore, e.g. `https://services.test.com/test` */
11
+ ignoredUrls?: string[];
12
+ /**
13
+ * List of url patterns to ignore, e.g. `/^GET https://test.com\/pages\/.*$/`
14
+ *
15
+ * Url to match with is in the format: `${method} ${url}`, e.g. `GET https://test.com/pages/123`
16
+ */
17
+ ignoredPatterns?: RegExp[];
18
+ /**
19
+ * Force the network logger to start even if another program is using the network interceptor
20
+ * e.g. a dev/debuging program
21
+ */
22
+ forceEnable?: boolean;
23
+ };
24
+
25
+ interface HttpRequestInfo {
26
+ id: string;
27
+ method: RequestMethod;
28
+ url: string;
29
+ timeout: number;
30
+ requestHeaders: Record<string, string>;
31
+ requestData: any | null;
32
+ startTime: number;
33
+ endTime: number;
34
+ responseHeaders: Headers;
35
+ responseData: any | null;
36
+ status: number;
37
+ duration: number;
38
+ responseContentType: string;
39
+ responseSize: number;
40
+ responseURL: string;
41
+ responseType: string;
42
+ }
43
+
44
+ type RequestMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
45
+
46
+ type XHR = {
47
+ uniqueId: string;
48
+ responseHeaders?: Headers;
49
+ };
50
+
51
+ type EventName =
52
+ | 'open'
53
+ | 'requestHeader'
54
+ | 'headerReceived'
55
+ | 'send'
56
+ | 'response';
57
+
58
+ const extractHost = (url: string) => {
59
+ const host = url.split('//')[1]?.split(':')[0]?.split('/')[0] || undefined;
60
+
61
+ return host;
62
+ };
63
+
64
+ const generateUniqueId = () => {
65
+ return Date.now().toString(36) + Math.random().toString(36).substr(2);
66
+ };
67
+
68
+ const parseResponseBlob = async (response: Blob) => {
69
+ const blobReader = new BlobFileReader();
70
+ blobReader.readAsText(response);
71
+
72
+ return await new Promise<string>((resolve, reject) => {
73
+ const handleError = () => reject(blobReader.error);
74
+
75
+ blobReader.addEventListener('load', () => {
76
+ resolve(blobReader.result ?? '');
77
+ });
78
+ blobReader.addEventListener('error', handleError);
79
+ blobReader.addEventListener('abort', handleError);
80
+ });
81
+ };
82
+
83
+ const getResponseBody = async (responseType: string, response: any) => {
84
+ try {
85
+ if (responseType === 'blob' && response) {
86
+ return await parseResponseBlob(response as unknown as Blob);
87
+ }
88
+ return response ?? null;
89
+ } catch (error) {
90
+ logger.warn("getResponseBody---error---", error)
91
+ return null;
92
+ }
93
+ };
94
+
95
+ class HTTPInterceptor {
96
+ private static _index = 0;
97
+ private ignoredHosts: Set<string> | undefined;
98
+ private ignoredUrls: Set<string> | undefined;
99
+ private ignoredPatterns: RegExp[] | undefined;
100
+ // 只保存正在请求中的
101
+ private allRequests = new Map<string, Partial<HttpRequestInfo>>();
102
+
103
+ private userListeners: [
104
+ EventName,
105
+ (data: Partial<HttpRequestInfo>) => Promise<void> | void,
106
+ ][] = [];
107
+
108
+ private enabled = false;
109
+
110
+ addListener = (
111
+ eventName: EventName,
112
+ listener: (data: Partial<HttpRequestInfo>) => Promise<void> | void,
113
+ ) => {
114
+ // 如果之前已经订阅过了就过滤掉
115
+ if (
116
+ this.userListeners.find(
117
+ ([name, tempListener]) =>
118
+ name === eventName && tempListener === listener,
119
+ )
120
+ ) {
121
+ return;
122
+ }
123
+ this.userListeners.push([eventName, listener]);
124
+
125
+ return () => {
126
+ this.userListeners = this.userListeners.filter(
127
+ ([name, tempListener]) =>
128
+ name !== eventName || tempListener !== listener,
129
+ );
130
+ };
131
+ };
132
+
133
+ removeListener = (
134
+ eventName: EventName,
135
+ listener: (data: Partial<HttpRequestInfo>) => Promise<void> | void,
136
+ ) => {
137
+ this.userListeners = this.userListeners.filter(
138
+ ([name, tempListener]) => name !== eventName || tempListener !== listener,
139
+ );
140
+ };
141
+
142
+ removeAllListener() {
143
+ this.userListeners = [];
144
+ }
145
+
146
+ private listenerHandle = (
147
+ eventName: EventName,
148
+ data: Partial<HttpRequestInfo>,
149
+ ) => {
150
+ this.userListeners.forEach(async ([name, listener]) => {
151
+ try {
152
+ if (name === eventName) {
153
+ await listener(data);
154
+ }
155
+ } catch (error: any) {
156
+ console.warn(`eventName=${eventName}, error=${error?.message}`)
157
+ }
158
+ });
159
+ };
160
+
161
+ private openHandle = (method: RequestMethod, url: string, xhr: XHR) => {
162
+ if (this.ignoredHosts) {
163
+ const host = extractHost(url);
164
+ if (host && this.ignoredHosts.has(host)) {
165
+ return;
166
+ }
167
+ }
168
+ if (this.ignoredUrls && this.ignoredUrls.has(url)) {
169
+ return;
170
+ }
171
+
172
+ if (this.ignoredPatterns) {
173
+ if (
174
+ this.ignoredPatterns.some(pattern => pattern.test(`${method} ${url}`))
175
+ ) {
176
+ return;
177
+ }
178
+ }
179
+ xhr.uniqueId = HTTPInterceptor._index + generateUniqueId();
180
+ const newRequest = {
181
+ id: xhr.uniqueId,
182
+ method,
183
+ url,
184
+ };
185
+ this.allRequests.set(xhr.uniqueId, newRequest);
186
+ this.listenerHandle('open', newRequest);
187
+ };
188
+
189
+ private requestHeaderHandle = (header: string, value: string, xhr: XHR) => {
190
+ const currentRequest = this.allRequests.get(xhr.uniqueId);
191
+ if (!currentRequest) {
192
+ return;
193
+ }
194
+ if (!currentRequest.requestHeaders) {
195
+ currentRequest.requestHeaders = {};
196
+ }
197
+ currentRequest.requestHeaders[header] = value;
198
+ this.listenerHandle('requestHeader', currentRequest);
199
+ };
200
+
201
+ private headerReceivedHandle = (
202
+ responseContentType: string,
203
+ responseSize: number,
204
+ responseHeaders: Headers,
205
+ xhr: XHR,
206
+ ) => {
207
+ const currentRequest = this.allRequests.get(xhr.uniqueId);
208
+ if (!currentRequest) {
209
+ return;
210
+ }
211
+ currentRequest.responseContentType = responseContentType;
212
+ currentRequest.responseSize = responseSize;
213
+ currentRequest.responseHeaders = xhr.responseHeaders;
214
+ this.listenerHandle('headerReceived', currentRequest);
215
+ };
216
+
217
+ private responseHandle = async (
218
+ status: number,
219
+ timeout: number,
220
+ response: any,
221
+ responseURL: string,
222
+ responseType: string,
223
+ xhr: XHR,
224
+ ) => {
225
+ const currentRequest = this.allRequests.get(xhr.uniqueId);
226
+ if (!currentRequest) {
227
+ return;
228
+ }
229
+ currentRequest.endTime = Date.now();
230
+ currentRequest.status = status;
231
+ currentRequest.timeout = timeout;
232
+ currentRequest.responseData = await getResponseBody(responseType, response);
233
+ currentRequest.responseURL = responseURL;
234
+ currentRequest.responseType = responseType;
235
+ currentRequest.duration =
236
+ currentRequest.endTime - (currentRequest.startTime ?? 0);
237
+ this.listenerHandle('response', currentRequest);
238
+ this.allRequests.delete(xhr.uniqueId);
239
+ };
240
+
241
+ private sendHandle = (data: any, xhr: XHR) => {
242
+ const currentRequest = this.allRequests.get(xhr.uniqueId);
243
+ if (!currentRequest) {
244
+ return;
245
+ }
246
+ try {
247
+ if (data && typeof data === 'object' && data instanceof FormData) {
248
+ currentRequest.requestData = formDataToString(data);
249
+ } else {
250
+ currentRequest.requestData = JSON.parse(data);
251
+ }
252
+ } catch (error) {
253
+ currentRequest.requestData = null;
254
+ }
255
+ currentRequest.startTime = Date.now();
256
+ this.listenerHandle('send', currentRequest);
257
+ };
258
+
259
+ setIgnoredUrls = (ignoredUrls: string[]) => {
260
+ if (ignoredUrls?.length) {
261
+ if (
262
+ !Array.isArray(ignoredUrls) ||
263
+ typeof ignoredUrls[0] !== 'string'
264
+ ) {
265
+ console.warn(
266
+ 'ignoredUrls must be an array of strings. The logger has not been started.',
267
+ );
268
+ return;
269
+ }
270
+ this.ignoredUrls = new Set(ignoredUrls);
271
+ }
272
+ }
273
+
274
+ enable = (options?: StartNetworkLoggingOptions) => {
275
+ try {
276
+ if (
277
+ this.enabled ||
278
+ (XHRInterceptor.isInterceptorEnabled() && !options?.forceEnable)
279
+ ) {
280
+ if (!this.enabled) {
281
+ console.warn(
282
+ 'network interceptor has not been enabled as another interceptor is already running (e.g. another debugging program). Use option `forceEnable: true` to override this behaviour.',
283
+ );
284
+ }
285
+ return;
286
+ }
287
+
288
+ if (options?.ignoredHosts) {
289
+ if (
290
+ !Array.isArray(options.ignoredHosts) ||
291
+ typeof options.ignoredHosts[0] !== 'string'
292
+ ) {
293
+ console.warn(
294
+ 'ignoredHosts must be an array of strings. The logger has not been started.',
295
+ );
296
+ return;
297
+ }
298
+ this.ignoredHosts = new Set(options.ignoredHosts);
299
+ }
300
+
301
+ if (options?.ignoredPatterns) {
302
+ this.ignoredPatterns = options.ignoredPatterns;
303
+ }
304
+ this.setIgnoredUrls(options?.ignoredUrls ?? [])
305
+ XHRInterceptor.setOpenCallback(this.openHandle);
306
+ XHRInterceptor.setRequestHeaderCallback(this.requestHeaderHandle);
307
+ XHRInterceptor.setHeaderReceivedCallback(this.headerReceivedHandle);
308
+ XHRInterceptor.setSendCallback(this.sendHandle);
309
+ XHRInterceptor.setResponseCallback(this.responseHandle);
310
+ XHRInterceptor.enableInterception();
311
+ this.enabled = true;
312
+ } catch (error) {}
313
+ };
314
+
315
+ disable = () => {
316
+ if (!this.enabled) {
317
+ return;
318
+ }
319
+ XHRInterceptor.disableInterception();
320
+ this.enabled = false;
321
+ };
322
+
323
+ reset = () => {
324
+ this.disable();
325
+ this.removeAllListener();
326
+ this.ignoredHosts = undefined;
327
+ this.ignoredUrls = undefined;
328
+ this.ignoredPatterns = undefined;
329
+ this.allRequests.clear();
330
+ };
331
+ }
332
+
333
+ const SafeHTTPInterceptor = createClassWithErrorHandling(HTTPInterceptor)
334
+ const httpInterceptor = new SafeHTTPInterceptor();
335
+ export {
336
+ type StartNetworkLoggingOptions,
337
+ httpInterceptor,
338
+ type EventName,
339
+ type RequestMethod,
340
+ };