deeplcom / deepl-node Goto Github PK
View Code? Open in Web Editor NEWOfficial Node.js library for the DeepL language translation API.
License: MIT License
Official Node.js library for the DeepL language translation API.
License: MIT License
Version used by deepl-node has vulnerabilities and should be updated
This library cannot be used in cloudflare workers because it depends on XMLHttpRequest.
Moreover, if I send requests manually they fail with status code 525.
Code to reproduce
const deepLUrl = 'https://api-free.deepl.com/v2/translate'
const text = 'I like my cat'
const to = 'de'
const from = 'en'
const resp = await fetch(deepLUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `DeepL-Auth-Key ${env.DEEPL}`,
},
body: `text=${encodeURIComponent(text)}&target_lang=${to.toUpperCase()}&source_lang=${from.toUpperCase()}`,
})
if (!resp.ok) throw new Error(`DeepL error (${resp.status}) ` + resp.statusText) // throws in workers
const response = await resp.json()
response.translations[0].text // works in node
This problem is often mentioned in cloudflare community (example). According to cloudflare "This is typically caused by a configuration issue in the origin web server".
Is there any hope for a fix? Cloudflare workers become more and more popular nowadays.
I need to detect source language of word "Insomnia". When i use deepl-node package, i got source language Slovak(sk). When i use Deepl on site translator i got, when i typed "Insomnia", English language detection.
today autotranslate does not work, until yesterday it worked fine, today the language detected is the same as the target language
We are found when we test to use deepl-node packages in our mobile app.
Package download link..
deepl-node - npm (npmjs.com)
Our app is based on react-native language.
We just use sample code and connection tests with deepl server.
Found err info:
[TypeError: Cannot read property 'prototype' of undefined]
createGlossaryFromCsv
method does not exist in deepl-node
but there is createGlossaryWithCsv
instead.
Hi , I have recently subscribed on Deepl Pro Advanced plan. I am trying to use deepl-node package: https://github.com/DeepLcom/deepl-node
However i get the following error : AuthorizationError: Authorization failure, check auth_key, message: Wrong endpoint. Use https://api.deepl.com
at checkStatusCode
I tried creating a new authentication key and I tried with it but no chance.I was wondering if you could help me, please?
Describe the bug
For all languages in the getSourceLanguages call an empty 'supportyFormality' field is returned, this should be omitted.
{ name: 'Bulgarian', code: 'bg', supportsFormality: undefined },
{ name: 'Czech', code: 'cs', supportsFormality: undefined },
{ name: 'Danish', code: 'da', supportsFormality: undefined },
{ name: 'German', code: 'de', supportsFormality: undefined },
To Reproduce
use translator.getSourceLanguages()
Expected behavior
undefined fields should be omited
https://github.com/DeepLcom/deepl-node/blob/main/src/types.ts#L168 is missing 'ar' which is supported by DeepL.
Hi there, thanks for the great library to use the DeepL API!
I made a github action for using deepl-node to translate text documents, however there's quite a lot of limitations in trying to parse markdown elements.
You can refer to some limitations that's mentioned in this demo or this PR.
The formatting errors that were raised in both examples may be due to the use of markdown checkboxes, bolded text etc, since most other HTML elements were able to be translated accurately, and only break on certain languages.
The contributors file said that would-be contributors should open an issue for suggested features instead of just jumping straight into making a pull request. I'm using the bug template because there is no feature template.
Generate a translated HTML document based off of the URL for a webpage. The following code snippet would translate the page for DeepL's English Wikipedia article into German and save it in the file DeepLWiki.html:
await translator.translateWebpageToDocument(
'https://en.wikipedia.org/wiki/DeepL_Translator',
'DeepLWiki.html',
'en',
'de',
{ formality: 'more' },
);
In line with the other document related functions, there can be an uploadWebpageToDocument
function that takes a URL as the first argument with the rest of its arguments being the same as uploadDocument
. getDocumentStatus
and downloadDocument
would not need their own versions as uploadWebpageToDocument
would return a DocumentHandle
like uploadDocument
does.
Without writing the exact code, I think uploadWebpageToDocument
would first make a request to the URL that's passed in as an argument. If the request is successful and the response has it's Content-Type
header set text/html
, the response HTML gets put into a buffer and passed to uploadDocument
along with the rest of the parameters. If the request to the website fails or the response is not the expected mime type, the function throws an error.
Describe the bug
Since we updated to version node-deepl to version 1.13.0, and follow-redirects 1.15.6 (because of a security update) we've seen an increasing number of errors of the type "socket hang up". We've never seen this error before.
node_modules/axios/dist/node/axios.cjs:836:14 in AxiosError.from
node_modules/axios/dist/node/axios.cjs:3086:25 in RedirectableRequest.handleRequestError
node:events:539:35 in RedirectableRequest.emit
node_modules/follow-redirects/index.js:38:24 in eventHandlers.<computed>
node:events:527:28 in ClientRequest.emit
node:_http_client:478:9 in TLSSocket.socketOnEnd
node:events:539:35 in TLSSocket.emit
node:internal/streams/readable:1344:12 in endReadableNT
node:internal/process/task_queues:82:21 in process.processTicksAndRejections
node_modules/axios/dist/node/axios.cjs:3876:41 in Axios.request
node:internal/process/task_queues:95:5 in process.processTicksAndRejections
node_modules/deepl-node/dist/client.js:180:30 in async Function.sendAxiosRequest
node_modules/deepl-node/dist/client.js:143:28 in async HttpClient.sendRequestWithBackoff
node_modules/deepl-node/dist/index.js:363:41 in async Translator.translateText
To Reproduce
We haven't found a way to reproduce.
Expected behavior
Do not fail with "socket hang up", maybe another error more descriptive.
Additional info
The update of follow-redirects was because this security update:
Bump follow-redirects from 1.15.4 to 1.15.6 (#161) Bumps follow-redirects from 1.15.4 to 1.15.6. - Release notes - Commits
Describe the bug
When translating strings that contains square brackets it doesn't work well. It duplicates the content and removes the first bracket.
It's also happening in the web version.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
[1s] [1s] [1s] [1s] [1s]
Screenshots
I become this error when i initialise the repository
Uncaught TypeError: os.type is not a function
at Translator.constructUserAgentString (deepl-node.js?v=e2e7fb1a:3446:33)
at new Translator (deepl-node.js?v=e2e7fb1a:3116:30)
at main.js:8:20
constructUserAgentString @ deepl-node.js?v=e2e7fb1a:3446
Translator @ deepl-node.js?v=e2e7fb1a:3116
(anonym) @ main.js:8
Currently, a request that specifies a formality setting not yet supported by DeepL returns an error without a translation.
DeepLError: Bad request, message: 'formality' is not supported for given 'target_lang'.
Maybe a more user friendly alternative would be to just ignore any unsupported options in the request, possibly attaching a warning message to the response informing the user of their mistake. This way, applications that call the DeepL api won't break when supplied an invalid configuration.
If axios
v1.2.0 is used, the following error can occur when calling many library functions (e.g. getUsage()
):
DeepLError: Error parsing response JSON: SyntaxError: Unexpected token in JSON at position 0
We have released v1.7.2 as a workaround: this updates the dependency requirement to disallow version axios v1.2.0, and are working on a fix.
Describe the bug
When building my Svelte app that uses deepl-node, I get a warning about circular dependencies:
Circular dependency: node_modules/.pnpm/[email protected]/node_modules/deepl-node/dist/index.js -> node_modules/.pnpm/[email protected]/node_modules/deepl-node/dist/parsing.js -> node_modules/.pnpm/[email protected]/node_modules/deepl-node/dist/index.js
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The warning not to appear by refactoring your code
Desktop (please complete the following information):
Describe the bug
I am translating a text using Deepl API that contains XML tags and some of these tags include custom attributes; ex.
That’s the <fontcolor="#007af2">timer</fontcolor>! It measures the time you spend in a module OR the time you have left to complete a challenge!
However, the format of the XML tag is not conserved when the text is translated to Slovenian and Italian (I have not tested in other languages but could be the case for others as well). The result is like this:
Slovenian: To je časovnik <fontcolor="#007af2"></fontcolor> ! Meri čas, ki ga porabite v modulu, ALI čas, ki vam je ostal do konca izziva!
Italian: Questo è il timer <fontcolor="#007af2"></fontcolor> ! Misura il tempo trascorso in un modulo O il tempo rimasto per completare una sfida!
Meaning that instead of putting the word timer
inside the tag, it gets out and leaves the tag empty. This happens when the tagHandling
option is set to either XML
or HTML
, however if I set the tagHandling
to off
, the result is OK but other problems occur for my text because the tagHandling
is set to off
.
To Reproduce
Steps to reproduce the behavior:
Can be reproduced in the Deepl API Simulator: https://www.deepl.com/en/docs-api/simulator/
That’s the <fontcolor="#007af2">timer</fontcolor>! It measures the time you spend in a module OR the time you have left to complete a challenge!
in the Text field.Expected behavior
The correct text should be:
Slovenian: To je <fontcolor="#007af2">časomer</fontcolor>! Meri čas, ki ga porabite v modulu, ALI čas, ki vam je ostal za dokončanje izziva!
Italian: È il <fontcolor="#007af2">timer</fontcolor>! Misura il tempo trascorso in un modulo O il tempo rimanente per completare una sfida!
Which is the case when the tagHandling
is set to off
but that should not be the case.
What has been tested
I tried combining different options together to see if I can make it work but none of them gave me the intended result. These are the parameters that I changed:
SentenceSplitting=on,off,noNewLines
preserveFormatting=on,off
nonSplittingTags=fontcolor,null
UPDATE 07/10/2023 11:47 AM
The problem seems to be the fact that the API takes into account the ="#007af2"
part of the tag as the name of the tag and it doesn't see the closing tag for the same thing. So if we add a space: <fontcolor "=#007af2">
, it will work as expected. I don't know if a fix for that would be necessary but maybe a support for custom attributes like this would be nice.
When using the translator in the website we are able to get alternatives along with the translated phrase. For example I'm translating the word friend
into Czech language and I'm getting the following result:
When using deepl-node
API I'm only getting a single string in return which seems to be the original translation. Is it possible to get a translation response including these alternatives ? If not, why not ?
Thanks
I'm trying to implement this package while using webpack, and each time there always seems to be a new problem. Is it just not possible to use deepl-node with webpack?
I think there is only portuguese as SourceLanguageCode
and not PT_BR 😢
Describe the bug
A clear and concise description of what the bug is.
Since DeepL API does not understand text in multiple lines, I query just like below. encodeURIComponent()
is a solution that I was actually suggested by DeepL support.
const inputText = encodeURIComponent(translateText);
const responseDeepL = await axios.post(
deeplURL,
`text=${inputText}&target_lang=${targetLang}`,
{
headers: {
Authorization: `DeepL-Auth-Key ${DEEPL_KEY}`,
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "axios 1.2.0-alpha.1",
},
}
);
The problem is the volume of string becomes way larger than the original input.
For example,
const inputText = "こんにちは";
console.log( encodeURIComponent(inputText).length ) // this is 45 characters
console.log( inputText.length ) // this is 5 characters
Describe the bug
See fix in jest: jestjs/jest#13414
Unfortunately, this version of Jest (29.2+) requires Node 14.
To Reproduce
In the console, running tests may give a warning similar to the following
$ node_modules/.bin/jest --detectOpenHandles --no-cache tests/
PASS tests/general.test.ts
PASS tests/glossary.test.ts (24.288 s)
PASS tests/translateDocument.test.ts (31.975 s)
PASS tests/translateText.test.ts (6.858 s)
Test Suites: 4 passed, 4 total
Tests: 11 skipped, 50 passed, 61 total
Snapshots: 0 total
Time: 66.442 s
Ran all test suites matching /tests\//i.
Jest has detected the following 2 open handles potentially keeping Jest from exiting:
● TLSWRAP
220 | ): Promise<{ statusCode: number; content: TContent }> {
221 | try {
> 222 | const response = await axios.request(axiosRequestConfig);
| ^
223 |
224 | if (axiosRequestConfig.responseType === 'text') {
225 | // Workaround for axios-bug: https://github.com/axios/axios/issues/907
at node_modules/nock/lib/intercept.js:427:16
at Object.module.request (node_modules/nock/lib/common.js:96:14)
at RedirectableRequest.Object.<anonymous>.RedirectableRequest._performRequest (node_modules/follow-redirects/index.js:284:24)
at new RedirectableRequest (node_modules/follow-redirects/index.js:66:8)
at Object.request (node_modules/follow-redirects/index.js:523:14)
at dispatchHttpRequest (node_modules/axios/lib/adapters/http.js:436:21)
at node_modules/axios/lib/adapters/http.js:143:5
at wrapAsync (node_modules/axios/lib/adapters/http.js:123:10)
at http (node_modules/axios/lib/adapters/http.js:149:10)
at Axios.dispatchRequest (node_modules/axios/lib/core/dispatchRequest.js:51:10)
at Axios.request (node_modules/axios/lib/core/Axios.js:148:33)
at Function.wrap [as request] (node_modules/axios/lib/helpers/bind.js:5:15)
at Function.sendAxiosRequest (src/client.ts:222:42)
at HttpClient.sendRequestWithBackoff (src/client.ts:176:45)
at Translator.translateText (src/index.ts:571:63)
at Object.<anonymous> (tests/translateText.test.ts:19:41)
at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)
at runJest (node_modules/@jest/core/build/runJest.js:404:19)
at _run10000 (node_modules/@jest/core/build/cli/index.js:320:7)
at runCLI (node_modules/@jest/core/build/cli/index.js:173:3)
● TLSWRAP
220 | ): Promise<{ statusCode: number; content: TContent }> {
221 | try {
> 222 | const response = await axios.request(axiosRequestConfig);
| ^
223 |
224 | if (axiosRequestConfig.responseType === 'text') {
225 | // Workaround for axios-bug: https://github.com/axios/axios/issues/907
at node_modules/nock/lib/intercept.js:427:16
at Object.module.request (node_modules/nock/lib/common.js:96:14)
at RedirectableRequest.Object.<anonymous>.RedirectableRequest._performRequest (node_modules/follow-redirects/index.js:284:24)
at new RedirectableRequest (node_modules/follow-redirects/index.js:66:8)
at Object.request (node_modules/follow-redirects/index.js:523:14)
at dispatchHttpRequest (node_modules/axios/lib/adapters/http.js:436:21)
at node_modules/axios/lib/adapters/http.js:143:5
at wrapAsync (node_modules/axios/lib/adapters/http.js:123:10)
at http (node_modules/axios/lib/adapters/http.js:149:10)
at Axios.dispatchRequest (node_modules/axios/lib/core/dispatchRequest.js:51:10)
at Axios.request (node_modules/axios/lib/core/Axios.js:148:33)
at Function.wrap [as request] (node_modules/axios/lib/helpers/bind.js:5:15)
at Function.sendAxiosRequest (src/client.ts:222:42)
at HttpClient.sendRequestWithBackoff (src/client.ts:176:45)
at Translator.translateText (src/index.ts:571:63)
at Object.<anonymous> (tests/translateText.test.ts:221:41)
at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)
at runJest (node_modules/@jest/core/build/runJest.js:404:19)
at _run10000 (node_modules/@jest/core/build/cli/index.js:320:7)
at runCLI (node_modules/@jest/core/build/cli/index.js:173:3)
Expected behavior
Tests should run without throwing warnings.
Describe the bug
A clear and concise description of what the bug is.
[Type error]: I input the target language (string) but deepl.TargetLanguageCode does not allow it.
const defaultLang = "ja";
let typedTargetLang: deepl.TargetLanguageCode = defaultLang;
Type 'string' is not assignable to type 'TargetLanguageCode'.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
Add any other context about the problem here.
Hi, i am trying to integrate deepl-node with my react native app but i keep getting this error after following the installation steps
error message:
iOS Bundling failed 232ms
Unable to resolve module fs from C:\Users\oem\Desktop\Reway\Reway-App-Dev\node_modules\deepl-node\dist\index.js: fs could not be found within the project or in these directories:
node_modules
39 | const parsing_1 = require("./parsing");
40 | const utils_1 = require("./utils");
41 | const fs = __importStar(require("fs"));
| ^
42 | const http_1 = require("http");
43 | const path_1 = __importDefault(require("path"));
44 | const url_1 = require("url");
Describe the bug
When translating a English text with HTML elements to French, the response contains unexpected additional HTML Tags and often a full sentence that was not in the input.
To Reproduce
Minimal JS Script to reproduce the Error (last tested on March 9th 2024 6PM CET)
const deepl = require('deepl-node')
const authKey = "<authkey>"
const translator = new deepl.Translator(authKey)
async function translate(targetLang) {
const result = await translator.translateText('<p><strong>Testing the system</strong></p>', 'en', targetLang, tag_handling = 'html')
console.log(result)
}
translate('de')
translate('fr')
This results in the following responses:
{
text: '<p><strong>Test des Systems</strong></p>',
detectedSourceLang: 'en'
}
{
text: "</p><strong>Tester le système</strong></p><strong></p><strong>La mise en place d'un système de gestion de l'information est une priorité.",
detectedSourceLang: 'en'
}
The German translation is correct but the French translation has <strong></p><strong>La mise en place d'un système de gestion de l'information est une priorité.
appended to a seemingly correct result.
I've noticed that without the <strong>
Tag it does not happen but I have not tested that exhaustively.
Thank you very much.
This is not really an issue, but rather a question, and possibly feature request.
Would it be possible to have some kind of temporary glossaries, that you could pass as an argument in a translate request, without having to create a glossary?
To give a more precise example, here is my use case:
I am building a translation tool that would allow automatically translating strings from one language to a bunch of other languages.
Those strings may contain parameters (something like The count is [count].
).
Sometimes, the translation result will rightly place the parameter like a word in a sentence, keeping its original form.
Sometimes it will also translate the parameter's name.
I would like to keep the original parameter name, without creating a glossary that would hold values on your side, when I only need them once.
This is admittedly much more complex than just a stipped-down glossary feature, but that would already be a start.
I hope you were able to understand my thoughts and hope this is somewhat usable feedback, but I am completly aware of its complexity and would not be surprised if it never finds its way onto future updates.
Also I apologize for my english if you didn't understand everything, I'm not a native speaker and I try not to use Deepl but to talk by myself as much as I can (ironically haha).
Hello,
I am utilizing the PRO Deepl API and have encountered some challenges related to concurrent requests while using the Deepl-Node client.
Here's the scenario: I have a service hosted on Azure, leveraging Azure Functions. Within this setup, there are 15 concurrent functions that attempt to translate a total of 72 KiB of text. The translateText<string[]>
function takes an array of strings as input. The interesting aspect is that when these 15 functions are triggered, I encounter 'timeout' errors for all the requests. It's important to note that all these functions run on the same Virtual Machine, which implies that a single Deepl Client is employed to handle these 15 concurrent requests.
My questions are as follows:
Your insights and guidance on optimizing these concurrent translation calls would be greatly appreciated. The service aim to translate ~1 000 000 000 characters.
Please be aware that the translation process functions correctly when a single request is made. This singular request encompasses the following elements:
An array input containing 600 texts (It is noteworthy to mention that the documentation indicates a limit of 50 texts per request.)
A maximum of 72 KiB of text, equating to a request payload of approximately 76 KiB (It is important to acknowledge that the documentation specifies a payload size allowance of up to 128 KiB. However, I have observed that if the payload size exceeds 85 KiB, it results in a '413 - Payload Too Large' error).
Could you provide more information regarding the limits documented?
Describe the bug
All requests result in the following error:
C:\Projects\ext\translate-doc\node_modules\deepl-node\dist\client.js:163
const error = new errors_1.ConnectionError(`Connection failure: ${message}`);
^
ConnectionError: Connection failure: write EPROTO 98720000:error:0A000152:SSL routines:final_renegotiate:unsafe legacy renegotiation disabled:c:\ws\de
ps\openssl\openssl\ssl\statem\extensions.c:922:
at HttpClient.sendAxiosRequest (C:\Projects\ext\translate-doc\node_modules\deepl-node\dist\client.js:163:27)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async HttpClient.sendRequestWithBackoff (C:\Projects\ext\translate-doc\node_modules\deepl-node\dist\client.js:114:28)
at async Translator.translateText (C:\Projects\ext\translate-doc\node_modules\deepl-node\dist\index.js:355:41)
at async file:///C:/Projects/ext/translate-doc/index.js:7:20 {
error: AxiosError: write EPROTO 98720000:error:0A000152:SSL routines:final_renegotiate:unsafe legacy renegotiation disabled:c:\ws\deps\openssl\opens
sl\ssl\statem\extensions.c:922:
at AxiosError.from (C:\Projects\ext\translate-doc\node_modules\axios\dist\node\axios.cjs:836:14)
at RedirectableRequest.handleRequestError (C:\Projects\ext\translate-doc\node_modules\axios\dist\node\axios.cjs:3010:25)
at RedirectableRequest.emit (node:events:525:35)
at eventHandlers.<computed> (C:\Projects\ext\translate-doc\node_modules\follow-redirects\index.js:14:24)
at ClientRequest.emit (node:events:513:28)
at TLSSocket.socketErrorListener (node:_http_client:502:9)
at TLSSocket.emit (node:events:513:28)
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
The underlying issue is probably the following: https://stackoverflow.com/questions/74324019/allow-legacy-renegotiation-for-nodejs
This only occurs on Node 17+.
To Reproduce
npm init
with index.js
npm install deepl-node
node index.js
Expected behavior
The translation is logged to the console
Desktop
The options parameter of the Translator constructor only takes one type of proxy as ProxyConfig
(looks same as AxiosProxyConfig
).
It would be useful to be able to use a proxy URL string as proxy parameter. An axios instance creation in the client should look like this:
import { HttpProxyAgent, HttpProxyAgent } from 'hpagent';
axios.create({
proxy: true,
httpsAgent: new HttpsProxyAgent({ proxy: 'http://user:[email protected]:4567' })
httpAgent: new HttpProxyAgent({ proxy: 'http://user:[email protected]:4567' })
})
Would it be an improvement in flexibility?
I always use one secret for the whole proxy URL, so it would help a lot.
The most flexible approach would be to have an axiosInstanace
parameter for the Translator constructor, but this would cause a lot of code rewrites :(
Describe the bug
When using the latest version 1.13.0 of the Deepl NodeJS lib I notice an issue with XML tags.
When using source text Please start your '<x id=p1>Basic</x>' plan by clicking the button '<x id=p2>Accept</x>'.
, the translation gets different syntax around the <x></x>
tags.
To Reproduce
Steps to reproduce the behavior:
const result = await translator.translateText("Please start your '<x id=p1>Basic</x>' plan by clicking the button '<x id=p2>Accept</x>'.", "en", "de", { tagHandling: 'xml' });
Bitte starten Sie Ihren<x id=p1>'Basic</x>'-Plan, indem Sie auf die Schaltfläche<x id=p2>'Akzeptieren</x>' klicken.
'<x id=p1>Basic</x>'
, while in the German output the opening quote is moved within the tags: <x id=p1>'Basic</x>'
❌your '<x id=p1>Basic</x>'
, while in the German output the opening tag is directly concatenated to the previous word: Ihren<x id=p1>'Basic</x>'
❌Bitte starten Sie Ihren '<x id=p1>Basic</x>'-Plan, indem Sie auf die Schaltfläche '<x id=p2>Akzeptieren</x>' klicken.
preserveFormatting: true
, outlineDetection: true
and nonSplittingTags: ['x']
, but each individual or all possible combinations provide the same German output string.Expected behavior
It's expected that formatting characters (like spaces) and other non-translatable characters (like quotes) around tags are maintained, especially when option preserveFormatting
is set to true
.
Update
After creating this post I did some more testing. It appears that the (single) quotes might be the issue. When using double quotes, the same issue occurs.
However, when removing the quotes around the XML tags:
const result = await translator.translateText("Please start your <x id=p1>Basic</x> plan by clicking the button <x id=p2>Accept</x>.", "en", "de", { tagHandling: 'xml' });
The output maintains the spaces around the tags ✅:
Bitte starten Sie Ihren <x id=p1>Basic-Plan</x>, indem Sie auf die Schaltfläche <x id=p2>Akzeptieren</x> klicken.
Update 2
After creating this post I noticed that I didn't use quotes for the value of attribute id
(see table "With Attributes" at https://developers.deepl.com/docs/xml-and-html-handling/xml). So basically my input string was malformed XML.
However, when applying quotes around p1
and p2
, the API still returns the same erroneous output:
const result = await translator.translateText("Please start your '<x id="p1">Basic</x>' plan by clicking the button '<x id="p2">Accept</x>'.", "en", "de", { tagHandling: 'xml' });
Question
Why doesn't the API handle quotes around XML tags properly?
Screenshots
N/A
Desktop (please complete the following information):
Additional context
I need to translate a lot of data, when i try to do translate in loop i got this error. How i can prevent this?
ConnectionError: Connection failure: socket hang up
at Function.sendAxiosRequest (/Users/matthew/IdeaProjects/backend/node_modules/deepl-node/dist/client.js:163:27)
at runMicrotasks ()
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async HttpClient.sendRequestWithBackoff (/Users/matthew/IdeaProjects/backend/node_modules/deepl-node/dist/client.js:114:28)
at async Translator.translateText (/Users/matthew/IdeaProjects/backend/node_modules/deepl-node/dist/index.js:354:41)
at async /Users/matthew/IdeaProjects/backend/lib/utils/formatDocsJSON.js:156:17
at async Promise.all (index 45)
at async /Users/matthew/IdeaProjects/backend/lib/utils/formatDocsJSON.js:140:16
at async Promise.all (index 3)
at async formatJsonFile (/Users/matthew/IdeaProjects/backend/lib/utils/formatDocsJSON.js:139:18)
at async main (/Users/matthew/IdeaProjects/backend/lib/utils/formatDocsJSON.js:34:5) {
error: AxiosError: socket hang up
at Function.AxiosError.from (/Users/matthew/IdeaProjects/backend/node_modules/axios/dist/node/axios.cjs:789:14)
at RedirectableRequest.handleRequestError (/Users/matthew/IdeaProjects/backend/node_modules/axios/dist/node/axios.cjs:2744:25)
at RedirectableRequest.emit (node:events:525:35)
at ClientRequest.eventHandlers. (/Users/matthew/IdeaProjects/backend/node_modules/follow-redirects/index.js:14:24)
at ClientRequest.emit (node:events:513:28)
at TLSSocket.socketOnEnd (node:_http_client:518:9)
at TLSSocket.emit (node:events:525:35)
at endReadableNT (node:internal/streams/readable:1358:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
code: 'ECONNRESET',
config: {
transitional: [Object],
adapter: [Array],
transformRequest: [Array],
transformResponse: [Array],
timeout: 20000,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: [Object],
validateStatus: null,
headers: [AxiosHeaders],
url: '/v2/translate',
method: 'post',
baseURL: 'https://api.deepl.com',
responseType: 'text',
data: 'target_lang=en-US&source_lang=de&text=Apikoaortales%2C+klappentragendes+Konduit'
},
request: Writable {
_writableState: [WritableState],
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 79,
_requestBodyBuffers: [Array],
_onNativeResponse: [Function (anonymous)],
_currentRequest: [ClientRequest],
_currentUrl: 'https://api.deepl.com/v2/translate',
_timeout: null,
[Symbol(kCapture)]: false
},
cause: Error: socket hang up
at connResetException (node:internal/errors:705:14)
at TLSSocket.socketOnEnd (node:_http_client:518:23)
at TLSSocket.emit (node:events:525:35)
at endReadableNT (node:internal/streams/readable:1358:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
code: 'ECONNRESET'
}
},
shouldRetry: false
}
This is my configutration deepl.Translator(config.deeplApiKey, { maxRetries: 50, minTimeout: 20000 });
Your definition of .translateText
runs into this canonically known typescript issue. It expects the language compiler to exhaustively perform a combinatorically expensive type casting which is not supported.
type TranslationText = string | string[];
const firstTextToTranslate: TranslationText = 'hello world';
const secondTextToTranslate: TranslationText = ['hello world'];
deepl.translateText(firstTextToTranslate, ...);
/* yields compiler error:
No overload matches this call.
Overload 1 of 2, '(texts: string, sourceLang: SourceLanguageCode | null, targetLang: TargetLanguageCode, options?: TranslateTextOptions | undefined): Promise<...>', gave the following error.
Argument of type 'string | string[]' is not assignable to parameter of type 'string'.
Type 'string[]' is not assignable to type 'string'.
Overload 2 of 2, '(texts: string[], sourceLang: SourceLanguageCode | null, targetLang: TargetLanguageCode, options?: TranslateTextOptions | undefined): Promise<...>', gave the following error.
Argument of type 'string | string[]' is not assignable to parameter of type 'string[]'.
Type 'string' is not assignable to type 'string[]'.ts(2769)
*/
// on the other hand...
deepl.translateText(secondTextToTranslate, ...);
/* yields the same compiler error: */
Typescript/your type definitions should be able to deduce that your function supports both types of inputs
As the Typescript team already made very clear that they are not planning to implement a combinatorically expensive feature, we have to work around this.
The typescript docs on conditional types state that overloading is unnecessary and your function definition could be done in a single, stable go with some generics and conditional types.
async translateText<T extends string | string[]>(
texts: T,
sourceLang: SourceLanguageCode | null,
targetLang: TargetLanguageCode,
options?: TranslateTextOptions,
): Promise<T extends string ? TextResult : TextResult[]>
Describe the bug
According to RFC1738 a HTTP URL takes the form of http://<host>:<port>/<path>?<searchpart>
.
When setting the serverUrl
in the TranslatorOptions
, it only replaces the host:port
part.
To Reproduce
Construct a new Translator:
const translator = new deepl.Translator(
process.env.DEEPL_API_KEY,
{
serverUrl: 'http://some-other-host.com/resource',
},
);
Translate something through this translator and the server at http://some-other-host.com
will receive POST /resource/v2/translate HTTP/1.1
.
Expected behavior
The option should replace the whole URL and not add its own path to the request.
Alternatively, it should be renamed to use the proper terminology, e.g. replaceHostAndPort
.
I have tried to use this library but when I run my code I get the following error in the browser console:
index.3240d547.js:10 Uncaught (in promise) TypeError: oe.URLSearchParams is not a constructor
at je (index.3240d547.js:10:69597)
at a.Translator.translateText (index.3240d547.js:10:73014)
at Le (index.3240d547.js:10:71558)
Desktop (please complete the following information):
Additional context
I'm using typescript and have no errors when I build my app - only when I run it. However, I'm not a professional programmer so it's possible I've installed the wrong version of something. My tsconfig.json file is below:
{
"compilerOptions": {
"lib": [
"es2021",
"dom"
],
"module": "commonjs",
"target": "es2021",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node"
}
}
and my package.json
{
"name": "logseq-deepl-integration",
"version": "0.0.1",
"description": "Translate selected blocks via deepl",
"main": "dist/index.html",
"targets": {
"main": false
},
"scripts": {
"build": "parcel build --no-source-maps index.html --public-url ./",
"dev": "parcel build --no-optimize index.html --public-url ./"
},
"author": "dcoales",
"license": "MIT",
"dependencies": {
"@logseq/libs": "^0.0.10",
"deepl-node": "^1.7.3"
},
"logseq": {
"id": "logseq-deepl",
"title": "Logseq Deepl Integration",
"author": "dcoales",
"description": "Translate selected blocks via deepl"
},
"devDependencies": {
"@types/jest": "^29.0.3",
"@types/node": "^18.11.9",
"buffer": "^5.5.0",
"events": "^3.3.0",
"parcel": "^2.8.0",
"path-browserify": "^1.0.1",
"punycode": "^1.4.1",
"querystring-es3": "^0.2.1",
"stream-http": "^3.2.0",
"ts-node": "^10.9.1",
"typescript": "^4.8.3",
"url": "^0.11.0",
"util": "^0.12.5"
}
}
I'm running this as a plugin to a tool called LogSeq. The plugin code is below. Any help would be much appreciated. Thanks.
import '@logseq/libs';
import {BlockEntity} from "@logseq/libs/dist/LSPlugin";
import { SettingSchemaDesc } from '@logseq/libs/dist/LSPlugin.user';
import * as deepl from 'deepl-node';
import {TextResult} from "deepl-node";
/**
* entry
*/
function main() {
logseq.useSettingsSchema(settings);
logseq.Editor.registerSlashCommand('Get Jira Details for Selection', (_) => {
return translate();
})
logseq.App.registerCommand('deeplTranslate', {
key: 'deeplTranslate',
label: 'Translate the selected lines',
desc: 'Get translations for each of the currently selected lines',
keybinding: {binding: 'mod+alt+t'}
}, (e) => {
return translate();
})
}
async function translate() {
let selection: BlockEntity[] | null = await logseq.Editor.getSelectedBlocks();
//console.log(selection);
if (!selection || selection.length === 0) {
const block: BlockEntity | null = await logseq.Editor.getCurrentBlock();
if (block){
selection = [block];
}
}
const lines:string[] = [];
if (selection){
for (let b of selection){
lines.push(b.content);
}
}
const authKey = logseq.settings?.APIToken;
const translator = new deepl.Translator(authKey);
const results:TextResult[] = await translator.translateText(lines,null,logseq.settings?.language);
results.map((result: deepl.TextResult) => {
console.log(result.text);
});
}
const settings: SettingSchemaDesc[] = [
{
key: "language",
description: "The language for the translated text",
type: "string",
default: "pl",
title: "Translated text language",
},
{
key: "APIToken",
description: "Deepl API token",
type: "string",
default: "",
title: "Deepl API token",
}
];
logseq.ready(main).catch(console.error);
Hi,
I'm trying to build a node app with vite using : npm create vite@latest
when using your code example after installing npm install deepl-node
:
import './style.css'
import * as deepl from 'deepl-node';
const authKey = "...-...-...-...-...:fx"; // Replace with your key
const translator = new deepl.Translator(authKey);
(async () => {
const result = await translator.translateText('Hello, world!', null, 'fr');
console.log(result.text); // Bonjour, le monde !
})();
I get the following error:
Uncaught (in promise) TypeError: url_1.URLSearchParams is not a constructor
at buildURLSearchParams (index.js:123:26)
at Translator.translateText (index.js:354:22)
at main.js?t=1656189862004:12:37
at main.js?t=1656189862004:14:3
I have a free account with DeepL
Thanks! (I'm pretty new to this ;-)
Good day, i am trying to translate a big array with deepl. Somehow when i put even a small array in the translateText function i am getting an error:
DeepLError: texts parameter must not be a non-empty string or array of non-empty strings at appendTextsAndReturnIsSingular projectpath/node_modules/deepl-node/dist/index.js:166:23
It seems that arrays are not supported
translator.translateText(
['hallo', 'test'],
req.body.sourceLanguageCode, //this is nl
req.body.targetLanguageCode, // this is en-GB
)
Describe the bug
ReferenceError when initializing deepl.Translator
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Expected no issues and a console log that it was successful
Desktop (please complete the following information):
Additional context
I am not sure what is going on. At first I thought it was a circular import issue but I have made sure I am not calling this anywhere else. I have deleted and generated a new page and I still get these issues at all times. I really need some help in understanding the approach I am doing wrong here. I appreciate all your help and please let me know if there is anything else I would need to provide.
If I remove the line const translator = new deepl.Translator(authkey);
, everything runs fine.
Describe the bug
When downloading PDFs via translator.downloadDocument()
, the resulting file is always empty and the file size is always 2KB. It seems that only the file's metadata is downloaded (see below), but the content itself is wiped out.
This is running inside a Lambda on AWS.
Note: .txt
files work as expected.
To Reproduce
Steps to reproduce the behavior:
Upload code
const myBuffer = fs.readFileSync(files["deepl-file-to-upload"].path);
console.log(`my buffer length: ${myBuffer.length}`); // <-- Buffer length is 143KB
translator.uploadDocument(
myBuffer,
`EN`,
`DE`,
{ filename: `${files["deepl-file-to-upload"].name}` }
).then((uploadResult) => {
console.log(uploadResult); // Returns documentId + documentKey as expected
}).catch((err) => {
console.log(err);
reject(err);
});
Download code
let builtDocumentHandle = {
'documentId': documentId,
'documentKey': documentKey
};
let myFileName = `translate-result-${builtDocumentHandle.documentId}.${fileType}`; // Define file name
let attachmentPath = `/tmp/${myFileName}`; // Build path where we will temporarily store file after it's been downloaded
let myWS = fs.createWriteStream(`/tmp/${myFileName}`); // Create write stream to hold the downloaded file
// Download newly translated document from DeepL
translator.downloadDocument(
builtDocumentHandle,
myWS
).then(() => {
// Check download file size for debug purposes
try {
let myFileSize = getFilesizeInBytes(attachmentPath);
console.log(`deepl file size after download: ${myFileSize} bytes`); // <-- Always returns around 2KB for PDFs
} catch (error) {
console.log('filesize error');
console.log(error);
}
}).catch((err) => {
console.log(err);
});
function getFilesizeInBytes(filename) {
var stats = fs.statSync(filename);
var fileSizeInBytes = stats.size;
return fileSizeInBytes;
}
Expected behavior
The downloaded PDF document should include all translated content.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Chrome Version 113.0.5672.126
Additional context
Example PDF content that I'm getting back from the DeepL API
%PDF-1.7
5 0 obj
<</Type /Page/Parent 3 0 R/Contents 6 0 R/MediaBox [0 0 612 792]/Resources<<>>/Group <</Type/Group/S/Transparency/CS/DeviceRGB>>>>
endobj
6 0 obj
<</Length 7 0 R>>stream
1 0 0 -1 0 792 cm q 1 0 0 1 86 91 cm q 1 0 0 1 3.852 0 cm Q Q 1 0 0 -1 -0 792 cm
endstream
endobj
7 0 obj
81
endobj
8 0 obj
<</Type /Page/Parent 3 0 R/Contents 9 0 R/MediaBox [0 0 612 792]/Resources<<>>/Group <</Type/Group/S/Transparency/CS/DeviceRGB>>>>
endobj
9 0 obj
<</Length 10 0 R>>stream
1 0 0 -1 0 792 cm q 1 0 0 1 86 91 cm Q 1 0 0 -1 -0 792 cm
endstream
endobj
10 0 obj
58
endobj
1 0 obj
<</Keywords(���,� �d�o�c�I�d�:�C�E�C�6�4�8�3�6�7�9�5�B�F�E�C�8�B�1�2�9�E�0�E�F�2�0�8�A�C�7�E�E)/Creator(���M�i�c�r�o�s�o�f�t� �O�f�f�i�c�e� �W�o�r�d)/Producer(���A�s�p�o�s�e�.�W�o�r�d�s� �f�o�r� �.�N�E�T� �2�3�.�1�.�0)/CreationDate(D:20230608155704Z)/ModDate(D:20230608155704Z)>>
endobj
2 0 obj
<</Type /Catalog/Pages 3 0 R/Lang(en-US)/Metadata 4 0 R>>
endobj
3 0 obj
<</Type /Pages/Count 2/Kids[5 0 R 8 0 R ]>>
endobj
4 0 obj
<</Type /Metadata/Subtype /XML/Length 11 0 R>>stream
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="PDFNet">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/">
<xmp:CreateDate>2023-06-08T15:57:04Z</xmp:CreateDate>
<xmp:ModifyDate>2023-06-08T15:57:04Z</xmp:ModifyDate>
<xmp:CreatorTool>Microsoft Office Word</xmp:CreatorTool>
</rdf:Description>
<rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:format>application/pdf</dc:format>
</rdf:Description>
<rdf:Description rdf:about="" xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
<pdf:Keywords>, docId:CEC64836795BFEC8B129E0EF208AC7EE</pdf:Keywords>
<pdf:Producer>Aspose.Words for .NET 23.1.0</pdf:Producer>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>
endstream
endobj
11 0 obj
826
endobj
12 0 obj
<</Type /XRef/W [1 4 2]/Size 13/Info 1 0 R/Root 2 0 R/ID [<395C0EA322A4574B9446E6B21AB973A7><395C0EA322A4574B9446E6B21AB973A7>]/Length 91>>stream
�����������[���������������������������
�������������'������=�������������D����������������
endstream
endobj
startxref
1973
%%EOF
Describe the bug
I try to translate Hello darkness my old friend Ive come to talk with you again to Spanish gives Hello darkness my old friend Ive come to talk with you again.
However with French and Italian it works correctly
To Reproduce
Steps to reproduce the behavior:
Use the API To Translate English to Spanish
Hello darkness my old friend Ive come to talk with you again to Spanish gives Hello darkness my old friend Ive come to talk with you again.
Expected behavior
It should translate to Spanish
Timestamp: 2024-06-25 22:15:42
I'm using deepl-node with node v16.14.0
I am having issue in very specific translations from fr to en-gb when there is only one sentence, markup and ponctuations
🔴<p>C'est bien d'avoir fait ça !</p>
-> <It's good that you did that!
✅<p>C'est bien d'avoir fait ça !</p><p>Non ?</p><p>Si bien sûr</p>
-> <p>It's good that you did that!</p><p>Didn't you?</p><p>Yes of course</p>
✅<p>C'est bien d'avoir fait ça</p>
-> <p>It's good to have done this</p>
I have tried these options without success tag_handling: 'xml'
tag_handling: 'html'
splitSentences : 'off'
preserveFormatting: true
Thanks for your help
Hello,
Is there a way to translate a text to multiple languages?
like this:
Translator.translateText(text, null, targetLangs as deepl.TargetLanguageCode[]);
Describe the bug
After creating a glossary and running a test translation, the glossary entry provided was partially translated and the source entry is sometimes included in the translation.
To Reproduce
Steps to reproduce the behavior:
This is the code I'm calling the translations with:
const testTranslation3 = await translator.translateText('test1', 'en', 'de', {
glossary: glossaryId,
})
Expected behavior
I'm uncertain if I misunderstood how glossaries work, but I thought they would always take precedence over default translations. Also, the source language string should never show up in the translation.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.