@od-oneapp/observability 2026.2.1701 → 2026.2.2001-canary.1
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/CHANGELOG.md +3 -3
- package/README.md +6 -6
- package/client-next.d.mts +6 -6
- package/client-next.mjs +4 -4
- package/client.d.mts +3 -3
- package/client.mjs +1 -1
- package/client.mjs.map +1 -1
- package/core-BgKCqXjb.mjs +95 -0
- package/core-BgKCqXjb.mjs.map +1 -0
- package/env.mjs +1 -1
- package/env.mjs.map +1 -1
- package/{factory-DkY353r8.mjs → factory-d1469fpz.mjs} +2 -2
- package/factory-d1469fpz.mjs.map +1 -0
- package/hooks-useObservability.d.mts +1 -1
- package/hooks-useObservability.mjs +1 -1
- package/hooks-useObservability.mjs.map +1 -1
- package/{index-CpcdzWrF.d.mts → index-CktVJJqJ.d.mts} +3 -3
- package/{index-CpcdzWrF.d.mts.map → index-CktVJJqJ.d.mts.map} +1 -1
- package/index.mjs +1 -1
- package/index.mjs.map +1 -1
- package/logs-DkncIKEw.mjs +112 -0
- package/logs-DkncIKEw.mjs.map +1 -0
- package/{manager-BxQqOPEg.d.mts → manager-CONEYB97.d.mts} +2 -2
- package/{manager-BxQqOPEg.d.mts.map → manager-CONEYB97.d.mts.map} +1 -1
- package/package.json +33 -40
- package/{plugin-Bt-ygG1m.d.mts → plugin-81171XQL.d.mts} +4 -4
- package/{plugin-Bt-ygG1m.d.mts.map → plugin-81171XQL.d.mts.map} +1 -1
- package/{plugin-CaQxviDs.d.mts → plugin-CEOGIJFN.d.mts} +2 -2
- package/{plugin-CaQxviDs.d.mts.map → plugin-CEOGIJFN.d.mts.map} +1 -1
- package/plugin-CuRZ8qQf.mjs +593 -0
- package/plugin-CuRZ8qQf.mjs.map +1 -0
- package/{plugin-CP895lBx.mjs → plugin-DApSl5bY.mjs} +2 -2
- package/plugin-DApSl5bY.mjs.map +1 -0
- package/{plugin-lPdJirTY.mjs → plugin-LhaOv4eq.mjs} +2 -2
- package/plugin-LhaOv4eq.mjs.map +1 -0
- package/{plugin-Bfq-o3nr.d.mts → plugin-pvH_kv0a.d.mts} +1 -1
- package/{plugin-Bfq-o3nr.d.mts.map → plugin-pvH_kv0a.d.mts.map} +1 -1
- package/plugins-betterstack-env.mjs +1 -1
- package/plugins-betterstack-env.mjs.map +1 -1
- package/plugins-betterstack.d.mts +2 -2
- package/plugins-betterstack.mjs +1 -1
- package/plugins-console.d.mts +1 -1
- package/plugins-sentry-env.d.mts +4 -4
- package/plugins-sentry-env.mjs +1 -1
- package/plugins-sentry-env.mjs.map +1 -1
- package/plugins-sentry-microfrontend-env.mjs +1 -1
- package/plugins-sentry-microfrontend-env.mjs.map +1 -1
- package/plugins-sentry-microfrontend.d.mts +1 -1
- package/plugins-sentry-microfrontend.mjs +1 -1
- package/plugins-sentry.d.mts +2 -2
- package/plugins-sentry.mjs +1 -1
- package/server-edge.d.mts +4 -4
- package/server-edge.mjs +2 -2
- package/server-next.d.mts +6 -6
- package/server-next.mjs +4 -4
- package/server.d.mts +3 -3
- package/server.mjs +1 -1
- package/server.mjs.map +1 -1
- package/{utils-DjjqCeoW.d.mts → utils-6Gg4fkvH.d.mts} +4 -3
- package/utils-6Gg4fkvH.d.mts.map +1 -0
- package/factory-DkY353r8.mjs.map +0 -1
- package/plugin-CP895lBx.mjs.map +0 -1
- package/plugin-CxeJHHeJ.mjs +0 -1195
- package/plugin-CxeJHHeJ.mjs.map +0 -1
- package/plugin-lPdJirTY.mjs.map +0 -1
- package/utils-DjjqCeoW.d.mts.map +0 -1
package/server.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","names":[],"sources":["../src/server.ts"],"sourcesContent":["/**\n * @fileoverview Auto-configuring server export for Node.js environments (non-Next.js)\n * Auto-configuring server export for Node.js environments (non-Next.js)\n */\n\nimport { safeEnv } from '../env';\n\nimport { ObservabilityBuilder } from './factory/builder';\nimport { createConsoleServerPlugin } from './plugins/console';\nimport { shouldEnableConsole } from './shared';\n\n/**\n * Auto-configured observability for Node.js server environments\n * Automatically sets up console logging based on environment variables\n */\nconst builder = ObservabilityBuilder.create();\n\n// Console logging control using shared utility\nconst env = safeEnv();\nconst enableConsole = shouldEnableConsole(\n env.NEXT_PUBLIC_NODE_ENV,\n env.NEXT_PUBLIC_OBSERVABILITY_CONSOLE_ENABLED,\n env.NEXT_PUBLIC_OBSERVABILITY_DEBUG,\n);\n\n// Always add console plugin, control via enabled flag\nbuilder.withPlugin(\n createConsoleServerPlugin({\n prefix: '[Server]',\n enabled: enableConsole,\n }),\n);\n\n// Note: Production providers would typically be configured by the app\n// This is just a fallback for non-Next.js server usage\n\n/**\n * Pre-configured observability instance for Node.js server environments\n * Includes console logging with automatic environment-based configuration\n */\nexport const observability = builder.build();\n\n// Export types and utilities\nexport * from './core/types';\nexport { createObservability } from './factory';\nexport { ObservabilityBuilder } from './factory/builder';\n\n/**\n * Synchronous logger functions for non-Next.js Node.js environments.\n * These are bound to a pre-built observability instance at module load time.\n *\n * Note: For Next.js apps, use `@repo/observability/server/next` instead,\n * which provides async loggers that support lazy initialization.\n *\n * @example\n * ```typescript\n * import { logInfo, logError } from '@
|
|
1
|
+
{"version":3,"file":"server.mjs","names":[],"sources":["../src/server.ts"],"sourcesContent":["/**\n * @fileoverview Auto-configuring server export for Node.js environments (non-Next.js)\n * Auto-configuring server export for Node.js environments (non-Next.js)\n */\n\nimport { safeEnv } from '../env';\n\nimport { ObservabilityBuilder } from './factory/builder';\nimport { createConsoleServerPlugin } from './plugins/console';\nimport { shouldEnableConsole } from './shared';\n\n/**\n * Auto-configured observability for Node.js server environments\n * Automatically sets up console logging based on environment variables\n */\nconst builder = ObservabilityBuilder.create();\n\n// Console logging control using shared utility\nconst env = safeEnv();\nconst enableConsole = shouldEnableConsole(\n env.NEXT_PUBLIC_NODE_ENV,\n env.NEXT_PUBLIC_OBSERVABILITY_CONSOLE_ENABLED,\n env.NEXT_PUBLIC_OBSERVABILITY_DEBUG,\n);\n\n// Always add console plugin, control via enabled flag\nbuilder.withPlugin(\n createConsoleServerPlugin({\n prefix: '[Server]',\n enabled: enableConsole,\n }),\n);\n\n// Note: Production providers would typically be configured by the app\n// This is just a fallback for non-Next.js server usage\n\n/**\n * Pre-configured observability instance for Node.js server environments\n * Includes console logging with automatic environment-based configuration\n */\nexport const observability = builder.build();\n\n// Export types and utilities\nexport * from './core/types';\nexport { createObservability } from './factory';\nexport { ObservabilityBuilder } from './factory/builder';\n\n/**\n * Synchronous logger functions for non-Next.js Node.js environments.\n * These are bound to a pre-built observability instance at module load time.\n *\n * Note: For Next.js apps, use `@repo/observability/server/next` instead,\n * which provides async loggers that support lazy initialization.\n *\n * @example\n * ```typescript\n * import { logInfo, logError } from '@od-oneapp/shared/logger';\n * logInfo('Server started', { port: 3000 });\n * logError('Database connection failed', { error: err });\n * ```\n */\n// Legacy function for backward compatibility (no-op)\n/**\n * @deprecated Configuration now happens through the observability system\n */\nexport const configureLogger = () => {\n // No-op: Configuration now happens through the observability system\n};\n\n// Re-export type\nexport type LogContext = Record<string, any>;\n"],"mappings":";;;;;;;;;;;;;;AAeA,MAAM,UAAU,qBAAqB,QAAQ;AAG7C,MAAM,MAAM,SAAS;AACrB,MAAM,gBAAgB,oBACpB,IAAI,sBACJ,IAAI,2CACJ,IAAI,gCACL;AAGD,QAAQ,WACN,0BAA0B;CACxB,QAAQ;CACR,SAAS;CACV,CAAC,CACH;;;;;AASD,MAAa,gBAAgB,QAAQ,OAAO;;;;;;;;;;;;;;;;;;AAyB5C,MAAa,wBAAwB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { l as ObservabilityContext, o as LogLevel } from "./plugin-
|
|
2
|
-
import { n as SentryPluginConfig } from "./plugin-
|
|
1
|
+
import { l as ObservabilityContext, o as LogLevel } from "./plugin-pvH_kv0a.mjs";
|
|
2
|
+
import { n as SentryPluginConfig } from "./plugin-81171XQL.mjs";
|
|
3
|
+
import { SentryPlugin } from "@od-oneapp/integration-sentry/observability-plugin/plugin";
|
|
3
4
|
|
|
4
5
|
//#region src/plugins/sentry-microfrontend/types.d.ts
|
|
5
6
|
interface BackstageAppConfig {
|
|
@@ -73,4 +74,4 @@ declare function isHostEnvironment(): boolean;
|
|
|
73
74
|
declare function createBackstageScope(backstageApp: string, additionalTags?: Record<string, string>): unknown;
|
|
74
75
|
//#endregion
|
|
75
76
|
export { createSentryMicroFrontendPlugin as a, MicroFrontendMode as c, SentryMicroFrontendPlugin as i, SentryMicroFrontendConfig as l, detectCurrentBackstageApp as n, createMultiplexedTransport as o, isHostEnvironment as r, BackstageAppConfig as s, createBackstageScope as t };
|
|
76
|
-
//# sourceMappingURL=utils-
|
|
77
|
+
//# sourceMappingURL=utils-6Gg4fkvH.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-6Gg4fkvH.d.mts","names":[],"sources":["../src/plugins/sentry-microfrontend/types.ts","../src/plugins/sentry-microfrontend/multiplexed-transport.ts","../src/plugins/sentry-microfrontend/plugin.ts","../src/plugins/sentry-microfrontend/utils.ts"],"mappings":";;;;;UAUiB,kBAAA;EAIf,IAAA;EAKA,GAAA;EAKA,OAAA;EAKA,IAAA,GAAO,MAAA;EAKP,YAAA,aAAyB,MAAA;AAAA;AAAA,KAMf,iBAAA;AAAA,UAKK,yBAAA,SAAkC,IAAA,CAAK,kBAAA;EAItD,MAAA;EAKA,YAAA;EAKA,aAAA,GAAgB,kBAAA;EAMhB,YAAA;EAKA,oBAAA;EAMA,mBAAA;EAKA,WAAA;EAMA,uBAAA;EAKA,UAAA,GAAa,MAAA;EAMb,oBAAA;EAKA,iBAAA;IACE,wBAAA;IACA,yBAAA;IACA,mBAAA;EAAA;EAOF,YAAA;IACE,UAAA;EAAA;AAAA;AAAA,QAOI,MAAA;EAAA,UACI,MAAA;IACR,MAAA;IAEA,8BAAA;IAEA,6BAAA;EAAA;AAAA;;;iBC1GY,0BAAA,CACd,SAAA,EAAW,kBAAA,IACX,WAAA,WAEA,YAAA;;;cCgBW,yBAAA,SAAkC,YAAA;EAAA,QACrC,IAAA;EAAA,QACA,YAAA;EAAA,QACA,YAAA;EAAA,QACA,cAAA;EAAA,QACA,mBAAA;EAAA,QACA,qBAAA;cAOI,MAAA,GAAQ,yBAAA;EAAA,eA2CL,aAAA;EAAA,eAwBA,aAAA;EAwBT,UAAA,CAAW,MAAA,GAAS,yBAAA,GAA4B,OAAA;EAAA,QAwC9C,qBAAA;EAAA,QA6CA,aAAA;EAAA,QA0CA,kBAAA;EAqBR,gBAAA,CAAiB,KAAA,EAAO,KAAA,YAAiB,OAAA,GAAU,oBAAA;EAuDnD,cAAA,CAAe,OAAA,UAAiB,KAAA,GAAO,QAAA,EAAmB,OAAA,GAAU,oBAAA;EAoDpE,OAAA,CAAA,GAAW,iBAAA;EAOX,eAAA,CAAA;EAOA,OAAA,CAAA;EAQA,YAAA,CAAA,GAAgB,MAAA;EAcV,OAAA,CAAA,GAAW,OAAA;EAkCX,OAAA,CAAA,GAAW,OAAA;AAAA;AAAA,cAyBN,+BAAA,GACX,MAAA,GAAS,yBAAA,KACR,yBAAA;;;iBCtda,yBAAA,CACd,cAAA,GAAiB,kBAAA;AAAA,iBA+DH,iBAAA,CAAA;AAAA,iBAkCA,oBAAA,CACd,YAAA,UACA,cAAA,GAAiB,MAAA"}
|
package/factory-DkY353r8.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"factory-DkY353r8.mjs","names":[],"sources":["../src/core/manager.ts","../src/factory/builder.ts","../src/factory/index.ts"],"sourcesContent":["/**\n * @fileoverview ObservabilityManager - Core orchestrator for multiple observability providers\n * ObservabilityManager - Core orchestrator for multiple observability providers\n */\n\nimport { logError, logWarn } from '@repo/shared/logs';\n\nimport type { ObservabilityPlugin, ObservabilityServerPlugin, PluginLifecycle } from './plugin';\nimport type {\n Breadcrumb,\n LogLevel,\n ObservabilityContext,\n ObservabilityScope,\n ObservabilityServer,\n ObservabilityUser,\n} from './types';\n\n/**\n * Manager that orchestrates multiple observability plugins\n * Broadcasts all method calls to enabled plugins\n */\nexport class ObservabilityManager implements ObservabilityServer {\n private plugins = new Map<string, ObservabilityPlugin | ObservabilityServerPlugin>();\n private initialized = false;\n private initializationPromise: Promise<void> | null = null;\n private lifecycle: PluginLifecycle = {};\n private initializationError: Error | null = null;\n\n /**\n * Create a new ObservabilityManager instance.\n *\n * @param lifecycle - Optional lifecycle callbacks for plugin events\n */\n constructor(lifecycle?: PluginLifecycle) {\n if (lifecycle) {\n this.lifecycle = lifecycle;\n }\n }\n\n /**\n * Add a plugin to the manager\n */\n addPlugin(plugin: ObservabilityPlugin | ObservabilityServerPlugin): this {\n this.plugins.set(plugin.name, plugin);\n return this;\n }\n\n /**\n * Get a specific plugin by name.\n *\n * @param name - Name of the plugin to retrieve\n * @returns Plugin instance if found, undefined otherwise\n */\n getPlugin<T extends ObservabilityPlugin>(name: string): T | undefined {\n return this.plugins.get(name) as T;\n }\n\n /**\n * Get all registered plugins.\n *\n * @returns Array of all registered plugins\n */\n getPlugins(): ObservabilityPlugin[] {\n return Array.from(this.plugins.values());\n }\n\n /**\n * List all registered plugins (alias for getPlugins).\n *\n * @returns Array of all registered plugins\n */\n listPlugins(): ObservabilityPlugin[] {\n return this.getPlugins();\n }\n\n /**\n * Initialize all plugins\n * Note: Failed initialization is retryable - subsequent calls will re-attempt initialization.\n * This allows recovery from transient failures (network issues, temporary misconfigurations).\n */\n async initialize(): Promise<void> {\n // If there's already an initialization in progress, wait for it\n if (this.initializationPromise) {\n return this.initializationPromise;\n }\n\n // If already initialized successfully, return early\n if (this.initialized) {\n return;\n }\n\n // Allow retry if previous attempt failed\n if (this.initializationError) {\n // Log retry attempt for debugging\n logWarn('ObservabilityManager: Retrying failed initialization');\n // Clear previous error to allow fresh attempt\n this.initializationError = null;\n }\n\n // Create the initialization promise and store it to prevent concurrent calls\n this.initializationPromise = this.doInitialize();\n\n try {\n await this.initializationPromise;\n } finally {\n // Clear the promise after initialization completes (success or failure)\n this.initializationPromise = null;\n }\n }\n\n private async doInitialize(): Promise<void> {\n const initPromises = Array.from(this.plugins.values())\n .filter(plugin => plugin.enabled && plugin.initialize)\n .map(async plugin => {\n try {\n if (plugin.initialize) {\n await plugin.initialize();\n }\n this.lifecycle.onInitialized?.(plugin);\n } catch (error) {\n logError(`Failed to initialize plugin ${plugin.name}`, {\n error,\n pluginName: plugin.name,\n });\n this.lifecycle.onError?.(error as Error, plugin);\n // Re-throw to propagate error to Promise.all\n throw error;\n }\n });\n\n try {\n await Promise.all(initPromises);\n this.initialized = true;\n } catch (error) {\n this.initializationError = error instanceof Error ? error : new Error(String(error));\n throw this.initializationError;\n }\n }\n\n /**\n * Check if initialization had an error\n * @returns `true` if initialization failed, `false` otherwise\n */\n hasInitializationError(): boolean {\n return this.initializationError !== null;\n }\n\n /**\n * Get the initialization error if one occurred\n * @returns The initialization error or `null` if no error\n */\n getInitializationError(): Error | null {\n return this.initializationError;\n }\n\n /**\n * Shutdown all plugins\n */\n async shutdown(): Promise<void> {\n const shutdownPromises = Array.from(this.plugins.values())\n .filter(plugin => plugin.shutdown)\n .map(async plugin => {\n try {\n if (plugin.shutdown) {\n await plugin.shutdown();\n }\n this.lifecycle.onShutdown?.(plugin);\n } catch (error) {\n logError(`Failed to shutdown plugin ${plugin.name}`, { error, pluginName: plugin.name });\n this.lifecycle.onError?.(error as Error, plugin);\n }\n });\n\n await Promise.allSettled(shutdownPromises);\n this.initialized = false;\n }\n\n /**\n * Broadcast exception to all enabled plugins.\n *\n * @param error - Error object or unknown error value\n * @param context - Optional additional context data\n */\n captureException(error: Error | unknown, context?: ObservabilityContext): void {\n this.broadcast(plugin => plugin.captureException(error, context));\n }\n\n /**\n * Broadcast message to all enabled plugins.\n *\n * @param message - Message to log\n * @param level - Log level (default: 'info')\n * @param context - Optional additional context data\n */\n captureMessage(message: string, level: LogLevel = 'info', context?: ObservabilityContext): void {\n this.broadcast(plugin => plugin.captureMessage(message, level, context));\n }\n\n /**\n * Validate and sanitize user data to prevent injection and DoS attacks\n * @param user - User data to validate\n * @returns Validated user data with length limits and format validation applied\n */\n private validateUser(user: ObservabilityUser | null): ObservabilityUser | null {\n if (!user) return null;\n\n // Validate required ID field\n const id = String(user.id).trim().slice(0, 255);\n if (!id) {\n // Log warning but don't throw - graceful degradation\n logWarn('ObservabilityManager: User ID is empty, ignoring user data');\n return null;\n }\n\n const validated: ObservabilityUser = { id };\n\n // Validate email format if provided\n if ('email' in user && user.email) {\n const email = String(user.email).trim().slice(0, 255);\n // More robust email validation - RFC 5322 simplified but stricter\n // Allows: alphanumeric, dots, plus, hyphens, underscores before @\n // Requires: valid domain with at least one dot after @\n if (\n email &&\n // eslint-disable-next-line security/detect-unsafe-regex -- Safe: bounded input (max 255 chars), RFC 5322 compliant pattern\n /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(\n email,\n )\n ) {\n validated.email = email;\n }\n }\n\n // Validate username if provided\n if ('username' in user && user.username) {\n const username = String(user.username).trim().slice(0, 255);\n if (username) {\n validated.username = username;\n }\n }\n\n // Validate IP address format if provided\n if ('ip_address' in user && user.ip_address) {\n const ip = String(user.ip_address).trim();\n // Stricter IP validation\n // IPv4: Each octet must be 0-255\n const isValidIPv4 =\n // eslint-disable-next-line security/detect-unsafe-regex -- Safe: bounded pattern for IPv4 validation, input is trimmed string\n /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(\n ip,\n );\n // IPv6: Basic format check (full validation is complex, this catches most invalid cases)\n const looksLikeIPv6 =\n /^[0-9a-fA-F:]+$/.test(ip) && ip.includes(':') && ip.split(':').length <= 8;\n\n if (isValidIPv4 || looksLikeIPv6) {\n validated.ip_address = ip.slice(0, 45); // IPv6 max length\n }\n }\n\n return validated;\n }\n\n /**\n * Set user on all enabled plugins\n * User data is validated and sanitized before being set\n * @param user - User data to set (will be validated)\n */\n setUser(user: ObservabilityUser | null): void {\n const validatedUser = this.validateUser(user);\n this.broadcast(plugin => plugin.setUser(validatedUser));\n }\n\n /**\n * Add breadcrumb to all enabled plugins.\n *\n * @param breadcrumb - Breadcrumb data to add\n */\n addBreadcrumb(breadcrumb: Breadcrumb): void {\n this.broadcast(plugin => plugin.addBreadcrumb(breadcrumb));\n }\n\n /**\n * Execute callback within scope for all enabled plugins.\n *\n * @param callback - Callback that receives the scope\n */\n withScope(callback: (scope: ObservabilityScope) => void): void {\n this.broadcast(plugin => plugin.withScope(callback));\n }\n\n /**\n * Flush all plugins that support it.\n *\n * Waits for all enabled plugins with flush capability to send pending events.\n *\n * @param timeout - Maximum time to wait in milliseconds\n * @returns Promise resolving to true if all plugins flushed successfully\n */\n async flush(timeout?: number): Promise<boolean> {\n const flushPromises = Array.from(this.plugins.values())\n .filter((plugin): plugin is ObservabilityServerPlugin => {\n return plugin.enabled && 'flush' in plugin && typeof plugin.flush === 'function';\n })\n .map(plugin => plugin.flush(timeout));\n\n if (flushPromises.length === 0) {\n return true;\n }\n\n const results = await Promise.allSettled(flushPromises);\n return results.every(result => result.status === 'fulfilled' && result.value === true);\n }\n\n /**\n * Helper to broadcast a method call to all enabled plugins\n * Uses nested try-catch to ensure errors in error handling don't prevent other plugins from executing\n */\n private broadcast(fn: (plugin: ObservabilityPlugin) => void): void {\n this.plugins.forEach(plugin => {\n if (plugin.enabled) {\n try {\n fn(plugin);\n } catch (error) {\n // Safely handle error without throwing - nested try-catch ensures resilience\n try {\n logError(`Plugin ${plugin.name} error`, { error, pluginName: plugin.name });\n } catch {\n // Logger unavailable - continue silently\n }\n\n try {\n this.lifecycle.onError?.(error as Error, plugin);\n } catch {\n // Error handler failed - continue to next plugin\n }\n }\n }\n });\n }\n\n /**\n * Check if manager has any enabled plugins.\n *\n * @returns True if at least one plugin is enabled, false otherwise\n */\n hasEnabledPlugins(): boolean {\n return Array.from(this.plugins.values()).some(plugin => plugin.enabled);\n }\n\n /**\n * Get names of all enabled plugins.\n *\n * @returns Array of plugin names that are currently enabled\n */\n getEnabledPluginNames(): string[] {\n return Array.from(this.plugins.values())\n .filter(plugin => plugin.enabled)\n .map(plugin => plugin.name);\n }\n}\n","/**\n * @fileoverview ObservabilityBuilder - Fluent API for building observability instances\n * ObservabilityBuilder - Fluent API for building observability instances\n */\n\nimport { logError } from '@repo/shared/logs';\n\nimport { ObservabilityManager } from '../core/manager';\n\nimport type {\n ObservabilityPlugin,\n ObservabilityServerPlugin,\n PluginLifecycle,\n} from '../core/plugin';\n\n/**\n * Builder for creating configured ObservabilityManager instances\n */\nexport class ObservabilityBuilder {\n private plugins: (ObservabilityPlugin | ObservabilityServerPlugin)[] = [];\n private lifecycle: PluginLifecycle = {};\n private autoInitialize = true;\n\n /**\n * Add a plugin to the observability stack\n * @param plugin - Observability plugin to add\n * @returns Builder instance for chaining\n */\n withPlugin(plugin: ObservabilityPlugin | ObservabilityServerPlugin): this {\n if (plugin) {\n this.plugins.push(plugin);\n }\n return this;\n }\n\n /**\n * Add multiple plugins at once\n * @param plugins - Array of observability plugins to add\n * @returns Builder instance for chaining\n */\n withPlugins(plugins: (ObservabilityPlugin | ObservabilityServerPlugin)[]): this {\n if (plugins && Array.isArray(plugins)) {\n const validPlugins = plugins.filter(plugin => plugin != null);\n this.plugins.push(...validPlugins);\n }\n return this;\n }\n\n /**\n * Set lifecycle callbacks for plugin management\n * @param lifecycle - Lifecycle callback configuration\n * @returns Builder instance for chaining\n */\n withLifecycle(lifecycle: PluginLifecycle): this {\n this.lifecycle = { ...this.lifecycle, ...lifecycle };\n return this;\n }\n\n /**\n * Configure whether to auto-initialize plugins (default: true)\n */\n withAutoInitialize(autoInitialize: boolean): this {\n this.autoInitialize = autoInitialize;\n return this;\n }\n\n /**\n * Build the ObservabilityManager instance\n * @returns Configured ObservabilityManager instance\n */\n build(): ObservabilityManager {\n const manager = new ObservabilityManager(this.lifecycle);\n\n // Add all plugins\n this.plugins.forEach(plugin => manager.addPlugin(plugin));\n\n // Auto-initialize if enabled and not in edge runtime\n if (\n this.autoInitialize &&\n typeof process !== 'undefined' &&\n process.env.NEXT_RUNTIME !== 'edge'\n ) {\n // Initialize asynchronously with safe error handling\n void (async () => {\n try {\n await manager.initialize();\n } catch (error) {\n // Store error in manager for later inspection\n // Note: We can't directly set private property, but manager stores it internally\n\n // Try logError, but don't fail if unavailable\n try {\n logError('Failed to initialize observability', { error });\n } catch {\n // Logger unavailable - error is stored in manager via initialize() method\n }\n }\n })();\n }\n\n return manager;\n }\n\n /**\n * Build and initialize the ObservabilityManager instance\n * @returns Promise resolving to initialized ObservabilityManager\n */\n async buildWithAutoInit(): Promise<ObservabilityManager> {\n const manager = new ObservabilityManager(this.lifecycle);\n\n // Add all plugins\n this.plugins.forEach(plugin => manager.addPlugin(plugin));\n\n // Initialize all plugins - catch errors but still return manager (graceful degradation)\n try {\n await manager.initialize();\n } catch {\n // Error is stored in manager, but we still return it for graceful degradation\n // This allows the application to continue even if observability initialization fails\n }\n\n return manager;\n }\n\n /**\n * Create a new builder instance\n * @returns New ObservabilityBuilder instance\n */\n static create(): ObservabilityBuilder {\n return new ObservabilityBuilder();\n }\n}\n","/**\n * @fileoverview Factory functions for creating observability instances\n * Factory functions for creating observability instances\n */\n\nimport { ObservabilityManager } from '../core/manager';\n\nimport { ObservabilityBuilder } from './builder';\n\nimport type { ObservabilityPlugin, ObservabilityServerPlugin } from '../core/plugin';\n\nexport { ObservabilityManager } from '../core/manager';\nexport { ObservabilityBuilder } from './builder';\n\n/**\n * Create an observability instance with the provided plugins.\n *\n * Factory function that creates a configured ObservabilityManager with the given plugins.\n * Provides a simpler API than using ObservabilityBuilder directly.\n *\n * @param plugins - Array of observability plugins to include\n * @param options - Optional configuration options\n * @param options.autoInitialize - Whether to auto-initialize plugins (default: true)\n * @returns Configured ObservabilityManager instance\n *\n * @example\n * ```typescript\n * const obs = createObservability([\n * createConsolePlugin(),\n * createSentryPlugin({ dsn: '...' }),\n * ], { autoInitialize: true });\n * ```\n */\nexport function createObservability(\n plugins: (ObservabilityPlugin | ObservabilityServerPlugin)[],\n options?: {\n autoInitialize?: boolean;\n },\n): ObservabilityManager {\n const builder = new ObservabilityBuilder();\n\n if (options?.autoInitialize !== undefined) {\n builder.withAutoInitialize(options.autoInitialize);\n }\n\n return builder.withPlugins(plugins).build();\n}\n\n/**\n * Create a no-op observability instance for testing or when observability is disabled.\n *\n * Returns an ObservabilityManager with no plugins configured. All observability methods\n * will be no-ops. Useful for testing or when observability should be disabled.\n *\n * Note: For logging, use @repo/shared/logger instead.\n *\n * @returns Empty ObservabilityManager instance\n *\n * @example\n * ```typescript\n * const obs = createNoOpObservability();\n * obs.captureMessage('This will not be logged'); // No-op\n * ```\n */\nexport function createNoOpObservability(): ObservabilityManager {\n return new ObservabilityManager();\n}\n"],"mappings":";;;;;;;;;;;AAqBA,IAAa,uBAAb,MAAiE;CAC/D,AAAQ,0BAAU,IAAI,KAA8D;CACpF,AAAQ,cAAc;CACtB,AAAQ,wBAA8C;CACtD,AAAQ,YAA6B,EAAE;CACvC,AAAQ,sBAAoC;;;;;;CAO5C,YAAY,WAA6B;AACvC,MAAI,UACF,MAAK,YAAY;;;;;CAOrB,UAAU,QAA+D;AACvE,OAAK,QAAQ,IAAI,OAAO,MAAM,OAAO;AACrC,SAAO;;;;;;;;CAST,UAAyC,MAA6B;AACpE,SAAO,KAAK,QAAQ,IAAI,KAAK;;;;;;;CAQ/B,aAAoC;AAClC,SAAO,MAAM,KAAK,KAAK,QAAQ,QAAQ,CAAC;;;;;;;CAQ1C,cAAqC;AACnC,SAAO,KAAK,YAAY;;;;;;;CAQ1B,MAAM,aAA4B;AAEhC,MAAI,KAAK,sBACP,QAAO,KAAK;AAId,MAAI,KAAK,YACP;AAIF,MAAI,KAAK,qBAAqB;AAE5B,WAAQ,uDAAuD;AAE/D,QAAK,sBAAsB;;AAI7B,OAAK,wBAAwB,KAAK,cAAc;AAEhD,MAAI;AACF,SAAM,KAAK;YACH;AAER,QAAK,wBAAwB;;;CAIjC,MAAc,eAA8B;EAC1C,MAAM,eAAe,MAAM,KAAK,KAAK,QAAQ,QAAQ,CAAC,CACnD,QAAO,WAAU,OAAO,WAAW,OAAO,WAAW,CACrD,IAAI,OAAM,WAAU;AACnB,OAAI;AACF,QAAI,OAAO,WACT,OAAM,OAAO,YAAY;AAE3B,SAAK,UAAU,gBAAgB,OAAO;YAC/B,OAAO;AACd,aAAS,+BAA+B,OAAO,QAAQ;KACrD;KACA,YAAY,OAAO;KACpB,CAAC;AACF,SAAK,UAAU,UAAU,OAAgB,OAAO;AAEhD,UAAM;;IAER;AAEJ,MAAI;AACF,SAAM,QAAQ,IAAI,aAAa;AAC/B,QAAK,cAAc;WACZ,OAAO;AACd,QAAK,sBAAsB,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AACpF,SAAM,KAAK;;;;;;;CAQf,yBAAkC;AAChC,SAAO,KAAK,wBAAwB;;;;;;CAOtC,yBAAuC;AACrC,SAAO,KAAK;;;;;CAMd,MAAM,WAA0B;EAC9B,MAAM,mBAAmB,MAAM,KAAK,KAAK,QAAQ,QAAQ,CAAC,CACvD,QAAO,WAAU,OAAO,SAAS,CACjC,IAAI,OAAM,WAAU;AACnB,OAAI;AACF,QAAI,OAAO,SACT,OAAM,OAAO,UAAU;AAEzB,SAAK,UAAU,aAAa,OAAO;YAC5B,OAAO;AACd,aAAS,6BAA6B,OAAO,QAAQ;KAAE;KAAO,YAAY,OAAO;KAAM,CAAC;AACxF,SAAK,UAAU,UAAU,OAAgB,OAAO;;IAElD;AAEJ,QAAM,QAAQ,WAAW,iBAAiB;AAC1C,OAAK,cAAc;;;;;;;;CASrB,iBAAiB,OAAwB,SAAsC;AAC7E,OAAK,WAAU,WAAU,OAAO,iBAAiB,OAAO,QAAQ,CAAC;;;;;;;;;CAUnE,eAAe,SAAiB,QAAkB,QAAQ,SAAsC;AAC9F,OAAK,WAAU,WAAU,OAAO,eAAe,SAAS,OAAO,QAAQ,CAAC;;;;;;;CAQ1E,AAAQ,aAAa,MAA0D;AAC7E,MAAI,CAAC,KAAM,QAAO;EAGlB,MAAM,KAAK,OAAO,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI;AAC/C,MAAI,CAAC,IAAI;AAEP,WAAQ,6DAA6D;AACrE,UAAO;;EAGT,MAAM,YAA+B,EAAE,IAAI;AAG3C,MAAI,WAAW,QAAQ,KAAK,OAAO;GACjC,MAAM,QAAQ,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI;AAIrD,OACE,SAEA,uIAAuI,KACrI,MACD,CAED,WAAU,QAAQ;;AAKtB,MAAI,cAAc,QAAQ,KAAK,UAAU;GACvC,MAAM,WAAW,OAAO,KAAK,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI;AAC3D,OAAI,SACF,WAAU,WAAW;;AAKzB,MAAI,gBAAgB,QAAQ,KAAK,YAAY;GAC3C,MAAM,KAAK,OAAO,KAAK,WAAW,CAAC,MAAM;GAGzC,MAAM,cAEJ,8FAA8F,KAC5F,GACD;GAEH,MAAM,gBACJ,kBAAkB,KAAK,GAAG,IAAI,GAAG,SAAS,IAAI,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU;AAE5E,OAAI,eAAe,cACjB,WAAU,aAAa,GAAG,MAAM,GAAG,GAAG;;AAI1C,SAAO;;;;;;;CAQT,QAAQ,MAAsC;EAC5C,MAAM,gBAAgB,KAAK,aAAa,KAAK;AAC7C,OAAK,WAAU,WAAU,OAAO,QAAQ,cAAc,CAAC;;;;;;;CAQzD,cAAc,YAA8B;AAC1C,OAAK,WAAU,WAAU,OAAO,cAAc,WAAW,CAAC;;;;;;;CAQ5D,UAAU,UAAqD;AAC7D,OAAK,WAAU,WAAU,OAAO,UAAU,SAAS,CAAC;;;;;;;;;;CAWtD,MAAM,MAAM,SAAoC;EAC9C,MAAM,gBAAgB,MAAM,KAAK,KAAK,QAAQ,QAAQ,CAAC,CACpD,QAAQ,WAAgD;AACvD,UAAO,OAAO,WAAW,WAAW,UAAU,OAAO,OAAO,UAAU;IACtE,CACD,KAAI,WAAU,OAAO,MAAM,QAAQ,CAAC;AAEvC,MAAI,cAAc,WAAW,EAC3B,QAAO;AAIT,UADgB,MAAM,QAAQ,WAAW,cAAc,EACxC,OAAM,WAAU,OAAO,WAAW,eAAe,OAAO,UAAU,KAAK;;;;;;CAOxF,AAAQ,UAAU,IAAiD;AACjE,OAAK,QAAQ,SAAQ,WAAU;AAC7B,OAAI,OAAO,QACT,KAAI;AACF,OAAG,OAAO;YACH,OAAO;AAEd,QAAI;AACF,cAAS,UAAU,OAAO,KAAK,SAAS;MAAE;MAAO,YAAY,OAAO;MAAM,CAAC;YACrE;AAIR,QAAI;AACF,UAAK,UAAU,UAAU,OAAgB,OAAO;YAC1C;;IAKZ;;;;;;;CAQJ,oBAA6B;AAC3B,SAAO,MAAM,KAAK,KAAK,QAAQ,QAAQ,CAAC,CAAC,MAAK,WAAU,OAAO,QAAQ;;;;;;;CAQzE,wBAAkC;AAChC,SAAO,MAAM,KAAK,KAAK,QAAQ,QAAQ,CAAC,CACrC,QAAO,WAAU,OAAO,QAAQ,CAChC,KAAI,WAAU,OAAO,KAAK;;;;;;;;;;;;;ACpVjC,IAAa,uBAAb,MAAa,qBAAqB;CAChC,AAAQ,UAA+D,EAAE;CACzE,AAAQ,YAA6B,EAAE;CACvC,AAAQ,iBAAiB;;;;;;CAOzB,WAAW,QAA+D;AACxE,MAAI,OACF,MAAK,QAAQ,KAAK,OAAO;AAE3B,SAAO;;;;;;;CAQT,YAAY,SAAoE;AAC9E,MAAI,WAAW,MAAM,QAAQ,QAAQ,EAAE;GACrC,MAAM,eAAe,QAAQ,QAAO,WAAU,UAAU,KAAK;AAC7D,QAAK,QAAQ,KAAK,GAAG,aAAa;;AAEpC,SAAO;;;;;;;CAQT,cAAc,WAAkC;AAC9C,OAAK,YAAY;GAAE,GAAG,KAAK;GAAW,GAAG;GAAW;AACpD,SAAO;;;;;CAMT,mBAAmB,gBAA+B;AAChD,OAAK,iBAAiB;AACtB,SAAO;;;;;;CAOT,QAA8B;EAC5B,MAAM,UAAU,IAAI,qBAAqB,KAAK,UAAU;AAGxD,OAAK,QAAQ,SAAQ,WAAU,QAAQ,UAAU,OAAO,CAAC;AAGzD,MACE,KAAK,kBACL,OAAO,YAAY,eACnB,QAAQ,IAAI,iBAAiB,OAG7B,EAAM,YAAY;AAChB,OAAI;AACF,UAAM,QAAQ,YAAY;YACnB,OAAO;AAKd,QAAI;AACF,cAAS,sCAAsC,EAAE,OAAO,CAAC;YACnD;;MAIR;AAGN,SAAO;;;;;;CAOT,MAAM,oBAAmD;EACvD,MAAM,UAAU,IAAI,qBAAqB,KAAK,UAAU;AAGxD,OAAK,QAAQ,SAAQ,WAAU,QAAQ,UAAU,OAAO,CAAC;AAGzD,MAAI;AACF,SAAM,QAAQ,YAAY;UACpB;AAKR,SAAO;;;;;;CAOT,OAAO,SAA+B;AACpC,SAAO,IAAI,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;AChGrC,SAAgB,oBACd,SACA,SAGsB;CACtB,MAAM,UAAU,IAAI,sBAAsB;AAE1C,KAAI,SAAS,mBAAmB,OAC9B,SAAQ,mBAAmB,QAAQ,eAAe;AAGpD,QAAO,QAAQ,YAAY,QAAQ,CAAC,OAAO"}
|
package/plugin-CP895lBx.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-CP895lBx.mjs","names":[],"sources":["../src/plugins/sentry/plugin.ts"],"sourcesContent":["/**\n * @fileoverview Sentry plugin implementation\n * Sentry plugin implementation\n */\n\nimport { logDebug, logError, logWarn } from '@repo/shared/logger';\nimport type { ObservabilityServerPlugin } from '../../core/plugin';\nimport type {\n Breadcrumb,\n LogLevel,\n ObservabilityContext,\n ObservabilityUser,\n} from '../../core/types';\nimport { isBrowser } from '../../shared';\nimport { safeEnv } from './env';\nimport type { Hub, Scope, Span, SpanContext, Transaction, TransactionContext } from './types';\n\n/**\n * Default log filter function that filters out noisy development logs.\n * Filters out:\n * - Next.js Fast Refresh messages\n * - HMR (Hot Module Replacement) messages\n * - Prisma query logs (server-only)\n * - Prisma engine/info logs\n * - SQL queries matching Prisma's format\n *\n * Handles ANSI color codes, console formatting (%c, %s), and CSS styling.\n *\n * @param log - The log entry from Sentry\n * @param isServer - Whether this is running on the server (defaults to true)\n * @returns The log entry if it should be sent, or null to filter it out\n */\nexport function defaultBeforeSendLog(log: any, isServer = true): any | null {\n // Check both message and any formatted message fields\n const messageToCheck = log.message || log.formatted || '';\n if (!messageToCheck) {\n return log; // No message to filter, send as-is\n }\n\n const message = String(messageToCheck);\n\n // Remove ANSI color codes for comparison (e.g., \\u001b[34mprisma:query\\u001b[39m)\n // Also handle %c format codes used by console styling and %s placeholders\n const messageWithoutAnsi = message\n .replace(/\\u001b\\[[0-9;]*m/g, '') // Remove ANSI escape codes\n .replace(/%[csdfiO]/g, '') // Remove console format placeholders (%c, %s, %d, %f, %i, %o)\n .replace(/background:[^;]+;?/g, '') // Remove CSS background styles\n .replace(/color:[^;]+;?/g, '') // Remove CSS color styles\n .replace(/border-radius:[^;]+;?/g, '') // Remove CSS border-radius\n .replace(/light-dark\\([^)]+\\)/g, '') // Remove light-dark() CSS functions\n .replace(/rgba?\\([^)]+\\)/g, '') // Remove rgba/rgb color functions\n .replace(/#[0-9a-fA-F]{3,8}/g, '') // Remove hex colors\n .toLowerCase(); // Case-insensitive matching\n\n // Filter out Next.js Fast Refresh and HMR messages (both client and server)\n if (messageWithoutAnsi.includes('[fast refresh]') || messageWithoutAnsi.includes('[hmr]')) {\n return null; // Drop the log\n }\n\n // Filter out Prisma logs (server-only)\n if (isServer) {\n if (\n messageWithoutAnsi.includes('prisma:query') ||\n messageWithoutAnsi.includes('prisma:engine') ||\n messageWithoutAnsi.includes('prisma:info') ||\n // Also filter SQL queries that look like Prisma queries (SELECT ... FROM \"public\".)\n (messageWithoutAnsi.includes('select') &&\n messageWithoutAnsi.includes('from') &&\n (messageWithoutAnsi.includes('\"public\".') || messageWithoutAnsi.includes('public.')))\n ) {\n return null; // Drop the log\n }\n }\n\n return log; // Send the log\n}\n\n/**\n * Minimal Sentry interface for common methods across all Sentry packages\n */\ninterface SentryClient {\n init(options: any): void;\n captureException(error: any, captureContext?: any): string;\n captureMessage(message: string, captureContext?: any): string;\n setUser(user: any): void;\n addBreadcrumb(breadcrumb: any): void;\n withScope(callback: (scope: any) => void): void;\n getCurrentScope?(): any;\n getActiveTransaction?(): any;\n startTransaction?(context: TransactionContext, customSamplingContext?: any): any;\n startSpan?(context: SpanContext): any;\n configureScope?(callback: (scope: any) => void): void;\n getCurrentHub?(): any;\n flush?(timeout?: number): Promise<boolean>;\n close?(timeout?: number): Promise<boolean>;\n browserTracingIntegration?(): any;\n replayIntegration?(): any;\n profilesIntegration?(): any;\n consoleLoggingIntegration?(options?: { levels?: string[] }): any;\n logger?: {\n trace(message: string, attributes?: Record<string, unknown>): void;\n debug(message: string, attributes?: Record<string, unknown>): void;\n info(message: string, attributes?: Record<string, unknown>): void;\n warn(message: string, attributes?: Record<string, unknown>): void;\n error(message: string, attributes?: Record<string, unknown>): void;\n fatal(message: string, attributes?: Record<string, unknown>): void;\n fmt(strings: TemplateStringsArray, ...values: unknown[]): string;\n };\n}\n\n/**\n * Sentry plugin configuration\n */\nexport interface SentryPluginConfig {\n /**\n * The Sentry package to use (e.g., '@sentry/node', '@sentry/browser', '@sentry/nextjs')\n * If not provided, the plugin will try to detect based on environment\n */\n sentryPackage?: string;\n\n // Core Sentry options\n dsn?: string;\n environment?: string;\n release?: string;\n enabled?: boolean;\n debug?: boolean;\n\n // Sampling rates\n tracesSampleRate?: number;\n profilesSampleRate?: number;\n replaysSessionSampleRate?: number;\n replaysOnErrorSampleRate?: number;\n\n // Integrations and hooks\n integrations?: any[];\n beforeSend?: (event: any, hint: any) => any;\n beforeSendTransaction?: (event: any, hint: any) => any;\n beforeBreadcrumb?: (breadcrumb: any, hint?: any) => any;\n beforeSendLog?: (log: any) => any;\n\n // Logging options\n enableLogs?: boolean;\n consoleLoggingIntegration?: {\n levels?: ('log' | 'warn' | 'error' | 'debug' | 'info' | 'assert' | 'trace')[];\n };\n\n // Trace propagation\n tracePropagationTargets?: (string | RegExp)[];\n\n // Other options\n initialScope?: any;\n maxBreadcrumbs?: number;\n attachStacktrace?: boolean;\n autoSessionTracking?: boolean;\n sendDefaultPii?: boolean;\n}\n\n/**\n * Sentry plugin implementation\n */\n/**\n * Sentry plugin implementation.\n *\n * Integrates Sentry error tracking and performance monitoring into the observability system.\n * Auto-detects the appropriate Sentry package (@sentry/node, @sentry/browser, @sentry/nextjs)\n * based on the runtime environment.\n */\nexport class SentryPlugin<\n T extends SentryClient = SentryClient,\n> implements ObservabilityServerPlugin<T> {\n name = 'sentry';\n enabled: boolean;\n protected client: T | undefined;\n protected initialized = false;\n protected sentryPackage: string;\n protected config: SentryPluginConfig;\n\n /**\n * Create a new SentryPlugin instance.\n *\n * @param config - Sentry plugin configuration\n */\n constructor(config: SentryPluginConfig = {}) {\n this.config = config;\n const env = safeEnv();\n // Auto-enable if DSN is provided\n const hasDSN = config.dsn ?? env.SENTRY_DSN ?? env.NEXT_PUBLIC_SENTRY_DSN;\n this.enabled = config.enabled ?? Boolean(hasDSN);\n\n // Determine Sentry package to use\n this.sentryPackage = config.sentryPackage ?? this.detectSentryPackage();\n }\n\n /**\n * Detect which Sentry package to use based on the runtime environment.\n *\n * @returns Package name ('@sentry/node', '@sentry/browser', or '@sentry/nextjs')\n */\n private detectSentryPackage(): string {\n if (isBrowser()) {\n return '@sentry/browser';\n } else if (process.env.NEXT_RUNTIME === 'edge') {\n return '@sentry/nextjs'; // Next.js edge uses same package\n } else if (process.env.NEXT_RUNTIME) {\n return '@sentry/nextjs';\n } else {\n return '@sentry/node';\n }\n }\n\n getClient(): T | undefined {\n return this.client;\n }\n\n /**\n * Get safe environment access (for testing/mocking).\n *\n * @returns Environment configuration object\n */\n protected getSafeEnv() {\n return safeEnv();\n }\n\n async initialize(config?: SentryPluginConfig): Promise<void> {\n if (this.initialized || !this.enabled) return;\n\n const env = safeEnv();\n const mergedConfig = { ...this.config, ...config };\n\n // Check for DSN\n const dsn = mergedConfig.dsn ?? env.SENTRY_DSN ?? env.NEXT_PUBLIC_SENTRY_DSN;\n if (!dsn) {\n logWarn('Sentry plugin: No DSN provided, skipping initialization');\n this.enabled = false;\n return;\n }\n\n try {\n // Dynamic import of the specified Sentry package\n this.client = (await import(/* webpackIgnore: true */ this.sentryPackage)) as T;\n\n if (this.client && this.enabled) {\n // Build integrations array if not provided\n let { integrations } = mergedConfig;\n if (!integrations && this.client.browserTracingIntegration) {\n integrations = [];\n\n // Add browser tracing for performance monitoring\n if (\n mergedConfig.tracesSampleRate !== undefined ||\n env.SENTRY_TRACES_SAMPLE_RATE !== undefined\n ) {\n integrations.push(this.client.browserTracingIntegration());\n }\n\n // Add replay integration if configured\n if (\n this.client.replayIntegration &&\n (mergedConfig.replaysSessionSampleRate !== undefined ||\n env.SENTRY_REPLAYS_SESSION_SAMPLE_RATE !== undefined)\n ) {\n integrations.push(this.client.replayIntegration());\n }\n\n // Add profiling if configured\n if (\n this.client.profilesIntegration &&\n (mergedConfig.profilesSampleRate !== undefined ||\n env.SENTRY_PROFILES_SAMPLE_RATE !== undefined)\n ) {\n integrations.push(this.client.profilesIntegration());\n }\n }\n\n // Add console logging integration if logs are enabled\n const enableLogs = mergedConfig.enableLogs ?? true;\n if (enableLogs && this.client.consoleLoggingIntegration) {\n const consoleLoggingConfig = mergedConfig.consoleLoggingIntegration || {\n levels: ['log', 'warn', 'error'],\n };\n if (!integrations) {\n integrations = [];\n }\n integrations.push(this.client.consoleLoggingIntegration(consoleLoggingConfig));\n }\n\n this.client.init({\n dsn,\n environment: mergedConfig.environment ?? env.SENTRY_ENVIRONMENT ?? process.env.NODE_ENV,\n release: mergedConfig.release ?? env.SENTRY_RELEASE,\n debug: mergedConfig.debug ?? env.SENTRY_DEBUG,\n\n // Enable logs to be sent to Sentry\n enableLogs,\n\n // Sampling rates\n tracesSampleRate: mergedConfig.tracesSampleRate ?? env.SENTRY_TRACES_SAMPLE_RATE,\n profilesSampleRate: mergedConfig.profilesSampleRate ?? env.SENTRY_PROFILES_SAMPLE_RATE,\n replaysSessionSampleRate:\n mergedConfig.replaysSessionSampleRate ?? env.SENTRY_REPLAYS_SESSION_SAMPLE_RATE,\n replaysOnErrorSampleRate:\n mergedConfig.replaysOnErrorSampleRate ?? env.SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE,\n\n // Integrations and hooks\n integrations,\n beforeSend: mergedConfig.beforeSend,\n beforeSendTransaction: mergedConfig.beforeSendTransaction,\n // Use provided beforeSendLog, or default filter if logs are enabled and no custom filter provided\n beforeSendLog:\n mergedConfig.beforeSendLog ||\n (enableLogs ? (log: any) => defaultBeforeSendLog(log, !isBrowser()) : undefined),\n\n // Other options\n tracePropagationTargets: mergedConfig.tracePropagationTargets,\n initialScope: mergedConfig.initialScope,\n maxBreadcrumbs: mergedConfig.maxBreadcrumbs,\n attachStacktrace: mergedConfig.attachStacktrace,\n autoSessionTracking: mergedConfig.autoSessionTracking,\n });\n\n this.initialized = true;\n }\n } catch (error) {\n logError(`Failed to import Sentry package '${this.sentryPackage}'`, { error });\n this.enabled = false;\n }\n }\n\n async shutdown(): Promise<void> {\n if (this.client && this.initialized) {\n // Use close if available, otherwise flush\n if (this.client.close) {\n await this.client.close();\n } else if (this.client.flush) {\n await this.client.flush();\n }\n this.initialized = false;\n }\n }\n\n /**\n * Clean up the plugin (alias for shutdown)\n */\n async cleanup(): Promise<void> {\n await this.shutdown();\n }\n\n captureException(error: Error | unknown, context?: ObservabilityContext): void {\n if (!this.enabled || !this.client) return;\n\n // Additional build-time guard to prevent errors during static generation\n if (typeof this.client.captureException !== 'function') {\n // During build/static generation, Sentry client may not be properly initialized\n // Fall back to logging in development\n if (process.env.NODE_ENV === 'development') {\n logError('[Sentry Fallback] Exception', { error });\n }\n return;\n }\n\n try {\n this.client.captureException(error, context);\n } catch (captureError) {\n // Graceful fallback if Sentry fails during build\n if (process.env.NODE_ENV === 'development') {\n logWarn('[Sentry Plugin] Failed to capture exception', { error: captureError });\n logError('[Sentry Fallback] Exception', { error });\n }\n }\n }\n\n captureMessage(message: string, level: LogLevel = 'info', context?: ObservabilityContext): void {\n if (!this.enabled || !this.client) return;\n\n // Prefer Sentry.logger if available (structured logs)\n if (this.client.logger) {\n try {\n const attributes: Record<string, unknown> | undefined = context\n ? ((context.extra as Record<string, unknown> | undefined) ??\n (context as Record<string, unknown>))\n : undefined;\n switch (level) {\n case 'debug':\n this.client.logger.debug(message, attributes);\n return;\n case 'info':\n this.client.logger.info(message, attributes);\n return;\n case 'warning':\n this.client.logger.warn(message, attributes);\n return;\n case 'error':\n this.client.logger.error(message, attributes);\n return;\n }\n } catch (error) {\n // Fall through to captureMessage if logger fails\n if (process.env.NODE_ENV === 'development') {\n logWarn('[Sentry Plugin] Failed to log via logger', { error });\n }\n }\n }\n\n // Fallback to captureMessage for compatibility\n // Additional build-time guard to prevent errors during static generation\n if (typeof this.client.captureMessage !== 'function') {\n // During build/static generation, Sentry client may not be properly initialized\n // Fall back to logging in development\n if (process.env.NODE_ENV === 'development') {\n if (level === 'error') {\n logError(`[Sentry Fallback] ${message}`);\n } else if (level === 'warning') {\n logWarn(`[Sentry Fallback] ${message}`);\n } else {\n logDebug(`[Sentry Fallback] ${message}`);\n }\n }\n return;\n }\n\n // Map our log levels to Sentry severity levels\n const sentryLevel =\n level === 'warning'\n ? 'warning'\n : level === 'error'\n ? 'error'\n : level === 'debug'\n ? 'debug'\n : 'info';\n\n try {\n // Build capture context from ObservabilityContext\n const captureContext = context\n ? {\n level: sentryLevel,\n extra: context.extra ?? context,\n tags: context.tags,\n }\n : sentryLevel;\n\n this.client.captureMessage(message, captureContext);\n } catch (error) {\n // Graceful fallback if Sentry fails during build\n if (process.env.NODE_ENV === 'development') {\n logWarn('[Sentry Plugin] Failed to capture message', { error });\n if (level === 'error') {\n logError(`[Sentry Fallback] ${message}`);\n } else if (level === 'warning') {\n logWarn(`[Sentry Fallback] ${message}`);\n } else {\n logDebug(`[Sentry Fallback] ${message}`);\n }\n }\n }\n }\n\n setUser(user: ObservabilityUser | null): void {\n if (!this.enabled || !this.client) return;\n this.client.setUser(user);\n }\n\n addBreadcrumb(breadcrumb: Breadcrumb): void {\n if (!this.enabled || !this.client) return;\n this.client.addBreadcrumb({\n ...breadcrumb,\n timestamp: breadcrumb.timestamp ?? Date.now() / 1000,\n });\n }\n\n withScope(callback: (scope: any) => void): void {\n if (!this.enabled || !this.client) return;\n this.client.withScope(callback);\n }\n\n /**\n * Start a new transaction\n */\n startTransaction(\n context: TransactionContext,\n customSamplingContext?: any,\n ): Transaction | undefined {\n if (!this.enabled || !this.client) return undefined;\n\n if (this.client.startTransaction) {\n return this.client.startTransaction(context, customSamplingContext);\n }\n\n // Fallback for older versions\n logWarn('startTransaction not available in this Sentry version');\n return undefined;\n }\n\n /**\n * Start a new span\n */\n startSpan(context: SpanContext): Span | undefined {\n if (!this.enabled || !this.client) return undefined;\n\n if (this.client.startSpan) {\n return this.client.startSpan(context);\n }\n\n // Try to create span from active transaction\n const transaction = this.getActiveTransaction();\n if (transaction?.startChild) {\n return transaction.startChild(context);\n }\n\n return undefined;\n }\n\n /**\n * Get the currently active transaction\n */\n getActiveTransaction(): Transaction | undefined {\n if (!this.enabled || !this.client) return undefined;\n\n if (this.client.getActiveTransaction) {\n return this.client.getActiveTransaction();\n }\n\n // Try to get from current scope\n if (this.client.getCurrentScope) {\n const scope = this.client.getCurrentScope();\n if (scope?.getTransaction) {\n return scope.getTransaction();\n }\n }\n\n return undefined;\n }\n\n /**\n * Configure the current scope\n */\n configureScope(callback: (scope: Scope) => void): void {\n if (!this.enabled || !this.client) return;\n\n if (this.client.configureScope) {\n this.client.configureScope(callback);\n } else if (this.client.withScope) {\n // Fallback using withScope\n this.client.withScope(callback);\n }\n }\n\n /**\n * Get the current hub instance\n */\n getCurrentHub(): Hub | undefined {\n if (!this.enabled || !this.client) return undefined;\n\n if (this.client.getCurrentHub) {\n return this.client.getCurrentHub();\n }\n\n return undefined;\n }\n\n /**\n * Set a measurement on the active transaction\n */\n setMeasurement(name: string, value: number, unit?: string): void {\n if (!this.enabled || !this.client) return;\n\n const transaction = this.getActiveTransaction();\n if (transaction?.setMeasurement) {\n transaction.setMeasurement(name, value, unit);\n }\n }\n\n /**\n * Add performance entries as breadcrumbs and measurements\n */\n addPerformanceEntries(\n entries: Array<{\n entryType: string;\n name: string;\n startTime: number;\n duration: number;\n [key: string]: unknown;\n }>,\n ): void {\n if (!this.enabled || !this.client) return;\n\n const transaction = this.getActiveTransaction();\n\n entries.forEach(entry => {\n // Add as breadcrumb for context\n this.addBreadcrumb({\n category: 'performance',\n message: `${entry.entryType}: ${entry.name}`,\n data: {\n name: entry.name,\n duration: entry.duration,\n startTime: entry.startTime,\n ...(entry.entryType === 'navigation' && {\n transferSize: (entry as { transferSize?: number }).transferSize,\n encodedBodySize: (entry as { encodedBodySize?: number }).encodedBodySize,\n decodedBodySize: (entry as { decodedBodySize?: number }).decodedBodySize,\n }),\n ...(entry.entryType === 'resource' && {\n initiatorType: (entry as { initiatorType?: string }).initiatorType,\n transferSize: (entry as { transferSize?: number }).transferSize,\n }),\n },\n });\n\n // Add measurements for key metrics\n if (transaction && entry.entryType === 'navigation') {\n const navEntry = entry as unknown as {\n responseStart?: number;\n fetchStart?: number;\n domInteractive?: number;\n domComplete?: number;\n loadEventEnd?: number;\n transferSize?: number;\n encodedBodySize?: number;\n decodedBodySize?: number;\n [key: string]: unknown;\n };\n\n // Core Web Vitals and other metrics\n const fetchStart = navEntry.fetchStart ?? 0;\n if (navEntry.responseStart !== undefined) {\n this.setMeasurement('fcp', navEntry.responseStart - fetchStart, 'millisecond');\n }\n if (navEntry.domInteractive !== undefined) {\n this.setMeasurement(\n 'dom_interactive',\n navEntry.domInteractive - fetchStart,\n 'millisecond',\n );\n }\n if (navEntry.domComplete !== undefined) {\n this.setMeasurement('dom_complete', navEntry.domComplete - fetchStart, 'millisecond');\n }\n if (navEntry.loadEventEnd !== undefined) {\n this.setMeasurement('load_event_end', navEntry.loadEventEnd - fetchStart, 'millisecond');\n }\n }\n });\n }\n\n /**\n * Record a Web Vital measurement\n */\n recordWebVital(\n name: 'FCP' | 'LCP' | 'FID' | 'CLS' | 'TTFB' | 'INP' | string,\n value: number,\n options?: {\n unit?: string;\n rating?: 'good' | 'needs-improvement' | 'poor';\n },\n ): void {\n if (!this.enabled || !this.client) return;\n\n const { unit = 'millisecond', rating } = options ?? {};\n const transaction = this.getActiveTransaction();\n\n if (transaction) {\n // Set the measurement\n transaction.setMeasurement(name.toLowerCase(), value, unit);\n\n // Add rating as tag if provided\n if (rating) {\n transaction.setTag(`webvital.${name.toLowerCase()}.rating`, rating);\n }\n\n // Also send as a standalone event for monitoring\n this.client.captureMessage(`Web Vital: ${name}`, {\n level: 'info',\n tags: {\n 'webvital.name': name,\n 'webvital.value': value,\n 'webvital.unit': unit,\n ...(rating && { 'webvital.rating': rating }),\n },\n contexts: {\n trace: {\n trace_id: transaction.traceId,\n span_id: transaction.spanId,\n },\n },\n });\n }\n }\n\n /**\n * Create a custom performance mark\n */\n mark(name: string, options?: { detail?: any }): void {\n if (!this.enabled) return;\n\n // Use Performance API if available\n if (typeof performance !== 'undefined' && performance.mark) {\n performance.mark(name, options);\n }\n\n // Also add as breadcrumb\n this.addBreadcrumb({\n category: 'performance.mark',\n message: name,\n data: options?.detail,\n timestamp: Date.now() / 1000,\n });\n }\n\n /**\n * Create a custom performance measure\n */\n measure(\n name: string,\n startMarkOrOptions?:\n | string\n | { start?: string; end?: string; duration?: number; detail?: unknown },\n endMark?: string,\n ): void {\n if (!this.enabled) return;\n\n // Use Performance API if available\n if (typeof performance !== 'undefined' && performance.measure) {\n if (typeof startMarkOrOptions === 'string') {\n performance.measure(name, startMarkOrOptions, endMark);\n } else if (startMarkOrOptions) {\n performance.measure(name, startMarkOrOptions);\n } else {\n // No options provided, create a simple measure\n performance.measure(name);\n }\n\n // Get the measure to record its duration\n const measures = performance.getEntriesByName(name, 'measure');\n const measure = measures[measures.length - 1];\n\n if (measure) {\n this.setMeasurement(name, measure.duration, 'millisecond');\n\n this.addBreadcrumb({\n category: 'performance.measure',\n message: name,\n data: {\n duration: measure.duration,\n startTime: measure.startTime,\n },\n timestamp: measure.startTime / 1000,\n });\n }\n }\n }\n\n /**\n * Log a trace message using Sentry.logger (if available).\n * Falls back to captureMessage if logger is not available.\n *\n * @param message - Trace message to log\n * @param attributes - Optional attributes to include with the log\n */\n logTrace(message: string, attributes?: Record<string, unknown>): void {\n if (!this.enabled || !this.client) return;\n\n if (this.client.logger?.trace) {\n try {\n this.client.logger.trace(message, attributes);\n return;\n } catch (error) {\n if (process.env.NODE_ENV === 'development') {\n logWarn('[Sentry Plugin] Failed to log trace', { error });\n }\n }\n }\n\n // Fallback to captureMessage\n this.captureMessage(message, 'debug', attributes);\n }\n\n /**\n * Log a debug message using Sentry.logger (if available).\n * Falls back to captureMessage if logger is not available.\n *\n * @param message - Debug message to log\n * @param attributes - Optional attributes to include with the log\n */\n logDebug(message: string, attributes?: Record<string, unknown>): void {\n if (!this.enabled || !this.client) return;\n\n if (this.client.logger?.debug) {\n try {\n this.client.logger.debug(message, attributes);\n return;\n } catch (error) {\n if (process.env.NODE_ENV === 'development') {\n logWarn('[Sentry Plugin] Failed to log debug', { error });\n }\n }\n }\n\n // Fallback to captureMessage\n this.captureMessage(message, 'debug', attributes);\n }\n\n /**\n * Log an info message using Sentry.logger (if available).\n * Falls back to captureMessage if logger is not available.\n *\n * @param message - Info message to log\n * @param attributes - Optional attributes to include with the log\n */\n logInfo(message: string, attributes?: Record<string, unknown>): void {\n if (!this.enabled || !this.client) return;\n\n if (this.client.logger?.info) {\n try {\n this.client.logger.info(message, attributes);\n return;\n } catch (error) {\n if (process.env.NODE_ENV === 'development') {\n logWarn('[Sentry Plugin] Failed to log info', { error });\n }\n }\n }\n\n // Fallback to captureMessage\n this.captureMessage(message, 'info', attributes);\n }\n\n /**\n * Log a warning message using Sentry.logger (if available).\n * Falls back to captureMessage if logger is not available.\n *\n * @param message - Warning message to log\n * @param attributes - Optional attributes to include with the log\n */\n logWarn(message: string, attributes?: Record<string, unknown>): void {\n if (!this.enabled || !this.client) return;\n\n if (this.client.logger?.warn) {\n try {\n this.client.logger.warn(message, attributes);\n return;\n } catch (error) {\n if (process.env.NODE_ENV === 'development') {\n logWarn('[Sentry Plugin] Failed to log warn', { error });\n }\n }\n }\n\n // Fallback to captureMessage\n this.captureMessage(message, 'warning', attributes);\n }\n\n /**\n * Log an error message using Sentry.logger (if available).\n * Falls back to captureMessage if logger is not available.\n *\n * @param message - Error message to log\n * @param attributes - Optional attributes to include with the log\n */\n logError(message: string, attributes?: Record<string, unknown>): void {\n if (!this.enabled || !this.client) return;\n\n if (this.client.logger?.error) {\n try {\n this.client.logger.error(message, attributes);\n return;\n } catch (error) {\n if (process.env.NODE_ENV === 'development') {\n logWarn('[Sentry Plugin] Failed to log error', { error });\n }\n }\n }\n\n // Fallback to captureMessage\n this.captureMessage(message, 'error', attributes);\n }\n\n /**\n * Log a fatal message using Sentry.logger (if available).\n * Falls back to captureMessage if logger is not available.\n *\n * @param message - Fatal message to log\n * @param attributes - Optional attributes to include with the log\n */\n logFatal(message: string, attributes?: Record<string, unknown>): void {\n if (!this.enabled || !this.client) return;\n\n if (this.client.logger?.fatal) {\n try {\n this.client.logger.fatal(message, attributes);\n return;\n } catch (error) {\n if (process.env.NODE_ENV === 'development') {\n logWarn('[Sentry Plugin] Failed to log fatal', { error });\n }\n }\n }\n\n // Fallback to captureMessage with error level\n this.captureMessage(message, 'error', attributes);\n }\n\n /**\n * Get the Sentry.logger instance if available.\n * This allows direct access to Sentry.logger APIs including fmt.\n *\n * @returns Sentry.logger instance or undefined if not available\n *\n * @example\n * ```typescript\n * const logger = sentryPlugin.getLogger();\n * if (logger) {\n * logger.info(logger.fmt`User ${user.id} logged in`);\n * }\n * ```\n */\n getLogger(): SentryClient['logger'] | undefined {\n if (!this.enabled || !this.client) return undefined;\n return this.client.logger;\n }\n\n async flush(timeout?: number): Promise<boolean> {\n if (!this.enabled || !this.client || !this.client.flush) return true;\n try {\n return await this.client.flush(timeout);\n } catch (_error) {\n return false;\n }\n }\n}\n\n/**\n * Factory function to create a Sentry plugin.\n *\n * Creates a configured SentryPlugin instance with optional configuration.\n * Auto-detects the appropriate Sentry package based on the environment.\n *\n * @param config - Optional Sentry plugin configuration\n * @returns SentryPlugin instance\n *\n * @example\n * ```typescript\n * const sentry = createSentryPlugin({\n * dsn: 'https://...',\n * environment: 'production',\n * tracesSampleRate: 0.1,\n * });\n * ```\n */\nexport const createSentryPlugin = <T extends SentryClient = SentryClient>(\n config?: SentryPluginConfig,\n): SentryPlugin<T> => {\n return new SentryPlugin<T>(config);\n};\n"],"mappings":"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"}
|