servactory 1.7.1 → 1.8.1

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: 16aa240b4c12f35c6cf2c43e1c5d56bdd39e19d40321ad3f66ac0bdd6ebcf110
4
- data.tar.gz: ad3418afd34e75c869424708dd080c27b192b6ffdc6770485e74fa70047a6620
3
+ metadata.gz: 1a4b777f0ef9ef743ab9af34ced8c2170a96585ecbb4fc6fdb290c07afc05ebf
4
+ data.tar.gz: 01e57d03342d0aa21bd4d49782dcbf9107ae94be2f2761511845313023bf6865
5
5
  SHA512:
6
- metadata.gz: 472eb5c2643cdb648e57ae8586e6a06795da73b90f7b0a2fcac30c43f02c932ba897f01fe0707707846b93b8131d4f16d7d0b143b4e3e08988dc7e5891cbaca3
7
- data.tar.gz: e25034c6b2d4c166e27c9db570db16e1436ff7cca39de6a9cb8ce6a8754f835968c2afe21b9ee287a31661e3801715503a78c09294974cabd893da07137c8f1a
6
+ metadata.gz: af1bd571ef3ad8941778c32fde6cd76eafcc8afc01f2966a2517b05d2dfcd51cdd108b6c0168af019e56094d98eaa3d75a530c85874eedcb6aeeb5aacda7e823
7
+ data.tar.gz: cafe7ad733b25bf2bf1e27ee8809a6f659c127fbd4bdb0ae9bffdb9240e9d2671b6217867442834351461f0a6ace6435a4bc9d42bd2b0e0ad31ff93d4bf232c1
data/README.md CHANGED
@@ -9,12 +9,18 @@ A set of tools for building reliable services of any complexity.
9
9
 
