apia 3.2.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f9eccaade7623f6fc8ecae88bb8c87da23d4a436a2d76801ac6dbd2d57db9efe
4
- data.tar.gz: c77009793790064a1f6219b6a362128359d2e98a0ccc7c8215d184f7afa36b5b
3
+ metadata.gz: f40c9dba04e5b064ced8833f9edb42f96efd59c9d4e9342a4fa6535a1e76c6ee
4
+ data.tar.gz: 2506e79260735d3c2029ac7eaa9733e481b975b177506f03fcdeba21760b8781
5
5
  SHA512:
6
- metadata.gz: 3dc391ac5e8ad44636978220ceeb55bef47b10ba03f5826e371ed4041e428873ed59d351447d3345817e3bbb8b25bfafc6ecd01f4f86745ddc1d0851c2bc19a2
7
- data.tar.gz: 2f92e720ce247b4408c21bc5a4096137ef75433b10c8712c4d2d115f8d4a33def15509bd5a7af05fd1bfffed9e465e57dac6cd4f5422e3aa2278e12aa0727664
6
+ metadata.gz: 7ae74d9f396b7dda8d14513d072f3e7f0902724c5b3e8bd0a430341f8d1e91dd83e4e6aae0b377dc954e3f248c5da7ba3984da354202fa42043c1e5d8d0e5ba7
7
+ data.tar.gz: 7e735b6a11cfc48325cd60ce0d01a36cb9eb776afeb2b74c3efe8de034b02413df3c8cec149b9ffa0883af4c85d4f631d7cc9f67e63c169e3fbcaeb4d0dbe517
data/lib/apia/api.rb CHANGED
@@ -79,7 +79,7 @@ module Apia
79
79
  # @param endpoint_name [Symbol]
80
80
  # @return [Apia::Response]
81
81
  def test_endpoint(endpoint, controller: nil)
82
- if controller && endpoint.is_a?(Symbol) || endpoint.is_a?(String)
82
+ if controller && (endpoint.is_a?(Symbol) || endpoint.is_a?(String))
83
83
  endpoint_name = endpoint
84
84
  endpoint = controller.definition.endpoints[endpoint.to_sym]
85
85
  if endpoint.nil?
@@ -36,7 +36,7 @@ module Apia
36
36
  end
37
37
 
38
38
  @controllers.each do |name, controller|
39
- unless name.to_s =~ /\A[\w\-]+\z/i
39
+ unless name.to_s =~ /\A[\w-]+\z/i
40
40
  errors.add self, 'InvalidControllerName', "The controller name #{name} is invalid. It can only contain letters, numbers, underscores, and hyphens"
41
41
  end
42
42
 
@@ -18,7 +18,7 @@ module Apia
18
18
 
19
19
  def endpoint(name, klass = nil, &block)
20
20
  if block_given?
21
- id = "#{@definition.id}/#{klass || Helpers.camelize(name) + 'Endpoint'}"
21
+ id = "#{@definition.id}/#{klass || (Helpers.camelize(name) + 'Endpoint')}"
22
22
  klass = Apia::Endpoint.create(id, &block)
23
23
  end
24
24
 
@@ -60,7 +60,7 @@ module Apia
60
60
 
61
61
  argument :per_page, type: Scalars::Integer, default: 30 do
62
62
  validation(:greater_than_zero) { |o| o.positive? }
63
- validation(:less_than_or_equal_to_100) { |o| o <= (pagination_options[:maximum_per_page]&.to_i || 200) }
63
+ validation(:less_than_or_equal_to_one_hundred) { |o| o <= (pagination_options[:maximum_per_page]&.to_i || 200) }
64
64
  end
65
65
 
66
66
  field :pagination, type: PaginationObject
@@ -5,6 +5,7 @@ require 'apia/scalar'
5
5
  require 'apia/object'
6
6
  require 'apia/enum'
7
7
  require 'apia/field_spec'
8
+ require 'apia/generated_hash'
8
9
 
9
10
  module Apia
10
11
  class FieldSet < Hash
