mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 12:37:49 +00:00
Added support for unevaluatedProperties as Schema and bool #118
Also ran `gofmt` across the entire project. Things need cleaning up. Signed-off-by: Dave Shanley <dave@quobix.com>
This commit is contained in:
@@ -32,14 +32,17 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// OpenAPI3SchemaData is an embedded version of the OpenAPI 3 Schema
|
// OpenAPI3SchemaData is an embedded version of the OpenAPI 3 Schema
|
||||||
|
//
|
||||||
//go:embed schemas/oas3-schema.json
|
//go:embed schemas/oas3-schema.json
|
||||||
var OpenAPI3SchemaData string // embedded OAS3 schema
|
var OpenAPI3SchemaData string // embedded OAS3 schema
|
||||||
|
|
||||||
// OpenAPI31SchemaData is an embedded version of the OpenAPI 3.1 Schema
|
// OpenAPI31SchemaData is an embedded version of the OpenAPI 3.1 Schema
|
||||||
|
//
|
||||||
//go:embed schemas/oas31-schema.json
|
//go:embed schemas/oas31-schema.json
|
||||||
var OpenAPI31SchemaData string // embedded OAS31 schema
|
var OpenAPI31SchemaData string // embedded OAS31 schema
|
||||||
|
|
||||||
// OpenAPI2SchemaData is an embedded version of the OpenAPI 2 (Swagger) Schema
|
// OpenAPI2SchemaData is an embedded version of the OpenAPI 2 (Swagger) Schema
|
||||||
|
//
|
||||||
//go:embed schemas/swagger2-schema.json
|
//go:embed schemas/swagger2-schema.json
|
||||||
var OpenAPI2SchemaData string // embedded OAS3 schema
|
var OpenAPI2SchemaData string // embedded OAS3 schema
|
||||||
|
|
||||||
|
|||||||
@@ -9,4 +9,3 @@
|
|||||||
// beats, particularly when polymorphism is used. By re-using the same superset Schema across versions, we can ensure
|
// beats, particularly when polymorphism is used. By re-using the same superset Schema across versions, we can ensure
|
||||||
// that all the latest features are collected, without damaging backwards compatibility.
|
// that all the latest features are collected, without damaging backwards compatibility.
|
||||||
package base
|
package base
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Contact represents a high-level representation of the Contact definitions found at
|
// Contact represents a high-level representation of the Contact definitions found at
|
||||||
|
//
|
||||||
// v2 - https://swagger.io/specification/v2/#contactObject
|
// v2 - https://swagger.io/specification/v2/#contactObject
|
||||||
// v3 - https://spec.openapis.org/oas/v3.1.0#contact-object
|
// v3 - https://spec.openapis.org/oas/v3.1.0#contact-object
|
||||||
type Contact struct {
|
type Contact struct {
|
||||||
@@ -47,6 +48,3 @@ func (c *Contact) MarshalYAML() (interface{}, error) {
|
|||||||
nb := low2.NewNodeBuilder(c, c.low)
|
nb := low2.NewNodeBuilder(c, c.low)
|
||||||
return nb.Render(), nil
|
return nb.Render(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
// which is used to inform the consumer of the document of an alternative schema based on the value associated with it.
|
// which is used to inform the consumer of the document of an alternative schema based on the value associated with it.
|
||||||
//
|
//
|
||||||
// When using the discriminator, inline schemas will not be considered.
|
// When using the discriminator, inline schemas will not be considered.
|
||||||
|
//
|
||||||
// v3 - https://spec.openapis.org/oas/v3.1.0#discriminator-object
|
// v3 - https://spec.openapis.org/oas/v3.1.0#discriminator-object
|
||||||
type Discriminator struct {
|
type Discriminator struct {
|
||||||
PropertyName string `json:"propertyName,omitempty" yaml:"propertyName,omitempty"`
|
PropertyName string `json:"propertyName,omitempty" yaml:"propertyName,omitempty"`
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ func (d *DynamicValue[A, B]) RenderInline() ([]byte, error) {
|
|||||||
return yaml.Marshal(d)
|
return yaml.Marshal(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MarshalYAML will create a ready to render YAML representation of the DynamicValue object.
|
// MarshalYAML will create a ready to render YAML representation of the DynamicValue object.
|
||||||
func (d *DynamicValue[A, B]) MarshalYAML() (interface{}, error) {
|
func (d *DynamicValue[A, B]) MarshalYAML() (interface{}, error) {
|
||||||
// this is a custom renderer, we can't use the NodeBuilder out of the gate.
|
// this is a custom renderer, we can't use the NodeBuilder out of the gate.
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Example represents a high-level Example object as defined by OpenAPI 3+
|
// Example represents a high-level Example object as defined by OpenAPI 3+
|
||||||
|
//
|
||||||
// v3 - https://spec.openapis.org/oas/v3.1.0#example-object
|
// v3 - https://spec.openapis.org/oas/v3.1.0#example-object
|
||||||
type Example struct {
|
type Example struct {
|
||||||
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
|
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
// ExternalDoc represents a high-level External Documentation object as defined by OpenAPI 2 and 3
|
// ExternalDoc represents a high-level External Documentation object as defined by OpenAPI 2 and 3
|
||||||
//
|
//
|
||||||
// Allows referencing an external resource for extended documentation.
|
// Allows referencing an external resource for extended documentation.
|
||||||
|
//
|
||||||
// v2 - https://swagger.io/specification/v2/#externalDocumentationObject
|
// v2 - https://swagger.io/specification/v2/#externalDocumentationObject
|
||||||
// v3 - https://spec.openapis.org/oas/v3.1.0#external-documentation-object
|
// v3 - https://spec.openapis.org/oas/v3.1.0#external-documentation-object
|
||||||
type ExternalDoc struct {
|
type ExternalDoc struct {
|
||||||
|
|||||||
@@ -200,5 +200,3 @@ x-cake:
|
|||||||
bytes, _ := highInfo.Render()
|
bytes, _ := highInfo.Render()
|
||||||
assert.Len(t, bytes, 275)
|
assert.Len(t, bytes, 275)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// License is a high-level representation of a License object as defined by OpenAPI 2 and OpenAPI 3
|
// License is a high-level representation of a License object as defined by OpenAPI 2 and OpenAPI 3
|
||||||
|
//
|
||||||
// v2 - https://swagger.io/specification/v2/#licenseObject
|
// v2 - https://swagger.io/specification/v2/#licenseObject
|
||||||
// v3 - https://spec.openapis.org/oas/v3.1.0#license-object
|
// v3 - https://spec.openapis.org/oas/v3.1.0#license-object
|
||||||
type License struct {
|
type License struct {
|
||||||
|
|||||||
@@ -62,7 +62,10 @@ type Schema struct {
|
|||||||
PatternProperties map[string]*SchemaProxy `json:"patternProperties,omitempty" yaml:"patternProperties,omitempty"`
|
PatternProperties map[string]*SchemaProxy `json:"patternProperties,omitempty" yaml:"patternProperties,omitempty"`
|
||||||
PropertyNames *SchemaProxy `json:"propertyNames,omitempty" yaml:"propertyNames,omitempty"`
|
PropertyNames *SchemaProxy `json:"propertyNames,omitempty" yaml:"propertyNames,omitempty"`
|
||||||
UnevaluatedItems *SchemaProxy `json:"unevaluatedItems,omitempty" yaml:"unevaluatedItems,omitempty"`
|
UnevaluatedItems *SchemaProxy `json:"unevaluatedItems,omitempty" yaml:"unevaluatedItems,omitempty"`
|
||||||
UnevaluatedProperties *SchemaProxy `json:"unevaluatedProperties,omitempty" yaml:"unevaluatedProperties,omitempty"`
|
|
||||||
|
// in 3.1 UnevaluatedProperties can be a Schema or a boolean
|
||||||
|
// https://github.com/pb33f/libopenapi/issues/118
|
||||||
|
UnevaluatedProperties *DynamicValue[*SchemaProxy, *bool] `json:"unevaluatedProperties,omitempty" yaml:"unevaluatedProperties,omitempty"`
|
||||||
|
|
||||||
// in 3.1 Items can be a Schema or a boolean
|
// in 3.1 Items can be a Schema or a boolean
|
||||||
Items *DynamicValue[*SchemaProxy, bool] `json:"items,omitempty" yaml:"items,omitempty"`
|
Items *DynamicValue[*SchemaProxy, bool] `json:"items,omitempty" yaml:"items,omitempty"`
|
||||||
@@ -209,11 +212,27 @@ func NewSchema(schema *base.Schema) *Schema {
|
|||||||
Value: schema.UnevaluatedItems.Value,
|
Value: schema.UnevaluatedItems.Value,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
if !schema.UnevaluatedProperties.IsEmpty() {
|
// check if unevaluated properties is a schema
|
||||||
s.UnevaluatedProperties = &SchemaProxy{schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
if !schema.UnevaluatedProperties.IsEmpty() && schema.UnevaluatedProperties.Value.IsA() {
|
||||||
|
s.UnevaluatedProperties = &DynamicValue[*SchemaProxy, *bool]{
|
||||||
|
A: &SchemaProxy{
|
||||||
|
schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
||||||
ValueNode: schema.UnevaluatedProperties.ValueNode,
|
ValueNode: schema.UnevaluatedProperties.ValueNode,
|
||||||
Value: schema.UnevaluatedProperties.Value,
|
Value: schema.UnevaluatedProperties.Value.A,
|
||||||
}}
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if unevaluated properties is a bool
|
||||||
|
if !schema.UnevaluatedProperties.IsEmpty() && schema.UnevaluatedProperties.Value.IsB() {
|
||||||
|
s.UnevaluatedProperties = &DynamicValue[*SchemaProxy, *bool]{
|
||||||
|
B: schema.UnevaluatedProperties.Value.B,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !schema.UnevaluatedProperties.IsEmpty() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Pattern = schema.Pattern.Value
|
s.Pattern = schema.Pattern.Value
|
||||||
|
|||||||
@@ -65,4 +65,3 @@ func TestCreateSchemaProxyRef(t *testing.T) {
|
|||||||
assert.Equal(t, "#/components/schemas/MySchema", sp.GetReference())
|
assert.Equal(t, "#/components/schemas/MySchema", sp.GetReference())
|
||||||
assert.True(t, sp.IsReference())
|
assert.True(t, sp.IsReference())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ $anchor: anchor`
|
|||||||
assert.Equal(t, "string", compiled.DependentSchemas["schemaOne"].Schema().Type[0])
|
assert.Equal(t, "string", compiled.DependentSchemas["schemaOne"].Schema().Type[0])
|
||||||
assert.Equal(t, "string", compiled.PropertyNames.Schema().Type[0])
|
assert.Equal(t, "string", compiled.PropertyNames.Schema().Type[0])
|
||||||
assert.Equal(t, "boolean", compiled.UnevaluatedItems.Schema().Type[0])
|
assert.Equal(t, "boolean", compiled.UnevaluatedItems.Schema().Type[0])
|
||||||
assert.Equal(t, "integer", compiled.UnevaluatedProperties.Schema().Type[0])
|
assert.Equal(t, "integer", compiled.UnevaluatedProperties.A.Schema().Type[0])
|
||||||
assert.True(t, compiled.ReadOnly)
|
assert.True(t, compiled.ReadOnly)
|
||||||
assert.True(t, compiled.WriteOnly)
|
assert.True(t, compiled.WriteOnly)
|
||||||
assert.True(t, *compiled.Deprecated)
|
assert.True(t, *compiled.Deprecated)
|
||||||
@@ -1184,3 +1184,25 @@ components:
|
|||||||
schemaBytes, _ := compiled.RenderInline()
|
schemaBytes, _ := compiled.RenderInline()
|
||||||
assert.Len(t, schemaBytes, 585)
|
assert.Len(t, schemaBytes, 585)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnevaluatedPropertiesBoolean_True(t *testing.T) {
|
||||||
|
yml := `
|
||||||
|
type: number
|
||||||
|
unevaluatedProperties: true
|
||||||
|
`
|
||||||
|
highSchema := getHighSchema(t, yml)
|
||||||
|
|
||||||
|
value := true
|
||||||
|
assert.EqualValues(t, &value, highSchema.UnevaluatedProperties.B)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnevaluatedPropertiesBoolean_False(t *testing.T) {
|
||||||
|
yml := `
|
||||||
|
type: number
|
||||||
|
unevaluatedProperties: false
|
||||||
|
`
|
||||||
|
highSchema := getHighSchema(t, yml)
|
||||||
|
|
||||||
|
value := false
|
||||||
|
assert.EqualValues(t, &value, highSchema.UnevaluatedProperties.B)
|
||||||
|
}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ func (s *SecurityRequirement) MarshalYAML() (interface{}, error) {
|
|||||||
for t := range keys[k].val {
|
for t := range keys[k].val {
|
||||||
reqs[t] = &req{val: keys[k].val[t], line: 9999 + t}
|
reqs[t] = &req{val: keys[k].val[t], line: 9999 + t}
|
||||||
if keys[k].lowVal != nil {
|
if keys[k].lowVal != nil {
|
||||||
for _ = range keys[k].lowVal.Value[t].Value {
|
for range keys[k].lowVal.Value[t].Value {
|
||||||
fh := keys[k].val[t]
|
fh := keys[k].val[t]
|
||||||
df := keys[k].lowVal.Value[t].Value
|
df := keys[k].lowVal.Value[t].Value
|
||||||
if fh == df {
|
if fh == df {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
//
|
//
|
||||||
// When using arrays, XML element names are not inferred (for singular/plural forms) and the name property SHOULD be
|
// When using arrays, XML element names are not inferred (for singular/plural forms) and the name property SHOULD be
|
||||||
// used to add that information. See examples for expected behavior.
|
// used to add that information. See examples for expected behavior.
|
||||||
|
//
|
||||||
// v2 - https://swagger.io/specification/v2/#xmlObject
|
// v2 - https://swagger.io/specification/v2/#xmlObject
|
||||||
// v3 - https://swagger.io/specification/#xml-object
|
// v3 - https://swagger.io/specification/#xml-object
|
||||||
type XML struct {
|
type XML struct {
|
||||||
@@ -61,4 +62,3 @@ func (x *XML) MarshalYAML() (interface{}, error) {
|
|||||||
nb := high.NewNodeBuilder(x, x.low)
|
nb := high.NewNodeBuilder(x, x.low)
|
||||||
return nb.Render(), nil
|
return nb.Render(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ func ExtractExtensions(extensions map[low.KeyReference[string]]low.ValueReferenc
|
|||||||
// `low` represents the HIGH type of the object that contains the extensions.
|
// `low` represents the HIGH type of the object that contains the extensions.
|
||||||
//
|
//
|
||||||
// to use:
|
// to use:
|
||||||
|
//
|
||||||
// schema := schemaProxy.Schema() // any high-level object that has extensions
|
// schema := schemaProxy.Schema() // any high-level object that has extensions
|
||||||
// extensions, err := UnpackExtensions[MyComplexType, low.Schema](schema)
|
// extensions, err := UnpackExtensions[MyComplexType, low.Schema](schema)
|
||||||
func UnpackExtensions[T any, R low.HasExtensions[T]](low GoesLow[R]) (map[string]*T, error) {
|
func UnpackExtensions[T any, R low.HasExtensions[T]](low GoesLow[R]) (map[string]*T, error) {
|
||||||
@@ -75,4 +76,3 @@ func UnpackExtensions[T any, R low.HasExtensions[T]](low GoesLow[R]) (map[string
|
|||||||
}
|
}
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,17 +16,26 @@ import (
|
|||||||
// There are five possible parameter types.
|
// There are five possible parameter types.
|
||||||
//
|
//
|
||||||
// Path
|
// Path
|
||||||
|
//
|
||||||
// Used together with Path Templating, where the parameter value is actually part of the operation's URL.
|
// Used together with Path Templating, where the parameter value is actually part of the operation's URL.
|
||||||
// This does not include the host or base path of the API. For example, in /items/{itemId}, the path parameter is itemId.
|
// This does not include the host or base path of the API. For example, in /items/{itemId}, the path parameter is itemId.
|
||||||
|
//
|
||||||
// Query
|
// Query
|
||||||
|
//
|
||||||
// Parameters that are appended to the URL. For example, in /items?id=###, the query parameter is id.
|
// Parameters that are appended to the URL. For example, in /items?id=###, the query parameter is id.
|
||||||
|
//
|
||||||
// Header
|
// Header
|
||||||
|
//
|
||||||
// Custom headers that are expected as part of the request.
|
// Custom headers that are expected as part of the request.
|
||||||
|
//
|
||||||
// Body
|
// Body
|
||||||
|
//
|
||||||
// The payload that's appended to the HTTP request. Since there can only be one payload, there can only be one body parameter.
|
// The payload that's appended to the HTTP request. Since there can only be one payload, there can only be one body parameter.
|
||||||
// The name of the body parameter has no effect on the parameter itself and is used for documentation purposes only.
|
// The name of the body parameter has no effect on the parameter itself and is used for documentation purposes only.
|
||||||
// Since Form parameters are also in the payload, body and form parameters cannot exist together for the same operation.
|
// Since Form parameters are also in the payload, body and form parameters cannot exist together for the same operation.
|
||||||
|
//
|
||||||
// Form
|
// Form
|
||||||
|
//
|
||||||
// Used to describe the payload of an HTTP request when either application/x-www-form-urlencoded, multipart/form-data
|
// Used to describe the payload of an HTTP request when either application/x-www-form-urlencoded, multipart/form-data
|
||||||
// or both are used as the content type of the request (in Swagger's definition, the consumes property of an operation).
|
// or both are used as the content type of the request (in Swagger's definition, the consumes property of an operation).
|
||||||
// This is the only parameter type that can be used to send files, thus supporting the file type. Since form parameters
|
// This is the only parameter type that can be used to send files, thus supporting the file type. Since form parameters
|
||||||
@@ -39,6 +48,7 @@ import (
|
|||||||
// multipart/form-data - each parameter takes a section in the payload with an internal header. For example, for
|
// multipart/form-data - each parameter takes a section in the payload with an internal header. For example, for
|
||||||
// the header Content-Disposition: form-data; name="submit-name" the name of the parameter is
|
// the header Content-Disposition: form-data; name="submit-name" the name of the parameter is
|
||||||
// submit-name. This type of form parameters is more commonly used for file transfers
|
// submit-name. This type of form parameters is more commonly used for file transfers
|
||||||
|
//
|
||||||
// https://swagger.io/specification/v2/#parameterObject
|
// https://swagger.io/specification/v2/#parameterObject
|
||||||
type Parameter struct {
|
type Parameter struct {
|
||||||
Name string
|
Name string
|
||||||
|
|||||||
@@ -63,4 +63,3 @@ func (o *OAuthFlows) MarshalYAML() (interface{}, error) {
|
|||||||
nb := high.NewNodeBuilder(o, o.low)
|
nb := high.NewNodeBuilder(o, o.low)
|
||||||
return nb.Render(), nil
|
return nb.Render(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ func TestOperation_MarshalYAML(t *testing.T) {
|
|||||||
},
|
},
|
||||||
OperationId: "slice",
|
OperationId: "slice",
|
||||||
Parameters: []*Parameter{
|
Parameters: []*Parameter{
|
||||||
&Parameter{
|
{
|
||||||
Name: "mice",
|
Name: "mice",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -103,7 +103,7 @@ func TestOperation_MarshalYAMLInline(t *testing.T) {
|
|||||||
},
|
},
|
||||||
OperationId: "slice",
|
OperationId: "slice",
|
||||||
Parameters: []*Parameter{
|
Parameters: []*Parameter{
|
||||||
&Parameter{
|
{
|
||||||
Name: "mice",
|
Name: "mice",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -9,4 +9,3 @@
|
|||||||
// beats, particularly when polymorphism is used. By re-using the same superset Schema across versions, we can ensure
|
// beats, particularly when polymorphism is used. By re-using the same superset Schema across versions, we can ensure
|
||||||
// that all the latest features are collected, without damaging backwards compatibility.
|
// that all the latest features are collected, without damaging backwards compatibility.
|
||||||
package base
|
package base
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Contact represents a low-level representation of the Contact definitions found at
|
// Contact represents a low-level representation of the Contact definitions found at
|
||||||
|
//
|
||||||
// v2 - https://swagger.io/specification/v2/#contactObject
|
// v2 - https://swagger.io/specification/v2/#contactObject
|
||||||
// v3 - https://spec.openapis.org/oas/v3.1.0#contact-object
|
// v3 - https://spec.openapis.org/oas/v3.1.0#contact-object
|
||||||
type Contact struct {
|
type Contact struct {
|
||||||
@@ -42,4 +43,3 @@ func (c *Contact) Hash() [32]byte {
|
|||||||
}
|
}
|
||||||
return sha256.Sum256([]byte(strings.Join(f, "|")))
|
return sha256.Sum256([]byte(strings.Join(f, "|")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
// which is used to inform the consumer of the document of an alternative schema based on the value associated with it.
|
// which is used to inform the consumer of the document of an alternative schema based on the value associated with it.
|
||||||
//
|
//
|
||||||
// When using the discriminator, inline schemas will not be considered.
|
// When using the discriminator, inline schemas will not be considered.
|
||||||
|
//
|
||||||
// v3 - https://spec.openapis.org/oas/v3.1.0#discriminator-object
|
// v3 - https://spec.openapis.org/oas/v3.1.0#discriminator-object
|
||||||
type Discriminator struct {
|
type Discriminator struct {
|
||||||
PropertyName low.NodeReference[string]
|
PropertyName low.NodeReference[string]
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Example represents a low-level Example object as defined by OpenAPI 3+
|
// Example represents a low-level Example object as defined by OpenAPI 3+
|
||||||
|
//
|
||||||
// v3 - https://spec.openapis.org/oas/v3.1.0#example-object
|
// v3 - https://spec.openapis.org/oas/v3.1.0#example-object
|
||||||
type Example struct {
|
type Example struct {
|
||||||
Summary low.NodeReference[string]
|
Summary low.NodeReference[string]
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
// ExternalDoc represents a low-level External Documentation object as defined by OpenAPI 2 and 3
|
// ExternalDoc represents a low-level External Documentation object as defined by OpenAPI 2 and 3
|
||||||
//
|
//
|
||||||
// Allows referencing an external resource for extended documentation.
|
// Allows referencing an external resource for extended documentation.
|
||||||
|
//
|
||||||
// v2 - https://swagger.io/specification/v2/#externalDocumentationObject
|
// v2 - https://swagger.io/specification/v2/#externalDocumentationObject
|
||||||
// v3 - https://spec.openapis.org/oas/v3.1.0#external-documentation-object
|
// v3 - https://spec.openapis.org/oas/v3.1.0#external-documentation-object
|
||||||
type ExternalDoc struct {
|
type ExternalDoc struct {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// License is a low-level representation of a License object as defined by OpenAPI 2 and OpenAPI 3
|
// License is a low-level representation of a License object as defined by OpenAPI 2 and OpenAPI 3
|
||||||
|
//
|
||||||
// v2 - https://swagger.io/specification/v2/#licenseObject
|
// v2 - https://swagger.io/specification/v2/#licenseObject
|
||||||
// v3 - https://spec.openapis.org/oas/v3.1.0#license-object
|
// v3 - https://spec.openapis.org/oas/v3.1.0#license-object
|
||||||
type License struct {
|
type License struct {
|
||||||
|
|||||||
@@ -29,15 +29,26 @@ type SchemaDynamicValue[A any, B any] struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IsA will return true if the 'A' or left value is set. (OpenAPI 3)
|
// IsA will return true if the 'A' or left value is set. (OpenAPI 3)
|
||||||
func (s SchemaDynamicValue[A, B]) IsA() bool {
|
func (s *SchemaDynamicValue[A, B]) IsA() bool {
|
||||||
return s.N == 0
|
return s.N == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsB will return true if the 'B' or right value is set (OpenAPI 3.1)
|
// IsB will return true if the 'B' or right value is set (OpenAPI 3.1)
|
||||||
func (s SchemaDynamicValue[A, B]) IsB() bool {
|
func (s *SchemaDynamicValue[A, B]) IsB() bool {
|
||||||
return s.N == 1
|
return s.N == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hash will generate a stable hash of the SchemaDynamicValue
|
||||||
|
func (s *SchemaDynamicValue[A, B]) Hash() [32]byte {
|
||||||
|
var hash string
|
||||||
|
if s.IsA() {
|
||||||
|
hash = low.GenerateHashString(s.A)
|
||||||
|
} else {
|
||||||
|
hash = low.GenerateHashString(s.B)
|
||||||
|
}
|
||||||
|
return sha256.Sum256([]byte(hash))
|
||||||
|
}
|
||||||
|
|
||||||
// Schema represents a JSON Schema that support Swagger, OpenAPI 3 and OpenAPI 3.1
|
// Schema represents a JSON Schema that support Swagger, OpenAPI 3 and OpenAPI 3.1
|
||||||
//
|
//
|
||||||
// Until 3.1 OpenAPI had a strange relationship with JSON Schema. It's been a super-set/sub-set
|
// Until 3.1 OpenAPI had a strange relationship with JSON Schema. It's been a super-set/sub-set
|
||||||
@@ -89,7 +100,7 @@ type Schema struct {
|
|||||||
PatternProperties low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*SchemaProxy]]
|
PatternProperties low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*SchemaProxy]]
|
||||||
PropertyNames low.NodeReference[*SchemaProxy]
|
PropertyNames low.NodeReference[*SchemaProxy]
|
||||||
UnevaluatedItems low.NodeReference[*SchemaProxy]
|
UnevaluatedItems low.NodeReference[*SchemaProxy]
|
||||||
UnevaluatedProperties low.NodeReference[*SchemaProxy]
|
UnevaluatedProperties low.NodeReference[*SchemaDynamicValue[*SchemaProxy, *bool]]
|
||||||
Anchor low.NodeReference[string]
|
Anchor low.NodeReference[string]
|
||||||
|
|
||||||
// Compatible with all versions
|
// Compatible with all versions
|
||||||
@@ -706,7 +717,7 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
for i := range addPNode.Content {
|
for i := range addPNode.Content {
|
||||||
if utils.IsNodeMap(addPNode.Content[i]) {
|
if utils.IsNodeMap(addPNode.Content[i]) {
|
||||||
var prop map[string]any
|
var prop map[string]any
|
||||||
addPNode.Content[i].Decode(&prop)
|
_ = addPNode.Content[i].Decode(&prop)
|
||||||
addProps = append(addProps,
|
addProps = append(addProps,
|
||||||
low.ValueReference[any]{Value: prop, ValueNode: addPNode.Content[i]})
|
low.ValueReference[any]{Value: prop, ValueNode: addPNode.Content[i]})
|
||||||
} else {
|
} else {
|
||||||
@@ -801,6 +812,27 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check unevaluatedProperties type for schema or bool (3.1 only)
|
||||||
|
unevalIsBool := false
|
||||||
|
unevalBoolValue := true
|
||||||
|
_, unevalLabel, unevalValue := utils.FindKeyNodeFullTop(UnevaluatedPropertiesLabel, root.Content)
|
||||||
|
if unevalValue != nil {
|
||||||
|
if utils.IsNodeBoolValue(unevalValue) {
|
||||||
|
unevalIsBool = true
|
||||||
|
unevalBoolValue, _ = strconv.ParseBool(unevalValue.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if unevalIsBool {
|
||||||
|
s.UnevaluatedProperties = low.NodeReference[*SchemaDynamicValue[*SchemaProxy, *bool]]{
|
||||||
|
Value: &SchemaDynamicValue[*SchemaProxy, *bool]{
|
||||||
|
B: &unevalBoolValue,
|
||||||
|
N: 1,
|
||||||
|
},
|
||||||
|
KeyNode: unevalLabel,
|
||||||
|
ValueNode: unevalValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var allOf, anyOf, oneOf, prefixItems []low.ValueReference[*SchemaProxy]
|
var allOf, anyOf, oneOf, prefixItems []low.ValueReference[*SchemaProxy]
|
||||||
var items, not, contains, sif, selse, sthen, propertyNames, unevalItems, unevalProperties low.ValueReference[*SchemaProxy]
|
var items, not, contains, sif, selse, sthen, propertyNames, unevalItems, unevalProperties low.ValueReference[*SchemaProxy]
|
||||||
|
|
||||||
@@ -814,7 +846,6 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
_, selseLabel, selseValue := utils.FindKeyNodeFullTop(ElseLabel, root.Content)
|
_, selseLabel, selseValue := utils.FindKeyNodeFullTop(ElseLabel, root.Content)
|
||||||
_, sthenLabel, sthenValue := utils.FindKeyNodeFullTop(ThenLabel, root.Content)
|
_, sthenLabel, sthenValue := utils.FindKeyNodeFullTop(ThenLabel, root.Content)
|
||||||
_, propNamesLabel, propNamesValue := utils.FindKeyNodeFullTop(PropertyNamesLabel, root.Content)
|
_, propNamesLabel, propNamesValue := utils.FindKeyNodeFullTop(PropertyNamesLabel, root.Content)
|
||||||
|
|
||||||
_, unevalItemsLabel, unevalItemsValue := utils.FindKeyNodeFullTop(UnevaluatedItemsLabel, root.Content)
|
_, unevalItemsLabel, unevalItemsValue := utils.FindKeyNodeFullTop(UnevaluatedItemsLabel, root.Content)
|
||||||
_, unevalPropsLabel, unevalPropsValue := utils.FindKeyNodeFullTop(UnevaluatedPropertiesLabel, root.Content)
|
_, unevalPropsLabel, unevalPropsValue := utils.FindKeyNodeFullTop(UnevaluatedPropertiesLabel, root.Content)
|
||||||
|
|
||||||
@@ -882,7 +913,7 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
totalBuilds++
|
totalBuilds++
|
||||||
go buildSchema(unevalItemsChan, unevalItemsLabel, unevalItemsValue, errorChan, idx)
|
go buildSchema(unevalItemsChan, unevalItemsLabel, unevalItemsValue, errorChan, idx)
|
||||||
}
|
}
|
||||||
if unevalPropsValue != nil {
|
if !unevalIsBool && unevalPropsValue != nil {
|
||||||
totalBuilds++
|
totalBuilds++
|
||||||
go buildSchema(unevalPropsChan, unevalPropsLabel, unevalPropsValue, errorChan, idx)
|
go buildSchema(unevalPropsChan, unevalPropsLabel, unevalPropsValue, errorChan, idx)
|
||||||
}
|
}
|
||||||
@@ -1020,9 +1051,11 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
ValueNode: unevalItemsValue,
|
ValueNode: unevalItemsValue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !unevalProperties.IsEmpty() {
|
if !unevalIsBool && !unevalProperties.IsEmpty() {
|
||||||
s.UnevaluatedProperties = low.NodeReference[*SchemaProxy]{
|
s.UnevaluatedProperties = low.NodeReference[*SchemaDynamicValue[*SchemaProxy, *bool]]{
|
||||||
Value: unevalProperties.Value,
|
Value: &SchemaDynamicValue[*SchemaProxy, *bool]{
|
||||||
|
A: unevalProperties.Value,
|
||||||
|
},
|
||||||
KeyNode: unevalPropsLabel,
|
KeyNode: unevalPropsLabel,
|
||||||
ValueNode: unevalPropsValue,
|
ValueNode: unevalPropsValue,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ func Test_Schema(t *testing.T) {
|
|||||||
assert.Equal(t, "string", sch.FindPatternProperty("patternOne").Value.Schema().Type.Value.A)
|
assert.Equal(t, "string", sch.FindPatternProperty("patternOne").Value.Schema().Type.Value.A)
|
||||||
assert.Equal(t, "string", sch.PropertyNames.Value.Schema().Type.Value.A)
|
assert.Equal(t, "string", sch.PropertyNames.Value.Schema().Type.Value.A)
|
||||||
assert.Equal(t, "boolean", sch.UnevaluatedItems.Value.Schema().Type.Value.A)
|
assert.Equal(t, "boolean", sch.UnevaluatedItems.Value.Schema().Type.Value.A)
|
||||||
assert.Equal(t, "integer", sch.UnevaluatedProperties.Value.Schema().Type.Value.A)
|
assert.Equal(t, "integer", sch.UnevaluatedProperties.Value.A.Schema().Type.Value.A)
|
||||||
assert.Equal(t, "anchor", sch.Anchor.Value)
|
assert.Equal(t, "anchor", sch.Anchor.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1575,3 +1575,71 @@ allOf:
|
|||||||
- description: allOf sequence check 4
|
- description: allOf sequence check 4
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSchema_UnevaluatedPropertiesAsBool_DefinedAsTrue(t *testing.T) {
|
||||||
|
yml := `components:
|
||||||
|
schemas:
|
||||||
|
Something:
|
||||||
|
unevaluatedProperties: true`
|
||||||
|
|
||||||
|
var iNode yaml.Node
|
||||||
|
mErr := yaml.Unmarshal([]byte(yml), &iNode)
|
||||||
|
assert.NoError(t, mErr)
|
||||||
|
idx := index.NewSpecIndexWithConfig(&iNode, index.CreateOpenAPIIndexConfig())
|
||||||
|
|
||||||
|
yml = `$ref: '#/components/schemas/Something'`
|
||||||
|
|
||||||
|
var idxNode yaml.Node
|
||||||
|
_ = yaml.Unmarshal([]byte(yml), &idxNode)
|
||||||
|
|
||||||
|
res, _ := ExtractSchema(idxNode.Content[0], idx)
|
||||||
|
|
||||||
|
assert.True(t, res.Value.Schema().UnevaluatedProperties.Value.IsB())
|
||||||
|
assert.True(t, *res.Value.Schema().UnevaluatedProperties.Value.B)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSchema_UnevaluatedPropertiesAsBool_DefinedAsFalse(t *testing.T) {
|
||||||
|
yml := `components:
|
||||||
|
schemas:
|
||||||
|
Something:
|
||||||
|
unevaluatedProperties: false`
|
||||||
|
|
||||||
|
var iNode yaml.Node
|
||||||
|
mErr := yaml.Unmarshal([]byte(yml), &iNode)
|
||||||
|
assert.NoError(t, mErr)
|
||||||
|
idx := index.NewSpecIndexWithConfig(&iNode, index.CreateOpenAPIIndexConfig())
|
||||||
|
|
||||||
|
yml = `$ref: '#/components/schemas/Something'`
|
||||||
|
|
||||||
|
var idxNode yaml.Node
|
||||||
|
_ = yaml.Unmarshal([]byte(yml), &idxNode)
|
||||||
|
|
||||||
|
res, _ := ExtractSchema(idxNode.Content[0], idx)
|
||||||
|
|
||||||
|
assert.True(t, res.Value.Schema().UnevaluatedProperties.Value.IsB())
|
||||||
|
assert.False(t, *res.Value.Schema().UnevaluatedProperties.Value.B)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSchema_UnevaluatedPropertiesAsBool_Undefined(t *testing.T) {
|
||||||
|
yml := `components:
|
||||||
|
schemas:
|
||||||
|
Something:
|
||||||
|
description: I have not defined unevaluatedProperties`
|
||||||
|
|
||||||
|
var iNode yaml.Node
|
||||||
|
mErr := yaml.Unmarshal([]byte(yml), &iNode)
|
||||||
|
assert.NoError(t, mErr)
|
||||||
|
idx := index.NewSpecIndexWithConfig(&iNode, index.CreateOpenAPIIndexConfig())
|
||||||
|
|
||||||
|
yml = `$ref: '#/components/schemas/Something'`
|
||||||
|
|
||||||
|
var idxNode yaml.Node
|
||||||
|
_ = yaml.Unmarshal([]byte(yml), &idxNode)
|
||||||
|
|
||||||
|
res, _ := ExtractSchema(idxNode.Content[0], idx)
|
||||||
|
|
||||||
|
assert.Nil(t, res.Value.Schema().UnevaluatedProperties.Value)
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
//
|
//
|
||||||
// When using arrays, XML element names are not inferred (for singular/plural forms) and the name property SHOULD be
|
// When using arrays, XML element names are not inferred (for singular/plural forms) and the name property SHOULD be
|
||||||
// used to add that information. See examples for expected behavior.
|
// used to add that information. See examples for expected behavior.
|
||||||
|
//
|
||||||
// v2 - https://swagger.io/specification/v2/#xmlObject
|
// v2 - https://swagger.io/specification/v2/#xmlObject
|
||||||
// v3 - https://swagger.io/specification/#xml-object
|
// v3 - https://swagger.io/specification/#xml-object
|
||||||
type XML struct {
|
type XML struct {
|
||||||
|
|||||||
@@ -1024,7 +1024,7 @@ one:
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, things, 1)
|
assert.Len(t, things, 1)
|
||||||
|
|
||||||
for k, _ := range things {
|
for k := range things {
|
||||||
assert.Equal(t, "one", k.Value)
|
assert.Equal(t, "one", k.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func TestNodeReference_Mutate(t *testing.T) {
|
|||||||
func TestNodeReference_RefNode(t *testing.T) {
|
func TestNodeReference_RefNode(t *testing.T) {
|
||||||
nr := new(NodeReference[string])
|
nr := new(NodeReference[string])
|
||||||
nr.KeyNode = &yaml.Node{
|
nr.KeyNode = &yaml.Node{
|
||||||
Content: []*yaml.Node{&yaml.Node{
|
Content: []*yaml.Node{{
|
||||||
Value: "$ref",
|
Value: "$ref",
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
@@ -749,8 +749,3 @@ func TestKeyReference_GetKeyNode(t *testing.T) {
|
|||||||
assert.Equal(t, 3, nr.GetKeyNode().Line)
|
assert.Equal(t, 3, nr.GetKeyNode().Line)
|
||||||
assert.Equal(t, "pizza", nr.GetKeyNode().Value)
|
assert.Equal(t, "pizza", nr.GetKeyNode().Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,17 +22,26 @@ import (
|
|||||||
// There are five possible parameter types.
|
// There are five possible parameter types.
|
||||||
//
|
//
|
||||||
// Path
|
// Path
|
||||||
|
//
|
||||||
// Used together with Path Templating, where the parameter value is actually part of the operation's URL.
|
// Used together with Path Templating, where the parameter value is actually part of the operation's URL.
|
||||||
// This does not include the host or base path of the API. For example, in /items/{itemId}, the path parameter is itemId.
|
// This does not include the host or base path of the API. For example, in /items/{itemId}, the path parameter is itemId.
|
||||||
|
//
|
||||||
// Query
|
// Query
|
||||||
|
//
|
||||||
// Parameters that are appended to the URL. For example, in /items?id=###, the query parameter is id.
|
// Parameters that are appended to the URL. For example, in /items?id=###, the query parameter is id.
|
||||||
|
//
|
||||||
// Header
|
// Header
|
||||||
|
//
|
||||||
// Custom headers that are expected as part of the request.
|
// Custom headers that are expected as part of the request.
|
||||||
|
//
|
||||||
// Body
|
// Body
|
||||||
|
//
|
||||||
// The payload that's appended to the HTTP request. Since there can only be one payload, there can only be one body parameter.
|
// The payload that's appended to the HTTP request. Since there can only be one payload, there can only be one body parameter.
|
||||||
// The name of the body parameter has no effect on the parameter itself and is used for documentation purposes only.
|
// The name of the body parameter has no effect on the parameter itself and is used for documentation purposes only.
|
||||||
// Since Form parameters are also in the payload, body and form parameters cannot exist together for the same operation.
|
// Since Form parameters are also in the payload, body and form parameters cannot exist together for the same operation.
|
||||||
|
//
|
||||||
// Form
|
// Form
|
||||||
|
//
|
||||||
// Used to describe the payload of an HTTP request when either application/x-www-form-urlencoded, multipart/form-data
|
// Used to describe the payload of an HTTP request when either application/x-www-form-urlencoded, multipart/form-data
|
||||||
// or both are used as the content type of the request (in Swagger's definition, the consumes property of an operation).
|
// or both are used as the content type of the request (in Swagger's definition, the consumes property of an operation).
|
||||||
// This is the only parameter type that can be used to send files, thus supporting the file type. Since form parameters
|
// This is the only parameter type that can be used to send files, thus supporting the file type. Since form parameters
|
||||||
@@ -45,6 +54,7 @@ import (
|
|||||||
// multipart/form-data - each parameter takes a section in the payload with an internal header. For example, for
|
// multipart/form-data - each parameter takes a section in the payload with an internal header. For example, for
|
||||||
// the header Content-Disposition: form-data; name="submit-name" the name of the parameter is
|
// the header Content-Disposition: form-data; name="submit-name" the name of the parameter is
|
||||||
// submit-name. This type of form parameters is more commonly used for file transfers
|
// submit-name. This type of form parameters is more commonly used for file transfers
|
||||||
|
//
|
||||||
// https://swagger.io/specification/v2/#parameterObject
|
// https://swagger.io/specification/v2/#parameterObject
|
||||||
type Parameter struct {
|
type Parameter struct {
|
||||||
Name low.NodeReference[string]
|
Name low.NodeReference[string]
|
||||||
|
|||||||
@@ -446,5 +446,3 @@ func GenerateCleanSpecConfigBaseURL(baseURL *url.URL, dir string, includeFile bo
|
|||||||
return p
|
return p
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func (a *ExamplesChanges) TotalBreakingChanges() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CompareExamplesV2 compares two Swagger Examples objects, returning a pointer to
|
// CompareExamplesV2 compares two Swagger Examples objects, returning a pointer to
|
||||||
//ExamplesChanges if anything was found.
|
// ExamplesChanges if anything was found.
|
||||||
func CompareExamplesV2(l, r *v2.Examples) *ExamplesChanges {
|
func CompareExamplesV2(l, r *v2.Examples) *ExamplesChanges {
|
||||||
|
|
||||||
lHashes := make(map[string]string)
|
lHashes := make(map[string]string)
|
||||||
|
|||||||
@@ -1012,12 +1012,28 @@ func checkSchemaPropertyChanges(
|
|||||||
CreateChange(changes, ObjectRemoved, v3.UnevaluatedItemsLabel,
|
CreateChange(changes, ObjectRemoved, v3.UnevaluatedItemsLabel,
|
||||||
lSchema.UnevaluatedItems.ValueNode, nil, true, lSchema.UnevaluatedItems.Value, nil)
|
lSchema.UnevaluatedItems.ValueNode, nil, true, lSchema.UnevaluatedItems.Value, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnevaluatedProperties
|
// UnevaluatedProperties
|
||||||
if lSchema.UnevaluatedProperties.Value != nil && rSchema.UnevaluatedProperties.Value != nil {
|
if lSchema.UnevaluatedProperties.Value != nil && rSchema.UnevaluatedProperties.Value != nil {
|
||||||
if !low.AreEqual(lSchema.UnevaluatedProperties.Value, rSchema.UnevaluatedProperties.Value) {
|
if lSchema.UnevaluatedProperties.Value.IsA() && rSchema.UnevaluatedProperties.Value.IsA() {
|
||||||
sc.UnevaluatedPropertiesChanges = CompareSchemas(lSchema.UnevaluatedProperties.Value, rSchema.UnevaluatedProperties.Value)
|
if !low.AreEqual(lSchema.UnevaluatedProperties.Value.A, rSchema.UnevaluatedProperties.Value.A) {
|
||||||
|
sc.UnevaluatedPropertiesChanges = CompareSchemas(lSchema.UnevaluatedProperties.Value.A, rSchema.UnevaluatedProperties.Value.A)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if lSchema.UnevaluatedProperties.Value.IsB() && rSchema.UnevaluatedProperties.Value.IsB() {
|
||||||
|
if lSchema.UnevaluatedProperties.Value.B != rSchema.UnevaluatedProperties.Value.B {
|
||||||
|
CreateChange(changes, Modified, v3.UnevaluatedPropertiesLabel,
|
||||||
|
lSchema.UnevaluatedProperties.ValueNode, rSchema.UnevaluatedProperties.ValueNode, true,
|
||||||
|
lSchema.UnevaluatedProperties.Value.B, rSchema.UnevaluatedProperties.Value.B)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CreateChange(changes, Modified, v3.UnevaluatedPropertiesLabel,
|
||||||
|
lSchema.UnevaluatedProperties.ValueNode, rSchema.UnevaluatedProperties.ValueNode, true,
|
||||||
|
lSchema.UnevaluatedProperties.Value.B, rSchema.UnevaluatedProperties.Value.B)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// added UnevaluatedProperties
|
// added UnevaluatedProperties
|
||||||
if lSchema.UnevaluatedProperties.Value == nil && rSchema.UnevaluatedProperties.Value != nil {
|
if lSchema.UnevaluatedProperties.Value == nil && rSchema.UnevaluatedProperties.Value != nil {
|
||||||
CreateChange(changes, ObjectAdded, v3.UnevaluatedPropertiesLabel,
|
CreateChange(changes, ObjectAdded, v3.UnevaluatedPropertiesLabel,
|
||||||
|
|||||||
Reference in New Issue
Block a user