locize-cli 10.3.2 → 10.4.0

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/sync.js CHANGED
@@ -1,119 +1,121 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const { mkdirp } = require('mkdirp');
4
- const rimraf = require('rimraf');
5
- const async = require('async');
6
- const colors = require('colors');
7
- const request = require('./request');
8
- const flatten = require('flat');
9
- const cloneDeep = require('lodash.clonedeep');
10
- const getRemoteNamespace = require('./getRemoteNamespace');
11
- const getRemoteLanguages = require('./getRemoteLanguages');
12
- const convertToDesiredFormat = require('./convertToDesiredFormat');
13
- const parseLocalLanguages = require('./parseLocalLanguages');
14
- const parseLocalReference = require('./parseLocalReference');
15
- const formats = require('./formats');
16
- const lngCodes = require('./lngs.json');
17
- const deleteNamespace = require('./deleteNamespace');
18
- const getProjectStats = require('./getProjectStats');
19
- const reversedFileExtensionsMap = formats.reversedFileExtensionsMap;
20
- const locize2xcstrings = require('locize-xcstrings/cjs/locize2xcstrings');
21
- const getBranches = require('./getBranches');
22
- const isValidUuid = require('./isValidUuid');
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+ const { mkdirp } = require('mkdirp')
4
+ const rimraf = require('rimraf')
5
+ const async = require('async')
6
+ const colors = require('colors')
7
+ const request = require('./request')
8
+ const flatten = require('flat')
9
+ const cloneDeep = require('lodash.clonedeep')
10
+ const getRemoteNamespace = require('./getRemoteNamespace')
11
+ const getRemoteLanguages = require('./getRemoteLanguages')
12
+ const convertToDesiredFormat = require('./convertToDesiredFormat')
13
+ const parseLocalLanguages = require('./parseLocalLanguages')
14
+ const parseLocalReference = require('./parseLocalReference')
15
+ const formats = require('./formats')
16
+ const lngCodes = require('./lngs.json')
17
+ const deleteNamespace = require('./deleteNamespace')
18
+ const getProjectStats = require('./getProjectStats')
19
+ const reversedFileExtensionsMap = formats.reversedFileExtensionsMap
20
+ const locize2xcstrings = require('locize-xcstrings/cjs/locize2xcstrings')
21
+ const getBranches = require('./getBranches')
22
+ const isValidUuid = require('./isValidUuid')
23
23
 
24
24
  const getDirectories = (srcpath) => {
25
25
  return fs.readdirSync(srcpath).filter((file) => {
26
- return fs.statSync(path.join(srcpath, file)).isDirectory();
27
- });
28
- };
29
-
30
- function getInfosInUrl(download) {
31
- const splitted = download.key.split('/');
32
- const version = splitted[download.isPrivate ? 2 : 1];
33
- const language = splitted[download.isPrivate ? 3 : 2];
34
- const namespace = splitted[download.isPrivate ? 4 : 3];
35
- return { version, language, namespace };
26
+ return fs.statSync(path.join(srcpath, file)).isDirectory()
27
+ })
28
+ }
29
+
30
+ function getInfosInUrl (download) {
31
+ const splitted = download.key.split('/')
32
+ const version = splitted[download.isPrivate ? 2 : 1]
33
+ const language = splitted[download.isPrivate ? 3 : 2]
34
+ const namespace = splitted[download.isPrivate ? 4 : 3]
35
+ return { version, language, namespace }
36
36
  }
37
37
 
38
38
  const getDownloads = (opt, cb) => {
39
39
  if (!opt.unpublished) {
40
40
  request(opt.apiPath + '/download/' + opt.projectId + '/' + opt.version, {
41
41
  method: 'get',
42
- headers: opt.apiKey ? {
43
- 'Authorization': opt.apiKey
44
- } : undefined
42
+ headers: opt.apiKey
43
+ ? {
44
+ Authorization: opt.apiKey
45
+ }
46
+ : undefined
45
47
  }, (err, res, obj) => {
46
- if (err) return cb(err);
48
+ if (err) return cb(err)
47
49
  if (res.status >= 300) {
48
50
  if (obj && (obj.errorMessage || obj.message)) {
49
51
  if (res.statusText && res.status) {
50
- return cb(new Error(res.statusText + ' (' + res.status + ') | ' + (obj.errorMessage || obj.message)));
52
+ return cb(new Error(res.statusText + ' (' + res.status + ') | ' + (obj.errorMessage || obj.message)))
51
53
  }
52
- return cb(new Error((obj.errorMessage || obj.message)));
54
+ return cb(new Error((obj.errorMessage || obj.message)))
53
55
  }
54
- return cb(new Error(res.statusText + ' (' + res.status + ')'));
56
+ return cb(new Error(res.statusText + ' (' + res.status + ')'))
55
57
  }
56
58
  if (obj.length > 0) {
57
- if (opt.skipEmpty) obj = obj.filter((d) => d.size > 2);
58
- return cb(null, obj);
59
+ if (opt.skipEmpty) obj = obj.filter((d) => d.size > 2)
60
+ return cb(null, obj)
59
61
  }
60
62
 
61
63
  getProjectStats(opt, (err, res) => {
62
- if (err) return handleError(err, cb);
63
- if (!res) return handleError(new Error('Nothing found!'), cb);
64
- if (!res[opt.version]) return handleError(new Error(`Version "${opt.version}" not found!`), cb);
64
+ if (err) return handleError(err, cb)
65
+ if (!res) return handleError(new Error('Nothing found!'), cb)
66
+ if (!res[opt.version]) return handleError(new Error(`Version "${opt.version}" not found!`), cb)
65
67
 
66
- return cb(null, obj);
67
- });
68
- });
68
+ return cb(null, obj)
69
+ })
70
+ })
69
71
  } else {
70
72
  getProjectStats(opt, (err, res) => {
71
- if (err) return handleError(err, cb);
72
- if (!res) return handleError(new Error('Nothing found!'), cb);
73
- if (!res[opt.version]) return handleError(new Error(`Version "${opt.version}" not found!`), cb);
73
+ if (err) return handleError(err, cb)
74
+ if (!res) return handleError(new Error('Nothing found!'), cb)
75
+ if (!res[opt.version]) return handleError(new Error(`Version "${opt.version}" not found!`), cb)
74
76
 
75
- const toDownload = [];
76
- const lngsToCheck = opt.language ? [opt.language] : (opt.languages && opt.languages.length > 0) ? opt.languages : Object.keys(res[opt.version]);
77
+ const toDownload = []
78
+ const lngsToCheck = opt.language ? [opt.language] : (opt.languages && opt.languages.length > 0) ? opt.languages : Object.keys(res[opt.version])
77
79
  lngsToCheck.forEach((l) => {
78
80
  if (opt.namespaces) {
79
81
  opt.namespaces.forEach((n) => {
80
- if (!res[opt.version][l][n]) return;
81
- if (opt.skipEmpty && res[opt.version][l][n].segmentsTranslated === 0) return;
82
+ if (!res[opt.version][l][n]) return
83
+ if (opt.skipEmpty && res[opt.version][l][n].segmentsTranslated === 0) return
82
84
  toDownload.push({
83
85
  url: `${opt.apiPath}/${opt.projectId}/${opt.version}/${l}/${n}`,
84
86
  key: `${opt.projectId}/${opt.version}/${l}/${n}`,
85
87
  lastModified: '1960-01-01T00:00:00.000Z',
86
88
  size: 0
87
- });
88
- });
89
+ })
90
+ })
89
91
  } else if (opt.namespace) {
90
- if (!res[opt.version][l][opt.namespace]) return;
91
- if (opt.skipEmpty && res[opt.version][l][opt.namespace].segmentsTranslated === 0) return;
92
+ if (!res[opt.version][l][opt.namespace]) return
93
+ if (opt.skipEmpty && res[opt.version][l][opt.namespace].segmentsTranslated === 0) return
92
94
  toDownload.push({
93
95
  url: `${opt.apiPath}/${opt.projectId}/${opt.version}/${l}/${opt.namespace}`,
94
96
  key: `${opt.projectId}/${opt.version}/${l}/${opt.namespace}`,
95
97
  lastModified: '1960-01-01T00:00:00.000Z',
96
98
  size: 0
97
- });
99
+ })
98
100
  } else {
99
101
  Object.keys(res[opt.version][l]).forEach((n) => {
100
- if (opt.skipEmpty && res[opt.version][l][n].segmentsTranslated === 0) return;
102
+ if (opt.skipEmpty && res[opt.version][l][n].segmentsTranslated === 0) return
101
103
  toDownload.push({
102
104
  url: `${opt.apiPath}/${opt.projectId}/${opt.version}/${l}/${n}`,
103
105
  key: `${opt.projectId}/${opt.version}/${l}/${n}`,
104
106
  lastModified: '1960-01-01T00:00:00.000Z',
105
107
  size: 0
106
- });
107
- });
108
+ })
109
+ })
108
110
  }
