MicroFish/scripts/validate-locale.mjs

74 lines
2.1 KiB
JavaScript

import { readFileSync, existsSync } from 'node:fs'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const localePath = (name) => resolve(root, 'locales', `${name}.json`)
const readJson = (path) => JSON.parse(readFileSync(path, 'utf8'))
const languages = readJson(resolve(root, 'locales', 'languages.json'))
const en = readJson(localePath('en'))
const ptPath = localePath('pt-BR')
const errors = []
if (!languages['pt-BR']) {
errors.push('languages.json must register pt-BR')
}
if (!existsSync(ptPath)) {
errors.push('locales/pt-BR.json must exist')
}
const flattenKeys = (value, prefix = '') => {
if (Array.isArray(value)) {
return [prefix]
}
if (value && typeof value === 'object') {
return Object.keys(value).flatMap((key) => flattenKeys(value[key], prefix ? `${prefix}.${key}` : key))
}
return [prefix]
}
if (existsSync(ptPath)) {
const pt = readJson(ptPath)
const enKeys = flattenKeys(en).sort()
const ptKeys = flattenKeys(pt).sort()
const missing = enKeys.filter((key) => !ptKeys.includes(key))
const extra = ptKeys.filter((key) => !enKeys.includes(key))
if (missing.length) {
errors.push(`pt-BR is missing keys: ${missing.slice(0, 20).join(', ')}`)
}
if (extra.length) {
errors.push(`pt-BR has extra keys: ${extra.slice(0, 20).join(', ')}`)
}
const firstScreenKeys = [
'home.dragToUpload',
'home.startEngine',
'home.tagline',
'home.promptPlaceholder',
'home.workflowSequence',
'main.layoutWorkbench'
]
const getValue = (obj, path) => path.split('.').reduce((current, key) => current?.[key], obj)
for (const key of firstScreenKeys) {
const value = getValue(pt, key)
if (typeof value !== 'string') {
errors.push(`pt-BR key ${key} must be a string`)
continue
}
if (typeof value === 'string' && /\b(Upload|Start|Workflow|Workbench|Describe)\b/.test(value)) {
errors.push(`pt-BR key ${key} still appears to be English: ${value}`)
}
}
}
if (errors.length) {
console.error(errors.join('\n'))
process.exit(1)
}
console.log('pt-BR locale validation passed')