"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _circularJson = _interopRequireDefault(require("circular-json"));

var _react = _interopRequireDefault(require("react"));

var _autobindDecorator = _interopRequireDefault(require("autobind-decorator"));

var _cheerio = _interopRequireDefault(require("cheerio"));

var _express = _interopRequireDefault(require("express"));

var _fsExtra = _interopRequireDefault(require("fs-extra"));

var _ignoreWarnings = _interopRequireDefault(require("ignore-warnings"));

var _index = _interopRequireDefault(require("@reactant/web-isomorphic/index.html"));

var _path = _interopRequireDefault(require("path"));

var _core = require("@reactant/core");

var _plugin = require("@reactant/core/plugin");

var _server = require("react-dom/server");

var _Reactant = _interopRequireDefault(require("./Reactant"));

var _class;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

let ServerApp = (0, _autobindDecorator.default)(_class = class ServerApp extends _core.ReactantApp {
  constructor(BaseRoot = _Reactant.default, options = {}) {
    super(...arguments);
    const _options$app = options.app,
          app = _options$app === void 0 ? (0, _express.default)() : _options$app;
    this.BaseRoot = BaseRoot;
    this.app = app;

    if (!_core.config.options.debug) {
      (0, _ignoreWarnings.default)(_core.config.ignore.warnings || []);
      (0, _ignoreWarnings.default)('error', _core.config.ignore.errors || []);
    }
  }

  handle(req, res, next) {
    var _this = this;

    return _asyncToGenerator(function* () {
      const paths = _core.config.paths;

      try {
        if (global.reactant) req.reactant = global.reactant;

        _core.log.silly('url:', req.url);

        req.props = _objectSpread({}, _this.props);
        yield (0, _plugin.callLifecycle)('willRender', _this, {
          req,
          res
        });
        req.props.location = req.url;
        req.props.context = _objectSpread({}, req.props.context, {
          location: req.props.location
        });
        const Root = yield _this.getRoot({
          req,
          res
        });
        const props = req.props;
        if (req.reactant) req.reactant.context = props.context;
        const appHtml = (0, _server.renderToString)(_react.default.createElement(Root, props));

        const $ = _cheerio.default.load(_index.default, {
          _useHtmlParser2: true
        });

        $('title').text(_core.config.title);
        $('#app').append(appHtml);
        $('body').append(`<script src="${_core.assets.client.js}" defer${_core.config.environment === 'production' ? ' crossorigin' : ''}></script>`);
        req.$ = $;
        yield (0, _plugin.callLifecycle)('didRender', _this, {
          req,
          res
        });

        if (req.reactant) {
          _fsExtra.default.mkdirsSync(paths.debug);

          _fsExtra.default.writeFileSync(_path.default.resolve(paths.debug, 'reactant.json'), _circularJson.default.stringify(req.reactant, null, 2));
        }

        res.sent = true;
        return res.send(req.$.html());
      } catch (err) {
        return next(err);
      }
    })();
  }

  init() {
    var _this2 = this,
        _superprop_callInit = (..._args) => super.init(..._args);

    return _asyncToGenerator(function* () {
      yield _superprop_callInit();
      const paths = _core.config.paths;

      _this2.app.use(_express.default.static(_path.default.resolve(paths.dist, 'public')));

      _this2.app.get('/*', _this2.handle);

      return _this2;
    })();
  }

}) || _class;

exports.default = ServerApp;