verquest 0.2.1 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3937cd4b94f0a041133b0f36400e377afade0d8cc3c15bbc4b4f8ef601b8cf91
4
- data.tar.gz: c8e2ae6eea78d6840cc23c6ee461322fe2a7e79292e8c4cacf7ad0153a9bf215
3
+ metadata.gz: 725838444df6f3861ab842c88b430aa7bbc81023637595b4a0a8a909df5a2fbe
4
+ data.tar.gz: 88041a5f8bc888f90894975b5fb371ac8184877bb75b74e2e099ce57997b331a
5
5
  SHA512:
6
- metadata.gz: c7f9d528de6b8b0f7344ed02b52873a99c2a432a6c1d058e2fd25633bdc192c8ab68cd074e561add9567146b427a40256ba43bada339065b8138b9be8f02c9c4
7
- data.tar.gz: d94a551e3ba5804711630c54a33bd2717c711c8792565dfdaacdcfad902ca446a21a96d50fe03487fef7c4109d41efaf03db9b8a5c7cdb02699d8a5307144732
6
+ metadata.gz: 3991e8ff96b436e82a6edce43d591f35f669cbab9ef99b01bc26192bef94e3f48afe59595d8ae5d3d605bd96c0150bfdb557e555f1d20e79d74cbe4343d99c49
7
+ data.tar.gz: dcc10eeadec0f32073569db402893bb3f1ab5629da79eee32d605c476bbcf05f637f5b348f83478863bf7d28fc1d0b3d2cd9b54c38f356f3bfa53d51d3ac50bb
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ### Breaking Changes
4
+ - **BREAKING:** Renaming validation method from `validate_schema` to `valid_schema?` to better reflect its purpose.
5
+ - **BREAKING:** The `validate_schema` now returns an array of errors instead of a boolean value, allowing for more detailed error reporting.
6
+
7
+ ### New Features
8
+ - Add support for custom field types.
9
+
10
+ ### Fixed
11
+ - Loading the gem in another project with `zeitwerk` now works correctly.
12
+ - Fix schema validation after `json_schemer` refactoring.
13
+
14
+ ## [0.3.0] - 2025-06-25
15
+
16
+ ### Breaking Changes
17
+ - **BREAKING:** Replace `json-schema` gem with `json_schemer` for support of newer JSON Schema specifications (set the lasest by default).
18
+ - **BREAKING:** Schema and validation schema now uses string keys instead of symbols.
19
+
20
+ ### Added
21
+ - Allow insert default values for properties when validation is used.
3
22
 
4
23
  ## [0.2.1] - 2025-06-22
5
24
 
data/README.md CHANGED
@@ -19,7 +19,7 @@ Verquest is a Ruby gem that offers an elegant solution for versioning API reques
19
19
  Add this line to your application's Gemfile:
20
20
 
21
21
  ```ruby
22
- gem "verquest", "~> 0.2"
22
+ gem "verquest", "~> 0.3"
23
23
  ```
24
24
 
25
25
  And then execute:
@@ -128,48 +128,53 @@ UserCreateRequest.to_schema(version: "2025-06")
128
128
  Output:
129
129
  ```ruby
130
130
  {
131
- type: :object,
132
- description: "User Create Request",
133
- required: [:first_name, :last_name, :email, :address],
134
- properties: {
135
- first_name: {type: :string, description: "The first name of the user", maxLength: 50},
136
- last_name: {type: :string, description: "The last name of the user", maxLength: 50},
137
- email: {type: :string, format: "email", description: "The email address of the user"},
138
- birth_date: {type: :string, format: "date", description: "The birth date of the user"},
139
- address: {"$ref": "#/components/schemas/AddressCreateRequest"},
140
- permissions: {
141
- type: :array,
142
- items: {
143
- type: :object,
144
- required: [:name],
145
- properties: {
146
- name: {type: :string, description: "Name of the permission"},
147
- read: {type: :boolean, description: "Permission to read"},
148
- write: {type: :boolean, description: "Permission to write"}
131
+ "type" => "object",
132
+ "description" => "User Create Request",
133
+ "required" => ["first_name", "last_name", "email", "address"],
134
+ "properties" => {
135
+ "first_name" => {"type" => "string", "description" => "The first name of the user", "maxLength" => 50},
136
+ "last_name" => {"type" => "string", "description" => "The last name of the user", "maxLength" => 50},
137
+ "email" => {"type" => "string", "format" => "email", "description" => "The email address of the user"},
138
+ "birth_date" => {"type" => "string", "format" => "date", "description" => "The birth date of the user"},
139
+ "address" => {"$ref" => "#/components/schemas/AddressCreateRequest"},
140
+ "permissions" => {
141
+ "type" => "array",
142
+ "items" => {
143
+ "type" => "object",
144
+ "required" => ["name"],
145
+ "properties" => {
146
+ "name" => {"type" => "string", "description" => "Name of the permission"},
147
+ "read" => {"type" => "boolean", "description" => "Permission to read"},
148
+ "write" => {"type" => "boolean", "description" => "Permission to write"}
149
149
  }
150
- },
151
- description: "Permissions associated with the user"
150
+ },
151
+ "description" => "Permissions associated with the user"
152
152
  },
153
- role: {type: :string, description: "Role of the user", enum: ["member", "manager"], default: "member"},
154
- profile_details: {
155
- type: :object,
156
- required: [],
157
- properties: {
158
- bio: {type: :string, description: "Short biography of the user"},
159
- hobbies: {type: :array, items: {type: :string}, description: "Tags associated with the user"},
160
- social_links: {
161
- type: :object,
162
- required: [],
163
- properties: {
164
- github: {type: :string, format: "uri", description: "GitHub profile URL"},
165
- mastodon: {type: :string, format: "uri", description: "Mastodon profile URL"}
166
- },
167
- description: "Some social networks"
153
+ "role" => {
154
+ "type" => "string",
155
+ "description" => "Role of the user",
156
+ "enum" => ["member", "manager"],
157
+ "default" => "member"
158
+ },
159
+ "profile_details" => {
160
+ "type" => "object",
161
+ "required" => [],
162
+ "properties" => {
163
+ "bio" => {"type" => "string", "description" => "Short biography of the user"},
164
+ "hobbies" => {"type" => "array", "items" => {"type" => "string"}, "description" => "Tags associated with the user"},
165
+ "social_links" => {
166
+ "type" => "object",
167
+ "required" => [],
168
+ "properties" => {
169
+ "github" => {"type" => "string", "format" => "uri", "description" => "GitHub profile URL"},
170
+ "mastodon" => {"type" => "string", "format" => "uri", "description" => "Mastodon profile URL"}
171
+ },
172
+ "description" => "Some social networks"
168
173
  }
169
174
  }
170
175
  }
171
176
  },
172
- additionalProperties: false
177
+ "additionalProperties" => false
173
178
  }
174
179
  ```
