hecks-application 0.1.16.rc → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e835d560fad82657aced9156d3b9d73c3089d7a0
4
- data.tar.gz: 77a0909656ab8e840583cf33e312f0f9386ecfd0
3
+ metadata.gz: 5ea1241067264baa88f4ba4e89d1dcaf09fad09e
4
+ data.tar.gz: af63582186c185435e111912570f8eb23a8c6b06
5
5
  SHA512:
6
- metadata.gz: '019ef6624b3e1bbe7eb2c5d3806f258e9497a6219a501caf3604d1b9a3a20373fafabb27c6a5f18bcf91a04cb1f2361e7845ccbf0d45b433a2c630d5bb6358ea'
7
- data.tar.gz: '056639fa7558ec83222497faf09348c433b240e83a26121b170cdaeae42fec9aa0b69588b8db74a1e4acfceec2be9379542282bd7c95fe4287b704c9b5b6ddf4'
6
+ metadata.gz: d8c0a05ecae96f05662a2aad3e7b39b149df2bbbd20f927955a33821122c6e4d79281a854e3849903126afb2310fec9b076c202935360e1f47481163f36894db
7
+ data.tar.gz: fc16e2f199eb5199d7de6c5f9cd3b4b410f045d3d3a2e12b239f094b0e48952149d0da02c00201b1bcc253c7fcb9f8896e9865684bc55d80cde57b3054e4a1b1
@@ -0,0 +1,55 @@
1
+ require 'digest'
2
+
3
+ class HecksApplication
4
+ # Run an application command, with validations and broacast lifecycle events
5
+ class CommandRunner
6
+ attr_reader :module_name, :command
7
+
8
+ def initialize(command_name:, module_name:, args:, application:, async: false)
9
+ @command_name = command_name
10
+ @module_name = module_name
11
+ @args = args
12
+ @application = application
13
+ @domain_spec = application.domain_spec
14
+ @async = async
15
+ end
16
+
17
+ def call()
18
+ fetch_command
19
+ run_command
20
+ broadcast
21
+ command
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :command_name, :args, :application, :domain_spec, :async
27
+
28
+ def broadcast
29
+ application.events_port.send(command: command, module_name: module_name)
30
+ end
31
+
32
+ def fetch_command
33
+ args.merge!(id: SecureRandom.uuid) if command_name == :create
34
+ @command = Commands.const_get(command_name.to_s.camelcase).new(
35
+ repository: application.database[module_name],
36
+ args: args,
37
+ domain_module: fetch_module
38
+ )
39
+ end
40
+
41
+ def fetch_module
42
+ domain_spec.domain_modules[module_name.to_s.camelize.to_sym]
43
+ end
44
+
45
+ def run_command
46
+ if async
47
+ Thread::new { command.call }
48
+ else
49
+ command.call
50
+ end
51
+
52
+ command
53
+ end
54
+ end
55
+ end
@@ -2,4 +2,3 @@ require_relative 'update'
2
2
  require_relative 'create'
3
3
  require_relative 'delete'
4
4
  require_relative 'crud_handler'
5
- require_relative 'runner'
@@ -1,49 +1,49 @@
1
1
  # frozen_string_literal: true