109
- });
110
- cb(null, toDownload);
111
- });
111
+ })
112
+ cb(null, toDownload)
113
+ })
112
114
  }
113
- };
115
+ }
114
116
 
115
117
  const compareNamespace = (local, remote, lastModifiedLocal, lastModifiedRemote) => {
116
- const wasLastChangedRemote = lastModifiedLocal && lastModifiedRemote && lastModifiedLocal.getTime() < lastModifiedRemote.getTime();
118
+ const wasLastChangedRemote = lastModifiedLocal && lastModifiedRemote && lastModifiedLocal.getTime() < lastModifiedRemote.getTime()
117
119
  const diff = {
118
120
  toAdd: [],
119
121
  toAddLocally: [],
@@ -121,16 +123,16 @@ const compareNamespace = (local, remote, lastModifiedLocal, lastModifiedRemote)
121
123
  toUpdateLocally: [],
122
124
  toRemove: [],
123
125
  toRemoveLocally: []
124
- };
125
- local = local || {};
126
- remote = remote || {};
126
+ }
127
+ local = local || {}
128
+ remote = remote || {}
127
129
  Object.keys(local).forEach((k) => {
128
- if (remote[k] === '' && local[k] === '') return;
130
+ if (remote[k] === '' && local[k] === '') return
129
131
  if (!remote[k]) {
130
132
  if (wasLastChangedRemote) {
131
- diff.toRemoveLocally.push(k); // will download later
133
+ diff.toRemoveLocally.push(k) // will download later
132
134
  } else {
133
- diff.toAdd.push(k);
135
+ diff.toAdd.push(k)
134
136
  }
135
137
  }
136
138
  if (
@@ -140,643 +142,645 @@ const compareNamespace = (local, remote, lastModifiedLocal, lastModifiedRemote)
140
142
  )
141
143
  ) {
142
144
  if (wasLastChangedRemote) {
143
- diff.toUpdateLocally.push(k); // will download later
145
+ diff.toUpdateLocally.push(k) // will download later
144
146
  } else {
145
- diff.toUpdate.push(k);
147
+ diff.toUpdate.push(k)
146
148
  }
147
149
  }
148
- });
150
+ })
149
151
  Object.keys(remote).forEach((k) => {
150
- if (local[k] === '' && remote[k] === '') return;
152
+ if (local[k] === '' && remote[k] === '') return
151
153
  if (!local[k]) {
152
154
  if (wasLastChangedRemote) {
153
- diff.toAddLocally.push(k); // will download later
155
+ diff.toAddLocally.push(k) // will download later
154
156
  } else {
155
- diff.toRemove.push(k);
157
+ diff.toRemove.push(k)
156
158
  }
157
159
  }
158
- });
159
- return diff;
160
- };
160
+ })
161
+ return diff
162
+ }
161
163
 
162
164
  const compareNamespaces = (opt, localNamespaces, cb) => {
163
165
  async.mapLimit(localNamespaces, 20, (ns, clb) => {
164
166
  getRemoteNamespace(opt, ns.language, ns.namespace, (err, remoteNamespace, lastModified) => {
165
- if (err) return clb(err);
166
-
167
- const diff = compareNamespace(ns.content, remoteNamespace, opt.compareModificationTime ? ns.mtime : undefined, opt.compareModificationTime ? lastModified : undefined);
168
- ns.diff = diff;
169
- ns.remoteContent = remoteNamespace;
170
- clb(null, ns);
171
- });
172
- }, cb);
173
- };
167
+ if (err) return clb(err)
168
+
169
+ const diff = compareNamespace(ns.content, remoteNamespace, opt.compareModificationTime ? ns.mtime : undefined, opt.compareModificationTime ? lastModified : undefined)
170
+ ns.diff = diff
171
+ ns.remoteContent = remoteNamespace
172
+ clb(null, ns)
173
+ })
174
+ }, cb)
175
+ }
174
176
 
175
177
  const getNamespaceNamesAvailableInReference = (opt, downloads) => {
176
- var nsNames = [];
178
+ const nsNames = []
177
179
  downloads.forEach((d) => {
178
- const splitted = d.key.split('/');
179
- const lng = splitted[2];
180
- const ns = splitted[3];
180
+ const splitted = d.key.split('/')
181
+ const lng = splitted[2]
182
+ const ns = splitted[3]
181
183
  if (lng === opt.referenceLanguage) {
182
- nsNames.push(ns);
184
+ nsNames.push(ns)
183
185
  }
184
- });
185
- return nsNames;
186
- };
186
+ })
187
+ return nsNames
188
+ }
187
189
 
188
190
  const ensureAllNamespacesInLanguages = (opt, remoteLanguages, downloads) => {
189
- const namespaces = getNamespaceNamesAvailableInReference(opt, downloads);
191
+ const namespaces = getNamespaceNamesAvailableInReference(opt, downloads)
190
192
 
191
193
  remoteLanguages.forEach((lng) => {
192
194
  namespaces.forEach((n) => {
193
- const found = downloads.find((d) => d.key === `${opt.projectId}/${opt.version}/${lng}/${n}`);
195
+ const found = downloads.find((d) => d.key === `${opt.projectId}/${opt.version}/${lng}/${n}`)
194
196
  if (!found) {
195
197
  downloads.push({
196
198
  key: `${opt.projectId}/${opt.version}/${lng}/${n}`,
197
199
  lastModified: '1960-01-01T00:00:00.000Z',
198
200
  size: 0,
199
201
  url: `${opt.apiPath}/${opt.projectId}/${opt.version}/${lng}/${n}`
200
- });
202
+ })
201
203
  }
202
- });
203
- });
204
- };
204
+ })
205
+ })
206
+ }
205
207
 
206
208
  const downloadAll = (opt, remoteLanguages, omitRef, manipulate, cb) => {
207
209
  if (typeof cb !== 'function') {
208
210
  if (typeof manipulate === 'function') {
209
- cb = manipulate;
210
- manipulate = undefined;
211
+ cb = manipulate
212
+ manipulate = undefined
211
213
  }
212
214
  if (typeof omitRef === 'function') {
213
- cb = omitRef;
214
- manipulate = undefined;
215
- omitRef = false;
215
+ cb = omitRef
216
+ manipulate = undefined
217
+ omitRef = false
216
218
  }
217
219
  }
218
220
 
219
- if (!opt.dry && opt.format !== 'xcstrings') cleanupLanguages(opt, remoteLanguages);
221
+ if (!opt.dry && opt.format !== 'xcstrings') cleanupLanguages(opt, remoteLanguages)
220
222
 
221
223
  getDownloads(opt, (err, downloads) => {
222
- if (err) return cb(err);
224
+ if (err) return cb(err)
223
225
 
224
- ensureAllNamespacesInLanguages(opt, remoteLanguages, downloads);
226
+ ensureAllNamespacesInLanguages(opt, remoteLanguages, downloads)
225
227
 
226
228
  if (omitRef) {
227
229
  downloads = downloads.filter((d) => {
228
- const splitted = d.key.split('/');
229
- const lng = splitted[d.isPrivate ? 3 : 2];
230
- return lng !== opt.referenceLanguage;
231
- });
230
+ const splitted = d.key.split('/')
231
+ const lng = splitted[d.isPrivate ? 3 : 2]
232
+ return lng !== opt.referenceLanguage
233
+ })
232
234
  }
233
235
 
234
236
  if (opt.format === 'xcstrings') { // 1 file per namespace including all languages
235
- const downloadsByNamespace = {};
237
+ const downloadsByNamespace = {}
236
238
  downloads.forEach((download) => {
237
- const { namespace } = getInfosInUrl(download);
238
- downloadsByNamespace[namespace] = downloadsByNamespace[namespace] || [];
239
- downloadsByNamespace[namespace].push(download);
240
- });
239
+ const { namespace } = getInfosInUrl(download)
240
+ downloadsByNamespace[namespace] = downloadsByNamespace[namespace] || []
241
+ downloadsByNamespace[namespace].push(download)
242
+ })
241
243
 
