Class: Quonfig::Resolver

Inherits:
Object
  • Object
show all
Defined in:
lib/quonfig/resolver.rb

Overview

Public-API resolver: looks up a config by key in a ConfigStore and runs it through an Evaluator against a Context.

store     = Quonfig::ConfigStore.new(configs_hash)
evaluator = Quonfig::Evaluator.new(store)
resolver  = Quonfig::Resolver.new(store, evaluator)
result    = resolver.get('my.flag', context)

Mirrors the sdk-node pattern so integration tests (qfg-dk6.22-24) can drive evaluation without constructing a full Client. For the full production read path (with config_loader, SSE updates, telemetry), see Quonfig::ConfigResolver — the two coexist during the JSON migration.

Constant Summary collapse

TRUE_VALUES =
%w[true 1 t yes].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(store, evaluator) ⇒ Resolver

Returns a new instance of Resolver.



22
23
24
25
# File 'lib/quonfig/resolver.rb', line 22

def initialize(store, evaluator)
  @store = store
  @evaluator = evaluator
end

Instance Attribute Details

#evaluatorObject (readonly)

Returns the value of attribute evaluator.



19
20
21
# File 'lib/quonfig/resolver.rb', line 19

def evaluator
  @evaluator
end

#project_env_idObject

Returns the value of attribute project_env_id.



20
21
22
# File 'lib/quonfig/resolver.rb', line 20

def project_env_id
  @project_env_id
end

#storeObject (readonly)

Returns the value of attribute store.



19
20
21
# File 'lib/quonfig/resolver.rb', line 19

def store
  @store
end

Instance Method Details

#get(key, context = nil) ⇒ Object

Look up key and evaluate against context. Mirrors Quonfig.get_or_raise semantics: if the key is unknown to the store, raise Quonfig::Errors::MissingDefaultError so callers can distinguish “no such config” from “config matched a nil/false value”. Tests that want the legacy “return nil if absent” shape can rescue and recover (see IntegrationTestHelpers.assert_resolved, which folds a missing-key raise into the test’s expected default).



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/quonfig/resolver.rb', line 38

def get(key, context = nil)
  config = raw(key)
  raise Quonfig::Errors::MissingDefaultError.new(key) if config.nil?

  eval_result = @evaluator.evaluate_config(config, context, resolver: self)
  return nil if eval_result.nil?

  weighted_index = nil
  resolved_value = resolve_value(eval_result.value, config, context) do |idx|
    weighted_index = idx
  end
  EvalResult.new(
    value: resolved_value,
    rule_index: eval_result.rule_index,
    config: config,
    weighted_value_index: weighted_index
  )
end

#raw(key) ⇒ Object



27
28
29
# File 'lib/quonfig/resolver.rb', line 27

def raw(key)
  @store.get(key)
end

#resolve_value(value, config, context = nil, &on_weighted_index) ⇒ Object

Post-evaluation value resolution. Mirrors sdk-node Resolver#resolveValue and sdk-go resolver.Resolve:

  • “provided” + ENV_VAR → read ENV, coerce to config’s valueType

  • confidential + decryptWith → look up the key config, decrypt

  • everything else passes through unchanged



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/quonfig/resolver.rb', line 62

def resolve_value(value, config, context = nil, &on_weighted_index)
  return nil if value.nil?

  type = vget(value, :type, 'type')

  if type == 'provided'
    return resolve_provided(value, config)
  end

  if type == 'weighted_values'
    return resolve_weighted(value, config, context, &on_weighted_index)
  end

  confidential = vget(value, :confidential, 'confidential')
  decrypt_with = vget(value, :decryptWith, 'decryptWith', :decrypt_with, 'decrypt_with')
  return resolve_decryption(value, config, context, decrypt_with) if confidential && decrypt_with && !decrypt_with.to_s.empty?

  value
end

#symbolize_json_names?Boolean

Integration shims for code that expects a ConfigResolver. Keep these narrow; the real ConfigResolver still owns the production hot path.

Returns:

  • (Boolean)


84
85
86
# File 'lib/quonfig/resolver.rb', line 84

def symbolize_json_names?
  false
end