New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

ngx-i18nsupport

Package Overview
Dependencies
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ngx-i18nsupport - npm Package Compare versions

Comparing version 0.6.2 to 0.7.0

dist/autotranslate/auto-translate-result.js

9

Changelog.md

@@ -0,1 +1,10 @@

<a name="0.7.0"></a>
# [0.7.0](https://github.com/martinroob/ngx-i18nsupport/compare/v0.6.2...v0.7.0) (2017-07-07)
### Features
* **autotranslate:** Added google translate support ([#35](https://github.com/martinroob/ngx-i18nsupport/issues/35)).
You can now use the [Google Cloud Translation API](https://cloud.google.com/translate/) to automatically translate new units to different target languages.
For details how to use it have a look at the Wiki Page [xliffmerge-autotranslate-feature](https://github.com/martinroob/ngx-i18nsupport/wiki/xliffmerge-autotranslate-feature).
<a name="0.6.2"></a>

@@ -2,0 +11,0 @@ # [0.6.2](https://github.com/martinroob/ngx-i18nsupport/compare/v0.6.1...v0.6.2) (2017-06-02)

163

dist/xliffmerge/xlf12-merge.spec.js

@@ -9,2 +9,4 @@ "use strict";

var translation_messages_file_reader_1 = require("./translation-messages-file-reader");
var util_1 = require("util");
var auto_translate_service_spec_1 = require("../autotranslate/auto-translate-service.spec");
/**

@@ -29,3 +31,12 @@ * Created by martin on 18.02.2017.

function readXliff(path) {
return translation_messages_file_reader_1.TranslationMessagesFileReader.fromFile('xlf', path, ENCODING);
if (!path) {
throw new Error('oops, no file');
}
try {
return translation_messages_file_reader_1.TranslationMessagesFileReader.fromFile('xlf', path, ENCODING);
}
catch (err) {
console.log(util_1.format('error reading %s: "%s"', path, err.message));
return null;
}
}

@@ -191,3 +202,3 @@ describe('Merge process checks for format xlf', function () {

expect(ws.writtenData()).toContain('merged 12 trans-units from master to "en"');
expect(ws.writtenData()).toContain('removed 2 unused trans-units in "en"');
expect(ws.writtenData()).toContain('removed 3 unused trans-units in "en"');
// look, that the new file contains the old translation

@@ -277,2 +288,150 @@ langFileEnglish = readXliff(xliffMergeCmd.generatedI18nFile('en'));

});
describe('autotranslate via google translate', function () {
var apikey;
var ID_NACHRICHTEN = '57e605bfa130afb4de4ee40e496e854a9e8a28a7';
var ID_BESCHREIBUNG_WITH_PLACEHOLDER = 'a52ba049c16778bdb2e5a19a41acaadf87b104dc';
var ID_ICUMESSAGE = 'efec69fdcf74bd6d640b2a771558b7b09e271c28';
beforeEach(function () {
apikey = auto_translate_service_spec_1.getApiKey();
});
it('should detect invalid key', function (done) {
if (!apikey) {
// skip test
done();
return;
}
file_util_1.FileUtil.copy(MASTER1SRC, MASTER);
var ws = new writer_to_string_1.WriterToString();
var commandOut = new command_output_1.CommandOutput(ws);
var profileContent = {
xliffmergeOptions: {
defaultLanguage: 'de',
srcDir: WORKDIR,
genDir: WORKDIR,
i18nFile: MASTERFILE,
autotranslate: true,
apikey: 'lmaa'
}
};
var xliffMergeCmd = xliff_merge_1.XliffMerge.createFromOptions(commandOut, { languages: ['de', 'en'] }, profileContent);
xliffMergeCmd.run(function (retcode) {
expect(ws.writtenData()).toContain('API key not valid');
done();
});
});
it('should auto translate file', function (done) {
if (!apikey) {
// skip test
done();
return;
}
file_util_1.FileUtil.copy(MASTER1SRC, MASTER);
var ws = new writer_to_string_1.WriterToString();
var commandOut = new command_output_1.CommandOutput(ws);
var profileContent = {
xliffmergeOptions: {
defaultLanguage: 'de',
srcDir: WORKDIR,
genDir: WORKDIR,
i18nFile: MASTERFILE,
autotranslate: true,
apikey: apikey
}
};
var xliffMergeCmd = xliff_merge_1.XliffMerge.createFromOptions(commandOut, { languages: ['de', 'en'] }, profileContent);
xliffMergeCmd.run(function () {
expect(ws.writtenData()).not.toContain('ERROR');
var langFileEnglish = readXliff(xliffMergeCmd.generatedI18nFile('en'));
expect(langFileEnglish.targetLanguage()).toBe('en');
var tu = langFileEnglish.transUnitWithId(ID_NACHRICHTEN);
expect(tu.sourceContent()).toBe('Nachrichten');
expect(tu.targetContent()).toBe('news');
expect(tu.targetState()).toBe('translated');
var tuICU = langFileEnglish.transUnitWithId(ID_ICUMESSAGE);
expect(tuICU.sourceContent()).toContain('VAR_PLURAL');
expect(tuICU.targetContent()).toBe('{VAR_PLURAL, plural, =0 {No sheep} =1 {1 sheep} other {X sheep}}');
expect(tuICU.targetState()).toBe('translated');
done();
});
});
it('should auto translate file with region code (which will be ignored)', function (done) {
if (!apikey) {
// skip test
done();
return;
}
file_util_1.FileUtil.copy(MASTER1SRC, MASTER);
var ws = new writer_to_string_1.WriterToString();
var commandOut = new command_output_1.CommandOutput(ws);
var profileContent = {
xliffmergeOptions: {
defaultLanguage: 'de-de',
srcDir: WORKDIR,
genDir: WORKDIR,
i18nFile: MASTERFILE,
autotranslate: true,
apikey: apikey
}
};
var xliffMergeCmd = xliff_merge_1.XliffMerge.createFromOptions(commandOut, { languages: ['de-de', 'en-us'] }, profileContent);
xliffMergeCmd.run(function (retcode) {
expect(ws.writtenData()).not.toContain('ERROR');
var langFileEnglish = readXliff(xliffMergeCmd.generatedI18nFile('en-us'));
expect(langFileEnglish).toBeTruthy();
if (langFileEnglish) {
expect(langFileEnglish.targetLanguage()).toBe('en-us');
var tu = langFileEnglish.transUnitWithId(ID_BESCHREIBUNG_WITH_PLACEHOLDER);
expect(tu.sourceContentNormalized().asDisplayString()).toBe('Beschreibung zu {{0}} ({{1}})');
expect(tu.targetContentNormalized().asDisplayString()).toBe('Description of {{0}} ({{1}})');
expect(tu.targetState()).toBe('translated');
}
done();
});
});
it('should detect unsupported language when using auto translate', function (done) {
if (!apikey) {
// skip test
done();
return;
}
file_util_1.FileUtil.copy(MASTER1SRC, MASTER);
var ws = new writer_to_string_1.WriterToString();
var commandOut = new command_output_1.CommandOutput(ws);
var profileContent = {
xliffmergeOptions: {
defaultLanguage: 'de',
languages: ['de', 'xy', 'en'],
srcDir: WORKDIR,
genDir: WORKDIR,
i18nFile: MASTERFILE,
autotranslate: true,
apikey: apikey
}
};
var xliffMergeCmd = xliff_merge_1.XliffMerge.createFromOptions(commandOut, { verbose: true }, profileContent);
xliffMergeCmd.run(function (retcode) {
expect(ws.writtenData()).toContain('ERROR');
expect(ws.writtenData()).toContain('"xy" not supported');
var langFileEnglish = readXliff(xliffMergeCmd.generatedI18nFile('en'));
expect(langFileEnglish).toBeTruthy();
if (langFileEnglish) {
expect(langFileEnglish.targetLanguage()).toBe('en');
var tu = langFileEnglish.transUnitWithId(ID_BESCHREIBUNG_WITH_PLACEHOLDER);
expect(tu.sourceContentNormalized().asDisplayString()).toBe('Beschreibung zu {{0}} ({{1}})');
expect(tu.targetContentNormalized().asDisplayString()).toBe('Description of {{0}} ({{1}})');
expect(tu.targetState()).toBe('translated');
}
var langFileXy = readXliff(xliffMergeCmd.generatedI18nFile('xy'));
expect(langFileXy).toBeTruthy();
if (langFileXy) {
expect(langFileXy.targetLanguage()).toBe('xy');
var tu = langFileXy.transUnitWithId(ID_BESCHREIBUNG_WITH_PLACEHOLDER);
expect(tu.sourceContentNormalized().asDisplayString()).toBe('Beschreibung zu {{0}} ({{1}})');
expect(tu.targetContentNormalized().asDisplayString()).toBe('Beschreibung zu {{0}} ({{1}})');
expect(tu.targetState()).toBe('new');
}
done();
});
});
});
});

@@ -279,0 +438,0 @@ describe('ngx-translate processing for format xlf', function () {

@@ -125,2 +125,8 @@ /**

}
if (!util_1.isNullOrUndefined(profile.autotranslate)) {
this._autotranslate = profile.autotranslate;
}
if (profile.apikey) {
this._apikey = profile.apikey;
}
}

@@ -177,2 +183,15 @@ else {

}
// autotranslate requires api key
if (this.autotranslate() && !this.apikey()) {
this.errorsFound.push(new xliff_merge_error_1.XliffMergeError('autotranslate requires an API key, please set one'));
}
// autotranslated languages must be in list of all languages
this.autotranslatedLanguages().forEach(function (lang) {
if (_this.languages().indexOf(lang) < 0) {
_this.errorsFound.push(new xliff_merge_error_1.XliffMergeError('autotranslate language "' + lang + '" is not in list of languages'));
}
if (_this.languages().length > 0 && lang === _this.languages()[0]) {
_this.errorsFound.push(new xliff_merge_error_1.XliffMergeError('autotranslate language "' + lang + '" cannot be translated, because it is the source language'));
}
});
};

@@ -211,2 +230,7 @@ /**

commandOutput.debug('useSourceAsTarget:\t%s', this.useSourceAsTarget());
commandOutput.debug('autotranslate:\t%s', this.autotranslate());
if (this.autotranslate()) {
commandOutput.debug('autotranslated languages:\t%s', this.autotranslatedLanguages());
}
commandOutput.debug('apikey:\t%s', this.apikey());
};

@@ -303,2 +327,41 @@ /**

};
/**
* Whether to use autotranslate for new trans-units
* Default is false
*/
XliffMergeParameters.prototype.autotranslate = function () {
if (util_1.isNullOrUndefined(this._autotranslate)) {
return false;
}
if (util_1.isArray(this._autotranslate)) {
return this._autotranslate.length > 0;
}
return this._autotranslate;
};
/**
* Whether to use autotranslate for a given language.
* @param lang language code.
*/
XliffMergeParameters.prototype.autotranslateLanguage = function (lang) {
return this.autotranslatedLanguages().indexOf(lang) >= 0;
};
/**
* Return a list of languages to be autotranslated.
*/
XliffMergeParameters.prototype.autotranslatedLanguages = function () {
if (util_1.isNullOrUndefined(this._autotranslate) || this._autotranslate === false) {
return [];
}
if (util_1.isArray(this._autotranslate)) {
return this._autotranslate;
}
return this.languages().slice(1); // first is source language
};
/**
* API key to be used for Google Translate
* @return {string}
*/
XliffMergeParameters.prototype.apikey = function () {
return this._apikey;
};
return XliffMergeParameters;

@@ -305,0 +368,0 @@ }());

206

dist/xliffmerge/xliff-merge.js

@@ -13,2 +13,5 @@ "use strict";

var translation_messages_file_reader_1 = require("./translation-messages-file-reader");
var rxjs_1 = require("rxjs");
var xliff_merge_auto_translate_service_1 = require("../autotranslate/xliff-merge-auto-translate-service");
var auto_translate_summary_report_1 = require("../autotranslate/auto-translate-summary-report");
/**

@@ -27,4 +30,5 @@ * Created by martin on 17.02.2017.

var options = XliffMerge.parseArgs(argv);
var result = new XliffMerge(new command_output_1.CommandOutput(process.stdout), options).run();
process.exit(result);
new XliffMerge(new command_output_1.CommandOutput(process.stdout), options).run(function (result) {
process.exit(result);
});
};

@@ -79,22 +83,18 @@ XliffMerge.parseArgs = function (argv) {

};
XliffMerge.prototype.run = function () {
try {
this.doRun();
return 0;
}
catch (err) {
if (err instanceof xliff_merge_error_1.XliffMergeError) {
this.commandOutput.error(err.message);
return -1;
/**
* Run the command.
* This runs async.
* @param callbackFunction when command is executed, called with the return code (0 for ok), if given.
*/
XliffMerge.prototype.run = function (callbackFunction) {
this.doRun()
.subscribe(function (retcode) {
if (!util_1.isNullOrUndefined(callbackFunction)) {
callbackFunction(retcode);
}
else {
// unhandled
var filenameString = (this.currentFilename) ? util_1.format('file "%s", ', this.currentFilename) : '';
this.commandOutput.error(filenameString + 'oops ' + err);
throw err;
}
}
});
};
/**
* Ausführen merge-Process.
* Execute merge-Process.
* @return Async operation, on completion returns retcode 0=ok, other = error.
*/

@@ -121,3 +121,3 @@ XliffMerge.prototype.doRun = function () {

}
return;
return rxjs_1.Observable.of(-1);
}

