{"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<TO extends BaseTransportOptions>(\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<void | TransportMakeRequestResponse> => {\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<TO extends BaseTransportOptions>(\n  createTransport: (options: TO) => Transport,\n  matcher: Matcher,\n): (options: TO) => Transport {\n  return options => {\n    const fallbackTransport = createTransport(options);\n    const otherTransports = new Map<string, Transport>();\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\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<void | TransportMakeRequestResponse> {\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      if (transports.length === 0) {\n        // Don't override the DSN in the header for the fallback transport. '' is falsy\n        transports.push(['', fallbackTransport]);\n      }\n\n      const results = await Promise.all(\n        transports.map(([dsn, transport]) => transport.send(overrideDsn(envelope, dsn))),\n      );\n\n      return results[0];\n    }\n\n    async function flush(timeout: number | undefined): Promise<boolean> {\n      const promises = [await fallbackTransport.flush(timeout)];\n      for (const [, transport] of otherTransports) {\n        promises.push(await transport.flush(timeout));\n      }\n\n      return promises.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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"}