jbuilder-schema 2.6.7 → 2.6.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +228 -118
- data/lib/jbuilder/schema/template.rb +51 -26
- data/lib/jbuilder/schema/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc6b74ad43767a8a12d27263b224beb94b8a3aa4deab865e81fb2753ff367718
|
4
|
+
data.tar.gz: 03243e798c0e28991c926b52b90d448b79d7f66aa0f59b997d9fd384b5d4bd28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
3
|
+
Easily Generate OpenAPI 3.1 Schemas from Jbuilder Templates
|
4
4
|
|
5
|
-
##
|
5
|
+
## Quick Start
|
6
6
|
|
7
|
-
|
7
|
+
### Installation
|
8
|
+
|
9
|
+
Add this to your Gemfile:
|
8
10
|
|
9
11
|
gem "jbuilder"
|
10
12
|
gem "jbuilder-schema"
|
11
13
|
|
12
|
-
|
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
|
-
|
16
|
+
### Generating Schemas
|
19
17
|
|
20
|
-
|
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
|
-
|
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
|
-
|
26
|
+
## Contents
|
31
27
|
|
32
|
-
|
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
|
-
|
42
|
+
### Advanced Usage
|
35
43
|
|
36
|
-
|
44
|
+
#### Rendering Specific Directories
|
37
45
|
|
38
|
-
If
|
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
|
-
|
53
|
+
#### Rendering Templates
|
46
54
|
|
47
|
-
|
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`
|
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
|
-
|
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
|
-
|
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
|
-
|
97
|
-
|
93
|
+
type:
|
94
|
+
- string
|
95
|
+
- "null"
|
98
96
|
format: date-time
|
97
|
+
description: Timestamp when article was created
|
99
98
|
```
|
100
99
|
|
101
|
-
###
|
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
|
-
|
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
|
-
|
106
|
+
#### Example
|
106
107
|
|
107
108
|
```ruby
|
108
|
-
json.
|
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
|
-
|
112
|
+
#### Result
|
115
113
|
|
116
114
|
```yaml
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
176
|
+
#### Example
|
149
177
|
|
150
178
|
```ruby
|
151
|
-
json.
|
152
|
-
json.
|
153
|
-
|
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
|
-
|
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
|
-
|
232
|
+
Reference names are taken from `:as` option or first of the `locals:`.
|
160
233
|
|
161
|
-
|
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
|
-
|
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.
|
167
|
-
|
168
|
-
|
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.
|
171
|
-
json.
|
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
|
-
|
254
|
+
#### Result
|
176
255
|
|
177
256
|
```yaml
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
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
|
-
|
188
|
-
|
189
|
-
### Titles & Descriptions
|
306
|
+
#### Titles & Descriptions
|
190
307
|
|
191
|
-
|
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
|
-
|
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"
|
221
|
-
config.title_name = "title"
|
222
|
-
config.description_name =
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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(
|
33
|
+
super || translate(title_keys)
|
34
34
|
end
|
35
35
|
|
36
36
|
def description
|
37
|
-
super || translate(
|
37
|
+
super || translate(description_keys)
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
41
|
-
translate("fields.#{key}.#{
|
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(
|
47
|
-
|
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
|
192
|
-
|
193
|
-
|
194
|
-
|
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(
|
198
|
-
ref = {"$ref": "#/#{::Jbuilder::Schema.components_path}/#{
|
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
|
-
|
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
|
-
|
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.
|
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.
|
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:
|
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.
|
92
|
+
rubygems_version: 3.5.6
|
93
93
|
signing_key:
|
94
94
|
specification_version: 4
|
95
95
|
summary: Generate JSON Schema from Jbuilder files
|