activeinteractor 2.0.0.alpha.2.3.1 → 2.0.0.alpha.2.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8af4270754db50c59e2c28fd5877446d12e1d15617ff8ce2dc67b97a0a95830
4
- data.tar.gz: 43d1b328973b54ef6623db8e216a2d5a6d84098582ccb674e998ae181b88171a
3
+ metadata.gz: c7e53178ed391a9de1b1841a29f7655f66aa61e70d54e3a00df830550f71c70a
4
+ data.tar.gz: 462c26605e5db213de957fa7d6afd076849b500e93e4dc45f2ea0cc57a927ba5
5
5
  SHA512:
6
- metadata.gz: 5a9e727d815c173b8be85a47cf65110a48e5e3e65bf370764a29d12060f5da85e2b4a444f35e87c15e4c328795834f3e315a351993deb46fad1d8e7432b78a06
7
- data.tar.gz: 655d2a8362d581afb7074b8b00abbd97e496071bb5ce373dd4f475c04e881dc5a8406d4ecd95d7921c29d5e2346aaac7b6f532f54a2c7b31223f5dee38a4ab9f
6
+ metadata.gz: 278fbc63da4056d07904f48547e4ac40942e380194294d1836dbe866c665e16799e12e2fbcd1f47efc65ccfaab80bb84ce2c91e40ca53395e1648cd7d0cdcf9c
7
+ data.tar.gz: d35e2da1526d2b9f069227b72e048e2c55c38995dd539760b8338e8087afd487afe0257e45551b33921895781a16d04022d9c56cda2b8ef9294b0e95ec9d46de
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveInteractor
4
- module HasActiveModelErrors
4
+ module ActiveModelErrorMethods
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  attr_reader :errors
@@ -1,112 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveInteractor
4
- class Base
5
- include Type::HasTypes
6
-
7
- class << self
8
- delegate :argument, :argument_names, :arguments, to: :input_context_class
9
- delegate :returns, :field_names, :fields, to: :output_context_class
10
-
11
- def input_context_class
12
- @input_context_class ||= const_set(:InputContext, Class.new(Context::Input))
13
- end
14
-
15
- def accepts_arguments_matching(set_input_context_class)
16
- @input_context_class = set_input_context_class
17
- end
18
- alias input_context accepts_arguments_matching
19
-
20
- def output_context_class
21
- @output_context_class ||= const_set(:OutputContext, Class.new(Context::Output))
22
- end
23
-
24
- def perform!(input_context = {})
25
- new(input_context).perform!
26
- end
27
-
28
- def perform(input_context = {})
29
- perform!(input_context)
30
- rescue Error => e
31
- e.result
32
- rescue StandardError => e
33
- Result.failure(errors: e.message)
34
- end
35
-
36
- def returns_data_matching(set_output_context_class)
37
- @output_context_class = set_output_context_class
38
- end
39
- alias output_context returns_data_matching
40
-
41
- def runtime_context_class
42
- @runtime_context_class ||= begin
43
- context_class = const_set(:RuntimeContext, Class.new(Context::Runtime))
44
- context_class.send(:attribute_set).merge(input_context_class.send(:attribute_set).attributes)
45
- context_class.send(:attribute_set).merge(output_context_class.send(:attribute_set).attributes)
46
- context_class
47
- end
48
- end
49
- end
50
-
51
- def initialize(input = {})
52
- @raw_input = input.dup
53
- validate_input_and_generate_runtime_context!
54
- end
55
-
56
- def perform!
57
- with_notification(:perform) do |payload|
58
- interact
59
- generate_and_validate_output_context!
60
- payload[:result] = Result.success(data: @output)
61
- end
62
- end
63
-
64
- def perform
65
- perform!
66
- rescue Error => e
67
- e.result
68
- rescue StandardError => e
69
- Result.failure(errors: e.message)
70
- end
71
-
72
- def interact; end
73
- def rollback; end
74
-
75
- protected
76
-
77
- attr_accessor :context
78
-
79
- def fail!(errors = {})
80
- result = nil
81
- with_notification(:rollback) do |payload|
82
- rollback
83
- result = Result.failure(data: parse_output!, errors: errors)
84
- payload[:result] = result
85
- end
86
-
87
- raise Error, result
88
- end
89
-
90
- def generate_and_validate_output_context!
91
- @output = self.class.output_context_class.new(context.attributes)
92
- @output.validate!
93
- return @output if @output.errors.empty?
94
-
95
- raise Error, Result.failure(errors: @output.errors, status: Result::STATUS[:failed_at_output])
96
- end
97
-
98
- def validate_input_and_generate_runtime_context!
99
- @input = self.class.input_context_class.new(@raw_input)
100
- @input.validate!
101
- return (@context = self.class.runtime_context_class.new(@raw_input)) if @input.errors.empty?
102
-
103
- raise Error, Result.failure(errors: @input.errors, status: Result::STATUS[:failed_at_input])
104
- end
105
-
106
- def with_notification(action)
107
- ActiveSupport::Notifications.instrument("#{self.class.name}::#{action.to_s.classify}") do |payload|
108
- yield payload if block_given?
109
- end
110
- end
4
+ class Base < ActiveInteractor::Interactor::Base
5
+ include Type::DeclerationMethods
111
6
  end