@@ -131,7 +131,26 @@ if (this.parameters.warningsFound.length > 0) {

this.readMaster();
if (this.parameters.autotranslate()) {
this.autoTranslateService = new xliff_merge_auto_translate_service_1.XliffMergeAutoTranslateService(this.parameters.apikey());
}
var executionForAllLanguages = [];
this.parameters.languages().forEach(function (lang) {
_this.processLanguage(lang);
executionForAllLanguages.push(_this.processLanguage(lang));
});
return rxjs_1.Observable.forkJoin(executionForAllLanguages).map(function (retcodes) { return _this.totalRetcode(retcodes); });
};
/**
* Give an array of retcodes for the different languages, return the total retcode.
* If all are 0, it is 0, otherwise the first non zero.
* @param retcodes
* @return {number}
*/
XliffMerge.prototype.totalRetcode = function (retcodes) {
for (var i = 0; i < retcodes.length; i++) {
if (retcodes[i] !== 0) {
return retcodes[i];
}
}
return 0;
};
/**
* Return the name of the generated file for given lang.

@@ -154,37 +173,73 @@ * @param lang

var _this = this;
this.currentFilename = this.parameters.i18nFile();
this.master = translation_messages_file_reader_1.TranslationMessagesFileReader.fromFile(this.parameters.i18nFormat(), this.parameters.i18nFile(), this.parameters.encoding());
this.master.warnings().forEach(function (warning) {
_this.commandOutput.warn(warning);
});
var count = this.master.numberOfTransUnits();
var missingIdCount = this.master.numberOfTransUnitsWithMissingId();
this.commandOutput.info('master contains %s trans-units', count);
if (missingIdCount > 0) {
this.commandOutput.warn('master contains %s trans-units, but there are %s without id', count, missingIdCount);
try {
this.master = translation_messages_file_reader_1.TranslationMessagesFileReader.fromFile(this.parameters.i18nFormat(), this.parameters.i18nFile(), this.parameters.encoding());
this.master.warnings().forEach(function (warning) {
_this.commandOutput.warn(warning);
});
var count = this.master.numberOfTransUnits();
var missingIdCount = this.master.numberOfTransUnitsWithMissingId();
this.commandOutput.info('master contains %s trans-units', count);
if (missingIdCount > 0) {
this.commandOutput.warn('master contains %s trans-units, but there are %s without id', count, missingIdCount);
}
var sourceLang = this.master.sourceLanguage();
if (sourceLang && sourceLang !== this.parameters.defaultLanguage()) {
this.commandOutput.warn('master says to have source-language="%s", should be "%s" (your defaultLanguage)', sourceLang, this.parameters.defaultLanguage());
this.master.setSourceLanguage(this.parameters.defaultLanguage());
translation_messages_file_reader_1.TranslationMessagesFileReader.save(this.master);
this.commandOutput.warn('changed master source-language="%s" to "%s"', sourceLang, this.parameters.defaultLanguage());
}
}
var sourceLang = this.master.sourceLanguage();
if (sourceLang && sourceLang !== this.parameters.defaultLanguage()) {
this.commandOutput.warn('master says to have source-language="%s", should be "%s" (your defaultLanguage)', sourceLang, this.parameters.defaultLanguage());
this.master.setSourceLanguage(this.parameters.defaultLanguage());
translation_messages_file_reader_1.TranslationMessagesFileReader.save(this.master);
this.commandOutput.warn('changed master source-language="%s" to "%s"', sourceLang, this.parameters.defaultLanguage());
catch (err) {
if (err instanceof xliff_merge_error_1.XliffMergeError) {
this.commandOutput.error(err.message);
return rxjs_1.Observable.of(-1);
}
else {
// unhandled
var currentFilename = this.parameters.i18nFile();
var filenameString = (currentFilename) ? util_1.format('file "%s", ', currentFilename) : '';
this.commandOutput.error(filenameString + 'oops ' + err);
throw err;
}
}
this.currentFilename = null;
};
/**
* Process the given language.
* Async operation.
* @param lang
* @return {Observable<number>} on completion 0 for ok, other for error
*/
XliffMerge.prototype.processLanguage = function (lang) {
var _this = this;
this.commandOutput.debug('processing language %s', lang);
var languageXliffFile = this.parameters.generatedI18nFile(lang);
this.currentFilename = languageXliffFile;
var currentFilename = languageXliffFile;
var result;
if (!file_util_1.FileUtil.exists(languageXliffFile)) {
this.createUntranslatedXliff(lang, languageXliffFile);
result = this.createUntranslatedXliff(lang, languageXliffFile);
}
else {
this.mergeMasterTo(lang, languageXliffFile);
result = this.mergeMasterTo(lang, languageXliffFile);
}
if (this.parameters.supportNgxTranslate()) {
var languageSpecificMessagesFile = translation_messages_file_reader_1.TranslationMessagesFileReader.fromFile(XliffMerge.translationFormat(this.parameters.i18nFormat()), languageXliffFile, this.parameters.encoding(), this.master.filename());
ngx_translate_extractor_1.NgxTranslateExtractor.extract(languageSpecificMessagesFile, this.parameters.generatedNgxTranslateFile(lang));
}
this.currentFilename = null;
return result
.map(function () {
if (_this.parameters.supportNgxTranslate()) {
var languageSpecificMessagesFile = translation_messages_file_reader_1.TranslationMessagesFileReader.fromFile(XliffMerge.translationFormat(_this.parameters.i18nFormat()), languageXliffFile, _this.parameters.encoding(), _this.master.filename());
ngx_translate_extractor_1.NgxTranslateExtractor.extract(languageSpecificMessagesFile, _this.parameters.generatedNgxTranslateFile(lang));
}
return 0;
})
.catch(function (err) {
if (err instanceof xliff_merge_error_1.XliffMergeError) {
_this.commandOutput.error(err.message);
return rxjs_1.Observable.of(-1);
}
else {
// unhandled
var filenameString = (currentFilename) ? util_1.format('file "%s", ', currentFilename) : '';
_this.commandOutput.error(filenameString + 'oops ' + err);
throw err;
}
});
};