@@ -35,10 +36,12 @@ module Apia
35
36
  #
36
37
  # @param source [Object, Hash]
37
38
  # @param request [Apia::Request]
39
+ # @param object [Apia::Object] the object that this fieldset belongs to
38
40
  # @param only [Array]
39
41
  # @return [Hash]
40
- def generate_hash(source, request: nil, path: [])
41
- each_with_object({}) do |(_, field), hash|
42
+ def generate_hash(source, request: nil, path: [], object: nil)
43
+ new_hash = GeneratedHash.enabled? ? GeneratedHash.new(object, source, path: path) : {}
44
+ each_with_object(new_hash) do |(_, field), hash|
42
45
  next unless field.include?(source, request)
43
46
 
44
47
  field_path = path + [field]
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apia
4
+ class GeneratedHash < Hash
5
+
6
+ attr_reader :object
7
+ attr_reader :source
8
+ attr_reader :path
9
+
10
+ def initialize(object, source, path: nil)
11
+ super()
12
+ @object = object
13
+ @source = source
14
+ @path = path
15
+ end
16
+
17
+ class << self
18
+
19
+ def enabled?
20
+ @enabled == true
21
+ end
22
+
23
+ def enable
24
+ @enabled = true
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+ end
@@ -15,8 +15,9 @@ module Apia
15
15
  end
16
16
  end
17
17
 
18
- def add_handler(&block)
19
- handlers.push(block)
18
+ def add_handler(handler = nil, &block)
19
+ handlers.push(block) if block
20
+ handlers.push(handler) if handler
20
21
  end
21
22
 
22
23
  def clear_handlers
data/lib/apia/object.rb CHANGED
@@ -49,7 +49,7 @@ module Apia
49
49
  # @param request [Apia::Request] the associated request
50
50
  # @return [Hash]
51
51
  def hash(request: nil, path: [])
52
- self.class.definition.fields.generate_hash(@value, request: request, path: path)
52
+ self.class.definition.fields.generate_hash(@value, object: self, request: request, path: path)
53
53
  end
54
54
 
55
55
  # Should this type be included in any output?
data/lib/apia/rack.rb CHANGED
@@ -73,15 +73,22 @@ module Apia
73
73
  private
74
74
 
75
75
  def handle_request(env, api_path)
76
- if env['REQUEST_METHOD'].upcase == 'OPTIONS'
76
+ request = nil
77
+ request_method = env['REQUEST_METHOD'].upcase
78
+ notify_hash = { api: api, env: env, path: api_path, method: request_method }
79
+
80
+ if request_method.upcase == 'OPTIONS'
77
81
  return [204, {}, ['']]
78
82
  end
79
83
 
84
+ Apia::Notifications.notify(:request_start, notify_hash)
85
+
80
86
  validate_api if development?
81
87
 
82
- route = find_route(env['REQUEST_METHOD'], api_path)
88
+ route = find_route(request_method, api_path)
83
89
  if route.nil?
84
- raise RackError.new(404, 'route_not_found', "No route matches '#{api_path}' for #{env['REQUEST_METHOD']}")
90
+ Apia::Notifications.notify(:request_route_not_found, notify_hash)
91
+ raise RackError.new(404, 'route_not_found', "No route matches '#{api_path}' for #{request_method}")
85
92
  end
86
93
 
87
94
  request = Apia::Request.new(env)
@@ -92,30 +99,40 @@ module Apia
92
99
  request.endpoint = route.endpoint
93
100
  request.route = route
94
101
 
102
+ Apia::Notifications.notify(:request_before_execution, notify_hash.merge(request: request))
103
+
95
104
  start_time = Time.now
96
105
  response = request.endpoint.execute(request)
97
106
  end_time = Time.now
107
+ time = end_time - start_time
98
108
 
99
- Apia::Notifications.notify(:request, { request: request, response: response, time: (end_time - start_time).to_f })
109
+ Apia::Notifications.notify(:request, notify_hash.merge(request: request, response: response, time: time))
100
110
 
101
111
  response.rack_triplet
