import react from "@vitejs/plugin-react"
import dotenv from "dotenv"
import { readFileSync } from "fs"
import { resolve } from "path"
import { defineConfig, type Plugin } from "vite"
import mkcert from "vite-plugin-mkcert"
dotenv.config({ path: resolve(__dirname, ".env") })
const packageJSON = JSON.parse(readFileSync(resolve(__dirname, "package.json"), "utf8"))
const getBuildNumber = () => {
const d = new Date()
const pad = (n: number) => (n < 10 ? `0${n}` : `${n}`)
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}.${process.env.GITHUB_BUILD_NUMBER ?? "dev"}`
}
const getRestBaseUrl = () => {
const env = process.env.CLOUD_ENV
const prefix =
env === "production" ? "" : env === "staging" ? "staging." : env === "QA" ? "qa." : process.env.REST_BASE_API_DEV_SERVER_PREFIX ? `${process.env.REST_BASE_API_DEV_SERVER_PREFIX}.` : "dev."
return `https://api.${prefix}jmapcloud.io`
}
const getHtmlInputPath = () => resolve(__dirname, process.env.BUILD_TARGET === "cloud" ? "build/index.html" : "index.html")
const JMAP_OPTIONS_PLACEHOLDER = "/* __JMAP_OPTIONS_PLACEHOLDER__ */"
function jmapOptionsPlugin(): Plugin {
return {
name: "jmap-options",
transformIndexHtml(html: string) {
const replacement = `window.JMAP_OPTIONS = { restBaseUrl: "${getRestBaseUrl()}", map: {}, application: {}, hideMainLayout: true }`
return html.replace(JMAP_OPTIONS_PLACEHOLDER, replacement)
}
}
}
function inlineCssInLegacyBuildPlugin(isLegacyProductionBuild: boolean): Plugin {
return {
name: "inline-css-in-legacy-build",
apply: "build",
enforce: "post",
generateBundle(_outputOptions, bundle) {
if (!isLegacyProductionBuild) {
return
}
const cssAssets = Object.entries(bundle).flatMap(([fileName, output]) => {
if (output.type !== "asset" || !output.fileName.endsWith(".css")) {
return []
}
const source = output.source
const cssText = typeof source === "string" ? source : Buffer.from(source).toString("utf8")
return [{ fileName, cssText }]
})
const combinedCss = cssAssets.map(css => css.cssText).join("\n")
for (const output of Object.values(bundle)) {
if (output.type !== "chunk" || !output.isEntry) {
continue
}
if (!combinedCss) {
continue
}
const packageStyleNamespace = packageJSON.name.replace(/[^a-zA-Z0-9_-]/g, "-")
const styleId = `vite-inline-css-${packageStyleNamespace}-${output.fileName.replace(/[^a-zA-Z0-9_-]/g, "-")}`
const injectionCode = `(function(){var id=${JSON.stringify(styleId)};if(document.getElementById(id)){return;}var s=document.createElement("style");s.id=id;s.appendChild(document.createTextNode(${JSON.stringify(combinedCss)}));document.head.appendChild(s);}());`
output.code = `${injectionCode}\n${output.code}`
}
for (const css of cssAssets) {
const cssFileName = css.fileName
delete bundle[cssFileName]
}
for (const output of Object.values(bundle)) {
if (output.type !== "asset" || !output.fileName.endsWith(".html")) {
continue
}
const source = output.source
const html = typeof source === "string" ? source : Buffer.from(source).toString("utf8")
output.source = html
.replace(/]*rel=["']stylesheet["'][^>]*>\s*/g, "")
// Legacy mode uses classic scripts; strip module type first.
.replace(/