servactory 1.6.14 → 1.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a9d23fed4bbdc5728e707c47939ccfd2ed055c3bf052300908d09816ce580b7
4
- data.tar.gz: e64b68886cb0e74706fddf989f1facedf37fd6020419f1d11f533229688b55f1
3
+ metadata.gz: ff122141adf96c61aac5e2c89b9ca1ea0644ec4a9e106737e114108adbf06e17
4
+ data.tar.gz: 04d8ab68d2ce909e7b2ab9b92e3c4cd0c356385b87fd6f1b17040d16b22f9c43
5
5
  SHA512:
6
- metadata.gz: b108bb63a08baef6a09e11aa85f93407ce857a309e6d7e816a089db79285df5020a216ee3c4a1bef5ab87dd82951058514d11fbcd6c6b7682e2d984170545856
7
- data.tar.gz: 6ae5e3e1ab815608900749693d010397c584439f809e71aac8ccbf00007285b625bcbe258a45cec22c95f3ef340e5f1b0f202b1747d71cbe7902f3707a85ec06
6
+ metadata.gz: 3eea6b5733b7a80ceeac63a5fd9e16492367da3d3bd3ffbbdda343791578a788388eb1b77873595fc710d7ca0a62985a971d2e1ba02d1048b35dede880ce63e6
7
+ data.tar.gz: 35a1dee0a933768875c583678019c6f62cecc4b05fe7ffaf000edd3a01596a6dba18fa0111cce3b876013994e492b91e05062e7690a01ebfdd9b3f415325e3b6
data/README.md CHANGED
@@ -24,7 +24,7 @@ class UserService::Authenticate < ApplicationService::Base
24
24
 
25
25
  def call
26
26
  if (user = User.find_by(email: inputs.email)&.authenticate(inputs.password))
27
- self.user = user
27
+ outputs.user = user
28
28
  else
29
29
  fail!(message: "Authentication failed")
30
30
  end
@@ -27,7 +27,6 @@ module Servactory
27
27
  def default_input_option_helpers
28
28
  Set[
29
29
  Servactory::Inputs::OptionHelper.new(name: :optional, equivalent: { required: false }),
30
- Servactory::Inputs::OptionHelper.new(name: :internal, equivalent: { internal: true }),
31
30
  Servactory::Inputs::OptionHelper.new(name: :as_array, equivalent: { array: true })
32
31
  ]
33
32
  end
@@ -16,8 +16,6 @@ module Servactory
16
16
  collection_of_internals: collection_of_internals
17
17
  )
18
18
 
19
- prepare_data
20
-
21
19
  inputs_workbench.validate!
22
20
 
23
21
  methods_workbench.run!
@@ -43,8 +41,6 @@ module Servactory
43
41
  collection_of_internals: collection_of_internals
44
42
  )
45
43
 
46
- prepare_data
47
-
48
44
  inputs_workbench.validate!
49
45
 
50
46
  methods_workbench.run!
@@ -69,12 +65,6 @@ module Servactory
69
65
  outputs_workbench.assign(context: context_store.context)
70
66
  methods_workbench.assign(context: context_store.context)
71
67
  end
72
-
73
- def prepare_data
74
- inputs_workbench.prepare # 1
75
- outputs_workbench.prepare # 2
76
- internals_workbench.prepare # 3
77
- end
78
68
  end
79
69
  end
80
70
  end
@@ -3,9 +3,46 @@
3
3
  module Servactory
4
4
  module Context
5
5
  module Workspace
6
+ # class Inputs
7
+ # def initialize(**)
8
+ # # NOTE: Look at the file `lib/servactory/inputs/tools/prepare.rb`
9
+ # end
10
+ # end
11
+
6
12
  class Inputs
7
- def initialize(**)
8
- # NOTE: Look at the file `lib/servactory/inputs/tools/prepare.rb`
13
+ def initialize(context, workbench:)
14
+ @context = context
15
+
16
+ @collection_of_inputs = workbench.collection
17
+ @incoming_arguments = workbench.incoming_arguments
18
+ end
19
+
20
+ def method_missing(name, *args, &block)
21
+ if name.to_s.end_with?("=")
22
+ super
23
+ else
24
+ getter_with(name: name) { super }
25
+ end
26
+ end
27
+
28
+ def respond_to_missing?(name, *)
29
+ @collection_of_inputs.names.include?(name) || super
30
+ end
31
+
32
+ private
33
+
34
+ def getter_with(name:, &block) # rubocop:disable Lint/UnusedMethodArgument
35
+ input = @collection_of_inputs.find_by(name: name)
36
+
37
+ return yield if input.nil?
38
+
39
+ input_value = @incoming_arguments.fetch(input.name, nil)
40
+ input_value = input.default if input.optional? && input_value.blank?
41
+
42
+ input_prepare = input.prepare.fetch(:in, nil)
43
+ input_value = input_prepare.call(value: input_value) if input_prepare.present?
44
+
45
+ input_value
9
46
  end
