anylang
Version:
A translator's kit that uses the free APIs of Google Translate, Yandex, Bing, ChatGPT, and other LLMs
96 lines (94 loc) • 13.2 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { unescape } from 'lodash';
import queryString from 'query-string';
import z from 'zod';
import { BaseTranslator } from '../BaseTranslator';
import { getYandexSID } from './getYandexSID';
export class YandexTranslator extends BaseTranslator {
static isSupportedAutoFrom() {
return true;
}
static getSupportedLanguages() {
// Supported, but not valid languages ['mhr', 'pap', 'ceb', 'mrj', 'udm']
// eslint-disable
// prettier-ignore
return [
'af', 'am', 'ar', 'az', 'ba', 'be', 'bg', 'bn', 'bs', 'ca',
'ceb', 'cs', 'cv', 'cy', 'da', 'de', 'el', 'emj', 'en', 'eo',
'es', 'et', 'eu', 'fa', 'fi', 'fr', 'ga', 'gd', 'gl', 'gu',
'he', 'hi', 'hr', 'ht', 'hu', 'hy', 'id', 'is', 'it', 'ja',
'jv', 'ka', 'kazlat', 'kk', 'km', 'kn', 'ko', 'ky', 'la', 'lb',
'lo', 'lt', 'lv', 'mg', 'mhr', 'mi', 'mk', 'ml', 'mn', 'mr',
'mrj', 'ms', 'mt', 'my', 'ne', 'nl', 'no', 'pa', 'pap', 'pl',
'pt', 'ro', 'ru', 'sah', 'si', 'sjn', 'sk', 'sl', 'sq', 'sr',
'su', 'sv', 'sw', 'ta', 'te', 'tg', 'th', 'tl', 'tr', 'tt',
'udm', 'uk', 'ur', 'uz', 'uzbcyr', 'vi', 'xh', 'yi', 'zh', 'zu'
];
// eslint-enable
}
getLengthLimit() {
return 4000;
}
getRequestsTimeout() {
return 500;
}
checkLimitExceeding(text) {
if (Array.isArray(text)) {
const arrayLen = text.reduce((acc, text) => acc + text.length, 0);
const extra = arrayLen - this.getLengthLimit();
return extra > 0 ? extra : 0;
}
else {
const extra = text.length - this.getLengthLimit();
return extra > 0 ? extra : 0;
}
}
translate(text, from, to) {
return __awaiter(this, void 0, void 0, function* () {
return this.translateBatch([text], from, to).then((resp) => resp[0]);
});
}
translateBatch(text, from, to) {
return __awaiter(this, void 0, void 0, function* () {
const sid = yield getYandexSID(this.fetch);
if (sid === null) {
throw new Error('Invalid SID');
}
const options = {
format: 'html',
lang: from === 'auto' ? to : `${from}-${to}`,
};
let body = queryString.stringify(options);
for (const textChunk of text) {
body += '&text=' + encodeURIComponent(textChunk);
}
// NOTE: if service will resist and will not work, it may check order of headers, parameters and requests
// in this case just make requests less specific to it looks like requests from typical page (with overhead requests if require)
const urlWithSid = 'https://translate.yandex.net/api/v1/tr.json/translate?srv=tr-url-widget&id=' +
sid +
'-0-0&';
return this.fetch(urlWithSid + body, {
responseType: 'json',
method: 'GET',
headers: Object.assign({ 'Content-Type': 'application/x-www-form-urlencoded' }, this.options.headers),
}).then((response) => {
const data = z
.object({
text: z.string().array(),
})
.parse(response.data);
return data.text.map((text) => unescape(text));
});
});
}
}
YandexTranslator.translatorName = 'YandexTranslator';
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRyYW5zbGF0b3JzL1lhbmRleFRyYW5zbGF0b3IvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUNsQyxPQUFPLFdBQVcsTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDO0FBRXBCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFOUMsTUFBTSxPQUFPLGdCQUFpQixTQUFRLGNBQWM7SUFHNUMsTUFBTSxDQUFDLG1CQUFtQjtRQUNoQyxPQUFPLElBQUksQ0FBQztJQUNiLENBQUM7SUFFTSxNQUFNLENBQUMscUJBQXFCO1FBQ2xDLHlFQUF5RTtRQUV6RSxpQkFBaUI7UUFDakIsa0JBQWtCO1FBQ2xCLE9BQU87WUFDTixJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJO1lBQzFELEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUk7WUFDNUQsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSTtZQUMxRCxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJO1lBQzFELElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxJQUFJLEVB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QkFDOUIsSUFBSSxJQUFJLFFBQVEsR0FBRyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNsRCxDQUFDO1lBRUQseUdBQXlHO1lBQ3pHLGdJQUFnSTtZQUNoSSxNQUFNLFVBQVUsR0FDZiw2RUFBNkU7Z0JBQzdFLEdBQUc7Z0JBQ0gsT0FBTyxDQUFDO1lBQ1QsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRyxJQUFJLEVBQUU7Z0JBQ3BDLFlBQVksRUFBRSxNQUFNO2dCQUNwQixNQUFNLEVBQUUsS0FBSztnQkFDYixPQUFPLGtCQUNOLGNBQWMsRUFBRSxtQ0FBbUMsSUFDaEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQ3ZCO2FBQ0QsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFO2dCQUNwQixNQUFNLElBQUksR0FBRyxDQUFDO3FCQUNaLE1BQU0sQ0FBQztvQkFDUCxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRTtpQkFDeEIsQ0FBQztxQkFDRCxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUV2QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNoRCxDQUFDLENBQUMsQ0FBQztRQUNKLENBQUM7S0FBQTs7QUF2RnNCLCtCQUFjLEdBQUcsa0JBQWtCLENBQUMiLCJmaWxlIjoidHJhbnNsYXRvcnMvWWFuZGV4VHJhbnNsYXRvci9pbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHVuZXNjYXBlIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBxdWVyeVN0cmluZyBmcm9tICdxdWVyeS1zdHJpbmcnO1xuaW1wb3J0IHogZnJvbSAnem9kJztcblxuaW1wb3J0IHsgQmFzZVRyYW5zbGF0b3IgfSBmcm9tICcuLi9CYXNlVHJhbnNsYXRvcic7XG5pbXBvcnQgeyBnZXRZYW5kZXhTSUQgfSBmcm9tICcuL2dldFlhbmRleFNJRCc7XG5cbmV4cG9ydCBjbGFzcyBZYW5kZXhUcmFuc2xhdG9yIGV4dGVuZHMgQmFzZVRyYW5zbGF0b3Ige1xuXHRwdWJsaWMgc3RhdGljIHJlYWRvbmx5IHRyYW5zbGF0b3JOYW1lID0gJ1lhbmRleFRyYW5zbGF0b3InO1xuXG5cdHB1YmxpYyBzdGF0aWMgaXNTdXBwb3J0ZWRBdXRvRnJvbSgpIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdHB1YmxpYyBzdGF0aWMgZ2V0U3VwcG9ydGVkTGFuZ3VhZ2VzKCk6IHN0cmluZ1tdIHtcblx0XHQvLyBTdXBwb3J0ZWQsIGJ1dCBub3QgdmFsaWQgbGFuZ3VhZ2VzIFsnbWhyJywgJ3BhcCcsICdjZWInLCAnbXJqJywgJ3VkbSddXG5cblx0XHQvLyBlc2xpbnQtZGlzYWJsZVxuXHRcdC8vIHByZXR0aWVyLWlnbm9yZVxuXHRcdHJldHVybiBbXG5cdFx0XHQnYWYnLCAnYW0nLCAnYXInLCAnYXonLCAnYmEnLCAnYmUnLCAnYmcnLCAnYm4nLCAnYnMnLCAnY2EnLFxuXHRcdFx0J2NlYicsICdjcycsICdjdicsICdjeScsICdkYScsICdkZScsICdlbCcsICdlbWonLCAnZW4nLCAnZW8nLFxuXHRcdFx0J2VzJywgJ2V0JywgJ2V1JywgJ2ZhJywgJ2ZpJywgJ2ZyJywgJ2dhJywgJ2dkJywgJ2dsJywgJ2d1Jyxcblx0XHRcdCdoZScsICdoaScsICdocicsICdodCcsICdodScsICdoeScsICdpZCcsICdpcycsICdpdCcsICdqYScsXG5cdFx0XHQnanYnLCAna2EnLCAna2F6bGF0JywgJ2trJywgJ2ttJywgJ2tuJywgJ2tvJywgJ2t5JywgJ2xhJywgJ2xiJyxcblx0XHRcdCdsbycsICdsdCcsICdsdicsICdtZycsICdtaHInLCAnbWknLCAnbWsnLCAnbWwnLCAnbW4nLCAnbXInLFxuXHRcdFx0J21yaicsICdtcycsICdtdCcsICdteScsICduZScsICdubCcsICdubycsICdwYScsICdwYXAnLCAncGwnLFxuXHRcdFx0J3B0JywgJ3JvJywgJ3J1JywgJ3NhaCcsICdzaScsICdzam4nLCAnc2snLCAnc2wnLCAnc3EnLCAnc3InLFxuXHRcdFx0J3N1JywgJ3N2JywgJ3N3JywgJ3RhJywgJ3RlJywgJ3RnJywgJ3RoJywgJ3RsJywgJ3RyJywgJ3R0Jyxcblx0XHRcdCd1ZG0nLCAndWsnLCAndXInLCAndXonLCAndXpiY3lyJywgJ3ZpJywgJ3hoJywgJ3lpJywgJ3poJywgJ3p1J1xuXHRcdF07XG5cdFx0Ly8gZXNsaW50LWVuYWJsZVxuXHR9XG5cblx0cHVibGljIGdldExlbmd0aExpbWl0KCkge1xuXHRcdHJldHVybiA0MDAwO1xuXHR9XG5cblx0cHVibGljIGdldFJlcXVlc3RzVGltZW91dCgpIHtcblx0XHRyZXR1cm4gNTAwO1xuXHR9XG5cblx0cHVibGljIGNoZWNrTGltaXRFeGNlZWRpbmcodGV4dDogc3RyaW5nIHwgc3RyaW5nW10pIHtcblx0XHRpZiAoQXJyYXkuaXNBcnJheSh0ZXh0KSkge1xuXHRcdFx0Y29uc3QgYXJyYXlMZW4gPSB0ZXh0LnJlZHVjZSgoYWNjLCB0ZXh0KSA9PiBhY2MgKyB0ZXh0Lmxlbmd0aCwgMCk7XG5cdFx0XHRjb25zdCBleHRyYSA9IGFycmF5TGVuIC0gdGhpcy5nZXRMZW5ndGhMaW1pdCgpO1xuXHRcdFx0cmV0dXJuIGV4dHJhID4gMCA/IGV4dHJhIDogMDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3QgZXh0cmEgPSB0ZXh0Lmxlbmd0aCAtIHRoaXMuZ2V0TGVuZ3RoTGltaXQoKTtcblx0XHRcdHJldHVybiBleHRyYSA+IDAgPyBleHRyYSA6IDA7XG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGFzeW5jIHRyYW5zbGF0ZSh0ZXh0OiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZykge1xuXHRcdHJldHVybiB0aGlzLnRyYW5zbGF0ZUJhdGNoKFt0ZXh0XSwgZnJvbSwgdG8pLnRoZW4oKHJlc3ApID0+IHJlc3BbMF0pO1xuXHR9XG5cblx0cHVibGljIGFzeW5jIHRyYW5zbGF0ZUJhdGNoKHRleHQ6IHN0cmluZ1tdLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpIHtcblx0XHRjb25zdCBzaWQgPSBhd2FpdCBnZXRZYW5kZXhTSUQodGhpcy5mZXRjaCk7XG5cdFx0aWYgKHNpZCA9PT0gbnVsbCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFNJRCcpO1xuXHRcdH1cblxuXHRcdGNvbnN0IG9wdGlvbnMgPSB7XG5cdFx0XHRmb3JtYXQ6ICdodG1sJyxcblx0XHRcdGxhbmc6IGZyb20gPT09ICdhdXRvJyA/IHRvIDogYCR7ZnJvbX0tJHt0b31gLFxuXHRcdH07XG5cblx0XHRsZXQgYm9keSA9IHF1ZXJ5U3RyaW5nLnN0cmluZ2lmeShvcHRpb25zKTtcblx0XHRmb3IgKGNvbnN0IHRleHRDaHVuayBvZiB0ZXh0KSB7XG5cdFx0XHRib2R5ICs9ICcmdGV4dD0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHRleHRDaHVuayk7XG5cdFx0fVxuXG5cdFx0Ly8gTk9URTogaWYgc2VydmljZSB3aWxsIHJlc2lzdCBhbmQgd2lsbCBub3Qgd29yaywgaXQgbWF5IGNoZWNrIG9yZGVyIG9mIGhlYWRlcnMsIHBhcmFtZXRlcnMgYW5kIHJlcXVlc3RzXG5cdFx0Ly8gaW4gdGhpcyBjYXNlIGp1c3QgbWFrZSByZXF1ZXN0cyBsZXNzIHNwZWNpZmljIHRvIGl0IGxvb2tzIGxpa2UgcmVxdWVzdHMgZnJvbSB0eXBpY2FsIHBhZ2UgKHdpdGggb3ZlcmhlYWQgcmVxdWVzdHMgaWYgcmVxdWlyZSlcblx0XHRjb25zdCB1cmxXaXRoU2lkID1cblx0XHRcdCdodHRwczovL3RyYW5zbGF0ZS55YW5kZXgubmV0L2FwaS92MS90ci5qc29uL3RyYW5zbGF0ZT9zcnY9dHItdXJsLXdpZGdldCZpZD0nICtcblx0XHRcdHNpZCArXG5cdFx0XHQnLTAtMCYnO1xuXHRcdHJldHVybiB0aGlzLmZldGNoKHVybFdpdGhTaWQgKyBib2R5LCB7XG5cdFx0XHRyZXNwb25zZVR5cGU6ICdqc29uJyxcblx0XHRcdG1ldGhvZDogJ0dFVCcsXG5cdFx0XHRoZWFkZXJzOiB7XG5cdFx0XHRcdCdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxcblx0XHRcdFx0Li4udGhpcy5vcHRpb25zLmhlYWRlcnMsXG5cdFx0XHR9LFxuXHRcdH0pLnRoZW4oKHJlc3BvbnNlKSA9PiB7XG5cdFx0XHRjb25zdCBkYXRhID0gelxuXHRcdFx0XHQub2JqZWN0KHtcblx0XHRcdFx0XHR0ZXh0OiB6LnN0cmluZygpLmFycmF5KCksXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5wYXJzZShyZXNwb25zZS5kYXRhKTtcblxuXHRcdFx0cmV0dXJuIGRhdGEudGV4dC5tYXAoKHRleHQpID0+IHVuZXNjYXBlKHRleHQpKTtcblx0XHR9KTtcblx0fVxufVxuIl19