hooksniff 0.3.0 → 1.0.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 (209) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -0
  3. data/Gemfile.lock +56 -0
  4. data/README.md +23 -199
  5. data/Rakefile +2 -0
  6. data/hooksniff.gemspec +48 -0
  7. data/lib/hooksniff/api/authentication.rb +36 -0
  8. data/lib/hooksniff/api/endpoint.rb +102 -0
  9. data/lib/hooksniff/api/event_type.rb +66 -0
  10. data/lib/hooksniff/api/health.rb +16 -0
  11. data/lib/hooksniff/api/message.rb +48 -0
  12. data/lib/hooksniff/api/message_attempt.rb +38 -0
  13. data/lib/hooksniff/api/statistics.rb +37 -0
  14. data/lib/{openapi_client → hooksniff}/api_error.rb +8 -18
  15. data/lib/hooksniff/errors.rb +129 -0
  16. data/lib/hooksniff/hooksniff.rb +36 -0
  17. data/lib/hooksniff/hooksniff_http_client.rb +128 -0
  18. data/lib/hooksniff/http_error_out.rb +18 -0
  19. data/lib/hooksniff/http_validation_error.rb +18 -0
  20. data/lib/hooksniff/internal.rb +7 -0
  21. data/lib/hooksniff/models/aggregate_event_types_out.rb +59 -0
  22. data/lib/hooksniff/models/endpoint_created_event.rb +50 -0
  23. data/lib/hooksniff/models/endpoint_created_event_data.rb +63 -0
  24. data/lib/hooksniff/models/endpoint_deleted_event.rb +50 -0
  25. data/lib/hooksniff/models/endpoint_deleted_event_data.rb +63 -0
  26. data/lib/hooksniff/models/endpoint_disabled_event.rb +53 -0
  27. data/lib/hooksniff/models/endpoint_disabled_event_data.rb +69 -0
  28. data/lib/hooksniff/models/endpoint_enabled_event.rb +50 -0
  29. data/lib/hooksniff/models/endpoint_enabled_event_data.rb +63 -0
  30. data/lib/hooksniff/models/endpoint_headers_in.rb +46 -0
  31. data/lib/hooksniff/models/endpoint_headers_out.rb +52 -0
  32. data/lib/hooksniff/models/endpoint_headers_patch_in.rb +53 -0
  33. data/lib/hooksniff/models/endpoint_in.rb +102 -0
  34. data/lib/hooksniff/models/endpoint_out.rb +104 -0
  35. data/lib/hooksniff/models/endpoint_patch.rb +97 -0
  36. data/lib/hooksniff/models/endpoint_secret_out.rb +50 -0
  37. data/lib/hooksniff/models/endpoint_secret_rotate_in.rb +53 -0
  38. data/lib/hooksniff/models/endpoint_update.rb +90 -0
  39. data/lib/hooksniff/models/endpoint_updated_event.rb +50 -0
  40. data/lib/hooksniff/models/endpoint_updated_event_data.rb +63 -0
  41. data/lib/hooksniff/models/event_in.rb +50 -0
  42. data/lib/hooksniff/models/event_out.rb +53 -0
  43. data/lib/hooksniff/models/event_type_in.rb +80 -0
  44. data/lib/hooksniff/models/event_type_out.rb +87 -0
  45. data/lib/hooksniff/models/event_type_patch.rb +66 -0
  46. data/lib/hooksniff/models/event_type_update.rb +67 -0
  47. data/lib/hooksniff/models/list_response_endpoint_out.rb +58 -0
  48. data/lib/hooksniff/models/list_response_event_type_out.rb +58 -0
  49. data/lib/hooksniff/models/list_response_message_attempt_out.rb +58 -0
  50. data/lib/hooksniff/models/list_response_message_out.rb +58 -0
  51. data/lib/hooksniff/models/message_attempt_exhausted_event.rb +53 -0
  52. data/lib/hooksniff/models/message_attempt_exhausted_event_data.rb +70 -0
  53. data/lib/hooksniff/models/message_attempt_failed_data.rb +56 -0
  54. data/lib/hooksniff/models/message_attempt_failing_event.rb +54 -0
  55. data/lib/hooksniff/models/message_attempt_failing_event_data.rb +70 -0
  56. data/lib/hooksniff/models/message_attempt_log.rb +112 -0
  57. data/lib/hooksniff/models/message_attempt_log_event.rb +53 -0
  58. data/lib/hooksniff/models/message_attempt_out.rb +96 -0
  59. data/lib/hooksniff/models/message_attempt_recovered_event.rb +53 -0
  60. data/lib/hooksniff/models/message_attempt_recovered_event_data.rb +70 -0
  61. data/lib/hooksniff/models/message_attempt_trigger_type.rb +33 -0
  62. data/lib/hooksniff/models/message_endpoint_out.rb +112 -0
  63. data/lib/hooksniff/models/message_in.rb +100 -0
  64. data/lib/hooksniff/models/message_out.rb +71 -0
  65. data/lib/hooksniff/models/message_status.rb +39 -0
  66. data/lib/hooksniff/models/message_status_text.rb +32 -0
  67. data/lib/hooksniff/models/ordering.rb +30 -0
  68. data/lib/hooksniff/models/status_code_class.rb +41 -0
  69. data/lib/hooksniff/util.rb +69 -0
  70. data/lib/hooksniff/validation_error.rb +28 -0
  71. data/lib/hooksniff/version.rb +5 -0
  72. data/lib/hooksniff/webhook.rb +84 -0
  73. data/lib/hooksniff.rb +78 -0
  74. data/test/test_hooksniff.rb +86 -0
  75. metadata +127 -163
  76. data/lib/openapi_client/api/admin_api.rb +0 -452
  77. data/lib/openapi_client/api/alerts_api.rb +0 -322
  78. data/lib/openapi_client/api/analytics_api.rb +0 -208
  79. data/lib/openapi_client/api/api_keys_api.rb +0 -252
  80. data/lib/openapi_client/api/audit_log_api.rb +0 -140
  81. data/lib/openapi_client/api/auth_api.rb +0 -1080
  82. data/lib/openapi_client/api/billing_api.rb +0 -500
  83. data/lib/openapi_client/api/contact_api.rb +0 -88
  84. data/lib/openapi_client/api/custom_domains_api.rb +0 -253
  85. data/lib/openapi_client/api/customer_portal_api.rb +0 -700
  86. data/lib/openapi_client/api/delivery_details_api.rb +0 -146
  87. data/lib/openapi_client/api/devices_api.rb +0 -202
  88. data/lib/openapi_client/api/embed_api.rb +0 -128
  89. data/lib/openapi_client/api/endpoints_api.rb +0 -468
  90. data/lib/openapi_client/api/events_api.rb +0 -75
  91. data/lib/openapi_client/api/health_api.rb +0 -193
  92. data/lib/openapi_client/api/inbound_api.rb +0 -170
  93. data/lib/openapi_client/api/notifications_api.rb +0 -309
  94. data/lib/openapi_client/api/o_auth_api.rb +0 -181
  95. data/lib/openapi_client/api/outbound_ips_api.rb +0 -77
  96. data/lib/openapi_client/api/playground_api.rb +0 -143
  97. data/lib/openapi_client/api/rate_limits_api.rb +0 -252
  98. data/lib/openapi_client/api/routing_api.rb +0 -393
  99. data/lib/openapi_client/api/schemas_api.rb +0 -268
  100. data/lib/openapi_client/api/search_api.rb +0 -96
  101. data/lib/openapi_client/api/simulator_api.rb +0 -82
  102. data/lib/openapi_client/api/sso_api.rb +0 -241
  103. data/lib/openapi_client/api/stats_api.rb +0 -77
  104. data/lib/openapi_client/api/stream_api.rb +0 -88
  105. data/lib/openapi_client/api/teams_api.rb +0 -476
  106. data/lib/openapi_client/api/templates_api.rb +0 -213
  107. data/lib/openapi_client/api/transforms_api.rb +0 -368
  108. data/lib/openapi_client/api/webhooks_api.rb +0 -534
  109. data/lib/openapi_client/api_client.rb +0 -397
  110. data/lib/openapi_client/api_model_base.rb +0 -88
  111. data/lib/openapi_client/configuration.rb +0 -312
  112. data/lib/openapi_client/models/admin_revenue_get200_response_inner.rb +0 -165
  113. data/lib/openapi_client/models/admin_sdk_update_post_request.rb +0 -156
  114. data/lib/openapi_client/models/admin_users_id_plan_put_request.rb +0 -181
  115. data/lib/openapi_client/models/admin_users_id_status_put_request.rb +0 -147
  116. data/lib/openapi_client/models/alert_rule.rb +0 -237
  117. data/lib/openapi_client/models/api_key_info.rb +0 -185
  118. data/lib/openapi_client/models/apply_template_request.rb +0 -173
  119. data/lib/openapi_client/models/apply_template_response.rb +0 -156
  120. data/lib/openapi_client/models/auth2fa_enable_post200_response.rb +0 -156
  121. data/lib/openapi_client/models/auth_login_post200_response.rb +0 -104
  122. data/lib/openapi_client/models/auth_response.rb +0 -167
  123. data/lib/openapi_client/models/batch_replay_request.rb +0 -166
  124. data/lib/openapi_client/models/batch_response.rb +0 -160
  125. data/lib/openapi_client/models/batch_response_errors_inner.rb +0 -156
  126. data/lib/openapi_client/models/batch_webhook_request.rb +0 -166
  127. data/lib/openapi_client/models/billing_portal_post200_response.rb +0 -147
  128. data/lib/openapi_client/models/change_password_request.rb +0 -199
  129. data/lib/openapi_client/models/change_role_request.rb +0 -188
  130. data/lib/openapi_client/models/confirm2fa_request.rb +0 -182
  131. data/lib/openapi_client/models/contact_request.rb +0 -242
  132. data/lib/openapi_client/models/contact_response.rb +0 -156
  133. data/lib/openapi_client/models/create_alert_request.rb +0 -277
  134. data/lib/openapi_client/models/create_api_key_response.rb +0 -175
  135. data/lib/openapi_client/models/create_endpoint_request.rb +0 -288
  136. data/lib/openapi_client/models/create_team_request.rb +0 -164
  137. data/lib/openapi_client/models/create_transform_rule_request.rb +0 -216
  138. data/lib/openapi_client/models/create_webhook_request.rb +0 -201
  139. data/lib/openapi_client/models/custom_domains_post_request.rb +0 -147
  140. data/lib/openapi_client/models/customer_response.rb +0 -256
  141. data/lib/openapi_client/models/delivery.rb +0 -246
  142. data/lib/openapi_client/models/delivery_attempt.rb +0 -205
  143. data/lib/openapi_client/models/delivery_list_response.rb +0 -176
  144. data/lib/openapi_client/models/delivery_trend_response.rb +0 -158
  145. data/lib/openapi_client/models/delivery_trend_response_buckets_inner.rb +0 -174
  146. data/lib/openapi_client/models/device_token_response.rb +0 -174
  147. data/lib/openapi_client/models/disable2fa_request.rb +0 -164
  148. data/lib/openapi_client/models/enable2fa_request.rb +0 -164
  149. data/lib/openapi_client/models/endpoint.rb +0 -321
  150. data/lib/openapi_client/models/endpoint_health.rb +0 -183
  151. data/lib/openapi_client/models/endpoints_endpoint_id_transforms_test_post_request.rb +0 -156
  152. data/lib/openapi_client/models/endpoints_id_rotate_secret_post200_response.rb +0 -156
  153. data/lib/openapi_client/models/error.rb +0 -165
  154. data/lib/openapi_client/models/forgot_password_request.rb +0 -164
  155. data/lib/openapi_client/models/invite_request.rb +0 -207
  156. data/lib/openapi_client/models/invoice_response.rb +0 -183
  157. data/lib/openapi_client/models/latency_trend_response.rb +0 -167
  158. data/lib/openapi_client/models/latency_trend_response_buckets_inner.rb +0 -165
  159. data/lib/openapi_client/models/login_request.rb +0 -190
  160. data/lib/openapi_client/models/notification.rb +0 -193
  161. data/lib/openapi_client/models/notification_list_response.rb +0 -167
  162. data/lib/openapi_client/models/notification_preferences.rb +0 -201
  163. data/lib/openapi_client/models/notifications_unread_count_get200_response.rb +0 -147
  164. data/lib/openapi_client/models/outbound_ips_response.rb +0 -158
  165. data/lib/openapi_client/models/paginated_users.rb +0 -176
  166. data/lib/openapi_client/models/playground_get200_response.rb +0 -160
  167. data/lib/openapi_client/models/portal_notifications_put200_response.rb +0 -156
  168. data/lib/openapi_client/models/portal_profile.rb +0 -184
  169. data/lib/openapi_client/models/refresh_token_request.rb +0 -164
  170. data/lib/openapi_client/models/register_device_request.rb +0 -208
  171. data/lib/openapi_client/models/register_request.rb +0 -201
  172. data/lib/openapi_client/models/register_schema_request.rb +0 -191
  173. data/lib/openapi_client/models/resend_verification_request.rb +0 -164
  174. data/lib/openapi_client/models/reset_password_request.rb +0 -199
  175. data/lib/openapi_client/models/retry_policy.rb +0 -216
  176. data/lib/openapi_client/models/routing_info.rb +0 -193
  177. data/lib/openapi_client/models/search_result.rb +0 -158
  178. data/lib/openapi_client/models/simulator_post_request.rb +0 -165
  179. data/lib/openapi_client/models/sso_config_post_request.rb +0 -190
  180. data/lib/openapi_client/models/stats_response.rb +0 -210
  181. data/lib/openapi_client/models/stream_params.rb +0 -201
  182. data/lib/openapi_client/models/subscription_response.rb +0 -201
  183. data/lib/openapi_client/models/success_rate_response.rb +0 -183
  184. data/lib/openapi_client/models/system_stats.rb +0 -185
  185. data/lib/openapi_client/models/system_stats_plan_breakdown_inner.rb +0 -156
  186. data/lib/openapi_client/models/system_status.rb +0 -210
  187. data/lib/openapi_client/models/system_status_components_inner.rb +0 -184
  188. data/lib/openapi_client/models/team.rb +0 -165
  189. data/lib/openapi_client/models/team_detail_response.rb +0 -169
  190. data/lib/openapi_client/models/team_invite.rb +0 -174
  191. data/lib/openapi_client/models/team_member.rb +0 -193
  192. data/lib/openapi_client/models/test_webhook_request.rb +0 -199
  193. data/lib/openapi_client/models/test_webhook_response.rb +0 -174
  194. data/lib/openapi_client/models/transform_rule.rb +0 -201
  195. data/lib/openapi_client/models/two_factor_required_response.rb +0 -165
  196. data/lib/openapi_client/models/update_endpoint_request.rb +0 -278
  197. data/lib/openapi_client/models/update_notification_preferences.rb +0 -195
  198. data/lib/openapi_client/models/update_profile_request.rb +0 -190
  199. data/lib/openapi_client/models/update_routing_request.rb +0 -190
  200. data/lib/openapi_client/models/upgrade_request.rb +0 -209
  201. data/lib/openapi_client/models/upgrade_response.rb +0 -166
  202. data/lib/openapi_client/models/usage_response.rb +0 -201
  203. data/lib/openapi_client/models/user_summary.rb +0 -193
  204. data/lib/openapi_client/models/validate_event_request.rb +0 -164
  205. data/lib/openapi_client/models/verify2fa_request.rb +0 -208
  206. data/lib/openapi_client/models/verify_email_request.rb +0 -164
  207. data/lib/openapi_client/models/webhook_template.rb +0 -183
  208. data/lib/openapi_client/version.rb +0 -15
  209. data/lib/openapi_client.rb +0 -169
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+
5
+ module HookSniff
6
+ class Statistics
7
+ def initialize(client)
8
+ @client = client
9
+ end
10
+
11
+ def aggregate_event_types(options = {})
12
+ options = options.transform_keys(&:to_s)
13
+ res = @client.execute_request(
14
+ "GET",
15
+ "/v1/stats/event-types",
16
+ query_params: {
17
+ "since" => options["since"],
18
+ "until" => options["until"]
19
+ }
20
+ )
21
+ AggregateEventTypesOut.deserialize(res)
22
+ end
23
+
24
+ def app_stats(app_id, options = {})
25
+ options = options.transform_keys(&:to_s)
26
+ res = @client.execute_request(
27
+ "GET",
28
+ "/v1/stats/app/#{app_id}",
29
+ query_params: {
30
+ "since" => options["since"],
31
+ "until" => options["until"]
32
+ }
33
+ )
34
+ res
35
+ end
36
+ end
37
+ end
@@ -1,16 +1,6 @@
1
- =begin
2
- #HookSniff API
1
+ # frozen_string_literal: true
3
2
 