2
- module Hecks
3
- class Application
4
- module Commands
5
- class Create
6
- attr_accessor :args, :id, :errors, :repository, :domain_module
7
-
8
- def initialize(args:, repository:, domain_module: )
9
- @repository = repository
10
- @args = args
11
- @errors = {}
12
- @validator = Hecks::Adapters::Validator
13
- @domain_module = domain_module
14
- end
15
-
16
- def call
17
- validate
18
- create
19
- self
20
- end
21
-
22
- def to_h
23
- { errors: errors, id: repository_result, args: args }
24
- end
25
-
26
- def name
27
- self.class.to_s.split('::').last.underscore
28
- end
29
-
30
- def result
31
- { id: id, success: !id.nil?, errors: errors, args: args }
32
- end
33
-
34
- private
35
-
36
- attr_reader :repository_result
37
-
38
- def create
39
- return if @errors.count.positive?
40
- @id = @repository_result = repository.create(args).id
41
- end
42
-
43
- def validate
44
- return if @validator.nil?
45
- @errors = @validator.new(command: self).call.errors
46
- end
2
+ class HecksApplication
3
+ module Commands
4
+ # Create a resource
5
+ class Create
6
+ attr_accessor :args, :result, :errors, :repository, :domain_module, :id
7
+
8
+ def initialize(args:, repository:, domain_module:, validator: HecksApplication::Validator)
9
+ @repository = repository
10
+ @args = args
11
+ @errors = {}
12
+ @validator = validator
13
+ @domain_module = domain_module
14
+ end
15
+
16
+ def call
17
+ validate
18
+ create
19
+ self
20
+ end
21
+
22
+ def to_h
23
+ { errors: errors, id: repository_result, args: args }
24
+ end
25
+
26
+ def name
27
+ self.class.to_s.split('::').last.underscore
28
+ end
29
+
30
+ def result
31
+ { id: id, success: !id.nil?, errors: errors, args: args }
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :repository_result
37
+
38
+ def create
39
+ return if @errors.count.positive?
40
+ @id = args[:id]
41
+ repository.create(args)
42
+ end
43
+
44
+ def validate
45
+ return if @validator.nil?
46
+ @errors = @validator.new(command: self).call.errors
47
47
  end
48
48
  end
49
49
  end
@@ -1,45 +1,45 @@
1
- module Hecks
2
- class Application
3
- module Commands
4
- class CRUDHandler
5
- attr_reader :module_name, :application
1
+ class HecksApplication
2
+ module Commands
3
+ # Map resourceful methods to the domain
4
+ class CRUDHandler
5
+ attr_reader :module_name, :application, :validator
6
6
 
7
- def initialize(module_name:, application:)
8
- @module_name = module_name
9
- @application = application
10
- end
7
+ def initialize(module_name:, application:, validator:)
8
+ @module_name = module_name
9
+ @application = application
10
+ @validator = validator
11
+ end
11
12
 
12
- def create(attributes)
13
- application.call(
14
- module_name: module_name,
15
- command_name: :create,
16
- args: attributes
17
- )
18
- end
13
+ def create(args)
14
+ application.call(
15
+ module_name: module_name,
16
+ command_name: :create,
17
+ args: args
18
+ )
19
+ end
19
20
 
20
- def read(id)
21
- application.query(
22
- module_name: module_name,
23
- query_name: :find_by_id,
24
- args: { id: id }
25
- )
26
- end
21
+ def read(id)
22
+ application.query(
23
+ module_name: module_name,
24
+ query_name: :find_by_id,
25
+ args: { id: id }
26
+ )
27
+ end
27
28
 
28
- def update(id, attributes)
29
- application.call(
30
- module_name: module_name,
31
- command_name: :update,
32
- args: attributes.merge(id: id)
33
- )
34
- end
29
+ def update(attributes)
30
+ application.call(
31
+ module_name: module_name,
32
+ command_name: :update,
33
+ args: attributes
34
+ )
35
+ end
35
36
 
36
- def delete(id)
37
- application.call(
38
- module_name: module_name,
39
- command_name: :delete,
40
- args: { id: id }
41
- )
42
- end
37
+ def delete(id)
38
+ application.call(
39
+ module_name: module_name,
40
+ command_name: :delete,
41
+ args: { id: id }
42
+ )
43
43
  end
44
44
  end
45
45
  end
@@ -1,37 +1,40 @@
1
1
  # frozen_string_literal: true
