servactory 1.6.5 → 1.6.7

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: 7e0ef0253d0030321767ea6a532f52fada7923dcf9f0cc87e7651d7df5a1ec57
4
- data.tar.gz: 5e080cef06176ffdd734802503cf987fa6608f3acccf7d1497da6ad0968142c9
3
+ metadata.gz: 36958cd40c5a7f821265cbbaa4509262da61fb1dcb799d9ba57433012d2e35c1
4
+ data.tar.gz: 3a7a5736e738bc71be30ddef3bee4c536c108a29f24493da9359aa3cfd3eef3c
5
5
  SHA512:
6
- metadata.gz: 1195d6f2dcebe355307197eaf11cf0591ba5d9486020572afc8e4991741920664d0f8525052c1d1742e9af14eee627634e7be439529e9827ecfdaa437e87c8a0
7
- data.tar.gz: 48ed814dff14b30ac71d3484649ac7412e54ec8edcdc2bc8bcaa925d2babac1573efd473547717d83ea821064926ca8a9810c34fa91995d018d7b5e6c23bc221
6
+ metadata.gz: e9b3da95a52a025298169b2f6eea8e6b75bf538dc1ea98c4e903c3c43e50dccada335f37b6883f1cf7c1cb49ed4370a2b182ee2c05cb1c48e35b888575bdd26e
7
+ data.tar.gz: d52fe6ad625529e3f5efb114cbea5331505df217802f3acfc3a68acaa61e761de770c394210d28dd16be134c2eb1003e42d6ed1dc994e8ed8ec8ddad6538e1ad
data/README.md CHANGED
@@ -9,6 +9,53 @@ 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
13
+
14
+ ### Service
15
+
16
+ ```ruby
17
+ class UserService::Authenticate < ApplicationService::Base
18
+ input :email, type: String
19
+ input :password, type: String
20
+
21
+ output :user, type: User
22
+
23
+ private
24
+
25
+ def call
26
+ if (user = User.find_by(email: inputs.email)&.authenticate(inputs.password))
27
+ self.user = user
28
+ else
29
+ fail!(message: "Authentication failed")
30
+ end
31
+ end
32
+ end
33
+ ```
34
+
35
+ ### Using in controller
36
+
37
+ ```ruby
38
+ class SessionsController < ApplicationController
39
+ def create
40
+ service_result = UserService::Authenticate.call(**session_params)
41
+
42
+ if service_result.success?
43
+ session[:current_user_id] = service_result.user.id
44
+ redirect_to service_result.user
45
+ else
46
+ flash.now[:message] = service_result.errors.first.message
47
+ render :new
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def session_params
54
+ params.require(:session).permit(:email, :password)
55
+ end
56
+ end
57
+ ```
58
+
12
59
  ## Contributing
13
60
 
14
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.
@@ -6,6 +6,8 @@ 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
+
9
11
  assign_data_with(arguments)
10
12
 
11
13
  inputs_workbench.find_unnecessary!
@@ -31,6 +33,8 @@ module Servactory
31
33
  def call(arguments = {}) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
32
34
  @context_store = Store.new(self)
33
35
 
36
+ context_store.context.send(:assign_service_strict_mode, false)
37
+
34
38
  assign_data_with(arguments)
35
39
 
36
40
  inputs_workbench.find_unnecessary!
@@ -29,7 +29,17 @@ module Servactory
29
29
  end
30
30
 
31
31
  def fail!(message:, meta: nil)
32
- errors << Servactory.configuration.failure_class.new(message: message, meta: meta)
32
+ failure = Servactory.configuration.failure_class.new(message: message, meta: meta)
33
+
34
+ raise failure if @service_strict_mode
35
+
36
+ errors << failure
37
+ end
38
+
39
+ private
40
+
41
+ def assign_service_strict_mode(flag)
42
+ @service_strict_mode = flag
33
43
  end
34
44
  end
35
45
  end
@@ -16,9 +16,10 @@ module Servactory
16
16
 
17
17
  private
18
18
 
19
- def input(name, **options)
19
+ def input(name, *helpers, **options)
20
20
  collection_of_inputs << Input.new(
21
21
  name,
22
+ *helpers,
22
23
  **options
23
24
  )
24
25
  end
@@ -5,12 +5,21 @@ module Servactory
5
5
  class Input # rubocop:disable Metrics/ClassLength
6
6
  ARRAY_DEFAULT_VALUE = ->(is: false, message: nil) { { is: is, message: message } }
7
7
 
8
+ HELPER_LIBRARY = {
9
+ optional: { required: false },
10
+ internal: { internal: true },
11
+ as_array: { array: true }
12
+ }.freeze
13
+
14
+ private_constant :ARRAY_DEFAULT_VALUE, :HELPER_LIBRARY
15
+
8
16
  attr_reader :name,
9
17
  :internal_name
10
18
 
11
19
  # rubocop:disable Style/KeywordParametersOrder
