jbuilder-schema 2.6.7 → 2.6.9

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: 9df1e47129d5125d222c0f9b5fc39a678b1034814198d86f8ac9e661014d12e9
4
- data.tar.gz: 5724904ce752c19d7f9ef70bfca632996edc9c840fbdb9752259941f955808c7
3
+ metadata.gz: dc6b74ad43767a8a12d27263b224beb94b8a3aa4deab865e81fb2753ff367718
4
+ data.tar.gz: 03243e798c0e28991c926b52b90d448b79d7f66aa0f59b997d9fd384b5d4bd28
5
5
  SHA512:
6
- metadata.gz: 615e44bdebeb69b360ded48ae49a6450d39662cbe66c2f3061535934d0be2f7b2945a225082bb7cab2e975826c99ac724d7c98830e832be9ce58f73cc1afa23c
7
- data.tar.gz: 21b333cccdad9e9e1cde19b61f9424b9d3c7624766241185ac4046138a0da2df66de98fc7f5846c6c1c1f05ff0ac753da9f1173b6551f2884d7482a5a35d628b
6
+ metadata.gz: aaa65e842309918131ba5ae7f01f2063dcd9312505d9677a1037bab01801b8eab1865b8cd00daeca3712cbf367dd5494526939468623b4b1af706c86ac6c5751
7
+ data.tar.gz: a12318b8132a8a6edca71fcfe746dc6a757afe7a105405c17ca9ba22683ad7ebd51c4978bad692ab90c81f14d242ebf0dba016d6ff4e9fc039cc9b816ed007e5
data/README.md CHANGED
@@ -1,62 +1,58 @@
1
1
  # Jbuilder::Schema
2
2
 
3
- Generate JSON Schema compatible with OpenAPI 3 specs from Jbuilder files
3
+ Easily Generate OpenAPI 3.1 Schemas from Jbuilder Templates
4
4
 
5
- ## Installation
5
+ ## Quick Start
6
6
 
7
- In your Gemfile, put `gem "jbuilder-schema"` after Jbuilder:
7
+ ### Installation
8
+
9
+ Add this to your Gemfile:
8
10
 
9
11
  gem "jbuilder"
10
12
  gem "jbuilder-schema"
11
13
 
12
- And run:
13
-
14
- $ bundle
15
-
16
- Or install it yourself as:
14
+ Then, run `bundle` or install it manually using `gem install jbuilder-schema`.
17
15
 
18
- $ gem install jbuilder-schema
16
+ ### Generating Schemas
19
17
 
20
- ## Usage
21
-
22
- Wherever you want to generate schemas, call `Jbuilder::Schema.yaml` or `Jbuilder::Schema.json`:
18
+ Use `Jbuilder::Schema.yaml` or `Jbuilder::Schema.json` to create schemas. For example:
23
19
 
24
20
  ```ruby
25
21
  Jbuilder::Schema.yaml(@article, title: 'Article', description: 'Article in the blog', locals: { current_user: @user })
26
22
  ```
27
23
 
28
- Under the hood `Jbuilder::Schema.yaml`/`json` will use Action View's `render` method and support the same arguments.
24
+ This will render a Jbuilder template (e.g., `articles/_article.json.jbuilder`) and make `@article` available in the partial. You can also pass additional locals.
29
25
 
30
- So in the above example, the `@article`'s `to_partial_path` path is used to find and render a `articles/_article.json.jbuilder` template, and `article` is available in the partial.
26
+ ## Contents
31
27
 