242
244
  async.eachLimit(Object.keys(downloadsByNamespace), opt.unpublished ? 5 : 20, (namespace, clb) => {
243
245
  const locizeData = {
244
246
  sourceLng: opt.referenceLanguage,
245
247
  resources: {}
246
- };
248
+ }
247
249
 
248
250
  async.eachLimit(downloadsByNamespace[namespace], opt.unpublished ? 5 : 20, (download, clb) => {
249
- const { language } = getInfosInUrl(download);
250
- opt.isPrivate = download.isPrivate;
251
+ const { language } = getInfosInUrl(download)
252
+ opt.isPrivate = download.isPrivate
251
253
 
252
- if (opt.language && opt.language !== language && language !== opt.referenceLanguage) return clb(null);
253
- if (opt.languages && opt.languages.length > 0 && opt.languages.indexOf(language) < 0 && language !== opt.referenceLanguage) return clb(null);
254
- if (opt.namespace && opt.namespace !== namespace) return clb(null);
255
- if (opt.namespaces && opt.namespaces.length > 0 && opt.namespaces.indexOf(namespace) < 0) return clb(null);
254
+ if (opt.language && opt.language !== language && language !== opt.referenceLanguage) return clb(null)
255
+ if (opt.languages && opt.languages.length > 0 && opt.languages.indexOf(language) < 0 && language !== opt.referenceLanguage) return clb(null)
256
+ if (opt.namespace && opt.namespace !== namespace) return clb(null)
257
+ if (opt.namespaces && opt.namespaces.length > 0 && opt.namespaces.indexOf(namespace) < 0) return clb(null)
256
258
 
257
- if (opt.unpublished) opt.raw = true;
259
+ if (opt.unpublished) opt.raw = true
258
260
  getRemoteNamespace(opt, language, namespace, (err, ns, lastModified) => {
259
- if (err) return clb(err);
261
+ if (err) return clb(err)
260
262
 
261
263
  if (opt.skipEmpty && Object.keys(flatten(ns)).length === 0) {
262
- return clb(null);
264
+ return clb(null)
263
265
  }
264
266
 
265
- if (manipulate && typeof manipulate == 'function') manipulate(language, namespace, ns);
267
+ if (manipulate && typeof manipulate === 'function') manipulate(language, namespace, ns)
266
268
 
267
- locizeData.resources[language] = ns;
268
- clb();
269
- });
269
+ locizeData.resources[language] = ns
270
+ clb()
271
+ })
270
272
  }, (err) => {
271
- if (err) return clb(err);
273
+ if (err) return clb(err)
272
274
 
273
275
  try {
274
- const converted = locize2xcstrings(locizeData);
276
+ const converted = locize2xcstrings(locizeData)
275
277
 
276
- const filledMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, '').replace(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`, namespace) + reversedFileExtensionsMap[opt.format];
277
- if (opt.dry) return clb(null);
278
+ const filledMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, '').replace(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`, namespace) + reversedFileExtensionsMap[opt.format]
279
+ if (opt.dry) return clb(null)
278
280
  if (opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`) > opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`) && filledMask.lastIndexOf(path.sep) > 0) {
279
- mkdirp.sync(path.join(opt.path, filledMask.substring(0, filledMask.lastIndexOf(path.sep))));
281
+ mkdirp.sync(path.join(opt.path, filledMask.substring(0, filledMask.lastIndexOf(path.sep))))
280
282
  }
281
- const parentDir = path.dirname(path.join(opt.path, filledMask));
282
- mkdirp.sync(parentDir);
283
- const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted;
284
- fs.writeFile(path.join(opt.path, filledMask), fileContent, clb);
283
+ const parentDir = path.dirname(path.join(opt.path, filledMask))
284
+ mkdirp.sync(parentDir)
285
+ const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted
286
+ fs.writeFile(path.join(opt.path, filledMask), fileContent, clb)
285
287
  } catch (e) {
286
- err.message = 'Invalid content for "' + opt.format + '" format!\n' + (err.message || '');
287
- return clb(err);
288
+ err.message = 'Invalid content for "' + opt.format + '" format!\n' + (err.message || '')
289
+ return clb(err)
288
290
  }
289
- });
290
- }, cb);
291
+ })
292
+ }, cb)
291
293
  } else { // 1 file per namespace/lng
292
294
  async.eachLimit(downloads, opt.unpublished ? 5 : 20, (download, clb) => {
293
- const { language, namespace } = getInfosInUrl(download);
294
- opt.isPrivate = download.isPrivate;
295
+ const { language, namespace } = getInfosInUrl(download)
296
+ opt.isPrivate = download.isPrivate
295
297
 
296
- if (opt.language && opt.language !== language && language !== opt.referenceLanguage) return clb(null);
297
- if (opt.languages && opt.languages.length > 0 && opt.languages.indexOf(language) < 0 && language !== opt.referenceLanguage) return clb(null);
298
- if (opt.namespace && opt.namespace !== namespace) return clb(null);
299
- if (opt.namespaces && opt.namespaces.length > 0 && opt.namespaces.indexOf(namespace) < 0) return clb(null);
298
+ if (opt.language && opt.language !== language && language !== opt.referenceLanguage) return clb(null)
299
+ if (opt.languages && opt.languages.length > 0 && opt.languages.indexOf(language) < 0 && language !== opt.referenceLanguage) return clb(null)
300
+ if (opt.namespace && opt.namespace !== namespace) return clb(null)
301
+ if (opt.namespaces && opt.namespaces.length > 0 && opt.namespaces.indexOf(namespace) < 0) return clb(null)
300
302
 
301
303
  getRemoteNamespace(opt, language, namespace, (err, ns, lastModified) => {
302
- if (err) return clb(err);
304
+ if (err) return clb(err)
303
305
 
304
306
  if (opt.skipEmpty && Object.keys(flatten(ns)).length === 0) {
305
- return clb(null);
307
+ return clb(null)
306
308
  }
307
309
 
308
- if (manipulate && typeof manipulate == 'function') manipulate(language, namespace, ns);
310
+ if (manipulate && typeof manipulate === 'function') manipulate(language, namespace, ns)
309
311
 
310
312
  convertToDesiredFormat(opt, namespace, language, ns, lastModified, (err, converted) => {
311
313
  if (err) {
312
- err.message = 'Invalid content for "' + opt.format + '" format!\n' + (err.message || '');
313
- return clb(err);
314
+ err.message = 'Invalid content for "' + opt.format + '" format!\n' + (err.message || '')
315
+ return clb(err)
314
316
  }
315
317
 
316
- const filledMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, language).replace(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`, namespace) + reversedFileExtensionsMap[opt.format];
317
- if (opt.dry) return clb(null);
318
+ const filledMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, language).replace(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`, namespace) + reversedFileExtensionsMap[opt.format]
319
+ if (opt.dry) return clb(null)
318
320
  if (opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`) > opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`) && filledMask.lastIndexOf(path.sep) > 0) {
319
- mkdirp.sync(path.join(opt.path, filledMask.substring(0, filledMask.lastIndexOf(path.sep))));
321
+ mkdirp.sync(path.join(opt.path, filledMask.substring(0, filledMask.lastIndexOf(path.sep))))
320
322
  }
321
- const parentDir = path.dirname(path.join(opt.path, filledMask));
322
- mkdirp.sync(parentDir);
323
- const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted;
324
- fs.writeFile(path.join(opt.path, filledMask), fileContent, clb);
325
- });
326
- });
327
- }, cb);
323
+ const parentDir = path.dirname(path.join(opt.path, filledMask))
324
+ mkdirp.sync(parentDir)
325
+ const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted
326
+ fs.writeFile(path.join(opt.path, filledMask), fileContent, clb)
327
+ })
328
+ })
329
+ }, cb)
328
330
  }
