@rozenite/network-activity-plugin 1.0.0-alpha.15 → 1.0.0-alpha.16
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/dist/App.html +2 -2
- package/dist/assets/{App-CfJuBHc_.css → App-BrSkOkws.css} +21 -0
- package/dist/assets/{App-CZPlDq_M.js → App-CM3Ub2ZA.js} +911 -479
- package/dist/rozenite.json +1 -1
- package/dist/src/react-native/http/overrides-registry.d.ts +6 -0
- package/dist/src/react-native/http/xhr-interceptor.d.ts +5 -0
- package/dist/src/shared/client.d.ts +7 -0
- package/dist/src/ui/components/CodeEditor.d.ts +5 -0
- package/dist/src/ui/components/OverrideResponse.d.ts +8 -0
- package/dist/src/ui/components/RequestList.d.ts +3 -2
- package/dist/src/ui/components/Section.d.ts +2 -1
- package/dist/src/ui/state/hooks.d.ts +3 -0
- package/dist/src/ui/state/store.d.ts +26 -3
- package/dist/useNetworkActivityDevTools.cjs +72 -0
- package/dist/useNetworkActivityDevTools.js +72 -0
- package/package.json +4 -4
- package/src/react-native/http/network-inspector.ts +50 -0
- package/src/react-native/http/overrides-registry.ts +32 -0
- package/src/react-native/http/xhr-interceptor.ts +14 -0
- package/src/react-native/useNetworkActivityDevTools.ts +6 -0
- package/src/shared/client.ts +9 -0
- package/src/ui/components/CodeEditor.tsx +26 -0
- package/src/ui/components/OverrideResponse.tsx +132 -0
- package/src/ui/components/RequestList.tsx +15 -8
- package/src/ui/components/Section.tsx +5 -1
- package/src/ui/components/SidePanel.tsx +8 -0
- package/src/ui/state/hooks.ts +4 -0
- package/src/ui/state/store.ts +585 -502
- package/src/ui/tabs/ResponseTab.tsx +60 -12
- package/src/ui/views/InspectorView.tsx +7 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { useRef, useState } from 'react';
|
|
2
|
+
import { HttpNetworkEntry } from '../state/model';
|
|
3
|
+
import { Section } from '../components/Section';
|
|
4
|
+
import { KeyValueGrid } from '../components/KeyValueGrid';
|
|
5
|
+
import { useNetworkActivityActions } from '../state/hooks';
|
|
6
|
+
import { CodeEditor } from '../components/CodeEditor';
|
|
7
|
+
import { RequestOverride } from '../../shared/client';
|
|
8
|
+
import { Button } from './Button';
|
|
9
|
+
import { Check, CircleSlash2 } from 'lucide-react';
|
|
10
|
+
|
|
11
|
+
export type OverrideResponseProps = {
|
|
12
|
+
selectedRequest: HttpNetworkEntry;
|
|
13
|
+
initialOverride: RequestOverride | undefined;
|
|
14
|
+
onClear: () => void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const OverrideResponse = ({
|
|
18
|
+
selectedRequest,
|
|
19
|
+
initialOverride,
|
|
20
|
+
onClear,
|
|
21
|
+
}: OverrideResponseProps) => {
|
|
22
|
+
const actions = useNetworkActivityActions();
|
|
23
|
+
const [savedOverride, setSavedOverride] = useState<
|
|
24
|
+
RequestOverride | undefined
|
|
25
|
+
>(initialOverride);
|
|
26
|
+
const [editedBody, setEditedBody] = useState<string | undefined>(
|
|
27
|
+
initialOverride?.body
|
|
28
|
+
);
|
|
29
|
+
const [editedStatus, setEditedStatus] = useState<number | undefined>(
|
|
30
|
+
initialOverride?.status
|
|
31
|
+
);
|
|
32
|
+
const responseEditorRef = useRef<HTMLPreElement>(null);
|
|
33
|
+
const responseBody = selectedRequest.response?.body;
|
|
34
|
+
|
|
35
|
+
const saveOverride = () => {
|
|
36
|
+
if (editedBody === undefined && editedStatus === undefined) return;
|
|
37
|
+
|
|
38
|
+
const newOverrideData = {
|
|
39
|
+
body: editedBody,
|
|
40
|
+
status: editedStatus,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
setSavedOverride(newOverrideData);
|
|
44
|
+
actions.addOverride(selectedRequest.request.url, newOverrideData);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const clearOverride = () => {
|
|
48
|
+
setSavedOverride(undefined);
|
|
49
|
+
setEditedBody(undefined);
|
|
50
|
+
actions.clearOverride(selectedRequest.request.url);
|
|
51
|
+
onClear();
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
if (!responseBody || responseBody.data === null) {
|
|
55
|
+
return (
|
|
56
|
+
<div className="text-sm text-gray-400">
|
|
57
|
+
No response body available for this request
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const { type } = responseBody;
|
|
63
|
+
|
|
64
|
+
const hasChanges =
|
|
65
|
+
editedBody !== savedOverride?.body ||
|
|
66
|
+
editedStatus !== savedOverride?.status;
|
|
67
|
+
|
|
68
|
+
const overrideActions = (
|
|
69
|
+
<>
|
|
70
|
+
<Button
|
|
71
|
+
variant="ghost"
|
|
72
|
+
size="xs"
|
|
73
|
+
className="text-violet-300 hover:text-violet-300 ms-2"
|
|
74
|
+
onClick={clearOverride}
|
|
75
|
+
>
|
|
76
|
+
<CircleSlash2 className="h-2 w-2" />
|
|
77
|
+
Clear override
|
|
78
|
+
</Button>
|
|
79
|
+
|
|
80
|
+
<Button
|
|
81
|
+
variant="ghost"
|
|
82
|
+
size="xs"
|
|
83
|
+
className="text-violet-300 hover:text-violet-300"
|
|
84
|
+
onClick={saveOverride}
|
|
85
|
+
disabled={!hasChanges}
|
|
86
|
+
>
|
|
87
|
+
<Check className="h-2 w-2" />
|
|
88
|
+
{hasChanges ? 'Save override' : 'Saved'}
|
|
89
|
+
</Button>
|
|
90
|
+
</>
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
if (savedOverride !== undefined) {
|
|
94
|
+
return (
|
|
95
|
+
<Section
|
|
96
|
+
title="Response Body"
|
|
97
|
+
collapsible={false}
|
|
98
|
+
action={overrideActions}
|
|
99
|
+
>
|
|
100
|
+
<div className="space-y-4">
|
|
101
|
+
<KeyValueGrid
|
|
102
|
+
items={[
|
|
103
|
+
{
|
|
104
|
+
key: 'Content-Type',
|
|
105
|
+
value: type,
|
|
106
|
+
valueClassName: 'text-blue-400',
|
|
107
|
+
},
|
|
108
|
+
]}
|
|
109
|
+
/>
|
|
110
|
+
|
|
111
|
+
<div className="grid grid-cols-[minmax(7rem,25%)_minmax(3rem,1fr)] gap-x-2 gap-y-2 text-sm">
|
|
112
|
+
<span className={'text-gray-400 wrap-anywhere'}>Status Code</span>
|
|
113
|
+
<input
|
|
114
|
+
type="number"
|
|
115
|
+
value={editedStatus}
|
|
116
|
+
onChange={(e) => {
|
|
117
|
+
setEditedStatus(parseInt(e.target.value));
|
|
118
|
+
}}
|
|
119
|
+
className="max-w-24 font-mono text-gray-300 whitespace-pre-wrap bg-gray-800 p-1 rounded-md border border-gray-700 overflow-x-auto wrap-anywhere ring-offset-blue-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
|
120
|
+
/>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<CodeEditor
|
|
124
|
+
data={savedOverride?.body}
|
|
125
|
+
ref={responseEditorRef}
|
|
126
|
+
onInput={(e) => setEditedBody(e.currentTarget.innerText)}
|
|
127
|
+
/>
|
|
128
|
+
</div>
|
|
129
|
+
</Section>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
@@ -9,9 +9,10 @@ import {
|
|
|
9
9
|
useReactTable,
|
|
10
10
|
} from '@tanstack/react-table';
|
|
11
11
|
import { ProcessedRequest } from '../state/model';
|
|
12
|
-
import { RequestId } from '../../shared/client';
|
|
12
|
+
import { RequestId, RequestOverride } from '../../shared/client';
|
|
13
13
|
import {
|
|
14
14
|
useNetworkActivityActions,
|
|
15
|
+
useOverrides,
|
|
15
16
|
useProcessedRequests,
|
|
16
17
|
useSelectedRequestId,
|
|
17
18
|
} from '../state/hooks';
|
|
@@ -30,6 +31,7 @@ type NetworkRequest = {
|
|
|
30
31
|
time: string;
|
|
31
32
|
type: string;
|
|
32
33
|
startTime: string;
|
|
34
|
+
hasOverride: boolean;
|
|
33
35
|
};
|
|
34
36
|
|
|
35
37
|
const formatSize = (bytes: number): string => {
|
|
@@ -122,11 +124,13 @@ const sortTime: SortingFn<NetworkRequest> = (rowA, rowB, columnId) => {
|
|
|
122
124
|
};
|
|
123
125
|
|
|
124
126
|
const processNetworkRequests = (
|
|
125
|
-
processedRequests: ProcessedRequest[]
|
|
127
|
+
processedRequests: ProcessedRequest[],
|
|
128
|
+
overrides: Map<string, RequestOverride>
|
|
126
129
|
): NetworkRequest[] => {
|
|
127
130
|
return processedRequests.map((request): NetworkRequest => {
|
|
128
131
|
const { domain, path } = extractDomainAndPath(request.name);
|
|
129
132
|
const duration = request.duration || 0;
|
|
133
|
+
const hasOverride = overrides.has(request.name);
|
|
130
134
|
|
|
131
135
|
return {
|
|
132
136
|
id: request.id,
|
|
@@ -139,6 +143,7 @@ const processNetworkRequests = (
|
|
|
139
143
|
time: formatDuration(duration),
|
|
140
144
|
type: request.type,
|
|
141
145
|
startTime: formatStartTime(request.timestamp),
|
|
146
|
+
hasOverride: hasOverride,
|
|
142
147
|
};
|
|
143
148
|
});
|
|
144
149
|
};
|
|
@@ -155,11 +160,12 @@ const columns = [
|
|
|
155
160
|
columnHelper.accessor('name', {
|
|
156
161
|
header: 'Name',
|
|
157
162
|
cell: ({ row, getValue }) => (
|
|
158
|
-
<div
|
|
159
|
-
className="flex-1 min-w-0 truncate"
|
|
160
|
-
title={row.original.path}
|
|
161
|
-
>
|
|
163
|
+
<div className="flex-1 min-w-0 truncate" title={row.original.path}>
|
|
162
164
|
{getValue()}
|
|
165
|
+
|
|
166
|
+
{row.original.hasOverride && (
|
|
167
|
+
<span className="w-2 h-2 rounded-full bg-violet-300 ms-2 inline-block"></span>
|
|
168
|
+
)}
|
|
163
169
|
</div>
|
|
164
170
|
),
|
|
165
171
|
sortingFn: 'alphanumeric',
|
|
@@ -215,6 +221,7 @@ export const RequestList = ({ filter }: RequestListProps) => {
|
|
|
215
221
|
const processedRequests = useProcessedRequests();
|
|
216
222
|
const selectedRequestId = useSelectedRequestId();
|
|
217
223
|
const [sorting, setSorting] = useState<SortingState>([]);
|
|
224
|
+
const overrides = useOverrides();
|
|
218
225
|
|
|
219
226
|
// Filter requests based on current filter state
|
|
220
227
|
const filteredRequests = useMemo(() => {
|
|
@@ -243,8 +250,8 @@ export const RequestList = ({ filter }: RequestListProps) => {
|
|
|
243
250
|
}, [processedRequests, filter]);
|
|
244
251
|
|
|
245
252
|
const requests = useMemo(() => {
|
|
246
|
-
return processNetworkRequests(filteredRequests);
|
|
247
|
-
}, [filteredRequests]);
|
|
253
|
+
return processNetworkRequests(filteredRequests, overrides);
|
|
254
|
+
}, [filteredRequests, overrides]);
|
|
248
255
|
|
|
249
256
|
const table = useReactTable({
|
|
250
257
|
data: requests,
|
|
@@ -5,12 +5,14 @@ export type SectionProps = {
|
|
|
5
5
|
title: string;
|
|
6
6
|
children: React.ReactNode;
|
|
7
7
|
collapsible?: boolean;
|
|
8
|
+
action?: React.ReactNode;
|
|
8
9
|
};
|
|
9
10
|
|
|
10
11
|
export const Section = ({
|
|
11
12
|
title,
|
|
12
13
|
children,
|
|
13
14
|
collapsible = true,
|
|
15
|
+
action,
|
|
14
16
|
}: SectionProps) => {
|
|
15
17
|
const [isCollapsed, setIsCollapsed] = useState(false);
|
|
16
18
|
|
|
@@ -34,7 +36,9 @@ export const Section = ({
|
|
|
34
36
|
{collapsible && (
|
|
35
37
|
<span className={cn('mr-2', { 'rotate-90': !isCollapsed })}>▶</span>
|
|
36
38
|
)}
|
|
37
|
-
<span className="font-medium">{title}</span>
|
|
39
|
+
<span className="font-medium me-auto">{title}</span>
|
|
40
|
+
|
|
41
|
+
{action}
|
|
38
42
|
</button>
|
|
39
43
|
{isChildrenVisible && children}
|
|
40
44
|
</div>
|
|
@@ -10,6 +10,7 @@ import { X } from 'lucide-react';
|
|
|
10
10
|
import {
|
|
11
11
|
useNetworkActivityActions,
|
|
12
12
|
useNetworkActivityStore,
|
|
13
|
+
useOverrides,
|
|
13
14
|
useSelectedRequest,
|
|
14
15
|
} from '../state/hooks';
|
|
15
16
|
import { NetworkEntry as OldNetworkEntry } from '../types';
|
|
@@ -85,6 +86,7 @@ export const SidePanel = () => {
|
|
|
85
86
|
const actions = useNetworkActivityActions();
|
|
86
87
|
const selectedRequest = useSelectedRequest();
|
|
87
88
|
const client = useNetworkActivityStore((state) => state._client);
|
|
89
|
+
const overrides = useOverrides();
|
|
88
90
|
|
|
89
91
|
const onClose = (): void => {
|
|
90
92
|
actions.setSelectedRequest(null);
|
|
@@ -128,6 +130,9 @@ export const SidePanel = () => {
|
|
|
128
130
|
legacyNetworkEntries.set(legacyEntry.requestId, legacyEntry);
|
|
129
131
|
}
|
|
130
132
|
|
|
133
|
+
const override = legacyEntry !== null ? overrides.get(legacyEntry.url) : null;
|
|
134
|
+
const hasResponseOverride = override && override.body ? true : false;
|
|
135
|
+
|
|
131
136
|
const getTabsListTriggers = () => {
|
|
132
137
|
if (httpDetails) {
|
|
133
138
|
return (
|
|
@@ -149,6 +154,9 @@ export const SidePanel = () => {
|
|
|
149
154
|
className="data-[state=active]:bg-gray-700"
|
|
150
155
|
>
|
|
151
156
|
Response
|
|
157
|
+
{hasResponseOverride && (
|
|
158
|
+
<span className="w-2 h-2 rounded-full bg-violet-300 ms-2 inline-block"></span>
|
|
159
|
+
)}
|
|
152
160
|
</TabsTrigger>
|
|
153
161
|
<TabsTrigger
|
|
154
162
|
value="cookies"
|
package/src/ui/state/hooks.ts
CHANGED