jsapi 2.1.2 → 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/lib/jsapi/client/base.rb +182 -0
- data/lib/jsapi/client/exceptions.rb +45 -0
- data/lib/jsapi/client/request.rb +204 -0
- data/lib/jsapi/client/response.rb +120 -0
- data/lib/jsapi/client/session/base.rb +61 -0
- data/lib/jsapi/client/session/logger.rb +52 -0
- data/lib/jsapi/client/session/single_request.rb +16 -0
- data/lib/jsapi/client/session/test/class_methods.rb +49 -0
- data/lib/jsapi/client/session/test/response.rb +56 -0
- data/lib/jsapi/client/session/test/spy.rb +43 -0
- data/lib/jsapi/client/session/test.rb +17 -0
- data/lib/jsapi/client/session.rb +6 -0
- data/lib/jsapi/client.rb +7 -0
- data/lib/jsapi/configuration.rb +2 -2
- data/lib/jsapi/controller/authentication/credentials/http/bearer.rb +5 -12
- data/lib/jsapi/controller/authentication/credentials.rb +4 -4
- data/lib/jsapi/controller/authentication.rb +3 -3
- data/lib/jsapi/controller/methods.rb +43 -77
- data/lib/jsapi/controller/parameters.rb +6 -6
- data/lib/jsapi/controller/response.rb +7 -7
- data/lib/jsapi/{meta/definitions.rb → definition/api.rb} +62 -40
- data/lib/jsapi/{meta → definition}/callable/symbol_evaluator.rb +1 -1
- data/lib/jsapi/{meta → definition}/callable/symbol_sequence_evaluator.rb +1 -1
- data/lib/jsapi/{meta → definition}/callable.rb +1 -1
- data/lib/jsapi/{meta → definition}/callback/base.rb +5 -5
- data/lib/jsapi/{meta → definition}/callback/reference.rb +1 -1
- data/lib/jsapi/{meta → definition}/callback.rb +1 -1
- data/lib/jsapi/{meta → definition}/contact.rb +1 -1
- data/lib/jsapi/{meta → definition}/content.rb +11 -11
- data/lib/jsapi/{meta → definition}/defaults.rb +1 -1
- data/lib/jsapi/{meta → definition}/example/base.rb +1 -1
- data/lib/jsapi/{meta → definition}/example/builder.rb +4 -4
- data/lib/jsapi/{meta → definition}/example/reference.rb +1 -1
- data/lib/jsapi/{meta → definition}/example.rb +1 -1
- data/lib/jsapi/{meta → definition}/existence.rb +1 -1
- data/lib/jsapi/{meta → definition}/external_documentation.rb +1 -1
- data/lib/jsapi/{meta → definition}/header/base.rb +1 -1
- data/lib/jsapi/{meta → definition}/header/reference.rb +1 -1
- data/lib/jsapi/{meta → definition}/header.rb +1 -1
- data/lib/jsapi/{meta → definition}/info.rb +1 -1
- data/lib/jsapi/{meta → definition}/license.rb +1 -1
- data/lib/jsapi/{meta → definition}/link/base.rb +1 -1
- data/lib/jsapi/{meta → definition}/link/reference.rb +1 -1
- data/lib/jsapi/{meta → definition}/link.rb +1 -1
- data/lib/jsapi/{meta → definition}/model/attributes/class_methods.rb +1 -1
- data/lib/jsapi/{meta → definition}/model/attributes/frozen_error.rb +1 -1
- data/lib/jsapi/{meta → definition}/model/attributes/type_caster.rb +2 -2
- data/lib/jsapi/{meta → definition}/model/attributes.rb +1 -1
- data/lib/jsapi/{meta → definition}/model/base.rb +1 -1
- data/lib/jsapi/{meta → definition}/model/reference.rb +11 -11
- data/lib/jsapi/{meta → definition}/model/wrappable.rb +3 -3
- data/lib/jsapi/{meta → definition}/model/wrapper.rb +5 -5
- data/lib/jsapi/{meta → definition}/oauth_flow.rb +1 -1
- data/lib/jsapi/{meta → definition}/openapi/extensions.rb +1 -1
- data/lib/jsapi/{meta → definition}/openapi/path_item.rb +5 -5
- data/lib/jsapi/{meta → definition}/openapi/version.rb +2 -2
- data/lib/jsapi/{meta → definition}/openapi.rb +1 -1
- data/lib/jsapi/{meta → definition}/operation.rb +108 -62
- data/lib/jsapi/{meta → definition}/parameter/base.rb +11 -11
- data/lib/jsapi/{meta → definition}/parameter/reference.rb +5 -5
- data/lib/jsapi/{meta → definition}/parameter/wrapper.rb +2 -2
- data/lib/jsapi/{meta → definition}/parameter.rb +1 -1
- data/lib/jsapi/{meta → definition}/path.rb +1 -1
- data/lib/jsapi/{meta → definition}/pathname.rb +1 -1
- data/lib/jsapi/{meta → definition}/property.rb +2 -2
- data/lib/jsapi/{meta → definition}/reference_error.rb +1 -1
- data/lib/jsapi/{meta → definition}/request_body/base.rb +1 -1
- data/lib/jsapi/{meta → definition}/request_body/reference.rb +1 -1
- data/lib/jsapi/{meta → definition}/request_body/wrapper.rb +2 -2
- data/lib/jsapi/{meta → definition}/request_body.rb +1 -1
- data/lib/jsapi/{meta → definition}/rescue_handler.rb +1 -1
- data/lib/jsapi/{meta → definition}/response/base.rb +4 -4
- data/lib/jsapi/{meta → definition}/response/reference.rb +1 -1
- data/lib/jsapi/{meta → definition}/response/wrapper.rb +17 -5
- data/lib/jsapi/{meta → definition}/response.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/additional_properties.rb +2 -2
- data/lib/jsapi/{meta → definition}/schema/array.rb +2 -2
- data/lib/jsapi/{meta → definition}/schema/base.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/boolean.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/boundary.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/conversion.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/discriminator.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/integer.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/number.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/numeric.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/object.rb +13 -13
- data/lib/jsapi/{meta → definition}/schema/reference.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/string.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/validation/base.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/validation/enum.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/validation/max_items.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/validation/max_length.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/validation/maximum.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/validation/min_items.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/validation/min_length.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/validation/minimum.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/validation/multiple_of.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/validation/pattern.rb +1 -1
- data/lib/jsapi/{meta → definition}/schema/wrapper.rb +18 -4
- data/lib/jsapi/{meta → definition}/schema.rb +5 -5
- data/lib/jsapi/{meta → definition}/security_requirement.rb +1 -1
- data/lib/jsapi/{meta → definition}/security_scheme/api_key.rb +1 -1
- data/lib/jsapi/{meta → definition}/security_scheme/base.rb +1 -1
- data/lib/jsapi/{meta → definition}/security_scheme/http/basic.rb +1 -1
- data/lib/jsapi/{meta → definition}/security_scheme/http/bearer.rb +1 -1
- data/lib/jsapi/{meta → definition}/security_scheme/http/other.rb +1 -1
- data/lib/jsapi/{meta → definition}/security_scheme/http.rb +1 -1
- data/lib/jsapi/{meta → definition}/security_scheme/mutual_tls.rb +1 -1
- data/lib/jsapi/{meta → definition}/security_scheme/oauth2.rb +1 -1
- data/lib/jsapi/{meta → definition}/security_scheme/open_id_connect.rb +1 -1
- data/lib/jsapi/{meta → definition}/security_scheme.rb +1 -1
- data/lib/jsapi/{meta → definition}/server.rb +24 -1
- data/lib/jsapi/{meta → definition}/server_variable.rb +1 -1
- data/lib/jsapi/{meta → definition}/tag.rb +1 -1
- data/lib/jsapi/definition.rb +33 -0
- data/lib/jsapi/dsl/{definitions.rb → api.rb} +48 -48
- data/lib/jsapi/dsl/base.rb +7 -7
- data/lib/jsapi/dsl/class_methods.rb +34 -32
- data/lib/jsapi/dsl/examples.rb +1 -1
- data/lib/jsapi/dsl/operation.rb +9 -7
- data/lib/jsapi/dsl/parameter.rb +1 -1
- data/lib/jsapi/dsl/path.rb +8 -6
- data/lib/jsapi/dsl/response.rb +5 -5
- data/lib/jsapi/dsl/schema.rb +17 -17
- data/lib/jsapi/dsl/shared_operation_methods.rb +11 -26
- data/lib/jsapi/dsl.rb +2 -2
- data/lib/jsapi/model/errors.rb +3 -3
- data/lib/jsapi/status/code.rb +20 -0
- data/lib/jsapi/support/messages.rb +27 -0
- data/lib/jsapi/support.rb +3 -0
- data/lib/jsapi/version.rb +1 -1
- data/lib/jsapi.rb +3 -3
- metadata +115 -102
- data/lib/jsapi/jsonify_error.rb +0 -17
- data/lib/jsapi/messages.rb +0 -19
- data/lib/jsapi/meta.rb +0 -38
- /data/lib/jsapi/{meta → definition}/model.rb +0 -0
- /data/lib/jsapi/{meta → definition}/schema/validation.rb +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jsapi
|
|
4
|
+
module Client
|
|
5
|
+
module Session
|
|
6
|
+
module Test
|
|
7
|
+
module ClassMethods
|
|
8
|
+
# Stubs all sessions created in the passed block.
|
|
9
|
+
#
|
|
10
|
+
# Spying a single request session:
|
|
11
|
+
#
|
|
12
|
+
# Jsapi::Client::Session::SingleRequest.spy(200, '{}') do |spy|
|
|
13
|
+
# # Call operation
|
|
14
|
+
# assert_equal('...', spy.request.body)
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# Spying a session with multiple requests:
|
|
18
|
+
#
|
|
19
|
+
# Jsapi::Client::Session::Base.spy do |spy|
|
|
20
|
+
# spy.response_with(200, '{}')
|
|
21
|
+
# # Call operation
|
|
22
|
+
# assert_equal('...', spy.request.body)
|
|
23
|
+
#
|
|
24
|
+
# spy.response_with(400, '{}')
|
|
25
|
+
# # Call operation
|
|
26
|
+
# assert_equal('...', spy.request.body)
|
|
27
|
+
# end
|
|
28
|
+
def spy(...)
|
|
29
|
+
return unless block_given?
|
|
30
|
+
|
|
31
|
+
spy = Test::Spy.new(...)
|
|
32
|
+
|
|
33
|
+
klass = singleton_class
|
|
34
|
+
klass.alias_method(:__new__, :new)
|
|
35
|
+
klass.define_method(:new) { |*| spy }
|
|
36
|
+
|
|
37
|
+
begin
|
|
38
|
+
yield spy
|
|
39
|
+
ensure
|
|
40
|
+
klass.undef_method(:new)
|
|
41
|
+
klass.alias_method(:new, :__new__)
|
|
42
|
+
klass.undef_method(:__new__)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jsapi
|
|
4
|
+
module Client
|
|
5
|
+
module Session
|
|
6
|
+
module Test
|
|
7
|
+
# Dummy HTTP response.
|
|
8
|
+
class Response
|
|
9
|
+
##
|
|
10
|
+
# :attr_reader: body
|
|
11
|
+
# Mimics +body+ of Net::HTTPRespone.
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# :attr_reader: code
|
|
15
|
+
# Mimics +code+ of Net::HTTPRespone.
|
|
16
|
+
|
|
17
|
+
##
|
|
18
|
+
# :attr_reader: headers
|
|
19
|
+
# The headers of the HTTP response as a hash.
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# :attr_reader: http_version
|
|
23
|
+
# The HTTP version, always <code>"1.1"</code>
|
|
24
|
+
|
|
25
|
+
attr_reader :body, :code, :headers, :http_version
|
|
26
|
+
|
|
27
|
+
# Creates a dummy HTTP response. The default status code is <code>"200"</code>.
|
|
28
|
+
def initialize(status_code = nil, body = nil, **headers)
|
|
29
|
+
@http_version = '1.1'
|
|
30
|
+
@code = Status::Code.from(status_code || :ok).to_s
|
|
31
|
+
@body = body&.to_s
|
|
32
|
+
|
|
33
|
+
@headers = headers.to_h do |key, value|
|
|
34
|
+
[key.to_s.dasherize, value.to_s]
|
|
35
|
+
end.freeze
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Mimics +content_type+ of Net::HTTPRespone.
|
|
39
|
+
def content_type
|
|
40
|
+
@headers['content-type']
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Mimics +each_header+ of Net::HTTPRespone.
|
|
44
|
+
def each_header(&block)
|
|
45
|
+
@headers.each(&block)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def inspect # :nodoc:
|
|
49
|
+
"#<#{self.class.name} code: #{code}, " \
|
|
50
|
+
"body: #{body.inspect}, headers: #{headers.inspect}>"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jsapi
|
|
4
|
+
module Client
|
|
5
|
+
module Session
|
|
6
|
+
module Test
|
|
7
|
+
# Spies an HTTP session.
|
|
8
|
+
class Spy
|
|
9
|
+
##
|
|
10
|
+
# :attr_reader: request
|
|
11
|
+
# The last captured request.
|
|
12
|
+
attr_reader :request
|
|
13
|
+
|
|
14
|
+
def initialize(...)
|
|
15
|
+
@response = Response.new(...)
|
|
16
|
+
@finished = false
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Mimics +finish+ of Session::Base.
|
|
20
|
+
def finish
|
|
21
|
+
@finished = true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Returns true if +finish+ has been called before.
|
|
25
|
+
def finished?
|
|
26
|
+
@finished == true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Sets the response for subsequent calls.
|
|
30
|
+
def response_with(...)
|
|
31
|
+
@response = Response.new(...)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Mimics +send_request+ of Session::Base.
|
|
35
|
+
def send_request(request)
|
|
36
|
+
@request = request
|
|
37
|
+
@response
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'test/response'
|
|
4
|
+
require_relative 'test/spy'
|
|
5
|
+
require_relative 'test/class_methods'
|
|
6
|
+
|
|
7
|
+
module Jsapi
|
|
8
|
+
module Client
|
|
9
|
+
module Session
|
|
10
|
+
module Test
|
|
11
|
+
def self.included(base) # :nodoc:
|
|
12
|
+
base.extend(ClassMethods)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/jsapi/client.rb
ADDED
data/lib/jsapi/configuration.rb
CHANGED
|
@@ -4,11 +4,11 @@ module Jsapi
|
|
|
4
4
|
# Holds the \Jsapi configuration.
|
|
5
5
|
class Configuration
|
|
6
6
|
# The path where the API definitions are located relative to +Rails.root+.
|
|
7
|
-
# The default is <code>"jsapi
|
|
7
|
+
# The default is <code>"jsapi"</code>.
|
|
8
8
|
attr_accessor :api_defs_path
|
|
9
9
|
|
|
10
10
|
def initialize # :nodoc:
|
|
11
|
-
@api_defs_path = 'jsapi
|
|
11
|
+
@api_defs_path = 'jsapi'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
# Returns the absolute +Pathname+ for +args+ within +api_defs_path+.
|
|
@@ -9,19 +9,12 @@ module Jsapi
|
|
|
9
9
|
module HTTP
|
|
10
10
|
# Holds a token passed according to \HTTP \Bearer \Authentication.
|
|
11
11
|
class Bearer < Base
|
|
12
|
-
|
|
13
|
-
attr_reader
|
|
12
|
+
##
|
|
13
|
+
# :attr_reader: token
|
|
14
|
+
# The token.
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@token =
|
|
18
|
-
Base64.decode64(auth_param) \
|
|
19
|
-
if auth_scheme == 'Bearer' && auth_param.present?
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def well_formed? # :nodoc:
|
|
23
|
-
!token.nil?
|
|
24
|
-
end
|
|
16
|
+
# -
|
|
17
|
+
alias token auth_param
|
|
25
18
|
end
|
|
26
19
|
end
|
|
27
20
|
end
|
|
@@ -13,7 +13,7 @@ module Jsapi
|
|
|
13
13
|
# security scheme.
|
|
14
14
|
def create(request, security_scheme)
|
|
15
15
|
case security_scheme
|
|
16
|
-
when
|
|
16
|
+
when Definition::SecurityScheme::APIKey
|
|
17
17
|
name = security_scheme.name
|
|
18
18
|
APIKey.new(
|
|
19
19
|
case security_scheme.in
|
|
@@ -23,11 +23,11 @@ module Jsapi
|
|
|
23
23
|
request.query_parameters[name]
|
|
24
24
|
end
|
|
25
25
|
)
|
|
26
|
-
when
|
|
26
|
+
when Definition::SecurityScheme::HTTP::Basic
|
|
27
27
|
HTTP::Basic.new(request.authorization)
|
|
28
|
-
when
|
|
28
|
+
when Definition::SecurityScheme::HTTP::Bearer
|
|
29
29
|
HTTP::Bearer.new(request.authorization)
|
|
30
|
-
when
|
|
30
|
+
when Definition::SecurityScheme::HTTP::Other
|
|
31
31
|
HTTP::Base.new(request.authorization)
|
|
32
32
|
end
|
|
33
33
|
end
|
|
@@ -31,9 +31,9 @@ module Jsapi
|
|
|
31
31
|
# security schemes are satisfied.
|
|
32
32
|
#
|
|
33
33
|
# +operation_name+ can be omitted if the controller handles one operation only.
|
|
34
|
-
# If the operation
|
|
34
|
+
# If the operation does not exist, an OperationNotFound exception is raised.
|
|
35
35
|
def api_authenticated?(operation_name = nil)
|
|
36
|
-
_api_authenticated?(
|
|
36
|
+
_api_authenticated?(api.find_operation!(operation_name))
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
private
|
|
@@ -49,7 +49,7 @@ module Jsapi
|
|
|
49
49
|
next false unless authentication_handler
|
|
50
50
|
|
|
51
51
|
# Find the appropriate security scheme
|
|
52
|
-
security_scheme =
|
|
52
|
+
security_scheme = api.find_security_scheme(scheme_name)
|
|
53
53
|
next false unless security_scheme
|
|
54
54
|
|
|
55
55
|
# Create the credentials to be passed to the authenticator
|
|
@@ -4,26 +4,6 @@ require_relative 'methods/callbacks'
|
|
|
4
4
|
|
|
5
5
|
module Jsapi
|
|
6
6
|
module Controller
|
|
7
|
-
# Raised when no operation with the specified name could be found.
|
|
8
|
-
class OperationNotFound < StandardError
|
|
9
|
-
def initialize(operation_name)
|
|
10
|
-
super("operation not found: #{operation_name}")
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# Raised when no suitable response could be found.
|
|
15
|
-
class ResponseNotFound < StandardError
|
|
16
|
-
def initialize(operation, status)
|
|
17
|
-
super(
|
|
18
|
-
if operation.responses.none?
|
|
19
|
-
"#{operation.name.inspect} has no responses"
|
|
20
|
-
else
|
|
21
|
-
"#{operation.name.inspect} has no response for status #{status}"
|
|
22
|
-
end
|
|
23
|
-
)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
7
|
# Raised when the current request could not be authenticated.
|
|
28
8
|
class Unauthorized < StandardError
|
|
29
9
|
def initialize # :nodoc:
|
|
@@ -49,7 +29,9 @@ module Jsapi
|
|
|
49
29
|
|
|
50
30
|
# Overrides <code>Exception#message</code> to lazily generate the error message.
|
|
51
31
|
def message
|
|
52
|
-
|
|
32
|
+
@params.errors.full_messages.map do |message|
|
|
33
|
+
message.end_with?('.') ? message : "#{message}."
|
|
34
|
+
end.join(' ')
|
|
53
35
|
end
|
|
54
36
|
end
|
|
55
37
|
|
|
@@ -58,15 +40,17 @@ module Jsapi
|
|
|
58
40
|
base.include(Callbacks)
|
|
59
41
|
end
|
|
60
42
|
|
|
61
|
-
# Returns the
|
|
43
|
+
# Returns the Definition::API instance associated with the controller class. In
|
|
62
44
|
# particular, this method can be used to create an OpenAPI document, for example:
|
|
63
45
|
#
|
|
64
|
-
# render(json:
|
|
46
|
+
# render(json: api.openapi_document)
|
|
65
47
|
#
|
|
66
|
-
def
|
|
67
|
-
self.class.
|
|
48
|
+
def api
|
|
49
|
+
self.class.api
|
|
68
50
|
end
|
|
69
51
|
|
|
52
|
+
alias api_definitions api
|
|
53
|
+
|
|
70
54
|
##
|
|
71
55
|
# :method: api_operation
|
|
72
56
|
# :args: operation_name = nil, omit: nil, status: nil, strong: false, &block
|
|
@@ -92,11 +76,10 @@ module Jsapi
|
|
|
92
76
|
# end
|
|
93
77
|
#
|
|
94
78
|
# +operation_name+ can be omitted if the controller handles one operation only.
|
|
95
|
-
#
|
|
96
|
-
# If no operation could be found for +operation_name+, an OperationNotFound exception
|
|
97
|
-
# is raised.
|
|
79
|
+
# If the operation does not exist, an OperationNotFound error is raised.
|
|
98
80
|
#
|
|
99
81
|
# +:status+ specifies the HTTP status code of the response to be produced.
|
|
82
|
+
# If no suitable response exists, a ResponseNotFound error is raised.
|
|
100
83
|
#
|
|
101
84
|
# If +:strong+ is +true+, parameters that can be mapped are accepted only. That means
|
|
102
85
|
# that the model passed to the block is invalid if there are any request parameters
|
|
@@ -108,7 +91,7 @@ module Jsapi
|
|
|
108
91
|
# - +:empty+ - All of the properties whose value is empty are omitted.
|
|
109
92
|
# - +:nil+ - All of the properties whose value is +nil+ are omitted.
|
|
110
93
|
#
|
|
111
|
-
# Raises an Unauthorized
|
|
94
|
+
# Raises an Unauthorized error if the Authentication module is included and the
|
|
112
95
|
# current request could not be authenticated.
|
|
113
96
|
#
|
|
114
97
|
# See Callbacks::ClassMethods for possible callbacks.
|
|
@@ -117,8 +100,8 @@ module Jsapi
|
|
|
117
100
|
# :method: api_operation!
|
|
118
101
|
# :args: operation_name = nil, omit: nil, status: nil, strong: false, &block
|
|
119
102
|
#
|
|
120
|
-
# Like +api_operation+, except
|
|
121
|
-
#
|
|
103
|
+
# Like +api_operation+, except it raises a ParametersInvalid error when the request
|
|
104
|
+
# parameters are invalid.
|
|
122
105
|
#
|
|
123
106
|
# api_operation!('foo') do |api_params|
|
|
124
107
|
# # ...
|
|
@@ -127,14 +110,14 @@ module Jsapi
|
|
|
127
110
|
[true, false].each do |bang|
|
|
128
111
|
define_method(bang ? :api_operation! : :api_operation) \
|
|
129
112
|
do |operation_name = nil, omit: nil, status: nil, strong: false, &block|
|
|
130
|
-
raise ArgumentError, Messages.invalid_value(
|
|
113
|
+
raise ArgumentError, Support::Messages.invalid_value(
|
|
131
114
|
name: 'omit',
|
|
132
115
|
value: omit,
|
|
133
116
|
valid_values: %i[empty nil]
|
|
134
117
|
) if [nil, :empty, :nil].exclude?(omit)
|
|
135
118
|
|
|
136
|
-
operation =
|
|
137
|
-
|
|
119
|
+
operation = api.find_operation!(operation_name)
|
|
120
|
+
response_definition = nil
|
|
138
121
|
|
|
139
122
|
result = begin
|
|
140
123
|
# Authenticate request first if Authentication is included
|
|
@@ -145,7 +128,7 @@ module Jsapi
|
|
|
145
128
|
end
|
|
146
129
|
|
|
147
130
|
status = Status::Code.from(status)
|
|
148
|
-
|
|
131
|
+
response_definition = operation.find_response_for!(status)
|
|
149
132
|
|
|
150
133
|
api_params = _api_params(operation, strong: strong)
|
|
151
134
|
|
|
@@ -157,19 +140,17 @@ module Jsapi
|
|
|
157
140
|
|
|
158
141
|
block&.call(api_params)
|
|
159
142
|
rescue StandardError => e
|
|
160
|
-
definitions = api_definitions
|
|
161
|
-
|
|
162
143
|
# Lookup a rescue handler
|
|
163
|
-
rescue_handler =
|
|
144
|
+
rescue_handler = api.rescue_handler_for(e)
|
|
164
145
|
raise e if rescue_handler.nil?
|
|
165
146
|
|
|
166
|
-
# Replace the status code and response
|
|
147
|
+
# Replace the status code and response definition
|
|
167
148
|
status = rescue_handler.status_code
|
|
168
|
-
|
|
169
|
-
raise e if
|
|
149
|
+
response_definition = operation.find_response_for(status)
|
|
150
|
+
raise e if response_definition.nil?
|
|
170
151
|
|
|
171
152
|
# Call on_rescue callbacks
|
|
172
|
-
|
|
153
|
+
api.on_rescue_callbacks.each do |callback|
|
|
173
154
|
callback.respond_to?(:call) ? callback.call(e) : send(callback, e)
|
|
174
155
|
end
|
|
175
156
|
|
|
@@ -179,9 +160,12 @@ module Jsapi
|
|
|
179
160
|
return if response_body
|
|
180
161
|
|
|
181
162
|
# Produce response
|
|
182
|
-
media_type,
|
|
163
|
+
media_type, content_definition =
|
|
164
|
+
response_definition
|
|
165
|
+
.media_type_and_content_for(*_api_accept)
|
|
166
|
+
|
|
183
167
|
status = status&.to_i
|
|
184
|
-
return head(status) unless
|
|
168
|
+
return head(status) unless content_definition
|
|
185
169
|
|
|
186
170
|
result = _api_before_rendering(operation_name, result, api_params)
|
|
187
171
|
|
|
@@ -194,9 +178,9 @@ module Jsapi
|
|
|
194
178
|
elsif media_type.json? || media_type.json_seq?
|
|
195
179
|
api_response = Response.new(
|
|
196
180
|
result,
|
|
197
|
-
|
|
181
|
+
content_definition,
|
|
198
182
|
omit: omit,
|
|
199
|
-
locale:
|
|
183
|
+
locale: response_definition.locale
|
|
200
184
|
)
|
|
201
185
|
if media_type.json?
|
|
202
186
|
render(
|
|
@@ -225,8 +209,7 @@ module Jsapi
|
|
|
225
209
|
#
|
|
226
210
|
# +operation_name+ can be omitted if the controller handles one operation only.
|
|
227
211
|
#
|
|
228
|
-
# If
|
|
229
|
-
# is raised.
|
|
212
|
+
# If the operation does not exist, an OperationNotFound error is raised.
|
|
230
213
|
#
|
|
231
214
|
# If +strong+ is +true+, parameters that can be mapped are accepted only. That means
|
|
232
215
|
# that the model returned is invalid if there are any request parameters that can't be
|
|
@@ -234,20 +217,19 @@ module Jsapi
|
|
|
234
217
|
#
|
|
235
218
|
# Note that each call of +api_params+ returns a newly created instance.
|
|
236
219
|
def api_params(operation_name = nil, strong: false)
|
|
237
|
-
_api_params(
|
|
220
|
+
_api_params(api.find_operation!(operation_name), strong: strong)
|
|
238
221
|
end
|
|
239
222
|
|
|
240
|
-
# Returns a Response to serialize the JSON representation of +result+ according to
|
|
241
|
-
# appropriate +response+ specification.
|
|
223
|
+
# Returns a Response to serialize the JSON representation of +result+ according to
|
|
224
|
+
# the appropriate +response+ specification.
|
|
242
225
|
#
|
|
243
226
|
# render(json: api_response(bar, 'foo', status: 200))
|
|
244
227
|
#
|
|
245
228
|
# +operation_name+ can be omitted if the controller handles one operation only.
|
|
246
|
-
#
|
|
247
|
-
# If no operation could be found for +operation_name+, an OperationNotFound exception
|
|
248
|
-
# is raised.
|
|
229
|
+
# If the operation does not exist, an OperationNotFound error is raised.
|
|
249
230
|
#
|
|
250
231
|
# +:status+ specifies the HTTP status code of the response to be produced.
|
|
232
|
+
# If no suitable response exists, a ResponseNotFound error is raised.
|
|
251
233
|
#
|
|
252
234
|
# The +:omit+ option specifies on which conditions properties are omitted.
|
|
253
235
|
# Possible values are:
|
|
@@ -255,37 +237,28 @@ module Jsapi
|
|
|
255
237
|
# - +:empty+ - All of the properties whose value is empty are omitted.
|
|
256
238
|
# - +:nil+ - All of the properties whose value is +nil+ are omitted.
|
|
257
239
|
def api_response(result, operation_name = nil, omit: nil, status: nil)
|
|
258
|
-
raise ArgumentError, Messages.invalid_value(
|
|
240
|
+
raise ArgumentError, Support::Messages.invalid_value(
|
|
259
241
|
name: 'omit',
|
|
260
242
|
value: omit,
|
|
261
243
|
valid_values: %i[empty nil]
|
|
262
244
|
) if [nil, :empty, :nil].exclude?(omit)
|
|
263
245
|
|
|
264
246
|
status = Status::Code.from(status)
|
|
265
|
-
operation =
|
|
266
|
-
|
|
247
|
+
operation = api.find_operation!(operation_name)
|
|
248
|
+
response_definition = operation.find_response_for!(status)
|
|
267
249
|
|
|
268
250
|
Response.new(
|
|
269
251
|
result,
|
|
270
|
-
|
|
252
|
+
response_definition.content_for(*_api_accept),
|
|
271
253
|
omit: omit,
|
|
272
|
-
locale:
|
|
254
|
+
locale: response_definition.locale
|
|
273
255
|
)
|
|
274
256
|
end
|
|
275
257
|
|
|
276
258
|
private
|
|
277
259
|
|
|
278
|
-
def
|
|
279
|
-
|
|
280
|
-
*(request.headers['Accept']&.split(',').presence || [Media::Range::ALL])
|
|
281
|
-
)
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
def _api_operation(operation_name)
|
|
285
|
-
operation = api_definitions.find_operation(operation_name)
|
|
286
|
-
return operation if operation
|
|
287
|
-
|
|
288
|
-
raise OperationNotFound.new(operation_name)
|
|
260
|
+
def _api_accept
|
|
261
|
+
request.headers['Accept']&.split(',').presence || [Media::Range::ALL]
|
|
289
262
|
end
|
|
290
263
|
|
|
291
264
|
def _api_params(operation, strong:)
|
|
@@ -298,13 +271,6 @@ module Jsapi
|
|
|
298
271
|
)
|
|
299
272
|
)
|
|
300
273
|
end
|
|
301
|
-
|
|
302
|
-
def _api_response_model(operation, status)
|
|
303
|
-
response_model = operation.find_response(status)
|
|
304
|
-
return response_model if response_model
|
|
305
|
-
|
|
306
|
-
raise ResponseNotFound.new(operation, status)
|
|
307
|
-
end
|
|
308
274
|
end
|
|
309
275
|
end
|
|
310
276
|
end
|
|
@@ -20,11 +20,11 @@ module Jsapi
|
|
|
20
20
|
@params_to_be_validated = strong == true ? params.dup : {}
|
|
21
21
|
|
|
22
22
|
# Parameters
|
|
23
|
-
@raw_attributes = operation.parameters.transform_values do |
|
|
23
|
+
@raw_attributes = operation.parameters.transform_values do |parameter_definition|
|
|
24
24
|
JSON.wrap(
|
|
25
|
-
case
|
|
25
|
+
case parameter_definition.in
|
|
26
26
|
when 'header'
|
|
27
|
-
request.headers[
|
|
27
|
+
request.headers[parameter_definition.name]
|
|
28
28
|
when 'querystring'
|
|
29
29
|
query_params = request.query_parameters
|
|
30
30
|
keys = query_params.keys
|
|
@@ -32,11 +32,11 @@ module Jsapi
|
|
|
32
32
|
unassigned_params.except!(*keys)
|
|
33
33
|
@params_to_be_validated.except!(*keys)
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
parameter_definition.object? ? params.slice(*keys) : query_params.to_query
|
|
36
36
|
else
|
|
37
|
-
unassigned_params.delete(
|
|
37
|
+
unassigned_params.delete(parameter_definition.name)
|
|
38
38
|
end,
|
|
39
|
-
|
|
39
|
+
parameter_definition.schema,
|
|
40
40
|
context: :request
|
|
41
41
|
)
|
|
42
42
|
end
|
|
@@ -4,16 +4,16 @@ module Jsapi
|
|
|
4
4
|
module Controller
|
|
5
5
|
# Used to jsonify a response.
|
|
6
6
|
class Response
|
|
7
|
-
# Creates a new instance to jsonify +object+ according to +
|
|
7
|
+
# Creates a new instance to jsonify +object+ according to +content_definition+.
|
|
8
8
|
#
|
|
9
9
|
# The +:omit+ option specifies on which conditions properties are omitted.
|
|
10
10
|
# Possible values are:
|
|
11
11
|
#
|
|
12
12
|
# - +:empty+ - All of the properties whose value is empty are omitted.
|
|
13
13
|
# - +:nil+ - All of the properties whose value is +nil+ are omitted.
|
|
14
|
-
def initialize(object,
|
|
14
|
+
def initialize(object, content_definition, locale: nil, omit: nil)
|
|
15
15
|
@object = object
|
|
16
|
-
@
|
|
16
|
+
@content_definition = content_definition
|
|
17
17
|
@locale = locale
|
|
18
18
|
@omit = omit
|
|
19
19
|
end
|
|
@@ -21,13 +21,13 @@ module Jsapi
|
|
|
21
21
|
# Returns the \JSON representation of the response.
|
|
22
22
|
def as_json(*)
|
|
23
23
|
with_locale do
|
|
24
|
-
@
|
|
24
|
+
@content_definition.schema.jsonify(
|
|
25
25
|
@object,
|
|
26
26
|
context: :response,
|
|
27
27
|
omit: @omit
|
|
28
28
|
)
|
|
29
29
|
end
|
|
30
|
-
rescue JsonifyError => e
|
|
30
|
+
rescue Definition::Schema::JsonifyError => e
|
|
31
31
|
e.prepend('response body') if e.path.blank?
|
|
32
32
|
raise e
|
|
33
33
|
end
|
|
@@ -43,7 +43,7 @@ module Jsapi
|
|
|
43
43
|
|
|
44
44
|
# Writes the response in \JSON sequence text format to +stream+.
|
|
45
45
|
def write_json_seq_to(stream)
|
|
46
|
-
schema = @
|
|
46
|
+
schema = @content_definition.schema
|
|
47
47
|
object = @object
|
|
48
48
|
object = schema.default_value(context: :response) if object.nil?
|
|
49
49
|
|
|
@@ -65,7 +65,7 @@ module Jsapi
|
|
|
65
65
|
).to_json
|
|
66
66
|
)
|
|
67
67
|
stream.write("\n")
|
|
68
|
-
rescue JsonifyError => e
|
|
68
|
+
rescue Definition::Schema::JsonifyError => e
|
|
69
69
|
raise e.prepend("[#{index}]")
|
|
70
70
|
end
|
|
71
71
|
end
|