package generator import ( "bytes" "crypto/rand" "encoding/hex" "fmt" "html/template" "os" "path/filepath" ) // HTMLGenerator generates index.html only in dist folder type HTMLGenerator struct { projectDir string distDir string injector *ScriptInjector encryptionKey []byte } // NewHTMLGenerator creates a new HTML generator func NewHTMLGenerator(projectDir, distDir string) *HTMLGenerator { return &HTMLGenerator{ projectDir: projectDir, distDir: distDir, injector: NewScriptInjector(projectDir), } } // Generate creates the index.html in dist folder func (hg *HTMLGenerator) Generate(config *BuildConfig) error { // Load injected scripts if err := hg.injector.LoadScripts(); err != nil { return fmt.Errorf("failed to load injected scripts: %w", err) } // Generate encryption key at build time hg.encryptionKey = make([]byte, 32) if _, err := rand.Read(hg.encryptionKey); err != nil { return fmt.Errorf("failed to generate encryption key: %w", err) } // Create dist directory if err := os.MkdirAll(hg.distDir, 0755); err != nil { return fmt.Errorf("failed to create dist directory: %w", err) } // Generate HTML html, err := hg.buildHTML(config) if err != nil { return err } // Inject scripts html = hg.injector.InjectIntoHTML(html) // Write to dist indexPath := filepath.Join(hg.distDir, "index.html") if err := os.WriteFile(indexPath, []byte(html), 0644); err != nil { return fmt.Errorf("failed to write index.html: %w", err) } return nil } // BuildConfig holds build configuration type BuildConfig struct { Title string Description string BaseURL string APIBaseURL string DevMode bool Assets AssetManifest } // AssetManifest tracks generated assets type AssetManifest struct { JS []string CSS []string } func (hg *HTMLGenerator) buildHTML(config *BuildConfig) (string, error) { tmpl := `