json_data_extractor 0.0.9 → 0.0.11

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: bdd75c436a18caa753cb6c35536852852b8d876b44684de7f45d66678d012c6b
4
- data.tar.gz: 612d1cb976811a479e6e3f6c377186d90bd7d8fe900def4009dfeb7e2d63c81d
3
+ metadata.gz: aeef2dddd8e11795c682d9db785b955164fbab87e4dc1c63843ba02a76b65905
4
+ data.tar.gz: e17a062f72e0ae56bc09b42ccaa237c12149b667b63dfb0e58a60dd3ea8e5830
5
5
  SHA512:
6
- metadata.gz: 3137a8b5ecbf8850bbc8f96b46cb9c24688760e1d9c634a0735611a4beadafdf24fb6f1baa66de4f486157a31fbde3b36d1c489e887c1f27c1281225b944748e
7
- data.tar.gz: 1bdf6749d6c7ba7a86f7c076f0f22a113731938456b801084cbfbd9cb6bd8e15f12a3748a521d4c267a6ad59cacbf40e22ad86d78cb62cc9c09fc0f534ef3076
6
+ metadata.gz: b574bc9f7c79a4405d7b86739e1bf50e0ccbc82f1016befedf3e5bbb0da040db263492ee8978cd3d83957546d47338980bcfba80770a620a9c637937675bad46
7
+ data.tar.gz: 2a83cf29049a8c4205851a83e12e0867f42ae684564c6bc7ae9e183b4399f9a2390f9be36724f137064bf8e76f74b30d977539fdb1c620972c05a949f19883f2
data/README.md CHANGED
@@ -3,13 +3,15 @@
3
3
  NOTE: This is still a very early beta.
4
4
 
5
5
  Transform JSON data structures with the help of a simple schema and JsonPath expressions.
6
- Use the JsonDataExtractor gem to extract and modify data from complex JSON structures using a straightforward syntax
6
+ Use the JsonDataExtractor gem to extract and modify data from complex JSON structures using a
7
+ straightforward syntax
7
8
  and a range of built-in or custom modifiers.
8
9
 
9
10
  _Another try to make something for JSON that is XSLT for XML.
10
11
  We transform one JSON into another JSON with the help of a third JSON!!!111!!eleventy!!_
11
12
 
