lokalise.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* eslint-disable react-func/max-lines-per-function */
  2. /**
  3. * A script that syncs the local codebase with Lokalize. The script support two commands:
  4. *
  5. * 1. Pulling all translation files from Lokalize by using the syntax `yarn run lokalise:pull`.
  6. * 2. Pushing a specific file for a specific locale to Lokalise by using the syntax `yarn run lokalise:push {filename} {locale}` e.g. `yarn run lokalise:push common.json en`.
  7. */
  8. /* eslint-disable import/no-extraneous-dependencies */
  9. /* eslint-disable no-console */
  10. const fs = require('fs');
  11. const { LokaliseApi } = require('@lokalise/node-api');
  12. const admZip = require('adm-zip');
  13. const dotenv = require('dotenv');
  14. const inquirer = require('inquirer');
  15. const inquirerFileTreeSelection = require('inquirer-file-tree-selection-prompt');
  16. const request = require('superagent');
  17. const LOCALES_PATH = './locales';
  18. const DESTINATION_FILE = `${LOCALES_PATH}/locales.zip`;
  19. const configs = dotenv.config({ path: '.env.local' });
  20. const API_KEY = configs.parsed.LOKALISE_API_KEY;
  21. const PROJECT_ID = configs.parsed.LOKALISE_PROJECT_ID;
  22. const SYNC_REMOTE_TO_LOCAL = 'Sync remote files to local';
  23. const PUSH_LOCAL_TO_REMOTE = 'Push local file to remote';
  24. if (!API_KEY || !PROJECT_ID) {
  25. console.log('Lokalise API keys are not configured!');
  26. } else {
  27. const lokaliseApi = new LokaliseApi({ apiKey: API_KEY });
  28. inquirer.registerPrompt('file-tree-selection', inquirerFileTreeSelection);
  29. inquirer
  30. .prompt([
  31. {
  32. type: 'list',
  33. message: 'Please select the operation',
  34. name: 'operationType',
  35. choices: [SYNC_REMOTE_TO_LOCAL, PUSH_LOCAL_TO_REMOTE],
  36. },
  37. ])
  38. .then(({ operationType }) => {
  39. if (operationType === SYNC_REMOTE_TO_LOCAL) {
  40. console.log('Requesting zipped file url...');
  41. // 1. Request the url that contained the zipped file of all the translations files.
  42. lokaliseApi
  43. .files()
  44. .download(PROJECT_ID, { format: 'json', original_filenames: true, indentation: '2sp' })
  45. .then((response) => {
  46. console.log('Starting to download the zipped file...');
  47. // 2. Download the zipped file.
  48. request
  49. .get(response.bundle_url)
  50. .on('error', () => {
  51. console.log('An error occurred while trying to download the zipped file.');
  52. })
  53. .pipe(fs.createWriteStream(DESTINATION_FILE))
  54. .on('finish', () => {
  55. console.log('Downloaded the file successfully, starting to unzip the files...');
  56. // eslint-disable-next-line new-cap
  57. const zip = new admZip(DESTINATION_FILE);
  58. // 3. un-zip the file into the locales folder
  59. zip.extractAllTo(LOCALES_PATH, true);
  60. console.log('Unzipped the file successfully, deleting the zipped file.');
  61. // 4. delete the zipped file.
  62. fs.unlink(DESTINATION_FILE, (err) => {
  63. if (err) {
  64. console.log('An error occurred while trying to delete the zipped file.');
  65. }
  66. console.log('The zipped file was deleted successfully.');
  67. });
  68. });
  69. })
  70. .catch(() => {
  71. console.log('An error occurred while trying to request the zipped file url.');
  72. });
  73. } else if (operationType === PUSH_LOCAL_TO_REMOTE) {
  74. inquirer
  75. .prompt({
  76. type: 'file-tree-selection',
  77. name: 'file',
  78. message: 'choose a translation file',
  79. root: `${LOCALES_PATH}/en`,
  80. })
  81. .then((answers) => {
  82. const { file: filePath } = answers;
  83. const filenameSplits = filePath.split('/');
  84. const filename = filenameSplits[filenameSplits.length - 1];
  85. // 1. Open the file then convert it to base64
  86. const toBeUploadedFileContent = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
  87. const base64Data = Buffer.from(JSON.stringify(toBeUploadedFileContent)).toString(
  88. 'base64',
  89. );
  90. console.log(`Starting to push ${filename} to Lokalise`);
  91. // 2. Start the uploading process.
  92. lokaliseApi
  93. .files()
  94. .upload(PROJECT_ID, { data: base64Data, filename, lang_iso: 'en' })
  95. .then(() => {
  96. console.log(`${filename} has been pushed to Lokalise queue successfully!`);
  97. })
  98. .catch(() => {
  99. console.log('Something went wrong while trying to upload the file');
  100. });
  101. });
  102. }
  103. });
  104. }