Class: Inquirex::Definition
- Inherits:
-
Object
- Object
- Inquirex::Definition
- Defined in:
- lib/inquirex/definition.rb
Overview
Immutable, versionable flow graph. Maps step ids to Node objects and defines the entry point. Carries optional metadata (id, version, title, subtitle, brand) for the JS widget. Supports JSON round-trip serialization; lambdas are stripped on serialization.
Instance Attribute Summary collapse
-
#accumulators ⇒ Object
readonly
Returns the value of attribute accumulators.
-
#actions ⇒ Object
readonly
Returns the value of attribute actions.
-
#allowed_domains ⇒ Object
readonly
Returns the value of attribute allowed_domains.
-
#id ⇒ String?
readonly
flow identifier (e.g. "tax-intake-2025").
-
#meta ⇒ Hash
readonly
title, subtitle, brand info for the frontend.
-
#start_step_id ⇒ Symbol
readonly
id of the first step in the flow.
-
#steps ⇒ Hash<Symbol, Node>
readonly
frozen map of step id => node.
-
#version ⇒ String
readonly
semver string (default: "1.0.0").
Class Method Summary collapse
-
.from_h(hash) ⇒ Definition
Deserializes a Definition from a plain Hash.
-
.from_json(json) ⇒ Definition
Deserializes a Definition from a JSON string.
Instance Method Summary collapse
-
#allowed_host?(host) ⇒ Boolean
Whether a host is covered by the allowed_domains declaration.
-
#initialize(start_step_id:, nodes:, id: nil, version: "1.0.0", meta: {}, accumulators: {}, actions: [], allowed_domains: []) ⇒ Definition
constructor
A new instance of Definition.
-
#start_step ⇒ Node
The node for the start step.
-
#step(id) ⇒ Node
The node for that step.
-
#step_ids ⇒ Array<Symbol>
All step ids.
-
#to_h ⇒ Hash
Serializes to a plain Hash.
-
#to_json ⇒ String
Serializes the definition to a JSON string.
Constructor Details
#initialize(start_step_id:, nodes:, id: nil, version: "1.0.0", meta: {}, accumulators: {}, actions: [], allowed_domains: []) ⇒ Definition
Returns a new instance of Definition.
35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/inquirex/definition.rb', line 35 def initialize(start_step_id:, nodes:, id: nil, version: "1.0.0", meta: {}, accumulators: {}, actions: [], allowed_domains: []) @id = id @version = version @meta = .freeze @start_step_id = start_step_id.to_sym @steps = nodes.freeze @accumulators = accumulators.freeze @actions = actions.freeze @allowed_domains = normalize_domains(allowed_domains) validate! freeze end |
Instance Attribute Details
#accumulators ⇒ Object (readonly)
Returns the value of attribute accumulators.
16 17 18 |
# File 'lib/inquirex/definition.rb', line 16 def accumulators @accumulators end |
#actions ⇒ Object (readonly)
Returns the value of attribute actions.
16 17 18 |
# File 'lib/inquirex/definition.rb', line 16 def actions @actions end |
#allowed_domains ⇒ Object (readonly)
Returns the value of attribute allowed_domains.
16 17 18 |
# File 'lib/inquirex/definition.rb', line 16 def allowed_domains @allowed_domains end |
#id ⇒ String? (readonly)
flow identifier (e.g. "tax-intake-2025")
15 16 17 |
# File 'lib/inquirex/definition.rb', line 15 def id @id end |
#meta ⇒ Hash (readonly)
title, subtitle, brand info for the frontend
15 16 17 |
# File 'lib/inquirex/definition.rb', line 15 def @meta end |
#start_step_id ⇒ Symbol (readonly)
id of the first step in the flow
15 16 17 |
# File 'lib/inquirex/definition.rb', line 15 def start_step_id @start_step_id end |
#steps ⇒ Hash<Symbol, Node> (readonly)
frozen map of step id => node
15 16 17 |
# File 'lib/inquirex/definition.rb', line 15 def steps @steps end |
#version ⇒ String (readonly)
semver string (default: "1.0.0")
15 16 17 |
# File 'lib/inquirex/definition.rb', line 15 def version @version end |
Class Method Details
.from_h(hash) ⇒ Definition
Deserializes a Definition from a plain Hash.
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/inquirex/definition.rb', line 128 def self.from_h(hash) id = hash["id"] || hash[:id] version = hash["version"] || hash[:version] || "1.0.0" = hash["meta"] || hash[:meta] || {} start = hash["start"] || hash[:start] steps_data = hash["steps"] || hash[:steps] || {} acc_data = hash["accumulators"] || hash[:accumulators] || {} actions_data = hash["actions"] || hash[:actions] || [] domains = hash["allowed_domains"] || hash[:allowed_domains] || [] nodes = steps_data.each_with_object({}) do |(step_id, step_hash), acc| sym_id = step_id.to_sym acc[sym_id] = Node.from_h(sym_id, step_hash) end accumulators = acc_data.each_with_object({}) do |(name, entry), h| sym = name.to_sym h[sym] = Accumulator.from_h(sym, entry) end actions = actions_data.map { |entry| Actions::Action.from_h(entry) } new(start_step_id: start, nodes:, id:, version:, meta:, accumulators:, actions:, allowed_domains: domains) end |
.from_json(json) ⇒ Definition
Deserializes a Definition from a JSON string.
118 119 120 121 122 |
# File 'lib/inquirex/definition.rb', line 118 def self.from_json(json) from_h(JSON.parse(json)) rescue JSON::ParserError => e raise Errors::SerializationError, "Invalid JSON: #{e.}" end |
Instance Method Details
#allowed_host?(host) ⇒ Boolean
Whether a host is covered by the allowed_domains declaration. "example.com" matches that host exactly; "*.example.com" matches any subdomain but not the apex. Matching is case-insensitive; an empty allowlist allows nothing.
78 79 80 81 82 83 |
# File 'lib/inquirex/definition.rb', line 78 def allowed_host?(host) target = host.to_s.downcase @allowed_domains.any? do |entry| entry.start_with?("*.") ? target.end_with?(entry[1..]) : target == entry end end |
#start_step ⇒ Node
Returns the node for the start step.
50 51 52 |
# File 'lib/inquirex/definition.rb', line 50 def start_step step(@start_step_id) end |
#step(id) ⇒ Node
Returns the node for that step.
57 58 59 |
# File 'lib/inquirex/definition.rb', line 57 def step(id) @steps.fetch(id.to_sym) { raise Errors::UnknownStepError, "Unknown step: #{id.inspect}" } end |
#step_ids ⇒ Array<Symbol>
Returns all step ids.
62 63 64 |
# File 'lib/inquirex/definition.rb', line 62 def step_ids @steps.keys end |
#to_h ⇒ Hash
Serializes to a plain Hash.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/inquirex/definition.rb', line 96 def to_h hash = {} hash["id"] = @id if @id hash["version"] = @version hash["meta"] = @meta unless @meta.empty? hash["allowed_domains"] = @allowed_domains unless @allowed_domains.empty? hash["start"] = @start_step_id.to_s unless @accumulators.empty? hash["accumulators"] = @accumulators.each_with_object({}) do |(name, acc), h| h[name.to_s] = acc.to_h end end hash["steps"] = @steps.transform_keys(&:to_s).transform_values(&:to_h) serializable_actions = @actions.select(&:serializable?) hash["actions"] = serializable_actions.map(&:to_h) unless serializable_actions.empty? hash end |
#to_json ⇒ String
Serializes the definition to a JSON string. Lambdas (default procs, compute blocks) are silently stripped.
89 90 91 |
# File 'lib/inquirex/definition.rb', line 89 def to_json(*) JSON.generate(to_h) end |