i18n-js 4.0.0.alpha4 → 4.0.1

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: 3ecf4853a33adc9a67520a585c733a55e7b05e07bdc436830c519213bfc728b6
4
- data.tar.gz: 5a1b68a4182bc30fcc3c57438ab226ba72a97a7f16dd6c29ac938106f4c5e00c
3
+ metadata.gz: fb5f60568907f90a59b7d19a6b2f61cf9a3fff95ea419b1b8b31deab16529dc6
4
+ data.tar.gz: ca65b2bf6717b93218092e8c994cdbac8af6bc69fddab421ebef976c87dc5503
5
5
  SHA512:
6
- metadata.gz: f8468f07c440fa8c29c84a6550ef8b7d5914cf08ce93d0b02f77caf65838a4057f8a7653cc221c33a1dfaf1ab0486aa195a368248ca9509af4af7071ab76ddaa
7
- data.tar.gz: cb3822d5fe66aa90b20a4a596869a0adb93c3154d5877f66b1374794961536bc2916c051f8d5ce5f61d2d57c66951c25b477f8b808b7d737b39941875e545afb
6
+ metadata.gz: 3e33c8605b5197cbdc6a8f30ef1cb7e5f911f84dd177d488489fcfc82e5dd2b8fb3e387b0fe89683c3e71c6025ff7b47685163317540c4e2c5c756936660be55
7
+ data.tar.gz: b4367db58b89392c42c94121ccdde7179e1ea455de6c20685ded2c034304ce4c8c44cbfa1a4967610443e4f91116058ee86bc14d2e913a2c6006ee648c189dd9
data/CHANGELOG.md CHANGED
@@ -11,6 +11,13 @@ Prefix your message with one of the following:
11
11
  - [Security] in case of vulnerabilities.
12
12
  -->
13
13
 
14
- ## Unreleased
14
+ ## v4.0.1
15
15
 
