inquirex 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +119 -0
- data/docs/badges/coverage_badge.svg +2 -2
- data/examples/03_send_email_actions.rb +97 -0
- data/lib/inquirex/accumulator.rb +29 -0
- data/lib/inquirex/actions/action.rb +68 -0
- data/lib/inquirex/actions/base.rb +41 -0
- data/lib/inquirex/actions/custom.rb +31 -0
- data/lib/inquirex/actions/outbox.rb +57 -0
- data/lib/inquirex/actions/runner.rb +52 -0
- data/lib/inquirex/actions/send_email.rb +174 -0
- data/lib/inquirex/actions/template.rb +95 -0
- data/lib/inquirex/actions/webhook.rb +139 -0
- data/lib/inquirex/actions.rb +57 -0
- data/lib/inquirex/answers.rb +13 -0
- data/lib/inquirex/completion_metadata.rb +82 -0
- data/lib/inquirex/definition.rb +67 -5
- data/lib/inquirex/dsl/action_builder.rb +53 -0
- data/lib/inquirex/dsl/flow_builder.rb +49 -6
- data/lib/inquirex/engine/state_serializer.rb +6 -4
- data/lib/inquirex/engine.rb +97 -5
- data/lib/inquirex/errors.rb +5 -0
- data/lib/inquirex/graph/mermaid_exporter.rb +2 -0
- data/lib/inquirex/node.rb +2 -0
- data/lib/inquirex/rules/all.rb +12 -0
- data/lib/inquirex/rules/any.rb +11 -0
- data/lib/inquirex/rules/base.rb +6 -0
- data/lib/inquirex/rules/contains.rb +12 -0
- data/lib/inquirex/rules/equals.rb +12 -0
- data/lib/inquirex/rules/greater_than.rb +12 -0
- data/lib/inquirex/rules/less_than.rb +12 -0
- data/lib/inquirex/rules/not_empty.rb +12 -0
- data/lib/inquirex/validation/adapter.rb +1 -0
- data/lib/inquirex/validation/null_adapter.rb +5 -0
- data/lib/inquirex/version.rb +1 -1
- data/lib/inquirex/widget_registry.rb +1 -0
- data/lib/inquirex.rb +13 -0
- metadata +30 -4
|
@@ -6,6 +6,8 @@ module Inquirex
|
|
|
6
6
|
class LessThan < Base
|
|
7
7
|
attr_reader :field, :value
|
|
8
8
|
|
|
9
|
+
# @param field [Symbol, String] step id whose answer is compared
|
|
10
|
+
# @param value [Integer] threshold the answer must stay below
|
|
9
11
|
def initialize(field, value)
|
|
10
12
|
super()
|
|
11
13
|
@field = field.to_sym
|
|
@@ -13,18 +15,28 @@ module Inquirex
|
|
|
13
15
|
freeze
|
|
14
16
|
end
|
|
15
17
|
|
|
18
|
+
# True when the field's answer, coerced to an Integer, is below the threshold.
|
|
19
|
+
#
|
|
20
|
+
# @param answers [Hash{Symbol => Object}] answer context, step_id => value
|
|
21
|
+
# @return [Boolean]
|
|
16
22
|
def evaluate(answers)
|
|
17
23
|
answers[@field].to_i < @value
|
|
18
24
|
end
|
|
19
25
|
|
|
26
|
+
# @return [Hash{String => Object}] wire format, same shape .from_h accepts
|
|
20
27
|
def to_h
|
|
21
28
|
{ "op" => "less_than", "field" => @field.to_s, "value" => @value }
|
|
22
29
|
end
|
|
23
30
|
|
|
31
|
+
# @return [String] human-readable form, e.g. "dependents < 2"
|
|
24
32
|
def to_s
|
|
25
33
|
"#{@field} < #{@value}"
|
|
26
34
|
end
|
|
27
35
|
|
|
36
|
+
# Deserializes a LessThan rule from a plain Hash.
|
|
37
|
+
#
|
|
38
|
+
# @param hash [Hash] rule hash with string or symbol keys
|
|
39
|
+
# @return [LessThan]
|
|
28
40
|
def self.from_h(hash)
|
|
29
41
|
field = hash["field"] || hash[:field]
|
|
30
42
|
value = (hash["value"] || hash[:value]).to_i
|
|
@@ -6,12 +6,18 @@ module Inquirex
|
|
|
6
6
|
class NotEmpty < Base
|
|
7
7
|
attr_reader :field
|
|
8
8
|
|
|
9
|
+
# @param field [Symbol, String] step id whose answer is checked for presence
|
|
9
10
|
def initialize(field)
|
|
10
11
|
super()
|
|
11
12
|
@field = field.to_sym
|
|
12
13
|
freeze
|
|
13
14
|
end
|
|
14
15
|
|
|
16
|
+
# True when the field's answer is neither nil nor empty
|
|
17
|
+
# (empty String, Array, Hash, etc. all evaluate false).
|
|
18
|
+
#
|
|
19
|
+
# @param answers [Hash{Symbol => Object}] answer context, step_id => value
|
|
20
|
+
# @return [Boolean]
|
|
15
21
|
def evaluate(answers)
|
|
16
22
|
val = answers[@field]
|
|
17
23
|
return false if val.nil?
|
|
@@ -20,14 +26,20 @@ module Inquirex
|
|
|
20
26
|
true
|
|
21
27
|
end
|
|
22
28
|
|
|
29
|
+
# @return [Hash{String => Object}] wire format, same shape .from_h accepts
|
|
23
30
|
def to_h
|
|
24
31
|
{ "op" => "not_empty", "field" => @field.to_s }
|
|
25
32
|
end
|
|
26
33
|
|
|
34
|
+
# @return [String] human-readable form, e.g. "income_types is not empty"
|
|
27
35
|
def to_s
|
|
28
36
|
"#{@field} is not empty"
|
|
29
37
|
end
|
|
30
38
|
|
|
39
|
+
# Deserializes a NotEmpty rule from a plain Hash.
|
|
40
|
+
#
|
|
41
|
+
# @param hash [Hash] rule hash with string or symbol keys
|
|
42
|
+
# @return [NotEmpty]
|
|
31
43
|
def self.from_h(hash)
|
|
32
44
|
field = hash["field"] || hash[:field]
|
|
33
45
|
new(field)
|
|
@@ -5,6 +5,11 @@ module Inquirex
|
|
|
5
5
|
# No-op validator: always accepts any input.
|
|
6
6
|
# Used by default when no validation adapter is configured.
|
|
7
7
|
class NullAdapter < Adapter
|
|
8
|
+
# Accepts any input unconditionally.
|
|
9
|
+
#
|
|
10
|
+
# @param _node [Node] the current step (ignored)
|
|
11
|
+
# @param _input [Object] value submitted by the user (ignored)
|
|
12
|
+
# @return [Result] always valid, with no errors
|
|
8
13
|
def validate(_node, _input)
|
|
9
14
|
Result.new(valid: true)
|
|
10
15
|
end
|
data/lib/inquirex/version.rb
CHANGED
|
@@ -10,6 +10,7 @@ module Inquirex
|
|
|
10
10
|
# Adapters (TTY, JS, Rails) use this to pick an appropriate renderer when
|
|
11
11
|
# the DSL author has not specified an explicit `widget` hint.
|
|
12
12
|
module WidgetRegistry
|
|
13
|
+
# Every widget type an adapter may be asked to render, across all contexts.
|
|
13
14
|
WIDGET_TYPES = %i[
|
|
14
15
|
text_input
|
|
15
16
|
textarea
|
data/lib/inquirex.rb
CHANGED
|
@@ -24,16 +24,29 @@ require_relative "inquirex/accumulator"
|
|
|
24
24
|
require_relative "inquirex/node"
|
|
25
25
|
require_relative "inquirex/definition"
|
|
26
26
|
require_relative "inquirex/answers"
|
|
27
|
+
require_relative "inquirex/completion_metadata"
|
|
27
28
|
|
|
28
29
|
# Validation
|
|
29
30
|
require_relative "inquirex/validation/adapter"
|
|
30
31
|
require_relative "inquirex/validation/null_adapter"
|
|
31
32
|
|
|
33
|
+
# Post-completion actions
|
|
34
|
+
require_relative "inquirex/actions"
|
|
35
|
+
require_relative "inquirex/actions/template"
|
|
36
|
+
require_relative "inquirex/actions/outbox"
|
|
37
|
+
require_relative "inquirex/actions/base"
|
|
38
|
+
require_relative "inquirex/actions/send_email"
|
|
39
|
+
require_relative "inquirex/actions/webhook"
|
|
40
|
+
require_relative "inquirex/actions/custom"
|
|
41
|
+
require_relative "inquirex/actions/action"
|
|
42
|
+
require_relative "inquirex/actions/runner"
|
|
43
|
+
|
|
32
44
|
# DSL
|
|
33
45
|
require_relative "inquirex/dsl"
|
|
34
46
|
require_relative "inquirex/dsl/rule_helpers"
|
|
35
47
|
require_relative "inquirex/dsl/step_builder"
|
|
36
48
|
require_relative "inquirex/dsl/flow_builder"
|
|
49
|
+
require_relative "inquirex/dsl/action_builder"
|
|
37
50
|
|
|
38
51
|
# Engine
|
|
39
52
|
require_relative "inquirex/engine/state_serializer"
|
metadata
CHANGED
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: inquirex
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Konstantin Gredeskoul
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
-
dependencies:
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: ostruct
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0.6'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0.6'
|
|
12
26
|
description: Inquirex lets you define multi-step questionnaires as directed graphs
|
|
13
27
|
with conditional branching, using a conversational DSL (ask, say, mention) and an
|
|
14
28
|
AST-based rule system (contains, equals, greater_than, all, any). The engine walks
|
|
15
29
|
the graph, collects structured answers, and serializes everything to JSON — making
|
|
16
30
|
it the ideal backbone for cross-platform intake forms where the frontend is a chat
|
|
17
|
-
widget, a terminal, or a mobile app. Framework-agnostic,
|
|
18
|
-
immutable definitions.
|
|
31
|
+
widget, a terminal, or a mobile app. Framework-agnostic, no third-party dependencies,
|
|
32
|
+
thread-safe immutable definitions.
|
|
19
33
|
email:
|
|
20
34
|
- kigster@gmail.com
|
|
21
35
|
executables: []
|
|
@@ -35,14 +49,26 @@ files:
|
|
|
35
49
|
- examples/01_readme_example.rb
|
|
36
50
|
- examples/02_readme_mermaid.png
|
|
37
51
|
- examples/02_readme_mermaid.rb
|
|
52
|
+
- examples/03_send_email_actions.rb
|
|
38
53
|
- examples/README.md
|
|
39
54
|
- justfile
|
|
40
55
|
- lefthook.yml
|
|
41
56
|
- lib/inquirex.rb
|
|
42
57
|
- lib/inquirex/accumulator.rb
|
|
58
|
+
- lib/inquirex/actions.rb
|
|
59
|
+
- lib/inquirex/actions/action.rb
|
|
60
|
+
- lib/inquirex/actions/base.rb
|
|
61
|
+
- lib/inquirex/actions/custom.rb
|
|
62
|
+
- lib/inquirex/actions/outbox.rb
|
|
63
|
+
- lib/inquirex/actions/runner.rb
|
|
64
|
+
- lib/inquirex/actions/send_email.rb
|
|
65
|
+
- lib/inquirex/actions/template.rb
|
|
66
|
+
- lib/inquirex/actions/webhook.rb
|
|
43
67
|
- lib/inquirex/answers.rb
|
|
68
|
+
- lib/inquirex/completion_metadata.rb
|
|
44
69
|
- lib/inquirex/definition.rb
|
|
45
70
|
- lib/inquirex/dsl.rb
|
|
71
|
+
- lib/inquirex/dsl/action_builder.rb
|
|
46
72
|
- lib/inquirex/dsl/flow_builder.rb
|
|
47
73
|
- lib/inquirex/dsl/rule_helpers.rb
|
|
48
74
|
- lib/inquirex/dsl/step_builder.rb
|