mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-11 04:20:24 +00:00
Building out 2.0 low model
This commit is contained in:
@@ -38,7 +38,9 @@ type Components struct {
|
|||||||
func NewComponents(comp *low.Components) *Components {
|
func NewComponents(comp *low.Components) *Components {
|
||||||
c := new(Components)
|
c := new(Components)
|
||||||
c.low = comp
|
c.low = comp
|
||||||
c.Extensions = high.ExtractExtensions(comp.Extensions)
|
if len(comp.Extensions) > 0 {
|
||||||
|
c.Extensions = high.ExtractExtensions(comp.Extensions)
|
||||||
|
}
|
||||||
cbMap := make(map[string]*Callback)
|
cbMap := make(map[string]*Callback)
|
||||||
linkMap := make(map[string]*Link)
|
linkMap := make(map[string]*Link)
|
||||||
responseMap := make(map[string]*Response)
|
responseMap := make(map[string]*Response)
|
||||||
|
|||||||
@@ -45,9 +45,15 @@ func NewDocument(document *low.Document) *Document {
|
|||||||
if !document.ExternalDocs.IsEmpty() {
|
if !document.ExternalDocs.IsEmpty() {
|
||||||
d.ExternalDocs = NewExternalDoc(document.ExternalDocs.Value)
|
d.ExternalDocs = NewExternalDoc(document.ExternalDocs.Value)
|
||||||
}
|
}
|
||||||
d.Extensions = high.ExtractExtensions(document.Extensions)
|
if len(document.Extensions) > 0 {
|
||||||
d.Components = NewComponents(document.Components.Value)
|
d.Extensions = high.ExtractExtensions(document.Extensions)
|
||||||
d.Paths = NewPaths(document.Paths.Value)
|
}
|
||||||
|
if !document.Components.IsEmpty() {
|
||||||
|
d.Components = NewComponents(document.Components.Value)
|
||||||
|
}
|
||||||
|
if !document.Paths.IsEmpty() {
|
||||||
|
d.Paths = NewPaths(document.Paths.Value)
|
||||||
|
}
|
||||||
d.Index = document.Index
|
d.Index = document.Index
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,20 +6,199 @@ package v2
|
|||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefinitionsLabel = "definitions"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ParameterDefinitions struct {
|
type ParameterDefinitions struct {
|
||||||
Parameters low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Parameter]]
|
Definitions map[low.KeyReference[string]]low.ValueReference[*Parameter]
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResponsesDefinitions struct {
|
||||||
|
Definitions map[low.KeyReference[string]]low.ValueReference[*Response]
|
||||||
|
}
|
||||||
|
|
||||||
|
type SecurityDefinitions struct {
|
||||||
|
Definitions map[low.KeyReference[string]]low.ValueReference[*SecurityScheme]
|
||||||
}
|
}
|
||||||
|
|
||||||
type Definitions struct {
|
type Definitions struct {
|
||||||
Schemas low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*base.SchemaProxy]]
|
Schemas map[low.KeyReference[string]]low.ValueReference[*base.SchemaProxy]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Definitions) FindSchema(schema string) *low.ValueReference[*base.SchemaProxy] {
|
func (d *Definitions) FindSchema(schema string) *low.ValueReference[*base.SchemaProxy] {
|
||||||
return low.FindItemInMap[*base.SchemaProxy](schema, d.Schemas.Value)
|
return low.FindItemInMap[*base.SchemaProxy](schema, d.Schemas)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pd *ParameterDefinitions) FindSchema(schema string) *low.ValueReference[*Parameter] {
|
func (pd *ParameterDefinitions) FindParameter(schema string) *low.ValueReference[*Parameter] {
|
||||||
return low.FindItemInMap[*Parameter](schema, pd.Parameters.Value)
|
return low.FindItemInMap[*Parameter](schema, pd.Definitions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ResponsesDefinitions) FindResponse(schema string) *low.ValueReference[*Response] {
|
||||||
|
return low.FindItemInMap[*Response](schema, r.Definitions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SecurityDefinitions) FindSecurityScheme(schema string) *low.ValueReference[*SecurityScheme] {
|
||||||
|
return low.FindItemInMap[*SecurityScheme](schema, s.Definitions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Definitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
errorChan := make(chan error)
|
||||||
|
resultChan := make(chan definitionResult)
|
||||||
|
var defLabel *yaml.Node
|
||||||
|
totalDefinitions := 0
|
||||||
|
for i := range root.Content {
|
||||||
|
if i%2 == 0 {
|
||||||
|
defLabel = root.Content[i]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
totalDefinitions++
|
||||||
|
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex, r chan definitionResult, e chan error) {
|
||||||
|
obj, err := low.ExtractObjectRaw[*base.SchemaProxy](value, idx)
|
||||||
|
if err != nil {
|
||||||
|
e <- err
|
||||||
|
}
|
||||||
|
r <- definitionResult{k: label, v: low.ValueReference[any]{Value: obj, ValueNode: value}}
|
||||||
|
}
|
||||||
|
go buildFunc(defLabel, root.Content[i], idx, resultChan, errorChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
completedDefs := 0
|
||||||
|
results := make(map[low.KeyReference[string]]low.ValueReference[*base.SchemaProxy])
|
||||||
|
for completedDefs < totalDefinitions {
|
||||||
|
select {
|
||||||
|
case err := <-errorChan:
|
||||||
|
return err
|
||||||
|
case sch := <-resultChan:
|
||||||
|
results[low.KeyReference[string]{
|
||||||
|
Value: sch.k.Value,
|
||||||
|
KeyNode: sch.k,
|
||||||
|
}] = sch.v.(low.ValueReference[*base.SchemaProxy])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.Schemas = results
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pd *ParameterDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
errorChan := make(chan error)
|
||||||
|
resultChan := make(chan definitionResult)
|
||||||
|
var defLabel *yaml.Node
|
||||||
|
totalDefinitions := 0
|
||||||
|
for i := range root.Content {
|
||||||
|
if i%2 == 0 {
|
||||||
|
defLabel = root.Content[i]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
totalDefinitions++
|
||||||
|
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex, r chan definitionResult, e chan error) {
|
||||||
|
obj, err := low.ExtractObjectRaw[*Parameter](value, idx)
|
||||||
|
if err != nil {
|
||||||
|
e <- err
|
||||||
|
}
|
||||||
|
r <- definitionResult{k: label, v: low.ValueReference[any]{Value: obj, ValueNode: value}}
|
||||||
|
}
|
||||||
|
go buildFunc(defLabel, root.Content[i], idx, resultChan, errorChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
completedDefs := 0
|
||||||
|
results := make(map[low.KeyReference[string]]low.ValueReference[*Parameter])
|
||||||
|
for completedDefs < totalDefinitions {
|
||||||
|
select {
|
||||||
|
case err := <-errorChan:
|
||||||
|
return err
|
||||||
|
case sch := <-resultChan:
|
||||||
|
results[low.KeyReference[string]{
|
||||||
|
Value: sch.k.Value,
|
||||||
|
KeyNode: sch.k,
|
||||||
|
}] = sch.v.(low.ValueReference[*Parameter])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pd.Definitions = results
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type definitionResult struct {
|
||||||
|
k *yaml.Node
|
||||||
|
v any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ResponsesDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
errorChan := make(chan error)
|
||||||
|
resultChan := make(chan definitionResult)
|
||||||
|
var defLabel *yaml.Node
|
||||||
|
totalDefinitions := 0
|
||||||
|
for i := range root.Content {
|
||||||
|
if i%2 == 0 {
|
||||||
|
defLabel = root.Content[i]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
totalDefinitions++
|
||||||
|
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex, r chan definitionResult, e chan error) {
|
||||||
|
obj, err := low.ExtractObjectRaw[*Response](value, idx)
|
||||||
|
if err != nil {
|
||||||
|
e <- err
|
||||||
|
}
|
||||||
|
r <- definitionResult{k: label, v: low.ValueReference[any]{Value: obj, ValueNode: value}}
|
||||||
|
}
|
||||||
|
go buildFunc(defLabel, root.Content[i], idx, resultChan, errorChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
completedDefs := 0
|
||||||
|
results := make(map[low.KeyReference[string]]low.ValueReference[*Response])
|
||||||
|
for completedDefs < totalDefinitions {
|
||||||
|
select {
|
||||||
|
case err := <-errorChan:
|
||||||
|
return err
|
||||||
|
case sch := <-resultChan:
|
||||||
|
results[low.KeyReference[string]{
|
||||||
|
Value: sch.k.Value,
|
||||||
|
KeyNode: sch.k,
|
||||||
|
}] = sch.v.(low.ValueReference[*Response])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.Definitions = results
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SecurityDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
errorChan := make(chan error)
|
||||||
|
resultChan := make(chan definitionResult)
|
||||||
|
var defLabel *yaml.Node
|
||||||
|
totalDefinitions := 0
|
||||||
|
for i := range root.Content {
|
||||||
|
if i%2 == 0 {
|
||||||
|
defLabel = root.Content[i]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
totalDefinitions++
|
||||||
|
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex, r chan definitionResult, e chan error) {
|
||||||
|
obj, err := low.ExtractObjectRaw[*SecurityScheme](value, idx)
|
||||||
|
if err != nil {
|
||||||
|
e <- err
|
||||||
|
}
|
||||||
|
r <- definitionResult{k: label, v: low.ValueReference[any]{Value: obj, ValueNode: value}}
|
||||||
|
}
|
||||||
|
go buildFunc(defLabel, root.Content[i], idx, resultChan, errorChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
completedDefs := 0
|
||||||
|
results := make(map[low.KeyReference[string]]low.ValueReference[*SecurityScheme])
|
||||||
|
for completedDefs < totalDefinitions {
|
||||||
|
select {
|
||||||
|
case err := <-errorChan:
|
||||||
|
return err
|
||||||
|
case sch := <-resultChan:
|
||||||
|
results[low.KeyReference[string]{
|
||||||
|
Value: sch.k.Value,
|
||||||
|
KeyNode: sch.k,
|
||||||
|
}] = sch.v.(low.ValueReference[*SecurityScheme])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.Definitions = results
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
64
datamodel/low/2.0/examples.go
Normal file
64
datamodel/low/2.0/examples.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/utils"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Examples struct {
|
||||||
|
Values map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Examples) Build(root *yaml.Node, _ *index.SpecIndex) error {
|
||||||
|
var keyNode, currNode *yaml.Node
|
||||||
|
var err error
|
||||||
|
for i := range root.Content {
|
||||||
|
if i%2 == 0 {
|
||||||
|
keyNode = root.Content[i]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
currNode = root.Content[i]
|
||||||
|
if utils.IsNodeMap(currNode) {
|
||||||
|
var n map[string]interface{}
|
||||||
|
err = currNode.Decode(&n)
|
||||||
|
if err != nil {
|
||||||
|
var k []interface{}
|
||||||
|
err = currNode.Decode(&k)
|
||||||
|
if err != nil {
|
||||||
|
// lets just default to interface
|
||||||
|
var j interface{}
|
||||||
|
_ = currNode.Decode(&j)
|
||||||
|
e.Values[low.KeyReference[string]{
|
||||||
|
Value: keyNode.Value,
|
||||||
|
KeyNode: keyNode,
|
||||||
|
}] = low.ValueReference[any]{
|
||||||
|
Value: j,
|
||||||
|
ValueNode: currNode,
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
e.Values[low.KeyReference[string]{
|
||||||
|
Value: keyNode.Value,
|
||||||
|
KeyNode: keyNode,
|
||||||
|
}] = low.ValueReference[any]{
|
||||||
|
Value: k,
|
||||||
|
ValueNode: currNode,
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
e.Values[low.KeyReference[string]{
|
||||||
|
Value: keyNode.Value,
|
||||||
|
KeyNode: keyNode,
|
||||||
|
}] = low.ValueReference[any]{
|
||||||
|
Value: n,
|
||||||
|
ValueNode: currNode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -4,42 +4,45 @@
|
|||||||
package v2
|
package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
HeadersLabel = "headers"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Header struct {
|
type Header struct {
|
||||||
Type low.NodeReference[string]
|
Type low.NodeReference[string]
|
||||||
Format low.NodeReference[string]
|
Format low.NodeReference[string]
|
||||||
Description low.NodeReference[string]
|
Description low.NodeReference[string]
|
||||||
Items low.NodeReference[*Items]
|
Items low.NodeReference[*Items]
|
||||||
CollectionFormat low.NodeReference[string]
|
CollectionFormat low.NodeReference[string]
|
||||||
Default low.NodeReference[any]
|
Default low.NodeReference[any]
|
||||||
Maximum low.NodeReference[int]
|
Maximum low.NodeReference[int]
|
||||||
ExclusiveMaximum low.NodeReference[bool]
|
ExclusiveMaximum low.NodeReference[bool]
|
||||||
Minimum low.NodeReference[int]
|
Minimum low.NodeReference[int]
|
||||||
ExclusiveMinimum low.NodeReference[bool]
|
ExclusiveMinimum low.NodeReference[bool]
|
||||||
MaxLength low.NodeReference[int]
|
MaxLength low.NodeReference[int]
|
||||||
MinLength low.NodeReference[int]
|
MinLength low.NodeReference[int]
|
||||||
Pattern low.NodeReference[string]
|
Pattern low.NodeReference[string]
|
||||||
MaxItems low.NodeReference[int]
|
MaxItems low.NodeReference[int]
|
||||||
MinItems low.NodeReference[int]
|
MinItems low.NodeReference[int]
|
||||||
UniqueItems low.NodeReference[bool]
|
UniqueItems low.NodeReference[bool]
|
||||||
Enum low.NodeReference[[]string]
|
Enum low.NodeReference[[]string]
|
||||||
MultipleOf low.NodeReference[int]
|
MultipleOf low.NodeReference[int]
|
||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Header) FindExtension(ext string) *low.ValueReference[any] {
|
func (h *Header) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
return low.FindItemInMap[any](ext, h.Extensions)
|
return low.FindItemInMap[any](ext, h.Extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Header) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (h *Header) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
h.Extensions = low.ExtractExtensions(root)
|
h.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
// TODO: build items.
|
// TODO: build items.
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
72
datamodel/low/2.0/operation.go
Normal file
72
datamodel/low/2.0/operation.go
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Operation struct {
|
||||||
|
Tags low.NodeReference[[]low.ValueReference[string]]
|
||||||
|
Summary low.NodeReference[string]
|
||||||
|
Description low.NodeReference[string]
|
||||||
|
ExternalDocs low.NodeReference[*base.ExternalDoc]
|
||||||
|
OperationId low.NodeReference[string]
|
||||||
|
Consumes low.NodeReference[[]low.ValueReference[string]]
|
||||||
|
Produces low.NodeReference[[]low.ValueReference[string]]
|
||||||
|
Parameters low.NodeReference[[]low.ValueReference[*Parameter]]
|
||||||
|
Responses low.NodeReference[*Responses]
|
||||||
|
Schemes low.NodeReference[[]low.ValueReference[string]]
|
||||||
|
Deprecated low.NodeReference[bool]
|
||||||
|
Security low.NodeReference[[]low.ValueReference[*SecurityRequirement]]
|
||||||
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Operation) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
o.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
|
// extract externalDocs
|
||||||
|
extDocs, dErr := low.ExtractObject[*base.ExternalDoc](base.ExternalDocsLabel, root, idx)
|
||||||
|
if dErr != nil {
|
||||||
|
return dErr
|
||||||
|
}
|
||||||
|
o.ExternalDocs = extDocs
|
||||||
|
|
||||||
|
// extract parameters
|
||||||
|
params, ln, vn, pErr := low.ExtractArray[*Parameter](ParametersLabel, root, idx)
|
||||||
|
if pErr != nil {
|
||||||
|
return pErr
|
||||||
|
}
|
||||||
|
if params != nil {
|
||||||
|
o.Parameters = low.NodeReference[[]low.ValueReference[*Parameter]]{
|
||||||
|
Value: params,
|
||||||
|
KeyNode: ln,
|
||||||
|
ValueNode: vn,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract responses
|
||||||
|
respBody, respErr := low.ExtractObject[*Responses](ResponsesLabel, root, idx)
|
||||||
|
if respErr != nil {
|
||||||
|
return respErr
|
||||||
|
}
|
||||||
|
o.Responses = respBody
|
||||||
|
|
||||||
|
// extract parameters
|
||||||
|
sec, sln, svn, sErr := low.ExtractArray[*SecurityRequirement](SecurityLabel, root, idx)
|
||||||
|
if sErr != nil {
|
||||||
|
return sErr
|
||||||
|
}
|
||||||
|
if sec != nil {
|
||||||
|
o.Security = low.NodeReference[[]low.ValueReference[*SecurityRequirement]]{
|
||||||
|
Value: sec,
|
||||||
|
KeyNode: sln,
|
||||||
|
ValueNode: svn,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -5,10 +5,15 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ParametersLabel = "parameters"
|
||||||
|
)
|
||||||
|
|
||||||
type Parameter struct {
|
type Parameter struct {
|
||||||
Name low.NodeReference[string]
|
Name low.NodeReference[string]
|
||||||
In low.NodeReference[string]
|
In low.NodeReference[string]
|
||||||
@@ -17,6 +22,7 @@ type Parameter struct {
|
|||||||
Description low.NodeReference[string]
|
Description low.NodeReference[string]
|
||||||
Required low.NodeReference[bool]
|
Required low.NodeReference[bool]
|
||||||
AllowEmptyValue low.NodeReference[bool]
|
AllowEmptyValue low.NodeReference[bool]
|
||||||
|
Schema low.NodeReference[*base.SchemaProxy]
|
||||||
Items low.NodeReference[*Items]
|
Items low.NodeReference[*Items]
|
||||||
CollectionFormat low.NodeReference[string]
|
CollectionFormat low.NodeReference[string]
|
||||||
Default low.NodeReference[any]
|
Default low.NodeReference[any]
|
||||||
|
|||||||
179
datamodel/low/2.0/path_item.go
Normal file
179
datamodel/low/2.0/path_item.go
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/utils"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PathItem struct {
|
||||||
|
Ref low.NodeReference[string]
|
||||||
|
Get low.NodeReference[*Operation]
|
||||||
|
Put low.NodeReference[*Operation]
|
||||||
|
Post low.NodeReference[*Operation]
|
||||||
|
Delete low.NodeReference[*Operation]
|
||||||
|
Options low.NodeReference[*Operation]
|
||||||
|
Head low.NodeReference[*Operation]
|
||||||
|
Patch low.NodeReference[*Operation]
|
||||||
|
Parameters low.NodeReference[[]low.ValueReference[*Parameter]]
|
||||||
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PathItem) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
|
return low.FindItemInMap[any](ext, p.Extensions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
p.Extensions = low.ExtractExtensions(root)
|
||||||
|
skip := false
|
||||||
|
var currentNode *yaml.Node
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
var errors []error
|
||||||
|
|
||||||
|
var ops []low.NodeReference[*Operation]
|
||||||
|
|
||||||
|
// extract parameters
|
||||||
|
params, ln, vn, pErr := low.ExtractArray[*Parameter](ParametersLabel, root, idx)
|
||||||
|
if pErr != nil {
|
||||||
|
return pErr
|
||||||
|
}
|
||||||
|
if params != nil {
|
||||||
|
p.Parameters = low.NodeReference[[]low.ValueReference[*Parameter]]{
|
||||||
|
Value: params,
|
||||||
|
KeyNode: ln,
|
||||||
|
ValueNode: vn,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, pathNode := range root.Content {
|
||||||
|
if strings.HasPrefix(strings.ToLower(pathNode.Value), "x-") {
|
||||||
|
skip = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(strings.ToLower(pathNode.Value), "parameters") {
|
||||||
|
skip = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if skip {
|
||||||
|
skip = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i%2 == 0 {
|
||||||
|
currentNode = pathNode
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// the only thing we now care about is handling operations, filter out anything that's not a verb.
|
||||||
|
switch currentNode.Value {
|
||||||
|
case GetLabel:
|
||||||
|
break
|
||||||
|
case PostLabel:
|
||||||
|
break
|
||||||
|
case PutLabel:
|
||||||
|
break
|
||||||
|
case PatchLabel:
|
||||||
|
break
|
||||||
|
case DeleteLabel:
|
||||||
|
break
|
||||||
|
case HeadLabel:
|
||||||
|
break
|
||||||
|
case OptionsLabel:
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
continue // ignore everything else.
|
||||||
|
}
|
||||||
|
|
||||||
|
var op Operation
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
if ok, _, _ := utils.IsNodeRefValue(pathNode); ok {
|
||||||
|
r, err := low.LocateRefNode(pathNode, idx)
|
||||||
|
if r != nil {
|
||||||
|
pathNode = r
|
||||||
|
if err != nil {
|
||||||
|
if !idx.AllowCircularReferenceResolving() {
|
||||||
|
return fmt.Errorf("build schema failed: %s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("path item build failed: cannot find reference: %s at line %d, col %d",
|
||||||
|
pathNode.Content[1].Value, pathNode.Content[1].Line, pathNode.Content[1].Column)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
go low.BuildModelAsync(pathNode, &op, &wg, &errors)
|
||||||
|
|
||||||
|
opRef := low.NodeReference[*Operation]{
|
||||||
|
Value: &op,
|
||||||
|
KeyNode: currentNode,
|
||||||
|
ValueNode: pathNode,
|
||||||
|
}
|
||||||
|
|
||||||
|
ops = append(ops, opRef)
|
||||||
|
|
||||||
|
switch currentNode.Value {
|
||||||
|
case GetLabel:
|
||||||
|
p.Get = opRef
|
||||||
|
case PostLabel:
|
||||||
|
p.Post = opRef
|
||||||
|
case PutLabel:
|
||||||
|
p.Put = opRef
|
||||||
|
case PatchLabel:
|
||||||
|
p.Patch = opRef
|
||||||
|
case DeleteLabel:
|
||||||
|
p.Delete = opRef
|
||||||
|
case HeadLabel:
|
||||||
|
p.Head = opRef
|
||||||
|
case OptionsLabel:
|
||||||
|
p.Options = opRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//all operations have been superficially built,
|
||||||
|
//now we need to build out the operation, we will do this asynchronously for speed.
|
||||||
|
opBuildChan := make(chan bool)
|
||||||
|
opErrorChan := make(chan error)
|
||||||
|
|
||||||
|
var buildOpFunc = func(op low.NodeReference[*Operation], ch chan<- bool, errCh chan<- error) {
|
||||||
|
er := op.Value.Build(op.ValueNode, idx)
|
||||||
|
if er != nil {
|
||||||
|
errCh <- er
|
||||||
|
}
|
||||||
|
ch <- true
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ops) <= 0 {
|
||||||
|
return nil // nothing to do.
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, op := range ops {
|
||||||
|
go buildOpFunc(op, opBuildChan, opErrorChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
n := 0
|
||||||
|
total := len(ops)
|
||||||
|
for n < total {
|
||||||
|
select {
|
||||||
|
case buildError := <-opErrorChan:
|
||||||
|
return buildError
|
||||||
|
case <-opBuildChan:
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure we don't exit before the path is finished building.
|
||||||
|
if len(ops) > 0 {
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
125
datamodel/low/2.0/paths.go
Normal file
125
datamodel/low/2.0/paths.go
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/utils"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PathsLabel = "paths"
|
||||||
|
GetLabel = "get"
|
||||||
|
PostLabel = "post"
|
||||||
|
PatchLabel = "patch"
|
||||||
|
PutLabel = "put"
|
||||||
|
DeleteLabel = "delete"
|
||||||
|
OptionsLabel = "options"
|
||||||
|
HeadLabel = "head"
|
||||||
|
TraceLabel = "trace"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Paths struct {
|
||||||
|
PathItems map[low.KeyReference[string]]low.ValueReference[*PathItem]
|
||||||
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Paths) FindPath(path string) *low.ValueReference[*PathItem] {
|
||||||
|
for k, j := range p.PathItems {
|
||||||
|
if k.Value == path {
|
||||||
|
return &j
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Paths) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
|
return low.FindItemInMap[any](ext, p.Extensions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Paths) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
p.Extensions = low.ExtractExtensions(root)
|
||||||
|
skip := false
|
||||||
|
var currentNode *yaml.Node
|
||||||
|
|
||||||
|
pathsMap := make(map[low.KeyReference[string]]low.ValueReference[*PathItem])
|
||||||
|
|
||||||
|
// build each new path, in a new thread.
|
||||||
|
type pathBuildResult struct {
|
||||||
|
k low.KeyReference[string]
|
||||||
|
v low.ValueReference[*PathItem]
|
||||||
|
}
|
||||||
|
|
||||||
|
bChan := make(chan pathBuildResult)
|
||||||
|
eChan := make(chan error)
|
||||||
|
var buildPathItem = func(cNode, pNode *yaml.Node, b chan<- pathBuildResult, e chan<- error) {
|
||||||
|
if ok, _, _ := utils.IsNodeRefValue(pNode); ok {
|
||||||
|
r, err := low.LocateRefNode(pNode, idx)
|
||||||
|
if r != nil {
|
||||||
|
pNode = r
|
||||||
|
if err != nil {
|
||||||
|
if !idx.AllowCircularReferenceResolving() {
|
||||||
|
e <- fmt.Errorf("path item build failed: %s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e <- fmt.Errorf("path item build failed: cannot find reference: %s at line %d, col %d",
|
||||||
|
pNode.Content[1].Value, pNode.Content[1].Line, pNode.Content[1].Column)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
path := new(PathItem)
|
||||||
|
_ = low.BuildModel(pNode, path)
|
||||||
|
err := path.Build(pNode, idx)
|
||||||
|
if err != nil {
|
||||||
|
e <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b <- pathBuildResult{
|
||||||
|
k: low.KeyReference[string]{
|
||||||
|
Value: cNode.Value,
|
||||||
|
KeyNode: cNode,
|
||||||
|
},
|
||||||
|
v: low.ValueReference[*PathItem]{
|
||||||
|
Value: path,
|
||||||
|
ValueNode: pNode,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pathCount := 0
|
||||||
|
for i, pathNode := range root.Content {
|
||||||
|
if strings.HasPrefix(strings.ToLower(pathNode.Value), "x-") {
|
||||||
|
skip = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if skip {
|
||||||
|
skip = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i%2 == 0 {
|
||||||
|
currentNode = pathNode
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pathCount++
|
||||||
|
go buildPathItem(currentNode, pathNode, bChan, eChan)
|
||||||
|
}
|
||||||
|
completedItems := 0
|
||||||
|
for completedItems < pathCount {
|
||||||
|
select {
|
||||||
|
case err := <-eChan:
|
||||||
|
return err
|
||||||
|
case res := <-bChan:
|
||||||
|
completedItems++
|
||||||
|
pathsMap[res.k] = res.v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.PathItems = pathsMap
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -6,11 +6,50 @@ package v2
|
|||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ResponsesLabel = "responses"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
Description low.NodeReference[string]
|
Description low.NodeReference[string]
|
||||||
Schema low.NodeReference[*base.SchemaProxy]
|
Schema low.NodeReference[*base.SchemaProxy]
|
||||||
Headers low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Header]]
|
Headers low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Header]]
|
||||||
Examples low.NodeReference[map[low.KeyReference[string]]low.ValueReference[any]]
|
Examples low.NodeReference[*Examples]
|
||||||
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Response) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
|
return low.FindItemInMap[any](ext, r.Extensions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Response) FindHeader(hType string) *low.ValueReference[*Header] {
|
||||||
|
return low.FindItemInMap[*Header](hType, r.Headers.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Response) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
r.Extensions = low.ExtractExtensions(root)
|
||||||
|
s, err := base.ExtractSchema(root, idx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.Schema = *s
|
||||||
|
|
||||||
|
//extract headers
|
||||||
|
headers, lN, kN, err := low.ExtractMapFlat[*Header](HeadersLabel, root, idx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if headers != nil {
|
||||||
|
r.Headers = low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Header]]{
|
||||||
|
Value: headers,
|
||||||
|
KeyNode: lN,
|
||||||
|
ValueNode: kN,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
47
datamodel/low/2.0/responses.go
Normal file
47
datamodel/low/2.0/responses.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/utils"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Responses struct {
|
||||||
|
Codes map[low.KeyReference[string]]low.ValueReference[*Response]
|
||||||
|
Default low.NodeReference[*Response]
|
||||||
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Responses) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
r.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
|
if utils.IsNodeMap(root) {
|
||||||
|
codes, err := low.ExtractMapFlatNoLookup[*Response](root, idx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if codes != nil {
|
||||||
|
r.Codes = codes
|
||||||
|
}
|
||||||
|
|
||||||
|
def, derr := low.ExtractObject[*Response](DefaultLabel, root, idx)
|
||||||
|
if derr != nil {
|
||||||
|
return derr
|
||||||
|
}
|
||||||
|
if def.Value != nil {
|
||||||
|
r.Default = def
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("responses build failed: vn node is not a map! line %d, col %d", root.Line, root.Column)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Responses) FindResponseByCode(code string) *low.ValueReference[*Response] {
|
||||||
|
return low.FindItemInMap[*Response](code, r.Codes)
|
||||||
|
}
|
||||||
@@ -3,8 +3,21 @@
|
|||||||
|
|
||||||
package v2
|
package v2
|
||||||
|
|
||||||
import "github.com/pb33f/libopenapi/datamodel/low"
|
import (
|
||||||
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SecurityLabel = "security"
|
||||||
|
)
|
||||||
|
|
||||||
type SecurityRequirement struct {
|
type SecurityRequirement struct {
|
||||||
Values low.NodeReference[[]low.ValueReference[string]]
|
Values low.NodeReference[[]low.ValueReference[string]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SecurityRequirement) Build(_ *yaml.Node, _ *index.SpecIndex) error {
|
||||||
|
// not implemented.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,16 +3,27 @@
|
|||||||
|
|
||||||
package v2
|
package v2
|
||||||
|
|
||||||
import "github.com/pb33f/libopenapi/datamodel/low"
|
import (
|
||||||
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
type SecurityScheme struct {
|
type SecurityScheme struct {
|
||||||
Type low.NodeReference[string]
|
Type low.NodeReference[string]
|
||||||
Description low.NodeReference[string]
|
Description low.NodeReference[string]
|
||||||
Name low.NodeReference[string]
|
Name low.NodeReference[string]
|
||||||
In low.NodeReference[string]
|
In low.NodeReference[string]
|
||||||
Flow low.NodeReference[string]
|
Flow low.NodeReference[string]
|
||||||
AuthorizationUrl low.NodeReference[string]
|
AuthorizationUrl low.NodeReference[string]
|
||||||
TokenUrl low.NodeReference[string]
|
TokenUrl low.NodeReference[string]
|
||||||
Scopes low.NodeReference[*Scopes]
|
Scopes low.NodeReference[*Scopes]
|
||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ss *SecurityScheme) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
ss.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
|
// TODO: scopes
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,27 +4,132 @@
|
|||||||
package v2
|
package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/pb33f/libopenapi/datamodel"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/resolver"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type documentFunction func(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error)
|
||||||
|
|
||||||
type Swagger struct {
|
type Swagger struct {
|
||||||
Swagger low.NodeReference[string]
|
Swagger low.ValueReference[string]
|
||||||
Info low.NodeReference[*base.Info]
|
Info low.NodeReference[*base.Info]
|
||||||
Host low.NodeReference[string]
|
Host low.NodeReference[string]
|
||||||
BasePath low.NodeReference[string]
|
BasePath low.NodeReference[string]
|
||||||
Schemes low.NodeReference[[]low.ValueReference[string]]
|
Schemes low.NodeReference[[]low.ValueReference[string]]
|
||||||
Consumes low.NodeReference[[]low.ValueReference[string]]
|
Consumes low.NodeReference[[]low.ValueReference[string]]
|
||||||
Produces low.NodeReference[[]low.ValueReference[string]]
|
Produces low.NodeReference[[]low.ValueReference[string]]
|
||||||
|
Paths low.NodeReference[*Paths]
|
||||||
// TODO: paths
|
Definitions low.NodeReference[*Definitions]
|
||||||
|
SecurityDefinitions low.NodeReference[*SecurityDefinitions]
|
||||||
Definitions low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*base.SchemaProxy]]
|
Parameters low.NodeReference[*ParameterDefinitions]
|
||||||
Parameters low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Parameter]]
|
ResponsesDefinitions low.NodeReference[*ResponsesDefinitions]
|
||||||
Responses low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Response]]
|
Responses low.NodeReference[*Responses]
|
||||||
SecurityDefinitions low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*SecurityScheme]]
|
Security low.NodeReference[[]low.ValueReference[*SecurityRequirement]]
|
||||||
Security low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*SecurityRequirement]]
|
Tags low.NodeReference[[]low.ValueReference[*base.Tag]]
|
||||||
Tags low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*base.Tag]]
|
ExternalDocs low.NodeReference[*base.ExternalDoc]
|
||||||
ExternalDocs low.NodeReference[*base.ExternalDoc]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Index *index.SpecIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateDocument(info *datamodel.SpecInfo) (*Swagger, []error) {
|
||||||
|
|
||||||
|
doc := Swagger{Swagger: low.ValueReference[string]{Value: info.Version, ValueNode: info.RootNode}}
|
||||||
|
doc.Extensions = low.ExtractExtensions(info.RootNode.Content[0])
|
||||||
|
|
||||||
|
// 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 errors []error
|
||||||
|
|
||||||
|
extractionFuncs := []documentFunction{
|
||||||
|
extractInfo,
|
||||||
|
extractPaths,
|
||||||
|
extractDefinitions,
|
||||||
|
extractParamDefinitions,
|
||||||
|
extractResponsesDefinitions,
|
||||||
|
extractSecurityDefinitions,
|
||||||
|
}
|
||||||
|
doneChan := make(chan bool)
|
||||||
|
errChan := make(chan error)
|
||||||
|
for i := range extractionFuncs {
|
||||||
|
go extractionFuncs[i](info.RootNode, &doc, idx, doneChan, errChan)
|
||||||
|
}
|
||||||
|
completedExtractions := 0
|
||||||
|
for completedExtractions < len(extractionFuncs) {
|
||||||
|
select {
|
||||||
|
case <-doneChan:
|
||||||
|
completedExtractions++
|
||||||
|
case e := <-errChan:
|
||||||
|
errors = append(errors, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &doc, errors
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractInfo(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error) {
|
||||||
|
info, err := low.ExtractObject[*base.Info](base.InfoLabel, root, idx)
|
||||||
|
if err != nil {
|
||||||
|
e <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
doc.Info = info
|
||||||
|
c <- true
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractPaths(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error) {
|
||||||
|
paths, err := low.ExtractObject[*Paths](PathsLabel, root, idx)
|
||||||
|
if err != nil {
|
||||||
|
e <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
doc.Paths = paths
|
||||||
|
c <- true
|
||||||
|
}
|
||||||
|
func extractDefinitions(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error) {
|
||||||
|
def, err := low.ExtractObject[*Definitions](DefinitionsLabel, root, idx)
|
||||||
|
if err != nil {
|
||||||
|
e <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
doc.Definitions = def
|
||||||
|
c <- true
|
||||||
|
}
|
||||||
|
func extractParamDefinitions(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error) {
|
||||||
|
param, err := low.ExtractObject[*ParameterDefinitions](ParametersLabel, root, idx)
|
||||||
|
if err != nil {
|
||||||
|
e <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
doc.Parameters = param
|
||||||
|
c <- true
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractResponsesDefinitions(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error) {
|
||||||
|
resp, err := low.ExtractObject[*ResponsesDefinitions](ResponsesLabel, root, idx)
|
||||||
|
if err != nil {
|
||||||
|
e <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
doc.ResponsesDefinitions = resp
|
||||||
|
c <- true
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractSecurityDefinitions(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error) {
|
||||||
|
sec, err := low.ExtractObject[*SecurityDefinitions](SecurityLabel, root, idx)
|
||||||
|
if err != nil {
|
||||||
|
e <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
doc.SecurityDefinitions = sec
|
||||||
|
c <- true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import (
|
|||||||
|
|
||||||
func CreateDocument(info *datamodel.SpecInfo) (*Document, []error) {
|
func CreateDocument(info *datamodel.SpecInfo) (*Document, []error) {
|
||||||
|
|
||||||
// clean state
|
|
||||||
doc := Document{Version: low.ValueReference[string]{Value: info.Version, ValueNode: info.RootNode}}
|
doc := Document{Version: low.ValueReference[string]{Value: info.Version, ValueNode: info.RootNode}}
|
||||||
|
|
||||||
// build an index
|
// build an index
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ func (ex *Example) FindExtension(ext string) *low.ValueReference[any] {
|
|||||||
|
|
||||||
func (ex *Example) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (ex *Example) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
ex.Extensions = low.ExtractExtensions(root)
|
ex.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
_, ln, vn := utils.FindKeyNodeFull(ValueLabel, root.Content)
|
_, ln, vn := utils.FindKeyNodeFull(ValueLabel, root.Content)
|
||||||
|
|
||||||
if vn != nil {
|
if vn != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user