scratch-l10n/lib/validate.mjs
Christopher Willis-Ford 44c4b97581 refactor!: stop using babel-node
This should improve call stacks when debugging.

BREAKING CHANGE: Some files have been renamed from '.js' to '.mjs'
2024-10-28 13:48:36 -07:00

47 lines
2 KiB
JavaScript

import assert from 'assert';
import parse from 'format-message-parse';
// filter placeholders out of a message
// parse('a message with a {value} and {count, plural, one {one} other {more}}.')
// returns an array:
// [ 'a message with a ',
// [ 'value' ],
// ' and ',
// [ 'count', 'plural', 0, { one: [Array], other: [Array] } ],
// '.'
// ]
// placeholders are always an array, so filter for array elements to find the placeholders
const placeholders = message => (
// this will throw an error if the message is not valid ICU
// single quote (as in French l'année) messes up the parse and is not
// relevant for this check, so strip them out
parse(message.replace(/'/g, '')).filter(item => Array.isArray(item))
);
const validMessage = (message, source) => {
const transPlaceholders = placeholders(message.toString());
const srcPlaceholders = placeholders(source.toString());
// different number of placeholders
if (transPlaceholders.length !== srcPlaceholders.length) {
return false;
}
// TODO: Add checking to make sure placeholders in source have not been translated
// TODO: Add validation of scratch-blocks placeholders
return true;
};
const validateTranslations = (translation, source) => {
const locale = translation.locale;
const translations = translation.translations;
const transKeys = Object.keys(translations);
const sourceKeys = Object.keys(source);
assert.strictEqual(transKeys.length, sourceKeys.length, `locale ${locale} has a different number of message keys`);
transKeys.map(item => assert(sourceKeys.includes(item), `locale ${locale} has key ${item} not in the source`));
sourceKeys.map(item => assert(transKeys.includes(item), `locale ${locale} is missing key ${item}`));
sourceKeys.map(item => assert(
validMessage(translations[item], source[item]),
`locale ${locale}: "${translations[item]}" is not a valid translation for "${source[item]}"`)
);
};
export {validateTranslations, validMessage};