service_actor 2.0.0 → 3.1.2

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: e103cfa965d8a142d4d47ad910bd4411f90392ab4057b8536a265e12febbf42b
4
- data.tar.gz: cf297af32084c0a7ff7d3f85ecab5f52137516d5fc2d2c0aa1f5a1fb1aceccfd
3
+ metadata.gz: 182079e8ce5159c685b472dcecec697cd640e2006266f9f8e71b1fe829e24743
4
+ data.tar.gz: 28522d5045e623f0fb55ac77519720e3d76168f070c108a1785c46b322a04a9f
5
5
  SHA512:
6
- metadata.gz: 76cc57cc0c3eca0c951f3bf046e7132bd28157081ff7a815fa44b9ef6375180f035aecee14bf735d0a655e72fa48f840610694c505f90e81cb72e84bc67ea7b7
7
- data.tar.gz: 77c0cae0fe870e7a771023a45fbe919eeda92b8ed6e6d32187b4a85ddf906fbae27b1b615830d659214754914a7c0038ecdbba4a7b88b81234e2b96cdc08486c
6
+ metadata.gz: 6c4ae5e139ac02cc1244c24c8b245161cebe2246112bdfe25646c38d09f5b83d34d68f902ded72477149c1f6a928a617d1bbfbf5dd7479ee35d0d6f87c0b08a8
7
+ data.tar.gz: 2f0d5c297e68ba61db4467d6ef83e14ec92e12b839a5bea78d0fdd072ae08f7077676fd88cd8ad22f7e1e5790e987be69695c8bb0c465eea58d0e3a59cac7c04
data/README.md CHANGED
@@ -6,6 +6,8 @@ This Ruby gem lets you move your application logic into into small composable
6
6
  service objects. It is a lightweight framework that helps you keep your models
7
7
  and controllers thin.
8
8
 
