api/export.go
Claude 43abce034e
chore(api): AX compliance sweep — banned imports, naming, test coverage
Replace fmt/errors/strings/encoding/json/os/os/exec/path/filepath with
core primitives; rename abbreviated variables; add Ugly test variants to
all test files; rename integration tests to TestFilename_Function_{Good,Bad,Ugly}.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-31 09:27:41 +01:00

60 lines
1.7 KiB
Go

// SPDX-License-Identifier: EUPL-1.2
package api
import (
"io"
"gopkg.in/yaml.v3"
"dappco.re/go/core"
coreio "dappco.re/go/core/io"
coreerr "dappco.re/go/core/log"
)
// ExportSpec generates the OpenAPI spec and writes it to w.
// Format must be "json" or "yaml".
func ExportSpec(w io.Writer, format string, builder *SpecBuilder, groups []RouteGroup) error {
data, err := builder.Build(groups)
if err != nil {
return coreerr.E("ExportSpec", "build spec", err)
}
switch format {
case "json":
_, err = w.Write(data)
return err
case "yaml":
// Unmarshal JSON then re-marshal as YAML.
var obj any
result := core.JSONUnmarshal(data, &obj)
if !result.OK {
return coreerr.E("ExportSpec", "unmarshal spec", result.Value.(error))
}
encoder := yaml.NewEncoder(w)
encoder.SetIndent(2)
if err := encoder.Encode(obj); err != nil {
return coreerr.E("ExportSpec", "encode yaml", err)
}
return encoder.Close()
default:
return coreerr.E("ExportSpec", "unsupported format "+format+": use \"json\" or \"yaml\"", nil)
}
}
// ExportSpecToFile writes the spec to the given path.
// The parent directory is created if it does not exist.
//
// err := api.ExportSpecToFile("./docs/openapi.json", "json", builder, groups)
// err := api.ExportSpecToFile("./docs/openapi.yaml", "yaml", builder, groups)
func ExportSpecToFile(path, format string, builder *SpecBuilder, groups []RouteGroup) error {
if err := coreio.Local.EnsureDir(core.PathDir(path)); err != nil {
return coreerr.E("ExportSpecToFile", "create directory", err)
}
writer, err := coreio.Local.Create(path)
if err != nil {
return coreerr.E("ExportSpecToFile", "create file", err)
}
defer writer.Close()
return ExportSpec(writer, format, builder, groups)
}