thunderoperation 0.2.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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +3 -0
  3. data/config/default.yml +11 -0
  4. data/lib/rubocop/cop/thunderoperation/call_handlers.rb +56 -0
  5. data/lib/rubocop/cop/thunderoperation/def_outside_steps.rb +39 -0
  6. data/lib/rubocop/cop/thunderoperation/flow_required.rb +24 -0
  7. data/lib/rubocop/cop/thunderoperation/missing_steps.rb +42 -0
  8. data/lib/rubocop/cop/thunderoperation/operation_helpers.rb +124 -0
  9. data/lib/rubocop/cop/thunderoperation/operation_section_order.rb +51 -0
  10. data/lib/rubocop/cop/thunderoperation/steps_cannot_call_steps.rb +36 -0
  11. data/lib/rubocop/cop/thunderoperation/steps_order.rb +52 -0
  12. data/lib/rubocop/cop/thunderoperation/unknown_step.rb +61 -0
  13. data/lib/rubocop/cop/thunderoperation/unused_step.rb +29 -0
  14. data/lib/thunderoperation/adapter.rb +23 -0
  15. data/lib/thunderoperation/adapters/framer.rb +64 -0
  16. data/lib/thunderoperation/adapters/interruptable.rb +19 -0
  17. data/lib/thunderoperation/adapters/rich_parameters.rb +42 -0
  18. data/lib/thunderoperation/adapters/validations.rb +49 -0
  19. data/lib/thunderoperation/base.rb +144 -0
  20. data/lib/thunderoperation/clauses/base.rb +11 -0
  21. data/lib/thunderoperation/clauses/transaction.rb +11 -0
  22. data/lib/thunderoperation/clauses.rb +11 -0
  23. data/lib/thunderoperation/concerns/has_adapter.rb +47 -0
  24. data/lib/thunderoperation/config.rb +30 -0
  25. data/lib/thunderoperation/exceptions/trail.rb +27 -0
  26. data/lib/thunderoperation/exceptions.rb +32 -0
  27. data/lib/thunderoperation/flow/builder.rb +31 -0
  28. data/lib/thunderoperation/flow.rb +57 -0
  29. data/lib/thunderoperation/handlers.rb +43 -0
  30. data/lib/thunderoperation/lookup.rb +13 -0
  31. data/lib/thunderoperation/parameters/array_parameter.rb +48 -0
  32. data/lib/thunderoperation/parameters/base.rb +92 -0
  33. data/lib/thunderoperation/parameters/hash_parameter.rb +154 -0
  34. data/lib/thunderoperation/parameters.rb +11 -0
  35. data/lib/thunderoperation/response.rb +62 -0
  36. data/lib/thunderoperation/rubocop.rb +31 -0
  37. data/lib/thunderoperation/steps/base.rb +44 -0
  38. data/lib/thunderoperation/steps/clause.rb +32 -0
  39. data/lib/thunderoperation/steps/method.rb +34 -0
  40. data/lib/thunderoperation/steps/render.rb +22 -0
  41. data/lib/thunderoperation/steps/success.rb +29 -0
  42. data/lib/thunderoperation/steps.rb +33 -0
  43. data/lib/thunderoperation/steps_definition.rb +75 -0
  44. data/lib/thunderoperation/version.rb +5 -0
  45. data/lib/thunderoperation.rb +36 -0
  46. metadata +108 -0
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThunderOperation
4
+ module Parameters
5
+ class HashParameter < Base
6
+ attr_reader :configuration
7
+
8
+ def initialize(_type = nil, options = {}, &block)
9
+ super(Hash, options)
10
+
11
+ @configuration = {}
12
+
13
+ instance_exec(&block) if block
14
+ check_map_declaration!
15
+ end
16
+
17
+ def param(field_name, *, &)
18
+ @configuration[field_name.to_sym] = self.class.from_args(*, &)
19
+ end
20
+
21
+ # WARN: AI MADE
22
+ # The word of returns and event payloads (`returns Hash do field :title, String end`); params keep `param`.
23
+ alias field param
24
+
25
+ # A nested Hash read from an object's association when an external operation renders its result; elsewhere,
26
+ # the same as `field name, Hash do ... end`.
27
+ def association(field_name, options = {}, &)
28
+ field(field_name, Hash, options, &)
29
+ end
30
+
31
+ # WARN: AI MADE
32
+ # A map: `keys Date` and `values Integer` (or `values Hash do ... end`), for a Hash whose keys are data (dates,
33
+ # ids); a Hash with fixed keys declares them with `field`. A protobuf `map`.
34
+ def keys(*args)
35
+ return @keys if args.empty?
36
+
37
+ @keys = Base.from_args(*args)
38
+ end
39
+
40
+ def values(*args, &)
41
+ return @values if args.empty? && !block_given?
42
+
43
+ @values = Base.from_args(*args, &)
44
+ end
45
+
46
+ def map? = !@keys.nil? || !@values.nil?
47
+
48
+ def output_keys
49
+ @configuration.map { |field_name, parameter| parameter.options[:as] || field_name }
50
+ end
51
+
52
+ def filter(value)
53
+ return FILTERED if sensitive?
54
+ return value if value.nil?
55
+ return value.transform_values { |item| @values.filter(item) } if map?
56
+ return value if @configuration.empty?
57
+
58
+ filter_fields(value)
59
+ end
60
+
61
+ def sanitize(value, path: nil)
62
+ validate!(value, path:)
63
+
64
+ return if value.nil?
65
+ return sanitize_map(value, path) if map?
66
+ return value if @configuration.empty?
67
+
68
+ @configuration.filter_map { |field_name, parameter| sanitize_field(value, field_name, parameter, path) }.to_h
69
+ end
70
+
71
+ # WARN: AI MADE
72
+ def resolve_types!(&)
73
+ @configuration.each_value { |parameter| parameter.resolve_types!(&) }
74
+ @keys&.resolve_types!(&)
75
+ @values&.resolve_types!(&)
76
+ end
77
+
78
+ def check!(value, path: nil)
79
+ validate!(value, path:)
80
+ return if value.nil?
81
+ return check_map!(value, path) if map?
82
+ return if @configuration.empty?
83
+
84
+ unknown = value.keys.map(&:to_sym) - @configuration.keys
85
+ if unknown.any?
86
+ field_path = [path, unknown.first].compact.join('.')
87
+ raise Exceptions::ParameterError.new("Unknown field '#{field_path}'", field: field_path)
88
+ end
89
+
90
+ @configuration.each { |field_name, parameter| check_field!(value, field_name, parameter, path) }
91
+ end
92
+
93
+ private
94
+
95
+ # WARN: AI MADE
96
+ def check_map_declaration!
97
+ return unless map?
98
+ raise Exceptions::DeclarationError, 'a map declares both keys and values' if @keys.nil? || @values.nil?
99
+ return if @configuration.empty?
100
+
101
+ raise Exceptions::DeclarationError, 'a Hash declares fields or keys/values, not both'
102
+ end
103
+
104
+ def filter_fields(value)
105
+ @configuration.filter_map do |field_name, parameter|
106
+ key = parameter.options[:as] || field_name
107
+ [key, parameter.filter(value[key])] if value.key?(key)
108
+ end.to_h
109
+ end
110
+
111
+ def check_map!(value, path)
112
+ value.each do |key, item|
113
+ @keys.check!(key, path: "#{path}[#{key}]")
114
+ @values.check!(item, path: "#{path}[#{key}]")
115
+ end
116
+ end
117
+
118
+ def sanitize_map(value, path)
119
+ value.to_h do |key, item|
120
+ [@keys.sanitize(key, path: "#{path}[#{key}]"), @values.sanitize(item, path: "#{path}[#{key}]")]
121
+ end
122
+ end
123
+
124
+ def check_field!(value, field_name, parameter, path)
125
+ key = input_key(value, field_name)
126
+ field_path = path ? "#{path}.#{field_name}" : field_name.to_s
127
+
128
+ if key
129
+ parameter.check!(value[key], path: field_path)
130
+ elsif parameter.required?
131
+ raise Exceptions::ParameterError.new("Required field '#{field_path}' is missing", field: field_path)
132
+ end
133
+ end
134
+
135
+ def sanitize_field(value, field_name, parameter, path)
136
+ key = input_key(value, field_name)
137
+ field_path = path ? "#{path}.#{field_name}" : field_name.to_s
138
+
139
+ if key
140
+ [parameter.options[:as] || field_name, parameter.sanitize(value[key], path: field_path)]
141
+ elsif parameter.required?
142
+ raise Exceptions::ParameterError.new("Required field '#{field_path}' is missing", field: field_path)
143
+ end
144
+ end
145
+
146
+ def input_key(value, field_name)
147
+ return field_name if value.key?(field_name)
148
+
149
+ string_key = field_name.name
150
+ string_key if value.key?(string_key)
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThunderOperation
4
+ module Parameters
5
+ extend Lookup
6
+
7
+ def self.for_type(type)
8
+ resolve("#{type.name}Parameter", base: Base) if type
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThunderOperation
4
+ Response = Data.define(
5
+ :payload,
6
+ :was_success,
7
+ :error,
8
+ :status,
9
+ :headers,
10
+ :failed_step,
11
+ :operation_name
12
+ ) do
13
+ def initialize(error: nil, status: nil, headers: nil, failed_step: nil, **args)
14
+ super(**args, error:, status:, headers:, failed_step:)
15
+ end
16
+
17
+ def success?
18
+ was_success
19
+ end
20
+
21
+ def failure?
22
+ !was_success
23
+ end
24
+
25
+ alias_method :failed?, :failure?
26
+
27
+ def failure_message
28
+ error&.message
29
+ end
30
+
31
+ def failure_extras
32
+ error.extras if error.respond_to?(:extras)
33
+ end
34
+
35
+ def trail
36
+ return [] unless error.respond_to?(:operation_trail)
37
+
38
+ error.operation_trail.map(&:to_s)
39
+ end
40
+
41
+ def interrupted?
42
+ error.is_a?(Exceptions::Interruption)
43
+ end
44
+
45
+ def failure_data
46
+ return unless error
47
+
48
+ {
49
+ failed_step:,
50
+ trail:,
51
+ failure_message: error.message,
52
+ error_class: error.class.name,
53
+ operation_name:,
54
+ failure_extras:
55
+ }
56
+ end
57
+
58
+ def to_h
59
+ super.merge(failure_data:)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Entry point for `require: thunderoperation/rubocop` in .rubocop.yml: cops for the operation DSL.
4
+ require 'rubocop'
5
+
6
+ # WARN: AI MADE
7
+ # The defaults in config/default.yml, merged into RuboCop's own, so a project only has to load the cops.
8
+ module ThunderOperation
9
+ module RuboCop
10
+ CONFIG_DEFAULT = File.expand_path('../../config/default.yml', __dir__)
11
+
12
+ def self.inject_defaults!
13
+ hash = ::RuboCop::ConfigLoader.send(:load_yaml_configuration, CONFIG_DEFAULT)
14
+ config = ::RuboCop::ConfigLoader.merge_with_default(::RuboCop::Config.new(hash, CONFIG_DEFAULT), CONFIG_DEFAULT)
15
+ ::RuboCop::ConfigLoader.instance_variable_set(:@default_configuration, config)
16
+ end
17
+ end
18
+ end
19
+
20
+ ThunderOperation::RuboCop.inject_defaults!
21
+
22
+ require_relative '../rubocop/cop/thunderoperation/operation_helpers'
23
+ require_relative '../rubocop/cop/thunderoperation/operation_section_order'
24
+ require_relative '../rubocop/cop/thunderoperation/flow_required'
25
+ require_relative '../rubocop/cop/thunderoperation/unknown_step'
26
+ require_relative '../rubocop/cop/thunderoperation/missing_steps'
27
+ require_relative '../rubocop/cop/thunderoperation/unused_step'
28
+ require_relative '../rubocop/cop/thunderoperation/steps_order'
29
+ require_relative '../rubocop/cop/thunderoperation/steps_cannot_call_steps'
30
+ require_relative '../rubocop/cop/thunderoperation/def_outside_steps'
31
+ require_relative '../rubocop/cop/thunderoperation/call_handlers'
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThunderOperation
4
+ module Steps
5
+ class Base
6
+ def self.build(_name, *args, **kwargs)
7
+ new(*args, **kwargs)
8
+ end
9
+
10
+ def self.step_name
11
+ @step_name ||= name.demodulize.underscore.to_sym
12
+ end
13
+
14
+ def initialize
15
+ freeze
16
+ end
17
+
18
+ def name
19
+ self.class.step_name
20
+ end
21
+
22
+ def run(_instance)
23
+ raise NotImplementedError, "#{self.class.name}#run"
24
+ end
25
+
26
+ def to_s
27
+ name.to_s
28
+ end
29
+
30
+ def inspect
31
+ "#<#{self.class.name} #{self}>"
32
+ end
33
+
34
+ protected
35
+
36
+ def signature(name, args, kwargs)
37
+ rendered = args.map(&:inspect) + kwargs.map { |key, value| "#{key}: #{value.inspect}" }
38
+ return name.to_s if rendered.empty?
39
+
40
+ "#{name}(#{rendered.join(', ')})"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThunderOperation
4
+ module Steps
5
+ class Clause < Base
6
+ attr_reader :name, :handler, :args, :kwargs, :flow
7
+
8
+ def initialize(name, handler, *args, **kwargs, &block)
9
+ raise ArgumentError, "clause `#{name}` requires a block" unless block
10
+
11
+ @name = name.to_sym
12
+ @handler = handler
13
+ @args = args.freeze
14
+ @kwargs = kwargs.freeze
15
+ @flow = Flow.build(&block)
16
+ super()
17
+ end
18
+
19
+ def steps
20
+ flow.steps
21
+ end
22
+
23
+ def run(instance)
24
+ handler.call(instance, *args, **kwargs) { flow.run(instance) }
25
+ end
26
+
27
+ def to_s
28
+ "#{signature(name, args, kwargs)} { #{flow} }"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThunderOperation
4
+ module Steps
5
+ class Method < Base
6
+ attr_reader :name, :args, :kwargs
7
+
8
+ def self.build(name, *args, **kwargs)
9
+ new(name, *args, **kwargs)
10
+ end
11
+
12
+ def initialize(name, *args, **kwargs)
13
+ @name = name.to_sym
14
+ @args = args.freeze
15
+ @kwargs = kwargs.freeze
16
+ super()
17
+ end
18
+
19
+ def run(instance)
20
+ if args.empty? && kwargs.empty?
21
+ instance.send(name)
22
+ else
23
+ instance.send(name, *args, **kwargs)
24
+ end
25
+
26
+ nil
27
+ end
28
+
29
+ def to_s
30
+ signature(name, args, kwargs)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThunderOperation
4
+ module Steps
5
+ class Render < Success
6
+ attr_reader :status
7
+
8
+ def initialize(payload = nil, status: nil)
9
+ @status = status
10
+ super(payload)
11
+ end
12
+
13
+ def run(instance)
14
+ instance._success(resolve(instance), status:)
15
+ end
16
+
17
+ def to_s
18
+ signature(:render, payload.nil? ? [] : [payload], status ? { status: } : {})
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThunderOperation
4
+ module Steps
5
+ class Success < Base
6
+ attr_reader :payload
7
+
8
+ def initialize(payload = nil)
9
+ @payload = payload
10
+ @ivar = :"@#{payload}" if payload.is_a?(Symbol)
11
+ super()
12
+ end
13
+
14
+ def run(instance)
15
+ instance._success(resolve(instance))
16
+ end
17
+
18
+ def to_s
19
+ payload.nil? ? 'success' : "success(#{payload.inspect})"
20
+ end
21
+
22
+ protected
23
+
24
+ def resolve(instance)
25
+ @ivar ? instance.instance_variable_get(@ivar) : payload
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThunderOperation
4
+ module Steps
5
+ extend Lookup
6
+
7
+ INTERNAL = %w[Base Method Clause].freeze
8
+
9
+ class << self
10
+ def build(name, *args, **kwargs, &block)
11
+ return build_clause(name, *args, **kwargs, &block) if block
12
+
13
+ (lookup(name) || Method).build(name, *args, **kwargs)
14
+ end
15
+
16
+ def lookup(name)
17
+ resolve(name, base: Base, except: INTERNAL)
18
+ end
19
+
20
+ private
21
+
22
+ def build_clause(name, *args, **kwargs, &block)
23
+ handler = Clauses.lookup(name)
24
+ unless handler
25
+ raise ArgumentError,
26
+ "unknown clause `#{name}`; define ThunderOperation::Clauses::#{name.to_s.camelize}"
27
+ end
28
+
29
+ Clause.new(name, handler, *args, **kwargs, &block)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThunderOperation
4
+ class StepsDefinition
5
+ include Enumerable
6
+
7
+ MODULE_NAME = :StepMethods
8
+
9
+ class Methods < Module
10
+ attr_reader :names
11
+
12
+ def initialize
13
+ super
14
+ @names = []
15
+ end
16
+
17
+ def method_added(name)
18
+ super
19
+ @names << name unless @names.include?(name)
20
+ private(name)
21
+ end
22
+ end
23
+
24
+ attr_reader :owner, :methods_module
25
+
26
+ def self.build(owner, &block)
27
+ methods_module = methods_module_for(owner)
28
+ methods_module.class_exec(&block)
29
+
30
+ new(owner, methods_module)
31
+ end
32
+
33
+ def self.methods_module_for(owner)
34
+ return owner.const_get(MODULE_NAME, false) if owner.const_defined?(MODULE_NAME, false)
35
+
36
+ Methods.new.tap do |methods_module|
37
+ owner.const_set(MODULE_NAME, methods_module)
38
+ owner.include(methods_module)
39
+ end
40
+ end
41
+ private_class_method :methods_module_for
42
+
43
+ def initialize(owner, methods_module)
44
+ @owner = owner
45
+ @methods_module = methods_module
46
+ freeze
47
+ end
48
+
49
+ def names
50
+ methods_module.respond_to?(:names) ? methods_module.names : []
51
+ end
52
+
53
+ def each(&)
54
+ names.each(&)
55
+ end
56
+
57
+ def include?(name)
58
+ names.include?(name.to_sym)
59
+ end
60
+
61
+ def instance_method(name)
62
+ methods_module.instance_method(name)
63
+ end
64
+
65
+ def empty?
66
+ names.empty?
67
+ end
68
+
69
+ def to_s
70
+ names.join(', ')
71
+ end
72
+
73
+ NONE = new(nil, Module.new.freeze)
74
+ end
75
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThunderOperation
4
+ VERSION = '0.2.0'
5
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'active_support/core_ext/string/inflections'
5
+ require 'thunderframe'
6
+
7
+ require_relative 'thunderoperation/version'
8
+ require_relative 'thunderoperation/config'
9
+ require_relative 'thunderoperation/lookup'
10
+ require_relative 'thunderoperation/exceptions'
11
+ require_relative 'thunderoperation/exceptions/trail'
12
+ require_relative 'thunderoperation/response'
13
+ require_relative 'thunderoperation/handlers'
14
+ require_relative 'thunderoperation/adapter'
15
+ require_relative 'thunderoperation/concerns/has_adapter'
16
+ require_relative 'thunderoperation/parameters'
17
+ require_relative 'thunderoperation/parameters/base'
18
+ require_relative 'thunderoperation/parameters/hash_parameter'
19
+ require_relative 'thunderoperation/parameters/array_parameter'
20
+ require_relative 'thunderoperation/adapters/rich_parameters'
21
+ require_relative 'thunderoperation/adapters/interruptable'
22
+ require_relative 'thunderoperation/adapters/validations'
23
+ require_relative 'thunderoperation/adapters/framer'
24
+ require_relative 'thunderoperation/steps'
25
+ require_relative 'thunderoperation/steps/base'
26
+ require_relative 'thunderoperation/steps/method'
27
+ require_relative 'thunderoperation/steps/clause'
28
+ require_relative 'thunderoperation/steps/success'
29
+ require_relative 'thunderoperation/steps/render'
30
+ require_relative 'thunderoperation/clauses'
31
+ require_relative 'thunderoperation/clauses/base'
32
+ require_relative 'thunderoperation/clauses/transaction'
33
+ require_relative 'thunderoperation/flow'
34
+ require_relative 'thunderoperation/flow/builder'
35
+ require_relative 'thunderoperation/steps_definition'
36
+ require_relative 'thunderoperation/base'
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thunderoperation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Albert Alef
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: activesupport
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '8.1'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '8.1'
26
+ - !ruby/object:Gem::Dependency
27
+ name: thunderframe
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - '='
31
+ - !ruby/object:Gem::Version
32
+ version: 0.2.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - '='
38
+ - !ruby/object:Gem::Version
39
+ version: 0.2.0
40
+ executables: []
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - README.md
45
+ - config/default.yml
46
+ - lib/rubocop/cop/thunderoperation/call_handlers.rb
47
+ - lib/rubocop/cop/thunderoperation/def_outside_steps.rb
48
+ - lib/rubocop/cop/thunderoperation/flow_required.rb
49
+ - lib/rubocop/cop/thunderoperation/missing_steps.rb
50
+ - lib/rubocop/cop/thunderoperation/operation_helpers.rb
51
+ - lib/rubocop/cop/thunderoperation/operation_section_order.rb
52
+ - lib/rubocop/cop/thunderoperation/steps_cannot_call_steps.rb
53
+ - lib/rubocop/cop/thunderoperation/steps_order.rb
54
+ - lib/rubocop/cop/thunderoperation/unknown_step.rb
55
+ - lib/rubocop/cop/thunderoperation/unused_step.rb
56
+ - lib/thunderoperation.rb
57
+ - lib/thunderoperation/adapter.rb
58
+ - lib/thunderoperation/adapters/framer.rb
59
+ - lib/thunderoperation/adapters/interruptable.rb
60
+ - lib/thunderoperation/adapters/rich_parameters.rb
61
+ - lib/thunderoperation/adapters/validations.rb
62
+ - lib/thunderoperation/base.rb
63
+ - lib/thunderoperation/clauses.rb
64
+ - lib/thunderoperation/clauses/base.rb
65
+ - lib/thunderoperation/clauses/transaction.rb
66
+ - lib/thunderoperation/concerns/has_adapter.rb
67
+ - lib/thunderoperation/config.rb
68
+ - lib/thunderoperation/exceptions.rb
69
+ - lib/thunderoperation/exceptions/trail.rb
70
+ - lib/thunderoperation/flow.rb
71
+ - lib/thunderoperation/flow/builder.rb
72
+ - lib/thunderoperation/handlers.rb
73
+ - lib/thunderoperation/lookup.rb
74
+ - lib/thunderoperation/parameters.rb
75
+ - lib/thunderoperation/parameters/array_parameter.rb
76
+ - lib/thunderoperation/parameters/base.rb
77
+ - lib/thunderoperation/parameters/hash_parameter.rb
78
+ - lib/thunderoperation/response.rb
79
+ - lib/thunderoperation/rubocop.rb
80
+ - lib/thunderoperation/steps.rb
81
+ - lib/thunderoperation/steps/base.rb
82
+ - lib/thunderoperation/steps/clause.rb
83
+ - lib/thunderoperation/steps/method.rb
84
+ - lib/thunderoperation/steps/render.rb
85
+ - lib/thunderoperation/steps/success.rb
86
+ - lib/thunderoperation/steps_definition.rb
87
+ - lib/thunderoperation/version.rb
88
+ licenses: []
89
+ metadata:
90
+ rubygems_mfa_required: 'true'
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '3.4'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubygems_version: 3.6.9
106
+ specification_version: 4
107
+ summary: 'Operations engine: param, flow, steps, returns, adapters'
108
+ test_files: []