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