power-compass 0.3.1 → 0.4.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
  SHA256:
3
- metadata.gz: c873e63a81792879a36683624858b32b9a02279786b36c37a6c64fc3ccfa1b0f
4
- data.tar.gz: 2a43d082daaf8d7e0a758f9a71637458955a3c3b8a7aac74242f3d32d8be5ebc
3
+ metadata.gz: 92964d0bc95b3089f4e105800d24841f977eff9926bb711426139c5a41ef478b
4
+ data.tar.gz: b3035664afbd00d81063828910c177da1b0203110953401c493fc8660294561b
5
5
  SHA512:
6
- metadata.gz: 461e8ad448d14598e7ad037be842a560c771796107265a23608e265f59fcb50bb7b4558949d6a6f941fcf0f1db829c3f6e4a6a4cf4c5e1c7ce2583f10ecb5e26
7
- data.tar.gz: 87912b60c754bc176734a71ed37b107d1928fe20f5f37f686a3e0ad5c56e5d41fb539ca47d88bda5ba32f01099f0708f762ebe2cf2b4c2fc562e2c07f751c9bd
6
+ metadata.gz: 323ab2d69ef15f35515468721e9d96a9b86da4e0bb60e07f668b23d32088b5c6ef2f220ca1e6d02d8765fc67679fc93dd18b2e375078b815bc924d6c88c02678
7
+ data.tar.gz: 3cd5ecb57888a3323586d57f213095b4c256ba54fb6069ebd5197bb7313513b5b26d839d09a35fd477efad86a4a853cd97b2574f8637cb5011500e4c7327e7bc
@@ -15,7 +15,7 @@ module Compass
15
15
  private
16
16
 
17
17
  def providers
18
- @providers ||= Compass::Notification::Provider.global_notifications(current_context)
18
+ @providers ||= Compass::Notification.build(current_context)
19
19
  end
20
20
  end
21
21
  end
@@ -0,0 +1,100 @@
1
+ module Compass
2
+ # Formats an object into a JSON hash.
3
+ # @private
4
+ module JsonFormatter
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ class_attribute :_json_formatter, default: nil
9
+ end
10
+
11
+ class_methods do
12
+ # Formats an object into a JSON hash.
13
+ #
14
+ # @example
15
+ #
16
+ # class Service
17
+ # include Compass::JsonFormatter
18
+ #
19
+ # format :name, :email
20
+ # end
21
+ #
22
+ # class ServiceProvider < Service
23
+ # format do
24
+ # name &:name
25
+ # email &:email
26
+ # end
27
+ # end
28
+ #
29
+ # User < Struct.new(:name, :email)
30
+ # ServiceProvider.new.format(User.new("John Doe", "john.doe@example.com")) => { name: "John Doe", email: "john.doe@example.com" }
31
+ #
32
+ # A service provider can also default some format attribute by defining the method:
33
+ #
34
+ # class ServiceProvider < Service
35
+ # format do
36
+ # name &:name
37
+ # end
38
+ #
39
+ # def email = "john.doe@example.com"
40
+ # end
41
+ #
42
+ # ServiceProvider.new.format(User.new("John Doe")) => { name: "John Doe", email: "john.doe@example.com" }
43
+ #
44
+ # @param attrs [Array] the attributes to format
45
+ # @param attr_options [Hash] the options for the attributes
46
+ # @private
47
+ def format(*attrs, **attr_options)
48
+ self._json_formatter = Formatter.new(attrs + attr_options.keys, attr_options)
49
+ define_singleton_method(:format) do |obj = nil, &block|
50
+ raise ArgumentError, "Format must be defined for provider #{self.class}" if obj
51
+
52
+ self._json_formatter&.instance_eval(&block)
53
+
54
+ define_method(:format) do |object|
55
+ self._json_formatter&.to_h(self, object)
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ # Formats an object into a JSON hash.
62
+ # @private
63
+ class Formatter
64
+ # Initializes a new Formatter.
65
+ #
66
+ # @param attrs [Array] the attributes to format
67
+ # @param attr_options [Hash] the options for the attributes
68
+ def initialize(attrs, attr_options)
69
+ @attrs = attrs.index_with { nil }
70
+ @attr_options = attr_options
71
+ attrs.each do |attr|
72
+ define_singleton_method(attr) do |&block|
73
+ @attrs[attr] = block
74
+ end
75
+ end
76
+ end
77
+
78
+ # Formats an object into a ruby hash.
79
+ # @param service [Object] the service requesting the formatting of obj
80
+ # @param obj [Object] the object to format
81
+ # @return [Hash] the formatted hash
82
+ def to_h(service, obj)
83
+ Hash[@attrs.map do |method, formatter|
84
+ value = formatter ? formatter.call(obj) : service.try(method)
85
+ validate!(method, value)
86
+
87
+ [ method, value ]
88
+ end].compact
89
+ end
90
+
91
+ private
92
+
93
+ def validate!(method, value)
94
+ if value.blank? && @attr_options[method].eql?(:required)
95
+ raise ArgumentError, "#{self.class}#format must include :#{method}. Got: #{value.inspect}"
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -1,31 +1,10 @@
1
1
  module Compass
