"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.createSsrMiddleware = createSsrMiddleware;
function _reactRendering() {
  const data = require("@teambit/react.rendering.ssr");
  _reactRendering = function () {
    return data;
  };
  return data;
}
function _path() {
  const data = _interopRequireDefault(require("path"));
  _path = function () {
    return data;
  };
  return data;
}
function fs() {
  const data = _interopRequireWildcard(require("fs-extra"));
  fs = function () {
    return data;
  };
  return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
const denyList = /^\/favicon.ico$/;
async function createSsrMiddleware({
  root,
  port,
  title,
  logger
}) {
  const runtime = await loadRuntime(root, {
    logger
  });
  if (!runtime) return undefined;
  const {
    render
  } = runtime;
  const assets = _objectSpread(_objectSpread({}, runtime.assets), {}, {
    title
  });
  return async function serverRenderMiddleware(request, response, next) {
    const {
      query,
      url
    } = request;
    const browser = (0, _reactRendering().browserFromExpress)(request, port);
    if (denyList.test(url)) {
      logger.debug(`[ssr] skipping static denyList file ${url}`);
      next();
      return;
    }
    if (query.rendering === 'client') {
      logger.debug(`[ssr] skipping ${url}`);
      next();
      return;
    }
    logger.debug(`[ssr] ${request.method} ${url}`);
    const server = {
      port,
      request,
      response
    };
    const props = {
      assets,
      browser,
      request,
      response,
      server
    };
    try {
      const rendered = await render(props);
      response.set('Cache-Control', 'no-cache');
      response.send(rendered);
      logger.debug(`[ssr] success '${url}'`);
    } catch (e) {
      logger.error(`[ssr] failed at '${url}'`, e);
      next();
    }
  };
}
async function loadRuntime(root, {
  logger
}) {
  let render;
  let assets;
  try {
    const entryFilepath = _path().default.join(root, 'ssr', 'index.js');
    if (!fs().existsSync(entryFilepath)) {
      logger.warn(`[ssr] - Skipping setup - failed finding ssr bundle at "${entryFilepath}"`);
      return undefined;
    }
    const manifestFilepath = _path().default.join(root, 'asset-manifest.json');
    if (!fs().existsSync(manifestFilepath)) {
      logger.warn('[ssr] - Skipping setup (cannot find asset manifest file)');
      return undefined;
    }
    assets = await parseManifest(manifestFilepath);
    if (!assets) {
      logger.warn('[ssr] - Skipping setup (failed parsing assets manifest)');
      return undefined;
    }
    const imported = await Promise.resolve(`${entryFilepath}`).then(s => _interopRequireWildcard(require(s)));
    render = (imported === null || imported === void 0 ? void 0 : imported.default) || (imported === null || imported === void 0 ? void 0 : imported.render);
    if (!render || typeof render !== 'function') {
      logger.warn('[ssr] - index file does not export a render() function. Skipping setup.');
      return undefined;
    }
  } catch (e) {
    logger.error(e);
    return undefined;
  }
  return {
    render,
    assets
  };
}
async function parseManifest(filepath, logger) {
  try {
    const file = await fs().readFile(filepath);
    logger === null || logger === void 0 || logger.debug('[ssr] - ✓ aread manifest file');
    const contents = file.toString();
    const parsed = JSON.parse(contents);
    logger === null || logger === void 0 || logger.debug('[ssr] - ✓ prased manifest file', parsed);
    const assets = getAssets(parsed);
    logger === null || logger === void 0 || logger.debug('[ssr] - ✓ extracted data from manifest file', assets);
    return assets;
  } catch (e) {
    logger === null || logger === void 0 || logger.error('[ssr] - error parsing asset manifest', e);
    process.exit();
    return undefined;
  }
}
function getAssets(manifest) {
  var _manifest$entrypoints, _manifest$entrypoints2;
  const assets = {
    css: [],
    js: []
  };
  assets.css = (_manifest$entrypoints = manifest.entrypoints) === null || _manifest$entrypoints === void 0 ? void 0 : _manifest$entrypoints.filter(x => x.endsWith('css')).map(x => _path().default.join('/', x));
  assets.js = (_manifest$entrypoints2 = manifest.entrypoints) === null || _manifest$entrypoints2 === void 0 ? void 0 : _manifest$entrypoints2.filter(x => x.endsWith('js')).map(x => _path().default.join('/', x));
  return assets;
}

//# sourceMappingURL=ssr-middleware.js.map