jbuilder-schema 1.0.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,57 +1,38 @@
1
- # frozen_string_literal: true
2
-
3
- require "jbuilder/schema/template"
4
- # TODO: Find a better way to load main app's helpers:
5
- # Helpers don't work in Jbuilder itself, so no need to include them here!
6
- # ActionController::Base.all_helpers_from_path('app/helpers').each { |helper| require "./app/helpers/#{helper}_helper" }
7
-
8
- module JbuilderSchema
9
- # Here we initialize all the variables needed for template and pass them to it
10
- class Renderer
11
- # TODO: Find a better way to load main app's helpers:
12
- # Helpers don't work in Jbuilder itself, so no need to include them here!
13
- # ActionController::Base.all_helpers_from_path('app/helpers').each { |helper| include Object.const_get("::#{helper.camelize}Helper") }
14
-
15
- attr_reader :locals, :options
16
-
17
- def initialize(**options)
18
- @locals = options.delete(:locals) || {}
19
- @options = options
20
- _define_locals!
21
- end
22
-
23
- def render(source)
24
- Template.new(**options) do |json|
25
- # TODO: Get rid of 'eval'
26
- eval source.to_s # standard:disable Security/Eval
27
- end
28
- end
29
-
30
- def method_missing(method, *args)
31
- if method.to_s.end_with?("_path", "_url")
32
- method.to_s
33
- else
34
- super
35
- end
36
- end
37
-
38
- def respond_to_missing?(method_name, include_private = false)
39
- method_name.to_s.end_with?("_path", "_url") || super
40
- end
41
-
42
- private
43
-
44
- def _define_locals!
45
- locals.each do |k, v|
46
- # Setting instance variables (`@article`):
47
- instance_variable_set("@#{k}", v)
48
-
49
- # Setting local variables (`article`):
50
- # We can define method:
51
- # define_singleton_method(k) { v }
52
- # or set attr_reader on an instance, this feels better:
53
- singleton_class.instance_eval { attr_reader k }
54
- end
55
- end
1
+ require "active_support/core_ext/hash/deep_transform_values"
2
+ require_relative "template"
3
+
4
+ class Jbuilder::Schema::Renderer
5
+ @@view_renderer = ActionView::Base.with_empty_template_cache
6
+
7
+ def initialize(paths, default_locals = nil)
8
+ @view_renderer = @@view_renderer.with_view_paths(paths)
9
+ @default_locals = default_locals
10
+ end
11
+
12
+ def yaml(...)
13
+ normalize(render(...)).to_yaml
14
+ end
15
+
16
+ def json(...)
17
+ normalize(render(...)).to_json
18
+ end
19
+
20
+ def render(object = nil, title: nil, description: nil, assigns: nil, **options)
21
+ options.merge! partial: object.to_partial_path, object: object if object
22
+
23
+ options[:locals] ||= {}
24
+ options[:locals].merge! @default_locals if @default_locals
25
+ options[:locals][:__jbuilder_schema_options] = { model: object&.class, title: title, description: description }
26
+
27
+ @view_renderer.assign assigns if assigns
28
+ @view_renderer.render(options)
29
+ end
30
+
31
+ private
32
+
33
+ def normalize(schema)
34
+ schema.deep_stringify_keys
35
+ .deep_transform_values { |v| v.is_a?(Symbol) ? v.to_s : v }
36
+ .deep_transform_values { |v| v.is_a?(Regexp) ? v.source : v }
56
37
  end
57
38
  end
@@ -2,24 +2,49 @@
2
2
 
3
3
  require "jbuilder/jbuilder_template"
4
4
  require "active_support/inflections"
5
- require "active_support/core_ext/hash/deep_transform_values"
6
- require "safe_parser"
7
5
 
8
- module JbuilderSchema
9
- # Template parser class
6
+ class Jbuilder::Schema
10
7
  class Template < ::JbuilderTemplate
11
- attr_reader :attributes, :type, :models, :titles, :descriptions
8
+ attr_reader :attributes, :type
9
+ attr_reader :model_scope
12
10
 
