Files
Nip-05-api/internal/http/docs/docs.go
Michilis 7a1ceb49c3 Serve Swagger UI from embedded assets instead of unpkg CDN
Bundle swagger-ui-dist@5.32.5 (bundle + CSS) with go:embed and expose
/docs/swagger-ui-bundle.js and /docs/swagger-ui.css so /docs works without
external script loads (fixes timeouts when unpkg is unreachable).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-05 04:25:44 +00:00

112 lines
2.3 KiB
Go

package docs
import (
_ "embed"
"encoding/json"
"net/http"
"gopkg.in/yaml.v3"
)
//go:embed openapi.yaml
var openapiYAML []byte
//go:embed swagger-ui-bundle.js
var swaggerUIBundleJS []byte
//go:embed swagger-ui.css
var swaggerUICSS []byte
var openapiJSON []byte
func init() {
var raw any
if err := yaml.Unmarshal(openapiYAML, &raw); err != nil {
panic(err)
}
clean := convertMaps(raw)
b, err := json.Marshal(clean)
if err != nil {
panic(err)
}
openapiJSON = b
}
// convertMaps recursively converts map[interface{}]interface{} to map[string]interface{}.
func convertMaps(in any) any {
switch v := in.(type) {
case map[any]any:
m := make(map[string]any, len(v))
for k, val := range v {
m[toString(k)] = convertMaps(val)
}
return m
case map[string]any:
m := make(map[string]any, len(v))
for k, val := range v {
m[k] = convertMaps(val)
}
return m
case []any:
out := make([]any, len(v))
for i, item := range v {
out[i] = convertMaps(item)
}
return out
default:
return v
}
}
func toString(v any) string {
if s, ok := v.(string); ok {
return s
}
return ""
}
func ServeJSON(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Cache-Control", "public, max-age=300")
_, _ = w.Write(openapiJSON)
}
const swaggerHTML = `<!DOCTYPE html>
<html>
<head>
<title>NIP-05 API</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="/docs/swagger-ui.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="/docs/swagger-ui-bundle.js"></script>
<script>
window.onload = () => {
window.ui = SwaggerUIBundle({
url: "/openapi.json",
dom_id: "#swagger-ui",
deepLinking: true,
});
};
</script>
</body>
</html>`
func ServeUI(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
_, _ = w.Write([]byte(swaggerHTML))
}
func ServeJS(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
w.Header().Set("Cache-Control", "public, max-age=86400")
_, _ = w.Write(swaggerUIBundleJS)
}
func ServeCSS(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/css; charset=utf-8")
w.Header().Set("Cache-Control", "public, max-age=86400")
_, _ = w.Write(swaggerUICSS)
}