Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Add support for JSONL file translation #83

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions src/core/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as fs from 'fs/promises';
import * as YAML from 'yaml';
import { matchYamlExt } from '../utils/yaml';
import { error, messages } from '../utils/console';
import { getFileExt } from './json_file';

export async function getFile(objectPath: string) {
let json_file: any = undefined;
Expand Down Expand Up @@ -37,14 +38,20 @@ export function getRootFolder(path: string) {
}

export async function saveFilePublic(path: string, data: any) {
// When path extension is for YAML file, then stringify with YAML encoder.
// Otherwise, default JSON encoder is used.
var json = matchYamlExt(path) ? YAML.stringify(data) : JSON.stringify(data);
let json = ""
if (getFileExt(path) === "jsonl") {
// If the file extension is `.jsonl`, the data is serialized as JSON Lines (JSONL) format.
json = data.map((item: any) => JSON.stringify(item)).join('\n');
} else {
// When path extension is for YAML file, then stringify with YAML encoder.
// Otherwise, default JSON encoder is used.
json = matchYamlExt(path) ? YAML.stringify(data) : JSON.stringify(data);
}

await fs
.writeFile(path, json, 'utf8')
.then(_ => {})
.catch(_ => {
error(messages.file.cannot_save_file);
});
}
}
33 changes: 23 additions & 10 deletions src/core/json_file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ export async function fileTranslator(
return;
}

jsonObj = { data: JSON.parse(jsonObj) };
// if file extension is .jsonl convert the readed file to json with array of each line of the json file
if (getFileExt(objectPath) === "jsonl") {
jsonObj = { data: jsonObj.split('\n').map((line: string) => JSON.parse(line)) };
} else {
jsonObj = { data: JSON.parse(jsonObj) };
}

// step: check if translation file already exists, if exists save content of it in oldTranslations
let oldTranslations = JSON.parse("{}")
Expand All @@ -36,23 +41,26 @@ export async function fileTranslator(

let response = await getFileFromPath(fileName);
let oldTranslation = response?.jsonObj
try{
try {
if (oldTranslation === undefined) {
// Old Translation not found
oldTranslations[lang] = { data: {} };
} else {
oldTranslation = { data: JSON.parse(oldTranslation) };
oldTranslations[lang] = oldTranslation;
}
} catch{
} catch {
// If error in parsing json skip it
oldTranslations[lang] = { data: {} };
}

}

// if jsonl file force to translate all keys
const reTraslateOldTranslations = getFileExt(objectPath) === "jsonl";

// step: translate object
let newJsonObj = await objectTranslator(TranslationConfig, jsonObj, from, to, oldTranslations);
let newJsonObj = await objectTranslator(TranslationConfig, jsonObj, from, to, oldTranslations, reTraslateOldTranslations);
if (newJsonObj === undefined) {
error(messages.file.cannot_translate);
return;
Expand Down Expand Up @@ -91,13 +99,18 @@ export async function getFileFromPath(
return { jsonObj, objectPath };
}

function getFileExt(latestPath: string): string {
export function getFileExt(latestPath: string): string {
// Check if source file has YAML extension and return the extension ("yml" or "yaml").
const sourceFileMatchYamlExt = matchYamlExt(latestPath);

// When source file has "yml" or "yaml" extension, use the same in output file path.
// Otherwise, default "json" extension used.
const fileExt = sourceFileMatchYamlExt || 'json';

let fileExt = "";
if (latestPath.toLowerCase().endsWith('.jsonl')) {
// If the latestPath file extension is jsonl, keep fileExt jsonl
fileExt = "jsonl";
} else {
// When source file has "yml" or "yaml" extension, use the same in output file path.
// Otherwise, default "json" extension used.
fileExt = sourceFileMatchYamlExt || 'json';
}
return fileExt;
}
23 changes: 16 additions & 7 deletions src/core/json_object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,24 @@ export async function objectTranslator(
object: translatedObject,
from: string,
to: string[],
oldTranslations: { [key: string]: any }
oldTranslations: { [key: string]: any },
reTraslateOldTranslations: boolean = false
): Promise<translatedObject[]> {
queue.concurrency = TranslationConfig.concurrencyLimit;

if (object && from && to) {
let generalObject: translatedObject[] | null[] = [];

await Promise.all(
Object.keys(to).map(async function (index) {
const indexAsNum = Number(index);
// Remove the keys which are already translated
const copyObject = removeKeys(JSON.parse(JSON.stringify(object)), oldTranslations[to[indexAsNum]]);

let copyObject = JSON.parse(JSON.stringify(object))
if (!reTraslateOldTranslations) {
// Remove the keys which are already translated
copyObject = removeKeys(JSON.parse(JSON.stringify(object)), oldTranslations[to[indexAsNum]]);
}



const newTranslations = await deepDiver(
TranslationConfig,
Expand All @@ -33,12 +39,15 @@ export async function objectTranslator(
to[indexAsNum]
);

// Insert old translations that we removed into the generalObject
generalObject[indexAsNum] = mergeKeys(oldTranslations[to[indexAsNum]], newTranslations)
if (!reTraslateOldTranslations) {
// Insert old translations that we removed into the generalObject
generalObject[indexAsNum] = mergeKeys(oldTranslations[to[indexAsNum]], newTranslations);
} else {
generalObject[indexAsNum] = JSON.parse(JSON.stringify(newTranslations));
}

})
);

return generalObject as translatedObject[];
} else {
throw new Error(
Expand Down
9 changes: 9 additions & 0 deletions src/utils/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ export function removeKeys(fromDict: any, toDict: any): any {
return fromDict;
}

if (Array.isArray(fromDict)) {
return fromDict;
}

if (typeof fromDict !== 'object' || fromDict === null) {
return fromDict;
}
Expand Down Expand Up @@ -144,6 +148,11 @@ export function mergeKeys(base: any, insert: any): any {
return insert;
}

// Handle only insert is array
if (Array.isArray(insert)) {
return insert;
}

// Handle objects
const result = { ...base };

Expand Down