Module: Smplkit::Config::Helpers

Defined in:
lib/smplkit/config/helpers.rb

Class Method Summary collapse

Class Method Details

.build_config_request_body(config) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/smplkit/config/helpers.rb', line 43

def build_config_request_body(config)
  items = {}
  config.items.each do |item|
    items[item.name] = {
      "value" => item.value,
      "type" => item.type,
      "description" => item.description
    }.compact
  end

  environments = config.environments.each_with_object({}) do |(env, env_obj), out|
    out[env] = { "values" => env_obj.values_raw }
  end

  # The Config schema (per the OpenAPI spec) does not include +key+ in
  # attributes — the resource +id+ carries the customer-facing key.
  attributes = {
    "name" => config.name,
    "description" => config.description,
    "parent" => config.parent_id,
    "items" => items,
    "environments" => environments
  }.compact
  { "data" => { "type" => "config", "id" => config.key, "attributes" => attributes } }
end

.config_from_json(client, resource) ⇒ Object

Translate a JSON:API resource Hash into a Config domain model.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/smplkit/config/helpers.rb', line 9

def config_from_json(client, resource)
  attrs = resource["attributes"] || {}
  items = (attrs["items"] || {}).map do |name, item|
    if item.is_a?(Hash) && item.key?("value")
      ConfigItem.new(
        name: name,
        value: item["value"],
        type: item["type"],
        description: item["description"]
      )
    else
      ConfigItem.new(name: name, value: item, type: ItemType::JSON)
    end
  end

  environments = (attrs["environments"] || {}).each_with_object({}) do |(env, env_data), out|
    env_values = env_data.is_a?(Hash) ? (env_data["values"] || {}) : {}
    out[env] = ConfigEnvironment.new(values: env_values)
  end

  Config.new(
    client,
    id: resource["id"] || attrs["id"],
    key: attrs["key"] || resource["id"],
    name: attrs["name"],
    description: attrs["description"],
    parent_id: attrs["parent"] || attrs["parent_id"],
    items: items,
    environments: environments,
    created_at: attrs["created_at"],
    updated_at: attrs["updated_at"]
  )
end

.deep_merge(base, override) ⇒ Object

Deep-merge two Hashes, with override winning. Mirrors the Python deep_merge helper used by the resolver.



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/smplkit/config/helpers.rb', line 71

def deep_merge(base, override)
  result = base.dup
  override.each do |key, value|
    result[key] = if result[key].is_a?(Hash) && value.is_a?(Hash)
                    deep_merge(result[key], value)
                  else
                    value
                  end
  end
  result
end

.resolve_chain(chain, environment) ⇒ Object

Resolve the full configuration for an environment given a config chain.

Walks from root (last element) to child (first element), accumulating values via deep merge so child configs override parent configs.



94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/smplkit/config/helpers.rb', line 94

def resolve_chain(chain, environment)
  accumulated = {}
  chain.reverse_each do |config_data|
    raw_items = config_data["items"] || config_data["values"] || {}
    base_values = unwrap_items(raw_items)
    env_data = (config_data["environments"] || {})[environment] || {}
    env_raw = env_data.is_a?(Hash) ? (env_data["values"] || {}) : {}
    env_values = unwrap_items(env_raw)
    config_resolved = deep_merge(base_values, env_values)
    accumulated = deep_merge(accumulated, config_resolved)
  end
  accumulated
end

.unwrap_items(items) ⇒ Object

Unwrap typed items { key => { value, type, desc } } to { key => raw }.



84
85
86
87
88
# File 'lib/smplkit/config/helpers.rb', line 84

def unwrap_items(items)
  items.each_with_object({}) do |(k, v), out|
    out[k] = v.is_a?(Hash) && v.key?("value") ? v["value"] : v
  end
end