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
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'addressable/template'
|
2
2
|
require 'faraday'
|
3
|
-
require 'scorpio/util/faraday/response_media_type'
|
4
3
|
|
5
4
|
module Scorpio
|
6
5
|
# see also Faraday::Env::MethodsWithBodies
|
@@ -10,6 +9,9 @@ module Scorpio
|
|
10
9
|
|
11
10
|
class ResourceBase
|
12
11
|
class << self
|
12
|
+
# a hash of accessor names (Symbol) to default getter methods (UnboundMethod), used to determine
|
13
|
+
# what accessors have been overridden from their defaults.
|
14
|
+
(-> (x) { define_method(:inheritable_accessor_defaults) { x } }).({})
|
13
15
|
def define_inheritable_accessor(accessor, options = {})
|
14
16
|
if options[:default_getter]
|
15
17
|
# the value before the field is set (overwritten) is the result of the default_getter proc
|
@@ -19,6 +21,7 @@ module Scorpio
|
|
19
21
|
default_value = options[:default_value]
|
20
22
|
define_singleton_method(accessor) { default_value }
|
21
23
|
end
|
24
|
+
inheritable_accessor_defaults[accessor] = self.singleton_class.instance_method(accessor)
|
22
25
|
# field setter method. redefines the getter, replacing the method with one that returns the
|
23
26
|
# setter's argument (that being inherited to the scope of the define_method(accessor) block
|
24
27
|
define_singleton_method(:"#{accessor}=") do |value|
|
@@ -40,80 +43,76 @@ module Scorpio
|
|
40
43
|
end
|
41
44
|
end
|
42
45
|
end
|
43
|
-
# the class on which the openapi document is defined. subclasses use the openapi document set on this class
|
44
|
-
# (except in the unlikely event it is overwritten by a subclass)
|
45
|
-
define_inheritable_accessor(:openapi_document_class)
|
46
|
-
# the openapi document
|
47
|
-
define_inheritable_accessor(:tag_name, on_set: -> { update_dynamic_methods })
|
48
46
|
define_inheritable_accessor(:represented_schemas, default_value: [], on_set: proc do
|
49
47
|
unless represented_schemas.respond_to?(:to_ary)
|
50
48
|
raise(TypeError, "represented_schemas must be an array. received: #{represented_schemas.pretty_inspect.chomp}")
|
51
49
|
end
|
52
|
-
if represented_schemas.all? { |s| s.is_a?(
|
50
|
+
if represented_schemas.all? { |s| s.is_a?(JSI::Schema) }
|
53
51
|
represented_schemas.each do |schema|
|
54
52
|
openapi_document_class.models_by_schema = openapi_document_class.models_by_schema.merge(schema => self)
|
55
53
|
end
|
56
54
|
update_dynamic_methods
|
57
55
|
else
|
58
56
|
self.represented_schemas = self.represented_schemas.map do |schema|
|
59
|
-
unless schema.is_a?(
|
60
|
-
schema =
|
61
|
-
end
|
62
|
-
unless schema['type'].nil? || schema.describes_hash?
|
63
|
-
raise(TypeError, "given schema for #{self.inspect} not of type object - type must be object for Scorpio ResourceBase to represent this schema. schema is: #{schema.pretty_inspect.chomp}")
|
57
|
+
unless schema.is_a?(JSI::Schema)
|
58
|
+
schema = JSI::Schema.new(schema)
|
64
59
|
end
|
65
60
|
schema
|
66
61
|
end
|
67
62
|
end
|
68
63
|
end)
|
69
64
|
define_inheritable_accessor(:models_by_schema, default_value: {})
|
70
|
-
# the base url to which paths are appended.
|
71
|
-
# by default this looks at the openapi document's schemes, picking https or http first.
|
72
|
-
# it looks at the openapi_document's host and basePath.
|
73
65
|
# a model overriding this MUST include the openapi document's basePath if defined, e.g.
|
74
66
|
# class MyModel
|
75
67
|
# self.base_url = File.join('https://example.com/', openapi_document.basePath)
|
76
68
|
# end
|
77
69
|
define_inheritable_accessor(:base_url, default_getter: -> {
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
if openapi_document.host && scheme
|
85
|
-
Addressable::URI.new(
|
86
|
-
scheme: scheme,
|
87
|
-
host: openapi_document.host,
|
88
|
-
path: openapi_document.basePath,
|
89
|
-
).to_s
|
70
|
+
openapi_document.base_url(server: server, server_variables: server_variables)
|
71
|
+
})
|
72
|
+
|
73
|
+
define_inheritable_accessor(:server_variables, default_value: {}, on_set: -> {
|
74
|
+
if openapi_document && openapi_document.v2?
|
75
|
+
raise(ArgumentError, "server variables are not supported for OpenAPI V2")
|
90
76
|
end
|
91
77
|
})
|
92
78
|
|
93
|
-
define_inheritable_accessor(:
|
94
|
-
|
79
|
+
define_inheritable_accessor(:server, on_set: -> {
|
80
|
+
if openapi_document && openapi_document.v2?
|
81
|
+
raise(ArgumentError, "servers are not supported for OpenAPI V2")
|
82
|
+
end
|
83
|
+
unless server.is_a?(Scorpio::OpenAPI::V3::Server)
|
84
|
+
raise(TypeError, "server must be an #{Scorpio::OpenAPI::V3::Server.inspect}. received: #{server.pretty_inspect.chomp}")
|
85
|
+
end
|
95
86
|
})
|
96
|
-
|
97
|
-
define_inheritable_accessor(:
|
98
|
-
|
87
|
+
|
88
|
+
define_inheritable_accessor(:user_agent, default_getter: -> { openapi_document.user_agent })
|
89
|
+
|
90
|
+
define_inheritable_accessor(:faraday_builder, default_getter: -> { openapi_document.faraday_builder })
|
91
|
+
define_inheritable_accessor(:faraday_adapter, default_getter: -> { openapi_document.faraday_adapter })
|
99
92
|
class << self
|
93
|
+
# the openapi document
|
100
94
|
def openapi_document
|
101
95
|
nil
|
102
96
|
end
|
97
|
+
def openapi_document_class
|
98
|
+
nil
|
99
|
+
end
|
103
100
|
|
104
101
|
def openapi_document=(openapi_document)
|
105
|
-
|
106
|
-
|
107
|
-
if openapi_document.is_a?(Hash)
|
108
|
-
openapi_document = OpenAPI::V2::Document.new(openapi_document)
|
109
|
-
end
|
102
|
+
openapi_document = OpenAPI::Document.from_instance(openapi_document)
|
110
103
|
|
111
104
|
begin
|
112
105
|
singleton_class.instance_exec { remove_method(:openapi_document) }
|
113
106
|
rescue NameError
|
114
107
|
end
|
108
|
+
begin
|
109
|
+
singleton_class.instance_exec { remove_method(:openapi_document_class) }
|
110
|
+
rescue NameError
|
111
|
+
end
|
112
|
+
openapi_document_class = self
|
115
113
|
define_singleton_method(:openapi_document) { openapi_document }
|
116
|
-
define_singleton_method(:
|
114
|
+
define_singleton_method(:openapi_document_class) { openapi_document_class }
|
115
|
+
define_singleton_method(:openapi_document=) do |_|
|
117
116
|
if self == openapi_document_class
|
118
117
|
raise(ArgumentError, "openapi_document may only be set once on #{self.inspect}")
|
119
118
|
else
|
@@ -124,15 +123,36 @@ module Scorpio
|
|
124
123
|
|
125
124
|
openapi_document.paths.each do |path, path_item|
|
126
125
|
path_item.each do |http_method, operation|
|
127
|
-
|
128
|
-
|
129
|
-
raise("bad operation at #{operation.fragment}: #{operation.pretty_inspect}")
|
126
|
+
unless operation.is_a?(Scorpio::OpenAPI::Operation)
|
127
|
+
next
|
130
128
|
end
|
131
129
|
end
|
132
130
|
end
|
133
131
|
|
134
|
-
openapi_document
|
132
|
+
# TODO blame validate openapi_document
|
133
|
+
|
134
|
+
update_dynamic_methods
|
135
|
+
end
|
136
|
+
|
137
|
+
def tag_name
|
138
|
+
nil
|
139
|
+
end
|
135
140
|
|
141
|
+
def tag_name=(tag_name)
|
142
|
+
unless tag_name.respond_to?(:to_str)
|
143
|
+
raise(TypeError)
|
144
|
+
end
|
145
|
+
set_on_class = self
|
146
|
+
tag_name = tag_name.to_str
|
147
|
+
|
148
|
+
begin
|
149
|
+
singleton_class.instance_exec { remove_method(:tag_name) }
|
150
|
+
rescue NameError
|
151
|
+
end
|
152
|
+
define_singleton_method(:tag_name) { tag_name }
|
153
|
+
define_singleton_method(:tag_name=) do |_|
|
154
|
+
raise(ArgumentError, "tag_name may not be overridden. it is been set to #{tag_name.inspect}")
|
155
|
+
end
|
136
156
|
update_dynamic_methods
|
137
157
|
end
|
138
158
|
|
@@ -142,7 +162,7 @@ module Scorpio
|
|
142
162
|
end
|
143
163
|
|
144
164
|
def all_schema_properties
|
145
|
-
represented_schemas.map(&:
|
165
|
+
represented_schemas.map(&:described_object_property_names).inject(Set.new, &:|)
|
146
166
|
end
|
147
167
|
|
148
168
|
def update_instance_accessors
|
@@ -165,7 +185,7 @@ module Scorpio
|
|
165
185
|
|
166
186
|
return true if operation.tags.respond_to?(:to_ary) && operation.tags.include?(tag_name)
|
167
187
|
|
168
|
-
if operation.
|
188
|
+
if (operation.request_schemas || []).any? { |s| represented_schemas.include?(s) }
|
169
189
|
return true
|
170
190
|
end
|
171
191
|
|
@@ -192,7 +212,7 @@ module Scorpio
|
|
192
212
|
# should we define an instance method?
|
193
213
|
#request_attributes |= method_desc['parameters'] ? method_desc['parameters'].keys : []
|
194
214
|
|
195
|
-
schema_attributes = represented_schemas.map(&:
|
215
|
+
schema_attributes = represented_schemas.map(&:described_object_property_names).inject(Set.new, &:|)
|
196
216
|
|
197
217
|
return request_resource_is_self || (request_attributes & schema_attributes.to_a).any?
|
198
218
|
end
|
@@ -200,7 +220,7 @@ module Scorpio
|
|
200
220
|
def method_names_by_operation
|
201
221
|
@method_names_by_operation ||= Hash.new do |h, operation|
|
202
222
|
h[operation] = begin
|
203
|
-
raise(ArgumentError, operation.pretty_inspect) unless operation.is_a?(Scorpio::OpenAPI::
|
223
|
+
raise(ArgumentError, operation.pretty_inspect) unless operation.is_a?(Scorpio::OpenAPI::Operation)
|
204
224
|
|
205
225
|
if operation.tags.respond_to?(:to_ary) && operation.tags.include?(tag_name) && operation.operationId =~ /\A#{Regexp.escape(tag_name)}\.(\w+)\z/
|
206
226
|
method_name = $1
|
@@ -216,82 +236,95 @@ module Scorpio
|
|
216
236
|
path_item.each do |http_method, operation|
|
217
237
|
next if http_method == 'parameters' # parameters is not an operation. TOOD maybe just select the keys that are http methods?
|
218
238
|
method_name = method_names_by_operation[operation]
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
239
|
+
if method_name
|
240
|
+
# class method
|
241
|
+
if operation_for_resource_class?(operation) && !respond_to?(method_name)
|
242
|
+
define_singleton_method(method_name) do |call_params = nil|
|
243
|
+
call_operation(operation, call_params: call_params)
|
244
|
+
end
|
223
245
|
end
|
224
|
-
end
|
225
246
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
247
|
+
# instance method
|
248
|
+
if operation_for_resource_instance?(operation) && !method_defined?(method_name)
|
249
|
+
define_method(method_name) do |call_params = nil|
|
250
|
+
call_operation(operation, call_params: call_params)
|
251
|
+
end
|
230
252
|
end
|
231
253
|
end
|
232
254
|
end
|
233
255
|
end
|
234
256
|
end
|
235
257
|
|
236
|
-
def connection
|
237
|
-
Faraday.new(:headers => {'User-Agent' => user_agent}) do |c|
|
238
|
-
faraday_request_middleware.each do |m|
|
239
|
-
c.request(*m)
|
240
|
-
end
|
241
|
-
faraday_response_middleware.each do |m|
|
242
|
-
c.response(*m)
|
243
|
-
end
|
244
|
-
c.adapter(*faraday_adapter)
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
258
|
def call_operation(operation, call_params: nil, model_attributes: nil)
|
249
|
-
call_params =
|
250
|
-
model_attributes =
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
259
|
+
call_params = JSI.stringify_symbol_keys(call_params) if call_params.is_a?(Hash)
|
260
|
+
model_attributes = JSI.stringify_symbol_keys(model_attributes || {})
|
261
|
+
|
262
|
+
request = Scorpio::Request.new(operation)
|
263
|
+
|
264
|
+
accessor_overridden = -> (accessor) do
|
265
|
+
# an accessor is overridden if the default accessor getter (UnboundMethod) is the same
|
266
|
+
# as the UnboundMethod returned from instance_method on the owner of that instance method.
|
267
|
+
# gotta be the owner since different classes return different UnboundMethod instances for
|
268
|
+
# the same method. for example, referring to models of scorpio/test/blog_scorpio_models.rb
|
269
|
+
# with the server_variables instance method:
|
270
|
+
# Article.instance_method(:server_variables)
|
271
|
+
# => #<UnboundMethod: #<Class:Article>#server_variables>
|
272
|
+
# returns a different UnboundMethod than
|
273
|
+
# Scorpio::ResourceBase.instance_method(:server_variables)
|
274
|
+
# => #<UnboundMethod: #<Class:Scorpio::ResourceBase>#server_variables>
|
275
|
+
# even though they are really the same method (the #owner for both is Scorpio::ResourceBase)
|
276
|
+
inheritable_accessor_defaults[accessor] != self.singleton_class.instance_method(accessor).owner.instance_method(accessor)
|
264
277
|
end
|
265
|
-
|
266
|
-
#
|
267
|
-
|
268
|
-
|
269
|
-
|
278
|
+
|
279
|
+
# pretty ugly... may find a better way to do this.
|
280
|
+
request.base_url = self.base_url if accessor_overridden.(:base_url)
|
281
|
+
request.server_variables = self.server_variables if accessor_overridden.(:server_variables)
|
282
|
+
request.server = self.server if accessor_overridden.(:server)
|
283
|
+
request.user_agent = self.user_agent if accessor_overridden.(:user_agent)
|
284
|
+
request.faraday_builder = self.faraday_builder if accessor_overridden.(:faraday_builder)
|
285
|
+
request.faraday_adapter = self.faraday_adapter if accessor_overridden.(:faraday_adapter)
|
286
|
+
|
287
|
+
request.path_params = request.path_template.variables.map do |var|
|
288
|
+
if call_params.respond_to?(:to_hash) && call_params.key?(var)
|
289
|
+
{var => call_params[var]}
|
290
|
+
elsif model_attributes.respond_to?(:to_hash) && model_attributes.key?(var)
|
291
|
+
{var => model_attributes[var]}
|
292
|
+
else
|
293
|
+
{}
|
294
|
+
end
|
295
|
+
end.inject({}, &:update)
|
296
|
+
|
270
297
|
# assume that call_params must be included somewhere. model_attributes are a source of required things
|
271
298
|
# but not required to be here.
|
272
|
-
|
273
|
-
|
274
|
-
|
299
|
+
if call_params.respond_to?(:to_hash)
|
300
|
+
unused_call_params = call_params.reject { |k, _| request.path_template.variables.include?(k) }
|
301
|
+
if !unused_call_params.empty?
|
302
|
+
other_params = unused_call_params
|
303
|
+
else
|
304
|
+
other_params = nil
|
305
|
+
end
|
306
|
+
else
|
307
|
+
other_params = call_params
|
275
308
|
end
|
276
309
|
|
277
310
|
if operation.request_schema
|
278
311
|
# TODO deal with model_attributes / call_params better in nested whatever
|
279
312
|
if call_params.nil?
|
280
|
-
|
313
|
+
request.body_object = request_body_for_schema(model_attributes, operation.request_schema)
|
281
314
|
elsif call_params.is_a?(Hash)
|
282
315
|
body = request_body_for_schema(model_attributes.merge(call_params), operation.request_schema)
|
283
|
-
|
316
|
+
request.body_object = body.merge(call_params) # TODO
|
284
317
|
else
|
285
|
-
|
318
|
+
request.body_object = call_params
|
286
319
|
end
|
287
320
|
else
|
288
321
|
if other_params
|
289
|
-
if METHODS_WITH_BODIES.any? { |m| m.to_s == http_method.downcase.to_s }
|
290
|
-
|
322
|
+
if METHODS_WITH_BODIES.any? { |m| m.to_s == operation.http_method.downcase.to_s }
|
323
|
+
request.body_object = other_params
|
291
324
|
else
|
292
325
|
if other_params.is_a?(Hash)
|
293
326
|
# TODO pay more attention to 'parameters' api method attribute
|
294
|
-
|
327
|
+
request.query_params = other_params
|
295
328
|
else
|
296
329
|
raise
|
297
330
|
end
|
@@ -299,91 +332,25 @@ module Scorpio
|
|
299
332
|
end
|
300
333
|
end
|
301
334
|
|
302
|
-
|
303
|
-
|
304
|
-
if METHODS_WITH_BODIES.any? { |m| m.to_s == http_method.downcase.to_s } && body != nil
|
305
|
-
consumes = operation.consumes || openapi_document.consumes || []
|
306
|
-
if consumes.include?("application/json") || (!body.respond_to?(:to_str) && consumes.empty?)
|
307
|
-
# if we have a body that's not a string and no indication of how to serialize it, we guess json.
|
308
|
-
request_headers['Content-Type'] = "application/json"
|
309
|
-
unless body.respond_to?(:to_str)
|
310
|
-
body = ::JSON.pretty_generate(Typelike.as_json(body))
|
311
|
-
end
|
312
|
-
elsif consumes.include?("application/x-www-form-urlencoded")
|
313
|
-
request_headers['Content-Type'] = "application/x-www-form-urlencoded"
|
314
|
-
unless body.respond_to?(:to_str)
|
315
|
-
body = URI.encode_www_form(body)
|
316
|
-
end
|
317
|
-
elsif body.is_a?(String)
|
318
|
-
if consumes.size == 1
|
319
|
-
request_headers['Content-Type'] = consumes.first
|
320
|
-
end
|
321
|
-
else
|
322
|
-
raise("do not know how to serialize for #{consumes.inspect}: #{body.pretty_inspect.chomp}")
|
323
|
-
end
|
324
|
-
end
|
335
|
+
ur = request.run_ur
|
325
336
|
|
326
|
-
|
327
|
-
|
328
|
-
if response.media_type == 'application/json'
|
329
|
-
if response.body.empty?
|
330
|
-
response_object = nil
|
331
|
-
else
|
332
|
-
begin
|
333
|
-
response_object = ::JSON.parse(response.body)
|
334
|
-
rescue ::JSON::ParserError
|
335
|
-
# TODO warn
|
336
|
-
response_object = response.body
|
337
|
-
end
|
338
|
-
end
|
339
|
-
else
|
340
|
-
response_object = response.body
|
341
|
-
end
|
342
|
-
|
343
|
-
if operation.responses
|
344
|
-
_, operation_response = operation.responses.detect { |k, v| k.to_s == response.status.to_s }
|
345
|
-
operation_response ||= operation.responses['default']
|
346
|
-
response_schema = operation_response['schema'] if operation_response
|
347
|
-
end
|
348
|
-
if response_schema
|
349
|
-
# not too sure about this, but I don't think it makes sense to instantiate things that are
|
350
|
-
# not hash or array as a SchemaInstanceBase
|
351
|
-
if response_object.respond_to?(:to_hash) || response_object.respond_to?(:to_ary)
|
352
|
-
response_object = Scorpio.class_for_schema(response_schema).new(response_object)
|
353
|
-
end
|
354
|
-
end
|
355
|
-
|
356
|
-
error_class = Scorpio.error_classes_by_status[response.status]
|
357
|
-
error_class ||= if (400..499).include?(response.status)
|
358
|
-
ClientError
|
359
|
-
elsif (500..599).include?(response.status)
|
360
|
-
ServerError
|
361
|
-
elsif !response.success?
|
362
|
-
HTTPError
|
363
|
-
end
|
364
|
-
if error_class
|
365
|
-
message = "Error calling operation #{operation.operationId} on #{self}:\n" + (response.env[:raw_body] || response.env.body)
|
366
|
-
raise(error_class.new(message).tap do |e|
|
367
|
-
e.faraday_response = response
|
368
|
-
e.response_object = response_object
|
369
|
-
end)
|
370
|
-
end
|
337
|
+
ur.raise_on_http_error
|
371
338
|
|
372
339
|
initialize_options = {
|
373
340
|
'persisted' => true,
|
374
|
-
'source' => {'operationId' => operation.operationId, 'call_params' => call_params, 'url' =>
|
375
|
-
'
|
341
|
+
'source' => {'operationId' => operation.operationId, 'call_params' => call_params, 'url' => ur.request.uri.to_s},
|
342
|
+
'ur' => ur,
|
376
343
|
}
|
377
|
-
response_object_to_instances(
|
344
|
+
response_object_to_instances(ur.response.body_object, initialize_options)
|
378
345
|
end
|
379
346
|
|
380
347
|
def request_body_for_schema(object, schema)
|
381
348
|
if object.is_a?(Scorpio::ResourceBase)
|
382
349
|
# TODO request_schema_fail unless schema is for given model type
|
383
350
|
request_body_for_schema(object.attributes, schema)
|
384
|
-
elsif object.is_a?(
|
351
|
+
elsif object.is_a?(JSI::Base)
|
385
352
|
request_body_for_schema(object.instance, schema)
|
386
|
-
elsif object.is_a?(
|
353
|
+
elsif object.is_a?(JSI::JSON::Node)
|
387
354
|
request_body_for_schema(object.content, schema)
|
388
355
|
else
|
389
356
|
if object.is_a?(Hash)
|
@@ -436,7 +403,7 @@ module Scorpio
|
|
436
403
|
if schema['type'] == 'array'
|
437
404
|
# TODO index based subschema or whatever else works for array
|
438
405
|
subschema = schema['items']
|
439
|
-
|
406
|
+
elsif schema['type']
|
440
407
|
request_schema_fail(object, schema)
|
441
408
|
end
|
442
409
|
end
|
@@ -451,16 +418,16 @@ module Scorpio
|
|
451
418
|
end
|
452
419
|
|
453
420
|
def request_schema_fail(object, schema)
|
454
|
-
|
421
|
+
# TODO blame
|
455
422
|
end
|
456
423
|
|
457
424
|
def response_object_to_instances(object, initialize_options = {})
|
458
|
-
if object.is_a?(
|
425
|
+
if object.is_a?(JSI::Base)
|
459
426
|
model = models_by_schema[object.schema]
|
460
427
|
end
|
461
428
|
|
462
429
|
if object.respond_to?(:to_hash)
|
463
|
-
out = Typelike.modified_copy(object) do
|
430
|
+
out = JSI::Typelike.modified_copy(object) do
|
464
431
|
object.map do |key, value|
|
465
432
|
{key => response_object_to_instances(value, initialize_options)}
|
466
433
|
end.inject({}, &:update)
|
@@ -471,7 +438,7 @@ module Scorpio
|
|
471
438
|
out
|
472
439
|
end
|
473
440
|
elsif object.respond_to?(:to_ary)
|
474
|
-
Typelike.modified_copy(object) do
|
441
|
+
JSI::Typelike.modified_copy(object) do
|
475
442
|
object.map do |element|
|
476
443
|
response_object_to_instances(element, initialize_options)
|
477
444
|
end
|
@@ -483,8 +450,8 @@ module Scorpio
|
|
483
450
|
end
|
484
451
|
|
485
452
|
def initialize(attributes = {}, options = {})
|
486
|
-
@attributes =
|
487
|
-
@options =
|
453
|
+
@attributes = JSI.stringify_symbol_keys(attributes)
|
454
|
+
@options = JSI.stringify_symbol_keys(options)
|
488
455
|
@persisted = !!@options['persisted']
|
489
456
|
end
|
490
457
|
|
@@ -514,10 +481,9 @@ module Scorpio
|
|
514
481
|
# if we're making a POST or PUT and the request schema is this resource, we'll assume that
|
515
482
|
# the request is persisting this resource
|
516
483
|
request_resource_is_self = operation.request_schema && self.class.represented_schemas.include?(operation.request_schema)
|
517
|
-
if @options['
|
518
|
-
|
484
|
+
if @options['ur'].is_a?(Scorpio::Ur)
|
485
|
+
response_schema = @options['ur'].response.response_schema
|
519
486
|
end
|
520
|
-
response_schema = Scorpio::Schema.new(response_schema_node) if response_schema_node
|
521
487
|
response_resource_is_self = response_schema && self.class.represented_schemas.include?(response_schema)
|
522
488
|
if request_resource_is_self && %w(put post).include?(operation.http_method.to_s.downcase)
|
523
489
|
@persisted = true
|
@@ -531,7 +497,7 @@ module Scorpio
|
|
531
497
|
end
|
532
498
|
|
533
499
|
def as_json(*opt)
|
534
|
-
Typelike.as_json(@attributes, *opt)
|
500
|
+
JSI::Typelike.as_json(@attributes, *opt)
|
535
501
|
end
|
536
502
|
|
537
503
|
def inspect
|
@@ -552,8 +518,8 @@ module Scorpio
|
|
552
518
|
end
|
553
519
|
|
554
520
|
def fingerprint
|
555
|
-
{class: self.class, attributes: Typelike.as_json(@attributes)}
|
521
|
+
{class: self.class, attributes: JSI::Typelike.as_json(@attributes)}
|
556
522
|
end
|
557
|
-
include FingerprintHash
|
523
|
+
include JSI::FingerprintHash
|
558
524
|
end
|
559
525
|
end
|