@rozenite/network-activity-plugin 1.0.0-alpha.9 → 1.1.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.
Files changed (113) hide show
  1. package/README.md +2 -0
  2. package/dist/App.html +2 -2
  3. package/dist/assets/{App-DoHQsY5s.css → App-BrSkOkws.css} +223 -2
  4. package/dist/assets/{App-CA1Fbh0I.js → App-Kyi7zHUX.js} +8188 -2671
  5. package/dist/react-native.cjs +4 -1
  6. package/dist/react-native.js +4 -1
  7. package/dist/rozenite.json +1 -1
  8. package/dist/src/react-native/config.d.ts +20 -0
  9. package/dist/src/react-native/http/overrides-registry.d.ts +6 -0
  10. package/dist/src/react-native/http/xhr-interceptor.d.ts +7 -1
  11. package/dist/src/react-native/sse/sse-interceptor.d.ts +2 -2
  12. package/dist/src/react-native/useNetworkActivityDevTools.d.ts +2 -1
  13. package/dist/src/react-native/utils/getBlobName.d.ts +35 -0
  14. package/dist/src/react-native/utils/getFormDataEntries.d.ts +18 -0
  15. package/dist/src/shared/client.d.ts +55 -4
  16. package/dist/src/shared/sse-events.d.ts +4 -1
  17. package/dist/src/ui/components/Button.d.ts +2 -2
  18. package/dist/src/ui/components/CodeBlock.d.ts +3 -0
  19. package/dist/src/ui/components/CodeEditor.d.ts +5 -0
  20. package/dist/src/ui/components/CookieCard.d.ts +7 -0
  21. package/dist/src/ui/components/CopyRequestDropdown.d.ts +7 -0
  22. package/dist/src/ui/components/DropdownMenu.d.ts +27 -0
  23. package/dist/src/ui/components/FilterBar.d.ts +10 -0
  24. package/dist/src/ui/components/JsonTreeCopyableItem.d.ts +1 -1
  25. package/dist/src/ui/components/KeyValueGrid.d.ts +13 -0
  26. package/dist/src/ui/components/OverrideResponse.d.ts +8 -0
  27. package/dist/src/ui/components/RequestBody.d.ts +6 -0
  28. package/dist/src/ui/components/RequestList.d.ts +9 -4
  29. package/dist/src/ui/components/ScrollArea.d.ts +3 -2
  30. package/dist/src/ui/components/Section.d.ts +8 -0
  31. package/dist/src/ui/components/Separator.d.ts +2 -1
  32. package/dist/src/ui/components/Tabs.d.ts +7 -0
  33. package/dist/src/ui/state/hooks.d.ts +4 -0
  34. package/dist/src/ui/state/model.d.ts +22 -7
  35. package/dist/src/ui/state/store.d.ts +27 -3
  36. package/dist/src/ui/utils/checkRequestBodyBinary.d.ts +2 -0
  37. package/dist/src/ui/utils/escapeShellArg.d.ts +1 -0
  38. package/dist/src/ui/utils/generateCurlCommand.d.ts +2 -0
  39. package/dist/src/ui/utils/generateFetchCall.d.ts +2 -0
  40. package/dist/src/ui/utils/generateMultipartBody.d.ts +4 -0
  41. package/dist/src/utils/applyReactNativeRequestHeadersLogic.d.ts +7 -0
  42. package/dist/src/utils/applyReactNativeResponseHeadersLogic.d.ts +9 -0
  43. package/dist/src/utils/cookieParser.d.ts +6 -0
  44. package/dist/src/utils/getContentTypeMimeType.d.ts +2 -0
  45. package/dist/src/utils/getHttpHeader.d.ts +5 -0
  46. package/dist/src/utils/getHttpHeaderValueAsString.d.ts +11 -0
  47. package/dist/src/utils/getStringSizeInBytes.d.ts +1 -0
  48. package/dist/src/utils/inferContentTypeFromPostData.d.ts +2 -0
  49. package/dist/src/utils/safeStringify.d.ts +1 -0
  50. package/dist/src/utils/typeChecks.d.ts +9 -0
  51. package/dist/useNetworkActivityDevTools.cjs +337 -24
  52. package/dist/useNetworkActivityDevTools.js +338 -25
  53. package/package.json +7 -4
  54. package/react-native.ts +6 -1
  55. package/src/react-native/config.ts +43 -0
  56. package/src/react-native/http/network-inspector.ts +190 -8
  57. package/src/react-native/http/overrides-registry.ts +32 -0
  58. package/src/react-native/http/xhr-interceptor.ts +19 -2
  59. package/src/react-native/sse/sse-inspector.ts +27 -5
  60. package/src/react-native/sse/sse-interceptor.ts +26 -8
  61. package/src/react-native/useNetworkActivityDevTools.ts +86 -8
  62. package/src/react-native/utils/getBlobName.ts +45 -0
  63. package/src/react-native/utils/getFormDataEntries.ts +32 -0
  64. package/src/react-native/utils.ts +3 -3
  65. package/src/shared/client.ts +81 -4
  66. package/src/shared/sse-events.ts +4 -1
  67. package/src/ui/components/Button.tsx +1 -0
  68. package/src/ui/components/CodeBlock.tsx +19 -0
  69. package/src/ui/components/CodeEditor.tsx +26 -0
  70. package/src/ui/components/CookieCard.tsx +64 -0
  71. package/src/ui/components/CopyRequestDropdown.tsx +95 -0
  72. package/src/ui/components/DropdownMenu.tsx +206 -0
  73. package/src/ui/components/FilterBar.tsx +117 -0
  74. package/src/ui/components/Input.tsx +1 -1
  75. package/src/ui/components/JsonTree.tsx +10 -3
  76. package/src/ui/components/JsonTreeCopyableItem.tsx +14 -10
  77. package/src/ui/components/KeyValueGrid.tsx +51 -0
  78. package/src/ui/components/OverrideResponse.tsx +132 -0
  79. package/src/ui/components/RequestBody.tsx +86 -0
  80. package/src/ui/components/RequestList.tsx +74 -14
  81. package/src/ui/components/ScrollArea.tsx +1 -0
  82. package/src/ui/components/Section.tsx +46 -0
  83. package/src/ui/components/SidePanel.tsx +15 -5
  84. package/src/ui/components/Toolbar.tsx +3 -2
  85. package/src/ui/globals.css +4 -0
  86. package/src/ui/hooks/useCopyToClipboard.ts +2 -2
  87. package/src/ui/state/derived.ts +2 -0
  88. package/src/ui/state/hooks.ts +8 -0
  89. package/src/ui/state/model.ts +28 -7
  90. package/src/ui/state/store.ts +640 -500
  91. package/src/ui/tabs/CookiesTab.tsx +60 -263
  92. package/src/ui/tabs/HeadersTab.tsx +78 -89
  93. package/src/ui/tabs/RequestTab.tsx +58 -46
  94. package/src/ui/tabs/ResponseTab.tsx +98 -67
  95. package/src/ui/tabs/SSEMessagesTab.tsx +50 -39
  96. package/src/ui/utils/checkRequestBodyBinary.ts +7 -0
  97. package/src/ui/utils/escapeShellArg.ts +12 -0
  98. package/src/ui/utils/generateCurlCommand.ts +83 -0
  99. package/src/ui/utils/generateFetchCall.ts +64 -0
  100. package/src/ui/utils/generateMultipartBody.ts +19 -0
  101. package/src/ui/views/InspectorView.tsx +15 -3
  102. package/src/utils/applyReactNativeRequestHeadersLogic.ts +30 -0
  103. package/src/utils/applyReactNativeResponseHeadersLogic.ts +28 -0
  104. package/src/utils/cookieParser.ts +126 -0
  105. package/src/utils/getContentTypeMimeType.ts +17 -0
  106. package/src/utils/getHttpHeader.ts +17 -0
  107. package/src/utils/getHttpHeaderValueAsString.ts +13 -0
  108. package/src/utils/getStringSizeInBytes.ts +3 -0
  109. package/src/utils/inferContentTypeFromPostData.ts +9 -0
  110. package/src/utils/safeStringify.ts +7 -0
  111. package/src/utils/typeChecks.ts +27 -0
  112. package/dist/src/ui/utils/getHttpHeaderValue.d.ts +0 -2
  113. package/src/ui/utils/getHttpHeaderValue.ts +0 -14
