5558396bb7
Embed SvelteKit static build in Go binary via go:embed. Event bus for pub/sub with deploy log, instance status, and deploy status events. SSE endpoints for real-time streaming. Frontend SSE client with exponential backoff reconnection. Makefile for build pipeline. Update Phase 12 auth plan with OAuth2/OIDC support.
43 lines
1.0 KiB
Go
43 lines
1.0 KiB
Go
package api
|
|
|
|
import (
|
|
"io/fs"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
// StaticHandler serves embedded SPA files with fallback to index.html
|
|
// for all non-API routes (SPA client-side routing support).
|
|
func StaticHandler(webFS fs.FS) http.Handler {
|
|
fileServer := http.FileServer(http.FS(webFS))
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// Skip API routes — they are handled by the API router.
|
|
if strings.HasPrefix(r.URL.Path, "/api") {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
|
|
// Try to serve the exact file.
|
|
path := strings.TrimPrefix(r.URL.Path, "/")
|
|
if path == "" {
|
|
path = "index.html"
|
|
}
|
|
|
|
// Check if file exists in the embedded FS.
|
|
f, err := webFS.Open(path)
|
|
if err == nil {
|
|
f.Close()
|
|
// Clear the JSON content-type set by middleware — let file server decide.
|
|
w.Header().Del("Content-Type")
|
|
fileServer.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
// File not found: serve index.html for SPA client-side routing.
|
|
r.URL.Path = "/"
|
|
w.Header().Del("Content-Type")
|
|
fileServer.ServeHTTP(w, r)
|
|
})
|
|
}
|