jsapi 0.7.3 → 0.9.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.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jsapi/controller/{error_result.rb → error.rb} +1 -1
  3. data/lib/jsapi/controller/methods.rb +49 -38
  4. data/lib/jsapi/controller/parameters.rb +4 -2
  5. data/lib/jsapi/controller/response.rb +82 -64
  6. data/lib/jsapi/controller.rb +1 -1
  7. data/lib/jsapi/dsl/base.rb +55 -0
  8. data/lib/jsapi/dsl/callback.rb +21 -0
  9. data/lib/jsapi/dsl/class_methods.rb +116 -10
  10. data/lib/jsapi/dsl/definitions.rb +173 -33
  11. data/lib/jsapi/dsl/examples.rb +30 -0
  12. data/lib/jsapi/dsl/operation.rb +60 -32
  13. data/lib/jsapi/dsl/parameter.rb +2 -2
  14. data/lib/jsapi/dsl/request_body.rb +2 -2
  15. data/lib/jsapi/dsl/response.rb +35 -11
  16. data/lib/jsapi/dsl/schema.rb +16 -16
  17. data/lib/jsapi/dsl.rb +4 -4
  18. data/lib/jsapi/{helpers/invalid_value_helper.rb → invalid_value_helper.rb} +1 -1
  19. data/lib/jsapi/json/array.rb +7 -7
  20. data/lib/jsapi/json/object.rb +6 -6
  21. data/lib/jsapi/json.rb +4 -4
  22. data/lib/jsapi/meta/base/attributes.rb +21 -19
  23. data/lib/jsapi/meta/base/model.rb +15 -7
  24. data/lib/jsapi/meta/callback/model.rb +34 -0
  25. data/lib/jsapi/meta/callback/reference.rb +14 -0
  26. data/lib/jsapi/meta/callback.rb +19 -0
  27. data/lib/jsapi/meta/contact.rb +30 -0
  28. data/lib/jsapi/meta/defaults.rb +2 -2
  29. data/lib/jsapi/meta/definitions.rb +230 -124
  30. data/lib/jsapi/meta/example/model.rb +43 -0
  31. data/lib/jsapi/meta/example/reference.rb +14 -0
  32. data/lib/jsapi/meta/example.rb +19 -0
  33. data/lib/jsapi/meta/external_documentation.rb +25 -0
  34. data/lib/jsapi/meta/header/model.rb +81 -0
  35. data/lib/jsapi/meta/header/reference.rb +14 -0
  36. data/lib/jsapi/meta/header.rb +19 -0
  37. data/lib/jsapi/meta/info.rb +52 -0
  38. data/lib/jsapi/meta/license.rb +25 -0
  39. data/lib/jsapi/meta/link/model.rb +48 -0
  40. data/lib/jsapi/meta/link/reference.rb +14 -0
  41. data/lib/jsapi/meta/link.rb +19 -0
  42. data/lib/jsapi/meta/oauth_flow.rb +52 -0
  43. data/lib/jsapi/meta/openapi.rb +0 -28
  44. data/lib/jsapi/meta/operation.rb +19 -18
  45. data/lib/jsapi/meta/parameter/model.rb +6 -4
  46. data/lib/jsapi/meta/parameter/reference.rb +6 -4
  47. data/lib/jsapi/meta/parameter/to_openapi.rb +13 -0
  48. data/lib/jsapi/meta/parameter.rb +2 -1
  49. data/lib/jsapi/meta/property.rb +1 -1
  50. data/lib/jsapi/meta/request_body/model.rb +6 -5
  51. data/lib/jsapi/meta/request_body.rb +1 -1
  52. data/lib/jsapi/meta/response/model.rb +16 -13
  53. data/lib/jsapi/meta/response.rb +1 -1
  54. data/lib/jsapi/meta/schema/array.rb +1 -1
  55. data/lib/jsapi/meta/schema/base.rb +5 -5
  56. data/lib/jsapi/meta/schema/discriminator.rb +2 -2
  57. data/lib/jsapi/meta/schema/object.rb +3 -3
  58. data/lib/jsapi/meta/schema/reference.rb +1 -1
  59. data/lib/jsapi/meta/schema.rb +2 -2
  60. data/lib/jsapi/meta/security_requirement.rb +25 -0
  61. data/lib/jsapi/meta/security_scheme/api_key.rb +38 -0
  62. data/lib/jsapi/meta/security_scheme/base.rb +14 -0
  63. data/lib/jsapi/meta/security_scheme/http/basic.rb +34 -0
  64. data/lib/jsapi/meta/security_scheme/http/bearer.rb +36 -0
  65. data/lib/jsapi/meta/security_scheme/http/other.rb +36 -0
  66. data/lib/jsapi/meta/security_scheme/http.rb +29 -0
  67. data/lib/jsapi/meta/security_scheme/oauth2.rb +44 -0
  68. data/lib/jsapi/meta/security_scheme/open_id_connect.rb +32 -0
  69. data/lib/jsapi/meta/security_scheme.rb +49 -0
  70. data/lib/jsapi/meta/server.rb +34 -0
  71. data/lib/jsapi/meta/server_variable.rb +34 -0
  72. data/lib/jsapi/meta/tag.rb +34 -0
  73. data/lib/jsapi/meta.rb +15 -1
  74. data/lib/jsapi/model/base.rb +5 -5
  75. data/lib/jsapi/version.rb +1 -1
  76. data/lib/jsapi.rb +1 -1
  77. metadata +40 -44
  78. data/lib/jsapi/dsl/node.rb +0 -62
  79. data/lib/jsapi/dsl/openapi/callback.rb +0 -23
  80. data/lib/jsapi/dsl/openapi/callbacks.rb +0 -34
  81. data/lib/jsapi/dsl/openapi/examples.rb +0 -32
  82. data/lib/jsapi/dsl/openapi/root.rb +0 -126
  83. data/lib/jsapi/dsl/openapi.rb +0 -6
  84. data/lib/jsapi/meta/openapi/callback/model.rb +0 -34
  85. data/lib/jsapi/meta/openapi/callback/reference.rb +0 -16
  86. data/lib/jsapi/meta/openapi/callback.rb +0 -21
  87. data/lib/jsapi/meta/openapi/contact.rb +0 -32
  88. data/lib/jsapi/meta/openapi/example/model.rb +0 -44
  89. data/lib/jsapi/meta/openapi/example/reference.rb +0 -16
  90. data/lib/jsapi/meta/openapi/example.rb +0 -21
  91. data/lib/jsapi/meta/openapi/external_documentation.rb +0 -27
  92. data/lib/jsapi/meta/openapi/header/model.rb +0 -82
  93. data/lib/jsapi/meta/openapi/header/reference.rb +0 -16
  94. data/lib/jsapi/meta/openapi/header.rb +0 -21
  95. data/lib/jsapi/meta/openapi/info.rb +0 -54
  96. data/lib/jsapi/meta/openapi/license.rb +0 -27
  97. data/lib/jsapi/meta/openapi/link/model.rb +0 -50
  98. data/lib/jsapi/meta/openapi/link/reference.rb +0 -16
  99. data/lib/jsapi/meta/openapi/link.rb +0 -21
  100. data/lib/jsapi/meta/openapi/oauth_flow.rb +0 -52
  101. data/lib/jsapi/meta/openapi/root.rb +0 -132
  102. data/lib/jsapi/meta/openapi/security_requirement.rb +0 -27
  103. data/lib/jsapi/meta/openapi/security_scheme/api_key.rb +0 -40
  104. data/lib/jsapi/meta/openapi/security_scheme/base.rb +0 -16
  105. data/lib/jsapi/meta/openapi/security_scheme/http/basic.rb +0 -36
  106. data/lib/jsapi/meta/openapi/security_scheme/http/bearer.rb +0 -39
  107. data/lib/jsapi/meta/openapi/security_scheme/http/other.rb +0 -39
  108. data/lib/jsapi/meta/openapi/security_scheme/http.rb +0 -31
  109. data/lib/jsapi/meta/openapi/security_scheme/oauth2.rb +0 -46
  110. data/lib/jsapi/meta/openapi/security_scheme/open_id_connect.rb +0 -34
  111. data/lib/jsapi/meta/openapi/security_scheme.rb +0 -51
  112. data/lib/jsapi/meta/openapi/server.rb +0 -36
  113. data/lib/jsapi/meta/openapi/server_variable.rb +0 -36
  114. data/lib/jsapi/meta/openapi/tag.rb +0 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0b8caebf611ba584ebd5963fefb3e7f4600f3cdda59eeda99049225f4a17fff
