berrycrawl 0.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.
Files changed (136) hide show
  1. checksums.yaml +7 -0
  2. data/.fern/metadata.json +12 -0
  3. data/.rubocop.yml +103 -0
  4. data/CONTRIBUTING.md +120 -0
  5. data/LICENSE +17 -0
  6. data/README.md +183 -0
  7. data/Rakefile +20 -0
  8. data/custom.gemspec.rb +16 -0
  9. data/lib/Berrycrawl/account/client.rb +44 -0
  10. data/lib/Berrycrawl/brand/client.rb +48 -0
  11. data/lib/Berrycrawl/brand/types/brand_dto.rb +15 -0
  12. data/lib/Berrycrawl/client.rb +268 -0
  13. data/lib/Berrycrawl/environment.rb +7 -0
  14. data/lib/Berrycrawl/errors/api_error.rb +8 -0
  15. data/lib/Berrycrawl/errors/client_error.rb +17 -0
  16. data/lib/Berrycrawl/errors/redirect_error.rb +8 -0
  17. data/lib/Berrycrawl/errors/response_error.rb +42 -0
  18. data/lib/Berrycrawl/errors/server_error.rb +11 -0
  19. data/lib/Berrycrawl/errors/timeout_error.rb +8 -0
  20. data/lib/Berrycrawl/internal/errors/constraint_error.rb +10 -0
  21. data/lib/Berrycrawl/internal/errors/type_error.rb +10 -0
  22. data/lib/Berrycrawl/internal/http/base_request.rb +51 -0
  23. data/lib/Berrycrawl/internal/http/raw_client.rb +252 -0
  24. data/lib/Berrycrawl/internal/iterators/cursor_item_iterator.rb +28 -0
  25. data/lib/Berrycrawl/internal/iterators/cursor_page_iterator.rb +63 -0
  26. data/lib/Berrycrawl/internal/iterators/item_iterator.rb +65 -0
  27. data/lib/Berrycrawl/internal/iterators/offset_item_iterator.rb +30 -0
  28. data/lib/Berrycrawl/internal/iterators/offset_page_iterator.rb +103 -0
  29. data/lib/Berrycrawl/internal/json/request.rb +41 -0
  30. data/lib/Berrycrawl/internal/json/serializable.rb +25 -0
  31. data/lib/Berrycrawl/internal/multipart/multipart_encoder.rb +141 -0
  32. data/lib/Berrycrawl/internal/multipart/multipart_form_data.rb +78 -0
  33. data/lib/Berrycrawl/internal/multipart/multipart_form_data_part.rb +51 -0
  34. data/lib/Berrycrawl/internal/multipart/multipart_request.rb +40 -0
  35. data/lib/Berrycrawl/internal/types/array.rb +47 -0
  36. data/lib/Berrycrawl/internal/types/boolean.rb +34 -0
  37. data/lib/Berrycrawl/internal/types/enum.rb +56 -0
  38. data/lib/Berrycrawl/internal/types/hash.rb +36 -0
  39. data/lib/Berrycrawl/internal/types/model/field.rb +38 -0
  40. data/lib/Berrycrawl/internal/types/model.rb +208 -0
  41. data/lib/Berrycrawl/internal/types/type.rb +35 -0
  42. data/lib/Berrycrawl/internal/types/union.rb +161 -0
  43. data/lib/Berrycrawl/internal/types/unknown.rb +15 -0
  44. data/lib/Berrycrawl/internal/types/utils.rb +116 -0
  45. data/lib/Berrycrawl/jobs/client.rb +127 -0
  46. data/lib/Berrycrawl/jobs/types/cancel_jobs_request.rb +11 -0
  47. data/lib/Berrycrawl/jobs/types/get_jobs_request.rb +15 -0
  48. data/lib/Berrycrawl/jobs/types/list_jobs_request.rb +17 -0
  49. data/lib/Berrycrawl/jobs/types/list_jobs_request_status.rb +17 -0
  50. data/lib/Berrycrawl/jobs/types/list_jobs_request_type.rb +14 -0
  51. data/lib/Berrycrawl/types/account_response.rb +11 -0
  52. data/lib/Berrycrawl/types/account_response_data.rb +21 -0
  53. data/lib/Berrycrawl/types/account_response_data_plan.rb +17 -0
  54. data/lib/Berrycrawl/types/account_response_data_queue.rb +11 -0
  55. data/lib/Berrycrawl/types/action_dto.rb +21 -0
  56. data/lib/Berrycrawl/types/action_dto_direction.rb +12 -0
  57. data/lib/Berrycrawl/types/action_dto_type.rb +18 -0
  58. data/lib/Berrycrawl/types/agent_config_dto.rb +11 -0
  59. data/lib/Berrycrawl/types/agent_config_dto_mode.rb +12 -0
  60. data/lib/Berrycrawl/types/brand_asset.rb +17 -0
  61. data/lib/Berrycrawl/types/brand_profile.rb +27 -0
  62. data/lib/Berrycrawl/types/brand_profile_colors_item.rb +11 -0
  63. data/lib/Berrycrawl/types/brand_profile_fonts_item.rb +11 -0
  64. data/lib/Berrycrawl/types/brand_profile_socials_item.rb +11 -0
  65. data/lib/Berrycrawl/types/brand_response.rb +11 -0
  66. data/lib/Berrycrawl/types/brand_response_data.rb +11 -0
  67. data/lib/Berrycrawl/types/brand_response_data_meta.rb +15 -0
  68. data/lib/Berrycrawl/types/cancel_job_response.rb +11 -0
  69. data/lib/Berrycrawl/types/cancel_job_response_data.rb +11 -0
  70. data/lib/Berrycrawl/types/change_tracking_format_dto.rb +15 -0
  71. data/lib/Berrycrawl/types/change_tracking_format_dto_type.rb +11 -0
  72. data/lib/Berrycrawl/types/crawl_dto.rb +41 -0
  73. data/lib/Berrycrawl/types/crawl_dto_sitemap.rb +13 -0
  74. data/lib/Berrycrawl/types/extract_dto.rb +29 -0
  75. data/lib/Berrycrawl/types/extract_webhook_config_dto.rb +15 -0
  76. data/lib/Berrycrawl/types/job_created_response.rb +15 -0
  77. data/lib/Berrycrawl/types/job_response.rb +11 -0
  78. data/lib/Berrycrawl/types/job_response_data.rb +37 -0
  79. data/lib/Berrycrawl/types/job_response_data_errors_item.rb +11 -0
  80. data/lib/Berrycrawl/types/job_summary.rb +29 -0
  81. data/lib/Berrycrawl/types/job_summary_type.rb +12 -0
  82. data/lib/Berrycrawl/types/json_format_dto.rb +13 -0
  83. data/lib/Berrycrawl/types/json_format_dto_type.rb +11 -0
  84. data/lib/Berrycrawl/types/list_jobs_response.rb +11 -0
  85. data/lib/Berrycrawl/types/list_jobs_response_data.rb +11 -0
  86. data/lib/Berrycrawl/types/list_webhooks_response.rb +11 -0
  87. data/lib/Berrycrawl/types/location_dto.rb +11 -0
  88. data/lib/Berrycrawl/types/map_dto.rb +23 -0
  89. data/lib/Berrycrawl/types/map_dto_sitemap.rb +13 -0
  90. data/lib/Berrycrawl/types/map_link.rb +13 -0
  91. data/lib/Berrycrawl/types/map_response.rb +15 -0
  92. data/lib/Berrycrawl/types/message_response.rb +11 -0
  93. data/lib/Berrycrawl/types/pagination.rb +15 -0
  94. data/lib/Berrycrawl/types/parse_dto.rb +11 -0
  95. data/lib/Berrycrawl/types/scrape_dto.rb +49 -0
  96. data/lib/Berrycrawl/types/scrape_dto_formats_item.rb +17 -0
  97. data/lib/Berrycrawl/types/scrape_dto_formats_item_zero.rb +18 -0
  98. data/lib/Berrycrawl/types/scrape_dto_proxy.rb +16 -0
  99. data/lib/Berrycrawl/types/scrape_metadata.rb +17 -0
  100. data/lib/Berrycrawl/types/scrape_response.rb +17 -0
  101. data/lib/Berrycrawl/types/scrape_response_credits.rb +9 -0
  102. data/lib/Berrycrawl/types/screenshot_clip_dto.rb +15 -0
  103. data/lib/Berrycrawl/types/screenshot_cookie_dto.rb +21 -0
  104. data/lib/Berrycrawl/types/screenshot_cookie_dto_same_site.rb +13 -0
  105. data/lib/Berrycrawl/types/screenshot_dto.rb +79 -0
  106. data/lib/Berrycrawl/types/screenshot_dto_color_scheme.rb +12 -0
  107. data/lib/Berrycrawl/types/screenshot_dto_device.rb +15 -0
  108. data/lib/Berrycrawl/types/screenshot_dto_format.rb +13 -0
  109. data/lib/Berrycrawl/types/screenshot_dto_full_page_algorithm.rb +13 -0
  110. data/lib/Berrycrawl/types/screenshot_dto_proxy.rb +16 -0
  111. data/lib/Berrycrawl/types/screenshot_dto_response_format.rb +12 -0
  112. data/lib/Berrycrawl/types/screenshot_dto_scale.rb +12 -0
  113. data/lib/Berrycrawl/types/screenshot_dto_wait_until.rb +13 -0
  114. data/lib/Berrycrawl/types/screenshot_location_dto.rb +11 -0
  115. data/lib/Berrycrawl/types/screenshot_viewport_dto.rb +11 -0
  116. data/lib/Berrycrawl/types/search_dto.rb +23 -0
  117. data/lib/Berrycrawl/types/search_response.rb +19 -0
  118. data/lib/Berrycrawl/types/search_response_provider.rb +11 -0
  119. data/lib/Berrycrawl/types/search_result.rb +19 -0
  120. data/lib/Berrycrawl/types/search_result_provider.rb +11 -0
  121. data/lib/Berrycrawl/types/summary_format_dto.rb +11 -0
  122. data/lib/Berrycrawl/types/summary_format_dto_type.rb +11 -0
  123. data/lib/Berrycrawl/types/test_webhook_response.rb +15 -0
  124. data/lib/Berrycrawl/types/webhook.rb +23 -0
  125. data/lib/Berrycrawl/types/webhook_config_dto.rb +15 -0
  126. data/lib/Berrycrawl/types/webhook_response.rb +11 -0
  127. data/lib/Berrycrawl/version.rb +5 -0
  128. data/lib/Berrycrawl/webhooks/client.rb +214 -0
  129. data/lib/Berrycrawl/webhooks/types/create_webhook_dto.rb +13 -0
  130. data/lib/Berrycrawl/webhooks/types/delete_webhooks_request.rb +11 -0
  131. data/lib/Berrycrawl/webhooks/types/get_webhooks_request.rb +11 -0
  132. data/lib/Berrycrawl/webhooks/types/test_webhook_dto.rb +15 -0
  133. data/lib/Berrycrawl/webhooks/types/update_webhook_dto.rb +17 -0
  134. data/lib/Berrycrawl.rb +130 -0
  135. data/reference.md +1759 -0
  136. metadata +179 -0
