i18n-js 3.8.2 → 4.2.3

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.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +4 -0
  3. data/.github/FUNDING.yml +1 -1
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +41 -0
  5. data/.github/ISSUE_TEMPLATE/config.yml +5 -0
  6. data/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
  7. data/.github/PULL_REQUEST_TEMPLATE.md +38 -0
  8. data/.github/dependabot.yml +15 -0
  9. data/.github/workflows/ruby-tests.yml +73 -0
  10. data/.gitignore +13 -7
  11. data/.rubocop.yml +19 -0
  12. data/CHANGELOG.md +47 -512
  13. data/CODE_OF_CONDUCT.md +74 -0
  14. data/CONTRIBUTING.md +79 -0
  15. data/Gemfile +3 -0
  16. data/LICENSE.md +20 -0
  17. data/MIGRATING_FROM_V3_TO_V4.md +192 -0
  18. data/README.md +425 -921
  19. data/Rakefile +10 -20
  20. data/bin/release +81 -0
  21. data/exe/i18n +5 -0
  22. data/i18n-js.gemspec +51 -29
  23. data/lib/guard/i18n-js/templates/Guardfile +10 -0
  24. data/lib/guard/i18n-js/version.rb +13 -0
  25. data/lib/guard/i18n-js.rb +95 -0
  26. data/lib/i18n-js/clean_hash.rb +13 -0
  27. data/lib/i18n-js/cli/check_command.rb +17 -0
  28. data/lib/i18n-js/cli/command.rb +79 -0
  29. data/lib/i18n-js/cli/export_command.rb +95 -0
  30. data/lib/i18n-js/cli/init_command.rb +52 -0
  31. data/lib/i18n-js/cli/lint_scripts_command.rb +159 -0
  32. data/lib/i18n-js/cli/lint_translations_command.rb +157 -0
  33. data/lib/i18n-js/cli/plugins_command.rb +67 -0
  34. data/lib/i18n-js/cli/ui.rb +64 -0
  35. data/lib/i18n-js/cli/version_command.rb +18 -0
  36. data/lib/i18n-js/cli.rb +66 -0
  37. data/lib/i18n-js/embed_fallback_translations_plugin.rb +70 -0
  38. data/lib/i18n-js/export_files_plugin.rb +103 -0
  39. data/lib/i18n-js/lint.js +150645 -0
  40. data/lib/i18n-js/lint.ts +196 -0
  41. data/lib/i18n-js/listen.rb +96 -0
  42. data/lib/i18n-js/plugin.rb +103 -0
  43. data/lib/i18n-js/schema.rb +216 -0
  44. data/lib/i18n-js/sort_hash.rb +12 -0
  45. data/lib/i18n-js/version.rb +5 -0
  46. data/lib/i18n-js.rb +107 -1
  47. data/package.json +5 -20
  48. metadata +149 -189
  49. data/.editorconfig +0 -24
  50. data/.github/workflows/tests.yaml +0 -100
  51. data/.npmignore +0 -27
  52. data/Appraisals +0 -44
  53. data/app/assets/javascripts/i18n/filtered.js.erb +0 -23
  54. data/app/assets/javascripts/i18n/shims.js +0 -240
  55. data/app/assets/javascripts/i18n/translations.js +0 -3
  56. data/app/assets/javascripts/i18n.js +0 -1095
  57. data/gemfiles/i18n_0_6.gemfile +0 -7
  58. data/gemfiles/i18n_0_7.gemfile +0 -7
  59. data/gemfiles/i18n_0_8.gemfile +0 -7
  60. data/gemfiles/i18n_0_9.gemfile +0 -7
  61. data/gemfiles/i18n_1_0.gemfile +0 -7
  62. data/gemfiles/i18n_1_1.gemfile +0 -7
  63. data/gemfiles/i18n_1_2.gemfile +0 -7
  64. data/gemfiles/i18n_1_3.gemfile +0 -7
  65. data/gemfiles/i18n_1_4.gemfile +0 -7
  66. data/gemfiles/i18n_1_5.gemfile +0 -7
  67. data/gemfiles/i18n_1_6.gemfile +0 -7
  68. data/gemfiles/i18n_1_7.gemfile +0 -7
  69. data/gemfiles/i18n_1_8.gemfile +0 -7
  70. data/i18njs.png +0 -0
  71. data/lib/i18n/js/dependencies.rb +0 -63
  72. data/lib/i18n/js/engine.rb +0 -87
  73. data/lib/i18n/js/fallback_locales.rb +0 -70
  74. data/lib/i18n/js/formatters/base.rb +0 -25
  75. data/lib/i18n/js/formatters/js.rb +0 -32
  76. data/lib/i18n/js/formatters/json.rb +0 -13
  77. data/lib/i18n/js/middleware.rb +0 -82
  78. data/lib/i18n/js/private/config_store.rb +0 -31
  79. data/lib/i18n/js/private/hash_with_symbol_keys.rb +0 -36
  80. data/lib/i18n/js/segment.rb +0 -80
  81. data/lib/i18n/js/utils.rb +0 -78
  82. data/lib/i18n/js/version.rb +0 -7
  83. data/lib/i18n/js.rb +0 -264
  84. data/lib/rails/generators/i18n/js/config/config_generator.rb +0 -19
  85. data/lib/rails/generators/i18n/js/config/templates/i18n-js.yml +0 -27
  86. data/lib/tasks/export.rake +0 -8
  87. data/spec/fixtures/custom_path.yml +0 -5
  88. data/spec/fixtures/default.yml +0 -5
  89. data/spec/fixtures/erb.yml +0 -5
  90. data/spec/fixtures/except_condition.yml +0 -7
  91. data/spec/fixtures/js_export_dir_custom.yml +0 -7
  92. data/spec/fixtures/js_export_dir_none.yml +0 -6
  93. data/spec/fixtures/js_extend_parent.yml +0 -6
  94. data/spec/fixtures/js_extend_segment.yml +0 -6
  95. data/spec/fixtures/js_file_per_locale.yml +0 -7
  96. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_default_locale_symbol.yml +0 -4
  97. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_hash.yml +0 -6
  98. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_locale.yml +0 -4
  99. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_locale_without_fallback_translations.yml +0 -4
  100. data/spec/fixtures/js_file_per_locale_with_fallbacks_enabled.yml +0 -4
  101. data/spec/fixtures/js_file_per_locale_without_fallbacks.yml +0 -4
  102. data/spec/fixtures/js_file_with_namespace_prefix_and_pretty_print.yml +0 -9
  103. data/spec/fixtures/js_sort_translation_keys_false.yml +0 -6
  104. data/spec/fixtures/js_sort_translation_keys_true.yml +0 -6
  105. data/spec/fixtures/json_only.yml +0 -18
  106. data/spec/fixtures/locales.yml +0 -133
  107. data/spec/fixtures/merge_plurals.yml +0 -6
  108. data/spec/fixtures/merge_plurals_with_no_overrides.yml +0 -4
  109. data/spec/fixtures/merge_plurals_with_partial_overrides.yml +0 -4
  110. data/spec/fixtures/millions.yml +0 -4
  111. data/spec/fixtures/multiple_conditions.yml +0 -7
  112. data/spec/fixtures/multiple_conditions_per_locale.yml +0 -7
  113. data/spec/fixtures/multiple_files.yml +0 -7
  114. data/spec/fixtures/no_config.yml +0 -2
  115. data/spec/fixtures/no_scope.yml +0 -4
  116. data/spec/fixtures/simple_scope.yml +0 -5
  117. data/spec/js/currency.spec.js +0 -62
  118. data/spec/js/current_locale.spec.js +0 -19
  119. data/spec/js/dates.spec.js +0 -276
  120. data/spec/js/defaults.spec.js +0 -31
  121. data/spec/js/extend.spec.js +0 -110
  122. data/spec/js/interpolation.spec.js +0 -124
  123. data/spec/js/jasmine/MIT.LICENSE +0 -20
  124. data/spec/js/jasmine/jasmine-html.js +0 -190
  125. data/spec/js/jasmine/jasmine.css +0 -166
  126. data/spec/js/jasmine/jasmine.js +0 -2476
  127. data/spec/js/jasmine/jasmine_favicon.png +0 -0
  128. data/spec/js/locales.spec.js +0 -31
  129. data/spec/js/localization.spec.js +0 -78
  130. data/spec/js/numbers.spec.js +0 -174
  131. data/spec/js/placeholder.spec.js +0 -24
  132. data/spec/js/pluralization.spec.js +0 -219
  133. data/spec/js/prepare_options.spec.js +0 -41
  134. data/spec/js/require.js +0 -2083
  135. data/spec/js/specs.html +0 -49
  136. data/spec/js/specs_requirejs.html +0 -72
  137. data/spec/js/translate.spec.js +0 -304
  138. data/spec/js/translations.js +0 -188
  139. data/spec/js/utility_functions.spec.js +0 -20
  140. data/spec/ruby/i18n/js/fallback_locales_spec.rb +0 -84
  141. data/spec/ruby/i18n/js/segment_spec.rb +0 -219
  142. data/spec/ruby/i18n/js/utils_spec.rb +0 -106
  143. data/spec/ruby/i18n/js_spec.rb +0 -748
  144. data/spec/spec_helper.rb +0 -80
  145. data/yarn.lock +0 -131
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 0.6.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 0.7.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 0.8.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 0.9.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.0.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.1.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.2.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.3.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.4.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.5.1"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.6.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.7.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.8.0"
6
-
7
- gemspec path: "../"
data/i18njs.png DELETED
Binary file
@@ -1,63 +0,0 @@
1
- module I18n
2
- module JS
3
- # When using `safe_gem_check` to check for a pre-release version of gem,
4
- # we need to specify pre-release version suffix in version constraint
5
- module Dependencies
6
- class << self
7
- def rails?
8
- defined?(Rails) && Rails.respond_to?(:version)
9
- end
10
-
11
- def sprockets_rails_v2_plus?
12
- safe_gem_check("sprockets-rails", ">= 2")
13
- end
14
-
15
- # This cannot be called at class definition time
16
- # Since not all libraries are loaded
17
- #
18
- # Call this in an initializer
19
- def using_asset_pipeline?
20
- assets_pipeline_available =
21
- (rails3? || rails4? || rails5? || rails6?) &&
22
- Rails.respond_to?(:application) &&
23
- Rails.application.config.respond_to?(:assets)
24
- rails3_assets_enabled =
25
- rails3? &&
26
- assets_pipeline_available &&
27
- Rails.application.config.assets.enabled != false
28
-
29
- assets_pipeline_available && (rails4? || rails5? || rails6? || rails3_assets_enabled)
30
- end
31
-
32
- private
33
-
34
- def rails3?
35
- rails? && Rails.version.to_i == 3
36
- end
37
-
38
- def rails4?
39
- rails? && Rails.version.to_i == 4
40
- end
41
-
42
- def rails5?
43
- rails? && Rails.version.to_i == 5
44
- end
45
-
46
- def rails6?
47
- rails? && Rails.version.to_i == 6
48
- end
49
-
50
- def safe_gem_check(*args)
51
- if Gem::Specification.respond_to?(:find_by_name)
52
- Gem::Specification.find_by_name(*args)
53
- elsif Gem.respond_to?(:available?)
54
- Gem.available?(*args)
55
- end
56
- rescue Gem::LoadError
57
- false
58
- end
59
-
60
- end
61
- end
62
- end
63
- end
@@ -1,87 +0,0 @@
1
- require "i18n/js"
2
-
3
- module I18n
4
- module JS
5
- # @api private
6
- # The class cannot be private
7
- class SprocketsExtension
8
- # Actual definition is placed below
9
- end
10
-
11
- class Engine < ::Rails::Engine
12
- # See https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
13
- # for reference of supporting multiple versions
14
-
15
- # `sprockets.environment` was used for 1.x of `sprockets-rails`
16
- # https://github.com/rails/sprockets-rails/issues/227
17
- #
18
- # References for current values:
19
- #
20
- # Here is where sprockets are attached with Rails. There is no 'sprockets.environment' mentioned.
21
- # https://github.com/rails/sprockets-rails/blob/master/lib/sprockets/railtie.rb
22
- #
23
- # Finisher hook is the place which should be used as border.
24
- # http://guides.rubyonrails.org/configuring.html#initializers
25
- #
26
- # For detail see Pull Request:
27
- # https://github.com/fnando/i18n-js/pull/371
28
- initializer "i18n-js.register_preprocessor", after: :engines_blank_point, before: :finisher_hook do
29
- # This must be called inside initializer block
30
- # For details see comments for `using_asset_pipeline?`
31
- next unless JS::Dependencies.using_asset_pipeline?
32
-
33
- # From README of 2.x & 3.x of `sprockets-rails`
34
- # It seems the `configure` block is preferred way to call `register_preprocessor`
35
- # Not sure if this will break older versions of rails
36
- #
37
- # https://github.com/rails/sprockets-rails/blob/v2.3.3/README.md
38
- # https://github.com/rails/sprockets-rails/blob/v3.0.0/README.md
39
- if JS::Dependencies.sprockets_rails_v2_plus?
40
- Rails.application.config.assets.configure do |config|
41
- config.register_preprocessor("application/javascript", ::I18n::JS::SprocketsExtension)
42
- end
43
- elsif Rails.application.assets.respond_to?(:register_preprocessor)
44
- Rails.application.assets.register_preprocessor("application/javascript", ::I18n::JS::SprocketsExtension)
45
- end
46
- end
47
- end
48
-
49
- # @api private
50
- class SprocketsExtension
51
- def initialize(filename, &block)
52
- @filename = filename
53
- @source = block.call
54
- end
55
-
56
- def render(context, empty_hash_wtf)
57
- self.class.run(@filename, @source, context)
58
- end
59
-
60
- def self.run(filename, source, context)
61
- if context.logical_path == "i18n/filtered"
62
- ::I18n.load_path.each { |path| context.depend_on(File.expand_path(path)) }
63
-
64
- # Absolute path is required or
65
- # Sprockets assumes it's a logical path
66
- #
67
- # Calling `depend on` with an absent file
68
- # will invoke `resolve` and will throw an error in the end
69
- if I18n::JS.config_file_exists?
70
- context.depend_on(File.expand_path(I18n::JS.config_file_path))
71
- end
72
- end
73
-
74
- source
75
- end
76
-
77
- def self.call(input)
78
- filename = input[:filename]
79
- source = input[:data]
80
- context = input[:environment].context_class.new(input)
81
-
82
- result = run(filename, source, context)
83
- context.metadata.merge(data: result)
84
- end
85
- end
86
- end
87
- end
@@ -1,70 +0,0 @@
1
- module I18n
2
- module JS
3
- class FallbackLocales
4
- attr_reader :fallbacks, :locale
5
-
6
- def initialize(fallbacks, locale)
7
- @fallbacks = fallbacks
8
- @locale = locale
9
- end
10
-
11
- def each
12
- locales.each { |locale| yield(locale) }
13
- end
14
-
15
- # @return [Array<String, Symbol>]
16
- # An Array of locales to use as fallbacks for given locale.
17
- def locales
18
- locales = case fallbacks
19
- when true
20
- default_fallbacks
21
- when :default_locale
22
- [::I18n.default_locale]
23
- when Symbol, String
24
- [fallbacks.to_sym]
25
- when Array
26
- ensure_valid_fallbacks_as_array!
27
- fallbacks
28
- when Hash
29
- Array(fallbacks[locale] || default_fallbacks)
30
- else
31
- fail ArgumentError, "fallbacks must be: true, :default_locale an Array or a Hash - given: #{fallbacks}"
32
- end
33
-
34
- locales.map! { |locale| locale.to_sym }
35
- locales
36
- end
37
-
38
- private
39
-
40
- # @return [Array<String, Symbol>] An Array of locales.
41
- def default_fallbacks
42
- if using_i18n_fallbacks_module?
43
- I18n.fallbacks[locale]
44
- else
45
- [::I18n.default_locale]
46
- end
47
- end
48
-
49
- # @return
50
- # true if we can safely use I18n.fallbacks, false otherwise.
51
- #
52
- # @note
53
- # We should implement this as `I18n.respond_to?(:fallbacks)`, but
54
- # once I18n::Backend::Fallbacks is included, I18n will _always_
55
- # respond to :fallbacks. Even if we switch the backend to one
56
- # without fallbacks!
57
- #
58
- # Maybe this should be fixed within I18n.
59
- def using_i18n_fallbacks_module?
60
- I18n::JS.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
61
- end
62
-
63
- def ensure_valid_fallbacks_as_array!
64
- return if fallbacks.all? { |e| e.is_a?(String) || e.is_a?(Symbol) }
65
-
66
- fail ArgumentError, "If fallbacks is passed as Array, it must ony include Strings or Symbols. Given: #{fallbacks}"
67
- end
68
- end
69
- end
70
- end
@@ -1,25 +0,0 @@
1
- module I18n
2
- module JS
3
- module Formatters
4
- class Base
5
- def initialize(js_extend: false, namespace: nil, pretty_print: false, prefix: nil, suffix: nil)
6
- @js_extend = js_extend
7
- @namespace = namespace
8
- @pretty_print = pretty_print
9
- @prefix = prefix
10
- @suffix = suffix
11
- end
12
-
13
- protected
14
-
15
- def format_json(translations)
16
- if @pretty_print
17
- ::JSON.pretty_generate(translations)
18
- else
19
- translations.to_json
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,32 +0,0 @@
1
- require "i18n/js/formatters/base"
2
-
3
- module I18n
4
- module JS
5
- module Formatters
6
- class JS < Base
7
- def format(translations)
8
- contents = header
9
- translations.each do |locale, translations_for_locale|
10
- contents << line(locale, format_json(translations_for_locale))
11
- end
12
- contents << (@suffix || '')
13
- end
14
-
15
- protected
16
-
17
- def header
18
- text = @prefix || ''
19
- text + %(#{@namespace}.translations || (#{@namespace}.translations = {});\n)
20
- end
21
-
22
- def line(locale, translations)
23
- if @js_extend
24
- %(#{@namespace}.translations["#{locale}"] = I18n.extend((#{@namespace}.translations["#{locale}"] || {}), #{translations});\n)
25
- else
26
- %(#{@namespace}.translations["#{locale}"] = #{translations};\n)
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,13 +0,0 @@
1
- require "i18n/js/formatters/base"
2
-
3
- module I18n
4
- module JS
5
- module Formatters
6
- class JSON < Base
7
- def format(translations)
8
- format_json(translations)
9
- end
10
- end
11
- end
12
- end
13
- end
@@ -1,82 +0,0 @@
1
- require "fileutils"
2
-
3
- module I18n
4
- module JS
5
- class Middleware
6
- def initialize(app)
7
- @app = app
8
- clear_cache
9
- end
10
-
11
- def call(env)
12
- @cache = nil
13
- verify_locale_files!
14
- @app.call(env)
15
- end
16
-
17
- private
18
- def cache_path
19
- @cache_path ||= cache_dir.join("i18n-js.yml")
20
- end
21
-
22
- def cache_dir
23
- @cache_dir ||= Rails.root.join("tmp/cache")
24
- end
25
-
26
- def cache
27
- @cache ||= begin
28
- if cache_path.exist?
29
- YAML.load_file(cache_path) || {}
30
- else
31
- {}
32
- end
33
- end
34
- end
35
-
36
- def clear_cache
37
- # `File.delete` will raise error when "multiple worker"
38
- # Are running at the same time, like in a parallel test
39
- #
40
- # `FileUtils.rm_f` is tested manually
41
- #
42
- # See https://github.com/fnando/i18n-js/issues/436
43
- FileUtils.rm_f(cache_path) if File.exist?(cache_path)
44
- end
45
-
46
- def save_cache(new_cache)
47
- # path could be a symbolic link
48
- FileUtils.mkdir_p(cache_dir) unless File.exist?(cache_dir)
49
- File.open(cache_path, "w+") do |file|
50
- file << new_cache.to_yaml
51
- end
52
- end
53
-
54
- # Check if translations should be regenerated.
55
- # ONLY REGENERATE when these conditions are met:
56
- #
57
- # # Cache file doesn't exist
58
- # # Translations and cache size are different (files were removed/added)
59
- # # Translation file has been updated
60
- #
61
- def verify_locale_files!
62
- valid_cache = []
63
- new_cache = {}
64
-
65
- valid_cache.push cache_path.exist?
66
- valid_cache.push ::I18n.load_path.uniq.size == cache.size
67
-
68
- ::I18n.load_path.each do |path|
69
- changed_at = File.mtime(path).to_i
70
- valid_cache.push changed_at == cache[path]
71
- new_cache[path] = changed_at
72
- end
73
-
74
- return if valid_cache.all?
75
-
76
- save_cache(new_cache)
77
-
78
- ::I18n::JS.export
79
- end
80
- end
81
- end
82
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "singleton"
4
-
5
- module I18n
6
- module JS
7
- # @api private
8
- module Private
9
- # Caching implementation for I18n::JS.config
10
- #
11
- # @api private
12
- class ConfigStore
13
- include Singleton
14
-
15
- def fetch
16
- return @config if @config
17
-
18
- yield.tap do |obj|
19
- raise ArgumentError, "unexpected falsy object from block" unless obj
20
-
21
- @config = obj
22
- end
23
- end
24
-
25
- def flush_cache
26
- @config = nil
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,36 +0,0 @@
1
- module I18n
2
- module JS
3
- # @api private
4
- module Private
5
- # Hash with string keys converted to symbol keys
6
- # Used for handling values read on YAML
7
- #
8
- # @api private
9
- class HashWithSymbolKeys < ::Hash
10
- # An instance can only be created by passing in another hash
11
- def initialize(hash)
12
- raise TypeError unless hash.is_a?(::Hash)
13
-
14
- hash.each_key do |key|
15
- # Objects like `Integer` does not have `to_sym`
16
- new_key = key.respond_to?(:to_sym) ? key.to_sym : key
17
- self[new_key] = hash[key]
18
- end
19
-
20
- self.default = hash.default if hash.default
21
- self.default_proc = hash.default_proc if hash.default_proc
22
-
23
- freeze
24
- end
25
-
26
- # From AS Core extension
27
- def slice(*keys)
28
- hash = keys.each_with_object(Hash.new) do |k, hash|
29
- hash[k] = self[k] if has_key?(k)
30
- end
31
- self.class.new(hash)
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,80 +0,0 @@
1
- require "i18n/js/private/hash_with_symbol_keys"
2
- require "i18n/js/formatters/js"
3
- require "i18n/js/formatters/json"
4
-
5
- module I18n
6
- module JS
7
-
8
- # Class which enscapulates a translations hash and outputs a single JSON translation file
9
- class Segment
10
- OPTIONS = [:namespace, :pretty_print, :js_extend, :prefix, :suffix, :sort_translation_keys, :json_only].freeze
11
- LOCALE_INTERPOLATOR = /%\{locale\}/
12
-
13
- attr_reader *([:file, :translations] | OPTIONS)
14
-
15
- def initialize(file, translations, options = {})
16
- @file = file
17
- # `#slice` will be used
18
- # But when activesupport is absent,
19
- # the core extension from `i18n` gem will be used instead
20
- # And it's causing errors (at least in test)
21
- #
22
- # So the input is wrapped by our class for better `#slice`
23
- @translations = Private::HashWithSymbolKeys.new(translations)
24
- @namespace = options[:namespace] || 'I18n'
25
- @pretty_print = !!options[:pretty_print]
26
- @js_extend = options.key?(:js_extend) ? !!options[:js_extend] : true
27
- @prefix = options.key?(:prefix) ? options[:prefix] : nil
28
- @suffix = options.key?(:suffix) ? options[:suffix] : nil
29
- @sort_translation_keys = options.key?(:sort_translation_keys) ? !!options[:sort_translation_keys] : true
30
- @json_only = options.key?(:json_only) ? !!options[:json_only] : false
31
- end
32
-
33
- # Saves JSON file containing translations
34
- def save!
35
- if @file =~ LOCALE_INTERPOLATOR
36
- I18n.available_locales.each do |locale|
37
- write_file(file_for_locale(locale), @translations.slice(locale))
38
- end
39
- else
40
- write_file
41
- end
42
- end
43
-
44
- protected
45
-
46
- def file_for_locale(locale)
47
- @file.gsub(LOCALE_INTERPOLATOR, locale.to_s)
48
- end
49
-
50
- def write_file(_file = @file, _translations = @translations)
51
- FileUtils.mkdir_p File.dirname(_file)
52
- _translations = Utils.deep_key_sort(_translations) if @sort_translation_keys
53
- contents = formatter.format(_translations)
54
-
55
- return if File.exist?(_file) && File.read(_file) == contents
56
-
57
- File.open(_file, "w+") do |f|
58
- f << contents
59
- end
60
- end
61
-
62
- def formatter
63
- if @json_only
64
- Formatters::JSON.new(**formatter_options)
65
- else
66
- Formatters::JS.new(**formatter_options)
67
- end
68
- end
69
-
70
- def formatter_options
71
- { js_extend: @js_extend,
72
- namespace: @namespace,
73
- pretty_print: @pretty_print,
74
- prefix: @prefix,
75
- suffix: @suffix
76
- }
77
- end
78
- end
79
- end
80
- end