@buoy-gg/network 1.7.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 (67) hide show
  1. package/README.md +381 -0
  2. package/lib/commonjs/index.js +34 -0
  3. package/lib/commonjs/network/components/NetworkCopySettingsView.js +867 -0
  4. package/lib/commonjs/network/components/NetworkEventDetailView.js +837 -0
  5. package/lib/commonjs/network/components/NetworkEventItemCompact.js +323 -0
  6. package/lib/commonjs/network/components/NetworkFilterViewV3.js +297 -0
  7. package/lib/commonjs/network/components/NetworkModal.js +937 -0
  8. package/lib/commonjs/network/hooks/useNetworkEvents.js +320 -0
  9. package/lib/commonjs/network/hooks/useTickEveryMinute.js +34 -0
  10. package/lib/commonjs/network/index.js +102 -0
  11. package/lib/commonjs/network/types/index.js +1 -0
  12. package/lib/commonjs/network/utils/extractOperationName.js +80 -0
  13. package/lib/commonjs/network/utils/formatGraphQLVariables.js +219 -0
  14. package/lib/commonjs/network/utils/formatting.js +30 -0
  15. package/lib/commonjs/network/utils/networkEventStore.js +269 -0
  16. package/lib/commonjs/network/utils/networkListener.js +801 -0
  17. package/lib/commonjs/package.json +1 -0
  18. package/lib/commonjs/preset.js +83 -0
  19. package/lib/module/index.js +7 -0
  20. package/lib/module/network/components/NetworkCopySettingsView.js +862 -0
  21. package/lib/module/network/components/NetworkEventDetailView.js +834 -0
  22. package/lib/module/network/components/NetworkEventItemCompact.js +320 -0
  23. package/lib/module/network/components/NetworkFilterViewV3.js +293 -0
  24. package/lib/module/network/components/NetworkModal.js +933 -0
  25. package/lib/module/network/hooks/useNetworkEvents.js +316 -0
  26. package/lib/module/network/hooks/useTickEveryMinute.js +29 -0
  27. package/lib/module/network/index.js +20 -0
  28. package/lib/module/network/types/index.js +1 -0
  29. package/lib/module/network/utils/extractOperationName.js +76 -0
  30. package/lib/module/network/utils/formatGraphQLVariables.js +213 -0
  31. package/lib/module/network/utils/formatting.js +9 -0
  32. package/lib/module/network/utils/networkEventStore.js +265 -0
  33. package/lib/module/network/utils/networkListener.js +791 -0
  34. package/lib/module/preset.js +79 -0
  35. package/lib/typescript/index.d.ts +3 -0
  36. package/lib/typescript/index.d.ts.map +1 -0
  37. package/lib/typescript/network/components/NetworkCopySettingsView.d.ts +26 -0
  38. package/lib/typescript/network/components/NetworkCopySettingsView.d.ts.map +1 -0
  39. package/lib/typescript/network/components/NetworkEventDetailView.d.ts +13 -0
  40. package/lib/typescript/network/components/NetworkEventDetailView.d.ts.map +1 -0
  41. package/lib/typescript/network/components/NetworkEventItemCompact.d.ts +12 -0
  42. package/lib/typescript/network/components/NetworkEventItemCompact.d.ts.map +1 -0
  43. package/lib/typescript/network/components/NetworkFilterViewV3.d.ts +22 -0
  44. package/lib/typescript/network/components/NetworkFilterViewV3.d.ts.map +1 -0
  45. package/lib/typescript/network/components/NetworkModal.d.ts +14 -0
  46. package/lib/typescript/network/components/NetworkModal.d.ts.map +1 -0
  47. package/lib/typescript/network/hooks/useNetworkEvents.d.ts +72 -0
  48. package/lib/typescript/network/hooks/useNetworkEvents.d.ts.map +1 -0
  49. package/lib/typescript/network/hooks/useTickEveryMinute.d.ts +9 -0
  50. package/lib/typescript/network/hooks/useTickEveryMinute.d.ts.map +1 -0
  51. package/lib/typescript/network/index.d.ts +12 -0
  52. package/lib/typescript/network/index.d.ts.map +1 -0
  53. package/lib/typescript/network/types/index.d.ts +88 -0
  54. package/lib/typescript/network/types/index.d.ts.map +1 -0
  55. package/lib/typescript/network/utils/extractOperationName.d.ts +41 -0
  56. package/lib/typescript/network/utils/extractOperationName.d.ts.map +1 -0
  57. package/lib/typescript/network/utils/formatGraphQLVariables.d.ts +79 -0
  58. package/lib/typescript/network/utils/formatGraphQLVariables.d.ts.map +1 -0
  59. package/lib/typescript/network/utils/formatting.d.ts +6 -0
  60. package/lib/typescript/network/utils/formatting.d.ts.map +1 -0
  61. package/lib/typescript/network/utils/networkEventStore.d.ts +81 -0
  62. package/lib/typescript/network/utils/networkEventStore.d.ts.map +1 -0
  63. package/lib/typescript/network/utils/networkListener.d.ts +191 -0
  64. package/lib/typescript/network/utils/networkListener.d.ts.map +1 -0
  65. package/lib/typescript/preset.d.ts +76 -0
  66. package/lib/typescript/preset.d.ts.map +1 -0
  67. package/package.json +69 -0