112
7
  end
@@ -36,16 +36,14 @@ module ActiveInteractor
36
36
  "wrong number of arguments (given #{arguments.length}, expected 1)"
37
37
  end
38
38
 
39
- assign_attribute_value(method_name, arguments.first)
39
+ assign_attribute_value(method_name.to_s.delete('=').to_sym, arguments.first)
40
40
  end
41
41
 
42
- def method_missing(method_id, *arguments)
43
- return super unless respond_to_missing?(method_id)
42
+ def method_missing(method_name, *arguments)
43
+ return super unless respond_to_missing?(method_name)
44
+ return assignment_method_missing(method_name, *arguments) if method_name.to_s.end_with?('=')
44
45
 
45
- method_name = method_id[/.*(?==\z)/m]
46
- return assignment_method_missing(method_name, *arguments) if method_name
47
-
48
- read_attribute_value(method_id)
46
+ read_attribute_value(method_name)
49
47
  end
50
48
 
51
49
  def read_attribute_value(attribute_name)
@@ -57,7 +55,7 @@ module ActiveInteractor
57
55
 
58
56
  def respond_to_missing?(method_name, _include_private = false)
59
57
  return true if attribute_set.attribute_names.include?(method_name.to_sym)
60
- return true if attribute_set.attribute_names.include?(method_name[/.*(?==\z)/m]&.to_sym)
58
+ return true if attribute_set.attribute_names.include?(method_name.to_s.delete('=').to_sym)
61
59
 
62
60
  super
63
61
  end
@@ -3,11 +3,10 @@
3
3
  module ActiveInteractor
4
4
  module Context
5
5
  class Base
6
- include ActiveModel::Validations
7
- include HasActiveModelErrors
6
+ include ActiveModelErrorMethods
8
7
  include AttributeRegistration
9
8
  include AttributeAssignment
10
- include Type::HasTypes
9
+ include Type::DeclerationMethods
11
10
 
12
11
  def initialize(attributes = {})
13
12
  super
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInteractor
4
+ module Context
5
+ class Result
6
+ def self.register_owner(owner)
7
+ owner.const_set(:ResultContext, Class.new(self))
8
+ end
9
+
10
+ def self.for_output_context(owner, context)
11
+ context.fields.each_key { |field| owner::ResultContext.send(:attr_reader, field) }
12
+ owner::ResultContext.new(context.fields)
13
+ end
14
+
15
+ def initialize(attributes = {})
16
+ attributes.each_pair { |key, value| instance_variable_set(:"@#{key}", value) }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -28,11 +28,10 @@ module ActiveInteractor
28
28
  @table[attribute_name.to_sym] = value
29
29
  end
30
30
 
31
- def method_missing(method_id, *arguments)
32
- method_name = method_id[/.*(?==\z)/m]
33
- return assignment_method_missing(method_name, *arguments) if method_name
31
+ def method_missing(method_name, *arguments)
32
+ return assignment_method_missing(method_name, *arguments) if method_name.to_s.end_with?('=')
34
33
 
35
- read_attribute_value(method_id)
34
+ read_attribute_value(method_name)
36
35
  end
37
36
 
38
37
  def read_attribute_value(attribute_name)
@@ -11,6 +11,7 @@ module ActiveInteractor
11
11
  autoload :Base
12
12
  autoload :Input
13
13
  autoload :Output
14
+ autoload :Result
14
15
  autoload :Runtime
15
16
  end
