Module: Helio::Util
- Defined in:
- lib/helio/util.rb
Constant Summary collapse
- OPTS_USER_SPECIFIED =
Options that a user is allowed to specify.
Set[ :api_id, :api_token, :idempotency_key, :helio_version ]
- OPTS_COPYABLE =
Options that should be copyable from one HelioObject to another including options that may be internal.
( OPTS_USER_SPECIFIED + Set[:api_base] )
- OPTS_PERSISTABLE =
Options that should be persisted between API requests. This includes client, which is an object containing an HTTP client to reuse.
( OPTS_USER_SPECIFIED + Set[:client] - Set[:idempotency_key] )
Class Method Summary collapse
-
.array_to_hash(array) ⇒ Object
Transforms an array into a hash with integer keys.
- .check_api_token!(key) ⇒ Object
- .check_string_argument!(key) ⇒ Object
-
.convert_to_helio_object(data, opts = {}) ⇒ Object
Converts a hash of fields or an array of hashes into a
HelioObjector array of HelioObjects. -
.encode_parameters(params) ⇒ Object
Encodes a hash of parameters in a way that’s suitable for use as query parameters in a URI or as form parameters in a request body.
- .file_readable(file) ⇒ Object
- .flatten_params(params, parent_key = nil) ⇒ Object
- .flatten_params_array(value, calculated_key) ⇒ Object
- .log_debug(message, data = {}) ⇒ Object
- .log_error(message, data = {}) ⇒ Object
- .log_info(message, data = {}) ⇒ Object
-
.normalize_headers(headers) ⇒ Object
Normalizes header keys so that they’re all lower case and each hyphen-delimited section starts with a single capitalized letter.
- .normalize_id(id) ⇒ Object
-
.normalize_opts(opts) ⇒ Object
The secondary opts argument can either be a string or hash Turn this value into an api_token and a set of headers.
- .object_classes ⇒ Object
- .objects_to_ids(h) ⇒ Object
-
.request_id_dashboard_url(request_id, api_token) ⇒ Object
Generates a Dashboard link to inspect a request ID based off of a request ID value and an API key, which is used to attempt to extract whether the environment is livemode or testmode.
-
.secure_compare(a, b) ⇒ Object
Constant time string comparison to prevent timing attacks Code borrowed from ActiveSupport.
- .symbolize_names(object) ⇒ Object
-
.url_encode(key) ⇒ Object
Encodes a string in a way that makes it suitable for use in a set of query parameters in a URI or in a set of form parameters in a request body.
Class Method Details
.array_to_hash(array) ⇒ Object
Transforms an array into a hash with integer keys. Used for a small number of API endpoints. If the argument is not an Array, return it unchanged. Example: [‘bar’] => => {foo: “bar”}
145 146 147 148 149 150 151 152 153 154 |
# File 'lib/helio/util.rb', line 145 def self.array_to_hash(array) case array when Array hash = {} array.each_with_index { |v, i| hash[i.to_s] = v } hash else array end end |
.check_api_token!(key) ⇒ Object
230 231 232 233 |
# File 'lib/helio/util.rb', line 230 def self.check_api_token!(key) raise TypeError, "api_token must be a string" unless key.is_a?(String) key end |
.check_string_argument!(key) ⇒ Object
225 226 227 228 |
# File 'lib/helio/util.rb', line 225 def self.check_string_argument!(key) raise TypeError, "argument must be a string" unless key.is_a?(String) key end |
.convert_to_helio_object(data, opts = {}) ⇒ Object
Converts a hash of fields or an array of hashes into a HelioObject or array of HelioObjects. These new objects will be created as a concrete type as dictated by their object field (e.g. an object value of charge would create an instance of Charge), but if object is not present or of an unknown type, the newly created instance will fall back to being a HelioObject.
Attributes
-
data- Hash of fields and values to be converted into a HelioObject. -
opts- Options forHelioObjectlike an API key that will be reused on subsequent API calls.
65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/helio/util.rb', line 65 def self.convert_to_helio_object(data, opts = {}) case data when Array data.map { |i| convert_to_helio_object(i, opts) } when Hash # Try converting to a known object class. If none available, fall back to generic HelioObject object_classes.fetch(data[:object_type], HelioObject).construct_from(data, opts) else data end end |
.encode_parameters(params) ⇒ Object
Encodes a hash of parameters in a way that’s suitable for use as query parameters in a URI or as form parameters in a request body. This mainly involves escaping special characters from parameter keys and values (e.g. ‘&`).
137 138 139 140 |
# File 'lib/helio/util.rb', line 137 def self.encode_parameters(params) Util.flatten_params(params) .map { |k, v| "#{url_encode(k)}=#{url_encode(v)}" }.join("&") end |
.file_readable(file) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/helio/util.rb', line 101 def self.file_readable(file) # This is nominally equivalent to File.readable?, but that can # report incorrect results on some more oddball filesystems # (such as AFS) File.open(file) { |f| } rescue StandardError false else true end |
.flatten_params(params, parent_key = nil) ⇒ Object
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/helio/util.rb', line 167 def self.flatten_params(params, parent_key = nil) result = [] # do not sort the final output because arrays (and arrays of hashes # especially) can be order sensitive, but do sort incoming parameters params.each do |key, value| calculated_key = parent_key ? "#{parent_key}[#{key}]" : key.to_s if value.is_a?(Hash) result += flatten_params(value, calculated_key) elsif value.is_a?(Array) check_array_of_maps_start_keys!(value) result += flatten_params_array(value, calculated_key) else result << [calculated_key, value] end end result end |
.flatten_params_array(value, calculated_key) ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/helio/util.rb', line 187 def self.flatten_params_array(value, calculated_key) result = [] value.each do |elem| if elem.is_a?(Hash) result += flatten_params(elem, "#{calculated_key}[]") elsif elem.is_a?(Array) result += flatten_params_array(elem, calculated_key) else result << ["#{calculated_key}[]", elem] end end result end |
.log_debug(message, data = {}) ⇒ Object
93 94 95 96 97 98 99 |
# File 'lib/helio/util.rb', line 93 def self.log_debug(, data = {}) if !Helio.logger.nil? || !Helio.log_level.nil? && Helio.log_level <= Helio::LEVEL_DEBUG log_internal(, data, color: :blue, level: Helio::LEVEL_DEBUG, logger: Helio.logger, out: $stdout) end end |
.log_error(message, data = {}) ⇒ Object
77 78 79 80 81 82 83 |
# File 'lib/helio/util.rb', line 77 def self.log_error(, data = {}) if !Helio.logger.nil? || !Helio.log_level.nil? && Helio.log_level <= Helio::LEVEL_ERROR log_internal(, data, color: :cyan, level: Helio::LEVEL_ERROR, logger: Helio.logger, out: $stderr) end end |
.log_info(message, data = {}) ⇒ Object
85 86 87 88 89 90 91 |
# File 'lib/helio/util.rb', line 85 def self.log_info(, data = {}) if !Helio.logger.nil? || !Helio.log_level.nil? && Helio.log_level <= Helio::LEVEL_INFO log_internal(, data, color: :cyan, level: Helio::LEVEL_INFO, logger: Helio.logger, out: $stdout) end end |
.normalize_headers(headers) ⇒ Object
Normalizes header keys so that they’re all lower case and each hyphen-delimited section starts with a single capitalized letter. For example, request-id becomes Request-Id. This is useful for extracting certain key values when the user could have set them with a variety of diffent naming schemes.
240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/helio/util.rb', line 240 def self.normalize_headers(headers) headers.each_with_object({}) do |(k, v), new_headers| if k.is_a?(Symbol) k = titlecase_parts(k.to_s.tr("_", "-")) elsif k.is_a?(String) k = titlecase_parts(k) end new_headers[k] = v end end |
.normalize_id(id) ⇒ Object
201 202 203 204 205 206 207 208 209 |
# File 'lib/helio/util.rb', line 201 def self.normalize_id(id) if id.is_a?(Hash) # overloaded id params_hash = id.dup id = params_hash.delete(:id) else params_hash = {} end [id, params_hash] end |
.normalize_opts(opts) ⇒ Object
The secondary opts argument can either be a string or hash Turn this value into an api_token and a set of headers
213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/helio/util.rb', line 213 def self.normalize_opts(opts) case opts when String { api_token: opts } when Hash check_api_token!(opts.fetch(:api_token)) if opts.key?(:api_token) opts.clone else raise TypeError, "normalize_opts expects a string or a hash" end end |
.object_classes ⇒ Object
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/helio/util.rb', line 42 def self.object_classes @object_classes ||= { # data structures ListObject::OBJECT_NAME => ListObject, # business objects CustomerList::OBJECT_NAME => CustomerList, Participant::OBJECT_NAME => Participant, } end |
.objects_to_ids(h) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/helio/util.rb', line 27 def self.objects_to_ids(h) case h when APIResource h.id when Hash res = {} h.each { |k, v| res[k] = objects_to_ids(v) unless v.nil? } res when Array h.map { |v| objects_to_ids(v) } else h end end |
.request_id_dashboard_url(request_id, api_token) ⇒ Object
Generates a Dashboard link to inspect a request ID based off of a request ID value and an API key, which is used to attempt to extract whether the environment is livemode or testmode.
255 256 257 258 |
# File 'lib/helio/util.rb', line 255 def self.request_id_dashboard_url(request_id, api_token) env = !api_token.nil? && api_token.start_with?("sk_live") ? "live" : "test" "https://helio.zurb.com/#{env}/logs/#{request_id}" end |
.secure_compare(a, b) ⇒ Object
Constant time string comparison to prevent timing attacks Code borrowed from ActiveSupport
262 263 264 265 266 267 268 269 270 |
# File 'lib/helio/util.rb', line 262 def self.secure_compare(a, b) return false unless a.bytesize == b.bytesize l = a.unpack "C#{a.bytesize}" res = 0 b.each_byte { |byte| res |= byte ^ l.shift } res.zero? end |
.symbolize_names(object) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/helio/util.rb', line 113 def self.symbolize_names(object) case object when Hash new_hash = {} object.each do |key, value| key = (begin key.to_sym rescue StandardError key end) || key new_hash[key] = symbolize_names(value) end new_hash when Array object.map { |value| symbolize_names(value) } else object end end |
.url_encode(key) ⇒ Object
Encodes a string in a way that makes it suitable for use in a set of query parameters in a URI or in a set of form parameters in a request body.
159 160 161 162 163 164 165 |
# File 'lib/helio/util.rb', line 159 def self.url_encode(key) CGI.escape(key.to_s). # Don't use strict form encoding by changing the square bracket control # characters back to their literals. This is fine by the server, and # makes these parameter strings easier to read. gsub("%5B", "[").gsub("%5D", "]") end |