var __defProp = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
import eol from "eol";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
import { renderPage } from "../../runtime/server/index.js";
import { codeFrame, resolveDependency } from "../util.js";
import { getStylesForURL } from "./css.js";
import { injectTags } from "./html.js";
import { getParams, validateGetStaticPathsModule, validateGetStaticPathsResult } from "./routing.js";
import { createResult } from "./result.js";
import { assignStaticPaths, ensureRouteCached, findPathItemByKey } from "./route-cache.js";
const svelteStylesRE = /svelte\?svelte&type=style/;
const cache = new Map();
async function resolveRenderer(viteServer, renderer, astroConfig) {
  const resolvedRenderer = {};
  const {
    default: { name, client, polyfills, hydrationPolyfills, server }
  } = await import(resolveDependency(renderer, astroConfig));
  resolvedRenderer.name = name;
  if (client)
    resolvedRenderer.source = path.posix.join(renderer, client);
  resolvedRenderer.serverEntry = path.posix.join(renderer, server);
  if (Array.isArray(hydrationPolyfills))
    resolvedRenderer.hydrationPolyfills = hydrationPolyfills.map((src) => path.posix.join(renderer, src));
  if (Array.isArray(polyfills))
    resolvedRenderer.polyfills = polyfills.map((src) => path.posix.join(renderer, src));
  const { url } = await viteServer.moduleGraph.ensureEntryFromUrl(resolvedRenderer.serverEntry);
  const { default: rendererSSR } = await viteServer.ssrLoadModule(url);
  resolvedRenderer.ssr = rendererSSR;
  const completedRenderer = resolvedRenderer;
  return completedRenderer;
}
async function resolveRenderers(viteServer, astroConfig) {
  const ids = astroConfig.renderers;
  const renderers = await Promise.all(ids.map((renderer) => {
    if (cache.has(renderer))
      return cache.get(renderer);
    let promise = resolveRenderer(viteServer, renderer, astroConfig);
    cache.set(renderer, promise);
    return promise;
  }));
  return renderers;
}
async function errorHandler(e, { viteServer, filePath }) {
  if (e.stack) {
    e.stack = eol.lf(e.stack);
  }
  if (e instanceof Error) {
    viteServer.ssrFixStacktrace(e);
  }
  if (Array.isArray(e.errors)) {
    const { location, pluginName, text } = e.errors[0];
    const err = e;
    if (location)
      err.loc = { file: location.file, line: location.line, column: location.column };
    let src = err.pluginCode;
    if (!src && err.id && fs.existsSync(err.id))
      src = await fs.promises.readFile(err.id, "utf8");
    if (!src)
      src = await fs.promises.readFile(filePath, "utf8");
    err.frame = codeFrame(src, err.loc);
    err.id = location == null ? void 0 : location.file;
    err.message = `${location == null ? void 0 : location.file}: ${text}
${err.frame}
`;
    if (pluginName)
      err.plugin = pluginName;
    throw err;
  }
  throw e;
}
async function preload({ astroConfig, filePath, viteServer }) {
  const renderers = await resolveRenderers(viteServer, astroConfig);
  const mod = await viteServer.ssrLoadModule(fileURLToPath(filePath));
  return [renderers, mod];
}
async function getParamsAndProps({
  route,
  routeCache,
  logging,
  pathname,
  mod,
  validate = true
}) {
  let params = {};
  let pageProps;
  if (route && !route.pathname) {
    if (route.params.length) {
      const paramsMatch = route.pattern.exec(pathname);
      if (paramsMatch) {
        params = getParams(route.params)(paramsMatch);
      }
    }
    if (validate) {
      validateGetStaticPathsModule(mod);
    }
    if (!routeCache[route.component]) {
      await assignStaticPaths(routeCache, route, mod);
    }
    if (validate) {
      validateGetStaticPathsResult(routeCache[route.component], logging);
    }
    const staticPaths = routeCache[route.component];
    const paramsKey = JSON.stringify(params);
    const matchedStaticPath = findPathItemByKey(staticPaths, paramsKey, logging);
    if (!matchedStaticPath) {
      throw new Error(`[getStaticPaths] route pattern matched, but no matching static path found. (${pathname})`);
    }
    pageProps = Object.create(matchedStaticPath.props || Object.prototype);
  } else {
    pageProps = {};
  }
  return [params, pageProps];
}
async function render(renderers, mod, ssrOpts) {
  const { astroConfig, filePath, logging, mode, origin, pathname, route, routeCache, viteServer } = ssrOpts;
  let params = {};
  let pageProps = {};
  if (route && !route.pathname) {
    if (route.params.length) {
      const paramsMatch = route.pattern.exec(pathname);
      if (paramsMatch) {
        params = getParams(route.params)(paramsMatch);
      }
    }
    validateGetStaticPathsModule(mod);
    await ensureRouteCached(routeCache, route, mod);
    validateGetStaticPathsResult(routeCache[route.component], logging);
    const routePathParams = routeCache[route.component];
    const matchedStaticPath = routePathParams.find(({ params: _params }) => JSON.stringify(_params) === JSON.stringify(params));
    if (!matchedStaticPath) {
      throw new Error(`[getStaticPaths] route pattern matched, but no matching static path found. (${pathname})`);
    }
    pageProps = __spreadValues({}, matchedStaticPath.props) || {};
  }
  const Component = await mod.default;
  if (!Component)
    throw new Error(`Expected an exported Astro component but received typeof ${typeof Component}`);
  if (!Component.isAstroComponentFactory)
    throw new Error(`Unable to SSR non-Astro component (${route == null ? void 0 : route.component})`);
  const result = createResult({ astroConfig, origin, params, pathname, renderers });
  result.resolve = async (s) => {
    if (astroConfig.buildOptions.experimentalStaticBuild) {
      const [, resolvedPath] = await viteServer.moduleGraph.resolveUrl(s);
      return resolvedPath;
    } else {
      return s;
    }
  };
  let html = await renderPage(result, Component, pageProps, null);
  const tags = [];
  if (mode === "development") {
    tags.push({
      tag: "script",
      attrs: { type: "module" },
      children: await getHmrScript(),
      injectTo: "head"
    });
  }
  [...getStylesForURL(filePath, viteServer)].forEach((href) => {
    if (mode === "development" && svelteStylesRE.test(href)) {
      tags.push({
        tag: "script",
        attrs: { type: "module", src: href },
        injectTo: "head"
      });
    } else {
      tags.push({
        tag: "link",
        attrs: {
          rel: "stylesheet",
          href,
          "data-astro-injected": true
        },
        injectTo: "head"
      });
    }
  });
  html = injectTags(html, tags);
  if (mode === "development" && !astroConfig.buildOptions.experimentalStaticBuild) {
    const relativeURL = filePath.href.replace(astroConfig.projectRoot.href, "/");
    html = await viteServer.transformIndexHtml(relativeURL, html, pathname);
  }
  if (!/<!doctype html/i.test(html)) {
    html = "<!DOCTYPE html>\n" + html;
  }
  return html;
}
let hmrScript;
async function getHmrScript() {
  if (hmrScript)
    return hmrScript;
  const filePath = fileURLToPath(new URL("../../runtime/client/hmr.js", import.meta.url));
  const content = await fs.promises.readFile(filePath);
  hmrScript = content.toString();
  return hmrScript;
}
async function ssr(ssrOpts) {
  try {
    const [renderers, mod] = await preload(ssrOpts);
    return await render(renderers, mod, ssrOpts);
  } catch (e) {
    await errorHandler(e, { viteServer: ssrOpts.viteServer, filePath: ssrOpts.filePath });
    throw e;
  }
}
export {
  getParamsAndProps,
  preload,
  render,
  ssr
};
//# sourceMappingURL=data:application/json;base64, 
