hooks-ruby 0.3.2 → 0.5.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/hooks/app/api.rb +8 -10
- data/lib/hooks/app/endpoints/catchall.rb +9 -4
- data/lib/hooks/app/endpoints/health.rb +8 -2
- data/lib/hooks/app/endpoints/version.rb +8 -2
- data/lib/hooks/core/config_loader.rb +15 -3
- data/lib/hooks/core/config_validator.rb +5 -5
- data/lib/hooks/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60133a1ffe3b89d168e58f606335ce3f23da219251790a331973b5691310b7f9
|
4
|
+
data.tar.gz: 158d1d0522c8e8aa55dd014a06a67f6b4922e87a3224adefb173beea78feed27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e56464ca7e87dd022060b36bd0678795efbec4ea6c6fd9bf65c7318320a32624dd9e3c3ad21e2838f701be7593766ad34fe1a65bc851c41209e2e4c9fe149f51
|
7
|
+
data.tar.gz: b88b05bf7643f248181973c9954a23dde5b61b0d23bec67d364e20756e2f567a355863725ff81d0644dbdb480788ec261e611d25aba84f09725d6a54d59b629c
|
data/lib/hooks/app/api.rb
CHANGED
@@ -38,8 +38,8 @@ module Hooks
|
|
38
38
|
content_type :txt, "text/plain"
|
39
39
|
content_type :xml, "application/xml"
|
40
40
|
content_type :any, "*/*"
|
41
|
-
|
42
|
-
default_format :
|
41
|
+
|
42
|
+
default_format config[:default_format] || :json
|
43
43
|
end
|
44
44
|
|
45
45
|
api_class.class_eval do
|
@@ -117,22 +117,21 @@ module Hooks
|
|
117
117
|
log.info("successfully processed webhook event with handler: #{handler_class_name}")
|
118
118
|
log.debug("processing duration: #{Time.now - start_time}s")
|
119
119
|
status 200
|
120
|
-
|
121
|
-
response.to_json
|
120
|
+
response
|
122
121
|
rescue Hooks::Plugins::Handlers::Error => e
|
123
122
|
# Handler called error! method - immediately return error response and exit the request
|
124
123
|
log.debug("handler #{handler_class_name} called `error!` method")
|
125
124
|
|
126
|
-
error_response = nil
|
127
|
-
|
128
125
|
status e.status
|
129
126
|
case e.body
|
130
127
|
when String
|
128
|
+
# if error! was called with a string, we assume it's a simple text error
|
129
|
+
# example: error!("simple text error", 400) -> should return a plain text response
|
131
130
|
content_type "text/plain"
|
132
131
|
error_response = e.body
|
133
132
|
else
|
134
|
-
|
135
|
-
error_response = e.body
|
133
|
+
# Let Grape handle JSON conversion with the default format
|
134
|
+
error_response = e.body
|
136
135
|
end
|
137
136
|
|
138
137
|
return error_response
|
@@ -163,8 +162,7 @@ module Hooks
|
|
163
162
|
error_response[:handler] = handler_class_name unless config[:production]
|
164
163
|
|
165
164
|
status determine_error_code(e)
|
166
|
-
|
167
|
-
error_response.to_json
|
165
|
+
error_response
|
168
166
|
end
|
169
167
|
end
|
170
168
|
end
|
@@ -17,6 +17,13 @@ module Hooks
|
|
17
17
|
class CatchallEndpoint < Grape::API
|
18
18
|
include Hooks::App::Helpers
|
19
19
|
|
20
|
+
# Set up content types and default format to JSON to match main API
|
21
|
+
content_type :json, "application/json"
|
22
|
+
content_type :txt, "text/plain"
|
23
|
+
content_type :xml, "application/xml"
|
24
|
+
content_type :any, "*/*"
|
25
|
+
default_format :json
|
26
|
+
|
20
27
|
def self.mount_path(config)
|
21
28
|
# :nocov:
|
22
29
|
"#{config[:root_path]}/*path"
|
@@ -81,8 +88,7 @@ module Hooks
|
|
81
88
|
log.info("successfully processed webhook event with handler: #{handler_class_name}")
|
82
89
|
log.debug("processing duration: #{Time.now - start_time}s")
|
83
90
|
status 200
|
84
|
-
|
85
|
-
response.to_json
|
91
|
+
response
|
86
92
|
rescue StandardError => e
|
87
93
|
err_msg = "Error processing webhook event with handler: #{handler_class_name} - #{e.message} " \
|
88
94
|
"- request_id: #{request_id} - path: #{full_path} - method: #{http_method} - " \
|
@@ -102,8 +108,7 @@ module Hooks
|
|
102
108
|
error_response[:handler] = handler_class_name unless config[:production]
|
103
109
|
|
104
110
|
status determine_error_code(e)
|
105
|
-
|
106
|
-
error_response.to_json
|
111
|
+
error_response
|
107
112
|
end
|
108
113
|
end
|
109
114
|
end
|
@@ -6,14 +6,20 @@ require_relative "../../version"
|
|
6
6
|
module Hooks
|
7
7
|
module App
|
8
8
|
class HealthEndpoint < Grape::API
|
9
|
+
# Set up content types and default format to JSON
|
10
|
+
content_type :json, "application/json"
|
11
|
+
content_type :txt, "text/plain"
|
12
|
+
content_type :xml, "application/xml"
|
13
|
+
content_type :any, "*/*"
|
14
|
+
default_format :json
|
15
|
+
|
9
16
|
get do
|
10
|
-
content_type "application/json"
|
11
17
|
{
|
12
18
|
status: "healthy",
|
13
19
|
timestamp: Time.now.utc.iso8601,
|
14
20
|
version: Hooks::VERSION,
|
15
21
|
uptime_seconds: (Time.now - Hooks::App::API.server_start_time).to_i
|
16
|
-
}
|
22
|
+
}
|
17
23
|
end
|
18
24
|
end
|
19
25
|
end
|
@@ -6,12 +6,18 @@ require_relative "../../version"
|
|
6
6
|
module Hooks
|
7
7
|
module App
|
8
8
|
class VersionEndpoint < Grape::API
|
9
|
+
# Set up content types and default format to JSON
|
10
|
+
content_type :json, "application/json"
|
11
|
+
content_type :txt, "text/plain"
|
12
|
+
content_type :xml, "application/xml"
|
13
|
+
content_type :any, "*/*"
|
14
|
+
default_format :json
|
15
|
+
|
9
16
|
get do
|
10
|
-
content_type "application/json"
|
11
17
|
{
|
12
18
|
version: Hooks::VERSION,
|
13
19
|
timestamp: Time.now.utc.iso8601
|
14
|
-
}
|
20
|
+
}
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
@@ -20,7 +20,8 @@ module Hooks
|
|
20
20
|
production: true,
|
21
21
|
endpoints_dir: "./config/endpoints",
|
22
22
|
use_catchall_route: false,
|
23
|
-
normalize_headers: true
|
23
|
+
normalize_headers: true,
|
24
|
+
default_format: :json
|
24
25
|
}.freeze
|
25
26
|
|
26
27
|
SILENCE_CONFIG_LOADER_MESSAGES = ENV.fetch(
|
@@ -31,16 +32,24 @@ module Hooks
|
|
31
32
|
#
|
32
33
|
# @param config_path [String, Hash] Path to config file or config hash
|
33
34
|
# @return [Hash] Merged configuration
|
35
|
+
# @raise [ArgumentError] if config file path is provided but file doesn't exist
|
36
|
+
# @raise [RuntimeError] if config file exists but fails to load
|
34
37
|
def self.load(config_path: nil)
|
35
38
|
config = DEFAULT_CONFIG.dup
|
36
39
|
overrides = []
|
37
40
|
|
38
41
|
# Load from file if path provided
|
39
|
-
if config_path.is_a?(String)
|
42
|
+
if config_path.is_a?(String)
|
43
|
+
unless File.exist?(config_path)
|
44
|
+
raise ArgumentError, "Configuration file not found: #{config_path}"
|
45
|
+
end
|
46
|
+
|
40
47
|
file_config = load_config_file(config_path)
|
41
48
|
if file_config
|
42
49
|
overrides << "file config"
|
43
50
|
config.merge!(file_config)
|
51
|
+
else
|
52
|
+
raise RuntimeError, "Failed to load configuration from file: #{config_path}"
|
44
53
|
end
|
45
54
|
end
|
46
55
|
|
@@ -126,7 +135,6 @@ module Hooks
|
|
126
135
|
env_config = {}
|
127
136
|
|
128
137
|
env_mappings = {
|
129
|
-
"HOOKS_HANDLER_DIR" => :handler_dir,
|
130
138
|
"HOOKS_HANDLER_PLUGIN_DIR" => :handler_plugin_dir,
|
131
139
|
"HOOKS_AUTH_PLUGIN_DIR" => :auth_plugin_dir,
|
132
140
|
"HOOKS_LIFECYCLE_PLUGIN_DIR" => :lifecycle_plugin_dir,
|
@@ -141,6 +149,7 @@ module Hooks
|
|
141
149
|
"HOOKS_ENDPOINTS_DIR" => :endpoints_dir,
|
142
150
|
"HOOKS_USE_CATCHALL_ROUTE" => :use_catchall_route,
|
143
151
|
"HOOKS_NORMALIZE_HEADERS" => :normalize_headers,
|
152
|
+
"HOOKS_DEFAULT_FORMAT" => :default_format,
|
144
153
|
"HOOKS_SOME_STRING_VAR" => :some_string_var # Added for test
|
145
154
|
}
|
146
155
|
|
@@ -155,6 +164,9 @@ module Hooks
|
|
155
164
|
when :use_catchall_route, :normalize_headers
|
156
165
|
# Convert string to boolean
|
157
166
|
env_config[config_key] = %w[true 1 yes on].include?(value.downcase)
|
167
|
+
when :default_format
|
168
|
+
# Convert string to symbol
|
169
|
+
env_config[config_key] = value.to_sym
|
158
170
|
else
|
159
171
|
env_config[config_key] = value
|
160
172
|
end
|
@@ -12,21 +12,21 @@ module Hooks
|
|
12
12
|
|
13
13
|
# Global configuration schema
|
14
14
|
GLOBAL_CONFIG_SCHEMA = Dry::Schema.Params do
|
15
|
-
|
16
|
-
optional(:handler_plugin_dir).filled(:string)
|
15
|
+
required(:handler_plugin_dir).filled(:string)
|
17
16
|
optional(:auth_plugin_dir).maybe(:string)
|
18
17
|
optional(:lifecycle_plugin_dir).maybe(:string)
|
19
18
|
optional(:instruments_plugin_dir).maybe(:string)
|
20
|
-
|
19
|
+
required(:log_level).filled(:string, included_in?: %w[debug info warn error])
|
21
20
|
optional(:request_limit).filled(:integer, gt?: 0)
|
22
21
|
optional(:request_timeout).filled(:integer, gt?: 0)
|
23
|
-
|
22
|
+
required(:root_path).filled(:string)
|
24
23
|
optional(:health_path).filled(:string)
|
25
24
|
optional(:version_path).filled(:string)
|
26
|
-
|
25
|
+
required(:environment).filled(:string, included_in?: %w[development production])
|
27
26
|
optional(:endpoints_dir).filled(:string)
|
28
27
|
optional(:use_catchall_route).filled(:bool)
|
29
28
|
optional(:normalize_headers).filled(:bool)
|
29
|
+
optional(:default_format).filled(:symbol, included_in?: %i[json txt xml any])
|
30
30
|
|
31
31
|
optional(:ip_filtering).hash do
|
32
32
|
optional(:ip_header).filled(:string)
|
data/lib/hooks/version.rb
CHANGED