Module: Smplkit::Config::Helpers Private

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

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Internal conversion and resolution helpers shared by the config client.

Class Method Summary collapse

Class Method Details

.build_chain(target, by_id) ⇒ Array<Hash{String => Object}>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Build the parent chain (child-first, root-last) for a Config, walking parent_id pointers across the by_id map. Mirrors the Python SDK’s client-side chain construction.

Parameters:

  • target (Config)

    The config to build the chain for.

  • by_id (Hash{String => Config})

    Pre-fetched configs keyed by id, used to look up parents without extra network calls.

Returns:

  • (Array<Hash{String => Object}>)

    Chain entries from child to root.



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

def build_chain(target, by_id)
  chain = []
  current = target
  loop do
    chain << config_to_chain_entry(current)
    parent_id = current.parent_id
    break if parent_id.nil? || parent_id == ""

    parent = by_id[parent_id]
    break unless parent

    current = parent
  end
  chain
end

.config_from_json(client, resource) ⇒ Config

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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

Parameters:

  • client (ConfigClient, nil)

    The owning client, or nil for a detached model.

  • resource (Hash{String => Object})

    The JSON:API resource Hash.

Returns:

  • (Config)

    The constructed config domain model.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/smplkit/config/helpers.rb', line 18

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_data is already the flat override map +{key: rawValue}+ — the
    # old +{values: {...}}+ envelope is gone.
    env_values = env_data.is_a?(Hash) ? env_data : {}
    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

.config_to_chain_entry(config) ⇒ Hash{String => Object}

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Build a single chain entry (the id/items/environments Hash shape used by resolve_chain) from a Config domain model.

Parameters:

  • config (Config)

    The config to convert.

Returns:

  • (Hash{String => Object})

    An id/items/environments chain entry.



118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/smplkit/config/helpers.rb', line 118

def config_to_chain_entry(config)
  items_hash = config.items.to_h do |item|
    [item.name,
     { "value" => item.value, "type" => item.type, "description" => item.description }.compact]
  end
  environments = config.environments.each_with_object({}) do |(env_key, env_obj), out|
    # Env entries are flat +{key: rawValue}+ maps — no +values+
    # envelope, no per-key type wrapper.
    out[env_key] = env_obj.values
  end
  { "id" => config.id, "items" => items_hash, "environments" => environments }
end

.deep_merge(base, override) ⇒ Hash{String => Object}

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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

Parameters:

  • base (Hash{String => Object})

    The base Hash.

  • override (Hash{String => Object})

    The Hash whose values win on conflict.

Returns:

  • (Hash{String => Object})

    A new merged Hash.



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/smplkit/config/helpers.rb', line 62

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) ⇒ Hash{String => Object}

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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.

Parameters:

  • chain (Array<Hash{String => Object}>)

    Chain entries from child to root.

  • environment (String, nil)

    The environment whose overrides to apply, or nil for base values only.

Returns:

  • (Hash{String => Object})

    The resolved {key => value} map.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/smplkit/config/helpers.rb', line 142

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 entries are flat +{key: rawValue}+ maps — the resolver reads
    # the env entry directly as the override map.
    env_data = (config_data["environments"] || {})[environment] || {}
    env_values = env_data.is_a?(Hash) ? env_data : {}
    config_resolved = deep_merge(base_values, env_values)
    accumulated = deep_merge(accumulated, config_resolved)
  end
  accumulated
end

.unwrap_items(items) ⇒ Hash{String => Object}

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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

Parameters:

  • items (Hash{String => Object})

    Typed items keyed by item key.

Returns:

  • (Hash{String => Object})

    The items as { key => raw_value }.



79
80
81
82
83
# File 'lib/smplkit/config/helpers.rb', line 79

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