error_normalizer 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4035feeceb8c759e702989ff2d013b40a935fcf4b4ca2afe79b9742738ff39a6
4
- data.tar.gz: f7235ca637c3503f126ff091724d80d672462b08b6b7ade550bba1ad4ab801ef
3
+ metadata.gz: 6f05b5d39eabbca2f54ec830fff3ba92e575d7d1cd18fb8245a22958213e8d26
4
+ data.tar.gz: fea06df20e65dea4222593aa9f13c3c6a2254f4d39a5f5764362f96f84243e16
5
5
  SHA512:
6
- metadata.gz: 252e4a3d03e3c1a1f190c77774fa0ca2ac23adb6ca5bd02afc93a9e7cc4fbe819c63fee1c98c6fee7d9d0a4a485032773a2b56f935b16b8c7d958a17bb9cc7da
7
- data.tar.gz: e50077ea3edd89c7c091aa92138f54fd49bc41ac1f0670fbed866c829e63f7094be1b646613f058ff6ea1775713564af7fec106f0c84b85f4a2083dac6dd0e4e
6
+ metadata.gz: d59e524a3e46879e56b675b94b10434336b1433e3db00298a5b42a011fbe32d6ec3e8f7f1315785ed502732436e5057060afeecc83753864d380416c97ef79e6
7
+ data.tar.gz: 47e566c3b25befa7d1b22e5f5fde257466b69d6e5f657c5f227dc661fe487a938a801008a83802b372fb945618f1e54ed0060a3fe985e6d8087fa5b0c6c9c5cd
data/.rubocop.yml CHANGED
@@ -20,6 +20,9 @@ Style/FrozenStringLiteralComment:
20
20
  Style/ModuleFunction:
21
21
  Enabled: false
22
22
 
23
+ Style/LambdaCall:
24
+ Enabled: false
25
+
23
26
  #################### Naming ##########################
24
27
 
25
28
  Naming/AccessorMethodName:
data/Gemfile.lock CHANGED
@@ -8,6 +8,8 @@ GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  ast (2.4.0)
11
+ byebug (10.0.2)
12
+ coderay (1.1.2)
11
13
  concurrent-ruby (1.0.5)
12
14
  diff-lcs (1.3)
13
15
  dry-configurable (0.7.0)
@@ -37,11 +39,20 @@ GEM
37
39
  dry-equalizer (~> 0.2)
38
40
  dry-logic (~> 0.4, >= 0.4.0)
39
41
  dry-types (~> 0.13.1)
42
+ i18n (1.1.1)
43
+ concurrent-ruby (~> 1.0)
40
44
  jaro_winkler (1.5.1)
45
+ method_source (0.9.1)
41
46
  parallel (1.12.1)
42
47
  parser (2.5.1.2)
43
48
  ast (~> 2.4.0)
44
49
  powerpack (0.1.2)
50
+ pry (0.11.3)
51
+ coderay (~> 1.1.0)
52
+ method_source (~> 0.9.0)
53
+ pry-byebug (3.6.0)
54
+ byebug (~> 10.0)
55
+ pry (~> 0.10)
45
56
  rainbow (3.0.0)
46
57
  rake (10.4.2)
47
58
  rspec (3.8.0)
@@ -75,9 +86,11 @@ DEPENDENCIES
75
86
  bundler (~> 1.16)
76
87
  dry-validation (~> 0.12.2)
77
88
  error_normalizer!
89
+ i18n (~> 1)
90
+ pry-byebug (~> 3.6)
78
91
  rake (~> 10.0)
79
92
  rspec (~> 3.0)
80
93
  rubocop (= 0.59.2)
81
94
 
82
95
  BUNDLED WITH
83
- 1.16.6
96
+ 1.17.1
data/README.md CHANGED
@@ -28,6 +28,8 @@ Each error object **must have** 4 required fields: `key`, `type`, `message` and
28
28
 
29
29
  ## Usage
30
30
 
