grape-swagger 0.21.0 → 0.22.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +1 -1
- data/CHANGELOG.md +24 -2
- data/Gemfile +5 -0
- data/README.md +105 -3
- data/example/api/endpoints.rb +16 -16
- data/lib/grape-swagger.rb +0 -1
- data/lib/grape-swagger/doc_methods.rb +1 -0
- data/lib/grape-swagger/doc_methods/data_type.rb +15 -3
- data/lib/grape-swagger/doc_methods/extensions.rb +16 -12
- data/lib/grape-swagger/doc_methods/move_params.rb +139 -94
- data/lib/grape-swagger/doc_methods/parse_params.rb +9 -7
- data/lib/grape-swagger/endpoint.rb +36 -17
- data/lib/grape-swagger/version.rb +1 -1
- data/spec/lib/data_type_spec.rb +24 -0
- data/spec/lib/endpoint_spec.rb +13 -0
- data/spec/lib/move_params_spec.rb +124 -116
- data/spec/support/model_parsers/entity_parser.rb +8 -2
- data/spec/support/model_parsers/mock_parser.rb +10 -0
- data/spec/support/model_parsers/representable_parser.rb +7 -0
- data/spec/support/the_paths_definitions.rb +1 -2
- data/spec/swagger_v2/api_swagger_v2_definitions-models_spec.rb +2 -1
- data/spec/swagger_v2/api_swagger_v2_detail_spec.rb +1 -1
- data/spec/swagger_v2/api_swagger_v2_extensions_spec.rb +22 -1
- data/spec/swagger_v2/api_swagger_v2_global_configuration_spec.rb +4 -1
- data/spec/swagger_v2/api_swagger_v2_hash_and_array_spec.rb +60 -0
- data/spec/swagger_v2/api_swagger_v2_headers_spec.rb +14 -9
- data/spec/swagger_v2/api_swagger_v2_hide_param_spec.rb +90 -0
- data/spec/swagger_v2/api_swagger_v2_param_type_body_nested_spec.rb +185 -110
- data/spec/swagger_v2/api_swagger_v2_param_type_body_spec.rb +11 -13
- data/spec/swagger_v2/api_swagger_v2_response_spec.rb +5 -5
- data/spec/swagger_v2/endpoint_versioned_path_spec.rb +19 -18
- data/spec/swagger_v2/namespaced_api_spec.rb +20 -0
- data/spec/swagger_v2/param_multi_type_spec.rb +73 -0
- data/spec/swagger_v2/param_type_spec.rb +54 -27
- data/spec/swagger_v2/params_array_spec.rb +96 -6
- data/spec/swagger_v2/params_nested_spec.rb +2 -2
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96f5daf8e980cca96f1dc18f0a7dad2faf86b1f3
|
4
|
+
data.tar.gz: 665c50fb9409756ff95f526b2a13600a37db8a40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4e73ba96c6060cd24e22733de9160f267d72fdd9bc73f8baf76ecb6fe31ac908dab1506171ea6a9384631140ea338768fe7452513c6fbc9eb4a81ae70bc4819
|
7
|
+
data.tar.gz: 6d1a9f3df56f08ade9c36f43573a669b9a3a3c1172218cd02dc885dcee3e99897500249bcc5340b6cb4bb3dabafd098a1c529bd1ebf9e07eb50a212630409bb0
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,30 @@
|
|
8
8
|
|
9
9
|
* Your contribution here.
|
10
10
|
|
11
|
+
### 0.22.0 (July 12, 2016)
|
12
|
+
|
13
|
+
#### Features
|
14
|
+
|
15
|
+
* [#470](https://github.com/ruby-grape/grape-swagger/pull/470): Document request definitions inline - [@LeFnord](https://github.com/LeFnord).
|
16
|
+
* [#448](https://github.com/ruby-grape/grape-swagger/pull/448): Header parameters are now prepended to the parameter list - [@anakinj](https://github.com/anakinj).
|
17
|
+
* [#444](https://github.com/ruby-grape/grape-swagger/pull/444): With multi types parameter the first type is use as the documentation type - [@scauglog](https://github.com/scauglog).
|
18
|
+
* [#463](https://github.com/ruby-grape/grape-swagger/pull/463): Added 'hidden' option for parameter to be exclude from generated documentation - [@anakinj](https://github.com/anakinj).
|
19
|
+
* [#471](https://github.com/ruby-grape/grape-swagger/pull/471): Allow Security Definitions Objects to be defined - [@bendodd](https://github.com/bendodd).
|
20
|
+
|
21
|
+
#### Fixes
|
22
|
+
|
23
|
+
* [#472](https://github.com/ruby-grape/grape-swagger/pull/472): Fixes required property for request definitions - [@LeFnord](https://github.com/LeFnord).
|
24
|
+
* [#467](https://github.com/ruby-grape/grape-swagger/pull/467): Refactors moving of body params - [@LeFnord](https://github.com/LeFnord).
|
25
|
+
* [#464](https://github.com/ruby-grape/grape-swagger/pull/464): Fixes array params, sets correct type and format for items - [@LeFnord](https://github.com/LeFnord).
|
26
|
+
* [#461](https://github.com/ruby-grape/grape-swagger/pull/461): Fixes issue by adding extensions to definitions. It appeared, if for the given status code, no definition could be found - [@LeFnord](https://github.com/LeFnord).
|
27
|
+
* [#455](https://github.com/ruby-grape/grape-swagger/pull/455): Setting `type:` option as `Array[Class]` creates `array` type in JSON - [@tyspring](https://github.com/tyspring).
|
28
|
+
* [#450](https://github.com/ruby-grape/grape-swagger/pull/438): Do not add :description to definitions if :description is missing on path - [@texpert](https://github.com/texpert).
|
29
|
+
* [#447](https://github.com/ruby-grape/grape-swagger/pull/447): Version part of the url is now ignored when generating tags for endpoint - [@anakinj](https://github.com/anakinj).
|
30
|
+
* [#444](https://github.com/ruby-grape/grape-swagger//pull/444): Default value provided in the documentation hash, override the grape default [@scauglog](https://github.com/scauglog).
|
31
|
+
* [#443](https://github.com/ruby-grape/grape-swagger/issues/443): Type provided in the documentation hash, override the grape type [@scauglog](https://github.com/scauglog).
|
32
|
+
* [#454](https://github.com/ruby-grape/grape-swagger/pull/454): Include documented Hashes in documentation output - [@aschuster3](https://github.com/aschuster3).
|
33
|
+
* [#457](https://github.com/ruby-grape/grape-swagger/issues/457): Using camel case on namespace throws exception on add_swagger_documentation method - [@rayko](https://github.com/rayko/).
|
34
|
+
|
11
35
|
### 0.21.0 (June 1, 2016)
|
12
36
|
|
13
37
|
#### Features
|
@@ -15,7 +39,6 @@
|
|
15
39
|
* [#413](https://github.com/ruby-grape/grape-swagger/pull/413): Move all model parsing logic to separate gems `grape-swagger-entity` and added representable parser `grape-swagger` - [@Bugagazavr](https://github.com/Bugagazavr).
|
16
40
|
* [#434](https://github.com/ruby-grape/grape-swagger/pull/434): Add summary to the operation object generator to be more compliant with [OpenAPI v2](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#operation-object) - [@aschuster3](https://github.com/aschuster3).
|
17
41
|
* [#441](https://github.com/ruby-grape/grape-swagger/pull/441): Accepting `String`, `lambda` and `proc` for `host` and `base_path` - [@LeFnord](https://github.com/LeFnord).
|
18
|
-
* Your contribution here.
|
19
42
|
|
20
43
|
#### Fixes
|
21
44
|
|
@@ -23,7 +46,6 @@
|
|
23
46
|
* [#419](https://github.com/ruby-grape/grape-swagger/pull/419): Replaced github ref to rubygems for external gems - [@Bugagazavr](https://github.com/Bugagazavr).
|
24
47
|
* [#420](https://github.com/ruby-grape/grape-swagger/pull/420): Raise SwaggerSpec exception if swagger spec isn't satisfied, when no parser for model is registered or response model is empty - [@Bugagazavr](https://github.com/Bugagazavr).
|
25
48
|
* [#438](https://github.com/ruby-grape/grape-swagger/pull/438): Route version was missing in :options passed to PathString, so Endpoint.path_and_definitions_objects wasn't returning a versioned path when required - [@texpert](https://github.com/texpert).
|
26
|
-
* Your contribution here.
|
27
49
|
|
28
50
|
### 0.20.3 (May 9, 2016)
|
29
51
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -49,7 +49,8 @@ grape-swagger | swagger spec | grape | grape-entity | represen
|
|
49
49
|
0.11.0 | 1.2 | >= 0.16.2 | < 0.5.0 | n/a |
|
50
50
|
0.20.1 | 2.0 | >= 0.12.0 ... <= 0.14.0 | <= 0.5.1 | n/a |
|
51
51
|
0.20.3 | 2.0 | >= 0.12.0 ... ~> 0.16.2 | ~> 0.5.1 | n/a |
|
52
|
-
0.21.0
|
52
|
+
0.21.0 | 2.0 | >= 0.12.0 ... <= 0.16.2 | <= 0.5.1 | >= 2.4.1 |
|
53
|
+
0.21.1 (next) | 2.0 | >= 0.12.0 ... <= 0.16.2 | <= 0.5.1 | >= 2.4.1 |
|
53
54
|
|
54
55
|
<a name="swagger-spec" />
|
55
56
|
## Swagger-Spec
|
@@ -191,6 +192,7 @@ end
|
|
191
192
|
* [add_version](#add_version)
|
192
193
|
* [doc_version](#doc_version)
|
193
194
|
* [markdown](#markdown)
|
195
|
+
* [security_definitions](#security_definitions)
|
194
196
|
* [models](#models)
|
195
197
|
* [hide_documentation_path](#hide_documentation_path)
|
196
198
|
* [info](#info)
|
@@ -272,12 +274,24 @@ add_swagger_documentation \
|
|
272
274
|
markdown: GrapeSwagger::Markdown::RedcarpetAdapter.new
|
273
275
|
```
|
274
276
|
|
277
|
+
<a name="security_definitions" />
|
278
|
+
#### security_definitions:
|
279
|
+
Specify the [Security Definitions Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#security-definitions-object)
|
280
|
+
|
281
|
+
```ruby
|
282
|
+
add_swagger_documentation \
|
283
|
+
security_definitions: {
|
284
|
+
api_key: {
|
285
|
+
type: "apiKey",
|
286
|
+
name: "api_key",
|
287
|
+
in: "header"
|
288
|
+
}
|
289
|
+
}
|
290
|
+
```
|
275
291
|
|
276
292
|
#### *authorizations*:
|
277
293
|
This value is added to the `authorizations` key in the JSON documentation.
|
278
294
|
|
279
|
-
|
280
|
-
|
281
295
|
<a name="models" />
|
282
296
|
#### models:
|
283
297
|
A list of entities to document. Combine with the [grape-entity](https://github.com/ruby-grape/grape-entity) gem.
|
@@ -343,9 +357,14 @@ add_swagger_documentation \
|
|
343
357
|
|
344
358
|
* [Swagger Header Parameters](#headers)
|
345
359
|
* [Hiding an Endpoint](#hiding)
|
360
|
+
* [Overriding Auto-Generated Nicknames](#overriding-auto-generated-nicknames)
|
346
361
|
* [Defining an endpoint as array](#array)
|
347
362
|
* [Using an options hash](#options)
|
348
363
|
* [Specify endpoint details](#details)
|
364
|
+
* [Overriding param type](#overriding-param-type)
|
365
|
+
* [Overriding type](#overriding-type)
|
366
|
+
* [Multi types](#multi-types)
|
367
|
+
* [Hiding parameters](#hiding-parameters)
|
349
368
|
* [Response documentation](#response)
|
350
369
|
|
351
370
|
|
@@ -453,6 +472,89 @@ post :act do
|
|
453
472
|
end
|
454
473
|
```
|
455
474
|
|
475
|
+
#### Overriding type
|
476
|
+
|
477
|
+
You can override type, using the documentation hash.
|
478
|
+
|
479
|
+
```ruby
|
480
|
+
params do
|
481
|
+
requires :input, type: String, documentation: { type: 'integer' }
|
482
|
+
end
|
483
|
+
post :act do
|
484
|
+
...
|
485
|
+
end
|
486
|
+
```
|
487
|
+
|
488
|
+
```json
|
489
|
+
{
|
490
|
+
"in": "formData",
|
491
|
+
"name": "input",
|
492
|
+
"type": "integer",
|
493
|
+
"format": "int32",
|
494
|
+
"required": true
|
495
|
+
}
|
496
|
+
```
|
497
|
+
|
498
|
+
#### Array type
|
499
|
+
|
500
|
+
Array types are also supported.
|
501
|
+
|
502
|
+
```ruby
|
503
|
+
params do
|
504
|
+
requires :action_ids, type: Array[Integer]
|
505
|
+
end
|
506
|
+
post :act do
|
507
|
+
...
|
508
|
+
end
|
509
|
+
```
|
510
|
+
|
511
|
+
```json
|
512
|
+
{
|
513
|
+
"in": "formData",
|
514
|
+
"name": "action_ids",
|
515
|
+
"type": "array",
|
516
|
+
"items": {
|
517
|
+
"type": "integer"
|
518
|
+
},
|
519
|
+
"required": true
|
520
|
+
}
|
521
|
+
```
|
522
|
+
|
523
|
+
#### Multi types
|
524
|
+
|
525
|
+
By default when you set multi types, the first type is selected as swagger type
|
526
|
+
|
527
|
+
```ruby
|
528
|
+
params do
|
529
|
+
requires :action, types: [String, Integer]
|
530
|
+
end
|
531
|
+
post :act do
|
532
|
+
...
|
533
|
+
end
|
534
|
+
```
|
535
|
+
|
536
|
+
```json
|
537
|
+
{
|
538
|
+
"in": "formData",
|
539
|
+
"name": "action",
|
540
|
+
"type": "string",
|
541
|
+
"required": true
|
542
|
+
}
|
543
|
+
```
|
544
|
+
|
545
|
+
#### Hiding parameters
|
546
|
+
|
547
|
+
Exclude single optional parameter from the documentation
|
548
|
+
|
549
|
+
```ruby
|
550
|
+
params do
|
551
|
+
optional :one, documentation: { hidden: true }
|
552
|
+
optional :two, documentation: { hidden: -> { true } }
|
553
|
+
end
|
554
|
+
post :act do
|
555
|
+
...
|
556
|
+
end
|
557
|
+
```
|
456
558
|
|
457
559
|
#### Overriding the route summary
|
458
560
|
|
data/example/api/endpoints.rb
CHANGED
@@ -23,21 +23,21 @@ module Api
|
|
23
23
|
namespace :splines do
|
24
24
|
#
|
25
25
|
desc 'Get all splines',
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
is_array: true,
|
27
|
+
http_codes: [
|
28
|
+
{ code: 200, message: 'get Splines', model: Api::Entities::Splines },
|
29
|
+
{ code: 422, message: 'SplinesOutError' }
|
30
|
+
]
|
31
31
|
get do
|
32
32
|
present :items, @@splines, with: Entities::Splines
|
33
33
|
end
|
34
34
|
|
35
35
|
#
|
36
36
|
desc 'Return a spline.',
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
http_codes: [
|
38
|
+
{ code: 200, message: 'get Splines' },
|
39
|
+
{ code: 422, message: 'SplinesOutError' }
|
40
|
+
]
|
41
41
|
params do
|
42
42
|
requires :id, type: Integer, desc: 'Spline id.'
|
43
43
|
end
|
@@ -49,9 +49,9 @@ module Api
|
|
49
49
|
|
50
50
|
#
|
51
51
|
desc 'Create a spline.',
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
http_codes: [
|
53
|
+
{ code: 201, message: 'Spline created', model: Api::Entities::Splines }
|
54
|
+
]
|
55
55
|
params do
|
56
56
|
requires :spline, type: Hash do
|
57
57
|
requires :x, type: Numeric
|
@@ -73,10 +73,10 @@ module Api
|
|
73
73
|
|
74
74
|
#
|
75
75
|
desc 'Update a spline.',
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
76
|
+
http_codes: [
|
77
|
+
{ code: 200, message: 'update Splines', model: Api::Entities::Splines },
|
78
|
+
{ code: 422, message: 'SplinesOutError' }
|
79
|
+
]
|
80
80
|
params do
|
81
81
|
requires :id, type: Integer, desc: 'Spline id.'
|
82
82
|
optional :spline, type: Hash do
|
data/lib/grape-swagger.rb
CHANGED
@@ -65,7 +65,6 @@ module Grape
|
|
65
65
|
next unless route_match
|
66
66
|
resource = route_match.captures.first
|
67
67
|
next if resource.empty?
|
68
|
-
resource.downcase!
|
69
68
|
@target_class.combined_routes[resource] ||= []
|
70
69
|
next if doc_klass.hide_documentation_path && route.path.match(/#{doc_klass.mount_path}($|\/|\(\.)/)
|
71
70
|
@target_class.combined_routes[resource] << route
|
@@ -102,6 +102,7 @@ module GrapeSwagger
|
|
102
102
|
hide_documentation_path: true,
|
103
103
|
format: :json,
|
104
104
|
authorizations: nil,
|
105
|
+
security_definitions: nil,
|
105
106
|
api_documentation: { desc: 'Swagger compatible API description' },
|
106
107
|
specific_api_documentation: { desc: 'Swagger compatible API description for specific API' }
|
107
108
|
}
|
@@ -3,9 +3,10 @@ module GrapeSwagger
|
|
3
3
|
class DataType
|
4
4
|
class << self
|
5
5
|
def call(value)
|
6
|
-
raw_data_type = value[:type]
|
7
|
-
raw_data_type
|
8
|
-
raw_data_type
|
6
|
+
raw_data_type = value.is_a?(Hash) ? value[:type] : value
|
7
|
+
raw_data_type ||= 'String'
|
8
|
+
raw_data_type = parse_multi_type(raw_data_type)
|
9
|
+
|
9
10
|
case raw_data_type.to_s
|
10
11
|
when 'Boolean', 'Date', 'Integer', 'String', 'Float', 'JSON', 'Array'
|
11
12
|
raw_data_type.to_s.downcase
|
@@ -28,6 +29,17 @@ module GrapeSwagger
|
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
32
|
+
def parse_multi_type(raw_data_type)
|
33
|
+
case raw_data_type
|
34
|
+
when /\A\[.*\]\z/
|
35
|
+
raw_data_type.gsub(/[(\A\[)(\s+)(\]\z)]/, '').split(',').first
|
36
|
+
when Array
|
37
|
+
raw_data_type.first
|
38
|
+
else
|
39
|
+
raw_data_type
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
31
43
|
def parse_entity_name(model)
|
32
44
|
if model.respond_to?(:entity_name)
|
33
45
|
model.entity_name
|
@@ -4,6 +4,7 @@ module GrapeSwagger
|
|
4
4
|
class << self
|
5
5
|
def add(path, definitions, route)
|
6
6
|
@route = route
|
7
|
+
|
7
8
|
description = route.settings[:description]
|
8
9
|
add_extension_to(path[method], extension(description)) if description && extended?(description, :x)
|
9
10
|
|
@@ -20,29 +21,32 @@ module GrapeSwagger
|
|
20
21
|
def_extension = extension(settings, :x_def)
|
21
22
|
|
22
23
|
if def_extension[:x_def].is_a?(Array)
|
23
|
-
def_extension[:x_def].each
|
24
|
-
next unless extension.key?(:for)
|
25
|
-
status = extension.delete(:for)
|
26
|
-
definition = find_definition(status, path)
|
27
|
-
add_extension_to(definitions[definition], x_def: extension)
|
28
|
-
end
|
24
|
+
def_extension[:x_def].each { |extension| setup_definition(extension, path, definitions) }
|
29
25
|
else
|
30
|
-
|
31
|
-
status = def_extension[:x_def].delete(:for)
|
32
|
-
definition = find_definition(status, path)
|
33
|
-
add_extension_to(definitions[definition], def_extension)
|
26
|
+
setup_definition(def_extension[:x_def], path, definitions)
|
34
27
|
end
|
35
28
|
end
|
36
29
|
|
30
|
+
def setup_definition(def_extension, path, definitions)
|
31
|
+
return unless def_extension.key?(:for)
|
32
|
+
status = def_extension[:for]
|
33
|
+
|
34
|
+
definition = find_definition(status, path)
|
35
|
+
add_extension_to(definitions[definition], x_def: def_extension)
|
36
|
+
end
|
37
|
+
|
37
38
|
def find_definition(status, path)
|
38
39
|
response = path[method][:responses][status]
|
40
|
+
return if response.nil?
|
39
41
|
|
40
|
-
response[:schema]['$ref'].split('/').last
|
42
|
+
return response[:schema]['$ref'].split('/').last if response[:schema].key?('$ref')
|
43
|
+
return response[:schema]['items']['$ref'].split('/').last if response[:schema].key?('items')
|
41
44
|
end
|
42
45
|
|
43
46
|
def add_extension_to(part, extensions)
|
47
|
+
return if part.nil?
|
44
48
|
concatenate(extensions).each do |key, value|
|
45
|
-
part[key] = value
|
49
|
+
part[key] = value unless key.start_with?('x-for')
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
@@ -2,159 +2,204 @@ module GrapeSwagger
|
|
2
2
|
module DocMethods
|
3
3
|
class MoveParams
|
4
4
|
class << self
|
5
|
-
|
5
|
+
attr_accessor :definitions
|
6
|
+
|
7
|
+
def can_be_moved?(params, http_verb)
|
8
|
+
move_methods.include?(http_verb) && includes_body_param?(params)
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_definition(params, route, definitions)
|
6
12
|
@definitions = definitions
|
13
|
+
unify!(params)
|
7
14
|
|
8
|
-
|
9
|
-
|
10
|
-
method_object = method_definition[verb]
|
15
|
+
params_to_move = movable_params(params)
|
16
|
+
params << parent_definition_of_params(params_to_move, route)
|
11
17
|
|
12
|
-
|
13
|
-
end
|
18
|
+
params
|
14
19
|
end
|
15
20
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
private
|
22
|
+
|
23
|
+
def parent_definition_of_params(params, route)
|
24
|
+
definition_name = GrapeSwagger::DocMethods::OperationId.manipulate(parse_model(route.path))
|
25
|
+
referenced_definition = build_definition(definition_name, params, route.request_method.downcase)
|
26
|
+
definition = @definitions[referenced_definition]
|
27
|
+
|
28
|
+
move_params_to_new(definition, params)
|
29
|
+
|
30
|
+
definition[:description] = route.description if route.respond_to?(:description)
|
31
|
+
|
32
|
+
build_body_parameter(referenced_definition, definition_name)
|
33
|
+
end
|
34
|
+
|
35
|
+
def move_params_to_new(definition, params)
|
36
|
+
params, nested_params = params.partition { |x| !x[:name].include?('[') }
|
37
|
+
|
38
|
+
unless params.blank?
|
39
|
+
properties, required = build_properties(params)
|
40
|
+
add_properties_to_definition(definition, properties, required)
|
20
41
|
end
|
42
|
+
|
43
|
+
nested_properties = build_nested_properties(nested_params) unless nested_params.blank?
|
44
|
+
add_properties_to_definition(definition, nested_properties, []) unless nested_params.blank?
|
21
45
|
end
|
22
46
|
|
23
|
-
def
|
24
|
-
|
47
|
+
def build_nested_properties(params, properties = {})
|
48
|
+
property = params.bsearch { |x| x[:name].include?('[') }[:name].split('[').first
|
25
49
|
|
26
|
-
|
27
|
-
|
50
|
+
nested_params, params = params.partition { |x| x[:name].start_with?("#{property}[") }
|
51
|
+
prepare_nested_names(property, nested_params)
|
28
52
|
|
29
|
-
|
53
|
+
recursive_call(properties, property, nested_params) unless nested_params.empty?
|
54
|
+
build_nested_properties(params, properties) unless params.empty?
|
30
55
|
|
31
|
-
|
32
|
-
|
56
|
+
properties
|
57
|
+
end
|
33
58
|
|
34
|
-
|
35
|
-
|
36
|
-
|
59
|
+
def recursive_call(properties, property, nested_params)
|
60
|
+
if should_expose_as_array?(nested_params)
|
61
|
+
properties[property] = array_type
|
62
|
+
move_params_to_new(properties[property][:items], nested_params)
|
37
63
|
else
|
38
|
-
|
39
|
-
|
64
|
+
properties[property] = object_type
|
65
|
+
move_params_to_new(properties[property], nested_params)
|
40
66
|
end
|
67
|
+
end
|
41
68
|
|
42
|
-
|
69
|
+
def movable_params(params)
|
70
|
+
to_delete = params.each_with_object([]) { |x, memo| memo << x if deletable?(x) }
|
71
|
+
delete_from(params, to_delete)
|
43
72
|
|
44
|
-
|
45
|
-
path[:parameters] << build_body_parameter(response.dup, name)
|
73
|
+
to_delete
|
46
74
|
end
|
47
75
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
76
|
+
def delete_from(params, to_delete)
|
77
|
+
to_delete.each { |x| params.delete(x) }
|
78
|
+
end
|
51
79
|
|
52
|
-
|
80
|
+
def add_properties_to_definition(definition, properties, required)
|
81
|
+
if definition.key?(:items)
|
82
|
+
definition[:items][:properties].merge!(properties)
|
83
|
+
add_to_required(definition[:items], required)
|
84
|
+
else
|
85
|
+
definition[:properties].merge!(properties)
|
86
|
+
add_to_required(definition, required)
|
87
|
+
end
|
88
|
+
end
|
53
89
|
|
54
|
-
|
55
|
-
|
90
|
+
def add_to_required(definition, value)
|
91
|
+
return if value.blank?
|
56
92
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
properties[name].tap do |x|
|
61
|
-
property_keys.each do |attribute|
|
62
|
-
x[attribute] = param[attribute] unless param[attribute].nil?
|
63
|
-
end
|
64
|
-
end
|
93
|
+
definition[:required] ||= []
|
94
|
+
definition[:required].push(*value)
|
95
|
+
end
|
65
96
|
|
66
|
-
|
67
|
-
|
97
|
+
def build_properties(params)
|
98
|
+
properties = {}
|
99
|
+
required = []
|
68
100
|
|
69
|
-
|
70
|
-
end
|
101
|
+
prepare_nested_types(params) if should_expose_as_array?(params)
|
71
102
|
|
72
|
-
|
73
|
-
|
74
|
-
|
103
|
+
params.each do |param|
|
104
|
+
name = param[:name].to_sym
|
105
|
+
properties[name] = {}
|
75
106
|
|
76
|
-
|
77
|
-
|
78
|
-
nested_name = params.bsearch { |x| x[:name].include?('[') }
|
79
|
-
return if nested_name.nil?
|
107
|
+
if should_expose_as_array?([param])
|
108
|
+
prepare_nested_types([param])
|
80
109
|
|
81
|
-
|
110
|
+
properties[name][:type] = 'array'
|
111
|
+
properties[name][:items] = {}
|
112
|
+
properties[name][:items].tap do |x|
|
113
|
+
property_keys.each do |attribute|
|
114
|
+
x[attribute] = param[attribute] unless param[attribute].nil?
|
115
|
+
end
|
116
|
+
end
|
117
|
+
else
|
82
118
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
119
|
+
properties[name].tap do |x|
|
120
|
+
property_keys.each do |attribute|
|
121
|
+
x[attribute] = param[attribute] unless param[attribute].nil?
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
88
125
|
|
89
|
-
|
90
|
-
build_definition(def_name)
|
91
|
-
@definitions[def_name][:description] = "#{name} - #{nested_name}"
|
92
|
-
move_params_to_new(def_name, nested)
|
126
|
+
required << name if deletable?(param) && param[:required]
|
93
127
|
end
|
94
|
-
end
|
95
128
|
|
96
|
-
|
129
|
+
[properties, required]
|
130
|
+
end
|
97
131
|
|
98
|
-
def build_body_parameter(
|
99
|
-
|
100
|
-
|
101
|
-
body_param.tap do |x|
|
102
|
-
x[:name] = entity
|
132
|
+
def build_body_parameter(reference, name)
|
133
|
+
{}.tap do |x|
|
134
|
+
x[:name] = name
|
103
135
|
x[:in] = 'body'
|
104
136
|
x[:required] = true
|
105
|
-
x[:schema] = { '$ref' =>
|
106
|
-
x[:schema] = { '$ref' => "#/definitions/#{name}" } if name
|
137
|
+
x[:schema] = { '$ref' => "#/definitions/#{reference}" }
|
107
138
|
end
|
108
139
|
end
|
109
140
|
|
110
|
-
def build_definition(name, verb = nil)
|
111
|
-
name = "#{verb}
|
112
|
-
@definitions[name] =
|
141
|
+
def build_definition(name, params, verb = nil)
|
142
|
+
name = "#{verb}#{name}" if verb
|
143
|
+
@definitions[name] = should_expose_as_array?(params) ? array_type : object_type
|
113
144
|
|
114
145
|
name
|
115
146
|
end
|
116
147
|
|
117
|
-
def
|
118
|
-
|
119
|
-
param.tap do |x|
|
120
|
-
name = x[:name].partition('[').last.sub(']', '')
|
121
|
-
name = name.partition('[').last.sub(']', '') if name.start_with?('[')
|
122
|
-
x[:name] = name
|
123
|
-
end
|
124
|
-
end
|
148
|
+
def array_type
|
149
|
+
{ type: 'array', items: { type: 'object', properties: {} } }
|
125
150
|
end
|
126
151
|
|
127
|
-
def
|
152
|
+
def object_type
|
153
|
+
{ type: 'object', properties: {} }
|
154
|
+
end
|
155
|
+
|
156
|
+
def prepare_nested_types(params)
|
128
157
|
params.each do |param|
|
129
|
-
param[:
|
130
|
-
param[:
|
158
|
+
next unless param[:items]
|
159
|
+
param[:type] = param[:items][:type] == 'array' ? 'string' : param[:items][:type]
|
160
|
+
param[:format] = param[:items][:format] if param[:items][:format]
|
161
|
+
param.delete(:items)
|
131
162
|
end
|
132
163
|
end
|
133
164
|
|
134
|
-
def
|
135
|
-
|
165
|
+
def prepare_nested_names(property, params)
|
166
|
+
params.each { |x| x[:name] = x[:name].sub(property, '').sub('[', '').sub(']', '') }
|
136
167
|
end
|
137
168
|
|
138
|
-
def
|
139
|
-
[:
|
169
|
+
def unify!(params)
|
170
|
+
params.each { |x| x[:in] = x.delete(:param_type) if x[:param_type] }
|
171
|
+
params.each { |x| x[:in] = 'body' if x[:in] == 'formData' } if includes_body_param?(params)
|
172
|
+
end
|
173
|
+
|
174
|
+
def parse_model(ref)
|
175
|
+
parts = ref.split('/')
|
176
|
+
parts.last.include?('{') ? parts[0..-2].join('/') : parts[0..-1].join('/')
|
140
177
|
end
|
141
178
|
|
142
179
|
def property_keys
|
143
180
|
[:type, :format, :description, :minimum, :maximum, :items]
|
144
181
|
end
|
145
182
|
|
146
|
-
def
|
147
|
-
|
148
|
-
false
|
183
|
+
def deletable?(param)
|
184
|
+
param[:in] == 'body'
|
149
185
|
end
|
150
186
|
|
151
|
-
def
|
152
|
-
|
187
|
+
def move_methods
|
188
|
+
[:post, :put, :patch, 'POST', 'PUT', 'PATCH']
|
189
|
+
end
|
190
|
+
|
191
|
+
def includes_body_param?(params)
|
192
|
+
params.map { |x| return true if x[:in] == 'body' || x[:param_type] == 'body' }
|
153
193
|
false
|
154
194
|
end
|
155
195
|
|
156
|
-
def
|
157
|
-
|
196
|
+
def should_expose_as_array?(params)
|
197
|
+
should_exposed_as(params) == 'array'
|
198
|
+
end
|
199
|
+
|
200
|
+
def should_exposed_as(params)
|
201
|
+
params.map { |x| return 'object' if x[:type] && x[:type] != 'array' }
|
202
|
+
'array'
|
158
203
|
end
|
159
204
|
end
|
160
205
|
end
|