@sentry/core
Version:
Base implementation for all Sentry JavaScript SDKs
157 lines (125 loc) • 5.25 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const currentScopes = require('./currentScopes.js');
const debugBuild = require('./debug-build.js');
const logger = require('./utils-hoist/logger.js');
const installedIntegrations = [];
/** Map of integrations assigned to a client */
/**
* Remove duplicates from the given array, preferring the last instance of any duplicate. Not guaranteed to
* preserve the order of integrations in the array.
*
* @private
*/
function filterDuplicates(integrations) {
const integrationsByName = {};
integrations.forEach((currentInstance) => {
const { name } = currentInstance;
const existingInstance = integrationsByName[name];
// We want integrations later in the array to overwrite earlier ones of the same type, except that we never want a
// default instance to overwrite an existing user instance
if (existingInstance && !existingInstance.isDefaultInstance && currentInstance.isDefaultInstance) {
return;
}
integrationsByName[name] = currentInstance;
});
return Object.values(integrationsByName);
}
/** Gets integrations to install */
function getIntegrationsToSetup(options) {
const defaultIntegrations = options.defaultIntegrations || [];
const userIntegrations = options.integrations;
// We flag default instances, so that later we can tell them apart from any user-created instances of the same class
defaultIntegrations.forEach((integration) => {
integration.isDefaultInstance = true;
});
let integrations;
if (Array.isArray(userIntegrations)) {
integrations = [...defaultIntegrations, ...userIntegrations];
} else if (typeof userIntegrations === 'function') {
const resolvedUserIntegrations = userIntegrations(defaultIntegrations);
integrations = Array.isArray(resolvedUserIntegrations) ? resolvedUserIntegrations : [resolvedUserIntegrations];
} else {
integrations = defaultIntegrations;
}
return filterDuplicates(integrations);
}
/**
* Given a list of integration instances this installs them all. When `withDefaults` is set to `true` then all default
* integrations are added unless they were already provided before.
* @param integrations array of integration instances
* @param withDefault should enable default integrations
*/
function setupIntegrations(client, integrations) {
const integrationIndex = {};
integrations.forEach((integration) => {
// guard against empty provided integrations
if (integration) {
setupIntegration(client, integration, integrationIndex);
}
});
return integrationIndex;
}
/**
* Execute the `afterAllSetup` hooks of the given integrations.
*/
function afterSetupIntegrations(client, integrations) {
for (const integration of integrations) {
// guard against empty provided integrations
if (integration?.afterAllSetup) {
integration.afterAllSetup(client);
}
}
}
/** Setup a single integration. */
function setupIntegration(client, integration, integrationIndex) {
if (integrationIndex[integration.name]) {
debugBuild.DEBUG_BUILD && logger.logger.log(`Integration skipped because it was already installed: ${integration.name}`);
return;
}
integrationIndex[integration.name] = integration;
// `setupOnce` is only called the first time
if (installedIntegrations.indexOf(integration.name) === -1 && typeof integration.setupOnce === 'function') {
integration.setupOnce();
installedIntegrations.push(integration.name);
}
// `setup` is run for each client
if (integration.setup && typeof integration.setup === 'function') {
integration.setup(client);
}
if (typeof integration.preprocessEvent === 'function') {
const callback = integration.preprocessEvent.bind(integration) ;
client.on('preprocessEvent', (event, hint) => callback(event, hint, client));
}
if (typeof integration.processEvent === 'function') {
const callback = integration.processEvent.bind(integration) ;
const processor = Object.assign((event, hint) => callback(event, hint, client), {
id: integration.name,
});
client.addEventProcessor(processor);
}
debugBuild.DEBUG_BUILD && logger.logger.log(`Integration installed: ${integration.name}`);
}
/** Add an integration to the current scope's client. */
function addIntegration(integration) {
const client = currentScopes.getClient();
if (!client) {
debugBuild.DEBUG_BUILD && logger.logger.warn(`Cannot add integration "${integration.name}" because no SDK Client is available.`);
return;
}
client.addIntegration(integration);
}
/**
* Define an integration function that can be used to create an integration instance.
* Note that this by design hides the implementation details of the integration, as they are considered internal.
*/
function defineIntegration(fn) {
return fn;
}
exports.addIntegration = addIntegration;
exports.afterSetupIntegrations = afterSetupIntegrations;
exports.defineIntegration = defineIntegration;
exports.getIntegrationsToSetup = getIntegrationsToSetup;
exports.installedIntegrations = installedIntegrations;
exports.setupIntegration = setupIntegration;
exports.setupIntegrations = setupIntegrations;
//# sourceMappingURL=integration.js.map