json-path-builder 0.1.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 +7 -0
- data/.github/workflows/main.yml +27 -0
- data/.gitignore +20 -0
- data/.rspec +4 -0
- data/.rubocop.yml +247 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +21 -0
- data/README.md +188 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/bin/setup +8 -0
- data/dev/setup.rb +19 -0
- data/json_path_builder.gemspec +33 -0
- data/lib/json-path/builder.rb +232 -0
- data/lib/json-path/default_data_wrapper.rb +7 -0
- data/lib/json-path/path_context.rb +135 -0
- data/lib/json-path/path_context_collection.rb +65 -0
- data/lib/json-path/version.rb +5 -0
- data/lib/json_path.rb +15 -0
- data/sig/json_path_builder.rbs +4 -0
- data/spec/coverage_helper.rb +12 -0
- data/spec/json-path/builder_spec.rb +168 -0
- data/spec/json-path/default_data_wrapper_spec.rb +33 -0
- data/spec/json-path/path_context_collection_spec.rb +46 -0
- data/spec/json-path/path_context_spec.rb +90 -0
- data/spec/json_path_builder_spec.rb +7 -0
- data/spec/spec_helper.rb +16 -0
- metadata +161 -0
@@ -0,0 +1,168 @@
|
|
1
|
+
module JsonPath
|
2
|
+
RSpec.describe Builder do
|
3
|
+
let(:key) { "some-value" }
|
4
|
+
let(:other_key) { "some-other-value" }
|
5
|
+
let(:list) { %w[some-list-value-1 some-list-value-2] }
|
6
|
+
|
7
|
+
let(:input) { { key: key, other_key: other_key, list: list }.as_json }
|
8
|
+
|
9
|
+
subject(:instance) { described_class.new }
|
10
|
+
|
11
|
+
describe '.from' do
|
12
|
+
it 'handles simple path mapping' do
|
13
|
+
%i[key other_key].each { |k| instance.from(k) }
|
14
|
+
|
15
|
+
expect(instance.build_for(input)).to eql({ key: key, other_key: other_key })
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'handles renaming path name' do
|
19
|
+
instance.from(:other_key, to: :another_key)
|
20
|
+
|
21
|
+
expect(instance.build_for(input)).to eql({ another_key: other_key })
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'handles transformations' do
|
25
|
+
instance.from(:key, transform: proc { |v| v.upcase })
|
26
|
+
|
27
|
+
expect(instance.build_for(input)).to eql({ key: key.upcase })
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.from_each' do
|
32
|
+
it 'handles simple path mapping' do
|
33
|
+
instance.from_each(:list)
|
34
|
+
|
35
|
+
expect(instance.build_for(input)).to eql({ list: list })
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'handles renaming path name' do
|
39
|
+
instance.from(:list, to: :another_list_key)
|
40
|
+
|
41
|
+
expect(instance.build_for(input)).to eql({ another_list_key: list })
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'handles transformations' do
|
45
|
+
instance.from_each(:list, transform: proc { |v| v.upcase })
|
46
|
+
|
47
|
+
expect(instance.build_for(input)).to eql({ list: list.map(&:upcase) })
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'handles skipping items' do
|
51
|
+
instance.from_each(:list, skip_if: proc { |v| v == 'some-list-value-1' })
|
52
|
+
|
53
|
+
expect(instance.build_for(input)).to eql({ list: ['some-list-value-2'] })
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#within' do
|
58
|
+
let(:email) { 'email@domain.com' }
|
59
|
+
let(:user_id) { 1 }
|
60
|
+
let(:input) { { root: { deep: { profile: { email: email, uid: user_id } } } }.as_json }
|
61
|
+
|
62
|
+
it 'uses scope to simplify dot notation' do
|
63
|
+
builder = described_class.new
|
64
|
+
builder.within('root.deep.profile') do |b|
|
65
|
+
b.from(:email)
|
66
|
+
b.from(:uid, to: :user_id)
|
67
|
+
end
|
68
|
+
|
69
|
+
expect(builder.build_for(input)).to eql({ email: email, user_id: user_id })
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '#with_wrapped_data_class' do
|
74
|
+
let(:email) { 'email@domain.com' }
|
75
|
+
let(:user_id) { 123 }
|
76
|
+
let(:input) { { profile: { email: email } }.as_json }
|
77
|
+
let(:user) { double(:user, id: user_id) }
|
78
|
+
let(:user_repo) { double(:user_repo, find_by: user) }
|
79
|
+
|
80
|
+
let(:wrapped_data_class) do
|
81
|
+
Class.new(SimpleDelegator) do
|
82
|
+
class << self
|
83
|
+
attr_accessor :user_repo
|
84
|
+
end
|
85
|
+
|
86
|
+
def user
|
87
|
+
self.class.user_repo.find_by(email: dig('profile', 'email'))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
before do
|
93
|
+
wrapped_data_class.user_repo = user_repo
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'wraps input data in wrapped class' do
|
97
|
+
builder = described_class.new
|
98
|
+
builder.with_wrapped_data_class(wrapped_data_class)
|
99
|
+
transform = proc do |_email, path_context|
|
100
|
+
path_context.wrapped_source_data.user.id
|
101
|
+
end
|
102
|
+
|
103
|
+
builder.from('profile.email', to: :user_id, transform: transform)
|
104
|
+
expect(builder.build_for(input)).to eql({ user_id: user_id })
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#wrapped_data_class' do
|
109
|
+
context 'with custom data class' do
|
110
|
+
let(:wrapper_class) { Class.new(DefaultDataWrapper) }
|
111
|
+
|
112
|
+
it 'returns custom class' do
|
113
|
+
instance.with_wrapped_data_class(wrapper_class)
|
114
|
+
|
115
|
+
expect(instance.data_wrapper_class).to eql(wrapper_class)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'without custom data class' do
|
120
|
+
let(:custom_wrapper) { nil }
|
121
|
+
|
122
|
+
it 'returns default class' do
|
123
|
+
expect(instance.data_wrapper_class).to eql(DefaultDataWrapper)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# describe PathsBuilder::PathContext do
|
129
|
+
# let(:key) { "some-value" }
|
130
|
+
# let(:other_key) { "some-other-value" }
|
131
|
+
# let(:list) { %w[some-list-value-1 some-list-value-2] }
|
132
|
+
#
|
133
|
+
# let(:input) { { key: key, other_key: other_key, list: list }.as_json }
|
134
|
+
# let(:builder) { PathsBuilder.new }
|
135
|
+
# let(:path_context) { builder.path_context_collection.first }
|
136
|
+
#
|
137
|
+
# before(:each) do
|
138
|
+
# builder.from(:key, to: :another_key, transform: proc { |val| val.upcase })
|
139
|
+
# builder.with_source_data(input)
|
140
|
+
# end
|
141
|
+
#
|
142
|
+
#
|
143
|
+
# it 'returns path context instance' do
|
144
|
+
# expect(path_context).to be_instance_of(described_class)
|
145
|
+
# end
|
146
|
+
#
|
147
|
+
# describe '#wrapped_source_data' do
|
148
|
+
# subject { path_context.wrapped_source_data }
|
149
|
+
#
|
150
|
+
# context 'with custom data class' do
|
151
|
+
# let(:wrapper_class) { Sharplaunch::PropertyListingDataWrapper }
|
152
|
+
#
|
153
|
+
# before(:each) { builder.with_wrapped_data_class(wrapper_class) }
|
154
|
+
#
|
155
|
+
# it 'returns custom class' do
|
156
|
+
# expect(subject).to be_an_instance_of(wrapper_class)
|
157
|
+
# end
|
158
|
+
# end
|
159
|
+
#
|
160
|
+
# context 'without custom data wrapper class' do
|
161
|
+
# it 'returns default wrapper instance' do
|
162
|
+
# expect(subject).to be_instance_of(PathsBuilder::DefaultDataWrapper)
|
163
|
+
# end
|
164
|
+
# end
|
165
|
+
# end
|
166
|
+
# end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module JsonPath
|
2
|
+
RSpec.describe DefaultDataWrapper do
|
3
|
+
describe '#[]' do
|
4
|
+
context 'when the wrapped object is a hash with string keys' do
|
5
|
+
let(:data) { { 'name' => 'John', 'age' => 30 } }
|
6
|
+
let(:wrapper) { described_class.new(data) }
|
7
|
+
|
8
|
+
it 'returns the value associated with the symbol key' do
|
9
|
+
expect(wrapper[:name]).to eq('John')
|
10
|
+
expect(wrapper[:age]).to eq(30)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'does not modify the original hash' do
|
14
|
+
expect { wrapper[:name] }.not_to(change { data })
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when the wrapped object is a hash with symbol keys' do
|
19
|
+
let(:data) { { name: 'John', age: 30 } }
|
20
|
+
let(:wrapper) { described_class.new(data) }
|
21
|
+
|
22
|
+
it 'returns the value associated with the symbol key' do
|
23
|
+
expect(wrapper[:name]).to eq('John')
|
24
|
+
expect(wrapper[:age]).to eq(30)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'does not modify the original hash' do
|
28
|
+
expect { wrapper[:name] }.not_to(change { data })
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module JsonPath
|
2
|
+
# rubocop:disable Layout/LineLength,RSpec/MessageSpies,RSpec/StubbedMock
|
3
|
+
RSpec.describe PathContextCollection do
|
4
|
+
describe '#reject_from_paths!' do
|
5
|
+
let(:path_context1) { instance_double(PathContext, from: 'path1') }
|
6
|
+
let(:path_context2) { instance_double(PathContext, from: 'path2') }
|
7
|
+
let(:path_context3) { instance_double(PathContext, from: 'path3') }
|
8
|
+
|
9
|
+
it 'removes elements from the collection with matching from paths' do
|
10
|
+
collection = described_class.new([])
|
11
|
+
collection.push(path_context1, path_context2, path_context3)
|
12
|
+
|
13
|
+
collection.reject_from_paths!(%w[path1 path3])
|
14
|
+
|
15
|
+
expect(collection).to include(path_context2)
|
16
|
+
expect(collection).not_to include(path_context1, path_context3)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#add_path' do
|
21
|
+
let(:paths_builder) { instance_double(Builder) }
|
22
|
+
let(:iterable_data) { true }
|
23
|
+
let(:transform) { proc { |data| data.upcase } }
|
24
|
+
let(:defaults) { { foo: 'bar' } }
|
25
|
+
let(:fallback_proc) { proc { 'fallback' } }
|
26
|
+
let(:skip_if_proc) { proc { |data| data.nil? } }
|
27
|
+
let(:path_context) { instance_double(PathContext) }
|
28
|
+
|
29
|
+
before do
|
30
|
+
allow(PathContext).to receive(:new).and_return(path_context)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'adds a new PathContext object to the collection' do
|
34
|
+
collection = described_class.new([])
|
35
|
+
expect(PathContext).to receive(:new).with('path', paths_builder, to: nil, iterable_data: iterable_data,
|
36
|
+
transform: transform, use_builder: true, defaults: defaults, fallback_proc: fallback_proc, skip_if_proc: skip_if_proc).and_return(path_context)
|
37
|
+
|
38
|
+
result = collection.add_path('path', paths_builder, iterable_data: iterable_data, transform: transform,
|
39
|
+
defaults: defaults, fallback_proc: fallback_proc, skip_if_proc: skip_if_proc)
|
40
|
+
|
41
|
+
expect(result).to include(path_context)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
# rubocop:enable Layout/LineLength,RSpec/MessageSpies,RSpec/StubbedMock
|
46
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module JsonPath
|
2
|
+
RSpec.describe PathContext do
|
3
|
+
let(:builder) { double("PathsBuilder", nested_paths: []) }
|
4
|
+
let(:data) { { foo: "bar" } }
|
5
|
+
let(:transform) { :iso8601 }
|
6
|
+
let(:json_path) { "foo" }
|
7
|
+
let(:defaults) { nil }
|
8
|
+
let(:path_context) do
|
9
|
+
described_class.new(json_path, builder, iterable_data: false, transform: transform, use_builder: false,
|
10
|
+
defaults: defaults, fallback_proc: nil, skip_if_proc: nil)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#initialize" do
|
14
|
+
context "when json_path is blank" do
|
15
|
+
let(:json_path) { ' ' }
|
16
|
+
|
17
|
+
it "raises an ArgumentError" do
|
18
|
+
expect { path_context }.to raise_error(ArgumentError, "`from` must be filled")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when transform is not a symbol or a valid transform key" do
|
23
|
+
let(:transform) { "not_a_symbol_or_valid_transform" }
|
24
|
+
|
25
|
+
it "raises an ArgumentError" do
|
26
|
+
expect do
|
27
|
+
path_context
|
28
|
+
end.to raise_error(ArgumentError,
|
29
|
+
"`transform`: 'not_a_symbol_or_valid_transform' must be one of [:iso8601, :date]")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#parent" do
|
35
|
+
context "when the builder has a parent_path_context" do
|
36
|
+
let(:parent_path_context) { double("PathContext") }
|
37
|
+
|
38
|
+
before { allow(builder).to receive(:parent_path_context).and_return(parent_path_context) }
|
39
|
+
|
40
|
+
it "returns the parent_path_context" do
|
41
|
+
expect(path_context.parent).to eq(parent_path_context)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when the builder does not have a parent_path_context" do
|
46
|
+
before { allow(builder).to receive(:parent_path_context).and_return(nil) }
|
47
|
+
|
48
|
+
it "returns nil" do
|
49
|
+
expect(path_context.parent).to be_nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#defaults?" do
|
55
|
+
context "when defaults is an empty hash" do
|
56
|
+
let(:defaults) { {} }
|
57
|
+
|
58
|
+
it "returns false" do
|
59
|
+
expect(path_context.defaults?).to be false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when defaults is a non-empty hash" do
|
64
|
+
let(:defaults) { { baz: "qux" } }
|
65
|
+
|
66
|
+
it "returns true" do
|
67
|
+
expect(path_context.defaults?).to be true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#transformable?" do
|
73
|
+
context "when transform is a Proc" do
|
74
|
+
let(:transform) { ->(val) { val.to_s.upcase } }
|
75
|
+
|
76
|
+
it "returns true" do
|
77
|
+
expect(path_context.transformable?).to be true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when transform is not a Proc" do
|
82
|
+
let(:transform) { nil }
|
83
|
+
|
84
|
+
it "returns false" do
|
85
|
+
expect(path_context.transformable?).to be false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.join(__dir__, "..", 'dev', 'setup')
|
4
|
+
require Pathname.new(__dir__).realpath.join('coverage_helper').to_s
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
# Enable flags like --only-failures and --next-failure
|
8
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
9
|
+
|
10
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
11
|
+
config.disable_monkey_patching!
|
12
|
+
|
13
|
+
config.expect_with :rspec do |c|
|
14
|
+
c.syntax = :expect
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: json-path-builder
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Desmond O'Leary
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-02-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rordash
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.1.2
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.1.2
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: codecov
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.6.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.6.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 13.0.6
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 13.0.6
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 3.12.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 3.12.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.21.2
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.21.2
|
97
|
+
description: Declarative mapping JSON/Hash data structures
|
98
|
+
email:
|
99
|
+
- desoleary@gmail.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".github/workflows/main.yml"
|
105
|
+
- ".gitignore"
|
106
|
+
- ".rspec"
|
107
|
+
- ".rubocop.yml"
|
108
|
+
- CHANGELOG.md
|
109
|
+
- CODE_OF_CONDUCT.md
|
110
|
+
- Gemfile
|
111
|
+
- LICENSE.txt
|
112
|
+
- README.md
|
113
|
+
- Rakefile
|
114
|
+
- bin/console
|
115
|
+
- bin/rspec
|
116
|
+
- bin/rubocop
|
117
|
+
- bin/setup
|
118
|
+
- dev/setup.rb
|
119
|
+
- json_path_builder.gemspec
|
120
|
+
- lib/json-path/builder.rb
|
121
|
+
- lib/json-path/default_data_wrapper.rb
|
122
|
+
- lib/json-path/path_context.rb
|
123
|
+
- lib/json-path/path_context_collection.rb
|
124
|
+
- lib/json-path/version.rb
|
125
|
+
- lib/json_path.rb
|
126
|
+
- sig/json_path_builder.rbs
|
127
|
+
- spec/coverage_helper.rb
|
128
|
+
- spec/json-path/builder_spec.rb
|
129
|
+
- spec/json-path/default_data_wrapper_spec.rb
|
130
|
+
- spec/json-path/path_context_collection_spec.rb
|
131
|
+
- spec/json-path/path_context_spec.rb
|
132
|
+
- spec/json_path_builder_spec.rb
|
133
|
+
- spec/spec_helper.rb
|
134
|
+
homepage: https://github.com/omnitech-solutions/json-path-builder
|
135
|
+
licenses:
|
136
|
+
- MIT
|
137
|
+
metadata:
|
138
|
+
homepage_uri: https://github.com/omnitech-solutions/json-path-builder
|
139
|
+
source_code_uri: https://github.com/omnitech-solutions/json-path-builder
|
140
|
+
changelog_uri: https://github.com/omnitech-solutions/json-path-builder/CHANGELOG.md
|
141
|
+
rubygems_mfa_required: 'true'
|
142
|
+
post_install_message:
|
143
|
+
rdoc_options: []
|
144
|
+
require_paths:
|
145
|
+
- lib
|
146
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '2.7'
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
requirements: []
|
157
|
+
rubygems_version: 3.1.6
|
158
|
+
signing_key:
|
159
|
+
specification_version: 4
|
160
|
+
summary: Declarative mapping JSON/Hash data structures
|
161
|
+
test_files: []
|