329
- });
330
- };
331
+ })
332
+ }
331
333
 
332
334
  const update = (opt, lng, ns, shouldOmit, cb) => {
333
- var data = {};
335
+ const data = {}
334
336
  if (!opt.skipDelete) {
335
- ns.diff.toRemove.forEach((k) => data[k] = null);
337
+ ns.diff.toRemove.forEach((k) => { data[k] = null })
336
338
  }
337
- ns.diff.toAdd.forEach((k) => data[k] = ns.content[k]);
339
+ ns.diff.toAdd.forEach((k) => { data[k] = ns.content[k] })
338
340
  if (opt.updateValues) {
339
- ns.diff.toUpdate.forEach((k) => data[k] = ns.content[k]);
341
+ ns.diff.toUpdate.forEach((k) => { data[k] = ns.content[k] })
340
342
  }
341
343
 
342
- var keysToSend = Object.keys(data).length;
343
- if (keysToSend === 0) return cb(null);
344
+ const keysToSend = Object.keys(data).length
345
+ if (keysToSend === 0) return cb(null)
344
346
 
345
- if (opt.dry) return cb(null);
347
+ if (opt.dry) return cb(null)
346
348
 
347
- var payloadKeysLimit = 1000;
349
+ const payloadKeysLimit = 1000
348
350
 
349
- function send(d, so, clb, isRetrying) {
350
- const queryParams = new URLSearchParams();
351
+ function send (d, so, clb, isRetrying) {
352
+ const queryParams = new URLSearchParams()
351
353
  if (opt.autoTranslate && lng === opt.referenceLanguage) {
352
354
  /** @See https://www.locize.com/docs/api#optional-autotranslate */
353
- queryParams.append('autotranslate', 'true');
355
+ queryParams.append('autotranslate', 'true')
354
356
  }
355
357
  if (so) {
356
- queryParams.append('omitstatsgeneration', 'true');
358
+ queryParams.append('omitstatsgeneration', 'true')
357
359
  }
358
360
 
359
- const queryString = queryParams.size > 0 ? '?' + queryParams.toString() : '';
361
+ const queryString = queryParams.size > 0 ? '?' + queryParams.toString() : ''
360
362
 
361
363
  request(opt.apiPath + '/update/' + opt.projectId + '/' + opt.version + '/' + lng + '/' + ns.namespace + queryString, {
362
364
  method: 'post',
363
365
  body: d,
364
366
  headers: {
365
- 'Authorization': opt.apiKey
367
+ Authorization: opt.apiKey
366
368
  }
367
369
  }, (err, res, obj) => {
368
- if (err) return clb(err);
369
- const cliInfo = res.headers.get('x-cli-info');
370
+ if (err) return clb(err)
371
+ const cliInfo = res.headers.get('x-cli-info')
370
372
  if (cliInfo && cliInfo !== opt.lastShownCliInfo) {
371
- console.log(colors.yellow(cliInfo));
372
- opt.lastShownCliInfo = cliInfo;
373
+ console.log(colors.yellow(cliInfo))
374
+ opt.lastShownCliInfo = cliInfo
373
375
  }
374
376
  if (res.status === 504 && !isRetrying) {
375
- return setTimeout(() => send(d, so, clb, true), 3000);
377
+ return setTimeout(() => send(d, so, clb, true), 3000)
376
378
  }
377
379
  if (res.status >= 300 && res.status !== 412) {
378
380
  if (obj && (obj.errorMessage || obj.message)) {
379
- return clb(new Error((obj.errorMessage || obj.message)));
381
+ return clb(new Error((obj.errorMessage || obj.message)))
380
382
  }
381
- return clb(new Error(res.statusText + ' (' + res.status + ')'));
383
+ return clb(new Error(res.statusText + ' (' + res.status + ')'))
382
384
  }
383
- setTimeout(() => clb(null), 1000);
384
- });
385
+ setTimeout(() => clb(null), 1000)
386
+ })
385
387
  }
386
388
 
387
389
  if (keysToSend > payloadKeysLimit) {
388
- var tasks = [];
389
- var keysInObj = Object.keys(data);
390
+ const tasks = []
391
+ const keysInObj = Object.keys(data)
390
392
 
391
393
  while (keysInObj.length > payloadKeysLimit) {
392
- (function() {
393
- var pagedData = {};
394
- keysInObj.splice(0, payloadKeysLimit).forEach((k) => pagedData[k] = data[k]);
395
- var hasMoreKeys = keysInObj.length > 0;
396
- tasks.push((c) => send(pagedData, hasMoreKeys ? true : shouldOmit, c));
397
- })();
394
+ (function () {
395
+ const pagedData = {}
396
+ keysInObj.splice(0, payloadKeysLimit).forEach((k) => { pagedData[k] = data[k] })
397
+ const hasMoreKeys = keysInObj.length > 0
398
+ tasks.push((c) => send(pagedData, hasMoreKeys ? true : shouldOmit, c))
399
+ })()
398
400
  }
399
401
 
400
- if (keysInObj.length === 0) return cb(null);
402
+ if (keysInObj.length === 0) return cb(null)
401
403
 
402
- var finalPagedData = {};
403
- keysInObj.splice(0, keysInObj.length).forEach((k) => finalPagedData[k] = data[k]);
404
- tasks.push((c) => send(finalPagedData, shouldOmit, c));
404
+ const finalPagedData = {}
405
+ keysInObj.splice(0, keysInObj.length).forEach((k) => { finalPagedData[k] = data[k] })
406
+ tasks.push((c) => send(finalPagedData, shouldOmit, c))
405
407
 
406
- async.series(tasks, cb);
407
- return;
408
+ async.series(tasks, cb)
409
+ return
408
410
  }
409
411
 
410
- send(data, shouldOmit, cb);
411
- };
412
+ send(data, shouldOmit, cb)
413
+ }
412
414
 
413
415
  const doesDirectoryExist = (p) => {
414
- var directoryExists = false;
416
+ let directoryExists = false
415
417
  try {
416
- directoryExists = fs.statSync(p).isDirectory();
418
+ directoryExists = fs.statSync(p).isDirectory()
417
419
  } catch (e) {}
418
- return directoryExists;
419
- };
420
+ return directoryExists
421
+ }
420
422
 