16
17
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInteractor
4
+ module Interactor
5
+ class Base
6
+ include ContextMethods
7
+ include InteractionMethods
8
+
9
+ def initialize(input = {})
10
+ @raw_input = input.dup
11
+ validate_input_and_generate_runtime_context!
12
+ end
13
+
14
+ def perform!
15
+ with_notification(:perform) do |payload|
16
+ interact
17
+ generate_and_validate_output_context!
18
+ payload[:result] = Result.success(data: output_to_result_context!)
19
+ end
20
+ end
21
+
22
+ protected
23
+
24
+ def fail!(errors = {})
25
+ result = nil
26
+ with_notification(:rollback) do |payload|
27
+ rollback
28
+ result = Result.failure(data: parse_output!, errors: errors)
29
+ payload[:result] = result
30
+ end
31
+
32
+ raise Error, result
33
+ end
34
+
35
+ def with_notification(action)
36
+ ActiveSupport::Notifications.instrument("#{self.class.name}::#{action.to_s.classify}") do |payload|
37
+ yield payload if block_given?
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInteractor
4
+ module Interactor
5
+ module ContextMethods
6
+ extend ActiveSupport::Concern
7
+
8
+ module ClassMethods
9
+ delegate :argument, :argument_names, :arguments, to: :input_context_class
10
+ delegate :returns, :field_names, :fields, to: :output_context_class
11
+
12
+ def input_context_class
13
+ @input_context_class ||= const_set(:InputContext, Class.new(Context::Input))
14
+ end
15
+
16
+ def accepts_arguments_matching(set_input_context_class)
17
+ @input_context_class = set_input_context_class
18
+ end
19
+ alias input_context accepts_arguments_matching
20
+ alias input_type accepts_arguments_matching
21
+
22
+ def output_context_class
23
+ @output_context_class ||= const_set(:OutputContext, Class.new(Context::Output))
24
+ end
25
+
26
+ def returns_data_matching(set_output_context_class)
27
+ @output_context_class = set_output_context_class
28
+ end
29
+ alias output_context returns_data_matching
30
+ alias output_type returns_data_matching
31
+
32
+ def runtime_context_class
33
+ @runtime_context_class ||= begin
34
+ context_class = const_set(:RuntimeContext, Class.new(Context::Runtime))
35
+ context_class.send(:attribute_set).merge(input_context_class.send(:attribute_set).attributes)
36
+ context_class.send(:attribute_set).merge(output_context_class.send(:attribute_set).attributes)
37
+ context_class
38
+ end
39
+ end
40
+
41
+ protected
42
+
43
+ def result_context
44
+ @result_context ||= Context::Result.register_owner(self)
45
+ end
46
+ end
47
+
48
+ included do
49
+ extend ClassMethods
50
+
51
+ protected
52
+
53
+ attr_reader :context
54
+ end
55
+
56
+ protected # rubocop:disable Lint/UselessAccessModifier
57
+
58
+ def generate_and_validate_output_context!
59
+ @output = self.class.output_context_class.new(context.attributes)
60
+ @output.validate!
61
+ return if @output.errors.empty?
62
+
63
+ raise Error, Result.failure(errors: @output.errors, status: Result::STATUS[:failed_at_output])
64
+ end
65
+
66
+ def output_to_result_context!
67
+ self.class.send(:result_context).for_output_context(self.class, @output)
68
+ end
69
+
70
+ def validate_input_and_generate_runtime_context!
71
+ @input = self.class.input_context_class.new(@raw_input)
72
+ @input.validate!
73
+ return (@context = self.class.runtime_context_class.new(@raw_input)) if @input.errors.empty?
74
+
75
+ raise Error, Result.failure(errors: @input.errors, status: Result::STATUS[:failed_at_input])
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInteractor
4
+ module Interactor
5
+ module InteractionMethods
6
+ extend ActiveSupport::Concern
7
+
8
+ module ClassMethods
9
+ def perform!(input_context = {})
10
+ new(input_context).perform!
11
+ end
12
+
13
+ def perform(input_context = {})
14
+ perform!(input_context)
15
+ rescue Error => e
16
+ e.result
17
+ rescue StandardError => e
18
+ Result.failure(errors: e.message)
19
+ end
20
+ end
21
+
22
+ included do
23
+ extend ClassMethods
24
+ end
25
+
26
+ def perform
27
+ perform!
28
+ rescue Error => e
29
+ e.result
30
+ rescue StandardError => e
31
+ Result.failure(errors: e.message)
32
+ end
33
+
34
+ def interact; end
35
+ def rollback; end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInteractor
4
+ module Interactor
5
+ extend ActiveSupport::Autoload
6
+
7
+ autoload :Base
8
+ autoload :ContextMethods
9
+ autoload :InteractionMethods
10
+ end
11
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ActiveInteractor
4
4
  class Result