10
10
  See [servactory.com](https://servactory.com) for documentation.
11
11
 
12
- ## Examples
12
+ ## Example
13
+
14
+ ### Installation
15
+
16
+ ```ruby
17
+ gem "servactory"
18
+ ```
13
19
 
14
20
  ### Service
15
21
 
16
22
  ```ruby
17
- class UserService::Authenticate < ApplicationService::Base
23
+ class UserService::Authenticate < Servactory::Base
18
24
  input :email, type: String
19
25
  input :password, type: String
20
26
 
@@ -32,7 +38,7 @@ class UserService::Authenticate < ApplicationService::Base
32
38
  end
33
39
  ```
34
40
 
35
- ### Using in controller
41
+ ### Usage
36
42
 
37
43
  ```ruby
38
44
  class SessionsController < ApplicationController
@@ -58,8 +64,10 @@ end
58
64
 
59
65
  ## Contributing
60
66
 
61
- This project is intended to be a safe, welcoming space for collaboration. Contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. We recommend reading the [contributing guide](./website/docs/CONTRIBUTING.md) as well.
67
+ This project is intended to be a safe, welcoming space for collaboration.
68
+ Contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
69
+ We recommend reading the [contributing guide](./website/docs/CONTRIBUTING.md) as well.
62
70
 
63
71
  ## License
64
72
 
65
- ViewComponent is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
73
+ Servactory is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -23,8 +23,12 @@ module Servactory
23
23
  Servactory.configuration.input_option_helpers.merge(input_option_helpers)
24
24
  end
25
25
 
26
- def method_shortcuts(method_shortcuts)
27
- Servactory.configuration.method_shortcuts.merge(method_shortcuts)
26
+ def aliases_for_make(aliases_for_make)
27
+ Servactory.configuration.aliases_for_make.merge(aliases_for_make)
28
+ end
29
+
30
+ def shortcuts_for_make(shortcuts_for_make)
31
+ Servactory.configuration.shortcuts_for_make.merge(shortcuts_for_make)
28
32
  end
29
33
  end
30
34
  end
@@ -8,7 +8,8 @@ module Servactory
8
8
  :output_error_class,
9
9
  :failure_class,
10
10
  :input_option_helpers,
11
- :method_shortcuts
11
+ :aliases_for_make,
12
+ :shortcuts_for_make
12
13
 
13
14
  def initialize
14
15
  @input_error_class = Servactory::Errors::InputError
@@ -19,7 +20,8 @@ module Servactory
19
20
 
20
21
  @input_option_helpers = Servactory::Inputs::OptionHelpersCollection.new(default_input_option_helpers)
21
22
 
22
- @method_shortcuts = Servactory::Methods::Shortcuts::Collection.new
23
+ @aliases_for_make = Servactory::Methods::AliasesForMake::Collection.new
24
+ @shortcuts_for_make = Servactory::Methods::ShortcutsForMake::Collection.new
23
25
  end
24
26
 
25
27
  private
@@ -6,8 +6,6 @@ module Servactory
6
6
  def call!(arguments = {}) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
7
7
  @context_store = Store.new(self)
8
8
 
9
- context_store.context.send(:assign_service_strict_mode, true)
10
-
11
9
  assign_data_with(arguments)
12
10
 
13
11
  inputs_workbench.find_unnecessary!
@@ -20,9 +18,7 @@ module Servactory
20
18
 
21
19
  methods_workbench.run!
22
20
 
23
- context_store.context.raise_first_fail
24
-
25
- Servactory::Result.prepare_for(
21
+ Servactory::Result.success_for(
26
22
  context: context_store.context,
27
23
  collection_of_outputs: collection_of_outputs
28
24
  )
@@ -31,8 +27,6 @@ module Servactory
31
27
  def call(arguments = {}) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
32
28
  @context_store = Store.new(self)
33
29
 
34
- context_store.context.send(:assign_service_strict_mode, false)
35
-
36
30
  assign_data_with(arguments)
37
31
 
38
32
  inputs_workbench.find_unnecessary!
@@ -45,10 +39,12 @@ module Servactory
45
39
 
46
40
  methods_workbench.run!
47
41
 
48
- Servactory::Result.prepare_for(
42
+ Servactory::Result.success_for(
49
43
  context: context_store.context,
50
44
  collection_of_outputs: collection_of_outputs
51
45
  )
46
+ rescue Servactory.configuration.failure_class => e
47
+ Servactory::Result.failure_for(exception: e)
52
48
  end
53
49
 
54
50
  private
@@ -18,20 +18,6 @@ module Servactory
18
18
  end
19
19
  alias out outputs
20
20
 
21
- def errors
22
- @errors ||= Servactory::Errors::Collection.new
23
- end
24
-
25
- def error
26
- errors.first
27
- end
28
-
29
- def raise_first_fail
30
- return if (tmp_errors = errors.for_fails.not_blank).empty?
31
-
32
- raise tmp_errors.first
33
- end
34
-
35
21
  protected
36
22
 
37
23
  def fail_input!(input_name, message:)
@@ -41,22 +27,8 @@ module Servactory
41
27
  )
42
28
  end
43
29
 
44
- def fail!(
45
- message:,
46
- failure_class: Servactory.configuration.failure_class,
47
- meta: nil
48
- )
49
- failure = failure_class.new(message: message, meta: meta)
50
-
51
- raise failure if @service_strict_mode
52
-
53
- errors << failure
54
- end
55
-
56
- private
57
-
58
- def assign_service_strict_mode(flag)
59
- @service_strict_mode = flag
30
+ def fail!(message:, meta: nil)
31
+ raise Servactory.configuration.failure_class.new(message: message, meta: meta)
60
32
  end
61
33
  end
62
34
  end
@@ -24,14 +24,20 @@ module Servactory
24
24
  options = apply_helpers_for_options(helpers: helpers, options: options) if helpers.present?
25
25
 
26
26
  add_basic_options_with(type: type, options: options)
27
+ end
28
+ # rubocop:enable Style/KeywordParametersOrder
27
29
 
28
- collection_of_options.each do |option|
29
- self.class.attr_reader(:"#{option.name}")
30
+ def method_missing(name, *args, &block)
31
+ option = collection_of_options.find_by(name: name)
30
32
 
31
- instance_variable_set(:"@#{option.name}", option.value)
32
- end
33
+ return super if option.nil?
34
+
35
+ option.value
36
+ end
37
+
38
+ def respond_to_missing?(name, *)
39
+ collection_of_options.names.include?(name) || super
33
40
  end
34
- # rubocop:enable Style/KeywordParametersOrder
35
41
 
36
42
  def apply_helpers_for_options(helpers:, options:)
37
43
  prepared_options = {}
@@ -5,12 +5,16 @@ module Servactory
5
5
  class OptionsCollection
6
6
  # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
7
7
  extend Forwardable
8
- def_delegators :@collection, :<<, :filter, :each, :map, :flat_map
8
+ def_delegators :@collection, :<<, :filter, :each, :map, :flat_map, :find
9
9
 
10
10
  def initialize(*)
11
11
  @collection = Set.new
12
12
  end
13
13
 
14
+ def names
15
+ map(&:name)
16
+ end
17
+
14
18
  def validation_classes
15
19
  filter { |option| option.validation_class.present? }.map(&:validation_class).uniq
16
20
  end
@@ -34,6 +38,10 @@ module Servactory
34
38
  end
35
39
  end.reject(&:blank?).first
36
40
  end
41
+
42
+ def find_by(name:)
43
+ find { |option| option.name == name }
44
+ end
37
45
  end
38
46
  end
39
47
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Methods
5
+ module AliasesForMake
6
+ class Collection
7
+ # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
8
+ extend Forwardable
9
+ def_delegators :@collection, :<<, :merge, :include?
10
+
11
+ def initialize(*)
12
+ @collection = Set.new
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -58,9 +58,28 @@ module Servactory
58
58
  collection_of_stages << @current_stage
59
59
  end
60
60
 
61
- def method_missing(shortcut_name, *args, &block)
62
- return super unless Servactory.configuration.method_shortcuts.include?(shortcut_name)
61
+ def method_missing(name, *args, &block)
62
+ if Servactory.configuration.aliases_for_make.include?(name)
63
+ return method_missing_for_aliases_for_make(name, *args, &block)
64
+ end
65
+
66
+ if Servactory.configuration.shortcuts_for_make.include?(name)
67
+ return method_missing_for_shortcuts_for_make(name, *args, &block)
68
+ end
69
+
70
+ super
71
+ end
72
+
73
+ def method_missing_for_aliases_for_make(_alias_name, *args, &block) # rubocop:disable Lint/UnusedMethodArgument
74
+ method_name = args.first
75
+ method_options = args.last.is_a?(Hash) ? args.pop : {}
76
+
77
+ return if method_name.nil?
78
+
79
+ make(method_name, **method_options)
80
+ end
63
81
 
82
+ def method_missing_for_shortcuts_for_make(shortcut_name, *args, &block) # rubocop:disable Lint/UnusedMethodArgument
64
83
  method_options = args.last.is_a?(Hash) ? args.pop : {}
65
84
 
66
85
  args.each do |method_name|
@@ -69,7 +88,9 @@ module Servactory
69
88
  end
70
89
 
71
90
  def respond_to_missing?(shortcut_name, *)
72
- Servactory.configuration.method_shortcuts.include?(shortcut_name) || super
91
+ Servactory.configuration.aliases_for_make.include?(shortcut_name) ||
92
+ Servactory.configuration.shortcuts_for_make.include?(name) ||
93
+ super
73
94
  end
74
95
 
75
96
  def next_position
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Servactory
4
4
  module Methods
5
- module Shortcuts
5
+ module ShortcutsForMake
6
6
  class Collection
7
7
  # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
8
8
  extend Forwardable
@@ -2,32 +2,62 @@
2
2
 
3
3
  module Servactory
4
4
  class Result
5
- def self.prepare_for(...)
6
- new.send(:prepare_for, ...)
5
+ def self.success_for(...)
6
+ new(...).send(:as_success)
7
+ end
8
+
9
+ def self.failure_for(...)
10
+ new(...).send(:as_failure)
11
+ end
12
+
13
+ def initialize(context: nil, collection_of_outputs: nil, exception: nil)
14
+ @context = context
15
+ @collection_of_outputs = collection_of_outputs
16
+ @exception = exception
17
+ end
18
+
19
+ def method_missing(name, *args, &block)
20
+ output = @collection_of_outputs&.find_by(name: name)
21
+
22
+ return super if output.nil?
23
+
24
+ output_value_for(output)
25
+ end
26
+
27
+ def respond_to_missing?(name, *)
28
+ @collection_of_outputs&.names&.include?(name) || super
29
+ end
30
+
31
+ def inspect
32
+ "#<#{self.class.name} #{draw_result}>"
7
33
  end
8
34
 
9
35
  private
10
36
 
11
- def prepare_for(context:, collection_of_outputs:)
12
- prepare_outputs_with(context: context, collection_of_outputs: collection_of_outputs)
13
- prepare_statuses_with(context: context)
37
+ def as_success
38
+ define_singleton_method(:success?) { true }
39
+ define_singleton_method(:failure?) { false }
14
40
 
15
41
  self
16
42
  end
17
43
 
18
- def prepare_outputs_with(context:, collection_of_outputs:)
19
- collection_of_outputs.each do |output|
20
- self.class.attr_reader(:"#{output.name}")
44
+ def as_failure
45
+ define_singleton_method(:error) { @exception }
46
+
47
+ define_singleton_method(:success?) { false }
48
+ define_singleton_method(:failure?) { true }
49
+
50
+ self
51
+ end
21
52
 
22
- instance_variable_set(:"@#{output.name}", context.instance_variable_get(:"@#{output.name}"))
23
- end
53
+ def draw_result
54
+ @collection_of_outputs&.map do |output|
55
+ "@#{output.name}=#{output_value_for(output).inspect}"
56
+ end&.join(", ")
24
57
  end
25
58
 
26
- def prepare_statuses_with(context:)
27
- define_singleton_method(:errors) { context.errors }
28
- define_singleton_method(:error) { context.error }
29
- define_singleton_method(:success?) { context.errors.empty? }
30
- define_singleton_method(:failure?) { !context.errors.empty? }
59
+ def output_value_for(output)
60
+ @context.instance_variable_get(:"@#{output.name}")
31
61
  end
32
62
  end
33
63
  end
@@ -3,7 +3,7 @@
3
3
  module Servactory
4
4
  module VERSION
5
5
  MAJOR = 1
6
- MINOR = 7
6
+ MINOR = 8
7
7
  PATCH = 1
8
8
 
9
9
  STRING = [MAJOR, MINOR, PATCH].join(".")
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.7.1
4
+ version: 1.8.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-18 00:00:00.000000000 Z
11
+ date: 2023-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -202,7 +202,6 @@ files:
202
202
  - lib/servactory/context/workspace/outputs.rb
203
203
  - lib/servactory/engine.rb
204
204
  - lib/servactory/errors/base.rb
205
- - lib/servactory/errors/collection.rb
206
205
  - lib/servactory/errors/failure.rb
207
206
  - lib/servactory/errors/input_error.rb
208
207
  - lib/servactory/errors/internal_error.rb
@@ -235,10 +234,11 @@ files:
235
234
  - lib/servactory/internals/validations/base.rb
236
235
  - lib/servactory/internals/validations/type.rb
237
236
  - lib/servactory/internals/workbench.rb
237
+ - lib/servactory/methods/aliases_for_make/collection.rb
238
238
  - lib/servactory/methods/dsl.rb
239
239
  - lib/servactory/methods/method.rb
240
240
  - lib/servactory/methods/method_collection.rb
241
- - lib/servactory/methods/shortcuts/collection.rb
241
+ - lib/servactory/methods/shortcuts_for_make/collection.rb
242
242
  - lib/servactory/methods/stage.rb
243
243
  - lib/servactory/methods/stage_collection.rb
244
244
  - lib/servactory/methods/workbench.rb
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Servactory
4
- module Errors
5
- class Collection
6
- # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
7
- extend Forwardable
8
- def_delegators :@collection, :<<, :to_a, :filter, :reject, :empty?, :first
9
-
10
- def initialize(collection = Set.new)
11
- @collection = collection
12
- end
13
-
14
- def not_blank
15
- Collection.new(reject(&:blank?))
16
- end
17
-
18
- def for_fails
19
- filtered = filter { |error| error.is_a?(Failure) }
20
-
21
- Collection.new(filtered)
22
- end
23
- end
24
- end
25
- end