realize 1.1.0 → 1.3.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 +4 -4
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +22 -0
- data/README.md +10 -1
- data/lib/realize.rb +2 -0
- data/lib/realize/format/date.rb +2 -4
- data/lib/realize/format/string_template.rb +38 -0
- data/lib/realize/format/substring.rb +44 -0
- data/lib/realize/logical/switch.rb +1 -1
- data/lib/realize/transformers.rb +23 -2
- data/lib/realize/type/boolean.rb +38 -0
- data/lib/realize/type/string.rb +22 -0
- data/lib/realize/value/now.rb +24 -0
- data/lib/realize/value/uuid.rb +14 -0
- data/lib/realize/version.rb +1 -1
- data/realize.gemspec +2 -1
- metadata +24 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d7bccc32a2837daee77ec8bcdda00975744c90e0ac08f62f5dbfcaf338dfd91
|
4
|
+
data.tar.gz: aa23c2077287abe225dc2c4b7aa3a2bec7a405bdfd4011ce375d7aed64ac5f56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1201c0671253238b656904b713482db1b53b1f720c36821b87618fd6d0ace49314eda6773080ccb3ed27fca50d8cb68f822547d9d631ff8529f437e7babdba5
|
7
|
+
data.tar.gz: aadc039cccfdcae68d14b7902e854e14078ea2a674d7c4e84cc2f16c2f1e54f6f1cc1568a408676b726b581a5f80004861d44f751a350eb340d1bd995f02d3fe
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
# 1.3.0 (November 4th, 2020)
|
2
|
+
|
3
|
+
New Transformers:
|
4
|
+
|
5
|
+
* r/format/string_template
|
6
|
+
* r/format/substring
|
7
|
+
|
8
|
+
# 1.2.0 (October 6th, 2020)
|
9
|
+
|
10
|
+
New Transformers:
|
11
|
+
|
12
|
+
* r/type/boolean
|
13
|
+
* r/type/string
|
14
|
+
* r/value/now
|
15
|
+
* r/value/uuid
|
16
|
+
|
17
|
+
# 1.1.1 (September 9th, 2020)
|
18
|
+
|
19
|
+
Fixes:
|
20
|
+
|
21
|
+
* Do not leverage #to_datetime even if it is available for date parsing. This removes un-intentional coupling of other libraries into Realize and keeps it based on Ruby standard and core libraries.
|
22
|
+
|
1
23
|
# 1.1.0 (June 24th, 2020)
|
2
24
|
|
3
25
|
Addition of r/collection/at_index, r/collection/first, and r/collection/last
|
data/README.md
CHANGED
@@ -13,7 +13,7 @@ It is currently used in production at Blue Marble to power the transformation pi
|
|
13
13
|
To install through Rubygems:
|
14
14
|
|
15
15
|
````
|
16
|
-
gem install
|
16
|
+
gem install realize
|
17
17
|
````
|
18
18
|
|
19
19
|
You can also add this to your Gemfile:
|
@@ -79,18 +79,27 @@ Here is a list of each built-in transformer, their options, and what their funct
|
|
79
79
|
* **r/format/date** [input_format, output_format]: Parses the incoming value into a Time object using the configured input_format and outputs it as formatted by the configured output_format.
|
80
80
|
* **r/format/remove_whitespace** []: Removes all whitespace from the incoming value.
|
81
81
|
* **r/format/string_replace** [original, replacement]: Replaces all occurrences of the configured original value with the replacement value.
|
82
|
+
* **r/format/string_template** [expression, separator, use_record]: String interpolate an expression using either the record or passed in value. Nested objects can be handled (i.e. key paths like dot-notation) by passing in a separator.
|
83
|
+
* **r/format/substring** [start_index, end_index, exclusive]: Cut a string in a given range. All options are optional. If a start_index is not provided, the beginning of the string is used. If no end_index is specified then the end of the string is used. If exclusive is set to true then the last index position will not be included. For example: "hellofriend" with a start_index of 0, an end_index of 5, and exclusive as true would yield: "hello". If exclusive was false then it would yield "hellof"
|
82
84
|
|
83
85
|
#### Logical Transformers
|
84
86
|
|
85
87
|
* **r/logical/switch** [cases, default_transformers, key]: Provides a value-based logic branching. If a value matches a specific case, the specific cases transformers will be executed. If it does not match any case then the default_transformers will be executed.
|
86
88
|
|
89
|
+
#### Type Transformers
|
90
|
+
|
91
|
+
* **r/type/boolean** [nullable]: Returns `true` if the input is 'truthy', `false` if not. By default nullable is false, which means a nil input will return false. Changing this to true will return nil if nil is passed in. A 'truthy' value is defined as matching: true, t, yes, y, or 1 (case-insensitive).
|
92
|
+
* **r/type/string** []: Calls `#to_s` on the value so the returned value is guaranteed to be a string type.
|
93
|
+
|
87
94
|
#### Value-oriented Transformers
|
88
95
|
|
89
96
|
* **r/value/blank** []: Always return a blank string.
|
90
97
|
* **r/value/map** [values]: Do a lookup on the value using the `values` hash. If a value is found, then its corresponding value is returned. If it isn't then the input is returned.
|
98
|
+
* **r/value/now** [utc_offset]: Returns a Time object, defaulting to UTC offset. You can optionally pass in a different offset in the FORM: "+/-HH:MM"
|
91
99
|
* **r/value/null** []: Always returns null.
|
92
100
|
* **r/value/resolve** [key]: Dynamically resolves a value based on the record's key. It uses the [Objectable](https://github.com/bluemarblepayroll/objectable) library by default, which provides some goodies like dot-notation for nested objects and type-insensitivity (works for Ruby objects, hashes, structs, etc.)
|
93
101
|
* **r/value/static** [value]: Always returns a hard-coded value.
|
102
|
+
* **r/value/uuid** []: Returns a new 36 character UUID (i.e. 6967fec6-bbde-4497-82d9-55ccc7b87cd0)
|
94
103
|
* **r/value/verbatim** []: Default transformer, simply echos back the input.
|
95
104
|
|
96
105
|
### Plugging in Transformers
|
data/lib/realize.rb
CHANGED
data/lib/realize/format/date.rb
CHANGED
@@ -30,12 +30,10 @@ module Realize
|
|
30
30
|
return nil if value.to_s.empty?
|
31
31
|
|
32
32
|
date_time =
|
33
|
-
if
|
34
|
-
value.to_datetime
|
35
|
-
elsif input_format?
|
33
|
+
if input_format?
|
36
34
|
DateTime.strptime(value, input_format)
|
37
35
|
else
|
38
|
-
DateTime.parse(value)
|
36
|
+
DateTime.parse(value.to_s)
|
39
37
|
end
|
40
38
|
|
41
39
|
date_time.strftime(output_format)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Realize
|
4
|
+
class Format
|
5
|
+
# Use an expression as a template and string interpolate it using the Stringento library.
|
6
|
+
# Stringento also uses Objectable to provide (optional) key-path notation for handling
|
7
|
+
# nested objects.
|
8
|
+
# For more information see underlying libraries:
|
9
|
+
# * Stringento: https://github.com/bluemarblepayroll/stringento
|
10
|
+
# * Objectable: https://github.com/bluemarblepayroll/objectable
|
11
|
+
class StringTemplate
|
12
|
+
acts_as_hashable
|
13
|
+
|
14
|
+
DEFAULT_SEPARATOR = '.'
|
15
|
+
|
16
|
+
attr_reader :expression, :resolver, :use_record
|
17
|
+
|
18
|
+
def initialize(expression: '', separator: DEFAULT_SEPARATOR, use_record: false)
|
19
|
+
@expression = expression.to_s
|
20
|
+
@resolver = Objectable.resolver(separator: separator)
|
21
|
+
@use_record = use_record || false
|
22
|
+
|
23
|
+
freeze
|
24
|
+
end
|
25
|
+
|
26
|
+
def transform(_resolver, value, _time, record)
|
27
|
+
input = use_record ? record : value
|
28
|
+
|
29
|
+
Stringento.evaluate(expression, input, resolver: self)
|
30
|
+
end
|
31
|
+
|
32
|
+
# For Stringento consumption
|
33
|
+
def resolve(value, input)
|
34
|
+
resolver.get(input, value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Realize
|
4
|
+
class Format
|
5
|
+
# Cut a string using a range (start and end index). You can also choose whether you wish the
|
6
|
+
# range selection to be inclusive (default) or exclusive.
|
7
|
+
#
|
8
|
+
# Examples using the string: '012-345-6789'
|
9
|
+
#
|
10
|
+
# Exclusive vs. Inclusive
|
11
|
+
#
|
12
|
+
# [start_index: 4, end_index: 6, exclusive: false] => '345'
|
13
|
+
# [start_index: 4, end_index: 6, exclusive: true] => '34'
|
14
|
+
#
|
15
|
+
# Default Values / Omitted Options
|
16
|
+
#
|
17
|
+
# [end_index: 6] => '012-345'
|
18
|
+
# [start_index: 4] => '345-6789'
|
19
|
+
class Substring
|
20
|
+
acts_as_hashable
|
21
|
+
|
22
|
+
DEFAULT_END_INDEX = -1
|
23
|
+
DEFAULT_START_INDEX = 0
|
24
|
+
|
25
|
+
attr_reader :end_index, :exclusive, :start_index
|
26
|
+
|
27
|
+
def initialize(
|
28
|
+
end_index: DEFAULT_END_INDEX,
|
29
|
+
exclusive: false,
|
30
|
+
start_index: DEFAULT_START_INDEX
|
31
|
+
)
|
32
|
+
@end_index = end_index.to_i
|
33
|
+
@exclusive = exclusive || false
|
34
|
+
@start_index = start_index.to_i
|
35
|
+
|
36
|
+
freeze
|
37
|
+
end
|
38
|
+
|
39
|
+
def transform(_resolver, value, _time, _record)
|
40
|
+
exclusive ? value.to_s[start_index...end_index] : value.to_s[start_index..end_index]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -14,7 +14,7 @@ module Realize
|
|
14
14
|
|
15
15
|
attr_reader :cases, :default_transformers, :key
|
16
16
|
|
17
|
-
def initialize(cases: [], default_transformers: []
|
17
|
+
def initialize(key:, cases: [], default_transformers: [])
|
18
18
|
raise ArgumentError, 'key is required' if key.to_s.empty?
|
19
19
|
|
20
20
|
@cases = Case.array(cases)
|
data/lib/realize/transformers.rb
CHANGED
@@ -4,19 +4,30 @@ require_relative 'collection/at_index'
|
|
4
4
|
require_relative 'collection/first'
|
5
5
|
require_relative 'collection/last'
|
6
6
|
require_relative 'collection/sort'
|
7
|
+
|
7
8
|
require_relative 'filter/by_key_record_value'
|
8
9
|
require_relative 'filter/by_key_value'
|
9
10
|
require_relative 'filter/by_key_value_presence'
|
10
11
|
require_relative 'filter/inactive'
|
12
|
+
|
11
13
|
require_relative 'format/date'
|
12
14
|
require_relative 'format/remove_whitespace'
|
13
15
|
require_relative 'format/string_replace'
|
16
|
+
require_relative 'format/string_template'
|
17
|
+
require_relative 'format/substring'
|
18
|
+
|
14
19
|
require_relative 'logical/switch'
|
20
|
+
|
21
|
+
require_relative 'type/boolean'
|
22
|
+
require_relative 'type/string'
|
23
|
+
|
15
24
|
require_relative 'value/blank'
|
16
25
|
require_relative 'value/map'
|
26
|
+
require_relative 'value/now'
|
17
27
|
require_relative 'value/null'
|
18
28
|
require_relative 'value/resolve'
|
19
29
|
require_relative 'value/static'
|
30
|
+
require_relative 'value/uuid'
|
20
31
|
require_relative 'value/verbatim'
|
21
32
|
|
22
33
|
module Realize
|
@@ -27,24 +38,34 @@ module Realize
|
|
27
38
|
class Transformers
|
28
39
|
acts_as_hashable_factory
|
29
40
|
|
30
|
-
register '', Value::Verbatim
|
31
41
|
register 'r/collection/at_index', Collection::AtIndex
|
32
42
|
register 'r/collection/first', Collection::First
|
33
43
|
register 'r/collection/last', Collection::Last
|
34
44
|
register 'r/collection/sort', Collection::Sort
|
45
|
+
|
35
46
|
register 'r/filter/by_key_record_value', Filter::ByKeyRecordValue
|
36
47
|
register 'r/filter/by_key_value', Filter::ByKeyValue
|
37
48
|
register 'r/filter/by_key_value_presence', Filter::ByKeyValuePresence
|
38
49
|
register 'r/filter/inactive', Filter::Inactive
|
50
|
+
|
39
51
|
register 'r/format/date', Format::Date
|
40
52
|
register 'r/format/remove_whitespace', Format::RemoveWhitespace
|
41
53
|
register 'r/format/string_replace', Format::StringReplace
|
54
|
+
register 'r/format/string_template', Format::StringTemplate
|
55
|
+
register 'r/format/substring', Format::Substring
|
56
|
+
|
42
57
|
register 'r/logical/switch', Logical::Switch
|
58
|
+
|
59
|
+
register 'r/type/boolean', Type::Boolean
|
60
|
+
register 'r/type/string', Type::String
|
61
|
+
|
43
62
|
register 'r/value/blank', Value::Blank
|
44
63
|
register 'r/value/map', Value::Map
|
64
|
+
register 'r/value/now', Value::Now
|
45
65
|
register 'r/value/null', Value::Null
|
46
66
|
register 'r/value/resolve', Value::Resolve
|
47
67
|
register 'r/value/static', Value::Static
|
48
|
-
register 'r/value/
|
68
|
+
register 'r/value/uuid', Value::Uuid
|
69
|
+
register 'r/value/verbatim', '', Value::Verbatim
|
49
70
|
end
|
50
71
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Realize
|
4
|
+
class Type
|
5
|
+
# Convert input into either true, false, or nil.
|
6
|
+
# By default nils will return false unless nullable: true is passed in.
|
7
|
+
# This transformer is very liberal in its parsing and will return true for:
|
8
|
+
# true, 'true', 't', 'TRUE', 'True', 1, '1', 'Y', 'yes', 'Yes', 'YES'
|
9
|
+
# All other non-truthy values will evaluate to false, such as:
|
10
|
+
# false, 'false', 'f', 'FALSE', 'False', 0, '0', 'N', 'no', 'No', 'NO', {}, [], '',
|
11
|
+
# 'abc', 123, :abc, etc...
|
12
|
+
class Boolean
|
13
|
+
acts_as_hashable
|
14
|
+
|
15
|
+
attr_reader :nullable
|
16
|
+
|
17
|
+
def initialize(nullable: false)
|
18
|
+
@nullable = nullable || false
|
19
|
+
end
|
20
|
+
|
21
|
+
def transform(_resolver, value, _time, _record)
|
22
|
+
if nullable && value.nil?
|
23
|
+
nil
|
24
|
+
elsif truthy?(value)
|
25
|
+
true
|
26
|
+
else
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def truthy?(value)
|
34
|
+
value.to_s.match?(/(true|t|yes|y|1)$/i)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Realize
|
4
|
+
class Type
|
5
|
+
# Call #to_s on the value and return result.
|
6
|
+
class String
|
7
|
+
acts_as_hashable
|
8
|
+
|
9
|
+
attr_reader :nullable
|
10
|
+
|
11
|
+
def initialize(nullable: false)
|
12
|
+
@nullable = nullable || false
|
13
|
+
end
|
14
|
+
|
15
|
+
def transform(_resolver, value, _time, _record)
|
16
|
+
return nil if nullable && value.nil?
|
17
|
+
|
18
|
+
value.to_s
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Realize
|
4
|
+
class Value
|
5
|
+
# Return a current Time object.
|
6
|
+
class Now
|
7
|
+
acts_as_hashable
|
8
|
+
|
9
|
+
DEFAULT_UTC_OFFSET = '+00:00'
|
10
|
+
|
11
|
+
attr_reader :utc_offset
|
12
|
+
|
13
|
+
def initialize(utc_offset: DEFAULT_UTC_OFFSET)
|
14
|
+
@utc_offset = utc_offset || DEFAULT_UTC_OFFSET
|
15
|
+
|
16
|
+
freeze
|
17
|
+
end
|
18
|
+
|
19
|
+
def transform(_resolver, _value, _time, _record)
|
20
|
+
Time.now.utc.localtime(utc_offset)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/realize/version.rb
CHANGED
data/realize.gemspec
CHANGED
@@ -30,12 +30,13 @@ Gem::Specification.new do |s|
|
|
30
30
|
|
31
31
|
s.add_dependency('acts_as_hashable', '~>1', '>=1.2.0')
|
32
32
|
s.add_dependency('objectable', '~>1')
|
33
|
+
s.add_dependency('stringento', '~>2.1')
|
33
34
|
|
34
35
|
s.add_development_dependency('guard-rspec', '~>4.7')
|
35
36
|
s.add_development_dependency('pry', '~>0')
|
36
37
|
s.add_development_dependency('rake', '~> 13')
|
37
38
|
s.add_development_dependency('rspec')
|
38
|
-
s.add_development_dependency('rubocop', '~>
|
39
|
+
s.add_development_dependency('rubocop', '~>1.1')
|
39
40
|
s.add_development_dependency('simplecov', '~>0.17.0')
|
40
41
|
s.add_development_dependency('simplecov-console', '~>0.6.0')
|
41
42
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: realize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Ruggio
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-11-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: acts_as_hashable
|
@@ -45,6 +45,20 @@ dependencies:
|
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '1'
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: stringento
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.1'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.1'
|
48
62
|
- !ruby/object:Gem::Dependency
|
49
63
|
name: guard-rspec
|
50
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,14 +121,14 @@ dependencies:
|
|
107
121
|
requirements:
|
108
122
|
- - "~>"
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
124
|
+
version: '1.1'
|
111
125
|
type: :development
|
112
126
|
prerelease: false
|
113
127
|
version_requirements: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
129
|
- - "~>"
|
116
130
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
131
|
+
version: '1.1'
|
118
132
|
- !ruby/object:Gem::Dependency
|
119
133
|
name: simplecov
|
120
134
|
requirement: !ruby/object:Gem::Requirement
|
@@ -179,15 +193,21 @@ files:
|
|
179
193
|
- lib/realize/format/date.rb
|
180
194
|
- lib/realize/format/remove_whitespace.rb
|
181
195
|
- lib/realize/format/string_replace.rb
|
196
|
+
- lib/realize/format/string_template.rb
|
197
|
+
- lib/realize/format/substring.rb
|
182
198
|
- lib/realize/logical/switch.rb
|
183
199
|
- lib/realize/logical/switch/case.rb
|
184
200
|
- lib/realize/pipeline.rb
|
185
201
|
- lib/realize/transformers.rb
|
202
|
+
- lib/realize/type/boolean.rb
|
203
|
+
- lib/realize/type/string.rb
|
186
204
|
- lib/realize/value/blank.rb
|
187
205
|
- lib/realize/value/map.rb
|
206
|
+
- lib/realize/value/now.rb
|
188
207
|
- lib/realize/value/null.rb
|
189
208
|
- lib/realize/value/resolve.rb
|
190
209
|
- lib/realize/value/static.rb
|
210
|
+
- lib/realize/value/uuid.rb
|
191
211
|
- lib/realize/value/verbatim.rb
|
192
212
|
- lib/realize/version.rb
|
193
213
|
- realize.gemspec
|