scorpio 0.2.3 → 0.3.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 +5 -0
- data/README.md +4 -2
- data/lib/scorpio.rb +9 -22
- data/lib/scorpio/google_api_document.rb +13 -16
- data/lib/scorpio/openapi.rb +141 -143
- data/lib/scorpio/openapi/document.rb +167 -0
- data/lib/scorpio/openapi/operation.rb +208 -0
- data/lib/scorpio/openapi/operations_scope.rb +29 -0
- data/lib/scorpio/openapi/v3/server.rb +32 -0
- data/lib/scorpio/request.rb +227 -0
- data/lib/scorpio/resource_base.rb +148 -182
- data/lib/scorpio/response.rb +34 -0
- data/lib/scorpio/ur.rb +33 -0
- data/lib/scorpio/version.rb +1 -1
- data/scorpio.gemspec +3 -4
- metadata +32 -36
- data/lib/scorpio/json-schema-fragments.rb +0 -191
- data/lib/scorpio/json.rb +0 -5
- data/lib/scorpio/json/node.rb +0 -256
- data/lib/scorpio/schema.rb +0 -249
- data/lib/scorpio/schema_instance_base.rb +0 -325
- data/lib/scorpio/schema_instance_base/to_rb.rb +0 -127
- data/lib/scorpio/schema_instance_json_coder.rb +0 -83
- data/lib/scorpio/struct_json_coder.rb +0 -30
- data/lib/scorpio/typelike_modules.rb +0 -164
- data/lib/scorpio/util.rb +0 -89
- data/lib/scorpio/util/faraday/response_media_type.rb +0 -15
@@ -0,0 +1,167 @@
|
|
1
|
+
module Scorpio
|
2
|
+
module OpenAPI
|
3
|
+
module Document
|
4
|
+
class << self
|
5
|
+
def from_instance(instance)
|
6
|
+
if instance.is_a?(Hash)
|
7
|
+
instance = JSI::JSON::Node.new_doc(instance)
|
8
|
+
end
|
9
|
+
if instance.is_a?(JSI::JSON::Node)
|
10
|
+
if instance['swagger'] =~ /\A2(\.|\z)/
|
11
|
+
instance = Scorpio::OpenAPI::V2::Document.new(instance)
|
12
|
+
elsif instance['openapi'] =~ /\A3(\.|\z)/
|
13
|
+
instance = Scorpio::OpenAPI::V3::Document.new(instance)
|
14
|
+
else
|
15
|
+
raise(ArgumentError, "instance does not look like a recognized openapi document")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
if instance.is_a?(Scorpio::OpenAPI::Document)
|
19
|
+
instance
|
20
|
+
elsif instance.is_a?(JSI::Base)
|
21
|
+
raise(TypeError, "instance is unexpected JSI type: #{instance.class.inspect}")
|
22
|
+
elsif instance.respond_to?(:to_hash)
|
23
|
+
from_instance(instance.to_hash)
|
24
|
+
else
|
25
|
+
raise(TypeError, "instance does not look like a hash (json object)")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module Configurables
|
31
|
+
attr_writer :request_headers
|
32
|
+
def request_headers
|
33
|
+
return @request_headers if instance_variable_defined?(:@request_headers)
|
34
|
+
{}.freeze
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_writer :user_agent
|
38
|
+
def user_agent
|
39
|
+
return @user_agent if instance_variable_defined?(:@user_agent)
|
40
|
+
"Scorpio/#{Scorpio::VERSION} (https://github.com/notEthan/scorpio) Faraday/#{Faraday::VERSION} Ruby/#{RUBY_VERSION}"
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_writer :faraday_builder
|
44
|
+
def faraday_builder
|
45
|
+
return @faraday_builder if instance_variable_defined?(:@faraday_builder)
|
46
|
+
-> (_) { }
|
47
|
+
end
|
48
|
+
|
49
|
+
attr_writer :faraday_adapter
|
50
|
+
def faraday_adapter
|
51
|
+
return @faraday_adapter if instance_variable_defined?(:@faraday_adapter)
|
52
|
+
[Faraday.default_adapter]
|
53
|
+
end
|
54
|
+
|
55
|
+
attr_writer :logger
|
56
|
+
def logger
|
57
|
+
return @logger if instance_variable_defined?(:@logger)
|
58
|
+
(Object.const_defined?(:Rails) && ::Rails.respond_to?(:logger) ? ::Rails.logger : nil)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
include Configurables
|
62
|
+
|
63
|
+
def v2?
|
64
|
+
is_a?(V2::Document)
|
65
|
+
end
|
66
|
+
|
67
|
+
def v3?
|
68
|
+
is_a?(V3::Document)
|
69
|
+
end
|
70
|
+
|
71
|
+
def operations
|
72
|
+
return @operations if instance_variable_defined?(:@operations)
|
73
|
+
@operations = OperationsScope.new(self)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
module V3
|
78
|
+
raise(Bug) unless const_defined?(:Document)
|
79
|
+
class Document
|
80
|
+
module Configurables
|
81
|
+
def scheme
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
attr_writer :server
|
85
|
+
def server
|
86
|
+
return @server if instance_variable_defined?(:@server)
|
87
|
+
if servers.respond_to?(:to_ary) && servers.size == 1
|
88
|
+
servers.first
|
89
|
+
else
|
90
|
+
nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
attr_writer :server_variables
|
94
|
+
def server_variables
|
95
|
+
return @server_variables if instance_variable_defined?(:@server_variables)
|
96
|
+
{}.freeze
|
97
|
+
end
|
98
|
+
attr_writer :base_url
|
99
|
+
def base_url(scheme: nil, server: self.server, server_variables: self.server_variables)
|
100
|
+
return @base_url if instance_variable_defined?(:@base_url)
|
101
|
+
if server
|
102
|
+
server.expanded_url(server_variables)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
attr_writer :request_media_type
|
107
|
+
def request_media_type
|
108
|
+
return @request_media_type if instance_variable_defined?(:@request_media_type)
|
109
|
+
nil
|
110
|
+
end
|
111
|
+
end
|
112
|
+
include Configurables
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
module V2
|
117
|
+
raise(Bug) unless const_defined?(:Document)
|
118
|
+
class Document
|
119
|
+
module Configurables
|
120
|
+
attr_writer :scheme
|
121
|
+
def scheme
|
122
|
+
return @scheme if instance_variable_defined?(:@scheme)
|
123
|
+
if schemes.nil?
|
124
|
+
'https'
|
125
|
+
elsif schemes.respond_to?(:to_ary)
|
126
|
+
# prefer https, then http, then anything else since we probably don't support.
|
127
|
+
schemes.sort_by { |s| ['https', 'http'].index(s) || (1.0 / 0) }.first
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def server
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
def server_variables
|
135
|
+
nil
|
136
|
+
end
|
137
|
+
|
138
|
+
attr_writer :base_url
|
139
|
+
# the base url to which paths are appended.
|
140
|
+
# by default this looks at the openapi document's schemes, picking https or http first.
|
141
|
+
# it looks at the openapi_document's host and basePath.
|
142
|
+
def base_url(scheme: self.scheme, server: nil, server_variables: nil)
|
143
|
+
return @base_url if instance_variable_defined?(:@base_url)
|
144
|
+
if host && scheme
|
145
|
+
Addressable::URI.new(
|
146
|
+
scheme: scheme,
|
147
|
+
host: host,
|
148
|
+
path: basePath,
|
149
|
+
).to_s
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
attr_writer :request_media_type
|
154
|
+
def request_media_type
|
155
|
+
return @request_media_type if instance_variable_defined?(:@request_media_type)
|
156
|
+
if consumes.respond_to?(:to_ary)
|
157
|
+
Request.best_media_type(consumes)
|
158
|
+
else
|
159
|
+
nil
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
include Configurables
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
module Scorpio
|
2
|
+
module OpenAPI
|
3
|
+
module Operation
|
4
|
+
module Configurables
|
5
|
+
attr_writer :base_url
|
6
|
+
def base_url(scheme: self.scheme, server: self.server, server_variables: self.server_variables)
|
7
|
+
return @base_url if instance_variable_defined?(:@base_url)
|
8
|
+
openapi_document.base_url(scheme: scheme, server: server, server_variables: server_variables)
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_writer :request_headers
|
12
|
+
def request_headers
|
13
|
+
return @request_headers if instance_variable_defined?(:@request_headers)
|
14
|
+
openapi_document.request_headers
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_writer :user_agent
|
18
|
+
def user_agent
|
19
|
+
return @user_agent if instance_variable_defined?(:@user_agent)
|
20
|
+
openapi_document.user_agent
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_writer :faraday_builder
|
24
|
+
def faraday_builder
|
25
|
+
return @faraday_builder if instance_variable_defined?(:@faraday_builder)
|
26
|
+
openapi_document.faraday_builder
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_writer :faraday_adapter
|
30
|
+
def faraday_adapter
|
31
|
+
return @faraday_adapter if instance_variable_defined?(:@faraday_adapter)
|
32
|
+
openapi_document.faraday_adapter
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_writer :logger
|
36
|
+
def logger
|
37
|
+
return @logger if instance_variable_defined?(:@logger)
|
38
|
+
openapi_document.logger
|
39
|
+
end
|
40
|
+
end
|
41
|
+
include Configurables
|
42
|
+
|
43
|
+
def openapi_document
|
44
|
+
parents.detect { |p| p.is_a?(Scorpio::OpenAPI::Document) }
|
45
|
+
end
|
46
|
+
|
47
|
+
def path
|
48
|
+
return @path if instance_variable_defined?(:@path)
|
49
|
+
@path = begin
|
50
|
+
parent_is_pathitem = parent.is_a?(Scorpio::OpenAPI::V2::PathItem) || parent.is_a?(Scorpio::OpenAPI::V3::PathItem)
|
51
|
+
parent_parent_is_paths = parent.parent.is_a?(Scorpio::OpenAPI::V2::Paths) || parent.parent.is_a?(Scorpio::OpenAPI::V3::Paths)
|
52
|
+
if parent_is_pathitem && parent_parent_is_paths
|
53
|
+
parent.instance.path.last
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def http_method
|
59
|
+
return @http_method if instance_variable_defined?(:@http_method)
|
60
|
+
@http_method = begin
|
61
|
+
parent_is_pathitem = parent.is_a?(Scorpio::OpenAPI::V2::PathItem) || parent.is_a?(Scorpio::OpenAPI::V3::PathItem)
|
62
|
+
if parent_is_pathitem
|
63
|
+
instance.path.last
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def build_request(*a, &b)
|
69
|
+
request = Scorpio::Request.new(self, *a, &b)
|
70
|
+
end
|
71
|
+
|
72
|
+
def run_ur(*a, &b)
|
73
|
+
build_request(*a, &b).run_ur
|
74
|
+
end
|
75
|
+
|
76
|
+
def run(*a, &b)
|
77
|
+
build_request(*a, &b).run
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
module V3
|
82
|
+
raise(Bug) unless const_defined?(:Operation)
|
83
|
+
class Operation
|
84
|
+
module Configurables
|
85
|
+
def scheme
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
|
89
|
+
attr_writer :server
|
90
|
+
def server
|
91
|
+
return @server if instance_variable_defined?(:@server)
|
92
|
+
openapi_document.server
|
93
|
+
end
|
94
|
+
|
95
|
+
attr_writer :server_variables
|
96
|
+
def server_variables
|
97
|
+
return @server_variables if instance_variable_defined?(:@server_variables)
|
98
|
+
openapi_document.server_variables
|
99
|
+
end
|
100
|
+
|
101
|
+
attr_writer :request_media_type
|
102
|
+
def request_media_type
|
103
|
+
return @request_media_type if instance_variable_defined?(:@request_media_type)
|
104
|
+
if requestBody && requestBody['content']
|
105
|
+
Request.best_media_type(requestBody['content'].keys)
|
106
|
+
else
|
107
|
+
openapi_document.request_media_type
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
include Configurables
|
112
|
+
|
113
|
+
def request_schema(media_type: self.request_media_type)
|
114
|
+
# TODO typechecking on requestBody & children
|
115
|
+
requestBody &&
|
116
|
+
requestBody['content'] &&
|
117
|
+
requestBody['content'][media_type] &&
|
118
|
+
requestBody['content'][media_type]['schema'] &&
|
119
|
+
requestBody['content'][media_type]['schema'].deref
|
120
|
+
end
|
121
|
+
|
122
|
+
def request_schemas
|
123
|
+
if requestBody && requestBody['content']
|
124
|
+
# oamt is for Scorpio::OpenAPI::V3::MediaType
|
125
|
+
requestBody['content'].values.map { |oamt| oamt['schema'] }.compact.map(&:deref)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# @return JSI::Schema
|
130
|
+
def response_schema(status: , media_type: )
|
131
|
+
status = status.to_s if status.is_a?(Numeric)
|
132
|
+
if self.responses
|
133
|
+
# Scorpio::OpenAPI::V3::Response
|
134
|
+
_, oa_response = self.responses.detect { |k, v| k.to_s == status }
|
135
|
+
oa_response ||= self.responses['default']
|
136
|
+
end
|
137
|
+
oa_media_types = oa_response ? oa_response['content'] : nil # Scorpio::OpenAPI::V3::MediaTypes
|
138
|
+
oa_media_type = oa_media_types ? oa_media_types[media_type] : nil # Scorpio::OpenAPI::V3::MediaType
|
139
|
+
oa_schema = oa_media_type ? oa_media_type['schema'] : nil # Scorpio::OpenAPI::V3::Schema
|
140
|
+
oa_schema ? JSI::Schema.new(oa_schema) : nil
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
module V2
|
145
|
+
raise(Bug) unless const_defined?(:Operation)
|
146
|
+
class Operation
|
147
|
+
module Configurables
|
148
|
+
attr_writer :scheme
|
149
|
+
def scheme
|
150
|
+
return @scheme if instance_variable_defined?(:@scheme)
|
151
|
+
openapi_document.scheme
|
152
|
+
end
|
153
|
+
def server
|
154
|
+
nil
|
155
|
+
end
|
156
|
+
def server_variables
|
157
|
+
nil
|
158
|
+
end
|
159
|
+
|
160
|
+
attr_writer :request_media_type
|
161
|
+
def request_media_type
|
162
|
+
return @request_media_type if instance_variable_defined?(:@request_media_type)
|
163
|
+
if key?('consumes')
|
164
|
+
Request.best_media_type(consumes)
|
165
|
+
else
|
166
|
+
openapi_document.request_media_type
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
include Configurables
|
171
|
+
|
172
|
+
# there should only be one body parameter; this returns it
|
173
|
+
def body_parameter
|
174
|
+
body_parameters = (parameters || []).select { |parameter| parameter['in'] == 'body' }
|
175
|
+
if body_parameters.size == 0
|
176
|
+
nil
|
177
|
+
elsif body_parameters.size == 1
|
178
|
+
body_parameters.first
|
179
|
+
else
|
180
|
+
raise(Bug) # TODO BLAME
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def request_schema(media_type: nil)
|
185
|
+
if body_parameter && body_parameter['schema']
|
186
|
+
JSI::Schema.new(body_parameter['schema'])
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def request_schemas
|
191
|
+
[request_schema]
|
192
|
+
end
|
193
|
+
|
194
|
+
# @return JSI::Schema
|
195
|
+
def response_schema(status: , media_type: nil)
|
196
|
+
status = status.to_s if status.is_a?(Numeric)
|
197
|
+
if self.responses
|
198
|
+
# Scorpio::OpenAPI::V2::Response
|
199
|
+
_, oa_response = self.responses.detect { |k, v| k.to_s == status }
|
200
|
+
oa_response ||= self.responses['default']
|
201
|
+
end
|
202
|
+
oa_response_schema = oa_response ? oa_response['schema'] : nil # Scorpio::OpenAPI::V2::Schema
|
203
|
+
oa_response_schema ? JSI::Schema.new(oa_response_schema) : nil
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Scorpio
|
2
|
+
module OpenAPI
|
3
|
+
class OperationsScope
|
4
|
+
include JSI::Memoize
|
5
|
+
|
6
|
+
def initialize(openapi_document)
|
7
|
+
@openapi_document = openapi_document
|
8
|
+
end
|
9
|
+
attr_reader :openapi_document
|
10
|
+
|
11
|
+
def each
|
12
|
+
openapi_document.paths.each do |path, path_item|
|
13
|
+
path_item.each do |http_method, operation|
|
14
|
+
if operation.is_a?(Scorpio::OpenAPI::Operation)
|
15
|
+
yield operation
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
include Enumerable
|
21
|
+
|
22
|
+
def [](operationId_)
|
23
|
+
memoize(:[], operationId_) do |operationId|
|
24
|
+
detect { |operation| operation.operationId == operationId }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Scorpio
|
2
|
+
module OpenAPI
|
3
|
+
module V3
|
4
|
+
raise(Bug) unless const_defined?(:Server)
|
5
|
+
class Server
|
6
|
+
def expanded_url(given_server_variables)
|
7
|
+
if variables
|
8
|
+
server_variables = (given_server_variables.keys | variables.keys).map do |key|
|
9
|
+
server_variable = variables[key]
|
10
|
+
if server_variable && server_variable.enum
|
11
|
+
unless server_variable.enum.include?(given_server_variables[key])
|
12
|
+
warn # TODO BLAME
|
13
|
+
end
|
14
|
+
end
|
15
|
+
if given_server_variables.key?(key)
|
16
|
+
{key => given_server_variables[key]}
|
17
|
+
elsif server_variable.key?('default')
|
18
|
+
{key => server_variable.default}
|
19
|
+
else
|
20
|
+
{}
|
21
|
+
end
|
22
|
+
end.inject({}, &:update)
|
23
|
+
else
|
24
|
+
server_variables = given_server_variables
|
25
|
+
end
|
26
|
+
template = Addressable::Template.new(url)
|
27
|
+
template.expand(server_variables)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
module Scorpio
|
2
|
+
class Request
|
3
|
+
SUPPORTED_REQUEST_MEDIA_TYPES = ['application/json', 'application/x-www-form-urlencoded']
|
4
|
+
def self.best_media_type(media_types)
|
5
|
+
if media_types.size == 1
|
6
|
+
media_types.first
|
7
|
+
else
|
8
|
+
SUPPORTED_REQUEST_MEDIA_TYPES.detect { |mt| media_types.include?(mt) }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Configurables
|
13
|
+
attr_writer :path_params
|
14
|
+
def path_params
|
15
|
+
return @path_params if instance_variable_defined?(:@path_params)
|
16
|
+
{}.freeze
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_writer :query_params
|
20
|
+
def query_params
|
21
|
+
return @query_params if instance_variable_defined?(:@query_params)
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_writer :scheme
|
26
|
+
def scheme
|
27
|
+
return @scheme if instance_variable_defined?(:@scheme)
|
28
|
+
operation.scheme
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_writer :server
|
32
|
+
def server
|
33
|
+
return @server if instance_variable_defined?(:@server)
|
34
|
+
operation.server
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_writer :server_variables
|
38
|
+
def server_variables
|
39
|
+
return @server_variables if instance_variable_defined?(:@server_variables)
|
40
|
+
operation.server_variables
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_writer :base_url
|
44
|
+
def base_url
|
45
|
+
return @base_url if instance_variable_defined?(:@base_url)
|
46
|
+
operation.base_url(scheme: scheme, server: server, server_variables: server_variables)
|
47
|
+
end
|
48
|
+
|
49
|
+
attr_writer :body
|
50
|
+
def body
|
51
|
+
return @body if instance_variable_defined?(:@body)
|
52
|
+
if instance_variable_defined?(:@body_object)
|
53
|
+
# TODO handle media types like `application/schema-instance+json`
|
54
|
+
if media_type == 'application/json'
|
55
|
+
JSON.pretty_generate(JSI::Typelike.as_json(body_object))
|
56
|
+
elsif media_type == "application/x-www-form-urlencoded"
|
57
|
+
URI.encode_www_form(body_object)
|
58
|
+
|
59
|
+
# NOTE: the supported media types above should correspond to Request::SUPPORTED_REQUEST_MEDIA_TYPES
|
60
|
+
|
61
|
+
else
|
62
|
+
if body_object.respond_to?(:to_str)
|
63
|
+
body_object
|
64
|
+
else
|
65
|
+
raise(NotImplementedError)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
else
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
attr_accessor :body_object
|
74
|
+
|
75
|
+
attr_writer :headers
|
76
|
+
def headers
|
77
|
+
return @headers if instance_variable_defined?(:@headers)
|
78
|
+
operation.request_headers
|
79
|
+
end
|
80
|
+
|
81
|
+
attr_writer :media_type
|
82
|
+
def media_type
|
83
|
+
return @media_type if instance_variable_defined?(:@media_type)
|
84
|
+
content_type_header ? content_type_attrs.media_type : operation.request_media_type
|
85
|
+
end
|
86
|
+
|
87
|
+
attr_writer :user_agent
|
88
|
+
def user_agent
|
89
|
+
return @user_agent if instance_variable_defined?(:@user_agent)
|
90
|
+
operation.user_agent
|
91
|
+
end
|
92
|
+
|
93
|
+
attr_writer :faraday_builder
|
94
|
+
def faraday_builder
|
95
|
+
return @faraday_builder if instance_variable_defined?(:@faraday_builder)
|
96
|
+
operation.faraday_builder
|
97
|
+
end
|
98
|
+
|
99
|
+
attr_writer :faraday_adapter
|
100
|
+
def faraday_adapter
|
101
|
+
return @faraday_adapter if instance_variable_defined?(:@faraday_adapter)
|
102
|
+
operation.faraday_adapter
|
103
|
+
end
|
104
|
+
|
105
|
+
attr_writer :logger
|
106
|
+
def logger
|
107
|
+
return @logger if instance_variable_defined?(:@logger)
|
108
|
+
operation.logger
|
109
|
+
end
|
110
|
+
end
|
111
|
+
include Configurables
|
112
|
+
|
113
|
+
def initialize(operation, **configuration, &b)
|
114
|
+
configuration.each do |k, v|
|
115
|
+
settername = "#{k}="
|
116
|
+
if Configurables.public_method_defined?(settername)
|
117
|
+
Configurables.instance_method(settername).bind(self).call(v)
|
118
|
+
else
|
119
|
+
raise(ArgumentError, "unsupported configuration value passed: #{k.inspect} => #{v.inspect}")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
@operation = operation
|
124
|
+
if block_given?
|
125
|
+
yield self
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
attr_reader :operation
|
130
|
+
|
131
|
+
def openapi_document
|
132
|
+
operation.openapi_document
|
133
|
+
end
|
134
|
+
|
135
|
+
def http_method
|
136
|
+
operation.http_method.downcase.to_sym
|
137
|
+
end
|
138
|
+
|
139
|
+
def path_template
|
140
|
+
Addressable::Template.new(operation.path)
|
141
|
+
end
|
142
|
+
|
143
|
+
def path
|
144
|
+
missing_variables = path_template.variables - path_params.keys
|
145
|
+
if missing_variables.any?
|
146
|
+
raise(ArgumentError, "path #{operation.path} for operation #{operation.operationId} requires path_params " +
|
147
|
+
"which were missing: #{missing_variables.inspect}")
|
148
|
+
end
|
149
|
+
empty_variables = path_template.variables.select { |v| path_params[v].to_s.empty? }
|
150
|
+
if empty_variables.any?
|
151
|
+
raise(ArgumentError, "path #{operation.path} for operation #{operation.operationId} requires path_params " +
|
152
|
+
"which were empty: #{empty_variables.inspect}")
|
153
|
+
end
|
154
|
+
|
155
|
+
path_template.expand(path_params).tap do |path|
|
156
|
+
if query_params
|
157
|
+
path.query_values = query_params
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def url
|
163
|
+
unless base_url
|
164
|
+
raise(ArgumentError, "no base_url has been specified for request")
|
165
|
+
end
|
166
|
+
# we do not use Addressable::URI#join as the paths should just be concatenated, not resolved.
|
167
|
+
# we use File.join just to deal with consecutive slashes.
|
168
|
+
url = File.join(base_url, path)
|
169
|
+
url = Addressable::URI.parse(url)
|
170
|
+
end
|
171
|
+
|
172
|
+
def content_type_attrs
|
173
|
+
Ur::ContentTypeAttrs.new(content_type)
|
174
|
+
end
|
175
|
+
|
176
|
+
def content_type_header
|
177
|
+
headers.each do |k, v|
|
178
|
+
return v if k =~ /\Acontent[-_]type\z/i
|
179
|
+
end
|
180
|
+
nil
|
181
|
+
end
|
182
|
+
|
183
|
+
def content_type
|
184
|
+
content_type_header || media_type
|
185
|
+
end
|
186
|
+
|
187
|
+
def request_schema(media_type: self.media_type)
|
188
|
+
operation.request_schema(media_type: media_type)
|
189
|
+
end
|
190
|
+
|
191
|
+
def request_schema_class(media_type: self.media_type)
|
192
|
+
JSI.class_for_schema(request_schema(media_type: media_type))
|
193
|
+
end
|
194
|
+
|
195
|
+
def faraday_connection(yield_ur)
|
196
|
+
Faraday.new do |faraday_connection|
|
197
|
+
faraday_builder.call(faraday_connection)
|
198
|
+
::Ur::Faraday # autoload trigger
|
199
|
+
faraday_connection.response(:yield_ur, ur_class: Scorpio::Ur, logger: self.logger, &yield_ur)
|
200
|
+
faraday_connection.adapter(*faraday_adapter)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def run_ur
|
205
|
+
headers = {}
|
206
|
+
if user_agent
|
207
|
+
headers['User-Agent'] = user_agent
|
208
|
+
end
|
209
|
+
if media_type && !content_type_header
|
210
|
+
headers['Content-Type'] = media_type
|
211
|
+
end
|
212
|
+
if self.headers
|
213
|
+
headers.update(self.headers)
|
214
|
+
end
|
215
|
+
ur = nil
|
216
|
+
faraday_connection(-> (yur) { ur = yur }).run_request(http_method, url, body, headers)
|
217
|
+
ur.scorpio_request = self
|
218
|
+
ur
|
219
|
+
end
|
220
|
+
|
221
|
+
def run
|
222
|
+
ur = run_ur
|
223
|
+
ur.raise_on_http_error
|
224
|
+
ur.response.body_object
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|