32
- Additionally, we can pass any needed `locals:`.
28
+ - [Advanced Usage](#advanced-usage)
29
+ - [Rendering Specific Directories](#rendering-specific-directories)
30
+ - [Rendering Templates](#rendering-templates)
31
+ - [Output](#output)
32
+ - [Handling Arrays and Objects](#handling-arrays-and-objects)
33
+ - [Nested Partials and Arrays](#nested-partials-and-arrays)
34
+ - [Customization](#customization)
35
+ - [Titles & Descriptions](#titles--descriptions)
36
+ - [Configuration](#configuration)
37
+ - [Integration with RSwag](#integration-with-rswag)
38
+ - [Contributing](#contributing)
39
+ - [License](#license)
40
+ - [Sponsor](#open-source-development-sponsored-by)
33
41
 
34
- The `title` and `description` set the title and description of the schema — though they can also come from locale files (see *[Titles & Descriptions](#titles--descriptions)*);
42
+ ### Advanced Usage
35
43
 
36
- ### Use with a directory within app/views
44
+ #### Rendering Specific Directories
37
45
 
38
- If you have a directory within app/views where your Jbuilder templates are, you can use `renderer` to capture that along with any `locals:` common to the templates you'll render:
46
+ If your Jbuilder templates are in a specific directory, use `Jbuilder::Schema.renderer`:
39
47
 
40
48
  ```ruby
41
49
  jbuilder = Jbuilder::Schema.renderer('app/views/api/v1', locals: { current_user: @user })
42
50
  jbuilder.yaml @article, title: 'Article', description: 'Article in the blog'
43
51
  ```
44
52
 
45
- This means you don't have to write out the partial path, which gets tedious with multiple schema renders:
53
+ #### Rendering Templates
46
54
 
47
- ```ruby
48
- Jbuilder::Schema.yaml(partial: 'api/v1/articles/article', locals: { article: @article, current_user: @user }, title: 'Article', description: 'Article in the blog')
49
- ```
50
-
51
- ### Rendering a template
52
-
53
- If you're rendering a template like `app/views/articles/index.jbuilder`:
54
-
55
- ```ruby
56
- json.articles @articles, :id, :title
57
- ```
58
-
59
- You'll need to pass the relative template path in `template:` and any needed instance variables in `assigns:` like so:
55
+ For templates like `app/views/articles/index.jbuilder`, specify the template path and variables:
60
56
 
61
57
  ```ruby
62
58
  Jbuilder::Schema.yaml(template: "articles/index", assigns: { articles: Article.first(3) })
@@ -64,15 +60,16 @@ Jbuilder::Schema.yaml(template: "articles/index", assigns: { articles: Article.f
64
60
 
65
61
  ### Output
66
62
 
67
- Jbuilder::Schema automatically sets `description`, `type`, and `required` options in JSON-Schema.
63
+ Jbuilder::Schema automatically sets `description`, `type`, and `required` fields in the JSON Schema. You can *[customize](#customization)* these using the `schema:` hash.
68
64
 
69
- For example, if we have a `_article.json.jbuilder` file:
65
+ #### Example
70
66
 
71
67
  ```ruby
68
+ # _article.json.jbuilder
72
69
  json.extract! article, :id, :title, :body, :created_at
73
70
  ```
74
71
 
75
- This will produce the following:
72
+ #### Result
76
73
 
77
74
  ```yaml
78
75
  type: object
@@ -84,148 +81,261 @@ required:
84
81
  - body
85
82
  properties:
86
83
  id:
87
- description: ID of an article
88
84
  type: integer
85
+ description: Article ID
89
86
  title:
90
- description: Title of an article
91
87
  type: string
88
+ description: Article Title
92
89
  body:
93
- description: Contents of an article
94
90
  type: string
91
+ description: Article Contents
95
92
  created_at:
96
- description: Timestamp when article was created
97
- type: string
93
+ type:
94
+ - string
95
+ - "null"
98
96
  format: date-time
97
+ description: Timestamp when article was created
99
98
  ```
100
99
 
101
- ### Customization
100
+ ### Handling Arrays and Objects
101
+
102
+ The gem efficiently handles arrays and objects, including nested structures. Arrays with a single element type are straightforwardly represented, while arrays with mixed types use the `anyOf` keyword for versatility.
102
103
 
103
- #### Simple
104
+ Support of various object types like `Hash`, `Struct`, `OpenStruct`, and `ActiveRecord::Base` is also integrated. It simplifies object schemas by setting only `type` and `properties`.
104
105
 
105
- To set your own data in the generated JSON-Schema pass a `schema:` hash:
106
+ #### Example
106
107
 
107
108
  ```ruby
108
- json.id article.id, schema: { type: :number, description: "Custom ID description" }
109
- json.title article.title, schema: { minLength: 5, maxLength: 20 }
110
- json.body article.body, schema: { type: :text, maxLength: 500 }
111
- json.created_at article.created_at.strftime('%d/%m/%Y'), schema: { format: :date, pattern: /^(3[01]|[12][0-9]|0[1-9])\/(1[0-2]|0[1-9])\/[0-9]{4}$/ }
109
+ json.custom_array [1, article.user, 2, "Text", [3.14, 25.44], 5.33, [3, "Another text", {a: 4, b: "One more text"}], {c: 5, d: "And another"}, {e: 6, f: {g: 7, h: "Last Text"}}]
112
110
  ```
113
111
 
114
- This will produce the following:
112
+ #### Result
115
113
 
116
114
  ```yaml
117
- ...
118
- properties:
119
- id:
120
- description: Custom ID description
121
- type: number
122
- title:
123
- description: Title of an article
124
- type: string
125
- minLength: 5
126
- maxLength: 20
127
- body:
128
- description: Contents of an article
129
- type: string
130
- maxLength: 500
131
- created_at:
132
- description: Timestamp when article was created
133
- type: string
134
- format: date
135
- pattern: "^(3[01]|[12][0-9]|0[1-9])\/(1[0-2]|0[1-9])\/[0-9]{4}$"
115
+ properties:
116
+ custom_array:
117
+ type:
118
+ - array
119
+ - "null"
120
+ minContains: 0
121
+ contains:
122
+ anyOf:
123
+ - type: integer
124
+ - type: object
125
+ # ... ActiveRecord object properties ...
126
+ - type: string
127
+ - type: array
128
+ # All arrays are merged in one so all possible values of arrays are in one place
129
+ minContains: 0
130
+ contains:
131
+ anyOf:
132
+ - type: number
133
+ - type: integer
134
+ - type: string
135
+ - type: object
136
+ properties:
137
+ a:
138
+ type: integer
139
+ # ... description ...
140
+ b:
141
+ type: integer
142
+ # ... description ...
143
+ - type: number
144
+ - type: object
145
+ properties:
146
+ c:
147
+ type: integer
148
+ # ... description ...
149
+ d:
150
+ type: integer
151
+ # ... description ...
152
+ - type: object
153
+ properties:
154
+ e:
155
+ type: integer
156
+ # ... description ...
157
+ f:
158
+ type: object
159
+ properties:
160
+ h:
161
+ type: integer
162
+ # ... description ...
163
+ g:
164
+ type: string
165
+ # ... description ...
166
+ description: Very weird custom array
136
167
  ```
137
168
 
138
- #### Bulk
139
-
140
- You can customize output for multiple fields at once:
169
+ Each schema is unique, ensuring no duplication. Description fields are nested under parent field names for clarity.
141
170
 
142
- ```ruby
143
- json.extract! user, :id, :name, :email, schema: {id: {type: :string}, email: {type: :email, pattern: /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/}}
144
- ```
171
+ ### Nested Partials and Arrays
145
172
 
146
- ### Nested objects
173
+ Nested partials and arrays will most commonly produce reference to the related schema component.
174
+ Only if block with partial includes other fields, the inline object will be generated.
147
175
 
148
- When you have nested objects in your Jbuilder template, you have to pass it to `schema: {object: <nested_object>}` when the block starts:
176
+ #### Example
149
177
 
150
178
  ```ruby
151
- json.extract! article
152
- json.author schema: {object: article.user, object_title: "Author", object_description: "Authors are users who write articles"} do
153
- json.extract! article.user
179
+ json.author do
180
+ json.partial! "api/v1/users/user", user: article.user
181
+ end
182
+ json.comments do
183
+ json.array! article.comments, partial: "api/v1/articles/comments/comment", as: :article_comment
184
+ end
185
+ json.ratings do
186
+ json.array! article.ratings, schema: {object: article.ratings.first, title: "Rating", description: "Article Rating"} do |rating|
187
+ json.partial! "api/v1/shared/id", resource: rating
188
+ json.extract! rating, :value
189
+ end
154
190
  end
155
191
  ```
156
192
 
157
- This will help Jbuilder::Schema to process those fields right.
193
+ #### Result
194
+
195
+ ```yaml
196
+ # ... object description ...
197
+ properties:
198
+ author:
199
+ type: object
200
+ allOf:
201
+ - "$ref": "#/components/schemas/User"
202
+ description: User
203
+ comments:
204
+ type: array
205
+ items:
206
+ - "$ref": "#/components/schemas/Comment"
207
+ description: Comments
208
+ ratings:
209
+ type: array
210
+ items:
211
+ type: object
212
+ title: Rating
213
+ description: Article Rating
214
+ required:
215
+ - id
216
+ - value
217
+ properties:
218
+ id:
219
+ type: integer
220
+ description: Rating ID
221
+ public_id:
222
+ type:
223
+ - string
224
+ - "null"
225
+ description: Rating Public ID
226
+ value:
227
+ type: integer
228
+ description: Rating Value
229
+ description: Article Ratings
230
+ ```
158
231
 
159
- ### Collections
232
+ Reference names are taken from `:as` option or first of the `locals:`.
160
233
 
161
- If an object or an array of objects is generated in template, either in root or in some field through Jbuilder partials, JSON-Schema `$ref` is generated pointing to object with the same name as partial. By default those schemas should appear in `"#/components/schemas/"`.
234
+ The path to component schemas can be configured with `components_path` variable, which defaults to `components/schemas`. See *[Configuration](#configuration)* for more info.
162
235
 
163
- For example, if we have:
236
+ ### Customization
237
+
238
+ Customize individual or multiple fields at once using the `schema:` attribute.
239
+ For nested objects and collections, use the `schema: {object: <nested_object>}` format.
240
+
241
+ #### Example
164
242
 
165
243
  ```ruby
166
- json.user do
167
- json.partial! 'api/v1/users/user', user: user
168
- end
244
+ json.id article.id, schema: { type: :number, description: "Custom ID description" }
245
+ json.title article.title, schema: { minLength: 5, maxLength: 20 }
246
+ json.contents article.body, schema: { type: :text, maxLength: 500, required: true }
247
+ json.created_at article.created_at.strftime('%d/%m/%Y'), schema: { format: :date, pattern: /^(3[01]|[12][0-9]|0[1-9])\/(1[0-2]|0[1-9])\/[0-9]{4}$/ }
169
248
 
170
- json.articles do
171
- json.array! user.articles, partial: "api/v1/articles/article", as: :article
249
+ json.author schema: {object: article.user, title: "Article Author", description: "The person who wrote the article", required: true} do
250
+ json.extract! article.user, :id, :name, :email, schema: {id: {type: :string}, email: {type: :email, pattern: /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/}}
172
251
  end
173
252
  ```
174
253
 
175
- The result would be:
254
+ #### Result
176
255
 
177
256
  ```yaml
178
- user:
179
- type: object
180
- $ref: #/components/schemas/user
181
- articles:
182
- type: array
183
- items:
184
- $ref: #/components/schemas/article
257
+ type: object
258
+ title: Article
259
+ description: Article in the blog
260
+ required:
261
+ - id
262
+ - title
263
+ - contents
264
+ - author
265
+ properties:
266
+ id:
267
+ type: number
268
+ description: Custom ID description
269
+ title:
270
+ type: string
271
+ minLength: 5
272
+ maxLength: 20
273
+ description: Title of an article
274
+ contents:
275
+ type: string
276
+ maxLength: 500
277
+ description: Contents of an article
278
+ created_at:
279
+ type:
280
+ - string
281
+ - "null"
282
+ format: date
283
+ pattern: "^(3[01]|[12][0-9]|0[1-9])\/(1[0-2]|0[1-9])\/[0-9]{4}$"
284
+ description: Timestamp when article was created
285
+ author:
286
+ type: object
287
+ title: Article Author
288
+ description: The person who wrote the article
289
+ required:
290
+ - id
291
+ - name
292
+ - email
293
+ properties:
294
+ id:
295
+ type: string
296
+ description: User ID
297
+ name:
298
+ type: string
299
+ description: User Name
300
+ email:
301
+ type: email
302
+ pattern: "^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"
303
+ description: User Email
185
304
  ```
186
305
 
187
- The path to component schemas can be configured with `components_path` variable, which defaults to `components/schemas`. See *[Configuration](#configuration)* for more info.
188
-
189
- ### Titles & Descriptions
306
+ #### Titles & Descriptions
190
307
 
191
- Custom titles and descriptions for objects can be specified when calling `jbuilder-schema` helper (see *[Usage](#usage)*), for fields and nested objects within `schema` attributes (see *[Customization](#simple)* and *[Nested objects](#nested-objects)*). If not set, they will be searched in locale files.
192
-
193
- Titles and descriptions for the models are supposed to be found in locale files under `<underscored_plural_model_name>.<title_name>` and `<underscored_plural_model_name>.<description_name>`, for example:
308
+ Set custom titles and descriptions directly or through locale files. For models, use `<underscored_plural_model_name>.<title_name>` and for fields, use `<underscored_plural_model_name>.fields.<field_name>.<description_name>` in locale files:
194
309
 
195
310
  ```yaml
196
311
  en:
197
312
  articles:
198
313
  title: Article
199
314
  description: The main object on the blog
200
- ```
201
-
202
- Descriptions for the fields are supposed to be found in locale files under `<underscored_plural_model_name>.fields.<field_name>.<description_name>`, for example:
203
-
204
- ```yaml
205
- en:
206
- articles:
207
315
  fields:
208
316
  title:
209
317
  description: The title of an article
210
318
  ```
211
319
 
212
- `<title_name>` and `<description_name>` can be configured (see *[Configuration](#configuration)*), it defaults to `title` and `description`.
213
-
214
320
  ### Configuration
215
321
 
216
- You can configure some variables that Jbuilder::Schema uses (for example, in `config/initializers/jbuilder_schema.rb`):
322
+ Configure Jbuilder::Schema in `config/initializers/jbuilder_schema.rb`:
323
+
324
+ The `title_name` and `description_name` parameters can accept either a single string or an array of strings. This feature provides the flexibility to specify fallback keys.
217
325
 
218
326
  ```ruby
219
327
  Jbuilder::Schema.configure do |config|
220
- config.components_path = "components/schemas" # could be "definitions/schemas"
221
- config.title_name = "title" # could be "label"
222
- config.description_name = "description" # could be "heading"
328
+ config.components_path = "components/schemas" # could be "definitions/schemas"
329
+ config.title_name = "title" # could be "label", or an array to support fallbacks, like
330
+ config.description_name = %w[api_description description] # could be just string as well like "heading"
223
331
  end
224
332
  ```
225
333
 
226
- ### RSwag
334
+ With this configuration, the system will first try to find a translation for <underscored_plural_model_name>.fields.<field_name>.api_description. If it doesn't find a translation for this key, it will then attempt to find a translation for <underscored_plural_model_name>.fields.<field_name>.description.
335
+
336
+ ### Integration with RSwag
227
337
 
228
- You can use the `yaml`/`json` methods in your `swagger_helper.rb` like this:
338
+ Use `yaml`/`json` methods in your `swagger_helper.rb` for Swagger documentation:
229
339
 
230
340
  ```ruby
231
341
  RSpec.configure do |config|
@@ -246,11 +356,11 @@ end
246
356
 
247
357
  ## Contributing
248
358
 
249
- Bug reports and pull requests are welcome on GitHub at https://github.com/bullet-train-co/jbuilder-schema.
359
+ Contributions are welcome! Report bugs and submit pull requests on [GitHub](https://github.com/bullet-train-co/jbuilder-schema).
250
360
 
251
361
  ## License
252
362
 
253
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
363
+ This gem is open source under the [MIT License](https://opensource.org/licenses/MIT).
254
364
 
255
365
  ## Open-source development sponsored by:
256
366
 
@@ -30,21 +30,39 @@ class Jbuilder::Schema
30
30
  end
31
31
 
32
32
  def title
33
- super || translate(Jbuilder::Schema.title_name)
33
+ super || translate(title_keys)
34
34
  end
35
35
 
36
36
  def description
37
- super || translate(Jbuilder::Schema.description_name)
37
+ super || translate(description_keys)
38
38
  end
39
39
 
40
- def translate_field(key)
41
- translate("fields.#{key}.#{Jbuilder::Schema.description_name}")
40
+ def translate_title(key)
41
+ translate(title_keys.map { |k| "fields.#{key}.#{k}" })
42
+ end
43
+
44
+ def translate_description(key)
45
+ translate(description_keys.map { |k| "fields.#{key}.#{k}" })
42
46
  end
43
47
 
44
48
  private
45
49
 
46
- def translate(key)
47
- I18n.t(key, scope: @scope ||= object&.class&.name&.underscore&.pluralize)
50
+ def translate(keys)
51
+ keys.each do |key|
52
+ translation = I18n.t(key, scope: @scope ||= object&.class&.name&.underscore&.pluralize, default: nil)
53
+ return translation if translation.present?
54
+ end
55
+ # FIXME: This produces `addresses/countries` for namespaced models.
56
+ # Should be probably `addresses.countries`
57
+ I18n.t(keys.first, scope: @scope ||= object&.class&.model_name&.collection)
58
+ end
59
+
60
+ def title_keys
61
+ Array(Jbuilder::Schema.title_name)
62
+ end
63
+
64
+ def description_keys
65
+ Array(Jbuilder::Schema.description_name)
48
66
  end
49
67
  end
50
68
 
@@ -84,6 +102,7 @@ class Jbuilder::Schema
84
102
 
85
103
  def set!(key, value = BLANK, *args, schema: nil, **options, &block)
86
104
  old_configuration, @configuration = @configuration, Configuration.build(**schema) if schema&.dig(:object)
105
+ _required << key if schema&.delete(:required) == true
87
106
  @within_block = _within_block?(&block)
88
107
 
89
108
  _with_schema_overrides(key => schema) do
@@ -188,16 +207,18 @@ class Jbuilder::Schema
188
207
  }
189
208
  end
190
209
 
191
- def _set_description(key, value)
192
- if !value.key?(:description) && @configuration.object
193
- value[:description] = @configuration.translate_field(key)
194
- end
210
+ def _set_title_and_description(key, value)
211
+ overrides = @schema_overrides&.dig(key)&.to_h || {}
212
+ return unless overrides.any? || @configuration.object
213
+
214
+ value[:title] ||= overrides[:title] if overrides.key?(:title)
215
+ value[:description] ||= overrides[:description] || @configuration.translate_description(key)
195
216
  end
196
217
 
197
- def _set_ref(part, array: false)
198
- ref = {"$ref": "#/#{::Jbuilder::Schema.components_path}/#{part.split("/").last}"}
218
+ def _set_ref(object, **options)
219
+ ref = {"$ref": "#/#{::Jbuilder::Schema.components_path}/#{object.split("/").last}"}
199
220
 
200
- if array
221
+ if options[:array]
201
222
  _attributes.merge! type: :array, items: ref
202
223
  else
203
224
  _attributes.merge! type: :object, allOf: [ref]
@@ -209,6 +230,10 @@ class Jbuilder::Schema
209
230
  @attributes
210
231
  end
211
232
 
233
+ def _required
234
+ @required_keys ||= []
235
+ end
236
+
212
237
  FORMATS = {::DateTime => "date-time", ::ActiveSupport::TimeWithZone => "date-time", ::Date => "date", ::Time => "time"}
213
238
 
214
239
  def _schema(key, value, **options)
@@ -248,7 +273,7 @@ class Jbuilder::Schema
248
273
  options[:enum] = defined_enum.keys
249
274
  end
250
275
 
251
- _set_description key, options unless within_array
276
+ _set_title_and_description key, options unless within_array
252
277
  options
253
278
  end
254
279
 
@@ -281,7 +306,7 @@ class Jbuilder::Schema
281
306
  def _set_value(key, value)
282
307
  value = _value(value)
283
308
  value = _schema(key, value) unless value.is_a?(::Hash) && (value.key?(:type) || value.key?(:allOf)) # rubocop:disable Style/UnlessLogicalOperators
284
- _set_description(key, value)
309
+ _set_title_and_description(key, value)
285
310
  super
286
311
  end
287
312
 
@@ -296,10 +321,20 @@ class Jbuilder::Schema
296
321
  end
297
322
 
298
323
  def _required!(keys)
299
- presence_validated_attributes = @configuration.object&.class.try(:validators).to_a.flat_map { _1.attributes if _1.is_a?(::ActiveRecord::Validations::PresenceValidator) }
324
+ presence_validated_attributes = @configuration.object&.class.try(:validators).to_a.flat_map { _1.attributes if _1.is_a?(::ActiveRecord::Validations::PresenceValidator) } + _required
300
325
  keys & [_key(:id), *presence_validated_attributes.flat_map { [_key(_1), _key("#{_1}_id")] }]
301
326
  end
302
327
 
328
+ def _within_block?(&block)
329
+ block.present? && _one_line?(block.source)
330
+ end
331
+
332
+ def _one_line?(text)
333
+ text = text.gsub("{", " do\n").gsub("}", "\nend").tr(";", "\n")
334
+ lines = text.lines[1..-2].reject { |line| line.strip.empty? || !line.strip.start_with?("json.") }
335
+ lines.size == 1
336
+ end
337
+
303
338
  ###
304
339
  # Jbuilder methods
305
340
  ###
@@ -317,15 +352,5 @@ class Jbuilder::Schema
317
352
 
318
353
  _merge_values(current_value, value)
319
354
  end
320
-
321
- def _within_block?(&block)
322
- block.present? && _one_line?(block.source)
323
- end
324
-
325
- def _one_line?(text)
326
- text = text.gsub("{", " do\n").gsub("}", "\nend").tr(";", "\n")
327
- lines = text.lines[1..-2].reject { |line| line.strip.empty? || line.strip.start_with?("#") }
328
- lines.size == 1
329
- end
330
355
  end
331
356
  end
@@ -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.7"
4
+ JBUILDER_SCHEMA_VERSION = "2.6.9"
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.7
4
+ version: 2.6.9
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-12-04 00:00:00.000000000 Z
11
+ date: 2024-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jbuilder
@@ -89,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
89
  - !ruby/object:Gem::Version
90
90
  version: '0'
91
91
  requirements: []
92
- rubygems_version: 3.4.10
92
+ rubygems_version: 3.5.6
93
93
  signing_key:
94
94
  specification_version: 4
95
95
  summary: Generate JSON Schema from Jbuilder files