zen-service 2.2.2 → 2.2.4

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: d2a045fb0ae0896e986724321a4f4aa0d0a64cad73d8a89e626cd89e4acf3939
4
- data.tar.gz: 33c45fe9167acf965fa345cb1c0a9172a1b8a18cb3461a04fc692052f6101891
3
+ metadata.gz: 7c1c54fed5a49c87cdbdfbaf9cb369e8eed0ac2a0e1862eadd5edca95af1f931
4
+ data.tar.gz: 2c4d4efaaa636193e3d4daa6d94a375e1e67f7c8bfc0ab930d8cedbd36023012
5
5
  SHA512:
6
- metadata.gz: 40009fb2ea48e8f7f884579d5f9fb9e2e29569fbc35ae192b02fd1ccead1033ce25c0c0941003653e3ed4423236e6f4acbd410bb4e239c9700d6e6217def14b9
7
- data.tar.gz: 7b4f3074829a7bbbb4a6f18c7fd28b2bb27b742c4f629eea00e615adc25bed9d690677e2a96a31f8273959c16e83f72d68d404c51ead6e6c9a4dce427d020f77
6
+ metadata.gz: 24394d2ecd8f0af333c82b23089b5c53b2481db6cee8ebffc78f9f69b80fc371c58020064d1650453f5a146bd789d76e6db62b90a4885ad34fcc7af57959ce07
7
+ data.tar.gz: 746b18aaa03abe11e5c194e6817da0b84e1e18c1226f2f67e7f6a981bf9dfc331ff422afc8518e08ea11bdb58ec6f79b0dac34b855335eb2cdb361e2912b85b5
@@ -0,0 +1,36 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby-version: ['3.2', '3.3']
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Ruby ${{ matrix.ruby-version }}
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby-version }}
23
+ bundler-cache: true
24
+
25
+ - name: Run tests
26
+ run: bundle exec rspec
27
+
28
+ - name: Upload coverage to Codecov
29
+ if: matrix.ruby-version == '3.3'
30
+ uses: codecov/codecov-action@v4
31
+ with:
32
+ files: ./coverage/coverage.xml
33
+ flags: unittests
34
+ name: codecov-umbrella
35
+ fail_ci_if_error: false
36
+ token: ${{ secrets.CODECOV_TOKEN }}
data/.gitignore CHANGED
@@ -8,6 +8,7 @@
8
8
  /spec/reports/
9
9
  /tmp/
10
10
 
11
+ .github/workflows/README.md
11
12
  .rspec_status
12
13
  .ruby-version
13
14
  .ruby-gemset