10
47
  end
11
48
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Context
5
+ module Workspace
6
+ class Internals
7
+ def initialize(context, workbench:)
8
+ @context = context
9
+ @collection_of_internals = workbench.collection
10
+ end
11
+
12
+ def method_missing(name, *args, &block)
13
+ if name.to_s.end_with?("=")
14
+ setter_with(name: name, value: args.pop) { super }
15
+ else
16
+ getter_with(name: name) { super }
17
+ end
18
+ end
19
+
20
+ def respond_to_missing?(name, *)
21
+ @collection_of_internals.names.include?(name) || super
22
+ end
23
+
24
+ private
25
+
26
+ def setter_with(name:, value:, &block) # rubocop:disable Lint/UnusedMethodArgument
27
+ prepared_name = name.to_s.delete("=").to_sym
28
+
29
+ return yield unless @collection_of_internals.names.include?(prepared_name)
30
+
31
+ internal = @collection_of_internals.find_by(name: prepared_name)
32
+
33
+ Servactory::Internals::Validations::Type.validate!(
34
+ context: @context,
35
+ internal: internal,
36
+ value: value
37
+ )
38
+
39
+ @context.instance_variable_set(:"@#{internal.name}", value)
40
+ end
41
+
42
+ def getter_with(name:, &block) # rubocop:disable Lint/UnusedMethodArgument
43
+ internal = @collection_of_internals.find_by(name: name)
44
+
45
+ return yield if internal.nil?
46
+
47
+ @context.instance_variable_get(:"@#{internal.name}")
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Context
5
+ module Workspace
6
+ class Outputs
7
+ def initialize(context, workbench:)
8
+ @context = context
9
+ @collection_of_outputs = workbench.collection
10
+ end
11
+
12
+ def method_missing(name, *args, &block)
13
+ if name.to_s.end_with?("=")
14
+ setter_with(name: name, value: args.pop) { super }
15
+ else
16
+ getter_with(name: name) { super }
17
+ end
18
+ end
19
+
20
+ def respond_to_missing?(name, *)
21
+ @collection_of_outputs.names.include?(name) || super
22
+ end
23
+
24
+ private
25
+
26
+ def setter_with(name:, value:, &block) # rubocop:disable Lint/UnusedMethodArgument
27
+ prepared_name = name.to_s.delete("=").to_sym
28
+
29
+ return yield unless @collection_of_outputs.names.include?(prepared_name)
30
+
31
+ output = @collection_of_outputs.find_by(name: prepared_name)
32
+
33
+ Servactory::Outputs::Validations::Type.validate!(
34
+ context: @context,
35
+ output: output,
36
+ value: value
37
+ )
38
+
39
+ @context.instance_variable_set(:"@#{output.name}", value)
40
+ end
41
+
42
+ def getter_with(name:, &block) # rubocop:disable Lint/UnusedMethodArgument
43
+ output = @collection_of_outputs.find_by(name: name)
44
+
45
+ return yield if output.nil?
46
+
47
+ @context.instance_variable_get(:"@#{output.name}")
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -3,12 +3,23 @@
3
3
  module Servactory
4
4
  module Context
5
5
  module Workspace
6
- def errors
7
- @errors ||= Servactory::Errors::Collection.new
6
+ def inputs
7
+ @inputs ||= Inputs.new(self, workbench: self.class.send(:inputs_workbench))
8
8
  end
9
+ alias inp inputs
9
10
 
10
- def assign_inputs(inputs)
11
- @inputs = inputs
11
+ def internals
12
+ @internals ||= Internals.new(self, workbench: self.class.send(:internals_workbench))
13
+ end
14
+ alias int internals
15
+
16
+ def outputs
17
+ @outputs ||= Outputs.new(self, workbench: self.class.send(:outputs_workbench))
18
+ end
19
+ alias out outputs
20
+
21
+ def errors
22
+ @errors ||= Servactory::Errors::Collection.new
12
23
  end
13
24
 
14
25
  def raise_first_fail
@@ -19,8 +30,6 @@ module Servactory
19
30
 
20
31
  protected
21
32
 
22
- attr_reader :inputs
23
-
24
33
  def fail_input!(input_name, message:)
