@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,814 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.NetworkOverrideEditor = NetworkOverrideEditor;
7
- var _react = require("react");
8
- var _reactNative = require("react-native");
9
- var _sharedUi = require("@buoy-gg/shared-ui");
10
- var _Explorer = _interopRequireDefault(require("./response-editor/Explorer"));
11
- var _editorContext = require("./response-editor/editorContext");
12
- var _NetworkNumberPrompt = require("./NetworkNumberPrompt");
13
- var _types = require("../overrides/types");
14
- var _jsxRuntime = require("react/jsx-runtime");
15
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
- /**
17
- * The rule form — one decision, everything else out of the way.
18
- *
19
- * It used to ask for six things at equal weight (URL, method, kind, status,
20
- * body, lifetime) with three paragraphs of hint text explaining them. That's a
21
- * form, not a tool, and the hints were the tell: a control that needs a
22
- * paragraph is the wrong control.
23
- *
24
- * Two things fixed it.
25
- *
26
- * FIRST, `kind` is gone from the UI. `respond | fail | delay` is our data
27
- * model, not the developer's — nobody thinks "kind=respond, status=500", they
28
- * think "make it a 500" or "make it go offline". Folding kind + status +
29
- * failKind into a single OUTCOME list removes a section, a paragraph, and an
30
- * entire concept, and every option now says what it does without being
31
- * explained.
32
- *
33
- * SECOND, everything that arrives already correct is collapsed. A rule made
34
- * from a real request knows its URL and method, so those become one summary
35
- * line you can open if you need it. The body is prefilled and usually edited in
36
- * the response tree instead, so it collapses too. What's left on arrival is the
37
- * question actually being asked.
38
- */const METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
39
- const DELAY_PRESETS = [0, 500, 1000, 3000, 10000];
40
-
41
- /**
42
- * The single decision, ordered by how often a developer reaches for it.
43
- *
44
- * Each carries a plain-language name AND its status code: scanning for "the
45
- * auth one" shouldn't require knowing that 401 is unauthorized, and someone who
46
- * does know should be able to find 401 without reading labels.
47
- */
48
-
49
- const OUTCOMES = [{
50
- id: "500",
51
- label: "Server error",
52
- code: "500",
53
- danger: true,
54
- patch: {
55
- kind: "respond",
56
- status: 500,
57
- statusText: "Internal Server Error"
58
- }
59
- }, {
60
- id: "401",
61
- label: "Unauthorized",
62
- code: "401",
63
- danger: true,
64
- patch: {
65
- kind: "respond",
66
- status: 401,
67
- statusText: "Unauthorized"
68
- }
69
- }, {
70
- id: "404",
71
- label: "Not found",
72
- code: "404",
73
- danger: true,
74
- patch: {
75
- kind: "respond",
76
- status: 404,
77
- statusText: "Not Found"
78
- }
79
- }, {
80
- id: "403",
81
- label: "Forbidden",
82
- code: "403",
83
- danger: true,
84
- patch: {
85
- kind: "respond",
86
- status: 403,
87
- statusText: "Forbidden"
88
- }
89
- }, {
90
- id: "429",
91
- label: "Rate limited",
92
- code: "429",
93
- danger: true,
94
- patch: {
95
- kind: "respond",
96
- status: 429,
97
- statusText: "Too Many Requests"
98
- }
99
- }, {
100
- id: "503",
101
- label: "Unavailable",
102
- code: "503",
103
- danger: true,
104
- patch: {
105
- kind: "respond",
106
- status: 503,
107
- statusText: "Service Unavailable"
108
- }
109
- }, {
110
- id: "400",
111
- label: "Bad request",
112
- code: "400",
113
- danger: true,
114
- patch: {
115
- kind: "respond",
116
- status: 400,
117
- statusText: "Bad Request"
118
- }
119
- }, {
120
- id: "200",
121
- label: "Success",
122
- code: "200",
123
- patch: {
124
- kind: "respond",
125
- status: 200,
126
- statusText: "OK"
127
- }
128
- }, {
129
- id: "offline",
130
- label: "Offline",
131
- danger: true,
132
- patch: {
133
- kind: "fail",
134
- failKind: "network"
135
- }
136
- }, {
137
- id: "timeout",
138
- label: "Timeout",
139
- danger: true,
140
- patch: {
141
- kind: "fail",
142
- failKind: "timeout"
143
- }
144
- }, {
145
- id: "passthrough",
146
- label: "Real response",
147
- patch: {
148
- kind: "delay"
149
- }
150
- }];
151
- function outcomeIdFor(draft) {
152
- if (draft.kind === "delay") return "passthrough";
153
- if (draft.kind === "fail") {
154
- return draft.failKind === "timeout" ? "timeout" : "offline";
155
- }
156
- return String(draft.status ?? 200);
157
- }
158
- function OutcomeChip({
159
- outcome,
160
- active,
161
- onPress
162
- }) {
163
- const accent = outcome.danger ? _sharedUi.macOSColors.semantic.error : _sharedUi.macOSColors.semantic.info;
164
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
165
- onPress: onPress,
166
- "sentry-label": "ignore override outcome",
167
- testID: `buoy-network-outcome-${outcome.label.toLowerCase().replace(/\s+/g, "-")}${outcome.code ? `-${outcome.code}` : ""}`,
168
- accessibilityRole: "button",
169
- accessibilityLabel: `${outcome.label}${outcome.code ? ` ${outcome.code}` : ""}`,
170
- style: [styles.outcome, active && {
171
- borderColor: accent,
172
- backgroundColor: `${accent}1F`
173
- }],
174
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
175
- style: [styles.outcomeLabel, active && {
176
- color: accent
177
- }],
178
- children: outcome.label
179
- }), outcome.code ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
180
- style: [styles.outcomeCode, active && {
181
- color: accent
182
- }],
183
- children: outcome.code
184
- }) : null]
185
- });
186
- }
187
-
188
- /** A collapsed row that opens to reveal its controls. */
189
- function Disclosure({
190
- title,
191
- summary,
192
- open,
193
- onToggle,
194
- children
195
- }) {
196
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
197
- style: styles.disclosure,
198
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
199
- onPress: onToggle,
200
- "sentry-label": "ignore override disclosure",
201
- testID: `buoy-network-disclosure-${title.toLowerCase().replace(/\s+/g, "-")}`,
202
- accessibilityRole: "button",
203
- accessibilityLabel: title,
204
- style: styles.disclosureHeader,
205
- children: [open ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronDown, {
206
- size: 12,
207
- color: _sharedUi.macOSColors.text.muted
208
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronRight, {
209
- size: 12,
210
- color: _sharedUi.macOSColors.text.muted
211
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
212
- style: styles.disclosureTitle,
213
- children: title
214
- }), summary && !open ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
215
- style: styles.disclosureSummary,
216
- numberOfLines: 1,
217
- children: summary
218
- }) : null]
219
- }), open ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
220
- style: styles.disclosureBody,
221
- children: children
222
- }) : null]
223
- });
224
- }
225
- function Chip({
226
- label,
227
- active,
228
- onPress
229
- }) {
230
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
231
- onPress: onPress,
232
- "sentry-label": "ignore override chip",
233
- testID: `buoy-network-chip-${label.toLowerCase().replace(/\s+/g, "-")}`,
234
- accessibilityRole: "button",
235
- accessibilityLabel: label,
236
- style: [styles.chip, active && styles.chipActive],
237
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
238
- style: [styles.chipText, active && styles.chipTextActive],
239
- children: label
240
- })
241
- });
242
- }
243
- function NetworkOverrideEditor({
244
- draft,
245
- onChange,
246
- onSave,
247
- onCancel,
248
- saveLabel = "Save",
249
- applySafeAreaInset = false
250
- }) {
251
- // `minBottom` is a floor, not a preference: the dimension map can't know
252
- // about a device that ships next year, and an unmapped one falls through to
253
- // `bottom: 0`. This guarantees the buttons clear the indicator either way.
254
- const insets = (0, _sharedUi.useSafeAreaInsets)({
255
- minBottom: 16
256
- });
257
- const bottomInset = applySafeAreaInset ? insets.bottom : 0;
258
- const patch = next => onChange({
259
- ...draft,
260
- ...next
261
- });
262
-
263
- // A rule made from a request arrives with its scope already right, so it
264
- // starts closed. A blank one has nothing to match on yet, so it starts open.
265
- const [scopeOpen, setScopeOpen] = (0, _react.useState)(!draft.urlPattern.trim());
266
- const [bodyOpen, setBodyOpen] = (0, _react.useState)(false);
267
- /**
268
- * The "Edit all" buffer — deliberately NOT seeded with the current body.
269
- *
270
- * Prefilling it would be the obvious thing and it's wrong twice over: a real
271
- * response is routinely hundreds of KB, which a multiline TextInput handles
272
- * badly, and you only reach for this when you intend to REPLACE the whole
273
- * thing anyway. Starting empty means paste-and-go instead of select-all-
274
- * delete-paste on a field that's fighting you.
275
- */
276
- const [pasteText, setPasteText] = (0, _react.useState)(null);
277
- /** Which custom number the top-of-screen prompt is asking for, if any. */
278
- const [prompt, setPrompt] = (0, _react.useState)(null);
279
- const activeOutcome = outcomeIdFor(draft);
280
- /** True when the status is a real one that no listed outcome covers. */
281
- const customStatusActive = draft.kind === "respond" && typeof draft.status === "number" && !OUTCOMES.some(outcome => outcome.code === String(draft.status));
282
- const showsBody = draft.kind === "respond";
283
- const method = draft.methods?.[0];
284
- const scopeSummary = `${method ?? "Any"} ${draft.urlPattern || "No URL yet"}`;
285
- const bodySummary = (0, _react.useMemo)(() => {
286
- const body = (draft.body ?? "").trim();
287
- if (!body) return "Empty";
288
- const lines = body.split("\n").length;
289
- return `${lines} line${lines === 1 ? "" : "s"}`;
290
- }, [draft.body]);
291
-
292
- /**
293
- * The body as a tree, or null when it can't be one (empty, or not JSON).
294
- *
295
- * Memoized on the raw string because an override body can be large and this
296
- * would otherwise re-parse on every keystroke elsewhere in the form.
297
- */
298
- const parsedBody = (0, _react.useMemo)(() => {
299
- const body = (draft.body ?? "").trim();
300
- if (!body) return null;
301
- try {
302
- return JSON.parse(body);
303
- } catch {
304
- return null;
305
- }
306
- }, [draft.body]);
307
- const bodyIsNonJsonText = (draft.body ?? "").trim().length > 0 && !parsedBody;
308
- const delayMs = draft.delayMs ?? 0;
309
- /** Custom fields own the value only when no preset chip already claims it. */
310
- const customDelayActive = delayMs > 0 && !DELAY_PRESETS.includes(delayMs);
311
- const customTimesActive = !draft.alternate && typeof draft.times === "number" && draft.times !== 1;
312
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
313
- style: styles.root,
314
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
315
- testID: "buoy-network-editor-scroll",
316
- style: styles.scroll,
317
- contentContainerStyle: styles.scrollContent,
318
- keyboardShouldPersistTaps: "handled",
319
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(Disclosure, {
320
- title: "Applies to",
321
- summary: scopeSummary,
322
- open: scopeOpen,
323
- onToggle: () => setScopeOpen(v => !v),
324
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
325
- style: styles.input,
326
- value: draft.urlPattern,
327
- onChangeText: urlPattern => patch({
328
- urlPattern
329
- }),
330
- testID: "buoy-network-override-pattern",
331
- accessibilityLabel: "Override URL pattern",
332
- placeholder: "https://api.example.com/v1/users*",
333
- placeholderTextColor: _sharedUi.macOSColors.text.muted,
334
- autoCapitalize: "none",
335
- autoCorrect: false,
336
- multiline: true,
337
- "sentry-label": "ignore override url pattern"
338
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
339
- style: styles.chipRow,
340
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Chip, {
341
- label: "Any",
342
- active: !method,
343
- onPress: () => patch({
344
- methods: undefined
345
- })
346
- }), METHODS.map(m => /*#__PURE__*/(0, _jsxRuntime.jsx)(Chip, {
347
- label: m,
348
- active: method === m,
349
- onPress: () => patch({
350
- methods: [m]
351
- })
352
- }, m))]
353
- })]
354
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
355
- style: styles.outcomeGrid,
356
- children: [OUTCOMES.map(outcome => /*#__PURE__*/(0, _jsxRuntime.jsx)(OutcomeChip, {
357
- outcome: outcome,
358
- active: activeOutcome === outcome.id,
359
- onPress: () => patch(outcome.patch)
360
- }, outcome.id)), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
361
- onPress: () => setPrompt("status"),
362
- "sentry-label": "ignore custom status",
363
- accessibilityLabel: "Custom status code",
364
- style: [styles.customField, customStatusActive && styles.customFieldActive],
365
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
366
- style: [styles.customValue, customStatusActive && styles.customInputActive],
367
- children: customStatusActive ? String(draft.status) : "Custom"
368
- })
369
- })]
370
- }), showsBody ? /*#__PURE__*/(0, _jsxRuntime.jsx)(Disclosure, {
371
- title: "Response body",
372
- summary: bodySummary,
373
- open: bodyOpen,
374
- onToggle: () => setBodyOpen(v => !v),
375
- children: pasteText !== null ?
376
- /*#__PURE__*/
377
- /* Replace-the-whole-thing mode. Starts empty — see `pasteText`. */
378
- (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
379
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
380
- style: [styles.input, styles.bodyInput],
381
- value: pasteText,
382
- onChangeText: setPasteText,
383
- placeholder: "Paste a new body\u2026",
384
- placeholderTextColor: _sharedUi.macOSColors.text.muted,
385
- autoCapitalize: "none",
386
- autoCorrect: false,
387
- autoFocus: true,
388
- multiline: true,
389
- "sentry-label": "ignore override body paste"
390
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
391
- style: styles.inlineActions,
392
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
393
- onPress: () => setPasteText(null),
394
- "sentry-label": "ignore cancel body paste",
395
- style: styles.textButton,
396
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
397
- style: styles.textButtonMuted,
398
- children: "Cancel"
399
- })
400
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
401
- onPress: () => {
402
- const next = pasteText.trim();
403
- // Pretty-print JSON on the way in so the tree it becomes
404
- // is readable; anything else is kept exactly as pasted.
405
- try {
406
- patch({
407
- body: JSON.stringify(JSON.parse(next), null, 2)
408
- });
409
- } catch {
410
- patch({
411
- body: next
412
- });
413
- }
414
- setPasteText(null);
415
- },
416
- disabled: !pasteText.trim(),
417
- "sentry-label": "ignore apply body paste",
418
- style: styles.textButton,
419
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
420
- style: [styles.textButtonLabel, !pasteText.trim() && styles.textButtonDisabled],
421
- children: "Replace"
422
- })
423
- })]
424
- })]
425
- }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
426
- children: [parsedBody !== null ?
427
- /*#__PURE__*/
428
- /* The SAME tree as the request detail — tap a value to edit
429
- it. Editing writes the whole document back as the rule's
430
- body, so the two surfaces behave identically. */
431
- (0, _jsxRuntime.jsx)(_editorContext.ResponseEditorContext.Provider, {
432
- value: {
433
- root: parsedBody,
434
- onChange: next => patch({
435
- body: JSON.stringify(next, null, 2)
436
- })
437
- },
438
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Explorer.default, {
439
- editable: true,
440
- label: "",
441
- value: parsedBody,
442
- defaultExpanded: [""]
443
- })
444
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
445
- style: styles.emptyBody,
446
- children: bodyIsNonJsonText ? "This body isn't JSON, so there's no tree to show." : "No body yet."
447
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
448
- onPress: () => setPasteText(""),
449
- "sentry-label": "ignore edit all body",
450
- style: styles.textButton,
451
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
452
- style: styles.textButtonLabel,
453
- children: "Edit all"
454
- })
455
- })]
456
- })
457
- }) : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
458
- style: styles.field,
459
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
460
- style: styles.subLabel,
461
- children: "Delay"
462
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
463
- style: styles.chipRow,
464
- children: [DELAY_PRESETS.map(ms => /*#__PURE__*/(0, _jsxRuntime.jsx)(Chip, {
465
- label: ms === 0 ? "None" : `${ms / 1000}s`,
466
- active: delayMs === ms,
467
- onPress: () => patch({
468
- delayMs: ms
469
- })
470
- }, ms)), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
471
- onPress: () => setPrompt("delay"),
472
- "sentry-label": "ignore custom delay",
473
- accessibilityLabel: "Custom delay in seconds",
474
- style: [styles.customField, customDelayActive && styles.customFieldActive],
475
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
476
- style: [styles.customValue, customDelayActive && styles.customInputActive],
477
- children: customDelayActive ? `${delayMs / 1000}s` : "Custom"
478
- })
479
- })]
480
- })]
481
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
482
- style: styles.field,
483
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
484
- style: styles.subLabel,
485
- children: "Fires"
486
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
487
- style: styles.subHint,
488
- children: "A limited rule switches itself off once it's used up. Every other alternates forever \u2014 the first request through, the next overridden."
489
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
490
- style: styles.chipRow,
491
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Chip, {
492
- label: "Always",
493
- active: !draft.alternate && draft.times == null,
494
- onPress: () => patch({
495
- alternate: false,
496
- times: null
497
- })
498
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Chip, {
499
- label: "Once",
500
- active: !draft.alternate && draft.times === 1,
501
- onPress: () => patch({
502
- alternate: false,
503
- times: 1
504
- })
505
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Chip, {
506
- label: "Every other",
507
- active: draft.alternate === true,
508
- onPress: () => patch({
509
- alternate: true,
510
- times: null
511
- })
512
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
513
- onPress: () => {
514
- patch({
515
- alternate: false
516
- });
517
- setPrompt("times");
518
- },
519
- "sentry-label": "ignore custom times",
520
- accessibilityLabel: "Custom number of times",
521
- style: [styles.customField, customTimesActive && styles.customFieldActive],
522
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
523
- style: [styles.customValue, customTimesActive && styles.customInputActive],
524
- children: customTimesActive ? `${draft.times}×` : "Custom"
525
- })
526
- })]
527
- })]
528
- })]
529
- }), prompt === "status" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_NetworkNumberPrompt.NetworkNumberPrompt, {
530
- title: "Custom status code",
531
- hint: `${_types.STATUS_MIN}–${_types.STATUS_MAX}`,
532
- value: customStatusActive ? draft.status : undefined,
533
- min: _types.STATUS_MIN,
534
- max: _types.STATUS_MAX,
535
- onSubmit: next => {
536
- patch({
537
- kind: "respond",
538
- status: next ?? undefined,
539
- statusText: undefined
540
- });
541
- setPrompt(null);
542
- },
543
- onCancel: () => setPrompt(null)
544
- }) : null, prompt === "delay" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_NetworkNumberPrompt.NetworkNumberPrompt, {
545
- title: "Custom delay",
546
- hint: "Seconds",
547
- value: customDelayActive ? delayMs / 1000 : undefined,
548
- min: 0,
549
- onSubmit: next => {
550
- patch({
551
- delayMs: next != null ? Math.round(next * 1000) : 0
552
- });
553
- setPrompt(null);
554
- },
555
- onCancel: () => setPrompt(null)
556
- }) : null, prompt === "times" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_NetworkNumberPrompt.NetworkNumberPrompt, {
557
- title: "Fires how many times",
558
- hint: "Leave empty for always",
559
- value: customTimesActive ? draft.times : undefined,
560
- min: 1,
561
- onSubmit: next => {
562
- // Empty or zero means "no limit" rather than a rule that is spent
563
- // before it ever fires.
564
- patch({
565
- alternate: false,
566
- times: next && next > 0 ? next : null
567
- });
568
- setPrompt(null);
569
- },
570
- onCancel: () => setPrompt(null)
571
- }) : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
572
- style: [styles.footer, {
573
- paddingBottom: 12 + bottomInset
574
- }],
575
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
576
- onPress: onCancel,
577
- "sentry-label": "ignore cancel override",
578
- testID: "buoy-network-editor-cancel",
579
- accessibilityRole: "button",
580
- accessibilityLabel: "Cancel",
581
- style: [styles.footerButton, styles.cancelButton],
582
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
583
- style: styles.cancelText,
584
- children: "Cancel"
585
- })
586
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
587
- onPress: onSave,
588
- disabled: !draft.urlPattern.trim(),
589
- "sentry-label": "ignore save override",
590
- testID: "buoy-network-editor-save",
591
- accessibilityRole: "button",
592
- accessibilityLabel: saveLabel,
593
- style: [styles.footerButton, styles.saveButton, !draft.urlPattern.trim() && styles.saveButtonDisabled],
594
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
595
- style: styles.saveText,
596
- children: saveLabel
597
- })
598
- })]
599
- })]
600
- });
601
- }
602
- const styles = _reactNative.StyleSheet.create({
603
- root: {
604
- flex: 1
605
- },
606
- scroll: {
607
- flex: 1
608
- },
609
- scrollContent: {
610
- padding: 12,
611
- paddingBottom: 24,
612
- gap: 4
613
- },
614
- field: {
615
- gap: 8,
616
- paddingVertical: 6
617
- },
618
- outcomeGrid: {
619
- flexDirection: "row",
620
- flexWrap: "wrap",
621
- gap: 6,
622
- paddingVertical: 10
623
- },
624
- outcome: {
625
- flexDirection: "row",
626
- alignItems: "center",
627
- gap: 6,
628
- paddingHorizontal: 10,
629
- paddingVertical: 9,
630
- borderRadius: 6,
631
- borderWidth: 1,
632
- borderColor: _sharedUi.macOSColors.border.default,
633
- backgroundColor: _sharedUi.macOSColors.background.card
634
- },
635
- outcomeLabel: {
636
- fontSize: 12,
637
- fontWeight: "600",
638
- color: _sharedUi.macOSColors.text.primary
639
- },
640
- outcomeCode: {
641
- fontSize: 10,
642
- fontWeight: "700",
643
- color: _sharedUi.macOSColors.text.muted
644
- },
645
- disclosure: {
646
- borderRadius: 6,
647
- borderWidth: 1,
648
- borderColor: _sharedUi.macOSColors.border.default,
649
- backgroundColor: _sharedUi.macOSColors.background.card,
650
- overflow: "hidden"
651
- },
652
- disclosureHeader: {
653
- flexDirection: "row",
654
- alignItems: "center",
655
- gap: 6,
656
- paddingHorizontal: 10,
657
- paddingVertical: 10
658
- },
659
- disclosureTitle: {
660
- fontSize: 12,
661
- fontWeight: "600",
662
- color: _sharedUi.macOSColors.text.primary
663
- },
664
- disclosureSummary: {
665
- flex: 1,
666
- textAlign: "right",
667
- fontSize: 11,
668
- color: _sharedUi.macOSColors.text.muted
669
- },
670
- disclosureBody: {
671
- paddingHorizontal: 10,
672
- paddingBottom: 10,
673
- gap: 8
674
- },
675
- input: {
676
- backgroundColor: _sharedUi.macOSColors.background.input,
677
- borderWidth: 1,
678
- borderColor: _sharedUi.macOSColors.border.input,
679
- borderRadius: 6,
680
- paddingHorizontal: 10,
681
- paddingVertical: 8,
682
- color: _sharedUi.macOSColors.text.primary,
683
- fontSize: 12,
684
- fontFamily: _sharedUi.monoFont,
685
- minHeight: 40
686
- },
687
- bodyInput: {
688
- minHeight: 140,
689
- textAlignVertical: "top"
690
- },
691
- chipRow: {
692
- flexDirection: "row",
693
- flexWrap: "wrap",
694
- gap: 6
695
- },
696
- chip: {
697
- paddingHorizontal: 10,
698
- paddingVertical: 6,
699
- borderRadius: 5,
700
- borderWidth: 1,
701
- borderColor: _sharedUi.macOSColors.border.default,
702
- backgroundColor: _sharedUi.macOSColors.background.base
703
- },
704
- chipActive: {
705
- borderColor: _sharedUi.macOSColors.semantic.info,
706
- backgroundColor: `${_sharedUi.macOSColors.semantic.info}1F`
707
- },
708
- chipText: {
709
- fontSize: 11,
710
- fontWeight: "600",
711
- color: _sharedUi.macOSColors.text.secondary
712
- },
713
- chipTextActive: {
714
- color: _sharedUi.macOSColors.semantic.info
715
- },
716
- customField: {
717
- flexDirection: "row",
718
- alignItems: "center",
719
- paddingHorizontal: 8,
720
- borderRadius: 5,
721
- borderWidth: 1,
722
- borderColor: _sharedUi.macOSColors.border.default,
723
- backgroundColor: _sharedUi.macOSColors.background.base
724
- },
725
- customFieldActive: {
726
- borderColor: _sharedUi.macOSColors.semantic.info,
727
- backgroundColor: `${_sharedUi.macOSColors.semantic.info}1F`
728
- },
729
- customValue: {
730
- paddingVertical: 6,
731
- fontSize: 11,
732
- fontWeight: "600",
733
- color: _sharedUi.macOSColors.text.secondary
734
- },
735
- customInputActive: {
736
- color: _sharedUi.macOSColors.semantic.info
737
- },
738
- subHint: {
739
- fontSize: 10,
740
- lineHeight: 14,
741
- color: _sharedUi.macOSColors.text.muted,
742
- marginTop: -2
743
- },
744
- subLabel: {
745
- fontSize: 10,
746
- fontWeight: "700",
747
- letterSpacing: 0.6,
748
- color: _sharedUi.macOSColors.text.muted,
749
- textTransform: "uppercase"
750
- },
751
- textButton: {
752
- alignSelf: "flex-start",
753
- paddingVertical: 4
754
- },
755
- textButtonLabel: {
756
- fontSize: 11,
757
- fontWeight: "600",
758
- color: _sharedUi.macOSColors.semantic.info
759
- },
760
- textButtonMuted: {
761
- fontSize: 11,
762
- fontWeight: "600",
763
- color: _sharedUi.macOSColors.text.secondary
764
- },
765
- textButtonDisabled: {
766
- opacity: 0.4
767
- },
768
- inlineActions: {
769
- flexDirection: "row",
770
- alignItems: "center",
771
- justifyContent: "space-between"
772
- },
773
- emptyBody: {
774
- fontSize: 11,
775
- color: _sharedUi.macOSColors.text.muted,
776
- paddingVertical: 6
777
- },
778
- footer: {
779
- flexDirection: "row",
780
- gap: 8,
781
- padding: 12,
782
- borderTopWidth: 1,
783
- borderTopColor: _sharedUi.macOSColors.border.default,
784
- backgroundColor: _sharedUi.macOSColors.background.base
785
- },
786
- footerButton: {
787
- flex: 1,
788
- paddingVertical: 11,
789
- borderRadius: 6,
790
- alignItems: "center",
791
- borderWidth: 1
792
- },
793
- cancelButton: {
794
- borderColor: _sharedUi.macOSColors.border.default,
795
- backgroundColor: _sharedUi.macOSColors.background.card
796
- },
797
- cancelText: {
798
- fontSize: 12,
799
- fontWeight: "600",
800
- color: _sharedUi.macOSColors.text.secondary
801
- },
802
- saveButton: {
803
- borderColor: _sharedUi.macOSColors.semantic.info,
804
- backgroundColor: `${_sharedUi.macOSColors.semantic.info}22`
805
- },
806
- saveButtonDisabled: {
807
- opacity: 0.4
808
- },
809
- saveText: {
810
- fontSize: 12,
811
- fontWeight: "700",
812
- color: _sharedUi.macOSColors.semantic.info
813
- }
814
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.NetworkOverrideEditor=NetworkOverrideEditor;var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _Explorer=_interopRequireDefault(require("./response-editor/Explorer"));var _editorContext=require("./response-editor/editorContext");var _NetworkNumberPrompt=require("./NetworkNumberPrompt");var _types=require("../overrides/types");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const METHODS=["GET","POST","PUT","PATCH","DELETE"];const DELAY_PRESETS=[0,500,1e3,3e3,1e4];const OUTCOMES=[{id:"500",label:"Server error",code:"500",danger:true,patch:{kind:"respond",status:500,statusText:"Internal Server Error"}},{id:"401",label:"Unauthorized",code:"401",danger:true,patch:{kind:"respond",status:401,statusText:"Unauthorized"}},{id:"404",label:"Not found",code:"404",danger:true,patch:{kind:"respond",status:404,statusText:"Not Found"}},{id:"403",label:"Forbidden",code:"403",danger:true,patch:{kind:"respond",status:403,statusText:"Forbidden"}},{id:"429",label:"Rate limited",code:"429",danger:true,patch:{kind:"respond",status:429,statusText:"Too Many Requests"}},{id:"503",label:"Unavailable",code:"503",danger:true,patch:{kind:"respond",status:503,statusText:"Service Unavailable"}},{id:"400",label:"Bad request",code:"400",danger:true,patch:{kind:"respond",status:400,statusText:"Bad Request"}},{id:"200",label:"Success",code:"200",patch:{kind:"respond",status:200,statusText:"OK"}},{id:"offline",label:"Offline",danger:true,patch:{kind:"fail",failKind:"network"}},{id:"timeout",label:"Timeout",danger:true,patch:{kind:"fail",failKind:"timeout"}},{id:"passthrough",label:"Real response",patch:{kind:"delay"}}];function outcomeIdFor(e){if(e.kind==="delay")return"passthrough";if(e.kind==="fail"){return e.failKind==="timeout"?"timeout":"offline"}return String(e.status??200)}function OutcomeChip({outcome:e,active:r,onPress:s}){const n=e.danger?_sharedUi.macOSColors.semantic.error:_sharedUi.macOSColors.semantic.info;return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{onPress:s,"sentry-label":"ignore override outcome",testID:`buoy-network-outcome-${e.label.toLowerCase().replace(/\s+/g,"-")}${e.code?`-${e.code}`:""}`,accessibilityRole:"button",accessibilityLabel:`${e.label}${e.code?` ${e.code}`:""}`,style:[styles.outcome,r&&{borderColor:n,backgroundColor:`${n}1F`}],children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.outcomeLabel,r&&{color:n}],children:e.label}),e.code?(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.outcomeCode,r&&{color:n}],children:e.code}):null]})}function Disclosure({title:e,summary:r,open:s,onToggle:n,children:c}){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.disclosure,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{onPress:n,"sentry-label":"ignore override disclosure",testID:`buoy-network-disclosure-${e.toLowerCase().replace(/\s+/g,"-")}`,accessibilityRole:"button",accessibilityLabel:e,style:styles.disclosureHeader,children:[s?(0,_jsxRuntime.jsx)(_sharedUi.ChevronDown,{size:12,color:_sharedUi.macOSColors.text.muted}):(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:12,color:_sharedUi.macOSColors.text.muted}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.disclosureTitle,children:e}),r&&!s?(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.disclosureSummary,numberOfLines:1,children:r}):null]}),s?(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.disclosureBody,children:c}):null]})}function Chip({label:e,active:r,onPress:s}){return(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:s,"sentry-label":"ignore override chip",testID:`buoy-network-chip-${e.toLowerCase().replace(/\s+/g,"-")}`,accessibilityRole:"button",accessibilityLabel:e,style:[styles.chip,r&&styles.chipActive],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.chipText,r&&styles.chipTextActive],children:e})})}function NetworkOverrideEditor({draft:e,onChange:r,onSave:s,onCancel:n,saveLabel:c="Save",applySafeAreaInset:g=false}){const C=(0,_sharedUi.useSafeAreaInsets)({minBottom:16});const S=g?C.bottom:0;const o=t=>r({...e,...t});const[f,T]=(0,_react.useState)(!e.urlPattern.trim());const[O,v]=(0,_react.useState)(false);const[i,d]=(0,_react.useState)(null);const[y,l]=(0,_react.useState)(null);const j=outcomeIdFor(e);const u=e.kind==="respond"&&typeof e.status==="number"&&!OUTCOMES.some(t=>t.code===String(e.status));const w=e.kind==="respond";const x=e.methods?.[0];const k=`${x??"Any"} ${e.urlPattern||"No URL yet"}`;const P=(0,_react.useMemo)(()=>{const t=(e.body??"").trim();if(!t)return"Empty";const h=t.split("\n").length;return`${h} line${h===1?"":"s"}`},[e.body]);const m=(0,_react.useMemo)(()=>{const t=(e.body??"").trim();if(!t)return null;try{return JSON.parse(t)}catch{return null}},[e.body]);const A=(e.body??"").trim().length>0&&!m;const a=e.delayMs??0;const b=a>0&&!DELAY_PRESETS.includes(a);const p=!e.alternate&&typeof e.times==="number"&&e.times!==1;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.root,children:[(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{testID:"buoy-network-editor-scroll",style:styles.scroll,contentContainerStyle:styles.scrollContent,keyboardShouldPersistTaps:"handled",children:[(0,_jsxRuntime.jsxs)(Disclosure,{title:"Applies to",summary:k,open:f,onToggle:()=>T(t=>!t),children:[(0,_jsxRuntime.jsx)(_reactNative.TextInput,{style:styles.input,value:e.urlPattern,onChangeText:t=>o({urlPattern:t}),testID:"buoy-network-override-pattern",accessibilityLabel:"Override URL pattern",placeholder:"https://api.example.com/v1/users*",placeholderTextColor:_sharedUi.macOSColors.text.muted,autoCapitalize:"none",autoCorrect:false,multiline:true,"sentry-label":"ignore override url pattern"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.chipRow,children:[(0,_jsxRuntime.jsx)(Chip,{label:"Any",active:!x,onPress:()=>o({methods:void 0})}),METHODS.map(t=>(0,_jsxRuntime.jsx)(Chip,{label:t,active:x===t,onPress:()=>o({methods:[t]})},t))]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.outcomeGrid,children:[OUTCOMES.map(t=>(0,_jsxRuntime.jsx)(OutcomeChip,{outcome:t,active:j===t.id,onPress:()=>o(t.patch)},t.id)),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>l("status"),"sentry-label":"ignore custom status",accessibilityLabel:"Custom status code",style:[styles.customField,u&&styles.customFieldActive],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.customValue,u&&styles.customInputActive],children:u?String(e.status):"Custom"})})]}),w?(0,_jsxRuntime.jsx)(Disclosure,{title:"Response body",summary:P,open:O,onToggle:()=>v(t=>!t),children:i!==null?(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.TextInput,{style:[styles.input,styles.bodyInput],value:i,onChangeText:d,placeholder:"Paste a new body\u2026",placeholderTextColor:_sharedUi.macOSColors.text.muted,autoCapitalize:"none",autoCorrect:false,autoFocus:true,multiline:true,"sentry-label":"ignore override body paste"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inlineActions,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>d(null),"sentry-label":"ignore cancel body paste",style:styles.textButton,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.textButtonMuted,children:"Cancel"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>{const t=i.trim();try{o({body:JSON.stringify(JSON.parse(t),null,2)})}catch{o({body:t})}d(null)},disabled:!i.trim(),"sentry-label":"ignore apply body paste",style:styles.textButton,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.textButtonLabel,!i.trim()&&styles.textButtonDisabled],children:"Replace"})})]})]}):(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[m!==null?(0,_jsxRuntime.jsx)(_editorContext.ResponseEditorContext.Provider,{value:{root:m,onChange:t=>o({body:JSON.stringify(t,null,2)})},children:(0,_jsxRuntime.jsx)(_Explorer.default,{editable:true,label:"",value:m,defaultExpanded:[""]})}):(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyBody,children:A?"This body isn't JSON, so there's no tree to show.":"No body yet."}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>d(""),"sentry-label":"ignore edit all body",style:styles.textButton,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.textButtonLabel,children:"Edit all"})})]})}):null,(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.field,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.subLabel,children:"Delay"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.chipRow,children:[DELAY_PRESETS.map(t=>(0,_jsxRuntime.jsx)(Chip,{label:t===0?"None":`${t/1e3}s`,active:a===t,onPress:()=>o({delayMs:t})},t)),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>l("delay"),"sentry-label":"ignore custom delay",accessibilityLabel:"Custom delay in seconds",style:[styles.customField,b&&styles.customFieldActive],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.customValue,b&&styles.customInputActive],children:b?`${a/1e3}s`:"Custom"})})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.field,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.subLabel,children:"Fires"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.subHint,children:"A limited rule switches itself off once it's used up. Every other alternates forever \u2014 the first request through, the next overridden."}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.chipRow,children:[(0,_jsxRuntime.jsx)(Chip,{label:"Always",active:!e.alternate&&e.times==null,onPress:()=>o({alternate:false,times:null})}),(0,_jsxRuntime.jsx)(Chip,{label:"Once",active:!e.alternate&&e.times===1,onPress:()=>o({alternate:false,times:1})}),(0,_jsxRuntime.jsx)(Chip,{label:"Every other",active:e.alternate===true,onPress:()=>o({alternate:true,times:null})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>{o({alternate:false});l("times")},"sentry-label":"ignore custom times",accessibilityLabel:"Custom number of times",style:[styles.customField,p&&styles.customFieldActive],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.customValue,p&&styles.customInputActive],children:p?`${e.times}\xD7`:"Custom"})})]})]})]}),y==="status"?(0,_jsxRuntime.jsx)(_NetworkNumberPrompt.NetworkNumberPrompt,{title:"Custom status code",hint:`${_types.STATUS_MIN}\u2013${_types.STATUS_MAX}`,value:u?e.status:void 0,min:_types.STATUS_MIN,max:_types.STATUS_MAX,onSubmit:t=>{o({kind:"respond",status:t??void 0,statusText:void 0});l(null)},onCancel:()=>l(null)}):null,y==="delay"?(0,_jsxRuntime.jsx)(_NetworkNumberPrompt.NetworkNumberPrompt,{title:"Custom delay",hint:"Seconds",value:b?a/1e3:void 0,min:0,onSubmit:t=>{o({delayMs:t!=null?Math.round(t*1e3):0});l(null)},onCancel:()=>l(null)}):null,y==="times"?(0,_jsxRuntime.jsx)(_NetworkNumberPrompt.NetworkNumberPrompt,{title:"Fires how many times",hint:"Leave empty for always",value:p?e.times:void 0,min:1,onSubmit:t=>{o({alternate:false,times:t&&t>0?t:null});l(null)},onCancel:()=>l(null)}):null,(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.footer,{paddingBottom:12+S}],children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:n,"sentry-label":"ignore cancel override",testID:"buoy-network-editor-cancel",accessibilityRole:"button",accessibilityLabel:"Cancel",style:[styles.footerButton,styles.cancelButton],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.cancelText,children:"Cancel"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:s,disabled:!e.urlPattern.trim(),"sentry-label":"ignore save override",testID:"buoy-network-editor-save",accessibilityRole:"button",accessibilityLabel:c,style:[styles.footerButton,styles.saveButton,!e.urlPattern.trim()&&styles.saveButtonDisabled],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.saveText,children:c})})]})]})}const styles=_reactNative.StyleSheet.create({root:{flex:1},scroll:{flex:1},scrollContent:{padding:12,paddingBottom:24,gap:4},field:{gap:8,paddingVertical:6},outcomeGrid:{flexDirection:"row",flexWrap:"wrap",gap:6,paddingVertical:10},outcome:{flexDirection:"row",alignItems:"center",gap:6,paddingHorizontal:10,paddingVertical:9,borderRadius:6,borderWidth:1,borderColor:_sharedUi.macOSColors.border.default,backgroundColor:_sharedUi.macOSColors.background.card},outcomeLabel:{fontSize:12,fontWeight:"600",color:_sharedUi.macOSColors.text.primary},outcomeCode:{fontSize:10,fontWeight:"700",color:_sharedUi.macOSColors.text.muted},disclosure:{borderRadius:6,borderWidth:1,borderColor:_sharedUi.macOSColors.border.default,backgroundColor:_sharedUi.macOSColors.background.card,overflow:"hidden"},disclosureHeader:{flexDirection:"row",alignItems:"center",gap:6,paddingHorizontal:10,paddingVertical:10},disclosureTitle:{fontSize:12,fontWeight:"600",color:_sharedUi.macOSColors.text.primary},disclosureSummary:{flex:1,textAlign:"right",fontSize:11,color:_sharedUi.macOSColors.text.muted},disclosureBody:{paddingHorizontal:10,paddingBottom:10,gap:8},input:{backgroundColor:_sharedUi.macOSColors.background.input,borderWidth:1,borderColor:_sharedUi.macOSColors.border.input,borderRadius:6,paddingHorizontal:10,paddingVertical:8,color:_sharedUi.macOSColors.text.primary,fontSize:12,fontFamily:_sharedUi.monoFont,minHeight:40},bodyInput:{minHeight:140,textAlignVertical:"top"},chipRow:{flexDirection:"row",flexWrap:"wrap",gap:6},chip:{paddingHorizontal:10,paddingVertical:6,borderRadius:5,borderWidth:1,borderColor:_sharedUi.macOSColors.border.default,backgroundColor:_sharedUi.macOSColors.background.base},chipActive:{borderColor:_sharedUi.macOSColors.semantic.info,backgroundColor:`${_sharedUi.macOSColors.semantic.info}1F`},chipText:{fontSize:11,fontWeight:"600",color:_sharedUi.macOSColors.text.secondary},chipTextActive:{color:_sharedUi.macOSColors.semantic.info},customField:{flexDirection:"row",alignItems:"center",paddingHorizontal:8,borderRadius:5,borderWidth:1,borderColor:_sharedUi.macOSColors.border.default,backgroundColor:_sharedUi.macOSColors.background.base},customFieldActive:{borderColor:_sharedUi.macOSColors.semantic.info,backgroundColor:`${_sharedUi.macOSColors.semantic.info}1F`},customValue:{paddingVertical:6,fontSize:11,fontWeight:"600",color:_sharedUi.macOSColors.text.secondary},customInputActive:{color:_sharedUi.macOSColors.semantic.info},subHint:{fontSize:10,lineHeight:14,color:_sharedUi.macOSColors.text.muted,marginTop:-2},subLabel:{fontSize:10,fontWeight:"700",letterSpacing:.6,color:_sharedUi.macOSColors.text.muted,textTransform:"uppercase"},textButton:{alignSelf:"flex-start",paddingVertical:4},textButtonLabel:{fontSize:11,fontWeight:"600",color:_sharedUi.macOSColors.semantic.info},textButtonMuted:{fontSize:11,fontWeight:"600",color:_sharedUi.macOSColors.text.secondary},textButtonDisabled:{opacity:.4},inlineActions:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},emptyBody:{fontSize:11,color:_sharedUi.macOSColors.text.muted,paddingVertical:6},footer:{flexDirection:"row",gap:8,padding:12,borderTopWidth:1,borderTopColor:_sharedUi.macOSColors.border.default,backgroundColor:_sharedUi.macOSColors.background.base},footerButton:{flex:1,paddingVertical:11,borderRadius:6,alignItems:"center",borderWidth:1},cancelButton:{borderColor:_sharedUi.macOSColors.border.default,backgroundColor:_sharedUi.macOSColors.background.card},cancelText:{fontSize:12,fontWeight:"600",color:_sharedUi.macOSColors.text.secondary},saveButton:{borderColor:_sharedUi.macOSColors.semantic.info,backgroundColor:`${_sharedUi.macOSColors.semantic.info}22`},saveButtonDisabled:{opacity:.4},saveText:{fontSize:12,fontWeight:"700",color:_sharedUi.macOSColors.semantic.info}});