Files
CalendarApi/internal/api/openapi/openapi.go
Michilis 41f6ae916f first commit
Made-with: Cursor
2026-02-28 02:17:55 +00:00

121 lines
2.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package openapi
import (
"embed"
"encoding/json"
"io/fs"
"log"
"net/http"
"strings"
)
//go:embed specs/*.json
var specFiles embed.FS
var mergedSpec []byte
func init() {
spec, err := buildSpec()
if err != nil {
log.Fatalf("openapi: build spec: %v", err)
}
mergedSpec = spec
}
func buildSpec() ([]byte, error) {
base, err := loadJSON("specs/base.json")
if err != nil {
return nil, err
}
schemas, err := loadJSON("specs/schemas.json")
if err != nil {
return nil, err
}
if comps, ok := schemas["components"]; ok {
base["components"] = comps
}
allPaths := make(map[string]interface{})
entries, err := fs.ReadDir(specFiles, "specs")
if err != nil {
return nil, err
}
for _, entry := range entries {
name := entry.Name()
if name == "base.json" || name == "schemas.json" || !strings.HasSuffix(name, ".json") {
continue
}
partial, err := loadJSON("specs/" + name)
if err != nil {
return nil, err
}
if paths, ok := partial["paths"].(map[string]interface{}); ok {
for path, ops := range paths {
allPaths[path] = ops
}
}
}
base["paths"] = allPaths
return json.MarshalIndent(base, "", " ")
}
func loadJSON(path string) (map[string]interface{}, error) {
data, err := specFiles.ReadFile(path)
if err != nil {
return nil, err
}
var m map[string]interface{}
if err := json.Unmarshal(data, &m); err != nil {
return nil, err
}
return m, nil
}
func SpecHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Cache-Control", "public, max-age=3600")
w.Write(mergedSpec)
}
const swaggerHTML = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calendar & Contacts API Docs</title>
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css">
<style>
html { box-sizing: border-box; overflow-y: scroll; }
*, *:before, *:after { box-sizing: inherit; }
body { margin: 0; background: #fafafa; }
.topbar { display: none; }
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
<script>
SwaggerUIBundle({
url: "/openapi.json",
dom_id: "#swagger-ui",
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
layout: "BaseLayout"
});
</script>
</body>
</html>`
func DocsHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.Write([]byte(swaggerHTML))
}