apia 3.2.0 → 3.4.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/apia/api.rb +1 -1
- data/lib/apia/definitions/api.rb +1 -1
- data/lib/apia/dsls/controller.rb +1 -1
- data/lib/apia/dsls/endpoint.rb +1 -1
- data/lib/apia/field_set.rb +5 -2
- data/lib/apia/generated_hash.rb +30 -0
- data/lib/apia/notifications.rb +3 -2
- data/lib/apia/object.rb +1 -1
- data/lib/apia/rack.rb +29 -12
- data/lib/apia/request_headers.rb +1 -1
- data/lib/apia/route.rb +1 -1
- data/lib/apia/version.rb +1 -6
- metadata +4 -4
- data/VERSION +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f40c9dba04e5b064ced8833f9edb42f96efd59c9d4e9342a4fa6535a1e76c6ee
|
4
|
+
data.tar.gz: 2506e79260735d3c2029ac7eaa9733e481b975b177506f03fcdeba21760b8781
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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?
|
data/lib/apia/definitions/api.rb
CHANGED
@@ -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
|
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
|
|
data/lib/apia/dsls/controller.rb
CHANGED
@@ -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
|
|
data/lib/apia/dsls/endpoint.rb
CHANGED
@@ -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(:
|
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
|
data/lib/apia/field_set.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/apia/notifications.rb
CHANGED
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
|
-
|
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(
|
88
|
+
route = find_route(request_method, api_path)
|
83
89
|
if route.nil?
|
84
|
-
|
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,
|
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
|
-
|
104
|
-
|
105
|
-
|
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
|
-
|
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(
|
126
|
+
api.definition.exception_handlers.call(exception, {
|
110
127
|
env: env,
|
111
128
|
api: api,
|
112
|
-
request:
|
129
|
+
request: request
|
113
130
|
})
|
114
131
|
|
115
|
-
Apia::Notifications.notify(:request_error,
|
132
|
+
Apia::Notifications.notify(:request_error, notify_hash)
|
116
133
|
|
117
134
|
if development?
|
118
|
-
return triplet_for_exception(
|
135
|
+
return triplet_for_exception(exception)
|
119
136
|
end
|
120
137
|
|
121
138
|
self.class.error_triplet('unhandled_exception', status: 500)
|
data/lib/apia/request_headers.rb
CHANGED
@@ -26,7 +26,7 @@ module Apia
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def create_from_request(request)
|
29
|
-
hash = request.each_header.
|
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.
|
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
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.
|
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:
|
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.
|
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
|