openapi_parser 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yaml +1 -0
- data/CHANGELOG.md +9 -0
- data/lib/openapi_parser/errors.rb +7 -0
- data/lib/openapi_parser/schema_validator/integer_validator.rb +2 -0
- data/lib/openapi_parser/schema_validator.rb +13 -3
- data/lib/openapi_parser/schemas/openapi.rb +4 -0
- data/lib/openapi_parser/schemas/schema.rb +8 -0
- data/lib/openapi_parser/spec_validator/rules/boolean_schema_in_30.rb +26 -0
- data/lib/openapi_parser/spec_validator/rules/self_before_32.rb +20 -0
- data/lib/openapi_parser/spec_validator.rb +4 -0
- data/lib/openapi_parser/version.rb +1 -1
- data/sig/openapi_parser/spec_validator.rbs +8 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e570c33d05a24e9b11a3f5b86f5321f895088a672d404df68f3d14b4d3f9fb8f
|
|
4
|
+
data.tar.gz: fadcedd0e7b7c5ce057f2b0fa36f313218f151ae524dd2290c1242fbdfca02da
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 680325ae11c7dce38425d23c89918d3ce5cb768261dbd48f6d21c166ca0d89b2dbf9304297b2f754830f47cdf8d45dd2501371b396fe972957474e171f4b3b49
|
|
7
|
+
data.tar.gz: 27b757f70c102671ff1f2891918f5e7abb044796e280027b097214f4f0bbb2ff538b7f7c84d7d1bb7f1fc8b46b63591ad62e37985dab50ebb35c0603b854e92e
|
data/.github/workflows/ci.yaml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
## Unreleased
|
|
2
2
|
|
|
3
|
+
## 2.5.0 (2026-10-21)
|
|
4
|
+
* add OpenAPI 3.2 `SpecValidator` rules
|
|
5
|
+
* `SelfBefore32`: detect `$self` usage in pre-3.2 documents (3.2 addition)
|
|
6
|
+
* support root-level `$self` (OpenAPI 3.2) in the parse layer (`self_uri`); it is not yet used as the base URI for `$ref` resolution
|
|
7
|
+
* support boolean schemas (OpenAPI 3.1): `true` accepts any value and `false` rejects any value with `FalseSchemaError`, instead of crashing the loader with `NoMethodError`
|
|
8
|
+
* add `SpecValidator` rule `BooleanSchemaIn30`: detect boolean schemas in 3.0 documents (3.1 addition; `additionalProperties` is not affected)
|
|
9
|
+
* coerce non-String values into array-form `type` (3.1) the same way as a single `type` when `coerce_value` is on, so `type: [integer, "null"]` handles a Float the same way as `type: integer`
|
|
10
|
+
* stop truncating a Float with a fractional part in integer coercion (`coerce_value`): `1.5` for `type: integer` now fails instead of becoming `1`, while a Float with no fractional part, like `1.0`, is still converted
|
|
11
|
+
|
|
3
12
|
## 2.4.0 (2026-10-14)
|
|
4
13
|
* support `components.pathItems` so `$ref`s into it resolve, unblocking OpenAPI 3.1 documents that use reusable path items
|
|
5
14
|
* support array-form `type` (3.1) in value validation
|
|
@@ -38,6 +38,13 @@ module OpenAPIParser
|
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
+
# 3.1: raised for any value checked against the boolean schema `false`
|
|
42
|
+
class FalseSchemaError < OpenAPIError
|
|
43
|
+
def message
|
|
44
|
+
"#{@reference} does not allow any value"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
41
48
|
class NotExistRequiredKey < OpenAPIError
|
|
42
49
|
def initialize(keys, reference)
|
|
43
50
|
super(reference)
|
|
@@ -21,6 +21,8 @@ class OpenAPIParser::SchemaValidator
|
|
|
21
21
|
|
|
22
22
|
def coerce(value)
|
|
23
23
|
return value if value.kind_of?(Integer)
|
|
24
|
+
# Integer() truncates a Float, so convert only one with no fractional part.
|
|
25
|
+
return value.finite? && value == value.floor ? value.to_i : value if value.kind_of?(Float)
|
|
24
26
|
|
|
25
27
|
begin
|
|
26
28
|
Integer(value)
|
|
@@ -75,6 +75,13 @@ class OpenAPIParser::SchemaValidator
|
|
|
75
75
|
def validate_schema(value, schema, **keyword_args)
|
|
76
76
|
return [value, nil] unless schema
|
|
77
77
|
|
|
78
|
+
# 3.1: a boolean schema accepts (`true`) or rejects (`false`) any value,
|
|
79
|
+
# including null.
|
|
80
|
+
if schema.respond_to?(:raw_schema)
|
|
81
|
+
return [value, nil] if schema.raw_schema == true
|
|
82
|
+
return [nil, OpenAPIParser::FalseSchemaError.new(schema.object_reference)] if schema.raw_schema == false
|
|
83
|
+
end
|
|
84
|
+
|
|
78
85
|
# 3.1: `const` pins the value to exactly that constant. Checked before
|
|
79
86
|
# type dispatch so it applies uniformly across primitives. Detection
|
|
80
87
|
# uses raw_schema so an intentional `const: null` is honored.
|
|
@@ -154,11 +161,14 @@ class OpenAPIParser::SchemaValidator
|
|
|
154
161
|
end
|
|
155
162
|
end
|
|
156
163
|
|
|
157
|
-
# 3.1:
|
|
158
|
-
#
|
|
164
|
+
# 3.1: when coercing, a value whose class matches no listed type is tried
|
|
165
|
+
# against each listed type, the same way a single `type` coerces it.
|
|
166
|
+
# Request params arrive as Strings ("5" for `type: [integer, "null"]`),
|
|
167
|
+
# and a single `type: integer` also coerces a Float such as 1.0.
|
|
168
|
+
# nil is left to the nil validator, as it is for a single `type`.
|
|
159
169
|
# @return [Boolean]
|
|
160
170
|
def coerce_into_type_array?(value, schema)
|
|
161
|
-
return false unless @coerce_value && value.
|
|
171
|
+
return false unless @coerce_value && !value.nil?
|
|
162
172
|
return false if schema.any_of || schema.all_of || schema.one_of
|
|
163
173
|
|
|
164
174
|
schema.type.is_a?(Array) && pick_array_type(value, schema.type).nil?
|
|
@@ -53,6 +53,10 @@ module OpenAPIParser::Schemas
|
|
|
53
53
|
# @return [String, nil] dialect URI for embedded JSON Schemas (OpenAPI 3.1+)
|
|
54
54
|
openapi_attr_value :json_schema_dialect, schema_key: :jsonSchemaDialect
|
|
55
55
|
|
|
56
|
+
# @!attribute [r] self_uri
|
|
57
|
+
# @return [String, nil] the document's own URI, `$self` (OpenAPI 3.2+)
|
|
58
|
+
openapi_attr_value :self_uri, schema_key: :'$self'
|
|
59
|
+
|
|
56
60
|
# @return [OpenAPIParser::RequestOperation, nil]
|
|
57
61
|
def request_operation(http_method, request_path)
|
|
58
62
|
OpenAPIParser::RequestOperation.create(http_method, request_path, @path_item_finder, @config)
|
|
@@ -125,5 +125,13 @@ module OpenAPIParser::Schemas
|
|
|
125
125
|
def additional_properties
|
|
126
126
|
@additional_properties.nil? ? true : @additional_properties
|
|
127
127
|
end
|
|
128
|
+
|
|
129
|
+
# 3.1: a boolean schema (`true` / `false`) has no keywords to load.
|
|
130
|
+
def load_data
|
|
131
|
+
return super if raw_schema.is_a?(::Hash)
|
|
132
|
+
|
|
133
|
+
@_openapi_all_child_objects = {}
|
|
134
|
+
nil
|
|
135
|
+
end
|
|
128
136
|
end
|
|
129
137
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module OpenAPIParser
|
|
2
|
+
class SpecValidator
|
|
3
|
+
module Rules
|
|
4
|
+
# A boolean schema (`true` / `false` in place of a schema object) comes
|
|
5
|
+
# from JSON Schema 2020-12, which 3.1 adopts. 3.0 allows a boolean only
|
|
6
|
+
# for `additionalProperties`, which is not loaded as a Schema, so any
|
|
7
|
+
# Schema whose raw value is a boolean is a spec mismatch in 3.0.
|
|
8
|
+
class BooleanSchemaIn30 < Rule
|
|
9
|
+
def check(root)
|
|
10
|
+
return [] unless version_before?('3.1')
|
|
11
|
+
|
|
12
|
+
violations = []
|
|
13
|
+
each_schema(root) do |schema|
|
|
14
|
+
next unless schema.raw_schema == true || schema.raw_schema == false
|
|
15
|
+
|
|
16
|
+
violations << violation(
|
|
17
|
+
path: schema.object_reference,
|
|
18
|
+
message: 'a boolean schema is a 3.1 addition (from JSON Schema 2020-12); 3.0 allows a boolean only for `additionalProperties`',
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
violations
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module OpenAPIParser
|
|
2
|
+
class SpecValidator
|
|
3
|
+
module Rules
|
|
4
|
+
# `$self` is a 3.2 root-level addition declaring the document's own
|
|
5
|
+
# URI for reference resolution. The parse layer accepts it
|
|
6
|
+
# permissively; this rule reports the version mismatch.
|
|
7
|
+
class SelfBefore32 < Rule
|
|
8
|
+
def check(root)
|
|
9
|
+
return [] unless version_before?('3.2')
|
|
10
|
+
return [] unless root.raw_schema.is_a?(Hash) && root.raw_schema.key?('$self')
|
|
11
|
+
|
|
12
|
+
[violation(
|
|
13
|
+
path: '#/$self',
|
|
14
|
+
message: '`$self` is a 3.2 root-level addition; earlier documents have no such field',
|
|
15
|
+
)]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -5,6 +5,7 @@ require_relative 'spec_validator/rules/exclusive_maximum'
|
|
|
5
5
|
require_relative 'spec_validator/rules/content_encoding_in_30'
|
|
6
6
|
require_relative 'spec_validator/rules/content_media_type_in_30'
|
|
7
7
|
require_relative 'spec_validator/rules/prefix_items_in_30'
|
|
8
|
+
require_relative 'spec_validator/rules/boolean_schema_in_30'
|
|
8
9
|
require_relative 'spec_validator/rules/json_schema_dialect_in_30'
|
|
9
10
|
require_relative 'spec_validator/rules/type_array_in_30'
|
|
10
11
|
require_relative 'spec_validator/rules/path_items_in_30'
|
|
@@ -16,6 +17,7 @@ require_relative 'spec_validator/rules/const_in_30'
|
|
|
16
17
|
require_relative 'spec_validator/rules/dynamic_ref_in_30'
|
|
17
18
|
require_relative 'spec_validator/rules/dynamic_anchor_in_30'
|
|
18
19
|
require_relative 'spec_validator/rules/content_schema_in_30'
|
|
20
|
+
require_relative 'spec_validator/rules/self_before_32'
|
|
19
21
|
|
|
20
22
|
module OpenAPIParser
|
|
21
23
|
class SpecViolationError < OpenAPIError
|
|
@@ -68,6 +70,7 @@ module OpenAPIParser
|
|
|
68
70
|
Rules::ContentEncodingIn30,
|
|
69
71
|
Rules::ContentMediaTypeIn30,
|
|
70
72
|
Rules::PrefixItemsIn30,
|
|
73
|
+
Rules::BooleanSchemaIn30,
|
|
71
74
|
Rules::JsonSchemaDialectIn30,
|
|
72
75
|
Rules::TypeArrayIn30,
|
|
73
76
|
Rules::PathItemsIn30,
|
|
@@ -79,6 +82,7 @@ module OpenAPIParser
|
|
|
79
82
|
Rules::DynamicRefIn30,
|
|
80
83
|
Rules::DynamicAnchorIn30,
|
|
81
84
|
Rules::ContentSchemaIn30,
|
|
85
|
+
Rules::SelfBefore32,
|
|
82
86
|
]
|
|
83
87
|
end
|
|
84
88
|
end
|
|
@@ -59,6 +59,10 @@ module OpenAPIParser
|
|
|
59
59
|
def check: (OpenAPIParser::Schemas::OpenAPI root) -> Array[SpecValidator::SpecViolation]
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
+
class BooleanSchemaIn30 < Rule
|
|
63
|
+
def check: (OpenAPIParser::Schemas::OpenAPI root) -> Array[SpecValidator::SpecViolation]
|
|
64
|
+
end
|
|
65
|
+
|
|
62
66
|
class JsonSchemaDialectIn30 < Rule
|
|
63
67
|
def check: (OpenAPIParser::Schemas::OpenAPI root) -> Array[SpecValidator::SpecViolation]
|
|
64
68
|
end
|
|
@@ -102,6 +106,10 @@ module OpenAPIParser
|
|
|
102
106
|
class ContentSchemaIn30 < Rule
|
|
103
107
|
def check: (OpenAPIParser::Schemas::OpenAPI root) -> Array[SpecValidator::SpecViolation]
|
|
104
108
|
end
|
|
109
|
+
|
|
110
|
+
class SelfBefore32 < Rule
|
|
111
|
+
def check: (OpenAPIParser::Schemas::OpenAPI root) -> Array[SpecValidator::SpecViolation]
|
|
112
|
+
end
|
|
105
113
|
end
|
|
106
114
|
end
|
|
107
115
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openapi_parser
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ota42y
|
|
@@ -210,6 +210,7 @@ files:
|
|
|
210
210
|
- lib/openapi_parser/schemas/schema.rb
|
|
211
211
|
- lib/openapi_parser/spec_validator.rb
|
|
212
212
|
- lib/openapi_parser/spec_validator/rule.rb
|
|
213
|
+
- lib/openapi_parser/spec_validator/rules/boolean_schema_in_30.rb
|
|
213
214
|
- lib/openapi_parser/spec_validator/rules/const_in_30.rb
|
|
214
215
|
- lib/openapi_parser/spec_validator/rules/content_encoding_in_30.rb
|
|
215
216
|
- lib/openapi_parser/spec_validator/rules/content_media_type_in_30.rb
|
|
@@ -223,6 +224,7 @@ files:
|
|
|
223
224
|
- lib/openapi_parser/spec_validator/rules/nullable_deprecation.rb
|
|
224
225
|
- lib/openapi_parser/spec_validator/rules/path_items_in_30.rb
|
|
225
226
|
- lib/openapi_parser/spec_validator/rules/prefix_items_in_30.rb
|
|
227
|
+
- lib/openapi_parser/spec_validator/rules/self_before_32.rb
|
|
226
228
|
- lib/openapi_parser/spec_validator/rules/type_array_in_30.rb
|
|
227
229
|
- lib/openapi_parser/spec_validator/rules/type_null_in_30.rb
|
|
228
230
|
- lib/openapi_parser/spec_validator/rules/webhooks_in_30.rb
|