@@ -198,2 +253,3 @@ /**

XliffMerge.prototype.createUntranslatedXliff = function (lang, languageXliffFilePath) {
var _this = this;
// copy master ...

@@ -204,8 +260,11 @@ // and set target-language

var languageSpecificMessagesFile = this.master.createTranslationFileForLang(lang, languageXliffFilePath, isDefaultLang, this.parameters.useSourceAsTarget());
// write it to file
translation_messages_file_reader_1.TranslationMessagesFileReader.save(languageSpecificMessagesFile);
this.commandOutput.info('created new file "%s" for target-language="%s"', languageXliffFilePath, lang);
if (!isDefaultLang) {
this.commandOutput.warn('please translate file "%s" to target-language="%s"', languageXliffFilePath, lang);
}
return this.autoTranslate(this.master.sourceLanguage(), lang, languageSpecificMessagesFile).map(function (summary) {
// write it to file
translation_messages_file_reader_1.TranslationMessagesFileReader.save(languageSpecificMessagesFile);
_this.commandOutput.info('created new file "%s" for target-language="%s"', languageXliffFilePath, lang);
if (!isDefaultLang) {
_this.commandOutput.warn('please translate file "%s" to target-language="%s"', languageXliffFilePath, lang);
}
return null;
});
};

@@ -281,8 +340,12 @@ /**

else {
// write it to file
translation_messages_file_reader_1.TranslationMessagesFileReader.save(languageSpecificMessagesFile);
this.commandOutput.info('updated file "%s" for target-language="%s"', languageXliffFilePath, lang);
if (newCount > 0 && !isDefaultLang) {
this.commandOutput.warn('please translate file "%s" to target-language="%s"', languageXliffFilePath, lang);
}
return this.autoTranslate(this.master.sourceLanguage(), lang, languageSpecificMessagesFile)
.map(function () {
// write it to file
translation_messages_file_reader_1.TranslationMessagesFileReader.save(languageSpecificMessagesFile);
_this.commandOutput.info('updated file "%s" for target-language="%s"', languageXliffFilePath, lang);
if (newCount > 0 && !isDefaultLang) {
_this.commandOutput.warn('please translate file "%s" to target-language="%s"', languageXliffFilePath, lang);
}
return null;
});
}

@@ -313,2 +376,29 @@ };

};
/**
* Auto translate file via Google Translate.
* Will translate all new units in file.
* @param from
* @param to
* @param languageSpecificMessagesFile
* @return a promise with the execution result as a summary report.
*/
XliffMerge.prototype.autoTranslate = function (from, to, languageSpecificMessagesFile) {
var _this = this;
var serviceCall;
if (this.parameters.autotranslateLanguage(to)) {
serviceCall = this.autoTranslateService.autoTranslate(from, to, languageSpecificMessagesFile);
}
else {
serviceCall = rxjs_1.Observable.of(new auto_translate_summary_report_1.AutoTranslateSummaryReport(from, to));
}
return serviceCall.map(function (summary) {
if (summary.error() || summary.failed() > 0) {
_this.commandOutput.error(summary.content());
}
else {
_this.commandOutput.warn(summary.content());
}
return summary;
});
};
return XliffMerge;