421
423
  const cleanupLanguages = (opt, remoteLanguages) => {
422
- if (opt.pathMask.lastIndexOf(path.sep) < 0) return;
423
- const dirs = getDirectories(opt.path).filter((dir) => dir.indexOf('.') !== 0);
424
+ if (opt.pathMask.lastIndexOf(path.sep) < 0) return
425
+ const dirs = getDirectories(opt.path).filter((dir) => dir.indexOf('.') !== 0)
424
426
  if (!opt.language && (!opt.languages || opt.languages.length === 0) && !opt.namespace && !opt.namespaces) {
425
427
  dirs
426
428
  .filter((lng) => {
427
- const lMask = `${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`;
428
- const startLIndex = opt.pathMask.indexOf(lMask);
429
- const restLMask = lng.substring((startLIndex || 0) + lMask.length);
430
- lng = lng.substring(startLIndex || 0, lng.lastIndexOf(restLMask));
429
+ const lMask = `${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`
430
+ const startLIndex = opt.pathMask.indexOf(lMask)
431
+ const restLMask = lng.substring((startLIndex || 0) + lMask.length)
432
+ lng = lng.substring(startLIndex || 0, lng.lastIndexOf(restLMask))
431
433
 
432
- return lng !== opt.referenceLanguage
433
- && !!lngCodes.find((c) => lng === c || lng.indexOf(c + '-') === 0);
434
+ return lng !== opt.referenceLanguage &&
435
+ !!lngCodes.find((c) => lng === c || lng.indexOf(c + '-') === 0)
434
436
  })
435
437
  .forEach((lng) => {
436
- const filledLngMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, lng);
437
- var lngPath;
438
+ const filledLngMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, lng)
439
+ let lngPath
438
440
  if (filledLngMask.lastIndexOf(path.sep) > 0) {
439
- lngPath = filledLngMask.substring(0, filledLngMask.lastIndexOf(path.sep));
441
+ lngPath = filledLngMask.substring(0, filledLngMask.lastIndexOf(path.sep))
440
442
  }
441
- if (doesDirectoryExist(path.join(opt.path, lngPath, 'CVS'))) return; // special hack for CVS
442
- rimraf.sync(path.join(opt.path, lngPath));
443
- });
443
+ if (doesDirectoryExist(path.join(opt.path, lngPath, 'CVS'))) return // special hack for CVS
444
+ rimraf.sync(path.join(opt.path, lngPath))
445
+ })
444
446
  }
445
447
  remoteLanguages.forEach((lng) => {
446
- if (opt.language && opt.language !== lng) return;
447
- if (opt.languages && opt.languages.length > 0 && opt.languages.indexOf(lng) < 0) return;
448
- const filledLngMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, lng);
449
- var lngPath;
448
+ if (opt.language && opt.language !== lng) return
449
+ if (opt.languages && opt.languages.length > 0 && opt.languages.indexOf(lng) < 0) return
450
+ const filledLngMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, lng)
451
+ let lngPath
450
452
  if (filledLngMask.lastIndexOf(path.sep) > 0) {
451
- lngPath = filledLngMask.substring(0, filledLngMask.lastIndexOf(path.sep));
453
+ lngPath = filledLngMask.substring(0, filledLngMask.lastIndexOf(path.sep))
452
454
  }
453
- if (lngPath && lngPath.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`) < 0) mkdirp.sync(path.join(opt.path, lngPath));
454
- });
455
- };
455
+ if (lngPath && lngPath.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`) < 0) mkdirp.sync(path.join(opt.path, lngPath))
456
+ })
457
+ }
456
458
 
457
459
  const handleError = (err, cb) => {
458
460
  if (!cb && err) {
459
- console.error(colors.red(err.stack));
460
- process.exit(1);
461
+ console.error(colors.red(err.stack))
462
+ process.exit(1)
461
463
  }
462
- if (cb) cb(err);
463
- };
464
+ if (cb) cb(err)
465
+ }
464
466
 
465
467
  const checkForMissingLocalNamespaces = (downloads, localNamespaces, opt) => {
466
- const localMissingNamespaces = [];
468
+ const localMissingNamespaces = []
467
469
  downloads.forEach((d) => {
468
- const splitted = d.url.split('/');
469
- const namespace = splitted.pop();
470
- const language = splitted.pop();
470
+ const splitted = d.url.split('/')
471
+ const namespace = splitted.pop()
472
+ const language = splitted.pop()
471
473
  // if (!opt.referenceLanguageOnly || (opt.referenceLanguageOnly && language === opt.referenceLanguage)) {
472
474
  if (language === opt.referenceLanguage) {
473
- const foundLocalNamespace = localNamespaces.find((n) => n.namespace === namespace && n.language === language);
475
+ const foundLocalNamespace = localNamespaces.find((n) => n.namespace === namespace && n.language === language)
474
476
  if (!foundLocalNamespace) {
475
477
  localMissingNamespaces.push({
476
478
  language,
477
479
  namespace
478
- });
480
+ })
479
481
  }
480
482
  }
481
- });
482
- return localMissingNamespaces;
483
- };
483
+ })
484
+ return localMissingNamespaces
485
+ }
484
486
 
485
487
  const backupDeleted = (opt, ns, now) => {
486
- if (opt.dry || ns.diff.toRemove.length === 0) return;
487
- var m = now.getMonth() + 1;
488
- if (m < 10) m = `0${m}`;
489
- var d = now.getDate();
490
- if (d < 10) d = `0${d}`;
491
- var h = now.getHours();
492
- if (h < 10) h = `0${h}`;
493
- var mi = now.getMinutes();
494
- if (mi < 10) mi = `0${mi}`;
495
- var s = now.getSeconds();
496
- if (s < 10) s = `0${s}`;
497
- const currentBackupPath = path.join(opt.backupDeletedPath, `${now.getFullYear()}${m}${d}-${h}${mi}${s}`);
498
- mkdirp.sync(currentBackupPath);
488
+ if (opt.dry || ns.diff.toRemove.length === 0) return
489
+ let m = now.getMonth() + 1
490
+ if (m < 10) m = `0${m}`
491
+ let d = now.getDate()
492
+ if (d < 10) d = `0${d}`
493
+ let h = now.getHours()
494
+ if (h < 10) h = `0${h}`
495
+ let mi = now.getMinutes()
496
+ if (mi < 10) mi = `0${mi}`
497
+ let s = now.getSeconds()
498
+ if (s < 10) s = `0${s}`
499
+ const currentBackupPath = path.join(opt.backupDeletedPath, `${now.getFullYear()}${m}${d}-${h}${mi}${s}`)
500
+ mkdirp.sync(currentBackupPath)
499
501
  const removingRemote = ns.diff.toRemove.reduce((prev, k) => {
500
- prev[k] = ns.remoteContent[k];
501
- return prev;
502
- }, {});
503
- mkdirp.sync(path.join(currentBackupPath, ns.language));
504
- const content = JSON.stringify(removingRemote, null, 2);
505
- const fileContent = (opt.format !== 'xlsx' && !content.endsWith('\n')) ? (content + '\n') : content;
506
- fs.writeFileSync(path.join(currentBackupPath, ns.language, `${ns.namespace}.json`), fileContent);
507
- };
502
+ prev[k] = ns.remoteContent[k]
503
+ return prev
504
+ }, {})
505
+ mkdirp.sync(path.join(currentBackupPath, ns.language))
506
+ const content = JSON.stringify(removingRemote, null, 2)
507
+ const fileContent = (opt.format !== 'xlsx' && !content.endsWith('\n')) ? (content + '\n') : content
508
+ fs.writeFileSync(path.join(currentBackupPath, ns.language, `${ns.namespace}.json`), fileContent)
509
+ }
508
510
 
509
511
  const handleSync = (opt, remoteLanguages, localNamespaces, cb) => {
510
512
  if (!localNamespaces || localNamespaces.length === 0) {
511
513
  downloadAll(opt, remoteLanguages, (err) => {
512
- if (err) return handleError(err, cb);
513
- if (!cb) console.log(colors.green('FINISHED'));
514
- if (cb) cb(null);
515
- });
516
- return;
514
+ if (err) return handleError(err, cb)
515
+ if (!cb) console.log(colors.green('FINISHED'))
516
+ if (cb) cb(null)
517
+ })
518
+ return
517
519
  }
518
520
 