@@ -0,0 +1,126 @@
1
+ import { Cookie, HttpHeaders } from '../shared/client';
2
+ import { getHttpHeader } from './getHttpHeader';
3
+
4
+ export const parseSetCookieHeader = (setCookieStr: string): Cookie => {
5
+ const parts = setCookieStr.split(';').map((p) => p.trim());
6
+ const [nameValue, ...attributes] = parts;
7
+ const [name, ...valueParts] = nameValue.split('=');
8
+
9
+ const value = valueParts.join('=');
10
+
11
+ const cookieObj: Cookie = {
12
+ name: name?.trim() || '',
13
+ value: value?.trim() || '',
14
+ };
15
+
16
+ attributes.forEach((attr) => {
17
+ const [attrName, ...attrValueParts] = attr.split('=');
18
+ const lowerAttrName = attrName.trim().toLowerCase();
19
+ const attrValue = attrValueParts.join('=');
20
+
21
+ switch (lowerAttrName) {
22
+ case 'domain':
23
+ cookieObj.domain = attrValue;
24
+
25
+ break;
26
+
27
+ case 'path':
28
+ cookieObj.path = attrValue;
29
+
30
+ break;
31
+
32
+ case 'expires':
33
+ cookieObj.expires = attrValue;
34
+
35
+ break;
36
+
37
+ case 'max-age':
38
+ cookieObj.maxAge = attrValue;
39
+
40
+ break;
41
+
42
+ case 'secure':
43
+ cookieObj.secure = true;
44
+
45
+ break;
46
+
47
+ case 'httponly':
48
+ cookieObj.httpOnly = true;
49
+
50
+ break;
51
+
52
+ case 'samesite':
53
+ cookieObj.sameSite = attrValue;
54
+
55
+ break;
56
+ }
57
+ });
58
+
59
+ return cookieObj;
60
+ };
61
+
62
+ export const splitSetCookieHeaderByComma = (header: string): string[] => {
63
+ const regex = /(?:^|,\s)([^=;,]+=[^;]+(?:;[^,]*)*)/g;
64
+ const matches: string[] = [];
65
+
66
+ let match;
67
+
68
+ while ((match = regex.exec(header)) !== null) {
69
+ matches.push(match[1].trim());
70
+ }
71
+
72
+ return matches;
73
+ };
74
+
75
+ export const parseCookieHeader = (cookieString: string): Cookie[] => {
76
+ if (!cookieString) return [];
77
+
78
+ return cookieString
79
+ .split(';')
80
+ .map((cookieStr) => {
81
+ const [name, ...valueParts] = cookieStr.trim().split('=');
82
+ const value = valueParts.join('=');
83
+
84
+ return {
85
+ name: name?.trim() || '',
86
+ value: value?.trim() || '',
87
+ };
88
+ })
89
+ .filter((cookieObj) => cookieObj.name);
90
+ };
91
+
92
+ export const parseRequestCookiesFromHeaders = (
93
+ headers: HttpHeaders
94
+ ): Cookie[] => {
95
+ const cookieHeader = getHttpHeader(headers, 'cookie');
96
+
97
+ if (!cookieHeader) {
98
+ return [];
99
+ }
100
+
101
+ const { value } = cookieHeader;
102
+
103
+ if (Array.isArray(value)) {
104
+ return value.flatMap(parseCookieHeader);
105
+ }
106
+
107
+ return parseCookieHeader(value);
108
+ };
109
+
110
+ export const parseResponseCookiesFromHeaders = (
111
+ headers: HttpHeaders
112
+ ): Cookie[] => {
113
+ const setCookieHeader = getHttpHeader(headers, 'set-cookie');
114
+
115
+ if (!setCookieHeader) {
116
+ return [];
117
+ }
118
+
119
+ const { value } = setCookieHeader;
120
+
121
+ if (Array.isArray(value)) {
122
+ return value.flatMap(parseSetCookieHeader);
123
+ }
124
+
125
+ return [parseSetCookieHeader(value)];
126
+ };
@@ -0,0 +1,17 @@
1
+ import { HttpHeaders } from '../shared/client';
2
+ import { getHttpHeader } from './getHttpHeader';
3
+
4
+ export function getContentTypeMime(headers: HttpHeaders) {
5
+ const contentType = getHttpHeader(headers, 'content-type');
6
+
7
+ if (!contentType) {
8
+ return undefined;
9
+ }
10
+
11
+ const { value } = contentType;
12
+
13
+ // Content-Type can't be an array, but if it does we simply get the first element.
14
+ const actualValue = Array.isArray(value) ? value[0] : value;
15
+
16
+ return actualValue.split(';')[0].trim();
17
+ }
@@ -0,0 +1,17 @@
1
+ import { HttpHeaders, XHRHeaders } from '../shared/client';
2
+
3
+ // Utility to get header value and actual key case-insensitively
4
+ export function getHttpHeader<T extends HttpHeaders | XHRHeaders>(
5
+ headers: T,
6
+ name: string
7
+ ) {
8
+ const lowerName = name.toLowerCase();
9
+
10
+ for (const key in headers) {
11
+ if (key.toLowerCase() === lowerName) {
12
+ return { value: headers[key], originalKey: key };
13
+ }
14
+ }
15
+
16
+ return undefined;
17
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Combines multiple HTTP header values according to RFC 7230 Section 3.2.2
3
+ *
4
+ * Per RFC 7230 Section 3.2.2: "A recipient MAY combine multiple header fields
5
+ * with the same field name into one 'field-name: field-value' pair, without
6
+ * changing the semantics of the message, by appending each subsequent field
7
+ * value to the combined field value in order, separated by a comma."
8
+ *
9
+ * @see https://tools.ietf.org/html/rfc7230#section-3.2.2
10
+ */
11
+ export function getHttpHeaderValueAsString(value: string | string[]): string {
12
+ return Array.isArray(value) ? value.join(', ') : value;
13
+ }
@@ -0,0 +1,3 @@
1
+ export const getStringSizeInBytes = (value: string) => {
2
+ return new TextEncoder().encode(value).length;
3
+ };
@@ -0,0 +1,9 @@
1
+ import { RequestPostData } from '../shared/client';
2
+
3
+ export function inferContentTypeFromPostData(postData: RequestPostData) {
4
+ if (postData?.type === 'form-data') {
5
+ return 'multipart/form-data';
6
+ }
7
+
8
+ return undefined;
9
+ }
@@ -0,0 +1,7 @@
1
+ export function safeStringify(data: unknown): string {
2
+ try {
3
+ return typeof data === 'string' ? data : JSON.stringify(data);
4
+ } catch {
5
+ return String(data);
6
+ }
7
+ }
@@ -0,0 +1,27 @@
1
+ export const isBlob = (value: unknown): value is Blob => value instanceof Blob;
2
+
3
+ export const isArrayBuffer = (
4
+ value: unknown
5
+ ): value is ArrayBuffer | ArrayBufferView =>
6
+ value instanceof ArrayBuffer || ArrayBuffer.isView(value);
7
+
8
+ export const isFormData = (value: unknown): value is FormData =>
9
+ value instanceof FormData;
10
+
11
+ export const isNullOrUndefined = (value: unknown): value is null | undefined =>
12
+ value === null || value === undefined;
13
+
14
+ export const isString = (value: unknown): value is string =>
15
+ typeof value === 'string';
16
+
17
+ export const isNumber = (value: unknown): value is number =>
18
+ typeof value === 'number' && !isNaN(value);
19
+
20
+ export const isBoolean = (value: unknown): value is boolean =>
21
+ typeof value === 'boolean';
22
+
23
+ export const isObject = (value: unknown): value is object =>
24
+ typeof value === 'object' && value !== null;
25
+
26
+ export const isArray = (value: unknown): value is unknown[] =>
27
+ Array.isArray(value);
@@ -1,2 +0,0 @@
1
- import { HttpHeaders } from '../../shared/client';
2
- export declare function getHttpHeaderValue(headers: HttpHeaders, name: string): string | undefined;
@@ -1,14 +0,0 @@
1
- import { HttpHeaders } from "../../shared/client";
2
-
3
- // Utility to get header value case-insensitively
4
- export function getHttpHeaderValue(headers: HttpHeaders, name: string) {
5
- const lowerName = name.toLowerCase();
6
-
7
- for (const key in headers) {
8
- if (key.toLowerCase() === lowerName) {
9
- return headers[key];
10
- }
11
- }
12
-
13
- return undefined;
14
- }