4
- data.tar.gz: 94db4048e68964bc70e64068631a3ae01b9ef7434fab23976e69b6368f809d37
3
+ metadata.gz: e68467f73e8f1e909a03cd8c50f16674231dc0d070f05a5368b84e0f75dedfe6
4
+ data.tar.gz: 6c0b1304cb7192d223f517d5233fd96fa13aad7e0affb6832f313088bc3b3993
5
5
  SHA512:
6
- metadata.gz: 144e852da54524999df466dbdf078227cae7d5e68d3155fbc3730b298072d696a39cea1c786513c34862bcb71a14b163bd202b9c203e4736598cb0fddc28813b
7
- data.tar.gz: 9d76e40aa500597eec1a5a7dc02b794ccde643f603227455ccbcea76a6e074769c246335a1e554fa19bc6d06cf8cf36ad030147a651de58f148b3c4db5c12322
6
+ metadata.gz: 45b860d17ffc8f22cfbe4fca26d38e727ff87ddc93a959c6285fd1aaa8eb0de9c5e2a9c516f717f0f6d463b0bfe5c8708b9efa5bab5aa6b08eb642d90ee84d10
7
+ data.tar.gz: fe573b4b85e50373bd832f1ec3d4fdd9c11fe57bf42527fe80021d6c84d2271e01161b08cdedcee587a69bd43a28219562d36ed0c127197e4cbfe34e05902aca
@@ -3,7 +3,7 @@
3
3
  module Jsapi
