better_translate 0.5.0 → 1.0.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/.env.example +14 -0
- data/.rspec +3 -0
- data/.rubocop.yml +8 -0
- data/.yardopts +10 -0
- data/CHANGELOG.md +125 -114
- data/CLAUDE.md +385 -0
- data/README.md +629 -244
- data/Rakefile +7 -1
- data/Steepfile +29 -0
- data/docs/implementation/00-overview.md +220 -0
- data/docs/implementation/01-setup_dependencies.md +668 -0
- data/docs/implementation/02-error_handling.md +65 -0
- data/docs/implementation/03-core_components.md +457 -0
- data/docs/implementation/03.5-variable_preservation.md +509 -0
- data/docs/implementation/04-provider_architecture.md +571 -0
- data/docs/implementation/05-translation_logic.md +1065 -0
- data/docs/implementation/06-main_module_api.md +122 -0
- data/docs/implementation/07-direct_translation_helpers.md +582 -0
- data/docs/implementation/08-rails_integration.md +323 -0
- data/docs/implementation/09-testing_suite.md +228 -0
- data/docs/implementation/10-documentation_examples.md +150 -0
- data/docs/implementation/11-quality_security.md +65 -0
- data/docs/implementation/12-cli_standalone.md +698 -0
- data/exe/better_translate +9 -0
- data/lib/better_translate/cache.rb +125 -0
- data/lib/better_translate/cli.rb +304 -0
- data/lib/better_translate/configuration.rb +201 -0
- data/lib/better_translate/direct_translator.rb +131 -0
- data/lib/better_translate/errors.rb +101 -0
- data/lib/better_translate/progress_tracker.rb +157 -0
- data/lib/better_translate/provider_factory.rb +45 -0
- data/lib/better_translate/providers/anthropic_provider.rb +154 -0
- data/lib/better_translate/providers/base_http_provider.rb +239 -0
- data/lib/better_translate/providers/chatgpt_provider.rb +138 -44
- data/lib/better_translate/providers/gemini_provider.rb +123 -61
- data/lib/better_translate/railtie.rb +18 -0
- data/lib/better_translate/rate_limiter.rb +90 -0
- data/lib/better_translate/strategies/base_strategy.rb +58 -0
- data/lib/better_translate/strategies/batch_strategy.rb +56 -0
- data/lib/better_translate/strategies/deep_strategy.rb +45 -0
- data/lib/better_translate/strategies/strategy_selector.rb +43 -0
- data/lib/better_translate/translator.rb +115 -284
- data/lib/better_translate/utils/hash_flattener.rb +104 -0
- data/lib/better_translate/validator.rb +105 -0
- data/lib/better_translate/variable_extractor.rb +259 -0
- data/lib/better_translate/version.rb +2 -9
- data/lib/better_translate/yaml_handler.rb +168 -0
- data/lib/better_translate.rb +97 -73
- data/lib/generators/better_translate/analyze/USAGE +12 -0
- data/lib/generators/better_translate/analyze/analyze_generator.rb +94 -0
- data/lib/generators/better_translate/install/USAGE +13 -0
- data/lib/generators/better_translate/install/install_generator.rb +71 -0
- data/lib/generators/better_translate/install/templates/README +20 -0
- data/lib/generators/better_translate/install/templates/initializer.rb.tt +47 -0
- data/lib/generators/better_translate/translate/USAGE +13 -0
- data/lib/generators/better_translate/translate/translate_generator.rb +114 -0
- data/lib/tasks/better_translate.rake +136 -0
- data/sig/better_translate/cache.rbs +28 -0
- data/sig/better_translate/cli.rbs +24 -0
- data/sig/better_translate/configuration.rbs +78 -0
- data/sig/better_translate/direct_translator.rbs +18 -0
- data/sig/better_translate/errors.rbs +46 -0
- data/sig/better_translate/progress_tracker.rbs +29 -0
- data/sig/better_translate/provider_factory.rbs +8 -0
- data/sig/better_translate/providers/anthropic_provider.rbs +27 -0
- data/sig/better_translate/providers/base_http_provider.rbs +44 -0
- data/sig/better_translate/providers/chatgpt_provider.rbs +25 -0
- data/sig/better_translate/providers/gemini_provider.rbs +22 -0
- data/sig/better_translate/railtie.rbs +7 -0
- data/sig/better_translate/rate_limiter.rbs +20 -0
- data/sig/better_translate/strategies/base_strategy.rbs +19 -0
- data/sig/better_translate/strategies/batch_strategy.rbs +13 -0
- data/sig/better_translate/strategies/deep_strategy.rbs +11 -0
- data/sig/better_translate/strategies/strategy_selector.rbs +10 -0
- data/sig/better_translate/translator.rbs +24 -0
- data/sig/better_translate/utils/hash_flattener.rbs +14 -0
- data/sig/better_translate/validator.rbs +14 -0
- data/sig/better_translate/variable_extractor.rbs +40 -0
- data/sig/better_translate/version.rbs +4 -0
- data/sig/better_translate/yaml_handler.rbs +29 -0
- data/sig/better_translate.rbs +32 -2
- data/sig/faraday.rbs +22 -0
- data/sig/generators/better_translate/analyze/analyze_generator.rbs +18 -0
- data/sig/generators/better_translate/install/install_generator.rbs +14 -0
- data/sig/generators/better_translate/translate/translate_generator.rbs +10 -0
- data/sig/optparse.rbs +9 -0
- data/sig/psych.rbs +5 -0
- data/sig/rails.rbs +34 -0
- metadata +89 -203
- data/lib/better_translate/helper.rb +0 -83
- data/lib/better_translate/providers/base_provider.rb +0 -102
- data/lib/better_translate/service.rb +0 -144
- data/lib/better_translate/similarity_analyzer.rb +0 -218
- data/lib/better_translate/utils.rb +0 -55
- data/lib/better_translate/writer.rb +0 -75
- data/lib/generators/better_translate/analyze_generator.rb +0 -57
- data/lib/generators/better_translate/install_generator.rb +0 -14
- data/lib/generators/better_translate/templates/better_translate.rb +0 -56
- data/lib/generators/better_translate/translate_generator.rb +0 -84
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
# Base error class for all BetterTranslate errors
|
|
3
|
+
class Error < StandardError
|
|
4
|
+
@context: Hash[Symbol, untyped]
|
|
5
|
+
|
|
6
|
+
attr_reader context: Hash[Symbol, untyped]
|
|
7
|
+
|
|
8
|
+
def initialize: (?String? message, ?context: Hash[Symbol, untyped]) -> void
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Raised when configuration is invalid or incomplete
|
|
12
|
+
class ConfigurationError < Error
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Raised when input validation fails
|
|
16
|
+
class ValidationError < Error
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Raised when translation fails
|
|
20
|
+
class TranslationError < Error
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Raised when a provider encounters an error
|
|
24
|
+
class ProviderError < Error
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Raised when an API call fails
|
|
28
|
+
class ApiError < Error
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Raised when rate limit is exceeded
|
|
32
|
+
class RateLimitError < ApiError
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Raised when file operations fail
|
|
36
|
+
class FileError < Error
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Raised when YAML parsing fails
|
|
40
|
+
class YamlError < Error
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Raised when a provider is not found
|
|
44
|
+
class ProviderNotFoundError < Error
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
# Tracks and displays translation progress
|
|
3
|
+
#
|
|
4
|
+
# Shows real-time progress updates with colored console output.
|
|
5
|
+
class ProgressTracker
|
|
6
|
+
@enabled: bool
|
|
7
|
+
@start_time: Time
|
|
8
|
+
|
|
9
|
+
attr_reader enabled: bool
|
|
10
|
+
|
|
11
|
+
def initialize: (?enabled: bool) -> void
|
|
12
|
+
|
|
13
|
+
def update: (language: String, current_key: String, progress: Float) -> void
|
|
14
|
+
|
|
15
|
+
def complete: (String language, Integer total_strings) -> void
|
|
16
|
+
|
|
17
|
+
def error: (String language, StandardError error) -> void
|
|
18
|
+
|
|
19
|
+
def reset: () -> void
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def format_time: (Float seconds) -> String
|
|
24
|
+
|
|
25
|
+
def truncate: (String text, Integer max_length) -> String
|
|
26
|
+
|
|
27
|
+
def colorize: (String text, Symbol color) -> String
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
# Factory for creating translation providers
|
|
3
|
+
#
|
|
4
|
+
# Creates the appropriate provider instance based on configuration.
|
|
5
|
+
class ProviderFactory
|
|
6
|
+
def self.create: (Symbol provider_name, Configuration config) -> Providers::BaseHttpProvider
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
module Providers
|
|
3
|
+
# Anthropic Claude translation provider
|
|
4
|
+
#
|
|
5
|
+
# Uses claude-3-5-sonnet-20241022 model for high-quality translations.
|
|
6
|
+
class AnthropicProvider < BaseHttpProvider
|
|
7
|
+
API_URL: String
|
|
8
|
+
MODEL: String
|
|
9
|
+
API_VERSION: String
|
|
10
|
+
|
|
11
|
+
type message_data = { system: String, messages: Array[Hash[Symbol, String]] }
|
|
12
|
+
|
|
13
|
+
def translate_text: (String text, String target_lang_code, String target_lang_name) -> String
|
|
14
|
+
|
|
15
|
+
def translate_batch: (Array[String] texts, String target_lang_code, String target_lang_name) -> Array[String]
|
|
16
|
+
|
|
17
|
+
# Private methods
|
|
18
|
+
def build_messages: (String text, String target_lang_name) -> message_data
|
|
19
|
+
|
|
20
|
+
def build_system_message: (String target_lang_name) -> String
|
|
21
|
+
|
|
22
|
+
def make_messages_request: (message_data message_data) -> Faraday::Response
|
|
23
|
+
|
|
24
|
+
def extract_translation: (Faraday::Response response) -> String
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
# Translation provider implementations
|
|
3
|
+
module Providers
|
|
4
|
+
# Base class for HTTP-based translation providers
|
|
5
|
+
#
|
|
6
|
+
# Implements common functionality:
|
|
7
|
+
# - Faraday HTTP client with retry logic
|
|
8
|
+
# - Exponential backoff with jitter
|
|
9
|
+
# - Rate limiting
|
|
10
|
+
# - Caching
|
|
11
|
+
# - Error handling
|
|
12
|
+
class BaseHttpProvider
|
|
13
|
+
@config: Configuration
|
|
14
|
+
@cache: Cache
|
|
15
|
+
@rate_limiter: RateLimiter
|
|
16
|
+
@http_client: Faraday::Connection?
|
|
17
|
+
|
|
18
|
+
attr_reader config: Configuration
|
|
19
|
+
attr_reader cache: Cache
|
|
20
|
+
attr_reader rate_limiter: RateLimiter
|
|
21
|
+
|
|
22
|
+
def initialize: (Configuration config) -> void
|
|
23
|
+
|
|
24
|
+
def translate_text: (String text, String target_lang_code, String target_lang_name) -> String
|
|
25
|
+
|
|
26
|
+
def translate_batch: (Array[String] texts, String target_lang_code, String target_lang_name) -> Array[String]
|
|
27
|
+
|
|
28
|
+
# Protected methods (used by subclasses)
|
|
29
|
+
def make_request: (Symbol method, String url, ?body: Hash[untyped, untyped]?, ?headers: Hash[String, String]) -> Faraday::Response
|
|
30
|
+
|
|
31
|
+
def handle_response: (Faraday::Response response) -> void
|
|
32
|
+
|
|
33
|
+
def calculate_backoff: (Integer attempt) -> Float
|
|
34
|
+
|
|
35
|
+
def log_retry: (Integer attempt, Float delay, StandardError error) -> void
|
|
36
|
+
|
|
37
|
+
def http_client: () -> Faraday::Connection
|
|
38
|
+
|
|
39
|
+
def with_cache: [T] (String cache_key) { () -> T } -> T
|
|
40
|
+
|
|
41
|
+
def build_cache_key: (String text, String target_lang_code) -> String
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
module Providers
|
|
3
|
+
# OpenAI ChatGPT translation provider
|
|
4
|
+
#
|
|
5
|
+
# Uses GPT-5-nano model with temperature=1.0 for natural translations.
|
|
6
|
+
class ChatGPTProvider < BaseHttpProvider
|
|
7
|
+
API_URL: String
|
|
8
|
+
MODEL: String
|
|
9
|
+
TEMPERATURE: Float
|
|
10
|
+
|
|
11
|
+
def translate_text: (String text, String target_lang_code, String target_lang_name) -> String
|
|
12
|
+
|
|
13
|
+
def translate_batch: (Array[String] texts, String target_lang_code, String target_lang_name) -> Array[String]
|
|
14
|
+
|
|
15
|
+
# Private methods
|
|
16
|
+
def build_messages: (String text, String target_lang_name) -> Array[Hash[Symbol, String]]
|
|
17
|
+
|
|
18
|
+
def build_system_message: (String target_lang_name) -> String
|
|
19
|
+
|
|
20
|
+
def make_chat_completion_request: (Array[Hash[Symbol, String]] messages) -> Faraday::Response
|
|
21
|
+
|
|
22
|
+
def extract_translation: (Faraday::Response response) -> String
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
module Providers
|
|
3
|
+
# Google Gemini translation provider
|
|
4
|
+
#
|
|
5
|
+
# Uses gemini-2.0-flash-exp model for fast, high-quality translations.
|
|
6
|
+
class GeminiProvider < BaseHttpProvider
|
|
7
|
+
API_URL: String
|
|
8
|
+
MODEL: String
|
|
9
|
+
|
|
10
|
+
def translate_text: (String text, String target_lang_code, String target_lang_name) -> String
|
|
11
|
+
|
|
12
|
+
def translate_batch: (Array[String] texts, String target_lang_code, String target_lang_name) -> Array[String]
|
|
13
|
+
|
|
14
|
+
# Private methods
|
|
15
|
+
def build_prompt: (String text, String target_lang_name) -> String
|
|
16
|
+
|
|
17
|
+
def make_generation_request: (String prompt) -> Faraday::Response
|
|
18
|
+
|
|
19
|
+
def extract_translation: (Faraday::Response response) -> String
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
# Thread-safe rate limiter
|
|
3
|
+
#
|
|
4
|
+
# Ensures requests are spaced out by a minimum delay.
|
|
5
|
+
class RateLimiter
|
|
6
|
+
@delay: Float
|
|
7
|
+
@last_request_time: Time?
|
|
8
|
+
@mutex: Thread::Mutex
|
|
9
|
+
|
|
10
|
+
attr_reader delay: Float
|
|
11
|
+
|
|
12
|
+
def initialize: (?delay: Float) -> void
|
|
13
|
+
|
|
14
|
+
def wait: () -> void
|
|
15
|
+
|
|
16
|
+
def record_request: () -> void
|
|
17
|
+
|
|
18
|
+
def reset: () -> void
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
# Translation strategy implementations
|
|
3
|
+
module Strategies
|
|
4
|
+
# Base class for translation strategies
|
|
5
|
+
class BaseStrategy
|
|
6
|
+
@config: Configuration
|
|
7
|
+
@provider: Providers::BaseHttpProvider
|
|
8
|
+
@progress_tracker: ProgressTracker
|
|
9
|
+
|
|
10
|
+
attr_reader config: Configuration
|
|
11
|
+
attr_reader provider: Providers::BaseHttpProvider
|
|
12
|
+
attr_reader progress_tracker: ProgressTracker
|
|
13
|
+
|
|
14
|
+
def initialize: (Configuration config, Providers::BaseHttpProvider provider, ProgressTracker progress_tracker) -> void
|
|
15
|
+
|
|
16
|
+
def translate: (Hash[String, String] strings, String target_lang_code, String target_lang_name) -> Hash[String, String]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
module Strategies
|
|
3
|
+
# Batch translation strategy
|
|
4
|
+
#
|
|
5
|
+
# Translates strings in batches for improved performance.
|
|
6
|
+
# Used for larger files (>= 50 strings).
|
|
7
|
+
class BatchStrategy < BaseStrategy
|
|
8
|
+
BATCH_SIZE: Integer
|
|
9
|
+
|
|
10
|
+
def translate: (Hash[String, String] strings, String target_lang_code, String target_lang_name) -> Hash[String, String]
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
module Strategies
|
|
3
|
+
# Deep translation strategy
|
|
4
|
+
#
|
|
5
|
+
# Translates each string individually with detailed progress tracking.
|
|
6
|
+
# Used for smaller files (< 50 strings) to provide more granular progress.
|
|
7
|
+
class DeepStrategy < BaseStrategy
|
|
8
|
+
def translate: (Hash[String, String] strings, String target_lang_code, String target_lang_name) -> Hash[String, String]
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
module Strategies
|
|
3
|
+
# Selects the appropriate translation strategy based on content size
|
|
4
|
+
class StrategySelector
|
|
5
|
+
DEEP_STRATEGY_THRESHOLD: Integer
|
|
6
|
+
|
|
7
|
+
def self.select: (Integer strings_count, Configuration config, Providers::BaseHttpProvider provider, ProgressTracker progress_tracker) -> BaseStrategy
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
# Main translator class
|
|
3
|
+
#
|
|
4
|
+
# Coordinates the translation process using configuration, providers,
|
|
5
|
+
# strategies, and YAML handling.
|
|
6
|
+
class Translator
|
|
7
|
+
type translation_results = { success_count: Integer, failure_count: Integer, errors: Array[Hash[Symbol, untyped]] }
|
|
8
|
+
|
|
9
|
+
@config: Configuration
|
|
10
|
+
@provider: Providers::BaseHttpProvider
|
|
11
|
+
@yaml_handler: YAMLHandler
|
|
12
|
+
@progress_tracker: ProgressTracker
|
|
13
|
+
|
|
14
|
+
attr_reader config: Configuration
|
|
15
|
+
|
|
16
|
+
def initialize: (Configuration config) -> void
|
|
17
|
+
|
|
18
|
+
def translate_all: () -> translation_results
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def translate_language: (Hash[String, untyped] source_strings, Hash[Symbol, String] lang) -> void
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
# Utility classes and helpers
|
|
3
|
+
module Utils
|
|
4
|
+
# Utilities for flattening and unflattening nested hashes
|
|
5
|
+
#
|
|
6
|
+
# Used to convert nested YAML structures to flat key-value pairs
|
|
7
|
+
# and back again.
|
|
8
|
+
class HashFlattener
|
|
9
|
+
def self.flatten: (Hash[untyped, untyped] hash, ?String parent_key, ?String separator) -> Hash[String, untyped]
|
|
10
|
+
|
|
11
|
+
def self.unflatten: (Hash[String, untyped] hash, ?String separator) -> Hash[String, untyped]
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
# Input validation utilities
|
|
3
|
+
#
|
|
4
|
+
# Validates language codes, text, paths, and other inputs.
|
|
5
|
+
class Validator
|
|
6
|
+
def self.validate_language_code!: (String? code) -> true
|
|
7
|
+
|
|
8
|
+
def self.validate_text!: (String? text) -> true
|
|
9
|
+
|
|
10
|
+
def self.validate_file_exists!: (String? path) -> true
|
|
11
|
+
|
|
12
|
+
def self.validate_api_key!: (String? key, provider: Symbol) -> true
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
# Extracts and preserves interpolation variables during translation
|
|
3
|
+
#
|
|
4
|
+
# Supports multiple variable formats:
|
|
5
|
+
# - Rails I18n: %{name}, %{count}
|
|
6
|
+
# - I18n.js: {{user}}, {{email}}
|
|
7
|
+
# - ES6 templates: ${var}
|
|
8
|
+
# - Simple braces: {name}
|
|
9
|
+
class VariableExtractor
|
|
10
|
+
VARIABLE_PATTERNS: Hash[Symbol, Regexp]
|
|
11
|
+
COMBINED_PATTERN: Regexp
|
|
12
|
+
PLACEHOLDER_PREFIX: String
|
|
13
|
+
PLACEHOLDER_SUFFIX: String
|
|
14
|
+
|
|
15
|
+
@original_text: String
|
|
16
|
+
@variables: Array[String]
|
|
17
|
+
@placeholder_map: Hash[String, String]
|
|
18
|
+
@reverse_map: Hash[String, String]
|
|
19
|
+
|
|
20
|
+
attr_reader original_text: String
|
|
21
|
+
attr_reader variables: Array[String]
|
|
22
|
+
attr_reader placeholder_map: Hash[String, String]
|
|
23
|
+
|
|
24
|
+
def initialize: (String text) -> void
|
|
25
|
+
|
|
26
|
+
def extract: () -> String
|
|
27
|
+
|
|
28
|
+
def restore: (String translated_text, ?strict: bool) -> String
|
|
29
|
+
|
|
30
|
+
def variables?: () -> bool
|
|
31
|
+
|
|
32
|
+
def variable_count: () -> Integer
|
|
33
|
+
|
|
34
|
+
def validate_variables!: (String text) -> true
|
|
35
|
+
|
|
36
|
+
def self.find_variables: (String? text) -> Array[String]
|
|
37
|
+
|
|
38
|
+
def self.contains_variables?: (String? text) -> bool
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
# Handles YAML file operations
|
|
3
|
+
#
|
|
4
|
+
# Provides methods for:
|
|
5
|
+
# - Reading and parsing YAML files
|
|
6
|
+
# - Writing YAML files with proper formatting
|
|
7
|
+
# - Merging translations (incremental mode)
|
|
8
|
+
# - Handling exclusions
|
|
9
|
+
# - Flattening/unflattening nested structures
|
|
10
|
+
class YAMLHandler
|
|
11
|
+
@config: Configuration
|
|
12
|
+
|
|
13
|
+
attr_reader config: Configuration
|
|
14
|
+
|
|
15
|
+
def initialize: (Configuration config) -> void
|
|
16
|
+
|
|
17
|
+
def read_yaml: (String file_path) -> Hash[untyped, untyped]
|
|
18
|
+
|
|
19
|
+
def write_yaml: (String file_path, Hash[untyped, untyped] data, ?diff_preview: untyped) -> (Hash[untyped, untyped] | nil)
|
|
20
|
+
|
|
21
|
+
def get_source_strings: () -> Hash[String, untyped]
|
|
22
|
+
|
|
23
|
+
def filter_exclusions: (Hash[String, untyped] strings, String target_lang_code) -> Hash[String, untyped]
|
|
24
|
+
|
|
25
|
+
def merge_translations: (String file_path, Hash[String, untyped] new_translations) -> Hash[String, untyped]
|
|
26
|
+
|
|
27
|
+
def build_output_path: (String target_lang_code) -> String
|
|
28
|
+
end
|
|
29
|
+
end
|
data/sig/better_translate.rbs
CHANGED
|
@@ -1,4 +1,34 @@
|
|
|
1
|
+
# BetterTranslate - AI-powered YAML locale file translator
|
|
2
|
+
#
|
|
3
|
+
# Automatically translate YAML locale files using AI providers (ChatGPT, Gemini, Claude).
|
|
4
|
+
# Features intelligent caching, batch processing, and Rails integration.
|
|
1
5
|
module BetterTranslate
|
|
2
|
-
|
|
3
|
-
|
|
6
|
+
type translation_results = { success_count: Integer, failure_count: Integer, errors: Array[Hash[Symbol, untyped]] }
|
|
7
|
+
|
|
8
|
+
@configuration: Configuration?
|
|
9
|
+
|
|
10
|
+
# Configure BetterTranslate
|
|
11
|
+
#
|
|
12
|
+
# Yields the configuration object for setting up the gem.
|
|
13
|
+
def self.configure: () { (Configuration) -> void } -> Configuration
|
|
14
|
+
|
|
15
|
+
# Get current configuration
|
|
16
|
+
#
|
|
17
|
+
# Returns the configuration instance, creating it if needed.
|
|
18
|
+
def self.configuration: () -> Configuration
|
|
19
|
+
|
|
20
|
+
# Translate files using current configuration
|
|
21
|
+
#
|
|
22
|
+
# Performs translation based on configured settings.
|
|
23
|
+
def self.translate_files: () -> translation_results
|
|
24
|
+
|
|
25
|
+
# Reset configuration
|
|
26
|
+
#
|
|
27
|
+
# Clears the current configuration.
|
|
28
|
+
def self.reset!: () -> void
|
|
29
|
+
|
|
30
|
+
# Get gem version
|
|
31
|
+
#
|
|
32
|
+
# Returns the version string.
|
|
33
|
+
def self.version: () -> String
|
|
4
34
|
end
|
data/sig/faraday.rbs
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Minimal Faraday type definitions for BetterTranslate
|
|
2
|
+
module Faraday
|
|
3
|
+
class Response
|
|
4
|
+
def status: () -> Integer
|
|
5
|
+
def body: () -> String
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class Options
|
|
9
|
+
def timeout=: (Integer value) -> Integer
|
|
10
|
+
def open_timeout=: (Integer value) -> Integer
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class Connection
|
|
14
|
+
def send: (Symbol method, String url) { (untyped) -> void } -> Response
|
|
15
|
+
def options: () -> Options
|
|
16
|
+
def adapter: (untyped adapter) -> void
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.new: () { (Connection) -> void } -> Connection
|
|
20
|
+
|
|
21
|
+
def self.default_adapter: () -> untyped
|
|
22
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
module Generators
|
|
3
|
+
# Rails generator for analyzing YAML locale files
|
|
4
|
+
#
|
|
5
|
+
# Provides statistics about translation files: string count, structure, etc.
|
|
6
|
+
class AnalyzeGenerator < Rails::Generators::Base
|
|
7
|
+
attr_reader file_path: String
|
|
8
|
+
|
|
9
|
+
def analyze_file: () -> void
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def show_structure: (Hash[untyped, untyped] hash, Integer level) -> void
|
|
14
|
+
|
|
15
|
+
def count_strings: (Hash[untyped, untyped] hash) -> Integer
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module BetterTranslate
|
|
2
|
+
module Generators
|
|
3
|
+
# Rails generator for installing BetterTranslate
|
|
4
|
+
#
|
|
5
|
+
# Creates initializer and config files for Rails applications.
|
|
6
|
+
class InstallGenerator < Rails::Generators::Base
|
|
7
|
+
def create_initializer_file: () -> void
|
|
8
|
+
|
|
9
|
+
def create_config_file: () -> void
|
|
10
|
+
|
|
11
|
+
def show_readme: () -> void
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/sig/optparse.rbs
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Minimal OptionParser type definitions for BetterTranslate
|
|
2
|
+
class OptionParser
|
|
3
|
+
def initialize: () { (OptionParser) -> void } -> void
|
|
4
|
+
def banner=: (String) -> String
|
|
5
|
+
def on: (String, String) { (String) -> void } -> void
|
|
6
|
+
| (String, String, String) { (String) -> void } -> void
|
|
7
|
+
def parse!: (Array[String]?) -> void
|
|
8
|
+
| () -> void
|
|
9
|
+
end
|
data/sig/psych.rbs
ADDED
data/sig/rails.rbs
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Minimal Rails type definitions for BetterTranslate
|
|
2
|
+
module Rails
|
|
3
|
+
class Railtie
|
|
4
|
+
# Rake tasks registration
|
|
5
|
+
def self.rake_tasks: () { () -> void } -> void
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module Generators
|
|
9
|
+
class Base
|
|
10
|
+
# Class methods
|
|
11
|
+
def self.source_root: (String path) -> String
|
|
12
|
+
def self.desc: (String description) -> String
|
|
13
|
+
def self.argument: (Symbol name, ?type: Symbol, ?required: bool, ?default: untyped, ?desc: String) -> void
|
|
14
|
+
def self.class_option: (Symbol name, ?type: Symbol, ?default: untyped, ?desc: String) -> void
|
|
15
|
+
|
|
16
|
+
# Instance methods
|
|
17
|
+
def template: (String source, String destination) -> void
|
|
18
|
+
def create_file: (String path, String content) -> void
|
|
19
|
+
def readme: (String file) -> void
|
|
20
|
+
def say: (String message, ?Symbol color) -> void
|
|
21
|
+
def behavior: () -> Symbol
|
|
22
|
+
def options: () -> Hash[Symbol, untyped]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Rails root
|
|
27
|
+
def self.root: () -> Pathname
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Pathname support for Rails.root
|
|
31
|
+
class Pathname
|
|
32
|
+
def join: (*String | Pathname paths) -> Pathname
|
|
33
|
+
def to_s: () -> String
|
|
34
|
+
end
|