2
- module Hecks
3
- class Application
4
- module Commands
5
- class Delete
6
- attr_accessor :args, :errors, :repository
7
-
8
- def initialize(args: nil, repository:, domain_module:)
9
- @args = args || chained_command.args
10
- @repository = repository
11
- @errors = { base: [] }
12
- end
13
-
14
- def call
15
- delete
16
- self
17
- end
18
-
19
- def name
20
- self.class.to_s.split('::').last.underscore
21
- end
22
-
23
- def to_h
24
- { errors: errors, args: args }
25
- end
26
-
27
- private
28
-
29
- attr_accessor :command_result, :repository
30
-
31
- def delete
32
- @result = repository.delete(args[:id])
33
- @errors[:base] << "cound not find #{args[:id]}" unless @result
34
- end
2
+ class HecksApplication
3
+ module Commands
4
+ # Delete a resource.
5
+ class Delete
6
+ attr_accessor :args, :errors, :repository
7
+
8
+ def initialize(args: nil, repository:, domain_module:)
9
+ @args = args || chained_command.args
10
+ @repository = repository
11
+ @errors = { base: [] }
12
+ end
13
+
14
+ def call
15
+ delete
16
+ self
17
+ end
18
+
19
+ def name
20
+ self.class.to_s.split('::').last.underscore
21
+ end
22
+
23
+ def to_h
24
+ { errors: errors, args: args }
25
+ end
26
+
27
+ def result
28
+ { id: args[:id], errors: errors, args: args }
29
+ end
30
+
31
+ private
32
+
33
+ attr_accessor :command_result, :repository
34
+
35
+ def delete
36
+ @result = repository.delete(args[:id])
37
+ @errors[:base] << "cound not find #{args[:id]}" unless @result
35
38
  end
36
39
  end
37
40
  end
@@ -1,38 +1,41 @@
1
1
  # frozen_string_literal: true
2
- module Hecks
3
- class Application
4
- module Commands
5
- class Update
6
- attr_accessor :args, :errors, :id, :repository
7
-
8
- def initialize(args: nil, repository: Repository, domain_module:)
9
- @repository = repository
10
- @args = args
11
- @errors = []
12
- @id = @args.delete(:id)
13
- end
14
-
15
- def name
16
- self.class.to_s.split('::').last.underscore
17
- end
18
-
19
- def call
20
- update
21
- self
22
- end
23
-
24
- def to_h
25
- { id: id, args: args }
26
- end
27
-
28
- private
29
-
30
- attr_reader :repository_result
31
-
32
- def update
33
- return if @errors.count.positive?
34
- @repository_result = repository.update(id, args)
35
- end
2
+ class HecksApplication
3
+ module Commands
4
+ # Update a resource
5
+ class Update
6
+ attr_accessor :args, :repository
7
+
8
+ def initialize(args: nil, repository: Repository, domain_module:)
9
+ @repository = repository
10
+ @args = args
11
+ @errors = []
12
+ @id = @args.delete(:id)
13
+ end
14
+
15
+ def name
16
+ self.class.to_s.split('::').last.underscore
17
+ end
18
+
19
+ def call
20
+ update
21
+ self
22
+ end
23
+
24
+ def result
25
+ { success: errors.empty?, errors: errors, args: args }
26
+ end
27
+
28
+ def to_h
29
+ { id: id, args: args }
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :repository_result, :id, :errors
35
+
36
+ def update
37
+ return if @errors.count.positive?
38
+ @repository_result = repository.update(id, args)
36
39
  end
37
40
  end
38
41
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Send lifecycle events to listeners
4
+ class HecksEvents
5
+ def initialize(listeners: [])
6
+ @listeners = listeners
7
+ end
8
+
9
+ def send(module_name:, command:)
10
+ @command = command
11
+ @module_name = module_name
12
+ listeners.each do |listener|
13
+ next unless listener.respond_to?(event_name)
14
+ listener.public_send(event_name, command)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :listeners, :command, :module_name
21
+
22
+ def event_name
23
+ "#{module_name}_#{command.name}".to_sym
24
+ end
25
+ end
@@ -1,49 +1,57 @@
1
1
  # frozen_string_literal: true
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'hecks-memory-database'
5
+ require 'hecks-domain'
6
+
2
7
  require_relative 'commands/commands'
8
+ require_relative 'command_runner'
3
9
  require_relative 'queries/queries'
4
- require 'hecks-domain'
10
+ require_relative 'events'
11
+ require_relative 'logger'
12
+ require_relative 'validator'
5
13
 
6
- module Hecks
7
- def self.version
8
- path = "#{File.dirname(__FILE__)}/Version"
9
- File.read(path).gsub("\n", '')
14
+ # The Applicaiton port. Adapters usually talk to the domain through
15
+ # HecksApplication
16
+ class HecksApplication
17
+ attr_reader :database, :domain_spec, :events_port, :validator
18
+ def initialize(database: nil, listeners: [], domain:, validator: HecksApplication::Validator)
19
+ load(domain.spec_path)
20
+ @domain = domain
21
+ @database = database
22
+ @events_port = HecksEvents.new(listeners: listeners)
23
+ @domain_spec = DOMAIN
24
+ @validator = validator
10
25
  end