2
2
  module Notification
3
- class UnknownProvider < StandardError
4
- attr_reader :provider_name, :available_providers
5
-
6
- def initialize(provider_name, available_providers)
7
- @provider_name = provider_name
8
- @available_providers = available_providers
9
- super("Notification provider '#{provider_name}' not found")
10
- end
11
- end
12
-
13
3
  class Provider
14
- class << self
15
- def global_notifications(context = {})
16
- Compass.config.notification.providers.map do |provider|
17
- begin
18
- provider_class = provider.try(:constantize) || provider
19
- provider_class.new(**context)
20
- rescue => e
21
- Compass.logger&.error("[ Compass::Notification::Provider ] #{provider}: #{e.class}: #{e.message}")
22
- nil
23
- end
24
- end
25
- end
26
- end
4
+ include Compass::JsonFormatter
5
+
6
+ format :icon, :color, id: :required, title: :required, body: :required, url: :required, date: :required
27
7
 
28
- # Instance methods
29
8
  def initialize(**context)
30
9
  @context = context
31
10
  context.each { |key, value| define_singleton_method(key) { value } }
@@ -35,43 +14,30 @@ module Compass
35
14
  notifications.pluck(:id).hash
36
15
  end
37
16
 
38
- def fetch_notifications
39
- retrieve_notifications
17
+ def notifications
18
+ @notifications ||= Array(fetch).map { |notification| format(notification) }
40
19
  rescue => e
41
20
  log_error(e)
42
21
  []
43
22
  end
44
23
 
45
- def retrieve_notifications
46
- raise NotImplementedError, "#{self.class} must implement #retrieve_notifications"
47
- end
48
-
49
- def format_notification(notification)
50
- raise NotImplementedError, "#{self.class} must implement #format_notification and return a hash with :id, :title, :body, and :url keys"
51
- end
24
+ def fetch = must_implement(:fetch)
52
25
 
53
- def label
54
- raise NotImplementedError, "#{self.class} must implement #label"
55
- end
26
+ def label = must_implement(:label)
56
27
 
57
- def updated_at
58
- raise NotImplementedError, "#{self.class} must implement #updated_at"
59
- end
28
+ def updated_at = must_implement(:updated_at)
60
29
 
61
30
  def as_json(options = {})
62
31
  {
63
32
  label: label,
64
33
  notifications: notifications
65
- }
34
+ }.compact.as_json(options)
66
35
  end
67
36
 
68
37
  private
69
38
 
70
- def notifications
71
- @notifications ||= Array(fetch_notifications).map do |notification|
72
- formatted = format_notification(notification)
73
- formatted[:id] ? formatted : raise(ArgumentError, "#{self.class}#format_notification must include :id. Got: #{formatted.inspect}")
74
- end.compact
39
+ def must_implement(method)
40
+ raise NotImplementedError, "#{self.class} must implement ##{method}"
75
41
  end
76
42
 
77
43
  def log_error(error)
@@ -1,5 +1,19 @@
1
1
  module Compass
2
2
  module Notification
3
3
  autoload :Provider, "compass/notification/provider"
4
+
5
+ # Returns all notification providers for the given context.
6
+ #
7
+ # @param context [Hash] the context to pass to the notification providers
8
+ # @return [Array<Compass::Notification::Provider>] the notification providers
9
+ def self.build(context)
10
+ Compass.config.notification.providers.filter_map do |provider|
11
+ provider_class = provider.try(:constantize) || provider
12
+ provider_class.new(**context)
13
+ rescue => e
14
+ Compass.logger&.error("[ Compass::Notification::Provider ] #{provider}: #{e.class}: #{e.message}")
15
+ nil
16
+ end
17
+ end
4
18
  end
5
19
  end
@@ -1,3 +1,3 @@
1
1
  module Compass
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/compass.rb CHANGED
@@ -14,6 +14,7 @@ module Compass
14
14
  autoload :Notification, "compass/notification"
15
15
  autoload :Breadcrumb, "compass/breadcrumb"
16
16
  autoload :LazyAttribute, "compass/lazy_attribute"
17
+ autoload :JsonFormatter, "compass/json_formatter"
17
18
 
18
19
  include Compass::Configuration
19
20
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: power-compass
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carlos Palhares
@@ -108,6 +108,7 @@ files:
108
108
  - lib/compass/configuration/notification.rb
109
109
  - lib/compass/configuration/search.rb
110
110
  - lib/compass/engine.rb
111
+ - lib/compass/json_formatter.rb
111
112
  - lib/compass/lazy_attribute.rb
112
113
  - lib/compass/menu.rb
113
114
  - lib/compass/menu/item.rb