From 75d2c9c869ff2dbcfbf0e3338abb82a2cff69ff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Wed, 6 Sep 2023 12:45:51 +0300 Subject: [PATCH] RED-7497: Localazy scripts Update .gitlab-ci.yml file Update .gitlab-ci.yml file Update .gitlab-ci.yml file Update .gitlab-ci.yml file Update .gitlab-ci.yml file localazy script Update .gitlab-ci.yml file Update .gitlab-ci.yml file RED-7497: TS compile error localazy debug RED-7497: file import path localazy test localazy test localazy test localazy test localazy test localazy test --- .gitlab-ci.yml | 20 ++++++++++- package.json | 2 ++ tools/localazy/.gitignore | 2 ++ tools/localazy/package.json | 15 ++++++++ tools/localazy/src/constants.ts | 2 ++ tools/localazy/src/functions.ts | 63 +++++++++++++++++++++++++++++++++ tools/localazy/src/index.ts | 33 +++++++++++++++++ tools/localazy/src/utils.ts | 16 +++++++++ tools/localazy/tsconfig.json | 12 +++++++ yarn.lock | 5 +++ 10 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 tools/localazy/.gitignore create mode 100644 tools/localazy/package.json create mode 100644 tools/localazy/src/constants.ts create mode 100644 tools/localazy/src/functions.ts create mode 100644 tools/localazy/src/index.ts create mode 100644 tools/localazy/src/utils.ts create mode 100644 tools/localazy/tsconfig.json diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f0bf36d42..09c6f1293 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,4 +11,22 @@ workflow: include: - project: 'gitlab/gitlab' ref: 'main' - file: 'ci-templates/docker_build_nexus.yml' + file: 'ci-templates/docker_build_nexus_v2.yml' + +localazy update: + image: node:20.5 + cache: + - key: + files: + - yarn.lock + paths: + - .yarn-cache/ + script: + - cd tools/localazy + - yarn install --cache-folder .yarn-cache + - yarn start + rules: + - if: $LOCALAZY_RUN + - changes: + - tools/localazy/**/* + - red-ui/src/assets/i18n/**/* diff --git a/package.json b/package.json index 9ac65274f..0a6337b83 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "nx": "nx", "start": "nx serve", "update": "nx migrate latest", + "localazy": "ts-node tools/localazy/src/index.ts", "migrate": "nx migrate --run-migrations", "workspace-generator": "nx workspace-generator", "analyze": "nx build --stats-json && webpack-bundle-analyzer dist/apps/red-ui/stats.json", @@ -75,6 +76,7 @@ "@angular/compiler-cli": "16.2.2", "@angular/language-service": "16.2.2", "@bartholomej/ngx-translate-extract": "^8.0.2", + "@localazy/ts-api": "^1.0.0", "@nx/eslint-plugin": "16.7.4", "@nx/jest": "16.7.4", "@nx/linter": "16.7.4", diff --git a/tools/localazy/.gitignore b/tools/localazy/.gitignore new file mode 100644 index 000000000..d6ae6f5be --- /dev/null +++ b/tools/localazy/.gitignore @@ -0,0 +1,2 @@ +yarn.lock +node_modules/ diff --git a/tools/localazy/package.json b/tools/localazy/package.json new file mode 100644 index 000000000..65e81bae4 --- /dev/null +++ b/tools/localazy/package.json @@ -0,0 +1,15 @@ +{ + "name": "localazy", + "version": "1.0.0", + "dependencies": { + "@types/node": "^20.5.7" + }, + "scripts": { + "start": "ts-node src/index.ts" + }, + "devDependencies": { + "@localazy/ts-api": "^1.0.0", + "ts-node": "10.9.1", + "typescript": "5.1.3" + } +} diff --git a/tools/localazy/src/constants.ts b/tools/localazy/src/constants.ts new file mode 100644 index 000000000..c560ad948 --- /dev/null +++ b/tools/localazy/src/constants.ts @@ -0,0 +1,2 @@ +export const TOKEN: string = process.env.LOCALAZY_TOKEN || ''; +export const FILENAME = 'i18n.json'; diff --git a/tools/localazy/src/functions.ts b/tools/localazy/src/functions.ts new file mode 100644 index 000000000..438f34731 --- /dev/null +++ b/tools/localazy/src/functions.ts @@ -0,0 +1,63 @@ +import { FILENAME, TOKEN } 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'; + +const api = LocalazyApi({ + projectToken: TOKEN, + baseUrl: 'https://api.localazy.com', +}); + +export async function getProjectId(): Promise { + const projects = await api.listProjects(); + return projects[0].id; +} + +export async function getFileId(projectId: string): Promise { + const files = await api.listFiles({ projectId }); + return files.find(file => file.name === FILENAME)!.id; +} + +export async function uploadEn(projectId: string): Promise { + const enFile = (await import('./../../../apps/red-ui/src/assets/i18n/redact/en.json')).default; + + await api.import({ + projectId, + files: [ + { + name: FILENAME, + content: { type: 'json', features: ['plural_icu', 'filter_untranslated'], en: enFile }, + }, + ], + deprecate: 'project', + }); +} + +export async function downloadLanguage(projectId: string, fileId: string, lang: 'en' | 'de'): Promise { + const response = await api.getFileContents({ projectId, fileId, lang }); + return JSON.parse(await response.text()); +} + +export async function listKeys(projectId: string, fileId: string, lang: 'en' | 'de'): Promise { + const response = await api.listKeysInFileForLanguage({ projectId, fileId, lang }); + console.log(`Downloaded ${response.keys.length} keys for ${lang} language`); + return response.keys; +} + +export async function updateLocalEn(keys: Key[]): Promise { + const enFile = (await import('./../../../apps/red-ui/src/assets/i18n/redact/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/redact/en.json', JSON.stringify(enFile, null, 2)); +} + +export async function updateLocalDe(projectId: string, fileId: string): Promise { + const deFile = await downloadLanguage(projectId, fileId, 'de'); + await fs.promises.writeFile('./../../apps/red-ui/src/assets/i18n/redact/de.json', JSON.stringify(deFile, null, 2)); +} diff --git a/tools/localazy/src/index.ts b/tools/localazy/src/index.ts new file mode 100644 index 000000000..033f62f3e --- /dev/null +++ b/tools/localazy/src/index.ts @@ -0,0 +1,33 @@ +import { downloadLanguage, getFileId, getProjectId, listKeys, updateLocalDe, updateLocalEn, uploadEn } from './functions'; + +async function execute() { + const projectId = await getProjectId(); + const fileId = await getFileId(projectId); + + /** Update local en (source) file with potential remotely updated translations. */ + const remoteKeys = await listKeys(projectId, fileId, 'en'); + await updateLocalEn(remoteKeys); + + /** Upload local en (source) file in order to add new keys and deprecate unused keys. */ + await uploadEn(projectId); + + /** Download updated de file. */ + await updateLocalDe(projectId, fileId); +} + +async function uploadLocals() { + const projectId = await getProjectId(); + await uploadEn(projectId); +} + +async function downloadDe() { + const projectId = await getProjectId(); + const fileId = await getFileId(projectId); + + console.log({ projectId, fileId }); + console.log(await downloadLanguage(projectId, fileId, 'de')); +} + +execute().then(); +// uploadLocals().then(); +// downloadDe().then(); diff --git a/tools/localazy/src/utils.ts b/tools/localazy/src/utils.ts new file mode 100644 index 000000000..053be0303 --- /dev/null +++ b/tools/localazy/src/utils.ts @@ -0,0 +1,16 @@ +export function get(object: any, path: string[]): any { + return path.reduce((o, k) => (o || {})[k], object); +} + +export function set(object: any, path: string[], value: any): void { + path.reduce((o, k, i) => { + if (i === path.length - 1) { + o[k] = value; + } else { + if (o[k] === undefined) { + o[k] = {}; + } + } + return o[k]; + }, object); +} diff --git a/tools/localazy/tsconfig.json b/tools/localazy/tsconfig.json new file mode 100644 index 000000000..b7593cf3e --- /dev/null +++ b/tools/localazy/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "lib": ["es6", "DOM"], + "outDir": "build", + "strict": true, + "noImplicitAny": true, + "esModuleInterop": true, + "resolveJsonModule": true + } +} diff --git a/yarn.lock b/yarn.lock index 0c12bb2d7..da1f14aea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2494,6 +2494,11 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== +"@localazy/ts-api@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@localazy/ts-api/-/ts-api-1.1.0.tgz#e36edbea775fa950a6dcd54693686ed63fa67218" + integrity sha512-0iLFWRxmKPkuruASye4A6CQoYMDGLqQmPLS76zKhPywwNTc89oIlaWrkl63c2EP70NzHxKu6BnpmJAjqFSeXrg== + "@materia-ui/ngx-monaco-editor@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@materia-ui/ngx-monaco-editor/-/ngx-monaco-editor-6.0.0.tgz#9ae93666019e9a6d4f787370b4373cbb63a04a38"