31
+ [DOCUMENTATION](https://www.rubydoc.info/gems/error_normalizer/)
32
+
31
33
  ### dry-validation
32
34
 
33
35
  GIVEN following [dry-validation](https://dry-rb.org/gems/dry-validation/) schema
@@ -138,6 +140,70 @@ You can customize rule name match pattern, type name or turn off this feature co
138
140
  config.type_name = 'rule'
139
141
  end
140
142
 
143
+ #### I18n support
144
+
145
+ ##### Full message translation
146
+
147
+ This feature enables to define localization for schema attributes (think of `path` that you get in `payload`), translate it with I18n and concatenate it with the error messages.
148
+
149
+ schema = Dry::Validation.Schema do
150
+ required(:user).schema do
151
+ required(:favorite_pet).filled(size?: 3..8)
152
+ required(:vessel).schema do
153
+ required(:factory).filled(excluded_from?: ['Bilgewater', 'Shipwreck'])
154
+ end
155
+ end
156
+ end
157
+
158
+ AND following input
159
+
160
+ errors = schema.(user: { favorite_pet: 'Zuckerberg', vessel: { factory: 'Bilgewater' } }).errors
161
+ #=> {:user=>{:favorite_pet=>["length must be within 3 - 8"], :company=>{:name=>["must not be one of: Bilgewater, Shipwreck"]}}}
162
+
163
+ AND following translations loaded in `I18n`
164
+
165
+ en:
166
+ schemas:
167
+ user:
168
+ '@': cap
169
+ favorite_pet: parrot
170
+ vessel:
171
+ '@': ship
172
+ factory: dockyard
173
+
174
+ THEN we can convert it to fully translated errors
175
+
176
+ ErrorNormalizer.normalize(errors, i18n_messages: true)
177
+ # [{
178
+ # :key=>"length_must_be_within",
179
+ # :message=>"Cap parrot length must be within 3 - 8",
180
+ # :payload=>{:path=>"user.favorite_pet", :range=>["3", "15"]},
181
+ # :type=>"params"
182
+ # }, {
183
+ # :key=>"must_not_be_one_of",
184
+ # :message=>"Cap ship dockyard must not be one of: Bilgewater, Shipwreck",
185
+ # :payload=>{:path=>"user.vessel.factory", :list=>["Bilgewater", "Shipwreck"]},
186
+ # :type=>"params"
187
+ # }]
188
+
189
+ You can configure this behaviour globally:
190
+
191
+ ErrorNormalizer.configure do |config|
192
+ config.i18n_messages = true
193
+ end
194
+
195
+ For the i18n lookup rules go check [SchemaPathTranslator documentation](https://www.rubydoc.info/gems/error_normalizer/ErrorNormalizer/SchemaPathTranslator).
196
+
197
+ ##### Non-english error messages
198
+
199
+ If you want to support error messages for the other languages you'll need to define and register localized message parser. You can register it in configuration block:
200
+
201
+ ErrorNormalizer.configure do |config|
202
+ config.message_parsers << RussianMessageParser
203
+ end
204
+
205
+ For message parser implementation please check the [documentation](https://www.rubydoc.info/gems/error_normalizer/ErrorNormalizer/MessageParser) and the source code of `ErrorNormalizer::MessageParser::English`.
206
+
141
207
  ### ActiveModel::Validations
142
208
 
143
209
  ActiveModel errors aren't fully supported. By that I mean errors will be converted to the single format, however you won't see really unique error `key` or `payload` with additional info.
@@ -178,9 +244,9 @@ THEN we can normalize object errors to API error format
178
244
 
179
245
  ## TODO
180
246
 
181
- - plugin to make full error translation
182
247
  - configure Gitlab CI
183
248
  - parse ActiveModel error mesasges
249
+ - support array of errors as an input
184
250
 
185
251
  ## License
186
252
 
@@ -20,9 +20,11 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ['lib']
21
21
 
22
22
  spec.add_runtime_dependency 'dry-configurable', '~> 0.7.0'
23
+ spec.add_development_dependency 'i18n', '~> 1'
23
24
 
24
25
  spec.add_development_dependency 'bundler', '~> 1.16'
25
26
  spec.add_development_dependency 'dry-validation', '~> 0.12.2'
27
+ spec.add_development_dependency 'pry-byebug', '~> 3.6'
26
28
  spec.add_development_dependency 'rake', '~> 10.0'
27
29
  spec.add_development_dependency 'rspec', '~> 3.0'
28
30
  spec.add_development_dependency 'rubocop', '0.59.2'
@@ -2,9 +2,14 @@
2
2
 
3
3
  class ErrorNormalizer
4
4
  #
5
- # Error struct which makes cosmetic normalization
6
- # upon calling either {Error#to_hash} or {Error#to_json}.
7
- # Provides case equality check {Error.===} to support plain Hash structs.
5
+ # Struct which makes cosmetic normalization on calling
6
+ # either {Error#to_hash} or {Error#to_json}.
7
+ #
8
+ # Translates message with path via i18n if
9
+ # corresponding options is passed (see {Error#initialize}).
10
+ #
11
+ # Provides case equality check ({Error.===})
12
+ # to support plain Hash structs.
8
13
  #
9
14
  # @example
10
15
  # Error.new('not_plausible', message: "can't recognize your phone", path: 'user.phone')
@@ -23,10 +28,11 @@ class ErrorNormalizer
23
28
  # puts message #=> 'YEP'
24
29
  #
25
30
  class Error
26
- def initialize(error_key, message: nil, type: 'params', **payload)
31
+ def initialize(error_key, message: nil, type: 'params', i18n_messages: nil, **payload)
27
32
  @key = error_key
28
33
  @message = message
29
34
  @type = type
35
+ @i18n_messages = i18n_messages
30
36
  @payload = payload
31
37
  end
32
38
 
@@ -40,11 +46,23 @@ class ErrorNormalizer
40
46
  h.key?('key') && h.key?('message') && h.key?('payload') && h.key?('type')
41
47
  end
42
48
 
49
+ # Translate message with path via i18n.
50
+ # Delegates path translation to {SchemaPathTranslator}.
51
+ # @return [String]
52
+ def full_message
53
+ return message unless @i18n_messages && @type == 'params'
54
+
55
+ path = payload[:path]
56
+ return if path.nil?
57
+
58
+ translate_path(path)
59
+ end
60
+
43
61
  # @return [Hash] error Hash representation
44
62
  def to_hash
45
63
  {
46
64
  key: @key,
47
- message: message,
65
+ message: full_message,
48
66
  payload: payload,
49
67
  type: @type
50
68
  }
@@ -64,5 +82,12 @@ class ErrorNormalizer
64
82
  def payload
65
83
  @payload.delete_if { |_k, v| v.nil? || v.empty? }
66
84
  end
85
+
86
+ def translate_path(path)
87
+ require 'error_normalizer/schema_path_translator' # do not load if not needed
88
+
89
+ path_translation = SchemaPathTranslator.new(path).translate
90
+ "#{path_translation} #{message}"
91
+ end
67
92
  end
68
93
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'error_normalizer/message_parser'
4
+
5
+ class ErrorNormalizer
6
+ class MessageParser
7
+ #
8
+ # Parser tailored for dry-validation default error messages.
9
+ #
10
+ class English < MessageParser
11
+ locale :en
12
+
13
+ value_matcher :must_not_include, /\A(?<err>must not include) (?<val>.+)/
14
+ value_matcher :must_be_equal_to, /\A(?<err>must be equal to) (?<val>.+)/
15
+ value_matcher :must_not_be_equal_to, /\A(?<err>must not be equal to) (?<val>.+)/
16
+ value_matcher :must_be_greater_than, /\A(?<err>must be greater than) (?<val>\d+)/
17
+ value_matcher :must_be_greater_than_or_equal_to, /\A(?<err>must be greater than or equal to) (?<val>\d+)/
18
+ value_matcher :must_include, /\A(?<err>must include) (?<val>.+)/
19
+ value_matcher :must_be_less_than, /\A(?<err>must be less than) (?<val>\d+)/
20
+ value_matcher :must_be_less_than_or_equal_to, /\A(?<err>must be less than or equal to) (?<val>\d+)/
21
+ value_matcher :size_cannot_be_greater_than, /\A(?<err>size cannot be greater than) (?<val>\d+)/
22
+ value_matcher :size_cannot_be_less_than, /\A(?<err>size cannot be less than) (?<val>\d+)/
23
+ value_matcher :size_must_be, /\A(?<err>size must be) (?<val>\d+)/
24
+ value_matcher :length_must_be, /\A(?<err>length must be) (?<val>\d+)/
25
+
26
+ list_matcher :must_not_be_one_of, /\A(?<err>must not be one of): (?<val>.+)/
27
+ list_matcher :must_be_one_of, /\A(?<err>must be one of): (?<val>.+)/
28
+ list_matcher :size_must_be_within, /\A(?<err>size must be within) (?<val>.+)/
29
+ list_matcher :length_must_be_within, /\A(?<err>length must be within) (?<val>.+)/
30
+ end
31
+ end
32
+ end
@@ -2,7 +2,20 @@
2
2
 
3
3
  class ErrorNormalizer
4
4
  #
5
- # Parse error messages and extract payload metadata.
5
+ # Base implementation of the error message parser.
6
+ # Message parsers attempt to extract key, message and payload from the given message.
7
+ # Instances of {MessageParser} can't parse errors on its own because it does not define
8
+ # any error matchers but it defines all necessary parse logic
9
+ # since it doesn't depend on the locale.
10
+ #
11
+ # You can easily define your own parser by inheriting from {MessageParser}:
12
+ #
13
+ # class RussianMessageParser < ErrorNormalizer::MessageParser
14
+ # locale :ru
15
+ #
16
+ # value_matcher :must_be_equal_to, /(?<err>должен быть равным) (?<val>.+)/u
17
+ # list_matcher :must_be_on_of, /\A(?<err>должен быть одним из): (?<val>.+)/u
18
+ # end
6
19
  #
7
20
  # ActiveModel ignored for now because we don't plan to use its validations.
8
21
  # In case message isn't recognized we set error to be a simple
@@ -13,34 +26,66 @@ class ErrorNormalizer
13
26
  # - {https://github.com/svenfuchs/rails-i18n/blob/70b38b/rails/locale/en-US.yml#L111 ActiveModel::Errors}
14
27
  #
15
28
  class MessageParser
16
- VALUE_MATCHERS = [
17
- /\A(?<err>must not include) (?<val>.+)/,
18
- /\A(?<err>must be equal to) (?<val>.+)/,
19
- /\A(?<err>must not be equal to) (?<val>.+)/,
20
- /\A(?<err>must be greater than) (?<val>\d+)/,
21
- /\A(?<err>must be greater than or equal to) (?<val>\d+)/,
22
- /\A(?<err>must include) (?<val>.+)/,
23
- /\A(?<err>must be less than) (?<val>\d+)/,
24
- /\A(?<err>must be less than or equal to) (?<val>\d+)/,
25
- /\A(?<err>size cannot be greater than) (?<val>\d+)/,
26
- /\A(?<err>size cannot be less than) (?<val>\d+)/,
27
- /\A(?<err>size must be) (?<val>\d+)/,
28
- /\A(?<err>length must be) (?<val>\d+)/
29
- ].freeze
30
-
31
- LIST_MATCHERS = [
32
- /\A(?<err>must not be one of): (?<val>.+)/,
33
- /\A(?<err>must be one of): (?<val>.+)/,
34
- /\A(?<err>size must be within) (?<val>.+)/,
35
- /\A(?<err>length must be within) (?<val>.+)/
36
- ].freeze
29
+ AlreadyDefinedError = Class.new(StandardError)
30
+
31
+ class << self
32
+ # Get or set parser locale
33
+ # @return [Symbol]
34
+ def locale(i18n_locale = nil)
35
+ return @locale if i18n_locale.nil?
36
+
37
+ @locale = i18n_locale.intern
38
+ end
39
+
40
+ # Define message value matcher with a corresponding error key.
41
+ # Value matchers add a "value" property to the error payload.
42
+ # @param key [Symbol] set the error key for a given matcher
43
+ # @param matcher [Regexp] match and extract error and payload via regexp named groups
44
+ # @return [void]
45
+ def value_matcher(key, matcher)
46
+ raise ArgumentError, 'matcher should be a Regexp' unless matcher.is_a?(Regexp)
47
+
48
+ key = key.to_s
49
+ @value_matchers ||= {}
50
+
51
+ raise AlreadyDefinedError if @value_matchers.key?(key)
52
+
53
+ @value_matchers[key] = matcher
54
+ end
55
+
56
+ # Define message list matcher with a corresponding error key.
57
+ # List matchers add a "list" or "range" property to the error payload.
58
+ # @param key [Symbol] set the error key for a given matcher
59
+ # @param matcher [Regexp] match and extract error and payload via regexp named groups
60
+ # @return [void]
61
+ def list_matcher(key, matcher)
62
+ raise ArgumentError, 'matcher should be a Regexp' unless matcher.is_a?(Regexp)
63
+
64
+ key = key.to_s
65
+ @list_matchers ||= {}
66
+
67
+ raise AlreadyDefinedError if @list_matchers.key?(key)
68
+
69
+ @list_matchers[key] = matcher
70
+ end
71
+
72
+ # @return [Hash] value matchers
73
+ attr_reader :value_matchers
74
+
75
+ # @return [Hash] list matchers
76
+ attr_reader :list_matchers
77
+ end
37
78
 
38
79
  def initialize(message)
80
+ @locale = self.class.locale
39
81
  @message = message
40
82
  @key = nil
41
83
  @payload = {}
42
84
  end
43
85
 
86
+ # @return [String] parser locale
87
+ attr_reader :locale
88
+
44
89
  # Parse error message
45
90
  # @return (see #to_a)
46
91
  def parse
@@ -50,7 +95,7 @@ class ErrorNormalizer
50
95
  parse_list_message
51
96
  return to_a if @key
52
97
 
53
- @key = to_key(@message)
98
+ @key = normalize_message(@message)
54
99
  to_a
55
100
  end
56
101
 
@@ -62,30 +107,31 @@ class ErrorNormalizer
62
107
  private
63
108
 
64
109
  def parse_value_message
65
- VALUE_MATCHERS.each do |matcher|
110
+ self.class.value_matchers.each do |(key, matcher)|
66
111
  data = matcher.match(@message)
67
112
  next if data.nil?
68
113
 
69
- @key = to_key(data[:err])
70
- @payload[:value] = data[:val]
114
+ @key = key
115
+ @payload[:value] = data[:val] if data.names.include?('val')
71
116
 
72
117
  break
73
118
  end
74
119
  end
75
120
 
76
121
  def parse_list_message
77
- LIST_MATCHERS.each do |matcher|
122
+ self.class.list_matchers.each do |(key, matcher)|
78
123
  data = matcher.match(@message)
79
124
  next if data.nil?
80
125
 
81
- @key = to_key(data[:err])
82
- @payload.merge!(parse_list_payload(data[:val]))
126
+ @key = key
127
+ @payload.merge!(parse_list_payload(data[:val])) if data.names.include?('val')
83
128
 
84
129
  break
85
130
  end
86
131
  end
87
132
 
88
- def to_key(msg)
133
+ # TODO: fine tune for UTF-8 messages
134
+ def normalize_message(msg)
89
135
  msg.downcase.tr(' ', '_').gsub(/[^a-z0-9_]/, '')
90
136
  end
91
137
 
@@ -63,6 +63,7 @@ class ErrorNormalizer
63
63
 
64
64
  private
65
65
 
66
+ # TODO: support arrays of errors as input
66
67
  def normalize_hash(input) # rubocop:disable AbcSize
67
68
  return add_error(input) if input.is_a?(Error)
68
69
 
@@ -72,7 +73,7 @@ class ErrorNormalizer
72
73
  value.each { |msg| add_error(msg, options) }
73
74
  elsif value.is_a?(Hash)
74
75
  ns = namespaced_path(key)
75
- Normalizer.new(value, namespace: ns).normalize.errors.each { |e| add_error(e) }
76
+ Normalizer.new(value, namespace: ns, **@config).normalize.errors.each { |e| add_error(e) }
76
77
  else
77
78
  raise UnsupportedInputTypeError
78
79
  end
@@ -86,8 +87,8 @@ class ErrorNormalizer
86
87
  end
87
88
 
88
89
  def parse_error(err_message, path, options)
89
- result = MessageParser.new(err_message).parse
90
- key, msg, payload = result.to_a
90
+ options[:i18n_messages] = @config[:i18n_messages] if options[:i18n_messages].nil?
91
+ key, msg, payload = *pick_message_parser.new(err_message).parse
91
92
 
92
93
  Error.new(key, message: msg, path: namespaced_path(path), **payload, **options)
93
94
  end
@@ -111,5 +112,18 @@ class ErrorNormalizer
111
112
 
112
113
  payload.merge!(type: type)
113
114
  end
115
+
116
+ def pick_message_parser # rubocop:disable AbcSize
117
+ find_by_locale = ->(locale) { ->(parser) { parser.locale == locale } }
118
+
119
+ msg_parser = @config[:message_parsers].find(&find_by_locale.(I18n.locale))
120
+ return msg_parser unless msg_parser.nil?
121
+
122
+ warn "No message parser with #{I18n.locale} found, falling back to #{I18n.default_locale}"
123
+ msg_parser = @config[:message_parsers].find(&find_by_locale.(I18n.default_locale))
124
+ return msg_parser unless msg_parser.nil?
125
+
126
+ raise 'No message parser found' if msg_parser.nil?
127
+ end
114
128
  end
115
129
  end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ErrorNormalizer
4
+ #
5
+ # Find I18n locale for the given path.
6
+ #
7
+ class SchemaPathTranslator
8
+ def initialize(path)
9
+ @path = path
10
+ @namespace = 'schemas' # TODO: make it configurable
11
+ end
12
+
13
+ # Take the path and try to translate each part of it.
14
+ # Given the path: "user.account.status" lookup path (and translation) will looks like:
15
+ #
16
+ # schemas.user.@
17
+ # schemas.user
18
+ # user.@
19
+ # user
20
+ # +
21
+ # schemas.user.account.@
22
+ # schemas.user.account
23
+ # schemas.account.@
24
+ # schemas.account
25
+ # account.@
26
+ # account
27
+ # +
28
+ # schemas.user.account.status.@
29
+ # schemas.user.account.status
30
+ # schemas.status.@
31
+ # schemas.tatus
32
+ # status.@
33
+ # tatus
34
+ #
35
+ # @return [String] translated path
36
+ #
37
+ def translate
38
+ tokens = @path.split('.')
39
+
40
+ translated_tokens = []
41
+ tokens.each.with_index do |token, i|
42
+ translated_tokens << translate_token(token, i, tokens)
43
+ end
44
+
45
+ translated_tokens.join(' ').capitalize
46
+ end
47
+
48
+ private
49
+
50
+ def translate_token(token, token_idx, all_tokens)
51
+ translation = nil
52
+ full_path = all_tokens[0..token_idx].join('.')
53
+
54
+ lookup = build_lookup(token, full_path)
55
+ lookup.each { |path| break translation = I18n.t(path) if I18n.exists?(path) }
56
+
57
+ translation || token
58
+ end
59
+
60
+ def build_lookup(token, full_path)
61
+ Set.new.tap do |lookup|
62
+ lookup << "#{@namespace}.#{full_path}.@"
63
+ lookup << "#{@namespace}.#{full_path}"
64
+ lookup << "#{@namespace}.#{token}.@"
65
+ lookup << "#{@namespace}.#{token}"
66
+ lookup << "#{full_path}.@"
67
+ lookup << full_path
68
+ lookup << "#{token}.@"
69
+ lookup << token
70
+ end
71
+ end
72
+ end
73
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ErrorNormalizer
4
- VERSION = '0.1.1'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -3,6 +3,7 @@
3
3
  require 'dry-configurable'
4
4
  require 'error_normalizer/version'
5
5
  require 'error_normalizer/normalizer'
6
+ require 'error_normalizer/message_parser/english'
6
7
 
7
8
  #
8
9
  # This class provides high-level API to normalize errors to the single format:
@@ -22,6 +23,8 @@ class ErrorNormalizer
22
23
  setting :infer_type_from_rule_name, true
23
24
  setting :rule_matcher, /_rule\z/
24
25
  setting :type_name, 'rule'
26
+ setting :i18n_messages, false
27
+ setting :message_parsers, [ErrorNormalizer::MessageParser::English]
25
28
 
26
29
  #
27
30
  # Normalize errors to flat array of structured errors.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: error_normalizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Kondratenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-07 00:00:00.000000000 Z
11
+ date: 2018-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-configurable
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.7.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: i18n
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +66,20 @@ dependencies:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
68
  version: 0.12.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.6'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.6'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: rake
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -113,7 +141,9 @@ files:
113
141
  - lib/error_normalizer.rb
114
142
  - lib/error_normalizer/error.rb
115
143
  - lib/error_normalizer/message_parser.rb
144
+ - lib/error_normalizer/message_parser/english.rb
116
145
  - lib/error_normalizer/normalizer.rb
146
+ - lib/error_normalizer/schema_path_translator.rb
117
147
  - lib/error_normalizer/version.rb
118
148
  homepage: https://gitlab.yalantis.com/public-repo/error_normalizer/
119
149
  licenses: