@rozenite/network-activity-plugin 1.7.0 → 1.8.1
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/CHANGELOG.md +32 -0
- package/README.md +24 -0
- package/dist/devtools/App.html +2 -2
- package/dist/devtools/assets/{App-pokLiGYV.js → App-B3xlUjs6.js} +163 -115
- package/dist/devtools/assets/{App-BrSkOkws.css → App-m6xge0az.css} +13 -0
- package/dist/react-native/chunks/boot-recording.cjs +307 -28
- package/dist/react-native/chunks/boot-recording.js +310 -31
- package/dist/react-native/chunks/useNetworkActivityDevTools.require.cjs +192 -141
- package/dist/react-native/chunks/useNetworkActivityDevTools.require.js +193 -142
- package/dist/react-native/index.d.ts +24 -7
- package/dist/rozenite.json +1 -1
- package/dist/sdk/index.cjs +127 -0
- package/dist/sdk/index.d.ts +1243 -0
- package/dist/sdk/index.js +127 -0
- package/package.json +17 -6
- package/sdk.ts +59 -0
- package/src/react-native/__tests__/events-listener.test.ts +35 -0
- package/src/react-native/agent/__tests__/network-activity-agent-state.test.ts +21 -9
- package/src/react-native/agent/state.ts +13 -13
- package/src/react-native/agent/tools.ts +20 -146
- package/src/react-native/agent/use-network-activity-agent-tools.ts +73 -64
- package/src/react-native/events-listener.ts +12 -3
- package/src/react-native/http/http-inspector.ts +19 -5
- package/src/react-native/network-inspector.ts +46 -8
- package/src/react-native/nitro-fetch/__tests__/nitro-network-inspector.test.ts +198 -0
- package/src/react-native/nitro-fetch/nitro-network-inspector.ts +403 -0
- package/src/react-native/useHttpInspector.ts +9 -19
- package/src/react-native/useNetworkActivityDevTools.ts +13 -1
- package/src/react-native/websocket/__tests__/websocket-inspector.test.ts +69 -0
- package/src/react-native/websocket/websocket-inspector.ts +32 -17
- package/src/shared/agent-tools.ts +230 -0
- package/src/shared/client.ts +3 -0
- package/src/shared/http-events.ts +6 -0
- package/src/shared/websocket-events.ts +16 -7
- package/src/ui/components/RequestList.tsx +21 -0
- package/src/ui/components/SidePanel.tsx +12 -9
- package/src/ui/state/derived.ts +4 -0
- package/src/ui/state/model.ts +6 -1
- package/src/ui/state/store.ts +52 -36
- package/src/ui/tabs/HeadersTab.tsx +18 -4
- package/src/ui/tabs/ResponseTab.tsx +5 -3
- package/tsconfig.json +4 -1
- package/vite.config.ts +7 -0
|
@@ -37,7 +37,7 @@ const getTypeColor = (type: string) => {
|
|
|
37
37
|
const createLegacyNetworkEntry = (
|
|
38
38
|
selectedRequest: any,
|
|
39
39
|
httpDetails: any,
|
|
40
|
-
wsDetails: any
|
|
40
|
+
wsDetails: any,
|
|
41
41
|
): OldNetworkEntry | null => {
|
|
42
42
|
if (selectedRequest.type === 'http' && httpDetails) {
|
|
43
43
|
return {
|
|
@@ -108,22 +108,22 @@ export const SidePanel = () => {
|
|
|
108
108
|
selectedRequest.type === 'http'
|
|
109
109
|
? httpDetails?.request?.url || 'Unknown'
|
|
110
110
|
: selectedRequest.type === 'websocket'
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
? wsDetails?.connection?.url || 'Unknown'
|
|
112
|
+
: sseDetails?.request?.url || 'Unknown';
|
|
113
113
|
|
|
114
114
|
// Extract status from the request
|
|
115
115
|
const requestStatus =
|
|
116
116
|
selectedRequest.type === 'http'
|
|
117
117
|
? httpDetails?.response?.status || httpDetails?.status || 'pending'
|
|
118
118
|
: selectedRequest.type === 'websocket'
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
? wsDetails?.status || 'unknown'
|
|
120
|
+
: sseDetails?.status || 'unknown';
|
|
121
121
|
|
|
122
122
|
// Create legacy network entry for tab components
|
|
123
123
|
const legacyEntry = createLegacyNetworkEntry(
|
|
124
124
|
selectedRequest,
|
|
125
125
|
httpDetails,
|
|
126
|
-
wsDetails
|
|
126
|
+
wsDetails,
|
|
127
127
|
);
|
|
128
128
|
const legacyNetworkEntries = new Map<string, OldNetworkEntry>();
|
|
129
129
|
if (legacyEntry) {
|
|
@@ -131,7 +131,9 @@ export const SidePanel = () => {
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
const override = legacyEntry !== null ? overrides.get(legacyEntry.url) : null;
|
|
134
|
-
const
|
|
134
|
+
const supportsOverrides = httpDetails?.source !== 'nitro';
|
|
135
|
+
const hasResponseOverride =
|
|
136
|
+
supportsOverrides && override && override.body ? true : false;
|
|
135
137
|
|
|
136
138
|
const getTabsListTriggers = () => {
|
|
137
139
|
if (httpDetails) {
|
|
@@ -226,6 +228,7 @@ export const SidePanel = () => {
|
|
|
226
228
|
<TabsContent value="response" className="flex-1 m-0 overflow-hidden">
|
|
227
229
|
<ResponseTab
|
|
228
230
|
selectedRequest={httpDetails}
|
|
231
|
+
supportsOverrides={supportsOverrides}
|
|
229
232
|
onRequestResponseBody={(requestId) => {
|
|
230
233
|
if (client) {
|
|
231
234
|
client.send('get-response-body', {
|
|
@@ -289,14 +292,14 @@ export const SidePanel = () => {
|
|
|
289
292
|
<div className="flex items-center gap-2 min-w-0 flex-1">
|
|
290
293
|
<div
|
|
291
294
|
className={`w-3 h-3 rounded-full flex-shrink-0 ${getTypeColor(
|
|
292
|
-
selectedRequest.type
|
|
295
|
+
selectedRequest.type,
|
|
293
296
|
)}`}
|
|
294
297
|
></div>
|
|
295
298
|
<span className="font-medium truncate">{requestName}</span>
|
|
296
299
|
<Badge
|
|
297
300
|
variant="outline"
|
|
298
301
|
className={`${getStatusColor(
|
|
299
|
-
requestStatus
|
|
302
|
+
requestStatus,
|
|
300
303
|
)} border-current flex-shrink-0`}
|
|
301
304
|
>
|
|
302
305
|
{requestStatus}
|
package/src/ui/state/derived.ts
CHANGED
|
@@ -17,6 +17,7 @@ export const getProcessedRequests = memoize((state: NetworkActivityState) => {
|
|
|
17
17
|
requests.push({
|
|
18
18
|
id: httpEntry.id,
|
|
19
19
|
type: 'http',
|
|
20
|
+
source: httpEntry.source,
|
|
20
21
|
name: httpEntry.request.url,
|
|
21
22
|
status: httpEntry.status,
|
|
22
23
|
timestamp: httpEntry.timestamp,
|
|
@@ -31,6 +32,7 @@ export const getProcessedRequests = memoize((state: NetworkActivityState) => {
|
|
|
31
32
|
requests.push({
|
|
32
33
|
id: wsEntry.id,
|
|
33
34
|
type: 'websocket',
|
|
35
|
+
source: wsEntry.source,
|
|
34
36
|
name: wsEntry.connection.url,
|
|
35
37
|
status: wsEntry.status,
|
|
36
38
|
timestamp: wsEntry.timestamp,
|
|
@@ -77,6 +79,7 @@ export const getRequestSummary = (
|
|
|
77
79
|
return {
|
|
78
80
|
id: httpEntry.id,
|
|
79
81
|
type: 'http',
|
|
82
|
+
source: httpEntry.source,
|
|
80
83
|
name: httpEntry.request.url,
|
|
81
84
|
status: httpEntry.status,
|
|
82
85
|
timestamp: httpEntry.timestamp,
|
|
@@ -91,6 +94,7 @@ export const getRequestSummary = (
|
|
|
91
94
|
return {
|
|
92
95
|
id: wsEntry.id,
|
|
93
96
|
type: 'websocket',
|
|
97
|
+
source: wsEntry.source,
|
|
94
98
|
name: wsEntry.connection.url,
|
|
95
99
|
status: wsEntry.status,
|
|
96
100
|
timestamp: wsEntry.timestamp,
|
package/src/ui/state/model.ts
CHANGED
|
@@ -3,11 +3,12 @@ import {
|
|
|
3
3
|
ResourceType,
|
|
4
4
|
HttpHeaders,
|
|
5
5
|
RequestPostData,
|
|
6
|
+
NetworkEventSource,
|
|
6
7
|
} from '../../shared/client';
|
|
7
8
|
|
|
8
9
|
export type RequestId = string;
|
|
9
10
|
export type Timestamp = number;
|
|
10
|
-
export type SocketId =
|
|
11
|
+
export type SocketId = string;
|
|
11
12
|
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD';
|
|
12
13
|
|
|
13
14
|
export type NetworkEntryType = 'http' | 'websocket' | 'sse';
|
|
@@ -47,6 +48,7 @@ export type HttpNetworkEntry = {
|
|
|
47
48
|
id: RequestId;
|
|
48
49
|
type: 'http';
|
|
49
50
|
timestamp: Timestamp;
|
|
51
|
+
source?: NetworkEventSource;
|
|
50
52
|
duration?: number;
|
|
51
53
|
|
|
52
54
|
request: HttpRequest;
|
|
@@ -79,6 +81,7 @@ export type SSENetworkEntry = {
|
|
|
79
81
|
id: RequestId;
|
|
80
82
|
type: 'sse';
|
|
81
83
|
timestamp: Timestamp;
|
|
84
|
+
source?: NetworkEventSource;
|
|
82
85
|
duration?: number;
|
|
83
86
|
|
|
84
87
|
request: HttpRequest;
|
|
@@ -117,6 +120,7 @@ export type WebSocketNetworkEntry = {
|
|
|
117
120
|
id: RequestId;
|
|
118
121
|
type: 'websocket';
|
|
119
122
|
timestamp: Timestamp;
|
|
123
|
+
source?: NetworkEventSource;
|
|
120
124
|
duration?: number;
|
|
121
125
|
|
|
122
126
|
connection: WebSocketConnection;
|
|
@@ -135,6 +139,7 @@ export type NetworkEntry =
|
|
|
135
139
|
export type ProcessedRequest = {
|
|
136
140
|
id: RequestId;
|
|
137
141
|
type: NetworkEntryType;
|
|
142
|
+
source?: NetworkEventSource;
|
|
138
143
|
name: string;
|
|
139
144
|
status: HttpStatus | WebSocketStatus | SSEStatus;
|
|
140
145
|
timestamp: Timestamp;
|
package/src/ui/state/store.ts
CHANGED
|
@@ -50,7 +50,7 @@ export interface NetworkActivityState {
|
|
|
50
50
|
// Event handling
|
|
51
51
|
handleEvent: <K extends keyof NetworkActivityEventMap>(
|
|
52
52
|
eventType: K,
|
|
53
|
-
data: NetworkActivityEventMap[K]
|
|
53
|
+
data: NetworkActivityEventMap[K],
|
|
54
54
|
) => void;
|
|
55
55
|
|
|
56
56
|
// Client management
|
|
@@ -80,7 +80,7 @@ export const createNetworkActivityStore = () =>
|
|
|
80
80
|
|
|
81
81
|
_client.send(
|
|
82
82
|
isRecording ? 'network-enable' : 'network-disable',
|
|
83
|
-
{}
|
|
83
|
+
{},
|
|
84
84
|
);
|
|
85
85
|
set({ isRecording });
|
|
86
86
|
},
|
|
@@ -120,11 +120,22 @@ export const createNetworkActivityStore = () =>
|
|
|
120
120
|
// Event handling
|
|
121
121
|
handleEvent: <K extends keyof NetworkActivityEventMap>(
|
|
122
122
|
eventType: K,
|
|
123
|
-
data: NetworkActivityEventMap[K]
|
|
123
|
+
data: NetworkActivityEventMap[K],
|
|
124
124
|
) => {
|
|
125
125
|
switch (eventType) {
|
|
126
|
+
case 'recording-state': {
|
|
127
|
+
const eventData =
|
|
128
|
+
data as NetworkActivityEventMap['recording-state'];
|
|
129
|
+
const { isRecording, _client } = get();
|
|
130
|
+
if (_client && isRecording !== eventData.isRecording) {
|
|
131
|
+
_client.send(isRecording ? 'network-enable' : 'network-disable', {});
|
|
132
|
+
}
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
|
|
126
136
|
case 'client-ui-settings': {
|
|
127
|
-
const eventData =
|
|
137
|
+
const eventData =
|
|
138
|
+
data as NetworkActivityEventMap['client-ui-settings'];
|
|
128
139
|
set({ clientUISettings: eventData.settings || null });
|
|
129
140
|
break;
|
|
130
141
|
}
|
|
@@ -135,7 +146,7 @@ export const createNetworkActivityStore = () =>
|
|
|
135
146
|
const headersWithContentType =
|
|
136
147
|
applyReactNativeRequestHeadersLogic(
|
|
137
148
|
eventData.request.headers,
|
|
138
|
-
eventData.request.postData
|
|
149
|
+
eventData.request.postData,
|
|
139
150
|
);
|
|
140
151
|
|
|
141
152
|
const requestContentType =
|
|
@@ -145,6 +156,7 @@ export const createNetworkActivityStore = () =>
|
|
|
145
156
|
id: eventData.requestId,
|
|
146
157
|
type: 'http',
|
|
147
158
|
timestamp: eventData.timestamp,
|
|
159
|
+
source: eventData.source ?? 'builtin',
|
|
148
160
|
request: {
|
|
149
161
|
url: eventData.request.url,
|
|
150
162
|
method: eventData.request.method,
|
|
@@ -280,7 +292,7 @@ export const createNetworkActivityStore = () =>
|
|
|
280
292
|
? {
|
|
281
293
|
type:
|
|
282
294
|
getContentTypeMime(
|
|
283
|
-
httpEntry.response?.headers ?? {}
|
|
295
|
+
httpEntry.response?.headers ?? {},
|
|
284
296
|
) || 'text/plain',
|
|
285
297
|
data: eventData.body,
|
|
286
298
|
}
|
|
@@ -304,6 +316,7 @@ export const createNetworkActivityStore = () =>
|
|
|
304
316
|
id: `ws-${eventData.socketId}`,
|
|
305
317
|
type: 'websocket',
|
|
306
318
|
timestamp: eventData.timestamp,
|
|
319
|
+
source: eventData.source ?? 'builtin',
|
|
307
320
|
connection: {
|
|
308
321
|
url: eventData.url,
|
|
309
322
|
socketId: eventData.socketId,
|
|
@@ -332,7 +345,7 @@ export const createNetworkActivityStore = () =>
|
|
|
332
345
|
data as NetworkActivityEventMap['websocket-open'];
|
|
333
346
|
set((state) => {
|
|
334
347
|
const entry = state.networkEntries.get(
|
|
335
|
-
`ws-${eventData.socketId}
|
|
348
|
+
`ws-${eventData.socketId}`,
|
|
336
349
|
);
|
|
337
350
|
if (!entry || entry.type !== 'websocket') return state;
|
|
338
351
|
|
|
@@ -354,7 +367,7 @@ export const createNetworkActivityStore = () =>
|
|
|
354
367
|
data as NetworkActivityEventMap['websocket-close'];
|
|
355
368
|
set((state) => {
|
|
356
369
|
const entry = state.networkEntries.get(
|
|
357
|
-
`ws-${eventData.socketId}
|
|
370
|
+
`ws-${eventData.socketId}`,
|
|
358
371
|
);
|
|
359
372
|
if (!entry || entry.type !== 'websocket') return state;
|
|
360
373
|
|
|
@@ -394,8 +407,8 @@ export const createNetworkActivityStore = () =>
|
|
|
394
407
|
newMessages.set(
|
|
395
408
|
socketId,
|
|
396
409
|
[...currentMessages, message].slice(
|
|
397
|
-
-MAX_WEBSOCKET_MESSAGES_PER_CONNECTION
|
|
398
|
-
)
|
|
410
|
+
-MAX_WEBSOCKET_MESSAGES_PER_CONNECTION,
|
|
411
|
+
),
|
|
399
412
|
);
|
|
400
413
|
|
|
401
414
|
return { websocketMessages: newMessages };
|
|
@@ -423,8 +436,8 @@ export const createNetworkActivityStore = () =>
|
|
|
423
436
|
newMessages.set(
|
|
424
437
|
socketId,
|
|
425
438
|
[...currentMessages, message].slice(
|
|
426
|
-
-MAX_WEBSOCKET_MESSAGES_PER_CONNECTION
|
|
427
|
-
)
|
|
439
|
+
-MAX_WEBSOCKET_MESSAGES_PER_CONNECTION,
|
|
440
|
+
),
|
|
428
441
|
);
|
|
429
442
|
|
|
430
443
|
return { websocketMessages: newMessages };
|
|
@@ -437,7 +450,7 @@ export const createNetworkActivityStore = () =>
|
|
|
437
450
|
data as NetworkActivityEventMap['websocket-error'];
|
|
438
451
|
set((state) => {
|
|
439
452
|
const entry = state.networkEntries.get(
|
|
440
|
-
`ws-${eventData.socketId}
|
|
453
|
+
`ws-${eventData.socketId}`,
|
|
441
454
|
);
|
|
442
455
|
if (!entry || entry.type !== 'websocket') return state;
|
|
443
456
|
|
|
@@ -460,7 +473,7 @@ export const createNetworkActivityStore = () =>
|
|
|
460
473
|
data as NetworkActivityEventMap['websocket-connection-status-changed'];
|
|
461
474
|
set((state) => {
|
|
462
475
|
const entry = state.networkEntries.get(
|
|
463
|
-
`ws-${eventData.socketId}
|
|
476
|
+
`ws-${eventData.socketId}`,
|
|
464
477
|
);
|
|
465
478
|
if (!entry || entry.type !== 'websocket') return state;
|
|
466
479
|
|
|
@@ -520,7 +533,7 @@ export const createNetworkActivityStore = () =>
|
|
|
520
533
|
const updatedEntry: SSENetworkEntry = {
|
|
521
534
|
...sseEntry,
|
|
522
535
|
messages: [...sseEntry.messages, newMessage].slice(
|
|
523
|
-
-MAX_SSE_MESSAGES_PER_CONNECTION
|
|
536
|
+
-MAX_SSE_MESSAGES_PER_CONNECTION,
|
|
524
537
|
),
|
|
525
538
|
};
|
|
526
539
|
|
|
@@ -580,59 +593,62 @@ export const createNetworkActivityStore = () =>
|
|
|
580
593
|
|
|
581
594
|
// Subscribe to all events using the unified handler
|
|
582
595
|
const unsubscribeFunctions = [
|
|
596
|
+
client.onMessage('recording-state', (data) =>
|
|
597
|
+
handleEvent('recording-state', data)
|
|
598
|
+
),
|
|
583
599
|
client.onMessage('client-ui-settings', (data) =>
|
|
584
|
-
handleEvent('client-ui-settings', data)
|
|
600
|
+
handleEvent('client-ui-settings', data),
|
|
585
601
|
),
|
|
586
602
|
client.onMessage('request-sent', (data) =>
|
|
587
|
-
handleEvent('request-sent', data)
|
|
603
|
+
handleEvent('request-sent', data),
|
|
588
604
|
),
|
|
589
605
|
client.onMessage('request-progress', (data) =>
|
|
590
|
-
handleEvent('request-progress', data)
|
|
606
|
+
handleEvent('request-progress', data),
|
|
591
607
|
),
|
|
592
608
|
client.onMessage('response-received', (data) =>
|
|
593
|
-
handleEvent('response-received', data)
|
|
609
|
+
handleEvent('response-received', data),
|
|
594
610
|
),
|
|
595
611
|
client.onMessage('request-completed', (data) =>
|
|
596
|
-
handleEvent('request-completed', data)
|
|
612
|
+
handleEvent('request-completed', data),
|
|
597
613
|
),
|
|
598
614
|
client.onMessage('request-failed', (data) =>
|
|
599
|
-
handleEvent('request-failed', data)
|
|
615
|
+
handleEvent('request-failed', data),
|
|
600
616
|
),
|
|
601
617
|
client.onMessage('response-body', (data) =>
|
|
602
|
-
handleEvent('response-body', data)
|
|
618
|
+
handleEvent('response-body', data),
|
|
603
619
|
),
|
|
604
620
|
client.onMessage('websocket-connect', (data) =>
|
|
605
|
-
handleEvent('websocket-connect', data)
|
|
621
|
+
handleEvent('websocket-connect', data),
|
|
606
622
|
),
|
|
607
623
|
client.onMessage('websocket-open', (data) =>
|
|
608
|
-
handleEvent('websocket-open', data)
|
|
624
|
+
handleEvent('websocket-open', data),
|
|
609
625
|
),
|
|
610
626
|
client.onMessage('websocket-close', (data) =>
|
|
611
|
-
handleEvent('websocket-close', data)
|
|
627
|
+
handleEvent('websocket-close', data),
|
|
612
628
|
),
|
|
613
629
|
client.onMessage('websocket-message-sent', (data) =>
|
|
614
|
-
handleEvent('websocket-message-sent', data)
|
|
630
|
+
handleEvent('websocket-message-sent', data),
|
|
615
631
|
),
|
|
616
632
|
client.onMessage('websocket-message-received', (data) =>
|
|
617
|
-
handleEvent('websocket-message-received', data)
|
|
633
|
+
handleEvent('websocket-message-received', data),
|
|
618
634
|
),
|
|
619
635
|
client.onMessage('websocket-error', (data) =>
|
|
620
|
-
handleEvent('websocket-error', data)
|
|
636
|
+
handleEvent('websocket-error', data),
|
|
621
637
|
),
|
|
622
638
|
client.onMessage('websocket-connection-status-changed', (data) =>
|
|
623
|
-
handleEvent('websocket-connection-status-changed', data)
|
|
639
|
+
handleEvent('websocket-connection-status-changed', data),
|
|
624
640
|
),
|
|
625
641
|
client.onMessage('sse-open', (data) =>
|
|
626
|
-
handleEvent('sse-open', data)
|
|
642
|
+
handleEvent('sse-open', data),
|
|
627
643
|
),
|
|
628
644
|
client.onMessage('sse-message', (data) =>
|
|
629
|
-
handleEvent('sse-message', data)
|
|
645
|
+
handleEvent('sse-message', data),
|
|
630
646
|
),
|
|
631
647
|
client.onMessage('sse-error', (data) =>
|
|
632
|
-
handleEvent('sse-error', data)
|
|
648
|
+
handleEvent('sse-error', data),
|
|
633
649
|
),
|
|
634
650
|
client.onMessage('sse-close', (data) =>
|
|
635
|
-
handleEvent('sse-close', data)
|
|
651
|
+
handleEvent('sse-close', data),
|
|
636
652
|
),
|
|
637
653
|
];
|
|
638
654
|
|
|
@@ -651,7 +667,7 @@ export const createNetworkActivityStore = () =>
|
|
|
651
667
|
|
|
652
668
|
if (_unsubscribeFunctions) {
|
|
653
669
|
_unsubscribeFunctions.forEach(
|
|
654
|
-
(unsubscribe: { remove: () => void }) => unsubscribe.remove()
|
|
670
|
+
(unsubscribe: { remove: () => void }) => unsubscribe.remove(),
|
|
655
671
|
);
|
|
656
672
|
}
|
|
657
673
|
|
|
@@ -693,8 +709,8 @@ export const createNetworkActivityStore = () =>
|
|
|
693
709
|
},
|
|
694
710
|
}),
|
|
695
711
|
partialize: (state) => ({ overrides: state.overrides }), // Persist only the overrides
|
|
696
|
-
}
|
|
697
|
-
)
|
|
712
|
+
},
|
|
713
|
+
),
|
|
698
714
|
);
|
|
699
715
|
|
|
700
716
|
export const store = createNetworkActivityStore();
|
|
@@ -17,7 +17,7 @@ function getHeadersItems(headers?: HttpHeaders): KeyValueItem[] {
|
|
|
17
17
|
return Object.entries(headers).reduce<KeyValueItem[]>((acc, [key, value]) => {
|
|
18
18
|
if (Array.isArray(value)) {
|
|
19
19
|
acc.push(
|
|
20
|
-
...value.map((item) => ({ key: key.toLowerCase(), value: item }))
|
|
20
|
+
...value.map((item) => ({ key: key.toLowerCase(), value: item })),
|
|
21
21
|
);
|
|
22
22
|
} else {
|
|
23
23
|
acc.push({ key: key.toLowerCase(), value: value });
|
|
@@ -29,6 +29,12 @@ function getHeadersItems(headers?: HttpHeaders): KeyValueItem[] {
|
|
|
29
29
|
|
|
30
30
|
export const HeadersTab = ({ selectedRequest }: HeadersTabProps) => {
|
|
31
31
|
const requestBody = selectedRequest.request.body;
|
|
32
|
+
const sourceLabel =
|
|
33
|
+
selectedRequest.source === 'nitro'
|
|
34
|
+
? 'Nitro'
|
|
35
|
+
: selectedRequest.source === 'builtin'
|
|
36
|
+
? 'Built-in'
|
|
37
|
+
: null;
|
|
32
38
|
|
|
33
39
|
const generalItems: KeyValueItem[] = useMemo(
|
|
34
40
|
() => [
|
|
@@ -55,18 +61,26 @@ export const HeadersTab = ({ selectedRequest }: HeadersTabProps) => {
|
|
|
55
61
|
},
|
|
56
62
|
]
|
|
57
63
|
: []),
|
|
64
|
+
...(sourceLabel
|
|
65
|
+
? [
|
|
66
|
+
{
|
|
67
|
+
key: 'Source',
|
|
68
|
+
value: sourceLabel,
|
|
69
|
+
},
|
|
70
|
+
]
|
|
71
|
+
: []),
|
|
58
72
|
],
|
|
59
|
-
[selectedRequest]
|
|
73
|
+
[requestBody, selectedRequest, sourceLabel],
|
|
60
74
|
);
|
|
61
75
|
|
|
62
76
|
const responseHeadersItems = useMemo(
|
|
63
77
|
() => getHeadersItems(selectedRequest.response?.headers),
|
|
64
|
-
[selectedRequest]
|
|
78
|
+
[selectedRequest],
|
|
65
79
|
);
|
|
66
80
|
|
|
67
81
|
const requestHeadersItems = useMemo(
|
|
68
82
|
() => getHeadersItems(selectedRequest.request.headers),
|
|
69
|
-
[selectedRequest]
|
|
83
|
+
[selectedRequest],
|
|
70
84
|
);
|
|
71
85
|
|
|
72
86
|
return (
|
|
@@ -13,6 +13,7 @@ import { Pencil } from 'lucide-react';
|
|
|
13
13
|
|
|
14
14
|
export type ResponseTabProps = {
|
|
15
15
|
selectedRequest: HttpNetworkEntry;
|
|
16
|
+
supportsOverrides?: boolean;
|
|
16
17
|
onRequestResponseBody: (requestId: string) => void;
|
|
17
18
|
};
|
|
18
19
|
|
|
@@ -34,6 +35,7 @@ const RenderResponseBodySection = ({
|
|
|
34
35
|
|
|
35
36
|
export const ResponseTab = ({
|
|
36
37
|
selectedRequest,
|
|
38
|
+
supportsOverrides = true,
|
|
37
39
|
onRequestResponseBody,
|
|
38
40
|
}: ResponseTabProps) => {
|
|
39
41
|
const onRequestResponseBodyRef = useRef(onRequestResponseBody);
|
|
@@ -81,7 +83,7 @@ export const ResponseTab = ({
|
|
|
81
83
|
/>
|
|
82
84
|
);
|
|
83
85
|
|
|
84
|
-
const overrideAction = (
|
|
86
|
+
const overrideAction = supportsOverrides ? (
|
|
85
87
|
<Button
|
|
86
88
|
variant="ghost"
|
|
87
89
|
size="xs"
|
|
@@ -96,9 +98,9 @@ export const ResponseTab = ({
|
|
|
96
98
|
<Pencil className="h-2 w-2" />
|
|
97
99
|
Override
|
|
98
100
|
</Button>
|
|
99
|
-
);
|
|
101
|
+
) : null;
|
|
100
102
|
|
|
101
|
-
if (initialOverride !== undefined) {
|
|
103
|
+
if (supportsOverrides && initialOverride !== undefined) {
|
|
102
104
|
return (
|
|
103
105
|
<OverrideResponse
|
|
104
106
|
selectedRequest={selectedRequest}
|
package/tsconfig.json
CHANGED
|
@@ -11,12 +11,15 @@
|
|
|
11
11
|
"noFallthroughCasesInSwitch": true,
|
|
12
12
|
"module": "ESNext",
|
|
13
13
|
"moduleResolution": "bundler",
|
|
14
|
+
"paths": {
|
|
15
|
+
"@rozenite/agent-shared": ["../agent-shared/src/index.ts"]
|
|
16
|
+
},
|
|
14
17
|
"resolveJsonModule": true,
|
|
15
18
|
"isolatedModules": true,
|
|
16
19
|
"noEmit": true,
|
|
17
20
|
"jsx": "react-jsx"
|
|
18
21
|
},
|
|
19
|
-
"include": ["src/**/*", "react-native.ts", "rozenite.config.ts"],
|
|
22
|
+
"include": ["src/**/*", "react-native.ts", "sdk.ts", "rozenite.config.ts"],
|
|
20
23
|
"exclude": ["node_modules", "dist", "build"],
|
|
21
24
|
"references": [
|
|
22
25
|
{
|
package/vite.config.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
/// <reference types='vitest' />
|
|
2
|
+
import { resolve } from 'node:path';
|
|
2
3
|
import { defineConfig } from 'vite';
|
|
3
4
|
import { rozenitePlugin } from '@rozenite/vite-plugin';
|
|
4
5
|
|
|
5
6
|
export default defineConfig({
|
|
6
7
|
root: __dirname,
|
|
7
8
|
plugins: [rozenitePlugin()],
|
|
9
|
+
test: {
|
|
10
|
+
passWithNoTests: true,
|
|
11
|
+
alias: {
|
|
12
|
+
'@rozenite/agent-shared': resolve(__dirname, '../agent-shared/src/index.ts'),
|
|
13
|
+
},
|
|
14
|
+
},
|
|
8
15
|
base: './',
|
|
9
16
|
build: {
|
|
10
17
|
outDir: './dist',
|