dry-operation 1.0.0 → 1.1.0
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 +4 -4
- data/CHANGELOG.md +54 -0
- data/LICENSE +1 -1
- data/README.md +9 -6
- data/dry-operation.gemspec +30 -21
- data/lib/dry/operation/extensions/active_record.rb +26 -25
- data/lib/dry/operation/extensions/rom.rb +43 -33
- data/lib/dry/operation/extensions/sequel.rb +17 -17
- data/lib/dry/operation/version.rb +1 -1
- metadata +61 -21
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cc1e7ef446a048939d8e419f77946db6f9ee7621ddad0fed3108fa03129426d9
|
|
4
|
+
data.tar.gz: e45c7a1c4dc5f3baf42897396c227f34481446a2e3721d9ed4fc5f6a8497b4d9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4b914c5124f131eb116ce48e919cc38c0cc00c5f70893ae9629c7eb72dd8e35dcd6e709bcf262019104310d4c0035da7e0097b8ee715bdd5585a57458dd6f315
|
|
7
|
+
data.tar.gz: 4a7d4c96fce72d09f18e4da94dc2db0e49fb1cf99b3acc4ca56f1fbb0e3d9baeed1a862ea0bdf282128afc1d81135175bdbeca469e2605337edbb04c38befd62
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Break Versioning](https://www.taoensso.com/break-versioning).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
### Deprecated
|
|
15
|
+
|
|
16
|
+
### Removed
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
### Security
|
|
21
|
+
|
|
22
|
+
[Unreleased]: https://github.com/dry-rb/dry-operation/compare/v1.1.0...main
|
|
23
|
+
|
|
24
|
+
## [1.1.0] - 2026-02-06
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- In Rom extension, allow transaction options to be passed via `#transaction`. (@wuarmin in #37)
|
|
29
|
+
```ruby
|
|
30
|
+
# Set options at extension time (used for all transactions within the class):
|
|
31
|
+
include Dry::Operation::Extensions::ROM[isolation: :serializable]
|
|
32
|
+
|
|
33
|
+
# Or per-transaction, in instance methods. These will be merged with the extension-level
|
|
34
|
+
# options.
|
|
35
|
+
transaction(savepoint: true) do
|
|
36
|
+
# This transaction will have options `isolation: :serializable, savepoint: true`
|
|
37
|
+
end
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
[1.1.0]: https://github.com/dry-rb/dry-operation/compare/v1.0.1...v1.1.0
|
|
41
|
+
|
|
42
|
+
## [1.0.1] - 2025-10-24
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- Define `#transaction` method in extension modules themselves (which are included into the operation class), rather than directly on the operation class itself. This adheres to typical Ruby inheritance-based method lookup, and allows for overloads of `#transaction` to be defined directly in the operation class or mixed in via other modules. (@timriley in #33)
|
|
47
|
+
|
|
48
|
+
[1.0.1]: https://github.com/dry-rb/dry-operation/compare/v1.0.0...v1.0.1
|
|
49
|
+
|
|
50
|
+
## 1.0.0 - 2024-11-02
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
|
|
54
|
+
- Initial release. (@waiting-for-dev)
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
<!--- This file is synced from hanakai-rb/repo-sync -->
|
|
2
|
+
|
|
3
|
+
[rubygem]: https://rubygems.org/gems/dry-operation
|
|
2
4
|
[actions]: https://github.com/dry-rb/dry-operation/actions
|
|
3
5
|
|
|
4
|
-
# dry-operation [][
|
|
6
|
+
# dry-operation [][rubygem] [][actions]
|
|
5
7
|
|
|
6
8
|
## Links
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
- [User documentation](https://dry-rb.org/gems/dry-operation)
|
|
11
|
+
- [API documentation](http://rubydoc.info/gems/dry-operation)
|
|
12
|
+
- [Forum](https://discourse.dry-rb.org)
|
|
11
13
|
|
|
12
14
|
## License
|
|
13
15
|
|
|
14
|
-
See
|
|
16
|
+
See `LICENSE` file.
|
|
17
|
+
|
data/dry-operation.gemspec
CHANGED
|
@@ -1,31 +1,40 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# This file is synced from hanakai-rb/repo-sync. To update it, edit repo-sync.yml.
|
|
4
|
+
|
|
3
5
|
lib = File.expand_path("lib", __dir__)
|
|
4
|
-
$LOAD_PATH.
|
|
6
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
7
|
require "dry/operation/version"
|
|
6
8
|
|
|
7
9
|
Gem::Specification.new do |spec|
|
|
8
|
-
spec.name
|
|
9
|
-
spec.
|
|
10
|
-
spec.
|
|
11
|
-
spec.
|
|
12
|
-
spec.
|
|
13
|
-
|
|
14
|
-
spec.
|
|
15
|
-
|
|
16
|
-
spec.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
10
|
+
spec.name = "dry-operation"
|
|
11
|
+
spec.authors = ["Hanakai team"]
|
|
12
|
+
spec.email = ["info@hanakai.org"]
|
|
13
|
+
spec.license = "MIT"
|
|
14
|
+
spec.version = Dry::Operation::VERSION.dup
|
|
15
|
+
|
|
16
|
+
spec.summary = "A domain specific language for composable business transaction workflows."
|
|
17
|
+
spec.description = spec.summary
|
|
18
|
+
spec.homepage = "https://dry-rb.org/gems/dry-operation"
|
|
19
|
+
spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-operation.gemspec", "lib/**/*"]
|
|
20
|
+
spec.bindir = "exe"
|
|
21
|
+
spec.executables = Dir["exe/*"].map { |f| File.basename(f) }
|
|
22
|
+
spec.require_paths = ["lib"]
|
|
23
|
+
|
|
24
|
+
spec.extra_rdoc_files = ["README.md", "CHANGELOG.md", "LICENSE"]
|
|
25
|
+
|
|
26
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
|
27
|
+
spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-operation/blob/main/CHANGELOG.md"
|
|
28
|
+
spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-operation"
|
|
29
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-operation/issues"
|
|
30
|
+
spec.metadata["funding_uri"] = "https://github.com/sponsors/hanami"
|
|
24
31
|
|
|
25
32
|
spec.required_ruby_version = ">= 3.1.0"
|
|
26
|
-
spec.add_dependency "zeitwerk", "~> 2.6"
|
|
27
|
-
spec.add_dependency "dry-monads", "~> 1.6"
|
|
28
33
|
|
|
29
|
-
spec.
|
|
30
|
-
spec.
|
|
34
|
+
spec.add_runtime_dependency "dry-monads", "~> 1.6"
|
|
35
|
+
spec.add_runtime_dependency "zeitwerk", "~> 2.6"
|
|
36
|
+
spec.add_development_dependency "bundler"
|
|
37
|
+
spec.add_development_dependency "rspec"
|
|
38
|
+
spec.add_development_dependency "yard"
|
|
31
39
|
end
|
|
40
|
+
|
|
@@ -96,33 +96,34 @@ module Dry
|
|
|
96
96
|
@options = options
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
-
def included(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
99
|
+
def included(_klass)
|
|
100
|
+
default_connection = @connection
|
|
101
|
+
default_options = @options
|
|
102
|
+
|
|
103
|
+
# @!method transaction(connection = ActiveRecord::Base, **options, &steps)
|
|
104
|
+
# Wrap the given steps in an ActiveRecord transaction.
|
|
105
|
+
#
|
|
106
|
+
# If any of the steps returns a `Dry::Monads::Result::Failure`, the
|
|
107
|
+
# transaction will be rolled back and `:halt` will be thrown with the
|
|
108
|
+
# failure as its value.
|
|
109
|
+
#
|
|
110
|
+
# @param connection [#transaction] The class/object to use
|
|
111
|
+
# @param options [Hash] Additional options for the ActiveRecord transaction
|
|
112
|
+
# @yieldreturn [Object] the result of the block
|
|
113
|
+
# @see Dry::Operation#steps
|
|
114
|
+
# @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html#method-i-transaction
|
|
115
|
+
define_method(:transaction) do |connection = default_connection, **opts, &steps|
|
|
116
|
+
intercepting_failure do
|
|
117
|
+
result = nil
|
|
118
|
+
connection.transaction(**default_options.merge(opts)) do
|
|
119
|
+
intercepting_failure(->(failure) {
|
|
120
|
+
result = failure
|
|
121
|
+
raise ::ActiveRecord::Rollback
|
|
122
|
+
}) do
|
|
123
|
+
result = steps.()
|
|
123
124
|
end
|
|
124
|
-
result
|
|
125
125
|
end
|
|
126
|
+
result
|
|
126
127
|
end
|
|
127
128
|
end
|
|
128
129
|
end
|
|
@@ -9,15 +9,14 @@ end
|
|
|
9
9
|
module Dry
|
|
10
10
|
class Operation
|
|
11
11
|
module Extensions
|
|
12
|
-
# Add
|
|
12
|
+
# Add Rom transaction support to operations.
|
|
13
13
|
#
|
|
14
|
-
# When this extension is included, you can use a `#transaction` method
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
# back and, as usual, the rest of the flow will be skipped.
|
|
14
|
+
# When this extension is included, you can use a `#transaction` method to wrap the desired
|
|
15
|
+
# steps in a Rom transaction. If any of the steps returns a `Dry::Monads::Result::Failure`,
|
|
16
|
+
# the transaction will be rolled back and, as usual, the rest of the flow will be skipped.
|
|
18
17
|
#
|
|
19
|
-
# The extension expects the including class to give access to the rom
|
|
20
|
-
#
|
|
18
|
+
# The extension expects the including class to give access to the Rom container via a `#rom`
|
|
19
|
+
# method.
|
|
21
20
|
#
|
|
22
21
|
# ```ruby
|
|
23
22
|
# require "dry/operation/extensions/rom"
|
|
@@ -46,18 +45,27 @@ module Dry
|
|
|
46
45
|
# end
|
|
47
46
|
# ```
|
|
48
47
|
#
|
|
49
|
-
# By default, the `:default` gateway will be used
|
|
50
|
-
#
|
|
48
|
+
# By default, the `:default` gateway will be used and no additional
|
|
49
|
+
# options will be passed to the Rom transaction.
|
|
50
|
+
#
|
|
51
|
+
# You can change the default gateway and transaction options when
|
|
52
|
+
# including the extension:
|
|
51
53
|
#
|
|
52
54
|
# ```ruby
|
|
53
|
-
# include Dry::Operation::Extensions::ROM[
|
|
55
|
+
# include Dry::Operation::Extensions::ROM[
|
|
56
|
+
# gateway: :my_gateway,
|
|
57
|
+
# isolation: :serializable
|
|
58
|
+
# ]
|
|
54
59
|
# ```
|
|
55
60
|
#
|
|
56
|
-
#
|
|
61
|
+
# You can also override the gateway and/or transaction options at runtime:
|
|
57
62
|
#
|
|
58
63
|
# ```ruby
|
|
59
|
-
# user = transaction(
|
|
60
|
-
#
|
|
64
|
+
# user = transaction(
|
|
65
|
+
# gateway: :my_gateway,
|
|
66
|
+
# isolation: :serializable
|
|
67
|
+
# ) do
|
|
68
|
+
# # ...
|
|
61
69
|
# end
|
|
62
70
|
# ```
|
|
63
71
|
#
|
|
@@ -84,37 +92,39 @@ module Dry
|
|
|
84
92
|
# Include the extension providing a custom gateway
|
|
85
93
|
#
|
|
86
94
|
# @param gateway [Symbol] the rom gateway to use
|
|
87
|
-
def self.[](gateway: DEFAULT_GATEWAY)
|
|
88
|
-
Builder.new(gateway: gateway)
|
|
95
|
+
def self.[](gateway: DEFAULT_GATEWAY, **options)
|
|
96
|
+
Builder.new(gateway: gateway, **options)
|
|
89
97
|
end
|
|
90
98
|
|
|
91
99
|
# @api private
|
|
92
100
|
class Builder < Module
|
|
93
|
-
def initialize(gateway
|
|
101
|
+
def initialize(gateway:, **options)
|
|
94
102
|
super()
|
|
95
103
|
@gateway = gateway
|
|
104
|
+
@options = options
|
|
96
105
|
end
|
|
97
106
|
|
|
98
|
-
def included(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
107
|
+
def included(_klass)
|
|
108
|
+
default_gateway = @gateway
|
|
109
|
+
default_options = @options
|
|
110
|
+
|
|
111
|
+
define_method(:transaction) do |gateway: default_gateway, **opts, &steps|
|
|
112
|
+
raise Dry::Operation::ExtensionError, <<~MSG unless respond_to?(:rom)
|
|
113
|
+
When using the Rom extension, you need to define a #rom method \
|
|
114
|
+
that returns the Rom container
|
|
115
|
+
MSG
|
|
105
116
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
end
|
|
117
|
+
intercepting_failure do
|
|
118
|
+
result = nil
|
|
119
|
+
rom.gateways[gateway].transaction(**default_options.merge(opts)) do |t|
|
|
120
|
+
intercepting_failure(->(failure) {
|
|
121
|
+
result = failure
|
|
122
|
+
t.rollback!
|
|
123
|
+
}) do
|
|
124
|
+
result = steps.()
|
|
115
125
|
end
|
|
116
|
-
result
|
|
117
126
|
end
|
|
127
|
+
result
|
|
118
128
|
end
|
|
119
129
|
end
|
|
120
130
|
end
|
|
@@ -81,26 +81,26 @@ module Dry
|
|
|
81
81
|
@options = options
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
def included(
|
|
85
|
-
|
|
86
|
-
klass.define_method(:transaction) do |**opts, &steps|
|
|
87
|
-
raise Dry::Operation::ExtensionError, <<~MSG unless respond_to?(:db)
|
|
88
|
-
When using the Sequel extension, you need to define a #db method \
|
|
89
|
-
that returns the Sequel database object
|
|
90
|
-
MSG
|
|
84
|
+
def included(_klass)
|
|
85
|
+
default_options = @options
|
|
91
86
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
87
|
+
define_method(:transaction) do |**opts, &steps|
|
|
88
|
+
raise Dry::Operation::ExtensionError, <<~MSG unless respond_to?(:db)
|
|
89
|
+
When using the Sequel extension, you need to define a #db method \
|
|
90
|
+
that returns the Sequel database object
|
|
91
|
+
MSG
|
|
92
|
+
|
|
93
|
+
intercepting_failure do
|
|
94
|
+
result = nil
|
|
95
|
+
db.transaction(**default_options.merge(opts)) do
|
|
96
|
+
intercepting_failure(->(failure) {
|
|
97
|
+
result = failure
|
|
98
|
+
raise ::Sequel::Rollback
|
|
99
|
+
}) do
|
|
100
|
+
result = steps.()
|
|
101
101
|
end
|
|
102
|
-
result
|
|
103
102
|
end
|
|
103
|
+
result
|
|
104
104
|
end
|
|
105
105
|
end
|
|
106
106
|
end
|
metadata
CHANGED
|
@@ -1,52 +1,95 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dry-operation
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
bindir: bin
|
|
7
|
+
- Hanakai team
|
|
8
|
+
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: dry-monads
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
16
|
- - "~>"
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
18
|
+
version: '1.6'
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - "~>"
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
25
|
+
version: '1.6'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
27
|
+
name: zeitwerk
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
30
|
- - "~>"
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
32
|
+
version: '2.6'
|
|
34
33
|
type: :runtime
|
|
35
34
|
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
37
|
- - "~>"
|
|
39
38
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
41
|
-
|
|
39
|
+
version: '2.6'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: bundler
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rspec
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: yard
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
82
|
+
description: A domain specific language for composable business transaction workflows.
|
|
42
83
|
email:
|
|
43
|
-
-
|
|
84
|
+
- info@hanakai.org
|
|
44
85
|
executables: []
|
|
45
86
|
extensions: []
|
|
46
87
|
extra_rdoc_files:
|
|
47
|
-
-
|
|
88
|
+
- CHANGELOG.md
|
|
48
89
|
- LICENSE
|
|
90
|
+
- README.md
|
|
49
91
|
files:
|
|
92
|
+
- CHANGELOG.md
|
|
50
93
|
- LICENSE
|
|
51
94
|
- README.md
|
|
52
95
|
- dry-operation.gemspec
|
|
@@ -63,13 +106,11 @@ homepage: https://dry-rb.org/gems/dry-operation
|
|
|
63
106
|
licenses:
|
|
64
107
|
- MIT
|
|
65
108
|
metadata:
|
|
66
|
-
|
|
109
|
+
allowed_push_host: https://rubygems.org
|
|
67
110
|
changelog_uri: https://github.com/dry-rb/dry-operation/blob/main/CHANGELOG.md
|
|
68
|
-
documentation_uri: https://dry-rb.org/gems/dry-operation
|
|
69
|
-
funding_uri: https://github.com/sponsors/hanami
|
|
70
|
-
label: dry-operation
|
|
71
111
|
source_code_uri: https://github.com/dry-rb/dry-operation
|
|
72
|
-
|
|
112
|
+
bug_tracker_uri: https://github.com/dry-rb/dry-operation/issues
|
|
113
|
+
funding_uri: https://github.com/sponsors/hanami
|
|
73
114
|
rdoc_options: []
|
|
74
115
|
require_paths:
|
|
75
116
|
- lib
|
|
@@ -84,8 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
84
125
|
- !ruby/object:Gem::Version
|
|
85
126
|
version: '0'
|
|
86
127
|
requirements: []
|
|
87
|
-
rubygems_version: 3.
|
|
88
|
-
signing_key:
|
|
128
|
+
rubygems_version: 3.6.9
|
|
89
129
|
specification_version: 4
|
|
90
130
|
summary: A domain specific language for composable business transaction workflows.
|
|
91
131
|
test_files: []
|