5
- include HasActiveModelErrors
5
+ include ActiveModelErrorMethods
6
6
 
7
7
  delegate :to_json, to: :to_hash
8
8
 
@@ -68,7 +68,7 @@ module ActiveInteractor
68
68
  {
69
69
  success: success?,
70
70
  errors: errors.to_hash,
71
- data: data.to_hash
71
+ data: data.to_json
72
72
  }
73
73
  end
74
74
  alias to_h to_hash
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ActiveInteractor
4
4
  module Type
5
- module HasTypes
5
+ module DeclerationMethods
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  Boolean = ActiveInteractor::Type::Boolean
@@ -6,7 +6,7 @@ module ActiveInteractor
6
6
 
7
7
  autoload :Base
8
8
  autoload :Boolean
9
- autoload :HasTypes
9
+ autoload :DeclerationMethods
10
10
  autoload :List
11
11
  autoload :Union
12
12
  end
@@ -9,9 +9,10 @@ require_relative 'active_interactor/errors'
9
9
  module ActiveInteractor
10
10
  extend ActiveSupport::Autoload
11
11
 
12
+ autoload :ActiveModelErrorMethods
12
13
  autoload :Base
13
14
  autoload :Context
14
- autoload :HasActiveModelErrors
15
+ autoload :Interactor
15
16
  autoload :Result
16
17
  autoload :Type
17
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeinteractor
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.alpha.2.3.1
4
+ version: 2.0.0.alpha.2.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Allen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-12 00:00:00.000000000 Z
11
+ date: 2023-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -63,6 +63,7 @@ files:
63
63
  - LICENSE
64
64
  - README.md
65
65
  - lib/active_interactor.rb
66
+ - lib/active_interactor/active_model_error_methods.rb
66
67
  - lib/active_interactor/base.rb
67
68
  - lib/active_interactor/context.rb
68
69
  - lib/active_interactor/context/attribute.rb
@@ -72,14 +73,18 @@ files:
72
73
  - lib/active_interactor/context/base.rb
73
74
  - lib/active_interactor/context/input.rb
74
75
  - lib/active_interactor/context/output.rb
76
+ - lib/active_interactor/context/result.rb
75
77
  - lib/active_interactor/context/runtime.rb
76
78
  - lib/active_interactor/errors.rb
77
- - lib/active_interactor/has_active_model_errors.rb
79
+ - lib/active_interactor/interactor.rb
80
+ - lib/active_interactor/interactor/base.rb
81
+ - lib/active_interactor/interactor/context_methods.rb
82
+ - lib/active_interactor/interactor/interaction_methods.rb
78
83
  - lib/active_interactor/result.rb
79
84
  - lib/active_interactor/type.rb
80
85
  - lib/active_interactor/type/base.rb
81
86
  - lib/active_interactor/type/boolean.rb
82
- - lib/active_interactor/type/has_types.rb
87
+ - lib/active_interactor/type/decleration_methods.rb
83
88
  - lib/active_interactor/type/list.rb
84
89
  - lib/active_interactor/type/union.rb
85
90
  - sig/active_interactor.rbs
@@ -88,9 +93,9 @@ licenses:
88
93
  - MIT
89
94
  metadata:
90
95
  bug_tracker_uri: https://github.com/activeinteractor/activeinteractor/issues
91
- changelog_uri: https://github.com/activeinteractor/activeinteractor/blob/v2.0.0-alpha.2.3.1/CHANGELOG.md
96
+ changelog_uri: https://github.com/activeinteractor/activeinteractor/blob/v2.0.0-alpha.2.3.3/CHANGELOG.md
92
97
  homepage_uri: https://github.com/activeinteractor/activeinteractor
93
- source_code_uri: https://github.com/activeinteractor/activeinteractor/tree/v2.0.0-alpha.2.3.1
98
+ source_code_uri: https://github.com/activeinteractor/activeinteractor/tree/v2.0.0-alpha.2.3.3
94
99
  wiki_uri: https://github.com/activeinteractor/activeinteractor/wiki
95
100
  rubygems_mfa_required: 'true'
96
101
  post_install_message: