Skip to content

Commit

Permalink
feat: Updating documentation and adapting code to support any dynamic…
Browse files Browse the repository at this point in the history
… JSON structure
  • Loading branch information
gabriel-logan committed Jun 2, 2024
1 parent f12f076 commit 427a60e
Show file tree
Hide file tree
Showing 11 changed files with 275 additions and 74 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
node_modules/
private/
dist/
types/
/types/
tsconfigcopy.json
geraTraducoes.js
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ tsconfigcopy.json
tsconfig.json
tsconfig.types.json
.prettierrc.js
dist/types/
49 changes: 42 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ NPM PAGE: https://www.npmjs.com/package/azure-translator-code

GITHUB PAGE: https://github.com/gabriel-logan/Azure-translator-code

You con test the library in the following link: https://azuretranslatorcode.vercel.app

## Installation

To get started, you can install the library via npm:
Expand Down Expand Up @@ -49,14 +51,15 @@ const jsonFile = require('./jsonFileToTranslate/en.json');

// or

// IMPORTANT
// The file must follow this structure.
const jsonFile = {
"translation": {
"welcome": "Welcome",
"hello": "Hello",
}
};
"HomePage": {
"welcome": 'Welcome',
"hello": 'Hello',
"SubText": {
"subText": 'This is a subtext'
}
}
}
```

Now, you can use the library to translate the JSON file into multiple languages:
Expand Down Expand Up @@ -148,6 +151,38 @@ updateTranslationsMulti(key, endpoint, location, fromLang, toLangs, jsonFile, 'm
// This function will update the translations in the folder called myFolder
```

## Translate and Log the result

You can also log the result of the translation in the console.

```javascript
const { translate } = require('azure-translator-code');

const key = 'sds12312a213aaaa9b2d0c37eds37b'; // REPLACE WITH YOUR OWN KEY HERE
const endpoint = 'https://api.cognitive.microsofttranslator.com/';
const location = 'eastus';
const fromLang = 'en';
const toLang = 'pt';
const jsonFile = {
HomePage: {
Welcome: "Welcome",
Hello: "Hello",
},
};

translate(key, endpoint, location, fromLang, toLang, jsonFile).then((result) => console.log(result));

// Output
/**
* {
* "translation": {
* "Welcome": "Bem-vindo",
* "Hello": "Olá",
* }
* }
*/

```
Make sure to replace the key and endpoint information with your own Azure access credentials. Ensure that the JSON file and settings are correctly defined according to your needs.

