@deeplx/core
Version:
An unofficial but powerful and easy-to-use yet free DeepL API client for Node.js using [DeepL](https://www.deepl.com) by porting [OwO-Network/DeepLX](https://github.com/OwO-Network/DeepLX).
150 lines • 5.57 kB
JavaScript
import { createProxy } from 'node-fetch-native/proxy';
import { detectLang } from 'whatlang-node';
import { xfetch } from 'x-fetch';
import { API_URL, COMMON_HEADERS, HTTP_STATUS_NOT_FOUND, HTTP_STATUS_OK, HTTP_STATUS_SERVICE_UNAVAILABLE, } from "./constants.js";
import { abbreviateLanguage, formatPostString, getICount, getRandomNumber, getTimeStamp, } from "./utils.js";
const makeRequest = async (postData, proxyUrl, dlSession) => {
return xfetch(API_URL, {
method: 'POST',
body: formatPostString(postData),
headers: dlSession
? { ...COMMON_HEADERS, Cookie: `dl_session=${dlSession}` }
: COMMON_HEADERS,
...createProxy({ url: proxyUrl }),
});
};
const splitAndProcess = (text) => text.split('\n').map(line => (line.trim() === '' ? '\n' : line));
export const translateByDeepLX = async (sourceLang, targetLang, text, formal, tagHandling = 'plaintext', proxyUrl, dlSession) => {
if (!text) {
return { code: HTTP_STATUS_NOT_FOUND, message: 'No text to translate' };
}
const textParts = splitAndProcess(text);
const translatedParts = [];
const allAlternatives = [];
for (const part of textParts) {
if (!part.trim()) {
translatedParts.push('');
allAlternatives.push(['']);
continue;
}
if (!sourceLang || sourceLang === 'auto') {
sourceLang = detectLang(part, true);
}
const sourceLangCode = abbreviateLanguage(sourceLang) ??
sourceLang.toUpperCase();
const jobs = [
{
kind: 'default',
preferred_num_beams: 4,
raw_en_context_before: [],
raw_en_context_after: [],
sentences: [{ prefix: '', text: part, id: 0 }],
},
];
let hasRegionalVariant = false;
let targetLangCode = abbreviateLanguage(targetLang) ??
targetLang.toUpperCase();
const targetLangParts = targetLang.split('-');
if (targetLangParts.length > 1) {
targetLangCode = targetLangParts[0];
hasRegionalVariant = true;
}
const id = getRandomNumber();
const postData = {
jsonrpc: '2.0',
method: 'LMT_handle_jobs',
id,
params: {
commonJobParams: {
mode: 'translate',
formality: formal == null ? 'undefined' : formal ? 'formal' : 'informal',
transcribe_as: 'romanize',
advancedMode: false,
textType: tagHandling,
wasSpoken: false,
...(hasRegionalVariant && { regionalVariant: targetLang }),
},
lang: {
source_lang_user_selected: 'auto',
target_lang: targetLangCode,
source_lang_computed: sourceLangCode,
},
jobs,
timestamp: getTimeStamp(getICount(part)),
},
};
let translations;
try {
const { result } = await makeRequest(postData, proxyUrl, dlSession);
translations = result.translations;
}
catch (error) {
return {
code: HTTP_STATUS_SERVICE_UNAVAILABLE,
message: String(error),
};
}
let partTranslation = '';
const partAlternatives = [];
if (translations.length > 0) {
for (const translation of translations) {
partTranslation += translation.beams[0].sentences[0].text + ' ';
}
partTranslation = partTranslation.trim();
const numBeams = translations[0].beams.length;
for (let i = 1; i < numBeams; i++) {
let altText = '';
for (const translation of translations) {
const beams = translation.beams;
if (i < beams.length) {
altText += beams[i].sentences[0].text + ' ';
}
}
if (altText) {
partAlternatives.push(altText.trim());
}
}
}
if (!partTranslation) {
return {
code: HTTP_STATUS_SERVICE_UNAVAILABLE,
message: 'Translation failed',
};
}
translatedParts.push(partTranslation);
allAlternatives.push(partAlternatives);
}
const translatedText = translatedParts.join('\n');
const combinedAlternatives = [];
let maxAlts = 0;
for (const alts of allAlternatives) {
if (alts.length > maxAlts) {
maxAlts = alts.length;
}
}
for (let i = 0; i < maxAlts; i++) {
const altParts = [];
for (const [j, alts] of allAlternatives.entries()) {
if (i < alts.length) {
altParts.push(alts[i]);
}
else if (translatedParts[j].length === 0) {
altParts.push('');
}
else {
altParts.push(translatedParts[j]);
}
}
combinedAlternatives.push(altParts.join('\n'));
}
return {
code: HTTP_STATUS_OK,
id: getRandomNumber(),
data: translatedText,
alternatives: combinedAlternatives,
sourceLang: sourceLang,
targetLang,
method: dlSession ? 'Pro' : 'Free',
};
};
//# sourceMappingURL=translate.js.map