519
521
  getDownloads(opt, (err, downloads) => {
520
- if (err) return handleError(err, cb);
522
+ if (err) return handleError(err, cb)
521
523
 
522
- opt.isPrivate = downloads.length > 0 && downloads[0].isPrivate;
524
+ opt.isPrivate = downloads.length > 0 && downloads[0].isPrivate
523
525
 
524
- const localMissingNamespaces = checkForMissingLocalNamespaces(downloads, localNamespaces, opt);
526
+ const localMissingNamespaces = checkForMissingLocalNamespaces(downloads, localNamespaces, opt)
525
527
 
526
528
  compareNamespaces(opt, localNamespaces, (err, compared) => {
527
- if (err) return handleError(err, cb);
529
+ if (err) return handleError(err, cb)
528
530
 
529
- const onlyToUpdate = compared.filter((ns) => ns.diff.toAdd.concat(opt.skipDelete ? [] : ns.diff.toRemove).concat(ns.diff.toUpdate).length > 0);
531
+ const onlyToUpdate = compared.filter((ns) => ns.diff.toAdd.concat(opt.skipDelete ? [] : ns.diff.toRemove).concat(ns.diff.toUpdate).length > 0)
530
532
 
531
- const lngsInReqs = [];
532
- const nsInReqs = [];
533
+ const lngsInReqs = []
534
+ const nsInReqs = []
533
535
  onlyToUpdate.forEach((n) => {
534
536
  if (lngsInReqs.indexOf(n.language) < 0) {
535
- lngsInReqs.push(n.language);
537
+ lngsInReqs.push(n.language)
536
538
  }
537
539
  if (nsInReqs.indexOf(n.namespace) < 0) {
538
- nsInReqs.push(n.namespace);
540
+ nsInReqs.push(n.namespace)
539
541
  }
540
- });
541
- const shouldOmit = lngsInReqs.length > 5 || nsInReqs.length > 5;
542
+ })
543
+ const shouldOmit = lngsInReqs.length > 5 || nsInReqs.length > 5
542
544
 
543
- var wasThereSomethingToUpdate = opt.autoTranslate || false;
545
+ let wasThereSomethingToUpdate = opt.autoTranslate || false
544
546
 
545
- function updateComparedNamespaces() {
546
- const now = new Date();
547
+ function updateComparedNamespaces () {
548
+ const now = new Date()
547
549
  async.eachLimit(compared, Math.round(require('os').cpus().length / 2), (ns, clb) => {
548
550
  if (!cb) {
549
551
  if (ns.diff.toRemove.length > 0) {
550
552
  if (opt.skipDelete) {
551
- console.log(colors.bgRed(`skipping the removal of ${ns.diff.toRemove.length} keys in ${ns.language}/${ns.namespace}...`));
552
- if (opt.dry) console.log(colors.bgRed(`skipped to remove ${ns.diff.toRemove.join(', ')} in ${ns.language}/${ns.namespace}...`));
553
+ console.log(colors.bgRed(`skipping the removal of ${ns.diff.toRemove.length} keys in ${ns.language}/${ns.namespace}...`))
554
+ if (opt.dry) console.log(colors.bgRed(`skipped to remove ${ns.diff.toRemove.join(', ')} in ${ns.language}/${ns.namespace}...`))
553
555
  } else {
554
- console.log(colors.red(`removing ${ns.diff.toRemove.length} keys in ${ns.language}/${ns.namespace}...`));
555
- if (opt.dry) console.log(colors.red(`would remove ${ns.diff.toRemove.join(', ')} in ${ns.language}/${ns.namespace}...`));
556
- if (!opt.dry && opt.backupDeletedPath) backupDeleted(opt, ns, now);
556
+ console.log(colors.red(`removing ${ns.diff.toRemove.length} keys in ${ns.language}/${ns.namespace}...`))
557
+ if (opt.dry) console.log(colors.red(`would remove ${ns.diff.toRemove.join(', ')} in ${ns.language}/${ns.namespace}...`))
558
+ if (!opt.dry && opt.backupDeletedPath) backupDeleted(opt, ns, now)
557
559
  }
558
560
  }
559
561
  if (ns.diff.toRemoveLocally.length > 0) {
560
- console.log(colors.red(`removing ${ns.diff.toRemoveLocally.length} keys in ${ns.language}/${ns.namespace} locally...`));
561
- if (opt.dry) console.log(colors.red(`would remove ${ns.diff.toRemoveLocally.join(', ')} in ${ns.language}/${ns.namespace} locally...`));
562
+ console.log(colors.red(`removing ${ns.diff.toRemoveLocally.length} keys in ${ns.language}/${ns.namespace} locally...`))
563
+ if (opt.dry) console.log(colors.red(`would remove ${ns.diff.toRemoveLocally.join(', ')} in ${ns.language}/${ns.namespace} locally...`))
562
564
  }
563
565
  if (ns.diff.toAdd.length > 0) {
564
- console.log(colors.green(`adding ${ns.diff.toAdd.length} keys in ${ns.language}/${ns.namespace}...`));
565
- if (opt.dry) console.log(colors.green(`would add ${ns.diff.toAdd.join(', ')} in ${ns.language}/${ns.namespace}...`));
566
+ console.log(colors.green(`adding ${ns.diff.toAdd.length} keys in ${ns.language}/${ns.namespace}...`))
567
+ if (opt.dry) console.log(colors.green(`would add ${ns.diff.toAdd.join(', ')} in ${ns.language}/${ns.namespace}...`))
566
568
  }
567
569
  if (ns.diff.toAddLocally.length > 0) {
568
570
  if (opt.skipDelete) {
569
- console.log(colors.bgGreen(`skipping the addition of ${ns.diff.toAddLocally.length} keys in ${ns.language}/${ns.namespace} locally...`));
570
- if (opt.dry) console.log(colors.bgGreen(`skipped the addition of ${ns.diff.toAddLocally.join(', ')} in ${ns.language}/${ns.namespace} locally...`));
571
+ console.log(colors.bgGreen(`skipping the addition of ${ns.diff.toAddLocally.length} keys in ${ns.language}/${ns.namespace} locally...`))
572
+ if (opt.dry) console.log(colors.bgGreen(`skipped the addition of ${ns.diff.toAddLocally.join(', ')} in ${ns.language}/${ns.namespace} locally...`))
571
573
  } else {
572
- console.log(colors.green(`adding ${ns.diff.toAddLocally.length} keys in ${ns.language}/${ns.namespace} locally...`));
573
- if (opt.dry) console.log(colors.green(`would add ${ns.diff.toAddLocally.join(', ')} in ${ns.language}/${ns.namespace} locally...`));
574
+ console.log(colors.green(`adding ${ns.diff.toAddLocally.length} keys in ${ns.language}/${ns.namespace} locally...`))
575
+ if (opt.dry) console.log(colors.green(`would add ${ns.diff.toAddLocally.join(', ')} in ${ns.language}/${ns.namespace} locally...`))
574
576
  }
575
577
  }
576
578
  if (opt.updateValues) {
577
579
  if (ns.diff.toUpdate.length > 0) {
578
- console.log(colors.yellow(`updating ${ns.diff.toUpdate.length} keys in ${ns.language}/${ns.namespace}${opt.autoTranslate ? ' with automatic translation' : ''}...`));
579
- if (opt.dry) console.log(colors.yellow(`would update ${ns.diff.toUpdate.join(', ')} in ${ns.language}/${ns.namespace}...`));
580
+ console.log(colors.yellow(`updating ${ns.diff.toUpdate.length} keys in ${ns.language}/${ns.namespace}${opt.autoTranslate ? ' with automatic translation' : ''}...`))
581
+ if (opt.dry) console.log(colors.yellow(`would update ${ns.diff.toUpdate.join(', ')} in ${ns.language}/${ns.namespace}...`))
580
582
  }
581
583
  if (ns.diff.toUpdateLocally.length > 0) {
582
- console.log(colors.yellow(`updating ${ns.diff.toUpdateLocally.length} keys in ${ns.language}/${ns.namespace} locally...`));
583
- if (opt.dry) console.log(colors.yellow(`would update ${ns.diff.toUpdateLocally.join(', ')} in ${ns.language}/${ns.namespace} locally...`));
584
+ console.log(colors.yellow(`updating ${ns.diff.toUpdateLocally.length} keys in ${ns.language}/${ns.namespace} locally...`))
585
+ if (opt.dry) console.log(colors.yellow(`would update ${ns.diff.toUpdateLocally.join(', ')} in ${ns.language}/${ns.namespace} locally...`))
584
586
  }
585
587
  }
586
- const somethingToUpdate = ns.diff.toAdd.concat(opt.skipDelete ? [] : ns.diff.toRemove)/*.concat(ns.diff.toUpdate)*/.length > 0;
587
- if (!somethingToUpdate) console.log(colors.grey(`nothing to update for ${ns.language}/${ns.namespace}`));
588
- if (!wasThereSomethingToUpdate && somethingToUpdate) wasThereSomethingToUpdate = true;
588
+ const somethingToUpdate = ns.diff.toAdd.concat(opt.skipDelete ? [] : ns.diff.toRemove)/* .concat(ns.diff.toUpdate) */.length > 0
589
+ if (!somethingToUpdate) console.log(colors.grey(`nothing to update for ${ns.language}/${ns.namespace}`))
590
+ if (!wasThereSomethingToUpdate && somethingToUpdate) wasThereSomethingToUpdate = true
589
591
  }
590
592
  update(opt, ns.language, ns, shouldOmit, (err) => {
591
- if (err) return clb(err);
592
- if (ns.diff.toRemove.length === 0 || ns.language !== opt.referenceLanguage) return clb();
593
- const nsOnlyRemove = cloneDeep(ns);
594
- nsOnlyRemove.diff.toAdd = [];
595
- nsOnlyRemove.diff.toUpdate = [];
596
- async.eachLimit(remoteLanguages, Math.round(require('os').cpus().length / 2), (lng, clb) => update(opt, lng, nsOnlyRemove, shouldOmit, clb), clb);
597
- });
593
+ if (err) return clb(err)
594
+ if (ns.diff.toRemove.length === 0 || ns.language !== opt.referenceLanguage) return clb()
595
+ const nsOnlyRemove = cloneDeep(ns)
596
+ nsOnlyRemove.diff.toAdd = []
597
+ nsOnlyRemove.diff.toUpdate = []
598
+ async.eachLimit(remoteLanguages, Math.round(require('os').cpus().length / 2), (lng, clb) => update(opt, lng, nsOnlyRemove, shouldOmit, clb), clb)
599
+ })
598
600
  }, (err) => {
599
- if (err) return handleError(err, cb);
600
- if (!cb) console.log(colors.grey('syncing...'));
601
+ if (err) return handleError(err, cb)
602
+ if (!cb) console.log(colors.grey('syncing...'))
601
603
 
602
- function down() {
604
+ function down () {
603
605
  setTimeout(() => { // wait a bit before downloading... just to have a chance to get the newly published files
604
- downloadAll(opt, remoteLanguages, false, opt.skipDelete ? (lng, namespace, ns) => {
605
- const found = compared.find((n) => n.namespace === namespace && n.language === lng);
606
- if (found && found.diff) {
607
- if (found.diff.toAddLocally && found.diff.toAddLocally.length > 0) {
608
- found.diff.toAddLocally.forEach((k) => {
609
- delete ns[k];
610
- });
606
+ downloadAll(opt, remoteLanguages, false, opt.skipDelete
607
+ ? (lng, namespace, ns) => {
608
+ const found = compared.find((n) => n.namespace === namespace && n.language === lng)
609
+ if (found && found.diff) {
610
+ if (found.diff.toAddLocally && found.diff.toAddLocally.length > 0) {
611
+ found.diff.toAddLocally.forEach((k) => {
612
+ delete ns[k]
613
+ })
614
+ }
615
+ if (found.diff.toRemove && found.diff.toRemove.length > 0) {
616
+ found.diff.toRemove.forEach((k) => {
617
+ delete ns[k]
618
+ })
619
+ }
620
+ }
611
621
  }
612
- if (found.diff.toRemove && found.diff.toRemove.length > 0) {
613
- found.diff.toRemove.forEach((k) => {
614
- delete ns[k];
615
- });
616
- }
617
- }
618
- } : undefined, (err) => {
619
- if (err) return handleError(err, cb);
620
- if (!cb) console.log(colors.green('FINISHED'));
621
- if (cb) cb(null);
622
- });
623
- }, wasThereSomethingToUpdate && !opt.dry ? (opt.autoTranslate ? 10000 : 5000) : 0);
622
+ : undefined, (err) => {
623
+ if (err) return handleError(err, cb)
624
+ if (!cb) console.log(colors.green('FINISHED'))
625
+ if (cb) cb(null)
626
+ })
627
+ }, wasThereSomethingToUpdate && !opt.dry ? (opt.autoTranslate ? 10000 : 5000) : 0)
624
628
  }
625
629
 
626
- if (!shouldOmit) return down();
627
- if (opt.dry) return down();
630
+ if (!shouldOmit) return down()
631
+ if (opt.dry) return down()
628
632
 
629
633
  // optimize stats generation...
630
634
  request(opt.apiPath + '/stats/project/regenerate/' + opt.projectId + '/' + opt.version + (lngsInReqs.length === 1 ? `/${lngsInReqs[0]}` : '') + (nsInReqs.length === 1 ? `?namespace=${nsInReqs[0]}` : ''), {
631
635
  method: 'post',
632
636
  body: {},
633
637
  headers: {
634
- 'Authorization': opt.apiKey
638
+ Authorization: opt.apiKey
635
639
  }
636
640
  }, (err, res, obj) => {
637
- if (err) return handleError(err, cb);
641
+ if (err) return handleError(err, cb)
638
642
  if (res.status >= 300 && res.status !== 412) {
639
643
  if (obj && (obj.errorMessage || obj.message)) {
640
- return handleError(new Error((obj.errorMessage || obj.message)), cb);
644
+ return handleError(new Error((obj.errorMessage || obj.message)), cb)
641
645
  }
642
- return handleError(new Error(res.statusText + ' (' + res.status + ')'), cb);
646
+ return handleError(new Error(res.statusText + ' (' + res.status + ')'), cb)
643
647
  }
644
- down();
645
- });
646
- });
648
+ down()
649
+ })
650
+ })
647
651
  }
