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

openapi3: reference originating locations in YAML specs - step 1 #1007

Merged
merged 46 commits into from
Oct 21, 2024
Merged
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
20a9abd
add origin - step 1
reuvenharrison Aug 19, 2024
f90371a
delete origin from content
reuvenharrison Aug 20, 2024
7d41bd0
point to Origin
reuvenharrison Aug 21, 2024
77f909b
make include origin configurable
reuvenharrison Aug 22, 2024
15e7cab
generic unmarshalStringMap
reuvenharrison Aug 23, 2024
450e4d0
add origin to more components
reuvenharrison Aug 25, 2024
6b52b19
revert comments
reuvenharrison Aug 25, 2024
775ab17
use const originKey
reuvenharrison Aug 25, 2024
d241445
comment to Scopes
reuvenharrison Aug 26, 2024
206c1be
test more specs
reuvenharrison Aug 26, 2024
032ff76
Fix Discriminator
reuvenharrison Sep 17, 2024
4304772
update docs
reuvenharrison Sep 17, 2024
67ee9fa
test on a decent set of dedicated specs
reuvenharrison Sep 17, 2024
8095459
remove trainling spaces
reuvenharrison Sep 17, 2024
d24b68a
add comments
reuvenharrison Sep 17, 2024
c5cf284
remove trailing whitespace
reuvenharrison Sep 17, 2024
98ace80
update docs
reuvenharrison Sep 17, 2024
c981f30
dedicated tests
reuvenharrison Sep 17, 2024
6daf324
update docs
reuvenharrison Sep 17, 2024
17db6ab
remove whitespace
reuvenharrison Sep 17, 2024
015b63e
rm empty line
reuvenharrison Sep 17, 2024
34f95b7
rm last newline
reuvenharrison Sep 17, 2024
020e44b
add tests
reuvenharrison Sep 19, 2024
07a3b25
rm unused test files
reuvenharrison Sep 20, 2024
cba19cf
update deps
reuvenharrison Sep 20, 2024
2d5e393
fix paths test
reuvenharrison Sep 20, 2024
b9f7dd6
test components/security
reuvenharrison Sep 20, 2024
aa8c5b1
fix LF
reuvenharrison Sep 20, 2024
8a00ba0
include origin in unmarshal maps
reuvenharrison Sep 21, 2024
3aca4e0
move component unmarshallers to respective files
reuvenharrison Oct 14, 2024
7ea36a0
fix test (json-schema 301)
reuvenharrison Oct 14, 2024
929edf0
Add github.com/pb33f/libopenapi (#1004)
Jille Aug 22, 2024
d2c2b3c
Introduce an option to override the regex implementation (#1006)
alexbakker Aug 26, 2024
0125b1b
make form required field order deterministic (#1008)
jlsherrill Aug 30, 2024
45f4435
openapi2: fix un/marshalling discriminator field (#1011)
reversearrow Oct 1, 2024
cfdf905
README: add Fuego to dependents (#1017)
EwenQuim Oct 8, 2024
dd25946
openapi3: skip a test in CI to avoid 403s from some remote server (#1…
fenollp Oct 14, 2024
8113413
revert fix test (json-schema 301)
reuvenharrison Oct 16, 2024
4f2e185
openapi3: introduce StringMap type to enable unmarshalling of maps wi…
reuvenharrison Oct 16, 2024
e3b2867
add origin to more components
reuvenharrison Aug 25, 2024
3cba697
Fix Discriminator
reuvenharrison Sep 17, 2024
74dcf9e
update docs
reuvenharrison Sep 17, 2024
712c943
update doccs
reuvenharrison Oct 16, 2024
9aadd59
merge with stringmap
reuvenharrison Oct 16, 2024
184fa8c
remove unused Scopes
reuvenharrison Oct 16, 2024
5df8e49
Merge branch 'master' into master
reuvenharrison Oct 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add origin to more components
reuvenharrison committed Aug 25, 2024
commit 450e4d03a6a526c5c1312d64fe0bb38618f8d4c9
67 changes: 50 additions & 17 deletions openapi3/components.go
Original file line number Diff line number Diff line change
@@ -112,18 +112,16 @@ func (components *Components) UnmarshalJSON(data []byte) error {
return nil
}

type MapValue interface {
CallbackRef | ExampleRef | HeaderRef | LinkRef | ParameterRef | RequestBodyRef | ResponseRef | SchemaRef | SecuritySchemeRef |
MediaType
}

// TODO: add origin to all components
func unmarshalStringMap[V MapValue](data []byte) (map[string]*V, error) {
// unmarshalStringMapP unmarshals given json into a map[string]*V
func unmarshalStringMapP[V any](data []byte) (map[string]*V, error) {
var m map[string]any
if err := json.Unmarshal(data, &m); err != nil {
return nil, unmarshalError(err)
return nil, err
}

// TODO: add origin to the result
delete(m, "origin")

result := make(map[string]*V, len(m))
for k, v := range m {
if data, err := json.Marshal(v); err != nil {
@@ -140,48 +138,83 @@ func unmarshalStringMap[V MapValue](data []byte) (map[string]*V, error) {
return result, nil
}

// unmarshalStringMap unmarshals given json into a map[string]V
func unmarshalStringMap[V any](data []byte) (map[string]V, error) {
var m map[string]any
if err := json.Unmarshal(data, &m); err != nil {
return nil, err
}

// TODO: add origin to the result
delete(m, "origin")

result := make(map[string]V, len(m))
for k, v := range m {
if data, err := json.Marshal(v); err != nil {
return nil, err
} else {
var v V
if err = json.Unmarshal(data, &v); err != nil {
return nil, err
}
result[k] = v
}
}

return result, nil
}

// UnmarshalJSON sets Callbacks to a copy of data.
func (callbacks *Callbacks) UnmarshalJSON(data []byte) (err error) {
*callbacks, err = unmarshalStringMap[CallbackRef](data)
*callbacks, err = unmarshalStringMapP[CallbackRef](data)
return
}

// UnmarshalJSON sets Examples to a copy of data.
func (examples *Examples) UnmarshalJSON(data []byte) (err error) {
*examples, err = unmarshalStringMap[ExampleRef](data)
*examples, err = unmarshalStringMapP[ExampleRef](data)
return
}

// UnmarshalJSON sets Headers to a copy of data.
func (headers *Headers) UnmarshalJSON(data []byte) (err error) {
*headers, err = unmarshalStringMap[HeaderRef](data)
*headers, err = unmarshalStringMapP[HeaderRef](data)
return
}

// UnmarshalJSON sets Links to a copy of data.
func (links *Links) UnmarshalJSON(data []byte) (err error) {
*links, err = unmarshalStringMap[LinkRef](data)
*links, err = unmarshalStringMapP[LinkRef](data)
return
}

// UnmarshalJSON sets ParametersMap to a copy of data.
func (parametersMap *ParametersMap) UnmarshalJSON(data []byte) (err error) {
*parametersMap, err = unmarshalStringMap[ParameterRef](data)
*parametersMap, err = unmarshalStringMapP[ParameterRef](data)
return
}

// UnmarshalJSON sets RequestBodies to a copy of data.
func (requestBodies *RequestBodies) UnmarshalJSON(data []byte) (err error) {
*requestBodies, err = unmarshalStringMap[RequestBodyRef](data)
*requestBodies, err = unmarshalStringMapP[RequestBodyRef](data)
return
}

// UnmarshalJSON sets ResponseBodies to a copy of data.
func (responseBodies *ResponseBodies) UnmarshalJSON(data []byte) (err error) {
*responseBodies, err = unmarshalStringMap[ResponseRef](data)
*responseBodies, err = unmarshalStringMapP[ResponseRef](data)
return
}

// UnmarshalJSON sets Schemas to a copy of data.
func (schemas *Schemas) UnmarshalJSON(data []byte) (err error) {
*schemas, err = unmarshalStringMap[SchemaRef](data)
*schemas, err = unmarshalStringMapP[SchemaRef](data)
return
}

// UnmarshalJSON sets SecuritySchemes to a copy of data.
func (securitySchemes *SecuritySchemes) UnmarshalJSON(data []byte) (err error) {
*securitySchemes, err = unmarshalStringMap[SecuritySchemeRef](data)
*securitySchemes, err = unmarshalStringMapP[SecuritySchemeRef](data)
return
}

2 changes: 2 additions & 0 deletions openapi3/contact.go
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ import (
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#contact-object
type Contact struct {
Extensions map[string]any `json:"-" yaml:"-"`
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`

Name string `json:"name,omitempty" yaml:"name,omitempty"`
URL string `json:"url,omitempty" yaml:"url,omitempty"`
@@ -50,6 +51,7 @@ func (contact *Contact) UnmarshalJSON(data []byte) error {
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "origin")
delete(x.Extensions, "name")
delete(x.Extensions, "url")
delete(x.Extensions, "email")
2 changes: 1 addition & 1 deletion openapi3/content.go
Original file line number Diff line number Diff line change
@@ -125,6 +125,6 @@ func (content Content) Validate(ctx context.Context, opts ...ValidationOption) e

// UnmarshalJSON sets Content to a copy of data.
func (content *Content) UnmarshalJSON(data []byte) (err error) {
*content, err = unmarshalStringMap[MediaType](data)
*content, err = unmarshalStringMapP[MediaType](data)
return
}
2 changes: 2 additions & 0 deletions openapi3/discriminator.go
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ import (
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#discriminator-object
type Discriminator struct {
Extensions map[string]any `json:"-" yaml:"-"`
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`

PropertyName string `json:"propertyName" yaml:"propertyName"` // required
Mapping map[string]string `json:"mapping,omitempty" yaml:"mapping,omitempty"`
@@ -44,6 +45,7 @@ func (discriminator *Discriminator) UnmarshalJSON(data []byte) error {
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "origin")
delete(x.Extensions, "propertyName")
delete(x.Extensions, "mapping")
if len(x.Extensions) == 0 {
2 changes: 2 additions & 0 deletions openapi3/encoding.go
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ import (
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#encoding-object
type Encoding struct {
Extensions map[string]any `json:"-" yaml:"-"`
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`

ContentType string `json:"contentType,omitempty" yaml:"contentType,omitempty"`
Headers Headers `json:"headers,omitempty" yaml:"headers,omitempty"`
@@ -80,6 +81,7 @@ func (encoding *Encoding) UnmarshalJSON(data []byte) error {
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "origin")
delete(x.Extensions, "contentType")
delete(x.Extensions, "headers")
delete(x.Extensions, "style")
2 changes: 2 additions & 0 deletions openapi3/link.go
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ import (
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#link-object
type Link struct {
Extensions map[string]any `json:"-" yaml:"-"`
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`

OperationRef string `json:"operationRef,omitempty" yaml:"operationRef,omitempty"`
OperationID string `json:"operationId,omitempty" yaml:"operationId,omitempty"`
@@ -66,6 +67,7 @@ func (link *Link) UnmarshalJSON(data []byte) error {
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "origin")
delete(x.Extensions, "operationRef")
delete(x.Extensions, "operationId")
delete(x.Extensions, "description")
2 changes: 1 addition & 1 deletion openapi3/operation.go
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ import (
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object
type Operation struct {
Extensions map[string]any `json:"-" yaml:"-"`
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`

// Optional tags for documentation.
Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"`
6 changes: 6 additions & 0 deletions openapi3/security_requirements.go
Original file line number Diff line number Diff line change
@@ -49,3 +49,9 @@ func (security *SecurityRequirement) Validate(ctx context.Context, opts ...Valid

return nil
}

// UnmarshalJSON sets SecurityRequirement to a copy of data.
func (security *SecurityRequirement) UnmarshalJSON(data []byte) (err error) {
*security, err = unmarshalStringMap[[]string](data)
return
}
22 changes: 18 additions & 4 deletions openapi3/security_scheme.go
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ import (
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#security-scheme-object
type SecurityScheme struct {
Extensions map[string]any `json:"-" yaml:"-"`
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`

Type string `json:"type,omitempty" yaml:"type,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
@@ -100,6 +101,7 @@ func (ss *SecurityScheme) UnmarshalJSON(data []byte) error {
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "origin")
delete(x.Extensions, "type")
delete(x.Extensions, "description")
delete(x.Extensions, "name")
@@ -216,6 +218,7 @@ func (ss *SecurityScheme) Validate(ctx context.Context, opts ...ValidationOption
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#oauth-flows-object
type OAuthFlows struct {
Extensions map[string]any `json:"-" yaml:"-"`
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`

Implicit *OAuthFlow `json:"implicit,omitempty" yaml:"implicit,omitempty"`
Password *OAuthFlow `json:"password,omitempty" yaml:"password,omitempty"`
@@ -270,6 +273,7 @@ func (flows *OAuthFlows) UnmarshalJSON(data []byte) error {
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "origin")
delete(x.Extensions, "implicit")
delete(x.Extensions, "password")
delete(x.Extensions, "clientCredentials")
@@ -312,15 +316,18 @@ func (flows *OAuthFlows) Validate(ctx context.Context, opts ...ValidationOption)
return validateExtensions(ctx, flows.Extensions)
}

type Scopes map[string]string

// OAuthFlow is specified by OpenAPI/Swagger standard version 3.
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#oauth-flow-object
type OAuthFlow struct {
Extensions map[string]any `json:"-" yaml:"-"`
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`

AuthorizationURL string `json:"authorizationUrl,omitempty" yaml:"authorizationUrl,omitempty"`
TokenURL string `json:"tokenUrl,omitempty" yaml:"tokenUrl,omitempty"`
RefreshURL string `json:"refreshUrl,omitempty" yaml:"refreshUrl,omitempty"`
Scopes map[string]string `json:"scopes" yaml:"scopes"` // required
AuthorizationURL string `json:"authorizationUrl,omitempty" yaml:"authorizationUrl,omitempty"`
TokenURL string `json:"tokenUrl,omitempty" yaml:"tokenUrl,omitempty"`
RefreshURL string `json:"refreshUrl,omitempty" yaml:"refreshUrl,omitempty"`
Scopes Scopes `json:"scopes" yaml:"scopes"` // required
}

// MarshalJSON returns the JSON encoding of OAuthFlow.
@@ -359,6 +366,7 @@ func (flow *OAuthFlow) UnmarshalJSON(data []byte) error {
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "origin")
delete(x.Extensions, "authorizationUrl")
delete(x.Extensions, "tokenUrl")
delete(x.Extensions, "refreshUrl")
@@ -427,3 +435,9 @@ func (flow *OAuthFlow) validate(ctx context.Context, typ oAuthFlowType, opts ...

return flow.Validate(ctx, opts...)
}

// UnmarshalJSON sets Scopes to a copy of data.
func (scopes *Scopes) UnmarshalJSON(data []byte) (err error) {
*scopes, err = unmarshalStringMap[string](data)
return
}
4 changes: 4 additions & 0 deletions openapi3/server.go
Original file line number Diff line number Diff line change
@@ -52,6 +52,7 @@ func (servers Servers) MatchURL(parsedURL *url.URL) (*Server, []string, string)
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#server-object
type Server struct {
Extensions map[string]any `json:"-" yaml:"-"`
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`

URL string `json:"url" yaml:"url"` // Required
Description string `json:"description,omitempty" yaml:"description,omitempty"`
@@ -115,6 +116,7 @@ func (server *Server) UnmarshalJSON(data []byte) error {
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "origin")
delete(x.Extensions, "url")
delete(x.Extensions, "description")
delete(x.Extensions, "variables")
@@ -235,6 +237,7 @@ func (server *Server) Validate(ctx context.Context, opts ...ValidationOption) (e
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#server-variable-object
type ServerVariable struct {
Extensions map[string]any `json:"-" yaml:"-"`
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`

Enum []string `json:"enum,omitempty" yaml:"enum,omitempty"`
Default string `json:"default,omitempty" yaml:"default,omitempty"`
@@ -276,6 +279,7 @@ func (serverVariable *ServerVariable) UnmarshalJSON(data []byte) error {
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "origin")
delete(x.Extensions, "enum")
delete(x.Extensions, "default")
delete(x.Extensions, "description")
2 changes: 2 additions & 0 deletions openapi3/tag.go
Original file line number Diff line number Diff line change
@@ -34,6 +34,7 @@ func (tags Tags) Validate(ctx context.Context, opts ...ValidationOption) error {
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#tag-object
type Tag struct {
Extensions map[string]any `json:"-" yaml:"-"`
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`

Name string `json:"name,omitempty" yaml:"name,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
@@ -75,6 +76,7 @@ func (t *Tag) UnmarshalJSON(data []byte) error {
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "origin")
delete(x.Extensions, "name")
delete(x.Extensions, "description")
delete(x.Extensions, "externalDocs")