175
180
 
@@ -184,66 +189,69 @@ UserCreateRequest.to_validation_schema(version: "2025-06")
184
189
  Output:
185
190
  ```ruby
186
191
  {
187
- type: :object,
188
- description: "User Create Request",
189
- required: [:first_name, :last_name, :email, :address],
190
- properties: {
191
- first_name: {type: :string, description: "The first name of the user", maxLength: 50},
192
- last_name: {type: :string, description: "The last name of the user", maxLength: 50},
193
- email: {type: :string, format: "email", description: "The email address of the user"},
194
- birth_date: {type: :string, format: "date", description: "The birth date of the user"},
195
- address: { # from the AddressCreateRequest
196
- type: :object,
197
- description: "Address Create Request",
198
- required: [:street, :city, :postal_code, :country],
199
- properties: {
200
- street: {type: :string, description: "Street address"},
201
- city: {type: :string, description: "City of residence"},
202
- postal_code: {type: :string, description: "Postal code"},
203
- country: {type: :string, description: "Country of residence"}
192
+ "type" => "object",
193
+ "description" => "User Create Request",
194
+ "required" => ["first_name", "last_name", "email", "address"],
195
+ "properties" => {
196
+ "first_name" => {"type" => "string", "description" => "The first name of the user", "maxLength" => 50},
197
+ "last_name" => {"type" => "string", "description" => "The last name of the user", "maxLength" => 50},
198
+ "email" => {"type" => "string", "format" => "email", "description" => "The email address of the user"},
199
+ "birth_date" => {"type" => "string", "format" => "date", "description" => "The birth date of the user"},
200
+ "address" => { # from the AddressCreateRequest
201
+ "type" => "object",
202
+ "description" => "Address Create Request",
203
+ "required" => ["street", "city", "postal_code", "country"],
204
+ "properties" => {
205
+ "street" => {"type" => "string", "description" => "Street address"},
206
+ "city" => {"type" => "string", "description" => "City of residence"},
207
+ "postal_code" => {"type" => "string", "description" => "Postal code"},
208
+ "country" => {"type" => "string", "description" => "Country of residence"}
204
209
  },
205
- additionalProperties: false
210
+ "additionalProperties" => false
206
211
  },
207
- permissions: {
208
- type: :array,
209
- items: {
210
- type: :object,
211
- required: [:name],
212
- properties: {
213
- name: {type: :string, description: "Name of the permission"},
214
- read: {type: :boolean, description: "Permission to read"},
215
- write: {type: :boolean, description: "Permission to write"}
212
+ "permissions" => {
213
+ "type" => "array",
214
+ "items" => {
215
+ "type" => "object", "required" => ["name"],
216
+ "properties" => {
217
+ "name" => {"type" => "string", "description" => "Name of the permission"},
218
+ "read" => {"type" => "boolean", "description" => "Permission to read"},
219
+ "write" => {"type" => "boolean", "description" => "Permission to write"}
216
220
  }
217
221
  },
218
- description: "Permissions associated with the user"
222
+ "description" => "Permissions associated with the user"
219
223
  },
220
- role: {type: :string, description: "Role of the user", enum: ["member", "manager"], default: "member"},
221
- profile_details: {
222
- type: :object,
223
- required: [],
224
- properties: {
225
- bio: {type: :string, description: "Short biography of the user"},
226
- hobbies: {type: :array, items: {type: :string}, description: "Tags associated with the user"},
227
- social_links: {
228
- type: :object,
229
- required: [],
230
- properties: {
231
- github: {type: :string, format: "uri", description: "GitHub profile URL"},
232
- mastodon: {type: :string, format: "uri", description: "Mastodon profile URL"}
233
- },
234
- description: "Some social networks"
235
- }
224
+ "role" => {
225
+ "type" => "string",
226
+ "description" => "Role of the user",
227
+ "enum" => ["member", "manager"],
228
+ "default" => "member"
229
+ },
230
+ "profile_details" => {"type" => "object",
231
+ "required" => [],
232
+ "properties" => {
233
+ "bio" => {"type" => "string", "description" => "Short biography of the user"},
234
+ "hobbies" => {"type" => "array", "items" => {"type" => "string"}, "description" => "Tags associated with the user"},
235
+ "social_links" => {
236
+ "type" => "object",
237
+ "required" => [],
238
+ "properties" => {
239
+ "github" => {"type" => "string", "format" => "uri", "description" => "GitHub profile URL"},
240
+ "mastodon" => {"type" => "string", "format" => "uri", "description" => "Mastodon profile URL"}
241
+ },
242
+ "description" => "Some social networks"}
236
243
  }
237
244
  }
238
245
  },
239
- additionalProperties: false
246
+ "additionalProperties" => false
240
247
  }
241
248
  ```
242
249
 
243
250
  You can also validate it to ensure it meets the JSON Schema standards:
244
251
 
245
252
  ```ruby
246
- UserCreateRequest.validate_schema(version: "2025-06") # => true/false
253
+ UserCreateRequest.valid_schema?(version: "2025-06") # => true/false
254
+ UserCreateRequest.validate_schema(version: "2025-06") # => Array of errors or empty array if valid
247
255
  ```
248
256
 
249
257
  ## Core Features
@@ -268,6 +276,61 @@ The JSON schema can be used for both validation of incoming parameters and for g
268
276
  - `schema_options`: Allows you to set additional options for the JSON Schema, such as `additional_properties` for request or per version. All fields (except `reference`) can be defined with options like `required`, `format`, `min_lenght`, `max_length`, etc. all in snake case.
269
277
  - `with_options`: Allows you to define multiple fields with the same options, reducing repetition.
270
278
 