13
- def initialize(*args, **options)
11
+ class Handler < ::JbuilderHandler
12
+ def self.call(template, source = nil)
13
+ super.sub("JbuilderTemplate.new(self", "Jbuilder::Schema::Template.new(self, **__jbuilder_schema_options").sub("target!", "schema!")
14
+ end
15
+ end
16
+
17
+ ::ActiveSupport.on_load :action_view do
18
+ ::ActionView::Template.register_template_handler :jbuilder, ::Jbuilder::Schema::Template::Handler
19
+ end
20
+
21
+ ModelScope = ::Struct.new(:model, :title, :description, keyword_init: true) do
22
+ def initialize(**)
23
+ super
24
+ @scope = model&.name&.underscore&.pluralize
25
+ end
26
+
27
+ def i18n_title
28
+ title || ::I18n.t(::Jbuilder::Schema.title_name, scope: @scope)
29
+ end
30
+
31
+ def i18n_description
32
+ description || ::I18n.t(::Jbuilder::Schema.description_name, scope: @scope)
33
+ end
34
+
35
+ def translate_field(key)
36
+ ::I18n.t("fields.#{key}.#{::Jbuilder::Schema.description_name}", scope: @scope)
37
+ end
38
+ end
39
+
40
+ def initialize(context, **options)
14
41
  @type = :object
15
42
  @inline_array = false
16
43
  @collection = false
17
44
 
18
- @models = [options.delete(:model)]
19
- @titles = [options.delete(:title)]
20
- @descriptions = [options.delete(:description)]
45
+ @model_scope = ModelScope.new(**options)
21
46
 
22
- super(nil, *args)
47
+ super(context)
23
48
 
24
49
  @ignore_nil = false
25
50
  end
@@ -28,7 +53,7 @@ module JbuilderSchema
28
53
  {type: type}.merge(type == :object ? _object(**attributes.merge) : attributes)
29
54
  end
30
55
 
31
- def set!(key, value = BLANK, *args, **schema_options, &block)
56
+ def set!(key, value = BLANK, *args, schema: {}, **options, &block)
32
57
  result = if block
33
58
  if !_blank?(value)
34
59
  # OBJECTS ARRAY:
@@ -40,18 +65,10 @@ module JbuilderSchema
40
65
  # json.comments { ... }
41
66
  # { "comments": ... }
42
67
  @inline_array = true
43
- if schema_options.key?(:object)
44
- models << schema_options[:object].class
45
- titles << schema_options[:object_title] || nil
46
- descriptions << schema_options[:object_description] || nil
47
- end
48
- r = _merge_block(key) { yield self }
49
- if schema_options.key?(:object)
50
- models.pop
51
- titles.pop
52
- descriptions.pop
68
+
69
+ _with_model_scope(**schema) do
70
+ _merge_block(key) { yield self }
53
71
  end
54
- r
55
72
  end
56
73
  elsif args.empty?
57
74
  if ::Jbuilder === value
@@ -59,7 +76,7 @@ module JbuilderSchema
59
76
  # json.age 32
60
77
  # json.person another_jbuilder
61
78
  # { "age": 32, "person": { ... }
62
- _schema(key, _format_keys(value.attributes!), **schema_options)
79
+ _schema(key, _format_keys(value.attributes!), **schema)
63
80
  elsif _is_collection_array?(value)
64
81
  # ATTRIBUTE2:
65
82
  _scope { array! value }
@@ -67,7 +84,7 @@ module JbuilderSchema
67
84
  else
68
85
  # json.age 32
69
86
  # { "age": 32 }
70
- _schema(key, _format_keys(value), **schema_options)
87
+ _schema(key, _format_keys(value), **schema)
71
88
  end
72
89
  elsif _is_collection?(value)
73
90
  # COLLECTION:
@@ -77,46 +94,33 @@ module JbuilderSchema
77
94
  @collection = true
78
95
 
79
96
  _scope { array! value, *args }
80
- elsif schema_options.key?(:object)
97
+ else
81
98
  # EXTRACT!:
82
99
  # json.author @article.creator, :name, :email_address
83
100
  # { "author": { "name": "David", "email_address": "david@loudthinking.com" } }
84
-
85
- models << schema_options.delete(:object).class
86
- titles << schema_options.delete(:object_title) || nil
87
- descriptions << schema_options.delete(:object_description) || nil
88
- r = _merge_block(key) { extract! value, *args, **schema_options }
89
- models.pop
90
- titles.pop
91
- descriptions.pop
92
- r
93
- else
94
- _merge_block(key) { extract! value, *args, **schema_options }
101
+ _with_model_scope(**schema) do
102
+ _merge_block(key) { extract! value, *args, schema: schema }
103
+ end
95
104
  end
