service_core 0.1.3 → 1.0.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/.rubocop.yml +35 -2
- data/.tool-versions +1 -0
- data/Appraisals +19 -0
- data/CHANGELOG.md +79 -1
- data/README.md +227 -111
- data/Rakefile +3 -5
- data/gemfiles/rails_7.2.gemfile +18 -0
- data/gemfiles/rails_8.0.gemfile +18 -0
- data/gemfiles/rails_8.1.gemfile +18 -0
- data/lib/service_core/base.rb +38 -34
- data/lib/service_core/errors.rb +11 -0
- data/lib/service_core/field_set.rb +21 -0
- data/lib/service_core/logger.rb +0 -2
- data/lib/service_core/output.rb +45 -0
- data/lib/service_core/responder.rb +38 -0
- data/lib/service_core/response.rb +96 -20
- data/lib/service_core/step_validation.rb +24 -28
- data/lib/service_core/version.rb +1 -3
- data/lib/service_core.rb +3 -4
- metadata +23 -17
- data/.byebug_history +0 -71
- data/service_core.gemspec +0 -44
- data/sig/service_core.rbs +0 -4
data/lib/service_core/base.rb
CHANGED
|
@@ -1,70 +1,74 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
1
|
require "active_support/concern"
|
|
4
2
|
require "active_model"
|
|
5
|
-
|
|
3
|
+
require "set"
|
|
4
|
+
require_relative "responder"
|
|
6
5
|
|
|
7
6
|
module ServiceCore
|
|
8
7
|
module Base
|
|
9
8
|
extend ActiveSupport::Concern
|
|
10
9
|
|
|
10
|
+
RESERVED_FIELD_NAMES = Set[:call, :errors, :fields, :output, :perform, :response].freeze
|
|
11
|
+
|
|
11
12
|
included do
|
|
13
|
+
# NOTE: Responder is included first so its initialize (inherited
|
|
14
|
+
# from Output) runs at the bottom of the super chain.
|
|
15
|
+
include ServiceCore::Responder
|
|
12
16
|
include ActiveModel::Model
|
|
13
17
|
include ActiveModel::Attributes
|
|
14
18
|
include ActiveModel::Validations
|
|
15
|
-
include ServiceCore::Response
|
|
16
|
-
|
|
17
|
-
# NOTE: output attribute will hold output of the service
|
|
18
|
-
attr_reader :output
|
|
19
19
|
|
|
20
|
-
# NOTE: fields
|
|
20
|
+
# NOTE: fields holds a ServiceCore::FieldSet snapshot of declared
|
|
21
|
+
# fields and their values at initialize time.
|
|
21
22
|
attr_reader :fields
|
|
22
23
|
|
|
23
24
|
class << self
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@fields_defined ||= {}
|
|
25
|
+
def field_names
|
|
26
|
+
@field_names ||= Set.new
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def field(name, *args, **opts)
|
|
30
30
|
# field :active, :boolean, default: true
|
|
31
31
|
# field :active, type: :boolean, default: true
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
# field :active, :boolean, false # positional default
|
|
33
|
+
# field :payload # untyped (hash/array/object)
|
|
34
|
+
ensure_field_name_available!(name)
|
|
35
|
+
type = args.first || opts[:type]
|
|
36
|
+
# NOTE: arity check, not `||`, so a positional default of
|
|
37
|
+
# `false` or `nil` is not silently swallowed by opts[:default].
|
|
38
|
+
default = args.length >= 2 ? args[1] : opts[:default]
|
|
35
39
|
|
|
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
40
|
if type
|
|
43
41
|
attribute(name, type, default: default)
|
|
44
42
|
else
|
|
45
43
|
attr_accessor(name)
|
|
46
44
|
end
|
|
47
45
|
|
|
48
|
-
|
|
49
|
-
fields_defined[name] = default
|
|
46
|
+
field_names.add(name)
|
|
50
47
|
end
|
|
51
48
|
|
|
52
49
|
def call(attributes = {})
|
|
53
|
-
new(attributes)
|
|
50
|
+
obj = new(attributes)
|
|
51
|
+
obj.call
|
|
52
|
+
obj
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def ensure_field_name_available!(name)
|
|
58
|
+
return unless ServiceCore::Base::RESERVED_FIELD_NAMES.include?(name)
|
|
59
|
+
|
|
60
|
+
raise(
|
|
61
|
+
ServiceCore::ReservedFieldName,
|
|
62
|
+
"`#{name}` is reserved by ServiceCore and cannot be used as a field name"
|
|
63
|
+
)
|
|
54
64
|
end
|
|
55
65
|
end
|
|
56
66
|
|
|
57
67
|
def initialize(attributes = {})
|
|
58
68
|
super
|
|
59
69
|
@local_errors = {}
|
|
60
|
-
|
|
61
|
-
|
|
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" }
|
|
70
|
+
snapshot = self.class.field_names.to_h { |name| [name, send(name)] }
|
|
71
|
+
@fields = ServiceCore::FieldSet.new(snapshot)
|
|
68
72
|
end
|
|
69
73
|
|
|
70
74
|
def call
|
|
@@ -74,15 +78,15 @@ module ServiceCore
|
|
|
74
78
|
# perform the operation
|
|
75
79
|
perform
|
|
76
80
|
|
|
81
|
+
# auto assign status if output is dirty
|
|
82
|
+
auto_assign_status
|
|
83
|
+
|
|
77
84
|
# return output
|
|
78
85
|
output
|
|
79
86
|
end
|
|
80
87
|
|
|
81
88
|
private
|
|
82
89
|
|
|
83
|
-
# output writer is protected to be used inside class and sub-classes only
|
|
84
|
-
attr_writer :output
|
|
85
|
-
|
|
86
90
|
def perform
|
|
87
91
|
raise StandardError, "perform method not implemented"
|
|
88
92
|
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module ServiceCore
|
|
2
|
+
class Error < StandardError; end
|
|
3
|
+
|
|
4
|
+
# Raised when a value object access (Response#[], Response#[]=) targets
|
|
5
|
+
# a key that is not one of the four allowed response keys.
|
|
6
|
+
class InvalidKey < Error; end
|
|
7
|
+
|
|
8
|
+
# Raised by `field` when a declared name would shadow a method that
|
|
9
|
+
# the gem itself defines on every service.
|
|
10
|
+
class ReservedFieldName < Error; end
|
|
11
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module ServiceCore
|
|
2
|
+
# Immutable snapshot of a service's declared fields and their values
|
|
3
|
+
# at #initialize time. Each symbol key is exposed as a real method;
|
|
4
|
+
# call #to_h for the raw snapshot Hash.
|
|
5
|
+
class FieldSet
|
|
6
|
+
attr_reader :to_h
|
|
7
|
+
|
|
8
|
+
def initialize(values = {})
|
|
9
|
+
@to_h = values.to_h.freeze
|
|
10
|
+
@to_h.each_key do |name|
|
|
11
|
+
next unless name.is_a?(Symbol)
|
|
12
|
+
|
|
13
|
+
define_singleton_method(name) { @to_h[name] }
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def inspect
|
|
18
|
+
"#<#{self.class.name} #{@to_h.inspect}>"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/service_core/logger.rb
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require "active_support/concern"
|
|
2
|
+
require_relative "response"
|
|
3
|
+
|
|
4
|
+
module ServiceCore
|
|
5
|
+
module Output
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
ALLOWED_KEYS = ServiceCore::Response::ALLOWED_KEYS
|
|
9
|
+
|
|
10
|
+
# NOTE: output holds the ServiceCore::Response for the service.
|
|
11
|
+
# response is the preferred name; output is retained as an alias.
|
|
12
|
+
attr_reader :output
|
|
13
|
+
alias response output
|
|
14
|
+
|
|
15
|
+
def initialize(_attributes = {})
|
|
16
|
+
# NOTE: super() with empty parens so positional args aren't forwarded
|
|
17
|
+
# up to other modules in the ancestor chain (ActiveModel::Model et al).
|
|
18
|
+
super()
|
|
19
|
+
@output_dirty = false
|
|
20
|
+
@status_dirty = false
|
|
21
|
+
@output = ServiceCore::Response.new
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
# NOTE: nil values are skipped; legitimate falsy values
|
|
27
|
+
# (false, 0, "") are recorded faithfully.
|
|
28
|
+
def set_output(key, value)
|
|
29
|
+
return if key.nil? || value.nil?
|
|
30
|
+
|
|
31
|
+
@output[key] = value
|
|
32
|
+
@output_dirty = true
|
|
33
|
+
@status_dirty = true if key == :status
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def auto_assign_status
|
|
37
|
+
if !@output_dirty
|
|
38
|
+
set_output(:status, "success")
|
|
39
|
+
elsif !@status_dirty
|
|
40
|
+
status_value = output[:errors].blank? ? "success" : "error"
|
|
41
|
+
set_output(:status, status_value)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require "active_support/concern"
|
|
2
|
+
require "active_model/errors"
|
|
3
|
+
require_relative "output"
|
|
4
|
+
|
|
5
|
+
module ServiceCore
|
|
6
|
+
# Mixin that provides the response-building helpers used inside +perform+.
|
|
7
|
+
module Responder
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
include ServiceCore::Output
|
|
11
|
+
|
|
12
|
+
protected
|
|
13
|
+
|
|
14
|
+
def success_response(message: nil, data: nil)
|
|
15
|
+
formatted_response(status: "success", message: message, data: data)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def error_response(message:, errors: nil)
|
|
19
|
+
formatted_response(status: "error", message: message, errors: errors)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# NOTE: nil-valued keys are skipped; legitimate falsy values
|
|
23
|
+
# (false, 0, "") are recorded faithfully.
|
|
24
|
+
def formatted_response(status:, message: nil, data: nil, errors: nil)
|
|
25
|
+
set_output(:status, status)
|
|
26
|
+
set_output(:message, message)
|
|
27
|
+
set_output(:data, data)
|
|
28
|
+
set_output(:errors, error_messages(errors))
|
|
29
|
+
output
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def error_messages(errors)
|
|
33
|
+
return nil if errors.nil?
|
|
34
|
+
|
|
35
|
+
errors.is_a?(ActiveModel::Errors) ? errors.messages : errors
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -1,33 +1,109 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require "active_support/concern"
|
|
4
|
-
# require "active_model/errors"
|
|
1
|
+
require "active_support/json"
|
|
5
2
|
|
|
6
3
|
module ServiceCore
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
# Value object carrying the four-key service response.
|
|
5
|
+
class Response
|
|
6
|
+
ALLOWED_KEYS = %i[status data message errors].freeze
|
|
7
|
+
FETCH_DEFAULT_OMITTED = Object.new.freeze
|
|
8
|
+
private_constant :FETCH_DEFAULT_OMITTED
|
|
9
|
+
|
|
10
|
+
attr_accessor(*ALLOWED_KEYS)
|
|
11
|
+
|
|
12
|
+
def initialize(status: "initialized", data: nil, message: nil, errors: nil)
|
|
13
|
+
@status = status
|
|
14
|
+
@data = data
|
|
15
|
+
@message = message
|
|
16
|
+
@errors = errors
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# NOTE: writes police the four-key contract; reads (fetch, dig)
|
|
20
|
+
# follow Hash semantics so callers can treat Response like a Hash.
|
|
21
|
+
def [](key)
|
|
22
|
+
ensure_allowed_key!(key)
|
|
23
|
+
public_send(key)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def []=(key, value)
|
|
27
|
+
ensure_allowed_key!(key)
|
|
28
|
+
public_send(:"#{key}=", value)
|
|
29
|
+
end
|
|
9
30
|
|
|
10
|
-
|
|
31
|
+
def fetch(key, default = FETCH_DEFAULT_OMITTED, &block)
|
|
32
|
+
return public_send(key) if key?(key)
|
|
33
|
+
return block.call(key) if block
|
|
34
|
+
return default unless default.equal?(FETCH_DEFAULT_OMITTED)
|
|
11
35
|
|
|
12
|
-
|
|
13
|
-
formatted_response(status: "success", message: message, data: data)
|
|
36
|
+
raise(KeyError, "key not found: #{key.inspect}")
|
|
14
37
|
end
|
|
15
38
|
|
|
16
|
-
def
|
|
17
|
-
|
|
39
|
+
def key?(key)
|
|
40
|
+
ALLOWED_KEYS.include?(key) && !public_send(key).nil?
|
|
18
41
|
end
|
|
42
|
+
alias has_key? key?
|
|
43
|
+
alias include? key?
|
|
19
44
|
|
|
20
|
-
|
|
21
|
-
|
|
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
|
|
45
|
+
def keys
|
|
46
|
+
ALLOWED_KEYS.select { |key| key?(key) }
|
|
27
47
|
end
|
|
28
48
|
|
|
29
|
-
def
|
|
30
|
-
|
|
49
|
+
def values
|
|
50
|
+
keys.map { |key| public_send(key) }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def each_pair
|
|
54
|
+
return to_enum(:each_pair) unless block_given?
|
|
55
|
+
|
|
56
|
+
keys.each { |key| yield(key, public_send(key)) }
|
|
57
|
+
end
|
|
58
|
+
alias each each_pair
|
|
59
|
+
|
|
60
|
+
def to_h
|
|
61
|
+
ALLOWED_KEYS.each_with_object({}) do |key, hash|
|
|
62
|
+
value = public_send(key)
|
|
63
|
+
hash[key] = value unless value.nil?
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
alias to_hash to_h
|
|
67
|
+
|
|
68
|
+
def to_s
|
|
69
|
+
to_h.to_s
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def inspect
|
|
73
|
+
"#<#{self.class.name} #{to_h.inspect}>"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def ==(other)
|
|
77
|
+
case other
|
|
78
|
+
when Response then to_h == other.to_h
|
|
79
|
+
when Hash then to_h == other
|
|
80
|
+
else super
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def dig(key, *rest)
|
|
85
|
+
return nil unless ALLOWED_KEYS.include?(key)
|
|
86
|
+
|
|
87
|
+
value = public_send(key)
|
|
88
|
+
return value if rest.empty? || value.nil?
|
|
89
|
+
|
|
90
|
+
value.respond_to?(:dig) ? value.dig(*rest) : nil
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def as_json(options = nil)
|
|
94
|
+
to_h.as_json(options)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def to_json(*args)
|
|
98
|
+
to_h.to_json(*args)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
|
|
103
|
+
def ensure_allowed_key!(key)
|
|
104
|
+
return if ALLOWED_KEYS.include?(key)
|
|
105
|
+
|
|
106
|
+
raise(ServiceCore::InvalidKey, "Invalid key. Allowed keys are: #{ALLOWED_KEYS.join(", ")}")
|
|
31
107
|
end
|
|
32
108
|
end
|
|
33
109
|
end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
1
|
require "active_support/concern"
|
|
4
2
|
|
|
5
3
|
module ServiceCore
|
|
@@ -7,39 +5,37 @@ module ServiceCore
|
|
|
7
5
|
extend ActiveSupport::Concern
|
|
8
6
|
|
|
9
7
|
included do
|
|
10
|
-
# NOTE:
|
|
11
|
-
#
|
|
12
|
-
#
|
|
8
|
+
# NOTE: ActiveModel::Validations resets `errors` on every `valid?`,
|
|
9
|
+
# so we re-apply any errors recorded via #add_error through a
|
|
10
|
+
# registered validator. This lets a service accumulate errors
|
|
11
|
+
# mid-perform without them being wiped.
|
|
13
12
|
validate :local_errors_validation
|
|
13
|
+
end
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
def add_error(attribute, message, options = {})
|
|
16
|
+
value = options.empty? ? message : [message, options]
|
|
17
|
+
@local_errors[attribute] ||= []
|
|
18
|
+
@local_errors[attribute] << value
|
|
19
|
+
end
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
def add_error_and_validate(attribute, message, options = {})
|
|
22
|
+
add_error(attribute, message, options)
|
|
23
|
+
valid?
|
|
24
|
+
end
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
errors.add(attribute, *message.is_a?(Array) ? message : [message])
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
{}
|
|
28
|
-
end
|
|
26
|
+
private
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Array(@local_errors[attribute]) << value
|
|
34
|
-
else
|
|
35
|
-
[value]
|
|
36
|
-
end
|
|
28
|
+
def local_errors_validation
|
|
29
|
+
@local_errors.each do |attribute, messages|
|
|
30
|
+
Array(messages).each { |message| apply_local_error(attribute, message) }
|
|
37
31
|
end
|
|
32
|
+
end
|
|
38
33
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
def apply_local_error(attribute, message)
|
|
35
|
+
if message.is_a?(Array)
|
|
36
|
+
errors.add(attribute, *message)
|
|
37
|
+
else
|
|
38
|
+
errors.add(attribute, message)
|
|
43
39
|
end
|
|
44
40
|
end
|
|
45
41
|
end
|
data/lib/service_core/version.rb
CHANGED
data/lib/service_core.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
1
|
require_relative "service_core/version"
|
|
2
|
+
require_relative "service_core/errors"
|
|
3
|
+
require_relative "service_core/response"
|
|
4
|
+
require_relative "service_core/field_set"
|
|
4
5
|
require_relative "service_core/base"
|
|
5
6
|
require_relative "service_core/step_validation"
|
|
6
7
|
require_relative "service_core/logger"
|
|
@@ -17,8 +18,6 @@ module ServiceCore
|
|
|
17
18
|
include ServiceCore::Logger
|
|
18
19
|
end
|
|
19
20
|
|
|
20
|
-
class Error < StandardError; end
|
|
21
|
-
|
|
22
21
|
class << self
|
|
23
22
|
attr_writer :logger
|
|
24
23
|
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: service_core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- mayank sehgal
|
|
8
|
-
autorequire:
|
|
9
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
13
|
name: activemodel
|
|
@@ -19,7 +18,7 @@ dependencies:
|
|
|
19
18
|
version: '6.1'
|
|
20
19
|
- - "<"
|
|
21
20
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: '
|
|
21
|
+
version: '9.0'
|
|
23
22
|
type: :runtime
|
|
24
23
|
prerelease: false
|
|
25
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -29,7 +28,7 @@ dependencies:
|
|
|
29
28
|
version: '6.1'
|
|
30
29
|
- - "<"
|
|
31
30
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
31
|
+
version: '9.0'
|
|
33
32
|
- !ruby/object:Gem::Dependency
|
|
34
33
|
name: activesupport
|
|
35
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -39,7 +38,7 @@ dependencies:
|
|
|
39
38
|
version: '6.1'
|
|
40
39
|
- - "<"
|
|
41
40
|
- !ruby/object:Gem::Version
|
|
42
|
-
version: '
|
|
41
|
+
version: '9.0'
|
|
43
42
|
type: :runtime
|
|
44
43
|
prerelease: false
|
|
45
44
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -49,35 +48,43 @@ dependencies:
|
|
|
49
48
|
version: '6.1'
|
|
50
49
|
- - "<"
|
|
51
50
|
- !ruby/object:Gem::Version
|
|
52
|
-
version: '
|
|
53
|
-
description:
|
|
51
|
+
version: '9.0'
|
|
52
|
+
description: ServiceCore provides a four-key response contract (status, data, message,
|
|
53
|
+
errors) for service objects, with field declarations, validations, step validation,
|
|
54
|
+
structured logging, and a Hash-compatible Response value object.
|
|
54
55
|
email:
|
|
55
56
|
- sehgalmayank001@gmail.com
|
|
56
57
|
executables: []
|
|
57
58
|
extensions: []
|
|
58
59
|
extra_rdoc_files: []
|
|
59
60
|
files:
|
|
60
|
-
- ".byebug_history"
|
|
61
61
|
- ".rspec"
|
|
62
62
|
- ".rubocop.yml"
|
|
63
|
+
- ".tool-versions"
|
|
64
|
+
- Appraisals
|
|
63
65
|
- CHANGELOG.md
|
|
64
66
|
- CODE_OF_CONDUCT.md
|
|
65
67
|
- LICENSE.txt
|
|
66
68
|
- README.md
|
|
67
69
|
- Rakefile
|
|
70
|
+
- gemfiles/rails_7.2.gemfile
|
|
71
|
+
- gemfiles/rails_8.0.gemfile
|
|
72
|
+
- gemfiles/rails_8.1.gemfile
|
|
68
73
|
- lib/service_core.rb
|
|
69
74
|
- lib/service_core/base.rb
|
|
75
|
+
- lib/service_core/errors.rb
|
|
76
|
+
- lib/service_core/field_set.rb
|
|
70
77
|
- lib/service_core/logger.rb
|
|
78
|
+
- lib/service_core/output.rb
|
|
79
|
+
- lib/service_core/responder.rb
|
|
71
80
|
- lib/service_core/response.rb
|
|
72
81
|
- lib/service_core/step_validation.rb
|
|
73
82
|
- lib/service_core/version.rb
|
|
74
|
-
- service_core.gemspec
|
|
75
|
-
- sig/service_core.rbs
|
|
76
83
|
homepage: https://github.com/sehgalmayank001/service-core
|
|
77
84
|
licenses:
|
|
78
85
|
- MIT
|
|
79
|
-
metadata:
|
|
80
|
-
|
|
86
|
+
metadata:
|
|
87
|
+
rubygems_mfa_required: 'true'
|
|
81
88
|
rdoc_options: []
|
|
82
89
|
require_paths:
|
|
83
90
|
- lib
|
|
@@ -85,15 +92,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
85
92
|
requirements:
|
|
86
93
|
- - ">="
|
|
87
94
|
- !ruby/object:Gem::Version
|
|
88
|
-
version:
|
|
95
|
+
version: 3.1.0
|
|
89
96
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
97
|
requirements:
|
|
91
98
|
- - ">="
|
|
92
99
|
- !ruby/object:Gem::Version
|
|
93
100
|
version: '0'
|
|
94
101
|
requirements: []
|
|
95
|
-
rubygems_version: 3.
|
|
96
|
-
signing_key:
|
|
102
|
+
rubygems_version: 3.6.9
|
|
97
103
|
specification_version: 4
|
|
98
|
-
summary: A
|
|
104
|
+
summary: A standardised service object pattern for Ruby and Rails
|
|
99
105
|
test_files: []
|
data/.byebug_history
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
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
|