4
- #Webhook delivery, monitoring, and management API. All endpoints under `/v1` require authentication via `Authorization: Bearer <api_key>` header unless marked as **Public**.
5
-
6
- The version of the OpenAPI document: 1.0.0
7
- Contact: support@hooksniff.vercel.app
8
- Generated by: https://openapi-generator.tech
9
- Generator version: 7.22.0
10
-
11
- =end
12
-
13
- module OpenapiClient
3
+ module HookSniff
14
4
  class ApiError < StandardError
15
5
  attr_reader :code, :response_headers, :response_body
16
6
 
@@ -20,18 +10,18 @@ module OpenapiClient
20
10
  # ApiError.new(:code => 500, :response_headers => {}, :response_body => "")
21
11
  # ApiError.new(:code => 404, :message => "Not Found")
22
12
  def initialize(arg = nil)
23
- if arg.is_a? Hash
24
- if arg.key?(:message) || arg.key?('message')
25
- super(arg[:message] || arg['message'])
13
+ if arg.is_a?(Hash)
14
+ if arg.key?(:message) || arg.key?("message")
15
+ super(arg[:message] || arg["message"])
26
16
  else
27
- super arg
17
+ super(arg)
28
18
  end
29
19
 
30
20
  arg.each do |k, v|
31
- instance_variable_set "@#{k}", v
21
+ instance_variable_set("@#{k}", v)
32
22
  end