@@ -0,0 +1,268 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Berrycrawl
4
+ class Client
5
+ # @param request_options [Hash]
6
+ # @param params [Berrycrawl::Types::CrawlDto]
7
+ # @option request_options [String] :base_url
8
+ # @option request_options [Hash{String => Object}] :additional_headers
9
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
10
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
11
+ # @option request_options [Integer] :timeout_in_seconds
12
+ #
13
+ # @return [Berrycrawl::Types::JobCreatedResponse]
14
+ def crawl(request_options: {}, **params)
15
+ params = Berrycrawl::Internal::Types::Utils.normalize_keys(params)
16
+ request = Berrycrawl::Internal::JSON::Request.new(
17
+ base_url: request_options[:base_url],
18
+ method: "POST",
19
+ path: "crawl",
20
+ body: Berrycrawl::Types::CrawlDto.new(params).to_h,
21
+ request_options: request_options
22
+ )
23
+ begin
24
+ response = @client.send(request)
25
+ rescue Net::HTTPRequestTimeout
26
+ raise Berrycrawl::Errors::TimeoutError
27
+ end
28
+ code = response.code.to_i
29
+ if code.between?(200, 299)
30
+ Berrycrawl::Types::JobCreatedResponse.load(response.body)
31
+ else
32
+ error_class = Berrycrawl::Errors::ResponseError.subclass_for_code(code)
33
+ raise error_class.new(response.body, code: code)
34
+ end
35
+ end
36
+
37
+ # @param request_options [Hash]
38
+ # @param params [Berrycrawl::Types::ExtractDto]
39
+ # @option request_options [String] :base_url
40
+ # @option request_options [Hash{String => Object}] :additional_headers
41
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
42
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
43
+ # @option request_options [Integer] :timeout_in_seconds
44
+ #
45
+ # @return [Berrycrawl::Types::JobCreatedResponse]
46
+ def extract(request_options: {}, **params)
47
+ params = Berrycrawl::Internal::Types::Utils.normalize_keys(params)
48
+ request = Berrycrawl::Internal::JSON::Request.new(
49
+ base_url: request_options[:base_url],
50
+ method: "POST",
51
+ path: "extract",
52
+ body: Berrycrawl::Types::ExtractDto.new(params).to_h,
53
+ request_options: request_options
54
+ )
55
+ begin
56
+ response = @client.send(request)
57
+ rescue Net::HTTPRequestTimeout
58
+ raise Berrycrawl::Errors::TimeoutError
59
+ end
60
+ code = response.code.to_i
61
+ if code.between?(200, 299)
62
+ Berrycrawl::Types::JobCreatedResponse.load(response.body)
63
+ else
64
+ error_class = Berrycrawl::Errors::ResponseError.subclass_for_code(code)
65
+ raise error_class.new(response.body, code: code)
66
+ end
67
+ end
68
+
69
+ # @param request_options [Hash]
70
+ # @param params [Berrycrawl::Types::MapDto]
71
+ # @option request_options [String] :base_url
72
+ # @option request_options [Hash{String => Object}] :additional_headers
73
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
74
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
75
+ # @option request_options [Integer] :timeout_in_seconds
76
+ #
77
+ # @return [Berrycrawl::Types::MapResponse]
78
+ def map(request_options: {}, **params)
79
+ params = Berrycrawl::Internal::Types::Utils.normalize_keys(params)
80
+ request = Berrycrawl::Internal::JSON::Request.new(
81
+ base_url: request_options[:base_url],
82
+ method: "POST",
83
+ path: "map",
84
+ body: Berrycrawl::Types::MapDto.new(params).to_h,
85
+ request_options: request_options
86
+ )
87
+ begin
88
+ response = @client.send(request)
89
+ rescue Net::HTTPRequestTimeout
90
+ raise Berrycrawl::Errors::TimeoutError
91
+ end
92
+ code = response.code.to_i
93
+ if code.between?(200, 299)
94
+ Berrycrawl::Types::MapResponse.load(response.body)
95
+ else
96
+ error_class = Berrycrawl::Errors::ResponseError.subclass_for_code(code)
97
+ raise error_class.new(response.body, code: code)
98
+ end
99
+ end
100
+
101
+ # @param request_options [Hash]
102
+ # @param params [Berrycrawl::Types::ParseDto]
103
+ # @option request_options [String] :base_url
104
+ # @option request_options [Hash{String => Object}] :additional_headers
105
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
106
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
107
+ # @option request_options [Integer] :timeout_in_seconds
108
+ #
109
+ # @return [Berrycrawl::Types::ScrapeResponse]
110
+ def parse(request_options: {}, **params)
111
+ params = Berrycrawl::Internal::Types::Utils.normalize_keys(params)
112
+ request = Berrycrawl::Internal::JSON::Request.new(
113
+ base_url: request_options[:base_url],
114
+ method: "POST",
115
+ path: "parse",
116
+ body: Berrycrawl::Types::ParseDto.new(params).to_h,
117
+ request_options: request_options
118
+ )
119
+ begin
120
+ response = @client.send(request)
121
+ rescue Net::HTTPRequestTimeout
122
+ raise Berrycrawl::Errors::TimeoutError
123
+ end
124
+ code = response.code.to_i
125
+ if code.between?(200, 299)
126
+ Berrycrawl::Types::ScrapeResponse.load(response.body)
127
+ else
128
+ error_class = Berrycrawl::Errors::ResponseError.subclass_for_code(code)
129
+ raise error_class.new(response.body, code: code)
130
+ end
131
+ end
132
+
133
+ # @param request_options [Hash]
134
+ # @param params [Berrycrawl::Types::ScrapeDto]
135
+ # @option request_options [String] :base_url
136
+ # @option request_options [Hash{String => Object}] :additional_headers
137
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
138
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
139
+ # @option request_options [Integer] :timeout_in_seconds
140
+ #
141
+ # @return [Berrycrawl::Types::ScrapeResponse]
142
+ def scrape(request_options: {}, **params)
143
+ params = Berrycrawl::Internal::Types::Utils.normalize_keys(params)
144
+ request = Berrycrawl::Internal::JSON::Request.new(
145
+ base_url: request_options[:base_url],
146
+ method: "POST",
147
+ path: "scrape",
148
+ body: Berrycrawl::Types::ScrapeDto.new(params).to_h,
149
+ request_options: request_options
150
+ )
151
+ begin
152
+ response = @client.send(request)
153
+ rescue Net::HTTPRequestTimeout
154
+ raise Berrycrawl::Errors::TimeoutError
155
+ end
156
+ code = response.code.to_i
157
+ if code.between?(200, 299)
158
+ Berrycrawl::Types::ScrapeResponse.load(response.body)
159
+ else
160
+ error_class = Berrycrawl::Errors::ResponseError.subclass_for_code(code)
161
+ raise error_class.new(response.body, code: code)
162
+ end
163
+ end
164
+
165
+ # Cookie banners, blocking overlays, chat widgets, and lazy loading are handled by default. Every cleanup pass can
166
+ # be controlled per request.
167
+ #
168
+ # @param request_options [Hash]
169
+ # @param params [Berrycrawl::Types::ScreenshotDto]
170
+ # @option request_options [String] :base_url
171
+ # @option request_options [Hash{String => Object}] :additional_headers
172
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
173
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
174
+ # @option request_options [Integer] :timeout_in_seconds
175
+ #
176
+ # @return [Berrycrawl::Types::ScrapeResponse]
177
+ def screenshot(request_options: {}, **params)
178
+ params = Berrycrawl::Internal::Types::Utils.normalize_keys(params)
179
+ request = Berrycrawl::Internal::JSON::Request.new(
180
+ base_url: request_options[:base_url],
181
+ method: "POST",
182
+ path: "screenshot",
183
+ body: Berrycrawl::Types::ScreenshotDto.new(params).to_h,
184
+ request_options: request_options
185
+ )
186
+ begin
187
+ response = @client.send(request)
188
+ rescue Net::HTTPRequestTimeout
189
+ raise Berrycrawl::Errors::TimeoutError
190
+ end
191
+ code = response.code.to_i
192
+ if code.between?(200, 299)
193
+ Berrycrawl::Types::ScrapeResponse.load(response.body)
194
+ else
195
+ error_class = Berrycrawl::Errors::ResponseError.subclass_for_code(code)
196
+ raise error_class.new(response.body, code: code)
197
+ end
198
+ end
199
+
200
+ # @param request_options [Hash]
201
+ # @param params [Berrycrawl::Types::SearchDto]
202
+ # @option request_options [String] :base_url
203
+ # @option request_options [Hash{String => Object}] :additional_headers
204
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
205
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
206
+ # @option request_options [Integer] :timeout_in_seconds
207
+ #
208
+ # @return [Berrycrawl::Types::SearchResponse]
209
+ def search(request_options: {}, **params)
210
+ params = Berrycrawl::Internal::Types::Utils.normalize_keys(params)
211
+ request = Berrycrawl::Internal::JSON::Request.new(
212
+ base_url: request_options[:base_url],
213
+ method: "POST",
214
+ path: "search",
215
+ body: Berrycrawl::Types::SearchDto.new(params).to_h,
216
+ request_options: request_options
217
+ )
218
+ begin
219
+ response = @client.send(request)
220
+ rescue Net::HTTPRequestTimeout
221
+ raise Berrycrawl::Errors::TimeoutError
222
+ end
223
+ code = response.code.to_i
224
+ if code.between?(200, 299)
225
+ Berrycrawl::Types::SearchResponse.load(response.body)
226
+ else
227
+ error_class = Berrycrawl::Errors::ResponseError.subclass_for_code(code)
228
+ raise error_class.new(response.body, code: code)
229
+ end
230
+ end
231
+
232
+ # @param base_url [String, nil]
233
+ # @param token [String]
234
+ # @param max_retries [Integer]
235
+ #
236
+ # @return [void]
237
+ def initialize(base_url: nil, token: ENV.fetch("BERRYCRAWL_API_KEY", nil), max_retries: 2)
238
+ @raw_client = Berrycrawl::Internal::Http::RawClient.new(
239
+ base_url: base_url || Berrycrawl::Environment::PRODUCTION,
240
+ headers: {
241
+ "X-Fern-Language" => "Ruby",
242
+ Authorization: "Bearer #{token}"
243
+ },
244
+ max_retries: max_retries
245
+ )
246
+ end
247
+
248
+ # @return [Berrycrawl::Account::Client]
249
+ def account
250
+ @account ||= Berrycrawl::Account::Client.new(client: @raw_client)
251
+ end
252
+
253
+ # @return [Berrycrawl::Brand::Client]
254
+ def brand
255
+ @brand ||= Berrycrawl::Brand::Client.new(client: @raw_client)
256
+ end
257
+
258
+ # @return [Berrycrawl::Jobs::Client]
259
+ def jobs
260
+ @jobs ||= Berrycrawl::Jobs::Client.new(client: @raw_client)
261
+ end
262
+
263
+ # @return [Berrycrawl::Webhooks::Client]
264
+ def webhooks
265
+ @webhooks ||= Berrycrawl::Webhooks::Client.new(client: @raw_client)
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Berrycrawl
4
+ class Environment
5
+ PRODUCTION = "https://api.berrycrawl.com/api/v1"
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Berrycrawl
4
+ module Errors
5
+ class ApiError < StandardError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Berrycrawl
4
+ module Errors
5
+ class ClientError < ResponseError
6
+ end
7
+
8
+ class UnauthorizedError < ClientError
9
+ end
10
+
11
+ class ForbiddenError < ClientError
12
+ end
13
+
14
+ class NotFoundError < ClientError
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Berrycrawl
4
+ module Errors
5
+ class RedirectError < ResponseError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Berrycrawl
4
+ module Errors
5
+ class ResponseError < ApiError
6
+ attr_reader :code
7
+
8
+ def initialize(msg, code:)
9
+ @code = code
10
+ super(msg)
11
+ end
12
+
13
+ def inspect
14
+ "#<#{self.class.name} @code=#{code} @body=#{message}>"
15
+ end
16
+
17
+ # Returns the most appropriate error class for the given code.
18
+ #
19
+ # @return [Class]
20
+ def self.subclass_for_code(code)
21
+ case code
22
+ when 300..399
23
+ RedirectError
24
+ when 401
25
+ UnauthorizedError
26
+ when 403
27
+ ForbiddenError
28
+ when 404
29
+ NotFoundError
30
+ when 400..499
31
+ ClientError
32
+ when 503
33
+ ServiceUnavailableError
34
+ when 500..599
35
+ ServerError
36
+ else
37
+ ResponseError
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Berrycrawl
4
+ module Errors
5
+ class ServerError < ResponseError
6
+ end
7
+
8
+ class ServiceUnavailableError < ApiError
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Berrycrawl
4
+ module Errors
5
+ class TimeoutError < ApiError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Berrycrawl
4
+ module Internal
5
+ module Errors
6
+ class ConstraintError < StandardError
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Berrycrawl
4
+ module Internal
5
+ module Errors
6
+ class TypeError < StandardError
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Berrycrawl
4
+ module Internal
5
+ module Http
6
+ # @api private
7
+ class BaseRequest
8
+ attr_reader :base_url, :path, :method, :headers, :query, :request_options
9
+
10
+ # @param base_url [String] The base URL for the request
11
+ # @param path [String] The path for the request
12
+ # @param method [String] The HTTP method for the request (:get, :post, etc.)
13
+ # @param headers [Hash] Additional headers for the request (optional)
14
+ # @param query [Hash] Query parameters for the request (optional)
15
+ # @param request_options [Berrycrawl::RequestOptions, Hash{Symbol=>Object}, nil]
16
+ def initialize(base_url:, path:, method:, headers: {}, query: {}, request_options: {})
17
+ @base_url = base_url
18
+ @path = path
19
+ @method = method
20
+ @headers = headers
21
+ @query = query
22
+ @request_options = request_options
23
+ end
24
+
25
+ # @return [Hash] The query parameters merged with additional query parameters from request options.
26
+ def encode_query
27
+ additional_query = @request_options&.dig(:additional_query_parameters) || @request_options&.dig("additional_query_parameters") || {}
28
+ @query.merge(additional_query)
29
+ end
30
+
31
+ # Child classes should implement:
32
+ # - encode_headers: Returns the encoded HTTP request headers.
33
+ # - encode_body: Returns the encoded HTTP request body.
34
+
35
+ private
36
+
37
+ # Merges additional_headers from request_options into sdk_headers, filtering out
38
+ # any keys that collide with SDK-set or client-protected headers (case-insensitive).
39
+ # @param sdk_headers [Hash] Headers set by the SDK for this request type.
40
+ # @param protected_keys [Array<String>] Additional header keys that must not be overridden.
41
+ # @return [Hash] The merged headers.
42
+ def merge_additional_headers(sdk_headers, protected_keys: [])
43
+ additional_headers = @request_options&.dig(:additional_headers) || @request_options&.dig("additional_headers") || {}
44
+ all_protected = (sdk_headers.keys + protected_keys).to_set { |k| k.to_s.downcase }
45
+ filtered = additional_headers.reject { |key, _| all_protected.include?(key.to_s.downcase) }
46
+ sdk_headers.merge(filtered)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end