279
+ #### Custom Field Types
280
+
281
+ You can define custom field types that can be used in `field` and `array` in the configuration.
282
+
283
+ ```ruby
284
+ Verquest.configure do |config|
285
+ config.custom_field_types = {
286
+ email: {
287
+ type: "string",
288
+ schema_options: {format: "email"}
289
+ },
290
+ uuid: {
291
+ type: "string",
292
+ schema_options: {format: "uuid"}
293
+ }
294
+ }
295
+ end
296
+ ```
297
+
298
+ Then you can use it in your request:
299
+ ```ruby
300
+ class EmailRequest < Verquest::Base
301
+ description "User Create Request"
302
+ schema_options additional_properties: false
303
+
304
+ version "2025-06" do
305
+ field :email, type: :email
306
+ array :uuids, type: :uuid
307
+ end
308
+ end
309
+ ```
310
+
311
+ `EmailRequest.to_schema(version: "2025-06")` will then generate the following JSON Schema:
312
+ ```ruby
313
+ {
314
+ "type" => "object",
315
+ "description" => "User Create Request",
316
+ "required" => ["email"],
317
+ "properties" => {
318
+ "email" => {
319
+ "type" => "string",
320
+ "format" => "email"
321
+ },
322
+ "uuids" => {
323
+ "type" => "array",
324
+ "items" => {
325
+ "type" => "string",
326
+ "format" => "uuid"
327
+ }
328
+ }
329
+ },
330
+ "additionalProperties" => false
331
+ }
332
+ ```
333
+
271
334
  ### Versioning
272
335
 
273
336
  Verquest allows you to define multiple versions of your API requests, making it easy to evolve your API over time:
@@ -410,7 +473,7 @@ Verquest.configure do |config|
410
473
  config.current_version = -> { Current.api_version }
411
474
 
412
475
  # Set the JSON Schema version
413
- config.json_schema_version = :draft6 # default
476
+ config.json_schema_version = :draft2020_12 # default
414
477
 
415
478
  # Set the error handling strategy for processing params
416
479
  config.validation_error_handling = :raise # default, can be set also to :result
@@ -425,7 +488,7 @@ end
425
488
 
426
489
  ## Documentation
427
490
 
