service_core 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a394edd3cba542ec79b3749978672b3b2bdd1c64288f8b3180ca1420dfe22df3
4
+ data.tar.gz: 1e058a4a0a9d562939e617e70e8aaeb7889c73941e2be9236e04139c44424b1f
5
+ SHA512:
6
+ metadata.gz: f80ef1c0e7ae359d7c006b63a5476a4970432ab30efbe7e4b107f20f475fd9db0149ebf7166e50d438139ff297cfa7dd57bb8403108e9848d5f9ad7fcfa66e6c
7
+ data.tar.gz: bcd65b6b67539f4817cb7133456c9e174c61f9e1d702b2e8c88a0a10bc366ddda3fee96f6feb03d66fbf4604578c10b3c452136c2b92365e6cb873d829a859e4
data/.byebug_history ADDED
@@ -0,0 +1,71 @@
1
+ c
2
+ @logger
3
+ c
4
+ defined?(Rails) && Rails.logger ? Rails.logger : ActiveSupport::Logger.new($stdout)
5
+ c
6
+ defined?(Rails) && Rails.logger ? Rails.logger : ActiveSupport::Logger.new($stdout)
7
+ defined?(Rails)
8
+ c
9
+ defined?(Rails)
10
+ c
11
+ ServiceCore.logger
12
+ c
13
+ @logger
14
+ c
15
+ @logger
16
+ c
17
+ self.active
18
+ self.status
19
+ c
20
+ self.active
21
+ name
22
+ c
23
+ name
24
+ n
25
+ self.class.fields_defined
26
+ @fields
27
+ c
28
+ n
29
+ default
30
+ self
31
+ type
32
+ n
33
+ default
34
+ n
35
+ args
36
+ opts
37
+ c
38
+ args
39
+ opts
40
+ c
41
+ service
42
+ c
43
+ service
44
+ c
45
+ service
46
+ c
47
+ self.name
48
+ n
49
+ attributes
50
+ c
51
+ service
52
+ c
53
+ service.fields
54
+ service
55
+ c
56
+ service.name
57
+ c
58
+ send(name)
59
+ @fields
60
+ name
61
+ c
62
+ @fields
63
+ n
64
+ c
65
+ service
66
+ c
67
+ service.name
68
+ service
69
+ c
70
+ service.fields
71
+ service
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,19 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+
4
+ Style/StringLiterals:
5
+ Enabled: true
6
+ EnforcedStyle: double_quotes
7
+
8
+ Style/StringLiteralsInInterpolation:
9
+ Enabled: true
10
+ EnforcedStyle: double_quotes
11
+
12
+ Layout/LineLength:
13
+ Max: 120
14
+
15
+ Style/Documentation:
16
+ Enabled: false
17
+
18
+ Metrics/BlockLength:
19
+ Enabled: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2024-07-17
4
+
5
+ - Initial release
@@ -0,0 +1,84 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
+
7
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8
+
9
+ ## Our Standards
10
+
11
+ Examples of behavior that contributes to a positive environment for our community include:
12
+
13
+ * Demonstrating empathy and kindness toward other people
14
+ * Being respectful of differing opinions, viewpoints, and experiences
15
+ * Giving and gracefully accepting constructive feedback
16
+ * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
17
+ * Focusing on what is best not just for us as individuals, but for the overall community
18
+
19
+ Examples of unacceptable behavior include:
20
+
21
+ * The use of sexualized language or imagery, and sexual attention or
22
+ advances of any kind
23
+ * Trolling, insulting or derogatory comments, and personal or political attacks
24
+ * Public or private harassment
25
+ * Publishing others' private information, such as a physical or email
26
+ address, without their explicit permission
27
+ * Other conduct which could reasonably be considered inappropriate in a
28
+ professional setting
29
+
30
+ ## Enforcement Responsibilities
31
+
32
+ Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
33
+
34
+ Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
35
+
36
+ ## Scope
37
+
38
+ This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
39
+
40
+ ## Enforcement
41
+
42
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at sehgalmayank001@gmail.com. All complaints will be reviewed and investigated promptly and fairly.
43
+
44
+ All community leaders are obligated to respect the privacy and security of the reporter of any incident.
45
+
46
+ ## Enforcement Guidelines
47
+
48
+ Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
49
+
50
+ ### 1. Correction
51
+
52
+ **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
53
+
54
+ **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
55
+
56
+ ### 2. Warning
57
+
58
+ **Community Impact**: A violation through a single incident or series of actions.
59
+
60
+ **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
61
+
62
+ ### 3. Temporary Ban
63
+
64
+ **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
65
+
66
+ **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
67
+
68
+ ### 4. Permanent Ban
69
+
70
+ **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
71
+
72
+ **Consequence**: A permanent ban from any sort of public interaction within the community.
73
+
74
+ ## Attribution
75
+
76
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
77
+ available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
78
+
79
+ Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
80
+
81
+ [homepage]: https://www.contributor-covenant.org
82
+
83
+ For answers to common questions about this code of conduct, see the FAQ at
84
+ https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 mayank sehgal
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,205 @@
1
+ # ServiceCore
2
+
3
+ ServiceCore provides a standardized way to define and use service objects in your Ruby and Rails applications. It includes support for defining fields, validations, responses, and logging.
4
+
5
+ ## Installation
6
+ Install the gem and add to the application's Gemfile by executing:
7
+
8
+ ```sh
9
+ bundle add service_core
10
+ ```
11
+ If bundler is not being used to manage dependencies, install the gem by executing:
12
+
13
+ ```sh
14
+ gem install service_core
15
+ ```
16
+ ## Usage
17
+
18
+ ### Defining a Service
19
+
20
+ To define a new service, include the `ServiceCore` module in your service class and define your fields and the perform method.
21
+ ```ruby
22
+ # app/services/my_service.rb
23
+
24
+ class MyService
25
+ include ServiceCore
26
+
27
+ field :first_name, :string
28
+ field :last_name, :string
29
+ field :active, :boolean, default: true
30
+
31
+ def perform
32
+ success_response(message: "Hello, World", data: name)
33
+ end
34
+
35
+ def name
36
+ "#{first_name} #{last_name}"
37
+ end
38
+ end
39
+ ```
40
+
41
+ ### Using a Service
42
+ Instantiate and call the service to execute it. The call method will validate the input, perform the operation, and return the output.
43
+ ```ruby
44
+ service = MyService.new(first_name: "John", last_name: "Doe")
45
+ result = service.call
46
+ puts result
47
+ # Output:
48
+ # {
49
+ # status: "success",
50
+ # message: "Hello, World",
51
+ #. data: "John Doe"
52
+ # }
53
+
54
+ puts service.output
55
+ # Output:
56
+ # {
57
+ # status: "success",
58
+ # message: "Hello, World",
59
+ #. data: "John Doe"
60
+ # }
61
+ ```
62
+
63
+ ### Validations
64
+ You can define validation on the service and those will be invoked before service logic is invoked
65
+ ```ruby
66
+ class MyService
67
+ include ServiceCore
68
+
69
+ field :name, :string
70
+ validates :name, presence: true
71
+
72
+ def perform
73
+ success_response(message: "Hello, World", data: name)
74
+ end
75
+ end
76
+
77
+ service = MyService.new(name: "")
78
+ result = service.call
79
+ puts result
80
+ # Output:
81
+ #{
82
+ # status: "error",
83
+ # message: "validation failure",
84
+ # errors: { name: ["can't be blank"] }
85
+ # }
86
+ ```
87
+
88
+ ### Step Validation
89
+ You can perform validation at each step of service logic. This is helpful when result of previous step decides next logic.
90
+ ```ruby
91
+ class MyService
92
+ include ServiceCore
93
+
94
+ field :first_name, :string
95
+ field :last_name, :string
96
+ field :user
97
+
98
+ validates :first_name, presence: true
99
+ validates :user, presence: true
100
+
101
+ def perform
102
+ if last_name.blank?
103
+ add_error_and_validate(:last_name, "can't be nil")
104
+ return error_response(message: "validation failure", errors: errors)
105
+ end
106
+
107
+ success_response(data: { user: { id: 1 } })
108
+ end
109
+ end
110
+
111
+ MyService.call(first_name: 'abc')
112
+ # output:
113
+ # {
114
+ # status: "error",
115
+ # message: "validation failure",
116
+ # errors: { last_name: ["can't be nil"] }
117
+ # }
118
+ ```
119
+
120
+ ### Logging Errors
121
+ You can log errors using the `log_error` method.
122
+ ```ruby
123
+ class MyService
124
+ include ServiceCore
125
+
126
+ field :name, :string
127
+
128
+ def perform
129
+ begin
130
+ raise StandardError, "Something went wrong"
131
+ rescue StandardError => e
132
+ log_error(e)
133
+ error_response(message: "Failed", errors: { base: [e.message] })
134
+ end
135
+ end
136
+ end
137
+
138
+ service = MyService.new(name: "World")
139
+ result = service.call
140
+ puts result
141
+ # Output:
142
+ # {
143
+ # status: "error",
144
+ # message: "Failed",
145
+ # errors: { base: ["Something went wrong"] }
146
+ # }
147
+
148
+ ```
149
+
150
+ ### Configuring the Logger
151
+ You can configure the logger for the ServiceCore module.
152
+ ```ruby
153
+ ServiceCore.configure do |config|
154
+ config.logger = Logger.new(STDOUT)
155
+ end
156
+ ```
157
+
158
+ ### Custom Response
159
+ use `formatted_response` method to return any other status other than `success` or `error`
160
+ ```ruby
161
+
162
+ class MyService
163
+ include ServiceCore
164
+
165
+ field :first_name, :string
166
+ field :last_name, :string
167
+ field :active, :boolean, default: true
168
+
169
+ def perform
170
+ formatted_response(status: 'processed', message: "Hello, World", data: name)
171
+ end
172
+
173
+ def name
174
+ "#{first_name} #{last_name}"
175
+ end
176
+ end
177
+
178
+ service = MyService.new(first_name: "John", last_name: "Doe")
179
+ result = service.call
180
+ puts result
181
+ # Output:
182
+ # {
183
+ # status: "processed",
184
+ # message: "Hello, World",
185
+ #. data: "John Doe"
186
+ # }
187
+ ```
188
+
189
+ `formatted_response` accepts following arguments:
190
+ - status
191
+ - message
192
+ - data
193
+ - errors
194
+
195
+ ## Contributing
196
+
197
+ Bug reports and pull requests are welcome on GitHub at https://github.com/sehgalmayank001/service-core. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/sehgalmayank001/service-core/blob/main/CODE_OF_CONDUCT.md).
198
+
199
+ ## License
200
+
201
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
202
+
203
+ ## Code of Conduct
204
+
205
+ Everyone interacting in the ServiceCore project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/sehgalmayank001/service-core/blob/main/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
13
+
14
+ desc "Tag and push the current version"
15
+ task :release do
16
+ version = `ruby -r ./lib/service_core/version -e "puts ServiceCore::VERSION"`.strip
17
+ sh "git add ."
18
+ sh "git commit -m 'Prepare for version #{version} release'"
19
+ sh "git tag v#{version}"
20
+ sh "git push origin main --tags"
21
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+ require "active_model"
5
+ require_relative "response"
6
+
7
+ module ServiceCore
8
+ module Base
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ include ActiveModel::Model
13
+ include ActiveModel::Attributes
14
+ include ActiveModel::Validations
15
+ include ServiceCore::Response
16
+
17
+ # NOTE: output attribute will hold output of the service
18
+ attr_reader :output
19
+
20
+ # NOTE: fields attribute will hold the fields defined and their values
21
+ attr_reader :fields
22
+
23
+ class << self
24
+ # Wrapper method to define attribuutes and attr_accessor methods on object
25
+ def fields_defined
26
+ @fields_defined ||= {}
27
+ end
28
+
29
+ def field(name, *args, **opts)
30
+ # field :active, :boolean, default: true
31
+ # field :active, type: :boolean, default: true
32
+ # Both explicit and implicit definitions are handled
33
+ type = args[0] || opts[:type]
34
+ default = args[1] || opts[:default]
35
+
36
+ # NOTE: -
37
+ # ActiveModel::Attributes support only basic data types
38
+ # for ActiveRecord objects we use attr_accessor through ActiveModel::Model
39
+ # define attr_accessor to make instance variables also available for attributes
40
+
41
+ # define attribute if type is available to type cast
42
+ if type
43
+ attribute(name, type, default: default)
44
+ else
45
+ attr_accessor(name)
46
+ end
47
+
48
+ # save fields defind as an hash, makes it easier to check
49
+ fields_defined[name] = default
50
+ end
51
+
52
+ def call(attributes = {})
53
+ new(attributes).call
54
+ end
55
+ end
56
+
57
+ def initialize(attributes = {})
58
+ super
59
+ @local_errors = {}
60
+ @fields = {}
61
+ # NOTE: this helps identify values passed from values updated
62
+ self.class.fields_defined.each_key do |name|
63
+ @fields[name] = send(name)
64
+ end
65
+
66
+ # default value of output
67
+ @output = { status: "initialized" }
68
+ end
69
+
70
+ def call
71
+ # check if valid arguments are present?
72
+ return error_response(message: "validation failure", errors: errors) unless valid?
73
+
74
+ # perform the operation
75
+ perform
76
+
77
+ # return output
78
+ output
79
+ end
80
+
81
+ private
82
+
83
+ # output writer is protected to be used inside class and sub-classes only
84
+ attr_writer :output
85
+
86
+ def perform
87
+ raise StandardError, "perform method not implemented"
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module ServiceCore
6
+ module Logger
7
+ extend ActiveSupport::Concern
8
+
9
+ protected
10
+
11
+ def log_error(exception)
12
+ ServiceCore.logger.error("#{self.class.name}: #{exception.message}")
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+ # require "active_model/errors"
5
+
6
+ module ServiceCore
7
+ module Response
8
+ extend ActiveSupport::Concern
9
+
10
+ protected
11
+
12
+ def success_response(message: nil, data: nil)
13
+ formatted_response(status: "success", message: message, data: data)
14
+ end
15
+
16
+ def error_response(message:, errors: nil)
17
+ formatted_response(status: "error", message: message, errors: errors)
18
+ end
19
+
20
+ # set output response
21
+ def formatted_response(status:, message: nil, data: nil, errors: nil)
22
+ @output[:status] = status
23
+ @output[:message] = message if message.present?
24
+ @output[:data] = data if data.present?
25
+ @output[:errors] = error_messages(errors) if errors.present?
26
+ @output
27
+ end
28
+
29
+ def error_messages(errors)
30
+ errors.is_a?(ActiveModel::Errors) ? errors.messages : errors
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module ServiceCore
6
+ module StepValidation
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ # NOTE: #
11
+ # added this to support partial validation
12
+ # valid? method empties all errors, so needed a way to hold errors from within method invocation
13
+ validate :local_errors_validation
14
+
15
+ def local_errors_validation
16
+ _local_errors_validation(@local_errors)
17
+ end
18
+
19
+ def _local_errors_validation(errors_hsh)
20
+ errors_hsh.each do |attribute, messages|
21
+ next unless messages
22
+
23
+ messages.each do |message|
24
+ errors.add(attribute, *message.is_a?(Array) ? message : [message])
25
+ end
26
+ end
27
+ {}
28
+ end
29
+
30
+ def add_error(attribute, message, options = {})
31
+ value = options.present? ? [message, options] : message
32
+ @local_errors[attribute] = if @local_errors[attribute].present?
33
+ Array(@local_errors[attribute]) << value
34
+ else
35
+ [value]
36
+ end
37
+ end
38
+
39
+ # method to add partial errors and validate
40
+ def add_error_and_validate(attribute, message, _options = {})
41
+ add_error(attribute, message, {})
42
+ valid?
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ServiceCore
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "service_core/version"
4
+ require_relative "service_core/base"
5
+ require_relative "service_core/step_validation"
6
+ require_relative "service_core/logger"
7
+ require "active_model"
8
+ require "active_support/concern"
9
+ require "active_support/logger"
10
+
11
+ module ServiceCore
12
+ extend ActiveSupport::Concern
13
+
14
+ included do
15
+ include ServiceCore::Base
16
+ include ServiceCore::StepValidation
17
+ include ServiceCore::Logger
18
+ end
19
+
20
+ class Error < StandardError; end
21
+
22
+ class << self
23
+ attr_writer :logger
24
+
25
+ def logger
26
+ @logger ||= defined?(Rails) && Rails.logger ? Rails.logger : ActiveSupport::Logger.new($stdout)
27
+ end
28
+
29
+ def configure
30
+ yield self
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,4 @@
1
+ module ServiceCore
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: service_core
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - mayank sehgal
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-07-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activemodel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '6.1'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '8.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '6.1'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '8.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: activesupport
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '6.1'
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '8.0'
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '6.1'
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '8.0'
53
+ description: A service pattern implementation for Rails applications.
54
+ email:
55
+ - sehgalmayank001@gmail.com
56
+ executables: []
57
+ extensions: []
58
+ extra_rdoc_files: []
59
+ files:
60
+ - ".byebug_history"
61
+ - ".rspec"
62
+ - ".rubocop.yml"
63
+ - CHANGELOG.md
64
+ - CODE_OF_CONDUCT.md
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - lib/service_core.rb
69
+ - lib/service_core/base.rb
70
+ - lib/service_core/logger.rb
71
+ - lib/service_core/response.rb
72
+ - lib/service_core/step_validation.rb
73
+ - lib/service_core/version.rb
74
+ - sig/service_core.rbs
75
+ homepage: https://github.com/sehgalmayank001/service-core
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: 2.6.0
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubygems_version: 3.4.22
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: A Rails service pattern implementation
98
+ test_files: []