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 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) => handleDownload(opt, url, err, res, obj, cb));
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.6.16",
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.1",
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.1.0",
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.1",
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.6.2",
32
- "xlsx": "0.17.2"
31
+ "xliff": "5.7.2",
32
+ "xlsx": "0.17.4"
33
33
  },
34
34
  "devDependencies": {
35
35
  "eslint": "7.32.0",
36
- "gh-release": "5.0.0",
37
- "pkg": "5.3.2"
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(callback);
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
- setTimeout(() => {
379
- downloadAll(opt, remoteLanguages, false, opt.skipDelete ? (lng, namespace, ns) => {
380
- const found = compared.find((n) => n.namespace === namespace && n.language === lng);
381
- if (found && found.diff) {
382
- if (found.diff.toAddLocally && found.diff.toAddLocally.length > 0) {
383
- found.diff.toAddLocally.forEach((k) => {
384
- delete ns[k];
385
- });
386
- }
387
- if (found.diff.toRemove && found.diff.toRemove.length > 0) {
388
- found.diff.toRemove.forEach((k) => {
389
- delete ns[k];
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
- } : undefined, (err) => {
394
- if (err) return handleError(err);
395
- if (!cb) console.log(colors.green('FINISHED'));
396
- if (cb) cb(null);
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
  };