428
- For detailed documentation, please visit the [YARD documentation](https://www.rubydoc.info/gems/verquest).
491
+ For detailed documentation, please visit the [YARD documentation](https://www.rubydoc.info/gems/verquest/0.4.0/).
429
492
 
430
493
  ## Development
431
494
 
@@ -64,7 +64,7 @@ module Verquest
64
64
  instance_exec(&block)
65
65
  ensure
66
66
  version.description ||= versions.description
67
- version.schema_options = versions.schema_options.merge(version.schema_options)
67
+ version.schema_options = versions.schema_options.merge(version.schema_options).transform_keys(&:to_s)
68
68
  version.prepare
69
69
  end
70
70
 
@@ -12,7 +12,8 @@ module Verquest
12
12
  # @param version [String, nil] Specific version to use, defaults to configuration setting
13
13
  # @param validate [Boolean, nil] Whether to validate the params, defaults to configuration setting
14
14
  # @param remove_extra_root_keys [Boolean, nil] Whether to remove extra keys at the root level, defaults to configuration setting
15
- # @return [Verquest::Result] Success result with mapped params or failure result with validation errors
15
+ # @return [Verquest::Result, Hash, Exception] When validation_error_handling is :result, returns a Success result with mapped params or Failure result with validation errors.
16
+ # When validation_error_handling is :raise, returns mapped params directly or raises InvalidParamsError with validation errors.
16
17
  def process(params, version: nil, validate: nil, remove_extra_root_keys: nil)
17
18
  validate = Verquest.configuration.validate_params if validate.nil?
18
19
  remove_extra_root_keys = Verquest.configuration.remove_extra_root_keys if remove_extra_root_keys.nil?
@@ -23,7 +24,7 @@ module Verquest
23
24
  params = params.to_unsafe_h if params.respond_to?(:to_unsafe_h)
24
25
  params = params.slice(*version_class.properties.keys) if remove_extra_root_keys
25
26
 
26
- if validate && (validation_result = version_class.validate_params(params: params, component_reference: to_ref, remove_extra_root_keys: remove_extra_root_keys)) && validation_result.any?
27
+ if validate && (validation_result = version_class.validate_params(params: params)) && validation_result.any?
27
28
  case Verquest.configuration.validation_error_handling
28
29
  when :raise
29
30
  raise InvalidParamsError.new("Validation failed", errors: validation_result)
@@ -59,7 +60,7 @@ module Verquest
59
60
  version = resolve(version)
60
61
 
61
62
  if property
62
- version.validation_schema[:properties][property]
63
+ version.validation_schema["properties"][property.to_s]
63
64
  else
64
65
  version.validation_schema
65
66
  end
@@ -69,6 +70,19 @@ module Verquest
69
70
  #
70
71
  # @param version [String, nil] Specific version to use, defaults to configuration setting
71
72
  # @return [Boolean] True if schema is valid
73
+ def valid_schema?(version: nil)
74
+ resolve(version).valid_schema?
75
+ end
76
+
77
+ # Validates the schema against the metaschema and returns detailed validation errors
78
+ #
79
+ # This method validates the schema against the configured JSON Schema metaschema
80
+ # and returns detailed validation errors if any are found. It's useful for debugging
81
+ # schema issues during development and testing.
82
+ #
83
+ # @param version [String, nil] Specific version to use, defaults to configuration setting
84
+ # @return [Array<Hash>] An array of validation error details, empty if schema is valid
85
+ # @see #valid_schema?
72
86
  def validate_schema(version: nil)
73
87
  resolve(version).validate_schema
74
88
  end
@@ -76,7 +90,7 @@ module Verquest
76
90
  # Returns the mapping for a specific version or property
77
91
  #
78
92
  # @param version [String, nil] Specific version to use, defaults to configuration setting
79
- # @param property [Symbol, nil] Specific property to retrieve mapping for
93
+ # @param property [String, Symbol, nil] Specific property to retrieve mapping for
80
94
  # @return [Hash] The mapping configuration
81
95
  def mapping(version: nil, property: nil)
82
96
  version = resolve(version)
@@ -90,7 +104,7 @@ module Verquest
90
104
 
91
105
  # Returns the JSON reference for the request or a specific property
92
106
  #
93
- # @param property [Symbol, nil] Specific property to retrieve reference for
107
+ # @param property [String, Symbol, nil] Specific property to retrieve reference for
94
108
  # @return [String] The JSON reference for the request or property
95
109
  def to_ref(property: nil)
96
110
  base = "#/components/schemas/#{component_name}"
@@ -11,13 +11,35 @@ module Verquest
11
11
  # config.current_version = -> { Current.api_version }
12
12
  # end
13
13
  class Configuration
14
+ include Base::HelperClassMethods
15
+
16
+ # Mapping of supported JSON Schema versions to their implementation classes
17
+ #
18
+ # This constant maps the symbolic names of JSON Schema versions to their
19
+ # corresponding JSONSchemer implementation classes. These are used for schema
20
+ # validation and generation based on the configured schema version.
21
+ #
22
+ # @example Accessing a schema implementation
23
+ # schema_class = Verquest::Configuration::SCHEMAS[:draft2020_12]
24
+ #
25
+ # @return [Hash<Symbol, Class>] A frozen hash mapping schema version names to implementation classes
26
+ SCHEMAS = {
27
+ draft4: JSONSchemer::Draft4,
28
+ draft6: JSONSchemer::Draft6,
29
+ draft7: JSONSchemer::Draft7,
30
+ draft2019_09: JSONSchemer::Draft201909,
31
+ draft2020_12: JSONSchemer::Draft202012,
32
+ openapi30: JSONSchemer::OpenAPI30,
33
+ openapi31: JSONSchemer::OpenAPI31
34
+ }.freeze
35
+
14
36
  # @!attribute [rw] validate_params
15
37
  # Controls whether parameters are automatically validated against the schema
16
38
  # @return [Boolean] true if validation is enabled, false otherwise
17
39
  #
18
40
  # @!attribute [rw] json_schema_version
19
- # The JSON Schema draft version to use for validation and schema generation (see the json-schema gem)
20
- # @return [Symbol] The JSON Schema version (e.g., :draft4, :draft5)
41
+ # The JSON Schema draft version to use for validation and schema generation (see Configuration::SCHEMAS)
42
+ # @return [Symbol] The JSON Schema version (e.g., :draft2020_12, :draft2019_09, :draft7)
21
43
  #
22
44
  # @!attribute [rw] validation_error_handling
23
45
  # Controls how errors during parameter processing are handled
@@ -26,7 +48,11 @@ module Verquest
26
48
  # @!attribute [rw] remove_extra_root_keys
27
49
  # Controls if extra root keys not defined in the schema should be removed from the parameters
28
50
  # @return [Boolean] true if extra keys should be removed, false otherwise
29
- attr_accessor :validate_params, :json_schema_version, :validation_error_handling, :remove_extra_root_keys
51
+ #
52
+ # @!attribute [rw] insert_property_defaults
53
+ # Controls whether default values defined in property schemas should be inserted when not provided during validation
54
+ # @return [Boolean] true if default values should be inserted, false otherwise
55
+ attr_accessor :validate_params, :json_schema_version, :validation_error_handling, :remove_extra_root_keys, :insert_property_defaults
30
56
 
31
57
  # @!attribute [r] current_version
32
58
  # A callable object that returns the current API version to use when not explicitly specified
@@ -35,17 +61,23 @@ module Verquest
35
61
  # @!attribute [r] version_resolver
36
62
  # The resolver used to map version strings/identifiers to version objects
37
63
  # @return [#call] An object that responds to `call` for resolving versions
38
- attr_reader :current_version, :version_resolver
64
+ #
65
+ # @!attribute [r] custom_field_types
66
+ # Custom field types to extend the standard set of field types
67
+ # @return [Hash<Symbol, Hash>] Hash mapping field type names to their configuration
68
+ attr_reader :current_version, :version_resolver, :custom_field_types
39
69
 
40
70
  # Initialize a new Configuration with default values
41
71
  #
42
72
  # @return [Configuration] A new configuration instance with default settings
43
73
  def initialize
44
74
  @validate_params = true
45
- @json_schema_version = :draft6
75
+ @json_schema_version = :draft2020_12
46
76
  @validation_error_handling = :raise # or :result
47
77
  @remove_extra_root_keys = true
48
78
  @version_resolver = VersionResolver
79
+ @insert_property_defaults = true
80
+ @custom_field_types = {}
49
81
  end
50
82
 
51
83
  # Sets the current version strategy using a callable object
@@ -69,5 +101,53 @@ module Verquest
69
101
 
70
102
  @version_resolver = version_resolver
71
103
  end
104
+
105
+ # Sets the custom field types
106
+ #
107
+ # This method allows defining custom field types beyond the default ones.
108
+ # Custom field types can be used to extend validation with specific formats
109
+ # or patterns. Each custom field type should include a base type and optional
110
+ # schema validation options.
111
+ #
112
+ # @example Adding a phone number field type
113
+ # config.custom_field_types = {
114
+ # email: {
115
+ # type: "string",
116
+ # schema_options: {format: "email", pattern: /\A[^@\s]+@[^@.\s]+(\.[^@.\s]+)+\z/}
117
+ # },
118
+ # uuid: {
119
+ # type: "string",
120
+ # schema_options: {format: "uuid", pattern: /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/}
121
+ # }
122
+ # }
123
+ #
124
+ # @param custom_field_types [Hash] A hash mapping field type names to their configuration
125
+ # @raise [ArgumentError] If the provided value isn't a Hash
126
+ # @return [Hash<Symbol, Hash>] The processed custom field types hash with symbolized keys
127
+ def custom_field_types=(custom_field_types)
128
+ raise ArgumentError, "Custom field types must be a Hash" unless custom_field_types.is_a?(Hash)
129
+
130
+ custom_field_types.delete_if { |k, _| Properties::Field::DEFAULT_TYPES.include?(k.to_s) }
131
+ custom_field_types.each do |_, value|
132
+ value[:schema_options] = camelize(value[:schema_options]) if value[:schema_options]
133
+ end
134
+
135
+ @custom_field_types = custom_field_types.transform_keys(&:to_sym)
136
+ end
137
+
138
+ # Gets the JSON Schema class based on the configured version
139
+ #
140
+ # @return [Class] The JSON Schema class matching the configured version
141
+ # @raise [ArgumentError] If the configured json_schema_version is not supported
142
+ def json_schema
143
+ SCHEMAS[json_schema_version] || raise(ArgumentError, "Unsupported JSON Schema version: #{json_schema_version}")
144
+ end
145
+
146
+ # Gets the JSON Schema URI for the configured schema version
147
+ #
148
+ # @return [String] The base URI for the configured JSON Schema version
149
+ def json_schema_uri
150
+ json_schema::BASE_URI.to_s
151
+ end
72
152
  end
73
153
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Verquest
4
- GEM_VERSION = "0.2.1"
4
+ GEM_VERSION = "0.4.0"
5
5
  end
@@ -6,6 +6,7 @@ module Verquest
6
6
  #
7
7
  # Represents an array data structure in the schema with specified item type.
8
8
  # Used to define arrays of scalar types (string, number, integer, boolean).
9
+ # Supports both default item types and custom field types defined in the configuration.
9
10
  #
10
11
  # @example Define an array of strings
11
12
  # array = Verquest::Properties::Array.new(
@@ -16,20 +17,34 @@ module Verquest
16
17
  class Array < Base
17
18
  # Initialize a new Array property
18
19
  #
19
- # @param name [Symbol] The name of the property
20
- # @param type [Symbol] The type of items in the array
20
+ # @param name [String, Symbol] The name of the property
21
+ # @param type [String, Symbol] The type of items in the array, can be a default type or a custom field type
21
22
  # @param map [String, nil] The mapping path for this property (nil for no explicit mapping)
22
23
  # @param required [Boolean] Whether this property is required
23
- # @param schema_options [Hash] Additional JSON schema options for this property
24
+ # @param item_schema_options [Hash] Additional JSON schema options for the array items (merged with custom type options)
25
+ # @param schema_options [Hash] Additional JSON schema options for the array property itself
26
+ # @raise [ArgumentError] If type is not one of the allowed types (default or custom)
24
27
  # @raise [ArgumentError] If attempting to map an array to the root
25
- def initialize(name:, type:, map: nil, required: false, **schema_options)
28
+ def initialize(name:, type:, map: nil, required: false, item_schema_options: {}, **schema_options)
29
+ raise ArgumentError, "Type must be one of #{allowed_types.join(", ")}" unless allowed_types.include?(type.to_s)
26
30
  raise ArgumentError, "You can not map array to the root" if map == "/"
27
31
 
28
- @name = name
29
- @type = type
32
+ if (custom_type = Verquest.configuration.custom_field_types[type.to_sym])
33
+ @type = custom_type[:type].to_s
34
+ @item_schema_options = if custom_type.key?(:schema_options)
35
+ custom_type[:schema_options].merge(item_schema_options).transform_keys(&:to_s)
36
+ else
37
+ item_schema_options.transform_keys(&:to_s)
38
+ end
39
+ else
40
+ @type = type.to_s
41
+ @item_schema_options = item_schema_options.transform_keys(&:to_s)
42
+ end
43
+
44
+ @name = name.to_s
30
45
  @map = map
31
46
  @required = required
32
- @schema_options = schema_options
47
+ @schema_options = schema_options&.transform_keys(&:to_s)
33
48
  end
34
49
 
35
50
  # Generate JSON schema definition for this array property
@@ -38,16 +53,16 @@ module Verquest
38
53
  def to_schema
39
54
  {
40
55
  name => {
41
- type: :array,
42
- items: {type: type}
56
+ "type" => "array",
57
+ "items" => {"type" => type}.merge(item_schema_options)
43
58
  }.merge(schema_options)
44
59
  }
45
60
  end
46
61
 
47
62
  # Create mapping for this array property
48
63
  #
49
- # @param key_prefix [Array<Symbol>] Prefix for the source key
50
- # @param value_prefix [Array<Symbol>] Prefix for the target value
64
+ # @param key_prefix [Array<String>] Prefix for the source key
65
+ # @param value_prefix [Array<String>] Prefix for the target value
51
66
  # @param mapping [Hash] The mapping hash to be updated
52
67
  # @param version [String, nil] The version to create mapping for, defaults to configuration setting
53
68
  # @return [Hash] The updated mapping hash
@@ -57,7 +72,14 @@ module Verquest
57
72
 
58
73
  private
59
74
 
60
- attr_reader :type, :schema_options
75
+ attr_reader :type, :schema_options, :item_schema_options
76
+
77
+ # Gets the list of allowed item types, including both default and custom types
78
+ #
79
+ # @return [Array<String>] Array of allowed item type names
80
+ def allowed_types
81
+ Verquest::Properties::Field::DEFAULT_TYPES + Verquest.configuration.custom_field_types.keys.map(&:to_s)
82
+ end
61
83
  end
62
84
  end
63
85
  end
@@ -11,7 +11,7 @@ module Verquest
11
11
  # @abstract Subclass and override {#to_schema}, {#mapping} to implement
12
12
  class Base
13
13
  # @!attribute [rw] name
14
- # @return [Symbol] The name of the property
14
+ # @return [String] The name of the property
15
15
  # @!attribute [rw] required
16
16
  # @return [Boolean] Whether this property is required
17
17
  # @!attribute [rw] map
@@ -43,7 +43,7 @@ module Verquest
43
43
 
44
44
  # Creates mapping for this property
45
45
  # @abstract
46
- # @param key_prefix [Array<Symbol>] Prefix for the source key
46
+ # @param key_prefix [Array<String>] Prefix for the source key
47
47
  # @param value_prefix [Array<String>] Prefix for the target value
48
48
  # @param mapping [Hash] The mapping hash to be updated
49
49
  # @param version [String, nil] The version to create mapping for
@@ -20,7 +20,7 @@ module Verquest
20
20
  class Collection < Base
21
21
  # Initialize a new Collection property
22
22
  #
23
- # @param name [Symbol] The name of the property
23
+ # @param name [String, Symbol] The name of the property
24
24
  # @param item [Verquest::Base, nil] Optional reference to an external schema class
25
25
  # @param required [Boolean] Whether this property is required
26
26
  # @param map [String, nil] The mapping path for this property
@@ -31,11 +31,11 @@ module Verquest
31
31
 
32
32
  @properties = {}
33
33
 
34
- @name = name
34
+ @name = name.to_s
35
35
  @item = item
36
36
  @required = required
37
37
  @map = map
38
- @schema_options = schema_options
38
+ @schema_options = schema_options&.transform_keys(&:to_s)
39
39
  end
40
40
 
41
41
  # Add a child property to this collection's item definition
@@ -60,20 +60,20 @@ module Verquest
60
60
  if has_item?
61
61
  {
62
62
  name => {
63
- type: :array,
64
- items: {
65
- "$ref": item.to_ref
63
+ "type" => "array",
64
+ "items" => {
65
+ "$ref" => item.to_ref
66
66
  }
67
67
  }.merge(schema_options)
68
68
  }
69
69
  else
70
70
  {
71
71
  name => {
72
- type: :array,
73
- items: {
74
- type: :object,
75
- required: properties.values.select(&:required).map(&:name),
76
- properties: properties.transform_values { |property| property.to_schema[property.name] }
72
+ "type" => "array",
73
+ "items" => {
74
+ "type" => "object",
75
+ "required" => properties.values.select(&:required).map(&:name),
76
+ "properties" => properties.transform_values { |property| property.to_schema[property.name] }
77
77
  }
78
78
  }.merge(schema_options)
79
79
  }
@@ -88,18 +88,18 @@ module Verquest
88
88
  if has_item?
89
89
  {
90
90
  name => {
91
- type: :array,
92
- items: item.to_validation_schema(version: version)
91
+ "type" => "array",
92
+ "items" => item.to_validation_schema(version: version)
93
93
  }.merge(schema_options)
94
94
  }
95
95
  else
96
96
  {
97
97
  name => {
98
- type: :array,
99
- items: {
100
- type: :object,
101
- required: properties.values.select(&:required).map(&:name),
102
- properties: properties.transform_values { |property| property.to_validation_schema(version: version)[property.name] }
98
+ "type" => "array",
99
+ "items" => {
100
+ "type" => "object",
101
+ "required" => properties.values.select(&:required).map(&:name),
102
+ "properties" => properties.transform_values { |property| property.to_validation_schema(version: version)[property.name] }
103
103
  }
104
104
  }.merge(schema_options)
105
105
  }
@@ -118,7 +118,7 @@ module Verquest
118
118
  # - Creates mappings for each property in the collection items
119
119
  # - Each property gets mapped with array notation and appropriate prefixes
120
120
  #
121
- # @param key_prefix [Array<Symbol>] Prefix for the source key
121
+ # @param key_prefix [Array<String>] Prefix for the source key
122
122
  # @param value_prefix [Array<String>] Prefix for the target value
123
123
  # @param mapping [Hash] The mapping hash to be updated
124
124
  # @param version [String, nil] The version to create mapping for
@@ -6,6 +6,7 @@ module Verquest
6
6
  #
7
7
  # Represents simple scalar types (string, number, integer, boolean) in the schema.
8
8
  # Used for defining basic data fields without nesting.
9
+ # Supports both default types and custom field types defined in the configuration.
9
10
  #
10
11
  # @example Define a required string field
11
12
  # field = Verquest::Properties::Field.new(
@@ -15,35 +16,46 @@ module Verquest
15
16
  # format: "email"
16
17
  # )
17
18
  class Field < Base
18
- # List of allowed field types
19
+ # List of default field types
19
20
  # @return [Array<Symbol>]
20
- ALLOWED_TYPES = %i[string number integer boolean].freeze
21
+ DEFAULT_TYPES = %w[string number integer boolean].freeze
21
22
 
22
23
  # Initialize a new Field property
23
24
  #
24
- # @param name [Symbol] The name of the property
25
- # @param type [Symbol] The data type for this field, must be one of ALLOWED_TYPES
26
- # @param required [Boolean] Whether this property is required
25
+ # @param name [String, Symbol] The name of the property
26
+ # @param type [String, Symbol] The data type for this field, can be a default type or a custom field type
27
+ # @param required [Boolean] Whether this property is required (overridden by custom type if it defines required)
27
28
  # @param map [String, nil] The mapping path for this property
28
- # @param schema_options [Hash] Additional JSON schema options for this property
29
- # @raise [ArgumentError] If type is not one of the allowed types
29
+ # @param schema_options [Hash] Additional JSON schema options for this property (merged with custom type options)
30
+ # @raise [ArgumentError] If type is not one of the allowed types (default or custom)
30
31
  # @raise [ArgumentError] If attempting to map a field to root without a name
31
32
  def initialize(name:, type:, required: false, map: nil, **schema_options)
32
- raise ArgumentError, "Type must be one of #{ALLOWED_TYPES.join(", ")}" unless ALLOWED_TYPES.include?(type)
33
+ raise ArgumentError, "Type must be one of #{allowed_types.join(", ")}" unless allowed_types.include?(type.to_s)
33
34
  raise ArgumentError, "You can not map fields to the root without a name" if map == "/"
34
35
 
35
- @name = name
36
- @type = type
37
- @required = required
36
+ if (custom_type = Verquest.configuration.custom_field_types[type.to_sym])
37
+ @type = custom_type[:type].to_s
38
+ @required = custom_type.key?(:required) ? custom_type[:required] : required
39
+ @schema_options = if custom_type.key?(:schema_options)
40
+ custom_type[:schema_options].merge(schema_options).transform_keys(&:to_s)
41
+ else
42
+ schema_options.transform_keys(&:to_s)
43
+ end
44
+ else
45
+ @type = type.to_s
46
+ @required = required
47
+ @schema_options = schema_options&.transform_keys(&:to_s)
48
+ end
49
+
50
+ @name = name.to_s
38
51
  @map = map
39
- @schema_options = schema_options
40
52
  end
41
53
 
42
54
  # Generate JSON schema definition for this field
43
55
  #
44
56
  # @return [Hash] The schema definition for this field
45
57
  def to_schema
46
- {name => {type: type}.merge(schema_options)}
58
+ {name => {"type" => type}.merge(schema_options)}
47
59
  end
48
60
 
49
61
  # Create mapping for this field property
@@ -60,6 +72,13 @@ module Verquest
60
72
  private
61
73
 
62
74
  attr_reader :type, :schema_options
75
+
76
+ # Gets the list of allowed field types, including both default and custom types
77
+ #
78
+ # @return [Array<String>] Array of allowed field type names
79
+ def allowed_types
80
+ DEFAULT_TYPES + Verquest.configuration.custom_field_types.keys.map(&:to_s)
81
+ end
63
82
  end
64
83
  end
65
84
  end
@@ -14,17 +14,17 @@ module Verquest
14
14
  class Object < Base
15
15
  # Initialize a new Object property
16
16
  #
17
- # @param name [String] The name of the property
17
+ # @param name [String, Symbol] The name of the property
18
18
  # @param required [Boolean] Whether this property is required
19
19
  # @param map [String, nil] The mapping path for this property
20
20
  # @param schema_options [Hash] Additional JSON schema options for this property
21
21
  def initialize(name:, required: false, map: nil, **schema_options)
22
22
  @properties = {}
23
23
 
24
- @name = name
24
+ @name = name.to_s
25
25
  @required = required
26
26
  @map = map
27
- @schema_options = schema_options
27
+ @schema_options = schema_options&.transform_keys(&:to_s)
28
28
  end
29
29
 
30
30
  # Add a child property to this object
@@ -32,7 +32,7 @@ module Verquest
32
32
  # @param property [Verquest::Properties::Base] The property to add to this object
33
33
  # @return [Verquest::Properties::Base] The added property
34
34
  def add(property)
35
- properties[property.name] = property
35
+ properties[property.name.to_s] = property
36
36
  end
37
37
 
38
38
  # Generate JSON schema definition for this object property
@@ -41,9 +41,9 @@ module Verquest
41
41
  def to_schema
42
42
  {
43
43
  name => {
44
- type: :object,
45
- required: properties.values.select(&:required).map(&:name),
46
- properties: properties.transform_values { |property| property.to_schema[property.name] }
44
+ "type" => "object",
45
+ "required" => properties.values.select(&:required).map(&:name),
46
+ "properties" => properties.transform_values { |property| property.to_schema[property.name] }
47
47
  }.merge(schema_options)
48
48
  }
49
49
  end
@@ -55,16 +55,16 @@ module Verquest
55
55
  def to_validation_schema(version: nil)
56
56
  {
57
57
  name => {
58
- type: :object,
59
- required: properties.values.select(&:required).map(&:name),
60
- properties: properties.transform_values { |property| property.to_validation_schema(version:)[property.name] }
58
+ "type" => "object",
59
+ "required" => properties.values.select(&:required).map(&:name),
60
+ "properties" => properties.transform_values { |property| property.to_validation_schema(version: version)[property.name] }
61
61
  }.merge(schema_options)
62
62
  }
63
63
  end
64
64
 
65
65
  # Create mapping for this object property and all its children
66
66
  #
67
- # @param key_prefix [Array<Symbol>] Prefix for the source key
67
+ # @param key_prefix [Array<String>] Prefix for the source key
68
68
  # @param value_prefix [Array<String>] Prefix for the target value
69
69
  # @param mapping [Hash] The mapping hash to be updated
70
70
  # @param version [String, nil] The version to create mapping for
@@ -23,13 +23,13 @@ module Verquest
23
23
  class Reference < Base
24
24
  # Initialize a new Reference property
25
25
  #
26
- # @param name [String] The name of the property
26
+ # @param name [String, Symbol] The name of the property
27
27
  # @param from [Class] The schema class to reference
28
28
  # @param property [Symbol, nil] Optional specific property to reference
29
29
  # @param map [String, nil] The mapping path for this property
30
30
  # @param required [Boolean] Whether this property is required
31
31
  def initialize(name:, from:, property: nil, map: nil, required: false)
32
- @name = name
32
+ @name = name.to_s
33
33
  @from = from
34
34
  @property = property
35
35
  @map = map
@@ -41,7 +41,7 @@ module Verquest
41
41
  # @return [Hash] The schema definition with a $ref pointer
42
42
  def to_schema
43
43
  {
44
- name => {"$ref": from.to_ref(property:)}
44
+ name => {"$ref" => from.to_ref(property: property)}
45
45
  }
46
46
  end
47
47
 
@@ -58,7 +58,7 @@ module Verquest
58
58
  # Create mapping for this reference property
59
59
  # This delegates to the referenced schema's mapping with appropriate key prefixing
60
60
  #
61
- # @param key_prefix [Array<Symbol>] Prefix for the source key
61
+ # @param key_prefix [Array<String>] Prefix for the source key
62
62
  # @param value_prefix [Array<String>] Prefix for the target value
63
63
  # @param mapping [Hash] The mapping hash to be updated
64
64
  # @param version [String, nil] The version to create mapping for
@@ -113,12 +113,11 @@ module Verquest
113
113
 
114
114
  case data
115
115
  when Hash
116
- # Check if the key exists (as string or symbol)
117
- return nil unless data.key?(key.to_s) || data.key?(key.to_sym)
116
+ # Only check for string keys
117
+ return nil unless data.key?(key.to_s)
118
118
 
119
- # Determine the actual key type used in the hash
120
- actual_key = data.key?(key.to_s) ? key.to_s : key.to_sym
121
- value = data[actual_key]
119
+ # Always use string keys
120
+ value = data[key.to_s]
122
121
 
123
122
  if current_part[:array] && value.is_a?(Array)
124
123
  # Process array elements and filter out nil values
@@ -153,7 +152,7 @@ module Verquest
153
152
 
154
153
  current_part = path_parts.first
155
154
  remaining_path = path_parts[1..]
156
- key = current_part[:key].to_sym # Convert key to symbol for consistent symbol keys
155
+ key = current_part[:key].to_s # Ensure key is a string for consistency
157
156
 
158
157
  if remaining_path.empty?
159
158
  # End of path, set the value directly
@@ -50,7 +50,7 @@ module Verquest
50
50
  # @param name [String] The name/identifier of the version
51
51
  # @return [Version] A new Version instance
52
52
  def initialize(name:)
53
- @name = name
53
+ @name = name.to_s
54
54
  @schema_options = {}
55
55
  @properties = {}
56
56
  end
@@ -69,7 +69,7 @@ module Verquest
69
69
  # @return [Verquest::Properties::Base] The removed property
70
70
  # @raise [PropertyNotFoundError] If the property doesn't exist
71
71
  def remove(property_name)
72
- properties.delete(property_name) || raise(PropertyNotFoundError.new("Property '#{property_name}' is not defined on '#{name}"))
72
+ properties.delete(property_name.to_s) || raise(PropertyNotFoundError.new("Property '#{property_name}' is not defined on '#{name}'"))
73
73
  end
74
74
 
75
75
  # Check if this version has a property with the given name
@@ -77,7 +77,7 @@ module Verquest
77
77
  # @param property_name [Symbol, String] The name of the property to check
78
78
  # @return [Boolean] true if the property exists, false otherwise
79
79
  def has?(property_name)
80
- properties.key?(property_name)
80
+ properties.key?(property_name.to_s)
81
81
  end
82
82
 
83
83
  # Copy properties from another version
@@ -90,7 +90,7 @@ module Verquest
90
90
  raise ArgumentError, "Expected a Verquest::Version instance" unless version.is_a?(Version)
91
91
 
92
92
  version.properties.values.each do |property|
93
- next if exclude_properties.include?(property.name)
93
+ next if exclude_properties.include?(property.name.to_sym)
94
94
 
95
95
  add(property)
96
96
  end
@@ -113,28 +113,53 @@ module Verquest
113
113
  # Validate the schema against the metaschema
114
114
  #
115
115
  # @return [Boolean] true if the schema is valid, false otherwise
116
- def validate_schema
117
- schema_name = Verquest.configuration.json_schema_version
116
+ def valid_schema?
117
+ JSONSchemer.valid_schema?(
118
+ validation_schema,
119
+ meta_schema: Verquest.configuration.json_schema_uri
120
+ )
121
+ end
118
122
 
119
- metaschema = JSON::Validator.validator_for_name(schema_name).metaschema
120
- JSON::Validator.validate(metaschema, validation_schema)
123
+ # Validate the schema against the metaschema and return detailed errors
124
+ #
125
+ # This method validates the schema against the configured JSON Schema metaschema
126
+ # and returns detailed validation errors if any are found. It uses the JSONSchemer
127
+ # library with the schema version specified in the configuration.
128
+ #
129
+ # @return [Array<Hash>] An array of validation error details, empty if schema is valid
130
+ # @see #valid_schema?
131
+ def validate_schema
132
+ JSONSchemer.validate_schema(
133
+ validation_schema,
134
+ meta_schema: Verquest.configuration.json_schema_uri
135
+ ).map do |error|
136
+ {
137
+ pointer: error["data_pointer"],
138
+ type: error["type"],
139
+ message: error["error"],
140
+ details: error["details"]
141
+ }
142
+ end
121
143
  end
122
144
 
123
145
  # Validate request parameters against the version's validation schema
124
146
  #
125
147
  # @param params [Hash] The request parameters to validate
126
- # @param component_reference [String] A reference string for components in the schema
127
- # @param remove_extra_root_keys [Boolean] Whether to remove extra keys not in the schema
128
148
  # @return [Array<Hash>] An array of validation error details, or empty if valid
129
- def validate_params(params:, component_reference:, remove_extra_root_keys:)
130
- schema_name = Verquest.configuration.json_schema_version
131
-
132
- result = JSON::Validator.fully_validate(validation_schema, params, version: schema_name, errors_as_objects: true)
133
- return result if result.empty?
134
-
135
- result.map do |error|
136
- schema = error.delete(:schema)
137
- error[:message].gsub!(schema.to_s, component_reference)
149
+ def validate_params(params:)
150
+ schemer = JSONSchemer.schema(
151
+ validation_schema,
152
+ meta_schema: Verquest.configuration.json_schema_uri,
153
+ insert_property_defaults: Verquest.configuration.insert_property_defaults
154
+ )
155
+
156
+ schemer.validate(params).map do |error|
157
+ {
158
+ pointer: error["data_pointer"],
159
+ type: error["type"],
160
+ message: error["error"],
161
+ details: error["details"]
162
+ }
138
163
  end
139
164
  end
140
165
 
@@ -147,7 +172,7 @@ module Verquest
147
172
  raise PropertyNotFoundError.new("Property '#{property}' is not defined on '#{name}'") unless has?(property)
148
173
 
149
174
  {}.tap do |mapping|
150
- properties[property].mapping(key_prefix: [], value_prefix: [], mapping: mapping, version: name)
175
+ properties[property.to_s].mapping(key_prefix: [], value_prefix: [], mapping: mapping, version: name)
151
176
  end
152
177
  end
153
178
 
@@ -170,10 +195,10 @@ module Verquest
170
195
  # @return [Hash] The frozen schema hash
171
196
  def prepare_schema
172
197
  @schema = {
173
- type: :object,
174
- description: description,
175
- required: properties.values.select(&:required).map(&:name),
176
- properties: properties.transform_values { |property| property.to_schema[property.name] }
198
+ "type" => "object",
199
+ "description" => description,
200
+ "required" => properties.values.select(&:required).map(&:name),
201
+ "properties" => properties.transform_values { |property| property.to_schema[property.name] }
177
202
  }.merge(schema_options).freeze
178
203
  end
179
204
 
@@ -185,10 +210,10 @@ module Verquest
185
210
  # @return [Hash] The frozen validation schema hash
186
211
  def prepare_validation_schema
187
212
  @validation_schema = {
188
- type: :object,
189
- description: description,
190
- required: properties.values.select(&:required).map(&:name),
191
- properties: properties.transform_values { |property| property.to_validation_schema(version: name)[property.name] }
213
+ "type" => "object",
214
+ "description" => description,
215
+ "required" => properties.values.select(&:required).map(&:name),
216
+ "properties" => properties.transform_values { |property| property.to_validation_schema(version: name)[property.name] }
192
217
  }.merge(schema_options).freeze
193
218
  end
194
219
 
data/lib/verquest.rb CHANGED
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "zeitwerk"
4
- require "json-schema"
4
+ require "json_schemer"
5
+
6
+ require_relative "verquest/gem_version"
5
7
 
6
8
  loader = Zeitwerk::Loader.new
7
9
  loader.tag = File.basename(__FILE__, ".rb")
10
+ loader.ignore("#{File.dirname(__FILE__)}/verquest/gem_version.rb")
8
11
  loader.push_dir(File.dirname(__FILE__))
9
12
  loader.setup
10
13
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: verquest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Petr Hlavicka
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-06-22 00:00:00.000000000 Z
11
+ date: 2025-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.7'
27
27
  - !ruby/object:Gem::Dependency
28
- name: json-schema
28
+ name: json_schemer
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '5.0'
33
+ version: '2.4'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '5.0'
40
+ version: '2.4'
41
41
  description: Verquest helps you version API requests, simplifying the management of
42
42
  changes, handling the mapping for internal versus external names and structures,
43
43
  validating parameters, and exporting your requests to JSON Schema components for