12
20
  def initialize(
13
21
  name,
22
+ *helpers,
14
23
  as: nil,
15
24
  type:,
16
25
  **options
@@ -18,6 +27,8 @@ module Servactory
18
27
  @name = name
19
28
  @internal_name = as.present? ? as : name
20
29
 
30
+ options = apply_helpers_for_options(helpers: helpers, options: options) if helpers.present?
31
+
21
32
  add_basic_options_with(type: type, options: options)
22
33
 
23
34
  collection_of_options.each do |option|
@@ -28,6 +39,20 @@ module Servactory
28
39
  end
29
40
  # rubocop:enable Style/KeywordParametersOrder
30
41
 
42
+ def apply_helpers_for_options(helpers:, options:)
43
+ prepared_options = {}
44
+
45
+ helpers.each do |helper|
46
+ next unless HELPER_LIBRARY.key?(helper)
47
+
48
+ found_helper = HELPER_LIBRARY[helper]
49
+
50
+ prepared_options.merge!(found_helper)
51
+ end
52
+
53
+ options.merge(prepared_options)
54
+ end
55
+
31
56
  def add_basic_options_with(type:, options:)
32
57
  # Check Class: Servactory::Inputs::Validations::Required
33
58
  add_required_option_with(options)
@@ -63,7 +88,7 @@ module Servactory
63
88
  )
64
89
  ],
65
90
  define_input_conflicts: [
66
- DefineInputConflict.new(content: -> { return :required_vs_default if required? && default_value_present? })
91
+ DefineInputConflict.new(content: -> { :required_vs_default if required? && default_value_present? })
67
92
  ],
68
93
  need_for_checks: true,
69
94
  value_key: :is,
@@ -114,8 +139,8 @@ module Servactory
114
139
  )
115
140
  ],
116
141
  define_input_conflicts: [
117
- DefineInputConflict.new(content: -> { return :array_vs_array if array? && types.include?(Array) }),
118
- DefineInputConflict.new(content: -> { return :array_vs_inclusion if array? && inclusion_present? })
142
+ DefineInputConflict.new(content: -> { :array_vs_array if array? && types.include?(Array) }),
143
+ DefineInputConflict.new(content: -> { :array_vs_inclusion if array? && inclusion_present? })
119
144
  ],
120
145
  need_for_checks: false,
121
146
  value_key: :is,
@@ -94,7 +94,7 @@ module Servactory
94
94
  end
95
95
 
96
96
  def prepared_value
97
- @prepared_value ||= @input.optional? && !@input.default.nil? ? @input.default : @value
97
+ @prepared_value ||= @input.optional? && !@input.default.nil? && @value.blank? ? @input.default : @value
98
98
  end
99
99
  end
100
100
  end
@@ -31,6 +31,8 @@ module Servactory
31
31
  end
32
32
 
33
33
  def validate!
34
+ return unless should_be_checked?
35
+
34
36
  return if prepared_types.any? { |type| @value.is_a?(type) }
35
37
 
36
38
  raise_error_with(
@@ -44,6 +46,12 @@ module Servactory
44
46
 
45
47
  private
46
48
 
49
+ def should_be_checked?
50
+ @internal.required? || (
51
+ @internal.optional? && !@value.nil?
52
+ )
53
+ end
54
+
47
55
  def prepared_types
48
56
  @prepared_types ||=
49
57
  Array(@internal.types).map do |type|
@@ -31,6 +31,8 @@ module Servactory
31
31
  end
32
32
 
33
33
  def validate!
34
+ return unless should_be_checked?
35
+
34
36
  return if prepared_types.any? { |type| @value.is_a?(type) }
35
37
 
36
38
  raise_error_with(
@@ -44,6 +46,14 @@ module Servactory
44
46
 
45
47
  private
46
48
 
49
+ def should_be_checked?
50
+ @output.required? || (
51
+ @output.optional? && !@output.default.nil?
52
+ ) || (
53
+ @output.optional? && !@value.nil?
54
+ )
55
+ end
56
+
47
57
  def prepared_types
48
58
  @prepared_types ||=
49
59
  Array(@output.types).map do |type|
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Test
5
+ class FakeType; end
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Test
5
+ class Result
6
+ def initialize(**attributes)
7
+ attributes.each_pair do |method_name, method_return|
8
+ define_singleton_method(method_name) { method_return }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -4,7 +4,7 @@ module Servactory
4
4
  module VERSION
5
5
  MAJOR = 1
6
6
  MINOR = 6
7
- PATCH = 5
7
+ PATCH = 7
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.5
4
+ version: 1.6.7
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-06 00:00:00.000000000 Z
11
+ date: 2023-06-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -247,6 +247,8 @@ files:
247
247
  - lib/servactory/outputs/validations/type.rb
248
248
  - lib/servactory/outputs/workbench.rb
249
249
  - lib/servactory/result.rb
250
+ - lib/servactory/test/fake_type.rb
251
+ - lib/servactory/test/result.rb
250
252
  - lib/servactory/utils.rb
251
253
  - lib/servactory/version.rb
252
254
  homepage: https://github.com/afuno/servactory