@buoy-gg/network 7.0.13 → 7.0.14
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.
- package/lib/commonjs/index.js +39 -0
- package/lib/commonjs/network/components/NetworkEventDetailView.js +30 -3
- package/lib/commonjs/network/components/NetworkEventItemCompact.js +4 -0
- package/lib/commonjs/network/components/NetworkHeaderLive.js +26 -6
- package/lib/commonjs/network/components/NetworkHeaderMenu.js +183 -0
- package/lib/commonjs/network/components/NetworkListScreen.js +126 -5
- package/lib/commonjs/network/components/NetworkModal.js +136 -29
- package/lib/commonjs/network/components/NetworkNumberPrompt.js +178 -0
- package/lib/commonjs/network/components/NetworkOverrideEditor.js +797 -0
- package/lib/commonjs/network/components/NetworkOverrideHeaderButton.js +102 -0
- package/lib/commonjs/network/components/NetworkOverridesButton.js +88 -0
- package/lib/commonjs/network/components/NetworkOverridesScreen.js +489 -0
- package/lib/commonjs/network/components/response-editor/Explorer.js +973 -0
- package/lib/commonjs/network/components/response-editor/deleteNestedDataByPath.js +56 -0
- package/lib/commonjs/network/components/response-editor/editorContext.js +33 -0
- package/lib/commonjs/network/components/response-editor/updateNestedDataByPath.js +61 -0
- package/lib/commonjs/network/hooks/useOverrideRules.js +36 -0
- package/lib/commonjs/network/overrides/applyToFetch.js +80 -0
- package/lib/commonjs/network/overrides/applyToXhr.js +190 -0
- package/lib/commonjs/network/overrides/engine.js +70 -0
- package/lib/commonjs/network/overrides/matchRule.js +81 -0
- package/lib/commonjs/network/overrides/overrideRulesStore.js +550 -0
- package/lib/commonjs/network/overrides/presets.js +70 -0
- package/lib/commonjs/network/overrides/resolveOverride.js +158 -0
- package/lib/commonjs/network/overrides/types.js +85 -0
- package/lib/commonjs/network/sync/networkSyncAdapter.js +230 -1
- package/lib/commonjs/network/types/index.js +5 -1
- package/lib/commonjs/network/utils/networkEventStore.js +52 -6
- package/lib/commonjs/network/utils/networkListener.js +90 -10
- package/lib/commonjs/preset.js +11 -0
- package/lib/module/index.js +15 -0
- package/lib/module/network/components/NetworkEventDetailView.js +31 -4
- package/lib/module/network/components/NetworkEventItemCompact.js +5 -1
- package/lib/module/network/components/NetworkHeaderLive.js +26 -6
- package/lib/module/network/components/NetworkHeaderMenu.js +177 -0
- package/lib/module/network/components/NetworkListScreen.js +127 -6
- package/lib/module/network/components/NetworkModal.js +138 -31
- package/lib/module/network/components/NetworkNumberPrompt.js +174 -0
- package/lib/module/network/components/NetworkOverrideEditor.js +794 -0
- package/lib/module/network/components/NetworkOverrideHeaderButton.js +99 -0
- package/lib/module/network/components/NetworkOverridesButton.js +85 -0
- package/lib/module/network/components/NetworkOverridesScreen.js +485 -0
- package/lib/module/network/components/response-editor/Explorer.js +972 -0
- package/lib/module/network/components/response-editor/deleteNestedDataByPath.js +51 -0
- package/lib/module/network/components/response-editor/editorContext.js +29 -0
- package/lib/module/network/components/response-editor/updateNestedDataByPath.js +56 -0
- package/lib/module/network/hooks/useOverrideRules.js +32 -0
- package/lib/module/network/overrides/applyToFetch.js +72 -0
- package/lib/module/network/overrides/applyToXhr.js +185 -0
- package/lib/module/network/overrides/engine.js +64 -0
- package/lib/module/network/overrides/matchRule.js +75 -0
- package/lib/module/network/overrides/overrideRulesStore.js +547 -0
- package/lib/module/network/overrides/presets.js +65 -0
- package/lib/module/network/overrides/resolveOverride.js +152 -0
- package/lib/module/network/overrides/types.js +80 -0
- package/lib/module/network/sync/networkSyncAdapter.js +230 -1
- package/lib/module/network/types/index.js +3 -1
- package/lib/module/network/utils/networkEventStore.js +52 -6
- package/lib/module/network/utils/networkListener.js +91 -10
- package/lib/module/preset.js +13 -1
- package/lib/typescript/index.d.ts +8 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/network/components/NetworkEventDetailView.d.ts.map +1 -1
- package/lib/typescript/network/components/NetworkEventItemCompact.d.ts +6 -0
- package/lib/typescript/network/components/NetworkEventItemCompact.d.ts.map +1 -1
- package/lib/typescript/network/components/NetworkHeaderLive.d.ts +8 -1
- package/lib/typescript/network/components/NetworkHeaderLive.d.ts.map +1 -1
- package/lib/typescript/network/components/NetworkHeaderMenu.d.ts +46 -0
- package/lib/typescript/network/components/NetworkHeaderMenu.d.ts.map +1 -0
- package/lib/typescript/network/components/NetworkListScreen.d.ts.map +1 -1
- package/lib/typescript/network/components/NetworkModal.d.ts.map +1 -1
- package/lib/typescript/network/components/NetworkNumberPrompt.d.ts +33 -0
- package/lib/typescript/network/components/NetworkNumberPrompt.d.ts.map +1 -0
- package/lib/typescript/network/components/NetworkOverrideEditor.d.ts +17 -0
- package/lib/typescript/network/components/NetworkOverrideEditor.d.ts.map +1 -0
- package/lib/typescript/network/components/NetworkOverrideHeaderButton.d.ts +27 -0
- package/lib/typescript/network/components/NetworkOverrideHeaderButton.d.ts.map +1 -0
- package/lib/typescript/network/components/NetworkOverridesButton.d.ts +17 -0
- package/lib/typescript/network/components/NetworkOverridesButton.d.ts.map +1 -0
- package/lib/typescript/network/components/NetworkOverridesScreen.d.ts +29 -0
- package/lib/typescript/network/components/NetworkOverridesScreen.d.ts.map +1 -0
- package/lib/typescript/network/components/response-editor/Explorer.d.ts +17 -0
- package/lib/typescript/network/components/response-editor/Explorer.d.ts.map +1 -0
- package/lib/typescript/network/components/response-editor/deleteNestedDataByPath.d.ts +9 -0
- package/lib/typescript/network/components/response-editor/deleteNestedDataByPath.d.ts.map +1 -0
- package/lib/typescript/network/components/response-editor/editorContext.d.ts +29 -0
- package/lib/typescript/network/components/response-editor/editorContext.d.ts.map +1 -0
- package/lib/typescript/network/components/response-editor/updateNestedDataByPath.d.ts +10 -0
- package/lib/typescript/network/components/response-editor/updateNestedDataByPath.d.ts.map +1 -0
- package/lib/typescript/network/hooks/useOverrideRules.d.ts +29 -0
- package/lib/typescript/network/hooks/useOverrideRules.d.ts.map +1 -0
- package/lib/typescript/network/overrides/__tests__/applyToFetch.test.d.ts +16 -0
- package/lib/typescript/network/overrides/__tests__/applyToFetch.test.d.ts.map +1 -0
- package/lib/typescript/network/overrides/__tests__/applyToXhr.test.d.ts +19 -0
- package/lib/typescript/network/overrides/__tests__/applyToXhr.test.d.ts.map +1 -0
- package/lib/typescript/network/overrides/__tests__/resolveOverride.test.d.ts +22 -0
- package/lib/typescript/network/overrides/__tests__/resolveOverride.test.d.ts.map +1 -0
- package/lib/typescript/network/overrides/applyToFetch.d.ts +50 -0
- package/lib/typescript/network/overrides/applyToFetch.d.ts.map +1 -0
- package/lib/typescript/network/overrides/applyToXhr.d.ts +43 -0
- package/lib/typescript/network/overrides/applyToXhr.d.ts.map +1 -0
- package/lib/typescript/network/overrides/engine.d.ts +47 -0
- package/lib/typescript/network/overrides/engine.d.ts.map +1 -0
- package/lib/typescript/network/overrides/matchRule.d.ts +22 -0
- package/lib/typescript/network/overrides/matchRule.d.ts.map +1 -0
- package/lib/typescript/network/overrides/overrideRulesStore.d.ts +205 -0
- package/lib/typescript/network/overrides/overrideRulesStore.d.ts.map +1 -0
- package/lib/typescript/network/overrides/presets.d.ts +38 -0
- package/lib/typescript/network/overrides/presets.d.ts.map +1 -0
- package/lib/typescript/network/overrides/resolveOverride.d.ts +46 -0
- package/lib/typescript/network/overrides/resolveOverride.d.ts.map +1 -0
- package/lib/typescript/network/overrides/types.d.ts +169 -0
- package/lib/typescript/network/overrides/types.d.ts.map +1 -0
- package/lib/typescript/network/sync/networkSyncAdapter.d.ts +73 -0
- package/lib/typescript/network/sync/networkSyncAdapter.d.ts.map +1 -1
- package/lib/typescript/network/types/index.d.ts +10 -0
- package/lib/typescript/network/types/index.d.ts.map +1 -1
- package/lib/typescript/network/utils/networkEventStore.d.ts +14 -0
- package/lib/typescript/network/utils/networkEventStore.d.ts.map +1 -1
- package/lib/typescript/network/utils/networkListener.d.ts +3 -0
- package/lib/typescript/network/utils/networkListener.d.ts.map +1 -1
- package/lib/typescript/preset.d.ts.map +1 -1
- package/package.json +2 -2
package/lib/commonjs/index.js
CHANGED
|
@@ -9,12 +9,24 @@ Object.defineProperty(exports, "DEFAULT_SETTLE_MS", {
|
|
|
9
9
|
return _networkSelectionStore.DEFAULT_SETTLE_MS;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
|
+
Object.defineProperty(exports, "FREE_TIER_OVERRIDE_LIMIT", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _types.FREE_TIER_RULE_LIMIT;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
12
18
|
Object.defineProperty(exports, "FREE_TIER_SAVED_LIMIT", {
|
|
13
19
|
enumerable: true,
|
|
14
20
|
get: function () {
|
|
15
21
|
return _networkSavedStore.FREE_TIER_SAVED_LIMIT;
|
|
16
22
|
}
|
|
17
23
|
});
|
|
24
|
+
Object.defineProperty(exports, "MAX_OVERRIDE_RULES", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _types.MAX_RULES;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
18
30
|
Object.defineProperty(exports, "MAX_PINNED", {
|
|
19
31
|
enumerable: true,
|
|
20
32
|
get: function () {
|
|
@@ -75,6 +87,18 @@ Object.defineProperty(exports, "NetworkToolView", {
|
|
|
75
87
|
return _NetworkModal.NetworkToolView;
|
|
76
88
|
}
|
|
77
89
|
});
|
|
90
|
+
Object.defineProperty(exports, "OVERRIDE_STATUS_MAX", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function () {
|
|
93
|
+
return _types.STATUS_MAX;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(exports, "OVERRIDE_STATUS_MIN", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
get: function () {
|
|
99
|
+
return _types.STATUS_MIN;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
78
102
|
Object.defineProperty(exports, "TickProvider", {
|
|
79
103
|
enumerable: true,
|
|
80
104
|
get: function () {
|
|
@@ -93,6 +117,12 @@ Object.defineProperty(exports, "createNetworkTool", {
|
|
|
93
117
|
return _preset.createNetworkTool;
|
|
94
118
|
}
|
|
95
119
|
});
|
|
120
|
+
Object.defineProperty(exports, "draftFromEvent", {
|
|
121
|
+
enumerable: true,
|
|
122
|
+
get: function () {
|
|
123
|
+
return _presets.draftFromEvent;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
96
126
|
Object.defineProperty(exports, "flagsForEventId", {
|
|
97
127
|
enumerable: true,
|
|
98
128
|
get: function () {
|
|
@@ -171,6 +201,12 @@ Object.defineProperty(exports, "networkToolPreset", {
|
|
|
171
201
|
return _preset.networkToolPreset;
|
|
172
202
|
}
|
|
173
203
|
});
|
|
204
|
+
Object.defineProperty(exports, "overrideRulesStore", {
|
|
205
|
+
enumerable: true,
|
|
206
|
+
get: function () {
|
|
207
|
+
return _overrideRulesStore.overrideRulesStore;
|
|
208
|
+
}
|
|
209
|
+
});
|
|
174
210
|
Object.defineProperty(exports, "removeAllNetworkListeners", {
|
|
175
211
|
enumerable: true,
|
|
176
212
|
get: function () {
|
|
@@ -246,6 +282,9 @@ var _withPinnedFirst = require("./network/utils/withPinnedFirst");
|
|
|
246
282
|
var _networkSelectionStore = require("./network/utils/networkSelectionStore");
|
|
247
283
|
var _useTickEveryMinute = require("./network/hooks/useTickEveryMinute");
|
|
248
284
|
var _formatting = require("./network/utils/formatting");
|
|
285
|
+
var _overrideRulesStore = require("./network/overrides/overrideRulesStore");
|
|
286
|
+
var _presets = require("./network/overrides/presets");
|
|
287
|
+
var _types = require("./network/overrides/types");
|
|
249
288
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
250
289
|
var _networkSyncAdapter = require("./network/sync/networkSyncAdapter");
|
|
251
290
|
var _networkBodyResolver = require("./network/sync/networkBodyResolver");
|
|
@@ -74,8 +74,11 @@ const TimingPhases = ({
|
|
|
74
74
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
75
75
|
style: [styles.phaseBar, {
|
|
76
76
|
backgroundColor: phase.color,
|
|
77
|
-
// A floor so a 1ms phase is still a visible tick
|
|
78
|
-
|
|
77
|
+
// A floor so a 1ms phase is still a visible tick, and a
|
|
78
|
+
// ceiling because `total` and the phases are measured at
|
|
79
|
+
// different points — ttfb can exceed event.duration, which
|
|
80
|
+
// would push the bar past its track and over the label.
|
|
81
|
+
width: `${Math.min(100, Math.max(1, phase.value / span * 100))}%`
|
|
79
82
|
}]
|
|
80
83
|
})
|
|
81
84
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
@@ -443,6 +446,15 @@ ${JSON.stringify(requestDetails.responseData, null, 2)}
|
|
|
443
446
|
style: styles.httpDurationText,
|
|
444
447
|
children: (0, _formatting.formatDuration)(event.duration)
|
|
445
448
|
})]
|
|
449
|
+
}) : null, event.override ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
450
|
+
style: styles.overrideBadge,
|
|
451
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.FlaskConical, {
|
|
452
|
+
size: 10,
|
|
453
|
+
color: _sharedUi.macOSColors.semantic.warning
|
|
454
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
455
|
+
style: styles.overrideBadgeText,
|
|
456
|
+
children: event.override.ruleName || "Overridden"
|
|
457
|
+
})]
|
|
446
458
|
}) : null, isPro ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.InlineCopyButton
|
|
447
459
|
// LAZY, not `getFullRequestDetails()`. CopyButton resolves a
|
|
448
460
|
// function value at press time; calling it here instead
|
|
@@ -796,6 +808,20 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
796
808
|
color: _sharedUi.macOSColors.text.secondary,
|
|
797
809
|
fontSize: 11
|
|
798
810
|
},
|
|
811
|
+
overrideBadge: {
|
|
812
|
+
flexDirection: "row",
|
|
813
|
+
alignItems: "center",
|
|
814
|
+
gap: 4,
|
|
815
|
+
paddingHorizontal: 6,
|
|
816
|
+
paddingVertical: 3,
|
|
817
|
+
borderRadius: 4,
|
|
818
|
+
backgroundColor: _sharedUi.macOSColors.semantic.warningBackground
|
|
819
|
+
},
|
|
820
|
+
overrideBadgeText: {
|
|
821
|
+
color: _sharedUi.macOSColors.semantic.warning,
|
|
822
|
+
fontSize: 10,
|
|
823
|
+
fontWeight: "700"
|
|
824
|
+
},
|
|
799
825
|
copyFullButton: {
|
|
800
826
|
marginLeft: "auto",
|
|
801
827
|
flexShrink: 0,
|
|
@@ -948,7 +974,8 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
948
974
|
height: 7,
|
|
949
975
|
borderRadius: 4,
|
|
950
976
|
backgroundColor: _sharedUi.macOSColors.background.hover,
|
|
951
|
-
justifyContent: "center"
|
|
977
|
+
justifyContent: "center",
|
|
978
|
+
overflow: "hidden"
|
|
952
979
|
},
|
|
953
980
|
phaseBar: {
|
|
954
981
|
height: 7,
|
|
@@ -173,6 +173,7 @@ function NetworkEventItemCompact({
|
|
|
173
173
|
onPress,
|
|
174
174
|
pinned = false,
|
|
175
175
|
saved = false,
|
|
176
|
+
overridden = false,
|
|
176
177
|
onLongPress
|
|
177
178
|
}) {
|
|
178
179
|
const statusColor = getStatusColor(event.status, event.error);
|
|
@@ -211,6 +212,9 @@ function NetworkEventItemCompact({
|
|
|
211
212
|
}) : null, saved ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Bookmark, {
|
|
212
213
|
size: 10,
|
|
213
214
|
color: _sharedUi.macOSColors.semantic.debug
|
|
215
|
+
}) : null, overridden || event.override ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.FlaskConical, {
|
|
216
|
+
size: 10,
|
|
217
|
+
color: _sharedUi.macOSColors.semantic.warning
|
|
214
218
|
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(StatusIndicator, {
|
|
215
219
|
event: event,
|
|
216
220
|
isPending: isPending,
|
|
@@ -222,7 +222,8 @@ function NetworkHeaderCopyButton({
|
|
|
222
222
|
ignoredPatterns,
|
|
223
223
|
copySettings,
|
|
224
224
|
paused,
|
|
225
|
-
onUpgradePress
|
|
225
|
+
onUpgradePress,
|
|
226
|
+
label
|
|
226
227
|
}) {
|
|
227
228
|
const hasEvents = (0, _useNetworkHasMatches.useNetworkHasMatches)({
|
|
228
229
|
filter,
|
|
@@ -230,15 +231,18 @@ function NetworkHeaderCopyButton({
|
|
|
230
231
|
paused
|
|
231
232
|
});
|
|
232
233
|
if (!isPro) {
|
|
233
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
234
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
234
235
|
"sentry-label": "ignore copy pro",
|
|
235
236
|
onPress: onUpgradePress,
|
|
236
|
-
style: [styles.headerActionButton, !hasEvents && styles.headerActionButtonDisabled],
|
|
237
|
+
style: [label ? styles.copyMenuRow : styles.headerActionButton, !hasEvents && styles.headerActionButtonDisabled],
|
|
237
238
|
disabled: !hasEvents,
|
|
238
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Copy, {
|
|
239
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Copy, {
|
|
239
240
|
size: 14,
|
|
240
241
|
color: hasEvents ? _sharedUi.macOSColors.text.secondary : _sharedUi.macOSColors.text.disabled
|
|
241
|
-
})
|
|
242
|
+
}), label ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
243
|
+
style: styles.copyMenuLabel,
|
|
244
|
+
children: label
|
|
245
|
+
}) : null]
|
|
242
246
|
});
|
|
243
247
|
}
|
|
244
248
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CopyButton
|
|
@@ -247,7 +251,9 @@ function NetworkHeaderCopyButton({
|
|
|
247
251
|
, {
|
|
248
252
|
value: () => (0, _generateNetworkCopyText.generateNetworkCopyText)((0, _filterNetworkEvents.filterNetworkEvents)((0, _filterNetworkEvents.applyIgnoredPatterns)(_networkEventStore.networkEventStore.getEvents(), ignoredPatterns), filter), copySettings),
|
|
249
253
|
size: 14,
|
|
250
|
-
|
|
254
|
+
label: label,
|
|
255
|
+
buttonStyle: label ? styles.copyMenuRow : styles.headerActionButton,
|
|
256
|
+
labelStyle: styles.copyMenuLabel,
|
|
251
257
|
colors: {
|
|
252
258
|
idle: hasEvents ? _sharedUi.macOSColors.text.secondary : _sharedUi.macOSColors.text.disabled,
|
|
253
259
|
success: _sharedUi.macOSColors.semantic.success,
|
|
@@ -257,6 +263,20 @@ function NetworkHeaderCopyButton({
|
|
|
257
263
|
});
|
|
258
264
|
}
|
|
259
265
|
const styles = _reactNative.StyleSheet.create({
|
|
266
|
+
/** The overflow-menu variant: a full-width row, matching the other items. */
|
|
267
|
+
copyMenuRow: {
|
|
268
|
+
flexDirection: "row",
|
|
269
|
+
alignItems: "center",
|
|
270
|
+
gap: 10,
|
|
271
|
+
paddingHorizontal: 6,
|
|
272
|
+
paddingVertical: 11,
|
|
273
|
+
justifyContent: "flex-start"
|
|
274
|
+
},
|
|
275
|
+
copyMenuLabel: {
|
|
276
|
+
fontSize: 13,
|
|
277
|
+
fontWeight: "600",
|
|
278
|
+
color: _sharedUi.macOSColors.text.primary
|
|
279
|
+
},
|
|
260
280
|
headerChipRow: {
|
|
261
281
|
flexDirection: "row",
|
|
262
282
|
alignItems: "center",
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.NetworkHeaderMenu = NetworkHeaderMenu;
|
|
7
|
+
exports.NetworkHeaderMenuButton = NetworkHeaderMenuButton;
|
|
8
|
+
exports.NetworkHeaderMenuItem = NetworkHeaderMenuItem;
|
|
9
|
+
var _reactNative = require("react-native");
|
|
10
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
11
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
12
|
+
/**
|
|
13
|
+
* The header's overflow menu.
|
|
14
|
+
*
|
|
15
|
+
* The toolbar had grown to three status badges and six icon buttons, which on a
|
|
16
|
+
* 402pt screen meant the pending badge was being overlapped by the search
|
|
17
|
+
* button. Something had to leave, and the rule for deciding what is:
|
|
18
|
+
*
|
|
19
|
+
* **A control that COMMUNICATES STATE stays visible. A destination or a rare
|
|
20
|
+
* action goes in the menu.**
|
|
21
|
+
*
|
|
22
|
+
* That keeps the power toggle (are we capturing?), the overrides flask (is the
|
|
23
|
+
* app being lied to, and how many rules?), the status badges (what happened)
|
|
24
|
+
* and Clear (the reproduce loop is clear → repro → read, and burying the first
|
|
25
|
+
* step doubles it). Search stays because it's the only way through 500 rows.
|
|
26
|
+
*
|
|
27
|
+
* Filters, Saved and Copy leave. Filters is the interesting one — it does show
|
|
28
|
+
* state, so the ⋯ carries a dot when a filter is applied rather than hiding
|
|
29
|
+
* that fact.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
function NetworkHeaderMenuButton({
|
|
33
|
+
onPress,
|
|
34
|
+
isOpen,
|
|
35
|
+
hasIndicator
|
|
36
|
+
}) {
|
|
37
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
38
|
+
onPress: onPress,
|
|
39
|
+
"sentry-label": "ignore toggle header menu",
|
|
40
|
+
accessibilityLabel: isOpen ? "Close menu" : "More actions",
|
|
41
|
+
style: [styles.button, isOpen && styles.buttonOpen],
|
|
42
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
43
|
+
style: styles.dots,
|
|
44
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
45
|
+
style: [styles.dot, isOpen && styles.dotOpen]
|
|
46
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
47
|
+
style: [styles.dot, isOpen && styles.dotOpen]
|
|
48
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
49
|
+
style: [styles.dot, isOpen && styles.dotOpen]
|
|
50
|
+
})]
|
|
51
|
+
}), hasIndicator ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
52
|
+
style: styles.indicator
|
|
53
|
+
}) : null]
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The dropdown itself, rendered in the modal BODY rather than the header —
|
|
58
|
+
* the header is a fixed-height row and anything overflowing it is clipped, so
|
|
59
|
+
* a panel anchored to the top-right of the body lands exactly where a dropdown
|
|
60
|
+
* from the ⋯ should appear.
|
|
61
|
+
*/
|
|
62
|
+
function NetworkHeaderMenu({
|
|
63
|
+
onClose,
|
|
64
|
+
children
|
|
65
|
+
}) {
|
|
66
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
67
|
+
style: styles.overlay,
|
|
68
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
69
|
+
style: styles.backdrop,
|
|
70
|
+
activeOpacity: 1,
|
|
71
|
+
onPress: onClose,
|
|
72
|
+
"sentry-label": "ignore dismiss header menu"
|
|
73
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
74
|
+
style: styles.panel,
|
|
75
|
+
children: children
|
|
76
|
+
})]
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
function NetworkHeaderMenuItem({
|
|
80
|
+
icon,
|
|
81
|
+
label,
|
|
82
|
+
detail,
|
|
83
|
+
onPress
|
|
84
|
+
}) {
|
|
85
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
86
|
+
onPress: onPress,
|
|
87
|
+
"sentry-label": "ignore header menu item",
|
|
88
|
+
style: styles.item,
|
|
89
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
90
|
+
style: styles.itemIcon,
|
|
91
|
+
children: icon
|
|
92
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
93
|
+
style: styles.itemLabel,
|
|
94
|
+
children: label
|
|
95
|
+
}), detail ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
96
|
+
style: styles.itemDetail,
|
|
97
|
+
children: detail
|
|
98
|
+
}) : null]
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
const styles = _reactNative.StyleSheet.create({
|
|
102
|
+
// The same 32×32 box every other header action uses, minus the fill and
|
|
103
|
+
// border. Padding alone gave a 3pt-wide hit area AND a shorter box than its
|
|
104
|
+
// neighbours, which is why the dots sat high in the row; a fixed square
|
|
105
|
+
// centres the glyph on the same baseline as the search/power/clear icons.
|
|
106
|
+
button: {
|
|
107
|
+
width: 32,
|
|
108
|
+
height: 32,
|
|
109
|
+
borderRadius: 8,
|
|
110
|
+
alignItems: "center",
|
|
111
|
+
justifyContent: "center"
|
|
112
|
+
},
|
|
113
|
+
// Only lit while the menu is down — the button is the one thing not covered
|
|
114
|
+
// by the backdrop, so it has to look like the thing that is currently open.
|
|
115
|
+
buttonOpen: {
|
|
116
|
+
backgroundColor: _sharedUi.macOSColors.background.hover
|
|
117
|
+
},
|
|
118
|
+
dots: {
|
|
119
|
+
flexDirection: "column",
|
|
120
|
+
gap: 2.5,
|
|
121
|
+
alignItems: "center"
|
|
122
|
+
},
|
|
123
|
+
dot: {
|
|
124
|
+
width: 3,
|
|
125
|
+
height: 3,
|
|
126
|
+
borderRadius: 2,
|
|
127
|
+
backgroundColor: _sharedUi.macOSColors.text.secondary
|
|
128
|
+
},
|
|
129
|
+
dotOpen: {
|
|
130
|
+
backgroundColor: _sharedUi.macOSColors.text.primary
|
|
131
|
+
},
|
|
132
|
+
indicator: {
|
|
133
|
+
position: "absolute",
|
|
134
|
+
// Sits just up-and-right of the top dot. Anchored to the 32pt box's corner
|
|
135
|
+
// it would float off on its own, since the dot column is only 3pt wide.
|
|
136
|
+
top: 6,
|
|
137
|
+
right: 8,
|
|
138
|
+
width: 6,
|
|
139
|
+
height: 6,
|
|
140
|
+
borderRadius: 3,
|
|
141
|
+
backgroundColor: _sharedUi.macOSColors.semantic.info
|
|
142
|
+
},
|
|
143
|
+
overlay: {
|
|
144
|
+
..._sharedUi.absoluteFill,
|
|
145
|
+
zIndex: 50
|
|
146
|
+
},
|
|
147
|
+
backdrop: {
|
|
148
|
+
..._sharedUi.absoluteFill,
|
|
149
|
+
backgroundColor: "rgba(0,0,0,0.5)"
|
|
150
|
+
},
|
|
151
|
+
panel: {
|
|
152
|
+
position: "absolute",
|
|
153
|
+
top: 6,
|
|
154
|
+
right: 8,
|
|
155
|
+
minWidth: 196,
|
|
156
|
+
paddingVertical: 4,
|
|
157
|
+
borderRadius: 8,
|
|
158
|
+
borderWidth: 1,
|
|
159
|
+
borderColor: _sharedUi.macOSColors.border.hover,
|
|
160
|
+
backgroundColor: _sharedUi.macOSColors.background.card
|
|
161
|
+
},
|
|
162
|
+
item: {
|
|
163
|
+
flexDirection: "row",
|
|
164
|
+
alignItems: "center",
|
|
165
|
+
gap: 10,
|
|
166
|
+
paddingHorizontal: 12,
|
|
167
|
+
paddingVertical: 11
|
|
168
|
+
},
|
|
169
|
+
itemIcon: {
|
|
170
|
+
width: 16,
|
|
171
|
+
alignItems: "center"
|
|
172
|
+
},
|
|
173
|
+
itemLabel: {
|
|
174
|
+
flex: 1,
|
|
175
|
+
fontSize: 13,
|
|
176
|
+
fontWeight: "600",
|
|
177
|
+
color: _sharedUi.macOSColors.text.primary
|
|
178
|
+
},
|
|
179
|
+
itemDetail: {
|
|
180
|
+
fontSize: 11,
|
|
181
|
+
color: _sharedUi.macOSColors.text.muted
|
|
182
|
+
}
|
|
183
|
+
});
|
|
@@ -11,6 +11,8 @@ var _NetworkEventItemCompact = require("./NetworkEventItemCompact");
|
|
|
11
11
|
var _NetworkUpgradeBanner = require("./NetworkUpgradeBanner");
|
|
12
12
|
var _useNetworkEventList = require("../hooks/useNetworkEventList");
|
|
13
13
|
var _useNetworkSaved = require("../hooks/useNetworkSaved");
|
|
14
|
+
var _useOverrideRules = require("../hooks/useOverrideRules");
|
|
15
|
+
var _matchRule = require("../overrides/matchRule");
|
|
14
16
|
var _withPinnedFirst = require("../utils/withPinnedFirst");
|
|
15
17
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
16
18
|
/**
|
|
@@ -91,6 +93,62 @@ function PinnedSection({
|
|
|
91
93
|
}, event.id))]
|
|
92
94
|
});
|
|
93
95
|
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The OVERRIDDEN strip, above the pins.
|
|
99
|
+
*
|
|
100
|
+
* An overridden request is the one thing in this list that isn't true — the app
|
|
101
|
+
* got something the server never sent. That has to be impossible to miss, and a
|
|
102
|
+
* glyph on a row twenty scroll-positions down isn't. It sits ABOVE pins because
|
|
103
|
+
* a stale override explains a bug, whereas a pin only marks one.
|
|
104
|
+
*
|
|
105
|
+
* Rows are matched against the RULES rather than filtered on the `override`
|
|
106
|
+
* mark, so the request you built a rule from hoists immediately instead of
|
|
107
|
+
* waiting for the endpoint to be called again.
|
|
108
|
+
*
|
|
109
|
+
* The header button is PAUSE, not "Manage". Flipping overrides off and on is by
|
|
110
|
+
* far the most repeated action in a testing session — force the failure, check
|
|
111
|
+
* the UI, turn it off, check the happy path, turn it back on — and it used to
|
|
112
|
+
* cost a trip to another screen each way. The manager is still one tap away on
|
|
113
|
+
* the toolbar; it just isn't the thing you reach for twenty times an hour.
|
|
114
|
+
*/
|
|
115
|
+
function OverriddenSection({
|
|
116
|
+
events,
|
|
117
|
+
onEventPress,
|
|
118
|
+
onLongPress,
|
|
119
|
+
savedLiveIds,
|
|
120
|
+
paused,
|
|
121
|
+
onTogglePaused
|
|
122
|
+
}) {
|
|
123
|
+
if (events.length === 0) return null;
|
|
124
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
125
|
+
style: [styles.overriddenSection, paused && styles.overriddenSectionOff],
|
|
126
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
127
|
+
style: styles.overriddenHeader,
|
|
128
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.FlaskConical, {
|
|
129
|
+
size: 11,
|
|
130
|
+
color: paused ? _sharedUi.macOSColors.text.muted : _sharedUi.macOSColors.semantic.warning
|
|
131
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
132
|
+
style: [styles.overriddenTitle, paused && styles.overriddenTitleOff],
|
|
133
|
+
children: paused ? `PAUSED · ${events.length}` : `OVERRIDDEN · ${events.length}`
|
|
134
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
135
|
+
onPress: onTogglePaused,
|
|
136
|
+
"sentry-label": "ignore pause overrides",
|
|
137
|
+
style: styles.overriddenManage,
|
|
138
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
139
|
+
style: [styles.overriddenManageText, paused && styles.overriddenTitleOff],
|
|
140
|
+
children: paused ? "Resume" : "Pause"
|
|
141
|
+
})
|
|
142
|
+
})]
|
|
143
|
+
}), events.map(event => /*#__PURE__*/(0, _jsxRuntime.jsx)(_NetworkEventItemCompact.NetworkEventItemCompact, {
|
|
144
|
+
event: event,
|
|
145
|
+
onPress: onEventPress,
|
|
146
|
+
onLongPress: onLongPress,
|
|
147
|
+
overridden: true,
|
|
148
|
+
saved: savedLiveIds.has(event.id)
|
|
149
|
+
}, event.id))]
|
|
150
|
+
});
|
|
151
|
+
}
|
|
94
152
|
function NetworkListScreen({
|
|
95
153
|
visible,
|
|
96
154
|
paused,
|
|
@@ -122,6 +180,15 @@ function NetworkListScreen({
|
|
|
122
180
|
clearPinned
|
|
123
181
|
} = (0, _useNetworkSaved.useNetworkSaved)();
|
|
124
182
|
|
|
183
|
+
// Which rules are live right now — the strip below reflects the rules, not
|
|
184
|
+
// the history, so it's correct the moment a rule is made or removed.
|
|
185
|
+
const {
|
|
186
|
+
rules,
|
|
187
|
+
enabled: overridesEnabled,
|
|
188
|
+
setEnabled,
|
|
189
|
+
isRuleSpent
|
|
190
|
+
} = (0, _useOverrideRules.useOverrideRules)();
|
|
191
|
+
|
|
125
192
|
// Stable identity: handed to memoized rows.
|
|
126
193
|
const handleLongPress = (0, _react.useCallback)(event => {
|
|
127
194
|
togglePin(event);
|
|
@@ -136,6 +203,17 @@ function NetworkListScreen({
|
|
|
136
203
|
pinned,
|
|
137
204
|
rest
|
|
138
205
|
} = (0, _withPinnedFirst.splitPinned)(visibleEvents, pinnedEvents, pinnedLiveIds);
|
|
206
|
+
|
|
207
|
+
// Hoist anything an active rule covers. Done after `splitPinned` so a request
|
|
208
|
+
// that is both pinned and overridden appears once, in the louder section.
|
|
209
|
+
// Paused rules still populate the strip — that's how you find the thing you
|
|
210
|
+
// paused in order to resume it. The header says PAUSED instead.
|
|
211
|
+
const activeRules = rules.filter(rule => rule.enabled && !isRuleSpent(rule));
|
|
212
|
+
const isOverridden = event => activeRules.some(rule => (0, _matchRule.ruleMatches)(rule, event.url, String(event.method || "GET")));
|
|
213
|
+
const overridden = activeRules.length ? [...pinned, ...rest].filter(isOverridden) : [];
|
|
214
|
+
const overriddenIds = new Set(overridden.map(event => event.id));
|
|
215
|
+
const pinnedRows = pinned.filter(event => !overriddenIds.has(event.id));
|
|
216
|
+
const restRows = overriddenIds.size ? rest.filter(event => !overriddenIds.has(event.id)) : rest;
|
|
139
217
|
const isEnabled = !paused;
|
|
140
218
|
const renderItem = ({
|
|
141
219
|
item
|
|
@@ -167,14 +245,21 @@ function NetworkListScreen({
|
|
|
167
245
|
style: styles.disabledText,
|
|
168
246
|
children: "Network interception is disabled"
|
|
169
247
|
})]
|
|
170
|
-
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
171
|
-
events:
|
|
248
|
+
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(OverriddenSection, {
|
|
249
|
+
events: overridden,
|
|
250
|
+
onEventPress: onEventPress,
|
|
251
|
+
onLongPress: handleLongPress,
|
|
252
|
+
savedLiveIds: savedLiveIds,
|
|
253
|
+
paused: !overridesEnabled,
|
|
254
|
+
onTogglePaused: () => setEnabled(!overridesEnabled)
|
|
255
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(PinnedSection, {
|
|
256
|
+
events: pinnedRows,
|
|
172
257
|
onEventPress: onEventPress,
|
|
173
258
|
onLongPress: handleLongPress,
|
|
174
259
|
savedLiveIds: savedLiveIds,
|
|
175
260
|
onClearPinned: clearPinned
|
|
176
|
-
}),
|
|
177
|
-
data:
|
|
261
|
+
}), restRows.length > 0 || hasLockedEvents ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.FlatList, {
|
|
262
|
+
data: restRows,
|
|
178
263
|
renderItem: renderItem,
|
|
179
264
|
keyExtractor: keyExtractor,
|
|
180
265
|
contentContainerStyle: styles.listContent,
|
|
@@ -203,7 +288,7 @@ function NetworkListScreen({
|
|
|
203
288
|
extraData: savedLiveIds,
|
|
204
289
|
"sentry-label": "ignore network events list",
|
|
205
290
|
ListFooterComponent: renderListFooter
|
|
206
|
-
}) :
|
|
291
|
+
}) : pinnedRows.length > 0 || overridden.length > 0 ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(EmptyState, {
|
|
207
292
|
isEnabled: isEnabled
|
|
208
293
|
})]
|
|
209
294
|
});
|
|
@@ -218,6 +303,42 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
218
303
|
* these rows do NOT obey the filters, and the boundary is what tells the
|
|
219
304
|
* user why a request they just filtered out is still on screen.
|
|
220
305
|
*/
|
|
306
|
+
overriddenSection: {
|
|
307
|
+
borderBottomWidth: 1,
|
|
308
|
+
borderBottomColor: _sharedUi.macOSColors.semantic.warning + "44",
|
|
309
|
+
backgroundColor: _sharedUi.macOSColors.semantic.warningBackground
|
|
310
|
+
},
|
|
311
|
+
overriddenSectionOff: {
|
|
312
|
+
borderBottomColor: _sharedUi.macOSColors.border.default,
|
|
313
|
+
backgroundColor: _sharedUi.macOSColors.background.card
|
|
314
|
+
},
|
|
315
|
+
overriddenTitleOff: {
|
|
316
|
+
color: _sharedUi.macOSColors.text.muted
|
|
317
|
+
},
|
|
318
|
+
overriddenHeader: {
|
|
319
|
+
flexDirection: "row",
|
|
320
|
+
alignItems: "center",
|
|
321
|
+
gap: 6,
|
|
322
|
+
paddingHorizontal: 12,
|
|
323
|
+
paddingTop: 8,
|
|
324
|
+
paddingBottom: 4
|
|
325
|
+
},
|
|
326
|
+
overriddenTitle: {
|
|
327
|
+
flex: 1,
|
|
328
|
+
fontSize: 10,
|
|
329
|
+
fontWeight: "700",
|
|
330
|
+
letterSpacing: 0.8,
|
|
331
|
+
color: _sharedUi.macOSColors.semantic.warning
|
|
332
|
+
},
|
|
333
|
+
overriddenManage: {
|
|
334
|
+
paddingHorizontal: 6,
|
|
335
|
+
paddingVertical: 2
|
|
336
|
+
},
|
|
337
|
+
overriddenManageText: {
|
|
338
|
+
fontSize: 10,
|
|
339
|
+
fontWeight: "600",
|
|
340
|
+
color: _sharedUi.macOSColors.semantic.warning
|
|
341
|
+
},
|
|
221
342
|
pinnedSection: {
|
|
222
343
|
borderBottomWidth: 1,
|
|
223
344
|
borderBottomColor: _sharedUi.macOSColors.border.default,
|