rn-backstage 1.4.2 → 1.4.3

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/src/types.ts DELETED
@@ -1,280 +0,0 @@
1
- import type { ReactNode } from 'react'
2
- import type { StyleProp, TextStyle, ViewStyle } from 'react-native'
3
-
4
- // ─── Log Types ───────────────────────────────────────────────────────────────
5
-
6
- export enum LogLevel {
7
- log = 'log',
8
- debug = 'debug',
9
- info = 'info',
10
- warn = 'warn',
11
- error = 'error',
12
- }
13
-
14
- export interface LogEntry {
15
- id: string
16
- level: LogLevel
17
- message: string
18
- data?: unknown
19
- timestamp: number
20
- }
21
-
22
- // ─── Network Types ───────────────────────────────────────────────────────────
23
-
24
- export enum NetworkState {
25
- pending = 'pending',
26
- completed = 'completed',
27
- error = 'error',
28
- }
29
-
30
- export interface NetworkEntry {
31
- id: string
32
- method: string
33
- url: string
34
- startTime: number
35
- endTime?: number
36
- duration?: number
37
- status?: number
38
- statusText?: string
39
- requestHeaders?: Record<string, string>
40
- responseHeaders?: Record<string, string>
41
- requestBody?: string
42
- responseBody?: string
43
- responseSize?: number
44
- error?: string
45
- state: NetworkState
46
- }
47
-
48
- // ─── App Info ────────────────────────────────────────────────────────────────
49
-
50
- export interface AppInfoItem {
51
- label: string
52
- value: string
53
- }
54
-
55
- // ─── Quick Actions ───────────────────────────────────────────────────────────
56
-
57
- export interface QuickAction {
58
- title: string
59
- onPress: () => void
60
- closeOnPress?: boolean
61
- icon?: string
62
- destructive?: boolean
63
- testID?: string
64
- }
65
-
66
- // ─── Feature Flags ─────────────────────────────────────────────────────────
67
-
68
- export interface FeatureFlag {
69
- /** Unique key for this flag */
70
- key: string
71
- /** Display label */
72
- label: string
73
- /** Current value */
74
- value: boolean
75
- /** Optional description shown below the label */
76
- description?: string
77
- }
78
-
79
- // ─── Storage Adapter ─────────────────────────────────────────────────────────
80
-
81
- export interface StorageAdapter {
82
- /** Return all stored keys */
83
- getAllKeys: () => Promise<string[]>
84
- /** Get value for a key. Return null if not found */
85
- getItem: (key: string) => Promise<string | null>
86
- /** Set a value for a key */
87
- setItem: (key: string, value: string) => Promise<void>
88
- /** Remove an entry by key */
89
- removeItem: (key: string) => Promise<void>
90
- }
91
-
92
- // ─── Bug Report ──────────────────────────────────────────────────────────────
93
-
94
- export type BugReportSeverity = 'low' | 'medium' | 'high' | 'critical'
95
-
96
- export interface BugReport {
97
- /** Report title */
98
- title: string
99
- /** Detailed description */
100
- description: string
101
- /** Severity level */
102
- severity: BugReportSeverity
103
- /** Device & app info snapshot */
104
- deviceInfo: AppInfoItem[]
105
- /** Console log entries included in the report */
106
- logs: LogEntry[]
107
- /** Network entries included in the report */
108
- networkEntries: NetworkEntry[]
109
- /** State tree snapshot (if included) */
110
- state?: Record<string, unknown>
111
- /** Screenshot URI or base64 (if captured) */
112
- screenshotUri?: string
113
- /** Timestamp when the report was created */
114
- timestamp: number
115
- }
116
-
117
- export interface BugReportConfig {
118
- /** Callback when a report is submitted. Receives the full BugReport object */
119
- onSubmit?: (report: BugReport) => void
120
- /** Webhook URL to POST the report to */
121
- webhookUrl?: string
122
- /** Optional function to capture a screenshot. Return a file URI or base64 string */
123
- captureScreenshot?: () => Promise<string>
124
- /** Max number of log entries to include in the report. Default: 50 */
125
- maxLogsInReport?: number
126
- /** Max number of network entries to include in the report. Default: 20 */
127
- maxNetworkEntriesInReport?: number
128
- /** Whether to include the state tree in the report. Default: true */
129
- includeState?: boolean
130
- }
131
-
132
- // ─── Extensible Tabs ─────────────────────────────────────────────────────────
133
-
134
- export interface BackstageTab {
135
- key: string
136
- title: string
137
- icon?: string
138
- render: () => ReactNode
139
- }
140
-
141
- // ─── Theme ───────────────────────────────────────────────────────────────────
142
-
143
- export interface BackstageTheme {
144
- background: string
145
- surface: string
146
- surfaceElevated: string
147
- border: string
148
- text: string
149
- textSecondary: string
150
- textMuted: string
151
- accent: string
152
- accentDim: string
153
- error: string
154
- errorDim: string
155
- warning: string
156
- warningDim: string
157
- success: string
158
- info: string
159
- infoDim: string
160
- debugColor: string
161
- debugDim: string
162
- }
163
-
164
- // ─── Main Props ──────────────────────────────────────────────────────────────
165
-
166
- export interface BackstageProps {
167
- /** Whether the floating pill trigger is visible. Default: true */
168
- visible?: boolean
169
-
170
- /** Theme preference: 'light', 'dark', or 'auto' (follows device setting). Default: 'auto' */
171
- theme?: 'light' | 'dark' | 'auto'
172
-
173
- /** App version string (e.g., "1.2.3") */
174
- appVersion?: string
175
-
176
- /** Build number (e.g., "42") */
177
- buildNumber?: string
178
-
179
- /** Bundle identifier (e.g., "com.example.app") */
180
- bundleId?: string
181
-
182
- /** Additional device/app information rows */
183
- deviceInfo?: AppInfoItem[]
184
-
185
- /** State object to display in the tree viewer (Redux store, Zustand, etc.) */
186
- state?: Record<string, unknown>
187
-
188
- /** Custom action buttons in the Info tab */
189
- quickActions?: QuickAction[]
190
-
191
- /** Feature flags to display with toggle switches */
192
- featureFlags?: FeatureFlag[]
193
-
194
- /** Callback when a feature flag is toggled */
195
- onToggleFeatureFlag?: (key: string, value: boolean) => void
196
-
197
- /** Storage adapter for the Storage Viewer tab (AsyncStorage, MMKV, etc.) */
198
- storageAdapter?: StorageAdapter
199
-
200
- /** Maximum number of logs to retain in memory. Default: 500 */
201
- maxLogs?: number
202
-
203
- /** Log messages containing these strings will be excluded */
204
- logFilters?: string[]
205
-
206
- /** Callback triggered when user copies logs */
207
- onCopyLogs?: (logs: string) => void
208
-
209
- /** Additional custom tabs beyond Info and Logs */
210
- extraTabs?: BackstageTab[]
211
-
212
- /** Extra content rendered at the bottom of the Info tab */
213
- children?: ReactNode
214
-
215
- /** Custom styles overrides */
216
- styles?: BackstageStyleOverrides
217
-
218
- /** Initial X position for the floating pill */
219
- initialX?: number
220
-
221
- /** Initial Y position for the floating pill */
222
- initialY?: number
223
-
224
- /** Text displayed on the floating pill. Defaults to appVersion or "DEV" */
225
- pillText?: string
226
-
227
- /** Width of the floating pill. Default: 60 */
228
- pillWidth?: number
229
-
230
- /** Height of the floating pill. Default: 32 */
231
- pillHeight?: number
232
-
233
- /** Whether to enable network request interception. Default: true */
234
- enableNetworkInspector?: boolean
235
-
236
- /** Maximum number of network entries to retain in memory. Default: 500 */
237
- maxNetworkEntries?: number
238
-
239
- /** Maximum body size (bytes) to capture per request/response. Default: 65536 (64KB) */
240
- maxNetworkBodySize?: number
241
-
242
- /** URL substrings to exclude from network capture */
243
- networkFilters?: string[]
244
-
245
- /** Auto-filter console.logs from network callbacks (e.g., Axios interceptors) out of the Logs tab. Default: true */
246
- autoFilterNetworkLogs?: boolean
247
-
248
- /** Max nesting depth for JSON tree views (state tree, log data, network bodies). Default: 10 */
249
- jsonMaxDepth?: number
250
-
251
- /** Bug report configuration. When provided, shows a 📸 button in the panel header */
252
- bugReport?: BugReportConfig
253
- }
254
-
255
- export interface BackstageStyleOverrides {
256
- pillStyle?: StyleProp<ViewStyle>
257
- pillTextStyle?: StyleProp<TextStyle>
258
- panelStyle?: StyleProp<ViewStyle>
259
- headerTitleStyle?: StyleProp<TextStyle>
260
- sectionTitleStyle?: StyleProp<TextStyle>
261
- infoLabelStyle?: StyleProp<TextStyle>
262
- infoValueStyle?: StyleProp<TextStyle>
263
- actionButtonStyle?: StyleProp<ViewStyle>
264
- actionButtonTitleStyle?: StyleProp<TextStyle>
265
- logTimestampStyle?: StyleProp<TextStyle>
266
- logMessageStyle?: StyleProp<TextStyle>
267
- }
268
-
269
- // ─── Ref Methods ─────────────────────────────────────────────────────────────
270
-
271
- export interface BackstageRef {
272
- /** Open the backstage panel */
273
- open: () => void
274
- /** Close the backstage panel */
275
- close: () => void
276
- /** Clear all captured logs */
277
- clearLogs: () => void
278
- /** Open the bug report composer programmatically */
279
- submitBugReport: () => void
280
- }
@@ -1,22 +0,0 @@
1
- /**
2
- * Formats a timestamp (Date.now()) into a human-readable local time string.
3
- * Format: "h:mm:ss.SSS AM/PM"
4
- * No external dependencies — uses native Date API.
5
- */
6
- export function formatTimestamp(timestamp: number): string {
7
- const date = new Date(timestamp)
8
- let hours = date.getHours()
9
- const minutes = date.getMinutes()
10
- const seconds = date.getSeconds()
11
- const milliseconds = date.getMilliseconds()
12
- const ampm = hours >= 12 ? 'PM' : 'AM'
13
-
14
- hours = hours % 12
15
- hours = hours || 12
16
-
17
- const mm = minutes.toString().padStart(2, '0')
18
- const ss = seconds.toString().padStart(2, '0')
19
- const ms = milliseconds.toString().padStart(3, '0')
20
-
21
- return `${hours}:${mm}:${ss}.${ms} ${ampm}`
22
- }
@@ -1,90 +0,0 @@
1
- /**
2
- * Safely stringifies a value, handling circular references and Error objects.
3
- */
4
- export function safeStringify(value: unknown, indent = 2): string {
5
- if (value === undefined) return 'undefined'
6
- if (value === null) return 'null'
7
-
8
- if (value instanceof Error) {
9
- return JSON.stringify(
10
- {
11
- name: value.name,
12
- message: value.message,
13
- stack: value.stack,
14
- },
15
- null,
16
- indent,
17
- )
18
- }
19
-
20
- const seen = new WeakSet()
21
-
22
- try {
23
- return JSON.stringify(
24
- value,
25
- (_key, val) => {
26
- if (typeof val === 'object' && val !== null) {
27
- if (seen.has(val)) {
28
- return '[Circular]'
29
- }
30
- seen.add(val)
31
- }
32
- if (typeof val === 'bigint') {
33
- return val.toString()
34
- }
35
- if (typeof val === 'function') {
36
- return `[Function: ${val.name || 'anonymous'}]`
37
- }
38
- if (typeof val === 'symbol') {
39
- return val.toString()
40
- }
41
- return val
42
- },
43
- indent,
44
- )
45
- } catch {
46
- return String(value)
47
- }
48
- }
49
-
50
- /**
51
- * Formats a console message and its optional params into a single string.
52
- */
53
- export function formatLogMessage(message: unknown, optionalParams?: unknown[]): string {
54
- const parts: string[] = []
55
-
56
- if (message instanceof Error) {
57
- parts.push(`${message.name}: ${message.message}`)
58
- } else if (typeof message === 'object' && message !== null) {
59
- parts.push(safeStringify(message, 0))
60
- } else if (typeof message === 'string') {
61
- // Strip console color formatting (%c)
62
- parts.push(message.replace(/%c/g, '').trim())
63
- } else {
64
- parts.push(String(message))
65
- }
66
-
67
- if (optionalParams && optionalParams.length > 0) {
68
- for (const param of optionalParams) {
69
- if (typeof param === 'string' && isColorString(param)) {
70
- continue // skip css color strings from console.log('%c ...', 'color: ...')
71
- }
72
- if (typeof param === 'object' && param !== null) {
73
- parts.push(safeStringify(param, 0))
74
- } else {
75
- parts.push(String(param))
76
- }
77
- }
78
- }
79
-
80
- return parts.join(' ')
81
- }
82
-
83
- function isColorString(str: string): boolean {
84
- return (
85
- str.includes('color:') ||
86
- str.includes('background:') ||
87
- str.includes('font-') ||
88
- /^#[0-9A-Fa-f]{3,8}$/.test(str.trim())
89
- )
90
- }