summaryrefslogtreecommitdiff
path: root/shared/logger/node_modules/@sentry/core
diff options
context:
space:
mode:
Diffstat (limited to 'shared/logger/node_modules/@sentry/core')
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/api.js90
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/baseclient.js674
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/constants.js4
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/envelope.js74
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/exports.js193
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/hub.js564
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/integration.js112
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/integrations/functiontostring.js39
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/integrations/inboundfilters.js213
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/scope.js555
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/sdk.js35
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/session.js155
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/tracing/errors.js36
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/tracing/hubextensions.js241
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/tracing/idletransaction.js347
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/tracing/span.js378
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/tracing/trace.js78
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/tracing/transaction.js276
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/tracing/utils.js12
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/transports/base.js101
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/transports/multiplexed.js76
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/transports/offline.js122
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/utils/hasTracingEnabled.js23
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/utils/prepareEvent.js304
-rw-r--r--shared/logger/node_modules/@sentry/core/esm/version.js4
25 files changed, 4706 insertions, 0 deletions
diff --git a/shared/logger/node_modules/@sentry/core/esm/api.js b/shared/logger/node_modules/@sentry/core/esm/api.js
new file mode 100644
index 0000000..d8dd466
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/api.js
@@ -0,0 +1,90 @@
+import { makeDsn, dsnToString, urlEncode } from '@sentry/utils';
+
+const SENTRY_API_VERSION = '7';
+
+/** Returns the prefix to construct Sentry ingestion API endpoints. */
+function getBaseApiEndpoint(dsn) {
+ const protocol = dsn.protocol ? `${dsn.protocol}:` : '';
+ const port = dsn.port ? `:${dsn.port}` : '';
+ return `${protocol}//${dsn.host}${port}${dsn.path ? `/${dsn.path}` : ''}/api/`;
+}
+
+/** Returns the ingest API endpoint for target. */
+function _getIngestEndpoint(dsn) {
+ return `${getBaseApiEndpoint(dsn)}${dsn.projectId}/envelope/`;
+}
+
+/** Returns a URL-encoded string with auth config suitable for a query string. */
+function _encodedAuth(dsn, sdkInfo) {
+ return urlEncode({
+ // We send only the minimum set of required information. See
+ // https://github.com/getsentry/sentry-javascript/issues/2572.
+ sentry_key: dsn.publicKey,
+ sentry_version: SENTRY_API_VERSION,
+ ...(sdkInfo && { sentry_client: `${sdkInfo.name}/${sdkInfo.version}` }),
+ });
+}
+
+/**
+ * Returns the envelope endpoint URL with auth in the query string.
+ *
+ * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
+ */
+function getEnvelopeEndpointWithUrlEncodedAuth(
+ dsn,
+ // TODO (v8): Remove `tunnelOrOptions` in favor of `options`, and use the substitute code below
+ // options: ClientOptions = {} as ClientOptions,
+ tunnelOrOptions = {} ,
+) {
+ // TODO (v8): Use this code instead
+ // const { tunnel, _metadata = {} } = options;
+ // return tunnel ? tunnel : `${_getIngestEndpoint(dsn)}?${_encodedAuth(dsn, _metadata.sdk)}`;
+
+ const tunnel = typeof tunnelOrOptions === 'string' ? tunnelOrOptions : tunnelOrOptions.tunnel;
+ const sdkInfo =
+ typeof tunnelOrOptions === 'string' || !tunnelOrOptions._metadata ? undefined : tunnelOrOptions._metadata.sdk;
+
+ return tunnel ? tunnel : `${_getIngestEndpoint(dsn)}?${_encodedAuth(dsn, sdkInfo)}`;
+}
+
+/** Returns the url to the report dialog endpoint. */
+function getReportDialogEndpoint(
+ dsnLike,
+ dialogOptions
+
+,
+) {
+ const dsn = makeDsn(dsnLike);
+ if (!dsn) {
+ return '';
+ }
+
+ const endpoint = `${getBaseApiEndpoint(dsn)}embed/error-page/`;
+
+ let encodedOptions = `dsn=${dsnToString(dsn)}`;
+ for (const key in dialogOptions) {
+ if (key === 'dsn') {
+ continue;
+ }
+
+ if (key === 'user') {
+ const user = dialogOptions.user;
+ if (!user) {
+ continue;
+ }
+ if (user.name) {
+ encodedOptions += `&name=${encodeURIComponent(user.name)}`;
+ }
+ if (user.email) {
+ encodedOptions += `&email=${encodeURIComponent(user.email)}`;
+ }
+ } else {
+ encodedOptions += `&${encodeURIComponent(key)}=${encodeURIComponent(dialogOptions[key] )}`;
+ }
+ }
+
+ return `${endpoint}?${encodedOptions}`;
+}
+
+export { getEnvelopeEndpointWithUrlEncodedAuth, getReportDialogEndpoint };
+//# sourceMappingURL=api.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/baseclient.js b/shared/logger/node_modules/@sentry/core/esm/baseclient.js
new file mode 100644
index 0000000..d6e23b0
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/baseclient.js
@@ -0,0 +1,674 @@
+import { makeDsn, logger, checkOrSetAlreadyCaught, isPrimitive, resolvedSyncPromise, addItemToEnvelope, createAttachmentEnvelopeItem, SyncPromise, rejectedSyncPromise, SentryError, isThenable, isPlainObject } from '@sentry/utils';
+import { getEnvelopeEndpointWithUrlEncodedAuth } from './api.js';
+import { createEventEnvelope, createSessionEnvelope } from './envelope.js';
+import { setupIntegrations, setupIntegration } from './integration.js';
+import { updateSession } from './session.js';
+import { prepareEvent } from './utils/prepareEvent.js';
+
+const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured.";
+
+/**
+ * Base implementation for all JavaScript SDK clients.
+ *
+ * Call the constructor with the corresponding options
+ * specific to the client subclass. To access these options later, use
+ * {@link Client.getOptions}.
+ *
+ * If a Dsn is specified in the options, it will be parsed and stored. Use
+ * {@link Client.getDsn} to retrieve the Dsn at any moment. In case the Dsn is
+ * invalid, the constructor will throw a {@link SentryException}. Note that
+ * without a valid Dsn, the SDK will not send any events to Sentry.
+ *
+ * Before sending an event, it is passed through
+ * {@link BaseClient._prepareEvent} to add SDK information and scope data
+ * (breadcrumbs and context). To add more custom information, override this
+ * method and extend the resulting prepared event.
+ *
+ * To issue automatically created events (e.g. via instrumentation), use
+ * {@link Client.captureEvent}. It will prepare the event and pass it through
+ * the callback lifecycle. To issue auto-breadcrumbs, use
+ * {@link Client.addBreadcrumb}.
+ *
+ * @example
+ * class NodeClient extends BaseClient<NodeOptions> {
+ * public constructor(options: NodeOptions) {
+ * super(options);
+ * }
+ *
+ * // ...
+ * }
+ */
+class BaseClient {
+ /** Options passed to the SDK. */
+
+ /** The client Dsn, if specified in options. Without this Dsn, the SDK will be disabled. */
+
+ /** Array of set up integrations. */
+ __init() {this._integrations = {};}
+
+ /** Indicates whether this client's integrations have been set up. */
+ __init2() {this._integrationsInitialized = false;}
+
+ /** Number of calls being processed */
+ __init3() {this._numProcessing = 0;}
+
+ /** Holds flushable */
+ __init4() {this._outcomes = {};}
+
+ // eslint-disable-next-line @typescript-eslint/ban-types
+ __init5() {this._hooks = {};}
+
+ /**
+ * Initializes this client instance.
+ *
+ * @param options Options for the client.
+ */
+ constructor(options) {BaseClient.prototype.__init.call(this);BaseClient.prototype.__init2.call(this);BaseClient.prototype.__init3.call(this);BaseClient.prototype.__init4.call(this);BaseClient.prototype.__init5.call(this);
+ this._options = options;
+
+ if (options.dsn) {
+ this._dsn = makeDsn(options.dsn);
+ } else {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('No DSN provided, client will not do anything.');
+ }
+
+ if (this._dsn) {
+ const url = getEnvelopeEndpointWithUrlEncodedAuth(this._dsn, options);
+ this._transport = options.transport({
+ recordDroppedEvent: this.recordDroppedEvent.bind(this),
+ ...options.transportOptions,
+ url,
+ });
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
+ captureException(exception, hint, scope) {
+ // ensure we haven't captured this very object before
+ if (checkOrSetAlreadyCaught(exception)) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log(ALREADY_SEEN_ERROR);
+ return;
+ }
+
+ let eventId = hint && hint.event_id;
+
+ this._process(
+ this.eventFromException(exception, hint)
+ .then(event => this._captureEvent(event, hint, scope))
+ .then(result => {
+ eventId = result;
+ }),
+ );
+
+ return eventId;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ captureMessage(
+ message,
+ // eslint-disable-next-line deprecation/deprecation
+ level,
+ hint,
+ scope,
+ ) {
+ let eventId = hint && hint.event_id;
+
+ const promisedEvent = isPrimitive(message)
+ ? this.eventFromMessage(String(message), level, hint)
+ : this.eventFromException(message, hint);
+
+ this._process(
+ promisedEvent
+ .then(event => this._captureEvent(event, hint, scope))
+ .then(result => {
+ eventId = result;
+ }),
+ );
+
+ return eventId;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ captureEvent(event, hint, scope) {
+ // ensure we haven't captured this very object before
+ if (hint && hint.originalException && checkOrSetAlreadyCaught(hint.originalException)) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log(ALREADY_SEEN_ERROR);
+ return;
+ }
+
+ let eventId = hint && hint.event_id;
+
+ this._process(
+ this._captureEvent(event, hint, scope).then(result => {
+ eventId = result;
+ }),
+ );
+
+ return eventId;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ captureSession(session) {
+ if (!this._isEnabled()) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('SDK not enabled, will not capture session.');
+ return;
+ }
+
+ if (!(typeof session.release === 'string')) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('Discarded session because of missing or non-string release');
+ } else {
+ this.sendSession(session);
+ // After sending, we set init false to indicate it's not the first occurrence
+ updateSession(session, { init: false });
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getDsn() {
+ return this._dsn;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getOptions() {
+ return this._options;
+ }
+
+ /**
+ * @see SdkMetadata in @sentry/types
+ *
+ * @return The metadata of the SDK
+ */
+ getSdkMetadata() {
+ return this._options._metadata;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getTransport() {
+ return this._transport;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ flush(timeout) {
+ const transport = this._transport;
+ if (transport) {
+ return this._isClientDoneProcessing(timeout).then(clientFinished => {
+ return transport.flush(timeout).then(transportFlushed => clientFinished && transportFlushed);
+ });
+ } else {
+ return resolvedSyncPromise(true);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ close(timeout) {
+ return this.flush(timeout).then(result => {
+ this.getOptions().enabled = false;
+ return result;
+ });
+ }
+
+ /**
+ * Sets up the integrations
+ */
+ setupIntegrations() {
+ if (this._isEnabled() && !this._integrationsInitialized) {
+ this._integrations = setupIntegrations(this._options.integrations);
+ this._integrationsInitialized = true;
+ }
+ }
+
+ /**
+ * Gets an installed integration by its `id`.
+ *
+ * @returns The installed integration or `undefined` if no integration with that `id` was installed.
+ */
+ getIntegrationById(integrationId) {
+ return this._integrations[integrationId];
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getIntegration(integration) {
+ try {
+ return (this._integrations[integration.id] ) || null;
+ } catch (_oO) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn(`Cannot retrieve integration ${integration.id} from the current Client`);
+ return null;
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ addIntegration(integration) {
+ setupIntegration(integration, this._integrations);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ sendEvent(event, hint = {}) {
+ if (this._dsn) {
+ let env = createEventEnvelope(event, this._dsn, this._options._metadata, this._options.tunnel);
+
+ for (const attachment of hint.attachments || []) {
+ env = addItemToEnvelope(
+ env,
+ createAttachmentEnvelopeItem(
+ attachment,
+ this._options.transportOptions && this._options.transportOptions.textEncoder,
+ ),
+ );
+ }
+
+ const promise = this._sendEnvelope(env);
+ if (promise) {
+ promise.then(sendResponse => this.emit('afterSendEvent', event, sendResponse), null);
+ }
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ sendSession(session) {
+ if (this._dsn) {
+ const env = createSessionEnvelope(session, this._dsn, this._options._metadata, this._options.tunnel);
+ void this._sendEnvelope(env);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ recordDroppedEvent(reason, category, _event) {
+ // Note: we use `event` in replay, where we overwrite this hook.
+
+ if (this._options.sendClientReports) {
+ // We want to track each category (error, transaction, session, replay_event) separately
+ // but still keep the distinction between different type of outcomes.
+ // We could use nested maps, but it's much easier to read and type this way.
+ // A correct type for map-based implementation if we want to go that route
+ // would be `Partial<Record<SentryRequestType, Partial<Record<Outcome, number>>>>`
+ // With typescript 4.1 we could even use template literal types
+ const key = `${reason}:${category}`;
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log(`Adding outcome: "${key}"`);
+
+ // The following works because undefined + 1 === NaN and NaN is falsy
+ this._outcomes[key] = this._outcomes[key] + 1 || 1;
+ }
+ }
+
+ // Keep on() & emit() signatures in sync with types' client.ts interface
+
+ /** @inheritdoc */
+
+ /** @inheritdoc */
+ on(hook, callback) {
+ if (!this._hooks[hook]) {
+ this._hooks[hook] = [];
+ }
+
+ // @ts-ignore We assue the types are correct
+ this._hooks[hook].push(callback);
+ }
+
+ /** @inheritdoc */
+
+ /** @inheritdoc */
+ emit(hook, ...rest) {
+ if (this._hooks[hook]) {
+ // @ts-ignore we cannot enforce the callback to match the hook
+ this._hooks[hook].forEach(callback => callback(...rest));
+ }
+ }
+
+ /** Updates existing session based on the provided event */
+ _updateSessionFromEvent(session, event) {
+ let crashed = false;
+ let errored = false;
+ const exceptions = event.exception && event.exception.values;
+
+ if (exceptions) {
+ errored = true;
+
+ for (const ex of exceptions) {
+ const mechanism = ex.mechanism;
+ if (mechanism && mechanism.handled === false) {
+ crashed = true;
+ break;
+ }
+ }
+ }
+
+ // A session is updated and that session update is sent in only one of the two following scenarios:
+ // 1. Session with non terminal status and 0 errors + an error occurred -> Will set error count to 1 and send update
+ // 2. Session with non terminal status and 1 error + a crash occurred -> Will set status crashed and send update
+ const sessionNonTerminal = session.status === 'ok';
+ const shouldUpdateAndSend = (sessionNonTerminal && session.errors === 0) || (sessionNonTerminal && crashed);
+
+ if (shouldUpdateAndSend) {
+ updateSession(session, {
+ ...(crashed && { status: 'crashed' }),
+ errors: session.errors || Number(errored || crashed),
+ });
+ this.captureSession(session);
+ }
+ }
+
+ /**
+ * Determine if the client is finished processing. Returns a promise because it will wait `timeout` ms before saying
+ * "no" (resolving to `false`) in order to give the client a chance to potentially finish first.
+ *
+ * @param timeout The time, in ms, after which to resolve to `false` if the client is still busy. Passing `0` (or not
+ * passing anything) will make the promise wait as long as it takes for processing to finish before resolving to
+ * `true`.
+ * @returns A promise which will resolve to `true` if processing is already done or finishes before the timeout, and
+ * `false` otherwise
+ */
+ _isClientDoneProcessing(timeout) {
+ return new SyncPromise(resolve => {
+ let ticked = 0;
+ const tick = 1;
+
+ const interval = setInterval(() => {
+ if (this._numProcessing == 0) {
+ clearInterval(interval);
+ resolve(true);
+ } else {
+ ticked += tick;
+ if (timeout && ticked >= timeout) {
+ clearInterval(interval);
+ resolve(false);
+ }
+ }
+ }, tick);
+ });
+ }
+
+ /** Determines whether this SDK is enabled and a valid Dsn is present. */
+ _isEnabled() {
+ return this.getOptions().enabled !== false && this._dsn !== undefined;
+ }
+
+ /**
+ * Adds common information to events.
+ *
+ * The information includes release and environment from `options`,
+ * breadcrumbs and context (extra, tags and user) from the scope.
+ *
+ * Information that is already present in the event is never overwritten. For
+ * nested objects, such as the context, keys are merged.
+ *
+ * @param event The original event.
+ * @param hint May contain additional information about the original exception.
+ * @param scope A scope containing event metadata.
+ * @returns A new event with more information.
+ */
+ _prepareEvent(event, hint, scope) {
+ const options = this.getOptions();
+ const integrations = Object.keys(this._integrations);
+ if (!hint.integrations && integrations.length > 0) {
+ hint.integrations = integrations;
+ }
+ return prepareEvent(options, event, hint, scope);
+ }
+
+ /**
+ * Processes the event and logs an error in case of rejection
+ * @param event
+ * @param hint
+ * @param scope
+ */
+ _captureEvent(event, hint = {}, scope) {
+ return this._processEvent(event, hint, scope).then(
+ finalEvent => {
+ return finalEvent.event_id;
+ },
+ reason => {
+ if ((typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__)) {
+ // If something's gone wrong, log the error as a warning. If it's just us having used a `SentryError` for
+ // control flow, log just the message (no stack) as a log-level log.
+ const sentryError = reason ;
+ if (sentryError.logLevel === 'log') {
+ logger.log(sentryError.message);
+ } else {
+ logger.warn(sentryError);
+ }
+ }
+ return undefined;
+ },
+ );
+ }
+
+ /**
+ * Processes an event (either error or message) and sends it to Sentry.
+ *
+ * This also adds breadcrumbs and context information to the event. However,
+ * platform specific meta data (such as the User's IP address) must be added
+ * by the SDK implementor.
+ *
+ *
+ * @param event The event to send to Sentry.
+ * @param hint May contain additional information about the original exception.
+ * @param scope A scope containing event metadata.
+ * @returns A SyncPromise that resolves with the event or rejects in case event was/will not be send.
+ */
+ _processEvent(event, hint, scope) {
+ const options = this.getOptions();
+ const { sampleRate } = options;
+
+ if (!this._isEnabled()) {
+ return rejectedSyncPromise(new SentryError('SDK not enabled, will not capture event.', 'log'));
+ }
+
+ const isTransaction = isTransactionEvent(event);
+ const isError = isErrorEvent(event);
+ const eventType = event.type || 'error';
+ const beforeSendLabel = `before send for type \`${eventType}\``;
+
+ // 1.0 === 100% events are sent
+ // 0.0 === 0% events are sent
+ // Sampling for transaction happens somewhere else
+ if (isError && typeof sampleRate === 'number' && Math.random() > sampleRate) {
+ this.recordDroppedEvent('sample_rate', 'error', event);
+ return rejectedSyncPromise(
+ new SentryError(
+ `Discarding event because it's not included in the random sample (sampling rate = ${sampleRate})`,
+ 'log',
+ ),
+ );
+ }
+
+ const dataCategory = eventType === 'replay_event' ? 'replay' : eventType;
+
+ return this._prepareEvent(event, hint, scope)
+ .then(prepared => {
+ if (prepared === null) {
+ this.recordDroppedEvent('event_processor', dataCategory, event);
+ throw new SentryError('An event processor returned `null`, will not send event.', 'log');
+ }
+
+ const isInternalException = hint.data && (hint.data ).__sentry__ === true;
+ if (isInternalException) {
+ return prepared;
+ }
+
+ const result = processBeforeSend(options, prepared, hint);
+ return _validateBeforeSendResult(result, beforeSendLabel);
+ })
+ .then(processedEvent => {
+ if (processedEvent === null) {
+ this.recordDroppedEvent('before_send', dataCategory, event);
+ throw new SentryError(`${beforeSendLabel} returned \`null\`, will not send event.`, 'log');
+ }
+
+ const session = scope && scope.getSession();
+ if (!isTransaction && session) {
+ this._updateSessionFromEvent(session, processedEvent);
+ }
+
+ // None of the Sentry built event processor will update transaction name,
+ // so if the transaction name has been changed by an event processor, we know
+ // it has to come from custom event processor added by a user
+ const transactionInfo = processedEvent.transaction_info;
+ if (isTransaction && transactionInfo && processedEvent.transaction !== event.transaction) {
+ const source = 'custom';
+ processedEvent.transaction_info = {
+ ...transactionInfo,
+ source,
+ };
+ }
+
+ this.sendEvent(processedEvent, hint);
+ return processedEvent;
+ })
+ .then(null, reason => {
+ if (reason instanceof SentryError) {
+ throw reason;
+ }
+
+ this.captureException(reason, {
+ data: {
+ __sentry__: true,
+ },
+ originalException: reason,
+ });
+ throw new SentryError(
+ `Event processing pipeline threw an error, original event will not be sent. Details have been sent as a new event.\nReason: ${reason}`,
+ );
+ });
+ }
+
+ /**
+ * Occupies the client with processing and event
+ */
+ _process(promise) {
+ this._numProcessing++;
+ void promise.then(
+ value => {
+ this._numProcessing--;
+ return value;
+ },
+ reason => {
+ this._numProcessing--;
+ return reason;
+ },
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ _sendEnvelope(envelope) {
+ if (this._transport && this._dsn) {
+ this.emit('beforeEnvelope', envelope);
+
+ return this._transport.send(envelope).then(null, reason => {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error('Error while sending event:', reason);
+ });
+ } else {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error('Transport disabled');
+ }
+ }
+
+ /**
+ * Clears outcomes on this client and returns them.
+ */
+ _clearOutcomes() {
+ const outcomes = this._outcomes;
+ this._outcomes = {};
+ return Object.keys(outcomes).map(key => {
+ const [reason, category] = key.split(':') ;
+ return {
+ reason,
+ category,
+ quantity: outcomes[key],
+ };
+ });
+ }
+
+ /**
+ * @inheritDoc
+ */
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
+
+}
+
+/**
+ * Verifies that return value of configured `beforeSend` or `beforeSendTransaction` is of expected type, and returns the value if so.
+ */
+function _validateBeforeSendResult(
+ beforeSendResult,
+ beforeSendLabel,
+) {
+ const invalidValueError = `${beforeSendLabel} must return \`null\` or a valid event.`;
+ if (isThenable(beforeSendResult)) {
+ return beforeSendResult.then(
+ event => {
+ if (!isPlainObject(event) && event !== null) {
+ throw new SentryError(invalidValueError);
+ }
+ return event;
+ },
+ e => {
+ throw new SentryError(`${beforeSendLabel} rejected with ${e}`);
+ },
+ );
+ } else if (!isPlainObject(beforeSendResult) && beforeSendResult !== null) {
+ throw new SentryError(invalidValueError);
+ }
+ return beforeSendResult;
+}
+
+/**
+ * Process the matching `beforeSendXXX` callback.
+ */
+function processBeforeSend(
+ options,
+ event,
+ hint,
+) {
+ const { beforeSend, beforeSendTransaction } = options;
+
+ if (isErrorEvent(event) && beforeSend) {
+ return beforeSend(event, hint);
+ }
+
+ if (isTransactionEvent(event) && beforeSendTransaction) {
+ return beforeSendTransaction(event, hint);
+ }
+
+ return event;
+}
+
+function isErrorEvent(event) {
+ return event.type === undefined;
+}
+
+function isTransactionEvent(event) {
+ return event.type === 'transaction';
+}
+
+export { BaseClient };
+//# sourceMappingURL=baseclient.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/constants.js b/shared/logger/node_modules/@sentry/core/esm/constants.js
new file mode 100644
index 0000000..2c81ff6
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/constants.js
@@ -0,0 +1,4 @@
+const DEFAULT_ENVIRONMENT = 'production';
+
+export { DEFAULT_ENVIRONMENT };
+//# sourceMappingURL=constants.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/envelope.js b/shared/logger/node_modules/@sentry/core/esm/envelope.js
new file mode 100644
index 0000000..2d1047d
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/envelope.js
@@ -0,0 +1,74 @@
+import { getSdkMetadataForEnvelopeHeader, dsnToString, createEnvelope, createEventEnvelopeHeaders } from '@sentry/utils';
+
+/**
+ * Apply SdkInfo (name, version, packages, integrations) to the corresponding event key.
+ * Merge with existing data if any.
+ **/
+function enhanceEventWithSdkInfo(event, sdkInfo) {
+ if (!sdkInfo) {
+ return event;
+ }
+ event.sdk = event.sdk || {};
+ event.sdk.name = event.sdk.name || sdkInfo.name;
+ event.sdk.version = event.sdk.version || sdkInfo.version;
+ event.sdk.integrations = [...(event.sdk.integrations || []), ...(sdkInfo.integrations || [])];
+ event.sdk.packages = [...(event.sdk.packages || []), ...(sdkInfo.packages || [])];
+ return event;
+}
+
+/** Creates an envelope from a Session */
+function createSessionEnvelope(
+ session,
+ dsn,
+ metadata,
+ tunnel,
+) {
+ const sdkInfo = getSdkMetadataForEnvelopeHeader(metadata);
+ const envelopeHeaders = {
+ sent_at: new Date().toISOString(),
+ ...(sdkInfo && { sdk: sdkInfo }),
+ ...(!!tunnel && { dsn: dsnToString(dsn) }),
+ };
+
+ const envelopeItem =
+ 'aggregates' in session ? [{ type: 'sessions' }, session] : [{ type: 'session' }, session.toJSON()];
+
+ return createEnvelope(envelopeHeaders, [envelopeItem]);
+}
+
+/**
+ * Create an Envelope from an event.
+ */
+function createEventEnvelope(
+ event,
+ dsn,
+ metadata,
+ tunnel,
+) {
+ const sdkInfo = getSdkMetadataForEnvelopeHeader(metadata);
+
+ /*
+ Note: Due to TS, event.type may be `replay_event`, theoretically.
+ In practice, we never call `createEventEnvelope` with `replay_event` type,
+ and we'd have to adjut a looot of types to make this work properly.
+ We want to avoid casting this around, as that could lead to bugs (e.g. when we add another type)
+ So the safe choice is to really guard against the replay_event type here.
+ */
+ const eventType = event.type && event.type !== 'replay_event' ? event.type : 'event';
+
+ enhanceEventWithSdkInfo(event, metadata && metadata.sdk);
+
+ const envelopeHeaders = createEventEnvelopeHeaders(event, sdkInfo, tunnel, dsn);
+
+ // Prevent this data (which, if it exists, was used in earlier steps in the processing pipeline) from being sent to
+ // sentry. (Note: Our use of this property comes and goes with whatever we might be debugging, whatever hacks we may
+ // have temporarily added, etc. Even if we don't happen to be using it at some point in the future, let's not get rid
+ // of this `delete`, lest we miss putting it back in the next time the property is in use.)
+ delete event.sdkProcessingMetadata;
+
+ const eventItem = [{ type: eventType }, event];
+ return createEnvelope(envelopeHeaders, [eventItem]);
+}
+
+export { createEventEnvelope, createSessionEnvelope };
+//# sourceMappingURL=envelope.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/exports.js b/shared/logger/node_modules/@sentry/core/esm/exports.js
new file mode 100644
index 0000000..a7d8592
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/exports.js
@@ -0,0 +1,193 @@
+import { logger, uuid4 } from '@sentry/utils';
+import { getCurrentHub } from './hub.js';
+
+// Note: All functions in this file are typed with a return value of `ReturnType<Hub[HUB_FUNCTION]>`,
+// where HUB_FUNCTION is some method on the Hub class.
+//
+// This is done to make sure the top level SDK methods stay in sync with the hub methods.
+// Although every method here has an explicit return type, some of them (that map to void returns) do not
+// contain `return` keywords. This is done to save on bundle size, as `return` is not minifiable.
+
+/**
+ * Captures an exception event and sends it to Sentry.
+ *
+ * @param exception An exception-like object.
+ * @param captureContext Additional scope data to apply to exception event.
+ * @returns The generated eventId.
+ */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
+function captureException(exception, captureContext) {
+ return getCurrentHub().captureException(exception, { captureContext });
+}
+
+/**
+ * Captures a message event and sends it to Sentry.
+ *
+ * @param message The message to send to Sentry.
+ * @param Severity Define the level of the message.
+ * @returns The generated eventId.
+ */
+function captureMessage(
+ message,
+ // eslint-disable-next-line deprecation/deprecation
+ captureContext,
+) {
+ // This is necessary to provide explicit scopes upgrade, without changing the original
+ // arity of the `captureMessage(message, level)` method.
+ const level = typeof captureContext === 'string' ? captureContext : undefined;
+ const context = typeof captureContext !== 'string' ? { captureContext } : undefined;
+ return getCurrentHub().captureMessage(message, level, context);
+}
+
+/**
+ * Captures a manually created event and sends it to Sentry.
+ *
+ * @param event The event to send to Sentry.
+ * @returns The generated eventId.
+ */
+function captureEvent(event, hint) {
+ return getCurrentHub().captureEvent(event, hint);
+}
+
+/**
+ * Callback to set context information onto the scope.
+ * @param callback Callback function that receives Scope.
+ */
+function configureScope(callback) {
+ getCurrentHub().configureScope(callback);
+}
+
+/**
+ * Records a new breadcrumb which will be attached to future events.
+ *
+ * Breadcrumbs will be added to subsequent events to provide more context on
+ * user's actions prior to an error or crash.
+ *
+ * @param breadcrumb The breadcrumb to record.
+ */
+function addBreadcrumb(breadcrumb) {
+ getCurrentHub().addBreadcrumb(breadcrumb);
+}
+
+/**
+ * Sets context data with the given name.
+ * @param name of the context
+ * @param context Any kind of data. This data will be normalized.
+ */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+function setContext(name, context) {
+ getCurrentHub().setContext(name, context);
+}
+
+/**
+ * Set an object that will be merged sent as extra data with the event.
+ * @param extras Extras object to merge into current context.
+ */
+function setExtras(extras) {
+ getCurrentHub().setExtras(extras);
+}
+
+/**
+ * Set key:value that will be sent as extra data with the event.
+ * @param key String of extra
+ * @param extra Any kind of data. This data will be normalized.
+ */
+function setExtra(key, extra) {
+ getCurrentHub().setExtra(key, extra);
+}
+
+/**
+ * Set an object that will be merged sent as tags data with the event.
+ * @param tags Tags context object to merge into current context.
+ */
+function setTags(tags) {
+ getCurrentHub().setTags(tags);
+}
+
+/**
+ * Set key:value that will be sent as tags data with the event.
+ *
+ * Can also be used to unset a tag, by passing `undefined`.
+ *
+ * @param key String key of tag
+ * @param value Value of tag
+ */
+function setTag(key, value) {
+ getCurrentHub().setTag(key, value);
+}
+
+/**
+ * Updates user context information for future events.
+ *
+ * @param user User context object to be set in the current context. Pass `null` to unset the user.
+ */
+function setUser(user) {
+ getCurrentHub().setUser(user);
+}
+
+/**
+ * Creates a new scope with and executes the given operation within.
+ * The scope is automatically removed once the operation
+ * finishes or throws.
+ *
+ * This is essentially a convenience function for:
+ *
+ * pushScope();
+ * callback();
+ * popScope();
+ *
+ * @param callback that will be enclosed into push/popScope.
+ */
+function withScope(callback) {
+ getCurrentHub().withScope(callback);
+}
+
+/**
+ * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation.
+ *
+ * A tree structure can be built by adding child spans to the transaction, and child spans to other spans. To start a
+ * new child span within the transaction or any span, call the respective `.startChild()` method.
+ *
+ * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded.
+ *
+ * The transaction must be finished with a call to its `.finish()` method, at which point the transaction with all its
+ * finished child spans will be sent to Sentry.
+ *
+ * NOTE: This function should only be used for *manual* instrumentation. Auto-instrumentation should call
+ * `startTransaction` directly on the hub.
+ *
+ * @param context Properties of the new `Transaction`.
+ * @param customSamplingContext Information given to the transaction sampling function (along with context-dependent
+ * default values). See {@link Options.tracesSampler}.
+ *
+ * @returns The transaction which was just started
+ */
+function startTransaction(
+ context,
+ customSamplingContext,
+) {
+ return getCurrentHub().startTransaction({ ...context }, customSamplingContext);
+}
+
+/**
+ * Create a cron monitor check in and send it to Sentry.
+ *
+ * @param checkIn An object that describes a check in.
+ * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want
+ * to create a monitor automatically when sending a check in.
+ */
+function captureCheckIn(checkIn, upsertMonitorConfig) {
+ const client = getCurrentHub().getClient();
+ if (!client) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('Cannot capture check-in. No client defined.');
+ } else if (!client.captureCheckIn) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('Cannot capture check-in. Client does not support sending check-ins.');
+ } else {
+ return client.captureCheckIn(checkIn, upsertMonitorConfig);
+ }
+
+ return uuid4();
+}
+
+export { addBreadcrumb, captureCheckIn, captureEvent, captureException, captureMessage, configureScope, setContext, setExtra, setExtras, setTag, setTags, setUser, startTransaction, withScope };
+//# sourceMappingURL=exports.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/hub.js b/shared/logger/node_modules/@sentry/core/esm/hub.js
new file mode 100644
index 0000000..2dd6764
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/hub.js
@@ -0,0 +1,564 @@
+import { uuid4, dateTimestampInSeconds, consoleSandbox, logger, GLOBAL_OBJ, getGlobalSingleton } from '@sentry/utils';
+import { DEFAULT_ENVIRONMENT } from './constants.js';
+import { Scope } from './scope.js';
+import { closeSession, makeSession, updateSession } from './session.js';
+
+/**
+ * API compatibility version of this hub.
+ *
+ * WARNING: This number should only be increased when the global interface
+ * changes and new methods are introduced.
+ *
+ * @hidden
+ */
+const API_VERSION = 4;
+
+/**
+ * Default maximum number of breadcrumbs added to an event. Can be overwritten
+ * with {@link Options.maxBreadcrumbs}.
+ */
+const DEFAULT_BREADCRUMBS = 100;
+
+/**
+ * @inheritDoc
+ */
+class Hub {
+ /** Is a {@link Layer}[] containing the client and scope */
+
+ /** Contains the last event id of a captured event. */
+
+ /**
+ * Creates a new instance of the hub, will push one {@link Layer} into the
+ * internal stack on creation.
+ *
+ * @param client bound to the hub.
+ * @param scope bound to the hub.
+ * @param version number, higher number means higher priority.
+ */
+ constructor(client, scope = new Scope(), _version = API_VERSION) {this._version = _version;
+ this._stack = [{ scope }];
+ if (client) {
+ this.bindClient(client);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ isOlderThan(version) {
+ return this._version < version;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ bindClient(client) {
+ const top = this.getStackTop();
+ top.client = client;
+ if (client && client.setupIntegrations) {
+ client.setupIntegrations();
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ pushScope() {
+ // We want to clone the content of prev scope
+ const scope = Scope.clone(this.getScope());
+ this.getStack().push({
+ client: this.getClient(),
+ scope,
+ });
+ return scope;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ popScope() {
+ if (this.getStack().length <= 1) return false;
+ return !!this.getStack().pop();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ withScope(callback) {
+ const scope = this.pushScope();
+ try {
+ callback(scope);
+ } finally {
+ this.popScope();
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getClient() {
+ return this.getStackTop().client ;
+ }
+
+ /** Returns the scope of the top stack. */
+ getScope() {
+ return this.getStackTop().scope;
+ }
+
+ /** Returns the scope stack for domains or the process. */
+ getStack() {
+ return this._stack;
+ }
+
+ /** Returns the topmost scope layer in the order domain > local > process. */
+ getStackTop() {
+ return this._stack[this._stack.length - 1];
+ }
+
+ /**
+ * @inheritDoc
+ */
+ captureException(exception, hint) {
+ const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : uuid4());
+ const syntheticException = new Error('Sentry syntheticException');
+ this._withClient((client, scope) => {
+ client.captureException(
+ exception,
+ {
+ originalException: exception,
+ syntheticException,
+ ...hint,
+ event_id: eventId,
+ },
+ scope,
+ );
+ });
+ return eventId;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ captureMessage(
+ message,
+ // eslint-disable-next-line deprecation/deprecation
+ level,
+ hint,
+ ) {
+ const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : uuid4());
+ const syntheticException = new Error(message);
+ this._withClient((client, scope) => {
+ client.captureMessage(
+ message,
+ level,
+ {
+ originalException: message,
+ syntheticException,
+ ...hint,
+ event_id: eventId,
+ },
+ scope,
+ );
+ });
+ return eventId;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ captureEvent(event, hint) {
+ const eventId = hint && hint.event_id ? hint.event_id : uuid4();
+ if (!event.type) {
+ this._lastEventId = eventId;
+ }
+
+ this._withClient((client, scope) => {
+ client.captureEvent(event, { ...hint, event_id: eventId }, scope);
+ });
+ return eventId;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ lastEventId() {
+ return this._lastEventId;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ addBreadcrumb(breadcrumb, hint) {
+ const { scope, client } = this.getStackTop();
+
+ if (!client) return;
+
+ const { beforeBreadcrumb = null, maxBreadcrumbs = DEFAULT_BREADCRUMBS } =
+ (client.getOptions && client.getOptions()) || {};
+
+ if (maxBreadcrumbs <= 0) return;
+
+ const timestamp = dateTimestampInSeconds();
+ const mergedBreadcrumb = { timestamp, ...breadcrumb };
+ const finalBreadcrumb = beforeBreadcrumb
+ ? (consoleSandbox(() => beforeBreadcrumb(mergedBreadcrumb, hint)) )
+ : mergedBreadcrumb;
+
+ if (finalBreadcrumb === null) return;
+
+ if (client.emit) {
+ client.emit('beforeAddBreadcrumb', finalBreadcrumb, hint);
+ }
+
+ scope.addBreadcrumb(finalBreadcrumb, maxBreadcrumbs);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setUser(user) {
+ this.getScope().setUser(user);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setTags(tags) {
+ this.getScope().setTags(tags);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setExtras(extras) {
+ this.getScope().setExtras(extras);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setTag(key, value) {
+ this.getScope().setTag(key, value);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setExtra(key, extra) {
+ this.getScope().setExtra(key, extra);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ setContext(name, context) {
+ this.getScope().setContext(name, context);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ configureScope(callback) {
+ const { scope, client } = this.getStackTop();
+ if (client) {
+ callback(scope);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ run(callback) {
+ const oldHub = makeMain(this);
+ try {
+ callback(this);
+ } finally {
+ makeMain(oldHub);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getIntegration(integration) {
+ const client = this.getClient();
+ if (!client) return null;
+ try {
+ return client.getIntegration(integration);
+ } catch (_oO) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn(`Cannot retrieve integration ${integration.id} from the current Hub`);
+ return null;
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ startTransaction(context, customSamplingContext) {
+ const result = this._callExtensionMethod('startTransaction', context, customSamplingContext);
+
+ if ((typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && !result) {
+ // eslint-disable-next-line no-console
+ console.warn(`Tracing extension 'startTransaction' has not been added. Call 'addTracingExtensions' before calling 'init':
+Sentry.addTracingExtensions();
+Sentry.init({...});
+`);
+ }
+
+ return result;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ traceHeaders() {
+ return this._callExtensionMethod('traceHeaders');
+ }
+
+ /**
+ * @inheritDoc
+ */
+ captureSession(endSession = false) {
+ // both send the update and pull the session from the scope
+ if (endSession) {
+ return this.endSession();
+ }
+
+ // only send the update
+ this._sendSessionUpdate();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ endSession() {
+ const layer = this.getStackTop();
+ const scope = layer.scope;
+ const session = scope.getSession();
+ if (session) {
+ closeSession(session);
+ }
+ this._sendSessionUpdate();
+
+ // the session is over; take it off of the scope
+ scope.setSession();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ startSession(context) {
+ const { scope, client } = this.getStackTop();
+ const { release, environment = DEFAULT_ENVIRONMENT } = (client && client.getOptions()) || {};
+
+ // Will fetch userAgent if called from browser sdk
+ const { userAgent } = GLOBAL_OBJ.navigator || {};
+
+ const session = makeSession({
+ release,
+ environment,
+ user: scope.getUser(),
+ ...(userAgent && { userAgent }),
+ ...context,
+ });
+
+ // End existing session if there's one
+ const currentSession = scope.getSession && scope.getSession();
+ if (currentSession && currentSession.status === 'ok') {
+ updateSession(currentSession, { status: 'exited' });
+ }
+ this.endSession();
+
+ // Afterwards we set the new session on the scope
+ scope.setSession(session);
+
+ return session;
+ }
+
+ /**
+ * Returns if default PII should be sent to Sentry and propagated in ourgoing requests
+ * when Tracing is used.
+ */
+ shouldSendDefaultPii() {
+ const client = this.getClient();
+ const options = client && client.getOptions();
+ return Boolean(options && options.sendDefaultPii);
+ }
+
+ /**
+ * Sends the current Session on the scope
+ */
+ _sendSessionUpdate() {
+ const { scope, client } = this.getStackTop();
+
+ const session = scope.getSession();
+ if (session && client && client.captureSession) {
+ client.captureSession(session);
+ }
+ }
+
+ /**
+ * Internal helper function to call a method on the top client if it exists.
+ *
+ * @param method The method to call on the client.
+ * @param args Arguments to pass to the client function.
+ */
+ _withClient(callback) {
+ const { scope, client } = this.getStackTop();
+ if (client) {
+ callback(client, scope);
+ }
+ }
+
+ /**
+ * Calls global extension method and binding current instance to the function call
+ */
+ // @ts-ignore Function lacks ending return statement and return type does not include 'undefined'. ts(2366)
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ _callExtensionMethod(method, ...args) {
+ const carrier = getMainCarrier();
+ const sentry = carrier.__SENTRY__;
+ if (sentry && sentry.extensions && typeof sentry.extensions[method] === 'function') {
+ return sentry.extensions[method].apply(this, args);
+ }
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn(`Extension method ${method} couldn't be found, doing nothing.`);
+ }
+}
+
+/**
+ * Returns the global shim registry.
+ *
+ * FIXME: This function is problematic, because despite always returning a valid Carrier,
+ * it has an optional `__SENTRY__` property, which then in turn requires us to always perform an unnecessary check
+ * at the call-site. We always access the carrier through this function, so we can guarantee that `__SENTRY__` is there.
+ **/
+function getMainCarrier() {
+ GLOBAL_OBJ.__SENTRY__ = GLOBAL_OBJ.__SENTRY__ || {
+ extensions: {},
+ hub: undefined,
+ };
+ return GLOBAL_OBJ;
+}
+
+/**
+ * Replaces the current main hub with the passed one on the global object
+ *
+ * @returns The old replaced hub
+ */
+function makeMain(hub) {
+ const registry = getMainCarrier();
+ const oldHub = getHubFromCarrier(registry);
+ setHubOnCarrier(registry, hub);
+ return oldHub;
+}
+
+/**
+ * Returns the default hub instance.
+ *
+ * If a hub is already registered in the global carrier but this module
+ * contains a more recent version, it replaces the registered version.
+ * Otherwise, the currently registered hub will be returned.
+ */
+function getCurrentHub() {
+ // Get main carrier (global for every environment)
+ const registry = getMainCarrier();
+
+ if (registry.__SENTRY__ && registry.__SENTRY__.acs) {
+ const hub = registry.__SENTRY__.acs.getCurrentHub();
+
+ if (hub) {
+ return hub;
+ }
+ }
+
+ // Return hub that lives on a global object
+ return getGlobalHub(registry);
+}
+
+function getGlobalHub(registry = getMainCarrier()) {
+ // If there's no hub, or its an old API, assign a new one
+ if (!hasHubOnCarrier(registry) || getHubFromCarrier(registry).isOlderThan(API_VERSION)) {
+ setHubOnCarrier(registry, new Hub());
+ }
+
+ // Return hub that lives on a global object
+ return getHubFromCarrier(registry);
+}
+
+/**
+ * @private Private API with no semver guarantees!
+ *
+ * If the carrier does not contain a hub, a new hub is created with the global hub client and scope.
+ */
+function ensureHubOnCarrier(carrier, parent = getGlobalHub()) {
+ // If there's no hub on current domain, or it's an old API, assign a new one
+ if (!hasHubOnCarrier(carrier) || getHubFromCarrier(carrier).isOlderThan(API_VERSION)) {
+ const globalHubTopStack = parent.getStackTop();
+ setHubOnCarrier(carrier, new Hub(globalHubTopStack.client, Scope.clone(globalHubTopStack.scope)));
+ }
+}
+
+/**
+ * @private Private API with no semver guarantees!
+ *
+ * Sets the global async context strategy
+ */
+function setAsyncContextStrategy(strategy) {
+ // Get main carrier (global for every environment)
+ const registry = getMainCarrier();
+ registry.__SENTRY__ = registry.__SENTRY__ || {};
+ registry.__SENTRY__.acs = strategy;
+}
+
+/**
+ * Runs the supplied callback in its own async context. Async Context strategies are defined per SDK.
+ *
+ * @param callback The callback to run in its own async context
+ * @param options Options to pass to the async context strategy
+ * @returns The result of the callback
+ */
+function runWithAsyncContext(callback, options = {}) {
+ const registry = getMainCarrier();
+
+ if (registry.__SENTRY__ && registry.__SENTRY__.acs) {
+ return registry.__SENTRY__.acs.runWithAsyncContext(callback, options);
+ }
+
+ // if there was no strategy, fallback to just calling the callback
+ return callback();
+}
+
+/**
+ * This will tell whether a carrier has a hub on it or not
+ * @param carrier object
+ */
+function hasHubOnCarrier(carrier) {
+ return !!(carrier && carrier.__SENTRY__ && carrier.__SENTRY__.hub);
+}
+
+/**
+ * This will create a new {@link Hub} and add to the passed object on
+ * __SENTRY__.hub.
+ * @param carrier object
+ * @hidden
+ */
+function getHubFromCarrier(carrier) {
+ return getGlobalSingleton('hub', () => new Hub(), carrier);
+}
+
+/**
+ * This will set passed {@link Hub} on the passed object's __SENTRY__.hub attribute
+ * @param carrier object
+ * @param hub Hub
+ * @returns A boolean indicating success or failure
+ */
+function setHubOnCarrier(carrier, hub) {
+ if (!carrier) return false;
+ const __SENTRY__ = (carrier.__SENTRY__ = carrier.__SENTRY__ || {});
+ __SENTRY__.hub = hub;
+ return true;
+}
+
+export { API_VERSION, Hub, ensureHubOnCarrier, getCurrentHub, getHubFromCarrier, getMainCarrier, makeMain, runWithAsyncContext, setAsyncContextStrategy, setHubOnCarrier };
+//# sourceMappingURL=hub.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/integration.js b/shared/logger/node_modules/@sentry/core/esm/integration.js
new file mode 100644
index 0000000..db16727
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/integration.js
@@ -0,0 +1,112 @@
+import { arrayify, logger } from '@sentry/utils';
+import { getCurrentHub } from './hub.js';
+import { addGlobalEventProcessor } from './scope.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
+ * preseve 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.keys(integrationsByName).map(k => integrationsByName[k]);
+}
+
+/** 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 = 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 = findIndex(finalIntegrations, 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(integrations) {
+ const integrationIndex = {};
+
+ integrations.forEach(integration => {
+ // guard against empty provided integrations
+ if (integration) {
+ setupIntegration(integration, integrationIndex);
+ }
+ });
+
+ return integrationIndex;
+}
+
+/** Setup a single integration. */
+function setupIntegration(integration, integrationIndex) {
+ integrationIndex[integration.name] = integration;
+
+ if (installedIntegrations.indexOf(integration.name) === -1) {
+ integration.setupOnce(addGlobalEventProcessor, getCurrentHub);
+ installedIntegrations.push(integration.name);
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log(`Integration installed: ${integration.name}`);
+ }
+}
+
+// Polyfill for Array.findIndex(), which is not supported in ES5
+function findIndex(arr, callback) {
+ for (let i = 0; i < arr.length; i++) {
+ if (callback(arr[i]) === true) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+export { getIntegrationsToSetup, installedIntegrations, setupIntegration, setupIntegrations };
+//# sourceMappingURL=integration.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/integrations/functiontostring.js b/shared/logger/node_modules/@sentry/core/esm/integrations/functiontostring.js
new file mode 100644
index 0000000..dfe714a
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/integrations/functiontostring.js
@@ -0,0 +1,39 @@
+import { getOriginalFunction } from '@sentry/utils';
+
+let originalFunctionToString;
+
+/** Patch toString calls to return proper name for wrapped functions */
+class FunctionToString {constructor() { FunctionToString.prototype.__init.call(this); }
+ /**
+ * @inheritDoc
+ */
+ static __initStatic() {this.id = 'FunctionToString';}
+
+ /**
+ * @inheritDoc
+ */
+ __init() {this.name = FunctionToString.id;}
+
+ /**
+ * @inheritDoc
+ */
+ setupOnce() {
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ originalFunctionToString = Function.prototype.toString;
+
+ // intrinsics (like Function.prototype) might be immutable in some environments
+ // e.g. Node with --frozen-intrinsics, XS (an embedded JavaScript engine) or SES (a JavaScript proposal)
+ try {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ Function.prototype.toString = function ( ...args) {
+ const context = getOriginalFunction(this) || this;
+ return originalFunctionToString.apply(context, args);
+ };
+ } catch (e) {
+ // ignore errors here, just don't patch this
+ }
+ }
+} FunctionToString.__initStatic();
+
+export { FunctionToString };
+//# sourceMappingURL=functiontostring.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/integrations/inboundfilters.js b/shared/logger/node_modules/@sentry/core/esm/integrations/inboundfilters.js
new file mode 100644
index 0000000..a673271
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/integrations/inboundfilters.js
@@ -0,0 +1,213 @@
+import { logger, getEventDescription, stringMatchesSomePattern } from '@sentry/utils';
+
+// "Script error." is hard coded into browsers for errors that it can't read.
+// this is the result of a script being pulled in from an external domain and CORS.
+const DEFAULT_IGNORE_ERRORS = [/^Script error\.?$/, /^Javascript error: Script error\.? on line 0$/];
+
+const DEFAULT_IGNORE_TRANSACTIONS = [
+ /^.*healthcheck.*$/,
+ /^.*healthy.*$/,
+ /^.*live.*$/,
+ /^.*ready.*$/,
+ /^.*heartbeat.*$/,
+ /^.*\/health$/,
+ /^.*\/healthz$/,
+];
+
+/** Options for the InboundFilters integration */
+
+/** Inbound filters configurable by the user */
+class InboundFilters {
+ /**
+ * @inheritDoc
+ */
+ static __initStatic() {this.id = 'InboundFilters';}
+
+ /**
+ * @inheritDoc
+ */
+ __init() {this.name = InboundFilters.id;}
+
+ constructor( _options = {}) {this._options = _options;InboundFilters.prototype.__init.call(this);}
+
+ /**
+ * @inheritDoc
+ */
+ setupOnce(addGlobalEventProcessor, getCurrentHub) {
+ const eventProcess = (event) => {
+ const hub = getCurrentHub();
+ if (hub) {
+ const self = hub.getIntegration(InboundFilters);
+ if (self) {
+ const client = hub.getClient();
+ const clientOptions = client ? client.getOptions() : {};
+ const options = _mergeOptions(self._options, clientOptions);
+ return _shouldDropEvent(event, options) ? null : event;
+ }
+ }
+ return event;
+ };
+
+ eventProcess.id = this.name;
+ addGlobalEventProcessor(eventProcess);
+ }
+} InboundFilters.__initStatic();
+
+/** JSDoc */
+function _mergeOptions(
+ internalOptions = {},
+ clientOptions = {},
+) {
+ return {
+ allowUrls: [...(internalOptions.allowUrls || []), ...(clientOptions.allowUrls || [])],
+ denyUrls: [...(internalOptions.denyUrls || []), ...(clientOptions.denyUrls || [])],
+ ignoreErrors: [
+ ...(internalOptions.ignoreErrors || []),
+ ...(clientOptions.ignoreErrors || []),
+ ...(internalOptions.disableErrorDefaults ? [] : DEFAULT_IGNORE_ERRORS),
+ ],
+ ignoreTransactions: [
+ ...(internalOptions.ignoreTransactions || []),
+ ...(clientOptions.ignoreTransactions || []),
+ ...(internalOptions.disableTransactionDefaults ? [] : DEFAULT_IGNORE_TRANSACTIONS),
+ ],
+ ignoreInternal: internalOptions.ignoreInternal !== undefined ? internalOptions.ignoreInternal : true,
+ };
+}
+
+/** JSDoc */
+function _shouldDropEvent(event, options) {
+ if (options.ignoreInternal && _isSentryError(event)) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.warn(`Event dropped due to being internal Sentry Error.\nEvent: ${getEventDescription(event)}`);
+ return true;
+ }
+ if (_isIgnoredError(event, options.ignoreErrors)) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.warn(
+ `Event dropped due to being matched by \`ignoreErrors\` option.\nEvent: ${getEventDescription(event)}`,
+ );
+ return true;
+ }
+ if (_isIgnoredTransaction(event, options.ignoreTransactions)) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.warn(
+ `Event dropped due to being matched by \`ignoreTransactions\` option.\nEvent: ${getEventDescription(event)}`,
+ );
+ return true;
+ }
+ if (_isDeniedUrl(event, options.denyUrls)) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.warn(
+ `Event dropped due to being matched by \`denyUrls\` option.\nEvent: ${getEventDescription(
+ event,
+ )}.\nUrl: ${_getEventFilterUrl(event)}`,
+ );
+ return true;
+ }
+ if (!_isAllowedUrl(event, options.allowUrls)) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.warn(
+ `Event dropped due to not being matched by \`allowUrls\` option.\nEvent: ${getEventDescription(
+ event,
+ )}.\nUrl: ${_getEventFilterUrl(event)}`,
+ );
+ return true;
+ }
+ return false;
+}
+
+function _isIgnoredError(event, ignoreErrors) {
+ // If event.type, this is not an error
+ if (event.type || !ignoreErrors || !ignoreErrors.length) {
+ return false;
+ }
+
+ return _getPossibleEventMessages(event).some(message => stringMatchesSomePattern(message, ignoreErrors));
+}
+
+function _isIgnoredTransaction(event, ignoreTransactions) {
+ if (event.type !== 'transaction' || !ignoreTransactions || !ignoreTransactions.length) {
+ return false;
+ }
+
+ const name = event.transaction;
+ return name ? stringMatchesSomePattern(name, ignoreTransactions) : false;
+}
+
+function _isDeniedUrl(event, denyUrls) {
+ // TODO: Use Glob instead?
+ if (!denyUrls || !denyUrls.length) {
+ return false;
+ }
+ const url = _getEventFilterUrl(event);
+ return !url ? false : stringMatchesSomePattern(url, denyUrls);
+}
+
+function _isAllowedUrl(event, allowUrls) {
+ // TODO: Use Glob instead?
+ if (!allowUrls || !allowUrls.length) {
+ return true;
+ }
+ const url = _getEventFilterUrl(event);
+ return !url ? true : stringMatchesSomePattern(url, allowUrls);
+}
+
+function _getPossibleEventMessages(event) {
+ if (event.message) {
+ return [event.message];
+ }
+ if (event.exception) {
+ const { values } = event.exception;
+ try {
+ const { type = '', value = '' } = (values && values[values.length - 1]) || {};
+ return [`${value}`, `${type}: ${value}`];
+ } catch (oO) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error(`Cannot extract message for event ${getEventDescription(event)}`);
+ return [];
+ }
+ }
+ return [];
+}
+
+function _isSentryError(event) {
+ try {
+ // @ts-ignore can't be a sentry error if undefined
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+ return event.exception.values[0].type === 'SentryError';
+ } catch (e) {
+ // ignore
+ }
+ return false;
+}
+
+function _getLastValidUrl(frames = []) {
+ for (let i = frames.length - 1; i >= 0; i--) {
+ const frame = frames[i];
+
+ if (frame && frame.filename !== '<anonymous>' && frame.filename !== '[native code]') {
+ return frame.filename || null;
+ }
+ }
+
+ return null;
+}
+
+function _getEventFilterUrl(event) {
+ try {
+ let frames;
+ try {
+ // @ts-ignore we only care about frames if the whole thing here is defined
+ frames = event.exception.values[0].stacktrace.frames;
+ } catch (e) {
+ // ignore
+ }
+ return frames ? _getLastValidUrl(frames) : null;
+ } catch (oO) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error(`Cannot extract url for event ${getEventDescription(event)}`);
+ return null;
+ }
+}
+
+export { InboundFilters, _mergeOptions, _shouldDropEvent };
+//# sourceMappingURL=inboundfilters.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/scope.js b/shared/logger/node_modules/@sentry/core/esm/scope.js
new file mode 100644
index 0000000..0869323
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/scope.js
@@ -0,0 +1,555 @@
+import { isPlainObject, dateTimestampInSeconds, SyncPromise, logger, isThenable, arrayify, getGlobalSingleton } from '@sentry/utils';
+import { updateSession } from './session.js';
+
+/**
+ * Default value for maximum number of breadcrumbs added to an event.
+ */
+const DEFAULT_MAX_BREADCRUMBS = 100;
+
+/**
+ * Holds additional event information. {@link Scope.applyToEvent} will be
+ * called by the client before an event will be sent.
+ */
+class Scope {
+ /** Flag if notifying is happening. */
+
+ /** Callback for client to receive scope changes. */
+
+ /** Callback list that will be called after {@link applyToEvent}. */
+
+ /** Array of breadcrumbs. */
+
+ /** User */
+
+ /** Tags */
+
+ /** Extra */
+
+ /** Contexts */
+
+ /** Attachments */
+
+ /**
+ * A place to stash data which is needed at some point in the SDK's event processing pipeline but which shouldn't get
+ * sent to Sentry
+ */
+
+ /** Fingerprint */
+
+ /** Severity */
+ // eslint-disable-next-line deprecation/deprecation
+
+ /** Transaction Name */
+
+ /** Span */
+
+ /** Session */
+
+ /** Request Mode Session Status */
+
+ // NOTE: Any field which gets added here should get added not only to the constructor but also to the `clone` method.
+
+ constructor() {
+ this._notifyingListeners = false;
+ this._scopeListeners = [];
+ this._eventProcessors = [];
+ this._breadcrumbs = [];
+ this._attachments = [];
+ this._user = {};
+ this._tags = {};
+ this._extra = {};
+ this._contexts = {};
+ this._sdkProcessingMetadata = {};
+ }
+
+ /**
+ * Inherit values from the parent scope.
+ * @param scope to clone.
+ */
+ static clone(scope) {
+ const newScope = new Scope();
+ if (scope) {
+ newScope._breadcrumbs = [...scope._breadcrumbs];
+ newScope._tags = { ...scope._tags };
+ newScope._extra = { ...scope._extra };
+ newScope._contexts = { ...scope._contexts };
+ newScope._user = scope._user;
+ newScope._level = scope._level;
+ newScope._span = scope._span;
+ newScope._session = scope._session;
+ newScope._transactionName = scope._transactionName;
+ newScope._fingerprint = scope._fingerprint;
+ newScope._eventProcessors = [...scope._eventProcessors];
+ newScope._requestSession = scope._requestSession;
+ newScope._attachments = [...scope._attachments];
+ newScope._sdkProcessingMetadata = { ...scope._sdkProcessingMetadata };
+ }
+ return newScope;
+ }
+
+ /**
+ * Add internal on change listener. Used for sub SDKs that need to store the scope.
+ * @hidden
+ */
+ addScopeListener(callback) {
+ this._scopeListeners.push(callback);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ addEventProcessor(callback) {
+ this._eventProcessors.push(callback);
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setUser(user) {
+ this._user = user || {};
+ if (this._session) {
+ updateSession(this._session, { user });
+ }
+ this._notifyScopeListeners();
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getUser() {
+ return this._user;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getRequestSession() {
+ return this._requestSession;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setRequestSession(requestSession) {
+ this._requestSession = requestSession;
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setTags(tags) {
+ this._tags = {
+ ...this._tags,
+ ...tags,
+ };
+ this._notifyScopeListeners();
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setTag(key, value) {
+ this._tags = { ...this._tags, [key]: value };
+ this._notifyScopeListeners();
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setExtras(extras) {
+ this._extra = {
+ ...this._extra,
+ ...extras,
+ };
+ this._notifyScopeListeners();
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setExtra(key, extra) {
+ this._extra = { ...this._extra, [key]: extra };
+ this._notifyScopeListeners();
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setFingerprint(fingerprint) {
+ this._fingerprint = fingerprint;
+ this._notifyScopeListeners();
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setLevel(
+ // eslint-disable-next-line deprecation/deprecation
+ level,
+ ) {
+ this._level = level;
+ this._notifyScopeListeners();
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setTransactionName(name) {
+ this._transactionName = name;
+ this._notifyScopeListeners();
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setContext(key, context) {
+ if (context === null) {
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
+ delete this._contexts[key];
+ } else {
+ this._contexts[key] = context;
+ }
+
+ this._notifyScopeListeners();
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setSpan(span) {
+ this._span = span;
+ this._notifyScopeListeners();
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getSpan() {
+ return this._span;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getTransaction() {
+ // Often, this span (if it exists at all) will be a transaction, but it's not guaranteed to be. Regardless, it will
+ // have a pointer to the currently-active transaction.
+ const span = this.getSpan();
+ return span && span.transaction;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setSession(session) {
+ if (!session) {
+ delete this._session;
+ } else {
+ this._session = session;
+ }
+ this._notifyScopeListeners();
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getSession() {
+ return this._session;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ update(captureContext) {
+ if (!captureContext) {
+ return this;
+ }
+
+ if (typeof captureContext === 'function') {
+ const updatedScope = (captureContext )(this);
+ return updatedScope instanceof Scope ? updatedScope : this;
+ }
+
+ if (captureContext instanceof Scope) {
+ this._tags = { ...this._tags, ...captureContext._tags };
+ this._extra = { ...this._extra, ...captureContext._extra };
+ this._contexts = { ...this._contexts, ...captureContext._contexts };
+ if (captureContext._user && Object.keys(captureContext._user).length) {
+ this._user = captureContext._user;
+ }
+ if (captureContext._level) {
+ this._level = captureContext._level;
+ }
+ if (captureContext._fingerprint) {
+ this._fingerprint = captureContext._fingerprint;
+ }
+ if (captureContext._requestSession) {
+ this._requestSession = captureContext._requestSession;
+ }
+ } else if (isPlainObject(captureContext)) {
+ // eslint-disable-next-line no-param-reassign
+ captureContext = captureContext ;
+ this._tags = { ...this._tags, ...captureContext.tags };
+ this._extra = { ...this._extra, ...captureContext.extra };
+ this._contexts = { ...this._contexts, ...captureContext.contexts };
+ if (captureContext.user) {
+ this._user = captureContext.user;
+ }
+ if (captureContext.level) {
+ this._level = captureContext.level;
+ }
+ if (captureContext.fingerprint) {
+ this._fingerprint = captureContext.fingerprint;
+ }
+ if (captureContext.requestSession) {
+ this._requestSession = captureContext.requestSession;
+ }
+ }
+
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ clear() {
+ this._breadcrumbs = [];
+ this._tags = {};
+ this._extra = {};
+ this._user = {};
+ this._contexts = {};
+ this._level = undefined;
+ this._transactionName = undefined;
+ this._fingerprint = undefined;
+ this._requestSession = undefined;
+ this._span = undefined;
+ this._session = undefined;
+ this._notifyScopeListeners();
+ this._attachments = [];
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ addBreadcrumb(breadcrumb, maxBreadcrumbs) {
+ const maxCrumbs = typeof maxBreadcrumbs === 'number' ? maxBreadcrumbs : DEFAULT_MAX_BREADCRUMBS;
+
+ // No data has been changed, so don't notify scope listeners
+ if (maxCrumbs <= 0) {
+ return this;
+ }
+
+ const mergedBreadcrumb = {
+ timestamp: dateTimestampInSeconds(),
+ ...breadcrumb,
+ };
+ this._breadcrumbs = [...this._breadcrumbs, mergedBreadcrumb].slice(-maxCrumbs);
+ this._notifyScopeListeners();
+
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getLastBreadcrumb() {
+ return this._breadcrumbs[this._breadcrumbs.length - 1];
+ }
+
+ /**
+ * @inheritDoc
+ */
+ clearBreadcrumbs() {
+ this._breadcrumbs = [];
+ this._notifyScopeListeners();
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ addAttachment(attachment) {
+ this._attachments.push(attachment);
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getAttachments() {
+ return this._attachments;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ clearAttachments() {
+ this._attachments = [];
+ return this;
+ }
+
+ /**
+ * Applies data from the scope to the event and runs all event processors on it.
+ *
+ * @param event Event
+ * @param hint Object containing additional information about the original exception, for use by the event processors.
+ * @hidden
+ */
+ applyToEvent(event, hint = {}) {
+ if (this._extra && Object.keys(this._extra).length) {
+ event.extra = { ...this._extra, ...event.extra };
+ }
+ if (this._tags && Object.keys(this._tags).length) {
+ event.tags = { ...this._tags, ...event.tags };
+ }
+ if (this._user && Object.keys(this._user).length) {
+ event.user = { ...this._user, ...event.user };
+ }
+ if (this._contexts && Object.keys(this._contexts).length) {
+ event.contexts = { ...this._contexts, ...event.contexts };
+ }
+ if (this._level) {
+ event.level = this._level;
+ }
+ if (this._transactionName) {
+ event.transaction = this._transactionName;
+ }
+
+ // We want to set the trace context for normal events only if there isn't already
+ // a trace context on the event. There is a product feature in place where we link
+ // errors with transaction and it relies on that.
+ if (this._span) {
+ event.contexts = { trace: this._span.getTraceContext(), ...event.contexts };
+ const transaction = this._span.transaction;
+ if (transaction) {
+ event.sdkProcessingMetadata = {
+ dynamicSamplingContext: transaction.getDynamicSamplingContext(),
+ ...event.sdkProcessingMetadata,
+ };
+ const transactionName = transaction.name;
+ if (transactionName) {
+ event.tags = { transaction: transactionName, ...event.tags };
+ }
+ }
+ }
+
+ this._applyFingerprint(event);
+
+ event.breadcrumbs = [...(event.breadcrumbs || []), ...this._breadcrumbs];
+ event.breadcrumbs = event.breadcrumbs.length > 0 ? event.breadcrumbs : undefined;
+
+ event.sdkProcessingMetadata = { ...event.sdkProcessingMetadata, ...this._sdkProcessingMetadata };
+
+ return this._notifyEventProcessors([...getGlobalEventProcessors(), ...this._eventProcessors], event, hint);
+ }
+
+ /**
+ * Add data which will be accessible during event processing but won't get sent to Sentry
+ */
+ setSDKProcessingMetadata(newData) {
+ this._sdkProcessingMetadata = { ...this._sdkProcessingMetadata, ...newData };
+
+ return this;
+ }
+
+ /**
+ * This will be called after {@link applyToEvent} is finished.
+ */
+ _notifyEventProcessors(
+ processors,
+ event,
+ hint,
+ index = 0,
+ ) {
+ return new SyncPromise((resolve, reject) => {
+ const processor = processors[index];
+ if (event === null || typeof processor !== 'function') {
+ resolve(event);
+ } else {
+ const result = processor({ ...event }, hint) ;
+
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ processor.id &&
+ result === null &&
+ logger.log(`Event processor "${processor.id}" dropped event`);
+
+ if (isThenable(result)) {
+ void result
+ .then(final => this._notifyEventProcessors(processors, final, hint, index + 1).then(resolve))
+ .then(null, reject);
+ } else {
+ void this._notifyEventProcessors(processors, result, hint, index + 1)
+ .then(resolve)
+ .then(null, reject);
+ }
+ }
+ });
+ }
+
+ /**
+ * This will be called on every set call.
+ */
+ _notifyScopeListeners() {
+ // We need this check for this._notifyingListeners to be able to work on scope during updates
+ // If this check is not here we'll produce endless recursion when something is done with the scope
+ // during the callback.
+ if (!this._notifyingListeners) {
+ this._notifyingListeners = true;
+ this._scopeListeners.forEach(callback => {
+ callback(this);
+ });
+ this._notifyingListeners = false;
+ }
+ }
+
+ /**
+ * Applies fingerprint from the scope to the event if there's one,
+ * uses message if there's one instead or get rid of empty fingerprint
+ */
+ _applyFingerprint(event) {
+ // Make sure it's an array first and we actually have something in place
+ event.fingerprint = event.fingerprint ? arrayify(event.fingerprint) : [];
+
+ // If we have something on the scope, then merge it with event
+ if (this._fingerprint) {
+ event.fingerprint = event.fingerprint.concat(this._fingerprint);
+ }
+
+ // If we have no data at all, remove empty array default
+ if (event.fingerprint && !event.fingerprint.length) {
+ delete event.fingerprint;
+ }
+ }
+}
+
+/**
+ * Returns the global event processors.
+ */
+function getGlobalEventProcessors() {
+ return getGlobalSingleton('globalEventProcessors', () => []);
+}
+
+/**
+ * Add a EventProcessor to be kept globally.
+ * @param callback EventProcessor to add
+ */
+function addGlobalEventProcessor(callback) {
+ getGlobalEventProcessors().push(callback);
+}
+
+export { Scope, addGlobalEventProcessor };
+//# sourceMappingURL=scope.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/sdk.js b/shared/logger/node_modules/@sentry/core/esm/sdk.js
new file mode 100644
index 0000000..5cb2237
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/sdk.js
@@ -0,0 +1,35 @@
+import { logger } from '@sentry/utils';
+import { getCurrentHub } from './hub.js';
+
+/** A class object that can instantiate Client objects. */
+
+/**
+ * Internal function to create a new SDK client instance. The client is
+ * installed and then bound to the current scope.
+ *
+ * @param clientClass The client class to instantiate.
+ * @param options Options to pass to the client.
+ */
+function initAndBind(
+ clientClass,
+ options,
+) {
+ if (options.debug === true) {
+ if ((typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__)) {
+ logger.enable();
+ } else {
+ // use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped
+ // eslint-disable-next-line no-console
+ console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.');
+ }
+ }
+ const hub = getCurrentHub();
+ const scope = hub.getScope();
+ scope.update(options.initialScope);
+
+ const client = new clientClass(options);
+ hub.bindClient(client);
+}
+
+export { initAndBind };
+//# sourceMappingURL=sdk.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/session.js b/shared/logger/node_modules/@sentry/core/esm/session.js
new file mode 100644
index 0000000..48a948f
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/session.js
@@ -0,0 +1,155 @@
+import { timestampInSeconds, uuid4, dropUndefinedKeys } from '@sentry/utils';
+
+/**
+ * Creates a new `Session` object by setting certain default parameters. If optional @param context
+ * is passed, the passed properties are applied to the session object.
+ *
+ * @param context (optional) additional properties to be applied to the returned session object
+ *
+ * @returns a new `Session` object
+ */
+function makeSession(context) {
+ // Both timestamp and started are in seconds since the UNIX epoch.
+ const startingTime = timestampInSeconds();
+
+ const session = {
+ sid: uuid4(),
+ init: true,
+ timestamp: startingTime,
+ started: startingTime,
+ duration: 0,
+ status: 'ok',
+ errors: 0,
+ ignoreDuration: false,
+ toJSON: () => sessionToJSON(session),
+ };
+
+ if (context) {
+ updateSession(session, context);
+ }
+
+ return session;
+}
+
+/**
+ * Updates a session object with the properties passed in the context.
+ *
+ * Note that this function mutates the passed object and returns void.
+ * (Had to do this instead of returning a new and updated session because closing and sending a session
+ * makes an update to the session after it was passed to the sending logic.
+ * @see BaseClient.captureSession )
+ *
+ * @param session the `Session` to update
+ * @param context the `SessionContext` holding the properties that should be updated in @param session
+ */
+// eslint-disable-next-line complexity
+function updateSession(session, context = {}) {
+ if (context.user) {
+ if (!session.ipAddress && context.user.ip_address) {
+ session.ipAddress = context.user.ip_address;
+ }
+
+ if (!session.did && !context.did) {
+ session.did = context.user.id || context.user.email || context.user.username;
+ }
+ }
+
+ session.timestamp = context.timestamp || timestampInSeconds();
+
+ if (context.ignoreDuration) {
+ session.ignoreDuration = context.ignoreDuration;
+ }
+ if (context.sid) {
+ // Good enough uuid validation. — Kamil
+ session.sid = context.sid.length === 32 ? context.sid : uuid4();
+ }
+ if (context.init !== undefined) {
+ session.init = context.init;
+ }
+ if (!session.did && context.did) {
+ session.did = `${context.did}`;
+ }
+ if (typeof context.started === 'number') {
+ session.started = context.started;
+ }
+ if (session.ignoreDuration) {
+ session.duration = undefined;
+ } else if (typeof context.duration === 'number') {
+ session.duration = context.duration;
+ } else {
+ const duration = session.timestamp - session.started;
+ session.duration = duration >= 0 ? duration : 0;
+ }
+ if (context.release) {
+ session.release = context.release;
+ }
+ if (context.environment) {
+ session.environment = context.environment;
+ }
+ if (!session.ipAddress && context.ipAddress) {
+ session.ipAddress = context.ipAddress;
+ }
+ if (!session.userAgent && context.userAgent) {
+ session.userAgent = context.userAgent;
+ }
+ if (typeof context.errors === 'number') {
+ session.errors = context.errors;
+ }
+ if (context.status) {
+ session.status = context.status;
+ }
+}
+
+/**
+ * Closes a session by setting its status and updating the session object with it.
+ * Internally calls `updateSession` to update the passed session object.
+ *
+ * Note that this function mutates the passed session (@see updateSession for explanation).
+ *
+ * @param session the `Session` object to be closed
+ * @param status the `SessionStatus` with which the session was closed. If you don't pass a status,
+ * this function will keep the previously set status, unless it was `'ok'` in which case
+ * it is changed to `'exited'`.
+ */
+function closeSession(session, status) {
+ let context = {};
+ if (status) {
+ context = { status };
+ } else if (session.status === 'ok') {
+ context = { status: 'exited' };
+ }
+
+ updateSession(session, context);
+}
+
+/**
+ * Serializes a passed session object to a JSON object with a slightly different structure.
+ * This is necessary because the Sentry backend requires a slightly different schema of a session
+ * than the one the JS SDKs use internally.
+ *
+ * @param session the session to be converted
+ *
+ * @returns a JSON object of the passed session
+ */
+function sessionToJSON(session) {
+ return dropUndefinedKeys({
+ sid: `${session.sid}`,
+ init: session.init,
+ // Make sure that sec is converted to ms for date constructor
+ started: new Date(session.started * 1000).toISOString(),
+ timestamp: new Date(session.timestamp * 1000).toISOString(),
+ status: session.status,
+ errors: session.errors,
+ did: typeof session.did === 'number' || typeof session.did === 'string' ? `${session.did}` : undefined,
+ duration: session.duration,
+ attrs: {
+ release: session.release,
+ environment: session.environment,
+ ip_address: session.ipAddress,
+ user_agent: session.userAgent,
+ },
+ });
+}
+
+export { closeSession, makeSession, updateSession };
+//# sourceMappingURL=session.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/tracing/errors.js b/shared/logger/node_modules/@sentry/core/esm/tracing/errors.js
new file mode 100644
index 0000000..ddfd49b
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/tracing/errors.js
@@ -0,0 +1,36 @@
+import { addInstrumentationHandler, logger } from '@sentry/utils';
+import { getActiveTransaction } from './utils.js';
+
+let errorsInstrumented = false;
+
+/**
+ * Configures global error listeners
+ */
+function registerErrorInstrumentation() {
+ if (errorsInstrumented) {
+ return;
+ }
+
+ errorsInstrumented = true;
+ addInstrumentationHandler('error', errorCallback);
+ addInstrumentationHandler('unhandledrejection', errorCallback);
+}
+
+/**
+ * If an error or unhandled promise occurs, we mark the active transaction as failed
+ */
+function errorCallback() {
+ const activeTransaction = getActiveTransaction();
+ if (activeTransaction) {
+ const status = 'internal_error';
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log(`[Tracing] Transaction: ${status} -> Global error occured`);
+ activeTransaction.setStatus(status);
+ }
+}
+
+// The function name will be lost when bundling but we need to be able to identify this listener later to maintain the
+// node.js default exit behaviour
+errorCallback.tag = 'sentry_tracingErrorCallback';
+
+export { registerErrorInstrumentation };
+//# sourceMappingURL=errors.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/tracing/hubextensions.js b/shared/logger/node_modules/@sentry/core/esm/tracing/hubextensions.js
new file mode 100644
index 0000000..f96f922
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/tracing/hubextensions.js
@@ -0,0 +1,241 @@
+import { logger, isNaN } from '@sentry/utils';
+import { getMainCarrier } from '../hub.js';
+import { hasTracingEnabled } from '../utils/hasTracingEnabled.js';
+import { registerErrorInstrumentation } from './errors.js';
+import { IdleTransaction } from './idletransaction.js';
+import { Transaction } from './transaction.js';
+
+/** Returns all trace headers that are currently on the top scope. */
+function traceHeaders() {
+ const scope = this.getScope();
+ const span = scope.getSpan();
+
+ return span
+ ? {
+ 'sentry-trace': span.toTraceparent(),
+ }
+ : {};
+}
+
+/**
+ * Makes a sampling decision for the given transaction and stores it on the transaction.
+ *
+ * Called every time a transaction is created. Only transactions which emerge with a `sampled` value of `true` will be
+ * sent to Sentry.
+ *
+ * @param transaction: The transaction needing a sampling decision
+ * @param options: The current client's options, so we can access `tracesSampleRate` and/or `tracesSampler`
+ * @param samplingContext: Default and user-provided data which may be used to help make the decision
+ *
+ * @returns The given transaction with its `sampled` value set
+ */
+function sample(
+ transaction,
+ options,
+ samplingContext,
+) {
+ // nothing to do if tracing is not enabled
+ if (!hasTracingEnabled(options)) {
+ transaction.sampled = false;
+ return transaction;
+ }
+
+ // if the user has forced a sampling decision by passing a `sampled` value in their transaction context, go with that
+ if (transaction.sampled !== undefined) {
+ transaction.setMetadata({
+ sampleRate: Number(transaction.sampled),
+ });
+ return transaction;
+ }
+
+ // we would have bailed already if neither `tracesSampler` nor `tracesSampleRate` nor `enableTracing` were defined, so one of these should
+ // work; prefer the hook if so
+ let sampleRate;
+ if (typeof options.tracesSampler === 'function') {
+ sampleRate = options.tracesSampler(samplingContext);
+ transaction.setMetadata({
+ sampleRate: Number(sampleRate),
+ });
+ } else if (samplingContext.parentSampled !== undefined) {
+ sampleRate = samplingContext.parentSampled;
+ } else if (typeof options.tracesSampleRate !== 'undefined') {
+ sampleRate = options.tracesSampleRate;
+ transaction.setMetadata({
+ sampleRate: Number(sampleRate),
+ });
+ } else {
+ // When `enableTracing === true`, we use a sample rate of 100%
+ sampleRate = 1;
+ transaction.setMetadata({
+ sampleRate,
+ });
+ }
+
+ // Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The
+ // only valid values are booleans or numbers between 0 and 1.)
+ if (!isValidSampleRate(sampleRate)) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('[Tracing] Discarding transaction because of invalid sample rate.');
+ transaction.sampled = false;
+ return transaction;
+ }
+
+ // if the function returned 0 (or false), or if `tracesSampleRate` is 0, it's a sign the transaction should be dropped
+ if (!sampleRate) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.log(
+ `[Tracing] Discarding transaction because ${
+ typeof options.tracesSampler === 'function'
+ ? 'tracesSampler returned 0 or false'
+ : 'a negative sampling decision was inherited or tracesSampleRate is set to 0'
+ }`,
+ );
+ transaction.sampled = false;
+ return transaction;
+ }
+
+ // Now we roll the dice. Math.random is inclusive of 0, but not of 1, so strict < is safe here. In case sampleRate is
+ // a boolean, the < comparison will cause it to be automatically cast to 1 if it's true and 0 if it's false.
+ transaction.sampled = Math.random() < (sampleRate );
+
+ // if we're not going to keep it, we're done
+ if (!transaction.sampled) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.log(
+ `[Tracing] Discarding transaction because it's not included in the random sample (sampling rate = ${Number(
+ sampleRate,
+ )})`,
+ );
+ return transaction;
+ }
+
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log(`[Tracing] starting ${transaction.op} transaction - ${transaction.name}`);
+ return transaction;
+}
+
+/**
+ * Checks the given sample rate to make sure it is valid type and value (a boolean, or a number between 0 and 1).
+ */
+function isValidSampleRate(rate) {
+ // we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ if (isNaN(rate) || !(typeof rate === 'number' || typeof rate === 'boolean')) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.warn(
+ `[Tracing] Given sample rate is invalid. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify(
+ rate,
+ )} of type ${JSON.stringify(typeof rate)}.`,
+ );
+ return false;
+ }
+
+ // in case sampleRate is a boolean, it will get automatically cast to 1 if it's true and 0 if it's false
+ if (rate < 0 || rate > 1) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.warn(`[Tracing] Given sample rate is invalid. Sample rate must be between 0 and 1. Got ${rate}.`);
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Creates a new transaction and adds a sampling decision if it doesn't yet have one.
+ *
+ * The Hub.startTransaction method delegates to this method to do its work, passing the Hub instance in as `this`, as if
+ * it had been called on the hub directly. Exists as a separate function so that it can be injected into the class as an
+ * "extension method."
+ *
+ * @param this: The Hub starting the transaction
+ * @param transactionContext: Data used to configure the transaction
+ * @param CustomSamplingContext: Optional data to be provided to the `tracesSampler` function (if any)
+ *
+ * @returns The new transaction
+ *
+ * @see {@link Hub.startTransaction}
+ */
+function _startTransaction(
+
+ transactionContext,
+ customSamplingContext,
+) {
+ const client = this.getClient();
+ const options = (client && client.getOptions()) || {};
+
+ const configInstrumenter = options.instrumenter || 'sentry';
+ const transactionInstrumenter = transactionContext.instrumenter || 'sentry';
+
+ if (configInstrumenter !== transactionInstrumenter) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.error(
+ `A transaction was started with instrumenter=\`${transactionInstrumenter}\`, but the SDK is configured with the \`${configInstrumenter}\` instrumenter.
+The transaction will not be sampled. Please use the ${configInstrumenter} instrumentation to start transactions.`,
+ );
+
+ transactionContext.sampled = false;
+ }
+
+ let transaction = new Transaction(transactionContext, this);
+ transaction = sample(transaction, options, {
+ parentSampled: transactionContext.parentSampled,
+ transactionContext,
+ ...customSamplingContext,
+ });
+ if (transaction.sampled) {
+ transaction.initSpanRecorder(options._experiments && (options._experiments.maxSpans ));
+ }
+ if (client && client.emit) {
+ client.emit('startTransaction', transaction);
+ }
+ return transaction;
+}
+
+/**
+ * Create new idle transaction.
+ */
+function startIdleTransaction(
+ hub,
+ transactionContext,
+ idleTimeout,
+ finalTimeout,
+ onScope,
+ customSamplingContext,
+ heartbeatInterval,
+) {
+ const client = hub.getClient();
+ const options = (client && client.getOptions()) || {};
+
+ let transaction = new IdleTransaction(transactionContext, hub, idleTimeout, finalTimeout, heartbeatInterval, onScope);
+ transaction = sample(transaction, options, {
+ parentSampled: transactionContext.parentSampled,
+ transactionContext,
+ ...customSamplingContext,
+ });
+ if (transaction.sampled) {
+ transaction.initSpanRecorder(options._experiments && (options._experiments.maxSpans ));
+ }
+ if (client && client.emit) {
+ client.emit('startTransaction', transaction);
+ }
+ return transaction;
+}
+
+/**
+ * Adds tracing extensions to the global hub.
+ */
+function addTracingExtensions() {
+ const carrier = getMainCarrier();
+ if (!carrier.__SENTRY__) {
+ return;
+ }
+ carrier.__SENTRY__.extensions = carrier.__SENTRY__.extensions || {};
+ if (!carrier.__SENTRY__.extensions.startTransaction) {
+ carrier.__SENTRY__.extensions.startTransaction = _startTransaction;
+ }
+ if (!carrier.__SENTRY__.extensions.traceHeaders) {
+ carrier.__SENTRY__.extensions.traceHeaders = traceHeaders;
+ }
+
+ registerErrorInstrumentation();
+}
+
+export { addTracingExtensions, startIdleTransaction };
+//# sourceMappingURL=hubextensions.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/tracing/idletransaction.js b/shared/logger/node_modules/@sentry/core/esm/tracing/idletransaction.js
new file mode 100644
index 0000000..760c450
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/tracing/idletransaction.js
@@ -0,0 +1,347 @@
+import { logger, timestampInSeconds } from '@sentry/utils';
+import { SpanRecorder } from './span.js';
+import { Transaction } from './transaction.js';
+
+const TRACING_DEFAULTS = {
+ idleTimeout: 1000,
+ finalTimeout: 30000,
+ heartbeatInterval: 5000,
+};
+
+const FINISH_REASON_TAG = 'finishReason';
+
+const IDLE_TRANSACTION_FINISH_REASONS = [
+ 'heartbeatFailed',
+ 'idleTimeout',
+ 'documentHidden',
+ 'finalTimeout',
+ 'externalFinish',
+ 'cancelled',
+];
+
+/**
+ * @inheritDoc
+ */
+class IdleTransactionSpanRecorder extends SpanRecorder {
+ constructor(
+ _pushActivity,
+ _popActivity,
+ transactionSpanId,
+ maxlen,
+ ) {
+ super(maxlen);this._pushActivity = _pushActivity;this._popActivity = _popActivity;this.transactionSpanId = transactionSpanId; }
+
+ /**
+ * @inheritDoc
+ */
+ add(span) {
+ // We should make sure we do not push and pop activities for
+ // the transaction that this span recorder belongs to.
+ if (span.spanId !== this.transactionSpanId) {
+ // We patch span.finish() to pop an activity after setting an endTimestamp.
+ span.finish = (endTimestamp) => {
+ span.endTimestamp = typeof endTimestamp === 'number' ? endTimestamp : timestampInSeconds();
+ this._popActivity(span.spanId);
+ };
+
+ // We should only push new activities if the span does not have an end timestamp.
+ if (span.endTimestamp === undefined) {
+ this._pushActivity(span.spanId);
+ }
+ }
+
+ super.add(span);
+ }
+}
+
+/**
+ * An IdleTransaction is a transaction that automatically finishes. It does this by tracking child spans as activities.
+ * You can have multiple IdleTransactions active, but if the `onScope` option is specified, the idle transaction will
+ * put itself on the scope on creation.
+ */
+class IdleTransaction extends Transaction {
+ // Activities store a list of active spans
+ __init() {this.activities = {};}
+
+ // Track state of activities in previous heartbeat
+
+ // Amount of times heartbeat has counted. Will cause transaction to finish after 3 beats.
+ __init2() {this._heartbeatCounter = 0;}
+
+ // We should not use heartbeat if we finished a transaction
+ __init3() {this._finished = false;}
+
+ // Idle timeout was canceled and we should finish the transaction with the last span end.
+ __init4() {this._idleTimeoutCanceledPermanently = false;}
+
+ __init5() {this._beforeFinishCallbacks = [];}
+
+ /**
+ * Timer that tracks Transaction idleTimeout
+ */
+
+ __init6() {this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[4];}
+
+ constructor(
+ transactionContext,
+ _idleHub,
+ /**
+ * The time to wait in ms until the idle transaction will be finished. This timer is started each time
+ * there are no active spans on this transaction.
+ */
+ _idleTimeout = TRACING_DEFAULTS.idleTimeout,
+ /**
+ * The final value in ms that a transaction cannot exceed
+ */
+ _finalTimeout = TRACING_DEFAULTS.finalTimeout,
+ _heartbeatInterval = TRACING_DEFAULTS.heartbeatInterval,
+ // Whether or not the transaction should put itself on the scope when it starts and pop itself off when it ends
+ _onScope = false,
+ ) {
+ super(transactionContext, _idleHub);this._idleHub = _idleHub;this._idleTimeout = _idleTimeout;this._finalTimeout = _finalTimeout;this._heartbeatInterval = _heartbeatInterval;this._onScope = _onScope;IdleTransaction.prototype.__init.call(this);IdleTransaction.prototype.__init2.call(this);IdleTransaction.prototype.__init3.call(this);IdleTransaction.prototype.__init4.call(this);IdleTransaction.prototype.__init5.call(this);IdleTransaction.prototype.__init6.call(this);
+ if (_onScope) {
+ // We set the transaction here on the scope so error events pick up the trace
+ // context and attach it to the error.
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log(`Setting idle transaction on scope. Span ID: ${this.spanId}`);
+ _idleHub.configureScope(scope => scope.setSpan(this));
+ }
+
+ this._restartIdleTimeout();
+ setTimeout(() => {
+ if (!this._finished) {
+ this.setStatus('deadline_exceeded');
+ this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[3];
+ this.finish();
+ }
+ }, this._finalTimeout);
+ }
+
+ /** {@inheritDoc} */
+ finish(endTimestamp = timestampInSeconds()) {
+ this._finished = true;
+ this.activities = {};
+
+ if (this.op === 'ui.action.click') {
+ this.setTag(FINISH_REASON_TAG, this._finishReason);
+ }
+
+ if (this.spanRecorder) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.log('[Tracing] finishing IdleTransaction', new Date(endTimestamp * 1000).toISOString(), this.op);
+
+ for (const callback of this._beforeFinishCallbacks) {
+ callback(this, endTimestamp);
+ }
+
+ this.spanRecorder.spans = this.spanRecorder.spans.filter((span) => {
+ // If we are dealing with the transaction itself, we just return it
+ if (span.spanId === this.spanId) {
+ return true;
+ }
+
+ // We cancel all pending spans with status "cancelled" to indicate the idle transaction was finished early
+ if (!span.endTimestamp) {
+ span.endTimestamp = endTimestamp;
+ span.setStatus('cancelled');
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.log('[Tracing] cancelling span since transaction ended early', JSON.stringify(span, undefined, 2));
+ }
+
+ const keepSpan = span.startTimestamp < endTimestamp;
+ if (!keepSpan) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.log(
+ '[Tracing] discarding Span since it happened after Transaction was finished',
+ JSON.stringify(span, undefined, 2),
+ );
+ }
+ return keepSpan;
+ });
+
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log('[Tracing] flushing IdleTransaction');
+ } else {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log('[Tracing] No active IdleTransaction');
+ }
+
+ // if `this._onScope` is `true`, the transaction put itself on the scope when it started
+ if (this._onScope) {
+ const scope = this._idleHub.getScope();
+ if (scope.getTransaction() === this) {
+ scope.setSpan(undefined);
+ }
+ }
+
+ return super.finish(endTimestamp);
+ }
+
+ /**
+ * Register a callback function that gets excecuted before the transaction finishes.
+ * Useful for cleanup or if you want to add any additional spans based on current context.
+ *
+ * This is exposed because users have no other way of running something before an idle transaction
+ * finishes.
+ */
+ registerBeforeFinishCallback(callback) {
+ this._beforeFinishCallbacks.push(callback);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ initSpanRecorder(maxlen) {
+ if (!this.spanRecorder) {
+ const pushActivity = (id) => {
+ if (this._finished) {
+ return;
+ }
+ this._pushActivity(id);
+ };
+ const popActivity = (id) => {
+ if (this._finished) {
+ return;
+ }
+ this._popActivity(id);
+ };
+
+ this.spanRecorder = new IdleTransactionSpanRecorder(pushActivity, popActivity, this.spanId, maxlen);
+
+ // Start heartbeat so that transactions do not run forever.
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log('Starting heartbeat');
+ this._pingHeartbeat();
+ }
+ this.spanRecorder.add(this);
+ }
+
+ /**
+ * Cancels the existing idle timeout, if there is one.
+ * @param restartOnChildSpanChange Default is `true`.
+ * If set to false the transaction will end
+ * with the last child span.
+ */
+ cancelIdleTimeout(
+ endTimestamp,
+ {
+ restartOnChildSpanChange,
+ }
+
+ = {
+ restartOnChildSpanChange: true,
+ },
+ ) {
+ this._idleTimeoutCanceledPermanently = restartOnChildSpanChange === false;
+ if (this._idleTimeoutID) {
+ clearTimeout(this._idleTimeoutID);
+ this._idleTimeoutID = undefined;
+
+ if (Object.keys(this.activities).length === 0 && this._idleTimeoutCanceledPermanently) {
+ this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[5];
+ this.finish(endTimestamp);
+ }
+ }
+ }
+
+ /**
+ * Temporary method used to externally set the transaction's `finishReason`
+ *
+ * ** WARNING**
+ * This is for the purpose of experimentation only and will be removed in the near future, do not use!
+ *
+ * @internal
+ *
+ */
+ setFinishReason(reason) {
+ this._finishReason = reason;
+ }
+
+ /**
+ * Restarts idle timeout, if there is no running idle timeout it will start one.
+ */
+ _restartIdleTimeout(endTimestamp) {
+ this.cancelIdleTimeout();
+ this._idleTimeoutID = setTimeout(() => {
+ if (!this._finished && Object.keys(this.activities).length === 0) {
+ this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[1];
+ this.finish(endTimestamp);
+ }
+ }, this._idleTimeout);
+ }
+
+ /**
+ * Start tracking a specific activity.
+ * @param spanId The span id that represents the activity
+ */
+ _pushActivity(spanId) {
+ this.cancelIdleTimeout(undefined, { restartOnChildSpanChange: !this._idleTimeoutCanceledPermanently });
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log(`[Tracing] pushActivity: ${spanId}`);
+ this.activities[spanId] = true;
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log('[Tracing] new activities count', Object.keys(this.activities).length);
+ }
+
+ /**
+ * Remove an activity from usage
+ * @param spanId The span id that represents the activity
+ */
+ _popActivity(spanId) {
+ if (this.activities[spanId]) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log(`[Tracing] popActivity ${spanId}`);
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
+ delete this.activities[spanId];
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log('[Tracing] new activities count', Object.keys(this.activities).length);
+ }
+
+ if (Object.keys(this.activities).length === 0) {
+ const endTimestamp = timestampInSeconds();
+ if (this._idleTimeoutCanceledPermanently) {
+ this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[5];
+ this.finish(endTimestamp);
+ } else {
+ // We need to add the timeout here to have the real endtimestamp of the transaction
+ // Remember timestampInSeconds is in seconds, timeout is in ms
+ this._restartIdleTimeout(endTimestamp + this._idleTimeout / 1000);
+ }
+ }
+ }
+
+ /**
+ * Checks when entries of this.activities are not changing for 3 beats.
+ * If this occurs we finish the transaction.
+ */
+ _beat() {
+ // We should not be running heartbeat if the idle transaction is finished.
+ if (this._finished) {
+ return;
+ }
+
+ const heartbeatString = Object.keys(this.activities).join('');
+
+ if (heartbeatString === this._prevHeartbeatString) {
+ this._heartbeatCounter++;
+ } else {
+ this._heartbeatCounter = 1;
+ }
+
+ this._prevHeartbeatString = heartbeatString;
+
+ if (this._heartbeatCounter >= 3) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log('[Tracing] Transaction finished because of no change for 3 heart beats');
+ this.setStatus('deadline_exceeded');
+ this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[0];
+ this.finish();
+ } else {
+ this._pingHeartbeat();
+ }
+ }
+
+ /**
+ * Pings the heartbeat
+ */
+ _pingHeartbeat() {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log(`pinging Heartbeat -> current counter: ${this._heartbeatCounter}`);
+ setTimeout(() => {
+ this._beat();
+ }, this._heartbeatInterval);
+ }
+}
+
+export { IdleTransaction, IdleTransactionSpanRecorder, TRACING_DEFAULTS };
+//# sourceMappingURL=idletransaction.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/tracing/span.js b/shared/logger/node_modules/@sentry/core/esm/tracing/span.js
new file mode 100644
index 0000000..83ad954
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/tracing/span.js
@@ -0,0 +1,378 @@
+import { uuid4, timestampInSeconds, logger, dropUndefinedKeys } from '@sentry/utils';
+
+/**
+ * Keeps track of finished spans for a given transaction
+ * @internal
+ * @hideconstructor
+ * @hidden
+ */
+class SpanRecorder {
+ __init() {this.spans = [];}
+
+ constructor(maxlen = 1000) {SpanRecorder.prototype.__init.call(this);
+ this._maxlen = maxlen;
+ }
+
+ /**
+ * This is just so that we don't run out of memory while recording a lot
+ * of spans. At some point we just stop and flush out the start of the
+ * trace tree (i.e.the first n spans with the smallest
+ * start_timestamp).
+ */
+ add(span) {
+ if (this.spans.length > this._maxlen) {
+ span.spanRecorder = undefined;
+ } else {
+ this.spans.push(span);
+ }
+ }
+}
+
+/**
+ * Span contains all data about a span
+ */
+class Span {
+ /**
+ * @inheritDoc
+ */
+ __init2() {this.traceId = uuid4();}
+
+ /**
+ * @inheritDoc
+ */
+ __init3() {this.spanId = uuid4().substring(16);}
+
+ /**
+ * @inheritDoc
+ */
+
+ /**
+ * Internal keeper of the status
+ */
+
+ /**
+ * @inheritDoc
+ */
+
+ /**
+ * Timestamp in seconds when the span was created.
+ */
+ __init4() {this.startTimestamp = timestampInSeconds();}
+
+ /**
+ * Timestamp in seconds when the span ended.
+ */
+
+ /**
+ * @inheritDoc
+ */
+
+ /**
+ * @inheritDoc
+ */
+
+ /**
+ * @inheritDoc
+ */
+ __init5() {this.tags = {};}
+
+ /**
+ * @inheritDoc
+ */
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ __init6() {this.data = {};}
+
+ /**
+ * List of spans that were finalized
+ */
+
+ /**
+ * @inheritDoc
+ */
+
+ /**
+ * The instrumenter that created this span.
+ */
+ __init7() {this.instrumenter = 'sentry';}
+
+ /**
+ * You should never call the constructor manually, always use `Sentry.startTransaction()`
+ * or call `startChild()` on an existing span.
+ * @internal
+ * @hideconstructor
+ * @hidden
+ */
+ constructor(spanContext) {Span.prototype.__init2.call(this);Span.prototype.__init3.call(this);Span.prototype.__init4.call(this);Span.prototype.__init5.call(this);Span.prototype.__init6.call(this);Span.prototype.__init7.call(this);
+ if (!spanContext) {
+ return this;
+ }
+ if (spanContext.traceId) {
+ this.traceId = spanContext.traceId;
+ }
+ if (spanContext.spanId) {
+ this.spanId = spanContext.spanId;
+ }
+ if (spanContext.parentSpanId) {
+ this.parentSpanId = spanContext.parentSpanId;
+ }
+ // We want to include booleans as well here
+ if ('sampled' in spanContext) {
+ this.sampled = spanContext.sampled;
+ }
+ if (spanContext.op) {
+ this.op = spanContext.op;
+ }
+ if (spanContext.description) {
+ this.description = spanContext.description;
+ }
+ if (spanContext.data) {
+ this.data = spanContext.data;
+ }
+ if (spanContext.tags) {
+ this.tags = spanContext.tags;
+ }
+ if (spanContext.status) {
+ this.status = spanContext.status;
+ }
+ if (spanContext.startTimestamp) {
+ this.startTimestamp = spanContext.startTimestamp;
+ }
+ if (spanContext.endTimestamp) {
+ this.endTimestamp = spanContext.endTimestamp;
+ }
+ if (spanContext.instrumenter) {
+ this.instrumenter = spanContext.instrumenter;
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ startChild(
+ spanContext,
+ ) {
+ const childSpan = new Span({
+ ...spanContext,
+ parentSpanId: this.spanId,
+ sampled: this.sampled,
+ traceId: this.traceId,
+ });
+
+ childSpan.spanRecorder = this.spanRecorder;
+ if (childSpan.spanRecorder) {
+ childSpan.spanRecorder.add(childSpan);
+ }
+
+ childSpan.transaction = this.transaction;
+
+ if ((typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && childSpan.transaction) {
+ const opStr = (spanContext && spanContext.op) || '< unknown op >';
+ const nameStr = childSpan.transaction.name || '< unknown name >';
+ const idStr = childSpan.transaction.spanId;
+
+ const logMessage = `[Tracing] Starting '${opStr}' span on transaction '${nameStr}' (${idStr}).`;
+ childSpan.transaction.metadata.spanMetadata[childSpan.spanId] = { logMessage };
+ logger.log(logMessage);
+ }
+
+ return childSpan;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setTag(key, value) {
+ this.tags = { ...this.tags, [key]: value };
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
+ setData(key, value) {
+ this.data = { ...this.data, [key]: value };
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setStatus(value) {
+ this.status = value;
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setHttpStatus(httpStatus) {
+ this.setTag('http.status_code', String(httpStatus));
+ this.setData('http.response.status_code', httpStatus);
+ const spanStatus = spanStatusfromHttpCode(httpStatus);
+ if (spanStatus !== 'unknown_error') {
+ this.setStatus(spanStatus);
+ }
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ isSuccess() {
+ return this.status === 'ok';
+ }
+
+ /**
+ * @inheritDoc
+ */
+ finish(endTimestamp) {
+ if (
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ // Don't call this for transactions
+ this.transaction &&
+ this.transaction.spanId !== this.spanId
+ ) {
+ const { logMessage } = this.transaction.metadata.spanMetadata[this.spanId];
+ if (logMessage) {
+ logger.log((logMessage ).replace('Starting', 'Finishing'));
+ }
+ }
+
+ this.endTimestamp = typeof endTimestamp === 'number' ? endTimestamp : timestampInSeconds();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ toTraceparent() {
+ let sampledString = '';
+ if (this.sampled !== undefined) {
+ sampledString = this.sampled ? '-1' : '-0';
+ }
+ return `${this.traceId}-${this.spanId}${sampledString}`;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ toContext() {
+ return dropUndefinedKeys({
+ data: this.data,
+ description: this.description,
+ endTimestamp: this.endTimestamp,
+ op: this.op,
+ parentSpanId: this.parentSpanId,
+ sampled: this.sampled,
+ spanId: this.spanId,
+ startTimestamp: this.startTimestamp,
+ status: this.status,
+ tags: this.tags,
+ traceId: this.traceId,
+ });
+ }
+
+ /**
+ * @inheritDoc
+ */
+ updateWithContext(spanContext) {
+ this.data = spanContext.data || {};
+ this.description = spanContext.description;
+ this.endTimestamp = spanContext.endTimestamp;
+ this.op = spanContext.op;
+ this.parentSpanId = spanContext.parentSpanId;
+ this.sampled = spanContext.sampled;
+ this.spanId = spanContext.spanId || this.spanId;
+ this.startTimestamp = spanContext.startTimestamp || this.startTimestamp;
+ this.status = spanContext.status;
+ this.tags = spanContext.tags || {};
+ this.traceId = spanContext.traceId || this.traceId;
+
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ getTraceContext() {
+ return dropUndefinedKeys({
+ data: Object.keys(this.data).length > 0 ? this.data : undefined,
+ description: this.description,
+ op: this.op,
+ parent_span_id: this.parentSpanId,
+ span_id: this.spanId,
+ status: this.status,
+ tags: Object.keys(this.tags).length > 0 ? this.tags : undefined,
+ trace_id: this.traceId,
+ });
+ }
+
+ /**
+ * @inheritDoc
+ */
+ toJSON()
+
+ {
+ return dropUndefinedKeys({
+ data: Object.keys(this.data).length > 0 ? this.data : undefined,
+ description: this.description,
+ op: this.op,
+ parent_span_id: this.parentSpanId,
+ span_id: this.spanId,
+ start_timestamp: this.startTimestamp,
+ status: this.status,
+ tags: Object.keys(this.tags).length > 0 ? this.tags : undefined,
+ timestamp: this.endTimestamp,
+ trace_id: this.traceId,
+ });
+ }
+}
+
+/**
+ * Converts a HTTP status code into a {@link SpanStatusType}.
+ *
+ * @param httpStatus The HTTP response status code.
+ * @returns The span status or unknown_error.
+ */
+function spanStatusfromHttpCode(httpStatus) {
+ if (httpStatus < 400 && httpStatus >= 100) {
+ return 'ok';
+ }
+
+ if (httpStatus >= 400 && httpStatus < 500) {
+ switch (httpStatus) {
+ case 401:
+ return 'unauthenticated';
+ case 403:
+ return 'permission_denied';
+ case 404:
+ return 'not_found';
+ case 409:
+ return 'already_exists';
+ case 413:
+ return 'failed_precondition';
+ case 429:
+ return 'resource_exhausted';
+ default:
+ return 'invalid_argument';
+ }
+ }
+
+ if (httpStatus >= 500 && httpStatus < 600) {
+ switch (httpStatus) {
+ case 501:
+ return 'unimplemented';
+ case 503:
+ return 'unavailable';
+ case 504:
+ return 'deadline_exceeded';
+ default:
+ return 'internal_error';
+ }
+ }
+
+ return 'unknown_error';
+}
+
+export { Span, SpanRecorder, spanStatusfromHttpCode };
+//# sourceMappingURL=span.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/tracing/trace.js b/shared/logger/node_modules/@sentry/core/esm/tracing/trace.js
new file mode 100644
index 0000000..3892c89
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/tracing/trace.js
@@ -0,0 +1,78 @@
+import { isThenable } from '@sentry/utils';
+import { getCurrentHub } from '../hub.js';
+import { hasTracingEnabled } from '../utils/hasTracingEnabled.js';
+
+/**
+ * Wraps a function with a transaction/span and finishes the span after the function is done.
+ *
+ * Note that if you have not enabled tracing extensions via `addTracingExtensions`
+ * or you didn't set `tracesSampleRate`, this function will not generate spans
+ * and the `span` returned from the callback will be undefined.
+ *
+ * This function is meant to be used internally and may break at any time. Use at your own risk.
+ *
+ * @internal
+ * @private
+ */
+function trace(
+ context,
+ callback,
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ onError = () => {},
+) {
+ const ctx = { ...context };
+ // If a name is set and a description is not, set the description to the name.
+ if (ctx.name !== undefined && ctx.description === undefined) {
+ ctx.description = ctx.name;
+ }
+
+ const hub = getCurrentHub();
+ const scope = hub.getScope();
+
+ const parentSpan = scope.getSpan();
+
+ function getActiveSpan() {
+ if (!hasTracingEnabled()) {
+ return undefined;
+ }
+ return parentSpan ? parentSpan.startChild(ctx) : hub.startTransaction(ctx);
+ }
+
+ const activeSpan = getActiveSpan();
+ scope.setSpan(activeSpan);
+
+ function finishAndSetSpan() {
+ activeSpan && activeSpan.finish();
+ hub.getScope().setSpan(parentSpan);
+ }
+
+ let maybePromiseResult;
+ try {
+ maybePromiseResult = callback(activeSpan);
+ } catch (e) {
+ activeSpan && activeSpan.setStatus('internal_error');
+ onError(e);
+ finishAndSetSpan();
+ throw e;
+ }
+
+ if (isThenable(maybePromiseResult)) {
+ Promise.resolve(maybePromiseResult).then(
+ () => {
+ finishAndSetSpan();
+ },
+ e => {
+ activeSpan && activeSpan.setStatus('internal_error');
+ onError(e);
+ finishAndSetSpan();
+ },
+ );
+ } else {
+ finishAndSetSpan();
+ }
+
+ return maybePromiseResult;
+}
+
+export { trace };
+//# sourceMappingURL=trace.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/tracing/transaction.js b/shared/logger/node_modules/@sentry/core/esm/tracing/transaction.js
new file mode 100644
index 0000000..134f7fa
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/tracing/transaction.js
@@ -0,0 +1,276 @@
+import { logger, dropUndefinedKeys } from '@sentry/utils';
+import { DEFAULT_ENVIRONMENT } from '../constants.js';
+import { getCurrentHub } from '../hub.js';
+import { Span, SpanRecorder } from './span.js';
+
+/** JSDoc */
+class Transaction extends Span {
+
+ /**
+ * The reference to the current hub.
+ */
+
+ __init() {this._measurements = {};}
+
+ __init2() {this._contexts = {};}
+
+ __init3() {this._frozenDynamicSamplingContext = undefined;}
+
+ /**
+ * This constructor should never be called manually. Those instrumenting tracing should use
+ * `Sentry.startTransaction()`, and internal methods should use `hub.startTransaction()`.
+ * @internal
+ * @hideconstructor
+ * @hidden
+ */
+ constructor(transactionContext, hub) {
+ super(transactionContext);Transaction.prototype.__init.call(this);Transaction.prototype.__init2.call(this);Transaction.prototype.__init3.call(this);
+ this._hub = hub || getCurrentHub();
+
+ this._name = transactionContext.name || '';
+
+ this.metadata = {
+ source: 'custom',
+ ...transactionContext.metadata,
+ spanMetadata: {},
+ };
+
+ this._trimEnd = transactionContext.trimEnd;
+
+ // this is because transactions are also spans, and spans have a transaction pointer
+ this.transaction = this;
+
+ // If Dynamic Sampling Context is provided during the creation of the transaction, we freeze it as it usually means
+ // there is incoming Dynamic Sampling Context. (Either through an incoming request, a baggage meta-tag, or other means)
+ const incomingDynamicSamplingContext = this.metadata.dynamicSamplingContext;
+ if (incomingDynamicSamplingContext) {
+ // We shallow copy this in case anything writes to the original reference of the passed in `dynamicSamplingContext`
+ this._frozenDynamicSamplingContext = { ...incomingDynamicSamplingContext };
+ }
+ }
+
+ /** Getter for `name` property */
+ get name() {
+ return this._name;
+ }
+
+ /** Setter for `name` property, which also sets `source` as custom */
+ set name(newName) {
+ this.setName(newName);
+ }
+
+ /**
+ * JSDoc
+ */
+ setName(name, source = 'custom') {
+ this._name = name;
+ this.metadata.source = source;
+ }
+
+ /**
+ * Attaches SpanRecorder to the span itself
+ * @param maxlen maximum number of spans that can be recorded
+ */
+ initSpanRecorder(maxlen = 1000) {
+ if (!this.spanRecorder) {
+ this.spanRecorder = new SpanRecorder(maxlen);
+ }
+ this.spanRecorder.add(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setContext(key, context) {
+ if (context === null) {
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
+ delete this._contexts[key];
+ } else {
+ this._contexts[key] = context;
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setMeasurement(name, value, unit = '') {
+ this._measurements[name] = { value, unit };
+ }
+
+ /**
+ * @inheritDoc
+ */
+ setMetadata(newMetadata) {
+ this.metadata = { ...this.metadata, ...newMetadata };
+ }
+
+ /**
+ * @inheritDoc
+ */
+ finish(endTimestamp) {
+ // This transaction is already finished, so we should not flush it again.
+ if (this.endTimestamp !== undefined) {
+ return undefined;
+ }
+
+ if (!this.name) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('Transaction has no name, falling back to `<unlabeled transaction>`.');
+ this.name = '<unlabeled transaction>';
+ }
+
+ // just sets the end timestamp
+ super.finish(endTimestamp);
+
+ const client = this._hub.getClient();
+ if (client && client.emit) {
+ client.emit('finishTransaction', this);
+ }
+
+ if (this.sampled !== true) {
+ // At this point if `sampled !== true` we want to discard the transaction.
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log('[Tracing] Discarding transaction because its trace was not chosen to be sampled.');
+
+ if (client) {
+ client.recordDroppedEvent('sample_rate', 'transaction');
+ }
+
+ return undefined;
+ }
+
+ const finishedSpans = this.spanRecorder ? this.spanRecorder.spans.filter(s => s !== this && s.endTimestamp) : [];
+
+ if (this._trimEnd && finishedSpans.length > 0) {
+ this.endTimestamp = finishedSpans.reduce((prev, current) => {
+ if (prev.endTimestamp && current.endTimestamp) {
+ return prev.endTimestamp > current.endTimestamp ? prev : current;
+ }
+ return prev;
+ }).endTimestamp;
+ }
+
+ const metadata = this.metadata;
+
+ const transaction = {
+ contexts: {
+ ...this._contexts,
+ // We don't want to override trace context
+ trace: this.getTraceContext(),
+ },
+ spans: finishedSpans,
+ start_timestamp: this.startTimestamp,
+ tags: this.tags,
+ timestamp: this.endTimestamp,
+ transaction: this.name,
+ type: 'transaction',
+ sdkProcessingMetadata: {
+ ...metadata,
+ dynamicSamplingContext: this.getDynamicSamplingContext(),
+ },
+ ...(metadata.source && {
+ transaction_info: {
+ source: metadata.source,
+ },
+ }),
+ };
+
+ const hasMeasurements = Object.keys(this._measurements).length > 0;
+
+ if (hasMeasurements) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.log(
+ '[Measurements] Adding measurements to transaction',
+ JSON.stringify(this._measurements, undefined, 2),
+ );
+ transaction.measurements = this._measurements;
+ }
+
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log(`[Tracing] Finishing ${this.op} transaction: ${this.name}.`);
+
+ return this._hub.captureEvent(transaction);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ toContext() {
+ const spanContext = super.toContext();
+
+ return dropUndefinedKeys({
+ ...spanContext,
+ name: this.name,
+ trimEnd: this._trimEnd,
+ });
+ }
+
+ /**
+ * @inheritDoc
+ */
+ updateWithContext(transactionContext) {
+ super.updateWithContext(transactionContext);
+
+ this.name = transactionContext.name || '';
+
+ this._trimEnd = transactionContext.trimEnd;
+
+ return this;
+ }
+
+ /**
+ * @inheritdoc
+ *
+ * @experimental
+ */
+ getDynamicSamplingContext() {
+ if (this._frozenDynamicSamplingContext) {
+ return this._frozenDynamicSamplingContext;
+ }
+
+ const hub = this._hub || getCurrentHub();
+ const client = hub && hub.getClient();
+
+ if (!client) return {};
+
+ const { environment, release } = client.getOptions() || {};
+ const { publicKey: public_key } = client.getDsn() || {};
+
+ const maybeSampleRate = this.metadata.sampleRate;
+ const sample_rate = maybeSampleRate !== undefined ? maybeSampleRate.toString() : undefined;
+
+ const { segment: user_segment } = hub.getScope().getUser() || {};
+
+ const source = this.metadata.source;
+
+ // We don't want to have a transaction name in the DSC if the source is "url" because URLs might contain PII
+ const transaction = source && source !== 'url' ? this.name : undefined;
+
+ const dsc = dropUndefinedKeys({
+ environment: environment || DEFAULT_ENVIRONMENT,
+ release,
+ transaction,
+ user_segment,
+ public_key,
+ trace_id: this.traceId,
+ sample_rate,
+ });
+
+ // Uncomment if we want to make DSC immutable
+ // this._frozenDynamicSamplingContext = dsc;
+
+ client.emit && client.emit('createDsc', dsc);
+
+ return dsc;
+ }
+
+ /**
+ * Override the current hub with a new one.
+ * Used if you want another hub to finish the transaction.
+ *
+ * @internal
+ */
+ setHub(hub) {
+ this._hub = hub;
+ }
+}
+
+export { Transaction };
+//# sourceMappingURL=transaction.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/tracing/utils.js b/shared/logger/node_modules/@sentry/core/esm/tracing/utils.js
new file mode 100644
index 0000000..e3e7818
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/tracing/utils.js
@@ -0,0 +1,12 @@
+import { getCurrentHub } from '../hub.js';
+export { TRACEPARENT_REGEXP, extractTraceparentData, stripUrlQueryAndFragment } from '@sentry/utils';
+
+/** Grabs active transaction off scope, if any */
+function getActiveTransaction(maybeHub) {
+ const hub = maybeHub || getCurrentHub();
+ const scope = hub.getScope();
+ return scope.getTransaction() ;
+}
+
+export { getActiveTransaction };
+//# sourceMappingURL=utils.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/transports/base.js b/shared/logger/node_modules/@sentry/core/esm/transports/base.js
new file mode 100644
index 0000000..07adadd
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/transports/base.js
@@ -0,0 +1,101 @@
+import { makePromiseBuffer, forEachEnvelopeItem, envelopeItemTypeToDataCategory, isRateLimited, resolvedSyncPromise, createEnvelope, SentryError, logger, serializeEnvelope, updateRateLimits } from '@sentry/utils';
+
+const DEFAULT_TRANSPORT_BUFFER_SIZE = 30;
+
+/**
+ * Creates an instance of a Sentry `Transport`
+ *
+ * @param options
+ * @param makeRequest
+ */
+function createTransport(
+ options,
+ makeRequest,
+ buffer = makePromiseBuffer(
+ options.bufferSize || DEFAULT_TRANSPORT_BUFFER_SIZE,
+ ),
+) {
+ let rateLimits = {};
+ const flush = (timeout) => buffer.drain(timeout);
+
+ function send(envelope) {
+ const filteredEnvelopeItems = [];
+
+ // Drop rate limited items from envelope
+ forEachEnvelopeItem(envelope, (item, type) => {
+ const envelopeItemDataCategory = envelopeItemTypeToDataCategory(type);
+ if (isRateLimited(rateLimits, envelopeItemDataCategory)) {
+ const event = getEventForEnvelopeItem(item, type);
+ options.recordDroppedEvent('ratelimit_backoff', envelopeItemDataCategory, event);
+ } else {
+ filteredEnvelopeItems.push(item);
+ }
+ });
+
+ // Skip sending if envelope is empty after filtering out rate limited events
+ if (filteredEnvelopeItems.length === 0) {
+ return resolvedSyncPromise();
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const filteredEnvelope = createEnvelope(envelope[0], filteredEnvelopeItems );
+
+ // Creates client report for each item in an envelope
+ const recordEnvelopeLoss = (reason) => {
+ forEachEnvelopeItem(filteredEnvelope, (item, type) => {
+ const event = getEventForEnvelopeItem(item, type);
+ options.recordDroppedEvent(reason, envelopeItemTypeToDataCategory(type), event);
+ });
+ };
+
+ const requestTask = () =>
+ makeRequest({ body: serializeEnvelope(filteredEnvelope, options.textEncoder) }).then(
+ response => {
+ // We don't want to throw on NOK responses, but we want to at least log them
+ if (response.statusCode !== undefined && (response.statusCode < 200 || response.statusCode >= 300)) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn(`Sentry responded with status code ${response.statusCode} to sent event.`);
+ }
+
+ rateLimits = updateRateLimits(rateLimits, response);
+ return response;
+ },
+ error => {
+ recordEnvelopeLoss('network_error');
+ throw error;
+ },
+ );
+
+ return buffer.add(requestTask).then(
+ result => result,
+ error => {
+ if (error instanceof SentryError) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error('Skipped sending event because buffer is full.');
+ recordEnvelopeLoss('queue_overflow');
+ return resolvedSyncPromise();
+ } else {
+ throw error;
+ }
+ },
+ );
+ }
+
+ // We use this to identifify if the transport is the base transport
+ // TODO (v8): Remove this again as we'll no longer need it
+ send.__sentry__baseTransport__ = true;
+
+ return {
+ send,
+ flush,
+ };
+}
+
+function getEventForEnvelopeItem(item, type) {
+ if (type !== 'event' && type !== 'transaction') {
+ return undefined;
+ }
+
+ return Array.isArray(item) ? (item )[1] : undefined;
+}
+
+export { DEFAULT_TRANSPORT_BUFFER_SIZE, createTransport };
+//# sourceMappingURL=base.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/transports/multiplexed.js b/shared/logger/node_modules/@sentry/core/esm/transports/multiplexed.js
new file mode 100644
index 0000000..0ef2030
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/transports/multiplexed.js
@@ -0,0 +1,76 @@
+import { dsnFromString, forEachEnvelopeItem } from '@sentry/utils';
+import { getEnvelopeEndpointWithUrlEncodedAuth } from '../api.js';
+
+function eventFromEnvelope(env, types) {
+ let event;
+
+ forEachEnvelopeItem(env, (item, type) => {
+ if (types.includes(type)) {
+ event = Array.isArray(item) ? (item )[1] : undefined;
+ }
+ // bail out if we found an event
+ return !!event;
+ });
+
+ return event;
+}
+
+/**
+ * Creates a transport that can send events to different DSNs depending on the envelope contents.
+ */
+function makeMultiplexedTransport(
+ createTransport,
+ matcher,
+) {
+ return options => {
+ const fallbackTransport = createTransport(options);
+ const otherTransports = {};
+
+ function getTransport(dsn) {
+ if (!otherTransports[dsn]) {
+ const validatedDsn = dsnFromString(dsn);
+ if (!validatedDsn) {
+ return undefined;
+ }
+ const url = getEnvelopeEndpointWithUrlEncodedAuth(validatedDsn);
+ otherTransports[dsn] = createTransport({ ...options, url });
+ }
+
+ return otherTransports[dsn];
+ }
+
+ async function send(envelope) {
+ function getEvent(types) {
+ const eventTypes = types && types.length ? types : ['event'];
+ return eventFromEnvelope(envelope, eventTypes);
+ }
+
+ const transports = matcher({ envelope, getEvent })
+ .map(dsn => getTransport(dsn))
+ .filter((t) => !!t);
+
+ // If we have no transports to send to, use the fallback transport
+ if (transports.length === 0) {
+ transports.push(fallbackTransport);
+ }
+
+ const results = await Promise.all(transports.map(transport => transport.send(envelope)));
+
+ return results[0];
+ }
+
+ async function flush(timeout) {
+ const allTransports = [...Object.keys(otherTransports).map(dsn => otherTransports[dsn]), fallbackTransport];
+ const results = await Promise.all(allTransports.map(transport => transport.flush(timeout)));
+ return results.every(r => r);
+ }
+
+ return {
+ send,
+ flush,
+ };
+ };
+}
+
+export { makeMultiplexedTransport };
+//# sourceMappingURL=multiplexed.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/transports/offline.js b/shared/logger/node_modules/@sentry/core/esm/transports/offline.js
new file mode 100644
index 0000000..c9de714
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/transports/offline.js
@@ -0,0 +1,122 @@
+import { parseRetryAfterHeader, logger, envelopeContainsItemType } from '@sentry/utils';
+
+const MIN_DELAY = 100; // 100 ms
+const START_DELAY = 5000; // 5 seconds
+const MAX_DELAY = 3.6e6; // 1 hour
+
+function log(msg, error) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.info(`[Offline]: ${msg}`, error);
+}
+
+/**
+ * Wraps a transport and stores and retries events when they fail to send.
+ *
+ * @param createTransport The transport to wrap.
+ */
+function makeOfflineTransport(
+ createTransport,
+) {
+ return options => {
+ const transport = createTransport(options);
+ const store = options.createStore ? options.createStore(options) : undefined;
+
+ let retryDelay = START_DELAY;
+ let flushTimer;
+
+ function shouldQueue(env, error, retryDelay) {
+ // We don't queue Session Replay envelopes because they are:
+ // - Ordered and Replay relies on the response status to know when they're successfully sent.
+ // - Likely to fill the queue quickly and block other events from being sent.
+ // We also want to drop client reports because they can be generated when we retry sending events while offline.
+ if (envelopeContainsItemType(env, ['replay_event', 'replay_recording', 'client_report'])) {
+ return false;
+ }
+
+ if (options.shouldStore) {
+ return options.shouldStore(env, error, retryDelay);
+ }
+
+ return true;
+ }
+
+ function flushIn(delay) {
+ if (!store) {
+ return;
+ }
+
+ if (flushTimer) {
+ clearTimeout(flushTimer );
+ }
+
+ flushTimer = setTimeout(async () => {
+ flushTimer = undefined;
+
+ const found = await store.pop();
+ if (found) {
+ log('Attempting to send previously queued event');
+ void send(found).catch(e => {
+ log('Failed to retry sending', e);
+ });
+ }
+ }, delay) ;
+
+ // We need to unref the timer in node.js, otherwise the node process never exit.
+ if (typeof flushTimer !== 'number' && flushTimer.unref) {
+ flushTimer.unref();
+ }
+ }
+
+ function flushWithBackOff() {
+ if (flushTimer) {
+ return;
+ }
+
+ flushIn(retryDelay);
+
+ retryDelay = Math.min(retryDelay * 2, MAX_DELAY);
+ }
+
+ async function send(envelope) {
+ try {
+ const result = await transport.send(envelope);
+
+ let delay = MIN_DELAY;
+
+ if (result) {
+ // If there's a retry-after header, use that as the next delay.
+ if (result.headers && result.headers['retry-after']) {
+ delay = parseRetryAfterHeader(result.headers['retry-after']);
+ } // If we have a server error, return now so we don't flush the queue.
+ else if ((result.statusCode || 0) >= 400) {
+ return result;
+ }
+ }
+
+ flushIn(delay);
+ retryDelay = START_DELAY;
+ return result;
+ } catch (e) {
+ if (store && (await shouldQueue(envelope, e , retryDelay))) {
+ await store.insert(envelope);
+ flushWithBackOff();
+ log('Error sending. Event queued', e );
+ return {};
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ if (options.flushAtStartup) {
+ flushWithBackOff();
+ }
+
+ return {
+ send,
+ flush: t => transport.flush(t),
+ };
+ };
+}
+
+export { MIN_DELAY, START_DELAY, makeOfflineTransport };
+//# sourceMappingURL=offline.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/utils/hasTracingEnabled.js b/shared/logger/node_modules/@sentry/core/esm/utils/hasTracingEnabled.js
new file mode 100644
index 0000000..d71bd5a
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/utils/hasTracingEnabled.js
@@ -0,0 +1,23 @@
+import { getCurrentHub } from '../hub.js';
+
+// Treeshakable guard to remove all code related to tracing
+
+/**
+ * Determines if tracing is currently enabled.
+ *
+ * Tracing is enabled when at least one of `tracesSampleRate` and `tracesSampler` is defined in the SDK config.
+ */
+function hasTracingEnabled(
+ maybeOptions,
+) {
+ if (typeof __SENTRY_TRACING__ === 'boolean' && !__SENTRY_TRACING__) {
+ return false;
+ }
+
+ const client = getCurrentHub().getClient();
+ const options = maybeOptions || (client && client.getOptions());
+ return !!options && (options.enableTracing || 'tracesSampleRate' in options || 'tracesSampler' in options);
+}
+
+export { hasTracingEnabled };
+//# sourceMappingURL=hasTracingEnabled.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/utils/prepareEvent.js b/shared/logger/node_modules/@sentry/core/esm/utils/prepareEvent.js
new file mode 100644
index 0000000..eb695a8
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/utils/prepareEvent.js
@@ -0,0 +1,304 @@
+import { uuid4, dateTimestampInSeconds, resolvedSyncPromise, truncate, GLOBAL_OBJ, normalize } from '@sentry/utils';
+import { DEFAULT_ENVIRONMENT } from '../constants.js';
+import { Scope } from '../scope.js';
+
+/**
+ * Adds common information to events.
+ *
+ * The information includes release and environment from `options`,
+ * breadcrumbs and context (extra, tags and user) from the scope.
+ *
+ * Information that is already present in the event is never overwritten. For
+ * nested objects, such as the context, keys are merged.
+ *
+ * Note: This also triggers callbacks for `addGlobalEventProcessor`, but not `beforeSend`.
+ *
+ * @param event The original event.
+ * @param hint May contain additional information about the original exception.
+ * @param scope A scope containing event metadata.
+ * @returns A new event with more information.
+ * @hidden
+ */
+function prepareEvent(
+ options,
+ event,
+ hint,
+ scope,
+) {
+ const { normalizeDepth = 3, normalizeMaxBreadth = 1000 } = options;
+ const prepared = {
+ ...event,
+ event_id: event.event_id || hint.event_id || uuid4(),
+ timestamp: event.timestamp || dateTimestampInSeconds(),
+ };
+ const integrations = hint.integrations || options.integrations.map(i => i.name);
+
+ applyClientOptions(prepared, options);
+ applyIntegrationsMetadata(prepared, integrations);
+
+ // Only put debug IDs onto frames for error events.
+ if (event.type === undefined) {
+ applyDebugIds(prepared, options.stackParser);
+ }
+
+ // If we have scope given to us, use it as the base for further modifications.
+ // This allows us to prevent unnecessary copying of data if `captureContext` is not provided.
+ let finalScope = scope;
+ if (hint.captureContext) {
+ finalScope = Scope.clone(finalScope).update(hint.captureContext);
+ }
+
+ // We prepare the result here with a resolved Event.
+ let result = resolvedSyncPromise(prepared);
+
+ // This should be the last thing called, since we want that
+ // {@link Hub.addEventProcessor} gets the finished prepared event.
+ //
+ // We need to check for the existence of `finalScope.getAttachments`
+ // because `getAttachments` can be undefined if users are using an older version
+ // of `@sentry/core` that does not have the `getAttachments` method.
+ // See: https://github.com/getsentry/sentry-javascript/issues/5229
+ if (finalScope) {
+ // Collect attachments from the hint and scope
+ if (finalScope.getAttachments) {
+ const attachments = [...(hint.attachments || []), ...finalScope.getAttachments()];
+
+ if (attachments.length) {
+ hint.attachments = attachments;
+ }
+ }
+
+ // In case we have a hub we reassign it.
+ result = finalScope.applyToEvent(prepared, hint);
+ }
+
+ return result.then(evt => {
+ if (evt) {
+ // We apply the debug_meta field only after all event processors have ran, so that if any event processors modified
+ // file names (e.g.the RewriteFrames integration) the filename -> debug ID relationship isn't destroyed.
+ // This should not cause any PII issues, since we're only moving data that is already on the event and not adding
+ // any new data
+ applyDebugMeta(evt);
+ }
+
+ if (typeof normalizeDepth === 'number' && normalizeDepth > 0) {
+ return normalizeEvent(evt, normalizeDepth, normalizeMaxBreadth);
+ }
+ return evt;
+ });
+}
+
+/**
+ * Enhances event using the client configuration.
+ * It takes care of all "static" values like environment, release and `dist`,
+ * as well as truncating overly long values.
+ * @param event event instance to be enhanced
+ */
+function applyClientOptions(event, options) {
+ const { environment, release, dist, maxValueLength = 250 } = options;
+
+ if (!('environment' in event)) {
+ event.environment = 'environment' in options ? environment : DEFAULT_ENVIRONMENT;
+ }
+
+ if (event.release === undefined && release !== undefined) {
+ event.release = release;
+ }
+
+ if (event.dist === undefined && dist !== undefined) {
+ event.dist = dist;
+ }
+
+ if (event.message) {
+ event.message = truncate(event.message, maxValueLength);
+ }
+
+ const exception = event.exception && event.exception.values && event.exception.values[0];
+ if (exception && exception.value) {
+ exception.value = truncate(exception.value, maxValueLength);
+ }
+
+ const request = event.request;
+ if (request && request.url) {
+ request.url = truncate(request.url, maxValueLength);
+ }
+}
+
+const debugIdStackParserCache = new WeakMap();
+
+/**
+ * Puts debug IDs into the stack frames of an error event.
+ */
+function applyDebugIds(event, stackParser) {
+ const debugIdMap = GLOBAL_OBJ._sentryDebugIds;
+
+ if (!debugIdMap) {
+ return;
+ }
+
+ let debugIdStackFramesCache;
+ const cachedDebugIdStackFrameCache = debugIdStackParserCache.get(stackParser);
+ if (cachedDebugIdStackFrameCache) {
+ debugIdStackFramesCache = cachedDebugIdStackFrameCache;
+ } else {
+ debugIdStackFramesCache = new Map();
+ debugIdStackParserCache.set(stackParser, debugIdStackFramesCache);
+ }
+
+ // Build a map of filename -> debug_id
+ const filenameDebugIdMap = Object.keys(debugIdMap).reduce((acc, debugIdStackTrace) => {
+ let parsedStack;
+ const cachedParsedStack = debugIdStackFramesCache.get(debugIdStackTrace);
+ if (cachedParsedStack) {
+ parsedStack = cachedParsedStack;
+ } else {
+ parsedStack = stackParser(debugIdStackTrace);
+ debugIdStackFramesCache.set(debugIdStackTrace, parsedStack);
+ }
+
+ for (let i = parsedStack.length - 1; i >= 0; i--) {
+ const stackFrame = parsedStack[i];
+ if (stackFrame.filename) {
+ acc[stackFrame.filename] = debugIdMap[debugIdStackTrace];
+ break;
+ }
+ }
+ return acc;
+ }, {});
+
+ try {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ event.exception.values.forEach(exception => {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ exception.stacktrace.frames.forEach(frame => {
+ if (frame.filename) {
+ frame.debug_id = filenameDebugIdMap[frame.filename];
+ }
+ });
+ });
+ } catch (e) {
+ // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.
+ }
+}
+
+/**
+ * Moves debug IDs from the stack frames of an error event into the debug_meta field.
+ */
+function applyDebugMeta(event) {
+ // Extract debug IDs and filenames from the stack frames on the event.
+ const filenameDebugIdMap = {};
+ try {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ event.exception.values.forEach(exception => {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ exception.stacktrace.frames.forEach(frame => {
+ if (frame.debug_id) {
+ if (frame.abs_path) {
+ filenameDebugIdMap[frame.abs_path] = frame.debug_id;
+ } else if (frame.filename) {
+ filenameDebugIdMap[frame.filename] = frame.debug_id;
+ }
+ delete frame.debug_id;
+ }
+ });
+ });
+ } catch (e) {
+ // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.
+ }
+
+ if (Object.keys(filenameDebugIdMap).length === 0) {
+ return;
+ }
+
+ // Fill debug_meta information
+ event.debug_meta = event.debug_meta || {};
+ event.debug_meta.images = event.debug_meta.images || [];
+ const images = event.debug_meta.images;
+ Object.keys(filenameDebugIdMap).forEach(filename => {
+ images.push({
+ type: 'sourcemap',
+ code_file: filename,
+ debug_id: filenameDebugIdMap[filename],
+ });
+ });
+}
+
+/**
+ * This function adds all used integrations to the SDK info in the event.
+ * @param event The event that will be filled with all integrations.
+ */
+function applyIntegrationsMetadata(event, integrationNames) {
+ if (integrationNames.length > 0) {
+ event.sdk = event.sdk || {};
+ event.sdk.integrations = [...(event.sdk.integrations || []), ...integrationNames];
+ }
+}
+
+/**
+ * Applies `normalize` function on necessary `Event` attributes to make them safe for serialization.
+ * Normalized keys:
+ * - `breadcrumbs.data`
+ * - `user`
+ * - `contexts`
+ * - `extra`
+ * @param event Event
+ * @returns Normalized event
+ */
+function normalizeEvent(event, depth, maxBreadth) {
+ if (!event) {
+ return null;
+ }
+
+ const normalized = {
+ ...event,
+ ...(event.breadcrumbs && {
+ breadcrumbs: event.breadcrumbs.map(b => ({
+ ...b,
+ ...(b.data && {
+ data: normalize(b.data, depth, maxBreadth),
+ }),
+ })),
+ }),
+ ...(event.user && {
+ user: normalize(event.user, depth, maxBreadth),
+ }),
+ ...(event.contexts && {
+ contexts: normalize(event.contexts, depth, maxBreadth),
+ }),
+ ...(event.extra && {
+ extra: normalize(event.extra, depth, maxBreadth),
+ }),
+ };
+
+ // event.contexts.trace stores information about a Transaction. Similarly,
+ // event.spans[] stores information about child Spans. Given that a
+ // Transaction is conceptually a Span, normalization should apply to both
+ // Transactions and Spans consistently.
+ // For now the decision is to skip normalization of Transactions and Spans,
+ // so this block overwrites the normalized event to add back the original
+ // Transaction information prior to normalization.
+ if (event.contexts && event.contexts.trace && normalized.contexts) {
+ normalized.contexts.trace = event.contexts.trace;
+
+ // event.contexts.trace.data may contain circular/dangerous data so we need to normalize it
+ if (event.contexts.trace.data) {
+ normalized.contexts.trace.data = normalize(event.contexts.trace.data, depth, maxBreadth);
+ }
+ }
+
+ // event.spans[].data may contain circular/dangerous data so we need to normalize it
+ if (event.spans) {
+ normalized.spans = event.spans.map(span => {
+ // We cannot use the spread operator here because `toJSON` on `span` is non-enumerable
+ if (span.data) {
+ span.data = normalize(span.data, depth, maxBreadth);
+ }
+ return span;
+ });
+ }
+
+ return normalized;
+}
+
+export { applyDebugIds, applyDebugMeta, prepareEvent };
+//# sourceMappingURL=prepareEvent.js.map
diff --git a/shared/logger/node_modules/@sentry/core/esm/version.js b/shared/logger/node_modules/@sentry/core/esm/version.js
new file mode 100644
index 0000000..adb490c
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/core/esm/version.js
@@ -0,0 +1,4 @@
+const SDK_VERSION = '7.57.0';
+
+export { SDK_VERSION };
+//# sourceMappingURL=version.js.map