@buoy-gg/network 7.0.40 → 7.0.42

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 (275) hide show
  1. package/README.md +11 -79
  2. package/lib/commonjs/index.js +1 -325
  3. package/lib/commonjs/index.web.js +1 -420
  4. package/lib/commonjs/network/components/DataViewer.web.js +1 -879
  5. package/lib/commonjs/network/components/NetworkCopyScreen.web.js +1 -48
  6. package/lib/commonjs/network/components/NetworkCopySettingsView.js +27 -755
  7. package/lib/commonjs/network/components/NetworkCopySettingsView.web.js +14 -1242
  8. package/lib/commonjs/network/components/NetworkDetailScreen.web.js +1 -101
  9. package/lib/commonjs/network/components/NetworkDetailStepper.js +1 -108
  10. package/lib/commonjs/network/components/NetworkDetailStepper.web.js +1 -298
  11. package/lib/commonjs/network/components/NetworkEventDetailView.js +15 -1130
  12. package/lib/commonjs/network/components/NetworkEventDetailView.web.js +15 -1484
  13. package/lib/commonjs/network/components/NetworkEventItemCompact.js +2 -401
  14. package/lib/commonjs/network/components/NetworkEventItemCompact.web.js +2 -820
  15. package/lib/commonjs/network/components/NetworkFilterScreen.web.js +1 -55
  16. package/lib/commonjs/network/components/NetworkFilterViewV3.js +1 -442
  17. package/lib/commonjs/network/components/NetworkFilterViewV3.web.js +1 -1310
  18. package/lib/commonjs/network/components/NetworkHeaderLive.js +1 -375
  19. package/lib/commonjs/network/components/NetworkHeaderLive.web.js +1 -623
  20. package/lib/commonjs/network/components/NetworkHeaderMenu.js +1 -190
  21. package/lib/commonjs/network/components/NetworkListScreen.js +1 -404
  22. package/lib/commonjs/network/components/NetworkListScreen.web.js +1 -625
  23. package/lib/commonjs/network/components/NetworkModal.js +1 -786
  24. package/lib/commonjs/network/components/NetworkNumberPrompt.js +1 -178
  25. package/lib/commonjs/network/components/NetworkNumberPrompt.web.js +1 -232
  26. package/lib/commonjs/network/components/NetworkOverrideEditor.js +1 -814
  27. package/lib/commonjs/network/components/NetworkOverrideEditor.web.js +1 -942
  28. package/lib/commonjs/network/components/NetworkOverrideHeaderButton.js +1 -107
  29. package/lib/commonjs/network/components/NetworkOverrideHeaderButton.web.js +1 -133
  30. package/lib/commonjs/network/components/NetworkOverridesButton.js +1 -90
  31. package/lib/commonjs/network/components/NetworkOverridesButton.web.js +1 -143
  32. package/lib/commonjs/network/components/NetworkOverridesScreen.js +1 -543
  33. package/lib/commonjs/network/components/NetworkOverridesScreen.web.js +1 -830
  34. package/lib/commonjs/network/components/NetworkSavedScreen.js +1 -226
  35. package/lib/commonjs/network/components/NetworkSavedScreen.web.js +1 -463
  36. package/lib/commonjs/network/components/NetworkUpgradeBanner.js +1 -76
  37. package/lib/commonjs/network/components/response-editor/Explorer.js +1 -973
  38. package/lib/commonjs/network/components/response-editor/Explorer.web.js +1 -1136
  39. package/lib/commonjs/network/components/response-editor/deleteNestedDataByPath.js +1 -56
  40. package/lib/commonjs/network/components/response-editor/editorContext.js +1 -33
  41. package/lib/commonjs/network/components/response-editor/updateNestedDataByPath.js +1 -61
  42. package/lib/commonjs/network/conditions/NetworkConditionsControl.js +1 -235
  43. package/lib/commonjs/network/conditions/NetworkConditionsControl.test.js +1 -136
  44. package/lib/commonjs/network/conditions/NetworkConditionsIcon.js +1 -33
  45. package/lib/commonjs/network/conditions/NetworkFloatingTool.js +1 -310
  46. package/lib/commonjs/network/conditions/NetworkFloatingTool.test.js +1 -219
  47. package/lib/commonjs/network/conditions/store.js +1 -75
  48. package/lib/commonjs/network/conditions/wait.js +1 -43
  49. package/lib/commonjs/network/conditions/xhr.js +1 -110
  50. package/lib/commonjs/network/hooks/useLiveNetworkEvent.js +1 -62
  51. package/lib/commonjs/network/hooks/useNetworkBadgeCounts.js +1 -83
  52. package/lib/commonjs/network/hooks/useNetworkEventList.js +1 -108
  53. package/lib/commonjs/network/hooks/useNetworkEvents.js +1 -318
  54. package/lib/commonjs/network/hooks/useNetworkHasMatches.js +1 -56
  55. package/lib/commonjs/network/hooks/useNetworkSaved.js +1 -38
  56. package/lib/commonjs/network/hooks/useNetworkSelection.js +1 -53
  57. package/lib/commonjs/network/hooks/useOverrideRules.js +1 -36
  58. package/lib/commonjs/network/hooks/useTickEveryMinute.js +1 -21
  59. package/lib/commonjs/network/overrides/applyToFetch.js +1 -80
  60. package/lib/commonjs/network/overrides/applyToXhr.js +2 -453
  61. package/lib/commonjs/network/overrides/engine.js +1 -93
  62. package/lib/commonjs/network/overrides/matchRule.js +1 -81
  63. package/lib/commonjs/network/overrides/overriddenRows.js +1 -0
  64. package/lib/commonjs/network/overrides/overrideRulesStore.js +1 -550
  65. package/lib/commonjs/network/overrides/presets.js +1 -70
  66. package/lib/commonjs/network/overrides/resolveOverride.js +1 -158
  67. package/lib/commonjs/network/overrides/types.js +1 -90
  68. package/lib/commonjs/network/sync/networkBodyResolver.js +1 -39
  69. package/lib/commonjs/network/sync/networkSyncAdapter.js +1 -882
  70. package/lib/commonjs/network/sync/overrideHonesty.release.test.js +1 -36
  71. package/lib/commonjs/network/types/index.js +1 -5
  72. package/lib/commonjs/network/utils/extractOperationName.js +1 -80
  73. package/lib/commonjs/network/utils/filterNetworkEvents.js +1 -96
  74. package/lib/commonjs/network/utils/formatGraphQLVariables.js +1 -219
  75. package/lib/commonjs/network/utils/formatting.js +1 -30
  76. package/lib/commonjs/network/utils/generateCurl.js +2 -71
  77. package/lib/commonjs/network/utils/generateNetworkCopyText.js +37 -166
  78. package/lib/commonjs/network/utils/httpCompletion.js +1 -37
  79. package/lib/commonjs/network/utils/networkEventStore.js +1 -393
  80. package/lib/commonjs/network/utils/networkListener.js +4 -1259
  81. package/lib/commonjs/network/utils/networkSavedStore.js +3 -577
  82. package/lib/commonjs/network/utils/networkSelectionStore.js +1 -193
  83. package/lib/commonjs/network/utils/realNow.js +1 -0
  84. package/lib/commonjs/network/utils/requestId.js +1 -0
  85. package/lib/commonjs/network/utils/resolveRequestUrl.js +1 -0
  86. package/lib/commonjs/network/utils/selectSavedEvents.js +1 -39
  87. package/lib/commonjs/network/utils/startNetworkCapture.js +1 -0
  88. package/lib/commonjs/network/utils/withPinnedFirst.js +1 -32
  89. package/lib/commonjs/preset.js +1 -102
  90. package/lib/module/index.js +1 -103
  91. package/lib/module/index.web.js +1 -82
  92. package/lib/module/network/components/DataViewer.web.js +1 -875
  93. package/lib/module/network/components/NetworkCopyScreen.web.js +1 -44
  94. package/lib/module/network/components/NetworkCopySettingsView.js +27 -750
  95. package/lib/module/network/components/NetworkCopySettingsView.web.js +14 -1237
  96. package/lib/module/network/components/NetworkDetailScreen.web.js +1 -97
  97. package/lib/module/network/components/NetworkDetailStepper.js +1 -104
  98. package/lib/module/network/components/NetworkDetailStepper.web.js +1 -296
  99. package/lib/module/network/components/NetworkEventDetailView.js +15 -1129
  100. package/lib/module/network/components/NetworkEventDetailView.web.js +15 -1482
  101. package/lib/module/network/components/NetworkEventItemCompact.js +2 -398
  102. package/lib/module/network/components/NetworkEventItemCompact.web.js +2 -818
  103. package/lib/module/network/components/NetworkFilterScreen.web.js +1 -51
  104. package/lib/module/network/components/NetworkFilterViewV3.js +1 -438
  105. package/lib/module/network/components/NetworkFilterViewV3.web.js +1 -1306
  106. package/lib/module/network/components/NetworkHeaderLive.js +1 -366
  107. package/lib/module/network/components/NetworkHeaderLive.web.js +1 -617
  108. package/lib/module/network/components/NetworkHeaderMenu.js +1 -184
  109. package/lib/module/network/components/NetworkListScreen.js +1 -400
  110. package/lib/module/network/components/NetworkListScreen.web.js +1 -623
  111. package/lib/module/network/components/NetworkModal.js +1 -781
  112. package/lib/module/network/components/NetworkNumberPrompt.js +1 -174
  113. package/lib/module/network/components/NetworkNumberPrompt.web.js +1 -230
  114. package/lib/module/network/components/NetworkOverrideEditor.js +1 -811
  115. package/lib/module/network/components/NetworkOverrideEditor.web.js +1 -939
  116. package/lib/module/network/components/NetworkOverrideHeaderButton.js +1 -104
  117. package/lib/module/network/components/NetworkOverrideHeaderButton.web.js +1 -131
  118. package/lib/module/network/components/NetworkOverridesButton.js +1 -87
  119. package/lib/module/network/components/NetworkOverridesButton.web.js +1 -141
  120. package/lib/module/network/components/NetworkOverridesScreen.js +1 -539
  121. package/lib/module/network/components/NetworkOverridesScreen.web.js +1 -826
  122. package/lib/module/network/components/NetworkSavedScreen.js +1 -222
  123. package/lib/module/network/components/NetworkSavedScreen.web.js +1 -461
  124. package/lib/module/network/components/NetworkUpgradeBanner.js +1 -72
  125. package/lib/module/network/components/response-editor/Explorer.js +1 -972
  126. package/lib/module/network/components/response-editor/Explorer.web.js +1 -1133
  127. package/lib/module/network/components/response-editor/deleteNestedDataByPath.js +1 -51
  128. package/lib/module/network/components/response-editor/editorContext.js +1 -29
  129. package/lib/module/network/components/response-editor/updateNestedDataByPath.js +1 -56
  130. package/lib/module/network/conditions/NetworkConditionsControl.js +1 -231
  131. package/lib/module/network/conditions/NetworkConditionsControl.test.js +1 -135
  132. package/lib/module/network/conditions/NetworkConditionsIcon.js +1 -29
  133. package/lib/module/network/conditions/NetworkFloatingTool.js +1 -304
  134. package/lib/module/network/conditions/NetworkFloatingTool.test.js +1 -218
  135. package/lib/module/network/conditions/store.js +1 -65
  136. package/lib/module/network/conditions/wait.js +1 -38
  137. package/lib/module/network/conditions/xhr.js +1 -106
  138. package/lib/module/network/hooks/useLiveNetworkEvent.js +1 -58
  139. package/lib/module/network/hooks/useNetworkBadgeCounts.js +1 -79
  140. package/lib/module/network/hooks/useNetworkEventList.js +1 -104
  141. package/lib/module/network/hooks/useNetworkEvents.js +1 -314
  142. package/lib/module/network/hooks/useNetworkHasMatches.js +1 -52
  143. package/lib/module/network/hooks/useNetworkSaved.js +1 -34
  144. package/lib/module/network/hooks/useNetworkSelection.js +1 -46
  145. package/lib/module/network/hooks/useOverrideRules.js +1 -32
  146. package/lib/module/network/hooks/useTickEveryMinute.js +1 -11
  147. package/lib/module/network/overrides/applyToFetch.js +1 -72
  148. package/lib/module/network/overrides/applyToXhr.js +2 -446
  149. package/lib/module/network/overrides/engine.js +1 -85
  150. package/lib/module/network/overrides/matchRule.js +1 -75
  151. package/lib/module/network/overrides/overriddenRows.js +1 -0
  152. package/lib/module/network/overrides/overrideRulesStore.js +1 -547
  153. package/lib/module/network/overrides/presets.js +1 -65
  154. package/lib/module/network/overrides/resolveOverride.js +1 -152
  155. package/lib/module/network/overrides/types.js +1 -86
  156. package/lib/module/network/sync/networkBodyResolver.js +1 -34
  157. package/lib/module/network/sync/networkSyncAdapter.js +1 -880
  158. package/lib/module/network/sync/overrideHonesty.release.test.js +1 -35
  159. package/lib/module/network/types/index.js +1 -3
  160. package/lib/module/network/utils/extractOperationName.js +1 -76
  161. package/lib/module/network/utils/filterNetworkEvents.js +1 -92
  162. package/lib/module/network/utils/formatGraphQLVariables.js +1 -213
  163. package/lib/module/network/utils/formatting.js +1 -9
  164. package/lib/module/network/utils/generateCurl.js +2 -67
  165. package/lib/module/network/utils/generateNetworkCopyText.js +37 -162
  166. package/lib/module/network/utils/httpCompletion.js +1 -32
  167. package/lib/module/network/utils/networkEventStore.js +1 -391
  168. package/lib/module/network/utils/networkListener.js +4 -1249
  169. package/lib/module/network/utils/networkSavedStore.js +3 -572
  170. package/lib/module/network/utils/networkSelectionStore.js +1 -188
  171. package/lib/module/network/utils/realNow.js +1 -0
  172. package/lib/module/network/utils/requestId.js +1 -0
  173. package/lib/module/network/utils/resolveRequestUrl.js +1 -0
  174. package/lib/module/network/utils/selectSavedEvents.js +1 -35
  175. package/lib/module/network/utils/startNetworkCapture.js +1 -0
  176. package/lib/module/network/utils/withPinnedFirst.js +1 -28
  177. package/lib/module/preset.js +1 -100
  178. package/lib/typescript/index.d.ts +1 -0
  179. package/lib/typescript/network/overrides/applyToXhr.d.ts +1 -0
  180. package/lib/typescript/network/overrides/engine.d.ts +1 -1
  181. package/lib/typescript/network/overrides/matchRule.d.ts +1 -1
  182. package/lib/typescript/network/overrides/overriddenRows.d.ts +16 -0
  183. package/lib/typescript/network/overrides/resolveOverride.d.ts +2 -2
  184. package/lib/typescript/network/overrides/types.d.ts +9 -0
  185. package/lib/typescript/network/utils/networkListener.d.ts +14 -4
  186. package/lib/typescript/network/utils/networkSavedStore.d.ts +4 -4
  187. package/lib/typescript/network/utils/realNow.d.ts +18 -0
  188. package/lib/typescript/network/utils/requestId.d.ts +2 -0
  189. package/lib/typescript/network/utils/resolveRequestUrl.d.ts +3 -0
  190. package/lib/typescript/network/utils/startNetworkCapture.d.ts +6 -0
  191. package/lib/web/index.mjs +145 -0
  192. package/package.json +32 -10
  193. package/lib/typescript/index.d.ts.map +0 -1
  194. package/lib/typescript/index.web.d.ts.map +0 -1
  195. package/lib/typescript/network/components/DataViewer.web.d.ts.map +0 -1
  196. package/lib/typescript/network/components/NetworkCopyScreen.web.d.ts.map +0 -1
  197. package/lib/typescript/network/components/NetworkCopySettingsView.d.ts.map +0 -1
  198. package/lib/typescript/network/components/NetworkCopySettingsView.web.d.ts.map +0 -1
  199. package/lib/typescript/network/components/NetworkDetailScreen.web.d.ts.map +0 -1
  200. package/lib/typescript/network/components/NetworkDetailStepper.d.ts.map +0 -1
  201. package/lib/typescript/network/components/NetworkDetailStepper.web.d.ts.map +0 -1
  202. package/lib/typescript/network/components/NetworkEventDetailView.d.ts.map +0 -1
  203. package/lib/typescript/network/components/NetworkEventDetailView.web.d.ts.map +0 -1
  204. package/lib/typescript/network/components/NetworkEventItemCompact.d.ts.map +0 -1
  205. package/lib/typescript/network/components/NetworkEventItemCompact.web.d.ts.map +0 -1
  206. package/lib/typescript/network/components/NetworkFilterScreen.web.d.ts.map +0 -1
  207. package/lib/typescript/network/components/NetworkFilterViewV3.d.ts.map +0 -1
  208. package/lib/typescript/network/components/NetworkFilterViewV3.web.d.ts.map +0 -1
  209. package/lib/typescript/network/components/NetworkHeaderLive.d.ts.map +0 -1
  210. package/lib/typescript/network/components/NetworkHeaderLive.web.d.ts.map +0 -1
  211. package/lib/typescript/network/components/NetworkHeaderMenu.d.ts.map +0 -1
  212. package/lib/typescript/network/components/NetworkListScreen.d.ts.map +0 -1
  213. package/lib/typescript/network/components/NetworkListScreen.web.d.ts.map +0 -1
  214. package/lib/typescript/network/components/NetworkModal.d.ts.map +0 -1
  215. package/lib/typescript/network/components/NetworkNumberPrompt.d.ts.map +0 -1
  216. package/lib/typescript/network/components/NetworkNumberPrompt.web.d.ts.map +0 -1
  217. package/lib/typescript/network/components/NetworkOverrideEditor.d.ts.map +0 -1
  218. package/lib/typescript/network/components/NetworkOverrideEditor.web.d.ts.map +0 -1
  219. package/lib/typescript/network/components/NetworkOverrideHeaderButton.d.ts.map +0 -1
  220. package/lib/typescript/network/components/NetworkOverrideHeaderButton.web.d.ts.map +0 -1
  221. package/lib/typescript/network/components/NetworkOverridesButton.d.ts.map +0 -1
  222. package/lib/typescript/network/components/NetworkOverridesButton.web.d.ts.map +0 -1
  223. package/lib/typescript/network/components/NetworkOverridesScreen.d.ts.map +0 -1
  224. package/lib/typescript/network/components/NetworkOverridesScreen.web.d.ts.map +0 -1
  225. package/lib/typescript/network/components/NetworkSavedScreen.d.ts.map +0 -1
  226. package/lib/typescript/network/components/NetworkSavedScreen.web.d.ts.map +0 -1
  227. package/lib/typescript/network/components/NetworkUpgradeBanner.d.ts.map +0 -1
  228. package/lib/typescript/network/components/response-editor/Explorer.d.ts.map +0 -1
  229. package/lib/typescript/network/components/response-editor/Explorer.web.d.ts.map +0 -1
  230. package/lib/typescript/network/components/response-editor/deleteNestedDataByPath.d.ts.map +0 -1
  231. package/lib/typescript/network/components/response-editor/editorContext.d.ts.map +0 -1
  232. package/lib/typescript/network/components/response-editor/updateNestedDataByPath.d.ts.map +0 -1
  233. package/lib/typescript/network/conditions/NetworkConditionsControl.d.ts.map +0 -1
  234. package/lib/typescript/network/conditions/NetworkConditionsControl.test.d.ts.map +0 -1
  235. package/lib/typescript/network/conditions/NetworkConditionsIcon.d.ts.map +0 -1
  236. package/lib/typescript/network/conditions/NetworkFloatingTool.d.ts.map +0 -1
  237. package/lib/typescript/network/conditions/NetworkFloatingTool.test.d.ts.map +0 -1
  238. package/lib/typescript/network/conditions/store.d.ts.map +0 -1
  239. package/lib/typescript/network/conditions/wait.d.ts.map +0 -1
  240. package/lib/typescript/network/conditions/xhr.d.ts.map +0 -1
  241. package/lib/typescript/network/hooks/useLiveNetworkEvent.d.ts.map +0 -1
  242. package/lib/typescript/network/hooks/useNetworkBadgeCounts.d.ts.map +0 -1
  243. package/lib/typescript/network/hooks/useNetworkEventList.d.ts.map +0 -1
  244. package/lib/typescript/network/hooks/useNetworkEvents.d.ts.map +0 -1
  245. package/lib/typescript/network/hooks/useNetworkHasMatches.d.ts.map +0 -1
  246. package/lib/typescript/network/hooks/useNetworkSaved.d.ts.map +0 -1
  247. package/lib/typescript/network/hooks/useNetworkSelection.d.ts.map +0 -1
  248. package/lib/typescript/network/hooks/useOverrideRules.d.ts.map +0 -1
  249. package/lib/typescript/network/hooks/useTickEveryMinute.d.ts.map +0 -1
  250. package/lib/typescript/network/overrides/applyToFetch.d.ts.map +0 -1
  251. package/lib/typescript/network/overrides/applyToXhr.d.ts.map +0 -1
  252. package/lib/typescript/network/overrides/engine.d.ts.map +0 -1
  253. package/lib/typescript/network/overrides/matchRule.d.ts.map +0 -1
  254. package/lib/typescript/network/overrides/overrideRulesStore.d.ts.map +0 -1
  255. package/lib/typescript/network/overrides/presets.d.ts.map +0 -1
  256. package/lib/typescript/network/overrides/resolveOverride.d.ts.map +0 -1
  257. package/lib/typescript/network/overrides/types.d.ts.map +0 -1
  258. package/lib/typescript/network/sync/networkBodyResolver.d.ts.map +0 -1
  259. package/lib/typescript/network/sync/networkSyncAdapter.d.ts.map +0 -1
  260. package/lib/typescript/network/sync/overrideHonesty.release.test.d.ts.map +0 -1
  261. package/lib/typescript/network/types/index.d.ts.map +0 -1
  262. package/lib/typescript/network/utils/extractOperationName.d.ts.map +0 -1
  263. package/lib/typescript/network/utils/filterNetworkEvents.d.ts.map +0 -1
  264. package/lib/typescript/network/utils/formatGraphQLVariables.d.ts.map +0 -1
  265. package/lib/typescript/network/utils/formatting.d.ts.map +0 -1
  266. package/lib/typescript/network/utils/generateCurl.d.ts.map +0 -1
  267. package/lib/typescript/network/utils/generateNetworkCopyText.d.ts.map +0 -1
  268. package/lib/typescript/network/utils/httpCompletion.d.ts.map +0 -1
  269. package/lib/typescript/network/utils/networkEventStore.d.ts.map +0 -1
  270. package/lib/typescript/network/utils/networkListener.d.ts.map +0 -1
  271. package/lib/typescript/network/utils/networkSavedStore.d.ts.map +0 -1
  272. package/lib/typescript/network/utils/networkSelectionStore.d.ts.map +0 -1
  273. package/lib/typescript/network/utils/selectSavedEvents.d.ts.map +0 -1
  274. package/lib/typescript/network/utils/withPinnedFirst.d.ts.map +0 -1
  275. package/lib/typescript/preset.d.ts.map +0 -1
