Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.18.0 #328

Merged
merged 12 commits into from
Sep 9, 2024
15 changes: 9 additions & 6 deletions datamodel/high/base/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
package base

import (
low2 "github.com/pb33f/libopenapi/datamodel/high"
"github.com/pb33f/libopenapi/datamodel/high"
low "github.com/pb33f/libopenapi/datamodel/low/base"
"github.com/pb33f/libopenapi/orderedmap"
"gopkg.in/yaml.v3"
)

Expand All @@ -14,10 +15,11 @@ import (
// v2 - https://swagger.io/specification/v2/#contactObject
// v3 - https://spec.openapis.org/oas/v3.1.0#contact-object
type Contact struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
URL string `json:"url,omitempty" yaml:"url,omitempty"`
Email string `json:"email,omitempty" yaml:"email,omitempty"`
low *low.Contact `json:"-" yaml:"-"` // low-level representation
Name string `json:"name,omitempty" yaml:"name,omitempty"`
URL string `json:"url,omitempty" yaml:"url,omitempty"`
Email string `json:"email,omitempty" yaml:"email,omitempty"`
Extensions *orderedmap.Map[string, *yaml.Node] `json:"-" yaml:"-"`
low *low.Contact `json:"-" yaml:"-"` // low-level representation
}

// NewContact will create a new Contact instance using a low-level Contact
Expand All @@ -27,6 +29,7 @@ func NewContact(contact *low.Contact) *Contact {
c.URL = contact.URL.Value
c.Name = contact.Name.Value
c.Email = contact.Email.Value
c.Extensions = high.ExtractExtensions(contact.Extensions)
return c
}

Expand All @@ -45,6 +48,6 @@ func (c *Contact) Render() ([]byte, error) {
}