11
26
 
12
- class Application
13
- attr_reader :database, :domain_spec, :events_port
14
- def initialize(database: nil, listeners: [], domain:)
15
- load(domain.spec_path)
16
- @domain = domain
17
- @database = database
18
- @events_port = Adapters::Events.new(listeners: listeners)
19
- @domain_spec = DOMAIN
20
- end
21
-
22
- def call(command_name:, module_name:, args: {})
23
- Runner.new(
24
- command_name: command_name,
25
- module_name: module_name,
26
- args: args,
27
- application: self
28
- ).call
29
- end
27
+ def call(command_name:, module_name:, args: {})
28
+ CommandRunner.new(
29
+ command_name: command_name,
30
+ module_name: module_name,
31
+ args: args,
32
+ application: self
33
+ ).call
34
+ end
30
35
 
31
- def [](module_name)
32
- Commands::CRUDHandler.new(module_name: module_name, application: self)
33
- end
36
+ def [](module_name)
37
+ Commands::CRUDHandler.new(
38
+ module_name: module_name,
39
+ application: self,
40
+ validator: validator
41
+ )
42
+ end
34
43
 
35
- def query(query_name:, module_name:, args: {})
36
- QueryRunner.new(
37
- module_name: module_name,
38
- query_name: query_name,
39
- args: args,
40
- application: self
41
- ).call
42
- end
44
+ def query(query_name:, module_name:, args: {})
45
+ QueryRunner.new(
46
+ module_name: module_name,
47
+ query_name: query_name,
48
+ args: args,
49
+ application: self
50
+ ).call
51
+ end
43
52
 
44
- def database
45
- return @database.new(domain: @domain) if @database
46
- return Hecks::Adapters::MemoryDatabase.new(domain: @domain)
47
- end
53
+ def database
54
+ return @database.new(domain: @domain) if @database
55
+ return HecksAdapters::MemoryDatabase.new(domain: @domain)
48
56
  end
49
57
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Simple logger
4
+ class HecksLogger
5
+ def initialize(output: [])
6
+ @output = output
7
+ end
8
+
9
+ def method_missing(name, *args, &block)
10
+ @output << {name: name, command: args.first.to_h.to_s}.to_s
11
+ end
12
+
13
+ def respond_to?(name)
14
+ true
15
+ end
16
+ end
@@ -1,16 +1,15 @@
1
1
  # frozen_string_literal: true
2
- module Hecks
3
- class Application
4
- module Queries
5
- class FindById
6
- def initialize(repository:)
7
- @repository = repository
8
- end
2
+ class HecksApplication
3
+ module Queries
4
+ # Find a resource by id
5
+ class FindById
6
+ def initialize(repository:)
7
+ @repository = repository
8
+ end
9
9
 
10
- def call(params)
11
- return unless params.keys == [:id]
12
- @repository.read(params[:id])
13
- end
10
+ def call(params)
11
+ return unless params.keys == [:id]
12
+ @repository.read(params[:id])
14
13
  end
15
14
  end
16
15
  end
@@ -1,26 +1,26 @@
1
- module Hecks
2
- class Application
3
- class QueryRunner
4
- def initialize(query_name:, application:, module_name:, args:)
5
- @query_name = query_name
6
- @application = application
7
- @module_name = module_name
8
- @args = args
9
- end
1
+ class HecksApplication
10
2
 
11
- def call()
12
- fetch.new(repository: repository).call(@args)
13
- end
3
+ # Call queries by name
4
+ class QueryRunner
5
+ def initialize(query_name:, application:, module_name:, args:)
6
+ @query_name = query_name
7
+ @application = application
8
+ @module_name = module_name
9
+ @args = args
10
+ end
11
+
12
+ def call()
13
+ fetch.new(repository: repository).call(@args)
14
+ end
14
15
 
15
- private
16
+ private
16
17
 
17
- def fetch
18
- Queries.const_get(@query_name.to_s.camelcase)
19
- end
18
+ def fetch
19
+ Queries.const_get(@query_name.to_s.camelcase)
20
+ end
20
21
 
