-
-
Notifications
You must be signed in to change notification settings - Fork 239
Open
Description
For some unfortunate legacy reason, we require all OpenAPI spec schemas to have a common prefix.
We currently use the following code to fixup the generated spec. The way we do that is probably quite fickle.
Is there any way to make this more robust, e.g. via some builtin functionality?
// Add custom prefix to all supported schemas.
{
const prefix = "SomePrefix"
handled := make(map[any]struct{})
handleOnce := func(v any, fn func()) {
if _, ok := handled[v]; !ok {
handled[v] = struct{}{}
fn()
}
}
m := oapi.Components.Schemas.Map()
replaceSchemas := make(map[string]string, len(m))
for _, mk := range slices.Collect(maps.Keys(m)) {
v := m[mk]
handleOnce(v, func() {
delete(m, mk)
nk := prefix + mk
replaceSchemas[mk] = nk
m[nk] = v
})
}
for _, v := range m {
for _, p := range v.Properties {
if p.Ref != "" {
if suffix, found := strings.CutPrefix(p.Ref, "#/components/schemas/"); found {
p.Ref = "#/components/schemas/" + replaceSchemas[suffix]
}
}
if p.Items != nil {
handleOnce(p.Items, func() {
if suffix, found := strings.CutPrefix(p.Items.Ref, "#/components/schemas/"); found {
p.Items.Ref = "#/components/schemas/" + replaceSchemas[suffix]
}
})
}
for ek, ev := range p.Examples {
handleOnce(ev, func() {
if evs, ok := ev.(string); ok {
if !strings.HasSuffix(evs, ".json") {
return
}
evs = strings.TrimSuffix(evs, ".json")
ss := strings.Split(evs, "/")
ss[len(ss)-1] = replaceSchemas[ss[len(ss)-1]] + ".json"
p.Examples[ek] = strings.Join(ss, "/")
}
})
}
}
}
for _, p := range oapi.Paths {
for _, op := range []*huma.Operation{
p.Get,
p.Put,
p.Post,
p.Delete,
p.Options,
p.Head,
p.Patch,
p.Trace,
} {
if op == nil {
continue
}
contents := make([]*huma.MediaType, 0)
if op.RequestBody != nil {
for _, rc := range op.RequestBody.Content {
contents = append(contents, rc)
}
}
for _, r := range op.Responses {
for _, rc := range r.Content {
contents = append(contents, rc)
}
}
for _, c := range contents {
handleOnce(c.Schema, func() {
if suffix, found := strings.CutPrefix(c.Schema.Ref, "#/components/schemas/"); found {
c.Schema.Ref = "#/components/schemas/" + replaceSchemas[suffix]
}
})
if c.Schema.Items != nil {
handleOnce(c.Schema.Items, func() {
if suffix, found := strings.CutPrefix(c.Schema.Items.Ref, "#/components/schemas/"); found {
c.Schema.Items.Ref = "#/components/schemas/" + replaceSchemas[suffix]
}
})
}
}
}
}
}Metadata
Metadata
Assignees
Labels
No labels