Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .bumpversion.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Configuration file for bumpversion
# See https://github.com/callowayproject/bump-my-version
[tool.bumpversion]
current_version = "1.26.0"
current_version = "1.27.0"
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
serialize = ["{major}.{minor}.{patch}"]
search = "{current_version}"
Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [1.27.0] - 2026-04-27
### Changed
- Replaced the `uuid` dependency with Node's built-in `crypto.randomUUID()`.
Resolves GHSA-w5hq-g745-h8pq (`uuid <14.0.0`) and removes a runtime
dependency.
- Bumped minimum Node version from `>=12.0` to `>=14.17`. Node 12 reached
end of life in April 2022, and `crypto.randomUUID()` is available from
Node 14.17 onward.

### Fixed
- HTTP requests that fail with `ECONNRESET`, `EPIPE`, or `EAI_AGAIN` are now
retried. Previously these were classified as non-retryable, surfacing
transient transport failures (e.g. stale keep-alive sockets) as hard errors
on the first attempt. Behavior now aligns with deepl-python.

### Security
- Bump follow-redirects to 1.16.0 due to GHSA-r4q5-vmmm-2653.

Expand Down
73 changes: 23 additions & 50 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "deepl-node",
"description": "deepl-node is the official DeepL Node.js client library",
"version": "1.26.0",
"version": "1.27.0",
"author": "DeepL SE <open-source@deepl.com> (https://www.deepl.com)",
"license": "MIT",
"repository": {
Expand All @@ -11,7 +11,7 @@
"bugs": "https://github.com/DeepLcom/deepl-node/issues",
"homepage": "https://www.deepl.com/",
"engines": {
"node": ">=12.0"
"node": ">=14.17"
},
"keywords": [
"deepl",
Expand All @@ -23,14 +23,12 @@
"adm-zip": "^0.5.16",
"axios": "^1.7.4",
"form-data": "^3.0.4",
"loglevel": ">=1.6.2",
"uuid": "^8.3.2"
"loglevel": ">=1.6.2"
},
"devDependencies": {
"@types/adm-zip": "^0.5.7",
"@types/jest": "^29.5.0",
"@types/mock-fs": "^4.13.4",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.6.0",
"@typescript-eslint/parser": "^5.6.0",
"dotenv": "^16.4.7",
Expand Down
17 changes: 14 additions & 3 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ import * as http from 'http';

type HttpMethod = 'GET' | 'DELETE' | 'POST' | 'PUT' | 'PATCH';

/**
* Axios error codes for transient transport-level failures that should be retried.
* Mirrors deepl-python's broader ConnectionError retry coverage.
* @internal
*/
export const RETRYABLE_AXIOS_ERROR_CODES = new Set([
'ETIMEDOUT',
'ECONNABORTED',
'ECONNRESET',
'EPIPE',
'EAI_AGAIN',
]);

const axiosInstance = axios.create({
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
Expand Down Expand Up @@ -261,9 +274,7 @@ export class HttpClient {

const error = new ConnectionError(`Connection failure: ${message}`);
error.error = axiosError;
if (axiosError.code === 'ETIMEDOUT') {
error.shouldRetry = true;
} else if (axiosError.code === 'ECONNABORTED') {
if (axiosError.code !== undefined && RETRYABLE_AXIOS_ERROR_CODES.has(axiosError.code)) {
error.shouldRetry = true;
} else {
logDebug('Unrecognized axios error', axiosError);
Expand Down
4 changes: 2 additions & 2 deletions src/documentMinifier.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as path from 'path';
import * as fs from 'fs';
import * as os from 'os';
import { v4 as uuidv4 } from 'uuid';
import { randomUUID } from 'crypto';
import { DocumentDeminificationError, DocumentMinificationError } from './errors';
import AdmZip from 'adm-zip';
import { FsHelper } from './fsHelper';
Expand Down Expand Up @@ -283,7 +283,7 @@ export class DocumentMinifier implements IDocumentMinifier {
* @throws {DocumentMinificationError} If the temporary directory could not be created
*/
private static createTemporaryDirectory(): string {
const tempDir = path.join(os.tmpdir(), 'document_minification_' + uuidv4());
const tempDir = path.join(os.tmpdir(), 'document_minification_' + randomUUID());

if (fs.existsSync(tempDir)) {
throw new DocumentMinificationError(
Expand Down
2 changes: 1 addition & 1 deletion src/translator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ export class Translator {
sendPlatformInfo: boolean,
appInfo: AppInfo | undefined,
): string {
let libraryInfoString = 'deepl-node/1.26.0';
let libraryInfoString = 'deepl-node/1.27.0';
if (sendPlatformInfo) {
const systemType = os.type();
const systemVersion = os.version();
Expand Down
Loading
Loading