data/CHANGELOG.md ADDED
@@ -0,0 +1,103 @@
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 [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [2.2.4] - 2026-01-19
9
+
10
+ ### Fixed
11
+
12
+ - Fix using named attributes in `.call` and `.[]` class-level call helpers
13
+
14
+ ## [2.2.3] - 2026-01-19
15
+
16
+ ### Fixed
17
+
18
+ - Fix block passing when calling service using `.call` and `.[]` class methods
19
+
20
+ ### Changed
21
+
22
+ - Add CI workflow with GitHub Actions
23
+ - Add SimpleCov integration with 100% test coverage (line and branch coverage)
24
+ - Update README with comprehensive documentation, shield badges, and improved examples
25
+
26
+ ## [2.2.2] - 2025-12-30
27
+
28
+ ### Fixed
29
+
30
+ - Fix re-using plugin by inherited service classes
31
+
32
+ ## [2.2.1] - 2025-12-29
33
+
34
+ ### Fixed
35
+
36
+ - Fix plugin reflection options and configuration check
37
+
38
+ ## [2.2.0] - 2025-12-28
39
+
40
+ ### Added
41
+
42
+ - Allow registering plugins with class names (strings) instead of requiring class constants
43
+ - Useful when autoload isn't available yet, e.g., during Rails initialization
44
+
45
+ ### Changed
46
+
47
+ - Update README with improved documentation
48
+
49
+ ## [2.1.0] - 2025-12-20
50
+
51
+ ### Added
52
+
53
+ - Add `:call_unless_called` option to `:persisted_result` plugin
54
+ - When set to `true`, accessing `service.result` will automatically call `#call` if not yet called
55
+ - Default value is `false`
56
+
57
+ ### Changed
58
+
59
+ - Allow plugin re-registration with updated configuration
60
+ - Code cleanup and refactoring
61
+
62
+ ### Fixed
63
+
64
+ - Drop obsolete statements from codebase
65
+
66
+ ## [2.0.0] - 2025-12-06
67
+
68
+ ### Breaking Changes
69
+
70
+ - Complete rewrite focused on simplicity and extensibility
71
+ - Drop majority of built-in plugins from v1.x
72
+ - New plugin API based on `Zen::Service::Plugins::Plugin`
73
+
74
+ ### Added
75
+
76
+ - New core plugin architecture where even fundamental features are plugins
77
+ - `:callable` - Provides `.call` and `.[]` class methods
78
+ - `:attributes` - Manages service initialization parameters with runtime validation
79
+ - `:persisted_result` plugin - Provides `#result` method and `#called?` helper
80
+ - `:result_yielding` plugin - Enables nested service calls to return block-provided values
81
+ - Plugin lifecycle with `used` and `configure` callbacks
82
+ - Plugin inheritance and reconfiguration support
83
+ - Automatic plugin registration for modules extending `Plugin`
84
+ - Manual plugin registration via `Zen::Service::Plugins.register`
85
+
86
+ ### Changed
87
+
88
+ - Simplified service object pattern focusing on essential functionality
89
+ - Improved plugin DSL with `register_as`, `default_options`, and `service_extension`
90
+ - Complete README rewrite with comprehensive examples
91
+
92
+ ### Removed
93
+
94
+ - Most built-in plugins from v1.x for simplicity
95
+ - Removed legacy plugin APIs
96
+
97
+ [2.2.4]: https://github.com/akuzko/zen-service/compare/v2.2.3...v2.2.4
98
+ [2.2.3]: https://github.com/akuzko/zen-service/compare/v2.2.2...v2.2.3
99
+ [2.2.2]: https://github.com/akuzko/zen-service/compare/v2.2.1...v2.2.2
100
+ [2.2.1]: https://github.com/akuzko/zen-service/compare/v2.2.0...v2.2.1
101
+ [2.2.0]: https://github.com/akuzko/zen-service/compare/v2.1.0...v2.2.0
102
+ [2.1.0]: https://github.com/akuzko/zen-service/compare/v2.0.0...v2.1.0
103
+ [2.0.0]: https://github.com/akuzko/zen-service/releases/tag/v2.0.0
data/Gemfile CHANGED
@@ -4,3 +4,12 @@ source "https://rubygems.org"
4
4
 
5
5
  # Specify your gem"s dependencies in zen-service.gemspec
6
6
  gemspec
7
+
8
+ gem "pry"
9
+ gem "pry-nav"
10
+ gem "rake", "~> 13.0"
11
+ gem "rspec", "~> 3.0"
12
+ gem "rspec-its", "~> 1.2"
13
+ gem "rubocop", "~> 1.81"
14
+ gem "simplecov"
15
+ gem "simplecov-cobertura"
data/README.md CHANGED
@@ -2,7 +2,11 @@
2
2
 
3
3
  Flexible and highly extensible Service Objects for business logic organization.
4
4
 
5
- [![github release](https://img.shields.io/github/release/akuzko/zen-service.svg)](https://github.com/akuzko/zen-service/releases)
5
+ [![Gem Version](https://img.shields.io/gem/v/zen-service.svg)](https://rubygems.org/gems/zen-service)
6
+ [![CI Status](https://github.com/akuzko/zen-service/actions/workflows/ci.yml/badge.svg)](https://github.com/akuzko/zen-service/actions/workflows/ci.yml)
7
+ [![codecov](https://codecov.io/gh/akuzko/zen-service/branch/master/graph/badge.svg)](https://codecov.io/gh/akuzko/zen-service)
8
+ [![Ruby Version](https://img.shields.io/badge/ruby-%3E%3D%203.2-ruby.svg)](https://www.ruby-lang.org)
9
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
10
 
7
11
  ## Installation
8
12
 
@@ -22,12 +26,12 @@ Or install it yourself as:
22
26
 
23
27
  ## Usage
24
28
 
25
- The very basic usage of `Zen` services can be shown with following example:
29
+ The most basic usage of `Zen::Service` can be demonstrated with the following example:
26
30
 
27
- ```rb
31
+ ```ruby
28
32
  # app/services/todos/update.rb
29
33
  module Todos
30
- class Update < ApplicationService # base class for app services, inherits from Zen::Service
34
+ class Update < ApplicationService # Base class for app services, inherits from Zen::Service
31
35
  attributes :todo, :params
32
36
 
33
37
  def call
@@ -40,7 +44,7 @@ module Todos
40
44
  end
41
45
  end
42
46
 
43
- # app/controllers/todos/controller
47
+ # app/controllers/todos_controller.rb
44
48
  class TodosController < ApplicationController
45
49
  def update
46
50
  case Todos::Update.call(todo, params: todo_params)
@@ -51,97 +55,129 @@ class TodosController < ApplicationController
51
55
  end
52
56
  ```
53
57
 
54
- ### Service attributes
58
+ ### Service Attributes
55
59
 
56
- Read full version on [wiki](https://github.com/akuzko/zen-service/wiki#instantiating-service-with-attributes).
60
+ `Zen::Service` instances are initialized with _attributes_. To specify the list of available attributes, use the `attributes`
61
+ class method. All attributes are optional during initialization. You can omit keys and pass attributes as positional
62
+ parameters—they will be assigned in the order they were declared. However, you cannot:
57
63
 
58
- `Zen` services are initialized with _attributes_. To specify list of available attributes, use `attributes`
59
- class method. All attributes are optional during service initialization. It is possible to omit keys during
60
- initialization, and pass attributes as parameters - in this case attributes will be filled in correspondance
61
- to the order they were defined. However, you cannot pass more attributes than declared attributes list, as
62
- well as cannot pass single attribute multiple times (as parameter and as named attribute) or attributes that
63
- were not declared with `attributes` class method.
64
+ - Pass more attributes than declared
65
+ - Pass the same attribute multiple times (both as positional and keyword argument)
66
+ - Pass undeclared attributes
64
67
 
65
- ```rb
68
+ ```ruby
66
69
  class MyService < Zen::Service
67
70
  attributes :foo, :bar
68
71
 
69
72
  def call
70
- # do something
73
+ # Your business logic here
71
74
  end
72
75
 
73
76
  def foo
74
- super || 5
77
+ super || 5 # Provide default value
75
78
  end
76
79
  end
77
80
 
81
+ # Different ways to initialize services
78
82
  s1 = MyService.new
79
83
  s1.foo # => 5
80
84
  s1.bar # => nil
81
85
 
82
86
  s2 = MyService.new(6)
83
87
  s2.foo # => 6
88
+ s2.bar # => nil
84
89
 
85
- s3 = s2.with_attributes(foo: 1, bar: 2)
90
+ s3 = MyService.new(foo: 1, bar: 2)
86
91
  s3.foo # => 1
87
92
  s3.bar # => 2
93
+
94
+ # Create a new service from an existing one with some attributes changed
95
+ s4 = s3.with_attributes(bar: 3)
96
+ s4.foo # => 1
97
+ s4.bar # => 3
98
+
99
+ # Create a service from another service's attributes
100
+ s5 = MyService.from(s3)
101
+ s5.foo # => 1
102
+ s5.bar # => 2
88
103
  ```
89
104
 
90
105
  ### Service Extensions (Plugins)
91
106
 
92
- Read full version on [wiki](https://github.com/akuzko/zen-service/wiki/Plugins).
107
+ `zen-service` is built with extensibility at its core. Even fundamental functionality like callable behavior
108
+ and attributes are implemented as plugins. The base `Zen::Service` class uses two core plugins:
93
109
 
94
- `zen-service` is built with extensions in mind. Even core functionality is organized in plugins that are
95
- used in base `Zen::Service` class. Version 2.0.0 drops majority of built-in plugins for sake of
96
- simplicity.
110
+ - `:callable` - Provides class methods `.call` and `.[]` that instantiate and call the service
111
+ - `:attributes` - Manages service initialization parameters with runtime validation
97
112
 
98
- However, `zen-service` still provides a couple of helpfull plugins out-of-the-box:
113
+ In addition, `zen-service` provides optional built-in plugins:
99
114
 
100
- - `:persisted_result` - provides `#result` method that returns value of the latest `#call`
101
- method call. Also provides `#called?` helper method. Supports `call_unless_called` option.
102
- When set to `true`, calling `service.result` method will call `#call` method if it has
103
- not yet been called. Default value is `false`.
115
+ #### `:persisted_result`
104
116
 
105
- - `:result_yielding` - can be used in junction with nested service calls to result with
106
- block-provided value instead of nested service `call` return value. For example:
117
+ Provides `#result` method that returns the value from the most recent `#call` invocation, along with a
118
+ `#called?` helper method.
107
119
 
108
- ```rb
109
- def call
110
- logger.call do # logger uses `:result_yielding` plugin
111
- todo.update!(params)
112
- [:ok, todo]
113
- rescue ActiveRecord::RecordInvalid
114
- [:error, todo.errors.messages]
115
- end
116
- end
117
- ```
120
+ **Options:**
118
121
 
119
- #### Plugin Lifecycle
122
+ - `call_unless_called: false` (default) - When `true`, accessing `service.result` will automatically
123
+ call `#call` if it hasn't been called yet.
120
124
 
121
- When using a plugin on a service class:
125
+ ```ruby
126
+ class MyService < Zen::Service
127
+ use :persisted_result, call_unless_called: true
122
128
 
123
- - If the plugin is used for the first time, both `used` and `configure` callbacks are invoked
124
- - If the plugin was already used by an ancestor class, only the `configure` callback is invoked,
125
- allowing reconfiguration without re-including the module
129
+ attributes :value
126
130
 
127
- This design allows child classes to customize plugin behavior inherited from parent classes:
131
+ def call
132
+ value * 2
133
+ end
134
+ end
128
135
 
129
- ```rb
130
- class BaseService < Zen::Service
131
- use :persisted_result, call_unless_called: false
136
+ service = MyService.new(5)
137
+ service.called? # => false
138
+ service.result # => 10 (automatically calls #call)
139
+ service.called? # => true
140
+ ```
141
+
142
+ #### `:result_yielding`
143
+
144
+ Enables nested service calls to return block-provided values instead of the nested service's return value.
145
+ Useful for wrapping service calls with cross-cutting concerns like logging or error handling.
146
+
147
+ ```ruby
148
+ class Logger < Zen::Service
149
+ use :result_yielding
150
+
151
+ # Will result with value return by `yield` expression
152
+ def call
153
+ Rails.logger.info("Starting operation")
154
+ result = yield
155
+ Rails.logger.info("Operation completed: #{result.inspect}")
156
+ end
132
157
  end
133
158
 
134
- class ChildService < BaseService
135
- use :persisted_result, call_unless_called: true # Only reconfigures, doesn't re-include
159
+ class UpdateTodo < Zen::Service
160
+ attributes :todo, :params
161
+
162
+ def call
163
+ Logger.call do
164
+ todo.update!(params)
165
+ [:ok, todo]
166
+ rescue ActiveRecord::RecordInvalid
167
+ [:error, todo.errors.messages]
168
+ end
169
+ end
136
170
  end
137
171
  ```
138
172
 
139
- Bellow you can see sample implementation of a plugin that transforms resulting objects
140
- to camel-case notation (relying on ActiveSupport's core extensions)
173
+ ### Creating Custom Plugins
141
174
 
142
- ```rb
175
+ Creating custom plugins is straightforward. Below is an example of a plugin that transforms results to
176
+ camelCase notation (using ActiveSupport's core extensions):
177
+
178
+ ```ruby
143
179
  module CamelizeResult
144
- extend Zen::Service::Plugin
180
+ extend Zen::Service::Plugins::Plugin
145
181
 
146
182
  def self.used(service_class)
147
183
  service_class.prepend(Extension)
@@ -149,8 +185,8 @@ module CamelizeResult
149
185
 
150
186
  def self.camelize(obj)
151
187
  case obj
152
- when Array then obj.map { camelize(_1) }
153
- when Hash then obj.deep_transform_keys { _1.to_s.camelize(:lower).to_sym }
188
+ when Array then obj.map { |item| camelize(item) }
189
+ when Hash then obj.deep_transform_keys { |key| key.to_s.camelize(:lower).to_sym }
154
190
  else obj
155
191
  end
156
192
  end
@@ -161,11 +197,7 @@ module CamelizeResult
161
197
  end
162
198
  end
163
199
  end
164
- ```
165
-
166
- and then
167
200
 
168
- ```rb
169
201
  class Todos::Show < Zen::Service
170
202
  attributes :todo
171
203
 
@@ -182,22 +214,79 @@ end
182
214
  Todos::Show[todo] # => { id: 1, isCompleted: true }
183
215
  ```
184
216
 
185
- **Note**: Custom plugins need to be registered before they can be used. Plugins that extend
186
- `Zen::Service::Plugin` are automatically registered when the module is loaded. Alternatively,
187
- you can register plugins manually:
217
+ #### Plugin Registration
188
218
 
189
- ```rb
219
+ Plugins that extend `Zen::Service::Plugins::Plugin` are automatically registered when the module is loaded.
220
+ You can also register plugins manually:
221
+
222
+ ```ruby
190
223
  # Register a plugin module
191
224
  Zen::Service::Plugins.register(:my_plugin, MyPlugin)
192
225
 
193
- # Register by class name (useful when autoload isn't available yet, e.g., during Rails boot)
226
+ # Register by class name (useful when autoload isn't available yet, e.g., during Rails initialization)
194
227
  Zen::Service::Plugins.register(:my_plugin, "MyApp::Services::MyPlugin")
195
228
  ```
196
229
 
230
+ #### Plugin Lifecycle
231
+
232
+ When using a plugin on a service class:
233
+
234
+ - **First use**: Both `used` and `configure` callbacks are invoked, and the module is included
235
+ - **Inheritance**: If a plugin was already used by an ancestor class, only `configure` is called,
236
+ allowing reconfiguration without re-including the module
237
+
238
+ This design enables child classes to customize inherited plugin behavior:
239
+
240
+ ```ruby
241
+ class BaseService < Zen::Service
242
+ use :persisted_result, call_unless_called: false
243
+ end
244
+
245
+ class ChildService < BaseService
246
+ use :persisted_result, call_unless_called: true # Reconfigures without re-including
247
+ end
248
+ ```
249
+
250
+ #### Plugin DSL
251
+
252
+ Plugins can use several DSL methods when extending `Zen::Service::Plugins::Plugin`:
253
+
254
+ ```ruby
255
+ module MyPlugin
256
+ extend Zen::Service::Plugins::Plugin
257
+
258
+ # Override the auto-generated registration name
259
+ register_as :custom_name
260
+
261
+ # Set default options
262
+ default_options foo: 5, bar: false
263
+
264
+ # Called when plugin is first used on a class
265
+ def self.used(service_class, **options, &block)
266
+ # Include/prepend modules, add class methods, etc.
267
+ end
268
+
269
+ # Called every time the plugin is used (including on child classes)
270
+ def self.configure(service_class, **options, &block)
271
+ # Configure behavior based on options
272
+ end
273
+ end
274
+ ```
275
+
276
+ ## Testing
277
+
278
+ The gem has 100% test coverage with both line and branch coverage. To run the test suite:
279
+
280
+ ```bash
281
+ bundle exec rspec
282
+ ```
283
+
197
284
  ## Development
198
285
 
199
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
200
- You can also run `bin/console` for an interactive prompt that will allow you to experiment.
286
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to run
287
+ the tests. You can also run `bin/console` for an interactive prompt that allows you to experiment.
288
+
289
+ To install this gem onto your local machine, run `bundle exec rake install`.
201
290
 
202
291
  ## Contributing
203
292
 
@@ -13,7 +13,7 @@ module Zen
13
13
 
14
14
  def initialize_clone(*)
15
15
  super
16
- @attributes = @attributes.dup unless @attributes.nil?
16
+ @attributes = @attributes.dup
17
17
  end
18
18
 
19
19
  def with_attributes(attributes)
@@ -84,7 +84,7 @@ module Zen
84
84
  end
85
85
 
86
86
  def from(service)
87
- new(service.send(:attributes))
87
+ new(**service.send(:attributes))
88
88
  end
89
89
  end
90
90
  end
@@ -5,13 +5,13 @@ module Zen
5
5
  module Callable
6
6
  extend Plugin
7
7
 
8
- def call
8
+ def call(&)
9
9
  # No-op by default
10
10
  end
11
11
 
12
12
  module ClassMethods
13
- def call(...)
14
- new(...).call
13
+ def call(*args, **kwargs, &block)
14
+ new(*args, **kwargs).call(&block)
15
15
  end
16
16
  alias [] call
17
17
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Zen
4
4
  class Service
5
- VERSION = "2.2.2"
5
+ VERSION = "2.2.4"
6
6
  end
7
7
  end
data/zen-service.gemspec CHANGED
@@ -27,11 +27,4 @@ Gem::Specification.new do |spec|
27
27
  spec.bindir = "exe"
28
28
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]
30
-
31
- spec.add_development_dependency "pry"
32
- spec.add_development_dependency "pry-nav"
33
- spec.add_development_dependency "rake", "~> 13.0"
34
- spec.add_development_dependency "rspec", "~> 3.0"
35
- spec.add_development_dependency "rspec-its", "~> 1.2"
36
- spec.add_development_dependency "rubocop", "~> 1.81"
37
30
  end
metadata CHANGED
@@ -1,99 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zen-service
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2
4
+ version: 2.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Kuzko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-12-30 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: pry
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: pry-nav
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: rake
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '13.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '13.0'
55
- - !ruby/object:Gem::Dependency
56
- name: rspec
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '3.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '3.0'
69
- - !ruby/object:Gem::Dependency
70
- name: rspec-its
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '1.2'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '1.2'
83
- - !ruby/object:Gem::Dependency
84
- name: rubocop
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '1.81'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '1.81'
11
+ date: 2026-01-19 00:00:00.000000000 Z
12
+ dependencies: []
97
13
  description: Flexible and highly extensible Services for business logic organization
98
14
  email:
99
15
  - a.kuzko@gmail.com
@@ -102,12 +18,14 @@ extensions: []
102
18
  extra_rdoc_files: []
103
19
  files:
104
20
  - ".github/copilot-instructions.md"
21
+ - ".github/workflows/ci.yml"
105
22
  - ".gitignore"
106
23
  - ".rspec"
107
24
  - ".rubocop.yml"
108
25
  - ".tool-versions"
26
+ - CHANGELOG.md
109
27
  - Gemfile
110
- - LICENSE.txt
28
+ - LICENSE
111
29
  - README.md
112
30
  - Rakefile
113
31
  - bin/console
File without changes