scorpio 0.4.5 → 0.6.0
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 +13 -0
- data/LICENSE.md +613 -0
- data/README.md +31 -18
- data/documents/github.com/OAI/OpenAPI-Specification/blob/oas3-schema/schemas/v3.0/schema.yaml +30 -22
- data/lib/scorpio/google_api_document.rb +27 -15
- data/lib/scorpio/openapi/document.rb +8 -6
- data/lib/scorpio/openapi/operation.rb +92 -42
- data/lib/scorpio/openapi/operations_scope.rb +13 -11
- data/lib/scorpio/openapi/reference.rb +44 -0
- data/lib/scorpio/openapi/tag.rb +15 -0
- data/lib/scorpio/openapi/v3/server.rb +4 -2
- data/lib/scorpio/openapi.rb +186 -135
- data/lib/scorpio/pickle_adapter.rb +2 -0
- data/lib/scorpio/request.rb +60 -41
- data/lib/scorpio/resource_base.rb +238 -198
- data/lib/scorpio/response.rb +10 -6
- data/lib/scorpio/ur.rb +16 -15
- data/lib/scorpio/version.rb +3 -1
- data/lib/scorpio.rb +5 -6
- data/scorpio.gemspec +16 -23
- metadata +23 -206
- data/.simplecov +0 -1
- data/LICENSE.txt +0 -21
- data/Rakefile +0 -10
- data/bin/documents_to_yml.rb +0 -33
data/lib/scorpio/openapi.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Scorpio
|
2
4
|
module OpenAPI
|
5
|
+
class Error < StandardError
|
6
|
+
end
|
3
7
|
# an error in the semantics of an openapi document. for example, an Operation with
|
4
8
|
# two body parameters (in v2, not possible in v3) is a SemanticError. an Operation
|
5
9
|
# with more than one parameter with the same 'name' and 'in' properties would also be
|
@@ -7,172 +11,219 @@ module Scorpio
|
|
7
11
|
#
|
8
12
|
# an instance of a SemanticError may or may not correspond to a validation error of
|
9
13
|
# an OpenAPI document against the OpenAPI schema.
|
10
|
-
class SemanticError
|
14
|
+
class SemanticError < Error
|
11
15
|
end
|
12
16
|
|
13
17
|
autoload :Operation, 'scorpio/openapi/operation'
|
14
18
|
autoload :Document, 'scorpio/openapi/document'
|
19
|
+
autoload :Reference, 'scorpio/openapi/reference'
|
20
|
+
autoload :Tag, 'scorpio/openapi/tag'
|
15
21
|
autoload :OperationsScope, 'scorpio/openapi/operations_scope'
|
16
22
|
|
17
23
|
module V3
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
24
|
+
openapi_document_schema = JSI::JSONSchemaOrgDraft04.new_schema(::YAML.load_file(Scorpio.root.join(
|
25
|
+
'documents/github.com/OAI/OpenAPI-Specification/blob/oas3-schema/schemas/v3.0/schema.yaml'
|
26
|
+
)))
|
22
27
|
|
23
|
-
|
28
|
+
# the schema represented by Scorpio::OpenAPI::V3::Schema will describe schemas itself, so we set it
|
29
|
+
# include on its schema module the jsi_schema_instance_modules that implement schema functionality.
|
30
|
+
describe_schema = [
|
31
|
+
openapi_document_schema.definitions['Schema'],
|
32
|
+
openapi_document_schema.definitions['SchemaReference'],
|
33
|
+
# instead of the Schema definition allowing boolean, properties['additionalProperties']
|
34
|
+
# is a oneOf which allows a Schema, SchemaReference, or boolean.
|
35
|
+
# instances of the former two already include the schema implementation (per the previous
|
36
|
+
# describes_schema entries), but the boolean does not.
|
37
|
+
# including in properties['additionalProperties'] applies to any additionalProperties.
|
38
|
+
# (including in properties['additionalProperties'].anyOf[2] would extend booleans too, without
|
39
|
+
# the redundant inclusion that results for Schema and SchemaRef, but redundant inclusion is not
|
40
|
+
# a problem, and this way also applies when none of the anyOf match due to schema errors.)
|
41
|
+
openapi_document_schema.definitions['Schema'].properties['additionalProperties'],
|
42
|
+
]
|
43
|
+
describe_schema.each { |s| s.jsi_schema_instance_modules = [JSI::Schema::Draft04] }
|
44
|
+
|
45
|
+
Document = openapi_document_schema.jsi_schema_module
|
24
46
|
|
25
47
|
# naming these is not strictly necessary, but is nice to have.
|
26
|
-
# generated: `puts
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
48
|
+
# generated: `puts Scorpio::OpenAPI::V3::Document.schema.definitions.select { |k,v| ['object', nil].include?(v['type']) }.keys.map { |k| "#{k[0].upcase}#{k[1..-1]} = Document.definitions['#{k}']" }`
|
49
|
+
|
50
|
+
|
51
|
+
Reference = Document.definitions['Reference']
|
52
|
+
SchemaReference = Document.definitions['SchemaReference']
|
53
|
+
Info = Document.definitions['Info']
|
54
|
+
Contact = Document.definitions['Contact']
|
55
|
+
License = Document.definitions['License']
|
56
|
+
Server = Document.definitions['Server']
|
57
|
+
ServerVariable = Document.definitions['ServerVariable']
|
58
|
+
Components = Document.definitions['Components']
|
59
|
+
Schema = Document.definitions['Schema']
|
60
|
+
Discriminator = Document.definitions['Discriminator']
|
61
|
+
XML = Document.definitions['XML']
|
62
|
+
Response = Document.definitions['Response']
|
63
|
+
MediaType = Document.definitions['MediaType']
|
64
|
+
MediaTypeWithExample = Document.definitions['MediaTypeWithExample']
|
65
|
+
MediaTypeWithExamples = Document.definitions['MediaTypeWithExamples']
|
66
|
+
Example = Document.definitions['Example']
|
67
|
+
Header = Document.definitions['Header']
|
68
|
+
HeaderWithSchema = Document.definitions['HeaderWithSchema']
|
69
|
+
HeaderWithSchemaWithExample = Document.definitions['HeaderWithSchemaWithExample']
|
70
|
+
HeaderWithSchemaWithExamples = Document.definitions['HeaderWithSchemaWithExamples']
|
71
|
+
HeaderWithContent = Document.definitions['HeaderWithContent']
|
72
|
+
Paths = Document.definitions['Paths']
|
73
|
+
PathItem = Document.definitions['PathItem']
|
74
|
+
Operation = Document.definitions['Operation']
|
75
|
+
Responses = Document.definitions['Responses']
|
76
|
+
SecurityRequirement = Document.definitions['SecurityRequirement']
|
77
|
+
Tag = Document.definitions['Tag']
|
78
|
+
ExternalDocumentation = Document.definitions['ExternalDocumentation']
|
79
|
+
Parameter = Document.definitions['Parameter']
|
80
|
+
ParameterWithSchema = Document.definitions['ParameterWithSchema']
|
81
|
+
ParameterWithSchemaWithExample = Document.definitions['ParameterWithSchemaWithExample']
|
82
|
+
ParameterWithSchemaWithExampleInPath = Document.definitions['ParameterWithSchemaWithExampleInPath']
|
83
|
+
ParameterWithSchemaWithExampleInQuery = Document.definitions['ParameterWithSchemaWithExampleInQuery']
|
84
|
+
ParameterWithSchemaWithExampleInHeader = Document.definitions['ParameterWithSchemaWithExampleInHeader']
|
85
|
+
ParameterWithSchemaWithExampleInCookie = Document.definitions['ParameterWithSchemaWithExampleInCookie']
|
86
|
+
ParameterWithSchemaWithExamples = Document.definitions['ParameterWithSchemaWithExamples']
|
87
|
+
ParameterWithSchemaWithExamplesInPath = Document.definitions['ParameterWithSchemaWithExamplesInPath']
|
88
|
+
ParameterWithSchemaWithExamplesInQuery = Document.definitions['ParameterWithSchemaWithExamplesInQuery']
|
89
|
+
ParameterWithSchemaWithExamplesInHeader = Document.definitions['ParameterWithSchemaWithExamplesInHeader']
|
90
|
+
ParameterWithSchemaWithExamplesInCookie = Document.definitions['ParameterWithSchemaWithExamplesInCookie']
|
91
|
+
ParameterWithContent = Document.definitions['ParameterWithContent']
|
92
|
+
ParameterWithContentInPath = Document.definitions['ParameterWithContentInPath']
|
93
|
+
ParameterWithContentNotInPath = Document.definitions['ParameterWithContentNotInPath']
|
94
|
+
RequestBody = Document.definitions['RequestBody']
|
95
|
+
SecurityScheme = Document.definitions['SecurityScheme']
|
96
|
+
APIKeySecurityScheme = Document.definitions['APIKeySecurityScheme']
|
97
|
+
HTTPSecurityScheme = Document.definitions['HTTPSecurityScheme']
|
98
|
+
NonBearerHTTPSecurityScheme = Document.definitions['NonBearerHTTPSecurityScheme']
|
99
|
+
BearerHTTPSecurityScheme = Document.definitions['BearerHTTPSecurityScheme']
|
100
|
+
OAuth2SecurityScheme = Document.definitions['OAuth2SecurityScheme']
|
101
|
+
OpenIdConnectSecurityScheme = Document.definitions['OpenIdConnectSecurityScheme']
|
102
|
+
OAuthFlows = Document.definitions['OAuthFlows']
|
103
|
+
ImplicitOAuthFlow = Document.definitions['ImplicitOAuthFlow']
|
104
|
+
PasswordOAuthFlow = Document.definitions['PasswordOAuthFlow']
|
105
|
+
ClientCredentialsFlow = Document.definitions['ClientCredentialsFlow']
|
106
|
+
AuthorizationCodeOAuthFlow = Document.definitions['AuthorizationCodeOAuthFlow']
|
107
|
+
Link = Document.definitions['Link']
|
108
|
+
LinkWithOperationRef = Document.definitions['LinkWithOperationRef']
|
109
|
+
LinkWithOperationId = Document.definitions['LinkWithOperationId']
|
110
|
+
Callback = Document.definitions['Callback']
|
111
|
+
Encoding = Document.definitions['Encoding']
|
112
|
+
|
113
|
+
raise(Bug) unless Schema < JSI::Schema
|
114
|
+
raise(Bug) unless SchemaReference < JSI::Schema
|
87
115
|
end
|
88
116
|
module V2
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
117
|
+
openapi_document_schema = JSI.new_schema(::JSON.parse(Scorpio.root.join(
|
118
|
+
'documents/swagger.io/v2/schema.json'
|
119
|
+
).read))
|
120
|
+
|
121
|
+
# the schema represented by Scorpio::OpenAPI::V2::Schema will describe schemas itself, so we set it to
|
122
|
+
# include on its schema module the jsi_schema_instance_modules that implement schema functionality.
|
123
|
+
describe_schema = [
|
124
|
+
openapi_document_schema.definitions['schema'],
|
125
|
+
# comments above on v3's definitions['Schema'].properties['additionalProperties'] apply here too
|
126
|
+
openapi_document_schema.definitions['schema'].properties['additionalProperties'],
|
127
|
+
]
|
128
|
+
describe_schema.each { |s| s.jsi_schema_instance_modules = [JSI::Schema::Draft04] }
|
93
129
|
|
94
|
-
Document =
|
130
|
+
Document = openapi_document_schema.jsi_schema_module
|
95
131
|
|
96
132
|
# naming these is not strictly necessary, but is nice to have.
|
97
|
-
# generated: `puts Scorpio::OpenAPI::V2::Document.schema
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
133
|
+
# generated: `puts Scorpio::OpenAPI::V2::Document.schema.definitions.select { |k,v| ['object', nil].include?(v['type']) }.keys.map { |k| "#{k[0].upcase}#{k[1..-1]} = Document.definitions['#{k}']" }`
|
134
|
+
|
135
|
+
|
136
|
+
Info = Document.definitions['info']
|
137
|
+
Contact = Document.definitions['contact']
|
138
|
+
License = Document.definitions['license']
|
139
|
+
Paths = Document.definitions['paths']
|
140
|
+
Definitions = Document.definitions['definitions']
|
141
|
+
ParameterDefinitions = Document.definitions['parameterDefinitions']
|
142
|
+
ResponseDefinitions = Document.definitions['responseDefinitions']
|
143
|
+
ExternalDocs = Document.definitions['externalDocs']
|
144
|
+
Examples = Document.definitions['examples']
|
145
|
+
Operation = Document.definitions['operation']
|
146
|
+
PathItem = Document.definitions['pathItem']
|
147
|
+
Responses = Document.definitions['responses']
|
148
|
+
ResponseValue = Document.definitions['responseValue']
|
149
|
+
Response = Document.definitions['response']
|
150
|
+
Headers = Document.definitions['headers']
|
151
|
+
Header = Document.definitions['header']
|
152
|
+
VendorExtension = Document.definitions['vendorExtension']
|
153
|
+
BodyParameter = Document.definitions['bodyParameter']
|
154
|
+
HeaderParameterSubSchema = Document.definitions['headerParameterSubSchema']
|
155
|
+
QueryParameterSubSchema = Document.definitions['queryParameterSubSchema']
|
156
|
+
FormDataParameterSubSchema = Document.definitions['formDataParameterSubSchema']
|
157
|
+
PathParameterSubSchema = Document.definitions['pathParameterSubSchema']
|
158
|
+
NonBodyParameter = Document.definitions['nonBodyParameter']
|
159
|
+
Parameter = Document.definitions['parameter']
|
160
|
+
Schema = Document.definitions['schema']
|
161
|
+
FileSchema = Document.definitions['fileSchema']
|
162
|
+
PrimitivesItems = Document.definitions['primitivesItems']
|
163
|
+
SecurityRequirement = Document.definitions['securityRequirement']
|
164
|
+
Xml = Document.definitions['xml']
|
165
|
+
Tag = Document.definitions['tag']
|
166
|
+
SecurityDefinitions = Document.definitions['securityDefinitions']
|
167
|
+
BasicAuthenticationSecurity = Document.definitions['basicAuthenticationSecurity']
|
168
|
+
ApiKeySecurity = Document.definitions['apiKeySecurity']
|
169
|
+
Oauth2ImplicitSecurity = Document.definitions['oauth2ImplicitSecurity']
|
170
|
+
Oauth2PasswordSecurity = Document.definitions['oauth2PasswordSecurity']
|
171
|
+
Oauth2ApplicationSecurity = Document.definitions['oauth2ApplicationSecurity']
|
172
|
+
Oauth2AccessCodeSecurity = Document.definitions['oauth2AccessCodeSecurity']
|
173
|
+
Oauth2Scopes = Document.definitions['oauth2Scopes']
|
174
|
+
Title = Document.definitions['title']
|
175
|
+
Description = Document.definitions['description']
|
176
|
+
Default = Document.definitions['default']
|
177
|
+
MultipleOf = Document.definitions['multipleOf']
|
178
|
+
Maximum = Document.definitions['maximum']
|
179
|
+
ExclusiveMaximum = Document.definitions['exclusiveMaximum']
|
180
|
+
Minimum = Document.definitions['minimum']
|
181
|
+
ExclusiveMinimum = Document.definitions['exclusiveMinimum']
|
182
|
+
MaxLength = Document.definitions['maxLength']
|
183
|
+
MinLength = Document.definitions['minLength']
|
184
|
+
Pattern = Document.definitions['pattern']
|
185
|
+
MaxItems = Document.definitions['maxItems']
|
186
|
+
MinItems = Document.definitions['minItems']
|
187
|
+
UniqueItems = Document.definitions['uniqueItems']
|
188
|
+
Enum = Document.definitions['enum']
|
189
|
+
JsonReference = Document.definitions['jsonReference']
|
190
|
+
|
191
|
+
raise(Bug) unless Schema < JSI::Schema
|
152
192
|
end
|
153
193
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
end # (this block is here just so the above informative comment is not interpreted as module doc)
|
194
|
+
# the autoloads for OpenAPI::Operation and OpenAPI::Document are triggered below. these
|
195
|
+
# should not be triggered until all the classes their files reference are defined (above).
|
196
|
+
|
158
197
|
|
159
198
|
module V3
|
160
|
-
|
199
|
+
module Operation
|
161
200
|
include OpenAPI::Operation
|
162
201
|
end
|
163
|
-
|
202
|
+
module Document
|
164
203
|
include OpenAPI::Document
|
165
204
|
end
|
205
|
+
module Reference
|
206
|
+
include OpenAPI::Reference
|
207
|
+
end
|
208
|
+
module Tag
|
209
|
+
include OpenAPI::Tag
|
210
|
+
end
|
166
211
|
require 'scorpio/openapi/v3/server'
|
167
212
|
end
|
168
213
|
|
169
214
|
module V2
|
170
|
-
|
215
|
+
module Operation
|
171
216
|
include OpenAPI::Operation
|
172
217
|
end
|
173
|
-
|
218
|
+
module Document
|
174
219
|
include OpenAPI::Document
|
175
220
|
end
|
221
|
+
module JsonReference
|
222
|
+
include OpenAPI::Reference
|
223
|
+
end
|
224
|
+
module Tag
|
225
|
+
include OpenAPI::Tag
|
226
|
+
end
|
176
227
|
end
|
177
228
|
end
|
178
229
|
end
|
data/lib/scorpio/request.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Scorpio
|
2
4
|
class Request
|
3
|
-
SUPPORTED_REQUEST_MEDIA_TYPES = ['application/json', 'application/x-www-form-urlencoded']
|
5
|
+
SUPPORTED_REQUEST_MEDIA_TYPES = ['application/json'.freeze, 'application/x-www-form-urlencoded'.freeze].freeze
|
6
|
+
FALLBACK_CONTENT_TYPE = 'application/x-www-form-urlencoded'.freeze
|
7
|
+
|
4
8
|
def self.best_media_type(media_types)
|
5
9
|
if media_types.size == 1
|
6
10
|
media_types.first
|
@@ -116,12 +120,12 @@ module Scorpio
|
|
116
120
|
def initialize(operation, configuration = {}, &b)
|
117
121
|
@operation = operation
|
118
122
|
|
119
|
-
configuration = JSI.stringify_symbol_keys(configuration)
|
123
|
+
configuration = JSI::Util.stringify_symbol_keys(configuration)
|
120
124
|
params_set = Set.new # the set of params that have been set
|
121
125
|
# do the Configurables first
|
122
126
|
configuration.each do |name, value|
|
123
127
|
if Configurables.public_method_defined?("#{name}=")
|
124
|
-
Configurables.instance_method("#{name}=").
|
128
|
+
Configurables.instance_method("#{name}=").bind_call(self, value)
|
125
129
|
params_set << name
|
126
130
|
end
|
127
131
|
end
|
@@ -146,21 +150,23 @@ module Scorpio
|
|
146
150
|
operation.openapi_document
|
147
151
|
end
|
148
152
|
|
149
|
-
#
|
153
|
+
# the http method for this request
|
154
|
+
# @return [String]
|
150
155
|
def http_method
|
151
|
-
operation.http_method
|
156
|
+
operation.http_method
|
152
157
|
end
|
153
158
|
|
154
|
-
#
|
155
|
-
#
|
159
|
+
# the template for the request's path, to be expanded with {Configurables#path_params} and appended to
|
160
|
+
# the request's {Configurables#base_url}
|
161
|
+
# @return [Addressable::Template]
|
156
162
|
def path_template
|
157
163
|
operation.path_template
|
158
164
|
end
|
159
165
|
|
160
|
-
#
|
161
|
-
#
|
166
|
+
# an Addressable::URI containing only the path to append to the {Configurables#base_url} for this request
|
167
|
+
# @return [Addressable::URI]
|
162
168
|
def path
|
163
|
-
path_params = JSI.stringify_symbol_keys(self.path_params)
|
169
|
+
path_params = JSI::Util.stringify_symbol_keys(self.path_params)
|
164
170
|
missing_variables = path_template.variables - path_params.keys
|
165
171
|
if missing_variables.any?
|
166
172
|
raise(ArgumentError, "path #{operation.path_template_str} for operation #{operation.human_id} requires path_params " +
|
@@ -172,24 +178,26 @@ module Scorpio
|
|
172
178
|
"which were empty: #{empty_variables.inspect}")
|
173
179
|
end
|
174
180
|
|
175
|
-
path_template.expand(path_params)
|
176
|
-
|
177
|
-
|
178
|
-
end
|
181
|
+
path = path_template.expand(path_params)
|
182
|
+
if query_params
|
183
|
+
path.query_values = query_params
|
179
184
|
end
|
185
|
+
path.freeze
|
180
186
|
end
|
181
187
|
|
182
|
-
#
|
188
|
+
# the full URL for this request
|
189
|
+
# @return [Addressable::URI]
|
183
190
|
def url
|
184
191
|
unless base_url
|
185
192
|
raise(ArgumentError, "no base_url has been specified for request")
|
186
193
|
end
|
187
194
|
# we do not use Addressable::URI#join as the paths should just be concatenated, not resolved.
|
188
195
|
# we use File.join just to deal with consecutive slashes.
|
189
|
-
Addressable::URI.parse(File.join(base_url, path))
|
196
|
+
Addressable::URI.parse(File.join(base_url, path)).freeze
|
190
197
|
end
|
191
198
|
|
192
|
-
#
|
199
|
+
# the value of the request Content-Type header
|
200
|
+
# @return [::Ur::ContentType]
|
193
201
|
def content_type_header
|
194
202
|
headers.each do |k, v|
|
195
203
|
return ::Ur::ContentType.new(v) if k =~ /\Acontent[-_]type\z/i
|
@@ -197,10 +205,11 @@ module Scorpio
|
|
197
205
|
nil
|
198
206
|
end
|
199
207
|
|
200
|
-
#
|
201
|
-
#
|
208
|
+
# Content-Type for this request, taken from request headers if present, or the
|
209
|
+
# request {Configurables#media_type}.
|
210
|
+
# @return [::Ur::ContentType]
|
202
211
|
def content_type
|
203
|
-
content_type_header || ::Ur::ContentType.new(media_type)
|
212
|
+
content_type_header || (media_type ? ::Ur::ContentType.new(media_type) : nil)
|
204
213
|
end
|
205
214
|
|
206
215
|
# @return [::JSI::Schema]
|
@@ -208,11 +217,6 @@ module Scorpio
|
|
208
217
|
operation.request_schema(media_type: media_type)
|
209
218
|
end
|
210
219
|
|
211
|
-
# @return [Class subclassing JSI::Base]
|
212
|
-
def request_schema_class(media_type: self.media_type)
|
213
|
-
JSI.class_for_schema(request_schema(media_type: media_type))
|
214
|
-
end
|
215
|
-
|
216
220
|
# builds a Faraday connection with this Request's faraday_builder and faraday_adapter.
|
217
221
|
# passes a given proc yield_ur to middleware to yield an Ur for requests made with the connection.
|
218
222
|
#
|
@@ -222,8 +226,9 @@ module Scorpio
|
|
222
226
|
Faraday.new do |faraday_connection|
|
223
227
|
faraday_builder.call(faraday_connection)
|
224
228
|
if yield_ur
|
225
|
-
::Ur::Faraday # autoload trigger
|
226
|
-
|
229
|
+
-> { ::Ur::Faraday }.() # autoload trigger
|
230
|
+
|
231
|
+
faraday_connection.response(:yield_ur, schemas: Set[Scorpio::Ur.schema], logger: self.logger, &yield_ur)
|
227
232
|
end
|
228
233
|
faraday_connection.adapter(*faraday_adapter)
|
229
234
|
end
|
@@ -234,16 +239,17 @@ module Scorpio
|
|
234
239
|
# @param name [String, Symbol] the 'name' property of one applicable parameter
|
235
240
|
# @param value [Object] the applicable parameter will be applied to the request with the given value.
|
236
241
|
# @return [Object] echoes the value param
|
237
|
-
# @raise
|
242
|
+
# @raise (see #param_for!)
|
238
243
|
def set_param(name, value)
|
239
244
|
param = param_for!(name)
|
240
245
|
set_param_from(param['in'], param['name'], value)
|
241
246
|
value
|
242
247
|
end
|
243
248
|
|
249
|
+
# returns the value of the named parameter on this request
|
244
250
|
# @param name [String, Symbol] the 'name' property of one applicable parameter
|
245
|
-
# @return [Object]
|
246
|
-
# @raise
|
251
|
+
# @return [Object]
|
252
|
+
# @raise (see #param_for!)
|
247
253
|
def get_param(name)
|
248
254
|
param = param_for!(name)
|
249
255
|
get_param_from(param['in'], param['name'])
|
@@ -251,6 +257,7 @@ module Scorpio
|
|
251
257
|
|
252
258
|
# @param name [String, Symbol] the 'name' property of one applicable parameter
|
253
259
|
# @return [#to_hash, nil]
|
260
|
+
# @raise [Scorpio::AmbiguousParameter] if more than one parameter has the given name
|
254
261
|
def param_for(name)
|
255
262
|
name = name.to_s if name.is_a?(Symbol)
|
256
263
|
params = operation.inferred_parameters.select { |p| p['name'] == name }
|
@@ -265,17 +272,21 @@ module Scorpio
|
|
265
272
|
end
|
266
273
|
end
|
267
274
|
|
268
|
-
# @param name [String, Symbol] the name
|
275
|
+
# @param name [String, Symbol] the 'name' property of one applicable parameter
|
269
276
|
# @return [#to_hash]
|
277
|
+
# @raise [Scorpio::ParameterError] if no parameter has the given name
|
278
|
+
# @raise (see #param_for)
|
270
279
|
def param_for!(name)
|
271
280
|
param_for(name) || raise(ParameterError, "There is no parameter named #{name} on operation #{operation.human_id}:\n#{operation.pretty_inspect.chomp}")
|
272
281
|
end
|
273
282
|
|
274
|
-
#
|
283
|
+
# applies the named value to the appropriate parameter of the request
|
284
|
+
# @param param_in [String, Symbol] one of 'path', 'query', 'header', or 'cookie' - where to apply
|
285
|
+
# the named value
|
275
286
|
# @param name [String, Symbol] the parameter name to apply the value to
|
276
287
|
# @param value [Object] the value
|
277
288
|
# @return [Object] echoes the value param
|
278
|
-
# @raise [ArgumentError] invalid
|
289
|
+
# @raise [ArgumentError] invalid `param_in` parameter
|
279
290
|
# @raise [NotImplementedError] cookies aren't implemented
|
280
291
|
def set_param_from(param_in, name, value)
|
281
292
|
param_in = param_in.to_s if param_in.is_a?(Symbol)
|
@@ -294,10 +305,12 @@ module Scorpio
|
|
294
305
|
value
|
295
306
|
end
|
296
307
|
|
297
|
-
#
|
308
|
+
# returns the value of the named parameter from the specified `param_in` on this request
|
309
|
+
# @param param_in [String, Symbol] one of 'path', 'query', 'header', or 'cookie' - where to retrieve
|
310
|
+
# the named value
|
298
311
|
# @param name [String, Symbol] the parameter name
|
299
|
-
# @return [Object]
|
300
|
-
# @raise [ArgumentError] invalid
|
312
|
+
# @return [Object]
|
313
|
+
# @raise [ArgumentError] invalid `param_in` parameter
|
301
314
|
# @raise [NotImplementedError] cookies aren't implemented
|
302
315
|
def get_param_from(param_in, name)
|
303
316
|
if param_in == 'path'
|
@@ -322,24 +335,30 @@ module Scorpio
|
|
322
335
|
if user_agent
|
323
336
|
headers['User-Agent'] = user_agent
|
324
337
|
end
|
325
|
-
if
|
326
|
-
|
338
|
+
if !content_type_header
|
339
|
+
if media_type
|
340
|
+
headers['Content-Type'] = media_type
|
341
|
+
else
|
342
|
+
# I'd rather not have a default content-type, but if none is set then the HTTP adapter sets this to
|
343
|
+
# application/x-www-form-urlencoded and issues a warning about it.
|
344
|
+
headers['Content-Type'] = FALLBACK_CONTENT_TYPE
|
345
|
+
end
|
327
346
|
end
|
328
347
|
if self.headers
|
329
348
|
headers.update(self.headers)
|
330
349
|
end
|
331
350
|
ur = nil
|
332
|
-
faraday_connection(-> (yur) { ur = yur }).run_request(http_method, url, body, headers)
|
351
|
+
faraday_connection(-> (yur) { ur = yur }).run_request(http_method.downcase.to_sym, url, body, headers)
|
333
352
|
ur.scorpio_request = self
|
334
353
|
ur
|
335
354
|
end
|
336
355
|
|
337
356
|
# runs this request. returns the response body object - that is, the response body
|
338
357
|
# parsed according to an understood media type, and instantiated with the applicable
|
339
|
-
# response schema if one is specified. see Scorpio::Response#body_object for more detail.
|
358
|
+
# response schema if one is specified. see {Scorpio::Response#body_object} for more detail.
|
340
359
|
#
|
341
360
|
# @raise [Scorpio::HTTPError] if the request returns a 4xx or 5xx status, the appropriate
|
342
|
-
# error is raised - see Scorpio::HTTPErrors
|
361
|
+
# error is raised - see {Scorpio::HTTPErrors}
|
343
362
|
def run
|
344
363
|
ur = run_ur
|
345
364
|
ur.raise_on_http_error
|