service_base 1.0.1 → 1.0.3
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/README.md +105 -96
- data/lib/generators/application_service_generator.rb +26 -0
- data/lib/generators/service_base/install_generator.rb +12 -0
- data/lib/generators/types_generator.rb +27 -0
- data/lib/service_base/argument_type_annotations.rb +0 -4
- data/lib/service_base/service.rb +8 -16
- data/lib/service_base/types.rb +6 -12
- data/lib/service_base/version.rb +1 -1
- data/lib/service_base.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17af4f8d7a5f86ee24adbbbba2118e7b47134f2730e4e04fb0c0107c86cfa168
|
4
|
+
data.tar.gz: 1ad5a04d75c99bbc061d1ab53ce67d0d8864c132b8be85ebeb4da3b1f759d996
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 559196375ec8a48520b076feb989287c43e84cf7a759b91d0db753448f9199fe02f3febff0a06e9d797523f5774e58d26e4745f921820f94298519873d4a5732
|
7
|
+
data.tar.gz: ec37a4775094ebf67fa9e09b3db800206f31f8cfa5775866675f0213f9f188f5b228bc503e6e2ff7b3827bcfae039cc1dc0285796e96831ef990f182174a5709
|
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# Service Base
|
2
2
|
|
3
|
-
A base service class for Ruby applications that provides common functionality and argument type annotations.
|
3
|
+
A base service class for Ruby applications that provides common functionality and argument type annotations DSL.
|
4
|
+
|
5
|
+
## Dependencies
|
6
|
+
|
7
|
+
Simply Ruby. This gem can be used in a standalone fashion and Rails is not a dependency. This gem does, however, work very nicely with Rails conventions and includes generators for getting set up quickly.
|
4
8
|
|
5
9
|
## Installation
|
6
10
|
|
@@ -11,18 +15,23 @@ gem "service_base"
|
|
11
15
|
```
|
12
16
|
|
13
17
|
And then execute:
|
14
|
-
```
|
18
|
+
```sh
|
15
19
|
$ bundle install
|
16
20
|
```
|
17
21
|
|
18
22
|
Or install it yourself as:
|
19
|
-
```
|
23
|
+
```sh
|
20
24
|
$ gem install service_base
|
21
25
|
```
|
22
26
|
|
23
|
-
|
27
|
+
For Rails projects, then run:
|
28
|
+
```sh
|
29
|
+
rails g service_base:install
|
30
|
+
```
|
24
31
|
|
32
|
+
Installing the gem in a Rails project will create an `ApplicationService` subclass, following Rails conventions.
|
25
33
|
```rb
|
34
|
+
# app/services/application_service.rb
|
26
35
|
class ApplicationService < ServiceBase::Service
|
27
36
|
end
|
28
37
|
```
|
@@ -47,46 +56,37 @@ on Rails pattern: Service Objects](https://dev.to/joker666/ruby-on-rails-pattern
|
|
47
56
|
|
48
57
|
## Advantages
|
49
58
|
|
50
|
-
- The action of a service should read as a list of steps which makes
|
51
|
-
reading and maintaining the service easy.
|
59
|
+
- The action of a service should read as a list of steps which makes reading and maintaining the service easy.
|
52
60
|
- Instantiation of a service object allows fine grained control over
|
53
61
|
the arguments being passed in and reduces the need to pass arguments
|
54
62
|
between methods in the same instance.
|
55
63
|
- Encapsulation of logic in a service makes for reusable code, simpler
|
56
64
|
testing, and extracts logic from other objects that should not be
|
57
65
|
responsible for handling that logic.
|
66
|
+
- Removes the need for ActiveRecord callbacks and consolidates logic of related models into one place in the codebase.
|
58
67
|
- Verb-naming makes the intention of the service explicit.
|
59
68
|
- Single service actions reveal a single public interface.
|
60
69
|
|
61
70
|
## What defines a service?
|
62
71
|
|
63
|
-
- The main difference between a model and a service is that a model
|
64
|
-
“models” **what** something is while a service lists
|
65
|
-
**how** an action is performed.
|
72
|
+
- The main difference between a model and a service is that a model “models” **what** something is while a service lists **how** an action is performed.
|
66
73
|
- A service has a single public method, ie. `call`
|
67
|
-
- A model is a noun, a service is a verb’ed noun that does the one
|
68
|
-
|
69
|
-
|
70
|
-
- Ie. `StripeResponse` (model) versus `PaymentHistoryFetcherService` (service)
|
74
|
+
- A model is a noun, a service is a verb or verb’ed noun that does the one thing the name implies
|
75
|
+
- Ie. `User` (model) versus `User::CreatorService` (service)
|
76
|
+
- Ie. `StripeResponse` (model) versus `PaymentHistoryFetcherService` (service)
|
71
77
|
|
72
78
|
## Naming
|
73
79
|
|
74
|
-
One of the best ways to use the service pattern is for CRUD services - Ie. `ActiveRecordModel` +
|
75
|
-
`::CreateService`, `::UpdateService`,
|
76
|
-
`::DeleteService`. This avoids the use of callbacks, mystery guests, and unexpected side effects because all the steps to do a CRUD action are in one place and in order.
|
80
|
+
One of the best ways to use the service pattern is for CRUD services - Ie. `ActiveRecordModel` + `::CreateService`, `::UpdateService`, `::DeleteService`. This avoids the use of callbacks, mystery guests, and unexpected side effects because all the steps to do a CRUD action are in one place and in order of execution.
|
77
81
|
|
78
82
|
## Returning a Result
|
79
83
|
|
80
|
-
Each service inheriting from BaseService must define
|
81
|
-
|
82
|
-
`Failure`. These types are `Result` Monads from
|
83
|
-
the dry-monads gem. Both `Result` types may take any value as
|
84
|
-
input, ie. `Success(user)`,
|
85
|
-
`Failure(:not_found)`
|
84
|
+
Each service inheriting from BaseService must define `#call` and return a `Success` or `Failure`. These types are `Result` Monads from
|
85
|
+
the [dry-monads gem](https://dry-rb.org/gems/dry-monads/1.3/). Both `Result` types may take any value as input, ie. `Success(user)`, `Failure(:not_found)`
|
86
86
|
|
87
87
|
`Failure` can return any value you’d like the caller to have in order to understand the failure.
|
88
88
|
|
89
|
-
The caller of service can unwrap the Success
|
89
|
+
The caller of service can unwrap the `Success` or `Failure`.
|
90
90
|
|
91
91
|
```ruby
|
92
92
|
MyService.call(name: user.name) do |on|
|
@@ -95,8 +95,7 @@ MyService.call(name: user.name) do |on|
|
|
95
95
|
end
|
96
96
|
```
|
97
97
|
|
98
|
-
To match different expected values of success or failure, pass the
|
99
|
-
value as an argument.
|
98
|
+
To match different expected values of success or failure, pass the value as an argument when unwrapping it.
|
100
99
|
|
101
100
|
```ruby
|
102
101
|
MyService.call(name: user.name) do |on|
|
@@ -107,36 +106,23 @@ MyService.call(name: user.name) do |on|
|
|
107
106
|
end
|
108
107
|
```
|
109
108
|
|
110
|
-
Note that you must define both `on.success` and
|
111
|
-
`on.failure` or else an error will be raised in the
|
112
|
-
caller.
|
109
|
+
Note that you must define both `on.success` and `on.failure` or else an error will be raised in the caller.
|
113
110
|
|
114
|
-
Note that `raise`ing an error requires an error class
|
115
|
-
unless the error itself is an instance of an error class.
|
111
|
+
Note that `raise`ing an error requires an error class unless the error itself is an instance of an error class.
|
116
112
|
|
117
|
-
Please see [result](https://dry-rb.org/gems/dry-monads/1.3/result/) for
|
118
|
-
additional mechanisms used for chaining results and handling
|
119
|
-
success/failure values.
|
120
|
-
|
121
|
-
A recommended pattern within services is to return a
|
122
|
-
`Success` and/or `Failure` from each method and
|
123
|
-
yield the result in the caller. This forces you to consider how each
|
124
|
-
method could fail and allows for automatic bubbling up of the
|
125
|
-
`Failure` via railway-style programming. Examples at [https://dry-rb.org/gems/dry-monads/1.3/do-notation/#adding-batteries](https://dry-rb.org/gems/dry-monads/1.3/do-notation/#adding-batteries)
|
113
|
+
Please see [result](https://dry-rb.org/gems/dry-monads/1.3/result/) for additional mechanisms used for chaining results and handling success/failure values.
|
126
114
|
|
127
115
|
## Failures vs Exceptions
|
128
116
|
|
129
|
-
Failure = a known error case that may happen and should be gracefully
|
130
|
-
handled
|
117
|
+
Failure = a known error case that may happen and should be gracefully handled
|
131
118
|
|
132
|
-
Raising = an unexpected exception (exceptional circumstances)
|
119
|
+
Raising = an **unexpected** exception (exceptional circumstances)
|
133
120
|
|
134
121
|
Any call that `raise`s is not rescued by default and will
|
135
|
-
behave as a typical Ruby exception. This is a good thing.
|
122
|
+
behave as a typical Ruby exception. This is a good thing. You will be
|
136
123
|
alerted when exceptional circumstances arise.
|
137
124
|
|
138
|
-
Return a `Failure` instead when you know of a potential
|
139
|
-
failure case.
|
125
|
+
Return a `Failure` instead when you know of a potential failure case.
|
140
126
|
|
141
127
|
Avoid rescuing major error/exception superclasses such as
|
142
128
|
`StandardError`. Doing so will rescue all subclasses of that
|
@@ -161,81 +147,104 @@ end
|
|
161
147
|
## Arguments
|
162
148
|
|
163
149
|
Arguments to a service are defined via the `argument` DSL.
|
164
|
-
The positional name and type arguments are required, the other options
|
165
|
-
|
166
|
-
`argument(:name, String, optional: true, description: "The User's name")`
|
167
|
-
|
168
|
-
If an argument is optional and has a default value, simply set
|
169
|
-
`default: your_value` but do not also specify
|
170
|
-
`optional: true`. Doing so will raise an
|
171
|
-
`ArgumentError`. Additionally, be sure to
|
172
|
-
`.freeze` any mutable default values, ie.
|
173
|
-
`default: {}.freeze`. Failure to do so will raise an
|
174
|
-
`ArgumentError`.
|
150
|
+
The positional name and type arguments are required, the other options are as follows.
|
151
|
+
`argument(:name, Type::String, optional: true, description: "The User's name")`
|
175
152
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
153
|
+
If an argument is optional and has a default value, simply set `default: your_value` but do not also specify `optional: true`.
|
154
|
+
Doing so will raise an `ArgumentError`.
|
155
|
+
|
156
|
+
Additionally, be sure to `.freeze` any mutable default values, ie. `default: {}.freeze`.
|
157
|
+
Failure to do so will raise an `ArgumentError`.
|
158
|
+
|
159
|
+
To allow multiple types as arguments, use `|`. For example,
|
160
|
+
|
161
|
+
```rb
|
162
|
+
argument(:value, Type::String | Type::Integer)
|
163
|
+
```
|
180
164
|
|
181
|
-
A service should also define a `description`. This is
|
182
|
-
recommended for self-documentation, ie.
|
165
|
+
A service should also define a `description`. This is recommended for self-documentation, ie.
|
183
166
|
|
184
167
|
```ruby
|
185
|
-
class MyService <
|
168
|
+
class MyService < ApplicationService
|
186
169
|
description("Does a lot of cool things")
|
187
170
|
end
|
188
171
|
```
|
189
172
|
|
190
|
-
To get the full hash of `argument`s passed into a service,
|
191
|
-
|
192
|
-
services that update an object. For example
|
173
|
+
To get the full hash of `argument`'s keys and values passed into a service,
|
174
|
+
call `arguments`. This is a very useful technique for services that update an object. For example
|
193
175
|
|
194
176
|
```ruby
|
195
|
-
class User::UpdateService <
|
177
|
+
class User::UpdateService < ApplicationService
|
178
|
+
argument(:name, String)
|
179
|
+
|
196
180
|
def call
|
197
|
-
user.update(
|
181
|
+
user.update(arguments)
|
198
182
|
end
|
199
183
|
end
|
200
184
|
```
|
201
185
|
|
202
|
-
###
|
186
|
+
### Nil
|
203
187
|
|
204
|
-
|
188
|
+
Empty strings attempted to coerce into integers will throw an error.
|
189
|
+
See [this GH issue for an explaination](https://github.com/dry-rb/dry-types/issues/344#issuecomment-518743661)
|
190
|
+
To instead accept `nil`, do the following:
|
191
|
+
`argument(:some_integer, Type::Params::Nil | Type::Params::Integer)`
|
205
192
|
|
206
|
-
`argument(:my_record, ApplicationRecord)`
|
207
193
|
|
208
|
-
|
194
|
+
## Types
|
209
195
|
|
210
|
-
|
196
|
+
Argument types come from, [Dry.rb’s Types](https://dry-rb.org/gems/dry-types/1.2/built-in-types/), which can be extended.
|
197
|
+
You may also add custom types as outlined in [Dry.rb Custom Types](https://dry-rb.org/gems/dry-types/1.2/custom-types/).
|
211
198
|
|
212
|
-
|
199
|
+
The Rails generators will create a Type module, which includes `ServiceBase::Types`, which includes `Dry.Types`. Therefore, all types defined in Dry.rb's Types are available to you.
|
213
200
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
201
|
+
```rb
|
202
|
+
# app/models/type.rb
|
203
|
+
module Type
|
204
|
+
include ServiceBase::Types
|
205
|
+
|
206
|
+
# Any ApplicationRecord subclass
|
207
|
+
ApplicationRecord = Dry.Types.Instance(ApplicationRecord)
|
208
|
+
User = Dry.Types.Instance(User)
|
209
|
+
Project = Dry.Types.Instance(Project)
|
210
|
+
|
211
|
+
# Controller params are an ActionController::Parameters instance or a hash (easier for testing)
|
212
|
+
ControllerParams = Dry.Types.Instance(ActionController::Parameters) | Dry.Types.Instance(Hash)
|
213
|
+
|
214
|
+
# Customer param hashes
|
215
|
+
AddressParams = Dry::Types['hash'].schema(
|
216
|
+
address: Dry::Types['string'],
|
217
|
+
address2: Dry::Types['string'],
|
218
|
+
city: Dry::Types['string'],
|
219
|
+
state: Dry::Types['string'],
|
220
|
+
zip: Dry::Types['string']
|
221
|
+
)
|
222
|
+
end
|
218
223
|
|
219
|
-
|
224
|
+
# app/services/example_service.rb
|
225
|
+
class ExampleService < ApplicationService
|
226
|
+
argument(:any_model, Type::ApplicationRecord, description: "The model to update")
|
227
|
+
argument(:params, Type::ControllerParams, description: "The attributes to update")
|
228
|
+
argument(:user, Type::User, description: "A cool user that relates to the model")
|
229
|
+
argument(:project, Type::Project, description: "A project that the user is working on")
|
230
|
+
argument(:address, Type::AddressParams, description: "The user's address")
|
231
|
+
end
|
232
|
+
```
|
220
233
|
|
221
|
-
`Coercible` and `Params` Types are very
|
222
|
-
powerful and recommended for automatic parsing of inputs, ie. controller
|
223
|
-
parameters.
|
234
|
+
Dry.rb's `Coercible` and `Params` Types are very powerful and recommended for automatic parsing of inputs, ie. controller parameters.
|
224
235
|
|
225
|
-
For example `argument(:number, Params::Integer)` will
|
226
|
-
convert `"12"` ⇒ `12`
|
236
|
+
For example `argument(:number, Type::Params::Integer)` will convert `"12"` ⇒ `12`.
|
227
237
|
|
228
|
-
Entire hash structures may also be validated and automatically
|
229
|
-
parsed, for example:
|
238
|
+
Entire hash structures may also be validated and automatically parsed, for example:
|
230
239
|
|
231
240
|
```ruby
|
232
241
|
argument(
|
233
242
|
:line_items,
|
234
|
-
Array(
|
235
|
-
Hash.schema(
|
236
|
-
vintage_year: Params::Integer,
|
237
|
-
number_of_credits: Params::Integer,
|
238
|
-
price_dollars_usd: Params::Float,
|
243
|
+
Type::Array(
|
244
|
+
Type::Hash.schema(
|
245
|
+
vintage_year: Type::Params::Integer,
|
246
|
+
number_of_credits: Type::Params::Integer,
|
247
|
+
price_dollars_usd: Type::Params::Float,
|
239
248
|
),
|
240
249
|
),
|
241
250
|
```
|
@@ -266,10 +275,10 @@ roll the transaction back](https://www.loyalty.dev/posts/returning-from-transact
|
|
266
275
|
|
267
276
|
## Internal Method Result
|
268
277
|
|
269
|
-
|
270
|
-
`yield`
|
271
|
-
|
272
|
-
|
278
|
+
A recommended pattern within services is to return a `Success` and/or `Failure` from each method and
|
279
|
+
`yield` the result in the caller. This forces you to consider how each
|
280
|
+
method could fail and allows for automatic bubbling up of the
|
281
|
+
`Failure` via railway-style programming. Examples at [https://dry-rb.org/gems/dry-monads/1.3/do-notation/#adding-batteries](https://dry-rb.org/gems/dry-monads/1.3/do-notation/#adding-batteries)
|
273
282
|
|
274
283
|
If the internal methods of the service need to unwrap values, those specific methods need to be registered with the result matcher like so.
|
275
284
|
|
@@ -323,4 +332,4 @@ Bug reports and pull requests are welcome on GitHub.
|
|
323
332
|
|
324
333
|
## License
|
325
334
|
|
326
|
-
The gem is available as open source under the terms of the MIT License.
|
335
|
+
The gem is available as open source under the terms of the MIT License.
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ApplicationServiceGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path('templates', __dir__)
|
5
|
+
|
6
|
+
def create_application_service_file
|
7
|
+
service_path = 'app/services/application_service.rb'
|
8
|
+
|
9
|
+
if File.exist?(service_path)
|
10
|
+
# File exists, check if it needs to be updated
|
11
|
+
content = File.read(service_path)
|
12
|
+
|
13
|
+
unless content.include?('class ApplicationService < ServiceBase::Service')
|
14
|
+
# Update the class definition
|
15
|
+
new_content = content.sub(/class ApplicationService.*\n/, "class ApplicationService < ServiceBase::Service\n")
|
16
|
+
File.write(service_path, new_content)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
# Create new file with template
|
20
|
+
create_file service_path, <<~RUBY
|
21
|
+
class ApplicationService < ServiceBase::Service
|
22
|
+
end
|
23
|
+
RUBY
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TypesGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path('templates', __dir__)
|
5
|
+
|
6
|
+
def create_types_file
|
7
|
+
types_path = 'app/models/type.rb'
|
8
|
+
|
9
|
+
if File.exist?(types_path)
|
10
|
+
# File exists, check if it needs the include statement
|
11
|
+
content = File.read(types_path)
|
12
|
+
|
13
|
+
unless content.include?('include ServiceBase::Types')
|
14
|
+
# Add include statement at the top of the module
|
15
|
+
new_content = content.sub(/module Type\s*\n/, "module Type\n include ServiceBase::Types\n")
|
16
|
+
File.write(types_path, new_content)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
# Create new file with template
|
20
|
+
create_file types_path, <<~RUBY
|
21
|
+
module Type
|
22
|
+
include ServiceBase::Types
|
23
|
+
end
|
24
|
+
RUBY
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -7,10 +7,6 @@ module ServiceBase
|
|
7
7
|
if !klass.is_a?(Class) || !klass.ancestors.include?(Dry::Struct)
|
8
8
|
raise(TypeError, "#{name} should be extended on a Dry::Struct subclass")
|
9
9
|
end
|
10
|
-
|
11
|
-
# `Types` overrides default types to help shorthand Type::String.
|
12
|
-
# To access Ruby's native types within a service, use `::`, ie. `::String`
|
13
|
-
klass.include(Types)
|
14
10
|
end
|
15
11
|
|
16
12
|
def included(klass)
|
data/lib/service_base/service.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'dry-matcher'
|
4
|
-
require 'dry-struct'
|
5
|
-
require 'dry/matcher/result_matcher'
|
6
3
|
require 'dry/monads'
|
7
4
|
require 'dry/monads/do'
|
5
|
+
require 'dry/matcher/result_matcher'
|
6
|
+
require 'dry-struct'
|
7
|
+
require 'dry-matcher'
|
8
8
|
require 'memery'
|
9
9
|
|
10
10
|
module ServiceBase
|
@@ -95,24 +95,16 @@ module ServiceBase
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
+
# Returns a hash of all arguments and their values
|
99
|
+
def arguments
|
100
|
+
attributes
|
101
|
+
end
|
102
|
+
|
98
103
|
private
|
99
104
|
|
100
105
|
# The call method that must be defined by every inheriting service class
|
101
106
|
def call
|
102
107
|
raise(NotImplementedError)
|
103
108
|
end
|
104
|
-
|
105
|
-
# A locale lookup helper that uses the name of the service
|
106
|
-
def locale(selector, args = {})
|
107
|
-
class_name = self.class.name.gsub('::', '.').underscore
|
108
|
-
I18n.t(".#{selector}", scope: "services.#{class_name}", **args)
|
109
|
-
end
|
110
|
-
|
111
|
-
# Structured Monad Result Failure type for returning a ResponseError
|
112
|
-
class ResponseFailure < Dry::Monads::Result::Failure
|
113
|
-
def initialize(message, code, trace = Dry::Monads::RightBiased::Left.trace_caller)
|
114
|
-
super(ResponseError.new(message: message, code: code), trace)
|
115
|
-
end
|
116
|
-
end
|
117
109
|
end
|
118
110
|
end
|
data/lib/service_base/types.rb
CHANGED
@@ -1,20 +1,14 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Defines Dry Types. These Types are included in the ServiceBase for type
|
4
|
-
# enforcement when defining `argument`s.
|
5
|
-
#
|
6
|
-
# For example, you may want to add `ApplicationRecord = Types.Instance(ApplicationRecord)`
|
7
|
-
#
|
8
|
-
# Add custom types as outlined in
|
9
|
-
# https://dry-rb.org/gems/dry-types/1.2/custom-types/
|
10
|
-
|
11
1
|
require 'dry-types'
|
12
2
|
|
13
3
|
module ServiceBase
|
14
4
|
module Types
|
15
5
|
include Dry.Types()
|
16
6
|
|
17
|
-
|
18
|
-
|
7
|
+
def self.included(base)
|
8
|
+
constants.each { |constant| base.const_set(constant, const_get("#{self}::#{constant}")) }
|
9
|
+
end
|
10
|
+
|
11
|
+
# Alias Bool -> Boolean
|
12
|
+
Boolean = Dry::Types['bool']
|
19
13
|
end
|
20
14
|
end
|
data/lib/service_base/version.rb
CHANGED
data/lib/service_base.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'service_base/version'
|
4
|
-
require_relative 'service_base/types'
|
5
4
|
require_relative 'service_base/argument_type_annotations'
|
6
5
|
require_relative 'service_base/service'
|
6
|
+
require_relative 'service_base/types'
|
7
7
|
|
8
8
|
module ServiceBase
|
9
9
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: service_base
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Klein
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-04-
|
10
|
+
date: 2025-04-24 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: dry-matcher
|
@@ -89,6 +89,9 @@ extra_rdoc_files: []
|
|
89
89
|
files:
|
90
90
|
- LICENSE.txt
|
91
91
|
- README.md
|
92
|
+
- lib/generators/application_service_generator.rb
|
93
|
+
- lib/generators/service_base/install_generator.rb
|
94
|
+
- lib/generators/types_generator.rb
|
92
95
|
- lib/service_base.rb
|
93
96
|
- lib/service_base/argument_type_annotations.rb
|
94
97
|
- lib/service_base/rspec.rb
|