eco-helpers 3.2.5 → 3.2.7
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/CHANGELOG.md +25 -1
- data/lib/eco/api/organization/node_classifications.rb +2 -1
- data/lib/eco/api/organization/tag_tree.rb +6 -11
- data/lib/eco/api/usecases/graphql/helpers/location/base/classifications_parser.rb +23 -15
- data/lib/eco/data/locations/node_base/builder.rb +8 -4
- data/lib/eco/data/locations/node_base/parsing.rb +16 -5
- data/lib/eco/data/locations/node_base/tag_validations.rb +8 -3
- data/lib/eco/data/locations/node_base/treeify.rb +20 -1
- data/lib/eco/data/locations/node_base.rb +6 -1
- data/lib/eco/data/locations/node_level/parsing.rb +4 -1
- data/lib/eco/data/locations/node_level.rb +13 -5
- data/lib/eco/data/locations/node_plain/parsing.rb +4 -1
- data/lib/eco/data/locations/node_plain.rb +19 -14
- data/lib/eco/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfe97cd5583e8650f73c0f7cb2557fde896d3b59b7e729703fdb01f9323d6fbb
|
4
|
+
data.tar.gz: e40c8fdeae21780ca957c043aa7a637d06d9e85088fdbca6eb7c488448c74ab5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1f28e77164e7f8c439b09dba5d952594c34721457842963cfb9e037c90658de8049545c1029e25e6aa2aadda2a729a4fc103fb04335adcfb6359b1fe946ad60
|
7
|
+
data.tar.gz: '090c4c12745401c0191aec263bb3970bd92e5244c6b57f4d5ef6dd157acab37ab868ed239972d133bd52a4eb11ddcac0e4857a8e760e10321b7236f50a7d3c76'
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
-
## [3.2.
|
5
|
+
## [3.2.8] - 2025-09-xx
|
6
6
|
|
7
7
|
### Added
|
8
8
|
|
@@ -10,6 +10,30 @@ All notable changes to this project will be documented in this file.
|
|
10
10
|
|
11
11
|
### Fixed
|
12
12
|
|
13
|
+
## [3.2.7] - 2025-09-09
|
14
|
+
|
15
|
+
### Added
|
16
|
+
|
17
|
+
- `NodeBase` (and subclasses): **added** missed case `#self_parented?`
|
18
|
+
|
19
|
+
### Fixed
|
20
|
+
|
21
|
+
- **Added** early detection of `self-parented` nodes (from the input file).
|
22
|
+
|
23
|
+
## [3.2.6] - 2025-09-05
|
24
|
+
|
25
|
+
### Added
|
26
|
+
|
27
|
+
- **Improvement**: classifications conversion to ignore ending `s` (plurals).
|
28
|
+
|
29
|
+
### Fixed
|
30
|
+
|
31
|
+
- Node `id` and `parent_id` **upcase** in `NodePlain` (**case insensitive**)
|
32
|
+
- It was failing to pair children with their parent (on input files).
|
33
|
+
- **remove** _classifications treatment_ on `Organization::TagTree` and `NodePlain`
|
34
|
+
- This was a working around due to not using `as_nodes_json` as a **common** converter between `live_tree` and `file_tree` (which was fixed in a previous release).
|
35
|
+
- `as_nodes_json` already does the call to `node_parser_block`, which does the conversion of the **classifications**
|
36
|
+
|
13
37
|
## [3.2.5] - 2025-09-04
|
14
38
|
|
15
39
|
### Changed
|
@@ -66,10 +66,11 @@ module Eco
|
|
66
66
|
treat_classication(val)
|
67
67
|
end
|
68
68
|
|
69
|
+
# Enhances the lookup
|
69
70
|
def treat_classication(value)
|
70
71
|
return value unless value.is_a?(String)
|
71
72
|
|
72
|
-
value.strip.gsub(/\W+/, '')
|
73
|
+
value.strip.downcase.gsub(/s(?:\W|$)/, '').gsub(/\W+/, '-')
|
73
74
|
end
|
74
75
|
|
75
76
|
def init_caches
|
@@ -211,9 +211,9 @@ module Eco
|
|
211
211
|
&block
|
212
212
|
)
|
213
213
|
max_depth ||= total_depth
|
214
|
-
return
|
215
|
-
return []
|
216
|
-
return
|
214
|
+
return if max_depth < depth
|
215
|
+
return [] if top? && !include_children
|
216
|
+
return if archived? && !include_archived
|
217
217
|
|
218
218
|
if include_children
|
219
219
|
child_nodes = nodes
|
@@ -441,14 +441,13 @@ module Eco
|
|
441
441
|
|
442
442
|
def init_node
|
443
443
|
return if source.is_a?(Array)
|
444
|
+
|
444
445
|
@id = source.values_at('tag', 'id').compact.first&.upcase
|
445
446
|
@name = source['name']
|
446
447
|
@weight = source['weight']
|
447
448
|
@archived = as_boolean(source['archived'])
|
448
449
|
@archived_token = source['archived_token']
|
449
|
-
@classifications = into_a(source['classifications'])
|
450
|
-
treat_classication(value)
|
451
|
-
end
|
450
|
+
@classifications = into_a(source['classifications'])
|
452
451
|
@classification_names = into_a(source['classification_names'])
|
453
452
|
@raw_nodes = source['nodes'] || []
|
454
453
|
end
|
@@ -491,11 +490,6 @@ module Eco
|
|
491
490
|
[tnodes, ddepth]
|
492
491
|
end
|
493
492
|
|
494
|
-
def treat_classication(value)
|
495
|
-
return value unless value.is_a?(String)
|
496
|
-
value.strip.gsub(/\W+/, '').downcase
|
497
|
-
end
|
498
|
-
|
499
493
|
# Helper to convert to array
|
500
494
|
def into_a(value)
|
501
495
|
if value.is_a?(String)
|
@@ -510,6 +504,7 @@ module Eco
|
|
510
504
|
return true if value == true
|
511
505
|
return false if value.to_s.strip.empty?
|
512
506
|
return true if %w[yes x true].include?(value.downcase)
|
507
|
+
|
513
508
|
false
|
514
509
|
end
|
515
510
|
end
|
@@ -5,39 +5,46 @@ module Eco::API::UseCases::GraphQL::Helpers::Location
|
|
5
5
|
|
6
6
|
private
|
7
7
|
|
8
|
+
def to_classification_ids(values)
|
9
|
+
values = [values].flatten unless values.is_a?(Array)
|
10
|
+
|
11
|
+
values = values.compact.map {|val| val.split('|')}.flatten
|
12
|
+
values.compact.map {|val| to_classification(val)}.compact.uniq
|
13
|
+
end
|
14
|
+
|
8
15
|
# @note
|
9
16
|
# 1. It returns `nil` unless there are classifications defined
|
10
17
|
# 2. If the value is wrong, it warns and returns `nil`
|
11
18
|
def to_classification(value)
|
12
|
-
return
|
19
|
+
return unless node_classifications?
|
13
20
|
|
14
|
-
|
21
|
+
msg = "Expecting a single element. Given: #{value.class}"
|
22
|
+
raise ArgumentError, msg if value.is_a?(Enumerator)
|
15
23
|
|
16
|
-
return
|
24
|
+
return unless value.is_a?(String)
|
17
25
|
|
18
26
|
node_classifications.to_id(value).tap do |type|
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
27
|
+
next if type
|
22
28
|
|
23
|
-
|
24
|
-
|
25
|
-
values = values.compact.map {|val| val.split('|')}.flatten
|
26
|
-
values.compact.map {|val| to_classification(val)}.compact.uniq
|
29
|
+
unknown_classification!(value)
|
30
|
+
end
|
27
31
|
end
|
28
32
|
|
29
33
|
# @note
|
30
34
|
# 1. It returns `nil` unless there are classifications defined
|
31
35
|
# 2. If the value is wrong, it warns and returns `nil`
|
32
36
|
def to_classification_name(value)
|
33
|
-
return
|
37
|
+
return unless node_classifications?
|
34
38
|
|
35
|
-
|
39
|
+
msg = "Expecting a single element. Given: #{value.class}"
|
40
|
+
raise ArgumentError, msg if value.is_a?(Enumerator)
|
36
41
|
|
37
|
-
return
|
42
|
+
return unless value.is_a?(String)
|
38
43
|
|
39
44
|
node_classifications.to_name(value) do |name|
|
40
|
-
|
45
|
+
next unless name
|
46
|
+
|
47
|
+
unknown_classification!(value)
|
41
48
|
end
|
42
49
|
end
|
43
50
|
|
@@ -49,10 +56,11 @@ module Eco::API::UseCases::GraphQL::Helpers::Location
|
|
49
56
|
@node_classifications ||= session.node_classifications
|
50
57
|
end
|
51
58
|
|
52
|
-
def
|
59
|
+
def unknown_classification!(value)
|
53
60
|
return if unknown_classifications.include?(value)
|
54
61
|
|
55
62
|
unknown_classifications << value
|
63
|
+
|
56
64
|
log(:warn) {
|
57
65
|
"Unknown location node classification '#{value}'"
|
58
66
|
}
|
@@ -11,15 +11,19 @@ module Eco::Data::Locations::NodeBase
|
|
11
11
|
case data
|
12
12
|
when ::CSV::Table
|
13
13
|
return Eco::Data::Locations::NodePlain if Eco::Data::Locations::NodePlain.csv_matches_format?(csv)
|
14
|
-
|
14
|
+
|
15
|
+
Eco::Data::Locations::NodeLevel if Eco::Data::Locations::NodeLevel.csv_matches_format?(csv)
|
15
16
|
when Array
|
16
|
-
return
|
17
|
+
return unless (sample = data.first)
|
18
|
+
|
17
19
|
node_class(sample)
|
18
20
|
when Eco::Data::Locations::NodeBase
|
19
|
-
return
|
21
|
+
return unless data.class < Eco::Data::Locations::NodeBase
|
22
|
+
|
20
23
|
data.class
|
21
24
|
else
|
22
|
-
|
25
|
+
msg ="Expecting CSV::Table. Given: #{csv.class}"
|
26
|
+
raise ArgumentError, msg unless csv.is_a?(::CSV::Table)
|
23
27
|
end
|
24
28
|
end
|
25
29
|
end
|
@@ -6,10 +6,19 @@ module Eco::Data::Locations::NodeBase
|
|
6
6
|
# @param csv [CSV::Table]
|
7
7
|
# @return [Array<NodePlain>, Array<NodeLevel>] with integrity issues resolved.
|
8
8
|
def nodes_from_csv(csv)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
msg = "Expecting CSV::Table. Given: #{csv.class}"
|
10
|
+
raise ArgumentError, msg unless csv.is_a?(::CSV::Table)
|
11
|
+
|
12
|
+
if Eco::Data::Locations::NodePlain.csv_matches_format?(csv)
|
13
|
+
return Eco::Data::Locations::NodePlain.nodes_from_csv(csv)
|
14
|
+
end
|
15
|
+
|
16
|
+
if Eco::Data::Locations::NodeLevel.csv_matches_format?(csv)
|
17
|
+
return Eco::Data::Locations::NodeLevel.nodes_from_csv(csv)
|
18
|
+
end
|
19
|
+
|
20
|
+
msg = "The input csv does not have the required format to read a locations structure."
|
21
|
+
raise ArgumentError, msg
|
13
22
|
end
|
14
23
|
|
15
24
|
# @yield [node, json] optional custom serializer
|
@@ -18,7 +27,9 @@ module Eco::Data::Locations::NodeBase
|
|
18
27
|
# @yieldreturn [Hash] the serialized Node
|
19
28
|
# @return [Array<Hash>] a hierarchical tree of nested Hashes via `nodes` key.
|
20
29
|
def hash_tree_from_csv(csv, &block)
|
21
|
-
|
30
|
+
msg = "Expecting CSV::Table. Given: #{csv.class}"
|
31
|
+
raise ArgumentError, msg unless csv.is_a?(::CSV::Table)
|
32
|
+
|
22
33
|
treeify(nodes_from_csv(csv), &block)
|
23
34
|
end
|
24
35
|
|
@@ -2,7 +2,7 @@ module Eco::Data::Locations::NodeBase
|
|
2
2
|
module TagValidations
|
3
3
|
include Eco::Language::AuxiliarLogger
|
4
4
|
|
5
|
-
ALLOWED_CHARACTERS = "A-Za-z0-9 &_'
|
5
|
+
ALLOWED_CHARACTERS = "A-Za-z0-9 &_'/.-".freeze
|
6
6
|
VALID_TAG_REGEX = /^[#{ALLOWED_CHARACTERS}]+$/
|
7
7
|
INVALID_TAG_REGEX = /[^#{ALLOWED_CHARACTERS}]+/
|
8
8
|
VALID_TAG_CHARS = /[#{ALLOWED_CHARACTERS}]+/
|
@@ -11,9 +11,11 @@ module Eco::Data::Locations::NodeBase
|
|
11
11
|
def clean_id(str, notify: true, ref: '')
|
12
12
|
blanks_x2 = has_double_blanks?(str) # dubocop:disable Naming/VariableNumber
|
13
13
|
partial = replace_not_allowed(str)
|
14
|
+
|
14
15
|
remove_double_blanks(partial).tap do |result|
|
15
16
|
next unless notify
|
16
17
|
next if invalid_warned?(str)
|
18
|
+
|
17
19
|
if partial != str
|
18
20
|
invalid_chars = identify_invalid_characters(str)
|
19
21
|
log(:warn) {
|
@@ -24,6 +26,7 @@ module Eco::Data::Locations::NodeBase
|
|
24
26
|
"* #{ref}Double blanks removed: '#{str}' :_converted_>> '#{result}'"
|
25
27
|
}
|
26
28
|
end
|
29
|
+
|
27
30
|
invalid_warned!(str)
|
28
31
|
end
|
29
32
|
end
|
@@ -46,13 +49,15 @@ module Eco::Data::Locations::NodeBase
|
|
46
49
|
end
|
47
50
|
|
48
51
|
def remove_double_blanks(str)
|
49
|
-
return
|
52
|
+
return if str.nil?
|
53
|
+
|
50
54
|
str.gsub(DOUBLE_BLANKS, ' ').strip
|
51
55
|
end
|
52
56
|
|
53
57
|
def replace_not_allowed(str)
|
54
|
-
return
|
58
|
+
return if str.nil?
|
55
59
|
return str if str.match(VALID_TAG_REGEX)
|
60
|
+
|
56
61
|
str.gsub(INVALID_TAG_REGEX, ' ')
|
57
62
|
end
|
58
63
|
|
@@ -28,10 +28,12 @@ module Eco::Data::Locations::NodeBase
|
|
28
28
|
# @return [Array<Hash>] a hierarchical tree of nested Hashes via `nodes` key.
|
29
29
|
def treeify(nodes, skipped: [], unlinked_trees: [], &block)
|
30
30
|
return [] if nodes.empty?
|
31
|
+
|
31
32
|
block ||= nodes.first.class.serializer
|
32
33
|
done_ids = {}
|
33
34
|
warns = []
|
34
35
|
parents = parents_hash(nodes)
|
36
|
+
|
35
37
|
get_children(
|
36
38
|
nil, parents,
|
37
39
|
done_ids: done_ids, skipped: skipped,
|
@@ -43,6 +45,7 @@ module Eco::Data::Locations::NodeBase
|
|
43
45
|
skipped: skipped, unlinked_trees: unlinked_trees,
|
44
46
|
warns: warns, &block
|
45
47
|
)
|
48
|
+
|
46
49
|
log(:warn) { warns.join("\n") } unless warns.empty?
|
47
50
|
end
|
48
51
|
end
|
@@ -52,8 +55,25 @@ module Eco::Data::Locations::NodeBase
|
|
52
55
|
# @return [Hash] where `key`s are all the `parentId` of the nodes
|
53
56
|
# and `value` and `Array` of those nodes that have that `parentId`
|
54
57
|
def parents_hash(nodes)
|
58
|
+
self_parented = []
|
59
|
+
|
55
60
|
nodes.each_with_object({}) do |node, parents|
|
61
|
+
next self_parented.push(node) if node.self_parented?
|
62
|
+
|
56
63
|
(parents[node.parentId] ||= []).push(node)
|
64
|
+
end.tap do
|
65
|
+
next if self_parented.empty?
|
66
|
+
|
67
|
+
log(:error) {
|
68
|
+
msg = "#{self_parented.count} nodes are self-parented: "
|
69
|
+
msg << self_parented.map(&:id).map do |node_id|
|
70
|
+
"'#{node_id}'"
|
71
|
+
end.join(', ')
|
72
|
+
msg << "\nPlease amend the data."
|
73
|
+
msg
|
74
|
+
}
|
75
|
+
|
76
|
+
exit 1
|
57
77
|
end
|
58
78
|
end
|
59
79
|
|
@@ -135,7 +155,6 @@ module Eco::Data::Locations::NodeBase
|
|
135
155
|
# skipped keys is inherent, as they were excluded because of id clash with done_ids
|
136
156
|
unlinked_parent_ids = (parents.keys - done_ids.keys).compact
|
137
157
|
|
138
|
-
|
139
158
|
# The reason of missing nodes in the output tree is unknown!
|
140
159
|
if skipped.empty? && unlinked_parent_ids.empty?
|
141
160
|
msg = []
|
@@ -14,6 +14,10 @@ module Eco::Data::Locations
|
|
14
14
|
|
15
15
|
attr_accessor :tracked_level, :parent
|
16
16
|
|
17
|
+
def self_parented?
|
18
|
+
raise 'You should implement this method in child classes'
|
19
|
+
end
|
20
|
+
|
17
21
|
def copy
|
18
22
|
self.class.new.set_attrs(**to_h)
|
19
23
|
end
|
@@ -23,7 +27,7 @@ module Eco::Data::Locations
|
|
23
27
|
end
|
24
28
|
|
25
29
|
def attr?(sym)
|
26
|
-
!attr(sym).to_s.strip.empty?
|
30
|
+
!attr(sym).to_s.strip.empty? # rubocop:disable Style/Attr
|
27
31
|
end
|
28
32
|
|
29
33
|
def set_attrs(**kargs)
|
@@ -57,6 +61,7 @@ module Eco::Data::Locations
|
|
57
61
|
|
58
62
|
def slice(*attrs)
|
59
63
|
return {} if attrs.empty?
|
64
|
+
|
60
65
|
to_h(*attrs)
|
61
66
|
end
|
62
67
|
end
|
@@ -17,6 +17,7 @@ class Eco::Data::Locations::NodeLevel
|
|
17
17
|
# @return [Boolean] whether or not it's worthy trying to parse with `NodeLevel`.
|
18
18
|
def csv_matches_format?(csv)
|
19
19
|
return false unless csv.is_a?(::CSV::Table)
|
20
|
+
|
20
21
|
!Eco::Data::Locations::NodePlain.csv_matches_format?(csv)
|
21
22
|
end
|
22
23
|
|
@@ -26,7 +27,8 @@ class Eco::Data::Locations::NodeLevel
|
|
26
27
|
# @param `csv` [CSV::Table]
|
27
28
|
# @return [Array<NodeLevel>]
|
28
29
|
def nodes_from_csv(csv)
|
29
|
-
|
30
|
+
msg = "Expecting CSV::Table. Given: #{csv.class}"
|
31
|
+
raise ArgumentError, msg unless csv.is_a?(::CSV::Table)
|
30
32
|
|
31
33
|
possible_classifications = csv.headers
|
32
34
|
|
@@ -52,6 +54,7 @@ class Eco::Data::Locations::NodeLevel
|
|
52
54
|
|
53
55
|
prev_node = node
|
54
56
|
end
|
57
|
+
|
55
58
|
tidy_nodes(nodes)
|
56
59
|
end
|
57
60
|
end
|
@@ -36,15 +36,23 @@ module Eco::Data::Locations
|
|
36
36
|
end
|
37
37
|
|
38
38
|
# In node level the parent id is set via parsing
|
39
|
-
|
40
|
-
alias_method :
|
41
|
-
|
39
|
+
attr_writer :parent_id
|
40
|
+
alias_method :parentId=, :parent_id= # rubocop:disable Naming/MethodName
|
41
|
+
|
42
|
+
def parent_id
|
43
|
+
@parent_id&.upcase
|
44
|
+
end
|
45
|
+
alias_method :parentId, :parent_id # rubocop:disable Naming/MethodName
|
42
46
|
|
43
47
|
def id
|
44
48
|
tag.upcase
|
45
49
|
end
|
46
|
-
alias_method :
|
47
|
-
alias_method :
|
50
|
+
alias_method :node_id, :id
|
51
|
+
alias_method :nodeId, :id # rubocop:disable Naming/MethodName
|
52
|
+
|
53
|
+
def self_parented?
|
54
|
+
id == parent_id
|
55
|
+
end
|
48
56
|
|
49
57
|
def name
|
50
58
|
tag
|
@@ -16,6 +16,7 @@ class Eco::Data::Locations::NodePlain
|
|
16
16
|
# @return [Boolean] whether or not it's worthy trying to parse with `NodePlain`.
|
17
17
|
def csv_matches_format?(csv)
|
18
18
|
return false unless csv.is_a?(::CSV::Table)
|
19
|
+
|
19
20
|
(basic_headers & csv.headers) == basic_headers
|
20
21
|
end
|
21
22
|
|
@@ -23,7 +24,9 @@ class Eco::Data::Locations::NodePlain
|
|
23
24
|
# @param `csv` [CSV::Table] with specific headers
|
24
25
|
# @return [Array<NodePlain>]
|
25
26
|
def nodes_from_csv(csv)
|
26
|
-
|
27
|
+
msg = "Expecting CSV::Table. Given: #{csv.class}"
|
28
|
+
raise ArgumentError, msg unless csv.is_a?(::CSV::Table)
|
29
|
+
|
27
30
|
# Convert to Eco::CSV::Table for a fresh start
|
28
31
|
csv = Eco::CSV.parse(csv.to_csv).nil_blank_cells.add_index_column(:row_num)
|
29
32
|
headers = node_class::ALL_ATTRS.map(&:to_s)
|
@@ -22,19 +22,30 @@ module Eco::Data::Locations
|
|
22
22
|
PROP_ATTRS = (ALL_ATTRS - ADDITIONAL_ATTRS).freeze
|
23
23
|
|
24
24
|
def id
|
25
|
-
clean_id(
|
25
|
+
clean_id(
|
26
|
+
super,
|
27
|
+
ref: "(Row: #{row_num}) "
|
28
|
+
)&.upcase
|
26
29
|
end
|
27
30
|
# backwards compatibility
|
28
31
|
alias_method :tag, :id
|
29
32
|
|
30
|
-
def
|
31
|
-
|
33
|
+
def parent_id
|
34
|
+
clean_id(
|
35
|
+
super,
|
36
|
+
notify: false,
|
37
|
+
ref: "(Row: #{row_num} - parent_id) "
|
38
|
+
)&.upcase
|
32
39
|
end
|
40
|
+
alias_method :parentId, :parent_id # rubocop:disable Naming/MethodName
|
33
41
|
|
34
|
-
def
|
35
|
-
|
42
|
+
def self_parented?
|
43
|
+
id == parent_id
|
44
|
+
end
|
45
|
+
|
46
|
+
def name
|
47
|
+
super || id
|
36
48
|
end
|
37
|
-
alias_method :parentId, :parent_id
|
38
49
|
|
39
50
|
def archived
|
40
51
|
value = super
|
@@ -42,13 +53,12 @@ module Eco::Data::Locations
|
|
42
53
|
return true if value == true
|
43
54
|
return false if value.to_s.strip.empty?
|
44
55
|
return true if %w[yes x true].include?(value.downcase)
|
56
|
+
|
45
57
|
false
|
46
58
|
end
|
47
59
|
|
48
60
|
def classifications
|
49
|
-
into_a(super)
|
50
|
-
treat_classication(value)
|
51
|
-
end
|
61
|
+
into_a(super)
|
52
62
|
end
|
53
63
|
|
54
64
|
def classification_names
|
@@ -68,11 +78,6 @@ module Eco::Data::Locations
|
|
68
78
|
|
69
79
|
private
|
70
80
|
|
71
|
-
def treat_classication(value)
|
72
|
-
return value unless value.is_a?(String)
|
73
|
-
value.strip.gsub(/\W+/, '').downcase
|
74
|
-
end
|
75
|
-
|
76
81
|
# Helper to convert to array
|
77
82
|
def into_a(value)
|
78
83
|
if value.is_a?(String)
|
data/lib/eco/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eco-helpers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oscar Segura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-09-
|
11
|
+
date: 2025-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: byebug
|