648
652
 
649
653
  if (opt.deleteRemoteNamespace && localMissingNamespaces.length > 0) {
650
- wasThereSomethingToUpdate = true;
654
+ wasThereSomethingToUpdate = true
651
655
  async.eachLimit(localMissingNamespaces, 20, (n, clb) => {
652
656
  if (opt.dry) {
653
- console.log(colors.red(`would delete complete namespace ${n.namespace}...`));
654
- return clb();
657
+ console.log(colors.red(`would delete complete namespace ${n.namespace}...`))
658
+ return clb()
655
659
  }
656
- console.log(colors.red(`deleting complete namespace ${n.namespace}...`));
660
+ console.log(colors.red(`deleting complete namespace ${n.namespace}...`))
657
661
  deleteNamespace({
658
662
  apiPath: opt.apiPath,
659
663
  apiKey: opt.apiKey,
660
664
  projectId: opt.projectId,
661
665
  version: opt.version,
662
666
  namespace: n.namespace
663
- }, clb);
667
+ }, clb)
664
668
  }, (err) => {
665
- if (err) return handleError(err, cb);
666
- updateComparedNamespaces();
667
- });
668
- return;
669
+ if (err) return handleError(err, cb)
670
+ updateComparedNamespaces()
671
+ })
672
+ return
669
673
  }
670
- updateComparedNamespaces();
671
- });
672
- });
673
- };
674
+ updateComparedNamespaces()
675
+ })
676
+ })
677
+ }
674
678
 