16
- - Initial release.
16
+ - [Fixed] Shell out export to avoid handling I18n reloading heuristics.
17
+ - [Changed] `I18nJS.listen` now accepts a directories list to watch.
18
+ - [Changed] `I18nJS.listen` now accepts
19
+ [listen](https://rubygems.org/gems/listen) options via `:options`.
20
+
21
+ ## Jul 29, 2022
22
+
23
+ - Official release of i18n-js v4.0.0.
@@ -0,0 +1,191 @@
1
+ # Migrating from v3 to v4
2
+
3
+ I18n-js v4 is a breaking change release and diverges quite a lot from how the
4
+ previous version worked. This guides summarizes the process of upgrading an app
5
+ that uses i18n-js v3 to v4.
6
+
7
+ ## Development
8
+
9
+ Previously, you could use a middleware to export translations (some people even
10
+ used this in production 😬). In development, you can now use whatever your want,
11
+ because i18n-js doesn't make any assumptions. All you need to do is running
12
+ `i18n export`, either manually or by using something that listens to file
13
+ changes.
14
+
15
+ If you like watchman, you can use something like this:
16
+
17
+ ```bash
18
+ #!/usr/bin/env bash
19
+
20
+ root=`pwd`
21
+
22
+ watchman watch-del "$root"
23
+ watchman watch-project "$root"
24
+ watchman trigger-del "$root" i18n
25
+
26
+ watchman -j <<-JSON
27
+ [
28
+ "trigger",
29
+ "$root",
30
+ {
31
+ "name": "i18n",
32
+ "expression": [
33
+ "anyof",
34
+ ["match", "config/locales/**/*.yml", "wholename"],
35
+ ["match", "config/locales/**/*.po", "wholename"],
36
+ ["match", "config/i18n.yml", "wholename"]
37
+ ],
38
+ "command": ["i18n", "export"]
39
+ }
40
+ ]
41
+ JSON
42
+
43
+ # If you're running this through Foreman, then uncomment the following lines:
44
+ # while true; do
45
+ # sleep 1
46
+ # done
47
+ ```
48
+
49
+ You can also use guard. Make sure you have both
50
+ [guard](https://rubygems.org/packages/guard) and
51
+ [guard-compat](https://rubygems.org/packages/guard-compat) installed and use
52
+ Guardfile file with the following contents:
53
+
54
+ ```ruby
55
+ guard(:"i18n-js",
56
+ run_on_start: true,
57
+ config_file: "./config/i18n.yml",
58
+ require_file: "./config/environment.rb") do
59
+ watch(%r{^config/locales/.+\.(yml|po)$})
60
+ watch(%r{^config/i18n.yml$})
61
+ watch("Gemfile")
62
+ end
63
+ ```
64
+
65
+ To run guard, use `guard start -i`.
66
+
67
+ Finally, you can use [listen](https://rubygems.org/gems/listen). Create the file
68
+ `config/initializers/i18n.rb` with the following content:
69
+
70
+ ```ruby
71
+ Rails.application.config.after_initialize do
72
+ require "i18n-js/listen"
73
+ # This will only run in development.
74
+ I18nJS.listen
75
+ end
76
+ ```
77
+
78
+ > **Warning**:
79
+ >
80
+ > No matter which approach you choose, the idea is that you _precompile_ your
81
+ > translations when going to production. DO NOT RUN any of the above in
82
+ > production.
83
+
84
+ ## Exporting translations
85
+
86
+ The build process for i18n now relies on an external CLI called `i18n`. All you
87
+ need to do is executing `i18n export` in your build step to generate the json
88
+ files for your translations.
89
+
90
+ ## Using your translations
91
+
92
+ The JavaScript package is now a separate thing and need to be installed using
93
+ your favorite tooling (e.g. yarn, npm, pnpm, etc).
94
+
95
+ ```console
96
+ $ yarn add i18n-js@latest
97
+ $ npm i --save-dev i18n-js@latest
98
+ ```
99
+
100
+ From now on, the way you load translations and set up I18n-js is totally up to
101
+ you, but means you need to load the json files and attach to the I18n-js
102
+ instance. This is how I do it in a project I'm doing right now (Rails 7 +
103
+ esbuild + TypeScript). First, we need to load the I18n-js configuration from the
104
+ main JavaScript file:
105
+
106
+ ```typescript
107
+ // app/javascript/application.ts
108
+ import { i18n } from "./config/i18n";
109
+ ```
110
+
111
+ Then we need to load our translations and instantiate the I18n-js class.
112
+
113
+ ```typescript
114
+ // app/javascript/config/i18n.ts
115
+ import { I18n } from "i18n-js";
116
+ import translations from "translations.json";
117
+
118
+ // Fetch user locale from html#lang.
119
+ // This value is being set on `app/views/layouts/application.html.erb` and
120
+ // is inferred from `ACCEPT-LANGUAGE` header.
121
+ const userLocale = document.documentElement.lang;
122
+
123
+ export const i18n = new I18n();
124
+ i18n.store(translations);
125
+ i18n.defaultLocale = "en";
126
+ i18n.enableFallback = true;
127
+ i18n.locale = userLocale;
128
+ ```
129
+
130
+ The best thing about the above is that it is a pretty straightforward pattern in
131
+ the JavaScript community. It doesn't rely on specific parts from Sprockets (I'm
132
+ not even using it on my projects) or eRb files.
133
+
134
+ ## Ruby on Rails
135
+
136
+ ### Upgrading the configuration file
137
+
138
+ The configuration file loaded from `config/i18nyml` has changed. Given the v3
139
+ configuration below
140
+
141
+ ```yaml
142
+ ---
143
+ translations:
144
+ - file: "app/assets/javascripts/date_formats.js"
145
+ only: "*.date.formats"
146
+ - file: "app/assets/javascripts/other.js"
147
+ only: ["*.activerecord", "*.admin.*.title"]
148
+ - file: "app/assets/javascripts/everything_else.js"
149
+ except:
150
+ - "*.activerecord"
151
+ - "*.admin.*.title"
152
+ - "*.date.formats"
153
+ ```
154
+
155
+ the equivalent configuration file for v4 would be
156
+
157
+ ```yaml
158
+ ---
159
+ translations:
160
+ - file: "app/assets/javascripts/date_formats.js"
161
+ patterns:
162
+ - "*.date.formats"
163
+ - file: "app/assets/javascripts/other.js"
164
+ patterns:
165
+ - "*.activerecord"
166
+ - "*.admin.*.title"
167
+ - file: "app/assets/javascripts/everything_else.js"
168
+ patterns:
169
+ # Notice the exclamation mark.
170
+ - "!*.activerecord"
171
+ - "!*.admin.*.title"
172
+ - "!*.date.formats"
173
+ ```
174
+
175
+ Other configuration options:
176
+
177
+ - `export_i18n_js`: removed without an equivalent
178
+ - `fallbacks`: removed without an equivalent
179
+ - `js_available_locales`: removed (on v4 you can use groups, like in
180
+ `{pt-BR,en}.*`)
181
+ - `namespace`: removed without an equivalent
182
+ - `sort_translation_keys`: removed (on v4 keys will always be sorted)
183
+ - `translations[].prefix`: removed without an equivalent
184
+ - `translations[].pretty_print`: removed (on v4 files will always be exported in
185
+ a readable format)
186
+
187
+ ### Placeholders
188
+
189
+ Previously, v3 had the `%{locale}` placeholder, which can be used as part of the
190
+ directory and/or file name. Now, the syntax is just `:locale`. Additionally, you
191
+ can also use `:digest`, which uses a MD5 hex digest of the exported file.
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img width="250" height="58" src="https://github.com/fnando/i18n-js/raw/main/i18njs.png" alt="i18n.js">
2
+ <img width="250" height="58" src="https://github.com/fnando/i18n-js/raw/main/images/i18njs.png" alt="i18n.js">
3
3
  </p>
4
4
 
5
5
  <p align="center">
@@ -12,8 +12,8 @@
12
12
  <small>
13
13
  Oh, you don't use Ruby? No problem! You can still use i18n-js
14
14
  <br>
15
- and the
16
- <a href="https://www.npmjs.com/package/i18n-js/v/next">companion JavaScript package</a>.
15
+ and the
16
+ <a href="https://www.npmjs.com/package/i18n-js/v/latest">companion JavaScript package</a>.
17
17
  </small>
18
18
  </p>
19
19
 
@@ -24,8 +24,6 @@
24
24
  <a href="https://tldrlegal.com/license/mit-license"><img src="https://img.shields.io/:License-MIT-blue.svg" alt="MIT License"></a>
25
25
  </p>
26
26
 
27
- ![This branch contains the code for v4, our next major release.](https://messages-svg.herokuapp.com/warning.svg?message=This%20branch%20contains%20the%20code%20for%20v4%2C%20our%20next%20major%20release.)
28
-
29
27
  ## Installation
30
28
 
31
29
  ```bash
@@ -35,7 +33,7 @@ gem install i18n-js
35
33
  Or add the following line to your project's Gemfile:
36
34
 
37
35
  ```ruby
38
- gem "i18n-js", "~> 4.0.0.alpha1"
36
+ gem "i18n-js"
39
37
  ```
40
38
 
41
39
  ## Usage
@@ -47,6 +45,14 @@ About patterns:
47
45
  - `*.messages.*`
48
46
  - Patterns starting with `!` are excluded.
49
47
  - `!*.activerecord.*` will exclude all ActiveRecord translations.
48
+ - You can use groups:
49
+ - `{pt-BR,en}.js.*` will include only `pt-BR` and `en` translations, even if
50
+ more languages are available.
51
+
52
+ > **Note**:
53
+ >
54
+ > Patterns use [glob](https://rubygems.org/gems/glob), so check it out for the
55
+ > most up-to-date documentation about what's available.
50
56
 
51
57
  The config file:
52
58
 
@@ -111,9 +117,37 @@ default locale. Here's an example:
111
117
  This command will exist with status 1 whenever there are missing translations.
112
118
  This way you can use it as a CI linting.
113
119
 
120
+ You can ignore keys by adding a list to the config file:
121
+
122
+ ```yml
123
+ ---
124
+ translations:
125
+ - file: app/frontend/locales/en.json
126
+ patterns:
127
+ - "*"
128
+ - "!*.activerecord"
129
+ - "!*.errors"
130
+ - "!*.number.nth"
131
+
132
+ - file: app/frontend/locales/:locale.:digest.json
133
+ patterns:
134
+ - "*"
135
+
136
+ check:
137
+ ignore:
138
+ - en.mailer.login.subject
139
+ - en.mailer.login.body
140
+ ```
141
+
142
+ > **Note**:
143
+ >
144
+ > In order to avoid mistakenly ignoring keys, this configuration option only
145
+ > accepts the full translation scope, rather than accepting a pattern like
146
+ > `pt.ignored.scope.*`.
147
+
114
148
  ## Automatically export translations
115
149
 
116
- ### Using watchman
150
+ ### Using [watchman](https://facebook.github.io/watchman/)
117
151
 
118
152
  Create a script at `bin/i18n-watch`.
119
153
 
@@ -158,11 +192,11 @@ line to your Procfile:
158
192
  i18n: ./bin/i18n-watch
159
193
  ```
160
194
 
161
- ### Using guard
195
+ ### Using [guard](https://rubygems.org/gems/guard)
162
196
 
163
- Install [guard](https://rubygems.org/packages/guard) and
164
- [guard-compat](https://rubygems.org/packages/guard-compat). Then create a
165
- Guardfile with the following configuration:
197
+ Install [guard](https://rubygems.org/gems/guard) and
198
+ [guard-compat](https://rubygems.org/gems/guard-compat). Then create a Guardfile
199
+ with the following configuration:
166
200
 
167
201
  ```ruby
168
202
  guard(:"i18n-js",
@@ -180,7 +214,7 @@ accordingly.
180
214
 
181
215
  Now you can run `guard start -i`.
182
216
 
183
- ### Using listen
217
+ ### Using [listen](https://rubygems.org/gems/listen)
184
218
 
185
219
  Create a file under `config/initializers/i18n.rb` with the following content:
186
220
 
@@ -192,8 +226,21 @@ end
192
226
  ```
193
227
 
194
228
  The code above will watch for changes based on `config/i18n.yml` and
195
- `config/locales`. You can customize these options with
196
- `I18nJS.listen(config_file: "config/i18n.yml", locales_dir: "config/locales")`.
229
+ `config/locales`. You can customize these options:
230
+
231
+ - `config_file` - i18n-js configuration file
232
+ - `locales_dir` - one or multiple directories to watch for locales changes
233
+ - `options` - passed directly to [listen](https://github.com/guard/listen/#options)
234
+
235
+ Example:
236
+
237
+ ```ruby
238
+ I18nJS.listen(
239
+ config_file: "config/i18n.yml",
240
+ locales_dir: ["config/locales", "app/views"],
241
+ options: {only: %r{.yml$}
242
+ )
243
+ ```
197
244
 
198
245
  ### Integrating with your frontend
199
246
 
@@ -203,6 +250,13 @@ that loads all the exported translation.
203
250
 
204
251
  ### FAQ
205
252
 
253
+ #### I'm running v3. Is there a migration plan?
254
+
255
+ [There's a document](https://github.com/fnando/i18n-js/tree/main/MIGRATING_FROM_V3_TO_V4.md)
256
+ outlining some of the things you need to do to migrate from v3 to v4. It may not
257
+ be as complete as we'd like it to be, so let's know if you face any issues
258
+ during the migration is not outline is that document.
259
+
206
260
  #### How can I export translations without having a database around?
207
261
 
208
262
  Some people may have a build process using something like Docker that don't
@@ -222,9 +276,11 @@ require "action_view/railtie"
222
276
  I18n.load_path += Dir["./config/locales/**/*.yml"]
223
277
  ```
224
278
 
225
- Notice that you may not need to load ActiveSupport and ActionView lines, or even
226
- may need to add additional requires for other libs. With this approach you have
227
- full control on what's going to be loaded.
279
+ > **Note**:
280
+ >
281
+ > You may not need to load ActiveSupport and ActionView lines, or even may need
282
+ > to add additional requires for other libs. With this approach you have full
283
+ > control on what's going to be loaded.
228
284
 
229
285
  ## Maintainer
230
286
 
data/i18n-js.gemspec CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
29
29
  `git ls-files -z`
30
30
  .split("\x0")
31
- .reject {|f| f.match(%r{^(test|spec|features)/}) }
31
+ .reject {|f| f.match(%r{^(test|spec|features|images)/}) }
32
32
  end
33
33
 
34
34
  spec.bindir = "exe"
data/lib/guard/i18n-js.rb CHANGED
@@ -53,13 +53,30 @@ module Guard
53
53
  info("Changes detected: #{changes.join(', ')}") if changes
54
54
 
55
55
  @current_thread = Thread.new do
56
- require @require_file
57
- ::I18nJS.call(config_file: @config_file)
56
+ capture do
57
+ system "i18n",
58
+ "export",
59
+ "--config",
60
+ config_file.to_s,
61
+ "--require",
62
+ require_file.to_s,
63
+ "--quiet"
64
+ end
58
65
  end
59
66
 
60
67
  current_thread.join
61
68
  end
62
69
 
70
+ def capture
71
+ original = $stdout
72
+ $stdout = StringIO.new
73
+ yield
74
+ rescue StandardError
75
+ # noop
76
+ ensure
77
+ $stdout = original
78
+ end
79
+
63
80
  def validate_file(key, file)
64
81
  return true if file && File.file?(file)
65
82
 
@@ -68,11 +85,11 @@ module Guard
68
85
  end
69
86
 
70
87
  def error(message)
71
- ::Guard::UI.error "[guard-i18n-js] #{message}"
88
+ ::Guard::UI.error "[i18n-js] #{message}"
72
89
  end
73
90
 
74
91
  def info(message)
75
- ::Guard::UI.info "[guard-i18n-js] #{message}"
92
+ ::Guard::UI.info "[i18n-js] #{message}"
76
93
  end
77
94
  end
78
95
  end
@@ -69,9 +69,14 @@ module I18nJS
69
69
  )
70
70
  end
71
71
 
72
+ config = Glob::SymbolizeKeys.call(YAML.load_file(config_file))
73
+ Schema.validate!(config)
74
+
72
75
  load_require_file!(require_file) if require_file
76
+
73
77
  default_locale = I18n.default_locale
74
78
  available_locales = I18n.available_locales
79
+ ignored_keys = config.dig(:check, :ignore) || []
75
80
 
76
81
  mapping = available_locales.each_with_object({}) do |locale, buffer|
77
82
  buffer[locale] =
@@ -81,21 +86,50 @@ module I18nJS
81
86
 
82
87
  default_locale_keys = mapping.delete(default_locale)
83
88
 
89
+ if ignored_keys.any?
90
+ ui.stdout_print "=> Check #{options[:config_file].inspect} for " \
91
+ "ignored keys."
92
+ end
93
+
84
94
  ui.stdout_print "=> #{default_locale}: #{default_locale_keys.size} " \
85
95
  "translations"
86
96
 
87
97
  total_missing_count = 0
88
98
 
89
99
  mapping.each do |locale, partial_keys|
90
- extraneous = partial_keys - default_locale_keys
91
- missing = default_locale_keys - (partial_keys - extraneous)
100
+ ignored_count = 0
101
+
102
+ # Compute list of filtered keys (i.e. keys not ignored)
103
+ filtered_keys = partial_keys.reject do |key|
104
+ key = "#{locale}.#{key}"
105
+
106
+ ignored = ignored_keys.include?(key)
107
+ ignored_count += 1 if ignored
108
+ ignored
109
+ end
110
+
111
+ extraneous = (partial_keys - default_locale_keys).reject do |key|
112
+ key = "#{locale}.#{key}"
113
+ ignored = ignored_keys.include?(key)
114
+ ignored_count += 1 if ignored
115
+ ignored
116
+ end
117
+
118
+ missing = (default_locale_keys - (filtered_keys - extraneous))
119
+ .reject {|key| ignored_keys.include?("#{locale}.#{key}") }
120
+
121
+ ignored_count += extraneous.size
92
122
  total_missing_count += missing.size
123
+
93
124
  ui.stdout_print "=> #{locale}: #{missing.size} missing, " \
94
- "#{extraneous.size} extraneous"
125
+ "#{extraneous.size} extraneous, " \
126
+ "#{ignored_count} ignored"
95
127
 
96
128
  all_keys = (default_locale_keys + extraneous + missing).uniq.sort
97
129
 
98
130
  all_keys.each do |key|
131
+ next if ignored_keys.include?("#{locale}.#{key}")
132
+
99
133
  label = if extraneous.include?(key)
100
134
  ui.yellow("extraneous")
101
135
  elsif missing.include?(key)
@@ -27,6 +27,14 @@ module I18nJS
27
27
  options[:require_file] = require_file
28
28
  end
29
29
 
30
+ opts.on(
31
+ "-q",
32
+ "--quiet",
33
+ "A Ruby file that must be loaded"
34
+ ) do |quiet|
35
+ options[:quiet] = quiet
36
+ end
37
+
30
38
  opts.on("-h", "--help", "Prints this help") do
31
39
  ui.exit_with opts.to_s
32
40
  end
@@ -39,11 +47,11 @@ module I18nJS
39
47
  ui.fail_with("=> ERROR: you need to specify the config file")
40
48
  end
41
49
 
42
- ui.stdout_print("=> Config file:", options[:config_file].inspect)
50
+ log("=> Config file:", options[:config_file].inspect)
43
51
  config_file = File.expand_path(options[:config_file])
44
52
 
45
53
  if options[:require_file]
46
- ui.stdout_print("=> Require file:", options[:require_file].inspect)
54
+ log("=> Require file:", options[:require_file].inspect)
47
55
  require_file = File.expand_path(options[:require_file])
48
56
  end
49
57
 
@@ -66,7 +74,13 @@ module I18nJS
66
74
  I18nJS.call(config_file: config_file)
67
75
  end
68
76
 
69
- ui.stdout_print("=> Done in #{time.round(2)}s")
77
+ log("=> Done in #{time.round(2)}s")
78
+ end
79
+
80
+ private def log(*args)
81
+ return if options[:quiet]
82
+
83
+ ui.stdout_print(*args)
70
84
  end
71
85
 
72
86
  private def set_defaults!
@@ -7,7 +7,8 @@ module I18nJS
7
7
 
8
8
  def self.listen(
9
9
  config_file: Rails.root.join("config/i18n.yml"),
10
- locales_dir: Rails.root.join("config/locales")
10
+ locales_dir: Rails.root.join("config/locales"),
11
+ options: {}
11
12
  )
12
13
  return unless Rails.env.development?
13
14
  return if started
@@ -18,12 +19,14 @@ module I18nJS
18
19
 
19
20
  self.started = true
20
21
 
22
+ locales_dirs = Array(locales_dir)
23
+
21
24
  relative_paths =
22
- [config_file, locales_dir].map {|path| relative_path(path) }
25
+ [config_file, *locales_dirs].map {|path| relative_path(path) }
23
26
 
24
27
  debug("Watching #{relative_paths.inspect}")
25
28
 
26
- listener(config_file, locales_dir.to_s).start
29
+ listener(config_file, locales_dirs.map(&:to_s), options).start
27
30
  I18nJS.call(config_file: config_file)
28
31
  end
29
32
 
@@ -43,12 +46,12 @@ module I18nJS
43
46
  @logger ||= ActiveSupport::TaggedLogging.new(Rails.logger)
44
47
  end
45
48
 
46
- def self.listener(config_file, locales_dir)
47
- paths = [File.dirname(config_file), locales_dir]
49
+ def self.listener(config_file, locales_dirs, options)
50
+ paths = [File.dirname(config_file), *locales_dirs]
48
51
 
49
- Listen.to(*paths) do |changed, added, removed|
52
+ Listen.to(*paths, options) do |changed, added, removed|
50
53
  changes = compute_changes(
51
- [config_file, locales_dir],
54
+ [config_file, *locales_dirs],
52
55
  changed,
53
56
  added,
54
57
  removed
@@ -58,11 +61,22 @@ module I18nJS
58
61
 
59
62
  debug(changes.map {|key, value| "#{key}=#{value.inspect}" }.join(", "))
60
63
 
61
- ::I18n.backend.reload!
62
- I18nJS.call(config_file: config_file)
64
+ capture do
65
+ system "i18n", "export", "--config", config_file.to_s
66
+ end
63
67
  end
64
68
  end
65
69
 
70
+ def self.capture
71
+ original = $stdout
72
+ $stdout = StringIO.new
73
+ yield
74
+ rescue StandardError
75
+ # noop
76
+ ensure
77
+ $stdout = original
78
+ end
79
+
66
80
  def self.compute_changes(paths, changed, added, removed)
67
81
  paths = paths.map {|path| relative_path(path) }
68
82
 
@@ -4,8 +4,9 @@ module I18nJS
4
4
  class Schema
5
5
  InvalidError = Class.new(StandardError)
6
6
 
7
- ROOT_KEYS = %i[translations].freeze
7
+ ROOT_KEYS = %i[translations check].freeze
8
8
  REQUIRED_ROOT_KEYS = %i[translations].freeze
9
+ REQUIRED_CHECK_KEYS = %i[ignore].freeze
9
10
  REQUIRED_TRANSLATION_KEYS = %i[file patterns].freeze
10
11
  TRANSLATION_KEYS = %i[file patterns].freeze
11
12
 
@@ -25,6 +26,17 @@ module I18nJS
25
26
  expect_required_keys(REQUIRED_ROOT_KEYS, target)
26
27
  reject_extraneous_keys(ROOT_KEYS, target)
27
28
  validate_translations
29
+ validate_check
30
+ end
31
+
32
+ def validate_check
33
+ return unless target.key?(:check)
34
+
35
+ check = target[:check]
36
+
37
+ expect_type(:check, check, Hash, target)
38
+ expect_required_keys(REQUIRED_CHECK_KEYS, check)
39
+ expect_type(:ignore, check[:ignore], Array, check)
28
40
  end
29
41
 
30
42
  def validate_translations
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module I18nJS
4
- VERSION = "4.0.0.alpha4"
4
+ VERSION = "4.0.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n-js
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.alpha4
4
+ version: 4.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-21 00:00:00.000000000 Z
11
+ date: 2022-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glob
@@ -173,12 +173,11 @@ files:
173
173
  - CONTRIBUTING.md
174
174
  - Gemfile
175
175
  - LICENSE.md
176
+ - MIGRATING_FROM_V3_TO_V4.md
176
177
  - README.md
177
178
  - Rakefile
178
179
  - exe/i18n
179
180
  - i18n-js.gemspec
180
- - i18njs.png
181
- - images/i18njs-check.gif
182
181
  - lib/guard/i18n-js.rb
183
182
  - lib/guard/i18n-js/templates/Guardfile
184
183
  - lib/guard/i18n-js/version.rb
@@ -200,10 +199,10 @@ metadata:
200
199
  rubygems_mfa_required: 'true'
201
200
  homepage_uri: https://github.com/fnando/i18n-js
202
201
  bug_tracker_uri: https://github.com/fnando/i18n-js/issues
203
- source_code_uri: https://github.com/fnando/i18n-js/tree/v4.0.0.alpha4
204
- changelog_uri: https://github.com/fnando/i18n-js/tree/v4.0.0.alpha4/CHANGELOG.md
205
- documentation_uri: https://github.com/fnando/i18n-js/tree/v4.0.0.alpha4/README.md
206
- license_uri: https://github.com/fnando/i18n-js/tree/v4.0.0.alpha4/LICENSE.md
202
+ source_code_uri: https://github.com/fnando/i18n-js/tree/v4.0.1
203
+ changelog_uri: https://github.com/fnando/i18n-js/tree/v4.0.1/CHANGELOG.md
204
+ documentation_uri: https://github.com/fnando/i18n-js/tree/v4.0.1/README.md
205
+ license_uri: https://github.com/fnando/i18n-js/tree/v4.0.1/LICENSE.md
207
206
  post_install_message:
208
207
  rdoc_options: []
209
208
  require_paths:
@@ -215,9 +214,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
215
214
  version: 2.6.0
216
215
  required_rubygems_version: !ruby/object:Gem::Requirement
217
216
  requirements:
218
- - - ">"
217
+ - - ">="
219
218
  - !ruby/object:Gem::Version
220
- version: 1.3.1
219
+ version: '0'
221
220
  requirements: []
222
221
  rubygems_version: 3.3.7
223
222
  signing_key:
data/i18njs.png DELETED
Binary file
Binary file