import { defineConfig, type Plugin } from 'vite' import vue from '@vitejs/plugin-vue' import tailwindcss from '@tailwindcss/vite' import { resolve, dirname, extname, join } from 'path' import { readFileSync, existsSync, statSync, createReadStream } from 'fs' import { fileURLToPath } from 'url' import yaml from 'js-yaml' const __dirname = dirname(fileURLToPath(import.meta.url)) const cwd = process.cwd() const isTest = process.env.VITEST !== undefined const pkgVersion = JSON.parse( readFileSync(resolve(__dirname, 'package.json'), 'utf8'), ).version function yamlPlugin() { return { name: 'yaml-transform', transform(code: string, id: string) { if (!id.endsWith('.yml') && !id.endsWith('.yaml')) return const data = yaml.load(code) return { code: `export default ${JSON.stringify(data)}`, map: null } }, } } function faviconPlugin() { return { name: 'favicon-inject', transformIndexHtml(html: string) { const tags = process.env.FAVICON_HTML if (!tags) return html const faviconTags = tags.split('\n').map((line: string) => { const m = line.trim().match(/<(\w+)\s+(.*)\/?>/s) if (!m) return null const tag = m[1] const attrs: Record = {} for (const [, k, v] of m[2].matchAll(/(\w[\w-]*)="([^"]*)"/g)) { attrs[k] = v } return { tag, attrs, injectTo: 'head' as const } }).filter(Boolean) return { html, tags: faviconTags } }, } } function inlineDataPlugin() { let publicDir: string | undefined const cache: Map = new Map() return { name: 'inline-data', configResolved(config: any) { publicDir = config.publicDir }, transformIndexHtml(html: string) { if (!publicDir) return html const tags: any[] = [] for (const [id, path] of [ ['datasets-json', 'datasets.json'], ['site-config-json', 'site-config.json'], ] as const) { try { let data = cache.get(path) if (!data) { data = readFileSync(resolve(publicDir!, path), 'utf-8') cache.set(path, data) } tags.push({ tag: 'script', attrs: { type: 'application/json', id }, children: data, injectTo: 'body' as const, }) } catch { /* file may not exist during first build */ } } return { html, tags } }, } } function brandingPlugin() { return { name: 'branding-inject', transformIndexHtml(html: string) { let result = html const title = process.env.SITE_TITLE if (title) { result = result.replace(/[^<]*<\/title>/, `<title>${title}`) } const fontsUrl = process.env.SITE_FONTS_URL if (fontsUrl) { result = result.replace( /]*href="https:\/\/fonts\.googleapis\.com\/css2\?[^"]*"[^>]*>(?:\s*