675
679
  const continueToSync = (opt, cb) => {
676
- console.log(colors.grey('checking remote (locize)...'));
680
+ console.log(colors.grey('checking remote (locize)...'))
677
681
  getRemoteLanguages(opt, (err, remoteLanguages) => {
678
- if (err) return handleError(err, cb);
682
+ if (err) return handleError(err, cb)
679
683
 
680
684
  if (opt.referenceLanguageOnly && opt.language && opt.referenceLanguage !== opt.language) {
681
- opt.referenceLanguage = opt.language;
685
+ opt.referenceLanguage = opt.language
682
686
  }
683
687
  if (opt.referenceLanguageOnly && !opt.language && opt.languages && opt.languages.length > 0 && opt.languages.indexOf(opt.referenceLanguage) < 0) {
684
- opt.referenceLanguage = opt.languages[0];
688
+ opt.referenceLanguage = opt.languages[0]
685
689
  }
686
690
 
687
691
  if (opt.referenceLanguageOnly) {
688
- console.log(colors.grey(`checking local${opt.path !== process.cwd() ? ` (${opt.path})` : ''} only reference language...`));
692
+ console.log(colors.grey(`checking local${opt.path !== process.cwd() ? ` (${opt.path})` : ''} only reference language...`))
689
693
  parseLocalReference(opt, (err, localNamespaces) => {
690
- if (err) return handleError(err, cb);
694
+ if (err) return handleError(err, cb)
691
695
 
692
696
  if (!opt.dry && opt.cleanLocalFiles) {
693
- localNamespaces.forEach((ln) => fs.unlinkSync(ln.path));
694
- localNamespaces = [];
697
+ localNamespaces.forEach((ln) => fs.unlinkSync(ln.path))
698
+ localNamespaces = []
695
699
  }
696
700
 
697
- console.log(colors.grey('calculate diffs...'));
698
- handleSync(opt, remoteLanguages, localNamespaces, cb);
699
- });
700
- return;
701
+ console.log(colors.grey('calculate diffs...'))
702
+ handleSync(opt, remoteLanguages, localNamespaces, cb)
703
+ })
704
+ return
701
705
  }
702
706
 
703
- console.log(colors.grey(`checking local${opt.path !== process.cwd() ? ` (${opt.path})` : ''}...`));
707
+ console.log(colors.grey(`checking local${opt.path !== process.cwd() ? ` (${opt.path})` : ''}...`))
704
708
  parseLocalLanguages(opt, remoteLanguages, (err, localNamespaces) => {
705
- if (err) return handleError(err, cb);
709
+ if (err) return handleError(err, cb)
706
710
 
707
711
  if (!opt.dry && opt.cleanLocalFiles) {
708
- localNamespaces.forEach((ln) => fs.unlinkSync(ln.path));
709
- localNamespaces = [];
712
+ localNamespaces.forEach((ln) => fs.unlinkSync(ln.path))
713
+ localNamespaces = []
710
714
  }
711
715
 
712
- console.log(colors.grey('calculate diffs...'));
713
- handleSync(opt, remoteLanguages, localNamespaces, cb);
714
- });
715
- });
716
- };
716
+ console.log(colors.grey('calculate diffs...'))
717
+ handleSync(opt, remoteLanguages, localNamespaces, cb)
718
+ })
719
+ })
720
+ }
717
721
 
718
722
  const sync = (opt, cb) => {
719
- opt.format = opt.format || 'json';
723
+ opt.format = opt.format || 'json'
720
724
  if (!reversedFileExtensionsMap[opt.format]) {
721
- return handleError(new Error(`${opt.format} is not a valid format!`), cb);
725
+ return handleError(new Error(`${opt.format} is not a valid format!`), cb)
722
726
  }
723
727
 
724
728
  if (opt.autoTranslate && !opt.referenceLanguageOnly) {
725
- console.log(colors.yellow('Using the "--auto-translate true" option together with the "--reference-language-only false" option might result in inconsistent target language translations (automatic translation vs. what is sent direcly to locize).'));
729
+ console.log(colors.yellow('Using the "--auto-translate true" option together with the "--reference-language-only false" option might result in inconsistent target language translations (automatic translation vs. what is sent direcly to locize).'))
726
730
  }
727
731
 
728
- opt.version = opt.version || 'latest';
729
- opt.apiPath = opt.apiPath || 'https://api.locize.app';
732
+ opt.version = opt.version || 'latest'
733
+ opt.apiPath = opt.apiPath || 'https://api.locize.app'
730
734
 
731
- if (!opt.dry && opt.clean) rimraf.sync(path.join(opt.path, '*'));
735
+ if (!opt.dry && opt.clean) rimraf.sync(path.join(opt.path, '*'))
732
736
 
733
737
  if (opt.autoCreatePath === false) {
734
738
  if (!doesDirectoryExist(opt.path)) {
735
- return handleError(new Error(`${opt.path} does not exist!`), cb);
739
+ return handleError(new Error(`${opt.path} does not exist!`), cb)
736
740
  }
737
741
  }
738
- if (!opt.dry) mkdirp.sync(opt.path);
742
+ if (!opt.dry) mkdirp.sync(opt.path)
739
743
 
740
744
  if (opt.namespace && opt.namespace.indexOf(',') > 0 && opt.namespace.indexOf(' ') < 0) {
741
- opt.namespaces = opt.namespace.split(',');
742
- delete opt.namespace;
745
+ opt.namespaces = opt.namespace.split(',')
746
+ delete opt.namespace
743
747
  }
744
748
 
745
- opt.pathMaskInterpolationPrefix = opt.pathMaskInterpolationPrefix || '{{';
746
- opt.pathMaskInterpolationSuffix = opt.pathMaskInterpolationSuffix || '}}';
747
- opt.pathMask = opt.pathMask || `${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}${path.sep}${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`;
748
- opt.languageFolderPrefix = opt.languageFolderPrefix || '';
749
- opt.pathMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, `${opt.languageFolderPrefix}${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`);
749
+ opt.pathMaskInterpolationPrefix = opt.pathMaskInterpolationPrefix || '{{'
750
+ opt.pathMaskInterpolationSuffix = opt.pathMaskInterpolationSuffix || '}}'
751
+ opt.pathMask = opt.pathMask || `${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}${path.sep}${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`
752
+ opt.languageFolderPrefix = opt.languageFolderPrefix || ''
753
+ opt.pathMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, `${opt.languageFolderPrefix}${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`)
750
754
  if (opt.overriddenOnly) {
751
- opt.unpublished = true;
755
+ opt.unpublished = true
752
756
  }
753
757
  if (opt.unpublished && !opt.apiKey) {
754
- return handleError(new Error('Please provide also an api-key!'), cb);
758
+ return handleError(new Error('Please provide also an api-key!'), cb)
755
759
  }
756
760
 
757
761
  if (opt.branch === '') {
758
- return handleError(new Error('The branch name seems invalid!'), cb);
762
+ return handleError(new Error('The branch name seems invalid!'), cb)
759
763
  }
760
764
 
761
765
  if (opt.branch) {
762
766
  getBranches(opt, (err, branches) => {
763
- if (err) return handleError(err, cb);
767
+ if (err) return handleError(err, cb)
764
768
 
765
- let b;
766
- if (isValidUuid(opt.branch)) b = branches.find((br) => br.id === opt.branch);
767
- if (!b) b = branches.find((br) => br.name === opt.branch);
769
+ let b
770
+ if (isValidUuid(opt.branch)) b = branches.find((br) => br.id === opt.branch)
771
+ if (!b) b = branches.find((br) => br.name === opt.branch)
768
772
  if (!b) {
769
- return handleError(new Error(`Branch ${opt.branch} not found!`), cb);
773
+ return handleError(new Error(`Branch ${opt.branch} not found!`), cb)
770
774
  }
771
- opt.projectId = b.id;
772
- opt.version = b.version;
775
+ opt.projectId = b.id
776
+ opt.version = b.version
773
777
 
774
- continueToSync(opt, cb);
775
- });
776
- return;
778
+ continueToSync(opt, cb)
779
+ })
780
+ return
777
781
  }
778
782
 
779
- continueToSync(opt, cb);
780
- };
783
+ continueToSync(opt, cb)
784
+ }
781
785
 
782
- module.exports = sync;
786
+ module.exports = sync