Initial import from local backup (Documents-Playground/pakerpale)
This commit is contained in:
267
node_modules/relative-time-format/bin/generate-locale-messages.js
generated
vendored
Normal file
267
node_modules/relative-time-format/bin/generate-locale-messages.js
generated
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
import path from 'path'
|
||||
import fs from 'fs-extra'
|
||||
|
||||
import extractRelativeTimeMessages from '../source/CLDR/extractRelativeTimeMessages'
|
||||
import getLocalesListInCLDR from '../source/CLDR/getLocalesList'
|
||||
|
||||
// CLDR stubs missing translations with English ones.
|
||||
// This can be used to find out whether a translation is missing.
|
||||
const LONG_STYLE_TRANSLATION_STUB = `{
|
||||
"year": {
|
||||
"previous": "last year",
|
||||
"current": "this year",
|
||||
"next": "next year",
|
||||
"past": "-{0} y",
|
||||
"future": "+{0} y"
|
||||
}`
|
||||
|
||||
// Generate plurals first, then run this script.
|
||||
// Generating plurals creates locale folder structure.
|
||||
//
|
||||
// ```
|
||||
// npm run generate-locale-quantifiers
|
||||
// npm run generate-locale-messages
|
||||
// // npm run generate-load-all-locales
|
||||
// ````
|
||||
for (const locale of getLocalesListInCLDR())
|
||||
{
|
||||
if (
|
||||
// Different variations of "en" language have `en/short.json` and `en/narrow.json`
|
||||
// which differ from one another by a simple dot, e.g. `yr.` vs `yr`.
|
||||
// To reduce the resulting bundle size this dot difference is considered unimportant.
|
||||
locale.indexOf('en-') === 0 ||
|
||||
// For "pt" language the relative time messages seem to be different
|
||||
// from all other "pt-" variations which are identical to "pt-PT".
|
||||
// Seems like a bug in CLDR.
|
||||
// To reduce the resulting bundle size "pt" language is discarded
|
||||
// and "pt-PT" is used instead. All other "pt-" variations
|
||||
// seems to be identical to "pt-PT" so they're not included.
|
||||
locale.indexOf('pt-') === 0
|
||||
) {
|
||||
// Delete the locale folder.
|
||||
// (previously created by `npm run generate-locale-quantifiers`).
|
||||
fs.removeSync(path.join(__dirname, '../locale', locale))
|
||||
continue
|
||||
}
|
||||
|
||||
// console.log(locale)
|
||||
|
||||
// "language" is the top-most parent locale of the `locale`.
|
||||
const language = locale.split('-')[0]
|
||||
|
||||
// For "pt" language the relative time messages seem to be different
|
||||
// from all other "pt-" variations which are identical to "pt-PT".
|
||||
// Seems like a bug in CLDR.
|
||||
// To reduce the resulting bundle size "pt" language is discarded
|
||||
// and "pt-PT" is used instead. All other "pt-" variations
|
||||
// seems to be identical to "pt-PT" so they're not included.
|
||||
const localeInCLDR = locale === 'pt' ? 'pt-PT' : locale
|
||||
|
||||
const cldrJsonPath = `cldr-dates-full/main/${localeInCLDR}/dateFields.json`
|
||||
const localeDirectory = path.join(__dirname, '../locale', locale)
|
||||
const languageDirectory = path.join(__dirname, '../locale', language)
|
||||
|
||||
// If there's no pluralization classifier function
|
||||
// for this language then don't add it.
|
||||
const quantifyDirectory = findQuantifyDirectory(locale)
|
||||
|
||||
const localeMessages = extractRelativeTimeMessages(require(cldrJsonPath))
|
||||
|
||||
// "long" messages are always present.
|
||||
if (!localeMessages.long) {
|
||||
throw new Error(`Default (long) locale data is missing for locale "${locale}".`)
|
||||
}
|
||||
|
||||
// If there are no translations for a locale then skip it.
|
||||
if (JSON.stringify(localeMessages.long, null, '\t').indexOf(LONG_STYLE_TRANSLATION_STUB) === 0) {
|
||||
// console.log(`No translation for "${locale}". Skipping.`)
|
||||
fs.removeSync(localeDirectory)
|
||||
continue
|
||||
}
|
||||
|
||||
// "short" messages are always present.
|
||||
if (!localeMessages.short) {
|
||||
throw new Error(`Short locale data is missing for locale "${locale}".`)
|
||||
}
|
||||
|
||||
// "narrow" messages are always present.
|
||||
if (!localeMessages.narrow) {
|
||||
throw new Error(`Narrow locale data is missing for locale "${locale}".`)
|
||||
}
|
||||
|
||||
// Drop duplicate quantifier messages.
|
||||
compactQuantifiersData(localeMessages.long)
|
||||
compactQuantifiersData(localeMessages.short)
|
||||
compactQuantifiersData(localeMessages.narrow)
|
||||
|
||||
// What are "narrow" and "short" styles and how are they constructed:
|
||||
// http://cldr.unicode.org/translation/plurals#TOC-Narrow-and-Short-Forms
|
||||
|
||||
// Create `index.js` file in the locale directory.
|
||||
fs.outputFileSync(
|
||||
path.join(localeDirectory, 'index.js'),
|
||||
`
|
||||
module.exports = {
|
||||
${[
|
||||
"locale: '" + locale + "'",
|
||||
"long: require('" + createTimeLabels(locale, 'long', localeMessages) + "')",
|
||||
"short: require('" + createTimeLabels(locale, 'short', localeMessages) + "')",
|
||||
"narrow: require('" + createTimeLabels(locale, 'narrow', localeMessages) + "')",
|
||||
quantifyDirectory && ("quantify: require('" + quantifyDirectory + "/quantify')")
|
||||
]
|
||||
.filter(_ => _)
|
||||
.join(',\n\t')}
|
||||
}
|
||||
`.trim()
|
||||
)
|
||||
|
||||
// Remove all locales containing just `index.js`
|
||||
// which means they're fully inherting from their parent locale.
|
||||
for (const locale of getLocalesListGenerated()) {
|
||||
const files = fs.readdirSync(path.join(__dirname, '../locale', locale))
|
||||
if (files.length === 1 && files[0] === 'index.js') {
|
||||
fs.removeSync(path.resolve(__dirname, '../locale', locale))
|
||||
}
|
||||
}
|
||||
|
||||
// Remove strange locales.
|
||||
fs.removeSync(path.resolve(__dirname, '../locale/en-001'))
|
||||
fs.removeSync(path.resolve(__dirname, '../locale/en-150'))
|
||||
fs.removeSync(path.resolve(__dirname, '../locale/en-US-POSIX'))
|
||||
fs.removeSync(path.resolve(__dirname, '../locale/es-419'))
|
||||
}
|
||||
|
||||
/**
|
||||
* CLDR data always has relative time messages duplicated
|
||||
* for all keys if they're the same.
|
||||
* For example, if relative time messages are the same for
|
||||
* "one", "many" and "other" they will still be duplicated
|
||||
* in CLDR data files.
|
||||
* This function removes such duplication to reduce the
|
||||
* resulting bundle size.
|
||||
* Mutates the object passed as the argument directly.
|
||||
* @param {object} flavor — Relative time messages of a given flavor.
|
||||
*/
|
||||
function compactQuantifiersData(flavour) {
|
||||
for (const unit of Object.keys(flavour)) {
|
||||
for (const pastOrFuture of Object.keys(flavour[unit])) {
|
||||
for (const quantifier of Object.keys(flavour[unit][pastOrFuture])) {
|
||||
// "other" is the one holding the relative time message in case of duplication.
|
||||
if (quantifier === 'other') {
|
||||
continue
|
||||
}
|
||||
if (flavour[unit][pastOrFuture][quantifier] === flavour[unit][pastOrFuture].other) {
|
||||
delete flavour[unit][pastOrFuture][quantifier]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all supported locales.
|
||||
* @return {string[]}
|
||||
*/
|
||||
function getLocalesListGenerated() {
|
||||
return fs.readdirSync(path.join(__dirname, '../locale'))
|
||||
.filter(_ => fs.statSync(path.join(__dirname, '../locale', _)).isDirectory())
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a file with the time messages
|
||||
* of a given style for a given locale.
|
||||
* @param {string} locale
|
||||
* @param {string} style
|
||||
* @param {object} localeMessages — Time messages object containing all styles.
|
||||
* @return {object} The relative path to the time messages file.
|
||||
*/
|
||||
function createTimeLabels(locale, style, localeMessages) {
|
||||
const content = JSON.stringify(localeMessages[style], null, '\t')
|
||||
// `sr-Cyrl-BA` -> `sr-Cyrl` -> `sr`.
|
||||
const parentLocale = findParentLocaleHavingFile(locale, `${style}.json`, {
|
||||
condition: (file) => fs.readFileSync(file, 'utf-8') === content
|
||||
})
|
||||
if (parentLocale) {
|
||||
return `../${parentLocale}/${style}.json`
|
||||
}
|
||||
fs.outputFileSync(path.join(__dirname, '../locale', locale, `${style}.json`), content)
|
||||
return `./${style}.json`
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the relative path to a directory where
|
||||
* `quantify.js` resides for a given locale.
|
||||
* For example, there are different locales: "ar" and "ar-AE".
|
||||
* But their `quantify()` function is identical.
|
||||
* Therefore, it's only stored inside `ar` folder
|
||||
* and `getQuantifyDirectory('ar-AE')` is "../ar".
|
||||
* @param {string} locale
|
||||
* @return {string} [directory]
|
||||
*/
|
||||
function findQuantifyDirectory(locale) {
|
||||
// Look in parent locales' folders.
|
||||
// Example: `sr-Cyrl-BA` -> `sr-Cyrl` -> `sr`.
|
||||
const parentLocale = findParentLocaleHavingFile(locale, 'quantify.js')
|
||||
if (parentLocale) {
|
||||
return `../${parentLocale}`
|
||||
}
|
||||
// Look in this locale's folder.
|
||||
if (fs.existsSync(path.join(__dirname, '../locale', locale, 'quantify.js'))) {
|
||||
return '.'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the relative path to a directory where
|
||||
* a given "flavor" (short, long, narrow) labels file
|
||||
* resides for a given locale.
|
||||
* @param {string} locale
|
||||
* @param {string} flavor
|
||||
* @return {string} [directory]
|
||||
*/
|
||||
function findFlavorDirectory(locale, flavour) {
|
||||
// Look in parent locales' folders.
|
||||
// Example: `sr-Cyrl-BA` -> `sr-Cyrl` -> `sr`.
|
||||
const parentLocale = findParentLocaleHavingFile(locale, `${flavour}.json`, { self: true })
|
||||
if (parentLocale) {
|
||||
if (parentLocale === locale) {
|
||||
return '.'
|
||||
}
|
||||
return `../${parentLocale}`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Some files are inherited from a parent locale to a child locale.
|
||||
* For example, there are different locales: "ar" and "ar-AE".
|
||||
* But their `quantify()` function is identical.
|
||||
* Therefore, it's only stored inside `ar` folder
|
||||
* and "ar-AE" locale reuses that file.
|
||||
* @param {string} locale
|
||||
* @param {string} fileName
|
||||
* @param {object} [options]
|
||||
* @param {boolean} [options.self] — Allow returning same `locale`.
|
||||
* @param {function} [options.condition] — An extra condition imposed on the absolute file path of the file.
|
||||
* @return {string} [locale]
|
||||
*/
|
||||
function findParentLocaleHavingFile(locale, fileName, options = {}) {
|
||||
const restParts = locale.split('-')
|
||||
const parts = []
|
||||
let inheritFrom
|
||||
while (restParts.length > 0) {
|
||||
parts.push(restParts.shift())
|
||||
const parentLocale = parts.join('-')
|
||||
if (!options.self && parentLocale === locale) {
|
||||
continue
|
||||
}
|
||||
if (!fs.existsSync(path.join(__dirname, '../locale', parentLocale))) {
|
||||
continue
|
||||
}
|
||||
if (fs.existsSync(path.join(__dirname, '../locale', parentLocale, fileName))) {
|
||||
if (!options.condition || options.condition(path.join(__dirname, '../locale', parentLocale, fileName))) {
|
||||
inheritFrom = parentLocale
|
||||
}
|
||||
}
|
||||
}
|
||||
return inheritFrom
|
||||
}
|
||||
Reference in New Issue
Block a user