grape-swagger 2.1.1 → 2.1.3
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 +4 -4
- data/CHANGELOG.md +128 -99
- data/README.md +155 -32
- data/RELEASING.md +8 -8
- data/grape-swagger.gemspec +2 -3
- data/lib/grape-swagger/doc_methods/build_model_definition.rb +1 -1
- data/lib/grape-swagger/doc_methods/format_data.rb +1 -1
- data/lib/grape-swagger/doc_methods/move_params.rb +1 -1
- data/lib/grape-swagger/doc_methods/parse_params.rb +4 -2
- data/lib/grape-swagger/doc_methods.rb +0 -1
- data/lib/grape-swagger/endpoint.rb +52 -48
- data/lib/grape-swagger/errors.rb +2 -0
- data/lib/grape-swagger/rake/oapi_tasks.rb +1 -1
- data/lib/grape-swagger/request_param_parser_registry.rb +48 -0
- data/lib/grape-swagger/{endpoint/params_parser.rb → request_param_parsers/body.rb} +21 -22
- data/lib/grape-swagger/request_param_parsers/headers.rb +33 -0
- data/lib/grape-swagger/request_param_parsers/route.rb +66 -0
- data/lib/grape-swagger/token_owner_resolver.rb +101 -0
- data/lib/grape-swagger/version.rb +1 -1
- data/lib/grape-swagger.rb +12 -5
- metadata +11 -26
- data/lib/grape-swagger/doc_methods/headers.rb +0 -20
data/README.md
CHANGED
|
@@ -3,22 +3,92 @@
|
|
|
3
3
|
[](https://coveralls.io/github/ruby-grape/grape-swagger?branch=master)
|
|
4
4
|
[](https://codeclimate.com/github/ruby-grape/grape-swagger)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
# Table of Contents
|
|
7
|
+
|
|
8
|
+
- [What is grape-swagger? ](#what-is-grape-swagger-)
|
|
9
|
+
- [Related Projects ](#related-projects-)
|
|
10
|
+
- [Compatibility ](#compatibility-)
|
|
11
|
+
- [Swagger-Spec ](#swagger-spec-)
|
|
12
|
+
- [Installation ](#installation-)
|
|
13
|
+
- [Upgrade](#upgrade)
|
|
14
|
+
- [Usage ](#usage-)
|
|
15
|
+
- [Model Parsers ](#model-parsers-)
|
|
16
|
+
- [Custom Model Parsers](#custom-model-parsers)
|
|
17
|
+
- [insert_before](#insert_before)
|
|
18
|
+
- [insert_after](#insert_after)
|
|
19
|
+
- [CORS](#cors)
|
|
20
|
+
- [Configure ](#configure-)
|
|
21
|
+
- [host: ](#host-)
|
|
22
|
+
- [base_path: ](#base_path-)
|
|
23
|
+
- [mount_path: ](#mount_path-)
|
|
24
|
+
- [add_base_path: ](#add_base_path-)
|
|
25
|
+
- [add_root: ](#add_root-)
|
|
26
|
+
- [add_version: ](#add_version-)
|
|
27
|
+
- [doc_version: ](#doc_version-)
|
|
28
|
+
- [endpoint_auth_wrapper: ](#endpoint_auth_wrapper-)
|
|
29
|
+
- [swagger_endpoint_guard: ](#swagger_endpoint_guard-)
|
|
30
|
+
- [token_owner: ](#token_owner-)
|
|
31
|
+
- [security_definitions: ](#security_definitions-)
|
|
32
|
+
- [security: ](#security-)
|
|
33
|
+
- [models: ](#models-)
|
|
34
|
+
- [tags: ](#tags-)
|
|
35
|
+
- [hide_documentation_path: (default: true) ](#hide_documentation_path-default-true-)
|
|
36
|
+
- [info: ](#info-)
|
|
37
|
+
- [array_use_braces: ](#array_use_braces-)
|
|
38
|
+
- [api_documentation](#api_documentation)
|
|
39
|
+
- [specific_api_documentation](#specific_api_documentation)
|
|
40
|
+
- [consumes](#consumes)
|
|
41
|
+
- [produces](#produces)
|
|
42
|
+
- [Routes Configuration ](#routes-configuration-)
|
|
43
|
+
- [Swagger Header Parameters ](#swagger-header-parameters--)
|
|
44
|
+
- [Hiding an Endpoint ](#hiding-an-endpoint-)
|
|
45
|
+
- [Overriding Auto-Generated Nicknames ](#overriding-auto-generated-nicknames-)
|
|
46
|
+
- [Specify endpoint details ](#specify-endpoint-details-)
|
|
47
|
+
- [Overriding the route summary ](#overriding-the-route-summary-)
|
|
48
|
+
- [Overriding the tags ](#overriding-the-tags-)
|
|
49
|
+
- [Deprecating routes ](#deprecating-routes-)
|
|
50
|
+
- [Overriding the name of the body parameter ](#overriding-the-name-of-the-body-parameter-)
|
|
51
|
+
- [Defining an endpoint as an array ](#defining-an-endpoint-as-an-array-)
|
|
52
|
+
- [Using an options hash ](#using-an-options-hash-)
|
|
53
|
+
- [Overriding parameter type ](#overriding-parameter-type-)
|
|
54
|
+
- [Overriding data type of the parameter ](#overriding-data-type-of-the-parameter-)
|
|
55
|
+
- [Multiple types ](#multiple-types-)
|
|
56
|
+
- [Array of data type ](#array-of-data-type-)
|
|
57
|
+
- [Collection format of arrays ](#collection-format-of-arrays-)
|
|
58
|
+
- [Hiding parameters ](#hiding-parameters-)
|
|
59
|
+
- [Setting a Swagger default value ](#setting-a-swagger-default-value-)
|
|
60
|
+
- [Setting additionalProperties for object-type parameters ](#setting-additionalproperties-for-object-type-parameters-)
|
|
61
|
+
- [Allow any additional properties](#allow-any-additional-properties)
|
|
62
|
+
- [Allow any additional properties of a particular type](#allow-any-additional-properties-of-a-particular-type)
|
|
63
|
+
- [Allow any additional properties matching a defined schema](#allow-any-additional-properties-matching-a-defined-schema)
|
|
64
|
+
- [Example parameter value ](#example-parameter-value-)
|
|
65
|
+
- [Expose nested namespace as standalone route](#expose-nested-namespace-as-standalone-route)
|
|
66
|
+
- [With a custom name](#with-a-custom-name)
|
|
67
|
+
- [Response documentation ](#response-documentation-)
|
|
68
|
+
- [Changing default status codes ](#changing-default-status-codes-)
|
|
69
|
+
- [Multiple status codes for response ](#multiple-status-codes-for-response-)
|
|
70
|
+
- [File response ](#file-response-)
|
|
71
|
+
- [Default response ](#default-response-)
|
|
72
|
+
- [Extensions ](#extensions-)
|
|
73
|
+
- [Response examples documentation ](#response-examples-documentation-)
|
|
74
|
+
- [Response headers documentation ](#response-headers-documentation-)
|
|
75
|
+
- [Adding root element to responses ](#adding-root-element-to-responses-)
|
|
76
|
+
- [Multiple present Response ](#multiple-present-response-)
|
|
77
|
+
- [Using Grape Entities ](#using-grape-entities-)
|
|
78
|
+
- [Documented class/definition](#documented-classdefinition)
|
|
79
|
+
- [Relationships](#relationships)
|
|
80
|
+
- [1xN](#1xn)
|
|
81
|
+
- [1x1](#1x1)
|
|
82
|
+
- [Inheritance with allOf and discriminator](#inheritance-with-allof-and-discriminator)
|
|
83
|
+
- [Securing the Swagger UI ](#securing-the-swagger-ui-)
|
|
84
|
+
- [Example ](#example-)
|
|
85
|
+
- [Grouping the API list using Namespace](#grouping-the-api-list-using-namespace)
|
|
86
|
+
- [Example Code](#example-code)
|
|
87
|
+
- [Rake Tasks ](#rake-tasks-)
|
|
88
|
+
- [OpenApi/Swagger Documentation](#openapiswagger-documentation)
|
|
89
|
+
- [OpenApi/Swagger Validation](#openapiswagger-validation)
|
|
90
|
+
- [Contributing to grape-swagger](#contributing-to-grape-swagger)
|
|
91
|
+
- [Copyright and License](#copyright-and-license)
|
|
22
92
|
|
|
23
93
|
## What is grape-swagger? <a name="what"></a>
|
|
24
94
|
|
|
@@ -43,17 +113,19 @@ This screenshot is based on the [Hussars](https://github.com/LeFnord/hussars) sa
|
|
|
43
113
|
|
|
44
114
|
The following versions of grape, grape-entity and grape-swagger can currently be used together.
|
|
45
115
|
|
|
46
|
-
| grape-swagger
|
|
47
|
-
|
|
|
48
|
-
| 0.10.5
|
|
49
|
-
| 0.11.0
|
|
50
|
-
| 0.25.2
|
|
51
|
-
| 0.26.0
|
|
52
|
-
| 0.27.0
|
|
53
|
-
| 0.32.0
|
|
54
|
-
| 0.34.0
|
|
55
|
-
| >= 1.0.0
|
|
56
|
-
| >= 2.0.0
|
|
116
|
+
| grape-swagger | swagger spec | grape | grape-entity | representable |
|
|
117
|
+
| --------------------- | ------------ | ----------------------- | ------------ | ------------- |
|
|
118
|
+
| 0.10.5 | 1.2 | >= 0.10.0 ... <= 0.14.0 | < 0.5.0 | n/a |
|
|
119
|
+
| 0.11.0 | 1.2 | >= 0.16.2 | < 0.5.0 | n/a |
|
|
120
|
+
| 0.25.2 | 2.0 | >= 0.14.0 ... <= 0.18.0 | <= 0.6.0 | >= 2.4.1 |
|
|
121
|
+
| 0.26.0 | 2.0 | >= 0.16.2 ... <= 1.1.0 | <= 0.6.1 | >= 2.4.1 |
|
|
122
|
+
| 0.27.0 | 2.0 | >= 0.16.2 ... <= 1.1.0 | >= 0.5.0 | >= 2.4.1 |
|
|
123
|
+
| 0.32.0 | 2.0 | >= 0.16.2 | >= 0.5.0 | >= 2.4.1 |
|
|
124
|
+
| 0.34.0 | 2.0 | >= 0.16.2 ... < 1.3.0 | >= 0.5.0 | >= 2.4.1 |
|
|
125
|
+
| >= 1.0.0 | 2.0 | >= 1.3.0 | >= 0.5.0 | >= 2.4.1 |
|
|
126
|
+
| >= 2.0.0 | 2.0 | >= 1.7.0 | >= 0.5.0 | >= 2.4.1 |
|
|
127
|
+
| >= 2.0.0 ... <= 2.1.2 | 2.0 | >= 1.8.0 ... < 2.3.0 | >= 0.5.0 | >= 2.4.1 |
|
|
128
|
+
| > 2.1.2 | 2.0 | >= 1.8.0 ... < 4.0 | >= 0.5.0 | >= 2.4.1 |
|
|
57
129
|
|
|
58
130
|
|
|
59
131
|
## Swagger-Spec <a name="swagger-spec"></a>
|
|
@@ -485,7 +557,7 @@ add_swagger_documentation \
|
|
|
485
557
|
|
|
486
558
|
#### Swagger Header Parameters <a name="headers"></a>
|
|
487
559
|
|
|
488
|
-
Swagger also supports the documentation of parameters passed in the header. Since grape's ```params[]``` doesn't return header parameters we can specify header parameters
|
|
560
|
+
Swagger also supports the documentation of parameters passed in the header. Since grape's ```params[]``` doesn't return header parameters we can specify header parameters separately in a block after the description.
|
|
489
561
|
|
|
490
562
|
```ruby
|
|
491
563
|
desc "Return super-secret information", {
|
|
@@ -955,7 +1027,8 @@ The result is then something like following:
|
|
|
955
1027
|
|
|
956
1028
|
#### Changing default status codes <a name="change-status"></a>
|
|
957
1029
|
|
|
958
|
-
|
|
1030
|
+
|
|
1031
|
+
The default status codes, one could be found (-> [status codes](lib/grape-swagger/doc_methods/status_codes.rb)) can be changed to your specific needs, to achieve it, you have to change it for grape itself and for the documentation.
|
|
959
1032
|
|
|
960
1033
|
```ruby
|
|
961
1034
|
desc 'Get a list of stuff',
|
|
@@ -1444,7 +1517,6 @@ The result will look like following:
|
|
|
1444
1517
|
Add the [grape-entity](https://github.com/ruby-grape/grape-entity) and [grape-swagger-entity](https://github.com/ruby-grape/grape-swagger-entity) gem to your Gemfile.
|
|
1445
1518
|
|
|
1446
1519
|
The following example exposes statuses. And exposes statuses documentation adding :type, :desc and :required.
|
|
1447
|
-
The documented class/definition name could be set via `#entity_name`.
|
|
1448
1520
|
|
|
1449
1521
|
```ruby
|
|
1450
1522
|
module API
|
|
@@ -1487,6 +1559,57 @@ module API
|
|
|
1487
1559
|
end
|
|
1488
1560
|
```
|
|
1489
1561
|
|
|
1562
|
+
### Documented class/definition
|
|
1563
|
+
|
|
1564
|
+
You can set the name of the Entity when being documented via `#entity_name`:
|
|
1565
|
+
|
|
1566
|
+
```ruby
|
|
1567
|
+
module API
|
|
1568
|
+
module Entities
|
|
1569
|
+
class Status < Grape::Entity
|
|
1570
|
+
expose :text, documentation: { type: 'string', desc: 'Status update text.', required: true }
|
|
1571
|
+
end
|
|
1572
|
+
|
|
1573
|
+
class Link < Grape::Entity
|
|
1574
|
+
expose :href, documentation: { type: 'url' }
|
|
1575
|
+
|
|
1576
|
+
def self.entity_name
|
|
1577
|
+
'LinkedStatus'
|
|
1578
|
+
end
|
|
1579
|
+
|
|
1580
|
+
end
|
|
1581
|
+
end
|
|
1582
|
+
end
|
|
1583
|
+
```
|
|
1584
|
+
Should generate the following definitions in your swagger json:
|
|
1585
|
+
|
|
1586
|
+
```json
|
|
1587
|
+
{
|
|
1588
|
+
"definitions": {
|
|
1589
|
+
"API_Entities_Status": {
|
|
1590
|
+
"type": "object",
|
|
1591
|
+
"properties": {
|
|
1592
|
+
"text": {
|
|
1593
|
+
"type": "string",
|
|
1594
|
+
"description": "Status update text.",
|
|
1595
|
+
},
|
|
1596
|
+
},
|
|
1597
|
+
"required": [
|
|
1598
|
+
"text",
|
|
1599
|
+
],
|
|
1600
|
+
"description": "API_Entities_Pet model"
|
|
1601
|
+
},
|
|
1602
|
+
"LinkedStatus": {
|
|
1603
|
+
"type": "object",
|
|
1604
|
+
"properties": {
|
|
1605
|
+
"href": {
|
|
1606
|
+
"type": "url",
|
|
1607
|
+
},
|
|
1608
|
+
"description": "LinkedStatus model"
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
```
|
|
1490
1613
|
|
|
1491
1614
|
### Relationships
|
|
1492
1615
|
|
|
@@ -1678,7 +1801,7 @@ This is how to configure the grape_swagger documentation:
|
|
|
1678
1801
|
The guard method should inject the Security Requirement Object into the endpoint's route settings (see Grape::DSL::Settings.route_setting method).
|
|
1679
1802
|
|
|
1680
1803
|
The 'oauth2 false' added to swagger_documentation is making the main Swagger endpoint protected with OAuth, i.e. the
|
|
1681
|
-
access_token is being
|
|
1804
|
+
access_token is being retrieving from the HTTP request, but the 'false' scope is for skipping authorization and
|
|
1682
1805
|
showing the UI for everyone. If the scope would be set to something else, like 'oauth2 admin', for example, than the UI
|
|
1683
1806
|
wouldn't be displayed at all to unauthorized users.
|
|
1684
1807
|
|
|
@@ -1786,7 +1909,7 @@ params:
|
|
|
1786
1909
|
- store={ true | file_name.json } – save as JSON (optional)
|
|
1787
1910
|
- resource=resource_name – get only for this one (optional)
|
|
1788
1911
|
```
|
|
1789
|
-
For
|
|
1912
|
+
For multiversion API it creates several files with following naming: file_name_`API_VERSION`.json
|
|
1790
1913
|
|
|
1791
1914
|
#### OpenApi/Swagger Validation
|
|
1792
1915
|
|
data/RELEASING.md
CHANGED
|
@@ -16,7 +16,7 @@ Check that the last build succeeded in [Travis CI](https://travis-ci.org/ruby-gr
|
|
|
16
16
|
Change "Next" in [CHANGELOG.md](CHANGELOG.md) to the current date.
|
|
17
17
|
|
|
18
18
|
```
|
|
19
|
-
###
|
|
19
|
+
### 2.2.0 (2025-11-21)
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
Remove the lines with "Your contribution here.", since there will be no more contributions to this release.
|
|
@@ -25,7 +25,7 @@ Commit your changes.
|
|
|
25
25
|
|
|
26
26
|
```
|
|
27
27
|
git add CHANGELOG.md lib/grape-swagger/version.rb
|
|
28
|
-
git commit -m "Preparing for release,
|
|
28
|
+
git commit -m "Preparing for release, 2.2.0."
|
|
29
29
|
git push origin master
|
|
30
30
|
```
|
|
31
31
|
|
|
@@ -34,10 +34,10 @@ Release.
|
|
|
34
34
|
```
|
|
35
35
|
$ rake release
|
|
36
36
|
|
|
37
|
-
grape-swagger
|
|
38
|
-
Tagged
|
|
37
|
+
grape-swagger 2.2.0 built to pkg/grape-swagger-2.2.0.gem.
|
|
38
|
+
Tagged v2.2.0.
|
|
39
39
|
Pushed git commits and tags.
|
|
40
|
-
Pushed grape-swagger
|
|
40
|
+
Pushed grape-swagger 2.2.0 to rubygems.org.
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
### Prepare for the Next Version
|
|
@@ -47,7 +47,7 @@ Increment the minor version, the third number, modify [lib/grape-swagger/version
|
|
|
47
47
|
Add the next release to [CHANGELOG.md](CHANGELOG.md).
|
|
48
48
|
|
|
49
49
|
```
|
|
50
|
-
###
|
|
50
|
+
### 2.2.1 (Next)
|
|
51
51
|
|
|
52
52
|
#### Features
|
|
53
53
|
|
|
@@ -62,7 +62,7 @@ Commit your changes.
|
|
|
62
62
|
|
|
63
63
|
```
|
|
64
64
|
git add CHANGELOG.md lib/grape-swagger/version.rb
|
|
65
|
-
git commit -m "Preparing for next developer iteration,
|
|
65
|
+
git commit -m "Preparing for next developer iteration, 2.2.1."
|
|
66
66
|
git push origin master
|
|
67
67
|
```
|
|
68
68
|
|
|
@@ -71,7 +71,7 @@ git push origin master
|
|
|
71
71
|
Make an announcement on the [ruby-grape@googlegroups.com](mailto:ruby-grape@googlegroups.com) mailing list. The general format is as follows.
|
|
72
72
|
|
|
73
73
|
```
|
|
74
|
-
Grape-Swagger
|
|
74
|
+
Grape-Swagger 2.2.0 has been released.
|
|
75
75
|
|
|
76
76
|
There were 8 contributors to this release, not counting documentation.
|
|
77
77
|
|
data/grape-swagger.gemspec
CHANGED
|
@@ -14,9 +14,8 @@ Gem::Specification.new do |s|
|
|
|
14
14
|
|
|
15
15
|
s.metadata['rubygems_mfa_required'] = 'true'
|
|
16
16
|
|
|
17
|
-
s.required_ruby_version = '>= 3.
|
|
18
|
-
s.add_dependency 'grape', '>= 1.7', '<
|
|
19
|
-
s.add_dependency 'rack-test', '~> 2'
|
|
17
|
+
s.required_ruby_version = '>= 3.1'
|
|
18
|
+
s.add_dependency 'grape', '>= 1.7', '< 4.0'
|
|
20
19
|
|
|
21
20
|
s.files = Dir['lib/**/*', '*.md', 'LICENSE.txt', 'grape-swagger.gemspec']
|
|
22
21
|
s.require_paths = ['lib']
|
|
@@ -7,7 +7,7 @@ module GrapeSwagger
|
|
|
7
7
|
def to_format(parameters)
|
|
8
8
|
parameters.reject { |parameter| parameter[:in] == 'body' }.each do |b|
|
|
9
9
|
related_parameters = parameters.select do |p|
|
|
10
|
-
p[:name] != b[:name] && p[:name].
|
|
10
|
+
p[:name] != b[:name] && p[:name].start_with?("#{b[:name].to_s.gsub(/\[\]\z/, '')}[")
|
|
11
11
|
end
|
|
12
12
|
parameters.reject! { |p| p[:name] == b[:name] } if move_down(b, related_parameters)
|
|
13
13
|
end
|
|
@@ -163,7 +163,7 @@ module GrapeSwagger
|
|
|
163
163
|
end
|
|
164
164
|
|
|
165
165
|
def prepare_nested_names(property, params)
|
|
166
|
-
params.each { |x| x[:name] = x[:name].sub(property, '').sub('[', '').sub(']', '') }
|
|
166
|
+
params.each { |x| x[:name] = x[:name].sub(property.to_s, '').sub('[', '').sub(']', '') }
|
|
167
167
|
end
|
|
168
168
|
|
|
169
169
|
def unify!(params)
|
|
@@ -141,8 +141,10 @@ module GrapeSwagger
|
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
def document_example(settings)
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
return unless settings.key?(:example)
|
|
145
|
+
|
|
146
|
+
key = @parsed_param[:in] == 'body' ? :example : :'x-example'
|
|
147
|
+
@parsed_param[key] = settings[:example]
|
|
146
148
|
end
|
|
147
149
|
|
|
148
150
|
def param_type(value_type, consumes)
|
|
@@ -11,7 +11,6 @@ require 'grape-swagger/doc_methods/path_string'
|
|
|
11
11
|
require 'grape-swagger/doc_methods/tag_name_description'
|
|
12
12
|
require 'grape-swagger/doc_methods/parse_params'
|
|
13
13
|
require 'grape-swagger/doc_methods/move_params'
|
|
14
|
-
require 'grape-swagger/doc_methods/headers'
|
|
15
14
|
require 'grape-swagger/doc_methods/build_model_definition'
|
|
16
15
|
require 'grape-swagger/doc_methods/version'
|
|
17
16
|
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
require 'active_support'
|
|
4
4
|
require 'active_support/core_ext/string/inflections'
|
|
5
|
-
|
|
5
|
+
require_relative 'request_param_parsers/headers'
|
|
6
|
+
require_relative 'request_param_parsers/route'
|
|
7
|
+
require_relative 'request_param_parsers/body'
|
|
8
|
+
require_relative 'token_owner_resolver'
|
|
6
9
|
|
|
7
10
|
module Grape
|
|
8
11
|
class Endpoint # rubocop:disable Metrics/ClassLength
|
|
@@ -12,9 +15,7 @@ module Grape
|
|
|
12
15
|
if content_types.empty?
|
|
13
16
|
formats = [target_class.format, target_class.default_format].compact.uniq
|
|
14
17
|
formats = GrapeSwagger::FORMATTER_DEFAULTS.keys if formats.empty?
|
|
15
|
-
content_types =
|
|
16
|
-
formats.include? content_type
|
|
17
|
-
end.values
|
|
18
|
+
content_types = formats.filter_map { |f| GrapeSwagger::CONTENT_TYPE_DEFAULTS[f] }
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
content_types.uniq
|
|
@@ -207,11 +208,8 @@ module Grape
|
|
|
207
208
|
|
|
208
209
|
next build_file_response(memo[value[:code]]) if file_response?(value[:model])
|
|
209
210
|
|
|
210
|
-
if
|
|
211
|
-
|
|
212
|
-
value[:code] = 204
|
|
213
|
-
next
|
|
214
|
-
end
|
|
211
|
+
next build_delete_response(memo, value) if delete_response?(memo, route, value)
|
|
212
|
+
next build_response_for_type_parameter(memo, route, value, options) if value[:type]
|
|
215
213
|
|
|
216
214
|
# Explicitly request no model with { model: '' }
|
|
217
215
|
next if value[:model] == ''
|
|
@@ -284,6 +282,15 @@ module Grape
|
|
|
284
282
|
[default_code]
|
|
285
283
|
end
|
|
286
284
|
|
|
285
|
+
def build_delete_response(memo, value)
|
|
286
|
+
memo[204] = memo.delete(200)
|
|
287
|
+
value[:code] = 204
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def delete_response?(memo, route, value)
|
|
291
|
+
memo.key?(200) && route.request_method == 'DELETE' && value[:model].nil?
|
|
292
|
+
end
|
|
293
|
+
|
|
287
294
|
def build_memo_schema(memo, route, value, response_model, options)
|
|
288
295
|
if memo[value[:code]][:schema] && value[:as]
|
|
289
296
|
memo[value[:code]][:schema][:properties].merge!(build_reference(route, value, response_model, options))
|
|
@@ -304,6 +311,29 @@ module Grape
|
|
|
304
311
|
end
|
|
305
312
|
end
|
|
306
313
|
|
|
314
|
+
def build_response_for_type_parameter(memo, _route, value, _options)
|
|
315
|
+
type, format = prepare_type_and_format(value)
|
|
316
|
+
|
|
317
|
+
if memo[value[:code]].include?(:schema) && value.include?(:as)
|
|
318
|
+
memo[value[:code]][:schema][:properties].merge!(value[:as] => { type: type, format: format }.compact)
|
|
319
|
+
elsif value.include?(:as)
|
|
320
|
+
memo[value[:code]][:schema] =
|
|
321
|
+
{ type: :object, properties: { value[:as] => { type: type, format: format }.compact } }
|
|
322
|
+
else
|
|
323
|
+
memo[value[:code]][:schema] = { type: type }
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def prepare_type_and_format(value)
|
|
328
|
+
data_type = GrapeSwagger::DocMethods::DataType.call(value[:type])
|
|
329
|
+
|
|
330
|
+
if GrapeSwagger::DocMethods::DataType.primitive?(data_type)
|
|
331
|
+
GrapeSwagger::DocMethods::DataType.mapping(data_type)
|
|
332
|
+
else
|
|
333
|
+
data_type
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
307
337
|
def build_reference(route, value, response_model, settings)
|
|
308
338
|
# TODO: proof that the definition exist, if model isn't specified
|
|
309
339
|
reference = if value.key?(:as)
|
|
@@ -354,45 +384,15 @@ module Grape
|
|
|
354
384
|
end
|
|
355
385
|
|
|
356
386
|
def build_request_params(route, settings)
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
def merge_params(route)
|
|
368
|
-
path_params = get_path_params(route.app&.inheritable_setting&.namespace_stackable)
|
|
369
|
-
param_keys = route.params.keys
|
|
370
|
-
|
|
371
|
-
# Merge path params options into route params
|
|
372
|
-
route_params = route.params
|
|
373
|
-
route_params.each_key do |key|
|
|
374
|
-
path = path_params[key] || {}
|
|
375
|
-
params = route_params[key]
|
|
376
|
-
params = {} unless params.is_a? Hash
|
|
377
|
-
route_params[key] = path.merge(params)
|
|
387
|
+
GrapeSwagger.request_param_parsers.each_with_object({}) do |parser_klass, accum|
|
|
388
|
+
params = parser_klass.parse(
|
|
389
|
+
route,
|
|
390
|
+
accum,
|
|
391
|
+
settings,
|
|
392
|
+
self
|
|
393
|
+
)
|
|
394
|
+
accum.merge!(params.stringify_keys)
|
|
378
395
|
end
|
|
379
|
-
|
|
380
|
-
route.params.delete_if { |key| key.is_a?(String) && param_keys.include?(key.to_sym) }.to_a
|
|
381
|
-
end
|
|
382
|
-
|
|
383
|
-
# Iterates over namespaces recursively
|
|
384
|
-
# to build a hash of path params with options, including type
|
|
385
|
-
def get_path_params(stackable_values)
|
|
386
|
-
params = {}
|
|
387
|
-
return param unless stackable_values
|
|
388
|
-
return params unless stackable_values.is_a? Grape::Util::StackableValues
|
|
389
|
-
|
|
390
|
-
stackable_values&.new_values&.dig(:namespace)&.each do |namespace|
|
|
391
|
-
space = namespace.space.to_s.gsub(':', '')
|
|
392
|
-
params[space] = namespace.options || {}
|
|
393
|
-
end
|
|
394
|
-
inherited_params = get_path_params(stackable_values.inherited_values)
|
|
395
|
-
inherited_params.merge(params)
|
|
396
396
|
end
|
|
397
397
|
|
|
398
398
|
def default_type(params)
|
|
@@ -440,7 +440,10 @@ module Grape
|
|
|
440
440
|
route_hidden = route.options[:hidden] if route.options.key?(:hidden)
|
|
441
441
|
return route_hidden unless route_hidden.is_a?(Proc)
|
|
442
442
|
|
|
443
|
-
|
|
443
|
+
return route_hidden.call unless options[:token_owner]
|
|
444
|
+
|
|
445
|
+
token_owner = GrapeSwagger::TokenOwnerResolver.resolve(self, options[:token_owner])
|
|
446
|
+
GrapeSwagger::TokenOwnerResolver.evaluate_proc(route_hidden, token_owner)
|
|
444
447
|
end
|
|
445
448
|
|
|
446
449
|
def hidden_parameter?(value)
|
|
@@ -464,6 +467,7 @@ module Grape
|
|
|
464
467
|
default_code[:as] = entity[:as] if entity[:as]
|
|
465
468
|
default_code[:is_array] = entity[:is_array] if entity[:is_array]
|
|
466
469
|
default_code[:required] = entity[:required] if entity[:required]
|
|
470
|
+
default_code[:type] = entity[:type] if entity[:type]
|
|
467
471
|
else
|
|
468
472
|
default_code = GrapeSwagger::DocMethods::StatusCodes.get[route.request_method.downcase.to_sym]
|
|
469
473
|
default_code[:model] = entity if entity
|
data/lib/grape-swagger/errors.rb
CHANGED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'request_param_parsers/headers'
|
|
4
|
+
require_relative 'request_param_parsers/route'
|
|
5
|
+
require_relative 'request_param_parsers/body'
|
|
6
|
+
|
|
7
|
+
module GrapeSwagger
|
|
8
|
+
class RequestParamParserRegistry
|
|
9
|
+
DEFAULT_PARSERS = [
|
|
10
|
+
GrapeSwagger::RequestParamParsers::Headers,
|
|
11
|
+
GrapeSwagger::RequestParamParsers::Route,
|
|
12
|
+
GrapeSwagger::RequestParamParsers::Body
|
|
13
|
+
].freeze
|
|
14
|
+
|
|
15
|
+
include Enumerable
|
|
16
|
+
|
|
17
|
+
def initialize
|
|
18
|
+
@parsers = DEFAULT_PARSERS.dup
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def register(klass)
|
|
22
|
+
remove_parser(klass)
|
|
23
|
+
@parsers << klass
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def insert_before(before_klass, klass)
|
|
27
|
+
remove_parser(klass)
|
|
28
|
+
insert_at = @parsers.index(before_klass) || @parsers.size
|
|
29
|
+
@parsers.insert(insert_at, klass)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def insert_after(after_klass, klass)
|
|
33
|
+
remove_parser(klass)
|
|
34
|
+
insert_at = @parsers.index(after_klass)
|
|
35
|
+
@parsers.insert(insert_at ? insert_at + 1 : @parsers.size, klass)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def each(&)
|
|
39
|
+
@parsers.each(&)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def remove_parser(klass)
|
|
45
|
+
@parsers.reject! { |k| k == klass }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|