102
112
  rescue ::StandardError => e
103
- if e.is_a?(RackError) || e.is_a?(Apia::ManifestError)
104
- return e.triplet
105
- end
113
+ handle_error(e, env, request, request_method)
114
+ ensure
115
+ Apia::Notifications.notify(:request_end, notify_hash)
116
+ end
117
+
118
+ def handle_error(exception, env, request, request_method)
119
+ notify_hash = { api: api, env: env, path: request&.api_path, request: request, method: request_method, exception: exception }
106
120
 
107
- request_or_nil = defined?(request) ? request : nil
121
+ if exception.is_a?(RackError) || exception.is_a?(Apia::ManifestError)
122
+ Apia::Notifications.notify(:request_manifest_error, notify_hash)
123
+ return exception.triplet
124
+ end
108
125
 
109
- api.definition.exception_handlers.call(e, {
126
+ api.definition.exception_handlers.call(exception, {
110
127
  env: env,
111
128
  api: api,
112
- request: request_or_nil
129
+ request: request
113
130
  })
114
131
 
115
- Apia::Notifications.notify(:request_error, { exception: e, request: request_or_nil, api: api, env: env })
132
+ Apia::Notifications.notify(:request_error, notify_hash)
116
133
 
117
134
  if development?
118
- return triplet_for_exception(e)
135
+ return triplet_for_exception(exception)
119
136
  end
120
137
 
121
138
  self.class.error_triplet('unhandled_exception', status: 500)
@@ -26,7 +26,7 @@ module Apia
26
26
  end
27
27
 
28
28
  def create_from_request(request)
29
- hash = request.each_header.each_with_object({}) do |(key, value), inner_hash|
29
+ hash = request.each_header.with_object({}) do |(key, value), inner_hash|
30
30
  next unless key =~ /\AHTTP_(\w+)\z/
31
31
 
32
32
  name = Regexp.last_match[1]
data/lib/apia/route.rb CHANGED
@@ -49,7 +49,7 @@ module Apia
49
49
  # @return [Hash]
50
50
  def extract_arguments(given_path)
51
51
  given_path_parts = RouteSet.split_path(given_path)
52
- path_parts.each_with_index.each_with_object({}) do |(part, index), hash|
52
+ path_parts.each_with_index.with_object({}) do |(part, index), hash|
53
53
  next unless part =~ /\A:(\w+)/
54
54
 
55
55
  value = given_path_parts[index]
data/lib/apia/version.rb CHANGED
@@ -2,11 +2,6 @@
2
2
 
3
3
  module Apia
4
4
 
5
- VERSION_FILE_ROOT = File.expand_path('../../VERSION', __dir__)
6
- if File.file?(VERSION_FILE_ROOT)
7
- VERSION = File.read(VERSION_FILE_ROOT).strip.sub(/\Av/, '')
8
- else
9
- VERSION = '0.0.0.dev'
10
- end
5
+ VERSION = '3.4.0'
11
6
 
12
7
  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.2.0
4
+ version: 3.4.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: 2022-09-26 00:00:00.000000000 Z
11
+ date: 2023-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -45,7 +45,6 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
- - VERSION
49
48
  - lib/apia.rb
50
49
  - lib/apia/api.rb
51
50
  - lib/apia/argument_set.rb
@@ -110,6 +109,7 @@ files:
110
109
  - lib/apia/errors/standard_error.rb
111
110
  - lib/apia/field_set.rb
112
111
  - lib/apia/field_spec.rb
112
+ - lib/apia/generated_hash.rb
113
113
  - lib/apia/helpers.rb
114
114
  - lib/apia/hook_set.rb
115
115
  - lib/apia/lookup_argument_set.rb
@@ -184,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
184
184
  - !ruby/object:Gem::Version
185
185
  version: '0'
186
186
  requirements: []
187
- rubygems_version: 3.1.6
187
+ rubygems_version: 3.3.26
188
188
  signing_key:
189
189
  specification_version: 4
190
190
  summary: This gem provides a friendly DSL for constructing HTTP APIs.
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 3.2.0