crowdin-generate.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import fs from 'fs'
  2. import path from 'path'
  3. import chalk from 'chalk'
  4. import consola from 'consola'
  5. import { docRoot, errorAndExit } from '@element-plus/build-utils'
  6. // NB: this file is only for generating files that enables developers to develop the website.
  7. const componentLocaleRoot = path.resolve(docRoot, '.vitepress/crowdin')
  8. const exists = 'File already exists'
  9. async function main() {
  10. const localeOutput = path.resolve(docRoot, '.vitepress/i18n')
  11. if (fs.existsSync(localeOutput)) {
  12. throw new Error(exists)
  13. }
  14. consola.trace(chalk.cyan('Starting for build doc for developing'))
  15. // all language should be identical since it is mirrored from crowdin.
  16. const dirs = await fs.promises.readdir(componentLocaleRoot, {
  17. withFileTypes: true,
  18. })
  19. const languages = dirs.map(dir => dir.name)
  20. const langWithoutEn = languages.filter(l => l !== 'en-US')
  21. await fs.promises.mkdir(localeOutput)
  22. // build lang.json for telling `header>language-select` how many languages are there
  23. await fs.promises.writeFile(path.resolve(localeOutput, 'lang.json'), JSON.stringify(languages), 'utf-8')
  24. // loop through en-US
  25. const enUS = path.resolve(componentLocaleRoot, 'en-US')
  26. // we do not include en-US since we are currently using it as template
  27. const languagePaths = langWithoutEn.map(l => {
  28. return {
  29. name: l,
  30. pathname: path.resolve(componentLocaleRoot, l),
  31. }
  32. })
  33. consola.debug(languagePaths)
  34. await traverseDir(enUS, languagePaths, localeOutput)
  35. }
  36. async function traverseDir(dir: string, paths: { name: string; pathname: string }[], targetPath: string) {
  37. const contents = await fs.promises.readdir(dir, { withFileTypes: true })
  38. await Promise.all(
  39. contents.map(async c => {
  40. if (c.isDirectory()) {
  41. await fs.promises.mkdir(path.resolve(targetPath, c.name), {
  42. recursive: true,
  43. })
  44. return traverseDir(
  45. path.resolve(dir, c.name),
  46. paths.map(p => {
  47. return {
  48. ...p,
  49. pathname: path.resolve(p.pathname, c.name),
  50. }
  51. }),
  52. path.resolve(targetPath, c.name)
  53. )
  54. } else if (c.isFile()) {
  55. // eslint-disable-next-line @typescript-eslint/no-var-requires
  56. const content = require(path.resolve(dir, c.name))
  57. const contentToWrite = {
  58. 'en-US': content,
  59. }
  60. await Promise.all(
  61. paths.map(async p => {
  62. // eslint-disable-next-line @typescript-eslint/no-var-requires
  63. const content = require(path.resolve(p.pathname, c.name))
  64. contentToWrite[p.name] = content
  65. })
  66. )
  67. return fs.promises.writeFile(path.resolve(targetPath, c.name), JSON.stringify(contentToWrite, null, 2), {
  68. encoding: 'utf-8',
  69. })
  70. }
  71. })
  72. )
  73. }
  74. main()
  75. .then(() => {
  76. consola.success(chalk.green('Locale for website development generated'))
  77. })
  78. .catch(err => {
  79. if (err.message === exists) {
  80. // do nothing
  81. } else {
  82. errorAndExit(err)
  83. }
  84. })