text: "use strict";
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.setDebug = setDebug;
  exports.logDebug = logDebug;
  exports.getBodyAsString = getBodyAsString;
  exports.toBrowserPath = toBrowserPath;
  exports.toFilePath = toFilePath;
  exports.isIndexHTMLResponse = isIndexHTMLResponse;
  exports.isPolyfill = isPolyfill;
  exports.shoudlTransformToModule = shoudlTransformToModule;
  exports.isInlineScript = isInlineScript;
  exports.isGeneratedFile = isGeneratedFile;
  exports.getRequestFilePath = getRequestFilePath;
  exports.SSEStream = exports.IsBinaryFileError = exports.RequestCancelledError = void 0;
  
  var _isStream = _interopRequireDefault(require("is-stream"));
  
  var _getStream = _interopRequireDefault(require("get-stream"));
  
  var _stream = _interopRequireDefault(require("stream"));
  
  var _path = _interopRequireDefault(require("path"));
  
  var _isbinaryfile = require("isbinaryfile");
  
  var _constants = require("../constants.js");
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  /* eslint-disable no-console */
  let _debug = false;
  
  function setDebug(debug) {
    _debug = debug;
  }
  
  function logDebug(...messages) {
    if (_debug) {
      console.log('[es-dev-server]: ', ...messages);
    }
  }
  
  class RequestCancelledError extends Error {}
  
  exports.RequestCancelledError = RequestCancelledError;
  
  class IsBinaryFileError extends Error {}
  /**
   * koa-static stores the original served file path on ctx.body.path,
   * we need this path for file transformation but we overwrite body
   * with a string, so we keep a reference with a weakmap
   */
  
  /** @type {WeakMap<import('koa').Request, string>} */
  
  
  exports.IsBinaryFileError = IsBinaryFileError;
  const filePathsForRequests = new WeakMap();
  /**
   * Returns the body value as string. If the response is a stream, the
   * stream is drained and the result is returned. Because koa-static stores
   * a path variable on the stream, we need to create a new stream with
   * the same variable to preserve correct behavior.
   *
   * @param {import('koa').Context} ctx
   * @returns {Promise<string>}
   */
  
  async function getBodyAsString(ctx) {
    let requestCanceled;
    ctx.req.on('close', () => {
      requestCanceled = true;
    });
  
    if (Buffer.isBuffer(ctx.body)) {
      return ctx.body.toString();
    }
  
    if (typeof ctx.body === 'string') {
      return ctx.body;
    }
  
    if ((0, _isStream.default)(ctx.body)) {
      // cache request path, see above
      // @ts-ignore
      if (ctx.body.path) {
        // @ts-ignore
        filePathsForRequests.set(ctx.request, ctx.body.path);
      } // a stream can only be read once, so after reading it assign
      // the string response to the body so that it can be accessed
      // again later
  
  
      try {
        const bodyBuffer = await _getStream.default.buffer(ctx.body);
        const contentLength = Number(ctx.response.get('content-length'));
  
        if (await (0, _isbinaryfile.isBinaryFile)(bodyBuffer, contentLength)) {
          ctx.body = bodyBuffer;
          throw new IsBinaryFileError();
        }
  
        const bodyString = bodyBuffer.toString();
        ctx.body = bodyString;
        return bodyString;
      } catch (error) {
        if (requestCanceled) {
          throw new RequestCancelledError();
        }
  
        throw error;
      }
    }
  
    return ctx.body;
  }
  /**
   * Turns a file path into a path suitable for browsers, with a / as seperator.
   * @param {string} filePath
   * @returns {string}
   */
  
  
  function toBrowserPath(filePath) {
    return filePath.replace(new RegExp(_path.default.sep === '\\' ? '\\\\' : _path.default.sep, 'g'), '/');
  }
  /**
   * Transforms a file system path to a browser URL. For example windows uses `\` on the file system,
   * but it should use `/` in the browser.
   */
  
  
  function toFilePath(browserPath) {
    return browserPath.replace(new RegExp('/', 'g'), _path.default.sep);
  }
  
  class SSEStream extends _stream.default.Transform {
    sendMessage(name, data = '') {
      this.write(`event: ${name}\ndata: ${data}\n\n`);
    }
  
    _transform(data, enc, cb) {
      this.push(data.toString('utf8'));
      cb();
    }
  
  }
  /**
   * Returns the index html response, or null if this wasn't an index.html response
   * @param {import('koa').Context} ctx
   * @param {string} appIndex
   * @returns {Promise<boolean>}
   */
  
  
  exports.SSEStream = SSEStream;
  
  async function isIndexHTMLResponse(ctx, appIndex) {
    if (ctx.status < 200 || ctx.status >= 300) {
      return false;
    } // if we're serving the app index, it's an index html response
  
  
    if (ctx.url === appIndex) {
      return true;
    } // make the check based on content-type and check
  
  
    const contentType = ctx.response.header && ctx.response.header['content-type'];
    return contentType && contentType.includes('text/html');
  }
  /**
   * @param {string} url
   */
  
  
  function isPolyfill(url) {
    return url.includes('/polyfills/');
  }
  /**
   * @param {string} url
   */
  
  
  function shoudlTransformToModule(url) {
    return url.includes('transform-systemjs');
  }
  /**
   * @param {string} url
   */
  
  
  function isInlineScript(url) {
    return url.includes(`inline-script-`) && url.includes('?source=');
  }
  /**
   * Returns whether this is a file generated generated by the dev server
   * @param {string} url
   */
  
  
  function isGeneratedFile(url) {
    return url.startsWith(_constants.virtualFilePrefix) || isPolyfill(url) || isInlineScript(url);
  }
  /**
   * @param {import('koa').Context} ctx
   * @param {string} rootDir
   * @returns {string | null}
   */
  
  
  function getRequestFilePath(ctx, rootDir) {
    if (isPolyfill(ctx.url)) {
      return null;
    } // inline module requests have the source in a query string
  
  
    if (isInlineScript(ctx.url)) {
      const url = ctx.url.split('?')[0];
      const indexPath = toFilePath(url);
      return _path.default.join(rootDir, indexPath);
    } // otherwise koa-static adds the original file path on the body
  
  
    if (ctx.body && ctx.body.path) {
      return ctx.body.path;
    }
  
    return filePathsForRequests.get(ctx.request) || null;
  }