locize-cli 7.9.0 → 7.10.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 CHANGED
@@ -5,6 +5,19 @@ 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.10.1](https://github.com/locize/locize-cli/compare/v7.10.0...v7.10.1) - 2022-04-07
9
+
10
+ - cache dns lookups
11
+
12
+ ## [7.10.0](https://github.com/locize/locize-cli/compare/v7.9.1...v7.10.0) - 2022-03-15
13
+
14
+ - gettext_i18next: try to detect v4 format
15
+
16
+ ## [7.9.1](https://github.com/locize/locize-cli/compare/v7.9.0...v7.9.1) - 2022-03-02
17
+
18
+ - xliff: fix combined plural keys
19
+
20
+
8
21
  ## [7.9.0](https://github.com/locize/locize-cli/compare/v7.8.2...v7.9.0) - 2022-03-01
9
22
 
10
23
  - xliff: detect i18n format and merge pluralforms if necessary
@@ -28,8 +28,12 @@ const uniq = (value, index, self) => self.indexOf(value) === index;
28
28
  const stringify = (o) => {
29
29
  let str = jsyaml.dump(o);
30
30
  const subKeys = Object.keys(o);
31
- subKeys.forEach((sk, i) => {
32
- str = str.replace(new RegExp(`^(?:${sk}: )+`, 'm'), `{${sk}}: `);
31
+ subKeys.forEach((sk) => {
32
+ if (isNaN(sk)) {
33
+ str = str.replace(new RegExp(`^(?:${sk}: )+`, 'm'), `{${sk}}: `);
34
+ } else {
35
+ str = str.replace(new RegExp(`^(?:'${sk}': )+`, 'm'), `{${sk}}: `);
36
+ }
33
37
  });
34
38
  return str;
35
39
  };
@@ -38,6 +42,11 @@ const transformKeys = (segments, baseKeys, toMerge, deli) => {
38
42
  baseKeys.forEach((bk) => {
39
43
  const asObj = toMerge[bk].reduce((mem, k) => {
40
44
  const subKey = k.substring((bk + deli).length);
45
+ // special handling for i18next v3
46
+ if (deli === delimiter.i18next && subKey === 'plural' && segments[bk]) {
47
+ mem['__'] = segments[bk];
48
+ delete segments[bk];
49
+ }
41
50
  mem[subKey] = segments[k];
42
51
  return mem;
43
52
  }, {});
@@ -107,7 +116,12 @@ const parse = (s) => {
107
116
  let matchArray;
108
117
  while ((matchArray = skRegex.exec(s)) !== null) {
109
118
  const [match, sk] = matchArray;
110
- s = s.replace(new RegExp(`^(?:${match}: )+`, 'm'), `${sk}: `);
119
+ if (isNaN(sk)) {
120
+ s = s.replace(new RegExp(`^(?:${match}: )+`, 'm'), `${sk}: `);
121
+ } else {
122
+ const escapedMatch = match.replace('{', '\\{').replace('}', '\\}');
123
+ s = s.replace(new RegExp(`^(?:${escapedMatch}: )+`, 'm'), `${sk}: `);
124
+ }
111
125
  }
112
126
  return jsyaml.load(s);
113
127
  };
@@ -122,6 +136,10 @@ const prepareImport = (resources) => {
122
136
  Object.keys(parsed).map((sk) => {
123
137
  const skVal = parsed[sk];
124
138
  resources[`${baseKey}_${sk}`] = skVal;
139
+ if (sk === '__') {
140
+ resources[baseKey] = resources[`${baseKey}_${sk}`];
141
+ delete resources[`${baseKey}_${sk}`];
142
+ }
125
143
  });
126
144
  delete resources[k];
127
145
  }
@@ -56,11 +56,13 @@ const convertToDesiredFormat = (
56
56
  }
57
57
  if (opt.format === 'po_i18next' || opt.format === 'gettext_i18next') {
58
58
  const flatData = flatten(data);
59
+ const compatibilityJSON = !!Object.keys(flatData).find((k) => /_(zero|one|two|few|many|other)/.test(k)) && 'v4';
59
60
  const gettextOpt = {
60
61
  project: 'locize',
61
62
  language: lng,
62
63
  potCreationDate: lastModified,
63
- poRevisionDate: lastModified
64
+ poRevisionDate: lastModified,
65
+ compatibilityJSON
64
66
  };
65
67
  cb(null, i18next2po(lng, flatData, gettextOpt));
66
68
  return;
@@ -40,7 +40,9 @@ const convertToFlatFormat = (opt, data, lng, cb) => {
40
40
  }
41
41
  if (opt.format === 'po_i18next' || opt.format === 'gettext_i18next') {
42
42
  try {
43
- const ret = po2i18next(data.toString());
43
+ const potxt = data.toString();
44
+ const compatibilityJSON = /msgctxt "(zero|one|two|few|many|other)"/.test(potxt) && 'v4';
45
+ const ret = po2i18next(potxt, { compatibilityJSON });
44
46
  cb(null, flatten(ret));
45
47
  } catch (err) {
46
48
  cb(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "locize-cli",
3
- "version": "7.9.0",
3
+ "version": "7.10.1",
4
4
  "description": "locize cli to import locales",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -10,13 +10,14 @@
10
10
  "@js.properties/properties": "0.5.4",
11
11
  "android-string-resource": "2.3.4",
12
12
  "async": "3.2.3",
13
+ "cacheable-lookup": "6.0.4",
13
14
  "colors": "1.4.0",
14
15
  "commander": "9.0.0",
15
16
  "csvjson": "5.1.0",
16
17
  "diff": "5.0.0",
17
18
  "flat": "5.0.2",
18
19
  "fluent_conv": "3.1.0",
19
- "gettext-converter": "1.2.0",
20
+ "gettext-converter": "1.2.2",
20
21
  "https-proxy-agent": "5.0.0",
21
22
  "ini": "2.0.0",
22
23
  "js-yaml": "4.1.0",
@@ -29,11 +30,11 @@
29
30
  "strings-file": "0.0.5",
30
31
  "tmexchange": "2.0.4",
31
32
  "xliff": "6.0.3",
32
- "xlsx": "0.18.2"
33
+ "xlsx": "0.18.3"
33
34
  },
34
35
  "devDependencies": {
35
36
  "eslint": "7.32.0",
36
- "gh-release": "6.0.1",
37
+ "gh-release": "6.0.2",
37
38
  "pkg": "5.5.2"
38
39
  },
39
40
  "scripts": {
package/request.js CHANGED
@@ -1,10 +1,19 @@
1
1
  const package = require('./package.json');
2
2
  const fetch = require('node-fetch');
3
3
  const HttpsProxyAgent = require('https-proxy-agent');
4
+ const https = require('https');
5
+ const CacheableLookup = require('cacheable-lookup');
6
+ const cacheable = new CacheableLookup();
7
+ cacheable.install(https.globalAgent);
8
+
4
9
  const httpProxy = process.env.http_proxy || process.env.HTTP_PROXY || process.env.https_proxy || process.env.HTTPS_PROXY;
5
10
 
6
11
  module.exports = (url, options, callback) => {
7
- if (httpProxy) options.agent = new HttpsProxyAgent(httpProxy);
12
+ if (httpProxy) {
13
+ const httpsProxyAgent = new HttpsProxyAgent(httpProxy);
14
+ cacheable.install(httpsProxyAgent);
15
+ options.agent = httpsProxyAgent;
16
+ }
8
17
 
9
18
  options.headers = options.headers || {};
10
19
  options.headers['User-Agent'] = `${package.name}/v${package.version} (node/${process.version}; ${process.platform} ${process.arch})`;
@@ -23,7 +32,11 @@ module.exports = (url, options, callback) => {
23
32
  return { res };
24
33
  }
25
34
  }).then((ret) => callback(null, ret.res, ret.obj)).catch((err) => {
26
- if (err && err.message && err.message.indexOf('ENOTFOUND') > -1) {
35
+ if (err && err.message && (
36
+ err.message.indexOf('ENOTFOUND') > -1 ||
37
+ err.message.indexOf('ENODATA') > -1 ||
38
+ err.message.indexOf('ENOENT') > -1 // Windows: name exists, but not this record type
39
+ )) {
27
40
  setTimeout(() => {
28
41
  fetch(url, options).then((res) => {
29
42
  if (res.headers.get('content-type') && res.headers.get('content-type').indexOf('json') > 0) {
@@ -32,7 +45,7 @@ module.exports = (url, options, callback) => {
32
45
  return { res };
33
46
  }
34
47
  }).then((ret) => callback(null, ret.res, ret.obj)).catch(callback);
35
- }, 3000);
48
+ }, 5000);
36
49
  return;
37
50
  }
38
51
  callback(err);