@@ -315,0 +405,0 @@ }());

@@ -154,2 +154,60 @@ "use strict";

});
it('should output an error when autotranslate is set to true and there is no api key set', function (done) {
var ws = new writer_to_string_1.WriterToString();
var commandOut = new command_output_1.CommandOutput(ws);
var profileContent = {
xliffmergeOptions: {
autotranslate: true,
}
};
var xliffMergeCmd = xliff_merge_1.XliffMerge.createFromOptions(commandOut, {}, profileContent);
xliffMergeCmd.run();
expect(ws.writtenData()).toContain('ERROR');
expect(ws.writtenData()).toContain('autotranslate requires an API key');
done();
});
it('should output an error when autotranslate is set to a list of languages and there is no api key set', function (done) {
var ws = new writer_to_string_1.WriterToString();
var commandOut = new command_output_1.CommandOutput(ws);
var profileContent = {
xliffmergeOptions: {
autotranslate: ['de'],
}
};
var xliffMergeCmd = xliff_merge_1.XliffMerge.createFromOptions(commandOut, {}, profileContent);
xliffMergeCmd.run();
expect(ws.writtenData()).toContain('ERROR');
expect(ws.writtenData()).toContain('autotranslate requires an API key');
done();
});
it('should output an error when autotranslate language is not in list of languages', function (done) {
var ws = new writer_to_string_1.WriterToString();
var commandOut = new command_output_1.CommandOutput(ws);
var profileContent = {
xliffmergeOptions: {
languages: ['en', 'ru'],
autotranslate: ['de'],
}
};
var xliffMergeCmd = xliff_merge_1.XliffMerge.createFromOptions(commandOut, {}, profileContent);
xliffMergeCmd.run();
expect(ws.writtenData()).toContain('ERROR');
expect(ws.writtenData()).toContain('autotranslate language "de" is not in list of languages');
done();
});
it('should output an error when autotranslate language is set to default language', function (done) {
var ws = new writer_to_string_1.WriterToString();
var commandOut = new command_output_1.CommandOutput(ws);
var profileContent = {
xliffmergeOptions: {
languages: ['en', 'ru'],
autotranslate: ['en', 'ru'],
}
};
var xliffMergeCmd = xliff_merge_1.XliffMerge.createFromOptions(commandOut, {}, profileContent);
xliffMergeCmd.run();
expect(ws.writtenData()).toContain('ERROR');
expect(ws.writtenData()).toContain('autotranslate language "en" cannot be translated, because it is the source language');
done();
});
it('should accept i18n format xlf', function (done) {

@@ -156,0 +214,0 @@ var ws = new writer_to_string_1.WriterToString();

{
"name": "ngx-i18nsupport",
"version": "0.6.2",
"version": "0.7.0",
"description": "Some tooling to be used with the Angular 2 i18n workflow",

@@ -19,2 +19,3 @@ "main": "index.js",

"test": "./node_modules/.bin/jasmine-node dist",
"testintern": "set API_KEY_FILE=s:\\experimente\\ngx-i18nsupport\\googleTranslateApiKey.txt&& npm run test",
"precover": "npm run build",

@@ -44,2 +45,3 @@ "cover": "./node_modules/.bin/istanbul cover --root dist --include-all-sources ./node_modules/jasmine-node/bin/jasmine-node -- dist",

"@types/node": "^7.0.5",
"@types/request": "^0.0.45",
"coveralls": "^2.11.16",

@@ -52,6 +54,8 @@ "cpx": "^1.5.0",

"dependencies": {
"@akanass/rx-http-request": "^2.3.0",
"chalk": "^1.1.3",
"commander": "^2.9.0",
"ngx-i18nsupport-lib": "^1.3.1"
"ngx-i18nsupport-lib": "^1.4.6",
"rxjs": "^5.4.2"
}
}

@@ -97,4 +97,6 @@ [![Build Status][travis-badge]][travis-badge-url]

"useSourceAsTarget": false,
"autotranslate": false,
"apikey": "",
"verbose": false,
"quiet": false,
"quiet": false
}

@@ -115,2 +117,6 @@ }

