add support for env variables to the DSL

This commit is contained in:
2025-09-02 00:54:38 -06:00
parent c6f14e1787
commit 69f507f176
12 changed files with 842 additions and 84 deletions

View File

@ -140,23 +140,9 @@ func (hi *HTMLInterpreter) generatePageHTML(page *lang.Page) (string, error) {
// JavaScript for interactivity
html.WriteString(" <script>\n")
// API Base URL configuration
apiBaseURL := "http://localhost:8080"
if hi.server != nil {
host := "localhost"
port := 8080
for _, setting := range hi.server.Settings {
if setting.Host != nil {
host = *setting.Host
}
if setting.Port != nil {
port = *setting.Port
}
}
apiBaseURL = fmt.Sprintf("http://%s:%d", host, port)
}
// Generate server configuration code that handles env vars and defaults at runtime
html.WriteString(hi.generateServerConfigJS())
html.WriteString(fmt.Sprintf(" const API_BASE_URL = '%s';\n", apiBaseURL))
html.WriteString(" \n")
html.WriteString(" // API helper functions\n")
html.WriteString(" async function apiRequest(method, endpoint, data = null) {\n")
@ -348,6 +334,86 @@ func (hi *HTMLInterpreter) generatePageHTML(page *lang.Page) (string, error) {
return html.String(), nil
}
// generateServerConfigJS generates JavaScript code that handles server configuration at runtime
func (hi *HTMLInterpreter) generateServerConfigJS() string {
var js strings.Builder
// Default API base URL
js.WriteString(" // Server configuration\n")
js.WriteString(" let apiHost = 'localhost';\n")
js.WriteString(" let apiPort = 8080;\n\n")
if hi.server != nil {
for _, setting := range hi.server.Settings {
if setting.Host != nil {
js.WriteString(hi.generateConfigValueJS("apiHost", setting.Host))
}
if setting.Port != nil {
js.WriteString(hi.generateIntValueJS("apiPort", setting.Port))
}
}
}
js.WriteString(" const API_BASE_URL = `http://${apiHost}:${apiPort}`;\n")
js.WriteString(" console.log('API Base URL:', API_BASE_URL);\n")
return js.String()
}
// generateConfigValueJS generates JavaScript code to resolve a ConfigValue at runtime
func (hi *HTMLInterpreter) generateConfigValueJS(varName string, configValue *lang.ConfigValue) string {
var js strings.Builder
if configValue.Literal != nil {
// Simple literal assignment
js.WriteString(fmt.Sprintf(" %s = %q;\n", varName, *configValue.Literal))
} else if configValue.EnvVar != nil {
// Environment variable resolution in browser (note: this is limited in browsers)
// For client-side, we'll need to use a different approach since browsers can't access server env vars
// We'll generate code that looks for the env var in localStorage or a global config object
js.WriteString(fmt.Sprintf(" // Check for %s in global config or localStorage\n", configValue.EnvVar.Name))
js.WriteString(fmt.Sprintf(" if (window.CONFIG && window.CONFIG['%s']) {\n", configValue.EnvVar.Name))
js.WriteString(fmt.Sprintf(" %s = window.CONFIG['%s'];\n", varName, configValue.EnvVar.Name))
js.WriteString(fmt.Sprintf(" } else if (localStorage.getItem('%s')) {\n", configValue.EnvVar.Name))
js.WriteString(fmt.Sprintf(" %s = localStorage.getItem('%s');\n", varName, configValue.EnvVar.Name))
if configValue.EnvVar.Default != nil {
js.WriteString(" } else {\n")
js.WriteString(fmt.Sprintf(" %s = %q;\n", varName, *configValue.EnvVar.Default))
}
js.WriteString(" }\n")
}
return js.String()
}
// generateIntValueJS generates JavaScript code to resolve an IntValue at runtime
func (hi *HTMLInterpreter) generateIntValueJS(varName string, intValue *lang.IntValue) string {
var js strings.Builder
if intValue.Literal != nil {
// Simple literal assignment
js.WriteString(fmt.Sprintf(" %s = %d;\n", varName, *intValue.Literal))
} else if intValue.EnvVar != nil {
// Environment variable resolution for integers
js.WriteString(fmt.Sprintf(" // Check for %s in global config or localStorage\n", intValue.EnvVar.Name))
js.WriteString(fmt.Sprintf(" if (window.CONFIG && window.CONFIG['%s']) {\n", intValue.EnvVar.Name))
js.WriteString(fmt.Sprintf(" const val = parseInt(window.CONFIG['%s']);\n", intValue.EnvVar.Name))
js.WriteString(fmt.Sprintf(" if (!isNaN(val)) %s = val;\n", varName))
js.WriteString(fmt.Sprintf(" } else if (localStorage.getItem('%s')) {\n", intValue.EnvVar.Name))
js.WriteString(fmt.Sprintf(" const val = parseInt(localStorage.getItem('%s'));\n", intValue.EnvVar.Name))
js.WriteString(fmt.Sprintf(" if (!isNaN(val)) %s = val;\n", varName))
if intValue.EnvVar.Default != nil {
js.WriteString(" } else {\n")
js.WriteString(fmt.Sprintf(" %s = %s;\n", varName, *intValue.EnvVar.Default))
}
js.WriteString(" }\n")
}
return js.String()
}
// generateSectionHTML creates HTML for a section
func (hi *HTMLInterpreter) generateSectionHTML(section *lang.Section, indent int) (string, error) {
var html strings.Builder