interfacets 0.9.9 → 0.9.99

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.tmp +5 -0
  3. data/Rakefile +4 -0
  4. data/lib/interfacets/client/assets.rb +1 -0
  5. data/lib/interfacets/client/bus.rb +5 -1
  6. data/lib/interfacets/client/channels/api.rb +10 -3
  7. data/lib/interfacets/client/registry.rb +9 -70
  8. data/lib/interfacets/client/utils/mruby_patches.rb +1 -1
  9. data/lib/interfacets/client/utils/open_struct.rb +90 -77
  10. data/lib/interfacets/component_registry.rb +115 -0
  11. data/lib/interfacets/component_schema_parser.rb +84 -0
  12. data/lib/interfacets/server/api.rb +5 -25
  13. data/lib/interfacets/server/assets/facet.rb +5 -3
  14. data/lib/interfacets/server/assets.rb +13 -7
  15. data/lib/interfacets/server/basic_router.rb +15 -10
  16. data/lib/interfacets/server/bus.rb +4 -9
  17. data/lib/interfacets/server/config.rb +1 -1
  18. data/lib/interfacets/server/registry.rb +23 -184
  19. data/lib/interfacets/shared/basic_routable.rb +45 -0
  20. data/lib/interfacets/shared/entities/bus.rb +41 -29
  21. data/lib/interfacets/shared/entities/specs/handlers.rb +16 -0
  22. data/lib/interfacets/shared/entities/specs.rb +46 -9
  23. data/lib/interfacets/shared/entity.rb +23 -99
  24. data/lib/interfacets/shared/entity_dsl.rb +154 -0
  25. data/lib/interfacets/shared/facet.rb +200 -0
  26. data/lib/interfacets/shared/generated_store.rb +6 -2
  27. data/lib/interfacets/shared/utils.rb +1 -1
  28. data/lib/interfacets/shared/validations.rb +5 -1
  29. data/lib/interfacets/{client → shared}/view.rb +33 -6
  30. data/lib/interfacets/test/component_registry.rb +63 -0
  31. data/lib/interfacets/test/js/inline_bus.rb +21 -12
  32. data/lib/interfacets/test/js/nodo_bus.rb +18 -1
  33. data/lib/interfacets/test/js/receivers/api.rb +14 -3
  34. data/lib/interfacets/test/js/receivers/react/node/xml_parser.rb +75 -0
  35. data/lib/interfacets/test/js/receivers/react/node.rb +29 -63
  36. data/lib/interfacets/test/js/receivers/react.rb +4 -3
  37. data/lib/interfacets/test/js/receivers/timer.rb +77 -0
  38. data/lib/interfacets/test/js/receivers/url.rb +5 -0
  39. data/lib/interfacets/test/standard_elements.yml +173 -0
  40. data/lib/interfacets/test/{browser.rb → ui_simulator.rb} +18 -6
  41. data/lib/interfacets/test/validation_engine.rb +151 -0
  42. data/lib/interfacets/test.rb +0 -4
  43. data/lib/interfacets/version.rb +1 -1
  44. data/lib/interfacets.rb +3 -0
  45. metadata +29 -18
  46. data/lib/interfacets/client/facet.rb +0 -26
  47. data/lib/interfacets/client/facet2.rb +0 -15
  48. data/lib/interfacets/client/facets/attributes/accessor.rb +0 -28
  49. data/lib/interfacets/client/facets/attributes/association.rb +0 -50
  50. data/lib/interfacets/client/facets/attributes/bind.rb +0 -25
  51. data/lib/interfacets/client/facets/attributes/collection.rb +0 -47
  52. data/lib/interfacets/client/facets/attributes/readonly.rb +0 -19
  53. data/lib/interfacets/client/facets/deserializer.rb +0 -30
  54. data/lib/interfacets/client/facets/schema/deserializer.rb +0 -63
  55. data/lib/interfacets/client/facets/schema.rb +0 -63
  56. data/lib/interfacets/client/facets/serializer.rb +0 -18
  57. data/lib/interfacets/server/basic_routable.rb +0 -40
  58. data/lib/interfacets/server/facet.rb +0 -51
  59. data/lib/interfacets/shared/entity_collection.rb +0 -88
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json_schemer"
4
+ require "set"
5
+ require "yaml"
6
+
7
+ module Interfacets
8
+ module Test
9
+ class ValidationEngine
10
+ attr_reader :registry, :validation_mode
11
+
12
+ @warned_components = Set.new
13
+
14
+ def self.warned_components
15
+ @warned_components
16
+ end
17
+
18
+ def self.reset_warnings!
19
+ @warned_components.clear
20
+ end
21
+
22
+ def initialize(registry = ComponentRegistry.load, validation_mode: :strict)
23
+ @registry = registry
24
+ @validation_mode = validation_mode
25
+ end
26
+
27
+ def active?
28
+ registry.contracts.any?
29
+ end
30
+
31
+ def validate_props(component_name, props)
32
+ return unless active?
33
+
34
+ contract = registry.find_component(component_name)
35
+ is_standard = standard_element?(component_name)
36
+
37
+ props_config = contract&.dig("props")
38
+
39
+ if is_standard
40
+ return unless props_config
41
+ else
42
+ return unless contract_exists?(component_name)
43
+
44
+ raise ValidationError, "Missing props schema for custom component: #{component_name}" unless props_config
45
+ end
46
+
47
+ schema = { "type" => "object", "properties" => props_config }
48
+ validate!(schema, props, "properties for #{component_name}")
49
+ end
50
+
51
+ def validate_event(component_name, event_name, payload)
52
+ return unless active?
53
+
54
+ contract = registry.find_component(component_name)
55
+ is_standard = standard_element?(component_name)
56
+
57
+ event_config = contract&.dig("props", event_name.to_s)
58
+
59
+ if is_standard
60
+ return unless event_config
61
+ else
62
+ return unless contract_exists?(component_name)
63
+
64
+ raise ValidationError, "Missing events schema for custom component: #{component_name}" unless contract.key?("props")
65
+ raise ValidationError, "Missing event schema for '#{event_name}' in custom component: #{component_name}" unless event_config
66
+ end
67
+
68
+ schema = event_config.is_a?(Hash) ? (event_config["payload"] || {}) : {}
69
+
70
+ validate!(schema, payload, "event '#{event_name}' for #{component_name}")
71
+ end
72
+
73
+ private
74
+
75
+ def standard_element?(component_name)
76
+ @standard_elements ||= begin
77
+ yaml_path = File.expand_path("standard_elements.yml", __dir__)
78
+ Set.new(YAML.load_file(yaml_path).map(&:to_s))
79
+ end
80
+ @standard_elements.include?(component_name.to_s)
81
+ end
82
+
83
+ def contract_exists?(component_name)
84
+ contract = registry.find_component(component_name)
85
+ return true if contract
86
+
87
+ case validation_mode
88
+ when :strict
89
+ raise MissingComponentContractError, "Missing component contract for: #{component_name}"
90
+ when :warn
91
+ unless self.class.warned_components.include?(component_name)
92
+ warn "Warning: Missing component contract for: #{component_name}"
93
+ self.class.warned_components << component_name
94
+ end
95
+ false
96
+ when :permissive
97
+ false
98
+ else
99
+ raise ArgumentError, "Unknown validation_mode: #{validation_mode}"
100
+ end
101
+ end
102
+
103
+ def find_contract!(name)
104
+ contract = registry.find_component(name)
105
+ return contract if contract
106
+
107
+ raise MissingComponentContractError, "Missing component contract for: #{name}"
108
+ end
109
+
110
+ def validate!(schema, data, context)
111
+ full_schema = schema.dup
112
+ if full_schema["type"] == "object" && !full_schema.key?("additionalProperties")
113
+ full_schema["additionalProperties"] = false
114
+ end
115
+ full_schema["definitions"] = registry.definitions if registry.definitions.any?
116
+
117
+ schemer = JSONSchemer.schema(full_schema, keywords: {
118
+ "is_event" => lambda do |instance, keyword_value, pointer|
119
+ return true unless keyword_value
120
+ unless instance.is_a?(Hash) && instance.key?("type") && instance.key?("payload")
121
+ return [false, "missing 'type' or 'payload'"]
122
+ end
123
+
124
+ prop_name = pointer.split("/").last
125
+ prop_schema = full_schema.dig("properties", prop_name)
126
+ if prop_schema && (nested_schema = prop_schema["schema"])
127
+ nested_schemer = JSONSchemer.schema(nested_schema)
128
+ nested_errors = nested_schemer.validate(instance["payload"]).to_a
129
+ if nested_errors.any?
130
+ return [false, "event payload validation failed: #{nested_errors.map { |e| "#{e['data_pointer']}: #{e['type']} #{e['details']}" }.join(', ')}"]
131
+ end
132
+ end
133
+
134
+ true
135
+ end
136
+ })
137
+
138
+ errors = schemer.validate(data).to_a
139
+
140
+ return if errors.empty?
141
+
142
+ message = "Validation failed for #{context}:\n"
143
+ errors.each do |error|
144
+ message += " - #{error['data_pointer']}: #{error['type']} #{error['details']}\n"
145
+ end
146
+
147
+ raise ValidationError, message
148
+ end
149
+ end
150
+ end
151
+ end
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # require_relative "./test/session"
4
- # require_relative "./test/js"
5
- # require_relative "./test/js/channels"
6
-
7
3
  module Interfacets
8
4
  module Test
9
5
  module H
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Interfacets
4
- VERSION = "0.9.9"
4
+ VERSION = "0.9.99"
5
5
  end
data/lib/interfacets.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "zeitwerk"
4
+ require "active_support/concern"
4
5
 
5
6
  module Interfacets
6
7
  class << self
@@ -25,6 +26,8 @@ module Interfacets
25
26
  end
26
27
 
27
28
  class Error < StandardError; end
29
+ class ValidationError < Error; end
30
+ class MissingComponentContractError < Error; end
28
31
  end
29
32
 
30
33
  unless Interfacets.enable_reloading?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: interfacets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.9
4
+ version: 0.9.99
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pete Kinnecom
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-01-24 00:00:00.000000000 Z
11
+ date: 2026-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: json_schemer
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
41
55
  description:
42
56
  email:
43
57
  - git@k7u7.com
@@ -46,6 +60,7 @@ extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
48
62
  - ".rubocop.yml"
63
+ - ".tmp"
49
64
  - LICENSE
50
65
  - LICENSE.txt
51
66
  - Rakefile
@@ -67,24 +82,14 @@ files:
67
82
  - lib/interfacets/client/channels/url.rb
68
83
  - lib/interfacets/client/config.rb
69
84
  - lib/interfacets/client/delegator.rb
70
- - lib/interfacets/client/facet.rb
71
- - lib/interfacets/client/facet2.rb
72
- - lib/interfacets/client/facets/attributes/accessor.rb
73
- - lib/interfacets/client/facets/attributes/association.rb
74
- - lib/interfacets/client/facets/attributes/bind.rb
75
- - lib/interfacets/client/facets/attributes/collection.rb
76
- - lib/interfacets/client/facets/attributes/readonly.rb
77
- - lib/interfacets/client/facets/deserializer.rb
78
- - lib/interfacets/client/facets/schema.rb
79
- - lib/interfacets/client/facets/schema/deserializer.rb
80
- - lib/interfacets/client/facets/serializer.rb
81
85
  - lib/interfacets/client/registry.rb
82
86
  - lib/interfacets/client/system.rb
83
87
  - lib/interfacets/client/utils/active_support_concern.rb
84
88
  - lib/interfacets/client/utils/mruby_patches.rb
85
89
  - lib/interfacets/client/utils/open_struct.rb
86
90
  - lib/interfacets/client/utils/securerandom.rb
87
- - lib/interfacets/client/view.rb
91
+ - lib/interfacets/component_registry.rb
92
+ - lib/interfacets/component_schema_parser.rb
88
93
  - lib/interfacets/mruby/build.dockerfile
89
94
  - lib/interfacets/mruby/build_config.rb
90
95
  - lib/interfacets/mruby/entrypoint.rb
@@ -92,32 +97,38 @@ files:
92
97
  - lib/interfacets/server/api.rb
93
98
  - lib/interfacets/server/assets.rb
94
99
  - lib/interfacets/server/assets/facet.rb
95
- - lib/interfacets/server/basic_routable.rb
96
100
  - lib/interfacets/server/basic_router.rb
97
101
  - lib/interfacets/server/bus.rb
98
102
  - lib/interfacets/server/config.rb
99
- - lib/interfacets/server/facet.rb
100
103
  - lib/interfacets/server/facets/deserializer.rb
101
104
  - lib/interfacets/server/facets/schema/serializer.rb
102
105
  - lib/interfacets/server/facets/serializer.rb
103
106
  - lib/interfacets/server/registry.rb
107
+ - lib/interfacets/shared/basic_routable.rb
104
108
  - lib/interfacets/shared/entities/bus.rb
105
109
  - lib/interfacets/shared/entities/collection_proxy.rb
106
110
  - lib/interfacets/shared/entities/specs.rb
107
111
  - lib/interfacets/shared/entities/specs/handlers.rb
108
112
  - lib/interfacets/shared/entity.rb
109
- - lib/interfacets/shared/entity_collection.rb
113
+ - lib/interfacets/shared/entity_dsl.rb
114
+ - lib/interfacets/shared/facet.rb
110
115
  - lib/interfacets/shared/generated_store.rb
111
116
  - lib/interfacets/shared/utils.rb
112
117
  - lib/interfacets/shared/validations.rb
118
+ - lib/interfacets/shared/view.rb
113
119
  - lib/interfacets/test.rb
114
- - lib/interfacets/test/browser.rb
120
+ - lib/interfacets/test/component_registry.rb
115
121
  - lib/interfacets/test/js/inline_bus.rb
116
122
  - lib/interfacets/test/js/nodo_bus.rb
117
123
  - lib/interfacets/test/js/receivers/api.rb
118
124
  - lib/interfacets/test/js/receivers/react.rb
119
125
  - lib/interfacets/test/js/receivers/react/node.rb
126
+ - lib/interfacets/test/js/receivers/react/node/xml_parser.rb
127
+ - lib/interfacets/test/js/receivers/timer.rb
120
128
  - lib/interfacets/test/js/receivers/url.rb
129
+ - lib/interfacets/test/standard_elements.yml
130
+ - lib/interfacets/test/ui_simulator.rb
131
+ - lib/interfacets/test/validation_engine.rb
121
132
  - lib/interfacets/version.rb
122
133
  homepage: https://github.com/petekinnecom/interfacets
123
134
  licenses:
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Interfacets
4
- module Client
5
- class Facet
6
- class << self
7
- attr_accessor(
8
- :shared,
9
- :entity,
10
- :view,
11
- :store,
12
- )
13
- end
14
-
15
- attr_reader :entity, :view
16
- def initialize(entity)
17
- @entity = entity
18
- @view = self.class.view.new
19
- end
20
-
21
- def render(channels)
22
- view.render(entity:, channels:)
23
- end
24
- end
25
- end
26
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Interfacets
4
- module Client
5
- class Facet2
6
- class << self
7
- attr_accessor(
8
- :shared_entity,
9
- :entity,
10
- :view
11
- )
12
- end
13
- end
14
- end
15
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Interfacets
4
- module Client
5
- module Facets
6
- module Attributes
7
- class Accessor
8
- attr_reader :send_if
9
- def initialize(send_if:)
10
- @send_if = send_if
11
- end
12
-
13
- def coerce(val, **)
14
- val
15
- end
16
-
17
- def serialize(val)
18
- val
19
- end
20
-
21
- def should_send?(facet)
22
- facet.instance_exec(&send_if)
23
- end
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Interfacets
4
- module Client
5
- module Facets
6
- module Attributes
7
- class Association
8
- attr_reader :nested, :anonymous, :config, :bind_map
9
-
10
- def initialize(nested:, anonymous:, config:, bind_map:)
11
- @nested = nested
12
- @anonymous = anonymous
13
- @config = config
14
- @bind_map = bind_map
15
- end
16
-
17
- def coerce(val, parent:)
18
- return if val.nil?
19
-
20
- facet.build(
21
- attrs: val,
22
- binds: bind_map.transform_values { |v| Bind.new(name: v, facet: parent) },
23
- )
24
- end
25
-
26
- def build(attrs:, parent:)
27
- facet.build(
28
- attrs:,
29
- binds: bind_map.transform_values { |v| Bind.new(name: v, facet: parent) },
30
- )
31
- end
32
-
33
- def serialize(val)
34
- val&.serialize
35
- end
36
-
37
- def facet
38
- @facet ||= (
39
- if anonymous
40
- @nested
41
- else
42
- config.schema(@nested.fetch("name"))
43
- end
44
- )
45
- end
46
- end
47
- end
48
- end
49
- end
50
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Interfacets
4
- module Client
5
- module Facets
6
- module Attributes
7
- class Bind
8
- attr_reader :name, :facet
9
- def initialize(name:, facet:)
10
- @name = name
11
- @facet = facet
12
- end
13
-
14
- def get
15
- facet.public_send(name)
16
- end
17
-
18
- def set(v)
19
- facet.public_send("#{name}=", v)
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Interfacets
4
- module Client
5
- module Facets
6
- module Attributes
7
- class Collection
8
- attr_reader :nested, :anonymous, :config, :bind_map
9
-
10
- def initialize(nested:, anonymous:, config:, bind_map:)
11
- @nested = nested
12
- @anonymous = anonymous
13
- @config = config
14
- @bind_map = bind_map
15
- end
16
-
17
- def coerce(val, parent:)
18
- return [] if val.nil?
19
-
20
- val.map { build(attrs: _1, parent:) }
21
- end
22
-
23
- def build(attrs:, parent:)
24
- facet.build(
25
- attrs:,
26
- binds: bind_map.transform_values { |v| Bind.new(name: v, facet: parent) },
27
- )
28
- end
29
-
30
- def serialize(val)
31
- val.map(&:serialize)
32
- end
33
-
34
- def facet
35
- @facet ||= (
36
- if anonymous
37
- @nested
38
- else
39
- config.schema(@nested.fetch("name"))
40
- end
41
- )
42
- end
43
- end
44
- end
45
- end
46
- end
47
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Interfacets
4
- module Client
5
- module Facets
6
- module Attributes
7
- class Readonly
8
- def coerce(val, **)
9
- val
10
- end
11
-
12
- def serialize(val)
13
- val
14
- end
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Interfacets
4
- module Client
5
- module Facets
6
- class Deserializer
7
- def self.call(data:, config: Client.system.config)
8
- Logger.main.debug("deserializing facet: #{data.fetch("facet_class")}")
9
-
10
- klass = Object.const_get(data.fetch("facet_class"))
11
-
12
- Logger.main.debug("constructing: #{klass.client.name}")
13
-
14
- facet = klass.new
15
-
16
- entity = (
17
- klass
18
- .client
19
- .build(data.fetch("attributes"), parent: nil, facet:)
20
- )
21
-
22
- Logger.main.debug("entity constructed")
23
-
24
- facet.entity = entity
25
- facet
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,63 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Interfacets
4
- module Client
5
- module Facets
6
- module Schema
7
- class Deserializer
8
- def self.call(...)
9
- new(...).call
10
- end
11
-
12
- attr_reader :schema, :results
13
- def initialize(schema:)
14
- @schema = schema
15
- @results = { views: {}, entities: {}, apis: {} }
16
- end
17
-
18
- def call
19
- schema.fetch("views").each do |view_type, view_json|
20
- block = view_json.fetch("body")
21
-
22
- results[:views][view_type] = View.new(
23
- block: eval(block),
24
- name: view_type,
25
- )
26
- end
27
-
28
- schema.fetch("apis").each do |api_type, entity_json|
29
- block = entity_json.fetch("body")
30
-
31
- results[:apis][api_type] =
32
- Module.new do
33
- extend ActiveSupport::Concern
34
- define_singleton_method(:name) { api_type }
35
-
36
- included do
37
- class_exec(&eval(block))
38
- end
39
- end
40
- end
41
-
42
- schema.fetch("entities").each do |entity_type, client_json|
43
- block = client_json.fetch("body")
44
- api_type = client_json.fetch("api_type")
45
-
46
- api_mod = results[:apis].fetch(api_type)
47
-
48
- results[:entities][entity_type] =
49
- Class.new(Entity) do
50
- define_singleton_method(:name) { entity_type }
51
- include api_mod
52
-
53
- class_exec(&eval(block))
54
- end
55
- end
56
-
57
- results
58
- end
59
- end
60
- end
61
- end
62
- end
63
- end
@@ -1,63 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Interfacets
4
- module Client
5
- module Facets
6
- module Schema
7
- extend ActiveSupport::Concern
8
- class_methods do
9
- def view_spec(&block)
10
- @view_spec = block
11
- end
12
-
13
- def view
14
- # TODO: change this to just inherit from view
15
- @view ||= View.new(
16
- block: @view_spec,
17
- name: "#{self.name}::View",
18
- )
19
- end
20
-
21
- def client_spec(&block)
22
- @client_spec = block
23
- end
24
-
25
- def client
26
- # scoping
27
- client_name = "#{self.name}::Client"
28
- client_spec = @client_spec
29
- entity = self.entity
30
-
31
- @client ||=
32
- Class.new(Entity) do
33
- define_singleton_method(:name) { client_name }
34
- extend_entity { include entity }
35
-
36
- class_exec(&client_spec)
37
- end
38
- end
39
-
40
- def entity_spec(&block)
41
- @entity_spec = block
42
- end
43
-
44
- def entity
45
- # scoping
46
- entity_name = "#{self.name}::Entity"
47
- entity_spec = @entity_spec
48
-
49
- @entity ||=
50
- Module.new do
51
- extend ActiveSupport::Concern
52
- define_singleton_method(:name) { entity_name }
53
-
54
- included do
55
- class_exec(&entity_spec)
56
- end
57
- end
58
- end
59
- end
60
- end
61
- end
62
- end
63
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Interfacets
4
- module Client
5
- module Facets
6
- class Serializer
7
- class << self
8
- def call(facet)
9
- {
10
- facet_class: facet.class.name,
11
- attributes: facet.entity.serialize,
12
- }
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end