- `useSourceAsTarget` (boolean, default `true`): flag, if source should be copied to target for new trans-units
- `autotranslate` (since v0.7.0) (boolean or array of strings, default `false`): flag, if new units should be automatically translated by Google Translate.
You can also specify a string array with the languages you want to auto translate (e.g `"autotranslate": ["fr", "ru"]`).
For details how to use it have a look at the Wiki Page [xliffmerge-autotranslate-feature](https://github.com/martinroob/ngx-i18nsupport/wiki/xliffmerge-autotranslate-feature).
- `apikey` (since v0.7.0) (string, default ""): API key for usage of Google Translate. Must be set if you activate it by setting `autotranslate`.
- `verbose` (boolean, default `false`): controls output

@@ -117,0 +123,0 @@ - `quiet` (boolean, default `false`): controls output

@@ -40,3 +40,8 @@ /**

useSourceAsTarget?: boolean; // Flag, whether source must be used as target for new trans-units
autotranslate?: boolean|string[]; // enable auto translate via Google Translate
// if it is an array, list of languages to autotranslate
// if it is true, autotranslate all languages (except source language of course)
// if it is false (default) no autotranslate
apikey?: string; // API Key for Google Translate, required if autotranlate is enabled
}

@@ -10,2 +10,4 @@ import * as fs from "fs";

import {TranslationMessagesFileReader} from './translation-messages-file-reader';
import {format} from 'util';
import {getApiKey} from '../autotranslate/auto-translate-service.spec';

@@ -35,3 +37,11 @@ /**

function readXliff(path: string): ITranslationMessagesFile {
return TranslationMessagesFileReader.fromFile('xlf', path, ENCODING);
if (!path) {
throw new Error('oops, no file');
}
try {
return TranslationMessagesFileReader.fromFile('xlf', path, ENCODING);
} catch (err) {
console.log(format('error reading %s: "%s"', path, err.message));
return null;
}
}

@@ -207,3 +217,3 @@

expect(ws.writtenData()).toContain('merged 12 trans-units from master to "en"');
expect(ws.writtenData()).toContain('removed 2 unused trans-units in "en"');
expect(ws.writtenData()).toContain('removed 3 unused trans-units in "en"');

@@ -302,2 +312,158 @@ // look, that the new file contains the old translation

describe('autotranslate via google translate', () => {
let apikey: string;
const ID_NACHRICHTEN = '57e605bfa130afb4de4ee40e496e854a9e8a28a7';
const ID_BESCHREIBUNG_WITH_PLACEHOLDER = 'a52ba049c16778bdb2e5a19a41acaadf87b104dc';
const ID_ICUMESSAGE = 'efec69fdcf74bd6d640b2a771558b7b09e271c28';
beforeEach(() => {
apikey = getApiKey();
});
it('should detect invalid key', (done) => {
if (!apikey) {
// skip test
done();
return;
}
FileUtil.copy(MASTER1SRC, MASTER);
let ws: WriterToString = new WriterToString();
let commandOut = new CommandOutput(ws);
let profileContent: IConfigFile = {
xliffmergeOptions: {
defaultLanguage: 'de',
srcDir: WORKDIR,
genDir: WORKDIR,
i18nFile: MASTERFILE,
autotranslate: true,
apikey: 'lmaa'
}
};
let xliffMergeCmd = XliffMerge.createFromOptions(commandOut, {languages: ['de', 'en']}, profileContent);
xliffMergeCmd.run((retcode) => {
expect(ws.writtenData()).toContain('API key not valid');
done();
});
});
it('should auto translate file', (done) => {
if (!apikey) {
// skip test
done();
return;
}
FileUtil.copy(MASTER1SRC, MASTER);
let ws: WriterToString = new WriterToString();
let commandOut = new CommandOutput(ws);
let profileContent: IConfigFile = {
xliffmergeOptions: {
defaultLanguage: 'de',
srcDir: WORKDIR,
genDir: WORKDIR,
i18nFile: MASTERFILE,
autotranslate: true,
apikey: apikey
}
};
let xliffMergeCmd = XliffMerge.createFromOptions(commandOut, {languages: ['de', 'en']}, profileContent);
xliffMergeCmd.run(() => {
expect(ws.writtenData()).not.toContain('ERROR');
let langFileEnglish: ITranslationMessagesFile = readXliff(xliffMergeCmd.generatedI18nFile('en'));
expect(langFileEnglish.targetLanguage()).toBe('en');
let tu = langFileEnglish.transUnitWithId(ID_NACHRICHTEN);
expect(tu.sourceContent()).toBe('Nachrichten');
expect(tu.targetContent()).toBe('news');
expect(tu.targetState()).toBe('translated');
let tuICU = langFileEnglish.transUnitWithId(ID_ICUMESSAGE);
expect(tuICU.sourceContent()).toContain('VAR_PLURAL');
expect(tuICU.targetContent()).toBe('{VAR_PLURAL, plural, =0 {No sheep} =1 {1 sheep} other {X sheep}}');
expect(tuICU.targetState()).toBe('translated');
done();
});
});
it('should auto translate file with region code (which will be ignored)', (done) => {
if (!apikey) {
// skip test
done();
return;
}
FileUtil.copy(MASTER1SRC, MASTER);
let ws: WriterToString = new WriterToString();
let commandOut = new CommandOutput(ws);
let profileContent: IConfigFile = {
xliffmergeOptions: {
defaultLanguage: 'de-de',
srcDir: WORKDIR,
genDir: WORKDIR,
i18nFile: MASTERFILE,
autotranslate: true,
apikey: apikey
}
};
let xliffMergeCmd = XliffMerge.createFromOptions(commandOut, {languages: ['de-de', 'en-us']}, profileContent);
xliffMergeCmd.run((retcode) => {
expect(ws.writtenData()).not.toContain('ERROR');
let langFileEnglish: ITranslationMessagesFile = readXliff(xliffMergeCmd.generatedI18nFile('en-us'));
expect(langFileEnglish).toBeTruthy();
if (langFileEnglish) {
expect(langFileEnglish.targetLanguage()).toBe('en-us');
let tu = langFileEnglish.transUnitWithId(ID_BESCHREIBUNG_WITH_PLACEHOLDER);
expect(tu.sourceContentNormalized().asDisplayString()).toBe('Beschreibung zu {{0}} ({{1}})');
expect(tu.targetContentNormalized().asDisplayString()).toBe('Description of {{0}} ({{1}})');
expect(tu.targetState()).toBe('translated');
}
done();
});
});
it('should detect unsupported language when using auto translate', (done) => {
if (!apikey) {
// skip test
done();
return;
}
FileUtil.copy(MASTER1SRC, MASTER);
let ws: WriterToString = new WriterToString();
let commandOut = new CommandOutput(ws);
let profileContent: IConfigFile = {
xliffmergeOptions: {
defaultLanguage: 'de',
languages: ['de', 'xy', 'en'],
srcDir: WORKDIR,
genDir: WORKDIR,
i18nFile: MASTERFILE,
autotranslate: true,
apikey: apikey
}
};
let xliffMergeCmd = XliffMerge.createFromOptions(commandOut, {verbose: true}, profileContent);
xliffMergeCmd.run((retcode) => {
expect(ws.writtenData()).toContain('ERROR');
expect(ws.writtenData()).toContain('"xy" not supported');
let langFileEnglish: ITranslationMessagesFile = readXliff(xliffMergeCmd.generatedI18nFile('en'));
expect(langFileEnglish).toBeTruthy();
if (langFileEnglish) {
expect(langFileEnglish.targetLanguage()).toBe('en');
let tu = langFileEnglish.transUnitWithId(ID_BESCHREIBUNG_WITH_PLACEHOLDER);
expect(tu.sourceContentNormalized().asDisplayString()).toBe('Beschreibung zu {{0}} ({{1}})');
expect(tu.targetContentNormalized().asDisplayString()).toBe('Description of {{0}} ({{1}})');
expect(tu.targetState()).toBe('translated');
}
let langFileXy: ITranslationMessagesFile = readXliff(xliffMergeCmd.generatedI18nFile('xy'));
expect(langFileXy).toBeTruthy();
if (langFileXy) {
expect(langFileXy.targetLanguage()).toBe('xy');
let tu = langFileXy.transUnitWithId(ID_BESCHREIBUNG_WITH_PLACEHOLDER);
expect(tu.sourceContentNormalized().asDisplayString()).toBe('Beschreibung zu {{0}} ({{1}})');
expect(tu.targetContentNormalized().asDisplayString()).toBe('Beschreibung zu {{0}} ({{1}})');
expect(tu.targetState()).toBe('new');
}
done();
});
});
});
});

@@ -304,0 +470,0 @@

@@ -11,3 +11,3 @@ /**

import {CommandOutput} from '../common/command-output';
import {isNullOrUndefined} from 'util';
import {isArray, isNullOrUndefined} from 'util';
import {ProgramOptions, IConfigFile} from './i-xliff-merge-options';

@@ -29,2 +29,4 @@

private _useSourceAsTarget: boolean;
private _autotranslate: boolean|string[];
private _apikey: string;

@@ -150,2 +152,8 @@ public errorsFound: XliffMergeError[];

}
if (!isNullOrUndefined(profile.autotranslate)) {
this._autotranslate = profile.autotranslate;
}
if (profile.apikey) {
this._apikey = profile.apikey;
}
} else {

@@ -198,2 +206,15 @@ this.warningsFound.push('did not find "xliffmergeOptions" in profile, using defaults');

}
// autotranslate requires api key
if (this.autotranslate() && !this.apikey()) {
this.errorsFound.push(new XliffMergeError('autotranslate requires an API key, please set one'));
}
// autotranslated languages must be in list of all languages
this.autotranslatedLanguages().forEach((lang) => {
if (this.languages().indexOf(lang) < 0) {
this.errorsFound.push(new XliffMergeError('autotranslate language "' + lang + '" is not in list of languages'));
}
if (this.languages().length > 0 && lang === this.languages()[0]) {
this.errorsFound.push(new XliffMergeError('autotranslate language "' + lang + '" cannot be translated, because it is the source language'));
}
});
}

@@ -236,2 +257,7 @@

commandOutput.debug('useSourceAsTarget:\t%s', this.useSourceAsTarget());
commandOutput.debug('autotranslate:\t%s', this.autotranslate());
if (this.autotranslate()) {
commandOutput.debug('autotranslated languages:\t%s', this.autotranslatedLanguages());
}
commandOutput.debug('apikey:\t%s', this.apikey());
}

@@ -341,2 +367,45 @@

}
/**
* Whether to use autotranslate for new trans-units
* Default is false
*/
public autotranslate(): boolean {
if (isNullOrUndefined(this._autotranslate)) {
return false;
}
if (isArray(this._autotranslate)) {
return (<string[]>this._autotranslate).length > 0;
}
return <boolean> this._autotranslate;
}
/**
* Whether to use autotranslate for a given language.
* @param lang language code.
*/
public autotranslateLanguage(lang: string): boolean {
return this.autotranslatedLanguages().indexOf(lang) >= 0;
}
/**
* Return a list of languages to be autotranslated.
*/
public autotranslatedLanguages(): string[] {
if (isNullOrUndefined(this._autotranslate) || this._autotranslate === false) {
return [];
}
if (isArray(this._autotranslate)) {
return (<string[]>this._autotranslate);
}
return this.languages().slice(1); // first is source language
}
/**
* API key to be used for Google Translate
* @return {string}
*/
public apikey(): string {
return this._apikey;
}
}

