attributes-mapper 0.1.0 → 0.1.2
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 +4 -4
- data/README.md +34 -3
- data/dev/setup.rb +1 -0
- data/lib/attributes-mapper/builder.rb +67 -0
- data/lib/attributes-mapper/version.rb +1 -1
- data/lib/attributes_mapper.rb +4 -0
- data/spec/attributes-mapper/builder_spec.rb +66 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4de21050a409102a97ed7a57ad9a4e3e407ae1c9236ee12bcf56ba065df09674
|
4
|
+
data.tar.gz: aa2537d23e5d13baa679133e50d046992a2a31a2b5abdd3ebad5ec1be5b6e745
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 804ff034798b639ba1c8cc522df79ecdfafa4403ef4fd320c626db053367d6da846dceecc56449197b20fda7cc6dda1b00fbc91e6cdf230c0804ea0ff757d9ca
|
7
|
+
data.tar.gz: 4aadd98e8b6d7e7caaaf4a741eb59231612770a733408d9a98ee064bc561d00d3c50ffc6ba2c723277d64d017f831c4fe5dcf26df8a5c3d2be84a14fc7e426b2
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# AttributesMapper
|
2
2
|
|
3
|
-
|
3
|
+
Builds upon `[json-path-builder](https://github.com/omnitech-solutions/json-path-builder)` to deliver a highly declarative and dynamic mapping of JSON/Hash Attributes
|
4
4
|
|
5
|
-
|
5
|
+
## Console
|
6
|
+
run `irb -r ./dev/setup` for an interactive prompt.
|
6
7
|
|
7
8
|
## Installation
|
8
9
|
|
@@ -22,7 +23,37 @@ Or install it yourself as:
|
|
22
23
|
|
23
24
|
## Usage
|
24
25
|
|
25
|
-
|
26
|
+
```ruby
|
27
|
+
class UserAttributesMapper < AttributesMapper::Builder
|
28
|
+
configure do |config|
|
29
|
+
config.required_attributes = %i[name email]
|
30
|
+
config.optional_attributes = %i[age key]
|
31
|
+
config.scopes = { profile: 'user.profile', info: 'user.info' }
|
32
|
+
end
|
33
|
+
|
34
|
+
name { { from: :username, scope: :profile } } # corresponds to path `user.profile.username`
|
35
|
+
email { { from: :email, scope: :profile } } # corresponds to path `user.profile.email`
|
36
|
+
age { { from: :age, scope: :info } } # corresponds to path `user.info.age`
|
37
|
+
key { { from: :key } } # corresponds to path `key`
|
38
|
+
end
|
39
|
+
|
40
|
+
input = { user:
|
41
|
+
{ profile:
|
42
|
+
{
|
43
|
+
username: 'Joe Bloggs',
|
44
|
+
email: 'joe@email.com'
|
45
|
+
},
|
46
|
+
info: {
|
47
|
+
|
48
|
+
age: 23
|
49
|
+
}
|
50
|
+
},
|
51
|
+
key: 'some-value'
|
52
|
+
}
|
53
|
+
|
54
|
+
builder = UserAttributesMapper.new(input).build
|
55
|
+
builder.to_h #=> { name: 'Joe Bloggs', email: 'joe@email.com', age: 23, key: 'some-value' }
|
56
|
+
```
|
26
57
|
|
27
58
|
## Development
|
28
59
|
|
data/dev/setup.rb
CHANGED
@@ -10,6 +10,7 @@ require 'active_support/core_ext/object/blank'
|
|
10
10
|
require 'active_support/core_ext/object/json'
|
11
11
|
require 'active_support/core_ext/enumerable'
|
12
12
|
require 'active_support/configurable'
|
13
|
+
require 'rudash'
|
13
14
|
|
14
15
|
%w[../../lib/attributes_mapper ../../spec/spec_helper].each do |rel_path|
|
15
16
|
require File.expand_path(rel_path, Pathname.new(__FILE__).realpath)
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module AttributesMapper
|
2
|
+
class Builder
|
3
|
+
include HasAttributes
|
4
|
+
|
5
|
+
attr_reader :input
|
6
|
+
|
7
|
+
def initialize(input)
|
8
|
+
transformed_input = if configuration.apply_input_data_transform?
|
9
|
+
configuration.apply_input_data_transform_proc.call(input)
|
10
|
+
else
|
11
|
+
input
|
12
|
+
end
|
13
|
+
|
14
|
+
@input = Rordash::HashUtil.deep_symbolize_keys(transformed_input)
|
15
|
+
@mapped_input = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def build
|
19
|
+
@mapped_input = paths_builder.build_for(input).deep_symbolize_keys
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_h
|
24
|
+
@mapped_input
|
25
|
+
end
|
26
|
+
|
27
|
+
def paths_builder
|
28
|
+
@paths_builder ||= begin
|
29
|
+
builder = JsonPath::Builder.new
|
30
|
+
if configuration.source_data_wrapper_class?
|
31
|
+
builder.with_wrapped_data_class(configuration.source_data_wrapper_class)
|
32
|
+
end
|
33
|
+
add_paths_to_builder(builder)
|
34
|
+
builder
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def add_paths_to_builder(builder)
|
41
|
+
self.class.each_path_context_key_value_pair do |to, path_attrs|
|
42
|
+
params = path_attrs.merge(to: to)
|
43
|
+
|
44
|
+
if params.key?(SCOPE)
|
45
|
+
scope_path = self.class.find_path_by_scope_name(params[SCOPE])
|
46
|
+
builder.within(scope_path) { add_path_to_builder(builder, params) }
|
47
|
+
else
|
48
|
+
add_path_to_builder(builder, params)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def add_path_to_builder(builder, path_params)
|
54
|
+
builder.from(path_params[:from], **path_params.except(:from, SCOPE))
|
55
|
+
end
|
56
|
+
|
57
|
+
def method_missing(method_name, *arguments, &block)
|
58
|
+
return @mapped_input[method_name] if @mapped_input.key?(method_name)
|
59
|
+
|
60
|
+
super
|
61
|
+
end
|
62
|
+
|
63
|
+
def respond_to_missing?(method_name, include_private = false)
|
64
|
+
@mapped_input.key?(method_name) || super
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/attributes_mapper.rb
CHANGED
@@ -2,11 +2,15 @@
|
|
2
2
|
|
3
3
|
require 'rordash'
|
4
4
|
require 'json-path/builder'
|
5
|
+
require 'json-path/default_data_wrapper'
|
6
|
+
require 'json-path/path_context'
|
7
|
+
require 'json-path/path_context_collection'
|
5
8
|
|
6
9
|
%w[
|
7
10
|
version
|
8
11
|
configuration
|
9
12
|
has_attributes
|
13
|
+
builder
|
10
14
|
].each do |filename|
|
11
15
|
require File.expand_path("../attributes-mapper/#{filename}", Pathname.new(__FILE__).realpath)
|
12
16
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AttributesMapper
|
4
|
+
RSpec.describe Builder do
|
5
|
+
let(:subject_class) do
|
6
|
+
Class.new(described_class) do
|
7
|
+
configure do |config|
|
8
|
+
config.required_attributes = %i[name email]
|
9
|
+
config.optional_attributes = %i[age key]
|
10
|
+
config.scopes = { profile: 'user.profile', info: 'user.info' }
|
11
|
+
end
|
12
|
+
|
13
|
+
name { { from: :username, scope: :profile } }
|
14
|
+
email { { from: :email, scope: :profile } }
|
15
|
+
age { { from: :age, scope: :info } }
|
16
|
+
key { { from: :key } }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:name) { 'Joe Bloggs' }
|
21
|
+
let(:email) { 'joe@email.com' }
|
22
|
+
let(:age) { 23 }
|
23
|
+
let(:value) { 'some-value' }
|
24
|
+
let(:input) { { user: { profile: { username: name, email: email }, info: { age: age } }, key: value } }
|
25
|
+
|
26
|
+
subject(:built_builder) { subject_class.new(input).build }
|
27
|
+
|
28
|
+
describe '#build' do
|
29
|
+
it 'handles simple mappings' do
|
30
|
+
expect(built_builder.key).to eql(value)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'handle nested paths via declared scopes' do
|
34
|
+
expect(built_builder.name).to eql(name)
|
35
|
+
expect(built_builder.email).to eql(email)
|
36
|
+
expect(built_builder.age).to eql(age)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#to_h' do
|
41
|
+
it 'maps input to the specified paths' do
|
42
|
+
expect(built_builder.to_h).to eq({ name: name, email: email, age: age, key: value })
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#method_missing' do
|
47
|
+
it 'returns the value of a mapped key' do
|
48
|
+
expect(built_builder.key).to eq(value)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'raises an error when the key does not exist' do
|
52
|
+
expect { built_builder.baz }.to raise_error(NoMethodError)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#respond_to_missing?' do
|
57
|
+
it 'returns true when the key exists' do
|
58
|
+
expect(built_builder.respond_to?(:name)).to be true
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'returns false when the key does not exist' do
|
62
|
+
expect(built_builder.respond_to?(:baz)).to be false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attributes-mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Desmond O'Leary
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-03-
|
11
|
+
date: 2023-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json-path-builder
|
@@ -117,11 +117,13 @@ files:
|
|
117
117
|
- bin/rubocop
|
118
118
|
- bin/setup
|
119
119
|
- dev/setup.rb
|
120
|
+
- lib/attributes-mapper/builder.rb
|
120
121
|
- lib/attributes-mapper/configuration.rb
|
121
122
|
- lib/attributes-mapper/has_attributes.rb
|
122
123
|
- lib/attributes-mapper/version.rb
|
123
124
|
- lib/attributes_mapper.rb
|
124
125
|
- sig/attributes/mapper.rbs
|
126
|
+
- spec/attributes-mapper/builder_spec.rb
|
125
127
|
- spec/attributes-mapper/configuration_spec.rb
|
126
128
|
- spec/attributes-mapper/has_attributes_spec.rb
|
127
129
|
- spec/attributes_mapper_spec.rb
|