mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-10 04:20:24 +00:00
Refactored version directory names
3.0 and 2.0 do not work, there are multiple versions and anything with a period in it sucks from my point of view, v2 and v3 feel much better from a DX perspective.
This commit is contained in:
192
datamodel/low/v3/create_document.go
Normal file
192
datamodel/low/v3/create_document.go
Normal file
@@ -0,0 +1,192 @@
|
||||
package v3
|
||||
|
||||
import (
|
||||
"github.com/pb33f/libopenapi/datamodel"
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||
"github.com/pb33f/libopenapi/index"
|
||||
"github.com/pb33f/libopenapi/resolver"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func CreateDocument(info *datamodel.SpecInfo) (*Document, []error) {
|
||||
|
||||
doc := Document{Version: low.ValueReference[string]{Value: info.Version, ValueNode: info.RootNode}}
|
||||
|
||||
// build an index
|
||||
idx := index.NewSpecIndex(info.RootNode)
|
||||
doc.Index = idx
|
||||
|
||||
// create resolver and check for circular references.
|
||||
resolve := resolver.NewResolver(idx)
|
||||
_ = resolve.CheckForCircularReferences()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
var errors []error
|
||||
|
||||
doc.Extensions = low.ExtractExtensions(info.RootNode.Content[0])
|
||||
|
||||
// if set, extract jsonSchemaDialect (3.1)
|
||||
_, dialectLabel, dialectNode := utils.FindKeyNodeFull(JSONSchemaDialectLabel, info.RootNode.Content)
|
||||
if dialectNode != nil {
|
||||
doc.JsonSchemaDialect = low.NodeReference[string]{
|
||||
Value: dialectNode.Value, KeyNode: dialectLabel, ValueNode: dialectLabel}
|
||||
}
|
||||
|
||||
var runExtraction = func(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex,
|
||||
runFunc func(i *datamodel.SpecInfo, d *Document, idx *index.SpecIndex) error,
|
||||
ers *[]error,
|
||||
wg *sync.WaitGroup) {
|
||||
|
||||
if er := runFunc(info, doc, idx); er != nil {
|
||||
*ers = append(*ers, er)
|
||||
}
|
||||
wg.Done()
|
||||
}
|
||||
extractionFuncs := []func(i *datamodel.SpecInfo, d *Document, idx *index.SpecIndex) error{
|
||||
extractInfo,
|
||||
extractServers,
|
||||
extractTags,
|
||||
extractComponents,
|
||||
extractSecurity,
|
||||
extractExternalDocs,
|
||||
extractPaths,
|
||||
extractWebhooks,
|
||||
}
|
||||
|
||||
wg.Add(len(extractionFuncs))
|
||||
for _, f := range extractionFuncs {
|
||||
go runExtraction(info, &doc, idx, f, &errors, &wg)
|
||||
}
|
||||
wg.Wait()
|
||||
return &doc, errors
|
||||
}
|
||||
|
||||
func extractInfo(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
|
||||
_, ln, vn := utils.FindKeyNodeFull(base.InfoLabel, info.RootNode.Content)
|
||||
if vn != nil {
|
||||
ir := base.Info{}
|
||||
_ = low.BuildModel(vn, &ir)
|
||||
_ = ir.Build(vn, idx)
|
||||
nr := low.NodeReference[*base.Info]{Value: &ir, ValueNode: vn, KeyNode: ln}
|
||||
doc.Info = nr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractSecurity(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
|
||||
sec, sErr := low.ExtractObject[*SecurityRequirement](SecurityLabel, info.RootNode, idx)
|
||||
if sErr != nil {
|
||||
return sErr
|
||||
}
|
||||
doc.Security = sec
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractExternalDocs(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
|
||||
extDocs, dErr := low.ExtractObject[*base.ExternalDoc](base.ExternalDocsLabel, info.RootNode, idx)
|
||||
if dErr != nil {
|
||||
return dErr
|
||||
}
|
||||
doc.ExternalDocs = extDocs
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractComponents(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
|
||||
_, ln, vn := utils.FindKeyNodeFull(ComponentsLabel, info.RootNode.Content)
|
||||
if vn != nil {
|
||||
ir := Components{}
|
||||
_ = low.BuildModel(vn, &ir)
|
||||
err := ir.Build(vn, idx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nr := low.NodeReference[*Components]{Value: &ir, ValueNode: vn, KeyNode: ln}
|
||||
doc.Components = nr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractServers(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
|
||||
_, ln, vn := utils.FindKeyNodeFull(ServersLabel, info.RootNode.Content)
|
||||
if vn != nil {
|
||||
if utils.IsNodeArray(vn) {
|
||||
var servers []low.ValueReference[*Server]
|
||||
for _, srvN := range vn.Content {
|
||||
if utils.IsNodeMap(srvN) {
|
||||
srvr := Server{}
|
||||
_ = low.BuildModel(srvN, &srvr)
|
||||
_ = srvr.Build(srvN, idx)
|
||||
servers = append(servers, low.ValueReference[*Server]{
|
||||
Value: &srvr,
|
||||
ValueNode: srvN,
|
||||
})
|
||||
}
|
||||
}
|
||||
doc.Servers = low.NodeReference[[]low.ValueReference[*Server]]{
|
||||
Value: servers,
|
||||
KeyNode: ln,
|
||||
ValueNode: vn,
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractTags(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
|
||||
_, ln, vn := utils.FindKeyNodeFull(base.TagsLabel, info.RootNode.Content)
|
||||
if vn != nil {
|
||||
if utils.IsNodeArray(vn) {
|
||||
var tags []low.ValueReference[*base.Tag]
|
||||
for _, tagN := range vn.Content {
|
||||
if utils.IsNodeMap(tagN) {
|
||||
tag := base.Tag{}
|
||||
_ = low.BuildModel(tagN, &tag)
|
||||
if err := tag.Build(tagN, idx); err != nil {
|
||||
return err
|
||||
}
|
||||
tags = append(tags, low.ValueReference[*base.Tag]{
|
||||
Value: &tag,
|
||||
ValueNode: tagN,
|
||||
})
|
||||
}
|
||||
}
|
||||
doc.Tags = low.NodeReference[[]low.ValueReference[*base.Tag]]{
|
||||
Value: tags,
|
||||
KeyNode: ln,
|
||||
ValueNode: vn,
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractPaths(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
|
||||
_, ln, vn := utils.FindKeyNodeFull(PathsLabel, info.RootNode.Content)
|
||||
if vn != nil {
|
||||
ir := Paths{}
|
||||
err := ir.Build(vn, idx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nr := low.NodeReference[*Paths]{Value: &ir, ValueNode: vn, KeyNode: ln}
|
||||
doc.Paths = nr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractWebhooks(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
|
||||
hooks, hooksL, hooksN, eErr := low.ExtractMapFlat[*PathItem](WebhooksLabel, info.RootNode, idx)
|
||||
if eErr != nil {
|
||||
return eErr
|
||||
}
|
||||
if hooks != nil {
|
||||
doc.Webhooks = low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*PathItem]]{
|
||||
Value: hooks,
|
||||
KeyNode: hooksL,
|
||||
ValueNode: hooksN,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user