verquest 0.6.3 → 0.6.4
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/CHANGELOG.md +5 -0
- data/README.md +25 -6
- data/lib/verquest/base/private_class_methods.rb +4 -2
- data/lib/verquest/gem_version.rb +1 -1
- data/lib/verquest/properties/base.rb +12 -0
- data/lib/verquest/properties/const.rb +4 -4
- data/lib/verquest/properties/enum.rb +1 -5
- data/lib/verquest/properties/field.rb +1 -0
- data/lib/verquest/properties/one_of.rb +4 -11
- data/lib/verquest/properties/reference.rb +2 -21
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5be764c988f4ea26a04112ed68684fcc7d292e25c37c6c2105f1c62ba7c92bc8
|
|
4
|
+
data.tar.gz: 15cead4ea24fc972317e15157fd14194098f2f543ae7d2402ae81a443ad198d9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 898d20e10c9ea20ccacd10fb8711778444f7cc096c09152e6ba48a167e363a19e60a2d8ed481205d2331b3b5a076ccc888a279ba44121342e698ade944ff9c8b
|
|
7
|
+
data.tar.gz: 23dba503f13f33a571f65008eaa13f2f94347dd974cfa45e9e8bb2f76e9e2599e0ab19fed299b2ea43144641e642c54a30d636ffe0d332967cb7ec84c521f3d6
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -319,6 +319,20 @@ Will produce this validation schema:
|
|
|
319
319
|
|
|
320
320
|
You can define nullable properties in your request schema by setting the `nullable` option to `true`. This feature is based on the latest JSON Schema specification, which is also used in OpenAPI 3.1.
|
|
321
321
|
|
|
322
|
+
Nullable enums include Ruby `nil` in their allowed values, which exports as JSON `null`, not the string `"null"`. This also applies to fields with an `enum:` constraint (including custom field types). The supplied values array is not modified.
|
|
323
|
+
|
|
324
|
+
```ruby
|
|
325
|
+
enum :role, values: %w[member admin], nullable: true
|
|
326
|
+
# => {"role" => {"enum" => ["member", "admin", nil]}}
|
|
327
|
+
|
|
328
|
+
const :kind, value: "user", nullable: true
|
|
329
|
+
# => {"kind" => {"anyOf" => [{"const" => "user"}, {"type" => "null"}]}}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Nullable constants and references use `anyOf` with a null alternative in both exported and validation schemas. Nullable `one_of` uses an outer `anyOf` around the original `oneOf` and the null alternative. This allows null even when a referenced schema or multiple variants already accept it, while preserving all restrictions on non-null values. A discriminator, when present, stays alongside the inner `oneOf`.
|
|
333
|
+
|
|
334
|
+
`required: true` still requires the key to be present; `nullable: true` only permits its value to be null. Defaults stay on the outer nullable schema so missing properties still receive them when default insertion is enabled. Explicit null values are not replaced by defaults.
|
|
335
|
+
|
|
322
336
|
```ruby
|
|
323
337
|
class NullableRequest < Verquest::Base
|
|
324
338
|
description "This is a simple request with nullable properties for testing purposes."
|
|
@@ -365,13 +379,18 @@ Will produce this validation schema:
|
|
|
365
379
|
"additionalProperties" => false
|
|
366
380
|
},
|
|
367
381
|
"referenced_object" => {
|
|
368
|
-
"
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
382
|
+
"anyOf" => [
|
|
383
|
+
{
|
|
384
|
+
"type" => "object",
|
|
385
|
+
"description" => "This is an another example for testing purposes.",
|
|
386
|
+
"required" => %w[simple_field nested],
|
|
387
|
+
"properties" => {"simple_field" => {"type" => "string", "description" => "The simple field"}, "nested" => {"type" => "object", "required" => %w[nested_field_1 nested_field_2], "properties" => {"nested_field_1" => {"type" => "string", "description" => "This is a nested field"}, "nested_field_2" => {"type" => "string", "description" => "This is another nested field"}}, "additionalProperties" => false}},
|
|
388
|
+
"additionalProperties" => false
|
|
389
|
+
},
|
|
390
|
+
{"type" => "null"}
|
|
391
|
+
]
|
|
373
392
|
},
|
|
374
|
-
"referenced_field" => {"type" =>
|
|
393
|
+
"referenced_field" => {"anyOf" => [{"type" => "string", "description" => "The simple field"}, {"type" => "null"}]}
|
|
375
394
|
},
|
|
376
395
|
"additionalProperties" => false
|
|
377
396
|
}
|
|
@@ -164,13 +164,15 @@ module Verquest
|
|
|
164
164
|
# @param value [Object] The value of the constant
|
|
165
165
|
# @param map [String, nil] An optional mapping to another constant
|
|
166
166
|
# @param required [Boolean, Array<Symbol>] Whether the constant is required
|
|
167
|
+
# @param nullable [Boolean] Whether the constant can be null
|
|
167
168
|
# @param schema_options [Hash] Additional schema options for the constant
|
|
168
169
|
# @return [void]
|
|
169
|
-
def const(name, value:, map: nil, required: nil, **schema_options)
|
|
170
|
+
def const(name, value:, map: nil, required: nil, nullable: nil, **schema_options)
|
|
170
171
|
camelize(schema_options)
|
|
171
172
|
required = default_options.fetch(:required, false) if required.nil?
|
|
173
|
+
nullable = default_options.fetch(:nullable, false) if nullable.nil?
|
|
172
174
|
|
|
173
|
-
const = Properties::Const.new(name:, value:, map:, required:, **schema_options)
|
|
175
|
+
const = Properties::Const.new(name:, value:, map:, required:, nullable:, **schema_options)
|
|
174
176
|
current_scope.add(const)
|
|
175
177
|
end
|
|
176
178
|
|
data/lib/verquest/gem_version.rb
CHANGED
|
@@ -12,6 +12,9 @@ module Verquest
|
|
|
12
12
|
class Base
|
|
13
13
|
include HelperMethods::RequiredProperties
|
|
14
14
|
|
|
15
|
+
# JSON Schema for null type, used when nullable is true
|
|
16
|
+
NULL_TYPE_SCHEMA = {"type" => "null"}.freeze
|
|
17
|
+
|
|
15
18
|
# @!attribute [rw] name
|
|
16
19
|
# @return [String] The name of the property
|
|
17
20
|
# @!attribute [rw] required
|
|
@@ -61,6 +64,15 @@ module Verquest
|
|
|
61
64
|
# @return [Boolean] Whether this property can be null
|
|
62
65
|
attr_reader :nullable
|
|
63
66
|
|
|
67
|
+
# Allows null without weakening constraints, keeping defaults available for insertion
|
|
68
|
+
# @param schema [Hash] The original property schema
|
|
69
|
+
# @return [Hash] The schema, optionally wrapped in a nullable union
|
|
70
|
+
def nullable_schema(schema)
|
|
71
|
+
return schema unless nullable
|
|
72
|
+
|
|
73
|
+
schema.slice("default").merge("anyOf" => [schema.except("default"), NULL_TYPE_SCHEMA])
|
|
74
|
+
end
|
|
75
|
+
|
|
64
76
|
# Determines the mapping target key based on mapping configuration
|
|
65
77
|
# @param value_prefix [Array<String>] Prefix for the target value
|
|
66
78
|
# @param collection [Boolean] Whether this is a collection mapping
|
|
@@ -14,12 +14,14 @@ module Verquest
|
|
|
14
14
|
# @param value [Object] The fixed value of the constant (can be any scalar value)
|
|
15
15
|
# @param map [Object, nil] Optional mapping information
|
|
16
16
|
# @param required [Boolean, Array<Symbol>] Whether this property is required, or array of dependency names (can be overridden by custom type)
|
|
17
|
+
# @param nullable [Boolean] Whether this property can be null
|
|
17
18
|
# @param schema_options [Hash] Additional JSON schema options for this property
|
|
18
|
-
def initialize(name:, value:, map: nil, required: false, **schema_options)
|
|
19
|
+
def initialize(name:, value:, map: nil, required: false, nullable: false, **schema_options)
|
|
19
20
|
@name = name.to_s
|
|
20
21
|
@value = value
|
|
21
22
|
@map = map
|
|
22
23
|
@required = required
|
|
24
|
+
@nullable = nullable
|
|
23
25
|
@schema_options = schema_options&.transform_keys(&:to_s)
|
|
24
26
|
end
|
|
25
27
|
|
|
@@ -28,9 +30,7 @@ module Verquest
|
|
|
28
30
|
# @return [Hash] The schema definition for this constant
|
|
29
31
|
def to_schema
|
|
30
32
|
{
|
|
31
|
-
name => {
|
|
32
|
-
"const" => value
|
|
33
|
-
}.merge(schema_options)
|
|
33
|
+
name => nullable_schema({"const" => value}.merge(schema_options))
|
|
34
34
|
}
|
|
35
35
|
end
|
|
36
36
|
|
|
@@ -26,15 +26,11 @@ module Verquest
|
|
|
26
26
|
raise ArgumentError, "Use const for a single value" if values.length == 1
|
|
27
27
|
|
|
28
28
|
@name = name.to_s
|
|
29
|
-
@values = values
|
|
29
|
+
@values = nullable ? values | [nil] : values
|
|
30
30
|
@required = required
|
|
31
31
|
@nullable = nullable
|
|
32
32
|
@map = map
|
|
33
33
|
@schema_options = schema_options&.transform_keys(&:to_s)
|
|
34
|
-
|
|
35
|
-
if nullable && !values.include?("null")
|
|
36
|
-
values << "null"
|
|
37
|
-
end
|
|
38
34
|
end
|
|
39
35
|
|
|
40
36
|
# Generate JSON schema definition for this enum
|
|
@@ -31,9 +31,6 @@ module Verquest
|
|
|
31
31
|
# one_of = Verquest::Properties::OneOf.new(name: :value)
|
|
32
32
|
# # Validates that exactly one schema matches
|
|
33
33
|
class OneOf < Base
|
|
34
|
-
# JSON Schema for null type, used when nullable is true
|
|
35
|
-
NULL_TYPE_SCHEMA = {"type" => "null"}.freeze
|
|
36
|
-
|
|
37
34
|
# @return [String, nil] The discriminator property name for schema selection
|
|
38
35
|
attr_reader :discriminator
|
|
39
36
|
|
|
@@ -75,7 +72,7 @@ module Verquest
|
|
|
75
72
|
# @return [Hash] The schema definition with oneOf array and optional discriminator
|
|
76
73
|
def to_schema
|
|
77
74
|
freeze_schemas
|
|
78
|
-
wrap_schema(build_schema_with_refs)
|
|
75
|
+
wrap_schema(nullable_schema(build_schema_with_refs))
|
|
79
76
|
end
|
|
80
77
|
|
|
81
78
|
# Generate validation schema for this oneOf property
|
|
@@ -87,7 +84,7 @@ module Verquest
|
|
|
87
84
|
# @return [Hash] The validation schema with inline schema definitions
|
|
88
85
|
def to_validation_schema(version: nil)
|
|
89
86
|
freeze_schemas
|
|
90
|
-
wrap_schema(build_validation_schema(version: version))
|
|
87
|
+
wrap_schema(nullable_schema(build_validation_schema(version: version)))
|
|
91
88
|
end
|
|
92
89
|
|
|
93
90
|
# Create mapping for this oneOf property
|
|
@@ -386,9 +383,7 @@ module Verquest
|
|
|
386
383
|
#
|
|
387
384
|
# @return [Array<Hash>] Array of schema references
|
|
388
385
|
def collect_schema_refs
|
|
389
|
-
|
|
390
|
-
refs << NULL_TYPE_SCHEMA if nullable
|
|
391
|
-
refs
|
|
386
|
+
schemas.values.map { |schema| schema.to_schema[schema.name] }
|
|
392
387
|
end
|
|
393
388
|
|
|
394
389
|
# Collects inline schema definitions for all variants
|
|
@@ -396,9 +391,7 @@ module Verquest
|
|
|
396
391
|
# @param version [String, nil] The version for schema resolution
|
|
397
392
|
# @return [Array<Hash>] Array of inline schema definitions
|
|
398
393
|
def collect_inline_schemas(version)
|
|
399
|
-
|
|
400
|
-
inline_schemas << NULL_TYPE_SCHEMA if nullable
|
|
401
|
-
inline_schemas
|
|
394
|
+
schemas.values.map { |schema| schema.to_validation_schema(version: version)[schema.name] }
|
|
402
395
|
end
|
|
403
396
|
|
|
404
397
|
# Adds discriminator information to the schema if present
|
|
@@ -42,20 +42,7 @@ module Verquest
|
|
|
42
42
|
#
|
|
43
43
|
# @return [Hash] The schema definition with a $ref pointer
|
|
44
44
|
def to_schema
|
|
45
|
-
|
|
46
|
-
{
|
|
47
|
-
name => {
|
|
48
|
-
"oneOf" => [
|
|
49
|
-
{"$ref" => from.to_ref(property: property)},
|
|
50
|
-
{"type" => "null"}
|
|
51
|
-
]
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
else
|
|
55
|
-
{
|
|
56
|
-
name => {"$ref" => from.to_ref(property: property)}
|
|
57
|
-
}
|
|
58
|
-
end
|
|
45
|
+
{name => nullable_schema({"$ref" => from.to_ref(property: property)})}
|
|
59
46
|
end
|
|
60
47
|
|
|
61
48
|
# Generate validation schema for this reference property
|
|
@@ -65,13 +52,7 @@ module Verquest
|
|
|
65
52
|
def to_validation_schema(version: nil)
|
|
66
53
|
schema = from.to_validation_schema(version:, property: property).dup
|
|
67
54
|
|
|
68
|
-
|
|
69
|
-
schema["type"] = [schema["type"], "null"] unless schema["type"].include?("null")
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
{
|
|
73
|
-
name => schema
|
|
74
|
-
}
|
|
55
|
+
{name => nullable_schema(schema)}
|
|
75
56
|
end
|
|
76
57
|
|
|
77
58
|
# Create mapping for this reference property
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: verquest
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Petr Hlavicka
|
|
@@ -98,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
98
98
|
- !ruby/object:Gem::Version
|
|
99
99
|
version: '0'
|
|
100
100
|
requirements: []
|
|
101
|
-
rubygems_version: 3.6.
|
|
101
|
+
rubygems_version: 3.6.9
|
|
102
102
|
specification_version: 4
|
|
103
103
|
summary: Verquest is a Ruby gem that offers an elegant solution for versioning API
|
|
104
104
|
requests
|