Skip to content
Open
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
13 changes: 2 additions & 11 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -483,17 +483,8 @@ To add a new locale:
},
```

4. Copy your translation file to `lunaria/files/` for translation tracking:

```bash
cp i18n/locales/uk-UA.json lunaria/files/uk-UA.json
```

> ⚠**Important:**
> This file must be committed. Lunaria uses git history to track translation progress, so the build will fail if this file is missing.

5. If the language is `right-to-left`, add `dir: 'rtl'` (see `ar-EG` in config for example)
6. If the language requires special pluralization rules, add a `pluralRule` callback (see `ar-EG` or `ru-RU` in config for examples)
4. If the language is `right-to-left`, add `dir: 'rtl'` (see `ar-EG` in config for example)
5. If the language requires special pluralization rules, add a `pluralRule` callback (see `ar-EG` or `ru-RU` in config for examples)

Check [Pluralization rule callback](https://vue-i18n.intlify.dev/guide/essentials/pluralization#custom-pluralization) and [Plural Rules](https://cldr.unicode.org/index/cldr-spec/plural-rules#TOC-Determining-Plural-Categories) for more info.

Expand Down
6 changes: 0 additions & 6 deletions config/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,6 @@ const locales: (LocaleObjectData | (Omit<LocaleObjectData, 'code'> & { code: str
},
]

const lunariaJSONFiles: Record<string, string> = {}

function buildLocales() {
const useLocales = Object.values(locales).reduce((acc, data) => {
const locales = countryLocaleVariants[data.code]
Expand All @@ -363,12 +361,10 @@ function buildLocales() {
name: l.name,
files: [data.file as string, `${l.code}.json`],
}
lunariaJSONFiles[l.code] = l.country ? (data.file as string) : `${l.code}.json`
delete entry.file
acc.push(entry)
})
} else {
lunariaJSONFiles[data.code] = data.file as string
acc.push(data as LocaleObjectData)
}
return acc
Expand All @@ -379,8 +375,6 @@ function buildLocales() {

export const currentLocales = buildLocales()

export { lunariaJSONFiles }

export const datetimeFormats = Object.values(currentLocales).reduce((acc, data) => {
const dateTimeFormats = data.dateTimeFormats
if (dateTimeFormats) {
Expand Down
69 changes: 65 additions & 4 deletions lunaria.config.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,78 @@
import { defineConfig } from '@lunariajs/core/config'
import { locales, sourceLocale } from './lunaria/prepare-json-files.ts'
import type { Locale, Merge } from '@lunariajs/core'
import { currentLocales, countryLocaleVariants } from './config/i18n.ts'

// The source locale is `en` (en.json contains all reference translation keys).
// Country variants like `en-US` inherit from `en` via the merge config.
const sourceLocale: Locale = { label: 'English', lang: 'en' }

// Build the list of Lunaria locales from currentLocales.
// currentLocales has expanded codes (en-US, en-GB, ar-EG, es-ES, es-419, etc.)
// but NOT the base codes (ar, es) that the variants inherit from.
// We need to add those base codes as Lunaria locales too, so they can be
// referenced in the merge config and tracked independently.
const localeSet = new Set<string>()
const locales: Locale[] = []

for (const l of currentLocales) {
if (l.code === sourceLocale.lang || !l.name) continue
if (!localeSet.has(l.code)) {
localeSet.add(l.code)
locales.push({ label: l.name, lang: l.code })
}
}

// Add base language codes (ar, es, etc.) that aren't already in the list.
// These are the keys of countryLocaleVariants that aren't the source locale.
for (const baseLang of Object.keys(countryLocaleVariants)) {
if (baseLang === sourceLocale.lang) continue
if (!localeSet.has(baseLang)) {
// Use the first variant's name or the base code as label
const variants = countryLocaleVariants[baseLang]!
const label = variants[0]?.name ?? baseLang
localeSet.add(baseLang)
locales.push({ label, lang: baseLang })
}
}

if (locales.length === 0) {
throw new Error('No locales found besides source locale')
}

// Build merge config from countryLocaleVariants:
// Each variant locale merges keys from its base locale, so keys present in
// the base file count as covered for the variant.
// e.g. { 'en-US': ['en'], 'en-GB': ['en'], 'ar-EG': ['ar'], 'es-ES': ['es'], 'es-419': ['es'] }
const merge: Merge = {}
for (const [baseLang, variants] of Object.entries(countryLocaleVariants)) {
for (const variant of variants) {
// Each variant merges from its base language and (if not the source) implicitly
// from the source via normal Lunaria tracking.
const existing = merge[variant.code]
if (existing) {
existing.push(baseLang)
} else {
merge[variant.code] = [baseLang]
}
}
}

export default defineConfig({
repository: {
name: 'npmx-dev/npmx.dev',
},
sourceLocale,
locales,
locales: locales as [Locale, ...Locale[]],
files: [
{
include: ['lunaria/files/en-US.json'],
pattern: 'lunaria/files/@lang.json',
include: ['i18n/locales/en.json'],
pattern: 'i18n/locales/@lang.json',
type: 'dictionary',
merge,
optionalKeys: {
$schema: true,
vacations: true,
},
},
],
tracking: {
Expand Down
Loading
Loading