scorpio 0.6.4 → 0.7.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/.yardopts +6 -1
- data/CHANGELOG.md +10 -2
- data/LICENSE.md +2 -4
- data/README.md +81 -67
- data/documents/{github.com/OAI/OpenAPI-Specification/blob/oas3-schema/schemas/v3.0 → spec.openapis.org/oas/3.0}/schema.yaml +164 -628
- data/documents/spec.openapis.org/oas/3.1/dialect/base.schema.yaml +22 -0
- data/documents/spec.openapis.org/oas/3.1/meta/base.schema.yaml +71 -0
- data/documents/spec.openapis.org/oas/3.1/schema-base.yaml +21 -0
- data/documents/spec.openapis.org/oas/3.1/schema.yaml +980 -0
- data/documents/swagger.io/v2/schema.json +1 -1
- data/documents/www.googleapis.com/discovery/v1/apis/discovery/v1/rest.yml +44 -4
- data/lib/scorpio/google_api_document.rb +121 -193
- data/lib/scorpio/openapi/document.rb +63 -31
- data/lib/scorpio/openapi/operation.rb +114 -96
- data/lib/scorpio/openapi/operations_scope.rb +35 -19
- data/lib/scorpio/openapi/reference.rb +88 -23
- data/lib/scorpio/openapi/schema_elements/type_nullable.rb +38 -0
- data/lib/scorpio/openapi/schema_elements.rb +7 -0
- data/lib/scorpio/openapi/server.rb +34 -0
- data/lib/scorpio/openapi/tag.rb +19 -3
- data/lib/scorpio/openapi/v2/dialect.rb +66 -0
- data/lib/scorpio/openapi/v2.rb +124 -0
- data/lib/scorpio/openapi/v3_0/dialect.rb +76 -0
- data/lib/scorpio/openapi/v3_0.rb +130 -0
- data/lib/scorpio/openapi/v3_1.rb +243 -0
- data/lib/scorpio/openapi.rb +23 -203
- data/lib/scorpio/request.rb +67 -61
- data/lib/scorpio/resource_base.rb +57 -49
- data/lib/scorpio/response.rb +28 -10
- data/lib/scorpio/ur.rb +7 -3
- data/lib/scorpio/version.rb +1 -1
- data/lib/scorpio.rb +12 -6
- data/pages/Request_Configuration.md +69 -0
- data/pages/Security.md +50 -0
- data/scorpio.gemspec +6 -5
- metadata +28 -15
- data/documents/www.googleapis.com/discovery/v1/apis/discovery/v1/rest +0 -684
- data/lib/scorpio/openapi/v3/server.rb +0 -44
data/lib/scorpio/openapi.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Scorpio
|
|
4
4
|
module OpenAPI
|
|
5
|
-
class Error <
|
|
5
|
+
class Error < Scorpio::Error
|
|
6
6
|
end
|
|
7
7
|
# an error in the semantics of an openapi document. for example, an Operation with
|
|
8
8
|
# two body parameters (in v2, not possible in v3) is a SemanticError. an Operation
|
|
@@ -18,219 +18,39 @@ module Scorpio
|
|
|
18
18
|
autoload :Document, 'scorpio/openapi/document'
|
|
19
19
|
autoload :Reference, 'scorpio/openapi/reference'
|
|
20
20
|
autoload :Tag, 'scorpio/openapi/tag'
|
|
21
|
+
autoload(:Tags, 'scorpio/openapi/tag')
|
|
22
|
+
autoload(:Server, 'scorpio/openapi/server')
|
|
21
23
|
autoload :OperationsScope, 'scorpio/openapi/operations_scope'
|
|
22
24
|
|
|
23
|
-
module
|
|
24
|
-
openapi_document_schema = JSI::JSONSchemaDraft04.new_schema(::YAML.load_file(Scorpio.root.join(
|
|
25
|
-
'documents/github.com/OAI/OpenAPI-Specification/blob/oas3-schema/schemas/v3.0/schema.yaml'
|
|
26
|
-
)))
|
|
27
|
-
|
|
28
|
-
# the schema represented by Scorpio::OpenAPI::V3::Schema will describe schemas itself.
|
|
29
|
-
# JSI::Schema#describes_schema! enables this to implement the functionality of schemas.
|
|
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.describes_schema!([JSI::Schema::Draft04]) }
|
|
44
|
-
|
|
45
|
-
Document = openapi_document_schema.jsi_schema_module
|
|
46
|
-
|
|
47
|
-
# naming these is not strictly necessary, but is nice to have.
|
|
48
|
-
# generated: `puts Scorpio::OpenAPI::V3::Document.schema.definitions.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
|
|
25
|
+
module Response
|
|
115
26
|
end
|
|
116
|
-
module V2
|
|
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.
|
|
122
|
-
# JSI::Schema#describes_schema! enables this to implement the functionality of schemas.
|
|
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.describes_schema!([JSI::Schema::Draft04]) }
|
|
129
|
-
|
|
130
|
-
Document = openapi_document_schema.jsi_schema_module
|
|
131
|
-
|
|
132
|
-
# naming these is not strictly necessary, but is nice to have.
|
|
133
|
-
# generated: `puts Scorpio::OpenAPI::V2::Document.schema.definitions.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
|
-
MimeType = Document.definitions['mimeType']
|
|
146
|
-
Operation = Document.definitions['operation']
|
|
147
|
-
PathItem = Document.definitions['pathItem']
|
|
148
|
-
Responses = Document.definitions['responses']
|
|
149
|
-
ResponseValue = Document.definitions['responseValue']
|
|
150
|
-
Response = Document.definitions['response']
|
|
151
|
-
Headers = Document.definitions['headers']
|
|
152
|
-
Header = Document.definitions['header']
|
|
153
|
-
VendorExtension = Document.definitions['vendorExtension']
|
|
154
|
-
BodyParameter = Document.definitions['bodyParameter']
|
|
155
|
-
HeaderParameterSubSchema = Document.definitions['headerParameterSubSchema']
|
|
156
|
-
QueryParameterSubSchema = Document.definitions['queryParameterSubSchema']
|
|
157
|
-
FormDataParameterSubSchema = Document.definitions['formDataParameterSubSchema']
|
|
158
|
-
PathParameterSubSchema = Document.definitions['pathParameterSubSchema']
|
|
159
|
-
NonBodyParameter = Document.definitions['nonBodyParameter']
|
|
160
|
-
Parameter = Document.definitions['parameter']
|
|
161
|
-
Schema = Document.definitions['schema']
|
|
162
|
-
FileSchema = Document.definitions['fileSchema']
|
|
163
|
-
PrimitivesItems = Document.definitions['primitivesItems']
|
|
164
|
-
Security = Document.definitions['security']
|
|
165
|
-
SecurityRequirement = Document.definitions['securityRequirement']
|
|
166
|
-
Xml = Document.definitions['xml']
|
|
167
|
-
Tag = Document.definitions['tag']
|
|
168
|
-
SecurityDefinitions = Document.definitions['securityDefinitions']
|
|
169
|
-
BasicAuthenticationSecurity = Document.definitions['basicAuthenticationSecurity']
|
|
170
|
-
ApiKeySecurity = Document.definitions['apiKeySecurity']
|
|
171
|
-
Oauth2ImplicitSecurity = Document.definitions['oauth2ImplicitSecurity']
|
|
172
|
-
Oauth2PasswordSecurity = Document.definitions['oauth2PasswordSecurity']
|
|
173
|
-
Oauth2ApplicationSecurity = Document.definitions['oauth2ApplicationSecurity']
|
|
174
|
-
Oauth2AccessCodeSecurity = Document.definitions['oauth2AccessCodeSecurity']
|
|
175
|
-
Oauth2Scopes = Document.definitions['oauth2Scopes']
|
|
176
|
-
MediaTypeList = Document.definitions['mediaTypeList']
|
|
177
|
-
ParametersList = Document.definitions['parametersList']
|
|
178
|
-
SchemesList = Document.definitions['schemesList']
|
|
179
|
-
CollectionFormat = Document.definitions['collectionFormat']
|
|
180
|
-
CollectionFormatWithMulti = Document.definitions['collectionFormatWithMulti']
|
|
181
|
-
Title = Document.definitions['title']
|
|
182
|
-
Description = Document.definitions['description']
|
|
183
|
-
Default = Document.definitions['default']
|
|
184
|
-
MultipleOf = Document.definitions['multipleOf']
|
|
185
|
-
Maximum = Document.definitions['maximum']
|
|
186
|
-
ExclusiveMaximum = Document.definitions['exclusiveMaximum']
|
|
187
|
-
Minimum = Document.definitions['minimum']
|
|
188
|
-
ExclusiveMinimum = Document.definitions['exclusiveMinimum']
|
|
189
|
-
MaxLength = Document.definitions['maxLength']
|
|
190
|
-
MinLength = Document.definitions['minLength']
|
|
191
|
-
Pattern = Document.definitions['pattern']
|
|
192
|
-
MaxItems = Document.definitions['maxItems']
|
|
193
|
-
MinItems = Document.definitions['minItems']
|
|
194
|
-
UniqueItems = Document.definitions['uniqueItems']
|
|
195
|
-
Enum = Document.definitions['enum']
|
|
196
|
-
JsonReference = Document.definitions['jsonReference']
|
|
197
27
|
|
|
198
|
-
|
|
28
|
+
module Paths
|
|
199
29
|
end
|
|
200
30
|
|
|
201
|
-
|
|
202
|
-
|
|
31
|
+
module PathItem
|
|
32
|
+
end
|
|
203
33
|
|
|
34
|
+
module SecurityScheme
|
|
35
|
+
include(Document::Descendent)
|
|
204
36
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
include OpenAPI::Document
|
|
211
|
-
end
|
|
212
|
-
module Reference
|
|
213
|
-
include OpenAPI::Reference
|
|
37
|
+
# @return [Enumerable<OpenAPI::Operation>]
|
|
38
|
+
def operations
|
|
39
|
+
openapi_document.operations.select do |op|
|
|
40
|
+
op.security.respond_to?(:to_ary) && op.security.any? { |sr| sr.each_key.include?(propertyName) }
|
|
41
|
+
end
|
|
214
42
|
end
|
|
215
|
-
module Tag
|
|
216
|
-
include OpenAPI::Tag
|
|
217
|
-
end
|
|
218
|
-
require 'scorpio/openapi/v3/server'
|
|
219
|
-
end
|
|
220
43
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
include OpenAPI::Operation
|
|
224
|
-
end
|
|
225
|
-
module Document
|
|
226
|
-
include OpenAPI::Document
|
|
227
|
-
end
|
|
228
|
-
module JsonReference
|
|
229
|
-
include OpenAPI::Reference
|
|
230
|
-
end
|
|
231
|
-
module Tag
|
|
232
|
-
include OpenAPI::Tag
|
|
44
|
+
def propertyName
|
|
45
|
+
jsi_ptr.tokens.last
|
|
233
46
|
end
|
|
234
47
|
end
|
|
48
|
+
|
|
49
|
+
autoload(:V2, 'scorpio/openapi/v2')
|
|
50
|
+
autoload(:V3, 'scorpio/openapi/v3_0')
|
|
51
|
+
autoload(:V3_0, 'scorpio/openapi/v3_0')
|
|
52
|
+
autoload(:V3_1, 'scorpio/openapi/v3_1')
|
|
53
|
+
|
|
54
|
+
autoload(:SchemaElements, 'scorpio/openapi/schema_elements')
|
|
235
55
|
end
|
|
236
56
|
end
|
data/lib/scorpio/request.rb
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Scorpio
|
|
4
|
+
# a Request from a {Scorpio::OpenAPI::Operation}.
|
|
5
|
+
# Used by {Scorpio::OpenAPI::Operation#build_request} and related methods.
|
|
4
6
|
class Request
|
|
5
|
-
# media types for which Scorpio has implemented generating
|
|
6
|
-
|
|
7
|
-
SUPPORTED_REQUEST_MEDIA_TYPES = %w(
|
|
7
|
+
# media types for which Scorpio has implemented generating {Request#body} from {Request#body_object}
|
|
8
|
+
SUPPORTED_MEDIA_TYPES = %w(
|
|
8
9
|
application/json
|
|
9
10
|
application/x-www-form-urlencoded
|
|
10
11
|
).map(&:freeze).freeze
|
|
11
12
|
|
|
12
13
|
FALLBACK_CONTENT_TYPE = 'application/x-www-form-urlencoded'.freeze
|
|
13
14
|
|
|
15
|
+
DEFAULT_USER_AGENT = -"Scorpio/#{Scorpio::VERSION} (https://github.com/notEthan/scorpio) Faraday/#{Faraday::VERSION} Ruby/#{RUBY_VERSION}"
|
|
16
|
+
|
|
14
17
|
# see also Faraday::Env::MethodsWithBodies
|
|
15
18
|
METHODS_WITH_BODIES = %w(post put patch options).map(&:freeze).freeze
|
|
16
19
|
|
|
@@ -18,17 +21,10 @@ module Scorpio
|
|
|
18
21
|
if media_types.size == 1
|
|
19
22
|
media_types.first
|
|
20
23
|
else
|
|
21
|
-
|
|
24
|
+
SUPPORTED_MEDIA_TYPES.detect { |mt| media_types.include?(mt) }
|
|
22
25
|
end
|
|
23
26
|
end
|
|
24
27
|
|
|
25
|
-
# @param http_method [String]
|
|
26
|
-
# @return [Boolean]
|
|
27
|
-
def self.method_with_body?(http_method)
|
|
28
|
-
raise(ArgumentError) unless http_method.is_a?(String)
|
|
29
|
-
METHODS_WITH_BODIES.include?(http_method.downcase)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
28
|
module Configurables
|
|
33
29
|
attr_writer :path_params
|
|
34
30
|
def path_params
|
|
@@ -66,6 +62,11 @@ module Scorpio
|
|
|
66
62
|
operation.base_url(scheme: scheme, server: server, server_variables: server_variables)
|
|
67
63
|
end
|
|
68
64
|
|
|
65
|
+
# overriding url will cause all of path_params, query_params, querystring, scheme, server, server_variables, and base_url to be ignored
|
|
66
|
+
def url=(url)
|
|
67
|
+
@url = JSI::Util.uri(url)
|
|
68
|
+
end
|
|
69
|
+
|
|
69
70
|
attr_writer :body
|
|
70
71
|
def body
|
|
71
72
|
return @body if instance_variable_defined?(:@body)
|
|
@@ -75,13 +76,13 @@ module Scorpio
|
|
|
75
76
|
elsif content_type && content_type.form_urlencoded?
|
|
76
77
|
URI.encode_www_form(body_object)
|
|
77
78
|
|
|
78
|
-
# NOTE: the supported media types above should correspond to Request::
|
|
79
|
+
# NOTE: the supported media types above should correspond to Request::SUPPORTED_MEDIA_TYPES
|
|
79
80
|
|
|
80
81
|
else
|
|
81
82
|
if body_object.respond_to?(:to_str)
|
|
82
83
|
body_object
|
|
83
84
|
else
|
|
84
|
-
raise(NotImplementedError, "Scorpio does not know how to generate the request body with content_type = #{content_type.respond_to?(:to_str) ? content_type : content_type.inspect} for operation: #{operation.human_id}. Scorpio supports media types: #{
|
|
85
|
+
raise(NotImplementedError, -"Scorpio does not know how to generate the request body with content_type = #{content_type.respond_to?(:to_str) ? content_type : content_type.inspect} for operation: #{operation.human_id}. Scorpio supports media types: #{SUPPORTED_MEDIA_TYPES.join(', ')}. body_object was: #{body_object.pretty_inspect.chomp}")
|
|
85
86
|
end
|
|
86
87
|
end
|
|
87
88
|
else
|
|
@@ -109,6 +110,18 @@ module Scorpio
|
|
|
109
110
|
operation.user_agent
|
|
110
111
|
end
|
|
111
112
|
|
|
113
|
+
attr_writer(:accept)
|
|
114
|
+
def accept
|
|
115
|
+
return @accept if instance_variable_defined?(:@accept)
|
|
116
|
+
operation.accept
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
attr_writer(:authorization)
|
|
120
|
+
def authorization
|
|
121
|
+
return @authorization if instance_variable_defined?(:@authorization)
|
|
122
|
+
operation.authorization
|
|
123
|
+
end
|
|
124
|
+
|
|
112
125
|
attr_writer :faraday_builder
|
|
113
126
|
def faraday_builder
|
|
114
127
|
return @faraday_builder if instance_variable_defined?(:@faraday_builder)
|
|
@@ -129,35 +142,21 @@ module Scorpio
|
|
|
129
142
|
end
|
|
130
143
|
include Configurables
|
|
131
144
|
|
|
132
|
-
@
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
def self.request_class_by_operation(operation)
|
|
140
|
-
@request_class_by_operation[operation]
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
# @param configuration [#to_hash] a hash keyed with configurable attributes for
|
|
144
|
-
# the request - instance methods of Scorpio::Request::Configurables, whose values
|
|
145
|
-
# will be assigned for those attributes.
|
|
146
|
-
def initialize(configuration = {}, &b)
|
|
145
|
+
# @param configuration [#to_hash] A hash of configurable attributes or
|
|
146
|
+
# parameters for the request - instance methods of
|
|
147
|
+
# {Scorpio::Request::Configurables}, or request parameters defined by the
|
|
148
|
+
# operation.
|
|
149
|
+
def initialize(operation, **configuration, &b)
|
|
150
|
+
@operation = operation
|
|
147
151
|
configuration = JSI::Util.stringify_symbol_keys(configuration)
|
|
148
|
-
params_set = Set.new # the set of params that have been set
|
|
149
|
-
# do the Configurables first
|
|
150
152
|
configuration.each do |name, value|
|
|
151
|
-
if Configurables.public_method_defined?("#{name}=")
|
|
152
|
-
|
|
153
|
-
|
|
153
|
+
if Configurables.public_method_defined?(:"#{name}=")
|
|
154
|
+
public_send(:"#{name}=", value)
|
|
155
|
+
else
|
|
156
|
+
param = param_for(name) || raise(ArgumentError, -"unrecognized configuration value passed: #{name.inspect}")
|
|
157
|
+
set_param_from(param['in'], param['name'], value)
|
|
154
158
|
end
|
|
155
159
|
end
|
|
156
|
-
# then do other top-level params
|
|
157
|
-
configuration.reject { |name, _| params_set.include?(name) }.each do |name, value|
|
|
158
|
-
param = param_for(name) || raise(ArgumentError, "unrecognized configuration value passed: #{name.inspect}")
|
|
159
|
-
set_param_from(param['in'], param['name'], value)
|
|
160
|
-
end
|
|
161
160
|
|
|
162
161
|
if block_given?
|
|
163
162
|
yield self
|
|
@@ -165,7 +164,7 @@ module Scorpio
|
|
|
165
164
|
end
|
|
166
165
|
|
|
167
166
|
# @return [Scorpio::OpenAPI::Operation]
|
|
168
|
-
attr_reader
|
|
167
|
+
attr_reader(:operation)
|
|
169
168
|
|
|
170
169
|
# @return [Scorpio::OpenAPI::Document]
|
|
171
170
|
def openapi_document
|
|
@@ -178,6 +177,11 @@ module Scorpio
|
|
|
178
177
|
operation.http_method
|
|
179
178
|
end
|
|
180
179
|
|
|
180
|
+
# @return [Boolean]
|
|
181
|
+
def http_method_with_body?
|
|
182
|
+
METHODS_WITH_BODIES.include?(http_method.to_str.downcase)
|
|
183
|
+
end
|
|
184
|
+
|
|
181
185
|
# the template for the request's path, to be expanded with {Configurables#path_params} and appended to
|
|
182
186
|
# the request's {Configurables#base_url}
|
|
183
187
|
# @return [Addressable::Template]
|
|
@@ -191,13 +195,11 @@ module Scorpio
|
|
|
191
195
|
path_params = JSI::Util.stringify_symbol_keys(self.path_params)
|
|
192
196
|
missing_variables = path_template.variables - path_params.keys
|
|
193
197
|
if missing_variables.any?
|
|
194
|
-
raise(ArgumentError, "path #{operation.path_template_str}
|
|
195
|
-
"which were missing: #{missing_variables.inspect}")
|
|
198
|
+
raise(ArgumentError, -"missing params: #{missing_variables.inspect}\nfor path: #{operation.path_template_str}\nfor operation: #{operation.human_id}")
|
|
196
199
|
end
|
|
197
200
|
empty_variables = path_template.variables.select { |v| path_params[v].to_s.empty? }
|
|
198
201
|
if empty_variables.any?
|
|
199
|
-
raise(ArgumentError, "path #{operation.path_template_str}
|
|
200
|
-
"which were empty: #{empty_variables.inspect}")
|
|
202
|
+
raise(ArgumentError, -"empty params: #{empty_variables.inspect}\sfor path: #{operation.path_template_str}\nfor operation #{operation.human_id}")
|
|
201
203
|
end
|
|
202
204
|
|
|
203
205
|
path = path_template.expand(path_params)
|
|
@@ -210,6 +212,7 @@ module Scorpio
|
|
|
210
212
|
# the full URL for this request
|
|
211
213
|
# @return [Addressable::URI]
|
|
212
214
|
def url
|
|
215
|
+
return @url if instance_variable_defined?(:@url)
|
|
213
216
|
unless base_url
|
|
214
217
|
raise(ArgumentError, "no base_url has been specified for request")
|
|
215
218
|
end
|
|
@@ -242,11 +245,11 @@ module Scorpio
|
|
|
242
245
|
# builds a Faraday connection with this Request's faraday_builder and faraday_adapter.
|
|
243
246
|
# passes a given proc yield_ur to middleware to yield an Ur for requests made with the connection.
|
|
244
247
|
#
|
|
245
|
-
# @param yield_ur [Proc]
|
|
248
|
+
# @param yield_ur [Proc, nil]
|
|
246
249
|
# @return [::Faraday::Connection]
|
|
247
250
|
def faraday_connection(yield_ur = nil)
|
|
248
251
|
Faraday.new do |faraday_connection|
|
|
249
|
-
faraday_builder.call(faraday_connection)
|
|
252
|
+
faraday_builder.call(faraday_connection) if faraday_builder
|
|
250
253
|
if yield_ur
|
|
251
254
|
-> { ::Ur::Faraday }.() # autoload trigger
|
|
252
255
|
|
|
@@ -289,7 +292,7 @@ module Scorpio
|
|
|
289
292
|
nil
|
|
290
293
|
else
|
|
291
294
|
raise(AmbiguousParameter.new(
|
|
292
|
-
"There are multiple parameters for #{name}. matched parameters were: #{params.pretty_inspect.chomp}"
|
|
295
|
+
-"There are multiple parameters for #{name}. matched parameters were: #{params.pretty_inspect.chomp}"
|
|
293
296
|
).tap { |e| e.name = name })
|
|
294
297
|
end
|
|
295
298
|
end
|
|
@@ -299,15 +302,15 @@ module Scorpio
|
|
|
299
302
|
# @raise [Scorpio::ParameterError] if no parameter has the given name
|
|
300
303
|
# @raise (see #param_for)
|
|
301
304
|
def param_for!(name)
|
|
302
|
-
param_for(name) || raise(ParameterError, "There is no parameter named #{name} on operation #{operation.human_id}:\n#{operation.pretty_inspect.chomp}")
|
|
305
|
+
param_for(name) || raise(ParameterError, -"There is no parameter named #{name} on operation #{operation.human_id}:\n#{operation.pretty_inspect.chomp}")
|
|
303
306
|
end
|
|
304
307
|
|
|
305
|
-
#
|
|
308
|
+
# Applies the given value to the appropriate parameter of the request
|
|
306
309
|
# @param param_in [String, Symbol] one of 'path', 'query', 'header', or 'cookie' - where to apply
|
|
307
|
-
# the
|
|
310
|
+
# the given value
|
|
308
311
|
# @param name [String, Symbol] the parameter name to apply the value to
|
|
309
|
-
# @param value [Object]
|
|
310
|
-
# @return [Object]
|
|
312
|
+
# @param value [Object] parameter value
|
|
313
|
+
# @return [Object] the given parameter value
|
|
311
314
|
# @raise [ArgumentError] invalid `param_in` parameter
|
|
312
315
|
# @raise [NotImplementedError] cookies aren't implemented
|
|
313
316
|
def set_param_from(param_in, name, value)
|
|
@@ -318,11 +321,11 @@ module Scorpio
|
|
|
318
321
|
elsif param_in == 'query'
|
|
319
322
|
self.query_params = (self.query_params || {}).merge(name => value)
|
|
320
323
|
elsif param_in == 'header'
|
|
321
|
-
self.headers = self.headers.merge(name => value)
|
|
324
|
+
self.headers = self.headers.merge(name => value.to_str)
|
|
322
325
|
elsif param_in == 'cookie'
|
|
323
|
-
raise(NotImplementedError, "cookies not implemented: #{name.inspect} => #{value.inspect}")
|
|
326
|
+
raise(NotImplementedError, -"cookies not implemented: #{name.inspect} => #{value.inspect}")
|
|
324
327
|
else
|
|
325
|
-
raise(ArgumentError, "cannot set param from param_in = #{param_in.inspect} (name: #{name.pretty_inspect.chomp}, value: #{value.pretty_inspect.chomp})")
|
|
328
|
+
raise(ArgumentError, -"cannot set param from param_in = #{param_in.inspect} (name: #{name.pretty_inspect.chomp}, value: #{value.pretty_inspect.chomp})")
|
|
326
329
|
end
|
|
327
330
|
value
|
|
328
331
|
end
|
|
@@ -340,12 +343,12 @@ module Scorpio
|
|
|
340
343
|
elsif param_in == 'query'
|
|
341
344
|
query_params ? query_params[name] : nil
|
|
342
345
|
elsif param_in == 'header'
|
|
343
|
-
_, value = headers.detect { |headername, _| headername.
|
|
346
|
+
_, value = headers.detect { |headername, _| headername.casecmp?(name) }
|
|
344
347
|
value
|
|
345
348
|
elsif param_in == 'cookie'
|
|
346
|
-
raise(NotImplementedError, "cookies not implemented: #{name.inspect}")
|
|
349
|
+
raise(NotImplementedError, -"cookies not implemented: #{name.inspect}")
|
|
347
350
|
else
|
|
348
|
-
raise(OpenAPI::SemanticError, "cannot get param from param_in = #{param_in.inspect} (name: #{name.pretty_inspect.chomp})")
|
|
351
|
+
raise(OpenAPI::SemanticError, -"cannot get param from param_in = #{param_in.inspect} (name: #{name.pretty_inspect.chomp})")
|
|
349
352
|
end
|
|
350
353
|
end
|
|
351
354
|
|
|
@@ -357,6 +360,8 @@ module Scorpio
|
|
|
357
360
|
if user_agent
|
|
358
361
|
headers['User-Agent'] = user_agent
|
|
359
362
|
end
|
|
363
|
+
headers['Accept'] = accept if accept
|
|
364
|
+
headers['Authorization'] = authorization if authorization
|
|
360
365
|
if !content_type_header
|
|
361
366
|
if media_type
|
|
362
367
|
headers['Content-Type'] = media_type
|
|
@@ -382,12 +387,13 @@ module Scorpio
|
|
|
382
387
|
# parsed according to an understood media type, and instantiated with the applicable
|
|
383
388
|
# response schema if one is specified. see {Scorpio::Response#body_object} for more detail.
|
|
384
389
|
#
|
|
390
|
+
# @param mutable (see Response#body_object)
|
|
385
391
|
# @raise [Scorpio::HTTPError] if the request returns a 4xx or 5xx status, the appropriate
|
|
386
392
|
# error is raised - see {Scorpio::HTTPErrors}
|
|
387
|
-
def run
|
|
393
|
+
def run(mutable: false)
|
|
388
394
|
ur = run_ur
|
|
389
395
|
ur.raise_on_http_error
|
|
390
|
-
ur.response.body_object
|
|
396
|
+
ur.response.body_object(mutable: mutable)
|
|
391
397
|
end
|
|
392
398
|
|
|
393
399
|
# Runs this request, passing the resulting Ur to the given block.
|
|
@@ -407,8 +413,8 @@ module Scorpio
|
|
|
407
413
|
while page_ur
|
|
408
414
|
unless page_ur.is_a?(Scorpio::Ur)
|
|
409
415
|
raise(TypeError, [
|
|
410
|
-
"next_page must result in a #{Scorpio::Ur}",
|
|
411
|
-
"this should be the result of #run_ur from a #{OpenAPI::Operation} or #{Request}",
|
|
416
|
+
-"next_page must result in a #{Scorpio::Ur}",
|
|
417
|
+
-"this should be the result of #run_ur from a #{OpenAPI::Operation} or #{Request}",
|
|
412
418
|
].join("\n"))
|
|
413
419
|
end
|
|
414
420
|
page_ur.raise_on_http_error if raise_on_http_error
|