96
105
 
97
- result = _set_description key, result if models.any?
106
+ result = _set_description key, result if model_scope.model
98
107
  _set_value key, result
99
108
  end
100
109
 
101
- def extract!(object, *attributes, **schema_options)
102
- schema_options = schema_options[:schema] if schema_options.key?(:schema)
103
-
110
+ def extract!(object, *attributes, schema: {})
104
111
  if ::Hash === object
105
- _extract_hash_values(object, attributes, **schema_options)
112
+ _extract_hash_values(object, attributes, schema: schema)
106
113
  else
107
- _extract_method_values(object, attributes, **schema_options)
114
+ _extract_method_values(object, attributes, schema: schema)
108
115
  end
109
116
  end
110
117
 
111
- def array!(collection = [], *args, &block)
112
- args, schema_options = _args_and_schema_options(*args)
113
- options = args.first
114
-
115
- if args.one? && _partial_options?(options)
118
+ def array!(collection = [], *args, schema: {}, **options, &block)
119
+ if _partial_options?(options)
116
120
  @collection = true
117
121
  _set_ref(options[:partial].split("/").last)
118
122
  else
119
- array = _make_array(collection, *args, **schema_options, &block)
123
+ array = _make_array(collection, *args, schema: schema, &block)
120
124
 
121
125
  if @inline_array
122
126
  @attributes = {}
@@ -139,7 +143,7 @@ module JbuilderSchema
139
143
  if args.one? && _is_active_model?(args.first)
140
144
  # TODO: Find where it is being used
141
145
  _render_active_model_partial args.first
142
- elsif args.first.is_a?(Hash)
146
+ elsif args.first.is_a?(::Hash)
143
147
  _set_ref(args.first[:partial].split("/").last)
144
148
  else
145
149
  @collection = true if args[1].key?(:collection)
@@ -150,10 +154,10 @@ module JbuilderSchema
150
154
  def merge!(object)
151
155
  hash_or_array = ::Jbuilder === object ? object.attributes! : object
152
156
  hash_or_array = _format_keys(hash_or_array)
153
- if hash_or_array.is_a?(Hash)
157
+ if hash_or_array.is_a?(::Hash)
154
158
  hash_or_array = hash_or_array.each_with_object({}) do |(key, value), a|
155
159
  result = _schema(key, value)
156
- result = _set_description(key, result) if models.any?
160
+ result = _set_description(key, result) if model_scope.model
157
161
  a[key] = result
158
162
  end
159
163
  end
@@ -161,169 +165,127 @@ module JbuilderSchema
161
165
  end
162
166
 
163
167
  def cache!(key = nil, **options)
164
- yield
165
- end
166
-
167
- def method_missing(*args, &block)
168
- args, schema_options = _args_and_schema_options(*args)
169
-
170
- if block
171
- set!(*args, **schema_options, &block)
172
- else
173
- set!(*args, **schema_options)
174
- end
168
+ yield # TODO: Our schema generation breaks Jbuilder's fragment caching.
175
169
  end
176
170
 
177
- def respond_to_missing?(method_name, include_private = false)
178
- super
171
+ def method_missing(*args, **options, &block) # standard:disable Style/MissingRespondToMissing
172
+ # TODO: Remove once Jbuilder passes keyword arguments along to `set!` in its `method_missing`.
173
+ set!(*args, **options, &block)
179
174
  end
180
175
 
181
176
  private
182
177
 
183
- def _object(**attrs)
184
- title = titles.last || ::I18n.t("#{models&.last&.name&.underscore&.pluralize}.#{JbuilderSchema.configuration.title_name}")
185
- description = descriptions.last || ::I18n.t("#{models&.last&.name&.underscore&.pluralize}.#{JbuilderSchema.configuration.description_name}")
178
+ def _with_model_scope(object: nil, object_title: nil, object_description: nil, **)
179
+ old_model_scope, @model_scope = @model_scope, ModelScope.new(model: object.class, title: object_title, description: object_description) if object
180
+ yield
181
+ ensure
182
+ @model_scope = old_model_scope if object
183
+ end
184
+
185
+ def _object(**attributes)
186
186
  {
187
187
  type: :object,
188
- title: title,
189
- description: description,
190
- required: _required!(**attrs),
191
- properties: attrs
188
+ title: model_scope.i18n_title,
189
+ description: model_scope.i18n_description,
190
+ required: _required!(attributes.keys),
191
+ properties: attributes
192
192
  }
