Fix/23066 i18n related commands are broken (#23071)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,175 +0,0 @@
|
|||||||
'use client'
|
|
||||||
import { loadLangResources } from '@/i18n-config/i18next-config'
|
|
||||||
import { useCallback, useEffect, useState } from 'react'
|
|
||||||
import cn from '@/utils/classnames'
|
|
||||||
import { LanguagesSupported } from '@/i18n-config/language'
|
|
||||||
|
|
||||||
export default function I18nTest() {
|
|
||||||
const [langs, setLangs] = useState<Lang[]>([])
|
|
||||||
|
|
||||||
const getLangs = useCallback(async () => {
|
|
||||||
const langs = await genLangs()
|
|
||||||
setLangs(langs)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getLangs()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: 'calc(100% - 6em)',
|
|
||||||
overflowY: 'auto',
|
|
||||||
margin: '1em 1em 5em',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
|
|
||||||
<div style={{ minHeight: '75vh' }}>
|
|
||||||
<h2>Summary</h2>
|
|
||||||
|
|
||||||
<table
|
|
||||||
className={cn('mt-2 min-w-[340px] border-collapse border-0')}
|
|
||||||
>
|
|
||||||
<thead className="system-xs-medium-uppercase text-text-tertiary">
|
|
||||||
<tr>
|
|
||||||
<td className="w-5 min-w-5 whitespace-nowrap rounded-l-lg bg-background-section-burn pl-2 pr-1">
|
|
||||||
#
|
|
||||||
</td>
|
|
||||||
<td className="w-20 min-w-20 whitespace-nowrap bg-background-section-burn py-1.5 pl-3">
|
|
||||||
lang
|
|
||||||
</td>
|
|
||||||
<td className="w-20 min-w-20 whitespace-nowrap bg-background-section-burn py-1.5 pl-3">
|
|
||||||
count
|
|
||||||
</td>
|
|
||||||
<td className="w-20 min-w-20 whitespace-nowrap bg-background-section-burn py-1.5 pl-3">
|
|
||||||
missing
|
|
||||||
</td>
|
|
||||||
<td className="w-20 min-w-20 whitespace-nowrap bg-background-section-burn py-1.5 pl-3">
|
|
||||||
extra
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody className="system-sm-regular text-text-secondary">
|
|
||||||
{langs.map(({ locale, count, missing, extra }, idx) => <tr key={locale}>
|
|
||||||
<td className="">{idx}</td>
|
|
||||||
<td className="p-1.5">{locale}</td>
|
|
||||||
<td>{count}</td>
|
|
||||||
<td>{missing.length}</td>
|
|
||||||
<td>{extra.length}</td>
|
|
||||||
</tr>)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>Details</h2>
|
|
||||||
|
|
||||||
<table
|
|
||||||
className={cn('mt-2 w-full min-w-[340px] border-collapse border-0')}
|
|
||||||
>
|
|
||||||
<thead className="system-xs-medium-uppercase text-text-tertiary">
|
|
||||||
<tr>
|
|
||||||
<td className="w-5 min-w-5 whitespace-nowrap rounded-l-lg bg-background-section-burn pl-2 pr-1">
|
|
||||||
#
|
|
||||||
</td>
|
|
||||||
<td className="w-20 min-w-20 whitespace-nowrap bg-background-section-burn py-1.5 pl-3">
|
|
||||||
lang
|
|
||||||
</td>
|
|
||||||
<td className="w-full whitespace-nowrap bg-background-section-burn py-1.5 pl-3">
|
|
||||||
missing
|
|
||||||
</td>
|
|
||||||
<td className="w-full whitespace-nowrap bg-background-section-burn py-1.5 pl-3">
|
|
||||||
extra
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
{langs.map(({ locale, missing, extra }, idx) => {
|
|
||||||
return (<tr key={locale}>
|
|
||||||
<td className="py-2 align-top">{idx}</td>
|
|
||||||
<td className="py-2 align-top">{locale}</td>
|
|
||||||
<td className="py-2 align-top">
|
|
||||||
<ul>
|
|
||||||
{missing.map(key => (
|
|
||||||
<li key={key}>{key}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
<td className="py-2 align-top">
|
|
||||||
<ul>
|
|
||||||
{extra.map(key => (
|
|
||||||
<li key={key}>{key}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function genLangs() {
|
|
||||||
const langs_: Lang[] = []
|
|
||||||
let en!: Lang
|
|
||||||
|
|
||||||
const resources: Record<string, any> = {}
|
|
||||||
// Initialize empty resource object
|
|
||||||
for (const lang of LanguagesSupported)
|
|
||||||
resources[lang] = await loadLangResources(lang)
|
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(resources)) {
|
|
||||||
const keys = getNestedKeys(value.translation)
|
|
||||||
const lang: Lang = {
|
|
||||||
locale: key,
|
|
||||||
keys: new Set(keys),
|
|
||||||
count: keys.length,
|
|
||||||
missing: [],
|
|
||||||
extra: [],
|
|
||||||
}
|
|
||||||
|
|
||||||
langs_.push(lang)
|
|
||||||
if (key === 'en-US') en = lang
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const lang of langs_) {
|
|
||||||
const missing: string[] = []
|
|
||||||
const extra: string[] = []
|
|
||||||
|
|
||||||
for (const key of lang.keys)
|
|
||||||
if (!en.keys.has(key)) extra.push(key)
|
|
||||||
|
|
||||||
for (const key of en.keys)
|
|
||||||
if (!lang.keys.has(key)) missing.push(key)
|
|
||||||
|
|
||||||
lang.missing = missing
|
|
||||||
lang.extra = extra
|
|
||||||
}
|
|
||||||
return langs_
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNestedKeys(translation: Record<string, any>): string[] {
|
|
||||||
const nestedKeys: string[] = []
|
|
||||||
const iterateKeys = (obj: Record<string, any>, prefix = '') => {
|
|
||||||
for (const key in obj) {
|
|
||||||
const nestedKey = prefix ? `${prefix}.${key}` : key
|
|
||||||
// nestedKeys.push(nestedKey);
|
|
||||||
if (typeof obj[key] === 'object') iterateKeys(obj[key], nestedKey)
|
|
||||||
else if (typeof obj[key] === 'string') nestedKeys.push(nestedKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
iterateKeys(translation)
|
|
||||||
return nestedKeys
|
|
||||||
}
|
|
||||||
|
|
||||||
type Lang = {
|
|
||||||
locale: string;
|
|
||||||
keys: Set<string>;
|
|
||||||
count: number;
|
|
||||||
missing: string[];
|
|
||||||
extra: string[];
|
|
||||||
}
|
|
@@ -1,9 +0,0 @@
|
|||||||
import type React from 'react'
|
|
||||||
import { notFound } from 'next/navigation'
|
|
||||||
|
|
||||||
export default async function Layout({ children }: React.PropsWithChildren) {
|
|
||||||
if (process.env.NODE_ENV !== 'development')
|
|
||||||
notFound()
|
|
||||||
|
|
||||||
return children
|
|
||||||
}
|
|
@@ -1,11 +0,0 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
import DemoForm from '../components/base/form/form-scenarios/demo'
|
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
return (
|
|
||||||
<div className='flex h-screen w-full items-center justify-center p-20'>
|
|
||||||
<DemoForm />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@@ -8,6 +8,7 @@ const { translate } = bingTranslate
|
|||||||
const data = require('./languages.json')
|
const data = require('./languages.json')
|
||||||
|
|
||||||
const targetLanguage = 'en-US'
|
const targetLanguage = 'en-US'
|
||||||
|
const i18nFolder = '../i18n' // Path to i18n folder relative to this script
|
||||||
// https://github.com/plainheart/bing-translate-api/blob/master/src/met/lang.json
|
// https://github.com/plainheart/bing-translate-api/blob/master/src/met/lang.json
|
||||||
const languageKeyMap = data.languages.reduce((map, language) => {
|
const languageKeyMap = data.languages.reduce((map, language) => {
|
||||||
if (language.supported) {
|
if (language.supported) {
|
||||||
@@ -52,10 +53,9 @@ async function translateMissingKeyDeeply(sourceObj, targetObject, toLanguage) {
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function autoGenTrans(fileName, toGenLanguage) {
|
async function autoGenTrans(fileName, toGenLanguage) {
|
||||||
const fullKeyFilePath = path.join(__dirname, targetLanguage, `${fileName}.ts`)
|
const fullKeyFilePath = path.join(__dirname, i18nFolder, targetLanguage, `${fileName}.ts`)
|
||||||
const toGenLanguageFilePath = path.join(__dirname, toGenLanguage, `${fileName}.ts`)
|
const toGenLanguageFilePath = path.join(__dirname, i18nFolder, toGenLanguage, `${fileName}.ts`)
|
||||||
// eslint-disable-next-line sonarjs/code-eval
|
// eslint-disable-next-line sonarjs/code-eval
|
||||||
const fullKeyContent = eval(transpile(fs.readFileSync(fullKeyFilePath, 'utf8')))
|
const fullKeyContent = eval(transpile(fs.readFileSync(fullKeyFilePath, 'utf8')))
|
||||||
// if toGenLanguageFilePath is not exist, create it
|
// if toGenLanguageFilePath is not exist, create it
|
||||||
@@ -87,9 +87,8 @@ async function main() {
|
|||||||
// Promise.all(Object.keys(languageKeyMap).map(async (toLanguage) => {
|
// Promise.all(Object.keys(languageKeyMap).map(async (toLanguage) => {
|
||||||
// await autoGenTrans(fileName, toLanguage)
|
// await autoGenTrans(fileName, toLanguage)
|
||||||
// }))
|
// }))
|
||||||
|
|
||||||
const files = fs
|
const files = fs
|
||||||
.readdirSync(path.join(__dirname, targetLanguage))
|
.readdirSync(path.join(__dirname, i18nFolder, targetLanguage))
|
||||||
.map(file => file.replace(/\.ts/, ''))
|
.map(file => file.replace(/\.ts/, ''))
|
||||||
.filter(f => f !== 'app-debug') // ast parse error in app-debug
|
.filter(f => f !== 'app-debug') // ast parse error in app-debug
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ const languages = data.languages.filter(language => language.supported).map(lang
|
|||||||
|
|
||||||
async function getKeysFromLanuage(language) {
|
async function getKeysFromLanuage(language) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const folderPath = path.join(__dirname, language)
|
const folderPath = path.join(__dirname, '../i18n', language)
|
||||||
let allKeys = []
|
let allKeys = []
|
||||||
fs.readdir(folderPath, (err, files) => {
|
fs.readdir(folderPath, (err, files) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@@ -30,8 +30,8 @@
|
|||||||
"prepare": "cd ../ && node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky ./web/.husky",
|
"prepare": "cd ../ && node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky ./web/.husky",
|
||||||
"gen-icons": "node ./app/components/base/icons/script.mjs",
|
"gen-icons": "node ./app/components/base/icons/script.mjs",
|
||||||
"uglify-embed": "node ./bin/uglify-embed",
|
"uglify-embed": "node ./bin/uglify-embed",
|
||||||
"check-i18n": "node ./i18n/check-i18n.js",
|
"check-i18n": "node ./i18n-config/check-i18n.js",
|
||||||
"auto-gen-i18n": "node ./i18n/auto-gen-i18n.js",
|
"auto-gen-i18n": "node ./i18n-config/auto-gen-i18n.js",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test:watch": "jest --watch",
|
"test:watch": "jest --watch",
|
||||||
"storybook": "storybook dev -p 6006",
|
"storybook": "storybook dev -p 6006",
|
||||||
|
Reference in New Issue
Block a user