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/CHANGELOG.md +3 -0
- package/README.md +2 -0
- package/add.js +49 -47
- package/bin/locize +693 -481
- package/combineSubkeyPreprocessor.js +86 -85
- package/convertToDesiredFormat.js +125 -125
- package/convertToFlatFormat.js +154 -154
- package/copyVersion.js +36 -36
- package/createBranch.js +32 -32
- package/deleteBranch.js +50 -50
- package/deleteNamespace.js +20 -20
- package/download.js +285 -283
- package/filterNamespaces.js +5 -5
- package/format.js +101 -101
- package/formats.js +10 -10
- package/get.js +40 -36
- package/getBranches.js +21 -21
- package/getJob.js +21 -21
- package/getProjectStats.js +21 -21
- package/getRemoteLanguages.js +19 -19
- package/getRemoteNamespace.js +59 -55
- package/index.js +1 -1
- package/isValidUuid.js +2 -2
- package/mergeBranch.js +53 -53
- package/migrate.js +148 -149
- package/missing.js +89 -89
- package/package.json +4 -2
- package/parseLocalLanguage.js +110 -110
- package/parseLocalLanguages.js +14 -14
- package/parseLocalReference.js +6 -6
- package/publishVersion.js +33 -33
- package/removeUndefinedFromArrays.js +8 -8
- package/removeVersion.js +33 -33
- package/request.js +32 -32
- package/shouldUnflatten.js +11 -11
- package/sortFlatResources.js +7 -7
- package/sync.js +417 -413
- package/unflatten.js +40 -40
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
|
-
|
|
44
|
-
|
|
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)
|
|
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)
|
|
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)
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
389
|
-
|
|
390
|
+
const tasks = []
|
|
391
|
+
const keysInObj = Object.keys(data)
|
|
390
392
|
|
|
391
393
|
while (keysInObj.length > payloadKeysLimit) {
|
|
392
|
-
(function() {
|
|
393
|
-
|
|
394
|
-
keysInObj.splice(0, payloadKeysLimit).forEach((k) => pagedData[k] = data[k])
|
|
395
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
488
|
-
if (m < 10) m = `0${m}
|
|
489
|
-
|
|
490
|
-
if (d < 10) d = `0${d}
|
|
491
|
-
|
|
492
|
-
if (h < 10) h = `0${h}
|
|
493
|
-
|
|
494
|
-
if (mi < 10) mi = `0${mi}
|
|
495
|
-
|
|
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
|
-
|
|
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)
|
|
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
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
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
|
-
|
|
613
|
-
|
|
614
|
-
|
|
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
|
-
|
|
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
|