servactory 1.6.14 → 1.7.1

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: 8a9d23fed4bbdc5728e707c47939ccfd2ed055c3bf052300908d09816ce580b7
4
- data.tar.gz: e64b68886cb0e74706fddf989f1facedf37fd6020419f1d11f533229688b55f1
3
+ metadata.gz: 16aa240b4c12f35c6cf2c43e1c5d56bdd39e19d40321ad3f66ac0bdd6ebcf110
4
+ data.tar.gz: ad3418afd34e75c869424708dd080c27b192b6ffdc6770485e74fa70047a6620
5
5
  SHA512:
6
- metadata.gz: b108bb63a08baef6a09e11aa85f93407ce857a309e6d7e816a089db79285df5020a216ee3c4a1bef5ab87dd82951058514d11fbcd6c6b7682e2d984170545856
7
- data.tar.gz: 6ae5e3e1ab815608900749693d010397c584439f809e71aac8ccbf00007285b625bcbe258a45cec22c95f3ef340e5f1b0f202b1747d71cbe7902f3707a85ec06
6
+ metadata.gz: 472eb5c2643cdb648e57ae8586e6a06795da73b90f7b0a2fcac30c43f02c932ba897f01fe0707707846b93b8131d4f16d7d0b143b4e3e08988dc7e5891cbaca3
7
+ data.tar.gz: e25034c6b2d4c166e27c9db570db16e1436ff7cca39de6a9cb8ce6a8754f835968c2afe21b9ee287a31661e3801715503a78c09294974cabd893da07137c8f1a
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
@@ -43,7 +43,7 @@ class SessionsController < ApplicationController
43
43
  session[:current_user_id] = service_result.user.id
44
44
  redirect_to service_result.user
45
45
  else
46
- flash.now[:message] = service_result.errors.first.message
46
+ flash.now[:message] = service_result.error.message
47
47
  render :new
48
48
  end
49
49
  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,27 @@
3
3
  module Servactory
4
4
  module Context
5
5
  module Workspace
6
+ def inputs
7
+ @inputs ||= Inputs.new(self, workbench: self.class.send(:inputs_workbench))
8
+ end
9
+ alias inp inputs
10
+
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
+
6
21
  def errors
7
22
  @errors ||= Servactory::Errors::Collection.new
8
23
  end
9
24
 
10
- def assign_inputs(inputs)
11
- @inputs = inputs
25
+ def error
26
+ errors.first
12
27
  end
13
28
 
14
29
  def raise_first_fail
@@ -19,8 +34,6 @@ module Servactory
19
34
 
20
35
  protected
21
36
 
22
- attr_reader :inputs
23
-
24
37
  def fail_input!(input_name, message:)
25
38
  raise Servactory.configuration.input_error_class.new(
26
39
  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
@@ -25,6 +25,7 @@ module Servactory
25
25
 
26
26
  def prepare_statuses_with(context:)
27
27
  define_singleton_method(:errors) { context.errors }
28
+ define_singleton_method(:error) { context.error }
28
29
  define_singleton_method(:success?) { context.errors.empty? }
29
30
  define_singleton_method(:failure?) { !context.errors.empty? }
30
31
  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 = 1
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.1
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-18 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