193
193
  end
194
194
 
195
- def _args_and_schema_options(*args)
196
- schema_options = args.extract! { |a| a.is_a?(::Hash) && a.key?(:schema) }.first.try(:[], :schema) || {}
197
- [args, schema_options]
198
- end
199
-
200
195
  def _set_description(key, value)
201
196
  unless value.key?(:description)
202
- description = ::I18n.t("#{models.last&.name&.underscore&.pluralize}.fields.#{key}.#{JbuilderSchema.configuration.description_name}")
197
+ description = model_scope.translate_field(key)
203
198
  value = {description: description}.merge! value
204
199
  end
205
200
  value
206
201
  end
207
202
 
208
203
  def _set_ref(component)
204
+ component_path = "#/#{::Jbuilder::Schema.components_path}/#{component}"
205
+
209
206
  if @inline_array
210
207
  if @collection
211
208
  _set_value(:type, :array)
212
- _set_value(:items, {:$ref => _component_path(component)})
209
+ _set_value(:items, {:$ref => component_path})
213
210
  else
214
211
  _set_value(:type, :object)
215
- _set_value(:$ref, _component_path(component))
212
+ _set_value(:$ref, component_path)
216
213
  end
217
214
  else
218
215
  @type = :array
219
- _set_value(:items, {:$ref => _component_path(component)})
216
+ _set_value(:items, {:$ref => component_path})
220
217
  end
221
218
  end
222
219
 
223
- def _component_path(component)
224
- "#/#{JbuilderSchema.configuration.components_path}/#{component}"
225
- end
220
+ FORMATS = {::DateTime => "date-time", ::ActiveSupport::TimeWithZone => "date-time", ::Date => "date", ::Time => "time"}
226
221
 
227
222
  def _schema(key, value, **options)
228
- options.merge!(_guess_type(value)) unless options[:type]
229
- options.merge!(_set_enum(key.to_s)) if models.last&.defined_enums&.keys&.include?(key.to_s)
230
- options
231
- end
223
+ unless options[:type]
224
+ options[:type] = _primitive_type value
232
225
 
233
- def _guess_type(value)
234
- type = value.class.name&.downcase&.to_sym
226
+ if options[:type] == :array && (types = value.map { _primitive_type _1 }.uniq).any?
227
+ options[:minContains] = 0
228
+ options[:contains] = {type: types.many? ? types : types.first}
229
+ end
235
230
 
236
- case type
237
- when :datetime, :"activesupport::timewithzone"
238
- {type: :string, format: "date-time"}
239
- when :time, :date
240
- {type: :string, format: type.to_s}
241
- when :array
242
- _guess_array_types(value)
243
- else
244
- {type: _type(type)}
231
+ format = FORMATS[value.class] and options[:format] ||= format
245
232
  end
246
- end
247
233
 
248
- def _guess_array_types(array)
249
- hash = {type: :array}
250
- types = array.map { |a| _type(a.class.name&.downcase&.to_sym) }.uniq
251
-
252
- unless types.empty?
253
- hash[:contains] = {type: types.size > 1 ? types : types.first}
254
- hash[:minContains] = 0
234
+ if (model = model_scope.model) && (defined_enum = model.try(:defined_enums)&.dig(key.to_s))
235
+ options[:enum] = defined_enum.keys
255
236
  end
256
237
 
257
- hash
238
+ options
258
239
  end
259
240
 
260
- def _type(type)
241
+ def _primitive_type(type)
261
242
  case type
262
- when :float, :bigdecimal
263
- :number
264
- when :trueclass, :falseclass
265
- :boolean
266
- when :integer
267
- :integer
243
+ when ::Array then :array
244
+ when ::Float, ::BigDecimal then :number
245
+ when true, false then :boolean
246
+ when ::Integer then :integer
268
247
  else
269
248
  :string
270
249
  end