12
- Remap one JSON structure into another with some basic rules and [jsonpath](https://github.com/joshbuddy/jsonpath).
13
+ Remap one JSON structure into another with some basic rules
14
+ and [jsonpath](https://github.com/joshbuddy/jsonpath).
13
15
 
14
16
  Heavily inspired by [xml_data_extractor](https://github.com/monde-sistemas/xml_data_extractor).
15
17
 
@@ -32,8 +34,8 @@ Or install it yourself as:
32
34
  ## Usage
33
35
 
34
36
  JsonDataExtractor allows you to remap one JSON structure into another with some basic rules
35
- and [JSONPath](https://goessner.net/articles/JsonPath/) expressions. The process involves defining a schema that maps
36
- the input JSON structure to the desired output structure.
37
+ and [JSONPath](https://goessner.net/articles/JsonPath/) expressions. The process involves defining a
38
+ schema that maps the input JSON structure to the desired output structure.
37
39
 
38
40
  We'll base our examples on the following source:
39
41
 
@@ -78,22 +80,24 @@ We'll base our examples on the following source:
78
80
 
79
81
  ### Defining a Schema
80
82
 
81
- A schema consists of one or more mappings that specify how to extract data from the input JSON and where to place it in
82
- the output JSON.
83
+ A schema consists of one or more mappings that specify how to extract data from the input JSON and
84
+ where to place it in the output JSON.
83
85
 
84
- Each mapping has a path field that specifies the JsonPath expression to use for data extraction, and an optional
85
- modifier field that specifies one or more modifiers to apply to the extracted data. Modifiers are used to transform the
86
- data in some way before placing it in the output JSON.
86
+ Each mapping has a path field that specifies the JsonPath expression to use for data extraction, and
87
+ an optional modifier field that specifies one or more modifiers to apply to the extracted data.
88
+ Modifiers are used to transform the data in some way before placing it in the output JSON.
87
89
 
88
- Here's an example schema that extracts the authors and categories from a JSON structure similar to the one used in the
89
- previous example (here it's in YAML just for readability):
90
+ Here's an example schema that extracts the authors and categories from a JSON structure similar to
91
+ the one used in the previous example:
90
92
 
91
- ```yaml
92
- schemas:
93
- authors:
94
- path: $.store.book[*].author
95
- modifier: downcase
96
- categories: $..category
93
+ ```json
94
+ {
95
+ "authors": {
96
+ "path": "$.store.book[*].author",
97
+ "modifier": "downcase"
98
+ },
99
+ "categories": "$..category"
100
+ }
97
101
  ```
98
102
 
99
103
  The resulting json will be:
@@ -116,23 +120,67 @@ The resulting json will be:
116
120
 
117
121
  ```
118
122
 
119
- Modifiers can be supplied on object creation and/or added later by calling `#add_modifier` method. Please see specs for
120
- examples.
123
+ ### Modifiers
124
+
125
+ Modifiers can be supplied on object creation and/or added later by calling `#add_modifier` method.
126
+ Please see specs for examples.
127
+ Modifiers allow you to perform transformations on the extracted data before it is returned. You can
128
+ use modifiers to clean up the data, format it, or apply any custom logic you need.
129
+
130
+ Modifiers can be defined in two ways: by providing a symbol corresponding to the name of the method
131
+ or lambda that should be called on each extracted value, or by providing an anonymous lambda. Here's
132
+ an example schema that uses both types of modifiers:
133
+
134
+ ```ruby
135
+ schema = {
136
+ name: '$.name',
137
+ age: { path: '$.age', modifier: :to_i },
138
+ email: { path: '$.contact.email', modifiers: [:downcase, lambda { |email| email.gsub(/\s/, '') }] }
139
+ }
140
+
141
+ ```
142
+
143
+ In this schema, the name value is simply extracted as-is. The age value is extracted from the JSON,
144
+ but it is modified with the `to_i` method, which converts the value to an integer. The email value
145
+ is extracted from a nested object, and then passed through two modifiers: first `downcase` is called
146
+ to convert the email address to all lowercase letters, and then an anonymous lambda is called to
147
+ remove any whitespace in the email address.
148
+
149
+ You can also define custom modifiers by passing a lambda to the `add_modifier` method on a
150
+ JsonDataExtractor instance:
151
+
152
+ ```ruby
153
+ extractor = JsonDataExtractor.new(json_data)
154
+ extractor.add_modifier(:remove_newlines) { |value| value.gsub("\n", '') }
155
+
156
+ schema = {
157
+ name: 'name',
158
+ bio: { path: 'bio', modifiers: [:remove_newlines] }
159
+ }
160
+
161
+ results = extractor.extract(schema)
162
+
163
+ ```
164
+
165
+ Modifiers are called in the order in which they are defined, so keep that in mind when defining your
166
+ schema. By default JDE raises an ArgumentError if a modifier is not applicable, but this behaviour
167
+ can be configured to ignore missing modifiers. See Configuration options for details
121
168
 
122
169
  ### Nested schemas
123
170
 
124
- JDE supports nested schemas. Just provide your element with a type of `array` and add a `schema` key for its data.
171
+ JDE supports nested schemas. Just provide your element with a type of `array` and add a `schema` key
172
+ for its data.
125
173
 
126
174
  E.g. this is a valid real-life schema with nested data:
127
175
 
128
176
  ```json
129
177
  {
130
- "name": "$.Name",
131
- "code": "$.Code",
132
- "services": "$.Services[*].Code",
178
+ "name": "$.Name",
179
+ "code": "$.Code",
180
+ "services": "$.Services[*].Code",
133
181
  "locations": {
134
- "path": "$.Locations[*]",
135
- "type": "array",
182
+ "path": "$.Locations[*]",
183
+ "type": "array",
136
184
  "schema": {
137
185
  "name": "$.Name",
138
186
  "type": "$.Type",
@@ -141,6 +189,26 @@ E.g. this is a valid real-life schema with nested data:
141
189
  }
142
190
  }
143
191
  ```
192
+ Nested schema can be also applied to objects, not arrays. See specs for more examples.
193
+
194
+ ## Configuration Options
195
+ The JsonDataExtractor gem provides a configuration option to control the behavior when encountering invalid modifiers.
196
+
197
+ ### Strict Modifiers
198
+ By default, the gem operates in strict mode, which means that if an invalid modifier is encountered, an `ArgumentError` will be raised. This ensures that only valid modifiers are applied to the extracted data.
199
+
200
+ To change this behavior and allow the use of invalid modifiers without raising an error, you can configure the gem to operate in non-strict mode.
201
+
202
+ ```ruby
203
+ JsonDataExtractor.configure do |config|
204
+ config.strict_modifiers = false
205
+ end
206
+ ```
207
+ When `strict_modifiers` is set to `false`, any invalid modifiers will be ignored, and the original value will be returned without applying any modification.
208
+
209
+ It is important to note that enabling non-strict mode should be done with caution, as it can lead to unexpected behavior if there are typos or incorrect modifiers specified in the schema.
210
+
211
+ By default, `strict_modifiers` is set to `true`, providing a safe and strict behavior. However, you can customize this configuration option according to your specific needs.
144
212
 
145
213
  ## TODO
146
214
 
@@ -148,25 +216,32 @@ Update this readme for better usage cases. Add info on arrays and modifiers.
148
216
 
149
217
  ## Development
150
218
 
151
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can
219
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run
220
+ the tests. You can
152
221
  also run `bin/console` for an interactive prompt that will allow you to experiment.
153
222
 
154
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
155
- version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version,
223
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new
224
+ version, update the
225
+ version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag
226
+ for the version,
156
227
  push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
157
228
 
158
229
  ## Contributing
159
230
 
160
- Bug reports and pull requests are welcome on GitHub at https://github.com/austerlitz/json_data_extractor. This project
161
- is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to
231
+ Bug reports and pull requests are welcome on GitHub
232
+ at https://github.com/austerlitz/json_data_extractor. This project
233
+ is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere
234
+ to
162
235
  the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
163
236
 
164
237
  ## License
165
238
 
166
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
239
+ The gem is available as open source under the terms of
240
+ the [MIT License](https://opensource.org/licenses/MIT).
167
241
 
168
242
  ## Code of Conduct
169
243
 
170
- Everyone interacting in the JsonDataExtractor project’s codebases, issue trackers, chat rooms and mailing lists is
244
+ Everyone interacting in the JsonDataExtractor project’s codebases, issue trackers, chat rooms and
245
+ mailing lists is
171
246
  expected to follow
172
247
  the [code of conduct](https://github.com/austerlitz/json_data_extractor/blob/master/CODE_OF_CONDUCT.md).
@@ -1,4 +1,5 @@
1
1
  require 'src/version'
2
+ require 'src/configuration'
2
3
  require 'jsonpath'
3
4
 
4
5
  class JsonDataExtractor
@@ -22,7 +23,16 @@ class JsonDataExtractor
22
23
  if val.is_a?(Hash)
23
24
  val.transform_keys!(&:to_sym)
24
25
  path = val[:path]
25
- modifiers = Array(val[:modifiers] || val[:modifier]).map(&:to_sym)
26
+ modifiers = Array(val[:modifiers] || val[:modifier]).map do |mod|
27
+ case mod
28
+ when Symbol, Proc
29
+ mod
30
+ when String
31
+ mod.to_sym
32
+ else
33
+ raise ArgumentError, "Invalid modifier: #{mod.inspect}"
34
+ end
35
+ end
26
36
  array_type = 'array' == val[:type]
27
37
  nested = val.dup.delete(:schema)
28
38
  else
@@ -79,8 +89,21 @@ class JsonDataExtractor
79
89
  modifiers[modifier].call(value)
80
90
  elsif value.respond_to?(modifier)
81
91
  value.send(modifier)
92
+ elsif self.class.configuration.strict_modifiers
93
+ raise ArgumentError, "Invalid modifier: :#{modifier}"
82
94
  else
83
95
  value
84
96
  end
85
97
  end
98
+
99
+
100
+ class << self
101
+ def configuration
102
+ @configuration ||= Configuration.new
103
+ end
104
+
105
+ def configure
106
+ yield(configuration)
107
+ end
108
+ end
86
109
  end
@@ -0,0 +1,9 @@
1
+ class JsonDataExtractor
2
+ class Configuration
3
+ attr_accessor :strict_modifiers
4
+
5
+ def initialize
6
+ @strict_modifiers = true
7
+ end
8
+ end
9
+ end
data/lib/src/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class JsonDataExtractor
2
- VERSION = '0.0.9'
2
+ VERSION = '0.0.11'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_data_extractor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max Buslaev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-11 00:00:00.000000000 Z
11
+ date: 2023-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -116,6 +116,7 @@ files:
116
116
  - bin/setup
117
117
  - json_data_extractor.gemspec
118
118
  - lib/json_data_extractor.rb
119
+ - lib/src/configuration.rb
119
120
  - lib/src/version.rb
120
121
  homepage: https://github.com/austerlitz/json_data_extractor
121
122
  licenses: