@od-oneapp/observability 2026.1.1301

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 (107) hide show
  1. package/README.md +523 -0
  2. package/dist/client-next.d.mts +20 -0
  3. package/dist/client-next.d.mts.map +1 -0
  4. package/dist/client-next.mjs +64 -0
  5. package/dist/client-next.mjs.map +1 -0
  6. package/dist/client.d.mts +11 -0
  7. package/dist/client.d.mts.map +1 -0
  8. package/dist/client.mjs +47 -0
  9. package/dist/client.mjs.map +1 -0
  10. package/dist/env.d.mts +15 -0
  11. package/dist/env.d.mts.map +1 -0
  12. package/dist/env.mjs +45 -0
  13. package/dist/env.mjs.map +1 -0
  14. package/dist/factory-DkY353r8.mjs +380 -0
  15. package/dist/factory-DkY353r8.mjs.map +1 -0
  16. package/dist/hooks-useObservability.d.mts +11 -0
  17. package/dist/hooks-useObservability.d.mts.map +1 -0
  18. package/dist/hooks-useObservability.mjs +174 -0
  19. package/dist/hooks-useObservability.mjs.map +1 -0
  20. package/dist/index-CpcdzWrF.d.mts +24 -0
  21. package/dist/index-CpcdzWrF.d.mts.map +1 -0
  22. package/dist/index.d.mts +88 -0
  23. package/dist/index.d.mts.map +1 -0
  24. package/dist/index.mjs +97 -0
  25. package/dist/index.mjs.map +1 -0
  26. package/dist/manager-BxQqOPEg.d.mts +33 -0
  27. package/dist/manager-BxQqOPEg.d.mts.map +1 -0
  28. package/dist/plugin-Bfq-o3nr.d.mts +60 -0
  29. package/dist/plugin-Bfq-o3nr.d.mts.map +1 -0
  30. package/dist/plugin-Bt-ygG1m.d.mts +254 -0
  31. package/dist/plugin-Bt-ygG1m.d.mts.map +1 -0
  32. package/dist/plugin-CLFwRERa.mjs +593 -0
  33. package/dist/plugin-CLFwRERa.mjs.map +1 -0
  34. package/dist/plugin-CP895lBx.mjs +534 -0
  35. package/dist/plugin-CP895lBx.mjs.map +1 -0
  36. package/dist/plugin-CaQxviDs.d.mts +61 -0
  37. package/dist/plugin-CaQxviDs.d.mts.map +1 -0
  38. package/dist/plugin-lPdJirTY.mjs +234 -0
  39. package/dist/plugin-lPdJirTY.mjs.map +1 -0
  40. package/dist/plugins-betterstack-env.d.mts +29 -0
  41. package/dist/plugins-betterstack-env.d.mts.map +1 -0
  42. package/dist/plugins-betterstack-env.mjs +75 -0
  43. package/dist/plugins-betterstack-env.mjs.map +1 -0
  44. package/dist/plugins-betterstack.d.mts +4 -0
  45. package/dist/plugins-betterstack.mjs +4 -0
  46. package/dist/plugins-console.d.mts +37 -0
  47. package/dist/plugins-console.d.mts.map +1 -0
  48. package/dist/plugins-console.mjs +196 -0
  49. package/dist/plugins-console.mjs.map +1 -0
  50. package/dist/plugins-sentry-env.d.mts +37 -0
  51. package/dist/plugins-sentry-env.d.mts.map +1 -0
  52. package/dist/plugins-sentry-env.mjs +79 -0
  53. package/dist/plugins-sentry-env.mjs.map +1 -0
  54. package/dist/plugins-sentry-microfrontend-env.d.mts +49 -0
  55. package/dist/plugins-sentry-microfrontend-env.d.mts.map +1 -0
  56. package/dist/plugins-sentry-microfrontend-env.mjs +80 -0
  57. package/dist/plugins-sentry-microfrontend-env.mjs.map +1 -0
  58. package/dist/plugins-sentry-microfrontend.d.mts +2 -0
  59. package/dist/plugins-sentry-microfrontend.mjs +3 -0
  60. package/dist/plugins-sentry.d.mts +5 -0
  61. package/dist/plugins-sentry.mjs +6 -0
  62. package/dist/server-edge.d.mts +15 -0
  63. package/dist/server-edge.d.mts.map +1 -0
  64. package/dist/server-edge.mjs +53 -0
  65. package/dist/server-edge.mjs.map +1 -0
  66. package/dist/server-next.d.mts +17 -0
  67. package/dist/server-next.d.mts.map +1 -0
  68. package/dist/server-next.mjs +64 -0
  69. package/dist/server-next.mjs.map +1 -0
  70. package/dist/server.d.mts +11 -0
  71. package/dist/server.d.mts.map +1 -0
  72. package/dist/server.mjs +48 -0
  73. package/dist/server.mjs.map +1 -0
  74. package/dist/utils-CuGrTcD6.d.mts +77 -0
  75. package/dist/utils-CuGrTcD6.d.mts.map +1 -0
  76. package/env.ts +67 -0
  77. package/package.json +147 -0
  78. package/src/client-next.ts +131 -0
  79. package/src/client.ts +70 -0
  80. package/src/core/index.ts +15 -0
  81. package/src/core/manager.ts +361 -0
  82. package/src/core/plugin.ts +61 -0
  83. package/src/core/types.ts +151 -0
  84. package/src/factory/builder.ts +132 -0
  85. package/src/factory/index.ts +67 -0
  86. package/src/factory/presets.ts +78 -0
  87. package/src/hooks/useObservability.ts +206 -0
  88. package/src/plugins/betterstack/env.ts +101 -0
  89. package/src/plugins/betterstack/index.ts +15 -0
  90. package/src/plugins/betterstack/plugin.ts +373 -0
  91. package/src/plugins/console/index.ts +323 -0
  92. package/src/plugins/sentry/__tests__/plugin-tracing.test.ts +511 -0
  93. package/src/plugins/sentry/env.ts +93 -0
  94. package/src/plugins/sentry/index.ts +28 -0
  95. package/src/plugins/sentry/plugin.ts +953 -0
  96. package/src/plugins/sentry/types.ts +252 -0
  97. package/src/plugins/sentry-microfrontend/env.ts +105 -0
  98. package/src/plugins/sentry-microfrontend/index.ts +12 -0
  99. package/src/plugins/sentry-microfrontend/multiplexed-transport.ts +221 -0
  100. package/src/plugins/sentry-microfrontend/plugin.ts +500 -0
  101. package/src/plugins/sentry-microfrontend/sentry-types.ts +140 -0
  102. package/src/plugins/sentry-microfrontend/types.ts +130 -0
  103. package/src/plugins/sentry-microfrontend/utils.ts +326 -0
  104. package/src/server-edge.ts +113 -0
  105. package/src/server-next.ts +114 -0
  106. package/src/server.ts +71 -0
  107. package/src/shared.ts +148 -0
