locize-cli 7.6.16 → 7.7.2
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 +21 -0
- package/README.md +2 -0
- package/download.js +5 -1
- package/package.json +9 -9
- package/request.js +15 -1
- package/sync.js +63 -25
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ 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
|
+
## [7.7.2](https://github.com/locize/locize-cli/compare/v7.7.1...v7.7.2) - 2021-12-10
|
|
9
|
+
|
|
10
|
+
- update dependencies
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## [7.7.1](https://github.com/locize/locize-cli/compare/v7.7.0...v7.7.1) - 2021-12-10
|
|
14
|
+
|
|
15
|
+
- new binary build (x64)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## [7.7.0](https://github.com/locize/locize-cli/compare/v7.6.17...v7.7.0) - 2021-12-08
|
|
19
|
+
|
|
20
|
+
- sync: optimize api requests on bigger projects
|
|
21
|
+
- retry on very short dns resolution errors
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## [7.6.17](https://github.com/locize/locize-cli/compare/v7.6.16...v7.6.17) - 2021-09-21
|
|
25
|
+
|
|
26
|
+
- check skipEmpty flag when downloading translations
|
|
27
|
+
|
|
28
|
+
|
|
8
29
|
## [7.6.16](https://github.com/locize/locize-cli/compare/v7.6.15...v7.6.16) - 2021-09-20
|
|
9
30
|
|
|
10
31
|
- by default set also languageFolderPrefix to empty string when using programmatically
|
package/README.md
CHANGED
|
@@ -91,6 +91,8 @@ locize download --project-id my-project-id-93e1-442a-ab35-24331fa294ba --ver lat
|
|
|
91
91
|
By using the sync command, you can keep your existing code setup and synchronize the translations with locize.
|
|
92
92
|
An example on how this could look like can be seen in [this tutorial](https://github.com/locize/react-tutorial#step-1---keep-existing-code-setup-but-synchronize-with-locize).
|
|
93
93
|
|
|
94
|
+
**⚠️ Since the remote source are the published translations, make sure the desired version is set to standard publish mode, or alternatively [publish](#publish-version) that version before you execute the cli command. ⚠️**
|
|
95
|
+
|
|
94
96
|
### Step 1: Go near to your translation files
|
|
95
97
|
|
|
96
98
|
```sh
|
package/download.js
CHANGED
|
@@ -152,10 +152,14 @@ const download = (opt, cb) => {
|
|
|
152
152
|
opt.apiKey = null;
|
|
153
153
|
request(url, {
|
|
154
154
|
method: 'get',
|
|
155
|
-
}, (err, res, obj) =>
|
|
155
|
+
}, (err, res, obj) => {
|
|
156
|
+
if (opt.skipEmpty) obj = obj.filter((d) => d.size > 2);
|
|
157
|
+
handleDownload(opt, url, err, res, obj, cb);
|
|
158
|
+
});
|
|
156
159
|
return;
|
|
157
160
|
}
|
|
158
161
|
|
|
162
|
+
if (opt.skipEmpty) obj = obj.filter((d) => d.size > 2);
|
|
159
163
|
handleDownload(opt, url, err, res, obj, cb);
|
|
160
164
|
});
|
|
161
165
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "locize-cli",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.7.2",
|
|
4
4
|
"description": "locize cli to import locales",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,37 +9,37 @@
|
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"@js.properties/properties": "0.5.4",
|
|
11
11
|
"android-string-resource": "2.3.4",
|
|
12
|
-
"async": "3.2.
|
|
12
|
+
"async": "3.2.2",
|
|
13
13
|
"colors": "1.4.0",
|
|
14
14
|
"commander": "7.2.0",
|
|
15
15
|
"csvjson": "5.1.0",
|
|
16
16
|
"diff": "5.0.0",
|
|
17
17
|
"flat": "5.0.2",
|
|
18
18
|
"fluent_conv": "3.1.0",
|
|
19
|
-
"gettext-converter": "1.
|
|
19
|
+
"gettext-converter": "1.2.0",
|
|
20
20
|
"https-proxy-agent": "5.0.0",
|
|
21
21
|
"ini": "2.0.0",
|
|
22
22
|
"js-yaml": "4.1.0",
|
|
23
23
|
"laravelphp": "2.0.3",
|
|
24
24
|
"lodash.clonedeep": "4.5.0",
|
|
25
25
|
"mkdirp": "1.0.4",
|
|
26
|
-
"node-fetch": "2.6.
|
|
26
|
+
"node-fetch": "2.6.6",
|
|
27
27
|
"resx": "2.0.3",
|
|
28
28
|
"rimraf": "3.0.2",
|
|
29
29
|
"strings-file": "0.0.5",
|
|
30
30
|
"tmexchange": "2.0.4",
|
|
31
|
-
"xliff": "5.
|
|
32
|
-
"xlsx": "0.17.
|
|
31
|
+
"xliff": "5.7.2",
|
|
32
|
+
"xlsx": "0.17.4"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"eslint": "7.32.0",
|
|
36
|
-
"gh-release": "
|
|
37
|
-
"pkg": "5.
|
|
36
|
+
"gh-release": "6.0.1",
|
|
37
|
+
"pkg": "5.5.1"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"lint": "eslint .",
|
|
41
41
|
"test": "npm run lint",
|
|
42
|
-
"pkg": "mkdir -p ./bins && pkg ./bin/locize --out-path ./bins",
|
|
42
|
+
"pkg": "mkdir -p ./bins && pkg ./bin/locize --out-path ./bins --targets node16-linux-x64,node16-macos-x64,node16-win-x64",
|
|
43
43
|
"release": "gh-release --assets ./bins/locize-linux,./bins/locize-macos,./bins/locize-win.exe",
|
|
44
44
|
"version": "npm run pkg",
|
|
45
45
|
"postversion": "git push && npm run release"
|
package/request.js
CHANGED
|
@@ -22,5 +22,19 @@ module.exports = (url, options, callback) => {
|
|
|
22
22
|
} else {
|
|
23
23
|
return { res };
|
|
24
24
|
}
|
|
25
|
-
}).then((ret) => callback(null, ret.res, ret.obj)).catch(
|
|
25
|
+
}).then((ret) => callback(null, ret.res, ret.obj)).catch((err) => {
|
|
26
|
+
if (err && err.message && err.message.indexOf('ENOTFOUND') > -1) {
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
fetch(url, options).then((res) => {
|
|
29
|
+
if (res.headers.get('content-type') && res.headers.get('content-type').indexOf('json') > 0) {
|
|
30
|
+
return new Promise((resolve, reject) => res.json().then((obj) => resolve({ res, obj })).catch(reject));
|
|
31
|
+
} else {
|
|
32
|
+
return { res };
|
|
33
|
+
}
|
|
34
|
+
}).then((ret) => callback(null, ret.res, ret.obj)).catch(callback);
|
|
35
|
+
}, 3000);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
callback(err);
|
|
39
|
+
});
|
|
26
40
|
};
|
package/sync.js
CHANGED
|
@@ -36,6 +36,7 @@ const getDownloads = (opt, cb) => {
|
|
|
36
36
|
}
|
|
37
37
|
return cb(new Error(res.statusText + ' (' + res.status + ')'));
|
|
38
38
|
}
|
|
39
|
+
if (opt.skipEmpty) obj = obj.filter((d) => d.size > 2);
|
|
39
40
|
cb(null, obj);
|
|
40
41
|
});
|
|
41
42
|
};
|
|
@@ -197,7 +198,7 @@ const downloadAll = (opt, remoteLanguages, omitRef, manipulate, cb) => {
|
|
|
197
198
|
});
|
|
198
199
|
};
|
|
199
200
|
|
|
200
|
-
const update = (opt, lng, ns, cb) => {
|
|
201
|
+
const update = (opt, lng, ns, shouldOmit, cb) => {
|
|
201
202
|
var data = {};
|
|
202
203
|
if (!opt.skipDelete) {
|
|
203
204
|
ns.diff.toRemove.forEach((k) => data[k] = null);
|
|
@@ -214,7 +215,7 @@ const update = (opt, lng, ns, cb) => {
|
|
|
214
215
|
var payloadKeysLimit = 1000;
|
|
215
216
|
|
|
216
217
|
function send(d, clb, isRetrying) {
|
|
217
|
-
request(opt.apiPath + '/update/' + opt.projectId + '/' + opt.version + '/' + lng + '/' + ns.namespace, {
|
|
218
|
+
request(opt.apiPath + '/update/' + opt.projectId + '/' + opt.version + '/' + lng + '/' + ns.namespace + (shouldOmit ? '?omitstatsgeneration=true' : ''), {
|
|
218
219
|
method: 'post',
|
|
219
220
|
body: d,
|
|
220
221
|
headers: {
|
|
@@ -320,6 +321,20 @@ const handleSync = (opt, remoteLanguages, localNamespaces, cb) => {
|
|
|
320
321
|
compareNamespaces(opt, localNamespaces, (err, compared) => {
|
|
321
322
|
if (err) return handleError(err);
|
|
322
323
|
|
|
324
|
+
const onlyToUpdate = compared.filter((ns) => ns.diff.toAdd.concat(opt.skipDelete ? [] : ns.diff.toRemove).concat(ns.diff.toUpdate).length > 0);
|
|
325
|
+
|
|
326
|
+
const lngsInReqs = [];
|
|
327
|
+
const nsInReqs = [];
|
|
328
|
+
onlyToUpdate.forEach((n) => {
|
|
329
|
+
if (lngsInReqs.indexOf(n.language) < 0) {
|
|
330
|
+
lngsInReqs.push(n.language);
|
|
331
|
+
}
|
|
332
|
+
if (nsInReqs.indexOf(n.namespace) < 0) {
|
|
333
|
+
nsInReqs.push(n.namespace);
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
const shouldOmit = lngsInReqs.length > 5 || nsInReqs.length > 5;
|
|
337
|
+
|
|
323
338
|
var wasThereSomethingToUpdate = false;
|
|
324
339
|
async.eachLimit(compared, Math.round(require('os').cpus().length / 2), (ns, clb) => {
|
|
325
340
|
if (!cb) {
|
|
@@ -363,40 +378,63 @@ const handleSync = (opt, remoteLanguages, localNamespaces, cb) => {
|
|
|
363
378
|
if (!somethingToUpdate) console.log(colors.grey(`nothing to update for ${ns.language}/${ns.namespace}`));
|
|
364
379
|
if (!wasThereSomethingToUpdate && somethingToUpdate) wasThereSomethingToUpdate = true;
|
|
365
380
|
}
|
|
366
|
-
update(opt, ns.language, ns, (err) => {
|
|
381
|
+
update(opt, ns.language, ns, shouldOmit, (err) => {
|
|
367
382
|
if (err) return clb(err);
|
|
368
383
|
if (ns.diff.toRemove.length === 0 || ns.language !== opt.referenceLanguage) return clb();
|
|
369
384
|
const nsOnlyRemove = cloneDeep(ns);
|
|
370
385
|
nsOnlyRemove.diff.toAdd = [];
|
|
371
386
|
nsOnlyRemove.diff.toUpdate = [];
|
|
372
|
-
async.eachLimit(remoteLanguages, Math.round(require('os').cpus().length / 2), (lng, clb) => update(opt, lng, nsOnlyRemove, clb), clb);
|
|
387
|
+
async.eachLimit(remoteLanguages, Math.round(require('os').cpus().length / 2), (lng, clb) => update(opt, lng, nsOnlyRemove, shouldOmit, clb), clb);
|
|
373
388
|
});
|
|
374
389
|
}, (err) => {
|
|
375
390
|
if (err) return handleError(err);
|
|
376
|
-
|
|
377
391
|
if (!cb) console.log(colors.grey('syncing...'));
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
392
|
+
|
|
393
|
+
function down() {
|
|
394
|
+
setTimeout(() => { // wait a bit before downloading... just to have a chance to get the newly published files
|
|
395
|
+
downloadAll(opt, remoteLanguages, false, opt.skipDelete ? (lng, namespace, ns) => {
|
|
396
|
+
const found = compared.find((n) => n.namespace === namespace && n.language === lng);
|
|
397
|
+
if (found && found.diff) {
|
|
398
|
+
if (found.diff.toAddLocally && found.diff.toAddLocally.length > 0) {
|
|
399
|
+
found.diff.toAddLocally.forEach((k) => {
|
|
400
|
+
delete ns[k];
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
if (found.diff.toRemove && found.diff.toRemove.length > 0) {
|
|
404
|
+
found.diff.toRemove.forEach((k) => {
|
|
405
|
+
delete ns[k];
|
|
406
|
+
});
|
|
407
|
+
}
|
|
391
408
|
}
|
|
409
|
+
} : undefined, (err) => {
|
|
410
|
+
if (err) return handleError(err);
|
|
411
|
+
if (!cb) console.log(colors.green('FINISHED'));
|
|
412
|
+
if (cb) cb(null);
|
|
413
|
+
});
|
|
414
|
+
}, wasThereSomethingToUpdate && !opt.dry ? 5000 : 0);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (!shouldOmit) return down();
|
|
418
|
+
if (opt.dry) return down();
|
|
419
|
+
|
|
420
|
+
// optimize stats generation...
|
|
421
|
+
request(opt.apiPath + '/stats/project/regenerate/' + opt.projectId + '/' + opt.version + (lngsInReqs.length === 1 ? `/${lngsInReqs[0]}` : '') + (nsInReqs.length === 1 ? `?namespace=${nsInReqs[0]}` : ''), {
|
|
422
|
+
method: 'post',
|
|
423
|
+
body: {},
|
|
424
|
+
headers: {
|
|
425
|
+
'Authorization': opt.apiKey
|
|
426
|
+
}
|
|
427
|
+
}, (err, res, obj) => {
|
|
428
|
+
if (err) return handleError(err);
|
|
429
|
+
if (res.status >= 300 && res.status !== 412) {
|
|
430
|
+
if (obj && (obj.errorMessage || obj.message)) {
|
|
431
|
+
return handleError(new Error((obj.errorMessage || obj.message)));
|
|
392
432
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}, wasThereSomethingToUpdate && !opt.dry ? 5000 : 0);
|
|
399
|
-
}); // wait a bit before downloading... just to have a chance to get the newly published files
|
|
433
|
+
return handleError(new Error(res.statusText + ' (' + res.status + ')'));
|
|
434
|
+
}
|
|
435
|
+
down();
|
|
436
|
+
});
|
|
437
|
+
});
|
|
400
438
|
});
|
|
401
439
|
});
|
|
402
440
|
};
|