25
34
  raise Servactory.configuration.input_error_class.new(
26
35
  input_name: input_name,
@@ -5,7 +5,7 @@ module Servactory
5
5
  class Collection
6
6
  # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
7
7
  extend Forwardable
8
- def_delegators :@collection, :<<, :each, :map, :merge
8
+ def_delegators :@collection, :<<, :each, :map, :merge, :find
9
9
 
10
10
  def initialize(*)
11
11
  @collection = Set.new
@@ -14,6 +14,10 @@ module Servactory
14
14
  def names
15
15
  map(&:name)
16
16
  end
17
+
18
+ def find_by(name:)
19
+ find { |input| input.internal_name == name }
20
+ end
17
21
  end
18
22
  end
19
23
  end
@@ -3,12 +3,15 @@
3
3
  module Servactory
4
4
  module Inputs
5
5
  class Workbench
6
+ attr_reader :collection,
7
+ :incoming_arguments
8
+
6
9
  def self.work_with(...)
7
10
  new(...)
8
11
  end
9
12
 
10
- def initialize(collection_of_inputs)
11
- @collection_of_inputs = collection_of_inputs
13
+ def initialize(collection)
14
+ @collection = collection
12
15
  end
13
16
 
14
17
  def assign(context:, arguments:)
@@ -17,25 +20,20 @@ module Servactory
17
20
  end
18
21
 
19
22
  def find_unnecessary!
20
- Tools::FindUnnecessary.validate!(context, @incoming_arguments, collection_of_inputs)
23
+ Tools::FindUnnecessary.validate!(context, @incoming_arguments, collection)
21
24
  end
22
25
 
23
26
  def check_rules!
24
- Tools::Rules.validate!(context, collection_of_inputs)
25
- end
26
-
27
- def prepare
28
- Tools::Prepare.prepare(context, @incoming_arguments, collection_of_inputs)
27
+ Tools::Rules.validate!(context, collection)
29
28
  end
30
29
 
31
30
  def validate!
32
- Tools::Validation.validate!(context, @incoming_arguments, collection_of_inputs)
31
+ Tools::Validation.validate!(context, @incoming_arguments, collection)
33
32
  end
34
33
 
35
34
  private
36
35
 
37
- attr_reader :context,
38
- :collection_of_inputs
36
+ attr_reader :context
39
37
  end
40
38
  end
41
39
  end
@@ -5,7 +5,7 @@ module Servactory
5
5
  class Collection
6
6
  # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
7
7
  extend Forwardable
8
- def_delegators :@collection, :<<, :each, :map, :merge
8
+ def_delegators :@collection, :<<, :each, :map, :merge, :find
9
9
 
10
10
  def initialize(*)
11
11
  @collection = Set.new
@@ -14,6 +14,10 @@ module Servactory
14
14
  def names
15
15
  map(&:name)
16
16
  end
17
+
18
+ def find_by(name:)
19
+ find { |internal| internal.name == name }
20
+ end
17
21
  end
18
22
  end
19
23
  end
@@ -3,26 +3,23 @@
3
3
  module Servactory
4
4
  module Internals
5
5
  class Workbench
6
+ attr_reader :collection
7
+
6
8
  def self.work_with(...)
7
9
  new(...)
8
10
  end
9
11
 
10
- def initialize(collection_of_internals)
11
- @collection_of_internals = collection_of_internals
12
+ def initialize(collection)
13
+ @collection = collection
12
14
  end
13
15
 
14
16
  def assign(context:)
15
17
  @context = context
16
18
  end
17
19
 
18
- def prepare
19
- Tools::Prepare.prepare(context, collection_of_internals)
20
- end
21
-
22
20
  private
23
21
 
24
- attr_reader :context,
25
- :collection_of_internals
22
+ attr_reader :context
26
23
  end
27
24
  end
28
25
  end
@@ -5,7 +5,7 @@ module Servactory
5
5
  class Collection
6
6
  # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
7
7
  extend Forwardable
8
- def_delegators :@collection, :<<, :each, :map, :merge
8
+ def_delegators :@collection, :<<, :each, :map, :merge, :find
9
9
 
10
10
  def initialize(*)
11
11
  @collection = Set.new
@@ -14,6 +14,10 @@ module Servactory
14
14
  def names
15
15
  map(&:name)
16
16
  end
17
+
18
+ def find_by(name:)
19
+ find { |output| output.name == name }
20
+ end
17
21
  end
18
22
  end
19
23
  end
@@ -3,12 +3,14 @@
3
3
  module Servactory
4
4
  module Outputs
5
5
  class Workbench
6
+ attr_reader :collection
7
+
6
8
  def self.work_with(...)
7
9
  new(...)
8
10
  end
9
11
 
10
- def initialize(collection_of_outputs)
11
- @collection_of_outputs = collection_of_outputs
12
+ def initialize(collection)
13
+ @collection = collection
12
14
  end
13
15
 
14
16
  def assign(context:)
@@ -16,16 +18,12 @@ module Servactory
16
18
  end
17
19
 
18
20
  def find_conflicts_in!(collection_of_internals:)
19
- Tools::Conflicts.validate!(context, collection_of_outputs, collection_of_internals)
20
- end
21
-
22
- def prepare
23
- Tools::Prepare.prepare(context, collection_of_outputs)
21
+ Tools::Conflicts.validate!(context, collection, collection_of_internals)
24
22
  end
25
23
 
26
24
  private
27
25
 
28
- attr_reader :context, :collection_of_outputs
26
+ attr_reader :context
29
27
  end
30
28
  end
31
29
  end
@@ -3,8 +3,8 @@
3
3
  module Servactory
4
4
  module VERSION
5
5
  MAJOR = 1
6
- MINOR = 6
7
- PATCH = 14
6
+ MINOR = 7
7
+ PATCH = 0
8
8
 
9
9
  STRING = [MAJOR, MINOR, PATCH].join(".")
10
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: servactory
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.14
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Sokolov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-16 00:00:00.000000000 Z
11
+ date: 2023-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -198,6 +198,8 @@ files:
198
198
  - lib/servactory/context/store.rb
199
199
  - lib/servactory/context/workspace.rb
200
200
  - lib/servactory/context/workspace/inputs.rb
201
+ - lib/servactory/context/workspace/internals.rb
202
+ - lib/servactory/context/workspace/outputs.rb
201
203
  - lib/servactory/engine.rb
202
204
  - lib/servactory/errors/base.rb
203
205
  - lib/servactory/errors/collection.rb
@@ -218,7 +220,6 @@ files:
218
220
  - lib/servactory/inputs/options_collection.rb
219
221
  - lib/servactory/inputs/tools/check_errors.rb
220
222
  - lib/servactory/inputs/tools/find_unnecessary.rb
221
- - lib/servactory/inputs/tools/prepare.rb
222
223
  - lib/servactory/inputs/tools/rules.rb
223
224
  - lib/servactory/inputs/tools/validation.rb
224
225
  - lib/servactory/inputs/validations/base.rb
@@ -231,7 +232,6 @@ files:
231
232
  - lib/servactory/internals/collection.rb
232
233
  - lib/servactory/internals/dsl.rb
233
234
  - lib/servactory/internals/internal.rb
234
- - lib/servactory/internals/tools/prepare.rb
235
235
  - lib/servactory/internals/validations/base.rb
236
236
  - lib/servactory/internals/validations/type.rb
237
237
  - lib/servactory/internals/workbench.rb
@@ -246,7 +246,6 @@ files:
246
246
  - lib/servactory/outputs/dsl.rb
247
247
  - lib/servactory/outputs/output.rb
248
248
  - lib/servactory/outputs/tools/conflicts.rb
249
- - lib/servactory/outputs/tools/prepare.rb
250
249
  - lib/servactory/outputs/validations/base.rb
251
250
  - lib/servactory/outputs/validations/type.rb
252
251
  - lib/servactory/outputs/workbench.rb
@@ -1,93 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Servactory
4
- module Inputs
5
- module Tools
6
- class Prepare
7
- def self.prepare(...)
8
- new(...).prepare
9
- end
10
-
11
- def initialize(context, incoming_arguments, collection_of_inputs)
12
- @context = context
13
- @incoming_arguments = incoming_arguments
14
- @collection_of_inputs = collection_of_inputs
15
- end
16
-
17
- def prepare
18
- @inputs_variables = {}
19
- @internal_variables = {}
20
-
21
- @collection_of_inputs.each do |input|
22
- process_input(input)
23
- end
24
-
25
- create_instance_variables
26
- end
27
-
28
- private
29
-
30
- def process_input(input)
31
- input_value = @incoming_arguments.fetch(input.name, nil)
32
- input_value = input.default if input.optional? && input_value.blank?
33
-
34
- input_prepare = input.prepare.fetch(:in, nil)
35
- input_value = input_prepare.call(value: input_value) if input_prepare.present?
36
-
37
- if input.internal?
38
- @internal_variables[input.name] = input_value
39
- else
40
- @inputs_variables[input.internal_name] = input_value
41
- end
42
- end
43
-
44
- def create_instance_variables
45
- inputs_class = Servactory::Context::Workspace::Inputs.dup
46
- inputs_class.class_eval(class_inputs_template) if class_inputs_template.present?
47
-
48
- @context.assign_inputs(inputs_class.new(**@inputs_variables))
49
-
50
- @context.class.class_eval(context_internal_variables_template) if context_internal_variables_template.present?
51
-
52
- @internal_variables.each do |input_name, input_value|
53
- @context.instance_variable_set(:"@#{input_name}", input_value)
54
- end
55
- end
56
-
57
- ########################################################################
58
-
59
- # EXAMPLE:
60
- #
61
- # attr_reader(*[:attr_1, :attr_2, :attr_3])
62
- #
63
- # def initialize(attr_1:, attr_2:, attr_3:)
64
- # @attr_1 = attr_1; @attr_2 = attr_2; @attr_3 = attr_3;
65
- # end
66
- #
67
- def class_inputs_template
68
- return if @inputs_variables.blank?
69
-
70
- @class_inputs_template ||= <<-RUBY
71
- attr_reader(*#{@inputs_variables.keys})
72
-
73
- def initialize(#{@inputs_variables.keys.join(':, ')}:)
74
- #{@inputs_variables.keys.map { |key| "@#{key} = #{key}" }.join('; ')}
75
- end
76
- RUBY
77
- end
78
-
79
- # EXAMPLE:
80
- #
81
- # attr_reader(*[:attr_1])
82
- #
83
- def context_internal_variables_template
84
- return if @internal_variables.blank?
85
-
86
- @context_internal_variables_template ||= <<-RUBY
87
- attr_reader(*#{@internal_variables.keys})
88
- RUBY
89
- end
90
- end
91
- end
92
- end
93
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Servactory
4
- module Internals
5
- module Tools
6
- class Prepare
7
- def self.prepare(...)
8
- new(...).prepare
9
- end
10
-
11
- def initialize(context, collection_of_internals)
12
- @context = context
13
- @collection_of_internals = collection_of_internals
14
- end
15
-
16
- def prepare
17
- @collection_of_internals.each do |internal|
18
- create_instance_variable_for(internal)
19
- end
20
- end
21
-
22
- private
23
-
24
- def create_instance_variable_for(internal)
25
- @context.class.class_eval(context_internal_template_for(internal))
26
- end
27
-
28
- # EXAMPLE:
29
- #
30
- # define_method(:user=) do |value|
31
- # Servactory::Internals::Validations::Type.validate!( context: self, internal:, value: )
32
- #
33
- # instance_variable_set(:@user, value)
34
- # end
35
- #
36
- # private attr_reader :user
37
- #
38
- def context_internal_template_for(internal)
39
- <<-RUBY
40
- define_method(:#{internal.name}=) do |value|
41
- Servactory::Internals::Validations::Type.validate!(
42
- context: self,
43
- internal: internal,
44
- value: value
45
- )
46
-
47
- instance_variable_set(:@#{internal.name}, value)
48
- end
49
-
50
- private
51
-
52
- attr_reader :#{internal.name}
53
- RUBY
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Servactory
4
- module Outputs
5
- module Tools
6
- class Prepare
7
- def self.prepare(...)
8
- new(...).prepare
9
- end
10
-
11
- def initialize(context, collection_of_outputs)
12
- @context = context
13
- @collection_of_outputs = collection_of_outputs
14
- end
15
-
16
- def prepare
17
- @collection_of_outputs.each do |output|
18
- create_instance_variable_for(output)
19
- end
20
- end
21
-
22
- private
23
-
24
- def create_instance_variable_for(output)
25
- @context.class.class_eval(context_output_template_for(output))
26
- end
27
-
28
- # EXAMPLE:
29
- #
30
- # define_method(:user=) do |value|
31
- # Servactory::Internals::Validations::Type.validate!( context: self, output:, value: )
32
- #
33
- # instance_variable_set(:@user, value)
34
- # end
35
- #
36
- def context_output_template_for(output)
37
- <<-RUBY
38
- define_method(:#{output.name}=) do |value|
39
- Servactory::Outputs::Validations::Type.validate!(
40
- context: self,
41
- output: output,
42
- value: value
43
- )
44
-
45
- instance_variable_set(:@#{output.name}, value)
46
- end
47
-
48
- attr_reader :#{output.name}
49
- RUBY
50
- end
51
- end
52
- end
53
- end
54
- end