Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# https://dart.dev/guides/libraries/private-files
# Created by `dart pub`
.dart_tool/

# Claude Code configuration
CLAUDE.md
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## 1.3.0
- Added Gemini-2.5-pro, Gemini-2.5-flash (new default for Gemini), and Gemini-2.5-flash-lite Support
- Updated default Gemini model from Gemini-2.0-flash to Gemini-2.5-flash
- Updated README.md

## 1.2.0
- Added Gemini-2.0-flash (new default for Gemini), Gemini-2.0-flash-lite and gpt4o-mini Support
- Deprecated Gemini-1.0-pro
- Updated README.md
- Bump dart sdk version to require 3.7 and updated packages

## 1.1.0
- Add custom model support

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ steps:
argument `--model-provider: open-ai`

4. (Optional) Select model used for translation. To do it add
`arb-translate-model` to `l10n.yaml` or use command argument `--model`. The available options are `[gemini-1.0-pro (default for Gemini), gemini-1.5-pro, gemini-1.5-flash, gpt-3.5-turbo (default for OpenAI), gpt-4, gpt-4-turbo, gpt-4o]`
`arb-translate-model` to `l10n.yaml` or use command argument `--model`. The available options are `[gemini-1.5-pro, gemini-1.5-flash, gemini-2.0-flash, gemini-2.0-flash-lite, gemini-2.5-pro, gemini-2.5-flash (default for Gemini), gemini-2.5-flash-lite, gpt-3.5-turbo (default for OpenAI), gpt-4, gpt-4-turbo, gpt-4o, gpt-4o-mini]`

5. (Optional) Add context of your application
`arb-translate-context: {your-app-context}` eg. "sporting goods store app"
Expand Down
8 changes: 5 additions & 3 deletions lib/src/find_untranslated_resource_ids.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ List<String> findUntranslatedResourceIds(
AppResourceBundle bundle,
AppResourceBundle templateBundle,
) {
final untranslatedMessageIds = templateBundle.resourceIds.where((id) =>
!bundle.resources.containsKey(id) ||
(bundle.resources[id] as String).isEmpty);
final untranslatedMessageIds = templateBundle.resourceIds.where(
(id) =>
!bundle.resources.containsKey(id) ||
(bundle.resources[id] as String).isEmpty,
);

return untranslatedMessageIds.toList();
}
78 changes: 39 additions & 39 deletions lib/src/translate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,53 +17,51 @@ import 'package:file/file.dart';
/// the ARB files.
/// The [options] parameter contains the translation options, including the
/// model provider, API key, context, safety settings, and more.
Future<void> translate(
FileSystem fileSystem,
TranslateOptions options,
) async {
Future<void> translate(FileSystem fileSystem, TranslateOptions options) async {
final translationDelegate = switch (options.modelProvider) {
ModelProvider.gemini => GeminiTranslationDelegate(
model: options.model,
apiKey: options.apiKey,
batchSize: options.batchSize,
context: options.context,
disableSafety: options.disableSafety,
useEscaping: options.useEscaping,
relaxSyntax: options.relaxSyntax,
),
model: options.model,
apiKey: options.apiKey,
batchSize: options.batchSize,
context: options.context,
disableSafety: options.disableSafety,
useEscaping: options.useEscaping,
relaxSyntax: options.relaxSyntax,
),
ModelProvider.vertexAi => GeminiTranslationDelegate.vertexAi(
model: options.model,
apiKey: options.apiKey,
projectUrl: options.vertexAiProjectUrl!,
batchSize: options.batchSize,
context: options.context,
disableSafety: options.disableSafety,
useEscaping: options.useEscaping,
relaxSyntax: options.relaxSyntax,
),
model: options.model,
apiKey: options.apiKey,
projectUrl: options.vertexAiProjectUrl!,
batchSize: options.batchSize,
context: options.context,
disableSafety: options.disableSafety,
useEscaping: options.useEscaping,
relaxSyntax: options.relaxSyntax,
),
ModelProvider.openAi => ChatGptTranslationDelegate(
model: options.model,
apiKey: options.apiKey,
batchSize: options.batchSize,
context: options.context,
useEscaping: options.useEscaping,
relaxSyntax: options.relaxSyntax,
),
model: options.model,
apiKey: options.apiKey,
batchSize: options.batchSize,
context: options.context,
useEscaping: options.useEscaping,
relaxSyntax: options.relaxSyntax,
),
ModelProvider.customOpenAiCompatible => ChatGptTranslationDelegate.custom(
model: options.customModel!,
apiKey: options.apiKey,
baseUrl: options.customModelProviderBaseUrl!,
batchSize: options.batchSize,
context: options.context,
useEscaping: options.useEscaping,
relaxSyntax: options.relaxSyntax,
),
model: options.customModel!,
apiKey: options.apiKey,
baseUrl: options.customModelProviderBaseUrl!,
batchSize: options.batchSize,
context: options.context,
useEscaping: options.useEscaping,
relaxSyntax: options.relaxSyntax,
),
};

final bundles =
AppResourceBundleCollection(fileSystem.directory(options.arbDir)).bundles;
final templateBundle = bundles.firstWhere(
(bundle) => bundle.file.path.endsWith(options.templateArbFile));
(bundle) => bundle.file.path.endsWith(options.templateArbFile),
);

for (final bundle in bundles.where((bundle) => bundle != templateBundle)) {
if (options.excludeLocales?.contains(bundle.locale.toString()) ?? false) {
Expand All @@ -85,8 +83,10 @@ Future<void> _translateBundle({
required AppResourceBundle templateBundle,
required AppResourceBundle bundle,
}) async {
final untranslatedResourceIds =
findUntranslatedResourceIds(bundle, templateBundle);
final untranslatedResourceIds = findUntranslatedResourceIds(
bundle,
templateBundle,
);

if (untranslatedResourceIds.isEmpty) {
print('No terms to translate for locale ${bundle.locale}');
Expand Down
Loading