brand.dev 0.5.0 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c9b8a81df466bce38f7b002c56275419af4bb2aeb616c1283db6f796f4a10599
4
- data.tar.gz: 280fc8c7f29abc5fb6afbc5e8a7f506bfd1f7f404471ed1caa3989842ed7021d
3
+ metadata.gz: f50feda932f54681e729abf32d227a1d656a0361750ea41e5ea71443d70a0a93
4
+ data.tar.gz: 315072b49cec6b6f60f68e863c0edbcda4862a24fdbd10530f405a70c6415f56
5
5
  SHA512:
6
- metadata.gz: d9978b7e21668705ea2c2a3cf90f58363ebdd131e1b554a0bcb489e7656375ff7b3b51405540441d0de3f7bc1a9c41667ff54034a75ef780174e4bb48420d3b7
7
- data.tar.gz: 0cdeef945be5f1957fe94861c2aeba966f1c98c2e073c41ad46738e61fa1fa64e5e381132e2251e3f99cf7b288c447ecffe30fac5045c303738d8b6c0aec0ba4
6
+ metadata.gz: ebf3e3c91166e69f34ab3e0fba78df2b579bebb323d3a8d5591ad871ab11a16f071d78f5af44912093d8e6a78d02d9077a5f09dd2091d53473cdd36f992322f7
7
+ data.tar.gz: c1d51e7e7d3dec11a1c46995b8d9277d68502b590900f16377a9f1a5e3e180db2e66e07c35971c178604f8aead837434b608661aa53b33eedf0143e8ddde5b13
data/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.0 (2025-09-27)
4
+
5
+ Full Changelog: [v0.6.0...v0.7.0](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.6.0...v0.7.0)
6
+
7
+ ### Features
8
+
9
+ * **api:** api update ([1e777a7](https://github.com/brand-dot-dev/ruby-sdk/commit/1e777a71af3ff2e5f0cad6223d05bfcc183fc2fd))
10
+ * expose response headers for both streams and errors ([569c645](https://github.com/brand-dot-dev/ruby-sdk/commit/569c645d77a1432570f2d47ac33c4b30197be2ef))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * shorten multipart boundary sep to less than RFC specificed max length ([a2e1171](https://github.com/brand-dot-dev/ruby-sdk/commit/a2e11713038013930d3b5b44d4665326e7bafece))
16
+
17
+
18
+ ### Performance Improvements
19
+
20
+ * faster code formatting ([d65a43b](https://github.com/brand-dot-dev/ruby-sdk/commit/d65a43b02c1ebe517f7119c984a540e435fc2a03))
21
+
22
+
23
+ ### Chores
24
+
25
+ * allow fast-format to use bsd sed as well ([88e0856](https://github.com/brand-dot-dev/ruby-sdk/commit/88e0856c917a0bb60e062fafe6a04753c8fb8059))
26
+ * do not install brew dependencies in ./scripts/bootstrap by default ([d067d3a](https://github.com/brand-dot-dev/ruby-sdk/commit/d067d3a622289a081516f2565b3bbd420586e8ac))
27
+ * **internal:** codegen related update ([2629fa5](https://github.com/brand-dot-dev/ruby-sdk/commit/2629fa5004386cd943bbba2da8635b10593fcdca))
28
+
29
+ ## 0.6.0 (2025-09-14)
30
+
31
+ Full Changelog: [v0.5.0...v0.6.0](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.5.0...v0.6.0)
32
+
33
+ ### Features
34
+
35
+ * **api:** api update ([f3a2056](https://github.com/brand-dot-dev/ruby-sdk/commit/f3a205642cd53962780b1789830c1d99665bb1b0))
36
+
3
37
  ## 0.5.0 (2025-09-07)
4
38
 
5
39
  Full Changelog: [v0.4.0...v0.5.0](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.4.0...v0.5.0)
data/README.md CHANGED
@@ -17,7 +17,7 @@ To use this gem, install via Bundler by adding the following to your application
17
17
  <!-- x-release-please-start-version -->
18
18
 
19
19
  ```ruby
20
- gem "brand.dev", "~> 0.5.0"
20
+ gem "brand.dev", "~> 0.7.0"
21
21
  ```
22
22
 
23
23
  <!-- x-release-please-end -->
@@ -40,6 +40,9 @@ module BrandDev
40
40
  # @return [Integer, nil]
41
41
  attr_accessor :status
42
42
 
43
+ # @return [Hash{String=>String}, nil]
44
+ attr_accessor :headers
45
+
43
46
  # @return [Object, nil]
44
47
  attr_accessor :body
45
48
 
@@ -47,13 +50,15 @@ module BrandDev
47
50
  #
48
51
  # @param url [URI::Generic]
49
52
  # @param status [Integer, nil]
53
+ # @param headers [Hash{String=>String}, nil]
50
54
  # @param body [Object, nil]
51
55
  # @param request [nil]
52
56
  # @param response [nil]
53
57
  # @param message [String, nil]
54
- def initialize(url:, status: nil, body: nil, request: nil, response: nil, message: nil)
58
+ def initialize(url:, status: nil, headers: nil, body: nil, request: nil, response: nil, message: nil)
55
59
  @url = url
56
60
  @status = status
61
+ @headers = headers
57
62
  @body = body
58
63
  @request = request
59
64
  @response = response
@@ -74,6 +79,7 @@ module BrandDev
74
79
  #
75
80
  # @param url [URI::Generic]
76
81
  # @param status [nil]
82
+ # @param headers [Hash{String=>String}, nil]
77
83
  # @param body [nil]
78
84
  # @param request [nil]
79
85
  # @param response [nil]
@@ -81,6 +87,7 @@ module BrandDev
81
87
  def initialize(
82
88
  url:,
83
89
  status: nil,
90
+ headers: nil,
84
91
  body: nil,
85
92
  request: nil,
86
93
  response: nil,
@@ -95,6 +102,7 @@ module BrandDev
95
102
  #
96
103
  # @param url [URI::Generic]
97
104
  # @param status [nil]
105
+ # @param headers [Hash{String=>String}, nil]
98
106
  # @param body [nil]
99
107
  # @param request [nil]
100
108
  # @param response [nil]
@@ -102,6 +110,7 @@ module BrandDev
102
110
  def initialize(
103
111
  url:,
104
112
  status: nil,
113
+ headers: nil,
105
114
  body: nil,
106
115
  request: nil,
107
116
  response: nil,
@@ -116,21 +125,24 @@ module BrandDev
116
125
  #
117
126
  # @param url [URI::Generic]
118
127
  # @param status [Integer]
128
+ # @param headers [Hash{String=>String}, nil]
119
129
  # @param body [Object, nil]
120
130
  # @param request [nil]
121
131
  # @param response [nil]
122
132
  # @param message [String, nil]
123
133
  #
124
134
  # @return [self]
125
- def self.for(url:, status:, body:, request:, response:, message: nil)
126
- kwargs = {
127
- url: url,
128
- status: status,
129
- body: body,
130
- request: request,
131
- response: response,
132
- message: message
133
- }
135
+ def self.for(url:, status:, headers:, body:, request:, response:, message: nil)
136
+ kwargs =
137
+ {
138
+ url: url,
139
+ status: status,
140
+ headers: headers,
141
+ body: body,
142
+ request: request,
143
+ response: response,
144
+ message: message
145
+ }
134
146
 
135
147
  case status
136
148
  in 400
@@ -162,15 +174,17 @@ module BrandDev
162
174
  #
163
175
  # @param url [URI::Generic]
164
176
  # @param status [Integer]
177
+ # @param headers [Hash{String=>String}, nil]
165
178
  # @param body [Object, nil]
166
179
  # @param request [nil]
167
180
  # @param response [nil]
168
181
  # @param message [String, nil]
169
- def initialize(url:, status:, body:, request:, response:, message: nil)
182
+ def initialize(url:, status:, headers:, body:, request:, response:, message: nil)
170
183
  message ||= {url: url.to_s, status: status, body: body}
171
184
  super(
172
185
  url: url,
173
186
  status: status,
187
+ headers: headers,
174
188
  body: body,
175
189
  request: request,
176
190
  response: response,
@@ -47,7 +47,7 @@ module BrandDev
47
47
  # @api private
48
48
  #
49
49
  # @param status [Integer]
50
- # @param headers [Hash{String=>String}, Net::HTTPHeader]
50
+ # @param headers [Hash{String=>String}]
51
51
  #
52
52
  # @return [Boolean]
53
53
  def should_retry?(status, headers:)
@@ -85,7 +85,7 @@ module BrandDev
85
85
  #
86
86
  # @param status [Integer]
87
87
  #
88
- # @param response_headers [Hash{String=>String}, Net::HTTPHeader]
88
+ # @param response_headers [Hash{String=>String}]
89
89
  #
90
90
  # @return [Hash{Symbol=>Object}]
91
91
  def follow_redirect(request, status:, response_headers:)
@@ -378,6 +378,7 @@ module BrandDev
378
378
  rescue BrandDev::Errors::APIConnectionError => e
379
379
  status = e
380
380
  end
381
+ headers = BrandDev::Internal::Util.normalized_headers(response&.each_header&.to_h)
381
382
 
382
383
  case status
383
384
  in ..299
@@ -390,7 +391,7 @@ module BrandDev
390
391
  in 300..399
391
392
  self.class.reap_connection!(status, stream: stream)
392
393
 
393
- request = self.class.follow_redirect(request, status: status, response_headers: response)
394
+ request = self.class.follow_redirect(request, status: status, response_headers: headers)
394
395
  send_request(
395
396
  request,
396
397
  redirect_count: redirect_count + 1,
@@ -399,9 +400,9 @@ module BrandDev
399
400
  )
400
401
  in BrandDev::Errors::APIConnectionError if retry_count >= max_retries
401
402
  raise status
402
- in (400..) if retry_count >= max_retries || !self.class.should_retry?(status, headers: response)
403
+ in (400..) if retry_count >= max_retries || !self.class.should_retry?(status, headers: headers)
403
404
  decoded = Kernel.then do
404
- BrandDev::Internal::Util.decode_content(response, stream: stream, suppress_error: true)
405
+ BrandDev::Internal::Util.decode_content(headers, stream: stream, suppress_error: true)
405
406
  ensure
406
407
  self.class.reap_connection!(status, stream: stream)
407
408
  end
@@ -409,6 +410,7 @@ module BrandDev
409
410
  raise BrandDev::Errors::APIStatusError.for(
410
411
  url: url,
411
412
  status: status,
413
+ headers: headers,
412
414
  body: decoded,
413
415
  request: nil,
414
416
  response: response
@@ -485,19 +487,21 @@ module BrandDev
485
487
  send_retry_header: send_retry_header
486
488
  )
487
489
 
488
- decoded = BrandDev::Internal::Util.decode_content(response, stream: stream)
490
+ headers = BrandDev::Internal::Util.normalized_headers(response.each_header.to_h)
491
+ decoded = BrandDev::Internal::Util.decode_content(headers, stream: stream)
489
492
  case req
490
493
  in {stream: Class => st}
491
494
  st.new(
492
495
  model: model,
493
496
  url: url,
494
497
  status: status,
498
+ headers: headers,
495
499
  response: response,
496
500
  unwrap: unwrap,
497
501
  stream: decoded
498
502
  )
499
503
  in {page: Class => page}
500
- page.new(client: self, req: req, headers: response, page_data: decoded)
504
+ page.new(client: self, req: req, headers: headers, page_data: decoded)
501
505
  else
502
506
  unwrapped = BrandDev::Internal::Util.dig(decoded, unwrap)
503
507
  BrandDev::Internal::Type::Converter.coerce(model, unwrapped)
@@ -39,7 +39,7 @@ module BrandDev
39
39
  #
40
40
  # @param client [BrandDev::Internal::Transport::BaseClient]
41
41
  # @param req [Hash{Symbol=>Object}]
42
- # @param headers [Hash{String=>String}, Net::HTTPHeader]
42
+ # @param headers [Hash{String=>String}]
43
43
  # @param page_data [Object]
44
44
  def initialize(client:, req:, headers:, page_data:)
45
45
  @client = client
@@ -566,7 +566,8 @@ module BrandDev
566
566
  #
567
567
  # @return [Array(String, Enumerable<String>)]
568
568
  private def encode_multipart_streaming(body)
569
- boundary = SecureRandom.urlsafe_base64(60)
569
+ # RFC 1521 Section 7.2.1 says we should have 70 char maximum for boundary length
570
+ boundary = SecureRandom.urlsafe_base64(46)
570
571
 
571
572
  closing = []
572
573
  strio = writable_enum do |y|
@@ -647,7 +648,7 @@ module BrandDev
647
648
  #
648
649
  # Assumes each chunk in stream has `Encoding::BINARY`.
649
650
  #
650
- # @param headers [Hash{String=>String}, Net::HTTPHeader]
651
+ # @param headers [Hash{String=>String}]
651
652
  # @param stream [Enumerable<String>]
652
653
  # @param suppress_error [Boolean]
653
654
  #
@@ -22,7 +22,24 @@ module BrandDev
22
22
  # @return [Symbol, BrandDev::Models::BrandScreenshotParams::FullScreenshot, nil]
23
23
  optional :full_screenshot, enum: -> { BrandDev::BrandScreenshotParams::FullScreenshot }
24
24
 
25
- # @!method initialize(domain:, full_screenshot: nil, request_options: {})
25
+ # @!attribute page
26
+ # Optional parameter to specify which page type to screenshot. If provided, the
27
+ # system will scrape the domain's links and use heuristics to find the most
28
+ # appropriate URL for the specified page type (30 supported languages). If not
29
+ # provided, screenshots the main domain landing page.
30
+ #
31
+ # @return [Symbol, BrandDev::Models::BrandScreenshotParams::Page, nil]
32
+ optional :page, enum: -> { BrandDev::BrandScreenshotParams::Page }
33
+
34
+ # @!attribute prioritize
35
+ # Optional parameter to prioritize screenshot capture. If 'speed', optimizes for
36
+ # faster capture with basic quality. If 'quality', optimizes for higher quality
37
+ # with longer wait times. Defaults to 'quality' if not provided.
38
+ #
39
+ # @return [Symbol, BrandDev::Models::BrandScreenshotParams::Prioritize, nil]
40
+ optional :prioritize, enum: -> { BrandDev::BrandScreenshotParams::Prioritize }
41
+
42
+ # @!method initialize(domain:, full_screenshot: nil, page: nil, prioritize: nil, request_options: {})
26
43
  # Some parameter documentations has been truncated, see
27
44
  # {BrandDev::Models::BrandScreenshotParams} for more details.
28
45
  #
@@ -30,6 +47,10 @@ module BrandDev
30
47
  #
31
48
  # @param full_screenshot [Symbol, BrandDev::Models::BrandScreenshotParams::FullScreenshot] Optional parameter to determine screenshot type. If 'true', takes a full page sc
32
49
  #
50
+ # @param page [Symbol, BrandDev::Models::BrandScreenshotParams::Page] Optional parameter to specify which page type to screenshot. If provided, the sy
51
+ #
52
+ # @param prioritize [Symbol, BrandDev::Models::BrandScreenshotParams::Prioritize] Optional parameter to prioritize screenshot capture. If 'speed', optimizes for f
53
+ #
33
54
  # @param request_options [BrandDev::RequestOptions, Hash{Symbol=>Object}]
34
55
 
35
56
  # Optional parameter to determine screenshot type. If 'true', takes a full page
@@ -44,6 +65,39 @@ module BrandDev
44
65
  # @!method self.values
45
66
  # @return [Array<Symbol>]
46
67
  end
68
+
69
+ # Optional parameter to specify which page type to screenshot. If provided, the
70
+ # system will scrape the domain's links and use heuristics to find the most
71
+ # appropriate URL for the specified page type (30 supported languages). If not
72
+ # provided, screenshots the main domain landing page.
73
+ module Page
74
+ extend BrandDev::Internal::Type::Enum
75
+
76
+ LOGIN = :login
77
+ SIGNUP = :signup
78
+ BLOG = :blog
79
+ CAREERS = :careers
80
+ PRICING = :pricing
81
+ TERMS = :terms
82
+ PRIVACY = :privacy
83
+ CONTACT = :contact
84
+
85
+ # @!method self.values
86
+ # @return [Array<Symbol>]
87
+ end
88
+
89
+ # Optional parameter to prioritize screenshot capture. If 'speed', optimizes for
90
+ # faster capture with basic quality. If 'quality', optimizes for higher quality
91
+ # with longer wait times. Defaults to 'quality' if not provided.
92
+ module Prioritize
93
+ extend BrandDev::Internal::Type::Enum
94
+
95
+ SPEED = :speed
96
+ QUALITY = :quality
97
+
98
+ # @!method self.values
99
+ # @return [Array<Symbol>]
100
+ end
47
101
  end
48
102
  end
49
103
  end
@@ -14,6 +14,15 @@ module BrandDev
14
14
  # @return [String]
15
15
  required :domain, String
16
16
 
17
+ # @!attribute prioritize
18
+ # Optional parameter to prioritize screenshot capture for styleguide extraction.
19
+ # If 'speed', optimizes for faster capture with basic quality. If 'quality',
20
+ # optimizes for higher quality with longer wait times. Defaults to 'quality' if
21
+ # not provided.
22
+ #
23
+ # @return [Symbol, BrandDev::Models::BrandStyleguideParams::Prioritize, nil]
24
+ optional :prioritize, enum: -> { BrandDev::BrandStyleguideParams::Prioritize }
25
+
17
26
  # @!attribute timeout_ms
18
27
  # Optional timeout in milliseconds for the request. If the request takes longer
19
28
  # than this value, it will be aborted with a 408 status code. Maximum allowed
@@ -22,15 +31,31 @@ module BrandDev
22
31
  # @return [Integer, nil]
23
32
  optional :timeout_ms, Integer
24
33
 
25
- # @!method initialize(domain:, timeout_ms: nil, request_options: {})
34
+ # @!method initialize(domain:, prioritize: nil, timeout_ms: nil, request_options: {})
26
35
  # Some parameter documentations has been truncated, see
27
36
  # {BrandDev::Models::BrandStyleguideParams} for more details.
28
37
  #
29
38
  # @param domain [String] Domain name to extract styleguide from (e.g., 'example.com', 'google.com'). The
30
39
  #
40
+ # @param prioritize [Symbol, BrandDev::Models::BrandStyleguideParams::Prioritize] Optional parameter to prioritize screenshot capture for styleguide extraction. I
41
+ #
31
42
  # @param timeout_ms [Integer] Optional timeout in milliseconds for the request. If the request takes longer th
32
43
  #
33
44
  # @param request_options [BrandDev::RequestOptions, Hash{Symbol=>Object}]
45
+
46
+ # Optional parameter to prioritize screenshot capture for styleguide extraction.
47
+ # If 'speed', optimizes for faster capture with basic quality. If 'quality',
48
+ # optimizes for higher quality with longer wait times. Defaults to 'quality' if
49
+ # not provided.
50
+ module Prioritize
51
+ extend BrandDev::Internal::Type::Enum
52
+
53
+ SPEED = :speed
54
+ QUALITY = :quality
55
+
56
+ # @!method self.values
57
+ # @return [Array<Symbol>]
58
+ end
34
59
  end
35
60
  end
36
61
  end
@@ -190,15 +190,20 @@ module BrandDev
190
190
  # {BrandDev::Models::BrandScreenshotParams} for more details.
191
191
  #
192
192
  # Beta feature: Capture a screenshot of a website. Supports both viewport
193
- # (standard browser view) and full-page screenshots. Returns a URL to the uploaded
194
- # screenshot image hosted on our CDN.
193
+ # (standard browser view) and full-page screenshots. Can also screenshot specific
194
+ # page types (login, pricing, etc.) by using heuristics to find the appropriate
195
+ # URL. Returns a URL to the uploaded screenshot image hosted on our CDN.
195
196
  #
196
- # @overload screenshot(domain:, full_screenshot: nil, request_options: {})
197
+ # @overload screenshot(domain:, full_screenshot: nil, page: nil, prioritize: nil, request_options: {})
197
198
  #
198
199
  # @param domain [String] Domain name to take screenshot of (e.g., 'example.com', 'google.com'). The domai
199
200
  #
200
201
  # @param full_screenshot [Symbol, BrandDev::Models::BrandScreenshotParams::FullScreenshot] Optional parameter to determine screenshot type. If 'true', takes a full page sc
201
202
  #
203
+ # @param page [Symbol, BrandDev::Models::BrandScreenshotParams::Page] Optional parameter to specify which page type to screenshot. If provided, the sy
204
+ #
205
+ # @param prioritize [Symbol, BrandDev::Models::BrandScreenshotParams::Prioritize] Optional parameter to prioritize screenshot capture. If 'speed', optimizes for f
206
+ #
202
207
  # @param request_options [BrandDev::RequestOptions, Hash{Symbol=>Object}, nil]
203
208
  #
204
209
  # @return [BrandDev::Models::BrandScreenshotResponse]
@@ -222,10 +227,12 @@ module BrandDev
222
227
  # a brand's website including colors, typography, spacing, shadows, and UI
223
228
  # components.
224
229
  #
225
- # @overload styleguide(domain:, timeout_ms: nil, request_options: {})
230
+ # @overload styleguide(domain:, prioritize: nil, timeout_ms: nil, request_options: {})
226
231
  #
227
232
  # @param domain [String] Domain name to extract styleguide from (e.g., 'example.com', 'google.com'). The
228
233
  #
234
+ # @param prioritize [Symbol, BrandDev::Models::BrandStyleguideParams::Prioritize] Optional parameter to prioritize screenshot capture for styleguide extraction. I
235
+ #
229
236
  # @param timeout_ms [Integer] Optional timeout in milliseconds for the request. If the request takes longer th
230
237
  #
231
238
  # @param request_options [BrandDev::RequestOptions, Hash{Symbol=>Object}, nil]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BrandDev
4
- VERSION = "0.5.0"
4
+ VERSION = "0.7.0"
5
5
  end
@@ -33,6 +33,9 @@ module BrandDev
33
33
  sig { returns(T.nilable(Integer)) }
34
34
  attr_accessor :status
35
35
 
36
+ sig { returns(T.nilable(T::Hash[String, String])) }
37
+ attr_accessor :headers
38
+
36
39
  sig { returns(T.nilable(T.anything)) }
37
40
  attr_accessor :body
38
41
 
@@ -41,6 +44,7 @@ module BrandDev
41
44
  params(
42
45
  url: URI::Generic,
43
46
  status: T.nilable(Integer),
47
+ headers: T.nilable(T::Hash[String, String]),
44
48
  body: T.nilable(Object),
45
49
  request: NilClass,
46
50
  response: NilClass,
@@ -50,6 +54,7 @@ module BrandDev
50
54
  def self.new(
51
55
  url:,
52
56
  status: nil,
57
+ headers: nil,
53
58
  body: nil,
54
59
  request: nil,
55
60
  response: nil,
@@ -70,6 +75,7 @@ module BrandDev
70
75
  params(
71
76
  url: URI::Generic,
72
77
  status: NilClass,
78
+ headers: T.nilable(T::Hash[String, String]),
73
79
  body: NilClass,
74
80
  request: NilClass,
75
81
  response: NilClass,
@@ -79,6 +85,7 @@ module BrandDev
79
85
  def self.new(
80
86
  url:,
81
87
  status: nil,
88
+ headers: nil,
82
89
  body: nil,
83
90
  request: nil,
84
91
  response: nil,
@@ -93,6 +100,7 @@ module BrandDev
93
100
  params(
94
101
  url: URI::Generic,
95
102
  status: NilClass,
103
+ headers: T.nilable(T::Hash[String, String]),
96
104
  body: NilClass,
97
105
  request: NilClass,
98
106
  response: NilClass,
@@ -102,6 +110,7 @@ module BrandDev
102
110
  def self.new(
103
111
  url:,
104
112
  status: nil,
113
+ headers: nil,
105
114
  body: nil,
106
115
  request: nil,
107
116
  response: nil,
@@ -116,13 +125,22 @@ module BrandDev
116
125
  params(
117
126
  url: URI::Generic,
118
127
  status: Integer,
128
+ headers: T.nilable(T::Hash[String, String]),
119
129
  body: T.nilable(Object),
120
130
  request: NilClass,
121
131
  response: NilClass,
122
132
  message: T.nilable(String)
123
133
  ).returns(T.attached_class)
124
134
  end
125
- def self.for(url:, status:, body:, request:, response:, message: nil)
135
+ def self.for(
136
+ url:,
137
+ status:,
138
+ headers:,
139
+ body:,
140
+ request:,
141
+ response:,
142
+ message: nil
143
+ )
126
144
  end
127
145
 
128
146
  sig { returns(Integer) }
@@ -133,13 +151,22 @@ module BrandDev
133
151
  params(
134
152
  url: URI::Generic,
135
153
  status: Integer,
154
+ headers: T.nilable(T::Hash[String, String]),
136
155
  body: T.nilable(Object),
137
156
  request: NilClass,
138
157
  response: NilClass,
139
158
  message: T.nilable(String)
140
159
  ).returns(T.attached_class)
141
160
  end
142
- def self.new(url:, status:, body:, request:, response:, message: nil)
161
+ def self.new(
162
+ url:,
163
+ status:,
164
+ headers:,
165
+ body:,
166
+ request:,
167
+ response:,
168
+ message: nil
169
+ )
143
170
  end
144
171
  end
145
172
 
@@ -84,10 +84,9 @@ module BrandDev
84
84
 
85
85
  # @api private
86
86
  sig do
87
- params(
88
- status: Integer,
89
- headers: T.any(T::Hash[String, String], Net::HTTPHeader)
90
- ).returns(T::Boolean)
87
+ params(status: Integer, headers: T::Hash[String, String]).returns(
88
+ T::Boolean
89
+ )
91
90
  end
92
91
  def should_retry?(status, headers:)
93
92
  end
@@ -97,7 +96,7 @@ module BrandDev
97
96
  params(
98
97
  request: BrandDev::Internal::Transport::BaseClient::RequestInput,
99
98
  status: Integer,
100
- response_headers: T.any(T::Hash[String, String], Net::HTTPHeader)
99
+ response_headers: T::Hash[String, String]
101
100
  ).returns(BrandDev::Internal::Transport::BaseClient::RequestInput)
102
101
  end
103
102
  def follow_redirect(request, status:, response_headers:)
@@ -30,7 +30,7 @@ module BrandDev
30
30
  params(
31
31
  client: BrandDev::Internal::Transport::BaseClient,
32
32
  req: BrandDev::Internal::Transport::BaseClient::RequestComponents,
33
- headers: T.any(T::Hash[String, String], Net::HTTPHeader),
33
+ headers: T::Hash[String, String],
34
34
  page_data: T.anything
35
35
  ).void
36
36
  end
@@ -361,7 +361,7 @@ module BrandDev
361
361
  # Assumes each chunk in stream has `Encoding::BINARY`.
362
362
  sig do
363
363
  params(
364
- headers: T.any(T::Hash[String, String], Net::HTTPHeader),
364
+ headers: T::Hash[String, String],
365
365
  stream: T::Enumerable[String],
366
366
  suppress_error: T::Boolean
367
367
  ).returns(T.anything)
@@ -34,11 +34,42 @@ module BrandDev
34
34
  end
35
35
  attr_writer :full_screenshot
36
36
 
37
+ # Optional parameter to specify which page type to screenshot. If provided, the
38
+ # system will scrape the domain's links and use heuristics to find the most
39
+ # appropriate URL for the specified page type (30 supported languages). If not
40
+ # provided, screenshots the main domain landing page.
41
+ sig do
42
+ returns(T.nilable(BrandDev::BrandScreenshotParams::Page::OrSymbol))
43
+ end
44
+ attr_reader :page
45
+
46
+ sig { params(page: BrandDev::BrandScreenshotParams::Page::OrSymbol).void }
47
+ attr_writer :page
48
+
49
+ # Optional parameter to prioritize screenshot capture. If 'speed', optimizes for
50
+ # faster capture with basic quality. If 'quality', optimizes for higher quality
51
+ # with longer wait times. Defaults to 'quality' if not provided.
52
+ sig do
53
+ returns(
54
+ T.nilable(BrandDev::BrandScreenshotParams::Prioritize::OrSymbol)
55
+ )
56
+ end
57
+ attr_reader :prioritize
58
+
59
+ sig do
60
+ params(
61
+ prioritize: BrandDev::BrandScreenshotParams::Prioritize::OrSymbol
62
+ ).void
63
+ end
64
+ attr_writer :prioritize
65
+
37
66
  sig do
38
67
  params(
39
68
  domain: String,
40
69
  full_screenshot:
41
70
  BrandDev::BrandScreenshotParams::FullScreenshot::OrSymbol,
71
+ page: BrandDev::BrandScreenshotParams::Page::OrSymbol,
72
+ prioritize: BrandDev::BrandScreenshotParams::Prioritize::OrSymbol,
42
73
  request_options: BrandDev::RequestOptions::OrHash
43
74
  ).returns(T.attached_class)
44
75
  end
@@ -50,6 +81,15 @@ module BrandDev
50
81
  # screenshot capturing all content. If 'false' or not provided, takes a viewport
51
82
  # screenshot (standard browser view).
52
83
  full_screenshot: nil,
84
+ # Optional parameter to specify which page type to screenshot. If provided, the
85
+ # system will scrape the domain's links and use heuristics to find the most
86
+ # appropriate URL for the specified page type (30 supported languages). If not
87
+ # provided, screenshots the main domain landing page.
88
+ page: nil,
89
+ # Optional parameter to prioritize screenshot capture. If 'speed', optimizes for
90
+ # faster capture with basic quality. If 'quality', optimizes for higher quality
91
+ # with longer wait times. Defaults to 'quality' if not provided.
92
+ prioritize: nil,
53
93
  request_options: {}
54
94
  )
55
95
  end
@@ -60,6 +100,8 @@ module BrandDev
60
100
  domain: String,
61
101
  full_screenshot:
62
102
  BrandDev::BrandScreenshotParams::FullScreenshot::OrSymbol,
103
+ page: BrandDev::BrandScreenshotParams::Page::OrSymbol,
104
+ prioritize: BrandDev::BrandScreenshotParams::Prioritize::OrSymbol,
63
105
  request_options: BrandDev::RequestOptions
64
106
  }
65
107
  )
@@ -100,6 +142,74 @@ module BrandDev
100
142
  def self.values
101
143
  end
102
144
  end
145
+
146
+ # Optional parameter to specify which page type to screenshot. If provided, the
147
+ # system will scrape the domain's links and use heuristics to find the most
148
+ # appropriate URL for the specified page type (30 supported languages). If not
149
+ # provided, screenshots the main domain landing page.
150
+ module Page
151
+ extend BrandDev::Internal::Type::Enum
152
+
153
+ TaggedSymbol =
154
+ T.type_alias { T.all(Symbol, BrandDev::BrandScreenshotParams::Page) }
155
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
156
+
157
+ LOGIN =
158
+ T.let(:login, BrandDev::BrandScreenshotParams::Page::TaggedSymbol)
159
+ SIGNUP =
160
+ T.let(:signup, BrandDev::BrandScreenshotParams::Page::TaggedSymbol)
161
+ BLOG = T.let(:blog, BrandDev::BrandScreenshotParams::Page::TaggedSymbol)
162
+ CAREERS =
163
+ T.let(:careers, BrandDev::BrandScreenshotParams::Page::TaggedSymbol)
164
+ PRICING =
165
+ T.let(:pricing, BrandDev::BrandScreenshotParams::Page::TaggedSymbol)
166
+ TERMS =
167
+ T.let(:terms, BrandDev::BrandScreenshotParams::Page::TaggedSymbol)
168
+ PRIVACY =
169
+ T.let(:privacy, BrandDev::BrandScreenshotParams::Page::TaggedSymbol)
170
+ CONTACT =
171
+ T.let(:contact, BrandDev::BrandScreenshotParams::Page::TaggedSymbol)
172
+
173
+ sig do
174
+ override.returns(
175
+ T::Array[BrandDev::BrandScreenshotParams::Page::TaggedSymbol]
176
+ )
177
+ end
178
+ def self.values
179
+ end
180
+ end
181
+
182
+ # Optional parameter to prioritize screenshot capture. If 'speed', optimizes for
183
+ # faster capture with basic quality. If 'quality', optimizes for higher quality
184
+ # with longer wait times. Defaults to 'quality' if not provided.
185
+ module Prioritize
186
+ extend BrandDev::Internal::Type::Enum
187
+
188
+ TaggedSymbol =
189
+ T.type_alias do
190
+ T.all(Symbol, BrandDev::BrandScreenshotParams::Prioritize)
191
+ end
192
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
193
+
194
+ SPEED =
195
+ T.let(
196
+ :speed,
197
+ BrandDev::BrandScreenshotParams::Prioritize::TaggedSymbol
198
+ )
199
+ QUALITY =
200
+ T.let(
201
+ :quality,
202
+ BrandDev::BrandScreenshotParams::Prioritize::TaggedSymbol
203
+ )
204
+
205
+ sig do
206
+ override.returns(
207
+ T::Array[BrandDev::BrandScreenshotParams::Prioritize::TaggedSymbol]
208
+ )
209
+ end
210
+ def self.values
211
+ end
212
+ end
103
213
  end
104
214
  end
105
215
  end
@@ -16,6 +16,24 @@ module BrandDev
16
16
  sig { returns(String) }
17
17
  attr_accessor :domain
18
18
 
19
+ # Optional parameter to prioritize screenshot capture for styleguide extraction.
20
+ # If 'speed', optimizes for faster capture with basic quality. If 'quality',
21
+ # optimizes for higher quality with longer wait times. Defaults to 'quality' if
22
+ # not provided.
23
+ sig do
24
+ returns(
25
+ T.nilable(BrandDev::BrandStyleguideParams::Prioritize::OrSymbol)
26
+ )
27
+ end
28
+ attr_reader :prioritize
29
+
30
+ sig do
31
+ params(
32
+ prioritize: BrandDev::BrandStyleguideParams::Prioritize::OrSymbol
33
+ ).void
34
+ end
35
+ attr_writer :prioritize
36
+
19
37
  # Optional timeout in milliseconds for the request. If the request takes longer
20
38
  # than this value, it will be aborted with a 408 status code. Maximum allowed
21
39
  # value is 300000ms (5 minutes).
@@ -28,6 +46,7 @@ module BrandDev
28
46
  sig do
29
47
  params(
30
48
  domain: String,
49
+ prioritize: BrandDev::BrandStyleguideParams::Prioritize::OrSymbol,
31
50
  timeout_ms: Integer,
32
51
  request_options: BrandDev::RequestOptions::OrHash
33
52
  ).returns(T.attached_class)
@@ -36,6 +55,11 @@ module BrandDev
36
55
  # Domain name to extract styleguide from (e.g., 'example.com', 'google.com'). The
37
56
  # domain will be automatically normalized and validated.
38
57
  domain:,
58
+ # Optional parameter to prioritize screenshot capture for styleguide extraction.
59
+ # If 'speed', optimizes for faster capture with basic quality. If 'quality',
60
+ # optimizes for higher quality with longer wait times. Defaults to 'quality' if
61
+ # not provided.
62
+ prioritize: nil,
39
63
  # Optional timeout in milliseconds for the request. If the request takes longer
40
64
  # than this value, it will be aborted with a 408 status code. Maximum allowed
41
65
  # value is 300000ms (5 minutes).
@@ -48,6 +72,7 @@ module BrandDev
48
72
  override.returns(
49
73
  {
50
74
  domain: String,
75
+ prioritize: BrandDev::BrandStyleguideParams::Prioritize::OrSymbol,
51
76
  timeout_ms: Integer,
52
77
  request_options: BrandDev::RequestOptions
53
78
  }
@@ -55,6 +80,39 @@ module BrandDev
55
80
  end
56
81
  def to_hash
57
82
  end
83
+
84
+ # Optional parameter to prioritize screenshot capture for styleguide extraction.
85
+ # If 'speed', optimizes for faster capture with basic quality. If 'quality',
86
+ # optimizes for higher quality with longer wait times. Defaults to 'quality' if
87
+ # not provided.
88
+ module Prioritize
89
+ extend BrandDev::Internal::Type::Enum
90
+
91
+ TaggedSymbol =
92
+ T.type_alias do
93
+ T.all(Symbol, BrandDev::BrandStyleguideParams::Prioritize)
94
+ end
95
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
96
+
97
+ SPEED =
98
+ T.let(
99
+ :speed,
100
+ BrandDev::BrandStyleguideParams::Prioritize::TaggedSymbol
101
+ )
102
+ QUALITY =
103
+ T.let(
104
+ :quality,
105
+ BrandDev::BrandStyleguideParams::Prioritize::TaggedSymbol
106
+ )
107
+
108
+ sig do
109
+ override.returns(
110
+ T::Array[BrandDev::BrandStyleguideParams::Prioritize::TaggedSymbol]
111
+ )
112
+ end
113
+ def self.values
114
+ end
115
+ end
58
116
  end
59
117
  end
60
118
  end
@@ -157,13 +157,16 @@ module BrandDev
157
157
  end
158
158
 
159
159
  # Beta feature: Capture a screenshot of a website. Supports both viewport
160
- # (standard browser view) and full-page screenshots. Returns a URL to the uploaded
161
- # screenshot image hosted on our CDN.
160
+ # (standard browser view) and full-page screenshots. Can also screenshot specific
161
+ # page types (login, pricing, etc.) by using heuristics to find the appropriate
162
+ # URL. Returns a URL to the uploaded screenshot image hosted on our CDN.
162
163
  sig do
163
164
  params(
164
165
  domain: String,
165
166
  full_screenshot:
166
167
  BrandDev::BrandScreenshotParams::FullScreenshot::OrSymbol,
168
+ page: BrandDev::BrandScreenshotParams::Page::OrSymbol,
169
+ prioritize: BrandDev::BrandScreenshotParams::Prioritize::OrSymbol,
167
170
  request_options: BrandDev::RequestOptions::OrHash
168
171
  ).returns(BrandDev::Models::BrandScreenshotResponse)
169
172
  end
@@ -175,6 +178,15 @@ module BrandDev
175
178
  # screenshot capturing all content. If 'false' or not provided, takes a viewport
176
179
  # screenshot (standard browser view).
177
180
  full_screenshot: nil,
181
+ # Optional parameter to specify which page type to screenshot. If provided, the
182
+ # system will scrape the domain's links and use heuristics to find the most
183
+ # appropriate URL for the specified page type (30 supported languages). If not
184
+ # provided, screenshots the main domain landing page.
185
+ page: nil,
186
+ # Optional parameter to prioritize screenshot capture. If 'speed', optimizes for
187
+ # faster capture with basic quality. If 'quality', optimizes for higher quality
188
+ # with longer wait times. Defaults to 'quality' if not provided.
189
+ prioritize: nil,
178
190
  request_options: {}
179
191
  )
180
192
  end
@@ -185,6 +197,7 @@ module BrandDev
185
197
  sig do
186
198
  params(
187
199
  domain: String,
200
+ prioritize: BrandDev::BrandStyleguideParams::Prioritize::OrSymbol,
188
201
  timeout_ms: Integer,
189
202
  request_options: BrandDev::RequestOptions::OrHash
190
203
  ).returns(BrandDev::Models::BrandStyleguideResponse)
@@ -193,6 +206,11 @@ module BrandDev
193
206
  # Domain name to extract styleguide from (e.g., 'example.com', 'google.com'). The
194
207
  # domain will be automatically normalized and validated.
195
208
  domain:,
209
+ # Optional parameter to prioritize screenshot capture for styleguide extraction.
210
+ # If 'speed', optimizes for faster capture with basic quality. If 'quality',
211
+ # optimizes for higher quality with longer wait times. Defaults to 'quality' if
212
+ # not provided.
213
+ prioritize: nil,
196
214
  # Optional timeout in milliseconds for the request. If the request takes longer
197
215
  # than this value, it will be aborted with a 408 status code. Maximum allowed
198
216
  # value is 300000ms (5 minutes).
@@ -21,11 +21,14 @@ module BrandDev
21
21
 
22
22
  attr_accessor status: Integer?
23
23
 
24
+ attr_accessor headers: ::Hash[String, String]?
25
+
24
26
  attr_accessor body: top?
25
27
 
26
28
  def initialize: (
27
29
  url: URI::Generic,
28
30
  ?status: Integer?,
31
+ ?headers: ::Hash[String, String]?,
29
32
  ?body: Object?,
30
33
  ?request: nil,
31
34
  ?response: nil,
@@ -37,6 +40,7 @@ module BrandDev
37
40
  def initialize: (
38
41
  url: URI::Generic,
39
42
  ?status: nil,
43
+ ?headers: ::Hash[String, String]?,
40
44
  ?body: nil,
41
45
  ?request: nil,
42
46
  ?response: nil,
@@ -48,6 +52,7 @@ module BrandDev
48
52
  def initialize: (
49
53
  url: URI::Generic,
50
54
  ?status: nil,
55
+ ?headers: ::Hash[String, String]?,
51
56
  ?body: nil,
52
57
  ?request: nil,
53
58
  ?response: nil,
@@ -59,6 +64,7 @@ module BrandDev
59
64
  def self.for: (
60
65
  url: URI::Generic,
61
66
  status: Integer,
67
+ headers: ::Hash[String, String]?,
62
68
  body: Object?,
63
69
  request: nil,
64
70
  response: nil,
@@ -68,6 +74,7 @@ module BrandDev
68
74
  def initialize: (
69
75
  url: URI::Generic,
70
76
  status: Integer,
77
+ headers: ::Hash[String, String]?,
71
78
  body: Object?,
72
79
  request: nil,
73
80
  response: nil,
@@ -3,7 +3,9 @@ module BrandDev
3
3
  type brand_screenshot_params =
4
4
  {
5
5
  domain: String,
6
- full_screenshot: BrandDev::Models::BrandScreenshotParams::full_screenshot
6
+ full_screenshot: BrandDev::Models::BrandScreenshotParams::full_screenshot,
7
+ page: BrandDev::Models::BrandScreenshotParams::page,
8
+ prioritize: BrandDev::Models::BrandScreenshotParams::prioritize
7
9
  }
8
10
  & BrandDev::Internal::Type::request_parameters
9
11
 
@@ -19,15 +21,31 @@ module BrandDev
19
21
  BrandDev::Models::BrandScreenshotParams::full_screenshot
20
22
  ) -> BrandDev::Models::BrandScreenshotParams::full_screenshot
21
23
 
24
+ attr_reader page: BrandDev::Models::BrandScreenshotParams::page?
25
+
26
+ def page=: (
27
+ BrandDev::Models::BrandScreenshotParams::page
28
+ ) -> BrandDev::Models::BrandScreenshotParams::page
29
+
30
+ attr_reader prioritize: BrandDev::Models::BrandScreenshotParams::prioritize?
31
+
32
+ def prioritize=: (
33
+ BrandDev::Models::BrandScreenshotParams::prioritize
34
+ ) -> BrandDev::Models::BrandScreenshotParams::prioritize
35
+
22
36
  def initialize: (
23
37
  domain: String,
24
38
  ?full_screenshot: BrandDev::Models::BrandScreenshotParams::full_screenshot,
39
+ ?page: BrandDev::Models::BrandScreenshotParams::page,
40
+ ?prioritize: BrandDev::Models::BrandScreenshotParams::prioritize,
25
41
  ?request_options: BrandDev::request_opts
26
42
  ) -> void
27
43
 
28
44
  def to_hash: -> {
29
45
  domain: String,
30
46
  full_screenshot: BrandDev::Models::BrandScreenshotParams::full_screenshot,
47
+ page: BrandDev::Models::BrandScreenshotParams::page,
48
+ prioritize: BrandDev::Models::BrandScreenshotParams::prioritize,
31
49
  request_options: BrandDev::RequestOptions
32
50
  }
33
51
 
@@ -41,6 +59,42 @@ module BrandDev
41
59
 
42
60
  def self?.values: -> ::Array[BrandDev::Models::BrandScreenshotParams::full_screenshot]
43
61
  end
62
+
63
+ type page =
64
+ :login
65
+ | :signup
66
+ | :blog
67
+ | :careers
68
+ | :pricing
69
+ | :terms
70
+ | :privacy
71
+ | :contact
72
+
73
+ module Page
74
+ extend BrandDev::Internal::Type::Enum
75
+
76
+ LOGIN: :login
77
+ SIGNUP: :signup
78
+ BLOG: :blog
79
+ CAREERS: :careers
80
+ PRICING: :pricing
81
+ TERMS: :terms
82
+ PRIVACY: :privacy
83
+ CONTACT: :contact
84
+
85
+ def self?.values: -> ::Array[BrandDev::Models::BrandScreenshotParams::page]
86
+ end
87
+
88
+ type prioritize = :speed | :quality
89
+
90
+ module Prioritize
91
+ extend BrandDev::Internal::Type::Enum
92
+
93
+ SPEED: :speed
94
+ QUALITY: :quality
95
+
96
+ def self?.values: -> ::Array[BrandDev::Models::BrandScreenshotParams::prioritize]
97
+ end
44
98
  end
45
99
  end
46
100
  end
@@ -1,7 +1,11 @@
1
1
  module BrandDev
2
2
  module Models
3
3
  type brand_styleguide_params =
4
- { domain: String, timeout_ms: Integer }
4
+ {
5
+ domain: String,
6
+ prioritize: BrandDev::Models::BrandStyleguideParams::prioritize,
7
+ timeout_ms: Integer
8
+ }
5
9
  & BrandDev::Internal::Type::request_parameters
6
10
 
7
11
  class BrandStyleguideParams < BrandDev::Internal::Type::BaseModel
@@ -10,21 +14,40 @@ module BrandDev
10
14
 
11
15
  attr_accessor domain: String
12
16
 
17
+ attr_reader prioritize: BrandDev::Models::BrandStyleguideParams::prioritize?
18
+
19
+ def prioritize=: (
20
+ BrandDev::Models::BrandStyleguideParams::prioritize
21
+ ) -> BrandDev::Models::BrandStyleguideParams::prioritize
22
+
13
23
  attr_reader timeout_ms: Integer?
14
24
 
15
25
  def timeout_ms=: (Integer) -> Integer
16
26
 
17
27
  def initialize: (
18
28
  domain: String,
29
+ ?prioritize: BrandDev::Models::BrandStyleguideParams::prioritize,
19
30
  ?timeout_ms: Integer,
20
31
  ?request_options: BrandDev::request_opts
21
32
  ) -> void
22
33
 
23
34
  def to_hash: -> {
24
35
  domain: String,
36
+ prioritize: BrandDev::Models::BrandStyleguideParams::prioritize,
25
37
  timeout_ms: Integer,
26
38
  request_options: BrandDev::RequestOptions
27
39
  }
40
+
41
+ type prioritize = :speed | :quality
42
+
43
+ module Prioritize
44
+ extend BrandDev::Internal::Type::Enum
45
+
46
+ SPEED: :speed
47
+ QUALITY: :quality
48
+
49
+ def self?.values: -> ::Array[BrandDev::Models::BrandStyleguideParams::prioritize]
50
+ end
28
51
  end
29
52
  end
30
53
  end
@@ -46,11 +46,14 @@ module BrandDev
46
46
  def screenshot: (
47
47
  domain: String,
48
48
  ?full_screenshot: BrandDev::Models::BrandScreenshotParams::full_screenshot,
49
+ ?page: BrandDev::Models::BrandScreenshotParams::page,
50
+ ?prioritize: BrandDev::Models::BrandScreenshotParams::prioritize,
49
51
  ?request_options: BrandDev::request_opts
50
52
  ) -> BrandDev::Models::BrandScreenshotResponse
51
53
 
52
54
  def styleguide: (
53
55
  domain: String,
56
+ ?prioritize: BrandDev::Models::BrandStyleguideParams::prioritize,
54
57
  ?timeout_ms: Integer,
55
58
  ?request_options: BrandDev::request_opts
56
59
  ) -> BrandDev::Models::BrandStyleguideResponse
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brand.dev
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brand Dev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-09-07 00:00:00.000000000 Z
11
+ date: 2025-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: connection_pool