21
- def repository
22
- @application.database[@module_name]
23
- end
22
+ def repository
23
+ @application.database[@module_name]
24
24
  end
25
25
  end
26
26
  end
@@ -0,0 +1,32 @@
1
+ class HecksApplication
2
+ # Looks for the presence of required fields.
3
+ class Validator
4
+ attr_reader :errors
5
+
6
+ def initialize(command:)
7
+ @args = command.args
8
+ @head_spec = command.domain_module.head
9
+ @errors = {}
10
+ end
11
+
12
+ def call
13
+ validate
14
+ return self
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :args, :head_spec
20
+
21
+ def validate
22
+ (missing_attributes).each do |missing_attribute|
23
+ errors[missing_attribute] = []
24
+ errors[missing_attribute] << "missing"
25
+ end
26
+ end
27
+
28
+ def missing_attributes
29
+ head_spec.attribute_hash.keys - args.keys
30
+ end
31
+ end
32
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hecks-application
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.16.rc
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Young
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-15 00:00:00.000000000 Z
11
+ date: 2017-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hecks-domain
@@ -16,31 +16,47 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.16.rc
19
+ version: 0.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.16.rc
26
+ version: 0.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: hecks-memory-database
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.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.2.0
27
41
  description: Hecks Application
28
42
  email: chris@example.com
29
43
  executables: []
30
44
  extensions: []
31
45
  extra_rdoc_files: []
32
46
  files:
33
- - lib/Version
47
+ - lib/command_runner.rb
34
48
  - lib/commands/commands.rb
35
49
  - lib/commands/create.rb
36
50
  - lib/commands/crud_handler.rb
37
51
  - lib/commands/delete.rb
38
- - lib/commands/runner.rb
39
52
  - lib/commands/update.rb
53
+ - lib/events.rb
40
54
  - lib/hecks-application.rb
55
+ - lib/logger.rb
41
56
  - lib/queries/find_by_id.rb
42
57
  - lib/queries/queries.rb
43
58
  - lib/queries/query_runner.rb
59
+ - lib/validator.rb
44
60
  homepage: https://github.com/chrisyoung/hecks-application
45
61
  licenses:
46
62
  - MIT
@@ -56,14 +72,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
56
72
  version: '0'
57
73
  required_rubygems_version: !ruby/object:Gem::Requirement
58
74
  requirements:
59
- - - ">"
75
+ - - ">="
60
76
  - !ruby/object:Gem::Version
61
- version: 1.3.1
77
+ version: '0'
62
78
  requirements: []
63
79
  rubyforge_project:
64
80
  rubygems_version: 2.6.10
65
81
  signing_key:
66
82
  specification_version: 4
67
- summary: Hecks::Application understands things and acts as an interface to Domains
68
- built with Hecks::Domain
83
+ summary: HecksApplication acts as an interface to Domains built with HecksDomain
69
84
  test_files: []
@@ -1 +0,0 @@
1
- 0.1.16.rc
@@ -1,46 +0,0 @@
1
- module Hecks
2
- class Application
3
- class Runner
4
- attr_reader :module_name, :command
5
-
6
- def initialize(command_name:, module_name:, args:, application:)
7
- @command_name = command_name
8
- @module_name = module_name
9
- @args = args
10
- @application = application
11
- @domain_spec = application.domain_spec
12
- end
13
-
14
- def call()
15
- fetch_command
16
- run_command
17
- broadcast
18
- command
19
- end
20
-
21
- private
22
-
23
- attr_reader :command_name, :args, :application, :domain_spec
24
-
25
- def broadcast
26
- application.events_port.send(command: command, module_name: module_name)
27
- end
28
-
29
- def fetch_command
30
- @command = Commands.const_get(command_name.to_s.camelcase).new(
31
- repository: application.database[module_name],
32
- args: args,
33
- domain_module: fetch_module
34
- )
35
- end
36
-
37
- def fetch_module
38
- domain_spec.domain_modules[module_name.to_s.camelize.to_sym]
39
- end
40
-
41
- def run_command
42
- @command = command.call
43
- end
44
- end
45
- end
46
- end