{"version":3,"file":"multiplexed.js","sources":["../../../src/transports/multiplexed.ts"],"sourcesContent":["import type {\n BaseTransportOptions,\n Envelope,\n EnvelopeItemType,\n Event,\n EventItem,\n Transport,\n TransportMakeRequestResponse,\n} from '@sentry/types';\nimport { createEnvelope, dsnFromString, forEachEnvelopeItem } from '@sentry/utils';\n\nimport { getEnvelopeEndpointWithUrlEncodedAuth } from '../api';\n\ninterface MatchParam {\n /** The envelope to be sent */\n envelope: Envelope;\n /**\n * A function that returns an event from the envelope if one exists. You can optionally pass an array of envelope item\n * types to filter by - only envelopes matching the given types will be multiplexed.\n * Allowed values are: 'event', 'transaction', 'profile', 'replay_event'\n *\n * @param types Defaults to ['event']\n */\n getEvent(types?: EnvelopeItemType[]): Event | undefined;\n}\n\ntype RouteTo = { dsn: string; release: string };\ntype Matcher = (param: MatchParam) => (string | RouteTo)[];\n\n/**\n * Gets an event from an envelope.\n *\n * This is only exported for use in the tests\n */\nexport function eventFromEnvelope(env: Envelope, types: EnvelopeItemType[]): Event | undefined {\n let event: Event | undefined;\n\n forEachEnvelopeItem(env, (item, type) => {\n if (types.includes(type)) {\n event = Array.isArray(item) ? (item as EventItem)[1] : undefined;\n }\n // bail out if we found an event\n return !!event;\n });\n\n return event;\n}\n\n/**\n * Creates a transport that overrides the release on all events.\n */\nfunction makeOverrideReleaseTransport(\n createTransport: (options: TO) => Transport,\n release: string,\n): (options: TO) => Transport {\n return options => {\n const transport = createTransport(options);\n\n return {\n ...transport,\n send: async (envelope: Envelope): Promise => {\n const event = eventFromEnvelope(envelope, ['event', 'transaction', 'profile', 'replay_event']);\n\n if (event) {\n event.release = release;\n }\n return transport.send(envelope);\n },\n };\n };\n}\n\n/** Overrides the DSN in the envelope header */\nfunction overrideDsn(envelope: Envelope, dsn: string): Envelope {\n return createEnvelope(\n dsn\n ? {\n ...envelope[0],\n dsn,\n }\n : envelope[0],\n envelope[1],\n );\n}\n\n/**\n * Creates a transport that can send events to different DSNs depending on the envelope contents.\n */\nexport function makeMultiplexedTransport(\n createTransport: (options: TO) => Transport,\n matcher: Matcher,\n): (options: TO) => Transport {\n return options => {\n const fallbackTransport = createTransport(options);\n const otherTransports: Map = new Map();\n\n function getTransport(dsn: string, release: string | undefined): [string, Transport] | undefined {\n // We create a transport for every unique dsn/release combination as there may be code from multiple releases in\n // use at the same time\n const key = release ? `${dsn}:${release}` : dsn;\n\n let transport = otherTransports.get(key);\n\n if (!transport) {\n const validatedDsn = dsnFromString(dsn);\n if (!validatedDsn) {\n return undefined;\n }\n const url = getEnvelopeEndpointWithUrlEncodedAuth(validatedDsn, options.tunnel);\n\n transport = release\n ? makeOverrideReleaseTransport(createTransport, release)({ ...options, url })\n : createTransport({ ...options, url });\n\n otherTransports.set(key, transport);\n }\n\n return [dsn, transport];\n }\n\n async function send(envelope: Envelope): Promise {\n function getEvent(types?: EnvelopeItemType[]): Event | undefined {\n const eventTypes: EnvelopeItemType[] = types && types.length ? types : ['event'];\n return eventFromEnvelope(envelope, eventTypes);\n }\n\n const transports = matcher({ envelope, getEvent })\n .map(result => {\n if (typeof result === 'string') {\n return getTransport(result, undefined);\n } else {\n return getTransport(result.dsn, result.release);\n }\n })\n .filter((t): t is [string, Transport] => !!t);\n\n // If we have no transports to send to, use the fallback transport\n // Don't override the DSN in the header for the fallback transport. '' is falsy\n const transportsWithFallback: [string, Transport][] = transports.length ? transports : [['', fallbackTransport]];\n\n const results = (await Promise.all(\n transportsWithFallback.map(([dsn, transport]) => transport.send(overrideDsn(envelope, dsn))),\n )) as [TransportMakeRequestResponse, ...TransportMakeRequestResponse[]];\n\n return results[0];\n }\n\n async function flush(timeout: number | undefined): Promise {\n const allTransports = [...otherTransports.values(), fallbackTransport];\n const results = await Promise.all(allTransports.map(transport => transport.flush(timeout)));\n return results.every(r => r);\n }\n\n return {\n send,\n flush,\n };\n };\n}\n"],"names":["forEachEnvelopeItem","createEnvelope","dsnFromString","getEnvelopeEndpointWithUrlEncodedAuth"],"mappings":"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"}