apia 3.0.0 → 3.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 834322a8dd87426fd34415e096964a331ca3fefd5101e05e23a216da197e1820
4
- data.tar.gz: d422b240f990920a61e520e360d15414aef1b8c0f39021684fa32d31d0aaf1a9
3
+ metadata.gz: e5db442aede360ce867a790d610a1fd52ca99149fae66d7122d18061cb2ac389
4
+ data.tar.gz: 30d3c64645a15f11b6e2d96326e987f31b0623e500a56c49194e80589e7303d1
5
5
  SHA512:
6
- metadata.gz: 6a42e4aaf195d8bd6dc7053a473bbc107ff4303d184bfae3c5bf1e7bb25ef618f57dbc86436c697b06786847f67077d9a06ae9451c6211fbf6072a5cfd6b755e
7
- data.tar.gz: 73762ac070550ec052ffa79f2a5e8fdbb0317b8cdb62020b74d494706a1f2e63a65d52691fed82da4f2ba60ed2d66a2572686d3e0c9fef237ec2632a67bc339b
6
+ metadata.gz: 70b9295d1b016210832c30b2d233683efa045797c5113e80bd959dfa6a6888c414f3a60e01ded946f63d50d51cd79cdae58514c2d8b483bfec29be71a89b83bd
7
+ data.tar.gz: af2fa9e9322ed357a2074336a2e536d8ebb3c955692bd1b6a85812fe788fc4d5f19b0b1ecc57ce99c82b118fb7b5024a276d54edbb3560ab594b718c80e88ccd
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.0
1
+ 3.1.0
@@ -5,6 +5,7 @@ require 'apia/definitions/argument_set'
5
5
  require 'apia/errors/invalid_argument_error'
6
6
  require 'apia/errors/missing_argument_error'
7
7
  require 'apia/helpers'
8
+ require 'apia/deep_merge'
8
9
 
9
10
  module Apia
10
11
  class ArgumentSet
@@ -46,7 +47,11 @@ module Apia
46
47
  # @param request [Apia::Request]
47
48
  # @return [Apia::ArgumentSet]
48
49
  def create_from_request(request)
49
- new(request.json_body || request.params || {}, request: request)
50
+ json_body = request.json_body || {}
51
+ params = request.params || {}
52
+ merged_params = DeepMerge.merge(params, json_body)
53
+
54
+ new(merged_params, request: request)
50
55
  end
51
56
 
52
57
  end
@@ -117,6 +122,13 @@ module Apia
117
122
  @source.key?(key.to_sym)
118
123
  end
119
124
 
125
+ # Return whether the argument set has no arguments within?
126
+ #
127
+ # @return [Boolean]
128
+ def empty?
129
+ @source.empty?
130
+ end
131
+
120
132
  # Validate an argument set and return any errors as appropriate
121
133
  #
122
134
  # @param argument [Apia::Argument]
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apia
4
+ module DeepMerge
5
+
6
+ class << self
7
+
8
+ def merge(hash_a, hash_b, &block)
9
+ hash_a.merge!(hash_b) do |key, this_val, other_val|
10
+ if this_val.is_a?(Hash) && other_val.is_a?(Hash)
11
+ merge(this_val, other_val, &block)
12
+ elsif block_given?
13
+ block.call(key, this_val, other_val)
14
+ else
15
+ other_val
16
+ end
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+ end
@@ -34,6 +34,10 @@ module Apia
34
34
  @group.description = description
35
35
  end
36
36
 
37
+ def no_schema
38
+ @group.schema = false
39
+ end
40
+
37
41
  def controller(controller)
38
42
  @group.default_controller = controller
39
43
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apia
4
+ class Notifications
5
+
6
+ class << self
7
+
8
+ def handlers
9
+ @handlers ||= []
10
+ end
11
+
12
+ def notify(event, args = {})
13
+ handlers.each do |handler|
14
+ handler.call(event, args)
15
+ end
16
+ end
17
+
18
+ def add_handler(&block)
19
+ handlers.push(block)
20
+ end
21
+
22
+ def clear_handlers
23
+ @handlers = nil
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+ end
data/lib/apia/rack.rb CHANGED
@@ -4,6 +4,7 @@ require 'json'
4
4
  require 'apia/rack_error'
5
5
  require 'apia/request'
6
6
  require 'apia/response'
7
+ require 'apia/notifications'
7
8
 
8
9
  module Apia
9
10
  class Rack
@@ -91,19 +92,28 @@ module Apia
91
92
  request.endpoint = route.endpoint
92
93
  request.route = route
93
94
 
95
+ start_time = Time.now
94
96
  response = request.endpoint.execute(request)
