@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,826 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * NetworkOverridesScreen.web — DOM twin of NetworkOverridesScreen.tsx.
5
- *
6
- * The rule manager: what's armed, and how to stop all of it. One bar across
7
- * the top is both the warning and the switch; rules render in the request
8
- * row's visual language (card, method badge, monospace path, status colors);
9
- * the rule editor takes over the whole screen while open, with the header's
10
- * back press routed through `backHandlerRef` (back-while-editing means "back
11
- * to the rule list", not "leave overrides").
12
- *
13
- * REUSED, not forked (all platform-free): `useOverrideRules`,
14
- * `overrideRulesStore` (persisting via the shared-ui barrel → the web shim's
15
- * localStorage `persistentStorage`, SAME `@react_buoy_network_overrides` key
16
- * + JSON shape as the phone), `isRuleSpent`, the free-tier enforcement, and
17
- * the pending-draft adoption flow. A rule saved here is picked up by the live
18
- * `networkListener` through the exact hooks native registers
19
- * (`setOverrideHooks` at overrideRulesStore import).
20
- *
21
- * shared-ui RN chrome is replicated as DOM with provenance (web consumers
22
- * resolve `@buoy-gg/shared-ui` to a minimal shim):
23
- * - `macOSColors` / `buoyColors` — inlined verbatim subsets from
24
- * shared/src/ui/gameUI/constants/.
25
- * - Icons — inline lucide SVGs (shared-ui's icons are lucide re-exports).
26
- * - `DevToolsCard` / `MethodBadge` — inlined DOM twins, values from
27
- * shared/src/ui/components/DevToolsCard.tsx and Badge.tsx (same twins the
28
- * F2 list rows carry).
29
- * - `EmptyState` — inlined DOM twin, values from
30
- * shared/src/ui/components/EmptyState.tsx (including its shipped
31
- * low-contrast description color, documented there).
32
- *
33
- * Intentional deviations (all logged):
34
- * - `hitSlop` on the row delete button has no DOM equivalent — the button
35
- * keeps its natural hit area.
36
- *
37
- * @platform React DOM Web
38
- */
39
-
40
- import { useCallback, useEffect, useState } from "react";
41
- import { useOverrideRules } from "../hooks/useOverrideRules";
42
- import { NetworkOverrideEditor } from "./NetworkOverrideEditor.web";
43
- import { overrideRulesStore } from "../overrides/overrideRulesStore";
44
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
45
- // =============================
46
- // Native palettes (provenance)
47
- // =============================
48
-
49
- /** macOSColors subset — shared/src/ui/gameUI/constants/macOSDesignSystemColors.ts, verbatim. */
50
- const macOSColors = {
51
- background: {
52
- base: "#0A0A0C",
53
- card: "#1A1A1C"
54
- },
55
- border: {
56
- default: "#2D2D2F",
57
- hover: "#4D4D4F"
58
- },
59
- text: {
60
- primary: "#F5F5F7",
61
- secondary: "#A1A1A6",
62
- muted: "#8E8E93",
63
- icon: "#6D6D6F"
64
- },
65
- semantic: {
66
- success: "#34C759",
67
- error: "#FF453A",
68
- warning: "#FFEB3B",
69
- warningBackground: "rgba(255, 235, 59, 0.15)",
70
- info: "#00B8E6"
71
- }
72
- };
73
-
74
- /** buoyColors subset — shared/src/ui/gameUI/constants/gameUIColors.ts (macOS theme), verbatim. */
75
- const buoy = {
76
- card: "#1A1A1A",
77
- border: "#333333",
78
- textSecondary: "#A0A0A0",
79
- textMuted: "#888888",
80
- primary: "#20C997",
81
- success: "#20C997",
82
- warning: "#FFA94D",
83
- error: "#EF4444"
84
- };
85
-
86
- // =============================
87
- // Inline lucide icons (shared-ui icons are lucide re-exports)
88
- // =============================
89
-
90
- function Svg({
91
- size = 14,
92
- color = "currentColor",
93
- children
94
- }) {
95
- return /*#__PURE__*/_jsx("svg", {
96
- width: size,
97
- height: size,
98
- viewBox: "0 0 24 24",
99
- fill: "none",
100
- stroke: color,
101
- strokeWidth: 2,
102
- strokeLinecap: "round",
103
- strokeLinejoin: "round",
104
- style: {
105
- flexShrink: 0,
106
- display: "block"
107
- },
108
- children: children
109
- });
110
- }
111
- const AlertCircle = p => /*#__PURE__*/_jsxs(Svg, {
112
- ...p,
113
- children: [/*#__PURE__*/_jsx("circle", {
114
- cx: "12",
115
- cy: "12",
116
- r: "10"
117
- }), /*#__PURE__*/_jsx("line", {
118
- x1: "12",
119
- x2: "12",
120
- y1: "8",
121
- y2: "12"
122
- }), /*#__PURE__*/_jsx("line", {
123
- x1: "12",
124
- x2: "12.01",
125
- y1: "16",
126
- y2: "16"
127
- })]
128
- });
129
- const AlertTriangle = p => /*#__PURE__*/_jsxs(Svg, {
130
- ...p,
131
- children: [/*#__PURE__*/_jsx("path", {
132
- d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 20h16a2 2 0 0 0 1.73-2Z"
133
- }), /*#__PURE__*/_jsx("path", {
134
- d: "M12 9v4"
135
- }), /*#__PURE__*/_jsx("path", {
136
- d: "M12 17h.01"
137
- })]
138
- });
139
- const FlaskConical = p => /*#__PURE__*/_jsxs(Svg, {
140
- ...p,
141
- children: [/*#__PURE__*/_jsx("path", {
142
- d: "M10 2v7.527a2 2 0 0 1-.211.896L4.72 20.55a1 1 0 0 0 .9 1.45h12.76a1 1 0 0 0 .9-1.45l-5.069-10.127A2 2 0 0 1 14 9.527V2"
143
- }), /*#__PURE__*/_jsx("path", {
144
- d: "M8.5 2h7"
145
- }), /*#__PURE__*/_jsx("path", {
146
- d: "M7 16h10"
147
- })]
148
- });
149
- const Plus = p => /*#__PURE__*/_jsxs(Svg, {
150
- ...p,
151
- children: [/*#__PURE__*/_jsx("path", {
152
- d: "M5 12h14"
153
- }), /*#__PURE__*/_jsx("path", {
154
- d: "M12 5v14"
155
- })]
156
- });
157
- const Trash2 = p => /*#__PURE__*/_jsxs(Svg, {
158
- ...p,
159
- children: [/*#__PURE__*/_jsx("path", {
160
- d: "M3 6h18"
161
- }), /*#__PURE__*/_jsx("path", {
162
- d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"
163
- }), /*#__PURE__*/_jsx("path", {
164
- d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"
165
- }), /*#__PURE__*/_jsx("line", {
166
- x1: "10",
167
- x2: "10",
168
- y1: "11",
169
- y2: "17"
170
- }), /*#__PURE__*/_jsx("line", {
171
- x1: "14",
172
- x2: "14",
173
- y1: "11",
174
- y2: "17"
175
- })]
176
- });
177
-
178
- // =============================
179
- // shared-ui DOM twins (provenance: Badge.tsx / DevToolsCard.tsx / EmptyState.tsx)
180
- // =============================
181
-
182
- /**
183
- * MethodBadge twin — shared/src/ui/components/Badge.tsx `MethodBadge`
184
- * (`size="small"`: 6/2 padding, 11px, weight 700, minWidth 45, `${color}15`
185
- * fill, `${color}40` border, radius 4). METHOD_COLORS map, verbatim — an
186
- * unknown method (the rule rows' "ANY", or "GET/POST") falls to #6B7280,
187
- * same as native.
188
- */
189
- const METHOD_COLORS = {
190
- GET: buoy.success,
191
- POST: buoy.primary,
192
- PUT: buoy.warning,
193
- PATCH: buoy.textSecondary,
194
- DELETE: buoy.error,
195
- HEAD: buoy.textMuted,
196
- OPTIONS: buoy.primary
197
- };
198
- function MethodBadgeWeb({
199
- method
200
- }) {
201
- const color = METHOD_COLORS[method.toUpperCase()] || "#6B7280";
202
- return /*#__PURE__*/_jsx("span", {
203
- style: {
204
- display: "inline-flex",
205
- alignItems: "center",
206
- justifyContent: "center",
207
- minWidth: 45,
208
- boxSizing: "border-box",
209
- padding: "2px 6px",
210
- fontSize: 11,
211
- fontWeight: 700,
212
- color,
213
- backgroundColor: `${color}15`,
214
- border: `1px solid ${color}40`,
215
- borderRadius: 4,
216
- flexShrink: 0
217
- },
218
- children: method.toUpperCase()
219
- });
220
- }
221
-
222
- /**
223
- * DevToolsCard twin — shared/src/ui/components/DevToolsCard.tsx (buoyColors
224
- * card fill, `${border}40` outline + bottom hairline, radius 8, padding 12,
225
- * minHeight 44). The rule list zeroes the wrapper margins — the list's own
226
- * gap spaces rows, same as native `cardWrapper`.
227
- */
228
- function DevToolsCardWeb({
229
- onPress,
230
- children,
231
- contentStyle
232
- }) {
233
- return /*#__PURE__*/_jsx("div", {
234
- style: {
235
- margin: 0
236
- },
237
- children: /*#__PURE__*/_jsx("div", {
238
- role: "button",
239
- tabIndex: 0,
240
- onClick: onPress,
241
- onKeyDown: e => {
242
- if (e.key === "Enter" || e.key === " ") onPress();
243
- },
244
- style: {
245
- backgroundColor: buoy.card,
246
- border: `1px solid ${buoy.border}40`,
247
- borderBottom: `1px solid ${buoy.border}`,
248
- borderRadius: 8,
249
- padding: 12,
250
- minHeight: 44,
251
- boxSizing: "border-box",
252
- cursor: "pointer",
253
- ...contentStyle
254
- },
255
- children: children
256
- })
257
- });
258
- }
259
-
260
- /**
261
- * EmptyState twin — shared/src/ui/components/EmptyState.tsx, default variant
262
- * (icon 48 @ border.hover, 16/500 title in text.icon, 14px description in
263
- * border.hover — the shipped low-contrast look, documented in the native
264
- * file).
265
- */
266
- function EmptyStateWeb({
267
- icon,
268
- title,
269
- description
270
- }) {
271
- const Icon = icon;
272
- return /*#__PURE__*/_jsx("div", {
273
- style: styles.emptyContainer,
274
- children: /*#__PURE__*/_jsxs("div", {
275
- style: styles.emptyContent,
276
- children: [/*#__PURE__*/_jsx("div", {
277
- style: {
278
- marginBottom: 16
279
- },
280
- children: /*#__PURE__*/_jsx(Icon, {
281
- size: 48,
282
- color: macOSColors.border.hover
283
- })
284
- }), /*#__PURE__*/_jsx("div", {
285
- style: styles.emptyTitle,
286
- children: title
287
- }), /*#__PURE__*/_jsx("div", {
288
- style: styles.emptyDescription,
289
- children: description
290
- })]
291
- })
292
- });
293
- }
294
-
295
- // =============================
296
- // Screen (structure mirrors the native file 1:1)
297
- // =============================
298
-
299
- function blankDraft() {
300
- return {
301
- enabled: true,
302
- urlPattern: "",
303
- kind: "respond",
304
- status: 500,
305
- body: "",
306
- times: null
307
- };
308
- }
309
- function toDraft(rule) {
310
- const {
311
- id: _id,
312
- hits: _hits,
313
- seen: _seen,
314
- createdAt: _createdAt,
315
- ...draft
316
- } = rule;
317
- return draft;
318
- }
319
-
320
- /**
321
- * Where the rule applies — PATH only, not the whole URL (the host is the same
322
- * for every rule in a typical app; same reasoning as the request row's
323
- * `displayUrl`).
324
- */
325
- function patternPath(rule) {
326
- const path = rule.urlPattern;
327
- const schemeEnd = path.indexOf("://");
328
- if (schemeEnd === -1) return path;
329
- const slash = path.indexOf("/", schemeEnd + 3);
330
- return slash === -1 ? path.slice(schemeEnd + 3) : path.slice(slash);
331
- }
332
-
333
- /** Delay and lifetime, in the editor's own words. Empty for a plain rule. */
334
- function extrasLine(rule) {
335
- const parts = [];
336
- if (rule.delayMs) parts.push(`${rule.delayMs / 1000}s delay`);
337
- if (rule.alternate) parts.push("every other");else if (rule.times === 1) parts.push("once");else if (typeof rule.times === "number") parts.push(`${rule.times}×`);
338
- return parts.join(" · ");
339
- }
340
-
341
- /** The outcome's color, on the request list's status scale — a forced 500
342
- * should look exactly like a real one. */
343
- function ruleAccent(rule) {
344
- if (rule.kind === "fail") return macOSColors.semantic.error;
345
- if (rule.kind === "delay") return macOSColors.semantic.info;
346
- const status = rule.status ?? 200;
347
- if (status >= 200 && status < 300) return macOSColors.semantic.success;
348
- if (status >= 300 && status < 400) return macOSColors.semantic.info;
349
- return macOSColors.semantic.error;
350
- }
351
-
352
- /**
353
- * One rule, in the request row's visual language — same card, method badge,
354
- * monospace path and status colors as `NetworkEventItemCompact`. A trash
355
- * instead of the type chip and chevron; the outcome color floods the left
356
- * edge only while the rule is live. No per-rule on/off — delete the rule, or
357
- * pause everything from the master bar. (Native comment.)
358
- */
359
- function RuleRow({
360
- rule,
361
- spent,
362
- onEdit,
363
- onDelete
364
- }) {
365
- const live = rule.enabled && !spent;
366
- const accent = ruleAccent(rule);
367
- const extras = extrasLine(rule);
368
- const method = rule.methods?.length ? rule.methods.join("/") : "ANY";
369
- return /*#__PURE__*/_jsxs(DevToolsCardWeb, {
370
- onPress: onEdit,
371
- contentStyle: {
372
- ...styles.card,
373
- borderLeft: `3px solid ${live ? accent : "transparent"}`
374
- },
375
- children: [/*#__PURE__*/_jsx(MethodBadgeWeb, {
376
- method: method
377
- }), /*#__PURE__*/_jsxs("div", {
378
- style: styles.cardMiddle,
379
- children: [/*#__PURE__*/_jsx("div", {
380
- style: {
381
- ...styles.urlText,
382
- ...(!live ? styles.urlTextOff : null)
383
- },
384
- children: patternPath(rule)
385
- }), extras ? /*#__PURE__*/_jsx("div", {
386
- style: styles.extrasText,
387
- children: extras
388
- }) : null]
389
- }), rule.hits > 0 ? /*#__PURE__*/_jsx("span", {
390
- style: styles.rowHits,
391
- children: rule.hits
392
- }) : null, rule.kind === "fail" ? /*#__PURE__*/_jsxs("span", {
393
- style: styles.failBadge,
394
- children: [/*#__PURE__*/_jsx(AlertCircle, {
395
- size: 10,
396
- color: macOSColors.semantic.error
397
- }), /*#__PURE__*/_jsx("span", {
398
- style: styles.failText,
399
- children: rule.failKind === "timeout" ? "TIMEOUT" : "OFFLINE"
400
- })]
401
- }) : /*#__PURE__*/_jsx("span", {
402
- style: {
403
- ...styles.statusText,
404
- color: accent
405
- },
406
- children: rule.kind === "delay" ? "PASS" : String(rule.status ?? 200)
407
- }), /*#__PURE__*/_jsx("button", {
408
- type: "button",
409
- onClick: e => {
410
- // The delete sits inside the card's press target — stop the row's
411
- // edit from also firing (native gets this free from nested
412
- // touchables).
413
- e.stopPropagation();
414
- onDelete();
415
- },
416
- "aria-label": "Delete rule",
417
- style: styles.rowDelete,
418
- children: /*#__PURE__*/_jsx(Trash2, {
419
- size: 13,
420
- color: macOSColors.text.muted
421
- })
422
- })]
423
- });
424
- }
425
- /**
426
- * Stable-router gate — same convention as native: a HIDDEN screen must not
427
- * subscribe to anything, so the subscribing body is split out and the shell
428
- * returns null.
429
- */
430
- export function NetworkOverridesScreen(props) {
431
- if (!props.visible) return null;
432
- return /*#__PURE__*/_jsx(OverridesBody, {
433
- ...props
434
- });
435
- }
436
- function OverridesBody({
437
- isPro,
438
- onUpgradePress: _onUpgradePress,
439
- pendingDraft,
440
- onPendingConsumed,
441
- backHandlerRef,
442
- applySafeAreaInset
443
- }) {
444
- const {
445
- enabled,
446
- autoPaused,
447
- rules,
448
- activeCount,
449
- setEnabled,
450
- upsertRule,
451
- setRuleEnabled,
452
- removeRule,
453
- isRuleSpent
454
- } = useOverrideRules();
455
- const [editing, setEditing] = useState(null);
456
-
457
- // Reaching this screen proves the app renders, so the launch-safety streak
458
- // has nothing to guard against — see `noteHealthyLaunch`.
459
- useEffect(() => {
460
- overrideRulesStore.noteHealthyLaunch();
461
- }, []);
462
-
463
- // Back while editing means "back to the rule list", not "leave overrides".
464
- // Cleared on unmount so a hidden screen can't swallow back presses.
465
- useEffect(() => {
466
- if (!backHandlerRef) return;
467
- backHandlerRef.current = editing ? () => {
468
- setEditing(null);
469
- return true;
470
- } : null;
471
- return () => {
472
- backHandlerRef.current = null;
473
- };
474
- }, [backHandlerRef, editing]);
475
-
476
- /**
477
- * Open a rule for editing, pulling its body over if this surface doesn't
478
- * have it. On the device (and this webview) that fetch resolves locally and
479
- * immediately; the `id` re-check keeps a slow reply from landing in a rule
480
- * you've since moved on from. (Native comment — kept for parity.)
481
- */
482
- const hydrateBody = useCallback(id => {
483
- void overrideRulesStore.fetchRuleBody(id).then(body => {
484
- if (body == null) return;
485
- setEditing(current => current?.id === id ? {
486
- ...current,
487
- draft: {
488
- ...current.draft,
489
- body,
490
- bodyOmitted: undefined
491
- }
492
- } : current);
493
- });
494
- }, []);
495
- useEffect(() => {
496
- if (!pendingDraft) return;
497
- const {
498
- id,
499
- ...draft
500
- } = pendingDraft;
501
- setEditing({
502
- id,
503
- draft
504
- });
505
- if (id && draft.bodyOmitted) hydrateBody(id);
506
- onPendingConsumed?.();
507
- }, [pendingDraft, onPendingConsumed, hydrateBody]);
508
-
509
- /**
510
- * Leave the editor when the rule it's editing stops existing — without
511
- * this, Save would upsert the old id and quietly RESURRECT a rule someone
512
- * had just deleted (dashboard / MCP agent). Only guards existing rules.
513
- */
514
- useEffect(() => {
515
- if (!editing?.id) return;
516
- if (rules.some(rule => rule.id === editing.id)) return;
517
- setEditing(null);
518
- }, [editing?.id, rules]);
519
- const openRule = rule => {
520
- setEditing({
521
- id: rule.id,
522
- draft: toDraft(rule)
523
- });
524
- if (rule.bodyOmitted) hydrateBody(rule.id);
525
- };
526
-
527
- /**
528
- * On the free tier a new rule REPLACES the live one rather than being
529
- * refused — "one override at a time" is a shape a developer understands.
530
- * (Native comment.)
531
- */
532
- const enforceFreeTier = keepId => {
533
- if (isPro) return;
534
- rules.filter(rule => rule.enabled && !isRuleSpent(rule) && rule.id !== keepId).forEach(rule => setRuleEnabled(rule.id, false));
535
- };
536
- const handleSave = () => {
537
- if (!editing) return;
538
- // Saving always arms the rule — the ONLY way back on for a rule the free
539
- // tier disabled or that used itself up. (Native comment.)
540
- const draft = {
541
- ...editing.draft,
542
- enabled: true,
543
- urlPattern: editing.draft.urlPattern.trim()
544
- };
545
- if (!draft.urlPattern) return;
546
- const saved = upsertRule({
547
- ...draft,
548
- id: editing.id
549
- });
550
- enforceFreeTier(saved?.id ?? editing.id);
551
- // Arm the master switch — a deliberately-created rule sitting inert
552
- // because overrides happen to be paused is the silent-failure this
553
- // feature can least afford. (Native comment.)
554
- setEnabled(true);
555
- setEditing(null);
556
- };
557
- if (editing) {
558
- return /*#__PURE__*/_jsx(NetworkOverrideEditor, {
559
- draft: editing.draft,
560
- onChange: draft => setEditing({
561
- ...editing,
562
- draft
563
- }),
564
- onSave: handleSave,
565
- onCancel: () => setEditing(null),
566
- saveLabel: editing.id ? "Save" : "Add",
567
- applySafeAreaInset: applySafeAreaInset
568
- });
569
- }
570
- const hasRules = rules.length > 0;
571
- return /*#__PURE__*/_jsxs("div", {
572
- style: styles.root,
573
- children: [hasRules ? /*#__PURE__*/_jsxs("div", {
574
- style: {
575
- ...styles.bar,
576
- ...(enabled && activeCount > 0 ? styles.barOn : null)
577
- },
578
- children: [enabled && activeCount > 0 ? /*#__PURE__*/_jsx(AlertTriangle, {
579
- size: 12,
580
- color: macOSColors.semantic.warning
581
- }) : null, /*#__PURE__*/_jsx("span", {
582
- style: {
583
- ...styles.barText,
584
- ...(enabled && activeCount > 0 ? styles.barTextOn : null)
585
- },
586
- children: autoPaused ? "Overrides paused — they'd been on for 3 launches" : enabled && activeCount > 0 ? `${activeCount} override${activeCount === 1 ? " is" : "s are"} on` : "Overrides are off"
587
- }), /*#__PURE__*/_jsx("button", {
588
- type: "button",
589
- onClick: () => setEnabled(!(enabled && activeCount > 0)),
590
- style: styles.barButton,
591
- children: /*#__PURE__*/_jsx("span", {
592
- style: styles.barButtonText,
593
- children: enabled && activeCount > 0 ? "Turn all off" : autoPaused ? "Turn back on" : "Turn on"
594
- })
595
- })]
596
- }) : null, /*#__PURE__*/_jsxs("div", {
597
- style: styles.listHeader,
598
- children: [/*#__PURE__*/_jsx("span", {
599
- style: styles.listHeaderText,
600
- children: hasRules ? `${rules.length} rule${rules.length === 1 ? "" : "s"}` : ""
601
- }), /*#__PURE__*/_jsx("button", {
602
- type: "button",
603
- onClick: () => setEditing({
604
- draft: blankDraft()
605
- }),
606
- "aria-label": "New override rule",
607
- style: styles.newButton,
608
- children: /*#__PURE__*/_jsx(Plus, {
609
- size: 14,
610
- color: macOSColors.semantic.info
611
- })
612
- })]
613
- }), !hasRules ? /*#__PURE__*/_jsx("div", {
614
- style: styles.emptyWrap,
615
- children: /*#__PURE__*/_jsx(EmptyStateWeb, {
616
- icon: FlaskConical,
617
- title: "Nothing overridden",
618
- description: "Open any request and tap Override, or + to write a rule."
619
- })
620
- }) : /*#__PURE__*/_jsx("div", {
621
- style: styles.list,
622
- children: /*#__PURE__*/_jsxs("div", {
623
- style: styles.listContent,
624
- children: [rules.map(rule => /*#__PURE__*/_jsx(RuleRow, {
625
- rule: rule,
626
- spent: isRuleSpent(rule),
627
- onEdit: () => openRule(rule),
628
- onDelete: () => removeRule(rule.id)
629
- }, rule.id)), !isPro ? /*#__PURE__*/_jsx("span", {
630
- style: styles.footNote,
631
- children: "Free: one override at a time. Pro: up to 50."
632
- }) : null]
633
- })
634
- })]
635
- });
636
- }
637
-
638
- // Values mirror the native StyleSheet block 1:1.
639
- const styles = {
640
- root: {
641
- display: "flex",
642
- flexDirection: "column",
643
- flex: 1,
644
- minHeight: 0
645
- },
646
- bar: {
647
- display: "flex",
648
- flexDirection: "row",
649
- alignItems: "center",
650
- gap: 8,
651
- padding: "10px 12px",
652
- borderBottom: `1px solid ${macOSColors.border.default}`,
653
- backgroundColor: macOSColors.background.card
654
- },
655
- barOn: {
656
- borderBottom: `1px solid ${macOSColors.semantic.warning}44`,
657
- backgroundColor: macOSColors.semantic.warningBackground
658
- },
659
- barText: {
660
- flex: 1,
661
- minWidth: 0,
662
- fontSize: 12,
663
- fontWeight: 600,
664
- color: macOSColors.text.secondary
665
- },
666
- barTextOn: {
667
- color: macOSColors.semantic.warning
668
- },
669
- barButton: {
670
- padding: "6px 10px",
671
- borderRadius: 5,
672
- border: `1px solid ${macOSColors.border.hover}`,
673
- backgroundColor: macOSColors.background.base,
674
- cursor: "pointer",
675
- margin: 0,
676
- flexShrink: 0
677
- },
678
- barButtonText: {
679
- fontSize: 11,
680
- fontWeight: 700,
681
- color: macOSColors.text.primary,
682
- whiteSpace: "nowrap"
683
- },
684
- listHeader: {
685
- display: "flex",
686
- flexDirection: "row",
687
- alignItems: "center",
688
- justifyContent: "space-between",
689
- padding: "10px 12px 4px"
690
- },
691
- listHeaderText: {
692
- fontSize: 10,
693
- fontWeight: 700,
694
- letterSpacing: 0.6,
695
- color: macOSColors.text.muted,
696
- textTransform: "uppercase"
697
- },
698
- newButton: {
699
- display: "inline-flex",
700
- padding: 6,
701
- borderRadius: 5,
702
- border: `1px solid ${macOSColors.border.default}`,
703
- backgroundColor: macOSColors.background.card,
704
- cursor: "pointer",
705
- margin: 0
706
- },
707
- emptyWrap: {
708
- flex: 1,
709
- minHeight: 0,
710
- display: "flex",
711
- flexDirection: "column",
712
- justifyContent: "center"
713
- },
714
- list: {
715
- flex: 1,
716
- minHeight: 0,
717
- overflowY: "auto"
718
- },
719
- listContent: {
720
- padding: 10,
721
- display: "flex",
722
- flexDirection: "column",
723
- gap: 6
724
- },
725
- card: {
726
- display: "flex",
727
- flexDirection: "row",
728
- alignItems: "center",
729
- gap: 8
730
- },
731
- cardMiddle: {
732
- flex: 1,
733
- minWidth: 0
734
- },
735
- // Same type as the request row's URL.
736
- urlText: {
737
- fontSize: 12,
738
- color: macOSColors.text.primary,
739
- lineHeight: "16px",
740
- fontFamily: "ui-monospace, Menlo, monospace",
741
- display: "-webkit-box",
742
- WebkitLineClamp: 2,
743
- WebkitBoxOrient: "vertical",
744
- overflow: "hidden",
745
- overflowWrap: "anywhere"
746
- },
747
- urlTextOff: {
748
- color: macOSColors.text.muted
749
- },
750
- extrasText: {
751
- fontSize: 10,
752
- color: macOSColors.text.secondary,
753
- marginTop: 2
754
- },
755
- statusText: {
756
- fontSize: 11,
757
- fontWeight: 600,
758
- flexShrink: 0
759
- },
760
- failBadge: {
761
- display: "inline-flex",
762
- flexDirection: "row",
763
- alignItems: "center",
764
- gap: 2,
765
- padding: "1px 4px",
766
- backgroundColor: `${macOSColors.semantic.error}26`,
767
- borderRadius: 3,
768
- flexShrink: 0
769
- },
770
- failText: {
771
- fontSize: 10,
772
- color: macOSColors.semantic.error,
773
- fontWeight: 600
774
- },
775
- rowHits: {
776
- fontSize: 11,
777
- fontWeight: 700,
778
- color: macOSColors.semantic.warning,
779
- flexShrink: 0
780
- },
781
- rowDelete: {
782
- display: "inline-flex",
783
- padding: 5,
784
- borderRadius: 5,
785
- border: `1px solid ${macOSColors.border.default}`,
786
- backgroundColor: macOSColors.background.base,
787
- cursor: "pointer",
788
- margin: 0,
789
- flexShrink: 0
790
- },
791
- footNote: {
792
- fontSize: 10,
793
- lineHeight: "14px",
794
- color: macOSColors.text.muted,
795
- padding: "8px 4px 0"
796
- },
797
- // EmptyState.tsx styles, verbatim (default variant).
798
- emptyContainer: {
799
- flex: 1,
800
- display: "flex",
801
- flexDirection: "column",
802
- justifyContent: "center",
803
- alignItems: "center",
804
- padding: 32
805
- },
806
- emptyContent: {
807
- display: "flex",
808
- flexDirection: "column",
809
- alignItems: "center",
810
- maxWidth: 300
811
- },
812
- emptyTitle: {
813
- color: macOSColors.text.icon,
814
- fontSize: 16,
815
- fontWeight: 500,
816
- textAlign: "center",
817
- marginBottom: 8
818
- },
819
- emptyDescription: {
820
- // Shipped low-contrast look — see the note in the native EmptyState.tsx.
821
- color: macOSColors.border.hover,
822
- fontSize: 14,
823
- textAlign: "center",
824
- lineHeight: "20px"
825
- }
826
- };
1
+ "use strict";import{useCallback as F,useEffect as k,useState as z}from"react";import{useOverrideRules as $}from"../hooks/useOverrideRules";import{NetworkOverrideEditor as H}from"./NetworkOverrideEditor.web";import{overrideRulesStore as A}from"../overrides/overrideRulesStore";import{jsx as t,jsxs as c}from"react/jsx-runtime";const n={background:{base:"#0A0A0C",card:"#1A1A1C"},border:{default:"#2D2D2F",hover:"#4D4D4F"},text:{primary:"#F5F5F7",secondary:"#A1A1A6",muted:"#8E8E93",icon:"#6D6D6F"},semantic:{success:"#34C759",error:"#FF453A",warning:"#FFEB3B",warningBackground:"rgba(255, 235, 59, 0.15)",info:"#00B8E6"}};const u={card:"#1A1A1A",border:"#333333",textSecondary:"#A0A0A0",textMuted:"#888888",primary:"#20C997",success:"#20C997",warning:"#FFA94D",error:"#EF4444"};function b({size:e=14,color:r="currentColor",children:l}){return t("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:r,strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",style:{flexShrink:0,display:"block"},children:l})}const P=e=>c(b,{...e,children:[t("circle",{cx:"12",cy:"12",r:"10"}),t("line",{x1:"12",x2:"12",y1:"8",y2:"12"}),t("line",{x1:"12",x2:"12.01",y1:"16",y2:"16"})]});const R=e=>c(b,{...e,children:[t("path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 20h16a2 2 0 0 0 1.73-2Z"}),t("path",{d:"M12 9v4"}),t("path",{d:"M12 17h.01"})]});const I=e=>c(b,{...e,children:[t("path",{d:"M10 2v7.527a2 2 0 0 1-.211.896L4.72 20.55a1 1 0 0 0 .9 1.45h12.76a1 1 0 0 0 .9-1.45l-5.069-10.127A2 2 0 0 1 14 9.527V2"}),t("path",{d:"M8.5 2h7"}),t("path",{d:"M7 16h10"})]});const j=e=>c(b,{...e,children:[t("path",{d:"M5 12h14"}),t("path",{d:"M12 5v14"})]});const L=e=>c(b,{...e,children:[t("path",{d:"M3 6h18"}),t("path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"}),t("path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"}),t("line",{x1:"10",x2:"10",y1:"11",y2:"17"}),t("line",{x1:"14",x2:"14",y1:"11",y2:"17"})]});const N={GET:u.success,POST:u.primary,PUT:u.warning,PATCH:u.textSecondary,DELETE:u.error,HEAD:u.textMuted,OPTIONS:u.primary};function _({method:e}){const r=N[e.toUpperCase()]||"#6B7280";return t("span",{style:{display:"inline-flex",alignItems:"center",justifyContent:"center",minWidth:45,boxSizing:"border-box",padding:"2px 6px",fontSize:11,fontWeight:700,color:r,backgroundColor:`${r}15`,border:`1px solid ${r}40`,borderRadius:4,flexShrink:0},children:e.toUpperCase()})}function U({onPress:e,children:r,contentStyle:l}){return t("div",{style:{margin:0},children:t("div",{role:"button",tabIndex:0,onClick:e,onKeyDown:a=>{if(a.key==="Enter"||a.key===" ")e()},style:{backgroundColor:u.card,border:`1px solid ${u.border}40`,borderBottom:`1px solid ${u.border}`,borderRadius:8,padding:12,minHeight:44,boxSizing:"border-box",cursor:"pointer",...l},children:r})})}function V({icon:e,title:r,description:l}){const a=e;return t("div",{style:i.emptyContainer,children:c("div",{style:i.emptyContent,children:[t("div",{style:{marginBottom:16},children:t(a,{size:48,color:n.border.hover})}),t("div",{style:i.emptyTitle,children:r}),t("div",{style:i.emptyDescription,children:l})]})})}function K(){return{enabled:true,urlPattern:"",kind:"respond",status:500,body:"",times:null}}function Y(e){const{id:r,hits:l,seen:a,createdAt:x,...m}=e;return m}function q(e){const r=e.urlPattern;const l=r.indexOf("://");if(l===-1)return r;const a=r.indexOf("/",l+3);return a===-1?r.slice(l+3):r.slice(a)}function G(e){const r=[];if(e.delayMs)r.push(`${e.delayMs/1e3}s delay`);if(e.alternate)r.push("every other");else if(e.times===1)r.push("once");else if(typeof e.times==="number")r.push(`${e.times}\xD7`);return r.join(" \xB7 ")}function Z(e){if(e.kind==="fail")return n.semantic.error;if(e.kind==="delay")return n.semantic.info;const r=e.status??200;if(r>=200&&r<300)return n.semantic.success;if(r>=300&&r<400)return n.semantic.info;return n.semantic.error}function J({rule:e,spent:r,onEdit:l,onDelete:a}){const x=e.enabled&&!r;const m=Z(e);const f=G(e);const g=e.methods?.length?e.methods.join("/"):"ANY";return c(U,{onPress:l,contentStyle:{...i.card,borderLeft:`3px solid ${x?m:"transparent"}`},children:[t(_,{method:g}),c("div",{style:i.cardMiddle,children:[t("div",{style:{...i.urlText,...!x?i.urlTextOff:null},children:q(e)}),f?t("div",{style:i.extrasText,children:f}):null]}),e.hits>0?t("span",{style:i.rowHits,children:e.hits}):null,e.kind==="fail"?c("span",{style:i.failBadge,children:[t(P,{size:10,color:n.semantic.error}),t("span",{style:i.failText,children:e.failKind==="timeout"?"TIMEOUT":"OFFLINE"})]}):t("span",{style:{...i.statusText,color:m},children:e.kind==="delay"?"PASS":String(e.status??200)}),t("button",{type:"button",onClick:p=>{p.stopPropagation();a()},"aria-label":"Delete rule",style:i.rowDelete,children:t(L,{size:13,color:n.text.muted})})]})}export function NetworkOverridesScreen(e){if(!e.visible)return null;return t(Q,{...e})}function Q({isPro:e,onUpgradePress:r,pendingDraft:l,onPendingConsumed:a,backHandlerRef:x,applySafeAreaInset:m}){const{enabled:f,autoPaused:g,rules:p,activeCount:y,setEnabled:T,upsertRule:O,setRuleEnabled:D,removeRule:B,isRuleSpent:w}=$();const[d,h]=z(null);k(()=>{A.noteHealthyLaunch()},[]);k(()=>{if(!x)return;x.current=d?()=>{h(null);return true}:null;return()=>{x.current=null}},[x,d]);const S=F(o=>{void A.fetchRuleBody(o).then(s=>{if(s==null)return;h(v=>v?.id===o?{...v,draft:{...v.draft,body:s,bodyOmitted:void 0}}:v)})},[]);k(()=>{if(!l)return;const{id:o,...s}=l;h({id:o,draft:s});if(o&&s.bodyOmitted)S(o);a?.()},[l,a,S]);k(()=>{if(!d?.id)return;if(p.some(o=>o.id===d.id))return;h(null)},[d?.id,p]);const E=o=>{h({id:o.id,draft:Y(o)});if(o.bodyOmitted)S(o.id)};const W=o=>{if(e)return;p.filter(s=>s.enabled&&!w(s)&&s.id!==o).forEach(s=>D(s.id,false))};const M=()=>{if(!d)return;const o={...d.draft,enabled:true,urlPattern:d.draft.urlPattern.trim()};if(!o.urlPattern)return;const s=O({...o,id:d.id});W(s?.id??d.id);T(true);h(null)};if(d){return t(H,{draft:d.draft,onChange:o=>h({...d,draft:o}),onSave:M,onCancel:()=>h(null),saveLabel:d.id?"Save":"Add",applySafeAreaInset:m})}const C=p.length>0;return c("div",{style:i.root,children:[C?c("div",{style:{...i.bar,...f&&y>0?i.barOn:null},children:[f&&y>0?t(R,{size:12,color:n.semantic.warning}):null,t("span",{style:{...i.barText,...f&&y>0?i.barTextOn:null},children:g?"Overrides paused \u2014 they'd been on for 3 launches":f&&y>0?`${y} override${y===1?" is":"s are"} on`:"Overrides are off"}),t("button",{type:"button",onClick:()=>T(!(f&&y>0)),style:i.barButton,children:t("span",{style:i.barButtonText,children:f&&y>0?"Turn all off":g?"Turn back on":"Turn on"})})]}):null,c("div",{style:i.listHeader,children:[t("span",{style:i.listHeaderText,children:C?`${p.length} rule${p.length===1?"":"s"}`:""}),t("button",{type:"button",onClick:()=>h({draft:K()}),"aria-label":"New override rule",style:i.newButton,children:t(j,{size:14,color:n.semantic.info})})]}),!C?t("div",{style:i.emptyWrap,children:t(V,{icon:I,title:"Nothing overridden",description:"Open any request and tap Override, or + to write a rule."})}):t("div",{style:i.list,children:c("div",{style:i.listContent,children:[p.map(o=>t(J,{rule:o,spent:w(o),onEdit:()=>E(o),onDelete:()=>B(o.id)},o.id)),!e?t("span",{style:i.footNote,children:"Free: one override at a time. Pro: up to 50."}):null]})})]})}const i={root:{display:"flex",flexDirection:"column",flex:1,minHeight:0},bar:{display:"flex",flexDirection:"row",alignItems:"center",gap:8,padding:"10px 12px",borderBottom:`1px solid ${n.border.default}`,backgroundColor:n.background.card},barOn:{borderBottom:`1px solid ${n.semantic.warning}44`,backgroundColor:n.semantic.warningBackground},barText:{flex:1,minWidth:0,fontSize:12,fontWeight:600,color:n.text.secondary},barTextOn:{color:n.semantic.warning},barButton:{padding:"6px 10px",borderRadius:5,border:`1px solid ${n.border.hover}`,backgroundColor:n.background.base,cursor:"pointer",margin:0,flexShrink:0},barButtonText:{fontSize:11,fontWeight:700,color:n.text.primary,whiteSpace:"nowrap"},listHeader:{display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:"10px 12px 4px"},listHeaderText:{fontSize:10,fontWeight:700,letterSpacing:.6,color:n.text.muted,textTransform:"uppercase"},newButton:{display:"inline-flex",padding:6,borderRadius:5,border:`1px solid ${n.border.default}`,backgroundColor:n.background.card,cursor:"pointer",margin:0},emptyWrap:{flex:1,minHeight:0,display:"flex",flexDirection:"column",justifyContent:"center"},list:{flex:1,minHeight:0,overflowY:"auto"},listContent:{padding:10,display:"flex",flexDirection:"column",gap:6},card:{display:"flex",flexDirection:"row",alignItems:"center",gap:8},cardMiddle:{flex:1,minWidth:0},urlText:{fontSize:12,color:n.text.primary,lineHeight:"16px",fontFamily:"ui-monospace, Menlo, monospace",display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden",overflowWrap:"anywhere"},urlTextOff:{color:n.text.muted},extrasText:{fontSize:10,color:n.text.secondary,marginTop:2},statusText:{fontSize:11,fontWeight:600,flexShrink:0},failBadge:{display:"inline-flex",flexDirection:"row",alignItems:"center",gap:2,padding:"1px 4px",backgroundColor:`${n.semantic.error}26`,borderRadius:3,flexShrink:0},failText:{fontSize:10,color:n.semantic.error,fontWeight:600},rowHits:{fontSize:11,fontWeight:700,color:n.semantic.warning,flexShrink:0},rowDelete:{display:"inline-flex",padding:5,borderRadius:5,border:`1px solid ${n.border.default}`,backgroundColor:n.background.base,cursor:"pointer",margin:0,flexShrink:0},footNote:{fontSize:10,lineHeight:"14px",color:n.text.muted,padding:"8px 4px 0"},emptyContainer:{flex:1,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",padding:32},emptyContent:{display:"flex",flexDirection:"column",alignItems:"center",maxWidth:300},emptyTitle:{color:n.text.icon,fontSize:16,fontWeight:500,textAlign:"center",marginBottom:8},emptyDescription:{color:n.border.hover,fontSize:14,textAlign:"center",lineHeight:"20px"}};