@@ -0,0 +1,837 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.NetworkEventDetailView = NetworkEventDetailView;
7
+ var _react = require("react");
8
+ var _reactNative = require("react-native");
9
+ var _sharedUi = require("@buoy-gg/shared-ui");
10
+ var _formatting = require("../utils/formatting");
11
+ var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
12
+ var _formatGraphQLVariables = require("../utils/formatGraphQLVariables");
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+ // Component for collapsible sections matching Sentry style
15
+ const CollapsibleSection = ({
16
+ title,
17
+ icon,
18
+ children,
19
+ defaultOpen = false
20
+ }) => {
21
+ const [isOpen, setIsOpen] = (0, _react.useState)(defaultOpen);
22
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
23
+ style: styles.collapsibleSection,
24
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
25
+ style: styles.collapsibleHeader,
26
+ onPress: () => setIsOpen(!isOpen),
27
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
28
+ style: styles.collapsibleTitle,
29
+ children: [icon, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
30
+ style: styles.collapsibleTitleText,
31
+ children: title
32
+ })]
33
+ }), isOpen ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronUp, {
34
+ size: 16,
35
+ color: _sharedUi.macOSColors.text.secondary
36
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronDown, {
37
+ size: 16,
38
+ color: _sharedUi.macOSColors.text.secondary
39
+ })]
40
+ }), isOpen ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
41
+ style: styles.collapsibleContent,
42
+ children: children
43
+ }) : null]
44
+ });
45
+ };
46
+
47
+ // URL breakdown component matching Sentry style
48
+ const UrlBreakdown = ({
49
+ url,
50
+ requestData,
51
+ operationName,
52
+ graphqlVariables,
53
+ requestClient,
54
+ isPro = false,
55
+ onUpgradePress
56
+ }) => {
57
+ const parseUrl = urlString => {
58
+ try {
59
+ const urlObj = new URL(urlString);
60
+ const protocol = String(urlObj.protocol || "");
61
+ const host = String(urlObj.host || "");
62
+ const isSecure = protocol === "https:";
63
+ let pathname = String(urlObj.pathname || "");
64
+
65
+ // If this is a GraphQL request with operation name, format with arrow notation
66
+ // Matches React Query pattern: "GetPokemon › Sandshrew"
67
+ if (requestClient === "graphql" && operationName) {
68
+ const graphqlDisplay = (0, _formatGraphQLVariables.formatGraphQLDisplay)(operationName, graphqlVariables);
69
+ pathname = `${pathname} (${graphqlDisplay})`;
70
+ } else if (operationName) {
71
+ // For non-GraphQL requests with operation names (e.g., gRPC)
72
+ pathname = `${pathname} (${operationName})`;
73
+ }
74
+
75
+ // Parse query parameters
76
+ const params = {};
77
+ const searchParams = urlObj.searchParams;
78
+ if (searchParams && typeof searchParams.forEach === "function") {
79
+ searchParams.forEach((value, key) => {
80
+ params[key] = value;
81
+ });
82
+ }
83
+ return {
84
+ protocol: protocol.replace(":", ""),
85
+ host,
86
+ pathname,
87
+ params: Object.keys(params).length > 0 ? params : null,
88
+ isSecure
89
+ };
90
+ } catch {
91
+ return {
92
+ protocol: "",
93
+ host: url,
94
+ pathname: "",
95
+ params: null,
96
+ isSecure: false
97
+ };
98
+ }
99
+ };
100
+ const urlParts = parseUrl(url);
101
+ const [showParams, setShowParams] = (0, _react.useState)(false);
102
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
103
+ style: styles.urlBreakdown,
104
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
105
+ style: styles.urlRow,
106
+ children: [urlParts.isSecure ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Lock, {
107
+ size: 12,
108
+ color: _sharedUi.macOSColors.semantic.success
109
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Unlock, {
110
+ size: 12,
111
+ color: _sharedUi.macOSColors.semantic.warning
112
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
113
+ style: styles.urlDomain,
114
+ children: urlParts.host
115
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
116
+ style: styles.urlProtocol,
117
+ children: ["(", urlParts.protocol.toUpperCase(), ")"]
118
+ }), isPro ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.InlineCopyButton, {
119
+ value: url,
120
+ buttonStyle: styles.copyButton
121
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
122
+ style: styles.copyButton,
123
+ onPress: onUpgradePress,
124
+ activeOpacity: 0.7,
125
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Copy, {
126
+ size: 14,
127
+ color: _sharedUi.macOSColors.text.secondary
128
+ })
129
+ })]
130
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
131
+ style: styles.urlPathRow,
132
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
133
+ style: styles.urlPath,
134
+ numberOfLines: 2,
135
+ children: [urlParts.pathname, urlParts.params ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
136
+ style: styles.urlQueryString,
137
+ children: ["?", new URLSearchParams(urlParts.params).toString()]
138
+ }) : null]
139
+ })
140
+ }), urlParts.params ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
141
+ style: styles.queryParamsCollapsible,
142
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
143
+ style: styles.queryParamsToggle,
144
+ onPress: () => setShowParams(!showParams),
145
+ activeOpacity: 0.7,
146
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
147
+ style: styles.queryParamsToggleText,
148
+ children: "Query Parameters"
149
+ }), showParams ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronUp, {
150
+ size: 14,
151
+ color: _sharedUi.macOSColors.text.secondary
152
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronDown, {
153
+ size: 14,
154
+ color: _sharedUi.macOSColors.text.secondary
155
+ })]
156
+ }), showParams ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.DataViewer, {
157
+ title: "",
158
+ data: urlParts.params,
159
+ showTypeFilter: false
160
+ }) : null]
161
+ }) : null]
162
+ });
163
+ };
164
+
165
+ /**
166
+ * Detailed inspector rendering request/response metadata for a single network event. Designed to
167
+ * mimic Sentry’s layout with collapsible sections, diff views, and quick copy affordances.
168
+ */
169
+ function NetworkEventDetailView({
170
+ event,
171
+ ignoredPatterns = new Set(),
172
+ onTogglePattern = () => {}
173
+ }) {
174
+ const status = event.status ? (0, _formatting.formatHttpStatus)(event.status) : null;
175
+ const isPending = !event.status && !event.error;
176
+
177
+ // Check Pro status for copy features
178
+ const {
179
+ isPro
180
+ } = (0, _sharedUi.useFeatureGate)();
181
+ const [showUpgradeModal, setShowUpgradeModal] = (0, _react.useState)(false);
182
+
183
+ // Generate full request details for copying
184
+ const getFullRequestDetails = () => {
185
+ const requestDetails = {
186
+ method: event.method,
187
+ url: event.url,
188
+ status: event.status,
189
+ statusText: event.statusText,
190
+ timestamp: new Date(event.timestamp).toISOString(),
191
+ duration: event.duration ? `${event.duration}ms` : "N/A",
192
+ requestHeaders: event.requestHeaders,
193
+ requestData: event.requestData,
194
+ responseHeaders: event.responseHeaders,
195
+ responseData: event.responseData,
196
+ requestSize: event.requestSize ? (0, _formatting.formatBytes)(event.requestSize) : "N/A",
197
+ responseSize: event.responseSize ? (0, _formatting.formatBytes)(event.responseSize) : "N/A",
198
+ error: event.error,
199
+ client: event.requestClient
200
+ };
201
+ return `# Network Request Details
202
+
203
+ ## Request
204
+ - **Method:** ${requestDetails.method}
205
+ - **URL:** ${requestDetails.url}
206
+ - **Client:** ${requestDetails.client || "N/A"}
207
+ - **Timestamp:** ${requestDetails.timestamp}
208
+
209
+ ## Response
210
+ - **Status:** ${requestDetails.status || "Pending"}${requestDetails.statusText ? ` (${requestDetails.statusText})` : ""}
211
+ - **Duration:** ${requestDetails.duration}
212
+ - **Request Size:** ${requestDetails.requestSize}
213
+ - **Response Size:** ${requestDetails.responseSize}
214
+ ${requestDetails.error ? `- **Error:** ${requestDetails.error}` : ""}
215
+
216
+ ## Request Headers
217
+ \`\`\`json
218
+ ${JSON.stringify(requestDetails.requestHeaders, null, 2)}
219
+ \`\`\`
220
+
221
+ ## Request Data
222
+ \`\`\`json
223
+ ${JSON.stringify(requestDetails.requestData, null, 2)}
224
+ \`\`\`
225
+
226
+ ## Response Headers
227
+ \`\`\`json
228
+ ${JSON.stringify(requestDetails.responseHeaders, null, 2)}
229
+ \`\`\`
230
+
231
+ ## Response Data
232
+ \`\`\`json
233
+ ${JSON.stringify(requestDetails.responseData, null, 2)}
234
+ \`\`\`
235
+ `;
236
+ };
237
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
238
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
239
+ style: styles.container,
240
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
241
+ style: styles.requestDetailsSection,
242
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
243
+ style: styles.httpHeader,
244
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
245
+ style: styles.httpMethodBadge,
246
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
247
+ style: styles.httpMethod,
248
+ children: event.method
249
+ })
250
+ }), event.status ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
251
+ style: [styles.httpStatusBadge, {
252
+ backgroundColor: `${status?.color}20`
253
+ }],
254
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
255
+ style: [styles.httpStatusText, {
256
+ color: status?.color
257
+ }],
258
+ children: [status?.text, " ", status?.meaning]
259
+ })
260
+ }) : isPending ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
261
+ style: styles.pendingBadge,
262
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Clock, {
263
+ size: 10,
264
+ color: _sharedUi.macOSColors.semantic.warning
265
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
266
+ style: styles.pendingBadgeText,
267
+ children: "Pending"
268
+ })]
269
+ }) : null, event.duration ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
270
+ style: styles.httpDuration,
271
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Clock, {
272
+ size: 10,
273
+ color: _sharedUi.macOSColors.text.muted
274
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
275
+ style: styles.httpDurationText,
276
+ children: (0, _formatting.formatDuration)(event.duration)
277
+ })]
278
+ }) : null, isPro ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.InlineCopyButton, {
279
+ value: getFullRequestDetails(),
280
+ buttonStyle: styles.copyFullButton
281
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
282
+ style: styles.copyFullButton,
283
+ onPress: () => setShowUpgradeModal(true),
284
+ activeOpacity: 0.7,
285
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Copy, {
286
+ size: 14,
287
+ color: _sharedUi.macOSColors.text.secondary
288
+ })
289
+ })]
290
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(UrlBreakdown, {
291
+ url: event.url,
292
+ requestData: event.requestData,
293
+ operationName: event.operationName,
294
+ graphqlVariables: event.graphqlVariables,
295
+ requestClient: event.requestClient,
296
+ isPro: isPro,
297
+ onUpgradePress: () => setShowUpgradeModal(true)
298
+ }), event.error ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
299
+ style: styles.errorBox,
300
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AlertCircle, {
301
+ size: 12,
302
+ color: _sharedUi.macOSColors.semantic.error
303
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
304
+ style: styles.errorText,
305
+ children: event.error
306
+ })]
307
+ }) : null]
308
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
309
+ style: styles.timingSection,
310
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
311
+ style: styles.timingRow,
312
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Clock, {
313
+ size: 12,
314
+ color: _sharedUi.macOSColors.text.secondary
315
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
316
+ style: styles.timingLabel,
317
+ children: "Started:"
318
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
319
+ style: styles.timingValue,
320
+ children: (0, _sharedUi.formatRelativeTime)(event.timestamp)
321
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
322
+ style: styles.timingExact,
323
+ children: ["(", new Date(event.timestamp).toLocaleTimeString(), ")"]
324
+ })]
325
+ }), event.requestSize || event.responseSize ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
326
+ style: styles.sizeRow,
327
+ children: [event.requestSize !== undefined ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
328
+ style: styles.sizeItem,
329
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Upload, {
330
+ size: 10,
331
+ color: _sharedUi.macOSColors.semantic.info
332
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
333
+ style: styles.sizeLabel,
334
+ children: "Sent:"
335
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
336
+ style: styles.sizeValue,
337
+ children: (0, _formatting.formatBytes)(event.requestSize)
338
+ })]
339
+ }) : null, event.responseSize !== undefined ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
340
+ style: styles.sizeItem,
341
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Download, {
342
+ size: 10,
343
+ color: _sharedUi.macOSColors.semantic.success
344
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
345
+ style: styles.sizeLabel,
346
+ children: "Received:"
347
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
348
+ style: styles.sizeValue,
349
+ children: (0, _formatting.formatBytes)(event.responseSize)
350
+ })]
351
+ }) : null]
352
+ }) : null]
353
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(CollapsibleSection, {
354
+ title: "Request Headers",
355
+ icon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Upload, {
356
+ size: 14,
357
+ color: _sharedUi.macOSColors.semantic.info
358
+ }),
359
+ defaultOpen: false,
360
+ children: Object.keys(event.requestHeaders).length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
361
+ style: styles.dataViewerContainer,
362
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.DataViewer, {
363
+ title: "",
364
+ data: event.requestHeaders,
365
+ showTypeFilter: true,
366
+ rawMode: true,
367
+ initialExpanded: true,
368
+ disableCopy: !isPro
369
+ })
370
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
371
+ style: styles.emptyText,
372
+ children: "No request headers"
373
+ })
374
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(CollapsibleSection, {
375
+ title: "Response Headers",
376
+ icon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Download, {
377
+ size: 14,
378
+ color: _sharedUi.macOSColors.semantic.success
379
+ }),
380
+ defaultOpen: false,
381
+ children: Object.keys(event.responseHeaders).length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
382
+ style: styles.dataViewerContainer,
383
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.DataViewer, {
384
+ title: "",
385
+ data: event.responseHeaders,
386
+ showTypeFilter: true,
387
+ rawMode: true,
388
+ initialExpanded: true,
389
+ disableCopy: !isPro
390
+ })
391
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
392
+ style: styles.emptyText,
393
+ children: "No response headers yet"
394
+ })
395
+ }), event.requestData ? /*#__PURE__*/(0, _jsxRuntime.jsx)(CollapsibleSection, {
396
+ title: "Request Body",
397
+ icon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.FileJson, {
398
+ size: 14,
399
+ color: _sharedUi.macOSColors.semantic.info
400
+ }),
401
+ defaultOpen: false,
402
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
403
+ style: styles.dataViewerContainer,
404
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.DataViewer, {
405
+ title: "",
406
+ data: event.requestData,
407
+ showTypeFilter: true,
408
+ rawMode: true,
409
+ initialExpanded: true,
410
+ disableCopy: !isPro
411
+ })
412
+ })
413
+ }) : null, event.responseData ? /*#__PURE__*/(0, _jsxRuntime.jsx)(CollapsibleSection, {
414
+ title: "Response Body",
415
+ icon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.FileJson, {
416
+ size: 14,
417
+ color: _sharedUi.macOSColors.semantic.success
418
+ }),
419
+ defaultOpen: false,
420
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
421
+ style: styles.dataViewerContainer,
422
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.DataViewer, {
423
+ title: "",
424
+ data: event.responseData,
425
+ showTypeFilter: true,
426
+ rawMode: true,
427
+ initialExpanded: true,
428
+ disableCopy: !isPro
429
+ })
430
+ })
431
+ }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(CollapsibleSection, {
432
+ title: "Filter Options",
433
+ icon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Filter, {
434
+ size: 14,
435
+ color: _sharedUi.macOSColors.semantic.warning
436
+ }),
437
+ defaultOpen: false,
438
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
439
+ style: styles.filterOptionsContainer,
440
+ children: (() => {
441
+ let domain = "";
442
+ let urlPath = "";
443
+ try {
444
+ const url = new URL(event.url);
445
+ domain = url.hostname;
446
+ urlPath = url.pathname;
447
+ } catch {
448
+ urlPath = event.url;
449
+ }
450
+ const isDomainIgnored = ignoredPatterns.has(domain);
451
+ const isUrlIgnored = ignoredPatterns.has(urlPath);
452
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
453
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
454
+ style: [styles.filterOption, isDomainIgnored && styles.filterOptionActive],
455
+ onPress: () => domain && onTogglePattern(domain),
456
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
457
+ style: styles.filterOptionLeft,
458
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Globe, {
459
+ size: 16,
460
+ color: isDomainIgnored ? _sharedUi.macOSColors.semantic.warning : _sharedUi.macOSColors.text.muted
461
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
462
+ style: styles.filterOptionContent,
463
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
464
+ style: styles.filterOptionLabel,
465
+ children: "Ignore Domain"
466
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
467
+ style: styles.filterOptionValue,
468
+ children: domain || "N/A"
469
+ })]
470
+ })]
471
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
472
+ style: [styles.filterToggle, isDomainIgnored && styles.filterToggleActive],
473
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
474
+ style: [styles.filterToggleText, isDomainIgnored && styles.filterToggleTextActive],
475
+ children: isDomainIgnored ? "IGNORED" : "IGNORE"
476
+ })
477
+ })]
478
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
479
+ style: [styles.filterOption, isUrlIgnored && styles.filterOptionActive],
480
+ onPress: () => urlPath && onTogglePattern(urlPath),
481
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
482
+ style: styles.filterOptionLeft,
483
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Link, {
484
+ size: 16,
485
+ color: isUrlIgnored ? _sharedUi.macOSColors.semantic.warning : _sharedUi.macOSColors.text.muted
486
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
487
+ style: styles.filterOptionContent,
488
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
489
+ style: styles.filterOptionLabel,
490
+ children: "Ignore URL Pattern"
491
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
492
+ style: styles.filterOptionValue,
493
+ numberOfLines: 1,
494
+ children: urlPath || "N/A"
495
+ })]
496
+ })]
497
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
498
+ style: [styles.filterToggle, isUrlIgnored && styles.filterToggleActive],
499
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
500
+ style: [styles.filterToggleText, isUrlIgnored && styles.filterToggleTextActive],
501
+ children: isUrlIgnored ? "IGNORED" : "IGNORE"
502
+ })
503
+ })]
504
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
505
+ style: styles.filterInfoBox,
506
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
507
+ style: styles.filterInfoText,
508
+ children: "Ignored requests will be hidden from the network list. You can manage filters in the Filters tab."
509
+ })
510
+ })]
511
+ });
512
+ })()
513
+ })
514
+ })]
515
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.UpgradeModal, {
516
+ visible: showUpgradeModal,
517
+ onClose: () => setShowUpgradeModal(false),
518
+ featureName: "Copy Request Details",
519
+ description: "Copy network request details to share or debug issues.",
520
+ benefits: ["Copy full request details including headers and body", "Export to JSON, Markdown, or plain text", "Share request data with teammates", "Feed data to AI assistants for debugging"]
521
+ })]
522
+ });
523
+ }
524
+ const styles = _reactNative.StyleSheet.create({
525
+ container: {
526
+ flex: 1,
527
+ backgroundColor: _sharedUi.macOSColors.background.base
528
+ },
529
+ // Request details section - always visible
530
+ requestDetailsSection: {
531
+ marginHorizontal: 12,
532
+ marginTop: 12,
533
+ backgroundColor: _sharedUi.macOSColors.background.card,
534
+ borderRadius: 8,
535
+ borderWidth: 1,
536
+ borderColor: _sharedUi.macOSColors.border.default,
537
+ padding: 12
538
+ },
539
+ httpHeader: {
540
+ flexDirection: "row",
541
+ alignItems: "center",
542
+ gap: 8,
543
+ marginBottom: 12,
544
+ flexWrap: "nowrap"
545
+ },
546
+ httpMethodBadge: {
547
+ backgroundColor: _sharedUi.macOSColors.semantic.infoBackground,
548
+ paddingHorizontal: 8,
549
+ paddingVertical: 4,
550
+ borderRadius: 4
551
+ },
552
+ httpMethod: {
553
+ color: _sharedUi.macOSColors.semantic.info,
554
+ fontSize: 11,
555
+ fontWeight: "700",
556
+ letterSpacing: 0.5
557
+ },
558
+ httpStatusBadge: {
559
+ paddingHorizontal: 8,
560
+ paddingVertical: 4,
561
+ borderRadius: 4
562
+ },
563
+ httpStatusText: {
564
+ fontSize: 11,
565
+ fontWeight: "600"
566
+ },
567
+ pendingBadge: {
568
+ flexDirection: "row",
569
+ alignItems: "center",
570
+ gap: 4,
571
+ backgroundColor: _sharedUi.macOSColors.semantic.warningBackground,
572
+ paddingHorizontal: 8,
573
+ paddingVertical: 4,
574
+ borderRadius: 4
575
+ },
576
+ pendingBadgeText: {
577
+ color: _sharedUi.macOSColors.semantic.warning,
578
+ fontSize: 11,
579
+ fontWeight: "600"
580
+ },
581
+ httpDuration: {
582
+ flexDirection: "row",
583
+ alignItems: "center",
584
+ gap: 4
585
+ },
586
+ httpDurationText: {
587
+ color: _sharedUi.macOSColors.text.secondary,
588
+ fontSize: 11
589
+ },
590
+ copyFullButton: {
591
+ marginLeft: "auto",
592
+ flexShrink: 0,
593
+ padding: 4
594
+ },
595
+ // URL breakdown styles
596
+ urlBreakdown: {
597
+ backgroundColor: _sharedUi.macOSColors.background.input,
598
+ borderRadius: 4,
599
+ padding: 8
600
+ },
601
+ urlRow: {
602
+ flexDirection: "row",
603
+ alignItems: "center",
604
+ gap: 6,
605
+ marginBottom: 4
606
+ },
607
+ urlDomain: {
608
+ color: _sharedUi.macOSColors.text.primary,
609
+ fontSize: 12,
610
+ fontWeight: "600",
611
+ flex: 1
612
+ },
613
+ urlProtocol: {
614
+ color: _sharedUi.macOSColors.text.muted,
615
+ fontSize: 10
616
+ },
617
+ copyButton: {
618
+ padding: 4
619
+ },
620
+ urlPathRow: {
621
+ paddingLeft: 18
622
+ },
623
+ urlPath: {
624
+ color: _sharedUi.macOSColors.text.secondary,
625
+ fontSize: 11,
626
+ fontFamily: "monospace"
627
+ },
628
+ urlQueryString: {
629
+ color: _sharedUi.macOSColors.semantic.info,
630
+ fontSize: 11,
631
+ fontFamily: "monospace"
632
+ },
633
+ // Query Parameters - Collapsible section
634
+ queryParamsCollapsible: {
635
+ marginTop: 8
636
+ },
637
+ queryParamsToggle: {
638
+ flexDirection: "row",
639
+ alignItems: "center",
640
+ justifyContent: "space-between",
641
+ paddingHorizontal: 12,
642
+ paddingVertical: 10,
643
+ backgroundColor: _sharedUi.macOSColors.background.hover,
644
+ borderRadius: 8,
645
+ borderWidth: 1,
646
+ borderColor: _sharedUi.macOSColors.border.default,
647
+ marginBottom: 8
648
+ },
649
+ queryParamsToggleText: {
650
+ color: _sharedUi.macOSColors.text.primary,
651
+ fontSize: 12,
652
+ fontWeight: "600",
653
+ letterSpacing: 0.3
654
+ },
655
+ // Timing section - always visible
656
+ timingSection: {
657
+ marginHorizontal: 12,
658
+ marginTop: 8,
659
+ backgroundColor: _sharedUi.macOSColors.background.card,
660
+ borderRadius: 8,
661
+ borderWidth: 1,
662
+ borderColor: _sharedUi.macOSColors.border.default,
663
+ padding: 12
664
+ },
665
+ timingRow: {
666
+ flexDirection: "row",
667
+ alignItems: "center",
668
+ gap: 6
669
+ },
670
+ timingLabel: {
671
+ color: _sharedUi.macOSColors.text.secondary,
672
+ fontSize: 11
673
+ },
674
+ timingValue: {
675
+ color: _sharedUi.macOSColors.text.primary,
676
+ fontSize: 11,
677
+ fontWeight: "600"
678
+ },
679
+ timingExact: {
680
+ color: _sharedUi.macOSColors.text.muted,
681
+ fontSize: 10,
682
+ marginLeft: 4
683
+ },
684
+ sizeRow: {
685
+ flexDirection: "row",
686
+ gap: 16,
687
+ marginTop: 8,
688
+ paddingTop: 8,
689
+ borderTopWidth: 1,
690
+ borderTopColor: _sharedUi.macOSColors.border.default
691
+ },
692
+ sizeItem: {
693
+ flexDirection: "row",
694
+ alignItems: "center",
695
+ gap: 4
696
+ },
697
+ sizeLabel: {
698
+ color: _sharedUi.macOSColors.text.muted,
699
+ fontSize: 10
700
+ },
701
+ sizeValue: {
702
+ color: _sharedUi.macOSColors.semantic.info,
703
+ fontSize: 10,
704
+ fontFamily: "monospace",
705
+ fontWeight: "600"
706
+ },
707
+ // Collapsible section styles
708
+ collapsibleSection: {
709
+ marginHorizontal: 12,
710
+ marginTop: 8,
711
+ backgroundColor: _sharedUi.macOSColors.background.card,
712
+ borderRadius: 8,
713
+ borderWidth: 1,
714
+ borderColor: _sharedUi.macOSColors.border.default,
715
+ overflow: "hidden"
716
+ },
717
+ collapsibleHeader: {
718
+ flexDirection: "row",
719
+ alignItems: "center",
720
+ justifyContent: "space-between",
721
+ padding: 12,
722
+ backgroundColor: _sharedUi.macOSColors.background.hover
723
+ },
724
+ collapsibleTitle: {
725
+ flexDirection: "row",
726
+ alignItems: "center",
727
+ gap: 8
728
+ },
729
+ collapsibleTitleText: {
730
+ color: _sharedUi.macOSColors.text.primary,
731
+ fontSize: 13,
732
+ fontWeight: "600"
733
+ },
734
+ collapsibleContent: {
735
+ padding: 12
736
+ },
737
+ // Data viewer container
738
+ dataViewerContainer: {
739
+ marginTop: -12,
740
+ marginHorizontal: -12,
741
+ marginBottom: -12
742
+ },
743
+ // Error box
744
+ errorBox: {
745
+ flexDirection: "row",
746
+ alignItems: "center",
747
+ gap: 6,
748
+ backgroundColor: _sharedUi.macOSColors.semantic.errorBackground,
749
+ padding: 8,
750
+ borderRadius: 4,
751
+ marginTop: 8
752
+ },
753
+ errorText: {
754
+ color: _sharedUi.macOSColors.semantic.error,
755
+ fontSize: 11,
756
+ flex: 1
757
+ },
758
+ // Empty state
759
+ emptyText: {
760
+ color: _sharedUi.macOSColors.text.muted,
761
+ fontSize: 12,
762
+ fontStyle: "italic",
763
+ textAlign: "center"
764
+ },
765
+ // Filter options styles
766
+ filterOptionsContainer: {
767
+ gap: 12
768
+ },
769
+ filterOption: {
770
+ flexDirection: "row",
771
+ alignItems: "center",
772
+ justifyContent: "space-between",
773
+ backgroundColor: _sharedUi.macOSColors.background.hover,
774
+ borderRadius: 8,
775
+ padding: 12,
776
+ borderWidth: 1,
777
+ borderColor: _sharedUi.macOSColors.border.default
778
+ },
779
+ filterOptionActive: {
780
+ backgroundColor: _sharedUi.macOSColors.semantic.warningBackground,
781
+ borderColor: _sharedUi.macOSColors.semantic.warning + "33"
782
+ },
783
+ filterOptionLeft: {
784
+ flexDirection: "row",
785
+ alignItems: "center",
786
+ gap: 12,
787
+ flex: 1
788
+ },
789
+ filterOptionContent: {
790
+ flex: 1
791
+ },
792
+ filterOptionLabel: {
793
+ color: _sharedUi.macOSColors.text.secondary,
794
+ fontSize: 11,
795
+ marginBottom: 2,
796
+ textTransform: "uppercase",
797
+ letterSpacing: 0.5
798
+ },
799
+ filterOptionValue: {
800
+ color: _sharedUi.macOSColors.text.primary,
801
+ fontSize: 13,
802
+ fontFamily: "monospace"
803
+ },
804
+ filterToggle: {
805
+ paddingHorizontal: 10,
806
+ paddingVertical: 6,
807
+ borderRadius: 4,
808
+ backgroundColor: _sharedUi.macOSColors.background.input,
809
+ borderWidth: 1,
810
+ borderColor: _sharedUi.macOSColors.border.default
811
+ },
812
+ filterToggleActive: {
813
+ backgroundColor: _sharedUi.macOSColors.semantic.warning + "26",
814
+ borderColor: _sharedUi.macOSColors.semantic.warning + "4D"
815
+ },
816
+ filterToggleText: {
817
+ fontSize: 10,
818
+ fontWeight: "600",
819
+ color: _sharedUi.macOSColors.text.muted,
820
+ letterSpacing: 0.5
821
+ },
822
+ filterToggleTextActive: {
823
+ color: _sharedUi.macOSColors.semantic.warning
824
+ },
825
+ filterInfoBox: {
826
+ backgroundColor: _sharedUi.macOSColors.semantic.infoBackground,
827
+ borderRadius: 6,
828
+ padding: 10,
829
+ borderWidth: 1,
830
+ borderColor: _sharedUi.macOSColors.semantic.info + "33"
831
+ },
832
+ filterInfoText: {
833
+ color: _sharedUi.macOSColors.text.secondary,
834
+ fontSize: 11,
835
+ lineHeight: 16
836
+ }
837
+ });