97
+ end_time = Time.now
98
+
99
+ Apia::Notifications.notify(:request, { request: request, response: response, time: (end_time - start_time).to_f })
100
+
95
101
  response.rack_triplet
96
102
  rescue ::StandardError => e
97
103
  if e.is_a?(RackError) || e.is_a?(Apia::ManifestError)
98
104
  return e.triplet
99
105
  end
100
106
 
107
+ request_or_nil = defined?(request) ? request : nil
108
+
101
109
  api.definition.exception_handlers.call(e, {
102
110
  env: env,
103
111
  api: api,
104
- request: defined?(request) ? request : nil
112
+ request: request_or_nil
105
113
  })
106
114
 
115
+ Apia::Notifications.notify(:request_error, { exception: e, request: request_or_nil, api: api, env: env })
116
+
107
117
  if development?
108
118
  return triplet_for_exception(e)
109
119
  end
data/lib/apia/request.rb CHANGED
@@ -39,12 +39,20 @@ module Apia
39
39
  has_header?('rack.input')
40
40
  end
41
41
 
42
+ def params
43
+ return {} unless body?
44
+
45
+ super
46
+ end
47
+
42
48
  private
43
49
 
44
50
  def parse_json_from_string(body)
45
51
  return {} if body.empty?
46
52
 
47
- JSON.parse(body)
53
+ response = JSON.parse(body)
54
+ response = {} unless response.is_a?(Hash)
55
+ response
48
56
  rescue JSON::ParserError => e
49
57
  raise InvalidJSONError, e.message
50
58
  end
@@ -1,20 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Apia
4
- class RouteGroup
4
+ class RouteGroup < Definition
5
5
 
6
- attr_reader :id
7
6
  attr_reader :parent
8
- attr_accessor :name
9
- attr_accessor :description
10
7
  attr_accessor :default_controller
11
8
  attr_reader :groups
12
9
 
10
+ # rubocop:disable Lint/MissingSuper
13
11
  def initialize(id, parent)
14
12
  @id = id
15
13
  @parent = parent
16
14
  @groups = []
17
15
  end
16
+ # rubocop:enable Lint/MissingSuper
18
17
 
19
18
  end
20
19
  end
@@ -18,8 +18,10 @@ module Apia
18
18
  end
19
19
  field :endpoints, type: [ControllerEndpointSchemaType] do
20
20
  backend do |c|
21
- c.endpoints.map do |key, endpoint|
22
- {
21
+ c.endpoints.each_with_object([]) do |(key, endpoint), array|
22
+ next unless endpoint.definition.schema?
23
+
24
+ array << {
23
25
  name: key.to_s,
24
26
  endpoint: endpoint.definition.id
25
27
  }
@@ -10,10 +10,15 @@ module Apia
10
10
 
11
11
  field :routes, [RouteSchemaType] do
12
12
  backend do |o|
13
- o.routes.select { |r| r.endpoint&.definition&.schema? }
13
+ o.routes.select { |r| r.group&.schema? && r.endpoint&.definition&.schema? }
14
+ end
15
+ end
16
+
17
+ field :groups, [RouteGroupSchemaType] do
18
+ backend do |o|
19
+ o.groups.select { |g| g.schema? }
14
20
  end
15
21
  end
16
- field :groups, [RouteGroupSchemaType]
17
22
 
18
23
  end
19
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apia
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Cooke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-04 00:00:00.000000000 Z
11
+ date: 2022-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -52,6 +52,7 @@ files:
52
52
  - lib/apia/authenticator.rb
53
53
  - lib/apia/callable_with_environment.rb
54
54
  - lib/apia/controller.rb
55
+ - lib/apia/deep_merge.rb
55
56
  - lib/apia/defineable.rb
56
57
  - lib/apia/definition.rb
57
58
  - lib/apia/definitions/api.rb
@@ -115,6 +116,7 @@ files:
115
116
  - lib/apia/lookup_environment.rb
116
117
  - lib/apia/manifest_errors.rb
117
118
  - lib/apia/mock_request.rb
119
+ - lib/apia/notifications.rb
118
120
  - lib/apia/object.rb
119
121
  - lib/apia/object_set.rb
120
122
  - lib/apia/pagination_object.rb
@@ -164,7 +166,8 @@ files:
164
166
  - lib/apia/schema/scope_type.rb
165
167
  - lib/apia/version.rb
166
168
  homepage: https://github.com/krystal/apia
167
- licenses: []
169
+ licenses:
170
+ - MIT
168
171
  metadata: {}
169
172
  post_install_message:
170
173
  rdoc_options: []