scorpio 0.4.5 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|