4
4
  module Controller
5
5
  # Used by Methods#api_operation! to produce an error response.
6
- class ErrorResult
6
+ class Error
7
7
  delegate_missing_to :@exception
8
8
 
9
9
  # The HTTP status code of the error response to be produced.
@@ -27,14 +27,18 @@ module Jsapi
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
- # The +:omit+ option specifies on which conditions properties are omitted.
30
+ # The +:omit+ option specifies on which conditions properties are omitted in responses.
31
31
  # Possible values are:
32
32
  #
33
33
  # - +:empty+ - All of the properties whose value is empty are omitted.
34
34
  # - +:nil+ - All of the properties whose value is +nil+ are omitted.
35
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)
36
+ # Raises an +ArgumentError+ when +:omit+ is other than +:empty+, +:nil+ or +nil+.
37
+ def api_operation(operation_name = nil,
38
+ omit: nil,
39
+ status: nil,
40
+ strong: false,
41
+ &block)
38
42
  _api_operation(
39
43
  operation_name,
40
44
  bang: false,
@@ -52,7 +56,11 @@ module Jsapi
52
56
  # # ...
53
57
  # end
54
58
  #
55
- def api_operation!(operation_name = nil, omit: nil, status: nil, strong: false, &block)
59
+ def api_operation!(operation_name = nil,
60
+ omit: nil,
61
+ status: nil,
62
+ strong: false,
63
+ &block)
56
64
  _api_operation(
57
65
  operation_name,
58
66
  bang: true,
@@ -97,13 +105,13 @@ module Jsapi
97
105
  # - +:empty+ - All of the properties whose value is empty are omitted.
98
106
  # - +:nil+ - All of the properties whose value is +nil+ are omitted.
99
107
  #
100
- # Raises an InvalidArgumentError when the value of +:omit+ is invalid.
108
+ # Raises an +ArgumentError+ when +:omit+ is other than +:empty+, +:nil+ or +nil+.
101
109
  def api_response(result, operation_name = nil, omit: nil, status: nil)
102
110
  definitions = api_definitions
103
111
  operation = _find_api_operation(operation_name, definitions)
104
- response = _api_response(operation, status, definitions)
112
+ response_model = _api_response(operation, status, definitions)
105
113
 
106
- Response.new(result, response, api_definitions, omit: omit)
114
+ Response.new(result, response_model, api_definitions, omit: omit)
107
115
  end
108
116
 
109
117
  private
@@ -111,40 +119,43 @@ module Jsapi
111
119
  def _api_operation(operation_name, bang:, omit:, status:, strong:, &block)
112
120
  definitions = api_definitions
113
121
  operation = _find_api_operation(operation_name, definitions)
114
- response = _api_response(operation, status, definitions)
115
-
116
- if block
117
- params = _api_params(operation, definitions, strong: strong)
118
- result = begin
119
- raise ParametersInvalid.new(params) if bang && params.invalid?
120
-
121
- block.call(params)
122
- rescue StandardError => e
123
- # Lookup a rescue handler
124
- rescue_handler = definitions.rescue_handler_for(e)
125
- raise e if rescue_handler.nil?
126
-
127
- # Change the HTTP status code and response schema
128
- status = rescue_handler.status
129
- response = operation.response(status)&.resolve(definitions)
130
- raise e if response.nil?
131
-
132
- # Call on_rescue callbacks
133
- definitions.on_rescue_callbacks.each do |callback|
134
- if callback.respond_to?(:call)
135
- callback.call(e)
136
- else
137
- send(callback, e)
138
- end
139
- end
140
122
 
141
- ErrorResult.new(e, status: status)
123
+ # Perform operation
124
+ response_model = _api_response(operation, status, definitions)
125
+ head(status) && return unless block
126
+
127
+ params = _api_params(operation, definitions, strong: strong)
128
+
129
+ result = begin
130
+ raise ParametersInvalid.new(params) if bang && params.invalid?
131
+
132
+ block.call(params)
133
+ rescue StandardError => e
134
+ # Lookup a rescue handler
135
+ rescue_handler = definitions.rescue_handler_for(e)
136
+ raise e if rescue_handler.nil?
137
+
138
+ # Change the HTTP status code and response model
139
+ status = rescue_handler.status
140
+ response_model = operation.response(status)&.resolve(definitions)
141
+ raise e if response_model.nil?
142
+
143
+ # Call on_rescue callbacks
144
+ definitions.on_rescue_callbacks.each do |callback|
145
+ if callback.respond_to?(:call)
146
+ callback.call(e)
147
+ else
148
+ send(callback, e)
149
+ end
142
150
  end
143
- render(json: Response.new(result, response, definitions, omit: omit), status: status)
144
- else
145
- head(status)
151
+
152
+ Error.new(e, status: status)
146
153
  end
147
- self.content_type = response.content_type
154
+ response = Response.new(result, response_model, definitions, omit: omit)
155
+
156
+ # Write response
157
+ self.content_type = response_model.content_type
158
+ render(json: response, status: status)
148
159
  end
149
160
 
150
161
  def _api_params(operation, definitions, strong:)
@@ -27,7 +27,8 @@ module Jsapi
27
27
  @raw_attributes[name] = JSON.wrap(
28
28
  parameter_model.in == 'header' ? headers[name] : @params[name],
29
29
  parameter_model.schema.resolve(definitions),
30
- definitions
30
+ definitions,
31
+ context: :request
31
32
  )
32
33
  end
33
34
 
@@ -38,7 +39,8 @@ module Jsapi
38
39
  request_body = JSON.wrap(
39
40
  @params.except(*operation.parameters.keys),
40
41
  request_body_schema,
41
- definitions
42
+ definitions,
43
+ context: :request
42
44
  )
43
45
  @raw_attributes.merge!(request_body.raw_attributes)
44
46
  @raw_additional_attributes = request_body.raw_additional_attributes
@@ -2,10 +2,20 @@
2
2
 
3
3
  module Jsapi
4
4
  module Controller
5
- # Used to serialize a response.
5
+ # Used to jsonify a response.
6
6
  class Response
7
+ class JsonifyError < RuntimeError # :nodoc:
8
+ def message
9
+ [@path&.delete_prefix('.') || 'response body', super].join(' ')
10
+ end
11
+
12
+ def prepend(origin)
13
+ @path = "#{origin}#{@path}"
14
+ self
15
+ end
16
+ end
7
17
 
8
- # Creates a new instance to serialize +object+ according to +response+. References
18
+ # Creates a new instance to jsonify +object+ according to +response+. References
9
19
  # are resolved to API components in +definitions+.
10
20
  #
11
21
  # The +:omit+ option specifies on which conditions properties are omitted.
@@ -14,111 +24,119 @@ module Jsapi
14
24
  # - +:empty+ - All of the properties whose value is empty are omitted.
15
25
  # - +:nil+ - All of the properties whose value is +nil+ are omitted.
16
26
  #
17
- # Raises an InvalidArgumentError when the value of +:omit+ is invalid.
27
+ # Raises an +ArgumentError+ when +:omit+ is other than +:empty+, +:nil+ or +nil+.
18
28
  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
-
23
29
  @object = object
24
30
  @response = response
25
31
  @definitions = definitions
26
- @omit = omit
32
+
33
+ @omittable_check =
34
+ case omit
35
+ when nil
36
+ nil
37
+ when :nil
38
+ ->(value, schema) { schema.omittable? && value.nil? }
39
+ when :empty
40
+ ->(value, schema) { schema.omittable? && value.try(:empty?) }
41
+ else
42
+ raise InvalidArgumentError.new('omit', omit, valid_values: %i[empty nil])
43
+ end
27
44
  end
28
45
 
29
46
  def inspect # :nodoc:
30
47
  "#<#{self.class.name} #{@object.inspect}>"
31
48
  end
32
49
 
33
- # Returns the JSON representation of the response as a +String+.
50
+ # Returns the \JSON representation of the response as a string.
34
51
  def to_json(*)
35
52
  schema = @response.schema.resolve(@definitions)
36
53
  if @response.locale
37
- I18n.with_locale(@response.locale) do
38
- serialize(@object, schema)
39
- end
54
+ I18n.with_locale(@response.locale) { jsonify(@object, schema) }
40
55
  else
41
- serialize(@object, schema)
56
+ jsonify(@object, schema)
42
57
  end.to_json
43
58
  end
44
59
 
45
60
  private
46
61
 
47
- def serialize(object, schema, path = nil)
62
+ def jsonify(object, schema)
48
63
  object = schema.default_value(@definitions, context: :response) if object.nil?
49
- return if object.nil? && schema.nullable?
50
-
51
- raise "#{path || 'response'} can't be nil" if object.nil?
52
-
53
- case schema.type
54
- when 'array'
55
- serialize_array(object, schema, path)
56
- when 'integer'
57
- schema.convert(object.to_i)
58
- when 'number'
59
- schema.convert(object.to_f)
60
- when 'object'
61
- serialize_object(object, schema, path)
62
- when 'string'
63
- schema.convert(
64
- case schema.format
65
- when 'date'
66
- object.to_date
67
- when 'date-time'
68
- object.to_datetime
69
- when 'duration'
70
- object.iso8601
71
- else
72
- object.to_s
73
- end
74
- )
64
+
65
+ if object.nil?
66
+ raise JsonifyError, "can't be nil" unless schema.nullable?
75
67
  else
76
- object
68
+ case schema.type
69
+ when 'array'
70
+ jsonify_array(object, schema)
71
+ when 'boolean'
72
+ object
73
+ when 'integer'
74
+ schema.convert(object.to_i)
75
+ when 'number'
76
+ schema.convert(object.to_f)
77
+ when 'object'
78
+ jsonify_object(object, schema)
79
+ when 'string'
80
+ schema.convert(
81
+ case schema.format
82
+ when 'date'
83
+ object.to_date
84
+ when 'date-time'
85
+ object.to_datetime
86
+ when 'duration'
87
+ object.iso8601
88
+ else
89
+ object.to_s
90
+ end
91
+ )
92
+ else
93
+ raise JsonifyError, "has an invalid type: #{schema.type.inspect}"
94
+ end
77
95
  end
78
96
  end
79
97
 
80
- def serialize_array(array, schema, path)
98
+ def jsonify_array(array, schema)
81
99
  item_schema = schema.items.resolve(@definitions)
82
- Array(array).map { |item| serialize(item, item_schema, path) }
100
+ index = 0
101
+
102
+ Array(array).map do |item|
103
+ item = jsonify(item, item_schema)
104
+ index += 1
105
+ item
106
+ rescue JsonifyError => e
107
+ raise e.prepend("[#{index}]")
108
+ end
83
109
  end
84
110
 
85
- def serialize_object(object, schema, path)
111
+ def jsonify_object(object, schema)
86
112
  schema = schema.resolve_schema(object, @definitions, context: :response)
87
113
  properties = {}
88
114
 
89
- # Serialize properties
90
- schema.resolve_properties(@definitions, context: :response).each do |key, property|
115
+ # Add properties
116
+ schema.resolve_properties(@definitions, context: :response).each_value do |property|
91
117
  property_schema = property.schema.resolve(@definitions)
92
118
  property_value = property.reader.call(object)
93
119
  property_value = property_schema.default if property_value.nil?
120
+ next if @omittable_check&.call(property_value, property_schema)
94
121
 
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,
102
- path.nil? ? property.name : "#{path}.#{property.name}"
103
- )
122
+ properties[property.name] = jsonify(property_value, property_schema)
123
+ rescue JsonifyError => e
124
+ raise e.prepend(".#{property.name}")
104
125
  end
105
- # Serialize additional properties
126
+ # Add additional properties
106
127
  if (additional_properties = schema.additional_properties)
107
128
  additional_properties_schema = additional_properties.schema.resolve(@definitions)
108
129
 
109
130
  additional_properties.source.call(object)&.each do |key, value|
110
- # Don't replace the property with the same key
111
131
  next if properties.key?(key = key.to_s)
112
132
 
113
- properties[key] = serialize(
114
- value,
115
- additional_properties_schema,
116
- path.nil? ? key : "#{path}.#{key}"
117
- )
133
+ properties[key] = jsonify(value, additional_properties_schema)
134
+ rescue JsonifyError => e
135
+ raise e.prepend(".#{key}")
118
136
  end
119
137
  end
120
- # Return properties if present, otherwise nil
121
- properties if properties.present?
138
+
139
+ properties.presence
122
140
  end
123
141
  end
124
142
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'controller/parameters_invalid'
4
- require_relative 'controller/error_result'
4
+ require_relative 'controller/error'
5
5
  require_relative 'controller/parameters'
6
6
  require_relative 'controller/response'
7
7
  require_relative 'controller/methods'
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jsapi
4
+ module DSL
5
+ class Base
6
+ def initialize(meta_model, &block)
7
+ @meta_model = meta_model
8
+
9
+ if block
10
+ if meta_model.reference?
11
+ raise Error, "reference can't be specified together with a block"
12
+ end
13
+
14
+ instance_eval(&block)
15
+ end
16
+ end
17
+
18
+ def respond_to_missing?(*args) # :nodoc:
19
+ keyword?(args.first)
20
+ end
21
+
22
+ private
23
+
24
+ def define(*args, &block)
25
+ block.call
26
+ rescue Error => e
27
+ raise e.prepend_origin(args.compact.join(' '))
28
+ rescue StandardError => e
29
+ raise Error.new(e, args.compact.join(' ').presence)
30
+ end
31
+
32
+ def find_method(name)
33
+ ["#{name}=", "add_#{name}"].find do |method|
34
+ @meta_model.respond_to?(method)
35
+ end
36
+ end
37
+
38
+ def keyword(name, *params, &block)
39
+ method = find_method(name)
40
+ raise "unsupported keyword: #{name}" unless method
41
+
42
+ define(name) do
43
+ result = @meta_model.public_send(method, *params)
44
+ Base.new(result, &block) if block
45
+ end
46
+ end
47
+
48
+ def keyword?(name)
49
+ find_method(name).present?
50
+ end
51
+
52
+ alias method_missing keyword
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jsapi
4
+ module DSL
5
+ # Used to specify an OpenAPI callback object.
6
+ class Callback < Base
7
+
8
+ # Adds a callback operation.
9
+ #
10
+ # operation '{$request.query.foo}' do
11
+ # parameter 'bar', type: 'string'
12
+ # end
13
+ def operation(expression, **keywords, &block)
14
+ define('operation', expression.inspect) do
15
+ operation_model = @meta_model.add_operation(expression, keywords)
16
+ Operation.new(operation_model, &block) if block
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -3,9 +3,27 @@
3
3
  module Jsapi
4
4
  module DSL
5
5
  module ClassMethods
6
+ # Specifies the base path of the API.
7
+ #
8
+ # api_base_path '/foo'
9
+ #
10
+ def api_base_path(arg)
11
+ api_definitions { base_path(arg) }
12
+ end
13
+
14
+ # Specifies a reusable callback.
15
+ #
16
+ # api_callback 'onFoo' do
17
+ # operation '{$request.query.foo}', path: '/bar'
18
+ # end
19
+ #
20
+ def api_callback(name, **keywords, &block)
21
+ api_definitions { callback(name, **keywords, &block) }
22
+ end
23
+
6
24
  # Specifies the general default values for +type+.
7
25
  #
8
- # api_default 'array', read: [], write: []
26
+ # api_default 'array', within_requests: [], within_responses: []
9
27
  #
10
28
  def api_default(type, **keywords, &block)
11
29
  api_definitions { default(type, **keywords, &block) }
@@ -21,17 +39,72 @@ module Jsapi
21
39
  @api_definitions
22
40
  end
23
41
 
42
+ # Specifies a reusable example.
43
+ #
44
+ # example 'foo', value: 'bar'
45
+ #
46
+ def api_example(name, **keywords, &block)
47
+ api_definitions { example(name, **keywords, &block) }
48
+ end
49
+
50
+ # Specifies the external documentation.
51
+ #
52
+ # api_external_docs url: 'https://foo.bar'
53
+ #
54
+ def api_external_docs(**keywords, &block)
55
+ api_definitions { external_docs(**keywords, &block) }
56
+ end
57
+
58
+ # Specifies a reusable header.
59
+ #
60
+ # api_header 'foo', type: 'string'
61
+ #
62
+ def api_header(name, **keywords, &block)
63
+ api_definitions { header(name, **keywords, &block) }
64
+ end
65
+
66
+ # Specifies the host serving the API.
67
+ #
68
+ # api_host 'foo.bar'
69
+ #
70
+ def api_host(arg)
71
+ api_definitions { host(arg) }
72
+ end
73
+
24
74
  # Includes API definitions from +klasses+.
25
75
  def api_include(*klasses)
26
76
  api_definitions { include(*klasses) }
27
77
  end
28
78
 
79
+ # Specifies general information about the API.
80
+ #
81
+ # api_info title: 'Foo', version: '1' do
82
+ # contact name: 'bar'
83
+ # end
84
+ def api_info(**keywords, &block)
85
+ api_definitions { info(**keywords, &block) }
86
+ end
87
+
88
+ # Specifies a reusable link.
89
+ #
90
+ # api_link 'foo', operation_id: 'bar'
91
+ #
92
+ def api_link(name, **keywords, &block)
93
+ api_definitions { link(name, **keywords, &block) }
94
+ end
95
+
29
96
  # Registers a callback to be called when rescuing an exception.
97
+ #
98
+ # api_on_rescue :foo
99
+ #
100
+ # api_on_rescue do |error|
101
+ # # ...
102
+ # end
30
103
  def api_on_rescue(method = nil, &block)
31
104
  api_definitions { on_rescue(method, &block) }
32
105
  end
33
106
 
34
- # Defines an operation.
107
+ # Specifies an operation.
35
108
  #
36
109
  # api_operation 'foo', path: '/foo' do
37
110
  # parameter 'bar', type: 'string'
@@ -45,7 +118,7 @@ module Jsapi
45
118
  api_definitions { operation(name, **keywords, &block) }
46
119
  end
47
120
 
48
- # Defines a reusable parameter.
121
+ # Specifies a reusable parameter.
49
122
  #
50
123
  # api_parameter 'foo', type: 'string'
51
124
  #
@@ -70,7 +143,7 @@ module Jsapi
70
143
  api_definitions { rescue_from(*klasses, with: with) }
71
144
  end
72
145
 
73
- # Defines a reusable response.
146
+ # Specifies a reusable response.
74
147
  #
75
148
  # api_response 'Foo', type: 'object' do
76
149
  # property 'bar', type: 'string'
@@ -79,7 +152,7 @@ module Jsapi
79
152
  api_definitions { response(name, **keywords, &block) }
80
153
  end
81
154
 
82
- # Defines a reusable schema.
155
+ # Specifies a reusable schema.
83
156
  #
84
157
  # api_schema 'Foo' do
85
158
  # property 'bar', type: 'string'
@@ -88,13 +161,46 @@ module Jsapi
88
161
  api_definitions { schema(name, **keywords, &block) }
89
162
  end
90
163
 
91
- # Defines the root of an OpenAPI document.
164
+ # Specifies a URI scheme supported by the API.
165
+ #
166
+ # api_scheme 'https'
167
+ #
168
+ def api_scheme(arg)
169
+ api_definitions { scheme(arg) }
170
+ end
171
+
172
+ # Specifies a security requirement.
92
173
  #
93
- # openapi do
94
- # info title: 'Foo', version: '1'
174
+ # api_security_requirement do
175
+ # scheme 'basic_auth'
95
176
  # end
96
- def openapi(**keywords, &block)
97
- api_definitions { openapi(**keywords, &block) }
177
+ #
178
+ def api_security_requirement(**keywords, &block)
179
+ api_definitions { security_requirement(**keywords, &block) }
180
+ end
181
+
182
+ # Specifies a security scheme.
183
+ #
184
+ # api_security_scheme 'basic_auth', type: 'http', scheme: 'basic'
185
+ #
186
+ def api_security_scheme(name, **keywords, &block)
187
+ api_definitions { security_scheme(name, **keywords, &block) }
188
+ end
189
+
190
+ # Specifies a server providing the API.
191
+ #
192
+ # api_server url: 'https://foo.bar/foo'
193
+ #
194
+ def api_server(**keywords, &block)
195
+ api_definitions { server(**keywords, &block) }
196
+ end
197
+
198
+ # Specifies a tag.
199
+ #
200
+ # api_tag name: 'foo', description: 'description of foo'
201
+ #
202
+ def api_tag(**keywords, &block)
203
+ api_definitions { tag(**keywords, &block) }
98
204
  end
99
205
  end
100
206
  end