-
Notifications
You must be signed in to change notification settings - Fork 112
Open
Description
With the following json schema, useRefAllOf
is expected to apply minItems: 1
and maxItems: 5
, and useOnlyRef
is expected to apply only minItems: 1
.
In practice, however, useOnlyRef
also applies minItems: 1
and maxItems: 5
.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"arrayMin1": {
"type": "object",
"additionalProperties": false,
"properties": {
"items": {
"type": "array",
"minItems": 1
}
}
}
},
"type": "object",
"additionalProperties": false,
"properties": {
"useRefAllOf": {
"allOf": [
{
"$ref": "#/definitions/arrayMin1"
},
{
"type": "object",
"properties": {
"items": {
"type": "array",
"maxItems": 5
}
}
}
]
},
"useOnlyRef": {
"$ref": "#/definitions/arrayMin1"
},
"noUseRefAllOf1": {
"allOf": [
{
"type": "object",
"properties": {
"items": {
"type": "array",
"minItems": 1
}
}
},
{
"type": "object",
"properties": {
"items": {
"type": "array",
"maxItems": 5
}
}
}
]
},
"noUseRefAllOf2": {
"allOf": [
{
"type": "object",
"properties": {
"items": {
"type": "array",
"minItems": 1
}
}
},
{
"type": "object",
"properties": {
"items": {
"type": "array",
"maxItems": 2
}
}
}
]
}
}
}
- output schema
// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT.
package entity
import "encoding/json"
import "fmt"
type ArrayMin1 struct {
// Items corresponds to the JSON schema field "items".
Items []interface{} `json:"items,omitempty" yaml:"items,omitempty" mapstructure:"items,omitempty"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *ArrayMin1) UnmarshalJSON(value []byte) error {
type Plain ArrayMin1
var plain Plain
if err := json.Unmarshal(value, &plain); err != nil {
return err
}
if plain.Items != nil && len(plain.Items) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "items", 1)
}
*j = ArrayMin1(plain)
return nil
}
type HelmChartValues struct {
// NoUseRefAllOf1 corresponds to the JSON schema field "noUseRefAllOf1".
NoUseRefAllOf1 *HelmChartValuesNoUseRefAllOf1 `json:"noUseRefAllOf1,omitempty" yaml:"noUseRefAllOf1,omitempty" mapstructure:"noUseRefAllOf1,omitempty"`
// NoUseRefAllOf2 corresponds to the JSON schema field "noUseRefAllOf2".
NoUseRefAllOf2 *HelmChartValuesNoUseRefAllOf2 `json:"noUseRefAllOf2,omitempty" yaml:"noUseRefAllOf2,omitempty" mapstructure:"noUseRefAllOf2,omitempty"`
// UseOnlyRef corresponds to the JSON schema field "useOnlyRef".
UseOnlyRef *ArrayMin1 `json:"useOnlyRef,omitempty" yaml:"useOnlyRef,omitempty" mapstructure:"useOnlyRef,omitempty"`
// UseRefAllOf corresponds to the JSON schema field "useRefAllOf".
UseRefAllOf *HelmChartValuesUseRefAllOf `json:"useRefAllOf,omitempty" yaml:"useRefAllOf,omitempty" mapstructure:"useRefAllOf,omitempty"`
}
type HelmChartValuesNoUseRefAllOf1 struct {
// Items corresponds to the JSON schema field "items".
Items []interface{} `json:"items,omitempty" yaml:"items,omitempty" mapstructure:"items,omitempty"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *HelmChartValuesNoUseRefAllOf1) UnmarshalJSON(value []byte) error {
type Plain HelmChartValuesNoUseRefAllOf1
var plain Plain
if err := json.Unmarshal(value, &plain); err != nil {
return err
}
if plain.Items != nil && len(plain.Items) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "items", 1)
}
if len(plain.Items) > 5 {
return fmt.Errorf("field %s length: must be <= %d", "items", 5)
}
*j = HelmChartValuesNoUseRefAllOf1(plain)
return nil
}
type HelmChartValuesNoUseRefAllOf2 struct {
// Items corresponds to the JSON schema field "items".
Items []interface{} `json:"items,omitempty" yaml:"items,omitempty" mapstructure:"items,omitempty"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *HelmChartValuesNoUseRefAllOf2) UnmarshalJSON(value []byte) error {
type Plain HelmChartValuesNoUseRefAllOf2
var plain Plain
if err := json.Unmarshal(value, &plain); err != nil {
return err
}
if plain.Items != nil && len(plain.Items) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "items", 1)
}
if len(plain.Items) > 2 {
return fmt.Errorf("field %s length: must be <= %d", "items", 2)
}
*j = HelmChartValuesNoUseRefAllOf2(plain)
return nil
}
type HelmChartValuesUseRefAllOf struct {
// Items corresponds to the JSON schema field "items".
Items []interface{} `json:"items,omitempty" yaml:"items,omitempty" mapstructure:"items,omitempty"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *HelmChartValuesUseRefAllOf) UnmarshalJSON(value []byte) error {
type Plain HelmChartValuesUseRefAllOf
var plain Plain
if err := json.Unmarshal(value, &plain); err != nil {
return err
}
if plain.Items != nil && len(plain.Items) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "items", 1)
}
if len(plain.Items) > 5 {
return fmt.Errorf("field %s length: must be <= %d", "items", 5)
}
*j = HelmChartValuesUseRefAllOf(plain)
return nil
}
I think the reason for this is that when ref
is included in allOf
, schema merge is performed on the Properties
map pointer value of the referring ref schema when schema merge is performed.
As a result, allOf
will affect all schemas that reference the same ref
.
https://github.com/omissis/go-jsonschema/blob/main/pkg/schemas/model.go#L275
https://github.com/omissis/go-jsonschema/blob/main/pkg/schemas/model.go#L315
I think you need to deep copy the pointer in the map before merge.
Metadata
Metadata
Assignees
Labels
No labels