text: "use strict";
  var __importDefault = (this && this.__importDefault) || function (mod) {
      return (mod && mod.__esModule) ? mod : { "default": mod };
  };
  var __importStar = (this && this.__importStar) || function (mod) {
      if (mod && mod.__esModule) return mod;
      var result = {};
      if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
      result["default"] = mod;
      return result;
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  const react_1 = __importDefault(require("react"));
  const server_1 = require("react-dom/server");
  const router_1 = __importDefault(require("../lib/router/router"));
  const utils_1 = require("../lib/utils");
  const head_1 = __importStar(require("../lib/head"));
  const loadable_1 = __importDefault(require("../lib/loadable"));
  const loadable_capture_1 = __importDefault(require("../lib/loadable-capture"));
  const get_dynamic_import_bundles_1 = require("./get-dynamic-import-bundles");
  const get_page_files_1 = require("./get-page-files");
  const amphtml_context_1 = require("../lib/amphtml-context");
  function enhanceComponents(options, App, Component) {
      // For backwards compatibility
      if (typeof options === 'function') {
          return {
              App,
              Component: options(Component),
          };
      }
      return {
          App: options.enhanceApp ? options.enhanceApp(App) : App,
          Component: options.enhanceComponent
              ? options.enhanceComponent(Component)
              : Component,
      };
  }
  function render(renderElementToString, element) {
      let html;
      let head;
      try {
          html = renderElementToString(element);
      }
      finally {
          head = head_1.default.rewind() || head_1.defaultHead();
      }
      return { html, head };
  }
  function renderDocument(Document, { ampEnabled = false, props, docProps, pathname, query, buildId, assetPrefix, runtimeConfig, nextExport, dynamicImportsIds, err, dev, amphtml, staticMarkup, devFiles, files, dynamicImports, }) {
      return ('<!DOCTYPE html>' +
          server_1.renderToStaticMarkup(react_1.default.createElement(amphtml_context_1.IsAmpContext.Provider, { value: amphtml },
              react_1.default.createElement(Document, Object.assign({ __NEXT_DATA__: {
                      props,
                      page: pathname,
                      query,
                      buildId,
                      assetPrefix: assetPrefix === '' ? undefined : assetPrefix,
                      runtimeConfig,
                      nextExport,
                      dynamicIds: dynamicImportsIds.length === 0 ? undefined : dynamicImportsIds,
                      err: err ? serializeError(dev, err) : undefined,
                  }, ampEnabled: ampEnabled, amphtml: amphtml, staticMarkup: staticMarkup, devFiles: devFiles, files: files, dynamicImports: dynamicImports, assetPrefix: assetPrefix }, docProps)))));
  }
  async function renderToHTML(req, res, pathname, query, renderOpts) {
      const { err, dev = false, staticMarkup = false, amphtml = false, App, Document, Component, buildManifest, reactLoadableManifest, ErrorDebug, } = renderOpts;
      await loadable_1.default.preloadAll(); // Make sure all dynamic imports are loaded
      if (dev) {
          const { isValidElementType } = require('react-is');
          if (!isValidElementType(Component)) {
              throw new Error(`The default export is not a React Component in page: "${pathname}"`);
          }
          if (!isValidElementType(App)) {
              throw new Error(`The default export is not a React Component in page: "/_app"`);
          }
          if (!isValidElementType(Document)) {
              throw new Error(`The default export is not a React Component in page: "/_document"`);
          }
      }
      const asPath = req.url;
      const ctx = { err, req, res, pathname, query, asPath };
      const router = new router_1.default(pathname, query, asPath);
      const props = await utils_1.loadGetInitialProps(App, { Component, router, ctx });
      // the response might be finished on the getInitialProps call
      if (utils_1.isResSent(res))
          return null;
      const devFiles = buildManifest.devFiles;
      const files = [
          ...new Set([
              ...get_page_files_1.getPageFiles(buildManifest, pathname),
              ...get_page_files_1.getPageFiles(buildManifest, '/_app'),
          ]),
      ];
      const reactLoadableModules = [];
      const renderPage = (options = {}) => {
          const renderElementToString = staticMarkup
              ? server_1.renderToStaticMarkup
              : server_1.renderToString;
          if (err && ErrorDebug) {
              return render(renderElementToString, react_1.default.createElement(ErrorDebug, { error: err }));
          }
          const { App: EnhancedApp, Component: EnhancedComponent, } = enhanceComponents(options, App, Component);
          return render(renderElementToString, react_1.default.createElement(amphtml_context_1.IsAmpContext.Provider, { value: amphtml },
              react_1.default.createElement(loadable_capture_1.default, { report: (moduleName) => reactLoadableModules.push(moduleName) },
                  react_1.default.createElement(EnhancedApp, Object.assign({ Component: EnhancedComponent, router: router }, props)))));
      };
      const docProps = await utils_1.loadGetInitialProps(Document, Object.assign({}, ctx, { renderPage }));
      // the response might be finished on the getInitialProps call
      if (utils_1.isResSent(res))
          return null;
      const dynamicImports = [
          ...get_dynamic_import_bundles_1.getDynamicImportBundles(reactLoadableManifest, reactLoadableModules),
      ];
      const dynamicImportsIds = dynamicImports.map((bundle) => bundle.id);
      return renderDocument(Document, Object.assign({}, renderOpts, { props,
          docProps,
          pathname,
          amphtml,
          query,
          dynamicImportsIds,
          dynamicImports,
          files,
          devFiles }));
  }
  exports.renderToHTML = renderToHTML;
  function errorToJSON(err) {
      const { name, message, stack } = err;
      return { name, message, stack };
  }
  function serializeError(dev, err) {
      if (dev) {
          return errorToJSON(err);
      }
      return {
          name: 'Internal Server Error.',
          message: '500 - Internal Server Error.',
          statusCode: 500,
      };
  }
  