text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.pluginTransformMiddleware = void 0;
  const PluginTransformCache_1 = require("./PluginTransformCache");
  const utils_1 = require("../utils");
  /**
   * Sets up a middleware which allows plugins to transform files before they are served to the browser.
   */
  function pluginTransformMiddleware(logger, config, fileWatcher) {
      var _a;
      const cache = new PluginTransformCache_1.PluginTransformCache(fileWatcher, config.rootDir);
      const transformPlugins = ((_a = config.plugins) !== null && _a !== void 0 ? _a : []).filter(p => 'transform' in p);
      if (transformPlugins.length === 0) {
          // nothing to transform
          return (ctx, next) => next();
      }
      return async (context, next) => {
          var _a;
          // The cache key is the request URL plus any specific cache keys provided by plugins.
          // For example plugins might do different transformations based on user agent.
          const cacheKey = context.url +
              (await Promise.all(transformPlugins.map(p => { var _a; return (_a = p.transformCacheKey) === null || _a === void 0 ? void 0 : _a.call(p, context); })))
                  .filter(_ => _)
                  .join('_');
          const result = await cache.get(cacheKey);
          if (result) {
              context.body = result.body;
              for (const [k, v] of Object.entries(result.headers)) {
                  context.response.set(k, v);
              }
              logger.debug(`Serving cache key "${cacheKey}" from plugin transform cache`);
              return;
          }
          await next();
          if (context.status < 200 || context.status >= 300) {
              return;
          }
          try {
              // ensure response body is turned into a string or buffer
              await utils_1.getResponseBody(context);
              let disableCache = false;
              let transformedCode = false;
              for (const plugin of transformPlugins) {
                  const result = await ((_a = plugin.transform) === null || _a === void 0 ? void 0 : _a.call(plugin, context));
                  if (typeof result === 'object') {
                      disableCache = result.transformCache === false ? true : disableCache;
                      if (result.body != null) {
                          context.body = result.body;
                          transformedCode = true;
                          logger.debug(`Plugin ${plugin.name} transformed ${context.path}.`);
                      }
                      if (result.headers) {
                          for (const [k, v] of Object.entries(result.headers)) {
                              context.response.set(k, v);
                          }
                      }
                  }
                  else if (typeof result === 'string') {
                      context.body = result;
                      transformedCode = true;
                      logger.debug(`Plugin ${plugin.name} transformed ${context.path}.`);
                  }
              }
              if (transformedCode && !disableCache) {
                  logger.debug(`Added cache key "${cacheKey}" to plugin transform cache`);
                  const filePath = utils_1.getRequestFilePath(context, config.rootDir);
                  cache.set(filePath, context.body, context.response.headers, cacheKey);
              }
          }
          catch (error) {
              if (error instanceof utils_1.RequestCancelledError) {
                  return undefined;
              }
              context.body = 'Error while transforming file. See the terminal for more information.';
              context.status = 500;
              if (error.name === 'PluginSyntaxError') {
                  logger.logSyntaxError(error);
                  return;
              }
              if (error.name === 'PluginError') {
                  logger.error(error.message);
                  return;
              }
              throw error;
          }
      };
  }
  exports.pluginTransformMiddleware = pluginTransformMiddleware;
  //# sourceMappingURL=pluginTransformMiddleware.js.map