locize-cli 12.3.0 → 12.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/cjs/cli.js +1 -1
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/request.js +15 -6
- package/dist/esm/cli.js +1 -1
- package/dist/esm/request.js +15 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
Project versioning adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
Change log format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
7
7
|
|
|
8
|
+
## [12.3.1](https://github.com/locize/locize-cli/compare/v12.3.0...v12.3.1) - 2026-06-18
|
|
9
|
+
|
|
10
|
+
- request: retry transient network failures with exponential backoff and jitter
|
|
11
|
+
instead of a fixed 5s delay. This spreads retries so that bursts of
|
|
12
|
+
concurrent CLI runs (e.g. in CI) no longer retry in lockstep and hit the API
|
|
13
|
+
at the same instant.
|
|
14
|
+
|
|
8
15
|
## [12.3.0](https://github.com/locize/locize-cli/compare/v12.2.0...v12.3.0) - 2026-06-10
|
|
9
16
|
|
|
10
17
|
- sync: creates missing remote languages on the fly. A project without any
|
package/dist/cjs/cli.js
CHANGED
|
@@ -50,7 +50,7 @@ const program = new commander.Command();
|
|
|
50
50
|
|
|
51
51
|
program
|
|
52
52
|
.description('The official locize CLI.')
|
|
53
|
-
.version('12.3.
|
|
53
|
+
.version('12.3.1'); // This string is replaced with the actual version at build time by rollup
|
|
54
54
|
// .option('-a, --api-endpoint <url>', `Specify the api-endpoint url that should be used (default: ${defaultApiEndpoint})`)
|
|
55
55
|
// .option('-C, --config-path <configPath>', `Specify the path to the optional locize config file (default: ${configInWorkingDirectory} or ${configInHome})`);
|
|
56
56
|
|
package/dist/cjs/package.json
CHANGED
package/dist/cjs/request.js
CHANGED
|
@@ -7,6 +7,10 @@ var CacheableLookup = require('cacheable-lookup');
|
|
|
7
7
|
const cacheable = new CacheableLookup();
|
|
8
8
|
cacheable.install(https.globalAgent);
|
|
9
9
|
|
|
10
|
+
const RETRY_MAX_ATTEMPTS = 3;
|
|
11
|
+
const RETRY_BASE_DELAY_MS = 2000;
|
|
12
|
+
const RETRY_MAX_DELAY_MS = 30000;
|
|
13
|
+
|
|
10
14
|
const httpProxy = process.env.http_proxy || process.env.HTTP_PROXY || process.env.https_proxy || process.env.HTTPS_PROXY;
|
|
11
15
|
const isRetriableError = (err) => {
|
|
12
16
|
return err && err.message && (
|
|
@@ -39,7 +43,7 @@ async function request (url, options) {
|
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
options.headers = options.headers || {};
|
|
42
|
-
options.headers['User-Agent'] = `locize-cli/v12.3.
|
|
46
|
+
options.headers['User-Agent'] = `locize-cli/v12.3.1 (node/${process.version}; ${process.platform} ${process.arch})`; // This string is replaced with the actual version at build time by rollup
|
|
43
47
|
options.headers['X-User-Agent'] = options.headers['User-Agent'];
|
|
44
48
|
if (options.body || options.method !== 'get') options.headers['Content-Type'] = 'application/json';
|
|
45
49
|
if (options.body) {
|
|
@@ -49,19 +53,24 @@ async function request (url, options) {
|
|
|
49
53
|
}
|
|
50
54
|
if (options.headers['Authorization'] === undefined) delete options.headers['Authorization'];
|
|
51
55
|
|
|
52
|
-
async function retriableFetch (
|
|
56
|
+
async function retriableFetch (retriesLeft, attempt = 0) {
|
|
53
57
|
try {
|
|
54
58
|
const response = await fetch(url, options);
|
|
55
59
|
const result = await handleResponse(response);
|
|
56
60
|
return result
|
|
57
61
|
} catch (err) {
|
|
58
|
-
if (
|
|
62
|
+
if (retriesLeft < 1) throw err
|
|
59
63
|
if (!isRetriableError(err)) throw err
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
// Exponential backoff with equal jitter: spreads retries so a burst of
|
|
65
|
+
// concurrent CLI runs (e.g. CI) doesn't all retry in lockstep and
|
|
66
|
+
// hammer the API at the same instant.
|
|
67
|
+
const expDelay = Math.min(RETRY_MAX_DELAY_MS, RETRY_BASE_DELAY_MS * (2 ** attempt));
|
|
68
|
+
const delay = Math.round(expDelay / 2 + Math.random() * (expDelay / 2));
|
|
69
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
70
|
+
return retriableFetch(retriesLeft - 1, attempt + 1)
|
|
62
71
|
}
|
|
63
72
|
}
|
|
64
|
-
return retriableFetch(
|
|
73
|
+
return retriableFetch(RETRY_MAX_ATTEMPTS)
|
|
65
74
|
}
|
|
66
75
|
|
|
67
76
|
module.exports = request;
|
package/dist/esm/cli.js
CHANGED
|
@@ -48,7 +48,7 @@ const program = new Command();
|
|
|
48
48
|
|
|
49
49
|
program
|
|
50
50
|
.description('The official locize CLI.')
|
|
51
|
-
.version('12.3.
|
|
51
|
+
.version('12.3.1'); // This string is replaced with the actual version at build time by rollup
|
|
52
52
|
// .option('-a, --api-endpoint <url>', `Specify the api-endpoint url that should be used (default: ${defaultApiEndpoint})`)
|
|
53
53
|
// .option('-C, --config-path <configPath>', `Specify the path to the optional locize config file (default: ${configInWorkingDirectory} or ${configInHome})`);
|
|
54
54
|
|
package/dist/esm/request.js
CHANGED
|
@@ -5,6 +5,10 @@ import CacheableLookup from 'cacheable-lookup';
|
|
|
5
5
|
const cacheable = new CacheableLookup();
|
|
6
6
|
cacheable.install(https.globalAgent);
|
|
7
7
|
|
|
8
|
+
const RETRY_MAX_ATTEMPTS = 3;
|
|
9
|
+
const RETRY_BASE_DELAY_MS = 2000;
|
|
10
|
+
const RETRY_MAX_DELAY_MS = 30000;
|
|
11
|
+
|
|
8
12
|
const httpProxy = process.env.http_proxy || process.env.HTTP_PROXY || process.env.https_proxy || process.env.HTTPS_PROXY;
|
|
9
13
|
const isRetriableError = (err) => {
|
|
10
14
|
return err && err.message && (
|
|
@@ -37,7 +41,7 @@ async function request (url, options) {
|
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
options.headers = options.headers || {};
|
|
40
|
-
options.headers['User-Agent'] = `locize-cli/v12.3.
|
|
44
|
+
options.headers['User-Agent'] = `locize-cli/v12.3.1 (node/${process.version}; ${process.platform} ${process.arch})`; // This string is replaced with the actual version at build time by rollup
|
|
41
45
|
options.headers['X-User-Agent'] = options.headers['User-Agent'];
|
|
42
46
|
if (options.body || options.method !== 'get') options.headers['Content-Type'] = 'application/json';
|
|
43
47
|
if (options.body) {
|
|
@@ -47,19 +51,24 @@ async function request (url, options) {
|
|
|
47
51
|
}
|
|
48
52
|
if (options.headers['Authorization'] === undefined) delete options.headers['Authorization'];
|
|
49
53
|
|
|
50
|
-
async function retriableFetch (
|
|
54
|
+
async function retriableFetch (retriesLeft, attempt = 0) {
|
|
51
55
|
try {
|
|
52
56
|
const response = await fetch(url, options);
|
|
53
57
|
const result = await handleResponse(response);
|
|
54
58
|
return result
|
|
55
59
|
} catch (err) {
|
|
56
|
-
if (
|
|
60
|
+
if (retriesLeft < 1) throw err
|
|
57
61
|
if (!isRetriableError(err)) throw err
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
// Exponential backoff with equal jitter: spreads retries so a burst of
|
|
63
|
+
// concurrent CLI runs (e.g. CI) doesn't all retry in lockstep and
|
|
64
|
+
// hammer the API at the same instant.
|
|
65
|
+
const expDelay = Math.min(RETRY_MAX_DELAY_MS, RETRY_BASE_DELAY_MS * (2 ** attempt));
|
|
66
|
+
const delay = Math.round(expDelay / 2 + Math.random() * (expDelay / 2));
|
|
67
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
68
|
+
return retriableFetch(retriesLeft - 1, attempt + 1)
|
|
60
69
|
}
|
|
61
70
|
}
|
|
62
|
-
return retriableFetch(
|
|
71
|
+
return retriableFetch(RETRY_MAX_ATTEMPTS)
|
|
63
72
|
}
|
|
64
73
|
|
|
65
74
|
export { request as default };
|