func (c *Contact) MarshalYAML() (interface{}, error) {
nb := low2.NewNodeBuilder(c, c.low)
nb := high.NewNodeBuilder(c, c.low)
return nb.Render(), nil
}
5 changes: 3 additions & 2 deletions datamodel/high/base/licence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ func TestLicense_Render_Identifier(t *testing.T) {

func TestLicense_Render_IdentifierAndURL_Error(t *testing.T) {

// this should fail because you can't have both an identifier and a URL
// this used to fail because you can't have both an identifier and a URL
// however in v0.18.0 I deleted this logic, because it's dumb.
highL := &License{Name: "MIT", Identifier: "MIT", URL: "https://pb33f.io"}
dat, _ := highL.Render()

Expand All @@ -95,5 +96,5 @@ func TestLicense_Render_IdentifierAndURL_Error(t *testing.T) {
_ = lowmodel.BuildModel(cNode.Content[0], &lowLicense)
err := lowLicense.Build(context.Background(), nil, cNode.Content[0], nil)

assert.Error(t, err)
assert.NoError(t, err)
}
13 changes: 8 additions & 5 deletions datamodel/high/base/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
package base

import (
low2 "github.com/pb33f/libopenapi/datamodel/high"
"github.com/pb33f/libopenapi/datamodel/high"
low "github.com/pb33f/libopenapi/datamodel/low/base"
"github.com/pb33f/libopenapi/orderedmap"
"gopkg.in/yaml.v3"
)

Expand All @@ -14,16 +15,18 @@ import (
// v2 - https://swagger.io/specification/v2/#licenseObject
// v3 - https://spec.openapis.org/oas/v3.1.0#license-object
type License struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
URL string `json:"url,omitempty" yaml:"url,omitempty"`
Identifier string `json:"identifier,omitempty" yaml:"identifier,omitempty"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
URL string `json:"url,omitempty" yaml:"url,omitempty"`
Identifier string `json:"identifier,omitempty" yaml:"identifier,omitempty"`
Extensions *orderedmap.Map[string, *yaml.Node] `json:"-" yaml:"-"`
low *low.License
}

// NewLicense will create a new high-level License instance from a low-level one.
func NewLicense(license *low.License) *License {
l := new(License)
l.low = license
l.Extensions = high.ExtractExtensions(license.Extensions)
if !license.URL.IsEmpty() {
l.URL = license.URL.Value
}
Expand Down Expand Up @@ -53,6 +56,6 @@ func (l *License) Render() ([]byte, error) {

// MarshalYAML will create a ready to render YAML representation of the License object.
func (l *License) MarshalYAML() (interface{}, error) {
nb := low2.NewNodeBuilder(l, l.low)
nb := high.NewNodeBuilder(l, l.low)
return nb.Render(), nil
}
18 changes: 13 additions & 5 deletions datamodel/low/base/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"crypto/sha256"
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/orderedmap"
"gopkg.in/yaml.v3"
"strings"
)
Expand All @@ -17,11 +18,12 @@ import (
// v2 - https://swagger.io/specification/v2/#contactObject
// v3 - https://spec.openapis.org/oas/v3.1.0#contact-object
type Contact struct {
Name low.NodeReference[string]
URL low.NodeReference[string]
Email low.NodeReference[string]
KeyNode *yaml.Node
RootNode *yaml.Node
Name low.NodeReference[string]
URL low.NodeReference[string]
Email low.NodeReference[string]
Extensions *orderedmap.Map[low.KeyReference[string], low.ValueReference[*yaml.Node]]
KeyNode *yaml.Node
RootNode *yaml.Node
*low.Reference
low.NodeMap
}
Expand All @@ -31,6 +33,7 @@ func (c *Contact) Build(ctx context.Context, keyNode, root *yaml.Node, _ *index.
c.RootNode = root
c.Reference = new(low.Reference)
c.Nodes = low.ExtractNodes(ctx, root)
c.Extensions = low.ExtractExtensions(root)
return nil
}

Expand Down Expand Up @@ -58,3 +61,8 @@ func (c *Contact) Hash() [32]byte {
}
return sha256.Sum256([]byte(strings.Join(f, "|")))
}

// GetExtensions returns all extensions for Contact
func (c *Contact) GetExtensions() *orderedmap.Map[low.KeyReference[string], low.ValueReference[*yaml.Node]] {
return c.Extensions
}
11 changes: 8 additions & 3 deletions datamodel/low/base/contact_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ func TestContact_Hash(t *testing.T) {

left := `url: https://pb33f.io
description: the ranch
email: buckaroo@pb33f.io`
email: buckaroo@pb33f.io
x-cake: yummy`

right := `url: https://pb33f.io
description: the ranch
email: buckaroo@pb33f.io`
email: buckaroo@pb33f.io
x-beer: cold`

var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
Expand All @@ -33,7 +35,10 @@ email: buckaroo@pb33f.io`
assert.Equal(t, lDoc.Hash(), rDoc.Hash())

c := Contact{}
c.Build(nil, &lNode, &rNode, nil)
c.Build(nil, lNode.Content[0], rNode.Content[0], nil)
assert.NotNil(t, c.GetRootNode())
assert.NotNil(t, c.GetKeyNode())
assert.Equal(t, 1, c.GetExtensions().Len())
assert.Equal(t, 1, c.GetExtensions().Len())

}
12 changes: 8 additions & 4 deletions datamodel/low/base/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ package base
import (
"context"
"crypto/sha256"
"fmt"
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/orderedmap"
"github.com/pb33f/libopenapi/utils"
"gopkg.in/yaml.v3"
"strings"
Expand All @@ -22,6 +22,7 @@ type License struct {
Name low.NodeReference[string]
URL low.NodeReference[string]
Identifier low.NodeReference[string]
Extensions *orderedmap.Map[low.KeyReference[string], low.ValueReference[*yaml.Node]]
KeyNode *yaml.Node
RootNode *yaml.Node
*low.Reference
Expand All @@ -36,10 +37,8 @@ func (l *License) Build(ctx context.Context, keyNode, root *yaml.Node, idx *inde
utils.CheckForMergeNodes(root)
l.Reference = new(low.Reference)
no := low.ExtractNodes(ctx, root)
l.Extensions = low.ExtractExtensions(root)
l.Nodes = no
if l.URL.Value != "" && l.Identifier.Value != "" {
return fmt.Errorf("license cannot have both a URL and an identifier, they are mutually exclusive")
}
return nil
}

Expand Down Expand Up @@ -67,3 +66,8 @@ func (l *License) Hash() [32]byte {
}
return sha256.Sum256([]byte(strings.Join(f, "|")))
}

// GetExtensions returns all extensions for License
func (l *License) GetExtensions() *orderedmap.Map[low.KeyReference[string], low.ValueReference[*yaml.Node]] {
return l.Extensions
}
31 changes: 6 additions & 25 deletions datamodel/low/base/license_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package base

import (
"context"
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
Expand All @@ -14,10 +13,12 @@ import (
func TestLicense_Hash(t *testing.T) {

left := `url: https://pb33f.io
description: the ranch`
description: the ranch
x-happy: dance`

right := `url: https://pb33f.io
description: the ranch`
description: the ranch
x-drink: beer`

var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
Expand All @@ -32,9 +33,10 @@ description: the ranch`
assert.Equal(t, lDoc.Hash(), rDoc.Hash())

l := License{}
l.Build(nil, &lNode, &rNode, nil)
l.Build(nil, lNode.Content[0], rNode.Content[0], nil)
assert.NotNil(t, l.GetRootNode())
assert.NotNil(t, l.GetKeyNode())
assert.Equal(t, 1, l.GetExtensions().Len())

}

Expand Down Expand Up @@ -62,24 +64,3 @@ description: the ranch`
assert.Equal(t, lDoc.Hash(), rDoc.Hash())

}

func TestLicense_WithIdentifierAndURL_Error(t *testing.T) {

left := `identifier: MIT
url: https://pb33f.io
description: the ranch`

var lNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)

// create low level objects
var lDoc License
err := low.BuildModel(lNode.Content[0], &lDoc)
assert.NoError(t, err)

err = lDoc.Build(context.Background(), nil, lNode.Content[0], nil)

assert.Error(t, err)
assert.Equal(t, "license cannot have both a URL and an identifier, they are mutually exclusive", err.Error())

}
3 changes: 1 addition & 2 deletions datamodel/low/model_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"fmt"
"reflect"
"strconv"
"strings"
"sync"

"github.com/pb33f/libopenapi/orderedmap"
Expand Down Expand Up @@ -44,7 +43,7 @@ func BuildModel(node *yaml.Node, model interface{}) error {
continue // internal construct
}

kn, vn := utils.FindKeyNodeTop(strings.ToLower(fName), node.Content)
kn, vn := utils.FindKeyNodeTop(fName, node.Content)
if vn == nil {
// no point in going on.
continue
Expand Down
4 changes: 3 additions & 1 deletion document_examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ func ExampleNewDocument_fromWithDocumentConfigurationSuccess() {
digitalOcean, _ := os.ReadFile("test_specs/digitalocean.yaml")

// Digital Ocean needs a baseURL to be set, so we can resolve relative references.
baseURL, _ := url.Parse("https://raw.githubusercontent.com/digitalocean/openapi/main/specification")
//baseURL, _ := url.Parse("https://raw.githubusercontent.com/digitalocean/openapi/main/specification")
// locked this in to a release, because the spec is throwing 404's occasionally.
baseURL, _ := url.Parse("https://raw.githubusercontent.com/digitalocean/openapi/9b763029ba805c3e0e56927fd6685d73bc27f3e8/specification")

// create a DocumentConfiguration that allows loading file and remote references, and sets the baseURL
// to somewhere that can resolve the relative references.
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
module github.com/pb33f/libopenapi

go 1.23
go 1.23.0

require (
github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb
github.com/stretchr/testify v1.8.4
github.com/stretchr/testify v1.9.0
github.com/vmware-labs/yaml-jsonpath v0.3.2
github.com/wk8/go-ordered-map/v2 v2.1.9-0.20240815153524-6ea36470d1bd
golang.org/x/net v0.0.0-20220225172249-27dd8689420f
Expand All @@ -15,7 +15,7 @@ require (
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect
github.com/dprotaso/go-yit v0.0.0-20240618133044-5a0af90af097 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
)
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58=
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w=
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q=
github.com/dprotaso/go-yit v0.0.0-20240618133044-5a0af90af097 h1:f5nA5Ys8RXqFXtKc0XofVRiuwNTuJzPIwTmbjLz9vj8=
github.com/dprotaso/go-yit v0.0.0-20240618133044-5a0af90af097/go.mod h1:FTAVyH6t+SlS97rv6EXRVuBDLkQqcIe/xQw9f4IFUI4=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
Expand Down Expand Up @@ -65,6 +67,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk=
github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ=
github.com/wk8/go-ordered-map/v2 v2.1.9-0.20240815153524-6ea36470d1bd h1:dLuIF2kX9c+KknGJUdJi1Il1SDiTSK158/BB9kdgAew=
Expand Down Expand Up @@ -136,5 +140,6 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
1 change: 1 addition & 0 deletions index/index_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ type SpecIndex struct {
allComponentSchemaDefinitions *sync.Map // all schemas found in components (openapi) or definitions (swagger).
securitySchemesNode *yaml.Node // components/securitySchemes node
allSecuritySchemes map[string]*Reference // all security schemes / definitions.
allComponentSchemas map[string]*Reference // all component schemas
requestBodiesNode *yaml.Node // components/requestBodies node
allRequestBodies map[string]*Reference // all request bodies
responsesNode *yaml.Node // components/responses node
Expand Down
7 changes: 6 additions & 1 deletion index/spec_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,12 @@ func (index *SpecIndex) GetAllReferenceSchemas() []*Reference {

// GetAllComponentSchemas will return all schemas defined in the components section of the document.
func (index *SpecIndex) GetAllComponentSchemas() map[string]*Reference {
return syncMapToMap[string, *Reference](index.allComponentSchemaDefinitions)
if index != nil && index.allComponentSchemas != nil {
return index.allComponentSchemas
}
schemaMap := syncMapToMap[string, *Reference](index.allComponentSchemaDefinitions)
index.allComponentSchemas = schemaMap
return index.allComponentSchemas
}

// GetAllSecuritySchemes will return all security schemes / definitions found in the document.
Expand Down
7 changes: 7 additions & 0 deletions index/spec_index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1801,3 +1801,10 @@ components:
schemas := index.GetAllReferences()
assert.Equal(t, 0, len(schemas))
}

func Test_GetAllComponentSchemas(t *testing.T) {

// check for a nil
index := SpecIndex{}
assert.Nil(t, index.GetAllComponentSchemas())
}
Loading
Loading