payload-translator 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 02ed271a4ef7404262e5cd5379853e948470c28d515d0e4f7ef2bbe7e05bc401
4
+ data.tar.gz: 07ca8129f964945d42f033426fb90646560516ddfdfbdc73db0efc131f537605
5
+ SHA512:
6
+ metadata.gz: fb0b462ede9e4bd3b68381a4e08ce963d4f685761e2b35d4871cbb84423511eeaebdf391f8c6055a0aa10649de0cebebeeafad51bfcdada0e2bf7b68615c0f97
7
+ data.tar.gz: 59b5335db5bbebeb535e31cdf6c1caec6c4e9464963e2d9a0ea72d1c4dd27221a6ae25b54cd451e6e37ad4845752a6f6ab8edbfc207321f02f5c8dd4c1905b06
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Miguel Savignano
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,88 @@
1
+ ## Payload translator
2
+
3
+ Using a yaml configuration you can transform a payload to another payload.
4
+ Example:
5
+
6
+ ```yaml
7
+ # config.yaml
8
+ payload:
9
+ id:
10
+ $field: _id
11
+ $formatter: to_integer
12
+ user_name:
13
+ $field: name
14
+ login_type:
15
+ $field: login_provider
16
+ $map:
17
+ google: GOOGLE
18
+ twitter: TWITTER
19
+ auth0: APP
20
+ country:
21
+ $fnc: get_country
22
+ ```
23
+
24
+ Input:
25
+
26
+ ```json
27
+ // internal_payload.json
28
+
29
+ {
30
+ "_id": 1,
31
+ "name": "Jhon Doe",
32
+ "login_provider": "auth0"
33
+ }
34
+ ```
35
+
36
+ ```ruby
37
+ translator = PayloadTranslator::Service.new(config)
38
+ external_payload = translator.translate(internal_payload)
39
+ ```
40
+
41
+ Return:
42
+
43
+ ```json
44
+ // external_payload.json
45
+
46
+ {
47
+ "id": "1",
48
+ "user_name": "Jhon Doe",
49
+ "login_type": "APP"
50
+ }
51
+ ```
52
+
53
+ ## Configure handlers
54
+
55
+ Resolve the field output with a custom function.
56
+
57
+ ```ruby
58
+ PayloadTranslator.configure do |config|
59
+ config.handlers = {
60
+ get_country: ->(payload) { payload['name'] },
61
+ }
62
+ end
63
+ ```
64
+
65
+ Or per service
66
+
67
+ ```ruby
68
+ PayloadTranslator::Service(config, handlers: get_country: ->(payload) { payload['name'] })
69
+ ```
70
+
71
+ ## Configure formatters
72
+
73
+ Apply different formatters to the output.
74
+
75
+ ```ruby
76
+ PayloadTranslator.configure do |config|
77
+ config.formatters = {
78
+ uppercase: ->(value) { value.upcase },
79
+ to_integer: ->(value) { value.to_i },
80
+ }
81
+ end
82
+ ```
83
+
84
+ Or formatter per service
85
+
86
+ ```ruby
87
+ PayloadTranslator::Service(config, formatters: to_integer: ->(value) { value.to_i })
88
+ ```
@@ -0,0 +1,22 @@
1
+ module PayloadTranslator
2
+ class Config
3
+ attr_reader :handlers, :formatters, :adapters_configurations
4
+ def initialize
5
+ @handlers = {}
6
+ @formatters = {}
7
+ @adapters_configurations = {}
8
+ end
9
+
10
+ def handlers=(value)
11
+ @handlers.merge!(value)
12
+ end
13
+
14
+ def adapters_configurations=(value)
15
+ @adapters_configurations.merge!(value)
16
+ end
17
+
18
+ def formatters=(value)
19
+ @formatters.merge!(value)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,90 @@
1
+ module PayloadTranslator
2
+ class FieldResolver
3
+ attr_reader :config, :handlers, :formatters, :configuration, :payload
4
+
5
+ def initialize(field_config, configuration)
6
+ @configuration = configuration
7
+ @handlers = configuration.handlers
8
+ @formatters = configuration.formatters
9
+ @config = field_config
10
+ end
11
+
12
+ def resolve(payload)
13
+ @payload = payload
14
+ if deep_object?
15
+ resolve_deep_object
16
+ elsif config["$fnc"]
17
+ resolve_fnc
18
+ elsif config["$map"]
19
+ resolve_map
20
+ else
21
+ resolve_value
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def resolve_value
28
+ with_formatter do
29
+ search_value(fetch_field)
30
+ end
31
+ end
32
+
33
+ def resolve_fnc
34
+ call_fnc(config.fetch("$fnc"))
35
+ end
36
+
37
+ def resolve_map
38
+ value = search_value(fetch_field)
39
+ if config["$map_formatter"]
40
+ fotmatter = formatters.fetch(config["$map_formatter"].to_sym)
41
+ value = fotmatter.call(value)
42
+ end
43
+
44
+ config["$map"].fetch(value) { config["$map_default"] }
45
+ end
46
+
47
+ def resolve_deep_object
48
+ config.each_with_object({}) do |(target_name, field_config), result|
49
+ result[target_name] = FieldResolver.new(field_config, configuration).resolve(payload)
50
+ end
51
+ end
52
+
53
+ def search_value(field_or_fields)
54
+ if field_or_fields.is_a?(Array)
55
+ field = field_or_fields.find { |field| payload[field] }
56
+ payload.fetch(field) { config["$default"] }
57
+ else
58
+ payload.fetch(field_or_fields) { config["$default"] }
59
+ end
60
+ end
61
+
62
+ def with_formatter
63
+ return yield unless config["$formatter"]
64
+ formatter = formatters.fetch(config["$formatter"].to_sym)
65
+ formatter.call(yield)
66
+ end
67
+
68
+ def fetch_field
69
+ config.fetch("$field") do
70
+ call_fnc(config.fetch("$field_fnc"))
71
+ end
72
+ end
73
+
74
+ def call_fnc(name)
75
+ handler = handlers.fetch(name.to_sym)
76
+ case handler.arity
77
+ when 0
78
+ handler.call
79
+ when 1
80
+ handler.call(payload)
81
+ when 2
82
+ handler.call(payload, config)
83
+ end
84
+ end
85
+
86
+ def deep_object?
87
+ !config.keys.any? {|key| key =~ /\$/ }
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,31 @@
1
+ module PayloadTranslator
2
+ class Service
3
+ attr_reader :adapt_config, :configuration
4
+
5
+ def initialize(adapter_config_or_name, handlers: {}, formatters: {})
6
+ @configuration = merge_configuration(handlers: handlers, formatters: formatters)
7
+ @adapt_config = fetch_adapter_config(adapter_config_or_name)
8
+ end
9
+
10
+ def merge_configuration(handlers: , formatters:)
11
+ PayloadTranslator::Config.new.tap do |config|
12
+ config.handlers = PayloadTranslator.configuration.handlers.merge(handlers)
13
+ config.formatters = PayloadTranslator.configuration.formatters.merge(formatters)
14
+ end
15
+ end
16
+
17
+ def translate(payload)
18
+ adapt_config["payload"].each_with_object({}) do |(target_name, field_config), result|
19
+ result[target_name] = FieldResolver.new(field_config, configuration).resolve(payload)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def fetch_adapter_config(adapter_config_or_name)
26
+ return adapter_config_or_name if adapter_config_or_name.is_a?(Hash)
27
+
28
+ PayloadTranslator.configuration.adapters_configurations.fetch(adapter_config_or_name)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,17 @@
1
+ require "zeitwerk"
2
+
3
+ loader = Zeitwerk::Loader.for_gem
4
+ loader.setup
5
+
6
+ module PayloadTranslator
7
+ def self.configuration
8
+ @@config ||= Config.new
9
+ end
10
+
11
+ def self.configure
12
+ yield(configuration)
13
+ configuration
14
+ end
15
+
16
+ VERSION = "0.1.0"
17
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: payload-translator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Miguel Savignano
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-04-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: zeitwerk
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
+ description: Use configuration to transform a payload to another payload
28
+ email: migue.masx@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - LICENSE
34
+ - README.md
35
+ - lib/payload_translator.rb
36
+ - lib/payload_translator/config.rb
37
+ - lib/payload_translator/field_resolver.rb
38
+ - lib/payload_translator/service.rb
39
+ homepage: https://github.com/devmasx/payload-translator
40
+ licenses:
41
+ - MIT
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.7.11
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: PayloadTranslator
63
+ test_files: []