locize-cli 11.0.0 → 12.0.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.
Files changed (108) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +1 -1
  3. package/README.md +1 -0
  4. package/dist/cjs/add.js +90 -0
  5. package/{bin/locize → dist/cjs/cli.js} +390 -670
  6. package/dist/cjs/combineSubkeyPreprocessor.js +155 -0
  7. package/dist/cjs/convertToDesiredFormat.js +205 -0
  8. package/dist/cjs/convertToFlatFormat.js +231 -0
  9. package/dist/cjs/copyVersion.js +60 -0
  10. package/dist/cjs/createBranch.js +59 -0
  11. package/dist/cjs/deleteBranch.js +89 -0
  12. package/dist/cjs/deleteNamespace.js +37 -0
  13. package/dist/cjs/download.js +376 -0
  14. package/dist/cjs/filterNamespaces.js +13 -0
  15. package/dist/cjs/format.js +156 -0
  16. package/dist/cjs/formats.js +33 -0
  17. package/dist/cjs/get.js +66 -0
  18. package/dist/cjs/getBranches.js +37 -0
  19. package/dist/cjs/getJob.js +37 -0
  20. package/dist/cjs/getProjectStats.js +37 -0
  21. package/dist/cjs/getRemoteLanguages.js +38 -0
  22. package/dist/cjs/getRemoteNamespace.js +125 -0
  23. package/dist/cjs/index.js +37 -0
  24. package/dist/cjs/isValidUuid.js +6 -0
  25. package/dist/cjs/lngs.js +215 -0
  26. package/dist/cjs/mapLimit.js +22 -0
  27. package/dist/cjs/mergeBranch.js +80 -0
  28. package/dist/cjs/migrate.js +239 -0
  29. package/dist/cjs/missing.js +162 -0
  30. package/dist/cjs/package.json +5 -0
  31. package/{parseLocalLanguage.js → dist/cjs/parseLocalLanguage.js} +135 -142
  32. package/dist/cjs/parseLocalLanguages.js +18 -0
  33. package/dist/cjs/parseLocalReference.js +11 -0
  34. package/dist/cjs/publishVersion.js +42 -0
  35. package/dist/cjs/removeUndefinedFromArrays.js +19 -0
  36. package/dist/cjs/removeVersion.js +42 -0
  37. package/dist/cjs/request.js +66 -0
  38. package/dist/cjs/shouldUnflatten.js +21 -0
  39. package/dist/cjs/sortFlatResources.js +13 -0
  40. package/dist/cjs/sync.js +772 -0
  41. package/dist/cjs/unflatten.js +81 -0
  42. package/dist/esm/add.js +88 -0
  43. package/dist/esm/cli.js +1020 -0
  44. package/{combineSubkeyPreprocessor.js → dist/esm/combineSubkeyPreprocessor.js} +70 -73
  45. package/dist/esm/convertToDesiredFormat.js +203 -0
  46. package/dist/esm/convertToFlatFormat.js +229 -0
  47. package/dist/esm/copyVersion.js +58 -0
  48. package/dist/esm/createBranch.js +57 -0
  49. package/dist/esm/deleteBranch.js +87 -0
  50. package/dist/esm/deleteNamespace.js +35 -0
  51. package/dist/esm/download.js +374 -0
  52. package/{filterNamespaces.js → dist/esm/filterNamespaces.js} +4 -4
  53. package/dist/esm/format.js +154 -0
  54. package/{formats.js → dist/esm/formats.js} +7 -11
  55. package/dist/esm/get.js +64 -0
  56. package/dist/esm/getBranches.js +35 -0
  57. package/dist/esm/getJob.js +35 -0
  58. package/dist/esm/getProjectStats.js +35 -0
  59. package/dist/esm/getRemoteLanguages.js +36 -0
  60. package/dist/esm/getRemoteNamespace.js +123 -0
  61. package/dist/esm/index.js +16 -0
  62. package/dist/esm/isValidUuid.js +4 -0
  63. package/dist/esm/lngs.js +213 -0
  64. package/dist/esm/mapLimit.js +20 -0
  65. package/dist/esm/mergeBranch.js +78 -0
  66. package/dist/esm/migrate.js +237 -0
  67. package/dist/esm/missing.js +160 -0
  68. package/dist/esm/parseLocalLanguage.js +194 -0
  69. package/dist/esm/parseLocalLanguages.js +16 -0
  70. package/dist/esm/parseLocalReference.js +9 -0
  71. package/dist/esm/publishVersion.js +40 -0
  72. package/{removeUndefinedFromArrays.js → dist/esm/removeUndefinedFromArrays.js} +5 -5
  73. package/dist/esm/removeVersion.js +40 -0
  74. package/dist/esm/request.js +64 -0
  75. package/{shouldUnflatten.js → dist/esm/shouldUnflatten.js} +7 -7
  76. package/dist/esm/sortFlatResources.js +11 -0
  77. package/dist/esm/sync.js +770 -0
  78. package/{unflatten.js → dist/esm/unflatten.js} +36 -34
  79. package/package.json +39 -18
  80. package/rollup.config.js +57 -0
  81. package/add.js +0 -105
  82. package/convertToDesiredFormat.js +0 -268
  83. package/convertToFlatFormat.js +0 -322
  84. package/copyVersion.js +0 -69
  85. package/createBranch.js +0 -61
  86. package/deleteBranch.js +0 -97
  87. package/deleteNamespace.js +0 -39
  88. package/download.js +0 -516
  89. package/format.js +0 -206
  90. package/get.js +0 -81
  91. package/getBranches.js +0 -40
  92. package/getJob.js +0 -40
  93. package/getProjectStats.js +0 -40
  94. package/getRemoteLanguages.js +0 -40
  95. package/getRemoteNamespace.js +0 -122
  96. package/index.js +0 -9
  97. package/isValidUuid.js +0 -2
  98. package/lngs.json +0 -211
  99. package/mergeBranch.js +0 -102
  100. package/migrate.js +0 -314
  101. package/missing.js +0 -169
  102. package/parseLocalLanguages.js +0 -22
  103. package/parseLocalReference.js +0 -10
  104. package/publishVersion.js +0 -64
  105. package/removeVersion.js +0 -64
  106. package/request.js +0 -64
  107. package/sortFlatResources.js +0 -9
  108. package/sync.js +0 -786