@@ -1,1149 +1,35 @@
1
- "use strict";
2
-
3
- import { useState, useEffect, useMemo, memo } 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, FlaskConical, InlineCopyButton, macOSColors, night, useFeatureGate, UpgradeModal, monoFont } 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 { useNetworkBodyResolver } from "../sync/networkBodyResolver";
11
-
12
- /**
13
- * Colour for the icons that merely LABEL a section (Sent/Received, the JSON
14
- * body glyphs). The Lock/Unlock pair keeps its colour because
15
- * secure-vs-insecure is a genuine signal, as does the status pill.
16
- */
17
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
18
- const NEUTRAL_ICON = night.color.accent;
19
-
20
- /** Hoisted so the defaults don't mint a new Set/function per render. */
21
- const EMPTY_PATTERNS = new Set();
22
- const noop = () => {};
23
- /**
24
- * The measurable slice of a request's lifetime, as proportional bars.
25
- *
26
- * Renders NOTHING when the interceptor couldn't measure it — an older device
27
- * talking to a newer dashboard, or a request that died before headers. A phase
28
- * row reading `0ms` would claim we measured zero, which is a different and
29
- * false statement from "we didn't measure this".
30
- *
31
- * Only two phases, on purpose. Queueing / DNS / TLS / request-send all happen
32
- * below the JS layer with nothing to read them from — see NetworkTimings. The
33
- * design this came from shows five, but derives the other three by multiplying
34
- * the total by fixed fractions, i.e. they are invented. Two real ones are worth
35
- * more than five where three are decoration.
36
- */
37
- const TimingPhases = ({
38
- timings,
39
- total
40
- }) => {
41
- // Guard the divisor: a sub-millisecond request would otherwise divide by 0.
42
- const span = Math.max(1, total);
43
- const phases = [{
44
- // Deliberately NOT called "server time". Measured from JS, this includes
45
- // queueing, DNS, TLS and sending the request — everything before the
46
- // headers land. The subtitle says so rather than implying Chrome-grade
47
- // precision we don't have.
48
- label: "Waiting (TTFB)",
49
- hint: "incl. queue, DNS, TLS",
50
- value: timings.ttfb,
51
- color: macOSColors.semantic.warning
52
- }, {
53
- label: "Content download",
54
- hint: undefined,
55
- value: timings.download,
56
- color: macOSColors.semantic.success
57
- }];
58
- return /*#__PURE__*/_jsx(View, {
59
- style: styles.phaseList,
60
- children: phases.map(phase => /*#__PURE__*/_jsxs(View, {
61
- style: styles.phaseRow,
62
- children: [/*#__PURE__*/_jsxs(View, {
63
- style: styles.phaseLabelGroup,
64
- children: [/*#__PURE__*/_jsx(Text, {
65
- style: styles.phaseLabel,
66
- children: phase.label
67
- }), phase.hint ? /*#__PURE__*/_jsx(Text, {
68
- style: styles.phaseHint,
69
- children: phase.hint
70
- }) : null]
71
- }), /*#__PURE__*/_jsx(View, {
72
- style: styles.phaseTrack,
73
- children: /*#__PURE__*/_jsx(View, {
74
- style: [styles.phaseBar, {
75
- backgroundColor: phase.color,
76
- // A floor so a 1ms phase is still a visible tick, and a
77
- // ceiling because `total` and the phases are measured at
78
- // different points — ttfb can exceed event.duration, which
79
- // would push the bar past its track and over the label.
80
- width: `${Math.min(100, Math.max(1, phase.value / span * 100))}%`
81
- }]
82
- })
83
- }), /*#__PURE__*/_jsx(Text, {
84
- style: styles.phaseValue,
85
- children: formatDuration(phase.value)
86
- })]
87
- }, phase.label))
88
- });
89
- };
90
-
91
- /**
92
- * Stand-in for a body tree while the prev/next cursor is still moving.
93
- *
94
- * Deliberately a fixed-height nothing: it must cost ~0 to render (that is the
95
- * entire point) and it must not resize the scroll view as the real tree swaps
96
- * in, or fast stepping would make the page jump under the reader.
97
- */
98
- const BodyDeferred = () => /*#__PURE__*/_jsx(View, {
99
- style: styles.bodyDeferred
100
- });
101
-
102
- // Component for collapsible sections matching Sentry style
103
- const CollapsibleSection = ({
104
- title,
105
- icon,
106
- children,
107
- defaultOpen = false,
108
- count
109
- }) => {
110
- const [isOpen, setIsOpen] = useState(defaultOpen);
111
- return /*#__PURE__*/_jsxs(View, {
112
- style: styles.collapsibleSection,
113
- children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
114
- style: styles.collapsibleHeader,
115
- onPress: () => setIsOpen(!isOpen),
116
- testID: `buoy-network-section-${title.toLowerCase().replace(/\s+/g, "-")}`,
117
- accessibilityRole: "button",
118
- accessibilityLabel: title,
119
- children: [/*#__PURE__*/_jsxs(View, {
120
- style: styles.collapsibleTitle,
121
- children: [icon, /*#__PURE__*/_jsx(Text, {
122
- style: styles.collapsibleTitleText,
123
- children: title
124
- }), count !== undefined ? /*#__PURE__*/_jsx(Text, {
125
- style: styles.collapsibleCount,
126
- children: count
127
- }) : null]
128
- }), isOpen ? /*#__PURE__*/_jsx(ChevronUp, {
129
- size: 16,
130
- color: night.color.textSecondary
131
- }) : /*#__PURE__*/_jsx(ChevronDown, {
132
- size: 16,
133
- color: night.color.textSecondary
134
- })]
135
- }), isOpen ? /*#__PURE__*/_jsx(View, {
136
- style: styles.collapsibleContent,
137
- children: children
138
- }) : null]
139
- });
140
- };
141
-
142
- // URL breakdown component matching Sentry style
143
- const UrlBreakdown = ({
144
- url,
145
- requestData,
146
- operationName,
147
- graphqlVariables,
148
- requestClient,
149
- isPro = false,
150
- onUpgradePress
151
- }) => {
152
- const parseUrl = urlString => {
153
- try {
154
- const urlObj = new URL(urlString);
155
- const protocol = String(urlObj.protocol || "");
156
- const host = String(urlObj.host || "");
157
- const isSecure = protocol === "https:";
158
- let pathname = String(urlObj.pathname || "");
159
-
160
- // If this is a GraphQL request with operation name, format with arrow notation
161
- // Matches React Query pattern: "GetPokemon › Sandshrew"
162
- if (requestClient === "graphql" && operationName) {
163
- const graphqlDisplay = formatGraphQLDisplay(operationName, graphqlVariables);
164
- pathname = `${pathname} (${graphqlDisplay})`;
165
- } else if (operationName) {
166
- // For non-GraphQL requests with operation names (e.g., gRPC)
167
- pathname = `${pathname} (${operationName})`;
168
- }
169
-
170
- // Parse query parameters
171
- const params = {};
172
- const searchParams = urlObj.searchParams;
173
- if (searchParams && typeof searchParams.forEach === "function") {
174
- searchParams.forEach((value, key) => {
175
- params[key] = value;
176
- });
177
- }
178
- return {
179
- protocol: protocol.replace(":", ""),
180
- host,
181
- pathname,
182
- params: Object.keys(params).length > 0 ? params : null,
183
- isSecure
184
- };
185
- } catch {
186
- return {
187
- protocol: "",
188
- host: url,
189
- pathname: "",
190
- params: null,
191
- isSecure: false
192
- };
193
- }
194
- };
195
-
196
- /**
197
- * MUST be memoized. `parseUrl` builds a fresh `params` object every call, and
198
- * that object is handed to `DataViewer` as its `data` prop — whose flattening
199
- * effect keys on `data` by IDENTITY. Computed inline, every render of this
200
- * component produced a new object, so the effect re-fired and re-entered
201
- * "Processing data…" forever. The detail view re-renders constantly on the
202
- * dashboard (it tracks the live event as the device pushes snapshots ~4×/sec),
203
- * so this pinned the query-parameter viewer in a permanent processing loop.
204
- *
205
- * `url` is a string, so this is stable by value.
206
- */
207
- const urlParts = useMemo(() => parseUrl(url),
208
- // parseUrl closes over the graphql/operation props, which are what change
209
- // the derived pathname.
210
- // eslint-disable-next-line react-hooks/exhaustive-deps
211
- [url, requestClient, operationName, graphqlVariables]);
212
- const [showParams, setShowParams] = useState(false);
213
- return /*#__PURE__*/_jsxs(View, {
214
- style: styles.urlBreakdown,
215
- children: [/*#__PURE__*/_jsxs(View, {
216
- style: styles.urlRow,
217
- children: [urlParts.isSecure ? /*#__PURE__*/_jsx(Lock, {
218
- size: 12,
219
- color: macOSColors.semantic.success
220
- }) : /*#__PURE__*/_jsx(Unlock, {
221
- size: 12,
222
- color: macOSColors.semantic.warning
223
- }), /*#__PURE__*/_jsx(Text, {
224
- style: styles.urlDomain,
225
- children: urlParts.host
226
- }), /*#__PURE__*/_jsxs(Text, {
227
- style: styles.urlProtocol,
228
- children: ["(", urlParts.protocol.toUpperCase(), ")"]
229
- }), isPro ? /*#__PURE__*/_jsx(InlineCopyButton, {
230
- value: url,
231
- buttonStyle: styles.copyButton
232
- }) : /*#__PURE__*/_jsx(TouchableOpacity, {
233
- style: styles.copyButton,
234
- onPress: onUpgradePress,
235
- activeOpacity: 0.7,
236
- children: /*#__PURE__*/_jsx(Copy, {
237
- size: 14,
238
- color: night.color.textSecondary
239
- })
240
- })]
241
- }), /*#__PURE__*/_jsx(View, {
242
- style: styles.urlPathRow,
243
- children: /*#__PURE__*/_jsxs(Text, {
244
- style: styles.urlPath,
245
- numberOfLines: 2,
246
- children: [urlParts.pathname, urlParts.params ? /*#__PURE__*/_jsxs(Text, {
247
- style: styles.urlQueryString,
248
- children: ["?", new URLSearchParams(urlParts.params).toString()]
249
- }) : null]
250
- })
251
- }), urlParts.params ? /*#__PURE__*/_jsxs(View, {
252
- style: styles.queryParamsCollapsible,
253
- children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
254
- style: styles.queryParamsToggle,
255
- onPress: () => setShowParams(!showParams),
256
- activeOpacity: 0.7,
257
- children: [/*#__PURE__*/_jsx(Text, {
258
- style: styles.queryParamsToggleText,
259
- children: "Query Parameters"
260
- }), /*#__PURE__*/_jsx(Text, {
261
- style: styles.collapsibleCount,
262
- children: Object.keys(urlParts.params).length
263
- }), showParams ? /*#__PURE__*/_jsx(ChevronUp, {
264
- size: 14,
265
- color: night.color.textSecondary
266
- }) : /*#__PURE__*/_jsx(ChevronDown, {
267
- size: 14,
268
- color: night.color.textSecondary
269
- })]
270
- }), showParams ? /*#__PURE__*/_jsx(DataViewer, {
271
- title: "",
272
- data: urlParts.params,
273
- showTypeFilter: true,
274
- rawMode: true,
275
- initialExpanded: true
276
- }) : null]
277
- }) : null]
278
- });
279
- };
280
-
281
- /**
282
- * Detailed inspector rendering request/response metadata for a single network event. Designed to
283
- * mimic Sentry’s layout with collapsible sections, diff views, and quick copy affordances.
284
- *
285
- * MEMOIZED with profiling evidence, not by reflex. Two render paths hit this
286
- * subtree with unchanged props:
287
- *
288
- * 1. `useLiveNetworkEvent` re-subscribes when the selected ID changes, and
289
- * `subscribeToEvents` replays immediately — so every step through the
290
- * prev/next footer committed the SAME event object twice, rendering this
291
- * whole tree (expanded DataViewer included) a second time for nothing.
292
- * 2. Any modal-root state change (header search, mode toggle) re-renders the
293
- * shell, and the detail body has nothing to do with it.
294
- *
295
- * Both props besides `event` are stable by construction — `values` is memoized
296
- * in `useIgnoredPatterns` and `toggle` is module-scope there — so the bail-out
297
- * actually fires.
298
- *
299
- * Measured baseline (js-top, example-dev-build, 5 steps over 109–324KB
300
- * pokeapi responses): 307ms of React work across 5 steps ≈ 61ms of JS per
301
- * step. Case 1 alone is half of that, since it re-ran the whole body render.
302
- */
303
- export const NetworkEventDetailView = /*#__PURE__*/memo(function NetworkEventDetailView({
304
- event,
305
- ignoredPatterns = EMPTY_PATTERNS,
306
- onTogglePattern = noop,
307
- showBodies = true
308
- }) {
309
- const status = event.status ? formatHttpStatus(event.status) : null;
310
- const isPending = !event.status && !event.error;
311
-
312
- // Check Pro status for copy features
313
- const {
314
- isPro
315
- } = useFeatureGate();
316
- const [showUpgradeModal, setShowUpgradeModal] = useState(false);
317
-
318
- // Auto-close upgrade modal when user becomes Pro
319
- useEffect(() => {
320
- if (showUpgradeModal && isPro) {
321
- setShowUpgradeModal(false);
322
- }
323
- }, [showUpgradeModal, isPro]);
324
-
325
- // Large bodies are omitted from synced snapshots (see networkSyncAdapter) and
326
- // fetched on demand through the resolver. On the device there is no resolver
327
- // and bodies are always inline, so this is a no-op there.
328
- const resolveBody = useNetworkBodyResolver();
329
- // The explicit flag is authoritative (adapter v5+). The size>0 fallback keeps
330
- // detail-on-demand working against a device on an older adapter, which marked
331
- // a withheld body only by leaving `data` undefined with a non-zero size.
332
- const requestBodyOmitted = event.requestData === undefined && (event.requestBodyOmitted === true || (event.requestSize ?? 0) > 0);
333
- const responseBodyOmitted = event.responseData === undefined && (event.responseBodyOmitted === true || (event.responseSize ?? 0) > 0);
334
- const headersOmitted = event.headersOmitted === true;
335
- const [resolvedBody, setResolvedBody] = useState(null);
336
- const [isLoadingBody, setIsLoadingBody] = useState(false);
337
- useEffect(() => {
338
- setResolvedBody(null);
339
- if (!resolveBody || !requestBodyOmitted && !responseBodyOmitted && !headersOmitted) {
340
- setIsLoadingBody(false);
341
- return;
342
- }
343
- let cancelled = false;
344
- setIsLoadingBody(true);
345
- resolveBody(event.id).then(body => {
346
- if (!cancelled) setResolvedBody(body);
347
- }).catch(() => {}).finally(() => {
348
- if (!cancelled) setIsLoadingBody(false);
349
- });
350
- return () => {
351
- cancelled = true;
352
- };
353
- }, [event.id, resolveBody, requestBodyOmitted, responseBodyOmitted, headersOmitted]);
354
-
355
- // Effective bodies: inline data when present, otherwise the lazily resolved
356
- // body. `null`/`undefined` both collapse to undefined ("no body").
357
- const requestData = event.requestData ?? resolvedBody?.requestData ?? undefined;
358
- const responseData = event.responseData ?? resolvedBody?.responseData ?? undefined;
359
- const requestHeaders = (headersOmitted ? resolvedBody?.requestHeaders : undefined) ?? event.requestHeaders;
360
- const responseHeaders = (headersOmitted ? resolvedBody?.responseHeaders : undefined) ?? event.responseHeaders;
361
-
362
- // Generate full request details for copying
363
- const getFullRequestDetails = () => {
364
- const requestDetails = {
365
- method: event.method,
366
- url: event.url,
367
- status: event.status,
368
- statusText: event.statusText,
369
- timestamp: new Date(event.timestamp).toISOString(),
370
- duration: event.duration ? `${event.duration}ms` : "N/A",
371
- requestHeaders,
372
- requestData,
373
- responseHeaders,
374
- responseData,
375
- requestSize: event.requestSize ? formatBytes(event.requestSize) : "N/A",
376
- responseSize: event.responseSize ? formatBytes(event.responseSize) : "N/A",
377
- error: event.error,
378
- client: event.requestClient
379
- };
380
- return `# Network Request Details
1
+ "use strict";import{useState as H,useEffect as U,useMemo as ee,memo as te}from"react";import{View as l,Text as i,StyleSheet as oe,ScrollView as re,TouchableOpacity as O}from"react-native";import{Clock as M,Upload as G,Download as J,AlertCircle as le,ChevronDown as _,ChevronUp as Q,Lock as ie,Unlock as ne,FileJson as E,Filter as ae,Globe as se,Link as ce,Copy as Y,FlaskConical as de,InlineCopyButton as K,macOSColors as N,night as o,useFeatureGate as ue,UpgradeModal as pe,monoFont as R}from"@buoy-gg/shared-ui";import{formatBytes as q,formatDuration as X,formatHttpStatus as ge}from"../utils/formatting";import{formatRelativeTime as he}from"@buoy-gg/shared-ui";import{DataViewer as F}from"@buoy-gg/shared-ui/dataViewer";import{formatGraphQLDisplay as fe}from"../utils/formatGraphQLVariables";import{useNetworkBodyResolver as ye}from"../sync/networkBodyResolver";import{jsx as e,jsxs as n,Fragment as W}from"react/jsx-runtime";const A=o.color.accent;const me=new Set;const be=()=>{};const Se=({timings:d,total:r})=>{const u=Math.max(1,r);const h=[{label:"Waiting (TTFB)",hint:"incl. queue, DNS, TLS",value:d.ttfb,color:N.semantic.warning},{label:"Content download",hint:void 0,value:d.download,color:N.semantic.success}];return e(l,{style:t.phaseList,children:h.map(s=>n(l,{style:t.phaseRow,children:[n(l,{style:t.phaseLabelGroup,children:[e(i,{style:t.phaseLabel,children:s.label}),s.hint?e(i,{style:t.phaseHint,children:s.hint}):null]}),e(l,{style:t.phaseTrack,children:e(l,{style:[t.phaseBar,{backgroundColor:s.color,width:`${Math.min(100,Math.max(1,s.value/u*100))}%`}]})}),e(i,{style:t.phaseValue,children:X(s.value)})]},s.label))})};const Z=()=>e(l,{style:t.bodyDeferred});const T=({title:d,icon:r,children:u,defaultOpen:h=false,count:s})=>{const[p,B]=H(h);return n(l,{style:t.collapsibleSection,children:[n(O,{style:t.collapsibleHeader,onPress:()=>B(!p),testID:`buoy-network-section-${d.toLowerCase().replace(/\s+/g,"-")}`,accessibilityRole:"button",accessibilityLabel:d,children:[n(l,{style:t.collapsibleTitle,children:[r,e(i,{style:t.collapsibleTitleText,children:d}),s!==void 0?e(i,{style:t.collapsibleCount,children:s}):null]}),p?e(Q,{size:16,color:o.color.textSecondary}):e(_,{size:16,color:o.color.textSecondary})]}),p?e(l,{style:t.collapsibleContent,children:u}):null]})};const xe=({url:d,requestData:r,operationName:u,graphqlVariables:h,requestClient:s,isPro:p=false,onUpgradePress:B})=>{const g=L=>{try{const y=new URL(L);const x=String(y.protocol||"");const C=String(y.host||"");const V=x==="https:";let m=String(y.pathname||"");if(s==="graphql"&&u){const z=fe(u,h);m=`${m} (${z})`}else if(u){m=`${m} (${u})`}const w={};const b=y.searchParams;if(b&&typeof b.forEach==="function"){b.forEach((z,D)=>{w[D]=z})}return{protocol:x.replace(":",""),host:C,pathname:m,params:Object.keys(w).length>0?w:null,isSecure:V}}catch{return{protocol:"",host:d,pathname:"",params:null,isSecure:false}}};const c=ee(()=>g(d),[d,s,u,h]);const[f,k]=H(false);return n(l,{style:t.urlBreakdown,children:[n(l,{style:t.urlRow,children:[c.isSecure?e(ie,{size:12,color:N.semantic.success}):e(ne,{size:12,color:N.semantic.warning}),e(i,{style:t.urlDomain,children:c.host}),n(i,{style:t.urlProtocol,children:["(",c.protocol.toUpperCase(),")"]}),p?e(K,{value:d,buttonStyle:t.copyButton}):e(O,{style:t.copyButton,onPress:B,activeOpacity:.7,children:e(Y,{size:14,color:o.color.textSecondary})})]}),e(l,{style:t.urlPathRow,children:n(i,{style:t.urlPath,numberOfLines:2,children:[c.pathname,c.params?n(i,{style:t.urlQueryString,children:["?",new URLSearchParams(c.params).toString()]}):null]})}),c.params?n(l,{style:t.queryParamsCollapsible,children:[n(O,{style:t.queryParamsToggle,onPress:()=>k(!f),activeOpacity:.7,children:[e(i,{style:t.queryParamsToggleText,children:"Query Parameters"}),e(i,{style:t.collapsibleCount,children:Object.keys(c.params).length}),f?e(Q,{size:14,color:o.color.textSecondary}):e(_,{size:14,color:o.color.textSecondary})]}),f?e(F,{title:"",data:c.params,showTypeFilter:true,rawMode:true,initialExpanded:true}):null]}):null]})};export const NetworkEventDetailView=te(function d({event:r,ignoredPatterns:u=me,onTogglePattern:h=be,showBodies:s=true}){const p=r.status?ge(r.status):null;const B=!r.status&&!r.error;const{isPro:g}=ue();const[c,f]=H(false);U(()=>{if(c&&g){f(false)}},[c,g]);const k=ye();const L=r.requestData===void 0&&(r.requestBodyOmitted===true||(r.requestSize??0)>0);const y=r.responseData===void 0&&(r.responseBodyOmitted===true||(r.responseSize??0)>0);const x=r.headersOmitted===true;const[C,V]=H(null);const[m,w]=H(false);U(()=>{V(null);if(!k||!L&&!y&&!x){w(false);return}let a=false;w(true);k(r.id).then(S=>{if(!a)V(S)}).catch(()=>{}).finally(()=>{if(!a)w(false)});return()=>{a=true}},[r.id,k,L,y,x]);const b=r.requestData??C?.requestData??void 0;const z=r.responseData??C?.responseData??void 0;const D=(x?C?.requestHeaders:void 0)??r.requestHeaders;const $=(x?C?.responseHeaders:void 0)??r.responseHeaders;const v=()=>{const a={method:r.method,url:r.url,status:r.status,statusText:r.statusText,timestamp:new Date(r.timestamp).toISOString(),duration:r.duration?`${r.duration}ms`:"N/A",requestHeaders:D,requestData:b,responseHeaders:$,responseData:z,requestSize:r.requestSize?q(r.requestSize):"N/A",responseSize:r.responseSize?q(r.responseSize):"N/A",error:r.error,client:r.requestClient};return`# Network Request Details
381
2
 
382
3
  ## Request
383
- - **Method:** ${requestDetails.method}
384
- - **URL:** ${requestDetails.url}
385
- - **Client:** ${requestDetails.client || "N/A"}
386
- - **Timestamp:** ${requestDetails.timestamp}
4
+ - **Method:** ${a.method}
5
+ - **URL:** ${a.url}
6
+ - **Client:** ${a.client||"N/A"}
7
+ - **Timestamp:** ${a.timestamp}
387
8
 
388
9
  ## Response
389
- - **Status:** ${requestDetails.status || "Pending"}${requestDetails.statusText ? ` (${requestDetails.statusText})` : ""}
390
- - **Duration:** ${requestDetails.duration}
391
- - **Request Size:** ${requestDetails.requestSize}
392
- - **Response Size:** ${requestDetails.responseSize}
393
- ${requestDetails.error ? `- **Error:** ${requestDetails.error}` : ""}
10
+ - **Status:** ${a.status||"Pending"}${a.statusText?` (${a.statusText})`:""}
11
+ - **Duration:** ${a.duration}
12
+ - **Request Size:** ${a.requestSize}
13
+ - **Response Size:** ${a.responseSize}
14
+ ${a.error?`- **Error:** ${a.error}`:""}
394
15
 
395
16
  ## Request Headers
396
17
  \`\`\`json
397
- ${JSON.stringify(requestDetails.requestHeaders, null, 2)}
18
+ ${JSON.stringify(a.requestHeaders,null,2)}
398
19
  \`\`\`
399
20
 
400
21
  ## Request Data
401
22
  \`\`\`json
402
- ${JSON.stringify(requestDetails.requestData, null, 2)}
23
+ ${JSON.stringify(a.requestData,null,2)}
403
24
  \`\`\`
404
25
 
405
26
  ## Response Headers
406
27
  \`\`\`json
407
- ${JSON.stringify(requestDetails.responseHeaders, null, 2)}
28
+ ${JSON.stringify(a.responseHeaders,null,2)}
408
29
  \`\`\`
409
30
 
410
31
  ## Response Data
411
32
  \`\`\`json
412
- ${JSON.stringify(requestDetails.responseData, null, 2)}
33
+ ${JSON.stringify(a.responseData,null,2)}
413
34
  \`\`\`
414
- `;
415
- };
416
- return /*#__PURE__*/_jsxs(_Fragment, {
417
- children: [/*#__PURE__*/_jsxs(ScrollView, {
418
- testID: "buoy-network-detail-scroll",
419
- style: styles.container,
420
- children: [/*#__PURE__*/_jsxs(View, {
421
- style: styles.requestDetailsSection,
422
- children: [/*#__PURE__*/_jsxs(View, {
423
- style: styles.httpHeader,
424
- children: [/*#__PURE__*/_jsx(View, {
425
- style: styles.httpMethodBadge,
426
- children: /*#__PURE__*/_jsx(Text, {
427
- style: styles.httpMethod,
428
- children: event.method
429
- })
430
- }), event.status ? /*#__PURE__*/_jsx(View, {
431
- style: [styles.httpStatusBadge, {
432
- backgroundColor: `${status?.color}20`
433
- }],
434
- children: /*#__PURE__*/_jsxs(Text, {
435
- style: [styles.httpStatusText, {
436
- color: status?.color
437
- }],
438
- children: [status?.text, " ", status?.meaning]
439
- })
440
- }) : isPending ? /*#__PURE__*/_jsxs(View, {
441
- style: styles.pendingBadge,
442
- children: [/*#__PURE__*/_jsx(Clock, {
443
- size: 10,
444
- color: night.color.warning
445
- }), /*#__PURE__*/_jsx(Text, {
446
- style: styles.pendingBadgeText,
447
- children: "Pending"
448
- })]
449
- }) : null, event.condition && /*#__PURE__*/_jsxs(Text, {
450
- style: {
451
- color: "#FFCC66"
452
- },
453
- children: ["Conditions: ", event.condition.profile, " (+", event.condition.delayMs, " ms)"]
454
- }), event.duration ? /*#__PURE__*/_jsxs(View, {
455
- style: styles.httpDuration,
456
- children: [/*#__PURE__*/_jsx(Clock, {
457
- size: 10,
458
- color: night.color.textTertiary
459
- }), /*#__PURE__*/_jsx(Text, {
460
- style: styles.httpDurationText,
461
- children: formatDuration(event.duration)
462
- })]
463
- }) : null, event.override ? /*#__PURE__*/_jsxs(View, {
464
- style: styles.overrideBadge,
465
- children: [/*#__PURE__*/_jsx(FlaskConical, {
466
- size: 10,
467
- color: night.color.warning
468
- }), /*#__PURE__*/_jsx(Text, {
469
- style: styles.overrideBadgeText,
470
- children: event.override.ruleName || "Overridden"
471
- })]
472
- }) : null, isPro ? /*#__PURE__*/_jsx(InlineCopyButton
473
- // LAZY, not `getFullRequestDetails()`. CopyButton resolves a
474
- // function value at press time; calling it here instead
475
- // pretty-printed the headers AND both bodies on every render —
476
- // four JSON.stringify passes over the full payload just to have
477
- // a string nobody asked for yet. Same shape NetworkSavedScreen
478
- // already uses for its copy button.
479
- , {
480
- value: getFullRequestDetails,
481
- buttonStyle: styles.copyFullButton
482
- }) : /*#__PURE__*/_jsx(TouchableOpacity, {
483
- style: styles.copyFullButton,
484
- onPress: () => setShowUpgradeModal(true),
485
- activeOpacity: 0.7,
486
- children: /*#__PURE__*/_jsx(Copy, {
487
- size: 14,
488
- color: night.color.textSecondary
489
- })
490
- })]
491
- }), /*#__PURE__*/_jsx(UrlBreakdown, {
492
- url: event.url,
493
- requestData: requestData,
494
- operationName: event.operationName,
495
- graphqlVariables: event.graphqlVariables,
496
- requestClient: event.requestClient,
497
- isPro: isPro,
498
- onUpgradePress: () => setShowUpgradeModal(true)
499
- }), event.error ? /*#__PURE__*/_jsxs(View, {
500
- style: styles.errorBox,
501
- children: [/*#__PURE__*/_jsx(AlertCircle, {
502
- size: 12,
503
- color: night.color.danger
504
- }), /*#__PURE__*/_jsx(Text, {
505
- style: styles.errorText,
506
- children: event.error
507
- })]
508
- }) : null]
509
- }), /*#__PURE__*/_jsxs(View, {
510
- style: styles.timingSection,
511
- children: [/*#__PURE__*/_jsxs(View, {
512
- style: styles.timingRow,
513
- children: [/*#__PURE__*/_jsx(Clock, {
514
- size: 12,
515
- color: night.color.textSecondary
516
- }), /*#__PURE__*/_jsx(Text, {
517
- style: styles.timingLabel,
518
- children: "Started:"
519
- }), /*#__PURE__*/_jsx(Text, {
520
- style: styles.timingValue,
521
- children: formatRelativeTime(event.timestamp)
522
- }), /*#__PURE__*/_jsxs(Text, {
523
- style: styles.timingExact,
524
- children: ["(", new Date(event.timestamp).toLocaleTimeString(), ")"]
525
- }), event.requestSize || event.responseSize ? /*#__PURE__*/_jsxs(View, {
526
- style: styles.sizeRow,
527
- children: [event.requestSize !== undefined ? /*#__PURE__*/_jsxs(View, {
528
- style: styles.sizeItem,
529
- children: [/*#__PURE__*/_jsx(Upload, {
530
- size: 10,
531
- color: night.color.info
532
- }), /*#__PURE__*/_jsx(Text, {
533
- style: styles.sizeLabel,
534
- children: "Sent:"
535
- }), /*#__PURE__*/_jsx(Text, {
536
- style: styles.sizeValue,
537
- children: formatBytes(event.requestSize)
538
- })]
539
- }) : null, event.responseSize !== undefined ? /*#__PURE__*/_jsxs(View, {
540
- style: styles.sizeItem,
541
- children: [/*#__PURE__*/_jsx(Download, {
542
- size: 10,
543
- color: NEUTRAL_ICON
544
- }), /*#__PURE__*/_jsx(Text, {
545
- style: styles.sizeLabel,
546
- children: "Received:"
547
- }), /*#__PURE__*/_jsx(Text, {
548
- style: styles.sizeValue,
549
- children: formatBytes(event.responseSize)
550
- })]
551
- }) : null]
552
- }) : null]
553
- }), event.timings ? /*#__PURE__*/_jsxs(_Fragment, {
554
- children: [/*#__PURE__*/_jsx(View, {
555
- style: styles.phaseDivider
556
- }), /*#__PURE__*/_jsx(TimingPhases, {
557
- timings: event.timings,
558
- total: event.duration ?? event.timings.ttfb + event.timings.download
559
- })]
560
- }) : null]
561
- }), /*#__PURE__*/_jsx(CollapsibleSection, {
562
- title: "Request Headers",
563
- icon: /*#__PURE__*/_jsx(Upload, {
564
- size: 14,
565
- color: night.color.info
566
- }),
567
- defaultOpen: false,
568
- count: Object.keys(requestHeaders).length,
569
- children: Object.keys(requestHeaders).length > 0 ? /*#__PURE__*/_jsx(View, {
570
- style: styles.dataViewerContainer,
571
- children: /*#__PURE__*/_jsx(DataViewer, {
572
- title: "",
573
- data: requestHeaders,
574
- showTypeFilter: true,
575
- rawMode: true,
576
- initialExpanded: true,
577
- disableCopy: !isPro
578
- })
579
- }) : /*#__PURE__*/_jsx(Text, {
580
- style: styles.emptyText,
581
- children: "No request headers"
582
- })
583
- }), /*#__PURE__*/_jsx(CollapsibleSection, {
584
- title: "Response Headers",
585
- icon: /*#__PURE__*/_jsx(Download, {
586
- size: 14,
587
- color: NEUTRAL_ICON
588
- }),
589
- defaultOpen: false,
590
- count: Object.keys(responseHeaders).length,
591
- children: Object.keys(responseHeaders).length > 0 ? /*#__PURE__*/_jsx(View, {
592
- style: styles.dataViewerContainer,
593
- children: /*#__PURE__*/_jsx(DataViewer, {
594
- title: "",
595
- data: responseHeaders,
596
- showTypeFilter: true,
597
- rawMode: true,
598
- initialExpanded: true,
599
- disableCopy: !isPro
600
- })
601
- }) : /*#__PURE__*/_jsx(Text, {
602
- style: styles.emptyText,
603
- children: "No response headers yet"
604
- })
605
- }), requestData !== undefined ? /*#__PURE__*/_jsx(CollapsibleSection, {
606
- title: "Request Body",
607
- icon: /*#__PURE__*/_jsx(FileJson, {
608
- size: 14,
609
- color: night.color.accent
610
- }),
611
- defaultOpen: false,
612
- children: /*#__PURE__*/_jsx(View, {
613
- style: styles.dataViewerContainer,
614
- children: showBodies ? /*#__PURE__*/_jsx(DataViewer, {
615
- title: "",
616
- data: requestData,
617
- showTypeFilter: true,
618
- rawMode: true,
619
- initialExpanded: true,
620
- disableCopy: !isPro
621
- }) : /*#__PURE__*/_jsx(BodyDeferred, {})
622
- })
623
- }) : requestBodyOmitted ? /*#__PURE__*/_jsx(CollapsibleSection, {
624
- title: "Request Body",
625
- icon: /*#__PURE__*/_jsx(FileJson, {
626
- size: 14,
627
- color: night.color.accent
628
- }),
629
- defaultOpen: true,
630
- children: /*#__PURE__*/_jsx(Text, {
631
- style: styles.emptyText,
632
- children: isLoadingBody ? `Loading request body (${formatBytes(event.requestSize ?? 0)})…` : "Request body unavailable"
633
- })
634
- }) : null, responseData !== undefined ? /*#__PURE__*/_jsx(CollapsibleSection, {
635
- title: "Response Body",
636
- icon: /*#__PURE__*/_jsx(FileJson, {
637
- size: 14,
638
- color: NEUTRAL_ICON
639
- })
640
- // The body is what you opened the row FOR — the design has it
641
- // expanded on arrival, everything else closed.
642
- ,
643
- defaultOpen: true,
644
- children: /*#__PURE__*/_jsx(View, {
645
- style: styles.dataViewerContainer,
646
- children: showBodies ? /*#__PURE__*/_jsx(DataViewer, {
647
- title: "",
648
- data: responseData,
649
- showTypeFilter: true,
650
- rawMode: true,
651
- initialExpanded: true,
652
- disableCopy: !isPro
653
- }) : /*#__PURE__*/_jsx(BodyDeferred, {})
654
- })
655
- }) : responseBodyOmitted ? /*#__PURE__*/_jsx(CollapsibleSection, {
656
- title: "Response Body",
657
- icon: /*#__PURE__*/_jsx(FileJson, {
658
- size: 14,
659
- color: NEUTRAL_ICON
660
- }),
661
- defaultOpen: true,
662
- children: /*#__PURE__*/_jsx(Text, {
663
- style: styles.emptyText,
664
- children: isLoadingBody ? `Loading response body (${formatBytes(event.responseSize ?? 0)})…` : "Response body unavailable"
665
- })
666
- }) : null, /*#__PURE__*/_jsx(CollapsibleSection, {
667
- title: "Filter Options",
668
- icon: /*#__PURE__*/_jsx(Filter, {
669
- size: 14,
670
- color: night.color.warning
671
- }),
672
- defaultOpen: false,
673
- children: /*#__PURE__*/_jsx(View, {
674
- style: styles.filterOptionsContainer,
675
- children: (() => {
676
- let domain = "";
677
- let urlPath = "";
678
- try {
679
- const url = new URL(event.url);
680
- domain = url.hostname;
681
- urlPath = url.pathname;
682
- } catch {
683
- urlPath = event.url;
684
- }
685
- const isDomainIgnored = ignoredPatterns.has(domain);
686
- const isUrlIgnored = ignoredPatterns.has(urlPath);
687
- return /*#__PURE__*/_jsxs(_Fragment, {
688
- children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
689
- style: [styles.filterOption, isDomainIgnored && styles.filterOptionActive],
690
- onPress: () => domain && onTogglePattern(domain),
691
- children: [/*#__PURE__*/_jsxs(View, {
692
- style: styles.filterOptionLeft,
693
- children: [/*#__PURE__*/_jsx(Globe, {
694
- size: 16,
695
- color: isDomainIgnored ? night.color.warning : night.color.textTertiary
696
- }), /*#__PURE__*/_jsxs(View, {
697
- style: styles.filterOptionContent,
698
- children: [/*#__PURE__*/_jsx(Text, {
699
- style: styles.filterOptionLabel,
700
- children: "Ignore Domain"
701
- }), /*#__PURE__*/_jsx(Text, {
702
- style: styles.filterOptionValue,
703
- children: domain || "N/A"
704
- })]
705
- })]
706
- }), /*#__PURE__*/_jsx(View, {
707
- style: [styles.filterToggle, isDomainIgnored && styles.filterToggleActive],
708
- children: /*#__PURE__*/_jsx(Text, {
709
- style: [styles.filterToggleText, isDomainIgnored && styles.filterToggleTextActive],
710
- children: isDomainIgnored ? "IGNORED" : "IGNORE"
711
- })
712
- })]
713
- }), /*#__PURE__*/_jsxs(TouchableOpacity, {
714
- style: [styles.filterOption, isUrlIgnored && styles.filterOptionActive],
715
- onPress: () => urlPath && onTogglePattern(urlPath),
716
- children: [/*#__PURE__*/_jsxs(View, {
717
- style: styles.filterOptionLeft,
718
- children: [/*#__PURE__*/_jsx(Link, {
719
- size: 16,
720
- color: isUrlIgnored ? night.color.warning : night.color.textTertiary
721
- }), /*#__PURE__*/_jsxs(View, {
722
- style: styles.filterOptionContent,
723
- children: [/*#__PURE__*/_jsx(Text, {
724
- style: styles.filterOptionLabel,
725
- children: "Ignore URL Pattern"
726
- }), /*#__PURE__*/_jsx(Text, {
727
- style: styles.filterOptionValue,
728
- numberOfLines: 1,
729
- children: urlPath || "N/A"
730
- })]
731
- })]
732
- }), /*#__PURE__*/_jsx(View, {
733
- style: [styles.filterToggle, isUrlIgnored && styles.filterToggleActive],
734
- children: /*#__PURE__*/_jsx(Text, {
735
- style: [styles.filterToggleText, isUrlIgnored && styles.filterToggleTextActive],
736
- children: isUrlIgnored ? "IGNORED" : "IGNORE"
737
- })
738
- })]
739
- }), /*#__PURE__*/_jsx(View, {
740
- style: styles.filterInfoBox,
741
- children: /*#__PURE__*/_jsx(Text, {
742
- style: styles.filterInfoText,
743
- children: "Ignored requests will be hidden from the network list. You can manage filters in the Filters tab."
744
- })
745
- })]
746
- });
747
- })()
748
- })
749
- })]
750
- }), /*#__PURE__*/_jsx(UpgradeModal, {
751
- visible: showUpgradeModal,
752
- onClose: () => setShowUpgradeModal(false),
753
- featureName: "Copy Request Details",
754
- description: "Copy network request details to share or debug issues.",
755
- 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"]
756
- })]
757
- });
758
- });
759
- const styles = StyleSheet.create({
760
- container: {
761
- flex: 1,
762
- // Transparent so the night sheet's star field shows through.
763
- backgroundColor: "transparent"
764
- },
765
- // Request details section - always visible
766
- requestDetailsSection: {
767
- marginHorizontal: 12,
768
- marginTop: 12,
769
- backgroundColor: night.color.surface,
770
- borderRadius: 8,
771
- borderWidth: 1,
772
- borderColor: night.color.border,
773
- padding: 12
774
- },
775
- httpHeader: {
776
- flexDirection: "row",
777
- alignItems: "center",
778
- gap: 8,
779
- marginBottom: 12,
780
- flexWrap: "nowrap"
781
- },
782
- httpMethodBadge: {
783
- backgroundColor: night.color.infoSoft,
784
- paddingHorizontal: 8,
785
- paddingVertical: 4,
786
- borderRadius: 4
787
- },
788
- httpMethod: {
789
- color: night.color.info,
790
- fontSize: 11,
791
- fontWeight: "700",
792
- letterSpacing: 0.5
793
- },
794
- httpStatusBadge: {
795
- paddingHorizontal: 8,
796
- paddingVertical: 4,
797
- borderRadius: 4
798
- },
799
- httpStatusText: {
800
- fontSize: 11,
801
- fontWeight: "600"
802
- },
803
- pendingBadge: {
804
- flexDirection: "row",
805
- alignItems: "center",
806
- gap: 4,
807
- backgroundColor: night.color.warningSoft,
808
- paddingHorizontal: 8,
809
- paddingVertical: 4,
810
- borderRadius: 4
811
- },
812
- pendingBadgeText: {
813
- color: night.color.warning,
814
- fontSize: 11,
815
- fontWeight: "600"
816
- },
817
- httpDuration: {
818
- flexDirection: "row",
819
- alignItems: "center",
820
- gap: 4
821
- },
822
- httpDurationText: {
823
- color: night.color.textSecondary,
824
- fontSize: 11
825
- },
826
- overrideBadge: {
827
- flexDirection: "row",
828
- alignItems: "center",
829
- gap: 4,
830
- paddingHorizontal: 6,
831
- paddingVertical: 3,
832
- borderRadius: 4,
833
- backgroundColor: night.color.warningSoft
834
- },
835
- overrideBadgeText: {
836
- color: night.color.warning,
837
- fontSize: 10,
838
- fontWeight: "700"
839
- },
840
- copyFullButton: {
841
- marginLeft: "auto",
842
- flexShrink: 0,
843
- padding: 4
844
- },
845
- // URL breakdown styles
846
- urlBreakdown: {
847
- // Inset code box — darker than the card, the night track color.
848
- backgroundColor: night.color.bg,
849
- borderRadius: 4,
850
- padding: 8
851
- },
852
- urlRow: {
853
- flexDirection: "row",
854
- alignItems: "center",
855
- gap: 6,
856
- marginBottom: 4
857
- },
858
- urlDomain: {
859
- color: night.color.text,
860
- fontSize: 12,
861
- fontWeight: "600",
862
- flex: 1
863
- },
864
- urlProtocol: {
865
- color: night.color.textTertiary,
866
- fontSize: 10
867
- },
868
- copyButton: {
869
- padding: 4
870
- },
871
- urlPathRow: {
872
- paddingLeft: 18
873
- },
874
- urlPath: {
875
- color: night.color.textSecondary,
876
- fontSize: 11,
877
- fontFamily: monoFont
878
- },
879
- urlQueryString: {
880
- color: night.color.info,
881
- fontSize: 11,
882
- fontFamily: monoFont
883
- },
884
- // Query Parameters - Collapsible section
885
- queryParamsCollapsible: {
886
- marginTop: 8
887
- },
888
- queryParamsToggle: {
889
- flexDirection: "row",
890
- alignItems: "center",
891
- justifyContent: "space-between",
892
- paddingHorizontal: 12,
893
- paddingVertical: 10,
894
- backgroundColor: night.color.surfaceElevated,
895
- borderRadius: 8,
896
- borderWidth: 1,
897
- borderColor: night.color.border,
898
- marginBottom: 8
899
- },
900
- queryParamsToggleText: {
901
- flexGrow: 0,
902
- color: night.color.text,
903
- fontSize: 12,
904
- fontWeight: "600",
905
- letterSpacing: 0.3
906
- },
907
- // Timing section - always visible
908
- timingSection: {
909
- marginHorizontal: 12,
910
- marginTop: 8,
911
- backgroundColor: night.color.surface,
912
- borderRadius: 8,
913
- borderWidth: 1,
914
- borderColor: night.color.border,
915
- padding: 12
916
- },
917
- timingRow: {
918
- flexDirection: "row",
919
- alignItems: "center",
920
- gap: 6,
921
- // Wraps rather than squashing when the card is narrow (a phone, or a
922
- // half-width panel) — the sizes drop to their own line there.
923
- flexWrap: "wrap"
924
- },
925
- timingLabel: {
926
- color: night.color.textSecondary,
927
- fontSize: 11
928
- },
929
- timingValue: {
930
- color: night.color.text,
931
- fontSize: 11,
932
- fontWeight: "600"
933
- },
934
- timingExact: {
935
- color: night.color.textTertiary,
936
- fontSize: 10,
937
- marginLeft: 4
938
- },
939
- sizeRow: {
940
- flexDirection: "row",
941
- alignItems: "center",
942
- gap: 16,
943
- // Pushed to the far end of the Started row. No top border/padding — it is
944
- // no longer a separate strip.
945
- marginLeft: "auto"
946
- },
947
- sizeItem: {
948
- flexDirection: "row",
949
- alignItems: "center",
950
- gap: 4
951
- },
952
- sizeLabel: {
953
- color: night.color.textTertiary,
954
- fontSize: 10
955
- },
956
- sizeValue: {
957
- color: night.color.info,
958
- fontSize: 10,
959
- fontFamily: monoFont,
960
- fontWeight: "600"
961
- },
962
- /* ---- Timing phases ---- */
963
- phaseDivider: {
964
- height: 1,
965
- backgroundColor: night.color.border,
966
- marginTop: 12,
967
- marginBottom: 12
968
- },
969
- phaseList: {
970
- gap: 8
971
- },
972
- phaseRow: {
973
- flexDirection: "row",
974
- alignItems: "center",
975
- gap: 14
976
- },
977
- phaseLabelGroup: {
978
- width: 150
979
- },
980
- phaseLabel: {
981
- fontSize: 12,
982
- color: night.color.textSecondary
983
- },
984
- phaseHint: {
985
- fontSize: 10,
986
- color: night.color.textTertiary
987
- },
988
- phaseTrack: {
989
- flex: 1,
990
- height: 7,
991
- borderRadius: 4,
992
- backgroundColor: night.color.surfaceElevated,
993
- justifyContent: "center",
994
- overflow: "hidden"
995
- },
996
- phaseBar: {
997
- height: 7,
998
- borderRadius: 4
999
- },
1000
- phaseValue: {
1001
- width: 72,
1002
- textAlign: "right",
1003
- fontSize: 12,
1004
- fontFamily: monoFont,
1005
- color: night.color.text
1006
- },
1007
- // Collapsible section styles
1008
- collapsibleSection: {
1009
- marginHorizontal: 12,
1010
- marginTop: 8,
1011
- backgroundColor: night.color.surface,
1012
- borderRadius: 8,
1013
- borderWidth: 1,
1014
- borderColor: night.color.border,
1015
- overflow: "hidden"
1016
- },
1017
- collapsibleHeader: {
1018
- flexDirection: "row",
1019
- alignItems: "center",
1020
- justifyContent: "space-between",
1021
- padding: 12,
1022
- // `background.hover` is the SELECTION grey — heavy enough here that every
1023
- // section header read as a toolbar. The design uses a near-white strip.
1024
- backgroundColor: night.color.surfaceElevated
1025
- },
1026
- collapsibleTitle: {
1027
- flexDirection: "row",
1028
- alignItems: "center",
1029
- gap: 8
1030
- },
1031
- collapsibleTitleText: {
1032
- color: night.color.text,
1033
- fontSize: 13,
1034
- fontWeight: "600"
1035
- },
1036
- /** The "how much is in here" number beside a section title. */
1037
- collapsibleCount: {
1038
- color: night.color.textTertiary,
1039
- fontSize: 11.5,
1040
- fontFamily: monoFont
1041
- },
1042
- collapsibleContent: {
1043
- padding: 12
1044
- },
1045
- // Data viewer container
1046
- dataViewerContainer: {
1047
- marginTop: -12,
1048
- marginHorizontal: -12,
1049
- marginBottom: -12
1050
- },
1051
- /** Placeholder for a not-yet-mounted body tree. See BodyDeferred. */
1052
- bodyDeferred: {
1053
- height: 120
1054
- },
1055
- // Error box
1056
- errorBox: {
1057
- flexDirection: "row",
1058
- alignItems: "center",
1059
- gap: 6,
1060
- backgroundColor: night.color.dangerSoft,
1061
- padding: 8,
1062
- borderRadius: 4,
1063
- marginTop: 8
1064
- },
1065
- errorText: {
1066
- color: night.color.danger,
1067
- fontSize: 11,
1068
- flex: 1
1069
- },
1070
- // Empty state
1071
- emptyText: {
1072
- color: night.color.textTertiary,
1073
- fontSize: 12,
1074
- fontStyle: "italic",
1075
- textAlign: "center"
1076
- },
1077
- // Filter options styles
1078
- filterOptionsContainer: {
1079
- gap: 12
1080
- },
1081
- filterOption: {
1082
- flexDirection: "row",
1083
- alignItems: "center",
1084
- justifyContent: "space-between",
1085
- backgroundColor: night.color.surfaceElevated,
1086
- borderRadius: 8,
1087
- padding: 12,
1088
- borderWidth: 1,
1089
- borderColor: night.color.border
1090
- },
1091
- filterOptionActive: {
1092
- backgroundColor: night.color.warningSoft,
1093
- borderColor: night.color.warning + "33"
1094
- },
1095
- filterOptionLeft: {
1096
- flexDirection: "row",
1097
- alignItems: "center",
1098
- gap: 12,
1099
- flex: 1
1100
- },
1101
- filterOptionContent: {
1102
- flex: 1
1103
- },
1104
- filterOptionLabel: {
1105
- color: night.color.textSecondary,
1106
- fontSize: 11,
1107
- marginBottom: 2,
1108
- textTransform: "uppercase",
1109
- letterSpacing: 0.5
1110
- },
1111
- filterOptionValue: {
1112
- color: night.color.text,
1113
- fontSize: 13,
1114
- fontFamily: monoFont
1115
- },
1116
- filterToggle: {
1117
- paddingHorizontal: 10,
1118
- paddingVertical: 6,
1119
- borderRadius: 4,
1120
- backgroundColor: night.color.bg,
1121
- borderWidth: 1,
1122
- borderColor: night.color.border
1123
- },
1124
- filterToggleActive: {
1125
- backgroundColor: night.color.warningSoft,
1126
- borderColor: night.color.warning + "4D"
1127
- },
1128
- filterToggleText: {
1129
- fontSize: 10,
1130
- fontWeight: "600",
1131
- color: night.color.textTertiary,
1132
- letterSpacing: 0.5
1133
- },
1134
- filterToggleTextActive: {
1135
- color: night.color.warning
1136
- },
1137
- filterInfoBox: {
1138
- backgroundColor: night.color.infoSoft,
1139
- borderRadius: 6,
1140
- padding: 10,
1141
- borderWidth: 1,
1142
- borderColor: night.color.info + "33"
1143
- },
1144
- filterInfoText: {
1145
- color: night.color.textSecondary,
1146
- fontSize: 11,
1147
- lineHeight: 16
1148
- }
1149
- });
35
+ `};return n(W,{children:[n(re,{testID:"buoy-network-detail-scroll",style:t.container,children:[n(l,{style:t.requestDetailsSection,children:[n(l,{style:t.httpHeader,children:[e(l,{style:t.httpMethodBadge,children:e(i,{style:t.httpMethod,children:r.method})}),r.status?e(l,{style:[t.httpStatusBadge,{backgroundColor:`${p?.color}20`}],children:n(i,{style:[t.httpStatusText,{color:p?.color}],children:[p?.text," ",p?.meaning]})}):B?n(l,{style:t.pendingBadge,children:[e(M,{size:10,color:o.color.warning}),e(i,{style:t.pendingBadgeText,children:"Pending"})]}):null,r.condition&&n(i,{style:{color:"#FFCC66"},children:["Conditions: ",r.condition.profile," (+",r.condition.delayMs," ms)"]}),r.duration?n(l,{style:t.httpDuration,children:[e(M,{size:10,color:o.color.textTertiary}),e(i,{style:t.httpDurationText,children:X(r.duration)})]}):null,r.override?n(l,{style:t.overrideBadge,children:[e(de,{size:10,color:o.color.warning}),e(i,{style:t.overrideBadgeText,children:r.override.ruleName||"Overridden"})]}):null,g?e(K,{value:v,buttonStyle:t.copyFullButton}):e(O,{style:t.copyFullButton,onPress:()=>f(true),activeOpacity:.7,children:e(Y,{size:14,color:o.color.textSecondary})})]}),e(xe,{url:r.url,requestData:b,operationName:r.operationName,graphqlVariables:r.graphqlVariables,requestClient:r.requestClient,isPro:g,onUpgradePress:()=>f(true)}),r.error?n(l,{style:t.errorBox,children:[e(le,{size:12,color:o.color.danger}),e(i,{style:t.errorText,children:r.error})]}):null]}),n(l,{style:t.timingSection,children:[n(l,{style:t.timingRow,children:[e(M,{size:12,color:o.color.textSecondary}),e(i,{style:t.timingLabel,children:"Started:"}),e(i,{style:t.timingValue,children:he(r.timestamp)}),n(i,{style:t.timingExact,children:["(",new Date(r.timestamp).toLocaleTimeString(),")"]}),r.requestSize||r.responseSize?n(l,{style:t.sizeRow,children:[r.requestSize!==void 0?n(l,{style:t.sizeItem,children:[e(G,{size:10,color:o.color.info}),e(i,{style:t.sizeLabel,children:"Sent:"}),e(i,{style:t.sizeValue,children:q(r.requestSize)})]}):null,r.responseSize!==void 0?n(l,{style:t.sizeItem,children:[e(J,{size:10,color:A}),e(i,{style:t.sizeLabel,children:"Received:"}),e(i,{style:t.sizeValue,children:q(r.responseSize)})]}):null]}):null]}),r.timings?n(W,{children:[e(l,{style:t.phaseDivider}),e(Se,{timings:r.timings,total:r.duration??r.timings.ttfb+r.timings.download})]}):null]}),e(T,{title:"Request Headers",icon:e(G,{size:14,color:o.color.info}),defaultOpen:false,count:Object.keys(D).length,children:Object.keys(D).length>0?e(l,{style:t.dataViewerContainer,children:e(F,{title:"",data:D,showTypeFilter:true,rawMode:true,initialExpanded:true,disableCopy:!g})}):e(i,{style:t.emptyText,children:"No request headers"})}),e(T,{title:"Response Headers",icon:e(J,{size:14,color:A}),defaultOpen:false,count:Object.keys($).length,children:Object.keys($).length>0?e(l,{style:t.dataViewerContainer,children:e(F,{title:"",data:$,showTypeFilter:true,rawMode:true,initialExpanded:true,disableCopy:!g})}):e(i,{style:t.emptyText,children:"No response headers yet"})}),b!==void 0?e(T,{title:"Request Body",icon:e(E,{size:14,color:o.color.accent}),defaultOpen:false,children:e(l,{style:t.dataViewerContainer,children:s?e(F,{title:"",data:b,showTypeFilter:true,rawMode:true,initialExpanded:true,disableCopy:!g}):e(Z,{})})}):L?e(T,{title:"Request Body",icon:e(E,{size:14,color:o.color.accent}),defaultOpen:true,children:e(i,{style:t.emptyText,children:m?`Loading request body (${q(r.requestSize??0)})\u2026`:"Request body unavailable"})}):null,z!==void 0?e(T,{title:"Response Body",icon:e(E,{size:14,color:A}),defaultOpen:true,children:e(l,{style:t.dataViewerContainer,children:s?e(F,{title:"",data:z,showTypeFilter:true,rawMode:true,initialExpanded:true,disableCopy:!g}):e(Z,{})})}):y?e(T,{title:"Response Body",icon:e(E,{size:14,color:A}),defaultOpen:true,children:e(i,{style:t.emptyText,children:m?`Loading response body (${q(r.responseSize??0)})\u2026`:"Response body unavailable"})}):null,e(T,{title:"Filter Options",icon:e(ae,{size:14,color:o.color.warning}),defaultOpen:false,children:e(l,{style:t.filterOptionsContainer,children:(()=>{let a="";let S="";try{const j=new URL(r.url);a=j.hostname;S=j.pathname}catch{S=r.url}const I=u.has(a);const P=u.has(S);return n(W,{children:[n(O,{style:[t.filterOption,I&&t.filterOptionActive],onPress:()=>a&&h(a),children:[n(l,{style:t.filterOptionLeft,children:[e(se,{size:16,color:I?o.color.warning:o.color.textTertiary}),n(l,{style:t.filterOptionContent,children:[e(i,{style:t.filterOptionLabel,children:"Ignore Domain"}),e(i,{style:t.filterOptionValue,children:a||"N/A"})]})]}),e(l,{style:[t.filterToggle,I&&t.filterToggleActive],children:e(i,{style:[t.filterToggleText,I&&t.filterToggleTextActive],children:I?"IGNORED":"IGNORE"})})]}),n(O,{style:[t.filterOption,P&&t.filterOptionActive],onPress:()=>S&&h(S),children:[n(l,{style:t.filterOptionLeft,children:[e(ce,{size:16,color:P?o.color.warning:o.color.textTertiary}),n(l,{style:t.filterOptionContent,children:[e(i,{style:t.filterOptionLabel,children:"Ignore URL Pattern"}),e(i,{style:t.filterOptionValue,numberOfLines:1,children:S||"N/A"})]})]}),e(l,{style:[t.filterToggle,P&&t.filterToggleActive],children:e(i,{style:[t.filterToggleText,P&&t.filterToggleTextActive],children:P?"IGNORED":"IGNORE"})})]}),e(l,{style:t.filterInfoBox,children:e(i,{style:t.filterInfoText,children:"Ignored requests will be hidden from the network list. You can manage filters in the Filters tab."})})]})})()})})]}),e(pe,{visible:c,onClose:()=>f(false),featureName:"Copy Request Details",description:"Copy network request details to share or debug issues.",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"]})]})});const t=oe.create({container:{flex:1,backgroundColor:"transparent"},requestDetailsSection:{marginHorizontal:12,marginTop:12,backgroundColor:o.color.surface,borderRadius:8,borderWidth:1,borderColor:o.color.border,padding:12},httpHeader:{flexDirection:"row",alignItems:"center",gap:8,marginBottom:12,flexWrap:"nowrap"},httpMethodBadge:{backgroundColor:o.color.infoSoft,paddingHorizontal:8,paddingVertical:4,borderRadius:4},httpMethod:{color:o.color.info,fontSize:11,fontWeight:"700",letterSpacing:.5},httpStatusBadge:{paddingHorizontal:8,paddingVertical:4,borderRadius:4},httpStatusText:{fontSize:11,fontWeight:"600"},pendingBadge:{flexDirection:"row",alignItems:"center",gap:4,backgroundColor:o.color.warningSoft,paddingHorizontal:8,paddingVertical:4,borderRadius:4},pendingBadgeText:{color:o.color.warning,fontSize:11,fontWeight:"600"},httpDuration:{flexDirection:"row",alignItems:"center",gap:4},httpDurationText:{color:o.color.textSecondary,fontSize:11},overrideBadge:{flexDirection:"row",alignItems:"center",gap:4,paddingHorizontal:6,paddingVertical:3,borderRadius:4,backgroundColor:o.color.warningSoft},overrideBadgeText:{color:o.color.warning,fontSize:10,fontWeight:"700"},copyFullButton:{marginLeft:"auto",flexShrink:0,padding:4},urlBreakdown:{backgroundColor:o.color.bg,borderRadius:4,padding:8},urlRow:{flexDirection:"row",alignItems:"center",gap:6,marginBottom:4},urlDomain:{color:o.color.text,fontSize:12,fontWeight:"600",flex:1},urlProtocol:{color:o.color.textTertiary,fontSize:10},copyButton:{padding:4},urlPathRow:{paddingLeft:18},urlPath:{color:o.color.textSecondary,fontSize:11,fontFamily:R},urlQueryString:{color:o.color.info,fontSize:11,fontFamily:R},queryParamsCollapsible:{marginTop:8},queryParamsToggle:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:12,paddingVertical:10,backgroundColor:o.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:o.color.border,marginBottom:8},queryParamsToggleText:{flexGrow:0,color:o.color.text,fontSize:12,fontWeight:"600",letterSpacing:.3},timingSection:{marginHorizontal:12,marginTop:8,backgroundColor:o.color.surface,borderRadius:8,borderWidth:1,borderColor:o.color.border,padding:12},timingRow:{flexDirection:"row",alignItems:"center",gap:6,flexWrap:"wrap"},timingLabel:{color:o.color.textSecondary,fontSize:11},timingValue:{color:o.color.text,fontSize:11,fontWeight:"600"},timingExact:{color:o.color.textTertiary,fontSize:10,marginLeft:4},sizeRow:{flexDirection:"row",alignItems:"center",gap:16,marginLeft:"auto"},sizeItem:{flexDirection:"row",alignItems:"center",gap:4},sizeLabel:{color:o.color.textTertiary,fontSize:10},sizeValue:{color:o.color.info,fontSize:10,fontFamily:R,fontWeight:"600"},phaseDivider:{height:1,backgroundColor:o.color.border,marginTop:12,marginBottom:12},phaseList:{gap:8},phaseRow:{flexDirection:"row",alignItems:"center",gap:14},phaseLabelGroup:{width:150},phaseLabel:{fontSize:12,color:o.color.textSecondary},phaseHint:{fontSize:10,color:o.color.textTertiary},phaseTrack:{flex:1,height:7,borderRadius:4,backgroundColor:o.color.surfaceElevated,justifyContent:"center",overflow:"hidden"},phaseBar:{height:7,borderRadius:4},phaseValue:{width:72,textAlign:"right",fontSize:12,fontFamily:R,color:o.color.text},collapsibleSection:{marginHorizontal:12,marginTop:8,backgroundColor:o.color.surface,borderRadius:8,borderWidth:1,borderColor:o.color.border,overflow:"hidden"},collapsibleHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:12,backgroundColor:o.color.surfaceElevated},collapsibleTitle:{flexDirection:"row",alignItems:"center",gap:8},collapsibleTitleText:{color:o.color.text,fontSize:13,fontWeight:"600"},collapsibleCount:{color:o.color.textTertiary,fontSize:11.5,fontFamily:R},collapsibleContent:{padding:12},dataViewerContainer:{marginTop:-12,marginHorizontal:-12,marginBottom:-12},bodyDeferred:{height:120},errorBox:{flexDirection:"row",alignItems:"center",gap:6,backgroundColor:o.color.dangerSoft,padding:8,borderRadius:4,marginTop:8},errorText:{color:o.color.danger,fontSize:11,flex:1},emptyText:{color:o.color.textTertiary,fontSize:12,fontStyle:"italic",textAlign:"center"},filterOptionsContainer:{gap:12},filterOption:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:o.color.surfaceElevated,borderRadius:8,padding:12,borderWidth:1,borderColor:o.color.border},filterOptionActive:{backgroundColor:o.color.warningSoft,borderColor:o.color.warning+"33"},filterOptionLeft:{flexDirection:"row",alignItems:"center",gap:12,flex:1},filterOptionContent:{flex:1},filterOptionLabel:{color:o.color.textSecondary,fontSize:11,marginBottom:2,textTransform:"uppercase",letterSpacing:.5},filterOptionValue:{color:o.color.text,fontSize:13,fontFamily:R},filterToggle:{paddingHorizontal:10,paddingVertical:6,borderRadius:4,backgroundColor:o.color.bg,borderWidth:1,borderColor:o.color.border},filterToggleActive:{backgroundColor:o.color.warningSoft,borderColor:o.color.warning+"4D"},filterToggleText:{fontSize:10,fontWeight:"600",color:o.color.textTertiary,letterSpacing:.5},filterToggleTextActive:{color:o.color.warning},filterInfoBox:{backgroundColor:o.color.infoSoft,borderRadius:6,padding:10,borderWidth:1,borderColor:o.color.info+"33"},filterInfoText:{color:o.color.textSecondary,fontSize:11,lineHeight:16}});