9
+ ![Photo of theater seats](https://user-images.githubusercontent.com/132/78340166-e7567000-7595-11ea-97c0-b3e5da2de7a1.png)
10
+
9
11
  ## Contents
10
12
 
11
13
  - [Installation](#installation)
@@ -21,22 +23,31 @@ and controllers thin.
21
23
  - [Rollback](#rollback)
22
24
  - [Lambdas](#lambdas)
23
25
  - [Play conditions](#play-conditions)
24
- - [Build your own actor](#build-your-own-actor)
25
26
  - [Testing](#testing)
27
+ - [Build your own actor](#build-your-own-actor)
26
28
  - [Influences](#influences)
29
+ - [Thanks](#thanks)
27
30
  - [Development](#development)
28
31
  - [Contributing](#contributing)
29
32
  - [License](#contributing)
30
33
 
31
34
  ## Installation
32
35
 
33
- Add these lines to your application's Gemfile:
36
+ Add these lines to your applications Gemfile:
34
37
 
35
38
  ```rb
36
39
  # Composable service objects
37
40
  gem 'service_actor'
38
41
  ```
39
42
 
43
+ When using Rails, you can include the
44
+ [service_actor-rails](https://github.com/sunny/actor-rails) gem:
45
+
46
+ ```ruby
47
+ # Composable service objects
48
+ gem "service_actor-rails"
49
+ ```
50
+
40
51
  ## Usage
41
52
 
42
53
  Actors are single-purpose actions in your application that represent your
@@ -59,7 +70,8 @@ SendNotification.call # => <ServiceActor::Result…>
59
70
  ```
60
71
 
61
72
  When called, actors return a Result. Reading and writing to this result allows
62
- actors to accept and return multiple arguments. Let's find out how to do that.
73
+ actors to accept and return multiple arguments. Let's find out how to do that
74
+ and then we'll see how to chain multiple actors togethor.
63
75
 
64
76
  ### Inputs
65
77
 
@@ -137,8 +149,21 @@ result = BuildGreeting.call
137
149
 
138
150
  ### Conditions
139
151
 
140
- You can add simple conditions that the inputs must verify, with the name of your
141
- choice under `must`:
152
+ You can ensure an input is included in a collection by using `in` (unreleased
153
+ yet):
154
+
155
+ ```rb
156
+ class Pay < Actor
157
+ input :currency, in: %w[EUR USD]
158
+
159
+ # …
160
+ end
161
+ ```
162
+
163
+ This raises an argument error if the input does not match one of the given
164
+ values.
165
+
166
+ You can also add custom conditions with the name of your choice by using `must`:
142
167
 
143
168
  ```rb
144
169
  class UpdateAdminUser < Actor
@@ -151,7 +176,7 @@ class UpdateAdminUser < Actor
151
176
  end
152
177
  ```
153
178
 
154
- In case the input does not match, it will raise an argument error.
179
+ This raises an argument error if the given lambda returns a falsey value.
155
180
 
156
181
  ### Allow nil
157
182
 
@@ -210,8 +235,7 @@ end
210
235
  This will raise an error in your app with the given data added to the result.
211
236
 
212
237
  To test for the success of your actor instead of raising an exception, use
213
- `.result` instead of `.call`. This lets you use `success?` and `failure?` on the
214
- result.
238
+ `.result` instead of `.call` and call `success?` or `failure?` on the result.
215
239
 
216
240
  For example in a Rails controller:
217
241
 
@@ -246,9 +270,9 @@ class PlaceOrder < Actor
246
270
  end
247
271
  ```
248
272
 
249
- This creates a `call` method where each actor will be called, taking their
250
- arguments from the previous actor's result. In fact, every actor along shares
251
- the same result instance to help shape the final result your application needs.
273
+ This creates a `call` method that will call every actor along the way. Inputs
274
+ and outputs will go from one actor to the next, all sharing the same result set
275
+ until it is finally returned.
252
276
 
253
277
  ### Rollback
254
278
 
@@ -320,6 +344,28 @@ end
320
344
 
321
345
  You can use this to trigger an early success.
322
346
 
347
+ ### Fail on argument error
348
+
349
+ By default, errors on inputs will raise an error, even when using `.result`
350
+ instead of `.call`. If instead you want to mark the actor as failed, you can
351
+ catch the exception to treat it as an actor failure:
352
+
353
+ ```rb
354
+ class PlaceOrder < Actor
355
+ fail_on ServiceActor::ArgumentError
356
+
357
+ # …
358
+ end
359
+ ```
360
+
361
+ ## Testing
362
+
363
+ In your application, add automated testing to your actors as you would do to any
364
+ other part of your applications.
365
+
366
+ You will find that cutting your business logic into single purpose actors will
367
+ make it easier for you to test your application.
368
+
323
369
  ## Build your own actor
324
370
 
325
371
  If you application already uses an "Actor" class, you can build your own by
@@ -337,19 +383,11 @@ class ApplicationActor
337
383
  end
338
384
  ```
339
385
 
340
- ## Testing
341
-
342
- In your application, add automated testing to your actors as you would do to any
343
- other part of your applications.
344
-
345
- You will find that cutting your business logic into single purpose actors makes
346
- your application much simpler to test.
347
-
348
386
  ## Influences
349
387
 
350
388
  This gem is heavily influenced by
351
389
  [Interactor](https://github.com/collectiveidea/interactor) ♥.
352
- However there are a few key differences which make `actor` unique:
390
+ Some key differences make `actor` unique:
353
391
 
354
392
  - Does not [hide errors when an actor fails inside another
355
393
  actor](https://github.com/collectiveidea/interactor/issues/170).
@@ -359,7 +397,7 @@ However there are a few key differences which make `actor` unique:
359
397
  and failures are not hidden away because you forgot to use `!`.
360
398
  - Allows defaults, type checking, requirements and conditions on inputs.
361
399
  - Delegates methods on the context: `foo` vs `context.foo`, `self.foo =` vs
362
- `context.foo = `, fail!` vs `context.fail!`.
400
+ `context.foo = `, `fail!` vs `context.fail!`.
363
401
  - Shorter setup syntax: inherit from `< Actor` vs having to `include Interactor`
364
402
  and `include Interactor::Organizer`.
365
403
  - Organizers allow lambdas, being called multiple times, and having conditions.
@@ -367,19 +405,29 @@ However there are a few key differences which make `actor` unique:
367
405
  - No `before`, `after` and `around` hooks, prefer using `play` with lambdas or
368
406
  overriding `call`.
369
407
 
408
+ Actor supports mixing actors & interactors when using `play` for a smooth
409
+ migration.
410
+
411
+ ## Thanks
412
+
370
413
  Thank you to @nicoolas25, @AnneSottise & @williampollet for the early thoughts
371
414
  and feedback on this gem.
372
415
 
416
+ Photo by [Lloyd Dirks](https://unsplash.com/photos/4SLz_RCk6kQ).
417
+
373
418
  ## Development
374
419
 
375
420
  After checking out the repo, run `bin/setup` to install dependencies. Then, run
376
- `rake` to run the tests and linting. You can also run `bin/console` for an
421
+ `bin/rake` to run the tests and linting. You can also run `bin/console` for an
377
422
  interactive prompt.
378
423
 
379
424
  To release a new version, update the version number in `version.rb`, and in the
380
- `CHANGELOG.md`, run `rake`, and create a commit for this version. You can then
381
- run `rake release`, which will create a git tag for the version, push git
382
- commits and tags, and push the gem to [rubygems.org](https://rubygems.org).
425
+ `CHANGELOG.md`. Update the `README.md` if there are missing segments, make sure
426
+ tests and linting are pristine by calling `bundle && bin/rake`, then create a
427
+ commit for this version.
428
+
429
+ You can then run `rake release`, which will assign a git tag, push using git,
430
+ and push the gem to [rubygems.org](https://rubygems.org).
383
431
 
384
432
  ## Contributing
385
433
 
@@ -389,7 +437,7 @@ Bug reports and pull requests are welcome
389
437
  This project is intended to be a safe, welcoming space for collaboration, and
390
438
  everyone interacting in the project’s codebase and issue tracker is expected to
391
439
  adhere to the [Contributor Covenant code of
392
- conduct](https://github.com/sunny/actor/blob/master/CODE_OF_CONDUCT.md).
440
+ conduct](https://github.com/sunny/actor/blob/main/CODE_OF_CONDUCT.md).
393
441
 
394
442
  ## License
395
443
 
@@ -1,36 +1,39 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'service_actor/core'
4
-
5
3
  # Exceptions
6
4
  require 'service_actor/error'
7
5
  require 'service_actor/failure'
8
- require 'service_actor/success'
9
6
  require 'service_actor/argument_error'
10
7
 
11
8
  # Core
12
- require 'service_actor/result'
9
+ require 'service_actor/core'
13
10
  require 'service_actor/attributable'
14
11
  require 'service_actor/playable'
15
- require 'service_actor/core'
12
+ require 'service_actor/result'
16
13
 
17
14
  # Concerns
18
15
  require 'service_actor/type_checkable'
19
16
  require 'service_actor/nil_checkable'
20
17
  require 'service_actor/conditionable'
21
18
  require 'service_actor/defaultable'
19
+ require 'service_actor/collectionable'
20
+ require 'service_actor/failable'
22
21
 
23
22
  module ServiceActor
24
23
  module Base
25
24
  def self.included(base)
26
25
  # Core
27
26
  base.include(Core)
27
+ base.include(Attributable)
28
+ base.include(Playable)
28
29
 
29
30
  # Concerns
30
31
  base.include(TypeCheckable)
31
32
  base.include(NilCheckable)
32
33
  base.include(Conditionable)
34
+ base.include(Collectionable)
33
35
  base.include(Defaultable)
36
+ base.include(Failable)
34
37
  end
35
38
  end
36
39
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ServiceActor
4
+ # Add checks to your inputs, by specifying what values are authorized
5
+ # under the "in" key.
6
+ #
7
+ # Example:
8
+ #
9
+ # class Pay < Actor
10
+ # input :provider, in: ['MANGOPAY', 'PayPal', 'Stripe']
11
+ # end
12
+ module Collectionable
13
+ def self.included(base)
14
+ base.prepend(PrependedMethods)
15
+ end
16
+
17
+ module PrependedMethods
18
+ def _call
19
+ self.class.inputs.each do |key, options|
20
+ next unless options[:in]
21
+
22
+ next if options[:in].include?(result[key])
23
+
24
+ raise ArgumentError,
25
+ "Input #{key} must be included in #{options[:in].inspect} " \
26
+ "but instead was #{result[key].inspect}"
27
+ end
28
+
29
+ super
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ServiceActor
4
- # Add checks to your inputs, by calling lambdas with the name of you choice.
5
- # Will raise an error if any check does return a truthy value.
4
+ # Add checks to your inputs, by calling lambdas with the name of you choice
5
+ # under the "must" key.
6
+ #
7
+ # Will raise an error if any check returns a truthy value.
6
8
  #
7
9
  # Example:
8
10
  #
@@ -27,7 +29,7 @@ module ServiceActor
27
29
  next if check.call(value)
28
30
 
29
31
  raise ArgumentError,
30
- "Input #{key} must #{name} but was #{value.inspect}."
32
+ "Input #{key} must #{name} but was #{value.inspect}"
31
33
  end
32
34
  end
33
35
 
@@ -1,13 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ServiceActor
4
- # Actors should start with a verb, inherit from Actor and implement a `call`
5
- # method.
6
4
  module Core
7
5
  def self.included(base)
8
6
  base.extend(ClassMethods)
9
- base.include(Attributable)
10
- base.include(Playable)
11
7
  end
12
8
 
13
9
  module ClassMethods
@@ -18,15 +14,6 @@ module ServiceActor
18
14
  result = Result.to_result(options).merge!(arguments)
19
15
  new(result)._call
20
16
  result
21
- # DEPRECATED
22
- rescue Success
23
- result
24
- end
25
-
26
- # :nodoc:
27
- def call!(**arguments)
28
- warn "DEPRECATED: Prefer `#{name}.call` to `#{name}.call!`."
29
- call(**arguments)
30
17
  end
31
18
 
32
19
  # Call an actor with arguments. Returns the result and does not raise on
@@ -61,20 +48,9 @@ module ServiceActor
61
48
  # Returns the current context from inside an actor.
62
49
  attr_reader :result
63
50
 
64
- def context
65
- warn "DEPRECATED: Prefer `result.` to `context.` in #{self.class.name}."
66
-
67
- result
68
- end
69
-
70
51
  # Can be called from inside an actor to stop execution and mark as failed.
71
52
  def fail!(**arguments)
72
53
  result.fail!(**arguments)
73
54
  end
74
-
75
- # DEPRECATED
76
- def succeed!(**arguments)
77
- result.succeed!(**arguments)
78
- end
79
55
  end
80
56
  end
@@ -20,13 +20,14 @@ module ServiceActor
20
20
  self.class.inputs.each do |name, input|
21
21
  next if result.key?(name)
22
22
 
23
- unless input.key?(:default)
24
- raise ArgumentError, "Input #{name} on #{self.class} is missing."
23
+ if input.key?(:default)
24
+ default = input[:default]
25
+ default = default.call if default.respond_to?(:call)
26
+ result[name] = default
27
+ next
25
28
  end
26
29
 
27
- default = input[:default]
28
- default = default.call if default.respond_to?(:call)
29
- result[name] = default
30
+ raise(ArgumentError, "Input #{name} on #{self.class} is missing")
30
31
  end
31
32
 
32
33
  super
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ServiceActor
4
+ # Adds the `fail_on` DSL to actors. This allows you to call `.result` and get
5
+ # back a failed actor instead of raising an exception.
6
+ #
7
+ # class ApplicationActor < Actor
8
+ # fail_on ServiceActor::ArgumentError
9
+ # end
10
+ module Failable
11
+ def self.included(base)
12
+ base.extend(ClassMethods)
13
+ base.prepend(PrependedMethods)
14
+ end
15
+
16
+ module ClassMethods
17
+ def inherited(child)
18
+ super
19
+
20
+ child.fail_ons.push(*fail_ons)
21
+ end
22
+
23
+ def fail_on(*exceptions)
24
+ fail_ons.push(*exceptions)
25
+ end
26
+
27
+ def fail_ons
28
+ @fail_ons ||= []
29
+ end
30
+ end
31
+
32
+ module PrependedMethods
33
+ def _call
34
+ super
35
+ rescue *self.class.fail_ons => e
36
+ fail!(error: e.message)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -27,30 +27,17 @@ module ServiceActor
27
27
 
28
28
  def check_context_for_nil(definitions, origin:)
29
29
  definitions.each do |name, options|
30
- warn_of_deprecated_required_option(options, name, origin)
31
-
32
30
  next if !result[name].nil? || allow_nil?(options)
33
31
 
34
32
  raise ArgumentError,
35
33
  "The #{origin} \"#{name}\" on #{self.class} does not allow " \
36
- 'nil values.'
34
+ 'nil values'
37
35
  end
38
36
  end
39
37
 
40
- def warn_of_deprecated_required_option(options, name, origin)
41
- return unless options.key?(:required)
42
-
43
- warn 'DEPRECATED: The "required" option is deprecated. Replace ' \
44
- "`#{origin} :#{name}, required: #{options[:required]}` by " \
45
- "`#{origin} :#{name}, allow_nil: #{!options[:required]}` in " \
46
- "#{self.class}."
47
- end
48
-
49
38
  def allow_nil?(options)
50
39
  if options.key?(:allow_nil)
51
40
  options[:allow_nil]
52
- elsif options.key?(:required)
53
- !options[:required]
54
41
  elsif options.key?(:default) && options[:default].nil?
55
42
  true
56
43
  elsif options[:type]
@@ -64,7 +64,8 @@ module ServiceActor
64
64
  actor = actor.new(result)
65
65
  actor._call
66
66
  else
67
- actor.call(result)
67
+ new_result = actor.call(result)
68
+ result.merge!(new_result.to_h) if new_result.respond_to?(:to_h)
68
69
  end
69
70
 
70
71
  (@played ||= []).unshift(actor)
@@ -3,7 +3,8 @@
3
3
  require 'ostruct'
4
4
 
5
5
  module ServiceActor
6
- # Represents the result of an actor.
6
+ # Represents the context of an actor, holding the data from both its inputs
7
+ # and outputs.
7
8
  class Result < OpenStruct
8
9
  def self.to_result(data)
9
10
  return data if data.is_a?(self)
@@ -22,22 +23,12 @@ module ServiceActor
22
23
  raise Failure, self
23
24
  end
24
25
 
25
- def succeed!(result = {})
26
- warn 'DEPRECATED: Early success with `succeed!` is deprecated in favor ' \
27
- 'of adding conditions to `play` calls.'
28
-
29
- merge!(result)
30
- merge!(failure?: false)
31
-
32
- raise Success, self
33
- end
34
-
35
26
  def success?
36
27
  !failure?
37
28
  end
38
29
 
39
30
  def failure?
40
- super || false
31
+ self[:failure?] || false
41
32
  end
42
33
 
43
34
  def merge!(result)
@@ -1,14 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ServiceActor
4
- # Adds `type:` checking to inputs and outputs. Accepts classes or class names
4
+ # Adds `type:` checking to inputs and outputs. Accepts class names or classes
5
5
  # that should match an ancestor. Also accepts arrays.
6
6
  #
7
7
  # Example:
8
8
  #
9
9
  # class ReduceOrderAmount < Actor
10
- # input :order, type: Order
11
- # input :coupon, type: 'Coupon'
10
+ # input :order, type: 'Order'
12
11
  # input :amount, type: [Integer, Float]
13
12
  # input :bonus_applied, type: [TrueClass FalseClass]
14
13
  # end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ServiceActor
4
- VERSION = '2.0.0'
4
+ VERSION = '3.1.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: service_actor
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sunny Ripert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-24 00:00:00.000000000 Z
11
+ date: 2021-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -80,6 +80,48 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-performance
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: code-scanning-rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: interactor
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
83
125
  description: Service objects for your application logic
84
126
  email:
85
127
  - sunny@sunfox.org
@@ -95,15 +137,16 @@ files:
95
137
  - lib/service_actor/argument_error.rb
96
138
  - lib/service_actor/attributable.rb
97
139
  - lib/service_actor/base.rb
140
+ - lib/service_actor/collectionable.rb
98
141
  - lib/service_actor/conditionable.rb
99
142
  - lib/service_actor/core.rb
100
143
  - lib/service_actor/defaultable.rb
101
144
  - lib/service_actor/error.rb
145
+ - lib/service_actor/failable.rb
102
146
  - lib/service_actor/failure.rb
103
147
  - lib/service_actor/nil_checkable.rb
104
148
  - lib/service_actor/playable.rb
105
149
  - lib/service_actor/result.rb
106
- - lib/service_actor/success.rb
107
150
  - lib/service_actor/type_checkable.rb
108
151
  - lib/service_actor/version.rb
109
152
  homepage: https://github.com/sunny/actor
@@ -112,7 +155,7 @@ licenses:
112
155
  metadata:
113
156
  homepage_uri: https://github.com/sunny/actor
114
157
  source_code_uri: https://github.com/sunny/actor
115
- changelog_uri: https://github.com/sunny/actor/blob/master/CHANGELOG.md
158
+ changelog_uri: https://github.com/sunny/actor/blob/main/CHANGELOG.md
116
159
  post_install_message:
117
160
  rdoc_options: []
118
161
  require_paths:
@@ -121,14 +164,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
164
  requirements:
122
165
  - - ">="
123
166
  - !ruby/object:Gem::Version
124
- version: '0'
167
+ version: '2.4'
125
168
  required_rubygems_version: !ruby/object:Gem::Requirement
126
169
  requirements:
127
170
  - - ">="
128
171
  - !ruby/object:Gem::Version
129
172
  version: '0'
130
173
  requirements: []
131
- rubygems_version: 3.1.2
174
+ rubygems_version: 3.1.4
132
175
  signing_key:
133
176
  specification_version: 4
134
177
  summary: Service objects for your application logic
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ServiceActor
4
- # Raised when using `succeed!` to halt the progression of an organizer.
5
- # DEPRECATED in favor of adding conditions to your play.
6
- class Success < Error; end
7
- end