271
250
  end
272
251
 
273
- def _set_enum(key)
274
- enums = models.last&.defined_enums[key].keys
275
- {enum: enums}
276
- end
277
-
278
- def _make_array(collection, *args, **schema_options, &block)
252
+ def _make_array(collection, *args, schema: {}, &block)
279
253
  if collection.nil?
280
254
  []
281
255
  elsif block
282
256
  _map_collection(collection, &block)
283
257
  elsif args.any?
284
- _map_collection(collection) { |element| extract! element, *args, **schema_options }
258
+ _map_collection(collection) { |element| extract! element, *args, schema: schema }
285
259
  else
286
260
  _format_keys(collection.to_a)
287
261
  end
288
262
  end
289
263
 
290
264
  def _is_collection_array?(object)
291
- # TODO: Find better way to determine if all array elements are models
292
- object.is_a?(Array) && object.map { |a| _is_active_model?(a) }.uniq == [true]
265
+ object.is_a?(::Array) && object.all? { _is_active_model? _1 }
293
266
  end
294
267
 
295
- def _required!(**attrs)
296
- if Object.const_defined?('ActiveRecord')
297
- attrs.keys.select { |attribute|
298
- models.last&.validators.try(:grep, ::ActiveRecord::Validations::PresenceValidator)
299
- .flat_map(&:attributes).unshift(_key(:id))
300
- .include?(attribute.to_s.underscore.to_sym)
301
- }.uniq
302
- else
303
- attrs.keys.include?(_key(:id)) ? [_key(:id)] : []
304
- end
268
+ def _required!(keys)
269
+ presence_validated_attributes = model_scope.model.try(:validators).to_a.flat_map { _1.attributes if _1.is_a?(::ActiveRecord::Validations::PresenceValidator) }
270
+ keys & [_key(:id), *presence_validated_attributes.map { _key _1 }]
305
271
  end
306
272
 
307
273
  ###
308
274
  # Jbuilder methods
309
275
  ###
310
276
 
311
- def _key(key)
312
- @key_formatter ? @key_formatter.format(key).to_sym : key.to_sym
313
- end
314
-
315
- def _extract_hash_values(object, attributes, **schema_options)
277
+ def _extract_hash_values(object, attributes, schema:)
316
278
  attributes.each do |key|
317
- result = _schema(key, _format_keys(object.fetch(key)), **schema_options[key] || {})
318
- result = _set_description(key, result) if models.any?
279
+ result = _schema(key, _format_keys(object.fetch(key)), **schema[key] || {})
280
+ result = _set_description(key, result) if model_scope.model
319
281
  _set_value key, result
320
282
  end
321
283
  end
322
284
 
323
- def _extract_method_values(object, attributes, **schema_options)
285
+ def _extract_method_values(object, attributes, schema:)
324
286
  attributes.each do |key|
325
- result = _schema(key, _format_keys(object.public_send(key)), **schema_options[key] || {})
326
- result = _set_description(key, result) if models.any?
287
+ result = _schema(key, _format_keys(object.public_send(key)), **schema[key] || {})
288
+ result = _set_description(key, result) if model_scope.model
327
289
  _set_value key, result
328
290
  end
329
291
  end
@@ -336,25 +298,21 @@ module JbuilderSchema
336
298
  current_value = _blank? ? BLANK : @attributes.fetch(_key(key), BLANK)
337
299
  raise NullError.build(key) if current_value.nil?
338
300
 
339
- new_value = _scope { yield self }
340
- unless new_value.key?(:type) && new_value[:type] == :array || new_value.key?(:$ref)
341
- new_value_properties = new_value
342
- new_value = _object(**new_value_properties)
343
- end
344
- _merge_values(current_value, new_value)
301
+ value = _scope { yield self }
302
+ value = _object(**value) unless value.values_at("type", :type).any?(:array) || value.key?(:$ref) || value.key?("$ref")
303
+ _merge_values(current_value, value)
345
304
  end
346
305
  end
347
306
  end
348
307
 
349
308
  class Jbuilder
350
- # Monkey-patch for Jbuilder::KeyFormatter to ignore schema keys
351
- class KeyFormatter
352
- alias_method :original_format, :format
309
+ module SkipFormatting
310
+ SCHEMA_KEYS = %i[type items properties]
353
311
 
