vite-plugin-pages.ts RawHistoryFolder
1import type { Plugin } from 'vite';
2import { writeFileSync, readFileSync } from 'fs';
3import { resolve } from 'path';
4
5interface PageConfig {
6 /** Page name (used for filename and script name) */
7 name: string;
8 /** Page title */
9 title: string;
10 /** Script filename (e.g., 'homepage.min.js') */
11 script: string;
12 /** Optional CSS filename */
13 css?: string;
14 /** Target filename (defaults to name + '.html') */
15 filename?: string;
16}
17
18// Load the favicon SVG from assets
19function getFaviconSVG(): string {
20 const logoPath = resolve(__dirname, '..', 'assets', 'logo.svg');
21 return readFileSync(logoPath, 'utf-8');
22}
23
24// Create favicon data URL for inline usage
25function getFaviconDataURL(): string {
26 const svg = getFaviconSVG();
27 const encoded = encodeURIComponent(svg)
28 .replace(/'/g, '%27')
29 .replace(/\(/g, '%28')
30 .replace(/\)/g, '%29');
31 return `data:image/svg+xml;utf8,${encoded}`;
32}
33
34// Generate HTML content for a page
35function generatePageHTML(config: PageConfig): string {
36 const cssLink = config.css ? `<link rel="stylesheet" href="./${config.css}">` : '';
37
38 return `<!DOCTYPE html>
39<html lang="en">
40<head>
41 <meta charset="UTF-8">
42 <meta name="viewport" content="width=device-width, initial-scale=1.0">
43 <title>${config.title}</title>
44 <link rel="icon" type="image/svg+xml" href="${getFaviconDataURL()}">
45 ${cssLink}
46</head>
47<body>
48 <script src="./${config.script}"></script>
49</body>
50</html>`;
51}
52
53/**
54 * Vite plugin to generate dumb:// protocol pages
55 * Supports multiple pages like homepage, config, about, etc.
56 */
57export function pageGenerator(pages: PageConfig[]): Plugin {
58 return {
59 name: 'dumb-page-generator',
60 writeBundle() {
61 const assetsDir = resolve(__dirname, '..', 'assets', 'gui');
62
63 try {
64 // Generate HTML files for each page
65 for (const page of pages) {
66 const htmlContent = generatePageHTML(page);
67 const filename = page.filename || `${page.name}.html`;
68 writeFileSync(resolve(assetsDir, filename), htmlContent);
69 console.log(`✓ Generated ${filename} for dumb://${page.name}`);
70 }
71
72 // Generate favicon.svg for scheme handler lookups
73 const faviconContent = getFaviconSVG();
74 writeFileSync(resolve(assetsDir, 'favicon.svg'), faviconContent);
75 console.log('✓ Generated favicon.svg');
76
77 } catch (error) {
78 console.error('✗ Failed to generate page files:', error);
79 throw error;
80 }
81 }
82 };
83}
84
85/**
86 * Convenience function for homepage generation
87 * @deprecated Use pageGenerator with homepage config instead
88 */
89export function homepageGenerator(): Plugin {
90 return pageGenerator([
91 {
92 name: 'homepage',
93 title: 'Dumber Browser',
94 script: 'homepage.min.js',
95 filename: 'index.html', // Special case: homepage uses index.html
96 }
97 ]);
98}