midnight-rails 0.0.1
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 +7 -0
- data/lib/abc.js +14 -0
- data/lib/midnight/rails.rb +20 -0
- data/lib/midnight/rails/active_record_event_adapter.rb +47 -0
- data/lib/midnight/rails/active_record_interactor.rb +70 -0
- data/lib/midnight/rails/active_record_wrapper.rb +55 -0
- data/lib/midnight/rails/command.rb +13 -0
- data/lib/midnight/rails/commit_hooker.rb +28 -0
- data/lib/midnight/rails/default_event.rb +7 -0
- data/lib/midnight/rails/default_migration.rb +83 -0
- data/lib/midnight/rails/default_state.rb +7 -0
- data/lib/midnight/rails/dry_event.rb +29 -0
- data/lib/midnight/rails/stale_object_error.rb +10 -0
- data/lib/midnight/rails/state_adapter.rb +56 -0
- data/lib/midnight/rails/version.rb +5 -0
- metadata +155 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 535ce5a0b745470d77c89d9d260029943e858104b4f163d8c1711c0d6eab9438
|
4
|
+
data.tar.gz: be0a0a44852886b9b21b8a8056be983a06254effc038d64117ef8e3119348094
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ebeb600cfca21c1f21aa457bf597a3891e8dd80b53e757ef0403d414eeadebc826db62b3c58c91acdf7c726720b09415476506e38aaca5c20985fbdbc7fc7b64
|
7
|
+
data.tar.gz: 82115430e1d49320ea26d75c4e61bf0ca1d2a45ce7c00d818beb71e5d826468d87660dfb80a9f2084ba5c60da49d307f4c3e6ff772efa9e08c6e990679b40184
|
data/lib/abc.js
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
var FindProxyForURL = (() => {
|
2
|
+
var torEndpoint = 'SOCKS5 localhost:9050';
|
3
|
+
var onionTester = /\.onion$/i;
|
4
|
+
var blockedTester = /^-$/; // nothing is blocking
|
5
|
+
return (url, host) => {
|
6
|
+
if (onionTester.test(host)) {
|
7
|
+
return torEndpoint;
|
8
|
+
}
|
9
|
+
if (blockedTester.test(host)) {
|
10
|
+
return torEndpoint;
|
11
|
+
}
|
12
|
+
return 'DIRECT';
|
13
|
+
};
|
14
|
+
})();
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'rails/version'
|
2
|
+
require 'active_support/dependencies/autoload'
|
3
|
+
|
4
|
+
module Midnight
|
5
|
+
module Rails
|
6
|
+
extend ::ActiveSupport::Autoload
|
7
|
+
|
8
|
+
autoload :ActiveRecordInteractor
|
9
|
+
autoload :ActiveRecordWrapper
|
10
|
+
autoload :CommitHooker
|
11
|
+
autoload :StateAdapter
|
12
|
+
autoload :DefaultState
|
13
|
+
autoload :ActiveRecordEventAdapter
|
14
|
+
autoload :DefaultEvent
|
15
|
+
autoload :Command
|
16
|
+
autoload :DryEvent
|
17
|
+
autoload :DefaultMigration
|
18
|
+
autoload :StaleObjectError
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'activerecord-import'
|
2
|
+
require 'midnight/utilities'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module Midnight
|
6
|
+
module Rails
|
7
|
+
# noinspection RubyDefParenthesesInspection
|
8
|
+
# noinspection RubyParameterNamingConvention
|
9
|
+
class ActiveRecordEventAdapter
|
10
|
+
attr_reader :active_record
|
11
|
+
|
12
|
+
def initialize(\
|
13
|
+
active_record: DefaultEvent,
|
14
|
+
serializer: Utilities::JsonSerializer,
|
15
|
+
fetch_event_timestamp: lambda do |event|
|
16
|
+
::Time.parse(event.metadata[:occurred_at])
|
17
|
+
end
|
18
|
+
)
|
19
|
+
@active_record = active_record
|
20
|
+
@serializer = serializer
|
21
|
+
@fetch_event_timestamp = fetch_event_timestamp
|
22
|
+
freeze
|
23
|
+
end
|
24
|
+
|
25
|
+
def save_events(events = [], next_position:, state_id:, **_)
|
26
|
+
serialized_events = events.each_with_index.map do |unserialized_event, position_offset|
|
27
|
+
{
|
28
|
+
event_type: unserialized_event.class.name,
|
29
|
+
data: @serializer.dump(unserialized_event.data),
|
30
|
+
metadata: @serializer.dump(unserialized_event.metadata),
|
31
|
+
position: next_position + position_offset,
|
32
|
+
state_id: state_id,
|
33
|
+
occurred_at: @fetch_event_timestamp.call(unserialized_event),
|
34
|
+
}
|
35
|
+
end
|
36
|
+
# https://github.com/zdennis/activerecord-import
|
37
|
+
active_record.import(serialized_events, validate: false)
|
38
|
+
end
|
39
|
+
|
40
|
+
# load functionality intentionally omitted
|
41
|
+
# different use cases requires different load implementation
|
42
|
+
# so we don't include it in Midnight::Rails
|
43
|
+
# but you can implement one easily
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'midnight/business_logic'
|
2
|
+
|
3
|
+
module Midnight
|
4
|
+
module Rails
|
5
|
+
DEFAULT_COMMAND_VALIDATOR = lambda(&:validate!)
|
6
|
+
|
7
|
+
# noinspection RubyParameterNamingConvention
|
8
|
+
class ActiveRecordInteractor
|
9
|
+
def initialize(
|
10
|
+
aggregate_key:,
|
11
|
+
build_aggregate:,
|
12
|
+
transaction_handler: Commons::NULL_EVENT_HANDLER,
|
13
|
+
committed_handler: Commons::NULL_EVENT_HANDLER,
|
14
|
+
command_validator: DEFAULT_COMMAND_VALIDATOR,
|
15
|
+
state_persistence: StateAdapter.new(
|
16
|
+
active_record: DefaultState
|
17
|
+
),
|
18
|
+
advance_state_metadata: lambda(&:advance_metadata),
|
19
|
+
save_state: lambda(&:save!)
|
20
|
+
)
|
21
|
+
@aggregate_key = aggregate_key
|
22
|
+
@build_aggregate = build_aggregate
|
23
|
+
@transaction_handler = transaction_handler
|
24
|
+
@committed_handler = committed_handler
|
25
|
+
@command_validator = command_validator
|
26
|
+
@state_persistence = state_persistence
|
27
|
+
@advance_state_metadata = advance_state_metadata
|
28
|
+
@save_state = save_state
|
29
|
+
freeze
|
30
|
+
end
|
31
|
+
|
32
|
+
def call(*commands)
|
33
|
+
commands.each(&@command_validator)
|
34
|
+
transaction do |aggregate|
|
35
|
+
commands.each(&aggregate.method(:dispatch))
|
36
|
+
aggregate.pending_events
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def transaction(&aggregate_operator)
|
43
|
+
@state_persistence.transaction do
|
44
|
+
state_record = @state_persistence.load(
|
45
|
+
key: @aggregate_key
|
46
|
+
)
|
47
|
+
aggregate = @build_aggregate.call(
|
48
|
+
state: state_record.state
|
49
|
+
)
|
50
|
+
state_metadata = state_record.metadata
|
51
|
+
pending_events = aggregate_operator.call(aggregate)
|
52
|
+
@transaction_handler.call(
|
53
|
+
pending_events,
|
54
|
+
state_metadata
|
55
|
+
)
|
56
|
+
@state_persistence.hook_commit do
|
57
|
+
@committed_handler.call(
|
58
|
+
pending_events,
|
59
|
+
state_metadata
|
60
|
+
)
|
61
|
+
end
|
62
|
+
state_record.state = aggregate.state
|
63
|
+
@advance_state_metadata.call(state_record, pending_events)
|
64
|
+
@save_state.call(state_record)
|
65
|
+
pending_events
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'midnight/business_logic'
|
3
|
+
|
4
|
+
module Midnight
|
5
|
+
module Rails
|
6
|
+
class ActiveRecordWrapper
|
7
|
+
|
8
|
+
def initialize(
|
9
|
+
record,
|
10
|
+
serializer:,
|
11
|
+
metadata_adapter:,
|
12
|
+
advance_metadata:
|
13
|
+
)
|
14
|
+
@record = record
|
15
|
+
@serializer = serializer
|
16
|
+
@metadata_adapter = metadata_adapter
|
17
|
+
@advance_metadata = advance_metadata
|
18
|
+
@state_loaded = false
|
19
|
+
@state_changed = false
|
20
|
+
end
|
21
|
+
|
22
|
+
def metadata
|
23
|
+
@metadata_adapter.call(@record)
|
24
|
+
end
|
25
|
+
|
26
|
+
def state
|
27
|
+
return @changed_state if @state_changed
|
28
|
+
return @loaded_state if @state_loaded
|
29
|
+
@loaded_state = @serializer.load(@record.state)
|
30
|
+
@state_loaded = true
|
31
|
+
@loaded_state
|
32
|
+
end
|
33
|
+
|
34
|
+
def state=(new_state)
|
35
|
+
@state_changed = true
|
36
|
+
@changed_state = new_state
|
37
|
+
end
|
38
|
+
|
39
|
+
def advance_metadata(events)
|
40
|
+
@advance_metadata.call(@record, events)
|
41
|
+
end
|
42
|
+
|
43
|
+
def save!
|
44
|
+
@record.state = @serializer.dump(@changed_state) \
|
45
|
+
if @state_changed
|
46
|
+
@record.save!
|
47
|
+
rescue ::ActiveRecord::StaleObjectError => e
|
48
|
+
# rescue just to add the convenient marker module to the exception
|
49
|
+
raise e if e.is_a?(Commons::ConcurrentWriteError)
|
50
|
+
raise StaleObjectError.new(e.record, e.attempted_action)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
private_constant :ActiveRecordWrapper
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Midnight
|
2
|
+
module Rails
|
3
|
+
# after_commit hook
|
4
|
+
# https://dev.to/evilmartians/rails-aftercommit-everywhere--4j9g
|
5
|
+
class CommitHooker
|
6
|
+
def initialize(&after_commit)
|
7
|
+
@after_commit = after_commit
|
8
|
+
freeze
|
9
|
+
end
|
10
|
+
|
11
|
+
# :nocov:
|
12
|
+
# rubocop:disable Style/MethodMissingSuper
|
13
|
+
def method_missing(method_name, *_args)
|
14
|
+
after_commit.call if method_name == :committed!
|
15
|
+
end
|
16
|
+
# rubocop:enable Style/MethodMissingSuper
|
17
|
+
|
18
|
+
def respond_to_missing?(_method_name, _include_private = false)
|
19
|
+
true
|
20
|
+
end
|
21
|
+
# :nocov:
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :after_commit
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_support/core_ext/object/blank'
|
3
|
+
require 'openssl'
|
4
|
+
|
5
|
+
module Midnight
|
6
|
+
module Rails
|
7
|
+
# noinspection RubyDefParenthesesInspection
|
8
|
+
# noinspection RubyParameterNamingConvention
|
9
|
+
module DefaultMigration
|
10
|
+
extend ::ActiveSupport::Concern
|
11
|
+
|
12
|
+
def change_state_table(\
|
13
|
+
table_name: :midnight__states,
|
14
|
+
identification_index_name: nil,
|
15
|
+
concurrent_safe: true,
|
16
|
+
**_
|
17
|
+
)
|
18
|
+
# if you are sure your application don't generate aggregate_key
|
19
|
+
# that easy to collide (e.g. running number) you can turn
|
20
|
+
# the concurrent safety off
|
21
|
+
create_table table_name do |t|
|
22
|
+
t.binary :state
|
23
|
+
t.string :aggregate_key, null: false, index: {
|
24
|
+
name: identification_index_name.presence || randomized_index_name(
|
25
|
+
"{#{table_name}: :aggregate_key}"
|
26
|
+
),
|
27
|
+
unique: concurrent_safe
|
28
|
+
}
|
29
|
+
t.integer :next_position, default: 1
|
30
|
+
t.integer :lock_version, default: 0
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def change_event_table(\
|
35
|
+
table_name: :midnight__events,
|
36
|
+
state_index_name: nil,
|
37
|
+
occurred_at_index_name: nil,
|
38
|
+
position_index_name: nil,
|
39
|
+
concurrent_safe: false,
|
40
|
+
**_
|
41
|
+
)
|
42
|
+
# if you have an application with relatively small traffic
|
43
|
+
# and don't have that much events to store
|
44
|
+
# you can turn the concurrent safety on for the peace of mind
|
45
|
+
create_table table_name do |t|
|
46
|
+
t.binary :data, null: false
|
47
|
+
t.binary :metadata, null: false
|
48
|
+
t.string :event_type, null: false
|
49
|
+
t.integer :position, null: false
|
50
|
+
t.references :state, index: {
|
51
|
+
name: state_index_name.presence || randomized_index_name(\
|
52
|
+
"{#{table_name}: :state_id}"\
|
53
|
+
)
|
54
|
+
}
|
55
|
+
t.datetime :occurred_at, index: {
|
56
|
+
name: occurred_at_index_name.presence || randomized_index_name(\
|
57
|
+
"{#{table_name}: :occurred_at}"\
|
58
|
+
)
|
59
|
+
}, null: false
|
60
|
+
t.index [:state_id, :position], \
|
61
|
+
name: position_index_name.presence || randomized_index_name(\
|
62
|
+
"{#{table_name}:[:state_id,:position]}"\
|
63
|
+
), \
|
64
|
+
unique: concurrent_safe
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def randomized_index_name(seed_data)
|
71
|
+
# the string can be hard coded
|
72
|
+
# but for transparency, lets leave the origin here
|
73
|
+
# instead of some magic constants
|
74
|
+
randomized_part = ::OpenSSL::HMAC.hexdigest(
|
75
|
+
'SHA256',
|
76
|
+
'Midnight::Rails',
|
77
|
+
seed_data
|
78
|
+
)
|
79
|
+
"index_rails_#{randomized_part[0, 10]}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'dry/schema'
|
2
|
+
require 'midnight/business_logic'
|
3
|
+
|
4
|
+
module Midnight
|
5
|
+
module Rails
|
6
|
+
class DryEvent < BusinessLogic::Event
|
7
|
+
class SchemaViolation < BusinessLogic::Event::SchemaViolation
|
8
|
+
end
|
9
|
+
|
10
|
+
class << self
|
11
|
+
private
|
12
|
+
|
13
|
+
def ensure_schema(data)
|
14
|
+
@data_schema ||= data_schema
|
15
|
+
result = @data_schema.call(data)
|
16
|
+
raise SchemaViolation unless result.success?
|
17
|
+
end
|
18
|
+
|
19
|
+
def data_schema
|
20
|
+
raise NotImplementedError
|
21
|
+
# example
|
22
|
+
# ::Dry::Schema.Params do
|
23
|
+
# required(:example_field).filled(:string)
|
24
|
+
# end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'midnight/utilities'
|
3
|
+
|
4
|
+
module Midnight
|
5
|
+
module Rails
|
6
|
+
class StateAdapter
|
7
|
+
def initialize(\
|
8
|
+
active_record: DefaultState,
|
9
|
+
serializer: Utilities::JsonSerializer,
|
10
|
+
metadata_adapter: lambda do |record|
|
11
|
+
{
|
12
|
+
next_position: record.next_position,
|
13
|
+
state_id: record.id,
|
14
|
+
aggregate_key: record.aggregate_key,
|
15
|
+
}
|
16
|
+
end,
|
17
|
+
advance_metadata: lambda do |record, events|
|
18
|
+
record.next_position += events.length
|
19
|
+
end
|
20
|
+
)
|
21
|
+
@model = active_record
|
22
|
+
@serializer = serializer
|
23
|
+
@metadata_adapter = metadata_adapter
|
24
|
+
@advance_metadata = advance_metadata
|
25
|
+
end
|
26
|
+
|
27
|
+
def load(key:, **_)
|
28
|
+
record = begin
|
29
|
+
@model.where(
|
30
|
+
aggregate_key: key
|
31
|
+
).first_or_create!
|
32
|
+
rescue ::ActiveRecord::RecordNotUnique
|
33
|
+
# :nocov:
|
34
|
+
retry
|
35
|
+
# :nocov:
|
36
|
+
end
|
37
|
+
ActiveRecordWrapper.new(
|
38
|
+
record,
|
39
|
+
serializer: @serializer,
|
40
|
+
metadata_adapter: @metadata_adapter,
|
41
|
+
advance_metadata: @advance_metadata
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def transaction(&block)
|
46
|
+
@model.transaction(&block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def hook_commit(&block)
|
50
|
+
@model.connection.add_transaction_record(
|
51
|
+
CommitHooker.new(&block)
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: midnight-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sarun Rattanasiri
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-08-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
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: activerecord
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
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: activerecord-import
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activemodel
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: dry-schema
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: midnight-business_logic
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: midnight-utilities
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Midnight::Rails enrich your Rails, and non-Rails application, decouples
|
112
|
+
your business logic from frameworks, databases, and UI with the sane default. See
|
113
|
+
for yourself how far an application adopting the clean architecture can go.
|
114
|
+
email: midnight_w@gmx.tw
|
115
|
+
executables: []
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- lib/abc.js
|
120
|
+
- lib/midnight/rails.rb
|
121
|
+
- lib/midnight/rails/active_record_event_adapter.rb
|
122
|
+
- lib/midnight/rails/active_record_interactor.rb
|
123
|
+
- lib/midnight/rails/active_record_wrapper.rb
|
124
|
+
- lib/midnight/rails/command.rb
|
125
|
+
- lib/midnight/rails/commit_hooker.rb
|
126
|
+
- lib/midnight/rails/default_event.rb
|
127
|
+
- lib/midnight/rails/default_migration.rb
|
128
|
+
- lib/midnight/rails/default_state.rb
|
129
|
+
- lib/midnight/rails/dry_event.rb
|
130
|
+
- lib/midnight/rails/stale_object_error.rb
|
131
|
+
- lib/midnight/rails/state_adapter.rb
|
132
|
+
- lib/midnight/rails/version.rb
|
133
|
+
homepage: https://gitlab.com/slime-systems/midnight-enterprise-toolkit/tree/master/midnight-rails
|
134
|
+
licenses: []
|
135
|
+
metadata: {}
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
requirements: []
|
151
|
+
rubygems_version: 3.0.3
|
152
|
+
signing_key:
|
153
|
+
specification_version: 4
|
154
|
+
summary: The default integration of Midnight::BusinessLogic with the sane choices.
|
155
|
+
test_files: []
|