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 {rollupPluginHTML} from "@web/rollup-plugin-html";
import fs from "fs";
import {bold, cyan, green, dim} from "kleur/colors";
import {performance} from "perf_hooks";
import vite from "../vite.js";
import {fileURLToPath} from "url";
import {createVite} from "../create-vite.js";
import {pad} from "../dev/util.js";
import {defaultLogOptions, levels, warn} from "../logger.js";
import {ssr} from "../ssr/index.js";
import {generatePaginateFunction} from "../ssr/paginate.js";
import {createRouteManifest, validateGetStaticPathsModule, validateGetStaticPathsResult} from "../ssr/routing.js";
import {generateRssFunction} from "../ssr/rss.js";
import {generateSitemap} from "../ssr/sitemap.js";
import {kb, profileHTML, profileJS} from "./stats.js";
async function build(config, options = {logging: defaultLogOptions}) {
  const builder = new AstroBuilder(config, options);
  await builder.build();
}
class AstroBuilder {
  constructor(config, options) {
    this.mode = "production";
    this.routeCache = {};
    if (!config.buildOptions.site && config.buildOptions.sitemap !== false) {
      warn(options.logging, "config", `Set "buildOptions.site" to generate correct canonical URLs and sitemap`);
    }
    if (options.mode)
      this.mode = options.mode;
    this.config = config;
    const port = config.devOptions.port;
    this.logging = options.logging;
    this.origin = config.buildOptions.site ? new URL(config.buildOptions.site).origin : `http://localhost:${port}`;
    this.manifest = createRouteManifest({config});
  }
  async build() {
    const start = performance.now();
    const {logging, origin} = this;
    const viteConfig = await createVite(__spreadValues({
      mode: this.mode,
      server: {
        hmr: {overlay: false},
        middlewareMode: "ssr"
      }
    }, this.config.vite || {}), {astroConfig: this.config, logging});
    const viteServer = await vite.createServer(viteConfig);
    const allPages = [];
    const assets = {};
    await Promise.all(this.manifest.routes.map(async (route) => {
      const {pathname} = route;
      const filePath = new URL(`./${route.component}`, this.config.projectRoot);
      if (pathname) {
        allPages.push(ssr({astroConfig: this.config, filePath, logging, mode: "production", origin, route, routeCache: this.routeCache, pathname, viteServer}).then((html) => ({
          html,
          name: pathname.replace(/\/?$/, "/index.html").replace(/^\//, "")
        })));
      } else {
        const staticPaths = await this.getStaticPathsForRoute(route, viteServer);
        if (staticPaths.rss && staticPaths.rss.xml) {
          const rssFile = new URL(staticPaths.rss.url.replace(/^\/?/, "./"), this.config.dist);
          if (assets[fileURLToPath(rssFile)]) {
            throw new Error(`[getStaticPaths] RSS feed ${staticPaths.rss.url} already exists.
Use \`rss(data, {url: '...'})\` to choose a unique, custom URL. (${route.component})`);
          }
          assets[fileURLToPath(rssFile)] = staticPaths.rss.xml;
        }
        staticPaths.paths.forEach((staticPath) => {
          allPages.push(ssr({astroConfig: this.config, filePath, logging, mode: "production", origin, route, routeCache: this.routeCache, pathname: staticPath, viteServer}).then((html) => ({
            html,
            name: staticPath.replace(/\/?$/, "/index.html").replace(/^\//, "")
          })));
        });
      }
    }));
    const input = await Promise.all(allPages);
    await vite.build({
      logLevel: "error",
      mode: "production",
      build: {
        emptyOutDir: true,
        minify: "esbuild",
        outDir: fileURLToPath(this.config.dist),
        rollupOptions: {
          input: [],
          output: {format: "esm"}
        },
        target: "es2020"
      },
      plugins: [
        rollupPluginHTML({input, extractAssets: false}),
        ...viteConfig.plugins || []
      ],
      publicDir: viteConfig.publicDir,
      root: viteConfig.root,
      server: viteConfig.server
    });
    Object.keys(assets).map((k) => {
      if (!assets[k])
        return;
      const filePath = new URL(`file://${k}`);
      fs.mkdirSync(new URL("./", filePath), {recursive: true});
      fs.writeFileSync(filePath, assets[k], "utf8");
      delete assets[k];
    });
    let sitemapTime = 0;
    if (this.config.buildOptions.sitemap && this.config.buildOptions.site) {
      const sitemapStart = performance.now();
      const sitemap = generateSitemap(input.map(({name}) => new URL(`/${name}`, this.config.buildOptions.site).href));
      const sitemapPath = new URL("./sitemap.xml", this.config.dist);
      await fs.promises.mkdir(new URL("./", sitemapPath), {recursive: true});
      await fs.promises.writeFile(sitemapPath, sitemap, "utf8");
      sitemapTime = performance.now() - sitemapStart;
    }
    await viteServer.close();
    if (logging.level && levels[logging.level] <= levels["info"]) {
      await this.printStats({
        cwd: this.config.dist,
        pageCount: input.length,
        pageTime: Math.round(performance.now() - start),
        sitemapTime
      });
    }
  }
  async getStaticPathsForRoute(route, viteServer) {
    const filePath = new URL(`./${route.component}`, this.config.projectRoot);
    const mod = await viteServer.ssrLoadModule(fileURLToPath(filePath));
    validateGetStaticPathsModule(mod);
    const rss = generateRssFunction(this.config.buildOptions.site, route);
    const staticPaths = (await mod.getStaticPaths({paginate: generatePaginateFunction(route), rss: rss.generator})).flat();
    validateGetStaticPathsResult(staticPaths, this.logging);
    return {
      paths: staticPaths.map((staticPath) => staticPath.params && route.generate(staticPath.params)).filter(Boolean),
      rss: rss.rss
    };
  }
  async printStats({cwd, pageTime, pageCount, sitemapTime}) {
    const end = Math.round(performance.now() - pageTime);
    const [js, html] = await Promise.all([profileJS({cwd, entryHTML: new URL("./index.html", cwd)}), profileHTML({cwd})]);
    console.log(`${pad(bold(cyan("Done")), 70)}${dim(` ${pad(`${end}ms`, 8, "left")}`)}
Pages (${pageCount} total)
  ${green(`\u2714 All pages under ${kb(html.maxSize)}`)}
JS
  ${pad("initial load", 50)}${pad(kb(js.entryHTML || 0), 8, "left")}
  ${pad("total size", 50)}${pad(kb(js.total), 8, "left")}
CSS
  ${pad("initial load", 50)}${pad("0 kB", 8, "left")}
  ${pad("total size", 50)}${pad("0 kB", 8, "left")}
Images
  ${green(`\u2714 All images under 50 kB`)}
`);
    if (sitemapTime > 0)
      console.log(`Sitemap
  ${green(`\u2714 Built in ${sitemapTime}`)}`);
  }
}
export {
  build as default
};
//# sourceMappingURL=data:application/json;base64, 
