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, renderSlot } from "../../runtime/server/index.js";
import { canonicalURL as getCanonicalURL, codeFrame, resolveDependency, viteifyURL } from "../util.js";
import { getStylesForURL } from "./css.js";
import { injectTags } from "./html.js";
import { generatePaginateFunction } from "./paginate.js";
import { getParams, validateGetStaticPathsModule, validateGetStaticPathsResult } from "./routing.js";
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);
  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(path.posix.join(renderer, server));
  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(viteifyURL(filePath));
  return [renderers, mod];
}
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);
    if (!routeCache[route.component]) {
      routeCache[route.component] = await (await mod.getStaticPaths({
        paginate: generatePaginateFunction(route),
        rss: () => {
        }
      })).flat();
    }
    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 = {
    styles: new Set(),
    scripts: new Set(),
    createAstro(astroGlobal, props, slots) {
      const site = new URL(origin);
      const url = new URL("." + pathname, site);
      const canonicalURL = getCanonicalURL("." + pathname, astroConfig.buildOptions.site || origin);
      return {
        __proto__: astroGlobal,
        props,
        request: {
          canonicalURL,
          params,
          url
        },
        slots: Object.fromEntries(Object.entries(slots || {}).map(([slotName]) => [slotName, true])),
        privateRenderSlotDoNotUse(slotName) {
          return renderSlot(result, slots ? slots[slotName] : null);
        },
        async privateRenderMarkdownDoNotUse(content, opts) {
          let mdRender = astroConfig.markdownOptions.render;
          let renderOpts = {};
          if (Array.isArray(mdRender)) {
            renderOpts = mdRender[1];
            mdRender = mdRender[0];
          }
          if (typeof mdRender === "string") {
            ({ default: mdRender } = await import(mdRender));
          }
          const { code } = await mdRender(content, __spreadValues(__spreadValues({}, renderOpts), opts != null ? opts : {}));
          return code;
        }
      };
    },
    _metadata: {
      renderers,
      pathname
    }
  };
  let html = await renderPage(result, Component, pageProps, null);
  if (!/<!doctype html/i.test(html)) {
    html = "<!DOCTYPE html>\n" + html;
  }
  const tags = [];
  if (mode === "development") {
    tags.push({
      tag: "script",
      attrs: { type: "module" },
      children: await getHmrScript(),
      injectTo: "head"
    });
  }
  [...getStylesForURL(filePath, viteServer)].forEach((href) => {
    tags.push({
      tag: "link",
      attrs: {
        rel: "stylesheet",
        href,
        "data-astro-injected": true
      },
      injectTo: "head"
    });
  });
  html = injectTags(html, tags);
  if (mode === "development") {
    html = await viteServer.transformIndexHtml(viteifyURL(filePath), html, pathname);
  }
  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 {
  preload,
  render,
  ssr
};
//# sourceMappingURL=data:application/json;base64, 