33
23
  else
34
- super arg
24
+ super(arg)
35
25
  @message = arg
36
26
  end
37
27
  end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HookSniff
4
+ # Base error class for all HookSniff API errors
5
+ class ApiError < StandardError
6
+ attr_reader :code, :response_headers, :response_body
7
+
8
+ def initialize(code:, response_headers: {}, response_body: nil)
9
+ @code = code
10
+ @response_headers = response_headers
11
+ @response_body = response_body
12
+ super("HookSniff API error #{code}")
13
+ end
14
+ end
15
+
16
+ # 400 Bad Request
17
+ class BadRequestError < ApiError
18
+ def initialize(response_headers: {}, response_body: nil)
19
+ super(code: 400, response_headers: response_headers, response_body: response_body)
20
+ end
21
+ end
22
+
23
+ # 401 Unauthorized
24
+ class UnauthorizedError < ApiError
25
+ def initialize(response_headers: {}, response_body: nil)
26
+ super(code: 401, response_headers: response_headers, response_body: response_body)
27
+ end
28
+ end
29
+
30
+ # 403 Forbidden
31
+ class ForbiddenError < ApiError
32
+ def initialize(response_headers: {}, response_body: nil)
33
+ super(code: 403, response_headers: response_headers, response_body: response_body)
34
+ end
35
+ end
36
+
37
+ # 404 Not Found
38
+ class NotFoundError < ApiError
39
+ def initialize(response_headers: {}, response_body: nil)
40
+ super(code: 404, response_headers: response_headers, response_body: response_body)
41
+ end
42
+ end
43
+
44
+ # 409 Conflict
45
+ class ConflictError < ApiError
46
+ def initialize(response_headers: {}, response_body: nil)
47
+ super(code: 409, response_headers: response_headers, response_body: response_body)
48
+ end
49
+ end
50
+
51
+ # 422 Unprocessable Entity
52
+ class UnprocessableEntityError < ApiError
53
+ attr_reader :validation_errors
54
+
55
+ def initialize(validation_errors: [], response_headers: {}, response_body: nil)
56
+ super(code: 422, response_headers: response_headers, response_body: response_body)
57
+ @validation_errors = validation_errors
58
+ end
59
+ end
60
+
61
+ # 429 Rate Limited
62
+ class RateLimitError < ApiError
63
+ attr_reader :retry_after
64
+
65
+ def initialize(retry_after: nil, response_headers: {}, response_body: nil)
66
+ super(code: 429, response_headers: response_headers, response_body: response_body)
67
+ @retry_after = retry_after
68
+ end
69
+ end
70
+
71
+ # 500 Internal Server Error
72
+ class InternalServerError < ApiError
73
+ def initialize(response_headers: {}, response_body: nil)
74
+ super(code: 500, response_headers: response_headers, response_body: response_body)
75
+ end
76
+ end
77
+
78
+ # 502 Bad Gateway
79
+ class BadGatewayError < ApiError
80
+ def initialize(response_headers: {}, response_body: nil)
81
+ super(code: 502, response_headers: response_headers, response_body: response_body)
82
+ end
83
+ end
84
+
85
+ # 503 Service Unavailable
86
+ class ServiceUnavailableError < ApiError
87
+ def initialize(response_headers: {}, response_body: nil)
88
+ super(code: 503, response_headers: response_headers, response_body: response_body)
89
+ end
90
+ end
91
+
92
+ # 504 Gateway Timeout
93
+ class GatewayTimeoutError < ApiError
94
+ def initialize(response_headers: {}, response_body: nil)
95
+ super(code: 504, response_headers: response_headers, response_body: response_body)
96
+ end
97
+ end
98
+
99
+ # Create the appropriate error from a status code
100
+ def self.create_error_from_status(status_code, response_headers: {}, response_body: nil)
101
+ case status_code
102
+ when 400
103
+ BadRequestError.new(response_headers: response_headers, response_body: response_body)
104
+ when 401
105
+ UnauthorizedError.new(response_headers: response_headers, response_body: response_body)
106
+ when 403
107
+ ForbiddenError.new(response_headers: response_headers, response_body: response_body)
108
+ when 404
109
+ NotFoundError.new(response_headers: response_headers, response_body: response_body)
110
+ when 409
111
+ ConflictError.new(response_headers: response_headers, response_body: response_body)
112
+ when 422
113
+ UnprocessableEntityError.new(response_headers: response_headers, response_body: response_body)
114
+ when 429
115
+ retry_after = response_headers["retry-after"]&.to_i
116
+ RateLimitError.new(retry_after: retry_after, response_headers: response_headers, response_body: response_body)
117
+ when 500
118
+ InternalServerError.new(response_headers: response_headers, response_body: response_body)
119
+ when 502
120
+ BadGatewayError.new(response_headers: response_headers, response_body: response_body)
121
+ when 503
122
+ ServiceUnavailableError.new(response_headers: response_headers, response_body: response_body)
123
+ when 504
124
+ GatewayTimeoutError.new(response_headers: response_headers, response_body: response_body)
125
+ else
126
+ ApiError.new(code: status_code, response_headers: response_headers, response_body: response_body)
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HookSniff
4
+ class HookSniffOptions
5
+ attr_accessor :debug
6
+ attr_accessor :server_url
7
+
8
+ def initialize(debug = false, server_url = nil)
9
+ @debug = debug
10
+ @server_url = server_url
11
+ end
12
+ end
13
+
14
+ class Client
15
+ attr_accessor :authentication
16
+ attr_accessor :endpoint
17
+ attr_accessor :event_type
18
+ attr_accessor :health
19
+ attr_accessor :message
20
+ attr_accessor :message_attempt
21
+ attr_accessor :statistics
22
+
23
+ def initialize(auth_token, options = HookSniffOptions.new)
24
+ uri = URI(options.server_url || "https://hooksniff-api-1046140057667.europe-west1.run.app")
25
+ api_client = HookSniffHttpClient.new(auth_token, uri)
26
+
27
+ @authentication = Authentication.new(api_client)
28
+ @endpoint = Endpoint.new(api_client)
29
+ @event_type = EventType.new(api_client)
30
+ @health = Health.new(api_client)
31
+ @message = Message.new(api_client)
32
+ @message_attempt = MessageAttempt.new(api_client)
33
+ @statistics = Statistics.new(api_client)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+ require "cgi"
3
+ require "uri"
4
+ require "net/http"
5
+ require "securerandom"
6
+
7
+
8
+ module HookSniff
9
+ class HookSniffHttpClient
10
+ def initialize(token, base_url)
11
+ @token = token
12
+ @base_url = base_url
13
+ end
14
+
15
+ def execute_request(method, path, **kwargs)
16
+ query_params = kwargs[:query_params] || {}
17
+ headers = kwargs[:headers] || {}
18
+ body = kwargs[:body] || {}
19
+
20
+ uri = URI("#{@base_url}#{path}")
21
+ encoded_query = encode_query_params(query_params)
22
+ if encoded_query != ""
23
+ uri.query = encoded_query
24
+ end
25
+
26
+ http = Net::HTTP.new(uri.host, uri.port)
27
+ http.use_ssl = (uri.scheme == "https")
28
+
29
+ # Dynamically select the request class based on method
30
+ request_class = case method.to_s.upcase
31
+ when "GET"
32
+ Net::HTTP::Get
33
+ when "POST"
34
+ Net::HTTP::Post
35
+ when "PUT"
36
+ Net::HTTP::Put
37
+ when "DELETE"
38
+ Net::HTTP::Delete
39
+ when "PATCH"
40
+ Net::HTTP::Patch
41
+ when "HEAD"
42
+ Net::HTTP::Head
43
+ else
44
+ raise ArgumentError, "Unsupported HTTP method: #{method}"
45
+ end
46
+
47
+ # Create request object
48
+ request = request_class.new(uri.request_uri)
49
+ request["Authorization"] = "Bearer #{@token}"
50
+ request["User-Agent"] = "hooksniff-libs/#{VERSION}/ruby"
51
+ request["hooksniff-req-id"] = rand(0...(2 ** 64))
52
+
53
+ # Add headers
54
+ headers.each { |key, value| request[key] = value }
55
+
56
+ # Check if idempotency-key header already exists
57
+ if !request.key?("idempotency-key") && method.to_s.upcase == "POST"
58
+ request["idempotency-key"] = "auto_" + SecureRandom.uuid.to_s
59
+ end
60
+
61
+ # Add body for non-GET requests
62
+ if %w[POST PUT PATCH].include?(method.to_s.upcase) && !body.nil?
63
+ request.body = body.to_json
64
+ request["Content-Type"] = "application/json"
65
+ end
66
+
67
+ res = execute_request_with_retries(request, http)
68
+
69
+ # Execute request
70
+ if Integer(res.code) == 204
71
+ nil
72
+ elsif Integer(res.code) >= 200 && Integer(res.code) <= 299
73
+ JSON.parse(res.body)
74
+ else
75
+ fail(
76
+ ApiError.new(
77
+ :code => Integer(res.code),
78
+ :response_headers => res.each_header.to_h,
79
+ :response_body => res.body
80
+ )
81
+ )
82
+ end
83
+ end
84
+
85
+ private def execute_request_with_retries(request, http)
86
+ res = http.request(request)
87
+
88
+ [0.05, 0.1, 0.2].each_with_index do |sleep_duration, index|
89
+ # 429 Rate Limit — respect Retry-After header
90
+ if Integer(res.code) == 429
91
+ retry_after = res["Retry-After"]
92
+ delay = retry_after ? retry_after.to_f : sleep_duration
93
+ sleep(delay)
94
+ request["hooksniff-retry-count"] = index + 1
95
+ res = http.request(request)
96
+ next
97
+ end
98
+
99
+ unless Integer(res.code) >= 500
100
+ break
101
+ end
102
+
103
+ sleep(sleep_duration)
104
+ request["hooksniff-retry-count"] = index + 1
105
+ res = http.request(request)
106
+ end
107
+
108
+ res
109
+ end
110
+
111
+ private def encode_query_params(query_params = {})
112
+ encoded_query_pairs = []
113
+ query_params.each do |k, v|
114
+ unless v.nil?
115
+ if v.kind_of?(Array)
116
+ encoded_query_pairs.append("#{k}=" + CGI::escape(v.sort.join(",")))
117
+ elsif v.kind_of?(Time)
118
+ encoded_query_pairs.append("#{k}=#{CGI::escape(v.utc.to_datetime.rfc3339)}")
119
+ else
120
+ encoded_query_pairs.append("#{k}=#{CGI::escape(v)}")
121
+ end
122
+ end
123
+ end
124
+
125
+ encoded_query_pairs.join("&")
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HookSniff
4
+ class HttpErrorOut
5
+ attr_accessor :code
6
+
7
+ attr_accessor :detail
8
+
9
+ def initialize(attributes = {})
10
+ if (!attributes.is_a?(Hash))
11
+ fail(ArgumentError, "The input argument (attributes) must be a hash in `HookSniff::HttpErrorOut` initialize method")
12
+ end
13
+
14
+ @detail = attributes[:"detail"]
15
+ @code = attributes[:"code"]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HookSniff
4
+ class HTTPValidationError
5
+ attr_accessor :detail
6
+
7
+ def initialize(attributes = {})
8
+ if (!attributes.is_a?(Hash))
9
+ fail(
10
+ ArgumentError,
11
+ "The input argument (attributes) must be a hash in `HookSniff::HTTPValidationError` initialize method"
12
+ )
13
+ end
14
+
15
+ @detail = attributes[:"detail"]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HookSniff
4
+ private_constant :HttpErrorOut
5
+ private_constant :HTTPValidationError
6
+ private_constant :ValidationError
7
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+ # This file is @generated
3
+ require "json"
4
+
5
+ module HookSniff
6
+ class AggregateEventTypesOut
7
+ # The QueueBackgroundTask's ID.
8
+ attr_accessor :id
9
+ attr_accessor :status
10
+ attr_accessor :task
11
+ attr_accessor :updated_at
12
+
13
+ ALL_FIELD ||= ["id", "status", "task", "updated_at"].freeze
14
+ private_constant :ALL_FIELD
15
+
16
+ def initialize(attributes = {})
17
+ unless attributes.is_a?(Hash)
18
+ fail(
19
+ ArgumentError,
20
+ "The input argument (attributes) must be a hash in `HookSniff::AggregateEventTypesOut` new method"
21
+ )
22
+ end
23
+
24
+ attributes.each do |k, v|
25
+ unless ALL_FIELD.include?(k.to_s)
26
+ fail(ArgumentError, "The field #{k} is not part of HookSniff::AggregateEventTypesOut")
27
+ end
28
+
29
+ instance_variable_set("@#{k}", v)
30
+ instance_variable_set("@__#{k}_is_defined", true)
31
+ end
32
+ end
33
+
34
+ def self.deserialize(attributes = {})
35
+ attributes = attributes.transform_keys(&:to_s)
36
+ attrs = Hash.new
37
+ attrs["id"] = attributes["id"]
38
+ attrs["status"] = HookSniff::BackgroundTaskStatus.deserialize(attributes["status"])
39
+ attrs["task"] = HookSniff::BackgroundTaskType.deserialize(attributes["task"])
40
+ attrs["updated_at"] = DateTime.rfc3339(attributes["updatedAt"]).to_time
41
+ new(attrs)
42
+ end
43
+
44
+ def serialize
45
+ out = Hash.new
46
+ out["id"] = HookSniff::serialize_primitive(@id) if @id
47
+ out["status"] = HookSniff::serialize_schema_ref(@status) if @status
48
+ out["task"] = HookSniff::serialize_schema_ref(@task) if @task
49
+ out["updatedAt"] = HookSniff::serialize_primitive(@updated_at) if @updated_at
50
+ out
51
+ end
52
+
53
+ # Serializes the object to a json string
54
+ # @return String
55
+ def to_json
56
+ JSON.dump(serialize)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+ # This file is @generated
3
+ require "json"
4
+
5
+ module HookSniff
6
+ # Sent when an endpoint is created.
7
+ class EndpointCreatedEvent
8
+ attr_accessor :data
9
+ attr_accessor :type
10
+
11
+ ALL_FIELD ||= ["data", "type"].freeze
12
+ private_constant :ALL_FIELD
13
+
14
+ def initialize(attributes = {})
15
+ unless attributes.is_a?(Hash)
16
+ fail(ArgumentError, "The input argument (attributes) must be a hash in `HookSniff::EndpointCreatedEvent` new method")
17
+ end
18
+
19
+ attributes.each do |k, v|
20
+ unless ALL_FIELD.include?(k.to_s)
21
+ fail(ArgumentError, "The field #{k} is not part of HookSniff::EndpointCreatedEvent")
22
+ end
23
+
24
+ instance_variable_set("@#{k}", v)
25
+ instance_variable_set("@__#{k}_is_defined", true)
26
+ end
27
+ end
28
+
29
+ def self.deserialize(attributes = {})
30
+ attributes = attributes.transform_keys(&:to_s)
31
+ attrs = Hash.new
32
+ attrs["data"] = HookSniff::EndpointCreatedEventData.deserialize(attributes["data"])
33
+ attrs["type"] = attributes["type"]
34
+ new(attrs)
35
+ end
36
+
37
+ def serialize
38
+ out = Hash.new
39
+ out["data"] = HookSniff::serialize_schema_ref(@data) if @data
40
+ out["type"] = HookSniff::serialize_primitive(@type) if @type
41
+ out
42
+ end
43
+
44
+ # Serializes the object to a json string
45
+ # @return String
46
+ def to_json
47
+ JSON.dump(serialize)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+ # This file is @generated
3
+ require "json"
4
+
5
+ module HookSniff
6
+ # Sent when an endpoint is created, updated, or deleted
7
+ class EndpointCreatedEventData
8
+ # The Application's ID.
9
+ attr_accessor :app_id
10
+ # The Application's UID.
11
+ attr_accessor :app_uid
12
+ # The Endpoint's ID.
13
+ attr_accessor :endpoint_id
14
+ # The Endpoint's UID.
15
+ attr_accessor :endpoint_uid
16
+
17
+ ALL_FIELD ||= ["app_id", "app_uid", "endpoint_id", "endpoint_uid"].freeze
18
+ private_constant :ALL_FIELD
19
+
20
+ def initialize(attributes = {})
21
+ unless attributes.is_a?(Hash)
22
+ fail(
23
+ ArgumentError,
24
+ "The input argument (attributes) must be a hash in `HookSniff::EndpointCreatedEventData` new method"
25
+ )
26
+ end
27
+
28
+ attributes.each do |k, v|
29
+ unless ALL_FIELD.include?(k.to_s)
30
+ fail(ArgumentError, "The field #{k} is not part of HookSniff::EndpointCreatedEventData")
31
+ end
32
+
33
+ instance_variable_set("@#{k}", v)
34
+ instance_variable_set("@__#{k}_is_defined", true)
35
+ end
36
+ end
37
+
38
+ def self.deserialize(attributes = {})
39
+ attributes = attributes.transform_keys(&:to_s)
40
+ attrs = Hash.new
41
+ attrs["app_id"] = attributes["appId"]
42
+ attrs["app_uid"] = attributes["appUid"]
43
+ attrs["endpoint_id"] = attributes["endpointId"]
44
+ attrs["endpoint_uid"] = attributes["endpointUid"]
45
+ new(attrs)
46
+ end
47
+
48
+ def serialize
49
+ out = Hash.new
50
+ out["appId"] = HookSniff::serialize_primitive(@app_id) if @app_id
51
+ out["appUid"] = HookSniff::serialize_primitive(@app_uid) if @app_uid
52
+ out["endpointId"] = HookSniff::serialize_primitive(@endpoint_id) if @endpoint_id
53
+ out["endpointUid"] = HookSniff::serialize_primitive(@endpoint_uid) if @endpoint_uid
54
+ out
55
+ end
56
+
57
+ # Serializes the object to a json string
58
+ # @return String
59
+ def to_json
60
+ JSON.dump(serialize)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+ # This file is @generated
3
+ require "json"
4
+
5
+ module HookSniff
6
+ # Sent when an endpoint is deleted.
7
+ class EndpointDeletedEvent
8
+ attr_accessor :data
9
+ attr_accessor :type
10
+
11
+ ALL_FIELD ||= ["data", "type"].freeze
12
+ private_constant :ALL_FIELD
13
+
14
+ def initialize(attributes = {})
15
+ unless attributes.is_a?(Hash)
16
+ fail(ArgumentError, "The input argument (attributes) must be a hash in `HookSniff::EndpointDeletedEvent` new method")
17
+ end
18
+
19
+ attributes.each do |k, v|
20
+ unless ALL_FIELD.include?(k.to_s)
21
+ fail(ArgumentError, "The field #{k} is not part of HookSniff::EndpointDeletedEvent")
22
+ end
23
+
24
+ instance_variable_set("@#{k}", v)
25
+ instance_variable_set("@__#{k}_is_defined", true)
26
+ end
27
+ end
28
+
29
+ def self.deserialize(attributes = {})
30
+ attributes = attributes.transform_keys(&:to_s)
31
+ attrs = Hash.new
32
+ attrs["data"] = HookSniff::EndpointDeletedEventData.deserialize(attributes["data"])
33
+ attrs["type"] = attributes["type"]
34
+ new(attrs)
35
+ end
36
+
37
+ def serialize
38
+ out = Hash.new
39
+ out["data"] = HookSniff::serialize_schema_ref(@data) if @data
40
+ out["type"] = HookSniff::serialize_primitive(@type) if @type
41
+ out
42
+ end
43
+
44
+ # Serializes the object to a json string
45
+ # @return String
46
+ def to_json
47
+ JSON.dump(serialize)
48
+ end
49
+ end
50
+ end