Skip to content

Commit e3920da

Browse files
fix: support OpenAPI 3.0 boolean exclusiveMinimum/exclusiveMaximum validation (#52)
Co-authored-by: Copilot <[email protected]>
1 parent ca028d0 commit e3920da

File tree

13 files changed

+713
-59
lines changed

13 files changed

+713
-59
lines changed

arazzo/arazzo.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import (
1212
"github.com/speakeasy-api/openapi/extensions"
1313
"github.com/speakeasy-api/openapi/internal/interfaces"
1414
"github.com/speakeasy-api/openapi/internal/utils"
15+
"github.com/speakeasy-api/openapi/jsonschema/oas3"
1516
"github.com/speakeasy-api/openapi/marshaller"
17+
"github.com/speakeasy-api/openapi/pointer"
1618
"github.com/speakeasy-api/openapi/validation"
1719
)
1820

@@ -98,6 +100,7 @@ func (a *Arazzo) Sync(ctx context.Context) error {
98100
// Validate will validate the Arazzo document against the Arazzo Specification.
99101
func (a *Arazzo) Validate(ctx context.Context, opts ...validation.Option) []error {
100102
opts = append(opts, validation.WithContextObject(a))
103+
opts = append(opts, validation.WithContextObject(&oas3.ParentDocumentVersion{Arazzo: pointer.From(a.Arazzo)}))
101104

102105
core := a.GetCore()
103106
errs := []error{}

arazzo/components.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,7 @@ func (c *Components) Validate(ctx context.Context, opts ...validation.Option) []
4747
errs = append(errs, validation.NewMapKeyError(validation.NewValueValidationError("components field inputs key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.Inputs, key))
4848
}
4949

50-
if input.IsLeft() {
51-
jsOpts := opts
52-
jsOpts = append(jsOpts, validation.WithContextObject(&componentKey{name: key}))
53-
54-
errs = append(errs, input.Left.Validate(ctx, jsOpts...)...)
55-
}
50+
errs = append(errs, input.Validate(ctx, opts...)...)
5651
}
5752

5853
for key, parameter := range c.Parameters.All() {

jsonschema/oas3/schema30.json

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
{
2+
"id": "https://spec.openapis.org/oas/3.0/dialect/2024-10-18",
3+
"$schema": "http://json-schema.org/draft-04/schema#",
4+
"description": "OpenAPI 3.0 Schema Object based on official https://spec.openapis.org/oas/3.0/schema/2024-10-18.html specification",
5+
"type": "object",
6+
"properties": {
7+
"$schema": {
8+
"type": "string",
9+
"format": "uri",
10+
"description": "Added unofficial support for $schema property to assist testing"
11+
},
12+
"title": {
13+
"type": "string"
14+
},
15+
"multipleOf": {
16+
"type": "number",
17+
"minimum": 0,
18+
"exclusiveMinimum": true
19+
},
20+
"maximum": {
21+
"type": "number"
22+
},
23+
"exclusiveMaximum": {
24+
"type": "boolean",
25+
"default": false
26+
},
27+
"minimum": {
28+
"type": "number"
29+
},
30+
"exclusiveMinimum": {
31+
"type": "boolean",
32+
"default": false
33+
},
34+
"maxLength": {
35+
"type": "integer",
36+
"minimum": 0
37+
},
38+
"minLength": {
39+
"type": "integer",
40+
"minimum": 0,
41+
"default": 0
42+
},
43+
"pattern": {
44+
"type": "string",
45+
"format": "regex"
46+
},
47+
"maxItems": {
48+
"type": "integer",
49+
"minimum": 0
50+
},
51+
"minItems": {
52+
"type": "integer",
53+
"minimum": 0,
54+
"default": 0
55+
},
56+
"uniqueItems": {
57+
"type": "boolean",
58+
"default": false
59+
},
60+
"maxProperties": {
61+
"type": "integer",
62+
"minimum": 0
63+
},
64+
"minProperties": {
65+
"type": "integer",
66+
"minimum": 0,
67+
"default": 0
68+
},
69+
"required": {
70+
"type": "array",
71+
"items": {
72+
"type": "string"
73+
},
74+
"minItems": 1,
75+
"uniqueItems": true
76+
},
77+
"enum": {
78+
"type": "array",
79+
"items": {},
80+
"minItems": 1,
81+
"uniqueItems": false
82+
},
83+
"type": {
84+
"type": "string",
85+
"enum": ["array", "boolean", "integer", "number", "object", "string"]
86+
},
87+
"not": {
88+
"oneOf": [{ "$ref": "#" }, { "$ref": "#/definitions/Reference" }]
89+
},
90+
"allOf": {
91+
"type": "array",
92+
"items": {
93+
"oneOf": [{ "$ref": "#" }, { "$ref": "#/definitions/Reference" }]
94+
}
95+
},
96+
"oneOf": {
97+
"type": "array",
98+
"items": {
99+
"oneOf": [{ "$ref": "#" }, { "$ref": "#/definitions/Reference" }]
100+
}
101+
},
102+
"anyOf": {
103+
"type": "array",
104+
"items": {
105+
"oneOf": [{ "$ref": "#" }, { "$ref": "#/definitions/Reference" }]
106+
}
107+
},
108+
"items": {
109+
"oneOf": [{ "$ref": "#" }, { "$ref": "#/definitions/Reference" }]
110+
},
111+
"properties": {
112+
"type": "object",
113+
"additionalProperties": {
114+
"oneOf": [{ "$ref": "#" }, { "$ref": "#/definitions/Reference" }]
115+
}
116+
},
117+
"additionalProperties": {
118+
"oneOf": [
119+
{ "$ref": "#" },
120+
{ "$ref": "#/definitions/Reference" },
121+
{ "type": "boolean" }
122+
],
123+
"default": true
124+
},
125+
"description": {
126+
"type": "string"
127+
},
128+
"format": {
129+
"type": "string"
130+
},
131+
"default": {},
132+
"nullable": {
133+
"type": "boolean",
134+
"default": false
135+
},
136+
"discriminator": {
137+
"$ref": "#/definitions/Discriminator"
138+
},
139+
"readOnly": {
140+
"type": "boolean",
141+
"default": false
142+
},
143+
"writeOnly": {
144+
"type": "boolean",
145+
"default": false
146+
},
147+
"example": {},
148+
"externalDocs": {
149+
"$ref": "#/definitions/ExternalDocumentation"
150+
},
151+
"deprecated": {
152+
"type": "boolean",
153+
"default": false
154+
},
155+
"xml": {
156+
"$ref": "#/definitions/XML"
157+
}
158+
},
159+
"patternProperties": {
160+
"^x-": {}
161+
},
162+
"additionalProperties": false,
163+
"definitions": {
164+
"Reference": {
165+
"type": "object",
166+
"required": ["$ref"],
167+
"patternProperties": {
168+
"^\\$ref$": {
169+
"type": "string",
170+
"format": "uri-reference"
171+
}
172+
}
173+
},
174+
"Discriminator": {
175+
"type": "object",
176+
"required": ["propertyName"],
177+
"properties": {
178+
"propertyName": {
179+
"type": "string"
180+
},
181+
"mapping": {
182+
"type": "object",
183+
"additionalProperties": {
184+
"type": "string"
185+
}
186+
}
187+
}
188+
},
189+
"XML": {
190+
"type": "object",
191+
"properties": {
192+
"name": {
193+
"type": "string"
194+
},
195+
"namespace": {
196+
"type": "string",
197+
"format": "uri"
198+
},
199+
"prefix": {
200+
"type": "string"
201+
},
202+
"attribute": {
203+
"type": "boolean",
204+
"default": false
205+
},
206+
"wrapped": {
207+
"type": "boolean",
208+
"default": false
209+
}
210+
},
211+
"patternProperties": {
212+
"^x-": {}
213+
},
214+
"additionalProperties": false
215+
},
216+
"ExternalDocumentation": {
217+
"type": "object",
218+
"required": ["url"],
219+
"properties": {
220+
"description": {
221+
"type": "string"
222+
},
223+
"url": {
224+
"type": "string",
225+
"format": "uri-reference"
226+
}
227+
},
228+
"patternProperties": {
229+
"^x-": {}
230+
},
231+
"additionalProperties": false
232+
}
233+
}
234+
}

0 commit comments

Comments
 (0)