import { Apps, FILENAME, Tokens } from './constants'; import LocalazyApi from '@localazy/ts-api'; import { Key } from '@localazy/ts-api/dist/models/responses/keys-in-file'; import { get, set } from './utils'; import * as fs from 'fs'; export class LocalazyRunner { private readonly _api; private _projectId = ''; private _fileId = ''; constructor(readonly app: Apps) { this._api = LocalazyApi({ projectToken: Tokens[app], baseUrl: 'https://api.localazy.com', }); } async initialize(): Promise { this._projectId = await this._getProjectId(); this._fileId = await this._getFileId(); } async synchronize(): Promise { /** Update local en (source) file with potential remotely updated translations. */ const remoteKeys = await this._listKeys('en'); await this._updateLocalEn(remoteKeys); /** Upload local en (source) file in order to add new keys and deprecate unused keys. */ await this._uploadLocal('en'); /** Download updated de file. */ await this._updateLocalDe(); } /** For debug purposes only. */ async uploadLocalDe() { await this._uploadLocal('de'); } /** For debug purposes only. */ async downloadDe() { console.log(await this._downloadLanguage('de')); } private async _uploadLocal(lang: 'en' | 'de'): Promise { const langFile = (await import(`./../../../apps/red-ui/src/assets/i18n/${this.app}/${lang}.json`)).default; await this._api.import({ projectId: this._projectId, files: [ { name: FILENAME, content: { type: 'json', features: ['plural_icu', 'filter_untranslated'], [lang]: langFile }, }, ], deprecate: 'project', }); } private async _listKeys(lang: 'en' | 'de'): Promise { let keys: Key[] = []; let next: string | undefined = undefined; do { const response = await this._api.listKeysInFileForLanguage({ projectId: this._projectId, fileId: this._fileId, lang, next }); next = response.next; keys = [...keys, ...response.keys]; } while (next); return keys; } private async _updateLocalEn(keys: Key[]): Promise { const enFile = (await import(`./../../../apps/red-ui/src/assets/i18n/${this.app}/en.json`)).default; keys.forEach(({ key, value }) => { if (get(enFile, key) !== undefined) { set(enFile, key, value); } }); await fs.promises.writeFile(`./../../apps/red-ui/src/assets/i18n/${this.app}/en.json`, JSON.stringify(enFile, null, 2)); } private async _updateLocalDe(): Promise { const deFile = await this._downloadLanguage('de'); await fs.promises.writeFile(`./../../apps/red-ui/src/assets/i18n/${this.app}/de.json`, JSON.stringify(deFile, null, 2)); } private async _downloadLanguage(lang: 'en' | 'de'): Promise { const response = await this._api.getFileContents({ projectId: this._projectId, fileId: this._fileId, lang }); return JSON.parse(await response.text()); } private async _getProjectId(): Promise { const projects = await this._api.listProjects(); return projects[0].id; } private async _getFileId(): Promise { const files = await this._api.listFiles({ projectId: this._projectId }); return files.find(file => file.name === FILENAME)!.id; } }