servactory 1.4.3 → 1.4.5

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: 3877871b09a517026f3b66849d43348aae44feca18f2f97e101d1948cbc4f9d0
4
- data.tar.gz: c6f0feca2515ebfd9e6123351c78ac29aee0ded0da66c4f689b259460ee7e403
3
+ metadata.gz: 8878b890cc7b43a45e8ea3e982a27e5873ec4d1aeff1ac91f6ce9ea77cc98e38
4
+ data.tar.gz: 4f2947b852d2f0e53965b79b88ce013ae442575dee4f6539b1a2684e242211a5
5
5
  SHA512:
6
- metadata.gz: 3d9d7237afe83f2b813d3c3555a322c5357dcc56aff1f45c0289c8efc47a139f5dc0f1bfec5f81005be1083aa0372b40a99b345df212aeded2edb425a03337c8
7
- data.tar.gz: e1c7a318ce6a853269c6c3240e4028921fbad2f2d50c0e0c8d1ef52820bff91fe96638e363bbf63f278419cf477c8c2211a929d0c8f19a7198dd4e76c2c122df
6
+ metadata.gz: 437c627bef5b24d7f5a5e7b3f4c3b75e207af58d37900d6a8c6cf8b73c69e6704feb575f01233362f1ce2c40f7c640d2900d3d58e416ea12ed682c9f23fd058b
7
+ data.tar.gz: fc9a5f1a97cf8db5483df7be46f805a6c8f5598b559237a89c2409ee761d61204b79da375d3d0228133b88f4e60fe124c22519c6a314d39bb33dbf585cd5422a
data/README.md CHANGED
@@ -14,10 +14,13 @@ A set of tools for building reliable services of any complexity.
14
14
  - [Preparation](#preparation)
15
15
  - [Usage](#usage)
16
16
  - [Minimal example](#minimal-example)
17
+ - [Call](#call)
18
+ - [Result](#result)
17
19
  - [Input attributes](#input-attributes)
18
20
  - [Isolated usage](#isolated-usage)
19
21
  - [As an internal argument](#isolated-usage)
20
22
  - [Optional inputs](#optional-inputs)
23
+ - [As (internal name)](#as-internal-name)
21
24
  - [An array of specific values](#an-array-of-specific-values)
22
25
  - [Inclusion](#inclusion)
23
26
  - [Must](#must)
@@ -25,7 +28,9 @@ A set of tools for building reliable services of any complexity.
25
28
  - [Internal attributes](#internal-attributes)
26
29
  - [Stage](#stage)
27
30
  - [Failures](#failures)
28
- - [Result](#result)
31
+ - [Testing](#testing)
32
+ - [Thanks](#thanks)
33
+ - [Contributing](#contributing)
29
34
 
30
35
  ## Requirements
31
36
 
@@ -108,6 +113,47 @@ end
108
113
 
109
114
  [More examples](https://github.com/afuno/servactory/tree/main/examples/usual)
110
115
 
116
+ ### Call
117
+
118
+ Services can only be called via `.call` and `.call!` methods.
119
+
120
+ The `.call` method will only fail if it catches an exception in the input arguments.
121
+ Internal and output attributes, as well as methods for failures - all this will be collected in the result.
122
+
123
+ The `.call!` method will fail if it catches any exception.
124
+
125
+ #### Via .call
126
+
127
+ ```ruby
128
+ UsersService::Accept.call(user: User.first)
129
+ ```
130
+
131
+ #### Via .call!
132
+
133
+ ```ruby
134
+ UsersService::Accept.call!(user: User.first)
135
+ ```
136
+
137
+ ### Result
138
+
139
+ All services have the result of their work. For example, in case of success this call:
140
+
141
+ ```ruby
142
+ service_result = UsersService::Accept.call!(user: User.first)
143
+ ```
144
+
145
+ Will return this:
146
+
147
+ ```ruby
148
+ #<Servactory::Result:0x0000000107ad9e88 @user="...">
149
+ ```
150
+
151
+ And then you can work with this result, for example, in this way:
152
+
153
+ ```ruby
154
+ Notification::SendJob.perform_later(service_result.user.id)
155
+ ```
156
+
111
157
  ### Input attributes
112
158
 
113
159
  #### Isolated usage
@@ -160,6 +206,26 @@ class UsersService::Create < ApplicationService::Base
160
206
  end
161
207
  ```
162
208
 
209
+ #### As (internal name)
210
+
211
+ This option changes the name of the input within the service.
212
+
213
+ ```ruby
214
+ class NotificationService::Create < ApplicationService::Base
215
+ input :customer, as: :user, type: User
216
+
217
+ output :notification, type: Notification
218
+
219
+ stage { make :create_notification! }
220
+
221
+ private
222
+
223
+ def create_notification!
224
+ self.notification = Notification.create!(user: inputs.user)
225
+ end
226
+ end
227
+ ```
228
+
163
229
  #### An array of specific values
164
230
 
165
231
  ```ruby
@@ -323,22 +389,18 @@ def check!
323
389
  end
324
390
  ```
325
391
 
326
- ### Result
392
+ ## Testing
327
393
 
328
- All services have the result of their work. For example, in case of success this call:
329
-
330
- ```ruby
331
- service_result = NotificationService::Create.call!(user: User.first)
332
- ```
394
+ Testing Servactory services is the same as testing regular Ruby classes.
333
395
 
334
- Will return this:
396
+ ## Thanks
335
397
 
336
- ```ruby
337
- #<Servactory::Result:0x0000000112c00748 @notification=...>
338
- ```
398
+ Thanks to [@sunny](https://github.com/sunny) for [Service Actor](https://github.com/sunny/actor).
339
399
 
340
- And then you can work with this result, for example, in this way:
400
+ ## Contributing
341
401
 
342
- ```ruby
343
- Notification::SendJob.perform_later(service_result.notification.id)
344
- ```
402
+ 1. Fork it (https://github.com/afuno/servactory/fork);
403
+ 2. Create your feature branch (`git checkout -b my-new-feature`);
404
+ 3. Commit your changes (`git commit -am "Add some feature"`);
405
+ 4. Push to the branch (`git push origin my-new-feature`);
406
+ 5. Create a new Pull Request.
@@ -8,5 +8,7 @@ module Servactory
8
8
  include InternalArguments::DSL
9
9
  include OutputArguments::DSL
10
10
  include Stage::DSL
11
+
12
+ private_class_method :new
11
13
  end
12
14
  end
@@ -28,6 +28,29 @@ module Servactory
28
28
  )
29
29
  end
30
30
 
31
+ def call(arguments = {}) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
32
+ @context_store = Store.new(self)
33
+
34
+ assign_data_with(arguments)
35
+
36
+ input_arguments_workbench.find_unnecessary!
37
+ input_arguments_workbench.check_rules!
38
+ output_arguments_workbench.find_conflicts_in!(
39
+ collection_of_internal_arguments: collection_of_internal_arguments
40
+ )
41
+
42
+ prepare_data
43
+
44
+ input_arguments_workbench.check!
45
+
46
+ stage_handyman.run_methods!
47
+
48
+ Servactory::Result.prepare_for(
49
+ context: context_store.context,
50
+ collection_of_output_arguments: collection_of_output_arguments
51
+ )
52
+ end
53
+
31
54
  private
32
55
 
33
56
  attr_reader :context_store
@@ -6,7 +6,7 @@ module Servactory
6
6
  attr_reader :context
7
7
 
8
8
  def initialize(service_class)
9
- @context = service_class.new
9
+ @context = service_class.send(:new)
10
10
  end
11
11
  end
12
12
  end
@@ -6,14 +6,14 @@ module Servactory
6
6
  class Errors
7
7
  # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
8
8
  extend Forwardable
9
- def_delegators :@collection, :<<, :filter, :reject, :empty?, :first
9
+ def_delegators :@collection, :<<, :to_a, :filter, :reject, :empty?, :first
10
10
 
11
- def initialize(collection = [])
11
+ def initialize(collection = Set.new)
12
12
  @collection = collection
13
13
  end
14
14
 
15
- def not_blank_and_uniq
16
- Errors.new(reject(&:blank?).uniq)
15
+ def not_blank
16
+ Errors.new(reject(&:blank?))
17
17
  end
18
18
 
19
19
  def for_fails
@@ -23,7 +23,7 @@ module Servactory
23
23
  end
24
24
 
25
25
  def raise_first_fail
26
- return if (tmp_errors = errors.for_fails.not_blank_and_uniq).empty?
26
+ return if (tmp_errors = errors.for_fails.not_blank).empty?
27
27
 
28
28
  raise Servactory.configuration.failure_class, tmp_errors.first.message
29
29
  end
@@ -4,18 +4,18 @@ module Servactory
4
4
  module InputArguments
5
5
  module Checks
6
6
  class Base
7
- def initialize
8
- @errors = []
9
- end
10
-
11
- attr_reader :errors
12
-
13
7
  protected
14
8
 
15
9
  def add_error(message, **arguments)
16
10
  message = message.call(**arguments) if message.is_a?(Proc)
17
11
 
18
- errors.push(message)
12
+ errors << message
13
+ end
14
+
15
+ private
16
+
17
+ def errors
18
+ @errors ||= Errors.new
19
19
  end
20
20
  end
21
21
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module InputArguments
5
+ module Checks
6
+ class Errors
7
+ # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
8
+ extend Forwardable
9
+ def_delegators :@collection, :<<, :to_a
10
+
11
+ def initialize(*)
12
+ @collection = Set.new
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -8,7 +8,7 @@ module Servactory
8
8
  def_delegators :@collection, :<<, :each, :map
9
9
 
10
10
  def initialize(*)
11
- @collection = []
11
+ @collection = Set.new
12
12
  end
13
13
 
14
14
  def names
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module InputArguments
5
+ class DefineInputConflict
6
+ attr_reader :content
7
+
8
+ def initialize(content:)
9
+ @content = content
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module InputArguments
5
+ class DefineInputMethod
6
+ attr_reader :name,
7
+ :content
8
+
9
+ def initialize(name:, content:)
10
+ @name = name.to_sym
11
+ @content = content
12
+ end
13
+ end
14
+ end
15
+ end
@@ -6,10 +6,19 @@ module Servactory
6
6
  ARRAY_DEFAULT_VALUE = ->(is: false, message: nil) { { is: is, message: message } }
7
7
 
8
8
  attr_reader :name,
9
+ :internal_name,
9
10
  :collection_of_options
10
11
 
11
- def initialize(name, collection_of_options:, type:, **options)
12
+ # rubocop:disable Style/KeywordParametersOrder
13
+ def initialize(
14
+ name,
15
+ as: nil,
16
+ collection_of_options:,
17
+ type:,
18
+ **options
19
+ )
12
20
  @name = name
21
+ @internal_name = as.present? ? as : name
13
22
  @collection_of_options = collection_of_options
14
23
 
15
24
  add_basic_options_with(type: type, options: options)
@@ -20,6 +29,7 @@ module Servactory
20
29
  instance_variable_set(:"@#{option.name}", option.value)
21
30
  end
22
31
  end
32
+ # rubocop:enable Style/KeywordParametersOrder
23
33
 
24
34
  def add_basic_options_with(type:, options:)
25
35
  # Check Class: Servactory::InputArguments::Checks::Required
@@ -45,22 +55,19 @@ module Servactory
45
55
  name: :required,
46
56
  input: self,
47
57
  check_class: Servactory::InputArguments::Checks::Required,
48
- define_input_methods: lambda do
49
- <<-RUBY
50
- def required?
51
- Servactory::Utils.boolean?(required[:is])
52
- end
53
-
54
- def optional?
55
- !required?
56
- end
57
- RUBY
58
- end,
59
- define_conflicts: lambda do
60
- <<-RUBY
61
- return :required_vs_default if required? && default_value_present?
62
- RUBY
63
- end,
58
+ define_input_methods: [
59
+ DefineInputMethod.new(
60
+ name: :required?,
61
+ content: ->(value:) { Servactory::Utils.boolean?(value[:is]) }
62
+ ),
63
+ DefineInputMethod.new(
64
+ name: :optional?,
65
+ content: ->(value:) { !Servactory::Utils.boolean?(value[:is]) }
66
+ )
67
+ ],
68
+ define_input_conflicts: [
69
+ DefineInputConflict.new(content: -> { return :required_vs_default if required? && default_value_present? })
70
+ ],
64
71
  need_for_checks: true,
65
72
  value_key: :is,
66
73
  value_fallback: true,
@@ -72,8 +79,8 @@ module Servactory
72
79
  collection_of_options << Option.new(
73
80
  name: :types,
74
81
  input: self,
75
- original_value: Array(type),
76
82
  check_class: Servactory::InputArguments::Checks::Type,
83
+ original_value: Array(type),
77
84
  need_for_checks: true,
78
85
  value_fallback: nil,
79
86
  with_advanced_mode: false
@@ -85,13 +92,12 @@ module Servactory
85
92
  name: :default,
86
93
  input: self,
87
94
  check_class: Servactory::InputArguments::Checks::Type,
88
- define_input_methods: lambda do
89
- <<-RUBY
90
- def default_value_present?
91
- !default.nil?
92
- end
93
- RUBY
94
- end,
95
+ define_input_methods: [
96
+ DefineInputMethod.new(
97
+ name: :default_value_present?,
98
+ content: ->(value:) { !value.nil? }
99
+ )
100
+ ],
95
101
  need_for_checks: true,
96
102
  value_fallback: nil,
97
103
  with_advanced_mode: false,
@@ -104,19 +110,16 @@ module Servactory
104
110
  name: :array,
105
111
  input: self,
106
112
  check_class: Servactory::InputArguments::Checks::Type,
107
- define_input_methods: lambda do
108
- <<-RUBY
109
- def array?
110
- Servactory::Utils.boolean?(array[:is])
111
- end
112
- RUBY
113
- end,
114
- define_conflicts: lambda do
115
- <<-RUBY
116
- return :array_vs_array if array? && types.include?(Array)
117
- return :array_vs_inclusion if array? && inclusion_present?
118
- RUBY
119
- end,
113
+ define_input_methods: [
114
+ DefineInputMethod.new(
115
+ name: :array?,
116
+ content: ->(value:) { Servactory::Utils.boolean?(value[:is]) }
117
+ )
118
+ ],
119
+ define_input_conflicts: [
120
+ DefineInputConflict.new(content: -> { return :array_vs_array if array? && types.include?(Array) }),
121
+ DefineInputConflict.new(content: -> { return :array_vs_inclusion if array? && inclusion_present? })
122
+ ],
120
123
  need_for_checks: false,
121
124
  value_key: :is,
122
125
  value_fallback: false,
@@ -129,13 +132,12 @@ module Servactory
129
132
  name: :inclusion,
130
133
  input: self,
131
134
  check_class: Servactory::InputArguments::Checks::Inclusion,
132
- define_input_methods: lambda do
133
- <<-RUBY
134
- def inclusion_present?
135
- inclusion[:in].is_a?(Array) && inclusion[:in].present?
136
- end
137
- RUBY
138
- end,
135
+ define_input_methods: [
136
+ DefineInputMethod.new(
137
+ name: :inclusion_present?,
138
+ content: ->(value:) { value[:in].is_a?(Array) && value[:in].present? }
139
+ )
140
+ ],
139
141
  need_for_checks: true,
140
142
  value_key: :in,
141
143
  value_fallback: nil,
@@ -148,13 +150,12 @@ module Servactory
148
150
  name: :must,
149
151
  input: self,
150
152
  check_class: Servactory::InputArguments::Checks::Must,
151
- define_input_methods: lambda do
152
- <<-RUBY
153
- def must_present?
154
- must.present?
155
- end
156
- RUBY
157
- end,
153
+ define_input_methods: [
154
+ DefineInputMethod.new(
155
+ name: :must_present?,
156
+ content: ->(value:) { value.present? }
157
+ )
158
+ ],
158
159
  need_for_checks: true,
159
160
  value_key: :is,
160
161
  value_fallback: nil,
@@ -167,15 +168,14 @@ module Servactory
167
168
  collection_of_options << Option.new(
168
169
  name: :internal,
169
170
  input: self,
170
- define_input_methods: lambda do
171
- <<-RUBY
172
- def internal?
173
- Servactory::Utils.boolean?(internal[:is])
174
- end
175
- RUBY
176
- end,
177
- need_for_checks: false,
178
171
  check_class: nil,
172
+ define_input_methods: [
173
+ DefineInputMethod.new(
174
+ name: :internal?,
175
+ content: ->(value:) { Servactory::Utils.boolean?(value[:is]) }
176
+ )
177
+ ],
178
+ need_for_checks: false,
179
179
  value_key: :is,
180
180
  value_fallback: false,
181
181
  **options
@@ -187,9 +187,7 @@ module Servactory
187
187
  end
188
188
 
189
189
  def conflict_code
190
- instance_eval(collection_of_options.defined_conflicts)
191
-
192
- nil
190
+ collection_of_options.defined_conflict_code
193
191
  end
194
192
 
195
193
  def with_conflicts?
@@ -9,7 +9,8 @@ module Servactory
9
9
 
10
10
  attr_reader :name,
11
11
  :check_class,
12
- :define_conflicts,
12
+ :define_input_methods,
13
+ :define_input_conflicts,
13
14
  :need_for_checks,
14
15
  :value_key,
15
16
  :value
@@ -24,13 +25,14 @@ module Servactory
24
25
  original_value: nil,
25
26
  value_key: nil,
26
27
  define_input_methods: nil,
27
- define_conflicts: nil,
28
+ define_input_conflicts: nil,
28
29
  with_advanced_mode: true,
29
30
  **options
30
31
  ) # do
31
32
  @name = name.to_sym
32
33
  @check_class = check_class
33
- @define_conflicts = define_conflicts
34
+ @define_input_methods = define_input_methods
35
+ @define_input_conflicts = define_input_conflicts
34
36
  @need_for_checks = need_for_checks
35
37
  @value_key = value_key
36
38
 
@@ -41,7 +43,7 @@ module Servactory
41
43
  with_advanced_mode: with_advanced_mode
42
44
  )
43
45
 
44
- input.instance_eval(define_input_methods.call) if define_input_methods.present?
46
+ prepare_input_methods_for(input)
45
47
  end
46
48
  # rubocop:enable Metrics/MethodLength
47
49
 
@@ -73,6 +75,22 @@ module Servactory
73
75
  DEFAULT_VALUE.call(key: value_key, value: value)
74
76
  end
75
77
  end
78
+
79
+ def prepare_input_methods_for(input)
80
+ input.instance_eval(define_input_methods_template) if define_input_methods_template.present?
81
+ end
82
+
83
+ def define_input_methods_template
84
+ return if @define_input_methods.blank?
85
+
86
+ @define_input_methods_template ||= @define_input_methods.map do |define_input_method|
87
+ <<-RUBY
88
+ def #{define_input_method.name}
89
+ #{define_input_method.content.call(value: @value)}
90
+ end
91
+ RUBY
92
+ end.join("\n")
93
+ end
76
94
  end
77
95
  end
78
96
  end
@@ -5,10 +5,10 @@ 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
8
+ def_delegators :@collection, :<<, :filter, :each, :map, :flat_map
9
9
 
10
10
  def initialize(*)
11
- @collection = []
11
+ @collection = Set.new
12
12
  end
13
13
 
14
14
  def check_classes
@@ -27,8 +27,12 @@ module Servactory
27
27
  end
28
28
  end
29
29
 
30
- def defined_conflicts
31
- map { |option| option.define_conflicts&.call }.reject(&:blank?).uniq.join
30
+ def defined_conflict_code
31
+ flat_map do |option|
32
+ option.define_input_conflicts&.map do |define_input_conflict|
33
+ define_input_conflict.content.call
34
+ end
35
+ end.reject(&:blank?).first
32
36
  end
33
37
  end
34
38
  end
@@ -13,8 +13,6 @@ module Servactory
13
13
  @incoming_arguments = incoming_arguments
14
14
  @collection_of_input_arguments = collection_of_input_arguments
15
15
  @collection_of_input_options = collection_of_input_options
16
-
17
- @errors = []
18
16
  end
19
17
 
20
18
  def check!
@@ -42,7 +40,7 @@ module Servactory
42
40
  check_options: check_options
43
41
  )
44
42
 
45
- @errors.push(*errors_from_checks)
43
+ errors.merge(errors_from_checks.to_a)
46
44
  end
47
45
  end
48
46
 
@@ -64,8 +62,12 @@ module Servactory
64
62
 
65
63
  ########################################################################
66
64
 
65
+ def errors
66
+ @errors ||= CheckErrors.new
67
+ end
68
+
67
69
  def raise_errors
68
- return if (tmp_errors = @errors.reject(&:blank?).uniq).empty?
70
+ return if (tmp_errors = errors.not_blank).empty?
69
71
 
70
72
  raise Servactory.configuration.input_argument_error_class, tmp_errors.first
71
73
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module InputArguments
5
+ module Tools
6
+ class CheckErrors
7
+ # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
8
+ extend Forwardable
9
+ def_delegators :@collection, :merge, :reject, :first, :empty?
10
+
11
+ def initialize(collection = Set.new)
12
+ @collection = collection
13
+ end
14
+
15
+ def not_blank
16
+ CheckErrors.new(reject(&:blank?))
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -31,7 +31,7 @@ module Servactory
31
31
  input_value = @incoming_arguments.fetch(input.name, nil)
32
32
  input_value = input.default if input.optional? && input_value.blank?
33
33
 
34
- @inputs_variables[input.name] = input_value
34
+ @inputs_variables[input.internal_name] = input_value
35
35
 
36
36
  return unless input.internal?
37
37
 
@@ -8,7 +8,7 @@ module Servactory
8
8
  def_delegators :@collection, :<<, :each, :map
9
9
 
10
10
  def initialize(*)
11
- @collection = []
11
+ @collection = Set.new
12
12
  end
13
13
 
14
14
  def names
@@ -8,7 +8,7 @@ module Servactory
8
8
  def_delegators :@collection, :<<, :each, :map
9
9
 
10
10
  def initialize(*)
11
- @collection = []
11
+ @collection = Set.new
12
12
  end
13
13
 
14
14
  def names
@@ -9,13 +9,24 @@ module Servactory
9
9
  private
10
10
 
11
11
  def prepare_for(context:, collection_of_output_arguments:)
12
+ prepare_outputs_with(context: context, collection_of_output_arguments: collection_of_output_arguments)
13
+ prepare_statuses_with(context: context)
14
+
15
+ self
16
+ end
17
+
18
+ def prepare_outputs_with(context:, collection_of_output_arguments:)
12
19
  collection_of_output_arguments.each do |output|
13
20
  self.class.attr_reader(:"#{output.name}")
14
21
 
15
22
  instance_variable_set(:"@#{output.name}", context.instance_variable_get(:"@#{output.name}"))
16
23
  end
24
+ end
17
25
 
18
- self
26
+ def prepare_statuses_with(context:)
27
+ define_singleton_method(:errors) { context.errors }
28
+ define_singleton_method(:success?) { context.errors.empty? }
29
+ define_singleton_method(:failure?) { !context.errors.empty? }
19
30
  end
20
31
  end
21
32
  end
@@ -8,7 +8,7 @@ module Servactory
8
8
  def_delegators :@methods, :<<, :each
9
9
 
10
10
  def initialize(*)
11
- @methods = []
11
+ @methods = Set.new
12
12
  end
13
13
  end
14
14
  end
@@ -4,7 +4,7 @@ module Servactory
4
4
  module VERSION
5
5
  MAJOR = 1
6
6
  MINOR = 4
7
- PATCH = 3
7
+ PATCH = 5
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.4.3
4
+ version: 1.4.5
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-05-12 00:00:00.000000000 Z
11
+ date: 2023-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -177,16 +177,20 @@ files:
177
177
  - lib/servactory/errors/internal_argument_error.rb
178
178
  - lib/servactory/errors/output_argument_error.rb
179
179
  - lib/servactory/input_arguments/checks/base.rb
180
+ - lib/servactory/input_arguments/checks/errors.rb
180
181
  - lib/servactory/input_arguments/checks/inclusion.rb
181
182
  - lib/servactory/input_arguments/checks/must.rb
182
183
  - lib/servactory/input_arguments/checks/required.rb
183
184
  - lib/servactory/input_arguments/checks/type.rb
184
185
  - lib/servactory/input_arguments/collection.rb
186
+ - lib/servactory/input_arguments/define_input_conflict.rb
187
+ - lib/servactory/input_arguments/define_input_method.rb
185
188
  - lib/servactory/input_arguments/dsl.rb
186
189
  - lib/servactory/input_arguments/input_argument.rb
187
190
  - lib/servactory/input_arguments/option.rb
188
191
  - lib/servactory/input_arguments/options_collection.rb
189
192
  - lib/servactory/input_arguments/tools/check.rb
193
+ - lib/servactory/input_arguments/tools/check_errors.rb
190
194
  - lib/servactory/input_arguments/tools/find_unnecessary.rb
191
195
  - lib/servactory/input_arguments/tools/prepare.rb
192
196
  - lib/servactory/input_arguments/tools/rules.rb