package/download.js DELETED
@@ -1,516 +0,0 @@
1
- const colors = require('colors')
2
- const { mkdirp } = require('mkdirp')
3
- const rimraf = require('rimraf')
4
- const request = require('./request')
5
- const fs = require('fs')
6
- const path = require('path')
7
- const async = require('async')
8
- const flatten = require('flat')
9
- const getRemoteNamespace = require('./getRemoteNamespace')
10
- const getRemoteLanguages = require('./getRemoteLanguages')
11
- const convertToDesiredFormat = require('./convertToDesiredFormat')
12
- const formats = require('./formats')
13
- const getProjectStats = require('./getProjectStats')
14
- const reversedFileExtensionsMap = formats.reversedFileExtensionsMap
15
- const locize2xcstrings = require('locize-xcstrings/cjs/locize2xcstrings')
16
- const getBranches = require('./getBranches')
17
- const isValidUuid = require('./isValidUuid')
18
-
19
- function getInfosInUrl (download) {
20
- const splitted = download.key.split('/')
21
- const version = splitted[download.isPrivate ? 2 : 1]
22
- const language = splitted[download.isPrivate ? 3 : 2]
23
- const namespace = splitted[download.isPrivate ? 4 : 3]
24
- return { version, language, namespace }
25
- }
26
-
27
- function handleDownload (opt, url, err, res, downloads, cb) {
28
- if (err || (downloads && (downloads.errorMessage || downloads.message))) {
29
- if (!cb) console.log(colors.red(`download failed for ${url} to ${opt.path}...`))
30
-
31
- if (err) {
32
- if (!cb) { console.error(colors.red(err.message)); process.exit(1) }
33
- if (cb) cb(err)
34
- return
35
- }
36
- if (downloads && (downloads.errorMessage || downloads.message)) {
37
- if (!cb) { console.error(colors.red((downloads.errorMessage || downloads.message))); process.exit(1) }
38
- if (cb) cb(new Error((downloads.errorMessage || downloads.message)))
39
- return
40
- }
41
- }
42
- if (res.status >= 300) {
43
- if (!cb) { console.error(colors.red(res.statusText + ' (' + res.status + ')')); process.exit(1) }
44
- if (cb) cb(new Error(res.statusText + ' (' + res.status + ')'))
45
- return
46
- }
47
-
48
- if (opt.format === 'xcstrings') { // 1 file per namespace including all languages
49
- const downloadsByNamespace = {}
50
- downloads.forEach((download) => {
51
- const { version, namespace } = getInfosInUrl(download)
52
- opt.isPrivate = download.isPrivate
53
-
54
- downloadsByNamespace[version] = downloadsByNamespace[version] || {}
55
- downloadsByNamespace[version][namespace] = downloadsByNamespace[version][namespace] || []
56
- downloadsByNamespace[version][namespace].push(download)
57
- })
58
-
59
- async.eachSeries(Object.keys(downloadsByNamespace), (version, clb) => {
60
- async.eachLimit(Object.keys(downloadsByNamespace[version]), 20, (ns, clb) => {
61
- if (opt.namespace && opt.namespace !== ns) return clb(null)
62
- if (opt.namespaces && opt.namespaces.length > 0 && opt.namespaces.indexOf(ns) < 0) return clb(null)
63
-
64
- const locizeData = {
65
- sourceLng: opt.referenceLanguage,
66
- resources: {}
67
- }
68
- async.eachLimit(downloadsByNamespace[version][ns], 20, (download, clb2) => {
69
- const { language } = getInfosInUrl(download)
70
- getRemoteNamespace(opt, language, ns, (err, ns, lastModified) => {
71
- if (err) return clb2(err)
72
-
73
- if (opt.skipEmpty && Object.keys(flatten(ns)).length === 0) {
74
- return clb2(null)
75
- }
76
-
77
- locizeData.resources[language] = ns
78
- clb2()
79
- })
80
- }, (err) => {
81
- if (err) return clb(err)
82
-
83
- try {
84
- const converted = locize2xcstrings(locizeData)
85
-
86
- const filledMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, '').replace(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`, ns) + reversedFileExtensionsMap[opt.format]
87
- let mkdirPath
88
- if (filledMask.lastIndexOf(path.sep) > 0) {
89
- mkdirPath = filledMask.substring(0, filledMask.lastIndexOf(path.sep))
90
- }
91
-
92
- function logAndClb (err) {
93
- if (err) return clb(err)
94
- if (!cb) console.log(colors.green(`downloaded ${version}/${ns} to ${opt.path}...`))
95
- if (clb) clb(null)
96
- }
97
-
98
- const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted
99
- if (!opt.version) {
100
- if (mkdirPath) mkdirp.sync(path.join(opt.path, version, mkdirPath))
101
- fs.writeFile(path.join(opt.path, version, filledMask), fileContent, logAndClb)
102
- return
103
- }
104
-
105
- if (mkdirPath) mkdirp.sync(path.join(opt.path, mkdirPath))
106
- fs.writeFile(path.join(opt.path, filledMask), converted, logAndClb)
107
- } catch (e) {
108
- err.message = 'Invalid content for "' + opt.format + '" format!\n' + (err.message || '')
109
- return clb(err)
110
- }
111
- })
112
- }, clb)
113
- }, (err) => {
114
- if (err) {
115
- if (!cb) {
116
- console.error(colors.red(err.message))
117
- process.exit(1)
118
- }
119
- if (cb) cb(err)
120
- return
121
- }
122
-
123
- if (cb) cb(null)
124
- })
125
- } else { // 1 file per namespace/lng
126
- async.eachLimit(downloads, 20, (download, clb) => {
127
- const { version, language, namespace } = getInfosInUrl(download)
128
- opt.isPrivate = download.isPrivate
129
-
130
- if (opt.namespace && opt.namespace !== namespace) return clb(null)
131
- if (opt.namespaces && opt.namespaces.length > 0 && opt.namespaces.indexOf(namespace) < 0) return clb(null)
132
-
133
- getRemoteNamespace(opt, language, namespace, (err, ns, lastModified) => {
134
- if (err) return clb(err)
135
-
136
- if (opt.skipEmpty && Object.keys(flatten(ns)).length === 0) {
137
- return clb(null)
138
- }
139
-
140
- convertToDesiredFormat(opt, namespace, language, ns, lastModified, (err, converted) => {
141
- if (err) {
142
- err.message = 'Invalid content for "' + opt.format + '" format!\n' + (err.message || '')
143
- return clb(err)
144
- }
145
- let filledMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, language).replace(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`, namespace) + reversedFileExtensionsMap[opt.format]
146
- let mkdirPath
147
- if (filledMask.lastIndexOf(path.sep) > 0) {
148
- mkdirPath = filledMask.substring(0, filledMask.lastIndexOf(path.sep))
149
- }
150
- const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted
151
- if (!opt.version) {
152
- if (mkdirPath) mkdirp.sync(path.join(opt.path, version, mkdirPath))
153
- fs.writeFile(path.join(opt.path, version, filledMask), fileContent, clb)
154
- return
155
- }
156
- if (!opt.language) {
157
- if (mkdirPath) mkdirp.sync(path.join(opt.path, mkdirPath))
158
- fs.writeFile(path.join(opt.path, filledMask), fileContent, clb)
159
- return
160
- }
161
-
162
- if (opt.languageFolderPrefix && filledMask.indexOf(path.sep) > 0) filledMask = filledMask.replace(opt.languageFolderPrefix + language, '')
163
- // if (opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`) > opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`) && filledMask.lastIndexOf(path.sep) > 0) {
164
- // mkdirp.sync(path.join(opt.path, filledMask.substring(0, filledMask.lastIndexOf(path.sep))));
165
- // }
166
- const parentDir = path.dirname(path.join(opt.path, filledMask))
167
- mkdirp.sync(parentDir)
168
- fs.writeFile(path.join(opt.path, filledMask), fileContent, clb)
169
- })
170
- })
171
- }, (err) => {
172
- if (err) {
173
- if (!cb) {
174
- console.error(colors.red(err.message))
175
- process.exit(1)
176
- }
177
- if (cb) cb(err)
178
- return
179
- }
180
-
181
- if (!cb) console.log(colors.green(`downloaded ${url} to ${opt.path}...`))
182
- if (cb) cb(null)
183
- })
184
- }
185
- }
186
-
187
- function handlePull (opt, toDownload, cb) {
188
- const url = opt.apiEndpoint + '/pull/' + opt.projectId + '/' + opt.version
189
-
190
- if (opt.format === 'xcstrings') { // 1 file per namespace including all languages
191
- const downloadsByNamespace = {}
192
- toDownload.forEach((download) => {
193
- const { namespace } = download
194
- downloadsByNamespace[namespace] = downloadsByNamespace[namespace] || []
195
- downloadsByNamespace[namespace].push(download)
196
- })
197
-
198
- async.eachLimit(Object.keys(downloadsByNamespace), 5, (namespace, clb) => {
199
- if (opt.namespace && opt.namespace !== namespace) return clb(null)
200
- if (opt.namespaces && opt.namespaces.length > 0 && opt.namespaces.indexOf(namespace) < 0) return clb(null)
201
-
202
- const locizeData = {
203
- sourceLng: opt.referenceLanguage,
204
- resources: {}
205
- }
206
-
207
- async.eachLimit(downloadsByNamespace[namespace], 5, (download, clb2) => {
208
- const { language } = download
209
- opt.raw = true
210
- getRemoteNamespace(opt, language, namespace, (err, ns, lastModified) => {
211
- if (err) return clb2(err)
212
-
213
- if (opt.skipEmpty && Object.keys(flatten(ns)).length === 0) {
214
- return clb2(null)
215
- }
216
-
217
- locizeData.resources[language] = ns
218
- clb2()
219
- })
220
- }, (err) => {
221
- if (err) return clb(err)
222
-
223
- try {
224
- const result = locize2xcstrings(locizeData)
225
- const converted = JSON.stringify(result, null, 2)
226
-
227
- const filledMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, '').replace(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`, namespace) + reversedFileExtensionsMap[opt.format]
228
- let mkdirPath
229
- if (filledMask.lastIndexOf(path.sep) > 0) {
230
- mkdirPath = filledMask.substring(0, filledMask.lastIndexOf(path.sep))
231
- }
232
-
233
- function logAndClb (err) {
234
- if (err) return clb(err)
235
- if (!cb) console.log(colors.green(`downloaded ${opt.version}/${namespace} to ${opt.path}...`))
236
- if (clb) clb(null)
237
- }
238
-
239
- if (mkdirPath) mkdirp.sync(path.join(opt.path, mkdirPath))
240
- const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted
241
- fs.writeFile(path.join(opt.path, filledMask), fileContent, logAndClb)
242
- } catch (e) {
243
- err.message = 'Invalid content for "' + opt.format + '" format!\n' + (err.message || '')
244
- return clb(err)
245
- }
246
- })
247
- }, (err) => {
248
- if (err) {
249
- if (!cb) {
250
- console.error(colors.red(err.message))
251
- process.exit(1)
252
- }
253
- if (cb) cb(err)
254
- return
255
- }
256
-
257
- if (cb) cb(null)
258
- })
259
- } else { // 1 file per namespace/lng
260
- async.eachLimit(toDownload, 5, (download, clb) => {
261
- const lng = download.language
262
- const namespace = download.namespace
263
-
264
- if (opt.namespace && opt.namespace !== namespace) return clb(null)
265
- if (opt.namespaces && opt.namespaces.length > 0 && opt.namespaces.indexOf(namespace) < 0) return clb(null)
266
-
267
- getRemoteNamespace(opt, lng, namespace, (err, ns, lastModified) => {
268
- if (err) return clb(err)
269
-
270
- if (opt.skipEmpty && Object.keys(flatten(ns)).length === 0) {
271
- return clb(null)
272
- }
273
-
274
- convertToDesiredFormat(opt, namespace, lng, ns, lastModified, (err, converted) => {
275
- if (err) {
276
- err.message = 'Invalid content for "' + opt.format + '" format!\n' + (err.message || '')
277
- return clb(err)
278
- }
279
- let filledMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, lng).replace(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`, namespace) + reversedFileExtensionsMap[opt.format]
280
- let mkdirPath
281
- if (filledMask.lastIndexOf(path.sep) > 0) {
282
- mkdirPath = filledMask.substring(0, filledMask.lastIndexOf(path.sep))
283
- }
284
- const fileContent = (opt.format !== 'xlsx' && !converted.endsWith('\n')) ? (converted + '\n') : converted
285
- if (!opt.language) {
286
- if (mkdirPath) mkdirp.sync(path.join(opt.path, mkdirPath))
287
- fs.writeFile(path.join(opt.path, filledMask), fileContent, clb)
288
- return
289
- }
290
-
291
- if (opt.languageFolderPrefix && filledMask.indexOf(path.sep) > 0) filledMask = filledMask.replace(opt.languageFolderPrefix + lng, '')
292
- // if (opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`) > opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`) && filledMask.lastIndexOf(path.sep) > 0) {
293
- // mkdirp.sync(path.join(opt.path, filledMask.substring(0, filledMask.lastIndexOf(path.sep))));
294
- // }
295
- const parentDir = path.dirname(path.join(opt.path, filledMask))
296
- mkdirp.sync(parentDir)
297
- fs.writeFile(path.join(opt.path, filledMask), fileContent, clb)
298
- })
299
- })
300
- }, (err) => {
301
- if (err) {
302
- if (!cb) {
303
- console.error(colors.red(err.message))
304
- process.exit(1)
305
- }
306
- if (cb) cb(err)
307
- return
308
- }
309
-
310
- if (!cb) console.log(colors.green(`downloaded ${url} to ${opt.path}...`))
311
- if (cb) cb(null)
312
- })
313
- }
314
- }
315
-
316
- const handleError = (err, cb) => {
317
- if (!cb && err) {
318
- console.error(colors.red(err.message))
319
- process.exit(1)
320
- }
321
- if (cb) cb(err)
322
- }
323
-
324
- const filterDownloadsLanguages = (opt, downloads) => {
325
- if (opt.languages) {
326
- downloads = downloads.filter((d) => {
327
- const splitted = d.key.split('/')
328
- // const p = splitted[d.isPrivate ? 1 : 0];
329
- // const v = splitted[d.isPrivate ? 2 : 1];
330
- const l = splitted[d.isPrivate ? 3 : 2]
331
- const n = splitted[d.isPrivate ? 4 : 3]
332
- return opt.languages.indexOf(l) > -1 && (!opt.namespace || opt.namespace === n)
333
- })
334
- }
335
- return downloads
336
- }
337
-
338
- const filterDownloads = (opt, downloads) => {
339
- if (opt.skipEmpty) return filterDownloadsLanguages(opt, downloads.filter((d) => d.size > 2))
340
- if (downloads.length < 1) return downloads
341
-
342
- const allNamespaces = []
343
- const downloadMap = {}
344
- downloads.forEach((d) => {
345
- const splitted = d.key.split('/')
346
- const p = splitted[d.isPrivate ? 1 : 0]
347
- const v = splitted[d.isPrivate ? 2 : 1]
348
- const l = splitted[d.isPrivate ? 3 : 2]
349
- const n = splitted[d.isPrivate ? 4 : 3]
350
- downloadMap[p] = downloadMap[p] || {}
351
- downloadMap[p][v] = downloadMap[p][v] || {}
352
- downloadMap[p][v][l] = downloadMap[p][v][l] || {}
353
- downloadMap[p][v][l][n] = d
354
- if (allNamespaces.indexOf(n) < 0) allNamespaces.push(n)
355
- })
356
- Object.keys(downloadMap).forEach((projectId) => {
357
- Object.keys(downloadMap[projectId]).forEach((version) => {
358
- Object.keys(downloadMap[projectId][version]).forEach((language) => {
359
- allNamespaces.forEach((namespace) => {
360
- if (!downloadMap[projectId][version][language][namespace]) {
361
- downloads.push({
362
- url: `${opt.apiEndpoint}/${projectId}/${version}/${language}/${namespace}`,
363
- key: `${projectId}/${version}/${language}/${namespace}`,
364
- lastModified: '1960-01-01T00:00:00.000Z',
365
- size: 0
366
- })
367
- }
368
- })
369
- })
370
- })
371
- })
372
- return filterDownloadsLanguages(opt, downloads)
373
- }
374
-
375
- const continueToDownload = (opt, cb) => {
376
- let url = opt.apiEndpoint + '/download/' + opt.projectId
377
-
378
- if (opt.namespace && opt.namespace.indexOf(',') > 0 && opt.namespace.indexOf(' ') < 0) {
379
- opt.namespaces = opt.namespace.split(',')
380
- delete opt.namespace
381
- }
382
-
383
- if (opt.version) {
384
- url += '/' + opt.version
385
- if (!opt.languages && opt.language) {
386
- url += '/' + opt.language
387
- if (opt.namespace) {
388
- url += '/' + opt.namespace
389
- }
390
- }
391
- }
392
-
393
- if (opt.clean) rimraf.sync(path.join(opt.path, '*'))
394
-
395
- mkdirp.sync(opt.path)
396
-
397
- if (!cb) console.log(colors.yellow(`downloading ${url} to ${opt.path}...`))
398
-
399
- getRemoteLanguages(opt, (err) => {
400
- if (err) return handleError(err, cb)
401
-
402
- if (!opt.unpublished) {
403
- request(url, {
404
- method: 'get',
405
- headers: opt.apiKey
406
- ? {
407
- Authorization: opt.apiKey
408
- }
409
- : undefined
410
- }, (err, res, obj) => {
411
- if (res && res.status === 401) {
412
- opt.apiKey = null
413
- request(url, {
414
- method: 'get',
415
- }, (err, res, obj) => {
416
- obj = filterDownloads(opt, obj || [])
417
- handleDownload(opt, url, err, res, obj, cb)
418
- })
419
- return
420
- }
421
-
422
- if (obj.length > 0) {
423
- obj = filterDownloads(opt, obj || [])
424
- return handleDownload(opt, url, err, res, obj, cb)
425
- }
426
-
427
- getProjectStats(opt, (err, res) => {
428
- if (err) return handleError(err, cb)
429
- if (!res) return handleError(new Error('Nothing found!'), cb)
430
- if (!res[opt.version]) return handleError(new Error(`Version "${opt.version}" not found!`), cb)
431
-
432
- obj = filterDownloads(opt, obj || [])
433
- return handleDownload(opt, url, err, res, obj, cb)
434
- })
435
- })
436
- return
437
- }
438
-
439
- getProjectStats(opt, (err, res) => {
440
- if (err) return handleError(err, cb)
441
- if (!res) return handleError(new Error('Nothing found!'), cb)
442
- if (!res[opt.version]) return handleError(new Error(`Version "${opt.version}" not found!`), cb)
443
-
444
- const toDownload = []
445
- const lngsToCheck = opt.language ? [opt.language] : Object.keys(res[opt.version])
446
- lngsToCheck.forEach((l) => {
447
- if (opt.namespaces) {
448
- opt.namespaces.forEach((n) => {
449
- if (!res[opt.version][l][n]) return
450
- if (opt.skipEmpty && res[opt.version][l][n].segmentsTranslated === 0) return
451
- toDownload.push({ language: l, namespace: n })
452
- })
453
- } else if (opt.namespace) {
454
- if (!res[opt.version][l][opt.namespace]) return
455
- if (opt.skipEmpty && res[opt.version][l][opt.namespace].segmentsTranslated === 0) return
456
- toDownload.push({ language: l, namespace: opt.namespace })
457
- } else {
458
- Object.keys(res[opt.version][l]).forEach((n) => {
459
- if (opt.skipEmpty && res[opt.version][l][n].segmentsTranslated === 0) return
460
- toDownload.push({ language: l, namespace: n })
461
- })
462
- }
463
- })
464
- handlePull(opt, toDownload, cb)
465
- })
466
- })
467
- }
468
-
469
- const download = (opt, cb) => {
470
- opt.format = opt.format || 'json'
471
- if (!reversedFileExtensionsMap[opt.format]) {
472
- return handleError(new Error(`${opt.format} is not a valid format!`), cb)
473
- }
474
-
475
- if (opt.skipEmpty === undefined) opt.skipEmpty = true
476
- opt.apiEndpoint = opt.apiEndpoint || 'https://api.locize.app'
477
- opt.version = opt.version || 'latest'
478
- opt.languageFolderPrefix = opt.languageFolderPrefix || ''
479
- opt.path = opt.path || opt.target
480
- opt.pathMaskInterpolationPrefix = opt.pathMaskInterpolationPrefix || '{{'
481
- opt.pathMaskInterpolationSuffix = opt.pathMaskInterpolationSuffix || '}}'
482
- opt.pathMask = opt.pathMask || `${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}${path.sep}${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`
483
- opt.pathMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, `${opt.languageFolderPrefix}${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`)
484
- if (opt.overriddenOnly) {
485
- opt.unpublished = true
486
- }
487
- if (opt.unpublished && !opt.apiKey) {
488
- return handleError(new Error('Please provide also an api-key!'), cb)
489
- }
490
-
491
- if (opt.branch === '') {
492
- return handleError(new Error('The branch name seems invalid!'), cb)
493
- }
494
-
495
- if (opt.branch) {
496
- getBranches(opt, (err, branches) => {
497
- if (err) return handleError(err, cb)
498
-
499
- let b
500
- if (isValidUuid(opt.branch)) b = branches.find((br) => br.id === opt.branch)
501
- if (!b) b = branches.find((br) => br.name === opt.branch)
502
- if (!b) {
503
- return handleError(new Error(`Branch ${opt.branch} not found!`), cb)
504
- }
505
- opt.projectId = b.id
506
- opt.version = b.version
507
-
508
- continueToDownload(opt, cb)
509
- })
510
- return
511
- }
512
-
513
- continueToDownload(opt, cb)
514
- }
515
-
516
- module.exports = download