Skip to content

Commit d767faa

Browse files
committed
refactor: type safety, explicit options
1 parent 88b6713 commit d767faa

2 files changed

Lines changed: 42 additions & 22 deletions

File tree

lunaria/prepare-json-files.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,27 +37,30 @@ export async function prepareJsonFiles(): Promise<void> {
3737
await Promise.all(currentLocales.map(l => mergeLocale(l)))
3838
}
3939

40+
type NestedObject = Record<string, unknown>
41+
4042
export async function mergeLocaleObject(
4143
locale: LocaleObject,
42-
copy = false,
43-
): Promise<void | unknown> {
44+
options: { copy?: boolean } = {},
45+
): Promise<NestedObject | undefined> {
46+
const { copy = false } = options
4447
const files = locale.files ?? []
4548
if (locale.file || files.length === 1) {
4649
const json =
4750
(locale.file ? getFileName(locale.file) : undefined) ??
4851
(files[0] ? getFileName(files[0]) : undefined)
49-
if (!json) return
52+
if (!json) return undefined
5053
if (copy) {
5154
await fs.cp(path.resolve(`${localesFolder}/${json}`), path.resolve(`${destFolder}/${json}`))
52-
return
55+
return undefined
5356
}
5457

55-
return await loadJsonFile(json)
58+
return await loadJsonFile<NestedObject>(json)
5659
}
5760

5861
const firstFile = files[0]
59-
if (!firstFile) return
60-
const source = await loadJsonFile(getFileName(firstFile))
62+
if (!firstFile) return undefined
63+
const source = await loadJsonFile<NestedObject>(getFileName(firstFile))
6164
let currentSource: unknown
6265
for (let i = 1; i < files.length; i++) {
6366
const file = files[i]
@@ -69,7 +72,7 @@ export async function mergeLocaleObject(
6972
return source
7073
}
7174

72-
async function loadJsonFile(name: string): Promise<unknown> {
75+
async function loadJsonFile<T = unknown>(name: string): Promise<T> {
7376
return JSON.parse(await fs.readFile(path.resolve(`${localesFolder}/${name}`), 'utf8'))
7477
}
7578

@@ -78,7 +81,7 @@ function getFileName(file: string | { path: string }): string {
7881
}
7982

8083
async function mergeLocale(locale: LocaleObject): Promise<void> {
81-
const source = await mergeLocaleObject(locale, true)
84+
const source = await mergeLocaleObject(locale, { copy: true })
8285
if (!source) {
8386
return
8487
}

scripts/compare-translations.ts

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,18 @@ interface LocaleInfo {
2424
const countries = new Map<string, Map<string, LocaleInfo>>()
2525
const availableLocales = new Map<string, LocaleObject>()
2626

27-
const extractLocalInfo = (
28-
filePath: string,
29-
forCountry: boolean = false,
30-
mergeLocale: boolean = false,
31-
): LocaleInfo => {
27+
function extractLocalInfo(filePath: string): LocaleInfo {
3228
const locale = basename(filePath, '.json')
3329
const [lang, country] = locale.split('-')
34-
return { filePath, locale, lang, country, forCountry, mergeLocale }
30+
return { filePath, locale, lang, country }
31+
}
32+
33+
function createVariantInfo(
34+
code: string,
35+
options: { forCountry: boolean; mergeLocale: boolean },
36+
): LocaleInfo {
37+
const [lang, country] = code.split('-')
38+
return { filePath: '', locale: code, lang, country, ...options }
3539
}
3640

3741
const populateLocaleCountries = (): void => {
@@ -42,10 +46,22 @@ const populateLocaleCountries = (): void => {
4246
countries.set(lang, new Map())
4347
}
4448
if (variant.country) {
45-
countries.get(lang)!.set(lang, extractLocalInfo(lang, true))
46-
countries.get(lang)!.set(variant.code, extractLocalInfo(variant.code, true, true))
49+
countries
50+
.get(lang)!
51+
.set(lang, createVariantInfo(lang, { forCountry: true, mergeLocale: false }))
52+
countries
53+
.get(lang)!
54+
.set(
55+
variant.code,
56+
createVariantInfo(variant.code, { forCountry: true, mergeLocale: true }),
57+
)
4758
} else {
48-
countries.get(lang)!.set(variant.code, extractLocalInfo(variant.code, false, true))
59+
countries
60+
.get(lang)!
61+
.set(
62+
variant.code,
63+
createVariantInfo(variant.code, { forCountry: false, mergeLocale: true }),
64+
)
4965
}
5066
}
5167
}
@@ -117,7 +133,7 @@ const loadJson = async ({ filePath, mergeLocale, locale }: LocaleInfo): Promise<
117133
console.error(`${COLORS.red}Error: Failed to merge locale "${locale}"${COLORS.reset}`)
118134
process.exit(1)
119135
}
120-
return merged as NestedObject
136+
return merged
121137
}
122138

123139
type SyncStats = {
@@ -146,8 +162,9 @@ const syncLocaleData = (
146162
if (isNested(refValue)) {
147163
const nextTarget = isNested(target[key]) ? target[key] : {}
148164
const data = syncLocaleData(refValue, nextTarget, stats, fix, propertyPath)
149-
// don't add empty objects: --fix will prevent this
150-
if (Object.keys(data).length === 0) {
165+
// When fixing, empty objects won't occur since missing keys get placeholders.
166+
// Without --fix, keep empty objects to preserve structural parity with the reference.
167+
if (fix && Object.keys(data).length === 0) {
151168
delete result[key]
152169
} else {
153170
result[key] = data
@@ -359,4 +376,4 @@ const run = async (): Promise<void> => {
359376
}
360377
}
361378

362-
run()
379+
await run()

0 commit comments

Comments
 (0)