{"version":3,"file":"integration.js","sources":["../../src/integration.ts"],"sourcesContent":["import type { Client } from './client';\nimport { getClient } from './currentScopes';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { Event, EventHint } from './types/event';\nimport type { Integration, IntegrationFn } from './types/integration';\nimport type { CoreOptions } from './types/options';\nimport type { StreamedSpanJSON } from './types/span';\nimport { debug } from './utils/debug-logger';\n\nexport const installedIntegrations: string[] = [];\n\n/** Map of integrations assigned to a client */\nexport type IntegrationIndex = {\n [key: string]: Integration;\n};\n\ntype IntegrationWithDefaultInstance = Integration & { isDefaultInstance?: true };\n\n/**\n * Remove duplicates from the given array, preferring the last instance of any duplicate. Not guaranteed to\n * preserve the order of integrations in the array.\n *\n * @private\n */\nfunction filterDuplicates(integrations: Integration[]): Integration[] {\n const integrationsByName: { [key: string]: Integration } = {};\n\n integrations.forEach((currentInstance: IntegrationWithDefaultInstance) => {\n const { name } = currentInstance;\n\n const existingInstance: IntegrationWithDefaultInstance | undefined = integrationsByName[name];\n\n // We want integrations later in the array to overwrite earlier ones of the same type, except that we never want a\n // default instance to overwrite an existing user instance\n if (existingInstance && !existingInstance.isDefaultInstance && currentInstance.isDefaultInstance) {\n return;\n }\n\n integrationsByName[name] = currentInstance;\n });\n\n return Object.values(integrationsByName);\n}\n\n/** Gets integrations to install */\nexport function getIntegrationsToSetup(\n options: Pick,\n): Integration[] {\n const defaultIntegrations = options.defaultIntegrations || [];\n const userIntegrations = options.integrations;\n\n // We flag default instances, so that later we can tell them apart from any user-created instances of the same class\n defaultIntegrations.forEach((integration: IntegrationWithDefaultInstance) => {\n integration.isDefaultInstance = true;\n });\n\n let integrations: Integration[];\n\n if (Array.isArray(userIntegrations)) {\n integrations = [...defaultIntegrations, ...userIntegrations];\n } else if (typeof userIntegrations === 'function') {\n const resolvedUserIntegrations = userIntegrations(defaultIntegrations);\n integrations = Array.isArray(resolvedUserIntegrations) ? resolvedUserIntegrations : [resolvedUserIntegrations];\n } else {\n integrations = defaultIntegrations;\n }\n\n return filterDuplicates(integrations);\n}\n\n/**\n * Given a list of integration instances this installs them all. When `withDefaults` is set to `true` then all default\n * integrations are added unless they were already provided before.\n * @param integrations array of integration instances\n * @param withDefault should enable default integrations\n */\nexport function setupIntegrations(client: Client, integrations: Integration[]): IntegrationIndex {\n const integrationIndex: IntegrationIndex = {};\n\n integrations.forEach((integration: Integration | undefined) => {\n if (integration?.beforeSetup) {\n integration.beforeSetup(client);\n }\n });\n\n integrations.forEach((integration: Integration | undefined) => {\n // guard against empty provided integrations\n if (integration) {\n setupIntegration(client, integration, integrationIndex);\n }\n });\n\n return integrationIndex;\n}\n\n/**\n * Execute the `afterAllSetup` hooks of the given integrations.\n */\nexport function afterSetupIntegrations(client: Client, integrations: Integration[]): void {\n for (const integration of integrations) {\n // guard against empty provided integrations\n if (integration?.afterAllSetup) {\n integration.afterAllSetup(client);\n }\n }\n}\n\n/** Setup a single integration. */\nexport function setupIntegration(client: Client, integration: Integration, integrationIndex: IntegrationIndex): void {\n if (integrationIndex[integration.name]) {\n DEBUG_BUILD && debug.log(`Integration skipped because it was already installed: ${integration.name}`);\n return;\n }\n integrationIndex[integration.name] = integration;\n\n // `setupOnce` is only called the first time\n if (!installedIntegrations.includes(integration.name) && typeof integration.setupOnce === 'function') {\n integration.setupOnce();\n installedIntegrations.push(integration.name);\n }\n\n // `setup` is run for each client\n if (integration.setup && typeof integration.setup === 'function') {\n integration.setup(client);\n }\n\n if (typeof integration.preprocessEvent === 'function') {\n const callback = integration.preprocessEvent.bind(integration) as typeof integration.preprocessEvent;\n client.on('preprocessEvent', (event, hint) => callback(event, hint, client));\n }\n\n if (typeof integration.processEvent === 'function') {\n const callback = integration.processEvent.bind(integration) as typeof integration.processEvent;\n\n const processor = Object.assign((event: Event, hint: EventHint) => callback(event, hint, client), {\n id: integration.name,\n });\n\n client.addEventProcessor(processor);\n }\n\n (['processSpan', 'processSegmentSpan'] as const).forEach(hook => {\n const callback = integration[hook];\n if (typeof callback === 'function') {\n // The cast is needed because TS can't resolve overloads when the discriminant is a union type.\n // Both overloads have the same callback signature so this is safe.\n client.on(hook as 'processSpan', (span: StreamedSpanJSON) => callback.call(integration, span, client));\n }\n });\n\n DEBUG_BUILD && debug.log(`Integration installed: ${integration.name}`);\n}\n\n/** Add an integration to the current scope's client. */\nexport function addIntegration(integration: Integration): void {\n const client = getClient();\n\n if (!client) {\n DEBUG_BUILD && debug.warn(`Cannot add integration \"${integration.name}\" because no SDK Client is available.`);\n return;\n }\n\n client.addIntegration(integration);\n}\n\n/**\n * Define an integration function that can be used to create an integration instance.\n * Note that this by design hides the implementation details of the integration, as they are considered internal.\n */\nexport function defineIntegration(fn: Fn): (...args: Parameters) => Integration {\n return fn;\n}\n"],"names":[],"mappings":"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"}