@buoy-gg/network 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +381 -0
- package/lib/commonjs/index.js +34 -0
- package/lib/commonjs/network/components/NetworkCopySettingsView.js +867 -0
- package/lib/commonjs/network/components/NetworkEventDetailView.js +837 -0
- package/lib/commonjs/network/components/NetworkEventItemCompact.js +323 -0
- package/lib/commonjs/network/components/NetworkFilterViewV3.js +297 -0
- package/lib/commonjs/network/components/NetworkModal.js +937 -0
- package/lib/commonjs/network/hooks/useNetworkEvents.js +320 -0
- package/lib/commonjs/network/hooks/useTickEveryMinute.js +34 -0
- package/lib/commonjs/network/index.js +102 -0
- package/lib/commonjs/network/types/index.js +1 -0
- package/lib/commonjs/network/utils/extractOperationName.js +80 -0
- package/lib/commonjs/network/utils/formatGraphQLVariables.js +219 -0
- package/lib/commonjs/network/utils/formatting.js +30 -0
- package/lib/commonjs/network/utils/networkEventStore.js +269 -0
- package/lib/commonjs/network/utils/networkListener.js +801 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/preset.js +83 -0
- package/lib/module/index.js +7 -0
- package/lib/module/network/components/NetworkCopySettingsView.js +862 -0
- package/lib/module/network/components/NetworkEventDetailView.js +834 -0
- package/lib/module/network/components/NetworkEventItemCompact.js +320 -0
- package/lib/module/network/components/NetworkFilterViewV3.js +293 -0
- package/lib/module/network/components/NetworkModal.js +933 -0
- package/lib/module/network/hooks/useNetworkEvents.js +316 -0
- package/lib/module/network/hooks/useTickEveryMinute.js +29 -0
- package/lib/module/network/index.js +20 -0
- package/lib/module/network/types/index.js +1 -0
- package/lib/module/network/utils/extractOperationName.js +76 -0
- package/lib/module/network/utils/formatGraphQLVariables.js +213 -0
- package/lib/module/network/utils/formatting.js +9 -0
- package/lib/module/network/utils/networkEventStore.js +265 -0
- package/lib/module/network/utils/networkListener.js +791 -0
- package/lib/module/preset.js +79 -0
- package/lib/typescript/index.d.ts +3 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/network/components/NetworkCopySettingsView.d.ts +26 -0
- package/lib/typescript/network/components/NetworkCopySettingsView.d.ts.map +1 -0
- package/lib/typescript/network/components/NetworkEventDetailView.d.ts +13 -0
- package/lib/typescript/network/components/NetworkEventDetailView.d.ts.map +1 -0
- package/lib/typescript/network/components/NetworkEventItemCompact.d.ts +12 -0
- package/lib/typescript/network/components/NetworkEventItemCompact.d.ts.map +1 -0
- package/lib/typescript/network/components/NetworkFilterViewV3.d.ts +22 -0
- package/lib/typescript/network/components/NetworkFilterViewV3.d.ts.map +1 -0
- package/lib/typescript/network/components/NetworkModal.d.ts +14 -0
- package/lib/typescript/network/components/NetworkModal.d.ts.map +1 -0
- package/lib/typescript/network/hooks/useNetworkEvents.d.ts +72 -0
- package/lib/typescript/network/hooks/useNetworkEvents.d.ts.map +1 -0
- package/lib/typescript/network/hooks/useTickEveryMinute.d.ts +9 -0
- package/lib/typescript/network/hooks/useTickEveryMinute.d.ts.map +1 -0
- package/lib/typescript/network/index.d.ts +12 -0
- package/lib/typescript/network/index.d.ts.map +1 -0
- package/lib/typescript/network/types/index.d.ts +88 -0
- package/lib/typescript/network/types/index.d.ts.map +1 -0
- package/lib/typescript/network/utils/extractOperationName.d.ts +41 -0
- package/lib/typescript/network/utils/extractOperationName.d.ts.map +1 -0
- package/lib/typescript/network/utils/formatGraphQLVariables.d.ts +79 -0
- package/lib/typescript/network/utils/formatGraphQLVariables.d.ts.map +1 -0
- package/lib/typescript/network/utils/formatting.d.ts +6 -0
- package/lib/typescript/network/utils/formatting.d.ts.map +1 -0
- package/lib/typescript/network/utils/networkEventStore.d.ts +81 -0
- package/lib/typescript/network/utils/networkEventStore.d.ts.map +1 -0
- package/lib/typescript/network/utils/networkListener.d.ts +191 -0
- package/lib/typescript/network/utils/networkListener.d.ts.map +1 -0
- package/lib/typescript/preset.d.ts +76 -0
- package/lib/typescript/preset.d.ts.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,867 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DEFAULT_COPY_SETTINGS = void 0;
|
|
7
|
+
exports.NetworkCopySettingsView = NetworkCopySettingsView;
|
|
8
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
9
|
+
var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
|
|
10
|
+
var _react = require("react");
|
|
11
|
+
var _reactNative = require("react-native");
|
|
12
|
+
var _useTickEveryMinute = require("../hooks/useTickEveryMinute");
|
|
13
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
|
+
const DEFAULT_COPY_SETTINGS = exports.DEFAULT_COPY_SETTINGS = {
|
|
15
|
+
includeMethod: true,
|
|
16
|
+
includeStatus: true,
|
|
17
|
+
includeDuration: true,
|
|
18
|
+
includeTimestamp: true,
|
|
19
|
+
includeClient: true,
|
|
20
|
+
includeSizes: true,
|
|
21
|
+
includeErrors: true,
|
|
22
|
+
includeRequestHeaders: true,
|
|
23
|
+
includeResponseHeaders: true,
|
|
24
|
+
includeRequestBody: true,
|
|
25
|
+
includeResponseBody: true,
|
|
26
|
+
bodySizeThreshold: 10,
|
|
27
|
+
format: "markdown",
|
|
28
|
+
filterMode: "all"
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// Preset configurations for comparison
|
|
32
|
+
const PRESET_CONFIGS = {
|
|
33
|
+
urls: {
|
|
34
|
+
includeMethod: true,
|
|
35
|
+
includeStatus: false,
|
|
36
|
+
includeDuration: false,
|
|
37
|
+
includeTimestamp: false,
|
|
38
|
+
includeClient: false,
|
|
39
|
+
includeSizes: false,
|
|
40
|
+
includeErrors: false,
|
|
41
|
+
includeRequestHeaders: false,
|
|
42
|
+
includeResponseHeaders: false,
|
|
43
|
+
includeRequestBody: false,
|
|
44
|
+
includeResponseBody: false,
|
|
45
|
+
bodySizeThreshold: 10,
|
|
46
|
+
format: "plaintext",
|
|
47
|
+
filterMode: "all"
|
|
48
|
+
},
|
|
49
|
+
llm: {
|
|
50
|
+
includeMethod: true,
|
|
51
|
+
includeStatus: true,
|
|
52
|
+
includeDuration: true,
|
|
53
|
+
includeTimestamp: true,
|
|
54
|
+
includeClient: true,
|
|
55
|
+
includeSizes: true,
|
|
56
|
+
includeErrors: true,
|
|
57
|
+
includeRequestHeaders: true,
|
|
58
|
+
includeResponseHeaders: true,
|
|
59
|
+
includeRequestBody: true,
|
|
60
|
+
includeResponseBody: true,
|
|
61
|
+
bodySizeThreshold: 10,
|
|
62
|
+
format: "markdown",
|
|
63
|
+
filterMode: "all"
|
|
64
|
+
},
|
|
65
|
+
json: {
|
|
66
|
+
includeMethod: true,
|
|
67
|
+
includeStatus: true,
|
|
68
|
+
includeDuration: true,
|
|
69
|
+
includeTimestamp: true,
|
|
70
|
+
includeClient: true,
|
|
71
|
+
includeSizes: true,
|
|
72
|
+
includeErrors: true,
|
|
73
|
+
includeRequestHeaders: true,
|
|
74
|
+
includeResponseHeaders: true,
|
|
75
|
+
includeRequestBody: true,
|
|
76
|
+
includeResponseBody: true,
|
|
77
|
+
bodySizeThreshold: -1,
|
|
78
|
+
format: "json",
|
|
79
|
+
filterMode: "all"
|
|
80
|
+
},
|
|
81
|
+
full: {
|
|
82
|
+
includeMethod: true,
|
|
83
|
+
includeStatus: true,
|
|
84
|
+
includeDuration: true,
|
|
85
|
+
includeTimestamp: true,
|
|
86
|
+
includeClient: true,
|
|
87
|
+
includeSizes: true,
|
|
88
|
+
includeErrors: true,
|
|
89
|
+
includeRequestHeaders: true,
|
|
90
|
+
includeResponseHeaders: true,
|
|
91
|
+
includeRequestBody: true,
|
|
92
|
+
includeResponseBody: true,
|
|
93
|
+
bodySizeThreshold: -1,
|
|
94
|
+
format: "markdown",
|
|
95
|
+
filterMode: "all"
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
// Detect which preset matches current settings
|
|
99
|
+
function detectActivePreset(settings) {
|
|
100
|
+
for (const [presetName, presetConfig] of Object.entries(PRESET_CONFIGS)) {
|
|
101
|
+
const matches = Object.keys(presetConfig).every(key => presetConfig[key] === settings[key]);
|
|
102
|
+
if (matches) return presetName;
|
|
103
|
+
}
|
|
104
|
+
return null; // No preset matches = Custom
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Size thresholds for warnings
|
|
108
|
+
const SIZE_WARNING_THRESHOLD = 100 * 1024; // 100KB - show warning
|
|
109
|
+
const SIZE_DANGER_THRESHOLD = 500 * 1024; // 500KB - show danger warning
|
|
110
|
+
|
|
111
|
+
// Helper to format bytes for display
|
|
112
|
+
function formatBytes(bytes) {
|
|
113
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
114
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
115
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
116
|
+
}
|
|
117
|
+
function NetworkCopySettingsView({
|
|
118
|
+
settings,
|
|
119
|
+
onSettingsChange,
|
|
120
|
+
events = []
|
|
121
|
+
}) {
|
|
122
|
+
// Check Pro status for gating
|
|
123
|
+
const {
|
|
124
|
+
isPro
|
|
125
|
+
} = (0, _sharedUi.useFeatureGate)();
|
|
126
|
+
|
|
127
|
+
// Use tick for updating relative time
|
|
128
|
+
const tick = (0, _useTickEveryMinute.useTickEveryMinute)();
|
|
129
|
+
|
|
130
|
+
// State for preview expansion - collapsed by default to prevent crashes
|
|
131
|
+
const [isPreviewExpanded, setIsPreviewExpanded] = (0, _react.useState)(false);
|
|
132
|
+
|
|
133
|
+
// Auto-detect if we have live data
|
|
134
|
+
const hasLiveData = events.length > 0;
|
|
135
|
+
|
|
136
|
+
// Get the most recent event timestamp for "last updated" display
|
|
137
|
+
const lastEventTimestamp = (0, _react.useMemo)(() => {
|
|
138
|
+
if (!hasLiveData) return null;
|
|
139
|
+
const timestamps = events.map(e => typeof e.timestamp === 'number' ? e.timestamp : new Date(e.timestamp).getTime());
|
|
140
|
+
return Math.max(...timestamps);
|
|
141
|
+
}, [events, hasLiveData]);
|
|
142
|
+
|
|
143
|
+
// Detect active preset
|
|
144
|
+
const activePreset = (0, _react.useMemo)(() => detectActivePreset(settings), [settings]);
|
|
145
|
+
|
|
146
|
+
// Quick preset handlers
|
|
147
|
+
const applyUrlsPreset = (0, _react.useCallback)(() => {
|
|
148
|
+
onSettingsChange(PRESET_CONFIGS.urls);
|
|
149
|
+
}, [onSettingsChange]);
|
|
150
|
+
const applyLLMPreset = (0, _react.useCallback)(() => {
|
|
151
|
+
onSettingsChange(PRESET_CONFIGS.llm);
|
|
152
|
+
}, [onSettingsChange]);
|
|
153
|
+
const applyJSONPreset = (0, _react.useCallback)(() => {
|
|
154
|
+
onSettingsChange(PRESET_CONFIGS.json);
|
|
155
|
+
}, [onSettingsChange]);
|
|
156
|
+
const applyFullPreset = (0, _react.useCallback)(() => {
|
|
157
|
+
onSettingsChange(PRESET_CONFIGS.full);
|
|
158
|
+
}, [onSettingsChange]);
|
|
159
|
+
|
|
160
|
+
// Handle individual option changes
|
|
161
|
+
const handleOptionChange = (0, _react.useCallback)((optionId, value) => {
|
|
162
|
+
const [group, key] = optionId.split("::");
|
|
163
|
+
if (group === "preset") {
|
|
164
|
+
switch (key) {
|
|
165
|
+
case "urls":
|
|
166
|
+
applyUrlsPreset();
|
|
167
|
+
break;
|
|
168
|
+
case "llm":
|
|
169
|
+
applyLLMPreset();
|
|
170
|
+
break;
|
|
171
|
+
case "json":
|
|
172
|
+
applyJSONPreset();
|
|
173
|
+
break;
|
|
174
|
+
case "full":
|
|
175
|
+
applyFullPreset();
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (group === "requestInfo") {
|
|
181
|
+
// Toggle boolean value
|
|
182
|
+
onSettingsChange({
|
|
183
|
+
...settings,
|
|
184
|
+
[key]: !settings[key]
|
|
185
|
+
});
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (group === "headers") {
|
|
189
|
+
// Toggle boolean value
|
|
190
|
+
onSettingsChange({
|
|
191
|
+
...settings,
|
|
192
|
+
[key]: !settings[key]
|
|
193
|
+
});
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (group === "body") {
|
|
197
|
+
if (key === "bodySizeThreshold") {
|
|
198
|
+
onSettingsChange({
|
|
199
|
+
...settings,
|
|
200
|
+
bodySizeThreshold: value
|
|
201
|
+
});
|
|
202
|
+
} else {
|
|
203
|
+
// Toggle boolean value
|
|
204
|
+
onSettingsChange({
|
|
205
|
+
...settings,
|
|
206
|
+
[key]: !settings[key]
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
if (group === "format") {
|
|
212
|
+
onSettingsChange({
|
|
213
|
+
...settings,
|
|
214
|
+
format: value
|
|
215
|
+
});
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (group === "filter") {
|
|
219
|
+
onSettingsChange({
|
|
220
|
+
...settings,
|
|
221
|
+
filterMode: value
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}, [settings, onSettingsChange, applyUrlsPreset, applyLLMPreset, applyJSONPreset, applyFullPreset]);
|
|
225
|
+
|
|
226
|
+
// Mock data for preview
|
|
227
|
+
const mockRequestData = (0, _react.useMemo)(() => ({
|
|
228
|
+
method: "POST",
|
|
229
|
+
url: "https://api.example.com/v1/users",
|
|
230
|
+
status: 201,
|
|
231
|
+
duration: 342,
|
|
232
|
+
timestamp: new Date().toISOString(),
|
|
233
|
+
requestHeaders: {
|
|
234
|
+
"Content-Type": "application/json",
|
|
235
|
+
"Authorization": "Bearer ***"
|
|
236
|
+
},
|
|
237
|
+
responseHeaders: {
|
|
238
|
+
"Content-Type": "application/json",
|
|
239
|
+
"X-Request-ID": "abc123"
|
|
240
|
+
},
|
|
241
|
+
requestBody: {
|
|
242
|
+
name: "John Doe",
|
|
243
|
+
email: "john@example.com"
|
|
244
|
+
},
|
|
245
|
+
responseBody: {
|
|
246
|
+
id: "user_123",
|
|
247
|
+
name: "John Doe",
|
|
248
|
+
email: "john@example.com",
|
|
249
|
+
createdAt: "2025-01-10T12:00:00Z"
|
|
250
|
+
}
|
|
251
|
+
}), []);
|
|
252
|
+
|
|
253
|
+
// Get data source - auto-detect live vs mock
|
|
254
|
+
const previewData = (0, _react.useMemo)(() => {
|
|
255
|
+
if (hasLiveData) {
|
|
256
|
+
return events; // Show ALL events
|
|
257
|
+
}
|
|
258
|
+
// Mock data - return as array for consistency
|
|
259
|
+
return [mockRequestData];
|
|
260
|
+
}, [hasLiveData, events, mockRequestData]);
|
|
261
|
+
|
|
262
|
+
// Estimate the size of the preview content to warn users about large payloads
|
|
263
|
+
const estimatedSize = (0, _react.useMemo)(() => {
|
|
264
|
+
const dataSource = hasLiveData ? events : [mockRequestData];
|
|
265
|
+
let totalSize = 0;
|
|
266
|
+
for (const eventData of dataSource) {
|
|
267
|
+
// Estimate based on what's included
|
|
268
|
+
if (settings.includeMethod) {
|
|
269
|
+
totalSize += (eventData.url?.length || 0) + 10;
|
|
270
|
+
}
|
|
271
|
+
if (settings.includeStatus) {
|
|
272
|
+
totalSize += 30;
|
|
273
|
+
}
|
|
274
|
+
if (settings.includeTimestamp) {
|
|
275
|
+
totalSize += 30;
|
|
276
|
+
}
|
|
277
|
+
if (settings.includeRequestHeaders) {
|
|
278
|
+
try {
|
|
279
|
+
totalSize += JSON.stringify(eventData.requestHeaders || {}).length;
|
|
280
|
+
} catch {
|
|
281
|
+
totalSize += 100;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
if (settings.includeRequestBody) {
|
|
285
|
+
const body = 'requestBody' in eventData ? eventData.requestBody : eventData.requestData;
|
|
286
|
+
try {
|
|
287
|
+
totalSize += JSON.stringify(body || {}).length;
|
|
288
|
+
} catch {
|
|
289
|
+
totalSize += 100;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (settings.includeResponseBody) {
|
|
293
|
+
const body = 'responseBody' in eventData ? eventData.responseBody : eventData.responseData;
|
|
294
|
+
try {
|
|
295
|
+
totalSize += JSON.stringify(body || {}).length;
|
|
296
|
+
} catch {
|
|
297
|
+
totalSize += 100;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return totalSize;
|
|
302
|
+
}, [hasLiveData, events, mockRequestData, settings]);
|
|
303
|
+
|
|
304
|
+
// Determine warning level based on estimated size
|
|
305
|
+
const sizeWarningLevel = (0, _react.useMemo)(() => {
|
|
306
|
+
if (estimatedSize >= SIZE_DANGER_THRESHOLD) return 'danger';
|
|
307
|
+
if (estimatedSize >= SIZE_WARNING_THRESHOLD) return 'warning';
|
|
308
|
+
return 'none';
|
|
309
|
+
}, [estimatedSize]);
|
|
310
|
+
|
|
311
|
+
// Generate copy text - should match preview content exactly
|
|
312
|
+
const generateCopyText = (0, _react.useCallback)(() => {
|
|
313
|
+
const dataSource = hasLiveData ? events : [mockRequestData];
|
|
314
|
+
const {
|
|
315
|
+
format,
|
|
316
|
+
includeMethod,
|
|
317
|
+
includeStatus,
|
|
318
|
+
includeTimestamp,
|
|
319
|
+
includeRequestHeaders,
|
|
320
|
+
includeRequestBody,
|
|
321
|
+
includeResponseBody
|
|
322
|
+
} = settings;
|
|
323
|
+
|
|
324
|
+
// Build filtered data for a single event
|
|
325
|
+
const buildFilteredData = eventData => {
|
|
326
|
+
const data = {};
|
|
327
|
+
if (includeMethod) {
|
|
328
|
+
data.method = eventData.method;
|
|
329
|
+
data.url = eventData.url;
|
|
330
|
+
}
|
|
331
|
+
if (includeStatus) {
|
|
332
|
+
data.status = eventData.status;
|
|
333
|
+
data.duration = eventData.duration;
|
|
334
|
+
}
|
|
335
|
+
if (includeTimestamp) {
|
|
336
|
+
data.timestamp = eventData.timestamp;
|
|
337
|
+
}
|
|
338
|
+
if (includeRequestHeaders) {
|
|
339
|
+
data.requestHeaders = eventData.requestHeaders;
|
|
340
|
+
}
|
|
341
|
+
if (includeRequestBody) {
|
|
342
|
+
data.requestBody = 'requestBody' in eventData ? eventData.requestBody : eventData.requestData;
|
|
343
|
+
}
|
|
344
|
+
if (includeResponseBody) {
|
|
345
|
+
data.responseBody = 'responseBody' in eventData ? eventData.responseBody : eventData.responseData;
|
|
346
|
+
}
|
|
347
|
+
return data;
|
|
348
|
+
};
|
|
349
|
+
if (format === "json") {
|
|
350
|
+
const allFilteredData = dataSource.map(buildFilteredData);
|
|
351
|
+
return JSON.stringify(allFilteredData, null, 2);
|
|
352
|
+
}
|
|
353
|
+
if (format === "markdown") {
|
|
354
|
+
const allRequests = dataSource.map((eventData, index) => {
|
|
355
|
+
const sections = [];
|
|
356
|
+
sections.push(`# Request ${index + 1}`);
|
|
357
|
+
if (includeMethod) {
|
|
358
|
+
sections.push(`\n**${eventData.method}** ${eventData.url}`);
|
|
359
|
+
}
|
|
360
|
+
const metaInfo = [];
|
|
361
|
+
if (includeStatus) {
|
|
362
|
+
metaInfo.push(`**Status:** ${eventData.status}`);
|
|
363
|
+
metaInfo.push(`**Duration:** ${eventData.duration}ms`);
|
|
364
|
+
}
|
|
365
|
+
if (includeTimestamp) {
|
|
366
|
+
metaInfo.push(`**Timestamp:** ${eventData.timestamp}`);
|
|
367
|
+
}
|
|
368
|
+
if (metaInfo.length > 0) {
|
|
369
|
+
sections.push('\n' + metaInfo.join('\n'));
|
|
370
|
+
}
|
|
371
|
+
if (includeRequestHeaders) {
|
|
372
|
+
const headers = eventData.requestHeaders || {};
|
|
373
|
+
sections.push(`\n## Request Headers\n\`\`\`json\n${JSON.stringify(headers, null, 2)}\n\`\`\``);
|
|
374
|
+
}
|
|
375
|
+
if (includeRequestBody) {
|
|
376
|
+
const body = 'requestBody' in eventData ? eventData.requestBody : eventData.requestData;
|
|
377
|
+
sections.push(`\n## Request Body\n\`\`\`json\n${JSON.stringify(body || {}, null, 2)}\n\`\`\``);
|
|
378
|
+
}
|
|
379
|
+
if (includeResponseBody) {
|
|
380
|
+
const body = 'responseBody' in eventData ? eventData.responseBody : eventData.responseData;
|
|
381
|
+
sections.push(`\n## Response Body\n\`\`\`json\n${JSON.stringify(body || {}, null, 2)}\n\`\`\``);
|
|
382
|
+
}
|
|
383
|
+
return sections.join('\n');
|
|
384
|
+
});
|
|
385
|
+
return allRequests.join('\n\n---\n\n') || "No data included";
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Plaintext
|
|
389
|
+
const allRequests = dataSource.map((eventData, index) => {
|
|
390
|
+
const lines = [];
|
|
391
|
+
lines.push(`Request ${index + 1}:`);
|
|
392
|
+
if (includeMethod) {
|
|
393
|
+
lines.push(`${eventData.method} ${eventData.url}`);
|
|
394
|
+
}
|
|
395
|
+
if (includeStatus) {
|
|
396
|
+
lines.push(`Status: ${eventData.status}`);
|
|
397
|
+
lines.push(`Duration: ${eventData.duration}ms`);
|
|
398
|
+
}
|
|
399
|
+
if (includeTimestamp) {
|
|
400
|
+
lines.push(`Timestamp: ${eventData.timestamp}`);
|
|
401
|
+
}
|
|
402
|
+
if (includeRequestBody) {
|
|
403
|
+
const body = 'requestBody' in eventData ? eventData.requestBody : eventData.requestData;
|
|
404
|
+
lines.push('\nRequest:');
|
|
405
|
+
lines.push(JSON.stringify(body || {}, null, 2));
|
|
406
|
+
}
|
|
407
|
+
if (includeResponseBody) {
|
|
408
|
+
const body = 'responseBody' in eventData ? eventData.responseBody : eventData.responseData;
|
|
409
|
+
lines.push('\nResponse:');
|
|
410
|
+
lines.push(JSON.stringify(body || {}, null, 2));
|
|
411
|
+
}
|
|
412
|
+
return lines.join('\n');
|
|
413
|
+
});
|
|
414
|
+
return allRequests.join('\n\n---\n\n') || "No data included";
|
|
415
|
+
}, [hasLiveData, events, mockRequestData, settings]);
|
|
416
|
+
|
|
417
|
+
// Generate the expanded preview content (only called when expanded)
|
|
418
|
+
const generateExpandedPreviewContent = (0, _react.useCallback)(() => {
|
|
419
|
+
const dataSource = hasLiveData ? events : [mockRequestData];
|
|
420
|
+
const {
|
|
421
|
+
format,
|
|
422
|
+
includeMethod,
|
|
423
|
+
includeStatus,
|
|
424
|
+
includeTimestamp,
|
|
425
|
+
includeRequestHeaders,
|
|
426
|
+
includeRequestBody,
|
|
427
|
+
includeResponseBody
|
|
428
|
+
} = settings;
|
|
429
|
+
|
|
430
|
+
// Build filtered data for a single event
|
|
431
|
+
const buildFilteredData = eventData => {
|
|
432
|
+
const data = {};
|
|
433
|
+
if (includeMethod) {
|
|
434
|
+
data.method = eventData.method;
|
|
435
|
+
data.url = eventData.url;
|
|
436
|
+
}
|
|
437
|
+
if (includeStatus) {
|
|
438
|
+
data.status = eventData.status;
|
|
439
|
+
data.duration = eventData.duration;
|
|
440
|
+
}
|
|
441
|
+
if (includeTimestamp) {
|
|
442
|
+
data.timestamp = eventData.timestamp;
|
|
443
|
+
}
|
|
444
|
+
if (includeRequestHeaders) {
|
|
445
|
+
data.requestHeaders = eventData.requestHeaders;
|
|
446
|
+
}
|
|
447
|
+
if (includeRequestBody) {
|
|
448
|
+
data.requestBody = 'requestBody' in eventData ? eventData.requestBody : eventData.requestData;
|
|
449
|
+
}
|
|
450
|
+
if (includeResponseBody) {
|
|
451
|
+
data.responseBody = 'responseBody' in eventData ? eventData.responseBody : eventData.responseData;
|
|
452
|
+
}
|
|
453
|
+
return data;
|
|
454
|
+
};
|
|
455
|
+
if (format === "json") {
|
|
456
|
+
const allFilteredData = dataSource.map(buildFilteredData);
|
|
457
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.DataViewer, {
|
|
458
|
+
data: allFilteredData,
|
|
459
|
+
title: "",
|
|
460
|
+
showTypeFilter: false
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
if (format === "markdown") {
|
|
464
|
+
const allRequests = dataSource.map((eventData, index) => {
|
|
465
|
+
const sections = [];
|
|
466
|
+
sections.push(`# Request ${index + 1}`);
|
|
467
|
+
if (includeMethod) {
|
|
468
|
+
sections.push(`\n**${eventData.method}** ${eventData.url}`);
|
|
469
|
+
}
|
|
470
|
+
const metaInfo = [];
|
|
471
|
+
if (includeStatus) {
|
|
472
|
+
metaInfo.push(`**Status:** ${eventData.status}`);
|
|
473
|
+
metaInfo.push(`**Duration:** ${eventData.duration}ms`);
|
|
474
|
+
}
|
|
475
|
+
if (includeTimestamp) {
|
|
476
|
+
metaInfo.push(`**Timestamp:** ${eventData.timestamp}`);
|
|
477
|
+
}
|
|
478
|
+
if (metaInfo.length > 0) {
|
|
479
|
+
sections.push('\n' + metaInfo.join('\n'));
|
|
480
|
+
}
|
|
481
|
+
if (includeRequestHeaders) {
|
|
482
|
+
const headers = eventData.requestHeaders || {};
|
|
483
|
+
sections.push(`\n## Request Headers\n\`\`\`json\n${JSON.stringify(headers, null, 2)}\n\`\`\``);
|
|
484
|
+
}
|
|
485
|
+
if (includeRequestBody) {
|
|
486
|
+
const body = 'requestBody' in eventData ? eventData.requestBody : eventData.requestData;
|
|
487
|
+
sections.push(`\n## Request Body\n\`\`\`json\n${JSON.stringify(body || {}, null, 2)}\n\`\`\``);
|
|
488
|
+
}
|
|
489
|
+
if (includeResponseBody) {
|
|
490
|
+
const body = 'responseBody' in eventData ? eventData.responseBody : eventData.responseData;
|
|
491
|
+
sections.push(`\n## Response Body\n\`\`\`json\n${JSON.stringify(body || {}, null, 2)}\n\`\`\``);
|
|
492
|
+
}
|
|
493
|
+
return sections.join('\n');
|
|
494
|
+
});
|
|
495
|
+
const markdown = allRequests.join('\n\n---\n\n');
|
|
496
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
|
|
497
|
+
style: styles.previewScroll,
|
|
498
|
+
nestedScrollEnabled: true,
|
|
499
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
500
|
+
style: styles.markdownText,
|
|
501
|
+
selectable: isPro,
|
|
502
|
+
children: markdown || "No data included"
|
|
503
|
+
})
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Plaintext
|
|
508
|
+
const allRequests = dataSource.map((eventData, index) => {
|
|
509
|
+
const lines = [];
|
|
510
|
+
lines.push(`Request ${index + 1}:`);
|
|
511
|
+
if (includeMethod) {
|
|
512
|
+
lines.push(`${eventData.method} ${eventData.url}`);
|
|
513
|
+
}
|
|
514
|
+
if (includeStatus) {
|
|
515
|
+
lines.push(`Status: ${eventData.status}`);
|
|
516
|
+
lines.push(`Duration: ${eventData.duration}ms`);
|
|
517
|
+
}
|
|
518
|
+
if (includeTimestamp) {
|
|
519
|
+
lines.push(`Timestamp: ${eventData.timestamp}`);
|
|
520
|
+
}
|
|
521
|
+
if (includeRequestBody) {
|
|
522
|
+
const body = 'requestBody' in eventData ? eventData.requestBody : eventData.requestData;
|
|
523
|
+
lines.push('\nRequest:');
|
|
524
|
+
lines.push(JSON.stringify(body || {}, null, 2));
|
|
525
|
+
}
|
|
526
|
+
if (includeResponseBody) {
|
|
527
|
+
const body = 'responseBody' in eventData ? eventData.responseBody : eventData.responseData;
|
|
528
|
+
lines.push('\nResponse:');
|
|
529
|
+
lines.push(JSON.stringify(body || {}, null, 2));
|
|
530
|
+
}
|
|
531
|
+
return lines.join('\n');
|
|
532
|
+
});
|
|
533
|
+
const plaintext = allRequests.join('\n\n---\n\n');
|
|
534
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
|
|
535
|
+
style: styles.previewScroll,
|
|
536
|
+
nestedScrollEnabled: true,
|
|
537
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
538
|
+
style: styles.plaintextText,
|
|
539
|
+
selectable: isPro,
|
|
540
|
+
children: plaintext || "No data included"
|
|
541
|
+
})
|
|
542
|
+
});
|
|
543
|
+
}, [settings, hasLiveData, events, mockRequestData, isPro]);
|
|
544
|
+
|
|
545
|
+
// Generate formatted output for copying/preview - with collapsible support
|
|
546
|
+
const generatePreviewContent = (0, _react.useCallback)(() => {
|
|
547
|
+
const dataSource = hasLiveData ? events : [mockRequestData];
|
|
548
|
+
const requestCount = dataSource.length;
|
|
549
|
+
|
|
550
|
+
// Collapsed state - show summary with expand button
|
|
551
|
+
if (!isPreviewExpanded) {
|
|
552
|
+
const warningColor = sizeWarningLevel === 'danger' ? _sharedUi.macOSColors.semantic.error : sizeWarningLevel === 'warning' ? _sharedUi.macOSColors.semantic.warning : _sharedUi.macOSColors.text.secondary;
|
|
553
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
554
|
+
style: styles.collapsedPreview,
|
|
555
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
556
|
+
style: styles.expandButton,
|
|
557
|
+
onPress: () => setIsPreviewExpanded(true),
|
|
558
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
559
|
+
style: styles.expandButtonContent,
|
|
560
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Eye, {
|
|
561
|
+
size: 16,
|
|
562
|
+
color: _sharedUi.macOSColors.semantic.info
|
|
563
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
564
|
+
style: styles.expandButtonTextContainer,
|
|
565
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
566
|
+
style: styles.expandButtonTitle,
|
|
567
|
+
children: "Show Preview"
|
|
568
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
569
|
+
style: styles.expandButtonSubtitle,
|
|
570
|
+
children: [requestCount, " request", requestCount !== 1 ? 's' : '', " \u2022 ~", formatBytes(estimatedSize)]
|
|
571
|
+
})]
|
|
572
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronDown, {
|
|
573
|
+
size: 16,
|
|
574
|
+
color: _sharedUi.macOSColors.text.muted
|
|
575
|
+
})]
|
|
576
|
+
})
|
|
577
|
+
}), sizeWarningLevel !== 'none' && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
578
|
+
style: [styles.sizeWarning, sizeWarningLevel === 'danger' && styles.sizeWarningDanger],
|
|
579
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AlertTriangle, {
|
|
580
|
+
size: 12,
|
|
581
|
+
color: warningColor
|
|
582
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
583
|
+
style: [styles.sizeWarningText, {
|
|
584
|
+
color: warningColor
|
|
585
|
+
}],
|
|
586
|
+
children: sizeWarningLevel === 'danger' ? 'Very large payload - may cause performance issues' : 'Large payload - preview may be slow'
|
|
587
|
+
})]
|
|
588
|
+
})]
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// Expanded state - show collapse button + actual content
|
|
593
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
594
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
595
|
+
style: styles.collapseButton,
|
|
596
|
+
onPress: () => setIsPreviewExpanded(false),
|
|
597
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
598
|
+
style: styles.collapseButtonText,
|
|
599
|
+
children: "Hide Preview"
|
|
600
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronUp, {
|
|
601
|
+
size: 14,
|
|
602
|
+
color: _sharedUi.macOSColors.text.secondary
|
|
603
|
+
})]
|
|
604
|
+
}), generateExpandedPreviewContent()]
|
|
605
|
+
});
|
|
606
|
+
}, [settings, hasLiveData, events, mockRequestData, isPreviewExpanded, estimatedSize, sizeWarningLevel, generateExpandedPreviewContent]);
|
|
607
|
+
|
|
608
|
+
// Render preview header actions (status label and Copy button)
|
|
609
|
+
const renderPreviewHeaderActions = (0, _react.useCallback)(() => {
|
|
610
|
+
const statusLabel = hasLiveData && lastEventTimestamp ? `Live data • Updated ${(0, _sharedUi.formatRelativeTime)(lastEventTimestamp, tick)}` : "Mock data (no events captured)";
|
|
611
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
612
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
613
|
+
style: styles.statusLabel,
|
|
614
|
+
children: statusLabel
|
|
615
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolbarCopyButton, {
|
|
616
|
+
value: generateCopyText(),
|
|
617
|
+
disabled: !isPro
|
|
618
|
+
})]
|
|
619
|
+
});
|
|
620
|
+
}, [hasLiveData, lastEventTimestamp, tick, generateCopyText, isPro]);
|
|
621
|
+
|
|
622
|
+
// Render preview content only
|
|
623
|
+
const renderPreviewContent = (0, _react.useCallback)(() => {
|
|
624
|
+
return generatePreviewContent();
|
|
625
|
+
}, [generatePreviewContent]);
|
|
626
|
+
const dynamicFilterConfig = (0, _react.useMemo)(() => ({
|
|
627
|
+
sections: [
|
|
628
|
+
// Quick Presets Section - Hero element
|
|
629
|
+
{
|
|
630
|
+
id: "presets",
|
|
631
|
+
title: "Presets",
|
|
632
|
+
type: "custom",
|
|
633
|
+
data: [{
|
|
634
|
+
id: "preset::urls",
|
|
635
|
+
label: "URLs",
|
|
636
|
+
icon: _sharedUi.Link,
|
|
637
|
+
color: _sharedUi.macOSColors.semantic.info,
|
|
638
|
+
value: "urls",
|
|
639
|
+
isActive: activePreset === "urls"
|
|
640
|
+
}, {
|
|
641
|
+
id: "preset::llm",
|
|
642
|
+
label: "LLM",
|
|
643
|
+
icon: _sharedUi.Zap,
|
|
644
|
+
color: _sharedUi.macOSColors.semantic.success,
|
|
645
|
+
value: "llm",
|
|
646
|
+
isActive: activePreset === "llm"
|
|
647
|
+
}, {
|
|
648
|
+
id: "preset::json",
|
|
649
|
+
label: "JSON",
|
|
650
|
+
icon: _sharedUi.FileCode,
|
|
651
|
+
color: _sharedUi.macOSColors.semantic.warning,
|
|
652
|
+
value: "json",
|
|
653
|
+
isActive: activePreset === "json"
|
|
654
|
+
}, {
|
|
655
|
+
id: "preset::full",
|
|
656
|
+
label: "Full",
|
|
657
|
+
icon: _sharedUi.FileText,
|
|
658
|
+
color: _sharedUi.macOSColors.semantic.info,
|
|
659
|
+
value: "full",
|
|
660
|
+
isActive: activePreset === "full"
|
|
661
|
+
}, {
|
|
662
|
+
id: "preset::custom",
|
|
663
|
+
label: "Custom",
|
|
664
|
+
icon: _sharedUi.Settings,
|
|
665
|
+
color: _sharedUi.macOSColors.text.secondary,
|
|
666
|
+
value: "custom",
|
|
667
|
+
isActive: activePreset === null
|
|
668
|
+
}]
|
|
669
|
+
},
|
|
670
|
+
// Include Section - Consolidated
|
|
671
|
+
{
|
|
672
|
+
id: "include",
|
|
673
|
+
title: "Include",
|
|
674
|
+
type: "custom",
|
|
675
|
+
data: [{
|
|
676
|
+
id: "requestInfo::includeMethod",
|
|
677
|
+
label: "URL",
|
|
678
|
+
value: "includeMethod",
|
|
679
|
+
isActive: settings.includeMethod
|
|
680
|
+
}, {
|
|
681
|
+
id: "requestInfo::includeStatus",
|
|
682
|
+
label: "Status",
|
|
683
|
+
value: "includeStatus",
|
|
684
|
+
isActive: settings.includeStatus
|
|
685
|
+
}, {
|
|
686
|
+
id: "requestInfo::includeTimestamp",
|
|
687
|
+
label: "Time",
|
|
688
|
+
value: "includeTimestamp",
|
|
689
|
+
isActive: settings.includeTimestamp
|
|
690
|
+
}, {
|
|
691
|
+
id: "headers::includeRequestHeaders",
|
|
692
|
+
label: "Headers",
|
|
693
|
+
value: "includeRequestHeaders",
|
|
694
|
+
isActive: settings.includeRequestHeaders
|
|
695
|
+
}, {
|
|
696
|
+
id: "body::includeRequestBody",
|
|
697
|
+
label: "Req Body",
|
|
698
|
+
value: "includeRequestBody",
|
|
699
|
+
isActive: settings.includeRequestBody
|
|
700
|
+
}, {
|
|
701
|
+
id: "body::includeResponseBody",
|
|
702
|
+
label: "Res Body",
|
|
703
|
+
value: "includeResponseBody",
|
|
704
|
+
isActive: settings.includeResponseBody
|
|
705
|
+
}, {
|
|
706
|
+
id: "requestInfo::includeErrors",
|
|
707
|
+
label: "Errors",
|
|
708
|
+
value: "includeErrors",
|
|
709
|
+
isActive: settings.includeErrors
|
|
710
|
+
}]
|
|
711
|
+
},
|
|
712
|
+
// Output Format
|
|
713
|
+
{
|
|
714
|
+
id: "format",
|
|
715
|
+
title: "Format",
|
|
716
|
+
type: "custom",
|
|
717
|
+
data: [{
|
|
718
|
+
id: "format::markdown",
|
|
719
|
+
label: "Markdown",
|
|
720
|
+
icon: _sharedUi.FileText,
|
|
721
|
+
color: _sharedUi.macOSColors.semantic.info,
|
|
722
|
+
value: "markdown",
|
|
723
|
+
isActive: settings.format === "markdown"
|
|
724
|
+
}, {
|
|
725
|
+
id: "format::json",
|
|
726
|
+
label: "JSON",
|
|
727
|
+
icon: _sharedUi.FileCode,
|
|
728
|
+
color: _sharedUi.macOSColors.semantic.warning,
|
|
729
|
+
value: "json",
|
|
730
|
+
isActive: settings.format === "json"
|
|
731
|
+
}, {
|
|
732
|
+
id: "format::plaintext",
|
|
733
|
+
label: "Text",
|
|
734
|
+
icon: _sharedUi.Hash,
|
|
735
|
+
color: _sharedUi.macOSColors.text.secondary,
|
|
736
|
+
value: "plaintext",
|
|
737
|
+
isActive: settings.format === "plaintext"
|
|
738
|
+
}]
|
|
739
|
+
}],
|
|
740
|
+
previewSection: {
|
|
741
|
+
enabled: true,
|
|
742
|
+
title: "PREVIEW",
|
|
743
|
+
icon: _sharedUi.Eye,
|
|
744
|
+
content: renderPreviewContent,
|
|
745
|
+
headerActions: renderPreviewHeaderActions
|
|
746
|
+
},
|
|
747
|
+
onFilterChange: handleOptionChange
|
|
748
|
+
}), [settings, handleOptionChange, renderPreviewContent, renderPreviewHeaderActions, activePreset]);
|
|
749
|
+
|
|
750
|
+
// For free users, show banner at the top explaining this is a Pro feature
|
|
751
|
+
// Users can interact with controls but copy is blocked at the button level
|
|
752
|
+
if (!isPro) {
|
|
753
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
754
|
+
style: styles.gatedContainer,
|
|
755
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ProFeatureBanner, {
|
|
756
|
+
featureName: "Network Export",
|
|
757
|
+
description: "Export network requests to share with your team, debug APIs, or feed into AI tools.",
|
|
758
|
+
benefits: ["Export to JSON, Markdown, or plain text", "Customizable copy presets (URLs only, LLM-ready, full data)", "Share request details with teammates", "Feed network data directly to AI assistants"]
|
|
759
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
760
|
+
style: styles.gatedPreview,
|
|
761
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.DynamicFilterView, {
|
|
762
|
+
...dynamicFilterConfig
|
|
763
|
+
})
|
|
764
|
+
})]
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.DynamicFilterView, {
|
|
768
|
+
...dynamicFilterConfig
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
const styles = _reactNative.StyleSheet.create({
|
|
772
|
+
previewScroll: {
|
|
773
|
+
maxHeight: 300
|
|
774
|
+
},
|
|
775
|
+
markdownText: {
|
|
776
|
+
fontFamily: "monospace",
|
|
777
|
+
fontSize: 11,
|
|
778
|
+
color: _sharedUi.macOSColors.text.primary,
|
|
779
|
+
lineHeight: 18
|
|
780
|
+
},
|
|
781
|
+
plaintextText: {
|
|
782
|
+
fontFamily: "monospace",
|
|
783
|
+
fontSize: 11,
|
|
784
|
+
color: _sharedUi.macOSColors.text.primary,
|
|
785
|
+
lineHeight: 18
|
|
786
|
+
},
|
|
787
|
+
statusLabel: {
|
|
788
|
+
fontSize: 11,
|
|
789
|
+
fontWeight: "600",
|
|
790
|
+
color: _sharedUi.macOSColors.text.muted,
|
|
791
|
+
marginRight: 8
|
|
792
|
+
},
|
|
793
|
+
// Collapsible preview styles
|
|
794
|
+
collapsedPreview: {
|
|
795
|
+
gap: 8
|
|
796
|
+
},
|
|
797
|
+
expandButton: {
|
|
798
|
+
backgroundColor: _sharedUi.macOSColors.background.input,
|
|
799
|
+
borderRadius: 8,
|
|
800
|
+
borderWidth: 1,
|
|
801
|
+
borderColor: _sharedUi.macOSColors.border.default,
|
|
802
|
+
padding: 12
|
|
803
|
+
},
|
|
804
|
+
expandButtonContent: {
|
|
805
|
+
flexDirection: 'row',
|
|
806
|
+
alignItems: 'center',
|
|
807
|
+
gap: 10
|
|
808
|
+
},
|
|
809
|
+
expandButtonTextContainer: {
|
|
810
|
+
flex: 1
|
|
811
|
+
},
|
|
812
|
+
expandButtonTitle: {
|
|
813
|
+
fontSize: 13,
|
|
814
|
+
fontWeight: '600',
|
|
815
|
+
color: _sharedUi.macOSColors.text.primary
|
|
816
|
+
},
|
|
817
|
+
expandButtonSubtitle: {
|
|
818
|
+
fontSize: 11,
|
|
819
|
+
color: _sharedUi.macOSColors.text.secondary,
|
|
820
|
+
marginTop: 2
|
|
821
|
+
},
|
|
822
|
+
collapseButton: {
|
|
823
|
+
flexDirection: 'row',
|
|
824
|
+
alignItems: 'center',
|
|
825
|
+
justifyContent: 'center',
|
|
826
|
+
gap: 6,
|
|
827
|
+
paddingVertical: 8,
|
|
828
|
+
marginBottom: 8,
|
|
829
|
+
backgroundColor: _sharedUi.macOSColors.background.hover,
|
|
830
|
+
borderRadius: 6,
|
|
831
|
+
borderWidth: 1,
|
|
832
|
+
borderColor: _sharedUi.macOSColors.border.default
|
|
833
|
+
},
|
|
834
|
+
collapseButtonText: {
|
|
835
|
+
fontSize: 12,
|
|
836
|
+
fontWeight: '500',
|
|
837
|
+
color: _sharedUi.macOSColors.text.secondary
|
|
838
|
+
},
|
|
839
|
+
sizeWarning: {
|
|
840
|
+
flexDirection: 'row',
|
|
841
|
+
alignItems: 'center',
|
|
842
|
+
gap: 6,
|
|
843
|
+
paddingHorizontal: 10,
|
|
844
|
+
paddingVertical: 6,
|
|
845
|
+
backgroundColor: _sharedUi.macOSColors.semantic.warningBackground,
|
|
846
|
+
borderRadius: 6,
|
|
847
|
+
borderWidth: 1,
|
|
848
|
+
borderColor: _sharedUi.macOSColors.semantic.warning + '30'
|
|
849
|
+
},
|
|
850
|
+
sizeWarningDanger: {
|
|
851
|
+
backgroundColor: _sharedUi.macOSColors.semantic.errorBackground,
|
|
852
|
+
borderColor: _sharedUi.macOSColors.semantic.error + '30'
|
|
853
|
+
},
|
|
854
|
+
sizeWarningText: {
|
|
855
|
+
fontSize: 11,
|
|
856
|
+
fontWeight: '500',
|
|
857
|
+
flex: 1
|
|
858
|
+
},
|
|
859
|
+
// Gated container styles for free users
|
|
860
|
+
gatedContainer: {
|
|
861
|
+
flex: 1,
|
|
862
|
+
padding: 12
|
|
863
|
+
},
|
|
864
|
+
gatedPreview: {
|
|
865
|
+
flex: 1
|
|
866
|
+
}
|
|
867
|
+
});
|