Class: Conexa::Util

Inherits:
Object show all
Defined in:
lib/conexa/util.rb

Constant Summary collapse

SINGULARS =
[
  [/(ss)$/i, '\1'],
  [/(n)ews$/i, '\1ews'],
  [/([ti])a$/i, '\1um'],
  [/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '\1sis'],
  [/(^analy)(sis|ses)$/i, '\1sis'],
  [/([^f])ves$/i, '\1fe'],
  [/(hive)s$/i, '\1'],
  [/(tive)s$/i, '\1'],
  [/([lr])ves$/i, '\1f'],
  [/([^aeiouy]|qu)ies$/i, '\1y'],
  [/(s)eries$/i, '\1eries'],
  [/(m)ovies$/i, '\1ovie'],
  [/(x|ch|ss|sh)es$/i, '\1'],
  [/^(m|l)ice$/i, '\1ouse'],
  [/(bus)(es)?$/i, '\1'],
  [/(o)es$/i, '\1'],
  [/(shoe)s$/i, '\1'],
  [/(cris|test)(is|es)$/i, '\1is'],
  [/^(a)x[ie]s$/i, '\1xis'],
  [/(octop|vir)(us|i)$/i, '\1us'],
  [/(alias|status)(es)?$/i, '\1'],
  [/^(ox)en/i, '\1'],
  [/(vert|ind)ices$/i, '\1ex'],
  [/(matr)ices$/i, '\1ix'],
  [/(quiz)zes$/i, '\1'],
  [/(database)s$/i, '\1'],
  [/s$/i, '']
].freeze

Class Method Summary collapse

Class Method Details

.camel_case_lower(str) ⇒ Object



115
116
117
# File 'lib/conexa/util.rb', line 115

def camel_case_lower str
  str.to_s.split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
end

.camelize_hash(hash) ⇒ Object

Convert a payload's keys to the camelCase the API expects, all the way down. Arrays of objects matter as much as nested hashes: ten documented endpoints take them (complementaryServices, productQuotas, devices, extraFields, bookingModels, visitors, costCenters, ...), and a snake_case key inside one is rejected outright.



95
96
97
98
99
100
101
# File 'lib/conexa/util.rb', line 95

def camelize_hash(hash)
  return {} if hash.nil?

  hash.each_with_object({}) do |(key, value), new_hash|
    new_hash[camel_case_lower(key).to_sym] = camelize_value(value)
  end
end

.camelize_str(str) ⇒ Object



111
112
113
# File 'lib/conexa/util.rb', line 111

def camelize_str(str)
  str.to_s.gsub(/_([a-z0-9])/) {  Regexp.last_match[1].upcase }
end

.camelize_value(value) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/conexa/util.rb', line 103

def camelize_value(value)
  case value
  when Hash  then camelize_hash(value)
  when Array then value.map { |element| camelize_value(element) }
  else value
  end
end

.normalize_end_date_param(params) ⇒ Hash

Both "end" endpoints — PATCH /contract/end/:id and PATCH /recurringSale/end/:id — document the closing date as date. The gem used to send end_date, which camelizes to endDate and is rejected: "endDate field does not exist or is not available in the company".

Both key spellings are handled, and both are removed. Checking only the symbol :date would leave a caller's string "date" in place and add a second, colliding key — camelize_hash folds the two into one and the last one wins, so the deprecated value would silently replace the real one.

Parameters:

  • params (Hash)

    caller params, possibly using the old name

Returns:

  • (Hash)

    a copy with end_date folded into date



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/conexa/util.rb', line 62

def normalize_end_date_param(params)
  params = params.dup

  # Collapse both spellings of each key up front. Leaving one behind would
  # let camelize_hash fold two `date` keys into one, last-write-wins — which
  # is how the deprecated value once silently replaced the real one.
  legacy   = [params.delete(:end_date), params.delete("end_date")].compact.first
  explicit = [params.delete(:date), params.delete("date")].compact.first

  warn_end_date_renamed if legacy

  # An explicit date wins; a key present with a nil value is not one.
  date = explicit || legacy
  params[:date] = date unless date.nil?
  params
end

.singularize(resource) ⇒ Object



37
38
39
40
41
42
43
44
# File 'lib/conexa/util.rb', line 37

def singularize(resource)
  str = resource.to_s
  SINGULARS.each do |pattern, replacement|
    result = str.sub(pattern, replacement)
    return resource.is_a?(Symbol) ? result.to_sym : result if result != str
  end
  resource
end

.to_snake_case(str) ⇒ Object



79
80
81
# File 'lib/conexa/util.rb', line 79

def to_snake_case str
  str.gsub(/([A-Z])/, '_\1').downcase.sub(/^_/, '')
end

.to_sym(string) ⇒ Object



46
47
48
# File 'lib/conexa/util.rb', line 46

def to_sym string
  string.to_s.strip.gsub(/[\s\-]+/, '_').to_sym
end

.warn_end_date_renamedObject



84
85
86
87
88
# File 'lib/conexa/util.rb', line 84

def warn_end_date_renamed
  Deprecation.warn_once(:end_date_param,
                        "`end_date:` foi renomeado para `date:` em conexa 0.2.0 " \
                        "(a API v2 rejeita `endDate`). O alias será removido em 0.3.0.")
end