medic / translation-checker

Check translations from .properties files with Mustache placeholders markup or messageformat syntax.
https://www.npmjs.com/package/@medic/translation-checker
GNU Affero General Public License v3.0
2 stars 0 forks source link
library messageformat mustache nodejs properties

translation-checker

Check translations from .properties files with Mustache placeholders markup or messageformat syntax.

Getting started

Node 8.10+ required. Install with:

$ npm install @medic/translation-checker

Here is how you can use it:

const {
  checkTranslations,
  TranslationException
} = require('@medic/translation-checker');

const dir = `${somePath}/translations`;
let fileNames;
try {
  fileNames = await checkTranslations(dir);
  // Your files passed the validations!
  // fileNames = ['messages-en.properties', 'messages-es.properties', ...]
} catch (err) {
    if (err instanceof TranslationException) {
      // Oops, translation errors !!
      fileNames = err.fileNames;  // ['messages-en.properties', 'messages-es.properties', ...]
      if (!err.errors) {
        return log.error('Exception checking translations:', err.message);
      }
      for (const error of err.errors) {
        switch (error.error) {
          case 'cannot-access-dir':
            return log.warn('Could not find custom translations dir:', dir);
          case 'missed-placeholder':
          case 'wrong-placeholder':
            log.error(error.message);
            break;
          case 'missing-key':
          case 'empty-message':
            // less severe, lets log it with WARN severity instead of ERROR
            log.warn(error.message);
            break;
          default:  // 'wrong-messageformat', 'wrong-placeholder'
            // This are more severe errors
            log.error(error.message);
            break;
        }
      }
    } else {
      throw err;  // unexpected ;(
    }
}

Logs from the example above will look like:

WARN Empty message found for key 'report.pregnancy.u_lmp_date' in 'en' translation 
WARN Empty message found for key 'report.pregnancy.method_lmp' in 'en' translation 
ERROR Cannot compile 'es' translation with key 'Number in month' has placeholders that do not match any in the base translation provided 
ERROR Cannot compile 'es' translation n.month = '{MONTHS, plural one{1 mes} other{# meses}}' : Expected "," but "o" found.

Arguments

checkTranslations(dir, options) (async)

Error details

All the errors raised by checkTranslations() are instances of TranslationException. The exception object has an errors array with one object for each error detected as following:

{
  "lang": "en",                     // The language where the error was found
  "error": "wrong-messageformat",   // The error code
  "key": "n.month2",                // The translation key
  "message": "Cannot compile ..."   // A message with more details about the error
}

These are the error codes and what they mean:

Placeholders check

The mustache placeholder check works as following:

Check the JSDoc of the source code to see more options.

Messageformat check

"Messageformat" check are also performed by default, you can disable it with options.checkMessageformat = false.

A common error is by mistake translate the messageformat keywords when using online translator tools, eg. this translation that is OK in English:

n.month = {MONTHS, plural, one{1 month} other{\# months}}

Wrong translated to Spanish:

n.month = {MONTHS, plural, uno{1 mes} otros{\# meses}}

Will raise an error with a the message:

Invalid key `uno` for argument `MONTHS`. Valid plural keys for this locale are `one`,
`other`, and explicit keys like `=0`

The right translations is:

n.month = {MONTHS, plural, one{1 mes} other{\# meses}}

Empty message checks

Validations fail if a key is found like this:

n.month = 

But some times empty keys are acceptable because the software that use the translations fallback to the default language, so to disable empties check set options.checkEmpties to false (default is true).

Publishing

$ npm publish --access=public