354
312
  def format(key)
355
- return key if %i[type items properties].include?(key)
356
-
357
- original_format(key)
313
+ SCHEMA_KEYS.include?(key) ? key : super
358
314
  end
359
315
  end
316
+
317
+ KeyFormatter.prepend SkipFormatting
360
318
  end
@@ -1,5 +1,4 @@
1
- # frozen_string_literal: true
2
-
3
- module JbuilderSchema
4
- VERSION = "1.0.3"
5
- end
1
+ # We can't use the standard `Jbuilder::Schema::VERSION =` because
2
+ # `Jbuilder` isn't a regular module namespace, but a class …which also loads Active Support.
3
+ # So we use trickery, and assign the proper version once `jbuilder/schema.rb` is loaded.
4
+ JBUILDER_SCHEMA_VERSION = "2.0.0"
@@ -1,12 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "jbuilder/schema/version"
4
- require "jbuilder/schema/configuration"
5
- require "jbuilder/schema/builder"
6
-
7
- # Main gem module with configuration and helper methods
8
- module JbuilderSchema
9
- def jbuilder_schema(path, **options)
10
- Builder.new(path, **options).schema!
3
+ require "active_support/core_ext/module/delegation"
4
+
5
+ class Jbuilder::Schema
6
+ VERSION = JBUILDER_SCHEMA_VERSION # See `jbuilder/schema/version.rb`
7
+
8
+ module IgnoreSchemaMeta
9
+ ::Jbuilder.prepend self
10
+
11
+ def method_missing(*args, schema: nil, **options, &block) # standard:disable Style/MissingRespondToMissing
12
+ super(*args, **options, &block)
13
+ end
14
+ end
15
+
16
+ singleton_class.alias_method :configure, :tap
17
+ singleton_class.attr_accessor :components_path, :title_name, :description_name
18
+ @components_path, @title_name, @description_name = "components/schemas", "title", "description"
19
+
20
+ autoload :Renderer, "jbuilder/schema/renderer"
21
+
22
+ def self.renderer(paths = nil, locals: nil)
23
+ if paths.nil? && locals.nil?
24
+ @renderer ||= Renderer.new("app/views")
25
+ else
26
+ Renderer.new(paths, locals)
27
+ end
11
28
  end
29
+ singleton_class.delegate :yaml, :json, :render, to: :renderer
12
30
  end
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: 1.0.3
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuri Sidorov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-15 00:00:00.000000000 Z
11
+ date: 2022-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jbuilder
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: safe_parser
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: rails
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -65,15 +51,10 @@ files:
65
51
  - LICENSE.txt
66
52
  - README.md
67
53
  - Rakefile
68
- - lib/jbuilder/jbuilder.rb
69
54
  - lib/jbuilder/schema.rb
70
- - lib/jbuilder/schema/builder.rb
71
- - lib/jbuilder/schema/configuration.rb
72
55
  - lib/jbuilder/schema/renderer.rb
73
- - lib/jbuilder/schema/resolver.rb
74
56
  - lib/jbuilder/schema/template.rb
75
57
  - lib/jbuilder/schema/version.rb
76
- - sig/jbuilder/schema.rbs
77
58
  homepage: https://github.com/bullet-train-co/jbuilder-schema
78
59
  licenses:
79
60
  - MIT
@@ -95,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
76
  - !ruby/object:Gem::Version
96
77
  version: '0'
97
78
  requirements: []
98
- rubygems_version: 3.3.16
79
+ rubygems_version: 3.3.7
99
80
  signing_key:
100
81
  specification_version: 4
101
82
  summary: Generate JSON Schema from Jbuilder files
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "jbuilder"
4
-
5
- # Patches for Jbuilder to make it ignore schema metadata
6
- class Jbuilder
7
- alias_method :original_method_missing, :method_missing
8
-
9
- def method_missing(*args, &block)
10
- args = _extract_schema_meta!(*args)
11
- original_method_missing(*args, &block)
12
- end
13
-
14
- def respond_to_missing?(method_name, include_private = false)
15
- super
16
- end
17
-
18
- private
19
-
20
- def _extract_schema_meta!(*args)
21
- args.delete_if { |a| a.is_a?(::Hash) && a.key?(:schema) }
22
- end
23
- end