@@ -171,2 +171,64 @@ import {XliffMerge} from './xliff-merge';

it('should output an error when autotranslate is set to true and there is no api key set', (done) => {
let ws: WriterToString = new WriterToString();
let commandOut = new CommandOutput(ws);
let profileContent: IConfigFile = {
xliffmergeOptions: {
autotranslate: true,
}
};
let xliffMergeCmd = XliffMerge.createFromOptions(commandOut, {}, profileContent);
xliffMergeCmd.run();
expect(ws.writtenData()).toContain('ERROR');
expect(ws.writtenData()).toContain('autotranslate requires an API key');
done();
});
it('should output an error when autotranslate is set to a list of languages and there is no api key set', (done) => {
let ws: WriterToString = new WriterToString();
let commandOut = new CommandOutput(ws);
let profileContent: IConfigFile = {
xliffmergeOptions: {
autotranslate: ['de'],
}
};
let xliffMergeCmd = XliffMerge.createFromOptions(commandOut, {}, profileContent);
xliffMergeCmd.run();
expect(ws.writtenData()).toContain('ERROR');
expect(ws.writtenData()).toContain('autotranslate requires an API key');
done();
});
it('should output an error when autotranslate language is not in list of languages', (done) => {
let ws: WriterToString = new WriterToString();
let commandOut = new CommandOutput(ws);
let profileContent: IConfigFile = {
xliffmergeOptions: {
languages: ['en', 'ru'],
autotranslate: ['de'],
}
};
let xliffMergeCmd = XliffMerge.createFromOptions(commandOut, {}, profileContent);
xliffMergeCmd.run();
expect(ws.writtenData()).toContain('ERROR');
expect(ws.writtenData()).toContain('autotranslate language "de" is not in list of languages');
done();
});
it('should output an error when autotranslate language is set to default language', (done) => {
let ws: WriterToString = new WriterToString();
let commandOut = new CommandOutput(ws);
let profileContent: IConfigFile = {
xliffmergeOptions: {
languages: ['en', 'ru'],
autotranslate: ['en', 'ru'],
}
};
let xliffMergeCmd = XliffMerge.createFromOptions(commandOut, {}, profileContent);
xliffMergeCmd.run();
expect(ws.writtenData()).toContain('ERROR');
expect(ws.writtenData()).toContain('autotranslate language "en" cannot be translated, because it is the source language');
done();
});
it('should accept i18n format xlf', (done) => {

@@ -173,0 +235,0 @@ let ws: WriterToString = new WriterToString();

@@ -13,2 +13,5 @@ import * as program from 'commander';

import {TranslationMessagesFileReader} from './translation-messages-file-reader';
import {Observable} from 'rxjs';
import {XliffMergeAutoTranslateService} from '../autotranslate/xliff-merge-auto-translate-service';
import {AutoTranslateSummaryReport} from '../autotranslate/auto-translate-summary-report';

@@ -25,4 +28,5 @@ /**

let options = XliffMerge.parseArgs(argv);
let result = new XliffMerge(new CommandOutput(process.stdout), options).run();
process.exit(result);
new XliffMerge(new CommandOutput(process.stdout), options).run((result) => {
process.exit(result);
});
}

@@ -76,8 +80,2 @@

/**
* during processing this will be set to the filename that is processed currently.
* Used in the error message, if there is an unexpected problem.
*/
private currentFilename: string;
/**
* The read master xlf file.

@@ -87,2 +85,4 @@ */

private autoTranslateService: XliffMergeAutoTranslateService;
/**

@@ -106,23 +106,21 @@ * For Tests, create instance with given profile

public run(): number {
try {
this.doRun();
return 0;
} catch (err) {
if (err instanceof XliffMergeError) {
this.commandOutput.error(err.message);
return -1;
} else {
// unhandled
let filenameString = (this.currentFilename) ? format('file "%s", ', this.currentFilename) : '';
this.commandOutput.error(filenameString + 'oops ' + err);
throw err;
}
}
/**
* Run the command.
* This runs async.
* @param callbackFunction when command is executed, called with the return code (0 for ok), if given.
*/
public run(callbackFunction?: ((retcode: number) => any)) {
this.doRun()
.subscribe((retcode: number) => {
if (!isNullOrUndefined(callbackFunction)) {
callbackFunction(retcode);
}
});
}
/**
* Ausführen merge-Process.
* Execute merge-Process.
* @return Async operation, on completion returns retcode 0=ok, other = error.
*/
private doRun() {
private doRun(): Observable<number> {
if (this.options && this.options.quiet) {

@@ -145,3 +143,3 @@ this.commandOutput.setQuiet();

}
return;
return Observable.of(-1);
}

@@ -154,8 +152,28 @@ if (this.parameters.warningsFound.length > 0) {

this.readMaster();
if (this.parameters.autotranslate()) {
this.autoTranslateService = new XliffMergeAutoTranslateService(this.parameters.apikey());
}
const executionForAllLanguages: Observable<number>[] = [];
this.parameters.languages().forEach((lang: string) => {
this.processLanguage(lang);
executionForAllLanguages.push(this.processLanguage(lang));
});
return Observable.forkJoin(executionForAllLanguages).map((retcodes: number[]) => {return this.totalRetcode(retcodes)});
}
/**
* Give an array of retcodes for the different languages, return the total retcode.
* If all are 0, it is 0, otherwise the first non zero.
* @param retcodes
* @return {number}
*/
private totalRetcode(retcodes: number[]): number {
for (let i = 0; i < retcodes.length; i++) {
if (retcodes[i] !== 0) {
return retcodes[i];
}
}
return 0;
}
/**
* Return the name of the generated file for given lang.

@@ -179,37 +197,69 @@ * @param lang

private readMaster() {
this.currentFilename = this.parameters.i18nFile();
this.master = TranslationMessagesFileReader.fromFile(this.parameters.i18nFormat(), this.parameters.i18nFile(), this.parameters.encoding());
this.master.warnings().forEach((warning: string) =>{
this.commandOutput.warn(warning);
});
let count = this.master.numberOfTransUnits();
let missingIdCount = this.master.numberOfTransUnitsWithMissingId();
this.commandOutput.info('master contains %s trans-units', count);
if (missingIdCount > 0) {
this.commandOutput.warn('master contains %s trans-units, but there are %s without id', count, missingIdCount);
try {
this.master = TranslationMessagesFileReader.fromFile(this.parameters.i18nFormat(), this.parameters.i18nFile(), this.parameters.encoding());
this.master.warnings().forEach((warning: string) =>{
this.commandOutput.warn(warning);
});
let count = this.master.numberOfTransUnits();
let missingIdCount = this.master.numberOfTransUnitsWithMissingId();
this.commandOutput.info('master contains %s trans-units', count);
if (missingIdCount > 0) {
this.commandOutput.warn('master contains %s trans-units, but there are %s without id', count, missingIdCount);
}
let sourceLang: string = this.master.sourceLanguage();
if (sourceLang && sourceLang !== this.parameters.defaultLanguage()) {
this.commandOutput.warn('master says to have source-language="%s", should be "%s" (your defaultLanguage)', sourceLang, this.parameters.defaultLanguage());
this.master.setSourceLanguage(this.parameters.defaultLanguage());
TranslationMessagesFileReader.save(this.master);
this.commandOutput.warn('changed master source-language="%s" to "%s"', sourceLang, this.parameters.defaultLanguage());
}
} catch (err) {
if (err instanceof XliffMergeError) {
this.commandOutput.error(err.message);
return Observable.of(-1);
} else {
// unhandled
const currentFilename = this.parameters.i18nFile();
let filenameString = (currentFilename) ? format('file "%s", ', currentFilename) : '';
this.commandOutput.error(filenameString + 'oops ' + err);
throw err;
}
}
let sourceLang: string = this.master.sourceLanguage();
if (sourceLang && sourceLang !== this.parameters.defaultLanguage()) {
this.commandOutput.warn('master says to have source-language="%s", should be "%s" (your defaultLanguage)', sourceLang, this.parameters.defaultLanguage());
this.master.setSourceLanguage(this.parameters.defaultLanguage());
TranslationMessagesFileReader.save(this.master);
this.commandOutput.warn('changed master source-language="%s" to "%s"', sourceLang, this.parameters.defaultLanguage());
}
this.currentFilename = null;
}
private processLanguage(lang: string) {
/**
* Process the given language.
* Async operation.
* @param lang
* @return {Observable<number>} on completion 0 for ok, other for error
*/
private processLanguage(lang: string): Observable<number> {
this.commandOutput.debug('processing language %s', lang);
let languageXliffFile = this.parameters.generatedI18nFile(lang);
this.currentFilename = languageXliffFile;
let currentFilename = languageXliffFile;
let result: Observable<void>;
if (!FileUtil.exists(languageXliffFile)) {
this.createUntranslatedXliff(lang, languageXliffFile);
result = this.createUntranslatedXliff(lang, languageXliffFile);
} else {
this.mergeMasterTo(lang, languageXliffFile);
result = this.mergeMasterTo(lang, languageXliffFile);
}
if (this.parameters.supportNgxTranslate()) {
let languageSpecificMessagesFile: ITranslationMessagesFile = TranslationMessagesFileReader.fromFile(XliffMerge.translationFormat(this.parameters.i18nFormat()), languageXliffFile, this.parameters.encoding(), this.master.filename());
NgxTranslateExtractor.extract(languageSpecificMessagesFile, this.parameters.generatedNgxTranslateFile(lang));
}
this.currentFilename = null;
return result
.map(() => {
if (this.parameters.supportNgxTranslate()) {
let languageSpecificMessagesFile: ITranslationMessagesFile = TranslationMessagesFileReader.fromFile(XliffMerge.translationFormat(this.parameters.i18nFormat()), languageXliffFile, this.parameters.encoding(), this.master.filename());
NgxTranslateExtractor.extract(languageSpecificMessagesFile, this.parameters.generatedNgxTranslateFile(lang));
}
return 0;
})
.catch((err) => {
if (err instanceof XliffMergeError) {
this.commandOutput.error(err.message);
return Observable.of(-1);
} else {
// unhandled
let filenameString = (currentFilename) ? format('file "%s", ', currentFilename) : '';
this.commandOutput.error(filenameString + 'oops ' + err);
throw err;
}
})
}

@@ -223,3 +273,3 @@

*/
private createUntranslatedXliff(lang: string, languageXliffFilePath: string) {
private createUntranslatedXliff(lang: string, languageXliffFilePath: string): Observable<void> {
// copy master ...

@@ -231,8 +281,11 @@ // and set target-language

// write it to file
TranslationMessagesFileReader.save(languageSpecificMessagesFile);
this.commandOutput.info('created new file "%s" for target-language="%s"', languageXliffFilePath, lang);
if (!isDefaultLang) {
this.commandOutput.warn('please translate file "%s" to target-language="%s"', languageXliffFilePath, lang);
}
return this.autoTranslate(this.master.sourceLanguage(), lang, languageSpecificMessagesFile).map((summary) => {
// write it to file
TranslationMessagesFileReader.save(languageSpecificMessagesFile);
this.commandOutput.info('created new file "%s" for target-language="%s"', languageXliffFilePath, lang);
if (!isDefaultLang) {
this.commandOutput.warn('please translate file "%s" to target-language="%s"', languageXliffFilePath, lang);
}
return null;
});
}

@@ -258,3 +311,3 @@

*/
private mergeMasterTo(lang: string, languageXliffFilePath: string) {
private mergeMasterTo(lang: string, languageXliffFilePath: string): Observable<void> {
// read lang specific file

@@ -309,9 +362,12 @@ let languageSpecificMessagesFile: ITranslationMessagesFile = TranslationMessagesFileReader.fromFile(XliffMerge.translationFormat(this.parameters.i18nFormat()), languageXliffFilePath, this.parameters.encoding());

} else {
// write it to file
TranslationMessagesFileReader.save(languageSpecificMessagesFile);
this.commandOutput.info('updated file "%s" for target-language="%s"', languageXliffFilePath, lang);
if (newCount > 0 && !isDefaultLang) {
this.commandOutput.warn('please translate file "%s" to target-language="%s"', languageXliffFilePath, lang);
}
return this.autoTranslate(this.master.sourceLanguage(), lang, languageSpecificMessagesFile)
.map(() => {
// write it to file
TranslationMessagesFileReader.save(languageSpecificMessagesFile);
this.commandOutput.info('updated file "%s" for target-language="%s"', languageXliffFilePath, lang);
if (newCount > 0 && !isDefaultLang) {
this.commandOutput.warn('please translate file "%s" to target-language="%s"', languageXliffFilePath, lang);
}
return null;
});
}

@@ -343,2 +399,28 @@ }

}
/**
* Auto translate file via Google Translate.
* Will translate all new units in file.
* @param from
* @param to
* @param languageSpecificMessagesFile
* @return a promise with the execution result as a summary report.
*/
private autoTranslate(from: string, to: string, languageSpecificMessagesFile: ITranslationMessagesFile): Observable<AutoTranslateSummaryReport> {
let serviceCall: Observable<AutoTranslateSummaryReport>;
if (this.parameters.autotranslateLanguage(to)) {
serviceCall = this.autoTranslateService.autoTranslate(from, to, languageSpecificMessagesFile);
} else {
serviceCall = Observable.of(new AutoTranslateSummaryReport(from, to));
}
return serviceCall.map((summary) => {
if (summary.error() || summary.failed() > 0) {
this.commandOutput.error(summary.content());
} else {
this.commandOutput.warn(summary.content());
}
return summary;
})
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc