mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 20:47:49 +00:00
We-worked model to remove resolver.
lookups are performed inline now. keeps things simpler, however it has a performance knock, so it's time to refine async building were possible.
This commit is contained in:
@@ -2,6 +2,8 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,22 +16,28 @@ func (cb *Callback) FindExpression(exp string) *low.ValueReference[*PathItem] {
|
|||||||
return FindItemInMap[*PathItem](exp, cb.Expression.Value)
|
return FindItemInMap[*PathItem](exp, cb.Expression.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cb *Callback) Build(root *yaml.Node) error {
|
func (cb *Callback) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
extensionMap, err := ExtractExtensions(root)
|
cb.Extensions = ExtractExtensions(root)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
cb.Extensions = extensionMap
|
|
||||||
|
|
||||||
// handle callback
|
// handle callback
|
||||||
var currentCB *yaml.Node
|
var currentCB *yaml.Node
|
||||||
callbacks := make(map[low.KeyReference[string]]low.ValueReference[*PathItem])
|
callbacks := make(map[low.KeyReference[string]]low.ValueReference[*PathItem])
|
||||||
|
|
||||||
|
if ok, _, _ := utils.IsNodeRefValue(root); ok {
|
||||||
|
r := LocateRefNode(root, idx)
|
||||||
|
if r != nil {
|
||||||
|
root = r
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for i, callbackNode := range root.Content {
|
for i, callbackNode := range root.Content {
|
||||||
if i%2 == 0 {
|
if i%2 == 0 {
|
||||||
currentCB = callbackNode
|
currentCB = callbackNode
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
callback, eErr := ExtractObjectRaw[*PathItem](callbackNode)
|
callback, eErr := ExtractObjectRaw[*PathItem](callbackNode, idx)
|
||||||
if eErr != nil {
|
if eErr != nil {
|
||||||
return eErr
|
return eErr
|
||||||
}
|
}
|
||||||
|
|||||||
36
datamodel/low/3.0/callback_test.go
Normal file
36
datamodel/low/3.0/callback_test.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package v3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCallback_Build_Success(t *testing.T) {
|
||||||
|
|
||||||
|
yml := `'{$request.query.queryUrl}':
|
||||||
|
post:
|
||||||
|
requestBody:
|
||||||
|
description: Callback payload
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: callback successfully processed`
|
||||||
|
|
||||||
|
var rootNode yaml.Node
|
||||||
|
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
|
||||||
|
assert.NoError(t, mErr)
|
||||||
|
|
||||||
|
var n Callback
|
||||||
|
err := BuildModel(rootNode.Content[0], &n)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
err = n.Build(rootNode.Content[0], nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Len(t, n.Expression.Value, 1)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -56,12 +57,8 @@ func (co *Components) FindCallback(callback string) *low.ValueReference[*Callbac
|
|||||||
return FindItemInMap[*Callback](callback, co.Callbacks.Value)
|
return FindItemInMap[*Callback](callback, co.Callbacks.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (co *Components) Build(root *yaml.Node) error {
|
func (co *Components) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
extensionMap, err := ExtractExtensions(root)
|
co.Extensions = ExtractExtensions(root)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
co.Extensions = extensionMap
|
|
||||||
|
|
||||||
// build out components asynchronously for speed. There could be some significant weight here.
|
// build out components asynchronously for speed. There could be some significant weight here.
|
||||||
skipChan := make(chan bool)
|
skipChan := make(chan bool)
|
||||||
@@ -76,15 +73,15 @@ func (co *Components) Build(root *yaml.Node) error {
|
|||||||
linkChan := make(chan low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Link]])
|
linkChan := make(chan low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Link]])
|
||||||
callbackChan := make(chan low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Callback]])
|
callbackChan := make(chan low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Callback]])
|
||||||
|
|
||||||
go extractComponentValues[*Schema](SchemasLabel, root, skipChan, errorChan, schemaChan)
|
go extractComponentValues[*Schema](SchemasLabel, root, skipChan, errorChan, schemaChan, idx)
|
||||||
go extractComponentValues[*Parameter](ParametersLabel, root, skipChan, errorChan, paramChan)
|
go extractComponentValues[*Parameter](ParametersLabel, root, skipChan, errorChan, paramChan, idx)
|
||||||
go extractComponentValues[*Response](ResponsesLabel, root, skipChan, errorChan, responsesChan)
|
go extractComponentValues[*Response](ResponsesLabel, root, skipChan, errorChan, responsesChan, idx)
|
||||||
go extractComponentValues[*Example](ExamplesLabel, root, skipChan, errorChan, examplesChan)
|
go extractComponentValues[*Example](ExamplesLabel, root, skipChan, errorChan, examplesChan, idx)
|
||||||
go extractComponentValues[*RequestBody](RequestBodiesLabel, root, skipChan, errorChan, requestBodiesChan)
|
go extractComponentValues[*RequestBody](RequestBodiesLabel, root, skipChan, errorChan, requestBodiesChan, idx)
|
||||||
go extractComponentValues[*Header](HeadersLabel, root, skipChan, errorChan, headersChan)
|
go extractComponentValues[*Header](HeadersLabel, root, skipChan, errorChan, headersChan, idx)
|
||||||
go extractComponentValues[*SecurityScheme](SecuritySchemesLabel, root, skipChan, errorChan, securitySchemesChan)
|
go extractComponentValues[*SecurityScheme](SecuritySchemesLabel, root, skipChan, errorChan, securitySchemesChan, idx)
|
||||||
go extractComponentValues[*Link](LinksLabel, root, skipChan, errorChan, linkChan)
|
go extractComponentValues[*Link](LinksLabel, root, skipChan, errorChan, linkChan, idx)
|
||||||
go extractComponentValues[*Callback](CallbacksLabel, root, skipChan, errorChan, callbackChan)
|
go extractComponentValues[*Callback](CallbacksLabel, root, skipChan, errorChan, callbackChan, idx)
|
||||||
|
|
||||||
n := 0
|
n := 0
|
||||||
total := 9
|
total := 9
|
||||||
@@ -159,7 +156,7 @@ allDone:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func extractComponentValues[T low.Buildable[N], N any](label string, root *yaml.Node,
|
func extractComponentValues[T low.Buildable[N], N any](label string, root *yaml.Node,
|
||||||
skip chan bool, errorChan chan<- error, resultChan chan<- low.NodeReference[map[low.KeyReference[string]]low.ValueReference[T]]) {
|
skip chan bool, errorChan chan<- error, resultChan chan<- low.NodeReference[map[low.KeyReference[string]]low.ValueReference[T]], idx *index.SpecIndex) {
|
||||||
_, nodeLabel, nodeValue := utils.FindKeyNodeFull(label, root.Content)
|
_, nodeLabel, nodeValue := utils.FindKeyNodeFull(label, root.Content)
|
||||||
if nodeValue == nil {
|
if nodeValue == nil {
|
||||||
skip <- true
|
skip <- true
|
||||||
@@ -177,7 +174,7 @@ func extractComponentValues[T low.Buildable[N], N any](label string, root *yaml.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
errorChan <- err
|
errorChan <- err
|
||||||
}
|
}
|
||||||
err = n.Build(v)
|
err = n.Build(v, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorChan <- err
|
errorChan <- err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -21,9 +22,9 @@ func (en *Encoding) FindHeader(hType string) *low.ValueReference[*Header] {
|
|||||||
return FindItemInMap[*Header](hType, en.Headers.Value)
|
return FindItemInMap[*Header](hType, en.Headers.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (en *Encoding) Build(root *yaml.Node) error {
|
func (en *Encoding) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
|
||||||
headers, hL, hN, err := ExtractMapFlat[*Header](HeadersLabel, root)
|
headers, hL, hN, err := ExtractMapFlat[*Header](HeadersLabel, root, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -20,19 +21,14 @@ type Example struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ex *Example) Build(root *yaml.Node) error {
|
func (ex *Example) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
// extract extensions
|
ex.Extensions = ExtractExtensions(root)
|
||||||
extensionMap, err := ExtractExtensions(root)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ex.Extensions = extensionMap
|
|
||||||
|
|
||||||
// extract value
|
// extract value
|
||||||
_, ln, vn := utils.FindKeyNodeFull(ValueLabel, root.Content)
|
_, ln, vn := utils.FindKeyNodeFull(ValueLabel, root.Content)
|
||||||
if vn != nil {
|
if vn != nil {
|
||||||
var n map[string]interface{}
|
var n map[string]interface{}
|
||||||
err = vn.Decode(&n)
|
err := vn.Decode(&n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -11,12 +12,7 @@ type ExternalDoc struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ex *ExternalDoc) Build(root *yaml.Node) error {
|
func (ex *ExternalDoc) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
// extract extensions
|
ex.Extensions = ExtractExtensions(root)
|
||||||
extensionMap, err := ExtractExtensions(root)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ex.Extensions = extensionMap
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -9,6 +10,13 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var KnownSchemas map[string]low.NodeReference[*Schema]
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
KnownSchemas = make(map[string]low.NodeReference[*Schema])
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func FindItemInMap[T any](item string, collection map[low.KeyReference[string]]low.ValueReference[T]) *low.ValueReference[T] {
|
func FindItemInMap[T any](item string, collection map[low.KeyReference[string]]low.ValueReference[T]) *low.ValueReference[T] {
|
||||||
for n, o := range collection {
|
for n, o := range collection {
|
||||||
if n.Value == item {
|
if n.Value == item {
|
||||||
@@ -18,15 +26,34 @@ func FindItemInMap[T any](item string, collection map[low.KeyReference[string]]l
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractSchema(root *yaml.Node) (*low.NodeReference[*Schema], error) {
|
func ExtractSchema(root *yaml.Node, idx *index.SpecIndex) (*low.NodeReference[*Schema], error) {
|
||||||
_, schLabel, schNode := utils.FindKeyNodeFull(SchemaLabel, root.Content)
|
var schLabel, schNode *yaml.Node
|
||||||
|
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
|
||||||
|
// locate reference in index.
|
||||||
|
ref := LocateRefNode(root, idx)
|
||||||
|
if ref != nil {
|
||||||
|
schNode = ref
|
||||||
|
schLabel = rl
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, schLabel, schNode = utils.FindKeyNodeFull(SchemaLabel, root.Content)
|
||||||
|
if schNode != nil {
|
||||||
|
if h, _, _ := utils.IsNodeRefValue(schNode); h {
|
||||||
|
ref := LocateRefNode(schNode, idx)
|
||||||
|
if ref != nil {
|
||||||
|
schNode = ref
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if schNode != nil {
|
if schNode != nil {
|
||||||
var schema Schema
|
var schema Schema
|
||||||
err := BuildModel(schNode, &schema)
|
err := BuildModel(schNode, &schema)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = schema.Build(schNode)
|
err = schema.Build(schNode, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -37,21 +64,49 @@ func ExtractSchema(root *yaml.Node) (*low.NodeReference[*Schema], error) {
|
|||||||
|
|
||||||
var mapLock sync.Mutex
|
var mapLock sync.Mutex
|
||||||
|
|
||||||
func ExtractObjectRaw[T low.Buildable[N], N any](root *yaml.Node) (T, error) {
|
func LocateRefNode(root *yaml.Node, idx *index.SpecIndex) *yaml.Node {
|
||||||
|
if rf, _, rv := utils.IsNodeRefValue(root); rf {
|
||||||
|
found := idx.GetMappedReferences()
|
||||||
|
if found != nil && found[rv] != nil {
|
||||||
|
return found[rv].Node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExtractObjectRaw[T low.Buildable[N], N any](root *yaml.Node, idx *index.SpecIndex) (T, error) {
|
||||||
var n T = new(N)
|
var n T = new(N)
|
||||||
err := BuildModel(root, n)
|
err := BuildModel(root, n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
err = n.Build(root)
|
err = n.Build(root, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractObject[T low.Buildable[N], N any](label string, root *yaml.Node) (low.NodeReference[T], error) {
|
func ExtractObject[T low.Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) (low.NodeReference[T], error) {
|
||||||
_, ln, vn := utils.FindKeyNodeFull(label, root.Content)
|
var ln, vn *yaml.Node
|
||||||
|
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
|
||||||
|
// locate reference in index.
|
||||||
|
ref := LocateRefNode(root, idx)
|
||||||
|
if ref != nil {
|
||||||
|
vn = ref
|
||||||
|
ln = rl
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, ln, vn = utils.FindKeyNodeFull(label, root.Content)
|
||||||
|
if vn != nil {
|
||||||
|
if h, _, _ := utils.IsNodeRefValue(vn); h {
|
||||||
|
ref := LocateRefNode(vn, idx)
|
||||||
|
if ref != nil {
|
||||||
|
vn = ref
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
var n T = new(N)
|
var n T = new(N)
|
||||||
err := BuildModel(vn, n)
|
err := BuildModel(vn, n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -60,7 +115,7 @@ func ExtractObject[T low.Buildable[N], N any](label string, root *yaml.Node) (lo
|
|||||||
if ln == nil {
|
if ln == nil {
|
||||||
return low.NodeReference[T]{}, nil
|
return low.NodeReference[T]{}, nil
|
||||||
}
|
}
|
||||||
err = n.Build(vn)
|
err = n.Build(vn, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return low.NodeReference[T]{}, err
|
return low.NodeReference[T]{}, err
|
||||||
}
|
}
|
||||||
@@ -71,17 +126,41 @@ func ExtractObject[T low.Buildable[N], N any](label string, root *yaml.Node) (lo
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractArray[T low.Buildable[N], N any](label string, root *yaml.Node) ([]low.ValueReference[T], *yaml.Node, *yaml.Node, error) {
|
func ExtractArray[T low.Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) ([]low.ValueReference[T], *yaml.Node, *yaml.Node, error) {
|
||||||
_, ln, vn := utils.FindKeyNodeFull(label, root.Content)
|
var ln, vn *yaml.Node
|
||||||
|
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
|
||||||
|
// locate reference in index.
|
||||||
|
ref := LocateRefNode(root, idx)
|
||||||
|
if ref != nil {
|
||||||
|
vn = ref
|
||||||
|
ln = rl
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, ln, vn = utils.FindKeyNodeFull(label, root.Content)
|
||||||
|
if vn != nil {
|
||||||
|
if h, _, _ := utils.IsNodeRefValue(vn); h {
|
||||||
|
ref := LocateRefNode(vn, idx)
|
||||||
|
if ref != nil {
|
||||||
|
vn = ref
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
var items []low.ValueReference[T]
|
var items []low.ValueReference[T]
|
||||||
if vn != nil && ln != nil {
|
if vn != nil && ln != nil {
|
||||||
for _, node := range vn.Content {
|
for _, node := range vn.Content {
|
||||||
|
if rf, _, _ := utils.IsNodeRefValue(node); rf {
|
||||||
|
ref := LocateRefNode(node, idx)
|
||||||
|
if ref != nil {
|
||||||
|
node = ref
|
||||||
|
}
|
||||||
|
}
|
||||||
var n T = new(N)
|
var n T = new(N)
|
||||||
err := BuildModel(node, n)
|
err := BuildModel(node, n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []low.ValueReference[T]{}, ln, vn, err
|
return []low.ValueReference[T]{}, ln, vn, err
|
||||||
}
|
}
|
||||||
berr := n.Build(node)
|
berr := n.Build(node, idx)
|
||||||
if berr != nil {
|
if berr != nil {
|
||||||
return nil, ln, vn, berr
|
return nil, ln, vn, berr
|
||||||
}
|
}
|
||||||
@@ -94,7 +173,7 @@ func ExtractArray[T low.Buildable[N], N any](label string, root *yaml.Node) ([]l
|
|||||||
return items, ln, vn, nil
|
return items, ln, vn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node) (map[low.KeyReference[string]]low.ValueReference[PT], error) {
|
func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node, idx *index.SpecIndex) (map[low.KeyReference[string]]low.ValueReference[PT], error) {
|
||||||
valueMap := make(map[low.KeyReference[string]]low.ValueReference[PT])
|
valueMap := make(map[low.KeyReference[string]]low.ValueReference[PT])
|
||||||
if utils.IsNodeMap(root) {
|
if utils.IsNodeMap(root) {
|
||||||
var currentKey *yaml.Node
|
var currentKey *yaml.Node
|
||||||
@@ -108,7 +187,7 @@ func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node) (map[lo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
berr := n.Build(node)
|
berr := n.Build(node, idx)
|
||||||
if berr != nil {
|
if berr != nil {
|
||||||
return nil, berr
|
return nil, berr
|
||||||
}
|
}
|
||||||
@@ -124,8 +203,26 @@ func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node) (map[lo
|
|||||||
return valueMap, nil
|
return valueMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node) (map[low.KeyReference[string]]low.ValueReference[PT], *yaml.Node, *yaml.Node, error) {
|
func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) (map[low.KeyReference[string]]low.ValueReference[PT], *yaml.Node, *yaml.Node, error) {
|
||||||
_, labelNode, valueNode := utils.FindKeyNodeFull(label, root.Content)
|
var labelNode, valueNode *yaml.Node
|
||||||
|
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
|
||||||
|
// locate reference in index.
|
||||||
|
ref := LocateRefNode(root, idx)
|
||||||
|
if ref != nil {
|
||||||
|
valueNode = ref
|
||||||
|
labelNode = rl
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, labelNode, valueNode = utils.FindKeyNodeFull(label, root.Content)
|
||||||
|
if valueNode != nil {
|
||||||
|
if h, _, _ := utils.IsNodeRefValue(valueNode); h {
|
||||||
|
ref := LocateRefNode(valueNode, idx)
|
||||||
|
if ref != nil {
|
||||||
|
valueNode = ref
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if valueNode != nil {
|
if valueNode != nil {
|
||||||
var currentLabelNode *yaml.Node
|
var currentLabelNode *yaml.Node
|
||||||
valueMap := make(map[low.KeyReference[string]]low.ValueReference[PT])
|
valueMap := make(map[low.KeyReference[string]]low.ValueReference[PT])
|
||||||
@@ -134,6 +231,15 @@ func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node) (
|
|||||||
currentLabelNode = en
|
currentLabelNode = en
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check our valueNode isn't a reference still.
|
||||||
|
if h, _, _ := utils.IsNodeRefValue(en); h {
|
||||||
|
ref := LocateRefNode(en, idx)
|
||||||
|
if ref != nil {
|
||||||
|
en = ref
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(strings.ToLower(currentLabelNode.Value), "x-") {
|
if strings.HasPrefix(strings.ToLower(currentLabelNode.Value), "x-") {
|
||||||
continue // yo, don't pay any attention to extensions, not here anyway.
|
continue // yo, don't pay any attention to extensions, not here anyway.
|
||||||
}
|
}
|
||||||
@@ -142,7 +248,7 @@ func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, labelNode, valueNode, err
|
return nil, labelNode, valueNode, err
|
||||||
}
|
}
|
||||||
berr := n.Build(en)
|
berr := n.Build(en, idx)
|
||||||
if berr != nil {
|
if berr != nil {
|
||||||
return nil, labelNode, valueNode, berr
|
return nil, labelNode, valueNode, berr
|
||||||
}
|
}
|
||||||
@@ -159,8 +265,19 @@ func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node) (
|
|||||||
return nil, labelNode, valueNode, nil
|
return nil, labelNode, valueNode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node) (map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[PT], error) {
|
func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) (map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[PT], error) {
|
||||||
_, labelNode, valueNode := utils.FindKeyNodeFull(label, root.Content)
|
var labelNode, valueNode *yaml.Node
|
||||||
|
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
|
||||||
|
// locate reference in index.
|
||||||
|
ref := LocateRefNode(root, idx)
|
||||||
|
if ref != nil {
|
||||||
|
valueNode = ref
|
||||||
|
labelNode = rl
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, labelNode, valueNode = utils.FindKeyNodeFull(label, root.Content)
|
||||||
|
}
|
||||||
|
|
||||||
if valueNode != nil {
|
if valueNode != nil {
|
||||||
var currentLabelNode *yaml.Node
|
var currentLabelNode *yaml.Node
|
||||||
valueMap := make(map[low.KeyReference[string]]low.ValueReference[PT])
|
valueMap := make(map[low.KeyReference[string]]low.ValueReference[PT])
|
||||||
@@ -177,7 +294,7 @@ func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node) (map[
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
berr := n.Build(en)
|
berr := n.Build(en, idx)
|
||||||
if berr != nil {
|
if berr != nil {
|
||||||
return nil, berr
|
return nil, berr
|
||||||
}
|
}
|
||||||
@@ -199,16 +316,13 @@ func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node) (map[
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractExtensions(root *yaml.Node) (map[low.KeyReference[string]]low.ValueReference[any], error) {
|
func ExtractExtensions(root *yaml.Node) map[low.KeyReference[string]]low.ValueReference[any] {
|
||||||
extensions := utils.FindExtensionNodes(root.Content)
|
extensions := utils.FindExtensionNodes(root.Content)
|
||||||
extensionMap := make(map[low.KeyReference[string]]low.ValueReference[any])
|
extensionMap := make(map[low.KeyReference[string]]low.ValueReference[any])
|
||||||
for _, ext := range extensions {
|
for _, ext := range extensions {
|
||||||
if utils.IsNodeMap(ext.Value) {
|
if utils.IsNodeMap(ext.Value) {
|
||||||
var v interface{}
|
var v interface{}
|
||||||
err := ext.Value.Decode(&v)
|
_ = ext.Value.Decode(&v)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
extensionMap[low.KeyReference[string]{
|
extensionMap[low.KeyReference[string]{
|
||||||
Value: ext.Key.Value,
|
Value: ext.Key.Value,
|
||||||
KeyNode: ext.Key,
|
KeyNode: ext.Key,
|
||||||
@@ -243,15 +357,12 @@ func ExtractExtensions(root *yaml.Node) (map[low.KeyReference[string]]low.ValueR
|
|||||||
}
|
}
|
||||||
if utils.IsNodeArray(ext.Value) {
|
if utils.IsNodeArray(ext.Value) {
|
||||||
var v []interface{}
|
var v []interface{}
|
||||||
err := ext.Value.Decode(&v)
|
_ = ext.Value.Decode(&v)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
extensionMap[low.KeyReference[string]{
|
extensionMap[low.KeyReference[string]{
|
||||||
Value: ext.Key.Value,
|
Value: ext.Key.Value,
|
||||||
KeyNode: ext.Key,
|
KeyNode: ext.Key,
|
||||||
}] = low.ValueReference[any]{Value: v, ValueNode: ext.Value}
|
}] = low.ValueReference[any]{Value: v, ValueNode: ext.Value}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return extensionMap, nil
|
return extensionMap
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -24,16 +25,11 @@ type Header struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Header) Build(root *yaml.Node) error {
|
func (h *Header) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
// extract extensions
|
h.Extensions = ExtractExtensions(root)
|
||||||
extensionMap, err := ExtractExtensions(root)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
h.Extensions = extensionMap
|
|
||||||
|
|
||||||
// handle examples if set.
|
// handle examples if set.
|
||||||
exps, eErr := ExtractMap[*Example](ExamplesLabel, root)
|
exps, eErr := ExtractMap[*Example](ExamplesLabel, root, idx)
|
||||||
if eErr != nil {
|
if eErr != nil {
|
||||||
return eErr
|
return eErr
|
||||||
}
|
}
|
||||||
@@ -42,7 +38,7 @@ func (h *Header) Build(root *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle schema
|
// handle schema
|
||||||
sch, sErr := ExtractSchema(root)
|
sch, sErr := ExtractSchema(root, idx)
|
||||||
if sErr != nil {
|
if sErr != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -51,7 +47,7 @@ func (h *Header) Build(root *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle content, if set.
|
// handle content, if set.
|
||||||
con, cErr := ExtractMap[*MediaType](ContentLabel, root)
|
con, cErr := ExtractMap[*MediaType](ContentLabel, root, idx)
|
||||||
if cErr != nil {
|
if cErr != nil {
|
||||||
return cErr
|
return cErr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -20,12 +21,8 @@ func (l *Link) FindParameter(pName string) *low.ValueReference[string] {
|
|||||||
return FindItemInMap[string](pName, l.Parameters.Value)
|
return FindItemInMap[string](pName, l.Parameters.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Link) Build(root *yaml.Node) error {
|
func (l *Link) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
extensionMap, err := ExtractExtensions(root)
|
l.Extensions = ExtractExtensions(root)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
l.Extensions = extensionMap
|
|
||||||
|
|
||||||
// extract parameters
|
// extract parameters
|
||||||
_, pl, pv := utils.FindKeyNodeFull(ParametersLabel, root.Content)
|
_, pl, pv := utils.FindKeyNodeFull(ParametersLabel, root.Content)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -26,14 +27,8 @@ func (mt *MediaType) GetAllExamples() map[low.KeyReference[string]]low.ValueRefe
|
|||||||
return mt.Examples.Value
|
return mt.Examples.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mt *MediaType) Build(root *yaml.Node) error {
|
func (mt *MediaType) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
mt.Extensions = ExtractExtensions(root)
|
||||||
// extract extensions
|
|
||||||
extensionMap, err := ExtractExtensions(root)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
mt.Extensions = extensionMap
|
|
||||||
|
|
||||||
// handle example if set.
|
// handle example if set.
|
||||||
_, expLabel, expNode := utils.FindKeyNodeFull(ExampleLabel, root.Content)
|
_, expLabel, expNode := utils.FindKeyNodeFull(ExampleLabel, root.Content)
|
||||||
@@ -42,7 +37,7 @@ func (mt *MediaType) Build(root *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle schema
|
// handle schema
|
||||||
sch, sErr := ExtractSchema(root)
|
sch, sErr := ExtractSchema(root, idx)
|
||||||
if sErr != nil {
|
if sErr != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -51,7 +46,7 @@ func (mt *MediaType) Build(root *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle examples if set.
|
// handle examples if set.
|
||||||
exps, expsL, expsN, eErr := ExtractMapFlat[*Example](ExamplesLabel, root)
|
exps, expsL, expsN, eErr := ExtractMapFlat[*Example](ExamplesLabel, root, idx)
|
||||||
if eErr != nil {
|
if eErr != nil {
|
||||||
return eErr
|
return eErr
|
||||||
}
|
}
|
||||||
@@ -64,9 +59,9 @@ func (mt *MediaType) Build(root *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle encoding
|
// handle encoding
|
||||||
encs, encsL, encsN, encErr := ExtractMapFlat[*Encoding](EncodingLabel, root)
|
encs, encsL, encsN, encErr := ExtractMapFlat[*Encoding](EncodingLabel, root, idx)
|
||||||
if encErr != nil {
|
if encErr != nil {
|
||||||
return err
|
return encErr
|
||||||
}
|
}
|
||||||
if encs != nil {
|
if encs != nil {
|
||||||
mt.Encoding = low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Encoding]]{
|
mt.Encoding = low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Encoding]]{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -22,32 +23,28 @@ type OAuthFlows struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OAuthFlows) Build(root *yaml.Node) error {
|
func (o *OAuthFlows) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
extensionMap, err := ExtractExtensions(root)
|
o.Extensions = ExtractExtensions(root)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
o.Extensions = extensionMap
|
|
||||||
|
|
||||||
v, vErr := ExtractObject[*OAuthFlow](ImplicitLabel, root)
|
v, vErr := ExtractObject[*OAuthFlow](ImplicitLabel, root, idx)
|
||||||
if vErr != nil {
|
if vErr != nil {
|
||||||
return vErr
|
return vErr
|
||||||
}
|
}
|
||||||
o.Implicit = v
|
o.Implicit = v
|
||||||
|
|
||||||
v, vErr = ExtractObject[*OAuthFlow](PasswordLabel, root)
|
v, vErr = ExtractObject[*OAuthFlow](PasswordLabel, root, idx)
|
||||||
if vErr != nil {
|
if vErr != nil {
|
||||||
return vErr
|
return vErr
|
||||||
}
|
}
|
||||||
o.Password = v
|
o.Password = v
|
||||||
|
|
||||||
v, vErr = ExtractObject[*OAuthFlow](ClientCredentialsLabel, root)
|
v, vErr = ExtractObject[*OAuthFlow](ClientCredentialsLabel, root, idx)
|
||||||
if vErr != nil {
|
if vErr != nil {
|
||||||
return vErr
|
return vErr
|
||||||
}
|
}
|
||||||
o.ClientCredentials = v
|
o.ClientCredentials = v
|
||||||
|
|
||||||
v, vErr = ExtractObject[*OAuthFlow](AuthorizationCodeLabel, root)
|
v, vErr = ExtractObject[*OAuthFlow](AuthorizationCodeLabel, root, idx)
|
||||||
if vErr != nil {
|
if vErr != nil {
|
||||||
return vErr
|
return vErr
|
||||||
}
|
}
|
||||||
@@ -68,12 +65,8 @@ func (o *OAuthFlow) FindScope(scope string) *low.ValueReference[string] {
|
|||||||
return FindItemInMap[string](scope, o.Scopes.Value)
|
return FindItemInMap[string](scope, o.Scopes.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OAuthFlow) Build(root *yaml.Node) error {
|
func (o *OAuthFlow) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
extensionMap, err := ExtractExtensions(root)
|
o.Extensions = ExtractExtensions(root)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
o.Extensions = extensionMap
|
|
||||||
|
|
||||||
var currSec *yaml.Node
|
var currSec *yaml.Node
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -29,22 +30,18 @@ type Operation struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Operation) Build(root *yaml.Node) error {
|
func (o *Operation) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
extensionMap, err := ExtractExtensions(root)
|
o.Extensions = ExtractExtensions(root)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
o.Extensions = extensionMap
|
|
||||||
|
|
||||||
// extract externalDocs
|
// extract externalDocs
|
||||||
extDocs, dErr := ExtractObject[*ExternalDoc](ExternalDocsLabel, root)
|
extDocs, dErr := ExtractObject[*ExternalDoc](ExternalDocsLabel, root, idx)
|
||||||
if dErr != nil {
|
if dErr != nil {
|
||||||
return dErr
|
return dErr
|
||||||
}
|
}
|
||||||
o.ExternalDocs = extDocs
|
o.ExternalDocs = extDocs
|
||||||
|
|
||||||
// extract parameters
|
// extract parameters
|
||||||
params, ln, vn, pErr := ExtractArray[*Parameter](ParametersLabel, root)
|
params, ln, vn, pErr := ExtractArray[*Parameter](ParametersLabel, root, idx)
|
||||||
if pErr != nil {
|
if pErr != nil {
|
||||||
return pErr
|
return pErr
|
||||||
}
|
}
|
||||||
@@ -57,21 +54,21 @@ func (o *Operation) Build(root *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// extract request body
|
// extract request body
|
||||||
rBody, rErr := ExtractObject[*RequestBody](RequestBodyLabel, root)
|
rBody, rErr := ExtractObject[*RequestBody](RequestBodyLabel, root, idx)
|
||||||
if rErr != nil {
|
if rErr != nil {
|
||||||
return rErr
|
return rErr
|
||||||
}
|
}
|
||||||
o.RequestBody = rBody
|
o.RequestBody = rBody
|
||||||
|
|
||||||
// extract responses
|
// extract responses
|
||||||
respBody, respErr := ExtractObject[*Responses](ResponsesLabel, root)
|
respBody, respErr := ExtractObject[*Responses](ResponsesLabel, root, idx)
|
||||||
if respErr != nil {
|
if respErr != nil {
|
||||||
return rErr
|
return rErr
|
||||||
}
|
}
|
||||||
o.Responses = respBody
|
o.Responses = respBody
|
||||||
|
|
||||||
// extract callbacks
|
// extract callbacks
|
||||||
callbacks, cbL, cbN, cbErr := ExtractMapFlat[*Callback](CallbacksLabel, root)
|
callbacks, cbL, cbN, cbErr := ExtractMapFlat[*Callback](CallbacksLabel, root, idx)
|
||||||
if cbErr != nil {
|
if cbErr != nil {
|
||||||
return cbErr
|
return cbErr
|
||||||
}
|
}
|
||||||
@@ -84,14 +81,14 @@ func (o *Operation) Build(root *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// extract security
|
// extract security
|
||||||
sec, sErr := ExtractObject[*SecurityRequirement](SecurityLabel, root)
|
sec, sErr := ExtractObject[*SecurityRequirement](SecurityLabel, root, idx)
|
||||||
if sErr != nil {
|
if sErr != nil {
|
||||||
return sErr
|
return sErr
|
||||||
}
|
}
|
||||||
o.Security = sec
|
o.Security = sec
|
||||||
|
|
||||||
// extract servers
|
// extract servers
|
||||||
servers, sl, sn, serErr := ExtractArray[*Server](ServersLabel, root)
|
servers, sl, sn, serErr := ExtractArray[*Server](ServersLabel, root, idx)
|
||||||
if serErr != nil {
|
if serErr != nil {
|
||||||
return serErr
|
return serErr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -36,14 +37,8 @@ func (p *Parameter) FindExample(eType string) *low.ValueReference[*Example] {
|
|||||||
return FindItemInMap[*Example](eType, p.Examples.Value)
|
return FindItemInMap[*Example](eType, p.Examples.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parameter) Build(root *yaml.Node) error {
|
func (p *Parameter) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
p.Extensions = ExtractExtensions(root)
|
||||||
// extract extensions
|
|
||||||
extensionMap, err := ExtractExtensions(root)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.Extensions = extensionMap
|
|
||||||
|
|
||||||
// handle example if set.
|
// handle example if set.
|
||||||
_, expLabel, expNode := utils.FindKeyNodeFull(ExampleLabel, root.Content)
|
_, expLabel, expNode := utils.FindKeyNodeFull(ExampleLabel, root.Content)
|
||||||
@@ -52,14 +47,16 @@ func (p *Parameter) Build(root *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle schema
|
// handle schema
|
||||||
sch, sErr := ExtractSchema(root)
|
sch, sErr := ExtractSchema(root, idx)
|
||||||
if sErr != nil {
|
if sErr != nil {
|
||||||
return sErr
|
return sErr
|
||||||
}
|
}
|
||||||
|
if sch != nil {
|
||||||
p.Schema = *sch
|
p.Schema = *sch
|
||||||
|
}
|
||||||
|
|
||||||
// handle examples if set.
|
// handle examples if set.
|
||||||
exps, expsL, expsN, eErr := ExtractMapFlat[*Example](ExamplesLabel, root)
|
exps, expsL, expsN, eErr := ExtractMapFlat[*Example](ExamplesLabel, root, idx)
|
||||||
if eErr != nil {
|
if eErr != nil {
|
||||||
return eErr
|
return eErr
|
||||||
}
|
}
|
||||||
@@ -72,7 +69,7 @@ func (p *Parameter) Build(root *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle content, if set.
|
// handle content, if set.
|
||||||
con, cL, cN, cErr := ExtractMapFlat[*MediaType](ContentLabel, root)
|
con, cL, cN, cErr := ExtractMapFlat[*MediaType](ContentLabel, root, idx)
|
||||||
if cErr != nil {
|
if cErr != nil {
|
||||||
return cErr
|
return cErr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -33,14 +35,8 @@ func (p *Paths) FindPath(path string) *low.ValueReference[*PathItem] {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Paths) Build(root *yaml.Node) error {
|
func (p *Paths) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
p.Extensions = ExtractExtensions(root)
|
||||||
// extract extensions
|
|
||||||
extensionMap, err := ExtractExtensions(root)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.Extensions = extensionMap
|
|
||||||
skip := false
|
skip := false
|
||||||
var currentNode *yaml.Node
|
var currentNode *yaml.Node
|
||||||
|
|
||||||
@@ -60,11 +56,11 @@ func (p *Paths) Build(root *yaml.Node) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var path = PathItem{}
|
var path = PathItem{}
|
||||||
err = BuildModel(pathNode, &path)
|
err := BuildModel(pathNode, &path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
}
|
}
|
||||||
err = path.Build(pathNode)
|
err = path.Build(pathNode, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -100,12 +96,8 @@ type PathItem struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PathItem) Build(root *yaml.Node) error {
|
func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
extensionMap, err := ExtractExtensions(root)
|
p.Extensions = ExtractExtensions(root)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.Extensions = extensionMap
|
|
||||||
skip := false
|
skip := false
|
||||||
var currentNode *yaml.Node
|
var currentNode *yaml.Node
|
||||||
|
|
||||||
@@ -114,6 +106,15 @@ func (p *PathItem) Build(root *yaml.Node) error {
|
|||||||
|
|
||||||
var ops []low.NodeReference[*Operation]
|
var ops []low.NodeReference[*Operation]
|
||||||
|
|
||||||
|
if ok, _, _ := utils.IsNodeRefValue(root); ok {
|
||||||
|
r := LocateRefNode(root, idx)
|
||||||
|
if r != nil {
|
||||||
|
root = r
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for i, pathNode := range root.Content {
|
for i, pathNode := range root.Content {
|
||||||
if strings.HasPrefix(strings.ToLower(pathNode.Value), "x-") {
|
if strings.HasPrefix(strings.ToLower(pathNode.Value), "x-") {
|
||||||
skip = true
|
skip = true
|
||||||
@@ -161,7 +162,9 @@ func (p *PathItem) Build(root *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
if len(ops) > 0 {
|
||||||
|
//wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
//all operations have been superficially built,
|
//all operations have been superficially built,
|
||||||
//now we need to build out the operation, we will do this asynchronously for speed.
|
//now we need to build out the operation, we will do this asynchronously for speed.
|
||||||
@@ -171,8 +174,8 @@ func (p *PathItem) Build(root *yaml.Node) error {
|
|||||||
var buildOpFunc = func(op low.NodeReference[*Operation], ch chan<- bool, errCh chan<- error) {
|
var buildOpFunc = func(op low.NodeReference[*Operation], ch chan<- bool, errCh chan<- error) {
|
||||||
|
|
||||||
//build out the operation.
|
//build out the operation.
|
||||||
er := op.Value.Build(op.ValueNode)
|
er := op.Value.Build(op.ValueNode, idx)
|
||||||
if err != nil {
|
if er != nil {
|
||||||
errCh <- er
|
errCh <- er
|
||||||
}
|
}
|
||||||
ch <- true
|
ch <- true
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -16,18 +17,11 @@ func (rb *RequestBody) FindContent(cType string) *low.ValueReference[*MediaType]
|
|||||||
return FindItemInMap[*MediaType](cType, rb.Content.Value)
|
return FindItemInMap[*MediaType](cType, rb.Content.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rb *RequestBody) Build(root *yaml.Node) error {
|
func (rb *RequestBody) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
// extract extensions
|
rb.Extensions = ExtractExtensions(root)
|
||||||
extensionMap, err := ExtractExtensions(root)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if extensionMap != nil {
|
|
||||||
rb.Extensions = extensionMap
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle content, if set.
|
// handle content, if set.
|
||||||
con, cL, cN, cErr := ExtractMapFlat[*MediaType](ContentLabel, root)
|
con, cL, cN, cErr := ExtractMapFlat[*MediaType](ContentLabel, root, idx)
|
||||||
if cErr != nil {
|
if cErr != nil {
|
||||||
return cErr
|
return cErr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -15,9 +16,9 @@ type Responses struct {
|
|||||||
Default low.NodeReference[*Response]
|
Default low.NodeReference[*Response]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Responses) Build(root *yaml.Node) error {
|
func (r *Responses) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
if utils.IsNodeMap(root) {
|
if utils.IsNodeMap(root) {
|
||||||
codes, err := ExtractMapFlatNoLookup[*Response](root)
|
codes, err := ExtractMapFlatNoLookup[*Response](root, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -52,15 +53,11 @@ func (r *Response) FindLink(hType string) *low.ValueReference[*Link] {
|
|||||||
return FindItemInMap[*Link](hType, r.Links.Value)
|
return FindItemInMap[*Link](hType, r.Links.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Response) Build(root *yaml.Node) error {
|
func (r *Response) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
extensionMap, err := ExtractExtensions(root)
|
r.Extensions = ExtractExtensions(root)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
r.Extensions = extensionMap
|
|
||||||
|
|
||||||
// extract headers
|
// extract headers
|
||||||
headers, lN, kN, err := ExtractMapFlat[*Header](HeadersLabel, root)
|
headers, lN, kN, err := ExtractMapFlat[*Header](HeadersLabel, root, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -73,7 +70,7 @@ func (r *Response) Build(root *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle content, if set.
|
// handle content, if set.
|
||||||
con, clN, cN, cErr := ExtractMapFlat[*MediaType](ContentLabel, root)
|
con, clN, cN, cErr := ExtractMapFlat[*MediaType](ContentLabel, root, idx)
|
||||||
if cErr != nil {
|
if cErr != nil {
|
||||||
return cErr
|
return cErr
|
||||||
}
|
}
|
||||||
@@ -86,7 +83,7 @@ func (r *Response) Build(root *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle links if set
|
// handle links if set
|
||||||
links, linkLabel, linkValue, lErr := ExtractMapFlat[*Link](LinksLabel, root)
|
links, linkLabel, linkValue, lErr := ExtractMapFlat[*Link](LinksLabel, root, idx)
|
||||||
if lErr != nil {
|
if lErr != nil {
|
||||||
return lErr
|
return lErr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -61,20 +62,17 @@ func (s *Schema) FindProperty(name string) *low.ValueReference[*Schema] {
|
|||||||
return FindItemInMap[*Schema](name, s.Properties.Value)
|
return FindItemInMap[*Schema](name, s.Properties.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Schema) Build(root *yaml.Node) error {
|
func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
return s.BuildLevel(root, 0)
|
return s.BuildLevel(root, idx, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Schema) BuildLevel(root *yaml.Node, level int) error {
|
func (s *Schema) BuildLevel(root *yaml.Node, idx *index.SpecIndex, level int) error {
|
||||||
level++
|
level++
|
||||||
if level > 50 {
|
if level > 10 {
|
||||||
return nil // we're done, son! too fricken deep.
|
return nil // we're done, son! too fricken deep.
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.extractExtensions(root)
|
s.extractExtensions(root)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle example if set.
|
// handle example if set.
|
||||||
_, expLabel, expNode := utils.FindKeyNodeFull(ExampleLabel, root.Content)
|
_, expLabel, expNode := utils.FindKeyNodeFull(ExampleLabel, root.Content)
|
||||||
@@ -85,7 +83,7 @@ func (s *Schema) BuildLevel(root *yaml.Node, level int) error {
|
|||||||
_, addPLabel, addPNode := utils.FindKeyNodeFull(AdditionalPropertiesLabel, root.Content)
|
_, addPLabel, addPNode := utils.FindKeyNodeFull(AdditionalPropertiesLabel, root.Content)
|
||||||
if addPNode != nil {
|
if addPNode != nil {
|
||||||
if utils.IsNodeMap(addPNode) {
|
if utils.IsNodeMap(addPNode) {
|
||||||
schema, serr := ExtractObjectRaw[*Schema](addPNode)
|
schema, serr := ExtractObjectRaw[*Schema](addPNode, idx)
|
||||||
if serr != nil {
|
if serr != nil {
|
||||||
return serr
|
return serr
|
||||||
}
|
}
|
||||||
@@ -102,7 +100,7 @@ func (s *Schema) BuildLevel(root *yaml.Node, level int) error {
|
|||||||
_, discLabel, discNode := utils.FindKeyNodeFull(DiscriminatorLabel, root.Content)
|
_, discLabel, discNode := utils.FindKeyNodeFull(DiscriminatorLabel, root.Content)
|
||||||
if discNode != nil {
|
if discNode != nil {
|
||||||
var discriminator Discriminator
|
var discriminator Discriminator
|
||||||
err = BuildModel(discNode, &discriminator)
|
err := BuildModel(discNode, &discriminator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -113,11 +111,11 @@ func (s *Schema) BuildLevel(root *yaml.Node, level int) error {
|
|||||||
_, extDocLabel, extDocNode := utils.FindKeyNodeFull(ExternalDocsLabel, root.Content)
|
_, extDocLabel, extDocNode := utils.FindKeyNodeFull(ExternalDocsLabel, root.Content)
|
||||||
if extDocNode != nil {
|
if extDocNode != nil {
|
||||||
var exDoc ExternalDoc
|
var exDoc ExternalDoc
|
||||||
err = BuildModel(extDocNode, &exDoc)
|
err := BuildModel(extDocNode, &exDoc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = exDoc.Build(extDocNode)
|
err = exDoc.Build(extDocNode, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -128,7 +126,7 @@ func (s *Schema) BuildLevel(root *yaml.Node, level int) error {
|
|||||||
_, xmlLabel, xmlNode := utils.FindKeyNodeFull(XMLLabel, root.Content)
|
_, xmlLabel, xmlNode := utils.FindKeyNodeFull(XMLLabel, root.Content)
|
||||||
if xmlNode != nil {
|
if xmlNode != nil {
|
||||||
var xml XML
|
var xml XML
|
||||||
err = BuildModel(xmlNode, &xml)
|
err := BuildModel(xmlNode, &xml)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -150,12 +148,21 @@ func (s *Schema) BuildLevel(root *yaml.Node, level int) error {
|
|||||||
currentProp = prop
|
currentProp = prop
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check our prop isn't reference
|
||||||
|
if h, _, _ := utils.IsNodeRefValue(prop); h {
|
||||||
|
ref := LocateRefNode(prop, idx)
|
||||||
|
if ref != nil {
|
||||||
|
prop = ref
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var property Schema
|
var property Schema
|
||||||
err = BuildModel(prop, &property)
|
err := BuildModel(prop, &property)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = property.BuildLevel(prop, level)
|
err = property.BuildLevel(prop, idx, level)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -179,11 +186,11 @@ func (s *Schema) BuildLevel(root *yaml.Node, level int) error {
|
|||||||
var allOf, anyOf, oneOf, not, items []low.NodeReference[*Schema]
|
var allOf, anyOf, oneOf, not, items []low.NodeReference[*Schema]
|
||||||
|
|
||||||
// make this async at some point to speed things up.
|
// make this async at some point to speed things up.
|
||||||
allOfLabel, allOfValue := buildSchema(&allOf, AllOfLabel, root, level, &errors)
|
allOfLabel, allOfValue := buildSchema(&allOf, AllOfLabel, root, level, &errors, idx)
|
||||||
anyOfLabel, anyOfValue := buildSchema(&anyOf, AnyOfLabel, root, level, &errors)
|
anyOfLabel, anyOfValue := buildSchema(&anyOf, AnyOfLabel, root, level, &errors, idx)
|
||||||
oneOfLabel, oneOfValue := buildSchema(&oneOf, OneOfLabel, root, level, &errors)
|
oneOfLabel, oneOfValue := buildSchema(&oneOf, OneOfLabel, root, level, &errors, idx)
|
||||||
notLabel, notValue := buildSchema(¬, NotLabel, root, level, &errors)
|
notLabel, notValue := buildSchema(¬, NotLabel, root, level, &errors, idx)
|
||||||
itemsLabel, itemsValue := buildSchema(&items, ItemsLabel, root, level, &errors)
|
itemsLabel, itemsValue := buildSchema(&items, ItemsLabel, root, level, &errors, idx)
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
// todo fix this
|
// todo fix this
|
||||||
@@ -228,16 +235,13 @@ func (s *Schema) BuildLevel(root *yaml.Node, level int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Schema) extractExtensions(root *yaml.Node) error {
|
func (s *Schema) extractExtensions(root *yaml.Node) {
|
||||||
extensionMap, err := ExtractExtensions(root)
|
s.Extensions = ExtractExtensions(root)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
s.Extensions = extensionMap
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildSchema(schemas *[]low.NodeReference[*Schema], attribute string, rootNode *yaml.Node, level int, errors *[]error) (labelNode *yaml.Node, valueNode *yaml.Node) {
|
func buildSchema(schemas *[]low.NodeReference[*Schema], attribute string, rootNode *yaml.Node, level int,
|
||||||
|
errors *[]error, idx *index.SpecIndex) (labelNode *yaml.Node, valueNode *yaml.Node) {
|
||||||
|
|
||||||
_, labelNode, valueNode = utils.FindKeyNodeFull(attribute, rootNode.Content)
|
_, labelNode, valueNode = utils.FindKeyNodeFull(attribute, rootNode.Content)
|
||||||
//wg.Add(1)
|
//wg.Add(1)
|
||||||
if valueNode != nil {
|
if valueNode != nil {
|
||||||
@@ -248,7 +252,7 @@ func buildSchema(schemas *[]low.NodeReference[*Schema], attribute string, rootNo
|
|||||||
*errors = append(*errors, err)
|
*errors = append(*errors, err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err = schema.BuildLevel(vn, level)
|
err = schema.BuildLevel(vn, idx, level)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
*errors = append(*errors, err)
|
*errors = append(*errors, err)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ additionalProperties: true `
|
|||||||
mbErr := BuildModel(&rootNode, &sch)
|
mbErr := BuildModel(&rootNode, &sch)
|
||||||
assert.NoError(t, mbErr)
|
assert.NoError(t, mbErr)
|
||||||
|
|
||||||
schErr := sch.Build(rootNode.Content[0])
|
schErr := sch.Build(rootNode.Content[0], nil)
|
||||||
assert.NoError(t, schErr)
|
assert.NoError(t, schErr)
|
||||||
assert.Equal(t, "something object", sch.Description.Value)
|
assert.Equal(t, "something object", sch.Description.Value)
|
||||||
assert.True(t, sch.AdditionalProperties.Value.(bool))
|
assert.True(t, sch.AdditionalProperties.Value.(bool))
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -28,14 +29,10 @@ type SecurityRequirement struct {
|
|||||||
Value []low.ValueReference[map[low.KeyReference[string]][]low.ValueReference[string]]
|
Value []low.ValueReference[map[low.KeyReference[string]][]low.ValueReference[string]]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SecurityScheme) Build(root *yaml.Node) error {
|
func (ss *SecurityScheme) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
extensionMap, err := ExtractExtensions(root)
|
ss.Extensions = ExtractExtensions(root)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ss.Extensions = extensionMap
|
|
||||||
|
|
||||||
oa, oaErr := ExtractObject[*OAuthFlows](OAuthFlowsLabel, root)
|
oa, oaErr := ExtractObject[*OAuthFlows](OAuthFlowsLabel, root, idx)
|
||||||
if oaErr != nil {
|
if oaErr != nil {
|
||||||
return oaErr
|
return oaErr
|
||||||
}
|
}
|
||||||
@@ -57,7 +54,7 @@ func (sr *SecurityRequirement) FindRequirement(name string) []low.ValueReference
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sr *SecurityRequirement) Build(root *yaml.Node) error {
|
func (sr *SecurityRequirement) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
if utils.IsNodeArray(root) {
|
if utils.IsNodeArray(root) {
|
||||||
var requirements []low.ValueReference[map[low.KeyReference[string]][]low.ValueReference[string]]
|
var requirements []low.ValueReference[map[low.KeyReference[string]][]low.ValueReference[string]]
|
||||||
for _, n := range root.Content {
|
for _, n := range root.Content {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -17,7 +18,7 @@ type Server struct {
|
|||||||
Variables low.NodeReference[map[string]low.NodeReference[*ServerVariable]]
|
Variables low.NodeReference[map[string]low.NodeReference[*ServerVariable]]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Build(root *yaml.Node) error {
|
func (s *Server) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
kn, vars := utils.FindKeyNode(VariablesLabel, root.Content)
|
kn, vars := utils.FindKeyNode(VariablesLabel, root.Content)
|
||||||
if vars == nil {
|
if vars == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -17,16 +18,11 @@ type Tag struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tag) Build(root *yaml.Node) error {
|
func (t *Tag) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
// extract extensions
|
t.Extensions = ExtractExtensions(root)
|
||||||
extensionMap, err := ExtractExtensions(root)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
t.Extensions = extensionMap
|
|
||||||
|
|
||||||
// extract externalDocs
|
// extract externalDocs
|
||||||
extDocs, dErr := ExtractObject[*ExternalDoc](ExternalDocsLabel, root)
|
extDocs, dErr := ExtractObject[*ExternalDoc](ExternalDocsLabel, root, idx)
|
||||||
if dErr != nil {
|
if dErr != nil {
|
||||||
return dErr
|
return dErr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,6 @@ type XML struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (x *XML) Build(root *yaml.Node) error {
|
func (x *XML) Build(root *yaml.Node) error {
|
||||||
extensionMap, err := ExtractExtensions(root)
|
x.Extensions = ExtractExtensions(root)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
x.Extensions = extensionMap
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
package low
|
package low
|
||||||
|
|
||||||
import "gopkg.in/yaml.v3"
|
import (
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
type HasNode interface {
|
type HasNode interface {
|
||||||
GetNode() *yaml.Node
|
GetNode() *yaml.Node
|
||||||
}
|
}
|
||||||
|
|
||||||
type Buildable[T any] interface {
|
type Buildable[T any] interface {
|
||||||
Build(node *yaml.Node) error
|
Build(node *yaml.Node, idx *index.SpecIndex) error
|
||||||
*T
|
*T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
localResolve int = 0
|
LocalResolve int = 0
|
||||||
httpResolve int = 1
|
HttpResolve int = 1
|
||||||
fileResolve int = 2
|
FileResolve int = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
// Reference is a wrapper around *yaml.Node results to make things more manageable when performing
|
// Reference is a wrapper around *yaml.Node results to make things more manageable when performing
|
||||||
@@ -72,7 +72,8 @@ type SpecIndex struct {
|
|||||||
responsesRefs map[string]*Reference // top level responses
|
responsesRefs map[string]*Reference // top level responses
|
||||||
headersRefs map[string]*Reference // top level responses
|
headersRefs map[string]*Reference // top level responses
|
||||||
examplesRefs map[string]*Reference // top level examples
|
examplesRefs map[string]*Reference // top level examples
|
||||||
linksRefs map[string]map[string][]*Reference // all links
|
callbacksRefs map[string]map[string][]*Reference // all links
|
||||||
|
linksRefs map[string]map[string][]*Reference // all callbacks
|
||||||
operationTagsRefs map[string]map[string][]*Reference // tags found in operations
|
operationTagsRefs map[string]map[string][]*Reference // tags found in operations
|
||||||
operationDescriptionRefs map[string]map[string]*Reference // descriptions in operations.
|
operationDescriptionRefs map[string]map[string]*Reference // descriptions in operations.
|
||||||
operationSummaryRefs map[string]map[string]*Reference // summaries in operations
|
operationSummaryRefs map[string]map[string]*Reference // summaries in operations
|
||||||
@@ -99,6 +100,7 @@ type SpecIndex struct {
|
|||||||
globalHeadersCount int // component headers
|
globalHeadersCount int // component headers
|
||||||
globalExamplesCount int // component examples
|
globalExamplesCount int // component examples
|
||||||
globalLinksCount int // component links
|
globalLinksCount int // component links
|
||||||
|
globalCallbacksCount int // component callbacks
|
||||||
globalCallbacks int // component callbacks.
|
globalCallbacks int // component callbacks.
|
||||||
pathCount int // number of paths
|
pathCount int // number of paths
|
||||||
operationCount int // number of operations
|
operationCount int // number of operations
|
||||||
@@ -207,6 +209,7 @@ func NewSpecIndex(rootNode *yaml.Node) *SpecIndex {
|
|||||||
index.responsesRefs = make(map[string]*Reference)
|
index.responsesRefs = make(map[string]*Reference)
|
||||||
index.headersRefs = make(map[string]*Reference)
|
index.headersRefs = make(map[string]*Reference)
|
||||||
index.examplesRefs = make(map[string]*Reference)
|
index.examplesRefs = make(map[string]*Reference)
|
||||||
|
index.callbacksRefs = make(map[string]map[string][]*Reference)
|
||||||
index.linksRefs = make(map[string]map[string][]*Reference)
|
index.linksRefs = make(map[string]map[string][]*Reference)
|
||||||
index.callbackRefs = make(map[string]*Reference)
|
index.callbackRefs = make(map[string]*Reference)
|
||||||
index.externalSpecIndex = make(map[string]*SpecIndex)
|
index.externalSpecIndex = make(map[string]*SpecIndex)
|
||||||
@@ -256,6 +259,7 @@ func NewSpecIndex(rootNode *yaml.Node) *SpecIndex {
|
|||||||
index.GetInlineUniqueParamCount,
|
index.GetInlineUniqueParamCount,
|
||||||
index.GetOperationTagsCount,
|
index.GetOperationTagsCount,
|
||||||
index.GetGlobalLinksCount,
|
index.GetGlobalLinksCount,
|
||||||
|
index.GetGlobalCallbacksCount,
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Add(len(countFuncs))
|
wg.Add(len(countFuncs))
|
||||||
@@ -872,13 +876,59 @@ func (index *SpecIndex) GetTotalTagsCount() int {
|
|||||||
return index.totalTagsCount
|
return index.totalTagsCount
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetGlobalLinksCount for each response of each operation method, multiple links can be defined
|
// GetGlobalCallbacksCount for each response of each operation method, multiple links can be defined
|
||||||
|
func (index *SpecIndex) GetGlobalCallbacksCount() int {
|
||||||
|
if index.root == nil {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if index.globalCallbacksCount > 0 {
|
||||||
|
return index.globalCallbacksCount
|
||||||
|
}
|
||||||
|
|
||||||
|
index.pathRefsLock.Lock()
|
||||||
|
for path, p := range index.pathRefs {
|
||||||
|
for _, m := range p {
|
||||||
|
|
||||||
|
// look through method for callbacks
|
||||||
|
callbacks, _ := yamlpath.NewPath("$..callbacks")
|
||||||
|
res, _ := callbacks.Find(m.Node)
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
|
||||||
|
for _, callback := range res[0].Content {
|
||||||
|
if utils.IsNodeMap(callback) {
|
||||||
|
|
||||||
|
ref := &Reference{
|
||||||
|
Definition: m.Name,
|
||||||
|
Name: m.Name,
|
||||||
|
Node: callback,
|
||||||
|
}
|
||||||
|
|
||||||
|
if index.callbacksRefs[path] == nil {
|
||||||
|
index.callbacksRefs[path] = make(map[string][]*Reference)
|
||||||
|
}
|
||||||
|
if len(index.callbacksRefs[path][m.Name]) > 0 {
|
||||||
|
index.callbacksRefs[path][m.Name] = append(index.callbacksRefs[path][m.Name], ref)
|
||||||
|
}
|
||||||
|
index.callbacksRefs[path][m.Name] = []*Reference{ref}
|
||||||
|
index.globalCallbacksCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index.pathRefsLock.Unlock()
|
||||||
|
return index.globalCallbacksCount
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGlobalLinksCount for each response of each operation method, multiple callbacks can be defined
|
||||||
func (index *SpecIndex) GetGlobalLinksCount() int {
|
func (index *SpecIndex) GetGlobalLinksCount() int {
|
||||||
if index.root == nil {
|
if index.root == nil {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
if index.globalLinksCount > 0 {
|
if index.globalCallbacksCount > 0 {
|
||||||
return index.globalLinksCount
|
return index.globalLinksCount
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -900,7 +950,6 @@ func (index *SpecIndex) GetGlobalLinksCount() int {
|
|||||||
Name: m.Name,
|
Name: m.Name,
|
||||||
Node: link,
|
Node: link,
|
||||||
}
|
}
|
||||||
|
|
||||||
if index.linksRefs[path] == nil {
|
if index.linksRefs[path] == nil {
|
||||||
index.linksRefs[path] = make(map[string][]*Reference)
|
index.linksRefs[path] = make(map[string][]*Reference)
|
||||||
}
|
}
|
||||||
@@ -1421,17 +1470,17 @@ func (index *SpecIndex) FindComponent(componentId string, parent *yaml.Node) *Re
|
|||||||
return index.lookupFileReference(id)
|
return index.lookupFileReference(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch determineReferenceResolveType(componentId) {
|
switch DetermineReferenceResolveType(componentId) {
|
||||||
case localResolve: // ideally, every single ref in every single spec is local. however, this is not the case.
|
case LocalResolve: // ideally, every single ref in every single spec is local. however, this is not the case.
|
||||||
return index.findComponentInRoot(componentId)
|
return index.FindComponentInRoot(componentId)
|
||||||
|
|
||||||
case httpResolve:
|
case HttpResolve:
|
||||||
uri := strings.Split(componentId, "#")
|
uri := strings.Split(componentId, "#")
|
||||||
if len(uri) == 2 {
|
if len(uri) == 2 {
|
||||||
return index.performExternalLookup(uri, componentId, remoteLookup, parent)
|
return index.performExternalLookup(uri, componentId, remoteLookup, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
case fileResolve:
|
case FileResolve:
|
||||||
uri := strings.Split(componentId, "#")
|
uri := strings.Split(componentId, "#")
|
||||||
if len(uri) == 2 {
|
if len(uri) == 2 {
|
||||||
return index.performExternalLookup(uri, componentId, fileLookup, parent)
|
return index.performExternalLookup(uri, componentId, fileLookup, parent)
|
||||||
@@ -1450,23 +1499,23 @@ func (index *SpecIndex) GetAllSummariesCount() int {
|
|||||||
return len(index.allSummaries)
|
return len(index.allSummaries)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* private */
|
func DetermineReferenceResolveType(ref string) int {
|
||||||
|
|
||||||
func determineReferenceResolveType(ref string) int {
|
|
||||||
if ref != "" && ref[0] == '#' {
|
if ref != "" && ref[0] == '#' {
|
||||||
return localResolve
|
return LocalResolve
|
||||||
}
|
}
|
||||||
if ref != "" && len(ref) >= 5 && (ref[:5] == "https" || ref[:5] == "http:") {
|
if ref != "" && len(ref) >= 5 && (ref[:5] == "https" || ref[:5] == "http:") {
|
||||||
return httpResolve
|
return HttpResolve
|
||||||
}
|
}
|
||||||
if strings.Contains(ref, ".json") ||
|
if strings.Contains(ref, ".json") ||
|
||||||
strings.Contains(ref, ".yaml") ||
|
strings.Contains(ref, ".yaml") ||
|
||||||
strings.Contains(ref, ".yml") {
|
strings.Contains(ref, ".yml") {
|
||||||
return fileResolve
|
return FileResolve
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* private */
|
||||||
|
|
||||||
func (index *SpecIndex) extractDefinitionsAndSchemas(schemasNode *yaml.Node, pathPrefix string) {
|
func (index *SpecIndex) extractDefinitionsAndSchemas(schemasNode *yaml.Node, pathPrefix string) {
|
||||||
var name string
|
var name string
|
||||||
for i, schema := range schemasNode.Content {
|
for i, schema := range schemasNode.Content {
|
||||||
@@ -1650,7 +1699,7 @@ func (index *SpecIndex) performExternalLookup(uri []string, componentId string,
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
foundRef := externalSpecIndex.findComponentInRoot(uri[1])
|
foundRef := externalSpecIndex.FindComponentInRoot(uri[1])
|
||||||
if foundRef != nil {
|
if foundRef != nil {
|
||||||
foundNode = foundRef.Node
|
foundNode = foundRef.Node
|
||||||
}
|
}
|
||||||
@@ -1670,7 +1719,7 @@ func (index *SpecIndex) performExternalLookup(uri []string, componentId string,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (index *SpecIndex) findComponentInRoot(componentId string) *Reference {
|
func (index *SpecIndex) FindComponentInRoot(componentId string) *Reference {
|
||||||
|
|
||||||
name, friendlySearch := utils.ConvertComponentIdIntoFriendlyPathSearch(componentId)
|
name, friendlySearch := utils.ConvertComponentIdIntoFriendlyPathSearch(componentId)
|
||||||
|
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ func TestSpecIndex_TestEmptyBrokenReferences(t *testing.T) {
|
|||||||
assert.Equal(t, 2, index.GetGlobalTagsCount())
|
assert.Equal(t, 2, index.GetGlobalTagsCount())
|
||||||
assert.Equal(t, 3, index.GetTotalTagsCount())
|
assert.Equal(t, 3, index.GetTotalTagsCount())
|
||||||
assert.Equal(t, 2, index.GetOperationTagsCount())
|
assert.Equal(t, 2, index.GetOperationTagsCount())
|
||||||
assert.Equal(t, 2, index.GetGlobalLinksCount())
|
assert.Equal(t, 4, index.GetGlobalLinksCount())
|
||||||
assert.Equal(t, 0, index.GetComponentParameterCount())
|
assert.Equal(t, 0, index.GetComponentParameterCount())
|
||||||
assert.Equal(t, 2, index.GetOperationsParameterCount())
|
assert.Equal(t, 2, index.GetOperationsParameterCount())
|
||||||
assert.Equal(t, 1, index.GetInlineDuplicateParamCount())
|
assert.Equal(t, 1, index.GetInlineDuplicateParamCount())
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
v3 "github.com/pb33f/libopenapi/datamodel/low/3.0"
|
v3 "github.com/pb33f/libopenapi/datamodel/low/3.0"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/resolver"
|
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
@@ -15,26 +14,27 @@ func CreateDocument(info *datamodel.SpecInfo) (*v3.Document, error) {
|
|||||||
doc := v3.Document{Version: low.NodeReference[string]{Value: info.Version, ValueNode: info.RootNode}}
|
doc := v3.Document{Version: low.NodeReference[string]{Value: info.Version, ValueNode: info.RootNode}}
|
||||||
|
|
||||||
// build an index
|
// build an index
|
||||||
rsolvr := resolver.NewResolver(index.NewSpecIndex(info.RootNode))
|
idx := index.NewSpecIndex(info.RootNode)
|
||||||
|
//rsolvr := resolver.NewResolver()
|
||||||
|
|
||||||
// todo handle errors
|
// todo handle errors
|
||||||
rsolvr.Resolve()
|
//rsolvr.Resolve()
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var errors []error
|
var errors []error
|
||||||
var runExtraction = func(info *datamodel.SpecInfo, doc *v3.Document,
|
var runExtraction = func(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecIndex,
|
||||||
runFunc func(i *datamodel.SpecInfo, d *v3.Document) error,
|
runFunc func(i *datamodel.SpecInfo, d *v3.Document, idx *index.SpecIndex) error,
|
||||||
ers *[]error,
|
ers *[]error,
|
||||||
wg *sync.WaitGroup) {
|
wg *sync.WaitGroup) {
|
||||||
|
|
||||||
if er := runFunc(info, doc); er != nil {
|
if er := runFunc(info, doc, idx); er != nil {
|
||||||
*ers = append(*ers, er)
|
*ers = append(*ers, er)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
extractionFuncs := []func(i *datamodel.SpecInfo, d *v3.Document) error{
|
extractionFuncs := []func(i *datamodel.SpecInfo, d *v3.Document, idx *index.SpecIndex) error{
|
||||||
extractInfo,
|
extractInfo,
|
||||||
extractServers,
|
extractServers,
|
||||||
extractTags,
|
extractTags,
|
||||||
@@ -45,7 +45,7 @@ func CreateDocument(info *datamodel.SpecInfo) (*v3.Document, error) {
|
|||||||
}
|
}
|
||||||
wg.Add(len(extractionFuncs))
|
wg.Add(len(extractionFuncs))
|
||||||
for _, f := range extractionFuncs {
|
for _, f := range extractionFuncs {
|
||||||
go runExtraction(info, &doc, f, &errors, &wg)
|
go runExtraction(info, &doc, idx, f, &errors, &wg)
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ func CreateDocument(info *datamodel.SpecInfo) (*v3.Document, error) {
|
|||||||
return &doc, nil
|
return &doc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractInfo(info *datamodel.SpecInfo, doc *v3.Document) error {
|
func extractInfo(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecIndex) error {
|
||||||
_, ln, vn := utils.FindKeyNodeFull(v3.InfoLabel, info.RootNode.Content)
|
_, ln, vn := utils.FindKeyNodeFull(v3.InfoLabel, info.RootNode.Content)
|
||||||
if vn != nil {
|
if vn != nil {
|
||||||
ir := v3.Info{}
|
ir := v3.Info{}
|
||||||
@@ -71,8 +71,8 @@ func extractInfo(info *datamodel.SpecInfo, doc *v3.Document) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractSecurity(info *datamodel.SpecInfo, doc *v3.Document) error {
|
func extractSecurity(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecIndex) error {
|
||||||
sec, sErr := v3.ExtractObject[*v3.SecurityRequirement](v3.SecurityLabel, info.RootNode)
|
sec, sErr := v3.ExtractObject[*v3.SecurityRequirement](v3.SecurityLabel, info.RootNode, idx)
|
||||||
if sErr != nil {
|
if sErr != nil {
|
||||||
return sErr
|
return sErr
|
||||||
}
|
}
|
||||||
@@ -80,8 +80,8 @@ func extractSecurity(info *datamodel.SpecInfo, doc *v3.Document) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractExternalDocs(info *datamodel.SpecInfo, doc *v3.Document) error {
|
func extractExternalDocs(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecIndex) error {
|
||||||
extDocs, dErr := v3.ExtractObject[*v3.ExternalDoc](v3.ExternalDocsLabel, info.RootNode)
|
extDocs, dErr := v3.ExtractObject[*v3.ExternalDoc](v3.ExternalDocsLabel, info.RootNode, idx)
|
||||||
if dErr != nil {
|
if dErr != nil {
|
||||||
return dErr
|
return dErr
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ func extractExternalDocs(info *datamodel.SpecInfo, doc *v3.Document) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractComponents(info *datamodel.SpecInfo, doc *v3.Document) error {
|
func extractComponents(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecIndex) error {
|
||||||
_, ln, vn := utils.FindKeyNodeFull(v3.ComponentsLabel, info.RootNode.Content)
|
_, ln, vn := utils.FindKeyNodeFull(v3.ComponentsLabel, info.RootNode.Content)
|
||||||
if vn != nil {
|
if vn != nil {
|
||||||
ir := v3.Components{}
|
ir := v3.Components{}
|
||||||
@@ -97,14 +97,14 @@ func extractComponents(info *datamodel.SpecInfo, doc *v3.Document) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = ir.Build(vn)
|
err = ir.Build(vn, idx)
|
||||||
nr := low.NodeReference[*v3.Components]{Value: &ir, ValueNode: vn, KeyNode: ln}
|
nr := low.NodeReference[*v3.Components]{Value: &ir, ValueNode: vn, KeyNode: ln}
|
||||||
doc.Components = nr
|
doc.Components = nr
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractServers(info *datamodel.SpecInfo, doc *v3.Document) error {
|
func extractServers(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecIndex) error {
|
||||||
_, ln, vn := utils.FindKeyNodeFull(v3.ServersLabel, info.RootNode.Content)
|
_, ln, vn := utils.FindKeyNodeFull(v3.ServersLabel, info.RootNode.Content)
|
||||||
if vn != nil {
|
if vn != nil {
|
||||||
if utils.IsNodeArray(vn) {
|
if utils.IsNodeArray(vn) {
|
||||||
@@ -116,7 +116,7 @@ func extractServers(info *datamodel.SpecInfo, doc *v3.Document) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
srvr.Build(srvN)
|
srvr.Build(srvN, idx)
|
||||||
servers = append(servers, low.ValueReference[*v3.Server]{
|
servers = append(servers, low.ValueReference[*v3.Server]{
|
||||||
Value: &srvr,
|
Value: &srvr,
|
||||||
ValueNode: srvN,
|
ValueNode: srvN,
|
||||||
@@ -133,7 +133,7 @@ func extractServers(info *datamodel.SpecInfo, doc *v3.Document) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractTags(info *datamodel.SpecInfo, doc *v3.Document) error {
|
func extractTags(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecIndex) error {
|
||||||
_, ln, vn := utils.FindKeyNodeFull(v3.TagsLabel, info.RootNode.Content)
|
_, ln, vn := utils.FindKeyNodeFull(v3.TagsLabel, info.RootNode.Content)
|
||||||
if vn != nil {
|
if vn != nil {
|
||||||
if utils.IsNodeArray(vn) {
|
if utils.IsNodeArray(vn) {
|
||||||
@@ -145,7 +145,7 @@ func extractTags(info *datamodel.SpecInfo, doc *v3.Document) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tag.Build(tagN)
|
tag.Build(tagN, idx)
|
||||||
tags = append(tags, low.ValueReference[*v3.Tag]{
|
tags = append(tags, low.ValueReference[*v3.Tag]{
|
||||||
Value: &tag,
|
Value: &tag,
|
||||||
ValueNode: tagN,
|
ValueNode: tagN,
|
||||||
@@ -162,11 +162,11 @@ func extractTags(info *datamodel.SpecInfo, doc *v3.Document) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractPaths(info *datamodel.SpecInfo, doc *v3.Document) error {
|
func extractPaths(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecIndex) error {
|
||||||
_, ln, vn := utils.FindKeyNodeFull(v3.PathsLabel, info.RootNode.Content)
|
_, ln, vn := utils.FindKeyNodeFull(v3.PathsLabel, info.RootNode.Content)
|
||||||
if vn != nil {
|
if vn != nil {
|
||||||
ir := v3.Paths{}
|
ir := v3.Paths{}
|
||||||
err := ir.Build(vn)
|
err := ir.Build(vn, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,17 @@ func BenchmarkCreateDocument(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkCreateDocument_Stripe(b *testing.B) {
|
||||||
|
data, _ := ioutil.ReadFile("../test_specs/stripe.yaml")
|
||||||
|
info, _ := datamodel.ExtractSpecInfo(data)
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, err := CreateDocument(info)
|
||||||
|
if err != nil {
|
||||||
|
panic("this should not error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCreateDocument(t *testing.T) {
|
func TestCreateDocument(t *testing.T) {
|
||||||
assert.Equal(t, "3.0.1", doc.Version.Value)
|
assert.Equal(t, "3.0.1", doc.Version.Value)
|
||||||
assert.Equal(t, "Burger Shop", doc.Info.Value.Title.Value)
|
assert.Equal(t, "Burger Shop", doc.Info.Value.Title.Value)
|
||||||
@@ -254,8 +265,9 @@ func TestCreateDocument_Components_Schemas(t *testing.T) {
|
|||||||
assert.NotNil(t, fries.Value)
|
assert.NotNil(t, fries.Value)
|
||||||
|
|
||||||
assert.Len(t, fries.Value.Properties.Value, 3)
|
assert.Len(t, fries.Value.Properties.Value, 3)
|
||||||
|
p := fries.Value.FindProperty("favoriteDrink")
|
||||||
assert.Equal(t, "a frosty cold beverage can be coke or sprite",
|
assert.Equal(t, "a frosty cold beverage can be coke or sprite",
|
||||||
fries.Value.FindProperty("favoriteDrink").Value.Description.Value)
|
p.Value.Description.Value)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -372,6 +372,17 @@ func IsNodeBoolValue(node *yaml.Node) bool {
|
|||||||
return node.Tag == "!!bool"
|
return node.Tag == "!!bool"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsNodeRefValue(node *yaml.Node) (bool, *yaml.Node, string) {
|
||||||
|
for i, r := range node.Content {
|
||||||
|
if i%2 == 0 {
|
||||||
|
if r.Value == "$ref" {
|
||||||
|
return true, r, node.Content[i+1].Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, nil, ""
|
||||||
|
}
|
||||||
|
|
||||||
// FixContext will clean up a JSONpath string to be correctly traversable.
|
// FixContext will clean up a JSONpath string to be correctly traversable.
|
||||||
func FixContext(context string) string {
|
func FixContext(context string) string {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user