text: import { __read, __spread } from "tslib";
  import { logger } from '@sentry/utils';
  /**
   * Express integration
   *
   * Provides an request and error handler for Express framework as well as tracing capabilities
   */
  var Express = /** @class */ (function () {
      /**
       * @inheritDoc
       */
      function Express(options) {
          if (options === void 0) { options = {}; }
          /**
           * @inheritDoc
           */
          this.name = Express.id;
          this._router = options.router || options.app;
          this._methods = (Array.isArray(options.methods) ? options.methods : []).concat('use');
      }
      /**
       * @inheritDoc
       */
      Express.prototype.setupOnce = function () {
          if (!this._router) {
              logger.error('ExpressIntegration is missing an Express instance');
              return;
          }
          instrumentMiddlewares(this._router, this._methods);
      };
      /**
       * @inheritDoc
       */
      Express.id = 'Express';
      return Express;
  }());
  export { Express };
  /**
   * Wraps original middleware function in a tracing call, which stores the info about the call as a span,
   * and finishes it once the middleware is done invoking.
   *
   * Express middlewares have 3 various forms, thus we have to take care of all of them:
   * // sync
   * app.use(function (req, res) { ... })
   * // async
   * app.use(function (req, res, next) { ... })
   * // error handler
   * app.use(function (err, req, res, next) { ... })
   *
   * They all internally delegate to the `router[method]` of the given application instance.
   */
  // eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any
  function wrap(fn, method) {
      var arity = fn.length;
      switch (arity) {
          case 2: {
              return function (req, res) {
                  var transaction = res.__sentry_transaction;
                  if (transaction) {
                      var span_1 = transaction.startChild({
                          description: fn.name,
                          op: "express.middleware." + method,
                      });
                      res.once('finish', function () {
                          span_1.finish();
                      });
                  }
                  return fn.call(this, req, res);
              };
          }
          case 3: {
              return function (req, res, next) {
                  var _a;
                  var transaction = res.__sentry_transaction;
                  var span = (_a = transaction) === null || _a === void 0 ? void 0 : _a.startChild({
                      description: fn.name,
                      op: "express.middleware." + method,
                  });
                  fn.call(this, req, res, function () {
                      var args = [];
                      for (var _i = 0; _i < arguments.length; _i++) {
                          args[_i] = arguments[_i];
                      }
                      var _a;
                      (_a = span) === null || _a === void 0 ? void 0 : _a.finish();
                      next.call.apply(next, __spread([this], args));
                  });
              };
          }
          case 4: {
              return function (err, req, res, next) {
                  var _a;
                  var transaction = res.__sentry_transaction;
                  var span = (_a = transaction) === null || _a === void 0 ? void 0 : _a.startChild({
                      description: fn.name,
                      op: "express.middleware." + method,
                  });
                  fn.call(this, err, req, res, function () {
                      var args = [];
                      for (var _i = 0; _i < arguments.length; _i++) {
                          args[_i] = arguments[_i];
                      }
                      var _a;
                      (_a = span) === null || _a === void 0 ? void 0 : _a.finish();
                      next.call.apply(next, __spread([this], args));
                  });
              };
          }
          default: {
              throw new Error("Express middleware takes 2-4 arguments. Got: " + arity);
          }
      }
  }
  /**
   * Takes all the function arguments passed to the original `app` or `router` method, eg. `app.use` or `router.use`
   * and wraps every function, as well as array of functions with a call to our `wrap` method.
   * We have to take care of the arrays as well as iterate over all of the arguments,
   * as `app.use` can accept middlewares in few various forms.
   *
   * app.use([<path>], <fn>)
   * app.use([<path>], <fn>, ...<fn>)
   * app.use([<path>], ...<fn>[])
   */
  function wrapMiddlewareArgs(args, method) {
      return args.map(function (arg) {
          if (typeof arg === 'function') {
              return wrap(arg, method);
          }
          if (Array.isArray(arg)) {
              return arg.map(function (a) {
                  if (typeof a === 'function') {
                      return wrap(a, method);
                  }
                  return a;
              });
          }
          return arg;
      });
  }
  /**
   * Patches original router to utilize our tracing functionality
   */
  function patchMiddleware(router, method) {
      var originalCallback = router[method];
      router[method] = function () {
          var args = [];
          for (var _i = 0; _i < arguments.length; _i++) {
              args[_i] = arguments[_i];
          }
          return originalCallback.call.apply(originalCallback, __spread([this], wrapMiddlewareArgs(args, method)));
      };
      return router;
  }
  /**
   * Patches original router methods
   */
  function instrumentMiddlewares(router, methods) {
      if (methods === void 0) { methods = []; }
      methods.forEach(function (method) { return patchMiddleware(router, method); });
  }
  //# sourceMappingURL=express.js.map