package.build.cjs.integration.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core Show documentation
Show all versions of core Show documentation
Base implementation for all Sentry JavaScript SDKs
Object.defineProperty(exports, '__esModule', { value: true });
const utils = require('@sentry/utils');
const currentScopes = require('./currentScopes.js');
const debugBuild = require('./debug-build.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') {
integrations = utils.arrayify(userIntegrations(defaultIntegrations));
} else {
integrations = defaultIntegrations;
}
const finalIntegrations = filterDuplicates(integrations);
// The `Debug` integration prints copies of the `event` and `hint` which will be passed to `beforeSend` or
// `beforeSendTransaction`. It therefore has to run after all other integrations, so that the changes of all event
// processors will be reflected in the printed values. For lack of a more elegant way to guarantee that, we therefore
// locate it and, assuming it exists, pop it out of its current spot and shove it onto the end of the array.
const debugIndex = finalIntegrations.findIndex(integration => integration.name === 'Debug');
if (debugIndex > -1) {
const [debugInstance] = finalIntegrations.splice(debugIndex, 1) ;
finalIntegrations.push(debugInstance);
}
return finalIntegrations;
}
/**
* 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 && integration.afterAllSetup) {
integration.afterAllSetup(client);
}
}
}
/** Setup a single integration. */
function setupIntegration(client, integration, integrationIndex) {
if (integrationIndex[integration.name]) {
debugBuild.DEBUG_BUILD && utils.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 && utils.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 && utils.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