@@ -0,0 +1,500 @@
1
+ /**
2
+ * @fileoverview Sentry Micro Frontend Plugin
3
+ * Sentry Micro Frontend Plugin
4
+ *
5
+ * Extends the base Sentry plugin with micro frontend-specific functionality
6
+ */
7
+
8
+ import { SentryPlugin } from '@integrations/sentry/observability-plugin/plugin';
9
+ import { logDebug, logError, logWarn } from '@repo/shared/logs';
10
+
11
+ import {
12
+ createBackstageBeforeSend,
13
+ createMultiplexedTransport,
14
+ enhanceEventWithBackstageApp,
15
+ } from './multiplexed-transport';
16
+ import { mapLogLevelToSentrySeverity } from './sentry-types';
17
+ import {
18
+ createBackstageScope,
19
+ detectCurrentBackstageApp,
20
+ ensureSingleInit,
21
+ getParentSentry,
22
+ hasParentSentry,
23
+ markAsHost,
24
+ } from './utils';
25
+
26
+ import type { SentryScope, SentrySDK } from './sentry-types';
27
+ import type { MicroFrontendMode, SentryMicroFrontendConfig } from './types';
28
+ import type { LogLevel, ObservabilityContext } from '../../core/types';
29
+
30
+ /**
31
+ * Sentry plugin optimized for micro frontend architectures
32
+ */
33
+ /**
34
+ * Sentry plugin optimized for micro frontend architectures.
35
+ *
36
+ * Extends SentryPlugin with micro frontend-specific features:
37
+ * - Host/child/standalone mode detection
38
+ * - Multiplexed transport for routing events to different Sentry projects
39
+ * - Backstage app context management
40
+ * - Parent Sentry instance detection and reuse
41
+ */
42
+ export class SentryMicroFrontendPlugin extends SentryPlugin {
43
+ private mode: MicroFrontendMode;
44
+ private backstageApp: string | undefined;
45
+ private parentSentry: SentrySDK | undefined;
46
+ private backstageScope: SentryScope | undefined;
47
+ private microFrontendConfig: SentryMicroFrontendConfig;
48
+ private eventProcessorCleanup?: (() => void) | undefined;
49
+
50
+ /**
51
+ * Create a new SentryMicroFrontendPlugin instance.
52
+ *
53
+ * @param config - Sentry micro frontend plugin configuration
54
+ */
55
+ constructor(config: SentryMicroFrontendConfig = {}) {
56
+ // Determine operation mode
57
+ const mode = SentryMicroFrontendPlugin.determineMode(config);
58
+
59
+ // Prepare base config based on mode
60
+ const baseConfig = SentryMicroFrontendPlugin.prepareConfig(config, mode);
61
+
62
+ // Initialize parent class
63
+ super(baseConfig);
64
+
65
+ this.mode = mode;
66
+ this.microFrontendConfig = config;
67
+ this.backstageApp = config.backstageApp ?? detectCurrentBackstageApp(config.backstageApps);
68
+
69
+ // Handle parent Sentry if in child mode
70
+ if (this.mode === 'child') {
71
+ const parent = getParentSentry();
72
+ if (parent) {
73
+ this.parentSentry = parent as SentrySDK;
74
+ this.enabled = true; // Re-enable since we'll use parent
75
+
76
+ // Create backstageApp-specific scope
77
+ if (this.backstageApp && this.parentSentry.Scope) {
78
+ this.backstageScope = createBackstageScope(
79
+ this.backstageApp,
80
+ config.globalTags,
81
+ ) as SentryScope;
82
+ }
83
+ }
84
+ }
85
+
86
+ // Mark as host if applicable
87
+ if (this.mode === 'host') {
88
+ markAsHost(this.backstageApp);
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Determine the operation mode based on configuration and environment.
94
+ *
95
+ * @param config - Plugin configuration
96
+ * @returns Operation mode ('host', 'child', or 'standalone')
97
+ */
98
+ private static determineMode(config: SentryMicroFrontendConfig): MicroFrontendMode {
99
+ // Explicit host mode
100
+ if (config.isHost) {
101
+ return 'host';
102
+ }
103
+
104
+ // Check for parent Sentry
105
+ if (config.detectParent !== false && hasParentSentry()) {
106
+ return 'child';
107
+ }
108
+
109
+ // Default to standalone
110
+ return 'standalone';
111
+ }
112
+
113
+ /**
114
+ * Prepare configuration based on operation mode.
115
+ *
116
+ * Adjusts configuration settings based on whether running as host, child, or standalone.
117
+ *
118
+ * @param config - Original plugin configuration
119
+ * @param mode - Determined operation mode
120
+ * @returns Prepared configuration object
121
+ */
122
+ private static prepareConfig(
123
+ config: SentryMicroFrontendConfig,
124
+ mode: MicroFrontendMode,
125
+ ): SentryMicroFrontendConfig {
126
+ const preparedConfig = { ...config };
127
+
128
+ if (mode === 'child') {
129
+ // Disable initialization in child mode
130
+ preparedConfig.enabled = false;
131
+ } else if (
132
+ mode === 'host' &&
133
+ config.backstageApps &&
134
+ config.useMultiplexedTransport !== false
135
+ ) {
136
+ // Host mode with multiplexed transport is handled in initialize()
137
+ // Don't set transport here as it needs Sentry to be loaded first
138
+ }
139
+
140
+ return preparedConfig;
141
+ }
142
+
143
+ /**
144
+ * Initialize the plugin
145
+ */
146
+ async initialize(config?: SentryMicroFrontendConfig): Promise<void> {
147
+ const mergedConfig = { ...this.microFrontendConfig, ...config };
148
+
149
+ if (this.mode === 'child') {
150
+ // In child mode, we don't initialize Sentry but set up our client reference
151
+ if (this.parentSentry) {
152
+ this.client = this.parentSentry;
153
+ this.initialized = true;
154
+
155
+ // Configure parent Sentry to include backstageApp information
156
+ if (this.backstageApp && mergedConfig.addBackstageContext !== false) {
157
+ this.configureParentSentry();
158
+ }
159
+ }
160
+ return;
161
+ }
162
+
163
+ // For host and standalone modes
164
+ if (mergedConfig.preventDuplicateInit !== false) {
165
+ try {
166
+ ensureSingleInit();
167
+ } catch (error) {
168
+ logError('Sentry initialization prevented', { error });
169
+ this.enabled = false;
170
+ return;
171
+ }
172
+ }
173
+
174
+ // Initialize parent class
175
+ await super.initialize(mergedConfig);
176
+
177
+ // Additional setup for host mode
178
+ if (this.mode === 'host' && this.client && mergedConfig.backstageApps) {
179
+ this.setupHostMode(mergedConfig);
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Configure parent Sentry instance for child mode
185
+ */
186
+ private configureParentSentry(): void {
187
+ if (!this.parentSentry || !this.backstageApp) {
188
+ logWarn(
189
+ '[SentryMicroFrontendPlugin] Cannot configure parent Sentry: missing parentSentry or backstageApp',
190
+ );
191
+ return;
192
+ }
193
+
194
+ try {
195
+ // Create event processor
196
+
197
+ const processor = (event: any) => {
198
+ try {
199
+ if (this.shouldProcessEvent(event)) {
200
+ enhanceEventWithBackstageApp(event, this.backstageApp ?? '', {
201
+ mode: this.mode,
202
+ plugin: 'SentryMicroFrontendPlugin',
203
+ });
204
+ }
205
+ } catch (error) {
206
+ logError('[SentryMicroFrontendPlugin] Error processing event', { error, event });
207
+ }
208
+ return event;
209
+ };
210
+
211
+ // Add global event processor to include backstageApp information
212
+ if (typeof this.parentSentry.addEventProcessor === 'function') {
213
+ this.parentSentry.addEventProcessor(processor);
214
+
215
+ // Store cleanup function
216
+ this.eventProcessorCleanup = () => {
217
+ // Note: Sentry SDK doesn't provide a way to remove event processors
218
+ // We'll mark events as processed to avoid double processing
219
+ };
220
+ } else {
221
+ logWarn('[SentryMicroFrontendPlugin] Parent Sentry does not support addEventProcessor');
222
+ }
223
+ } catch (error) {
224
+ logError('[SentryMicroFrontendPlugin] Failed to configure parent Sentry', { error });
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Set up host mode with multiplexed transport
230
+ */
231
+ private setupHostMode(config: SentryMicroFrontendConfig): void {
232
+ if (!config.backstageApps || !this.client) {
233
+ logWarn(
234
+ '[SentryMicroFrontendPlugin] Cannot setup host mode: missing backstageApps or client',
235
+ );
236
+ return;
237
+ }
238
+
239
+ try {
240
+ // Create multiplexed transport
241
+ const transport = createMultiplexedTransport(
242
+ config.backstageApps,
243
+ config.fallbackDsn ?? config.dsn,
244
+ this.client,
245
+ );
246
+
247
+ if (transport && typeof (this.client as any).init === 'function') {
248
+ // Re-initialize with multiplexed transport
249
+ const currentOptions =
250
+ typeof (this.client as any).getOptions === 'function'
251
+ ? (this.client as any).getOptions()
252
+ : {};
253
+
254
+ (this.client as any).init({
255
+ ...currentOptions,
256
+ transport,
257
+ beforeSend: createBackstageBeforeSend(this.backstageApp ?? 'main', config.beforeSend),
258
+ });
259
+ } else {
260
+ logWarn(
261
+ '[SentryMicroFrontendPlugin] Client does not support init method or transport creation failed',
262
+ );
263
+ }
264
+ } catch (error) {
265
+ logError('[SentryMicroFrontendPlugin] Failed to setup host mode', { error });
266
+ }
267
+ }
268
+
269
+ /**
270
+ * Check if we should process this event
271
+ */
272
+
273
+ private shouldProcessEvent(event: any): boolean {
274
+ // Don't double-process events
275
+ if (event.tags?.microFrontendProcessed) {
276
+ return false;
277
+ }
278
+
279
+ // Check if event is from our backstageApp
280
+ if (
281
+ this.backstageApp &&
282
+ event.tags?.backstageApp &&
283
+ event.tags.backstageApp !== this.backstageApp
284
+ ) {
285
+ return false;
286
+ }
287
+
288
+ return true;
289
+ }
290
+
291
+ /**
292
+ * Capture an exception with backstageApp context
293
+ */
294
+ captureException(error: Error | unknown, context?: ObservabilityContext): void {
295
+ if (!this.enabled) return;
296
+
297
+ try {
298
+ if (this.mode === 'child' && this.parentSentry && this.backstageScope) {
299
+ // Use parent Sentry with backstageApp scope
300
+ if (typeof this.parentSentry.withScope === 'function') {
301
+ this.parentSentry.withScope((scope: any) => {
302
+ try {
303
+ // Copy backstageApp scope properties
304
+ if (this.backstageScope && typeof scope.setTag === 'function') {
305
+ scope.setTag('backstageApp', this.backstageApp ?? 'unknown');
306
+ scope.setTag('microFrontend', true);
307
+ scope.setContext('microFrontend', {
308
+ backstageApp: this.backstageApp,
309
+ mode: this.mode,
310
+ });
311
+ }
312
+
313
+ // Add additional context
314
+ if (context && typeof scope.setContext === 'function') {
315
+ scope.setContext('additional', context);
316
+ }
317
+
318
+ if (this.parentSentry && typeof this.parentSentry.captureException === 'function') {
319
+ this.parentSentry.captureException(error);
320
+ }
321
+ } catch (scopeError) {
322
+ logError('[SentryMicroFrontendPlugin] Error in scope callback', {
323
+ error: scopeError,
324
+ });
325
+ }
326
+ });
327
+ } else {
328
+ logWarn('[SentryMicroFrontendPlugin] Parent Sentry does not support withScope');
329
+ }
330
+ } else {
331
+ // Use standard capture with backstageApp enhancement
332
+ const enhancedContext = {
333
+ ...context,
334
+ microFrontend: {
335
+ backstageApp: this.backstageApp,
336
+ mode: this.mode,
337
+ },
338
+ };
339
+ super.captureException(error, enhancedContext);
340
+ }
341
+ } catch (captureError) {
342
+ logError('[SentryMicroFrontendPlugin] Failed to capture exception', { error: captureError });
343
+ }
344
+ }
345
+
346
+ /**
347
+ * Capture a message with backstageApp context
348
+ */
349
+ captureMessage(message: string, level: LogLevel = 'info', context?: ObservabilityContext): void {
350
+ if (!this.enabled) return;
351
+
352
+ try {
353
+ const sentryLevel = mapLogLevelToSentrySeverity(level);
354
+
355
+ if (this.mode === 'child' && this.parentSentry && this.backstageScope) {
356
+ // Use parent Sentry with backstageApp scope
357
+ if (typeof this.parentSentry.withScope === 'function') {
358
+ this.parentSentry.withScope((scope: SentryScope) => {
359
+ try {
360
+ // Copy backstageApp scope properties
361
+ if (this.backstageScope && typeof scope.setTag === 'function') {
362
+ scope.setTag('backstageApp', this.backstageApp ?? 'unknown');
363
+ scope.setTag('microFrontend', true);
364
+ if (typeof scope.setContext === 'function') {
365
+ scope.setContext('microFrontend', {
366
+ backstageApp: this.backstageApp,
367
+ mode: this.mode,
368
+ });
369
+ }
370
+ }
371
+
372
+ // Add additional context
373
+ if (context && typeof scope.setContext === 'function') {
374
+ scope.setContext('additional', context);
375
+ }
376
+
377
+ if (this.parentSentry && typeof this.parentSentry.captureMessage === 'function') {
378
+ this.parentSentry.captureMessage(message, sentryLevel);
379
+ }
380
+ } catch (scopeError) {
381
+ logError('[SentryMicroFrontendPlugin] Error in scope callback', {
382
+ error: scopeError,
383
+ });
384
+ }
385
+ });
386
+ } else {
387
+ logWarn('[SentryMicroFrontendPlugin] Parent Sentry does not support withScope');
388
+ }
389
+ } else {
390
+ // Use standard capture
391
+ super.captureMessage(message, level, context);
392
+ }
393
+ } catch (captureError) {
394
+ logError('[SentryMicroFrontendPlugin] Failed to capture message', { error: captureError });
395
+ }
396
+ }
397
+
398
+ /**
399
+ * Get the current operation mode
400
+ */
401
+ getMode(): MicroFrontendMode {
402
+ return this.mode;
403
+ }
404
+
405
+ /**
406
+ * Get the current Backstage app identifier
407
+ */
408
+ getBackstageApp(): string | undefined {
409
+ return this.backstageApp;
410
+ }
411
+
412
+ /**
413
+ * @deprecated Use getBackstageApp instead.
414
+ */
415
+ getZone(): string | undefined {
416
+ return this.getBackstageApp();
417
+ }
418
+
419
+ /**
420
+ * Get debug information about the plugin state
421
+ */
422
+
423
+ getDebugInfo(): Record<string, any> {
424
+ return {
425
+ mode: this.mode,
426
+ backstageApp: this.backstageApp,
427
+ enabled: this.enabled,
428
+ initialized: this.initialized,
429
+ hasParentSentry: this.mode === 'child' && Boolean(this.parentSentry),
430
+ clientType: this.client ? this.client.constructor.name : 'none',
431
+ };
432
+ }
433
+
434
+ /**
435
+ * Clean up the plugin and release resources
436
+ */
437
+ async cleanup(): Promise<void> {
438
+ try {
439
+ // Clean up event processor if it exists
440
+ if (this.eventProcessorCleanup) {
441
+ this.eventProcessorCleanup();
442
+ this.eventProcessorCleanup = undefined;
443
+ }
444
+
445
+ // Clear backstageApp scope
446
+
447
+ if (this.backstageScope && typeof (this.backstageScope as any).clear === 'function') {
448
+ (this.backstageScope as any).clear();
449
+ }
450
+ this.backstageScope = undefined;
451
+
452
+ // Clear parent Sentry reference
453
+ this.parentSentry = undefined;
454
+
455
+ // Call parent cleanup
456
+ await super.cleanup();
457
+
458
+ // Mark as not initialized
459
+ this.initialized = false;
460
+ this.enabled = false;
461
+
462
+ logDebug('[SentryMicroFrontendPlugin] Cleanup completed');
463
+ } catch (error) {
464
+ logError('[SentryMicroFrontendPlugin] Error during cleanup', { error });
465
+ }
466
+ }
467
+
468
+ /**
469
+ * Destroy the plugin (alias for cleanup)
470
+ */
471
+ async destroy(): Promise<void> {
472
+ await this.cleanup();
473
+ }
474
+ }
475
+
476
+ /**
477
+ * Factory function to create a Sentry Micro Frontend plugin.
478
+ *
479
+ * Creates a configured SentryMicroFrontendPlugin instance with micro frontend-specific
480
+ * features like multiplexed transport and backstage app routing.
481
+ *
482
+ * @param config - Optional Sentry micro frontend plugin configuration
483
+ * @returns SentryMicroFrontendPlugin instance
484
+ *
485
+ * @example
486
+ * ```typescript
487
+ * const sentry = createSentryMicroFrontendPlugin({
488
+ * dsn: 'https://...',
489
+ * backstage: [
490
+ * { name: 'admin', dsn: 'https://admin-dsn...' },
491
+ * { name: 'dashboard', dsn: 'https://dashboard-dsn...' },
492
+ * ],
493
+ * });
494
+ * ```
495
+ */
496
+ export const createSentryMicroFrontendPlugin = (
497
+ config?: SentryMicroFrontendConfig,
498
+ ): SentryMicroFrontendPlugin => {
499
+ return new SentryMicroFrontendPlugin(config);
500
+ };
@@ -0,0 +1,140 @@
1
+ /**
2
+ * @fileoverview Type definitions for Sentry SDK
3
+ * Type definitions for Sentry SDK
4
+ * These are minimal types to avoid using 'any' throughout the plugin
5
+ */
6
+
7
+ import type { LogLevel } from '../../core/types';
8
+
9
+ /**
10
+ * Sentry Scope interface
11
+ */
12
+ export interface SentryScope {
13
+ setTag(key: string, value: string | number | boolean | null): void;
14
+ setContext(key: string, context: Record<string, any> | null): void;
15
+ setUser(user: Record<string, any> | null): void;
16
+ setLevel(level: SentrySeverityLevel): void;
17
+ setFingerprint(fingerprint: string[]): void;
18
+ clear(): void;
19
+ }
20
+
21
+ /**
22
+ * Sentry Hub interface
23
+ */
24
+ export interface SentryHub {
25
+ getScope(): SentryScope;
26
+ pushScope(): SentryScope;
27
+ popScope(): boolean;
28
+ withScope(callback: (scope: SentryScope) => void): void;
29
+ }
30
+
31
+ /**
32
+ * Sentry Client interface
33
+ */
34
+ export interface SentryClient {
35
+ captureException(exception: any, hint?: any): string;
36
+ captureMessage(message: string, level?: SentrySeverityLevel): string;
37
+ captureEvent(event: any): string;
38
+ flush(timeout?: number): Promise<boolean>;
39
+ close(timeout?: number): Promise<boolean>;
40
+ getOptions(): SentryOptions;
41
+ getCurrentHub?(): SentryHub;
42
+ }
43
+
44
+ /**
45
+ * Sentry SDK interface
46
+ */
47
+ export interface SentrySDK {
48
+ init(options: SentryOptions): void;
49
+ captureException(exception: any, captureContext?: any): string;
50
+ captureMessage(message: string, captureContext?: any): string;
51
+ captureEvent(event: any, hint?: any): string;
52
+ withScope(callback: (scope: SentryScope) => void): void;
53
+ addBreadcrumb(breadcrumb: any): void;
54
+ setUser(user: any): void;
55
+ setTag(key: string, value: string): void;
56
+ setContext(key: string, context: any): void;
57
+ setExtra(key: string, extra: any): void;
58
+ getCurrentHub(): SentryHub;
59
+ getClient<T extends SentryClient>(): T | undefined;
60
+ flush(timeout?: number): Promise<boolean>;
61
+ close(timeout?: number): Promise<boolean>;
62
+ lastEventId(): string | undefined;
63
+
64
+ // Integration methods
65
+ addEventProcessor(processor: (event: any) => any | null): void;
66
+
67
+ // Browser specific
68
+ Scope?: new () => SentryScope;
69
+
70
+ // Transport creation
71
+ makeMultiplexedTransport?(
72
+ createTransport: (options: any) => any,
73
+ matcher: (options: any) => any[],
74
+ ): any;
75
+ makeFetchTransport?(options: any): any;
76
+
77
+ // Integrations
78
+ browserTracingIntegration?(): any;
79
+ browserProfilingIntegration?(): any;
80
+ replayIntegration?(options?: any): any;
81
+ captureConsoleIntegration?(options?: any): any;
82
+ feedbackIntegration?(options?: any): any;
83
+ vercelAIIntegration?(): any;
84
+ }
85
+
86
+ /**
87
+ * Sentry Options interface
88
+ */
89
+ export interface SentryOptions {
90
+ dsn?: string;
91
+ release?: string;
92
+ environment?: string;
93
+ debug?: boolean;
94
+ sampleRate?: number;
95
+ tracesSampleRate?: number;
96
+ profilesSampleRate?: number;
97
+ replaysSessionSampleRate?: number;
98
+ replaysOnErrorSampleRate?: number;
99
+ transport?: any;
100
+ integrations?: any[];
101
+ beforeSend?: (event: any, hint: any) => any | null;
102
+ beforeSendTransaction?: (event: any, hint: any) => any | null;
103
+ beforeBreadcrumb?: (breadcrumb: any, hint?: any) => any | null;
104
+ tracePropagationTargets?: (string | RegExp)[];
105
+ initialScope?: any;
106
+ maxBreadcrumbs?: number;
107
+ attachStacktrace?: boolean;
108
+ autoSessionTracking?: boolean;
109
+ sendDefaultPii?: boolean;
110
+
111
+ _experiments?: Record<string, any>;
112
+ }
113
+
114
+ /**
115
+ * Sentry Severity Level
116
+ */
117
+ export type SentrySeverityLevel = 'fatal' | 'error' | 'warning' | 'log' | 'info' | 'debug';
118
+
119
+ /**
120
+ * Map LogLevel to Sentry Severity.
121
+ *
122
+ * Converts the observability package's LogLevel to Sentry's SeverityLevel format.
123
+ *
124
+ * @param level - Log level from observability package
125
+ * @returns Corresponding Sentry severity level
126
+ */
127
+ export function mapLogLevelToSentrySeverity(level: LogLevel): SentrySeverityLevel {
128
+ switch (level) {
129
+ case 'error':
130
+ return 'error';
131
+ case 'warning':
132
+ return 'warning';
133
+ case 'info':
134
+ return 'info';
135
+ case 'debug':
136
+ return 'debug';
137
+ default:
138
+ return 'info';
139
+ }
140
+ }