jbuilder-schema 2.6.1 → 2.6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3739c249efa5efeb070fb651dc9ae83cd6421078272997b34be154c5680a24a9
4
- data.tar.gz: 18523b00d2de89fcf36dcb9306826985dad2d9bc72845cdf5c53a74536978bc1
3
+ metadata.gz: 3ece2220807094bf6da825da24512a4dabd0ce985aa935a16e9247c0e5d4c70e
4
+ data.tar.gz: f04dc67915f12690c7eca1efc2357f915351584061a6b0ece6598326606b0bbf
5
5
  SHA512:
6
- metadata.gz: 24128255cc7873cdf4929ab24bd9f46819fe673cc5bf9c9a2cd9ec161e0a02b8910cb136d6e5410dd8fc9826679dd52d5a7f77ef99111a529bbe428bcc1c8361
7
- data.tar.gz: 886edbbc3c763fea1fd312bb682b43884d8d8036d0de74245cef418bae81bbd1954c1efa28bfcaaff7c6a5c2a9d754fd5c9bc5f28dc004f945f9af7212f5eb95
6
+ metadata.gz: eb350992a61f92fbaee952b0167369caf119fd2d3f2695f647e1d774974e461e01e6a9cd1b7d5d4da2c19abe0658f8a74b601bedeff7d4e78de8365a6c61b02b
7
+ data.tar.gz: c9582ca4c80ba75106468c8b806cc443be3ee54a630afaa786524d249a4ef8d8bc5eeaef1f1beebb2b00c32e739cfe23be7734695cfff04a51f95de326a7fbd4
@@ -117,8 +117,10 @@ class Jbuilder::Schema
117
117
  # Better would be not to set it if it's not needed, but I couldn't figure how,
118
118
  # as we have array of separate object partials hare, so each one of them would legally have allOf key.
119
119
  items = _scope { super(collection, *args, &block) }
120
- items = items[:allOf].first if items.key?(:allOf)
121
- items = _object(items, _required!(items.keys)) unless items.key?(:$ref) || items.key?(:object)
120
+ if items.is_a?(::Hash)
121
+ items = items[:allOf].first if items.key?(:allOf)
122
+ items = _object(items, _required!(items.keys)) unless items.key?(:$ref) || items.key?(:object)
123
+ end
122
124
  _attributes.merge! type: :array, items: items
123
125
  end
124
126
  end
@@ -210,29 +212,70 @@ class Jbuilder::Schema
210
212
  FORMATS = {::DateTime => "date-time", ::ActiveSupport::TimeWithZone => "date-time", ::Date => "date", ::Time => "time"}
211
213
 
212
214
  def _schema(key, value, **options)
215
+ within_array = options.delete(:within_array)
213
216
  options = @schema_overrides&.dig(key).to_h if options.empty?
214
217
 
215
218
  unless options[:type]
216
219
  options[:type] = _primitive_type value
217
220
 
218
- if options[:type] == :array && (types = value.map { _primitive_type _1 }.uniq).any?
221
+ if options[:type] == :array && (types = value.map { _primitive_type _1 }).any?
219
222
  options[:minContains] = 0
220
- options[:contains] = {type: types.many? ? types : types.first}
223
+
224
+ # Merge all arrays in one so we have all possible array items in one place
225
+ if types.include?(:array) && types.count(:array) > 1
226
+ array_indices = types.each_index.select { |i| types[i] == :array }
227
+ merged_array = array_indices.each_with_object([]) { |i, arr| arr.concat(value[i]) }
228
+ array_indices.each { |i| value[i] = merged_array }
229
+ end
230
+
231
+ options[:contains] = if types.uniq { |type| (type == :object) ? type.object_id : type }.many?
232
+ any_of = types.map.with_index do |type, index|
233
+ _fill_contains(key, value[index], type)
234
+ end
235
+
236
+ {anyOf: any_of.uniq}
237
+ else
238
+ _fill_contains(key, value[0], types.first)
239
+ end
240
+ elsif options[:type] == :object
241
+ options[:properties] = _set_properties(key, value)
221
242
  end
222
243
 
223
- format = FORMATS[value.class] and options[:format] ||= format
244
+ (format = FORMATS[value.class]) and options[:format] ||= format
224
245
  end
225
246
 
226
247
  if (klass = @configuration.object&.class) && (defined_enum = klass.try(:defined_enums)&.dig(key.to_s))
227
248
  options[:enum] = defined_enum.keys
228
249
  end
229
250
 
230
- _set_description key, options
251
+ _set_description key, options unless within_array
231
252
  options
232
253
  end
233
254
 
255
+ def _fill_contains(key, value, type)
256
+ case type
257
+ when :array
258
+ _schema(key, value, within_array: true)
259
+ when :object
260
+ value = value.attributes if value.is_a?(::ActiveRecord::Base)
261
+ {
262
+ type: type,
263
+ properties: _set_properties(key, value)
264
+ }
265
+ else
266
+ {type: type}
267
+ end
268
+ end
269
+
270
+ def _set_properties(key, value)
271
+ value.each_with_object({}) do |(attr_name, attr_value), properties|
272
+ properties[attr_name] = _schema("#{key}.#{attr_name}", attr_value)
273
+ end
274
+ end
275
+
234
276
  def _primitive_type(value)
235
277
  case value
278
+ when ::Hash, ::Struct, ::OpenStruct, ::ActiveRecord::Base then :object
236
279
  when ::Array then :array
237
280
  when ::Float, ::BigDecimal then :number
238
281
  when true, false then :boolean
@@ -1,4 +1,4 @@
1
1
  # We can't use the standard `Jbuilder::Schema::VERSION =` because
2
2
  # `Jbuilder` isn't a regular module namespace, but a class …which also loads Active Support.
3
3
  # So we use trickery, and assign the proper version once `jbuilder/schema.rb` is loaded.
4
- JBUILDER_SCHEMA_VERSION = "2.6.1"
4
+ JBUILDER_SCHEMA_VERSION = "2.6.3"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jbuilder-schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.1
4
+ version: 2.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuri Sidorov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-31 00:00:00.000000000 Z
11
+ date: 2023-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jbuilder