jsapi 0.5.0 → 0.6.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/controller/methods.rb +39 -13
- data/lib/jsapi/controller/parameters.rb +25 -23
- data/lib/jsapi/controller/response.rb +35 -22
- data/lib/jsapi/dsl/class_methods.rb +18 -10
- data/lib/jsapi/dsl/definitions.rb +11 -0
- data/lib/jsapi/dsl/openapi/callbacks.rb +34 -0
- data/lib/jsapi/dsl/openapi/examples.rb +32 -0
- data/lib/jsapi/dsl/openapi.rb +2 -0
- data/lib/jsapi/dsl/operation.rb +1 -1
- data/lib/jsapi/dsl/parameter.rb +1 -1
- data/lib/jsapi/dsl/request_body.rb +1 -1
- data/lib/jsapi/dsl/response.rb +1 -1
- data/lib/jsapi/dsl.rb +1 -3
- data/lib/jsapi/helpers/invalid_value_helper.rb +17 -0
- data/lib/jsapi/invalid_argument_error.rb +12 -0
- data/lib/jsapi/invalid_value_error.rb +12 -0
- data/lib/jsapi/json/object.rb +15 -14
- data/lib/jsapi/json.rb +1 -1
- data/lib/jsapi/meta/{attributes/class_methods.rb → base/attributes.rb} +2 -2
- data/lib/jsapi/meta/base/model.rb +44 -0
- data/lib/jsapi/meta/base/reference.rb +36 -0
- data/lib/jsapi/meta/{attributes → base}/type_caster.rb +2 -2
- data/lib/jsapi/meta/base.rb +4 -40
- data/lib/jsapi/meta/callable/symbol_evaluator.rb +30 -0
- data/lib/jsapi/meta/callable/symbol_sequence_evaluator.rb +29 -0
- data/lib/jsapi/meta/callable.rb +28 -0
- data/lib/jsapi/meta/defaults.rb +28 -0
- data/lib/jsapi/meta/definitions.rb +30 -25
- data/lib/jsapi/meta/openapi/callback/model.rb +1 -1
- data/lib/jsapi/meta/openapi/callback/reference.rb +1 -1
- data/lib/jsapi/meta/openapi/contact.rb +1 -1
- data/lib/jsapi/meta/openapi/example/model.rb +1 -1
- data/lib/jsapi/meta/openapi/example/reference.rb +1 -1
- data/lib/jsapi/meta/openapi/external_documentation.rb +1 -1
- data/lib/jsapi/meta/openapi/header/model.rb +17 -2
- data/lib/jsapi/meta/openapi/header/reference.rb +1 -1
- data/lib/jsapi/meta/openapi/info.rb +1 -1
- data/lib/jsapi/meta/openapi/license.rb +1 -1
- data/lib/jsapi/meta/openapi/link/model.rb +1 -1
- data/lib/jsapi/meta/openapi/link/reference.rb +1 -1
- data/lib/jsapi/meta/openapi/oauth_flow.rb +2 -2
- data/lib/jsapi/meta/openapi/root.rb +6 -20
- data/lib/jsapi/meta/openapi/security_requirement.rb +2 -2
- data/lib/jsapi/meta/openapi/security_scheme/base.rb +1 -1
- data/lib/jsapi/meta/openapi/security_scheme.rb +1 -1
- data/lib/jsapi/meta/openapi/server.rb +1 -1
- data/lib/jsapi/meta/openapi/server_variable.rb +1 -1
- data/lib/jsapi/meta/openapi/tag.rb +1 -1
- data/lib/jsapi/meta/operation.rb +21 -24
- data/lib/jsapi/meta/parameter/model.rb +4 -3
- data/lib/jsapi/meta/parameter/reference.rb +1 -1
- data/lib/jsapi/meta/property.rb +9 -3
- data/lib/jsapi/meta/request_body/model.rb +8 -3
- data/lib/jsapi/meta/request_body/reference.rb +1 -1
- data/lib/jsapi/meta/response/model.rb +9 -4
- data/lib/jsapi/meta/response/reference.rb +1 -1
- data/lib/jsapi/meta/schema/additional_properties.rb +5 -6
- data/lib/jsapi/meta/schema/base.rb +13 -7
- data/lib/jsapi/meta/schema/discriminator.rb +1 -9
- data/lib/jsapi/meta/schema/object.rb +27 -4
- data/lib/jsapi/meta/schema/reference.rb +1 -1
- data/lib/jsapi/meta/schema.rb +12 -5
- data/lib/jsapi/meta.rb +3 -5
- data/lib/jsapi/model/attributes.rb +10 -4
- data/lib/jsapi/model/base.rb +1 -1
- data/lib/jsapi/model/nestable.rb +25 -10
- data/lib/jsapi/version.rb +1 -1
- data/lib/jsapi.rb +4 -0
- metadata +15 -11
- data/lib/jsapi/dsl/callbacks.rb +0 -32
- data/lib/jsapi/dsl/examples.rb +0 -30
- data/lib/jsapi/meta/attributes.rb +0 -4
- data/lib/jsapi/meta/base_reference.rb +0 -34
- data/lib/jsapi/meta/invalid_argument_error.rb +0 -12
- data/lib/jsapi/meta/method_chain.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49b5e17933d1306b3c7637f0d0dd37d3efb7f698acc43b0664c239d6caf4b593
|
4
|
+
data.tar.gz: '08b7e251c989693f2d055c140488278d2c2fb047a814fe4ff90be7fdb2fa8869'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba696113c7b4e842085baa0ad4462a5566c7b5fb8c96030708eb4e33b47319865d86271d1f4b6643a39e83c7a59ee71c54b7d3ca6837e9515e6665d94e1ff7d2
|
7
|
+
data.tar.gz: 9f0e9aa79495064cdbebdfd12cbdd4501891ef5c5be30ffe3a0435afa58fd7ec87750eeb5c9068ff4da49a17e56c2e028512a260155ed2f0f13b4fde88cd23a4
|
@@ -13,9 +13,9 @@ module Jsapi
|
|
13
13
|
end
|
14
14
|
|
15
15
|
# Performs an API operation by calling the given block. The request parameters are
|
16
|
-
# passed as an instance of the operation's model class to the block.
|
17
|
-
#
|
18
|
-
#
|
16
|
+
# passed as an instance of the operation's model class to the block. The object
|
17
|
+
# returned by the block is implicitly rendered according to the appropriate +response+
|
18
|
+
# specification.
|
19
19
|
#
|
20
20
|
# api_operation('foo') do |api_params|
|
21
21
|
# # ...
|
@@ -23,13 +23,22 @@ module Jsapi
|
|
23
23
|
#
|
24
24
|
# +operation_name+ can be +nil+ if the controller handles one operation only.
|
25
25
|
#
|
26
|
-
# If
|
26
|
+
# If +:strong+ is +true+, parameters that can be mapped are accepted only. That means
|
27
27
|
# that the model passed to the block is invalid if there are any request parameters
|
28
28
|
# that can't be mapped to a parameter or a request body property of the operation.
|
29
29
|
#
|
30
|
-
|
30
|
+
# The +:omit+ option specifies on which conditions properties are omitted.
|
31
|
+
# Possible values are:
|
32
|
+
#
|
33
|
+
# - +:empty+ - All of the properties whose value is empty are omitted.
|
34
|
+
# - +:nil+ - All of the properties whose value is +nil+ are omitted.
|
35
|
+
#
|
36
|
+
# Raises an InvalidArgumentError when the value of +:omit+ is invalid.
|
37
|
+
def api_operation(operation_name = nil, omit: nil, status: nil, strong: false, &block)
|
31
38
|
_perform_api_operation(
|
32
|
-
operation_name,
|
39
|
+
operation_name,
|
40
|
+
bang: false,
|
41
|
+
omit: omit,
|
33
42
|
status: status,
|
34
43
|
strong: strong,
|
35
44
|
&block
|
@@ -43,9 +52,11 @@ module Jsapi
|
|
43
52
|
# # ...
|
44
53
|
# end
|
45
54
|
#
|
46
|
-
def api_operation!(operation_name = nil, status: nil, strong: false, &block)
|
55
|
+
def api_operation!(operation_name = nil, omit: nil, status: nil, strong: false, &block)
|
47
56
|
_perform_api_operation(
|
48
|
-
operation_name,
|
57
|
+
operation_name,
|
58
|
+
bang: true,
|
59
|
+
omit: omit,
|
49
60
|
status: status,
|
50
61
|
strong: strong,
|
51
62
|
&block
|
@@ -79,12 +90,20 @@ module Jsapi
|
|
79
90
|
# render(json: api_response(bar, 'foo', status: 200))
|
80
91
|
#
|
81
92
|
# +operation_name+ can be +nil+ if the controller handles one operation only.
|
82
|
-
|
93
|
+
#
|
94
|
+
# The +:omit+ option specifies on which conditions properties are omitted.
|
95
|
+
# Possible values are:
|
96
|
+
#
|
97
|
+
# - +:empty+ - All of the properties whose value is empty are omitted.
|
98
|
+
# - +:nil+ - All of the properties whose value is +nil+ are omitted.
|
99
|
+
#
|
100
|
+
# Raises an InvalidArgumentError when the value of +:omit+ is invalid.
|
101
|
+
def api_response(result, operation_name = nil, omit: nil, status: nil)
|
83
102
|
definitions = api_definitions
|
84
103
|
operation = _api_operation(operation_name, definitions)
|
85
104
|
response = _api_response(operation, status, definitions)
|
86
105
|
|
87
|
-
Response.new(result, response, api_definitions)
|
106
|
+
Response.new(result, response, api_definitions, omit: omit)
|
88
107
|
end
|
89
108
|
|
90
109
|
private
|
@@ -98,7 +117,13 @@ module Jsapi
|
|
98
117
|
|
99
118
|
def _api_params(operation, definitions, strong:)
|
100
119
|
(operation.model || Model::Base).new(
|
101
|
-
Parameters.new(
|
120
|
+
Parameters.new(
|
121
|
+
params.except(:action, :controller, :format).permit!,
|
122
|
+
headers,
|
123
|
+
operation,
|
124
|
+
definitions,
|
125
|
+
strong: strong
|
126
|
+
)
|
102
127
|
)
|
103
128
|
end
|
104
129
|
|
@@ -109,7 +134,7 @@ module Jsapi
|
|
109
134
|
raise "status code not defined: #{status}"
|
110
135
|
end
|
111
136
|
|
112
|
-
def _perform_api_operation(operation_name, bang
|
137
|
+
def _perform_api_operation(operation_name, bang:, omit:, status:, strong:, &block)
|
113
138
|
definitions = api_definitions
|
114
139
|
operation = _api_operation(operation_name, definitions)
|
115
140
|
response = _api_response(operation, status, definitions)
|
@@ -141,10 +166,11 @@ module Jsapi
|
|
141
166
|
|
142
167
|
ErrorResult.new(e, status: status)
|
143
168
|
end
|
144
|
-
render(json: Response.new(result, response, definitions), status: status)
|
169
|
+
render(json: Response.new(result, response, definitions, omit: omit), status: status)
|
145
170
|
else
|
146
171
|
head(status)
|
147
172
|
end
|
173
|
+
self.content_type = response.content_type
|
148
174
|
end
|
149
175
|
end
|
150
176
|
end
|
@@ -6,7 +6,7 @@ module Jsapi
|
|
6
6
|
class Parameters
|
7
7
|
include Model::Nestable
|
8
8
|
|
9
|
-
attr_reader :raw_attributes
|
9
|
+
attr_reader :raw_additional_attributes, :raw_attributes
|
10
10
|
|
11
11
|
# Creates a new instance that wraps +params+ according to +operation+. References are
|
12
12
|
# resolved to API components in +definitions+.
|
@@ -14,29 +14,35 @@ module Jsapi
|
|
14
14
|
# If +strong+ is true+ parameters that can be mapped are accepted only. That means that
|
15
15
|
# the instance created is invalid if +params+ contains any parameters that can't be
|
16
16
|
# mapped to a parameter or a request body property of +operation+.
|
17
|
-
def initialize(params, operation, definitions, strong: false)
|
18
|
-
@params = params
|
17
|
+
def initialize(params, headers, operation, definitions, strong: false)
|
18
|
+
@params = params.to_h
|
19
19
|
@strong = strong == true
|
20
20
|
@raw_attributes = {}
|
21
|
+
@raw_additional_attributes = {}
|
21
22
|
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
request_body = operation.request_body&.resolve(definitions)
|
27
|
-
if request_body && request_body.schema.respond_to?(:properties)
|
28
|
-
meta_models.merge!(request_body.schema.resolve_properties(:write, definitions))
|
29
|
-
end
|
23
|
+
# Parameters
|
24
|
+
operation.parameters.each do |name, parameter_model|
|
25
|
+
parameter_model = parameter_model.resolve(definitions)
|
30
26
|
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
@raw_attributes[name] = JSON.wrap(
|
28
|
+
parameter_model.in == 'header' ? headers[name] : @params[name],
|
29
|
+
parameter_model.schema.resolve(definitions),
|
30
|
+
definitions
|
31
|
+
)
|
34
32
|
end
|
35
|
-
end
|
36
33
|
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
# Request body
|
35
|
+
request_body_schema = operation.request_body&.resolve(definitions)
|
36
|
+
&.schema&.resolve(definitions)
|
37
|
+
if request_body_schema&.object?
|
38
|
+
request_body = JSON.wrap(
|
39
|
+
@params.except(*operation.parameters.keys),
|
40
|
+
request_body_schema,
|
41
|
+
definitions
|
42
|
+
)
|
43
|
+
@raw_attributes.merge!(request_body.raw_attributes)
|
44
|
+
@raw_additional_attributes = request_body.raw_additional_attributes
|
45
|
+
end
|
40
46
|
end
|
41
47
|
|
42
48
|
# Validates the request parameters. Returns true if the parameters are valid, false
|
@@ -44,11 +50,7 @@ module Jsapi
|
|
44
50
|
def validate(errors)
|
45
51
|
[
|
46
52
|
validate_attributes(errors),
|
47
|
-
!@strong || validate_parameters(
|
48
|
-
@params.except(:controller, :action, :format),
|
49
|
-
attributes,
|
50
|
-
errors
|
51
|
-
)
|
53
|
+
!@strong || validate_parameters(@params, attributes, errors)
|
52
54
|
].all?
|
53
55
|
end
|
54
56
|
|
@@ -7,10 +7,23 @@ module Jsapi
|
|
7
7
|
|
8
8
|
# Creates a new instance to serialize +object+ according to +response+. References
|
9
9
|
# are resolved to API components in +definitions+.
|
10
|
-
|
10
|
+
#
|
11
|
+
# The +:omit+ option specifies on which conditions properties are omitted.
|
12
|
+
# Possible values are:
|
13
|
+
#
|
14
|
+
# - +:empty+ - All of the properties whose value is empty are omitted.
|
15
|
+
# - +:nil+ - All of the properties whose value is +nil+ are omitted.
|
16
|
+
#
|
17
|
+
# Raises an InvalidArgumentError when the value of +:omit+ is invalid.
|
18
|
+
def initialize(object, response, definitions, omit: nil)
|
19
|
+
if [:empty, :nil, nil].exclude?(omit)
|
20
|
+
raise InvalidArgumentError.new('omit', omit, valid_values: %i[empty nil])
|
21
|
+
end
|
22
|
+
|
11
23
|
@object = object
|
12
24
|
@response = response
|
13
25
|
@definitions = definitions
|
26
|
+
@omit = omit
|
14
27
|
end
|
15
28
|
|
16
29
|
def inspect # :nodoc:
|
@@ -32,7 +45,9 @@ module Jsapi
|
|
32
45
|
private
|
33
46
|
|
34
47
|
def serialize(object, schema, path = nil)
|
48
|
+
object = schema.default_value(@definitions, context: :response) if object.nil?
|
35
49
|
return if object.nil? && schema.nullable?
|
50
|
+
|
36
51
|
raise "#{path || 'response'} can't be nil" if object.nil?
|
37
52
|
|
38
53
|
case schema.type
|
@@ -68,36 +83,33 @@ module Jsapi
|
|
68
83
|
end
|
69
84
|
|
70
85
|
def serialize_object(object, schema, path)
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
if (discriminator = schema.discriminator)
|
75
|
-
discriminator_property = schema.properties[discriminator.property_name]
|
76
|
-
schema = discriminator.resolve(
|
77
|
-
object.public_send(discriminator_property.source || discriminator_property.name.underscore),
|
78
|
-
@definitions
|
79
|
-
)
|
80
|
-
end
|
86
|
+
schema = schema.resolve_schema(object, @definitions, context: :response)
|
87
|
+
properties = {}
|
88
|
+
|
81
89
|
# Serialize properties
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
+
schema.resolve_properties(@definitions, context: :response).each do |key, property|
|
91
|
+
property_schema = property.schema.resolve(@definitions)
|
92
|
+
property_value = property.reader.call(object)
|
93
|
+
property_value = property.default if property_value.nil?
|
94
|
+
|
95
|
+
next if ((@omit == :empty && property_value.try(:empty?)) ||
|
96
|
+
(@omit == :nil && property_value.nil?)) &&
|
97
|
+
property_schema.omittable?
|
98
|
+
|
99
|
+
properties[key] = serialize(
|
100
|
+
property_value,
|
101
|
+
property_schema,
|
90
102
|
path.nil? ? property.name : "#{path}.#{property.name}"
|
91
103
|
)
|
92
104
|
end
|
93
|
-
|
105
|
+
# Serialize additional properties
|
106
|
+
if (additional_properties = schema.additional_properties)
|
94
107
|
additional_properties_schema = additional_properties.schema.resolve(@definitions)
|
95
108
|
|
96
109
|
additional_properties.source.call(object)&.each do |key, value|
|
97
110
|
# Don't replace the property with the same key
|
98
111
|
next if properties.key?(key = key.to_s)
|
99
112
|
|
100
|
-
# Serialize the additional property
|
101
113
|
properties[key] = serialize(
|
102
114
|
value,
|
103
115
|
additional_properties_schema,
|
@@ -105,7 +117,8 @@ module Jsapi
|
|
105
117
|
)
|
106
118
|
end
|
107
119
|
end
|
108
|
-
properties
|
120
|
+
# Return properties if present, otherwise nil
|
121
|
+
properties if properties.present?
|
109
122
|
end
|
110
123
|
end
|
111
124
|
end
|
@@ -3,6 +3,14 @@
|
|
3
3
|
module Jsapi
|
4
4
|
module DSL
|
5
5
|
module ClassMethods
|
6
|
+
# Specifies the general default values for +type+.
|
7
|
+
#
|
8
|
+
# api_default 'array', read: [], write: []
|
9
|
+
#
|
10
|
+
def api_default(type, **keywords, &block)
|
11
|
+
api_definitions { default(type, **keywords, &block) }
|
12
|
+
end
|
13
|
+
|
6
14
|
# The API definitions of the current class.
|
7
15
|
def api_definitions(&block)
|
8
16
|
@api_definitions ||= Meta::Definitions.new(self)
|
@@ -30,24 +38,24 @@ module Jsapi
|
|
30
38
|
# end
|
31
39
|
#
|
32
40
|
# +name+ can be +nil+ if the controller handles one operation only.
|
33
|
-
def api_operation(name = nil, **
|
34
|
-
api_definitions { operation(name, **
|
41
|
+
def api_operation(name = nil, **keywords, &block)
|
42
|
+
api_definitions { operation(name, **keywords, &block) }
|
35
43
|
end
|
36
44
|
|
37
45
|
# Defines a reusable parameter.
|
38
46
|
#
|
39
47
|
# api_parameter 'foo', type: 'string'
|
40
48
|
#
|
41
|
-
def api_parameter(name, **
|
42
|
-
api_definitions { parameter(name, **
|
49
|
+
def api_parameter(name, **keywords, &block)
|
50
|
+
api_definitions { parameter(name, **keywords, &block) }
|
43
51
|
end
|
44
52
|
|
45
53
|
# Defines a reusable request body.
|
46
54
|
#
|
47
55
|
# api_request_body 'foo', type: 'string'
|
48
56
|
#
|
49
|
-
def api_request_body(name, **
|
50
|
-
api_definitions { request_body(name, **
|
57
|
+
def api_request_body(name, **keywords, &block)
|
58
|
+
api_definitions { request_body(name, **keywords, &block) }
|
51
59
|
end
|
52
60
|
|
53
61
|
# Specifies the HTTP status code of an error response rendered when an
|
@@ -64,8 +72,8 @@ module Jsapi
|
|
64
72
|
# api_response 'Foo', type: 'object' do
|
65
73
|
# property 'bar', type: 'string'
|
66
74
|
# end
|
67
|
-
def api_response(name, **
|
68
|
-
api_definitions { response(name, **
|
75
|
+
def api_response(name, **keywords, &block)
|
76
|
+
api_definitions { response(name, **keywords, &block) }
|
69
77
|
end
|
70
78
|
|
71
79
|
# Defines a reusable schema.
|
@@ -73,8 +81,8 @@ module Jsapi
|
|
73
81
|
# api_schema 'Foo' do
|
74
82
|
# property 'bar', type: 'string'
|
75
83
|
# end
|
76
|
-
def api_schema(name, **
|
77
|
-
api_definitions { schema(name, **
|
84
|
+
def api_schema(name, **keywords, &block)
|
85
|
+
api_definitions { schema(name, **keywords, &block) }
|
78
86
|
end
|
79
87
|
|
80
88
|
# Defines the root of an OpenAPI document.
|
@@ -5,6 +5,17 @@ module Jsapi
|
|
5
5
|
# Used to define top-level API components.
|
6
6
|
class Definitions < Node
|
7
7
|
|
8
|
+
# Specifies the general default values for +type+.
|
9
|
+
#
|
10
|
+
# default 'array', read: [], write: []
|
11
|
+
#
|
12
|
+
def default(type, **keywords, &block)
|
13
|
+
_define('default', type.inspect) do
|
14
|
+
default = _meta_model.add_default(type, keywords)
|
15
|
+
Node.new(default, &block) if block
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
8
19
|
# Includes API definitions from +klasses+.
|
9
20
|
def include(*klasses)
|
10
21
|
klasses.each do |klass|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module DSL
|
5
|
+
module OpenAPI
|
6
|
+
module Callbacks
|
7
|
+
# Defines an \OpenAPI callback or refers a reusable callback.
|
8
|
+
#
|
9
|
+
# # define a callback
|
10
|
+
# callback 'foo' do
|
11
|
+
# operation '{$request.query.foo}'
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# # refer a reusable callback
|
15
|
+
# callback ref: 'foo'
|
16
|
+
#
|
17
|
+
# Refers the reusable callback with the same name if neither any
|
18
|
+
# keywords nor a block is specified.
|
19
|
+
#
|
20
|
+
# callback 'foo'
|
21
|
+
#
|
22
|
+
def callback(name = nil, **keywords, &block)
|
23
|
+
_define('callback', name&.inspect) do
|
24
|
+
name = keywords[:ref] if name.nil?
|
25
|
+
keywords = { ref: name } unless keywords.any? || block
|
26
|
+
|
27
|
+
callback_model = _meta_model.add_callback(name, keywords)
|
28
|
+
_eval(callback_model, OpenAPI::Callback, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module DSL
|
5
|
+
module OpenAPI
|
6
|
+
module Examples
|
7
|
+
# Adds an example.
|
8
|
+
#
|
9
|
+
# example 'foo', value: 'bar'
|
10
|
+
#
|
11
|
+
# example 'foo'
|
12
|
+
#
|
13
|
+
# The default name is <code>'default'</code>.
|
14
|
+
def example(name_or_value = nil, **keywords, &block)
|
15
|
+
_define('example', name_or_value&.inspect) do
|
16
|
+
if keywords.any? || block
|
17
|
+
# example 'foo', value: 'bar', ...
|
18
|
+
name = name_or_value
|
19
|
+
else
|
20
|
+
# example 'foo'
|
21
|
+
name = nil
|
22
|
+
keywords = { value: name_or_value }
|
23
|
+
end
|
24
|
+
|
25
|
+
example = _meta_model.add_example(name, keywords)
|
26
|
+
Node.new(example, &block) if block
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/jsapi/dsl/openapi.rb
CHANGED
data/lib/jsapi/dsl/operation.rb
CHANGED
data/lib/jsapi/dsl/parameter.rb
CHANGED
data/lib/jsapi/dsl/response.rb
CHANGED
data/lib/jsapi/dsl.rb
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'dsl/callbacks'
|
4
|
-
require_relative 'dsl/examples'
|
5
3
|
require_relative 'dsl/error'
|
6
4
|
require_relative 'dsl/node'
|
5
|
+
require_relative 'dsl/openapi'
|
7
6
|
require_relative 'dsl/schema'
|
8
7
|
require_relative 'dsl/parameter'
|
9
8
|
require_relative 'dsl/request_body'
|
10
9
|
require_relative 'dsl/response'
|
11
10
|
require_relative 'dsl/operation'
|
12
|
-
require_relative 'dsl/openapi'
|
13
11
|
require_relative 'dsl/definitions'
|
14
12
|
require_relative 'dsl/class_methods'
|
15
13
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module InvalidValueHelper
|
5
|
+
def build_message(name, value, valid_values)
|
6
|
+
case valid_values.count
|
7
|
+
when 0
|
8
|
+
"#{name} must not be #{value.inspect}"
|
9
|
+
when 1
|
10
|
+
"#{name} must be #{valid_values.first.inspect}, is #{value.inspect}"
|
11
|
+
else
|
12
|
+
"#{name} must be one of #{valid_values[0..-2].map(&:inspect).join(', ')} " \
|
13
|
+
"or #{valid_values.last.inspect}, is #{value.inspect}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
# Raised when an argument isn't contained in the list of valid values.
|
5
|
+
class InvalidArgumentError < ArgumentError
|
6
|
+
include InvalidValueHelper
|
7
|
+
|
8
|
+
def initialize(name, value, valid_values: [])
|
9
|
+
super(build_message(name, value, valid_values))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
# Raised when a value isn't contained in the list of valid values.
|
5
|
+
class InvalidValueError < RuntimeError
|
6
|
+
include InvalidValueHelper
|
7
|
+
|
8
|
+
def initialize(name, value, valid_values: [])
|
9
|
+
super(build_message(name, value, valid_values))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/jsapi/json/object.rb
CHANGED
@@ -6,18 +6,24 @@ module Jsapi
|
|
6
6
|
class Object < Value
|
7
7
|
include Model::Nestable
|
8
8
|
|
9
|
-
attr_reader :raw_attributes
|
9
|
+
attr_reader :raw_additional_attributes, :raw_attributes
|
10
10
|
|
11
11
|
def initialize(attributes, schema, definitions)
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
schema = schema.resolve_schema(attributes, definitions, context: :request)
|
13
|
+
properties = schema.resolve_properties(definitions, context: :request)
|
14
|
+
|
15
|
+
@raw_attributes = properties.transform_values do |property|
|
16
|
+
JSON.wrap(attributes[property.name], property.schema, definitions)
|
15
17
|
end
|
16
|
-
|
17
|
-
@
|
18
|
-
schema.
|
19
|
-
|
20
|
-
|
18
|
+
|
19
|
+
@raw_additional_attributes =
|
20
|
+
if (additional_properties = schema.additional_properties)
|
21
|
+
additional_properties_schema = additional_properties.schema.resolve(definitions)
|
22
|
+
|
23
|
+
attributes.except(*properties.keys).transform_values do |value|
|
24
|
+
JSON.wrap(value, additional_properties_schema, definitions)
|
25
|
+
end
|
26
|
+
end || {}
|
21
27
|
|
22
28
|
super(schema)
|
23
29
|
end
|
@@ -27,11 +33,6 @@ module Jsapi
|
|
27
33
|
@raw_attributes.values.all?(&:empty?)
|
28
34
|
end
|
29
35
|
|
30
|
-
def inspect # :nodoc:
|
31
|
-
"#<#{self.class.name} " \
|
32
|
-
"#{@raw_attributes.map { |k, v| "#{k}: #{v.inspect}" }.join(', ')}>"
|
33
|
-
end
|
34
|
-
|
35
36
|
# Returns a model to read attributes by.
|
36
37
|
def model
|
37
38
|
@model ||= (schema.model || Model::Base).new(self)
|
data/lib/jsapi/json.rb
CHANGED
@@ -16,7 +16,7 @@ module Jsapi
|
|
16
16
|
def wrap(object, schema, definitions = nil)
|
17
17
|
schema = schema.resolve(definitions) unless definitions.nil?
|
18
18
|
|
19
|
-
object = schema.
|
19
|
+
object = schema.default_value(definitions, context: :request) if object.nil?
|
20
20
|
return Null.new(schema) if object.nil?
|
21
21
|
|
22
22
|
case schema.type
|