Contributing
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "azure-translator-code",
"version": "1.1.2",
"version": "1.1.3",
"description": "Azure Cognitive Services Translator Text API Code for Use with Common Languages",
"author": {
"name": "Gabriel Logan"
Expand Down
9 changes: 8 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import translateToMultipleFolders from './translateToMultipleFolders';
import translateToUnicFolder from './translateToUnicFolder';
import updateTranslationsMulti from './updateTranslationMulti';
import updateTranslationsUnic from './updateTranslationUnic';
import translate from './translate';

export { translateToMultipleFolders, translateToUnicFolder, updateTranslationsMulti, translate };
export {
translateToMultipleFolders,
translateToUnicFolder,
updateTranslationsMulti,
updateTranslationsUnic,
translate,
};
8 changes: 1 addition & 7 deletions src/translate/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';

/**
* Represents the type of a translation object.
*/
export type TranslationType = {
[key: string]: string | TranslationType;
};
import type { TranslationType } from '../types';

async function translateText(
text: string,
Expand Down
9 changes: 2 additions & 7 deletions src/translateToMultipleFolders/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';
import * as fs from 'fs';
import * as path from 'path';

export type TranslationType = {
[key: string]: string | TranslationType;
};
import type { TranslationType } from '../types';

/**
* @param key Your key from azure translator, something like: 'sds12312a213aaaa9b2d0c37eds37b'
Expand All @@ -28,7 +25,7 @@ export type TranslationType = {
'tlh-Latn'
];
* @param jsonFile
* It must follow the following structure:
* It must be a valid JSON object:
*
* {
"translation": {
Expand All @@ -44,8 +41,6 @@ export type TranslationType = {
"error_message": "An error occurred"
}
}
*
If you need, copy this structure to get better then make your modification
*
@param [folderNamePath='multiFolderGeneratedTranslations'] If it is undefined, it will be associated by default: multiFolderGeneratedTranslations
You can use this like: 'myfoldername' or 'myfoldername/otherfolder' or './myfoldername/etcfolder'
Expand Down
8 changes: 2 additions & 6 deletions src/translateToUnicFolder/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';
import * as fs from 'fs';
import * as path from 'path';
import type { TranslationType } from '../types';

export type TranslationType = {
[key: string]: string | TranslationType;
};
/**
* @param key Your key from azure translator, something like: 'sds12312a213aaaa9b2d0c37eds37b'
* @param endpoint The endpoint: 'https://api.cognitive.microsofttranslator.com/'
Expand All @@ -27,7 +25,7 @@ export type TranslationType = {
'tlh-Latn'
];
* @param jsonFile
* It must follow the following structure:
* It must be a valid JSON object:
*
* {
"translation": {
Expand All @@ -43,8 +41,6 @@ export type TranslationType = {
"error_message": "An error occurred"
}
}
*
If you need, copy this structure to get better then make your modification
*
@param [folderNamePath='unicFolderGeneratedTranslations'] If it is undefined, it will be associated by default: unicFolderGeneratedTranslations
You can use this like: 'myfoldername' or 'myfoldername/otherfolder' or './myfoldername/etcfolder'
Expand Down
6 changes: 6 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Represents the type of a translation object.
*/
export type TranslationType = {
[key: string]: string | TranslationType;
};
103 changes: 59 additions & 44 deletions src/updateTranslationMulti/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';
import fs from 'fs';
import path from 'path';

export interface TranslationType {
translation: Record<string, string>;
}
import * as fs from 'fs';
import * as path from 'path';
import type { TranslationType } from '../types';

/**
* @param key Your key from azure translator, something like: 'sds12312a213aaaa9b2d0c37eds37b'
Expand All @@ -28,7 +25,7 @@ export interface TranslationType {
'tlh-Latn'
];
* @param jsonFile
* It must follow the following structure:
* It must be a valid JSON object:
*
* {
"translation": {
Expand All @@ -44,8 +41,6 @@ export interface TranslationType {
"error_message": "An error occurred"
}
}
*
If you need, copy this structure to get better then make your modification
*
* @description This function checks the json with the already existing translations and adds only the non-existing translations to the file, this serves to save data.
* Otherwise it works the same as the other 2 functions
Expand All @@ -62,16 +57,15 @@ export default function updateTranslationsMulti(
fromLang: string,
toLangs: string[],
jsonFile: TranslationType,
folderNamePath: string = 'multiFolderGeneratedTranslations',
folderNamePath: string = 'multiFolderGeneratedTranslations', // Onde sera salvo os arquivos
): void {
const rootDir: string = path.join(__dirname, '..', '..', '..', '..');
const traducoesDir: string = path.join(rootDir, folderNamePath);
const traducoesDir: string = path.join(__dirname, '..', '..', '..', '..', folderNamePath);

if (!fs.existsSync(traducoesDir)) {
fs.mkdirSync(traducoesDir, { recursive: true });
}

async function translateText(text: string, from: string, to: string) {
function translateText(text: string, from: string, to: string) {
return axios({
baseURL: endpoint,
url: '/translate',
Expand All @@ -96,48 +90,69 @@ export default function updateTranslationsMulti(
});
}

async function translateAndSave(lang: string) {
const langDir: string = path.join(traducoesDir, lang);

if (!fs.existsSync(langDir)) {
fs.mkdirSync(langDir);
}

const outputFileName: string = path.join(langDir, `${lang}.json`);
let translations: Record<string, string> = {};

if (fs.existsSync(outputFileName)) {
const existingData: TranslationType = JSON.parse(fs.readFileSync(outputFileName, 'utf8'));
translations = existingData.translation;
}
async function translateAndSave(
lang: string,
obj: TranslationType,
existingTranslations: TranslationType,
currentPath: string = '',
) {
const translations: Record<string, unknown> = existingTranslations;

const newTranslations: Record<string, string> = {};
for (const key in obj) {
const newPath = currentPath ? `${currentPath}.${key}` : key;

for (const key in jsonFile.translation) {
if (!translations[key]) {
try {
console.log('TO FAZENDO UMA REQUISICAO');
const response = await translateText(jsonFile.translation[key], fromLang, lang);
const translatedText: string = response.data[0].translations[0].text;
newTranslations[key] = translatedText;
console.log(`Translating "${jsonFile.translation[key]}" to ${lang} \n\n`);
} catch (error) {
if (error instanceof Error) {
console.error(`Error translating "${key}" to ${lang}: ${error.message} \n`);
} else {
console.error(`An error occurred within the error (: \n`);
if (typeof obj[key] === 'object' && obj[key] !== null) {
const nestedTranslations = await translateAndSave(
lang,
obj[key] as TranslationType,
(existingTranslations[key] || {}) as TranslationType,
newPath,
);
translations[key] = nestedTranslations;
} else {
if (!translations[key]) {
try {
const response = await translateText(obj[key] as string, fromLang, lang);
const translatedText = response.data[0].translations[0].text;
translations[key] = translatedText;
console.log(`Translating ${obj[key]} to ${lang} \n\n`);
} catch (error) {
if (error instanceof Error) {
console.error(`Error translating "${newPath}" to ${lang}: ${error.message} \n`);
} else {
console.error(`An error occurred within the error (: \n`);
}
}
}
}
}

translations = { ...translations, ...newTranslations };
fs.writeFileSync(outputFileName, JSON.stringify({ translation: translations }, null, 4));
const langDir = path.join(traducoesDir, lang);

if (!fs.existsSync(langDir)) {
fs.mkdirSync(langDir);
}

const outputFileName = path.join(langDir, `${lang}.json`);
fs.writeFileSync(outputFileName, JSON.stringify(translations, null, 4));
console.log(`Translations for ${lang} saved in ${outputFileName} \n\n`);

return translations;
}

async function translateAndSaveAll() {
const translationPromises: Promise<void>[] = toLangs.map((lang) => translateAndSave(lang));
const translationPromises = toLangs.map(async (lang) => {
const langDir = path.join(traducoesDir, lang);
const outputFileName = path.join(langDir, `${lang}.json`);

let existingTranslations: TranslationType = {};
if (fs.existsSync(outputFileName)) {
const rawData = fs.readFileSync(outputFileName, 'utf8');
existingTranslations = JSON.parse(rawData);
}

return translateAndSave(lang, jsonFile, existingTranslations);
});

await Promise.all(translationPromises);
}
Expand Down
Loading

0 comments on commit 427a60e

Please sign in to comment.