@rozenite/network-activity-plugin 1.0.0-alpha.8 → 1.0.0
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/README.md +2 -0
- package/dist/App.html +2 -2
- package/dist/assets/{App-R2ZMH9wJ.css → App-BrSkOkws.css} +269 -2
- package/dist/assets/{App-lNMijPJ4.js → App-C6wCDVkW.js} +17485 -10814
- package/dist/event-source.cjs +22 -0
- package/dist/event-source.js +23 -0
- package/dist/react-native.cjs +4 -1
- package/dist/react-native.js +4 -1
- package/dist/rozenite.json +1 -1
- package/dist/src/react-native/config.d.ts +20 -0
- package/dist/src/react-native/{network-inspector.d.ts → http/network-inspector.d.ts} +1 -1
- package/dist/src/react-native/http/overrides-registry.d.ts +6 -0
- package/dist/src/react-native/{xhr-interceptor.d.ts → http/xhr-interceptor.d.ts} +7 -1
- package/dist/src/react-native/sse/event-source.d.ts +2 -0
- package/dist/src/react-native/sse/sse-inspector.d.ts +9 -0
- package/dist/src/react-native/sse/sse-interceptor.d.ts +36 -0
- package/dist/src/react-native/sse/types.d.ts +6 -0
- package/dist/src/react-native/useNetworkActivityDevTools.d.ts +2 -1
- package/dist/src/react-native/utils/getBlobName.d.ts +35 -0
- package/dist/src/react-native/utils/getFormDataEntries.d.ts +18 -0
- package/dist/src/react-native/utils.d.ts +6 -0
- package/dist/src/react-native/websocket/websocket-inspector.d.ts +9 -0
- package/dist/src/react-native/websocket/websocket-interceptor.d.ts +74 -0
- package/dist/src/shared/client.d.ts +53 -6
- package/dist/src/shared/sse-events.d.ts +38 -0
- package/dist/src/shared/websocket-events.d.ts +60 -0
- package/dist/src/ui/components/Badge.d.ts +1 -1
- package/dist/src/ui/components/Button.d.ts +2 -2
- package/dist/src/ui/components/CodeBlock.d.ts +3 -0
- package/dist/src/ui/components/CodeEditor.d.ts +5 -0
- package/dist/src/ui/components/CookieCard.d.ts +7 -0
- package/dist/src/ui/components/CopyRequestDropdown.d.ts +7 -0
- package/dist/src/ui/components/DropdownMenu.d.ts +27 -0
- package/dist/src/ui/components/FilterBar.d.ts +10 -0
- package/dist/src/ui/components/JsonTreeCopyableItem.d.ts +7 -0
- package/dist/src/ui/components/KeyValueGrid.d.ts +13 -0
- package/dist/src/ui/components/OverrideResponse.d.ts +8 -0
- package/dist/src/ui/components/RequestBody.d.ts +6 -0
- package/dist/src/ui/components/RequestList.d.ts +13 -28
- package/dist/src/ui/components/ScrollArea.d.ts +3 -2
- package/dist/src/ui/components/Section.d.ts +8 -0
- package/dist/src/ui/components/Separator.d.ts +2 -1
- package/dist/src/ui/components/SidePanel.d.ts +1 -0
- package/dist/src/ui/components/Tabs.d.ts +7 -0
- package/dist/src/ui/components/Toolbar.d.ts +1 -0
- package/dist/src/ui/hooks/useCopyToClipboard.d.ts +4 -0
- package/dist/src/ui/state/derived.d.ts +5 -0
- package/dist/src/ui/state/hooks.d.ts +21 -0
- package/dist/src/ui/state/model.d.ts +103 -0
- package/dist/src/ui/state/store.d.ts +48 -0
- package/dist/src/ui/tabs/CookiesTab.d.ts +3 -6
- package/dist/src/ui/tabs/HeadersTab.d.ts +3 -15
- package/dist/src/ui/tabs/MessagesTab.d.ts +5 -0
- package/dist/src/ui/tabs/RequestTab.d.ts +2 -7
- package/dist/src/ui/tabs/ResponseTab.d.ts +2 -8
- package/dist/src/ui/tabs/SSEMessagesTab.d.ts +5 -0
- package/dist/src/ui/tabs/TimingTab.d.ts +3 -5
- package/dist/src/ui/types.d.ts +4 -1
- package/dist/src/ui/utils/assert.d.ts +1 -0
- package/dist/src/ui/utils/checkRequestBodyBinary.d.ts +2 -0
- package/dist/src/ui/utils/copyToClipboard.d.ts +1 -0
- package/dist/src/ui/utils/escapeShellArg.d.ts +1 -0
- package/dist/src/ui/utils/generateCurlCommand.d.ts +2 -0
- package/dist/src/ui/utils/generateFetchCall.d.ts +2 -0
- package/dist/src/ui/utils/generateMultipartBody.d.ts +4 -0
- package/dist/src/ui/utils/getId.d.ts +1 -0
- package/dist/src/ui/utils/getStatusColor.d.ts +1 -0
- package/dist/src/utils/applyReactNativeRequestHeadersLogic.d.ts +7 -0
- package/dist/src/utils/applyReactNativeResponseHeadersLogic.d.ts +9 -0
- package/dist/src/utils/cookieParser.d.ts +6 -0
- package/dist/src/utils/getContentTypeMimeType.d.ts +2 -0
- package/dist/src/utils/getHttpHeader.d.ts +5 -0
- package/dist/src/utils/getHttpHeaderValueAsString.d.ts +11 -0
- package/dist/src/utils/getStringSizeInBytes.d.ts +1 -0
- package/dist/src/utils/inferContentTypeFromPostData.d.ts +2 -0
- package/dist/src/utils/safeStringify.d.ts +1 -0
- package/dist/src/utils/typeChecks.d.ts +9 -0
- package/dist/useNetworkActivityDevTools.cjs +724 -40
- package/dist/useNetworkActivityDevTools.js +723 -41
- package/package.json +22 -8
- package/react-native.ts +6 -1
- package/src/react-native/config.ts +43 -0
- package/src/react-native/http/network-inspector.ts +388 -0
- package/src/react-native/http/overrides-registry.ts +32 -0
- package/src/react-native/{xhr-interceptor.ts → http/xhr-interceptor.ts} +19 -2
- package/src/react-native/{xml-request.d.ts → http/xml-request.d.ts} +1 -0
- package/src/react-native/sse/event-source.ts +25 -0
- package/src/react-native/sse/sse-inspector.ts +139 -0
- package/src/react-native/sse/sse-interceptor.ts +180 -0
- package/src/react-native/sse/types.ts +9 -0
- package/src/react-native/useNetworkActivityDevTools.ts +156 -4
- package/src/react-native/utils/getBlobName.ts +45 -0
- package/src/react-native/utils/getFormDataEntries.ts +32 -0
- package/src/react-native/utils.ts +43 -0
- package/src/react-native/websocket/websocket-inspector.ts +180 -0
- package/src/react-native/websocket/websocket-interceptor.d.ts +4 -0
- package/src/react-native/websocket/websocket-interceptor.ts +166 -0
- package/src/shared/client.ts +79 -6
- package/src/shared/sse-events.ts +47 -0
- package/src/shared/websocket-events.ts +79 -0
- package/src/ui/components/Button.tsx +1 -0
- package/src/ui/components/CodeBlock.tsx +19 -0
- package/src/ui/components/CodeEditor.tsx +26 -0
- package/src/ui/components/CookieCard.tsx +64 -0
- package/src/ui/components/CopyRequestDropdown.tsx +95 -0
- package/src/ui/components/DropdownMenu.tsx +206 -0
- package/src/ui/components/FilterBar.tsx +117 -0
- package/src/ui/components/Input.tsx +1 -1
- package/src/ui/components/JsonTree.tsx +20 -0
- package/src/ui/components/JsonTreeCopyableItem.tsx +37 -0
- package/src/ui/components/KeyValueGrid.tsx +51 -0
- package/src/ui/components/OverrideResponse.tsx +132 -0
- package/src/ui/components/RequestBody.tsx +86 -0
- package/src/ui/components/RequestList.tsx +101 -131
- package/src/ui/components/ScrollArea.tsx +1 -0
- package/src/ui/components/Section.tsx +46 -0
- package/src/ui/components/SidePanel.tsx +333 -0
- package/src/ui/components/Tabs.tsx +1 -1
- package/src/ui/components/Toolbar.tsx +45 -0
- package/src/ui/globals.css +4 -0
- package/src/ui/hooks/useCopyToClipboard.ts +28 -0
- package/src/ui/state/derived.ts +112 -0
- package/src/ui/state/hooks.ts +52 -0
- package/src/ui/state/model.ts +140 -0
- package/src/ui/state/store.ts +669 -0
- package/src/ui/tabs/CookiesTab.tsx +61 -278
- package/src/ui/tabs/HeadersTab.tsx +85 -103
- package/src/ui/tabs/MessagesTab.tsx +276 -0
- package/src/ui/tabs/RequestTab.tsx +58 -51
- package/src/ui/tabs/ResponseTab.tsx +101 -74
- package/src/ui/tabs/SSEMessagesTab.tsx +224 -0
- package/src/ui/tabs/TimingTab.tsx +30 -43
- package/src/ui/types.ts +4 -1
- package/src/ui/utils/assert.ts +5 -0
- package/src/ui/utils/checkRequestBodyBinary.ts +7 -0
- package/src/ui/utils/copyToClipboard.ts +3 -0
- package/src/ui/utils/escapeShellArg.ts +12 -0
- package/src/ui/utils/generateCurlCommand.ts +83 -0
- package/src/ui/utils/generateFetchCall.ts +64 -0
- package/src/ui/utils/generateMultipartBody.ts +19 -0
- package/src/ui/utils/getId.ts +10 -0
- package/src/ui/utils/getStatusColor.ts +15 -0
- package/src/ui/views/InspectorView.tsx +35 -319
- package/src/utils/applyReactNativeRequestHeadersLogic.ts +30 -0
- package/src/utils/applyReactNativeResponseHeadersLogic.ts +28 -0
- package/src/utils/cookieParser.ts +126 -0
- package/src/utils/getContentTypeMimeType.ts +17 -0
- package/src/utils/getHttpHeader.ts +17 -0
- package/src/utils/getHttpHeaderValueAsString.ts +13 -0
- package/src/utils/getStringSizeInBytes.ts +3 -0
- package/src/utils/inferContentTypeFromPostData.ts +9 -0
- package/src/utils/safeStringify.ts +7 -0
- package/src/utils/typeChecks.ts +27 -0
- package/tailwind.config.ts +3 -0
- package/vite.config.ts +12 -0
- package/dist/src/ui/utils/getHttpHeaderValue.d.ts +0 -2
- package/src/react-native/network-inspector.ts +0 -247
- package/src/ui/utils/getHttpHeaderValue.ts +0 -14
- /package/dist/src/react-native/{network-requests-registry.d.ts → http/network-requests-registry.d.ts} +0 -0
- /package/src/react-native/{network-requests-registry.ts → http/network-requests-registry.ts} +0 -0
|
@@ -2,15 +2,57 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const react = require("react");
|
|
4
4
|
const pluginBridge = require("@rozenite/plugin-bridge");
|
|
5
|
-
|
|
5
|
+
const nanoevents = require("nanoevents");
|
|
6
|
+
const reactNative = require("react-native");
|
|
7
|
+
const WebSocketInterceptor = require("react-native/Libraries/WebSocket/WebSocketInterceptor");
|
|
8
|
+
const eventSource = require("./event-source.cjs");
|
|
9
|
+
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
10
|
+
const WebSocketInterceptor__default = /* @__PURE__ */ _interopDefault(WebSocketInterceptor);
|
|
11
|
+
function safeStringify(data) {
|
|
12
|
+
try {
|
|
13
|
+
return typeof data === "string" ? data : JSON.stringify(data);
|
|
14
|
+
} catch {
|
|
15
|
+
return String(data);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function getHttpHeader(headers, name) {
|
|
6
19
|
const lowerName = name.toLowerCase();
|
|
7
20
|
for (const key in headers) {
|
|
8
21
|
if (key.toLowerCase() === lowerName) {
|
|
9
|
-
return headers[key];
|
|
22
|
+
return { value: headers[key], originalKey: key };
|
|
10
23
|
}
|
|
11
24
|
}
|
|
12
25
|
return void 0;
|
|
13
26
|
}
|
|
27
|
+
function getContentTypeMime(headers) {
|
|
28
|
+
const contentType = getHttpHeader(headers, "content-type");
|
|
29
|
+
if (!contentType) {
|
|
30
|
+
return void 0;
|
|
31
|
+
}
|
|
32
|
+
const { value } = contentType;
|
|
33
|
+
const actualValue = Array.isArray(value) ? value[0] : value;
|
|
34
|
+
return actualValue.split(";")[0].trim();
|
|
35
|
+
}
|
|
36
|
+
const getContentType = (request) => {
|
|
37
|
+
const responseHeaders = request.responseHeaders;
|
|
38
|
+
const responseType = request.responseType;
|
|
39
|
+
const contentType = getContentTypeMime(responseHeaders || {});
|
|
40
|
+
if (contentType) {
|
|
41
|
+
return contentType;
|
|
42
|
+
}
|
|
43
|
+
switch (responseType) {
|
|
44
|
+
case "arraybuffer":
|
|
45
|
+
case "blob":
|
|
46
|
+
return "application/octet-stream";
|
|
47
|
+
case "text":
|
|
48
|
+
case "":
|
|
49
|
+
return "text/plain";
|
|
50
|
+
case "json":
|
|
51
|
+
return "application/json";
|
|
52
|
+
case "document":
|
|
53
|
+
return "text/html";
|
|
54
|
+
}
|
|
55
|
+
};
|
|
14
56
|
const REQUEST_TTL = 1e3 * 60 * 5;
|
|
15
57
|
const getNetworkRequestsRegistry = () => {
|
|
16
58
|
const registry = /* @__PURE__ */ new Map();
|
|
@@ -44,6 +86,28 @@ const getNetworkRequestsRegistry = () => {
|
|
|
44
86
|
clear
|
|
45
87
|
};
|
|
46
88
|
};
|
|
89
|
+
function getBlobName(blob) {
|
|
90
|
+
if (typeof (blob == null ? void 0 : blob.name) === "string") {
|
|
91
|
+
return blob.name;
|
|
92
|
+
}
|
|
93
|
+
if ((blob == null ? void 0 : blob.data) && typeof blob.data.name === "string") {
|
|
94
|
+
return blob.data.name;
|
|
95
|
+
}
|
|
96
|
+
return void 0;
|
|
97
|
+
}
|
|
98
|
+
function getFormDataEntries(formData) {
|
|
99
|
+
if (!formData || typeof formData !== "object") {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
if (typeof formData.entries === "function") {
|
|
103
|
+
return formData.entries();
|
|
104
|
+
}
|
|
105
|
+
if (Array.isArray(formData._parts)) {
|
|
106
|
+
return formData._parts;
|
|
107
|
+
}
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
const XMLHttpRequest = global.XMLHttpRequest || window.XMLHttpRequest;
|
|
47
111
|
const originalXHROpen = XMLHttpRequest.prototype.open;
|
|
48
112
|
const originalXHRSend = XMLHttpRequest.prototype.send;
|
|
49
113
|
const originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
|
|
@@ -52,7 +116,8 @@ let sendCallback;
|
|
|
52
116
|
let requestHeaderCallback;
|
|
53
117
|
let headerReceivedCallback;
|
|
54
118
|
let responseCallback;
|
|
55
|
-
let
|
|
119
|
+
let overrideCallback;
|
|
120
|
+
let isInterceptorEnabled$1 = false;
|
|
56
121
|
const XHRInterceptor = {
|
|
57
122
|
/**
|
|
58
123
|
* Invoked before XMLHttpRequest.open(...) is called.
|
|
@@ -84,11 +149,17 @@ const XHRInterceptor = {
|
|
|
84
149
|
setRequestHeaderCallback(callback) {
|
|
85
150
|
requestHeaderCallback = callback;
|
|
86
151
|
},
|
|
152
|
+
/**
|
|
153
|
+
* Invoked before XMLHttpRequest.send(...) is called.
|
|
154
|
+
*/
|
|
155
|
+
setOverrideCallback(callback) {
|
|
156
|
+
overrideCallback = callback;
|
|
157
|
+
},
|
|
87
158
|
isInterceptorEnabled() {
|
|
88
|
-
return isInterceptorEnabled;
|
|
159
|
+
return isInterceptorEnabled$1;
|
|
89
160
|
},
|
|
90
161
|
enableInterception() {
|
|
91
|
-
if (isInterceptorEnabled) {
|
|
162
|
+
if (isInterceptorEnabled$1) {
|
|
92
163
|
return;
|
|
93
164
|
}
|
|
94
165
|
XMLHttpRequest.prototype.open = function(method, url) {
|
|
@@ -107,11 +178,14 @@ const XHRInterceptor = {
|
|
|
107
178
|
if (sendCallback) {
|
|
108
179
|
sendCallback(data, this);
|
|
109
180
|
}
|
|
181
|
+
if (overrideCallback) {
|
|
182
|
+
overrideCallback(this);
|
|
183
|
+
}
|
|
110
184
|
if (this.addEventListener) {
|
|
111
185
|
this.addEventListener(
|
|
112
186
|
"readystatechange",
|
|
113
187
|
() => {
|
|
114
|
-
if (!isInterceptorEnabled) {
|
|
188
|
+
if (!isInterceptorEnabled$1) {
|
|
115
189
|
return;
|
|
116
190
|
}
|
|
117
191
|
if (this.readyState === this.HEADERS_RECEIVED) {
|
|
@@ -151,14 +225,14 @@ const XHRInterceptor = {
|
|
|
151
225
|
}
|
|
152
226
|
originalXHRSend.apply(this, arguments);
|
|
153
227
|
};
|
|
154
|
-
isInterceptorEnabled = true;
|
|
228
|
+
isInterceptorEnabled$1 = true;
|
|
155
229
|
},
|
|
156
230
|
// Unpatch XMLHttpRequest methods and remove the callbacks.
|
|
157
231
|
disableInterception() {
|
|
158
|
-
if (!isInterceptorEnabled) {
|
|
232
|
+
if (!isInterceptorEnabled$1) {
|
|
159
233
|
return;
|
|
160
234
|
}
|
|
161
|
-
isInterceptorEnabled = false;
|
|
235
|
+
isInterceptorEnabled$1 = false;
|
|
162
236
|
XMLHttpRequest.prototype.send = originalXHRSend;
|
|
163
237
|
XMLHttpRequest.prototype.open = originalXHROpen;
|
|
164
238
|
XMLHttpRequest.prototype.setRequestHeader = originalXHRSetRequestHeader;
|
|
@@ -167,38 +241,132 @@ const XHRInterceptor = {
|
|
|
167
241
|
sendCallback = null;
|
|
168
242
|
headerReceivedCallback = null;
|
|
169
243
|
requestHeaderCallback = null;
|
|
244
|
+
overrideCallback = null;
|
|
170
245
|
}
|
|
171
246
|
};
|
|
247
|
+
const getStringSizeInBytes = (value) => {
|
|
248
|
+
return new TextEncoder().encode(value).length;
|
|
249
|
+
};
|
|
250
|
+
const splitSetCookieHeaderByComma = (header) => {
|
|
251
|
+
const regex = /(?:^|,\s)([^=;,]+=[^;]+(?:;[^,]*)*)/g;
|
|
252
|
+
const matches = [];
|
|
253
|
+
let match;
|
|
254
|
+
while ((match = regex.exec(header)) !== null) {
|
|
255
|
+
matches.push(match[1].trim());
|
|
256
|
+
}
|
|
257
|
+
return matches;
|
|
258
|
+
};
|
|
259
|
+
const applyReactNativeResponseHeadersLogic = (headers) => {
|
|
260
|
+
const parsedHeaders = { ...headers };
|
|
261
|
+
const setCookieHeader = getHttpHeader(headers, "set-cookie");
|
|
262
|
+
if (setCookieHeader) {
|
|
263
|
+
const { value, originalKey } = setCookieHeader;
|
|
264
|
+
const cookies = splitSetCookieHeaderByComma(value);
|
|
265
|
+
parsedHeaders[originalKey] = cookies.length > 0 ? cookies : value;
|
|
266
|
+
}
|
|
267
|
+
return parsedHeaders;
|
|
268
|
+
};
|
|
269
|
+
const isBlob = (value) => value instanceof Blob;
|
|
270
|
+
const isArrayBuffer = (value) => value instanceof ArrayBuffer || ArrayBuffer.isView(value);
|
|
271
|
+
const isFormData = (value) => value instanceof FormData;
|
|
272
|
+
const isNullOrUndefined = (value) => value === null || value === void 0;
|
|
273
|
+
const createOverridesRegistry = () => {
|
|
274
|
+
let overrides = /* @__PURE__ */ new Map();
|
|
275
|
+
const setOverrides = (newOverrides) => {
|
|
276
|
+
overrides = new Map(newOverrides);
|
|
277
|
+
};
|
|
278
|
+
const getOverrideForUrl = (url) => {
|
|
279
|
+
return overrides.get(url);
|
|
280
|
+
};
|
|
281
|
+
return {
|
|
282
|
+
setOverrides,
|
|
283
|
+
getOverrideForUrl
|
|
284
|
+
};
|
|
285
|
+
};
|
|
286
|
+
let registryInstance = null;
|
|
287
|
+
const getOverridesRegistry = () => {
|
|
288
|
+
if (!registryInstance) {
|
|
289
|
+
registryInstance = createOverridesRegistry();
|
|
290
|
+
}
|
|
291
|
+
return registryInstance;
|
|
292
|
+
};
|
|
172
293
|
const networkRequestsRegistry = getNetworkRequestsRegistry();
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
294
|
+
const overridesRegistry$1 = getOverridesRegistry();
|
|
295
|
+
const getBinaryPostData = (body) => ({
|
|
296
|
+
type: "binary",
|
|
297
|
+
value: {
|
|
298
|
+
size: body.size,
|
|
299
|
+
type: body.type,
|
|
300
|
+
name: getBlobName(body)
|
|
179
301
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
302
|
+
});
|
|
303
|
+
const getArrayBufferPostData = (body) => ({
|
|
304
|
+
type: "binary",
|
|
305
|
+
value: {
|
|
306
|
+
size: body.byteLength
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
const getTextPostData = (body) => ({
|
|
310
|
+
type: "text",
|
|
311
|
+
value: safeStringify(body)
|
|
312
|
+
});
|
|
313
|
+
const getFormDataPostData = (body) => ({
|
|
314
|
+
type: "form-data",
|
|
315
|
+
value: getFormDataEntries(body).reduce(
|
|
316
|
+
(acc, [key, value]) => {
|
|
317
|
+
if (isBlob(value)) {
|
|
318
|
+
acc[key] = getBinaryPostData(value);
|
|
319
|
+
} else if (isArrayBuffer(value)) {
|
|
320
|
+
acc[key] = getArrayBufferPostData(value);
|
|
321
|
+
} else {
|
|
322
|
+
acc[key] = getTextPostData(value);
|
|
323
|
+
}
|
|
324
|
+
return acc;
|
|
325
|
+
},
|
|
326
|
+
{}
|
|
327
|
+
)
|
|
328
|
+
});
|
|
329
|
+
const getRequestBody = (body) => {
|
|
330
|
+
if (isNullOrUndefined(body)) {
|
|
331
|
+
return body;
|
|
332
|
+
}
|
|
333
|
+
if (isBlob(body)) {
|
|
334
|
+
return getBinaryPostData(body);
|
|
191
335
|
}
|
|
336
|
+
if (isArrayBuffer(body)) {
|
|
337
|
+
return getArrayBufferPostData(body);
|
|
338
|
+
}
|
|
339
|
+
if (isFormData(body)) {
|
|
340
|
+
return getFormDataPostData(body);
|
|
341
|
+
}
|
|
342
|
+
return getTextPostData(body);
|
|
192
343
|
};
|
|
193
344
|
const getResponseSize = (request) => {
|
|
194
|
-
|
|
195
|
-
|
|
345
|
+
try {
|
|
346
|
+
const { responseType, response } = request;
|
|
347
|
+
if (response === null) {
|
|
348
|
+
return 0;
|
|
349
|
+
}
|
|
350
|
+
if (responseType === "" || responseType === "text") {
|
|
351
|
+
return getStringSizeInBytes(request.responseText);
|
|
352
|
+
}
|
|
353
|
+
if (responseType === "json") {
|
|
354
|
+
return getStringSizeInBytes(safeStringify(response));
|
|
355
|
+
}
|
|
356
|
+
if (responseType === "blob") {
|
|
357
|
+
return response.size;
|
|
358
|
+
}
|
|
359
|
+
if (responseType === "arraybuffer") {
|
|
360
|
+
return response.byteLength;
|
|
361
|
+
}
|
|
362
|
+
return 0;
|
|
363
|
+
} catch {
|
|
364
|
+
return null;
|
|
196
365
|
}
|
|
197
|
-
return request.response.length || 0;
|
|
198
366
|
};
|
|
199
367
|
const getResponseBody = async (request) => {
|
|
200
368
|
const responseType = request.responseType;
|
|
201
|
-
if (responseType === "text") {
|
|
369
|
+
if (responseType === "" || responseType === "text") {
|
|
202
370
|
return request.responseText;
|
|
203
371
|
}
|
|
204
372
|
if (responseType === "blob") {
|
|
@@ -213,6 +381,9 @@ const getResponseBody = async (request) => {
|
|
|
213
381
|
});
|
|
214
382
|
}
|
|
215
383
|
}
|
|
384
|
+
if (responseType === "json") {
|
|
385
|
+
return safeStringify(request.response);
|
|
386
|
+
}
|
|
216
387
|
return null;
|
|
217
388
|
};
|
|
218
389
|
const getInitiatorFromStack = () => {
|
|
@@ -243,17 +414,18 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
243
414
|
const handleRequestSend = (data, request) => {
|
|
244
415
|
const sendTime = Date.now();
|
|
245
416
|
const requestId = generateRequestId();
|
|
417
|
+
request._rozeniteRequestId = requestId;
|
|
246
418
|
const initiator = getInitiatorFromStack();
|
|
247
419
|
networkRequestsRegistry.addEntry(requestId, request);
|
|
248
420
|
let ttfb = 0;
|
|
249
421
|
pluginClient.send("request-sent", {
|
|
250
422
|
requestId,
|
|
251
|
-
timestamp: sendTime
|
|
423
|
+
timestamp: sendTime,
|
|
252
424
|
request: {
|
|
253
425
|
url: request._url,
|
|
254
426
|
method: request._method,
|
|
255
427
|
headers: request._headers,
|
|
256
|
-
postData: data
|
|
428
|
+
postData: getRequestBody(data)
|
|
257
429
|
},
|
|
258
430
|
type: "XHR",
|
|
259
431
|
initiator
|
|
@@ -266,23 +438,25 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
266
438
|
request.addEventListener("load", () => {
|
|
267
439
|
pluginClient.send("response-received", {
|
|
268
440
|
requestId,
|
|
269
|
-
timestamp: Date.now()
|
|
441
|
+
timestamp: Date.now(),
|
|
270
442
|
type: "XHR",
|
|
271
443
|
response: {
|
|
272
444
|
url: request._url,
|
|
273
445
|
status: request.status,
|
|
274
446
|
statusText: request.statusText,
|
|
275
|
-
headers:
|
|
447
|
+
headers: applyReactNativeResponseHeadersLogic(
|
|
448
|
+
request.responseHeaders || {}
|
|
449
|
+
),
|
|
276
450
|
contentType: getContentType(request),
|
|
277
451
|
size: getResponseSize(request),
|
|
278
|
-
responseTime: Date.now()
|
|
452
|
+
responseTime: Date.now()
|
|
279
453
|
}
|
|
280
454
|
});
|
|
281
455
|
});
|
|
282
456
|
request.addEventListener("loadend", () => {
|
|
283
457
|
pluginClient.send("request-completed", {
|
|
284
458
|
requestId,
|
|
285
|
-
timestamp: Date.now()
|
|
459
|
+
timestamp: Date.now(),
|
|
286
460
|
duration: Date.now() - sendTime,
|
|
287
461
|
size: getResponseSize(request),
|
|
288
462
|
ttfb
|
|
@@ -291,7 +465,7 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
291
465
|
request.addEventListener("error", () => {
|
|
292
466
|
pluginClient.send("request-failed", {
|
|
293
467
|
requestId,
|
|
294
|
-
timestamp: Date.now()
|
|
468
|
+
timestamp: Date.now(),
|
|
295
469
|
type: "XHR",
|
|
296
470
|
error: "Failed",
|
|
297
471
|
canceled: false
|
|
@@ -300,16 +474,52 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
300
474
|
request.addEventListener("abort", () => {
|
|
301
475
|
pluginClient.send("request-failed", {
|
|
302
476
|
requestId,
|
|
303
|
-
timestamp: Date.now()
|
|
477
|
+
timestamp: Date.now(),
|
|
304
478
|
type: "XHR",
|
|
305
479
|
error: "Aborted",
|
|
306
480
|
canceled: true
|
|
307
481
|
});
|
|
308
482
|
});
|
|
309
483
|
};
|
|
484
|
+
const handleRequestOverride = (request) => {
|
|
485
|
+
const override = overridesRegistry$1.getOverrideForUrl(
|
|
486
|
+
request._url
|
|
487
|
+
);
|
|
488
|
+
if (!override) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
request.addEventListener("readystatechange", () => {
|
|
492
|
+
if (override.body !== void 0) {
|
|
493
|
+
Object.defineProperty(request, "responseType", {
|
|
494
|
+
writable: true
|
|
495
|
+
});
|
|
496
|
+
Object.defineProperty(request, "response", {
|
|
497
|
+
writable: true
|
|
498
|
+
});
|
|
499
|
+
Object.defineProperty(request, "responseText", {
|
|
500
|
+
writable: true
|
|
501
|
+
});
|
|
502
|
+
const contentType = getContentType(request);
|
|
503
|
+
if (contentType === "application/json") {
|
|
504
|
+
request.responseType = "json";
|
|
505
|
+
} else if (contentType === "text/plain") {
|
|
506
|
+
request.responseType = "text";
|
|
507
|
+
}
|
|
508
|
+
request.response = override.body;
|
|
509
|
+
request.responseText = override.body;
|
|
510
|
+
}
|
|
511
|
+
if (override.status !== void 0) {
|
|
512
|
+
Object.defineProperty(request, "status", {
|
|
513
|
+
writable: true
|
|
514
|
+
});
|
|
515
|
+
request.status = override.status;
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
};
|
|
310
519
|
const enable = () => {
|
|
311
520
|
XHRInterceptor.disableInterception();
|
|
312
521
|
XHRInterceptor.setSendCallback(handleRequestSend);
|
|
522
|
+
XHRInterceptor.setOverrideCallback(handleRequestOverride);
|
|
313
523
|
XHRInterceptor.enableInterception();
|
|
314
524
|
};
|
|
315
525
|
const disable = () => {
|
|
@@ -352,19 +562,493 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
352
562
|
dispose
|
|
353
563
|
};
|
|
354
564
|
};
|
|
355
|
-
const
|
|
565
|
+
const getWebSocketInterceptor = () => {
|
|
566
|
+
if (reactNative.Platform.constants.reactNativeVersion.minor >= 79) {
|
|
567
|
+
return WebSocketInterceptor__default.default;
|
|
568
|
+
} else {
|
|
569
|
+
const WebSocketInterceptorPreRN079 = WebSocketInterceptor__default.default;
|
|
570
|
+
return {
|
|
571
|
+
...WebSocketInterceptorPreRN079,
|
|
572
|
+
setOnMessageCallback: (callback) => {
|
|
573
|
+
WebSocketInterceptorPreRN079.setOnMessageCallback((socketId, data) => {
|
|
574
|
+
callback(data, socketId);
|
|
575
|
+
});
|
|
576
|
+
},
|
|
577
|
+
setOnCloseCallback: (callback) => {
|
|
578
|
+
WebSocketInterceptorPreRN079.setOnCloseCallback((error, socketId) => {
|
|
579
|
+
callback(socketId, error);
|
|
580
|
+
});
|
|
581
|
+
},
|
|
582
|
+
setOnErrorCallback: (callback) => {
|
|
583
|
+
WebSocketInterceptorPreRN079.setOnErrorCallback((error, socketId) => {
|
|
584
|
+
callback(socketId, error);
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
const getWebSocketInspector = () => {
|
|
591
|
+
const eventEmitter = nanoevents.createNanoEvents();
|
|
592
|
+
const socketUrlMap = /* @__PURE__ */ new Map();
|
|
593
|
+
const webSocketInterceptor = getWebSocketInterceptor();
|
|
594
|
+
return {
|
|
595
|
+
enable: () => {
|
|
596
|
+
webSocketInterceptor.setConnectCallback(
|
|
597
|
+
(url, protocols, options, socketId) => {
|
|
598
|
+
socketUrlMap.set(socketId, url);
|
|
599
|
+
const event = {
|
|
600
|
+
type: "websocket-connect",
|
|
601
|
+
url,
|
|
602
|
+
socketId,
|
|
603
|
+
timestamp: Date.now(),
|
|
604
|
+
protocols,
|
|
605
|
+
options
|
|
606
|
+
};
|
|
607
|
+
eventEmitter.emit("websocket-connect", event);
|
|
608
|
+
}
|
|
609
|
+
);
|
|
610
|
+
webSocketInterceptor.setCloseCallback(
|
|
611
|
+
(code, reason, socketId) => {
|
|
612
|
+
const url = socketUrlMap.get(socketId);
|
|
613
|
+
if (!url) {
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
const event = {
|
|
617
|
+
type: "websocket-close",
|
|
618
|
+
url,
|
|
619
|
+
socketId,
|
|
620
|
+
timestamp: Date.now(),
|
|
621
|
+
code: code || 0,
|
|
622
|
+
reason: reason || void 0
|
|
623
|
+
};
|
|
624
|
+
eventEmitter.emit("websocket-close", event);
|
|
625
|
+
socketUrlMap.delete(socketId);
|
|
626
|
+
}
|
|
627
|
+
);
|
|
628
|
+
webSocketInterceptor.setOnMessageCallback(
|
|
629
|
+
(data, socketId) => {
|
|
630
|
+
const url = socketUrlMap.get(socketId);
|
|
631
|
+
if (!url) {
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
const event = {
|
|
635
|
+
type: "websocket-message-received",
|
|
636
|
+
url,
|
|
637
|
+
socketId,
|
|
638
|
+
timestamp: Date.now(),
|
|
639
|
+
data,
|
|
640
|
+
messageType: typeof data === "string" ? "text" : "binary"
|
|
641
|
+
};
|
|
642
|
+
eventEmitter.emit("websocket-message-received", event);
|
|
643
|
+
}
|
|
644
|
+
);
|
|
645
|
+
webSocketInterceptor.setOnErrorCallback(
|
|
646
|
+
(error, socketId) => {
|
|
647
|
+
const url = socketUrlMap.get(socketId);
|
|
648
|
+
if (!url) {
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
const event = {
|
|
652
|
+
type: "websocket-error",
|
|
653
|
+
url,
|
|
654
|
+
socketId,
|
|
655
|
+
timestamp: Date.now(),
|
|
656
|
+
error
|
|
657
|
+
};
|
|
658
|
+
eventEmitter.emit("websocket-error", event);
|
|
659
|
+
}
|
|
660
|
+
);
|
|
661
|
+
webSocketInterceptor.setSendCallback((data, socketId) => {
|
|
662
|
+
const url = socketUrlMap.get(socketId);
|
|
663
|
+
if (!url) {
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
const event = {
|
|
667
|
+
type: "websocket-message-sent",
|
|
668
|
+
url,
|
|
669
|
+
socketId,
|
|
670
|
+
timestamp: Date.now(),
|
|
671
|
+
data,
|
|
672
|
+
messageType: typeof data === "string" ? "text" : "binary"
|
|
673
|
+
};
|
|
674
|
+
eventEmitter.emit("websocket-message-sent", event);
|
|
675
|
+
});
|
|
676
|
+
webSocketInterceptor.setOnOpenCallback((socketId) => {
|
|
677
|
+
const url = socketUrlMap.get(socketId);
|
|
678
|
+
if (!url) {
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
const event = {
|
|
682
|
+
type: "websocket-open",
|
|
683
|
+
url,
|
|
684
|
+
socketId,
|
|
685
|
+
timestamp: Date.now()
|
|
686
|
+
};
|
|
687
|
+
eventEmitter.emit("websocket-open", event);
|
|
688
|
+
});
|
|
689
|
+
webSocketInterceptor.setOnCloseCallback(
|
|
690
|
+
(error, socketId) => {
|
|
691
|
+
const url = socketUrlMap.get(socketId);
|
|
692
|
+
if (!url) {
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
const event = {
|
|
696
|
+
type: "websocket-close",
|
|
697
|
+
url,
|
|
698
|
+
socketId,
|
|
699
|
+
timestamp: Date.now(),
|
|
700
|
+
code: error.code,
|
|
701
|
+
reason: error.reason
|
|
702
|
+
};
|
|
703
|
+
eventEmitter.emit("websocket-close", event);
|
|
704
|
+
socketUrlMap.delete(socketId);
|
|
705
|
+
}
|
|
706
|
+
);
|
|
707
|
+
webSocketInterceptor.enableInterception();
|
|
708
|
+
},
|
|
709
|
+
disable: () => {
|
|
710
|
+
webSocketInterceptor.disableInterception();
|
|
711
|
+
},
|
|
712
|
+
isEnabled: () => webSocketInterceptor.isInterceptorEnabled(),
|
|
713
|
+
dispose: () => {
|
|
714
|
+
eventEmitter.events = {};
|
|
715
|
+
socketUrlMap.clear();
|
|
716
|
+
},
|
|
717
|
+
on: (event, callback) => eventEmitter.on(event, callback)
|
|
718
|
+
};
|
|
719
|
+
};
|
|
720
|
+
let connectCallback;
|
|
721
|
+
let messageCallback;
|
|
722
|
+
let errorCallback;
|
|
723
|
+
let openEventCallback;
|
|
724
|
+
let closeCallback;
|
|
725
|
+
let isInterceptorEnabled = false;
|
|
726
|
+
const eventSourceClass = eventSource.getEventSource();
|
|
727
|
+
const originalOpen = eventSourceClass.prototype.open;
|
|
728
|
+
const originalDispatch = eventSourceClass.prototype.dispatch;
|
|
729
|
+
const BUILT_IN_EVENT_TYPES = /* @__PURE__ */ new Set(["open", "error", "close", "done"]);
|
|
730
|
+
const SSEInterceptor = {
|
|
731
|
+
/**
|
|
732
|
+
* Invoked when EventSource.open() is called (connection attempt starting).
|
|
733
|
+
*/
|
|
734
|
+
setConnectCallback(callback) {
|
|
735
|
+
connectCallback = callback;
|
|
736
|
+
},
|
|
737
|
+
/**
|
|
738
|
+
* Invoked when a message event is received.
|
|
739
|
+
*/
|
|
740
|
+
setMessageCallback(callback) {
|
|
741
|
+
messageCallback = callback;
|
|
742
|
+
},
|
|
743
|
+
/**
|
|
744
|
+
* Invoked when an error event occurs.
|
|
745
|
+
*/
|
|
746
|
+
setErrorCallback(callback) {
|
|
747
|
+
errorCallback = callback;
|
|
748
|
+
},
|
|
749
|
+
/**
|
|
750
|
+
* Invoked when the connection is successfully opened (open event fired).
|
|
751
|
+
*/
|
|
752
|
+
setOpenEventCallback(callback) {
|
|
753
|
+
openEventCallback = callback;
|
|
754
|
+
},
|
|
755
|
+
/**
|
|
756
|
+
* Invoked when the connection is closed.
|
|
757
|
+
*/
|
|
758
|
+
setCloseCallback(callback) {
|
|
759
|
+
closeCallback = callback;
|
|
760
|
+
},
|
|
761
|
+
isInterceptorEnabled() {
|
|
762
|
+
return isInterceptorEnabled;
|
|
763
|
+
},
|
|
764
|
+
enableInterception() {
|
|
765
|
+
if (isInterceptorEnabled) {
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
eventSourceClass.prototype.open = function() {
|
|
769
|
+
if (connectCallback) {
|
|
770
|
+
connectCallback(this.url, this);
|
|
771
|
+
}
|
|
772
|
+
this.addEventListener("open", (event) => {
|
|
773
|
+
if (openEventCallback) {
|
|
774
|
+
openEventCallback(event, this);
|
|
775
|
+
}
|
|
776
|
+
});
|
|
777
|
+
this.addEventListener(
|
|
778
|
+
"error",
|
|
779
|
+
(event) => {
|
|
780
|
+
if (errorCallback) {
|
|
781
|
+
errorCallback(event, this);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
);
|
|
785
|
+
this.addEventListener("close", (event) => {
|
|
786
|
+
if (closeCallback) {
|
|
787
|
+
closeCallback(event, this);
|
|
788
|
+
}
|
|
789
|
+
});
|
|
790
|
+
return originalOpen.call(this);
|
|
791
|
+
};
|
|
792
|
+
eventSourceClass.prototype.dispatch = function(eventType, data) {
|
|
793
|
+
if (!BUILT_IN_EVENT_TYPES.has(eventType)) {
|
|
794
|
+
if (messageCallback) {
|
|
795
|
+
messageCallback(data, this);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
return originalDispatch.call(this, eventType, data);
|
|
799
|
+
};
|
|
800
|
+
isInterceptorEnabled = true;
|
|
801
|
+
},
|
|
802
|
+
// Unpatch EventSource open method and remove the callbacks.
|
|
803
|
+
disableInterception() {
|
|
804
|
+
if (!isInterceptorEnabled) {
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
isInterceptorEnabled = false;
|
|
808
|
+
eventSourceClass.prototype.open = originalOpen;
|
|
809
|
+
eventSourceClass.prototype.dispatch = originalDispatch;
|
|
810
|
+
connectCallback = null;
|
|
811
|
+
messageCallback = null;
|
|
812
|
+
errorCallback = null;
|
|
813
|
+
openEventCallback = null;
|
|
814
|
+
closeCallback = null;
|
|
815
|
+
}
|
|
816
|
+
};
|
|
817
|
+
const getSSEInspector = () => {
|
|
818
|
+
const eventEmitter = nanoevents.createNanoEvents();
|
|
819
|
+
const getRequestId = (eventSource2) => {
|
|
820
|
+
var _a;
|
|
821
|
+
const requestId = (_a = eventSource2._xhr) == null ? void 0 : _a._rozeniteRequestId;
|
|
822
|
+
if (!requestId) {
|
|
823
|
+
return null;
|
|
824
|
+
}
|
|
825
|
+
return requestId;
|
|
826
|
+
};
|
|
827
|
+
return {
|
|
828
|
+
enable: () => {
|
|
829
|
+
SSEInterceptor.setOpenEventCallback((_, eventSource2) => {
|
|
830
|
+
const sseEventSource = eventSource2;
|
|
831
|
+
const requestId = getRequestId(sseEventSource);
|
|
832
|
+
if (!requestId) {
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
const sseXhr = sseEventSource._xhr;
|
|
836
|
+
const event = {
|
|
837
|
+
type: "sse-open",
|
|
838
|
+
requestId,
|
|
839
|
+
timestamp: Date.now(),
|
|
840
|
+
response: {
|
|
841
|
+
url: sseXhr._url,
|
|
842
|
+
status: sseXhr.status,
|
|
843
|
+
statusText: sseXhr.statusText,
|
|
844
|
+
headers: sseXhr.responseHeaders || {},
|
|
845
|
+
contentType: getContentType(sseXhr),
|
|
846
|
+
size: 0,
|
|
847
|
+
responseTime: Date.now()
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
eventEmitter.emit("sse-open", event);
|
|
851
|
+
});
|
|
852
|
+
SSEInterceptor.setMessageCallback((messageEvent, eventSource2) => {
|
|
853
|
+
const sseEventSource = eventSource2;
|
|
854
|
+
const requestId = getRequestId(sseEventSource);
|
|
855
|
+
if (!requestId) {
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
858
|
+
const event = {
|
|
859
|
+
type: "sse-message",
|
|
860
|
+
requestId,
|
|
861
|
+
timestamp: Date.now(),
|
|
862
|
+
payload: {
|
|
863
|
+
type: messageEvent.type,
|
|
864
|
+
data: messageEvent.data || ""
|
|
865
|
+
}
|
|
866
|
+
};
|
|
867
|
+
eventEmitter.emit("sse-message", event);
|
|
868
|
+
});
|
|
869
|
+
SSEInterceptor.setErrorCallback((errorEvent, eventSource2) => {
|
|
870
|
+
const sseEventSource = eventSource2;
|
|
871
|
+
const requestId = getRequestId(sseEventSource);
|
|
872
|
+
if (!requestId) {
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
const event = {
|
|
876
|
+
type: "sse-error",
|
|
877
|
+
requestId,
|
|
878
|
+
timestamp: Date.now(),
|
|
879
|
+
error: {
|
|
880
|
+
type: errorEvent.type,
|
|
881
|
+
message: errorEvent.type === "timeout" ? "Timeout" : errorEvent.message
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
eventEmitter.emit("sse-error", event);
|
|
885
|
+
});
|
|
886
|
+
SSEInterceptor.setCloseCallback((_, eventSource2) => {
|
|
887
|
+
const sseEventSource = eventSource2;
|
|
888
|
+
const requestId = getRequestId(sseEventSource);
|
|
889
|
+
if (!requestId) {
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
const event = {
|
|
893
|
+
type: "sse-close",
|
|
894
|
+
requestId,
|
|
895
|
+
timestamp: Date.now()
|
|
896
|
+
};
|
|
897
|
+
eventEmitter.emit("sse-close", event);
|
|
898
|
+
});
|
|
899
|
+
SSEInterceptor.enableInterception();
|
|
900
|
+
},
|
|
901
|
+
disable: () => {
|
|
902
|
+
SSEInterceptor.disableInterception();
|
|
903
|
+
},
|
|
904
|
+
isEnabled: () => SSEInterceptor.isInterceptorEnabled(),
|
|
905
|
+
dispose: () => {
|
|
906
|
+
SSEInterceptor.disableInterception();
|
|
907
|
+
eventEmitter.events = {};
|
|
908
|
+
},
|
|
909
|
+
on: (event, callback) => eventEmitter.on(event, callback)
|
|
910
|
+
};
|
|
911
|
+
};
|
|
912
|
+
const DEFAULT_CONFIG = {
|
|
913
|
+
inspectors: {
|
|
914
|
+
http: true,
|
|
915
|
+
websocket: true,
|
|
916
|
+
sse: true
|
|
917
|
+
},
|
|
918
|
+
clientUISettings: {
|
|
919
|
+
showUrlAsName: false
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
const validateConfig = (config) => {
|
|
923
|
+
const inspectors = config.inspectors;
|
|
924
|
+
if (!inspectors) {
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
if (inspectors.sse && !inspectors.http) {
|
|
928
|
+
throw new Error("SSE inspector requires HTTP inspector to be enabled.");
|
|
929
|
+
}
|
|
930
|
+
};
|
|
931
|
+
const overridesRegistry = getOverridesRegistry();
|
|
932
|
+
const useNetworkActivityDevTools = (config = DEFAULT_CONFIG) => {
|
|
933
|
+
var _a, _b, _c, _d;
|
|
934
|
+
const isRecordingEnabledRef = react.useRef(false);
|
|
356
935
|
const client = pluginBridge.useRozeniteDevToolsClient({
|
|
357
936
|
pluginId: "@rozenite/network-activity-plugin"
|
|
358
937
|
});
|
|
938
|
+
const isHttpInspectorEnabled = ((_a = config.inspectors) == null ? void 0 : _a.http) ?? true;
|
|
939
|
+
const isWebSocketInspectorEnabled = ((_b = config.inspectors) == null ? void 0 : _b.websocket) ?? true;
|
|
940
|
+
const isSSEInspectorEnabled = ((_c = config.inspectors) == null ? void 0 : _c.sse) ?? true;
|
|
941
|
+
const showUrlAsName = (_d = config.clientUISettings) == null ? void 0 : _d.showUrlAsName;
|
|
359
942
|
react.useEffect(() => {
|
|
360
943
|
if (!client) {
|
|
361
944
|
return;
|
|
362
945
|
}
|
|
946
|
+
validateConfig(config);
|
|
947
|
+
}, [config]);
|
|
948
|
+
react.useEffect(() => {
|
|
949
|
+
if (!client) {
|
|
950
|
+
return;
|
|
951
|
+
}
|
|
952
|
+
const sendClientUISettings = () => {
|
|
953
|
+
var _a2;
|
|
954
|
+
client.send("client-ui-settings", {
|
|
955
|
+
settings: {
|
|
956
|
+
showUrlAsName: showUrlAsName ?? ((_a2 = DEFAULT_CONFIG.clientUISettings) == null ? void 0 : _a2.showUrlAsName)
|
|
957
|
+
}
|
|
958
|
+
});
|
|
959
|
+
};
|
|
960
|
+
const subscriptions = [
|
|
961
|
+
client.onMessage("network-enable", () => {
|
|
962
|
+
isRecordingEnabledRef.current = true;
|
|
963
|
+
}),
|
|
964
|
+
client.onMessage("network-disable", () => {
|
|
965
|
+
isRecordingEnabledRef.current = false;
|
|
966
|
+
}),
|
|
967
|
+
client.onMessage("set-overrides", (data) => {
|
|
968
|
+
overridesRegistry.setOverrides(data.overrides);
|
|
969
|
+
}),
|
|
970
|
+
client.onMessage("get-client-ui-settings", () => {
|
|
971
|
+
sendClientUISettings();
|
|
972
|
+
})
|
|
973
|
+
];
|
|
974
|
+
sendClientUISettings();
|
|
975
|
+
return () => {
|
|
976
|
+
subscriptions.forEach((subscription) => subscription.remove());
|
|
977
|
+
};
|
|
978
|
+
}, [client, showUrlAsName]);
|
|
979
|
+
react.useEffect(() => {
|
|
980
|
+
if (!client || !isHttpInspectorEnabled) {
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
363
983
|
const networkInspector = getNetworkInspector(client);
|
|
984
|
+
if (isRecordingEnabledRef.current) {
|
|
985
|
+
networkInspector.enable();
|
|
986
|
+
}
|
|
364
987
|
return () => {
|
|
365
988
|
networkInspector.dispose();
|
|
366
989
|
};
|
|
367
|
-
}, [client]);
|
|
990
|
+
}, [client, isHttpInspectorEnabled]);
|
|
991
|
+
react.useEffect(() => {
|
|
992
|
+
if (!client || !isWebSocketInspectorEnabled) {
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
995
|
+
const eventsToForward = [
|
|
996
|
+
"websocket-connect",
|
|
997
|
+
"websocket-open",
|
|
998
|
+
"websocket-close",
|
|
999
|
+
"websocket-message-sent",
|
|
1000
|
+
"websocket-message-received",
|
|
1001
|
+
"websocket-error",
|
|
1002
|
+
"websocket-connection-status-changed"
|
|
1003
|
+
];
|
|
1004
|
+
const websocketInspector = getWebSocketInspector();
|
|
1005
|
+
eventsToForward.forEach((event) => {
|
|
1006
|
+
websocketInspector.on(event, (event2) => {
|
|
1007
|
+
client.send(event2.type, event2);
|
|
1008
|
+
});
|
|
1009
|
+
});
|
|
1010
|
+
client.onMessage("network-enable", () => {
|
|
1011
|
+
websocketInspector.enable();
|
|
1012
|
+
});
|
|
1013
|
+
client.onMessage("network-disable", () => {
|
|
1014
|
+
websocketInspector.disable();
|
|
1015
|
+
});
|
|
1016
|
+
if (isRecordingEnabledRef.current) {
|
|
1017
|
+
websocketInspector.enable();
|
|
1018
|
+
}
|
|
1019
|
+
return () => {
|
|
1020
|
+
websocketInspector.dispose();
|
|
1021
|
+
};
|
|
1022
|
+
}, [client, isWebSocketInspectorEnabled]);
|
|
1023
|
+
react.useEffect(() => {
|
|
1024
|
+
if (!client || !isSSEInspectorEnabled) {
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
const eventsToForward = [
|
|
1028
|
+
"sse-open",
|
|
1029
|
+
"sse-message",
|
|
1030
|
+
"sse-error",
|
|
1031
|
+
"sse-close"
|
|
1032
|
+
];
|
|
1033
|
+
const sseInspector = getSSEInspector();
|
|
1034
|
+
eventsToForward.forEach((event) => {
|
|
1035
|
+
sseInspector.on(event, (event2) => {
|
|
1036
|
+
client.send(event2.type, event2);
|
|
1037
|
+
});
|
|
1038
|
+
});
|
|
1039
|
+
client.onMessage("network-enable", () => {
|
|
1040
|
+
sseInspector.enable();
|
|
1041
|
+
});
|
|
1042
|
+
client.onMessage("network-disable", () => {
|
|
1043
|
+
sseInspector.disable();
|
|
1044
|
+
});
|
|
1045
|
+
if (isRecordingEnabledRef.current) {
|
|
1046
|
+
sseInspector.enable();
|
|
1047
|
+
}
|
|
1048
|
+
return () => {
|
|
1049
|
+
sseInspector.dispose();
|
|
1050
|
+
};
|
|
1051
|
+
}, [client, isSSEInspectorEnabled]);
|
|
368
1052
|
return client;
|
|
369
1053
|
};
|
|
370
1054
|
exports.useNetworkActivityDevTools = useNetworkActivityDevTools;
|