@enplug/scripts 1.11.4-dev6 → 1.11.4-dev61
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.
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const axios = require('axios');
|
|
2
2
|
const chalk = require('chalk');
|
|
3
3
|
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
4
5
|
const FormData = require('form-data');
|
|
5
6
|
const inquirer = require('inquirer');
|
|
6
7
|
const loadDevPrivateFile = require('../loadDevPrivateFile');
|
|
@@ -13,9 +14,7 @@ const { catchError, switchMap, tap, filter } = require('rxjs/operators');
|
|
|
13
14
|
const HTTP_UNAUTHORIZED_STATUS_CODE = 401;
|
|
14
15
|
const HTTP_NOT_FOUND_STATUS_CODE = 404;
|
|
15
16
|
|
|
16
|
-
// const CROWDIN_PROJECT_ID = 'enplug';
|
|
17
17
|
const CROWDIN_PROJECT_ID = '401630';
|
|
18
|
-
// const CROWDIN_PROJECT_URL = `https://api.crowdin.com/api/project/${CROWDIN_PROJECT_ID}`;
|
|
19
18
|
const CROWDIN_PROJECT_URL = `https://api.crowdin.com/api/v2/projects/${CROWDIN_PROJECT_ID}`;
|
|
20
19
|
const CROWDIN_STORAGE_URL = `https://api.crowdin.com/api/v2/storages`;
|
|
21
20
|
const CROWDIN_DIRECTORY_NOT_FOUND_ERROR_CODE = 17;
|
|
@@ -108,115 +107,72 @@ function getCrowdinConfig() {
|
|
|
108
107
|
return pkg.config.crowdin;
|
|
109
108
|
}
|
|
110
109
|
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
async function findCrowdinAppDirectoryId(credentials, crowdinPath) {
|
|
135
|
-
path = crowdinPath.startsWith('/') ? crowdinPath.substr(1) : crowdinPath;
|
|
136
|
-
if(path.startsWith('apps')){
|
|
137
|
-
const appName = path.split('/')[1];
|
|
138
|
-
const url = `${CROWDIN_PROJECT_URL}/directories?filter=${appName}`;
|
|
139
|
-
const AuthStr = 'Bearer '.concat(credentials.token);
|
|
140
|
-
const resp = await axios.get(url, { headers: { Authorization: AuthStr } });
|
|
141
|
-
console.log('resp', resp.data.data);
|
|
142
|
-
console.log('appName', appName);
|
|
143
|
-
const directories = resp.data.data;
|
|
144
|
-
const appdata = directories.find(d => {
|
|
145
|
-
return d.data.name === appName
|
|
146
|
-
});
|
|
147
|
-
console.log('appdata', appdata);
|
|
148
|
-
return appdata.id
|
|
149
|
-
} else if(path.startsWith('dashboard')) {
|
|
150
|
-
const url = `${CROWDIN_PROJECT_URL}/directories?filter=dashboard`;
|
|
151
|
-
const AuthStr = 'Bearer '.concat(credentials.token);
|
|
152
|
-
const directories = axios.get(url, { headers: { Authorization: AuthStr } });
|
|
153
|
-
console.log('directories', directories.data.data)
|
|
154
|
-
|
|
155
|
-
return directories.data.data.find(d => d.data.name === 'dashboard' && d.data.title === 'Dashboard' && d.data.path === '/dashboard').id;
|
|
110
|
+
async function findCrowdinAppDirectoryId(credentials, crowdinPath, appName) {
|
|
111
|
+
try {
|
|
112
|
+
if(crowdinPath.startsWith('apps') || appName !== 'en.json') { // path is apps/{app-name}/... or dashboard/{data-connector or regions-map or uploader}/en.json
|
|
113
|
+
const url = `${CROWDIN_PROJECT_URL}/directories?filter=${appName}`;
|
|
114
|
+
const AuthStr = 'Bearer '.concat(credentials.token);
|
|
115
|
+
const resp = await axios.get(url, { headers: { Authorization: AuthStr } });
|
|
116
|
+
const directory = resp.data.data.find(d => d.data.name === appName );
|
|
117
|
+
return directory ? directory.data.id : undefined;
|
|
118
|
+
} else if((crowdinPath.startsWith('dashboard') || crowdinPath.startsWith('player-web') || crowdinPath.startsWith('components')) && appName === 'en.json') { //path is dashboard/en.json or player-web/en.json or components/en.json
|
|
119
|
+
const url = `${CROWDIN_PROJECT_URL}/directories?filter=dashboard`;
|
|
120
|
+
const AuthStr = 'Bearer '.concat(credentials.token);
|
|
121
|
+
const resp = await axios.get(url, { headers: { Authorization: AuthStr } });
|
|
122
|
+
const directory = resp.data.data.find(d => d.data.name === 'dashboard' && d.data.title === 'Dashboard' && d.data.path === '/dashboard');
|
|
123
|
+
return directory ? directory.data.id : undefined;
|
|
124
|
+
}
|
|
125
|
+
} catch (err) {
|
|
126
|
+
if (err.response.status === HTTP_UNAUTHORIZED_STATUS_CODE) {
|
|
127
|
+
console.error(`\n${chalk.red.bold('Provided Crowdin token is invalid')}`);
|
|
128
|
+
console.log(`Check the ${chalk.default.yellow('dev.private.json')} file.`);
|
|
129
|
+
return throwError(err);
|
|
130
|
+
}
|
|
156
131
|
}
|
|
157
132
|
}
|
|
158
133
|
|
|
159
134
|
async function findCrowdinAppSubFolderId(credentials, directoryId, subfolderName) {
|
|
160
135
|
const url = `${CROWDIN_PROJECT_URL}/directories?directoryId=${directoryId}`;
|
|
161
136
|
const AuthStr = 'Bearer '.concat(credentials.token);
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
return directories.data.data.find(d => d.data.name === subfolderName).id;
|
|
137
|
+
const resp = await axios.get(url, { headers: { Authorization: AuthStr } });
|
|
138
|
+
const subdirectory = resp.data.data.find(d => d.data.name === subfolderName);
|
|
139
|
+
return subdirectory ? subdirectory.data.id : undefined;
|
|
166
140
|
}
|
|
167
141
|
|
|
168
142
|
async function getFileIdIfExists(credentials, directoryId, fileName) {
|
|
169
143
|
const url = `${CROWDIN_PROJECT_URL}/files?directoryId=${directoryId}`;
|
|
170
144
|
const AuthStr = 'Bearer '.concat(credentials.token);
|
|
171
|
-
const
|
|
172
|
-
|
|
145
|
+
const resp = await axios.get(url, { headers: { Authorization: AuthStr } });
|
|
146
|
+
const file = resp.data.data.find(d => d.data.name === fileName);
|
|
147
|
+
return file ? file.data.id : undefined;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function postFileToCrowdin(credentials, localPath) {
|
|
151
|
+
const AuthStr = 'Bearer '.concat(credentials.token);
|
|
152
|
+
const file = fs.readFileSync(localPath);
|
|
153
|
+
const url = `${CROWDIN_STORAGE_URL}`;
|
|
154
|
+
|
|
155
|
+
return from(axios.post(url, file, { headers: {
|
|
156
|
+
"Authorization": AuthStr,
|
|
157
|
+
"Content-Type": 'application/json',
|
|
158
|
+
"Crowdin-API-FileName": 'en.json'
|
|
159
|
+
} }));
|
|
173
160
|
}
|
|
174
161
|
|
|
175
|
-
async function uploadFileToCrowdinStorage(credentials,
|
|
162
|
+
async function uploadFileToCrowdinStorage(credentials, localPath) {
|
|
176
163
|
if (!fs.existsSync(localPath)) {
|
|
177
164
|
console.error(`${chalk.red.bold('Local file does not exists')} ${chalk.yellow.bold(`[${localPath}]`)}`);
|
|
178
165
|
throw new Error('Local file does not exist');
|
|
179
166
|
}
|
|
180
|
-
|
|
181
|
-
return postFileToCrowdin('update', credentials, crowdinPath, localPath).pipe(
|
|
167
|
+
return postFileToCrowdin(credentials, localPath).pipe(
|
|
182
168
|
catchError(error => {
|
|
183
|
-
|
|
184
|
-
return promptAddFile(crowdinPath).pipe(
|
|
185
|
-
filter(({addFileConfirm}) => addFileConfirm === true),
|
|
186
|
-
switchMap(() => postFileToCrowdin('add', credentials, crowdinPath, localPath))
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
|
|
169
|
+
console('ERROR could not upload file to crowdin storage')
|
|
190
170
|
return throwError(error);
|
|
191
171
|
}),
|
|
192
|
-
tap({
|
|
193
|
-
next: response => {
|
|
194
|
-
if (response.data) {
|
|
195
|
-
console.log(`${chalk.green.bold('Translations uploaded to Crowdin')} ${chalk.yellow.bold(`[${crowdinPath}]`)}`);
|
|
196
|
-
} else {
|
|
197
|
-
console.error('Unexpected result');
|
|
198
|
-
console.log(response);
|
|
199
|
-
}
|
|
200
|
-
},
|
|
201
|
-
error: error => {
|
|
202
|
-
const crowdinError = error.response && error.response.data && error.response.data.error;
|
|
203
|
-
|
|
204
|
-
if (crowdinError && crowdinError.code === CROWDIN_DIRECTORY_NOT_FOUND_ERROR_CODE) {
|
|
205
|
-
console.error(`\n${chalk.red.bold('Directory does not exist')} ${chalk.yellow.bold(`[${crowdinPath}]`)}`);
|
|
206
|
-
console.log('Create the directory in the Crowdin panel first.');
|
|
207
|
-
} else if (error.response.status === HTTP_UNAUTHORIZED_STATUS_CODE) {
|
|
208
|
-
console.error(`\n${chalk.red.bold('Provided Crowdin credentials are incorrect')}`);
|
|
209
|
-
console.log(`Check the ${chalk.default.yellow('dev.private.json')} file.`);
|
|
210
|
-
} else {
|
|
211
|
-
console.error('\nUnexpected error:');
|
|
212
|
-
console.error(error);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
})
|
|
216
172
|
).toPromise();
|
|
217
173
|
}
|
|
218
174
|
|
|
219
|
-
function updateCrowdinFile(credentials, storageId, fileId) {
|
|
175
|
+
async function updateCrowdinFile(credentials, crowdinPath, storageId, fileId) {
|
|
220
176
|
const url = `${CROWDIN_PROJECT_URL}/files/${fileId}`;
|
|
221
177
|
const AuthStr = 'Bearer '.concat(credentials.token);
|
|
222
178
|
const body = {
|
|
@@ -231,19 +187,66 @@ function updateCrowdinFile(credentials, storageId, fileId) {
|
|
|
231
187
|
},
|
|
232
188
|
"replaceModifiedContext": false
|
|
233
189
|
}
|
|
234
|
-
return axios.put(url, body, { headers: { Authorization: AuthStr } })
|
|
190
|
+
return from(axios.put(url, body, { headers: { Authorization: AuthStr } })).pipe(tap({
|
|
191
|
+
next: response => {
|
|
192
|
+
if (response.data) {
|
|
193
|
+
console.log(`${chalk.green.bold('Translations uploaded to Crowdin')} ${chalk.yellow.bold(`[${crowdinPath}]`)}`);
|
|
194
|
+
} else {
|
|
195
|
+
console.error('Unexpected result');
|
|
196
|
+
console.log(response);
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
error: error => {
|
|
200
|
+
console.error('\nUnexpected error:');
|
|
201
|
+
console.error(error);
|
|
202
|
+
}
|
|
203
|
+
})).toPromise();
|
|
235
204
|
}
|
|
236
205
|
|
|
237
|
-
function
|
|
238
|
-
const url = `${CROWDIN_PROJECT_URL}/
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
206
|
+
async function addCrowdinFile(credentials, crowdinPath, storageId, folderId) {
|
|
207
|
+
const url = `${CROWDIN_PROJECT_URL}/files`;
|
|
208
|
+
const AuthStr = 'Bearer '.concat(credentials.token);
|
|
209
|
+
const body = {
|
|
210
|
+
"storageId": storageId,
|
|
211
|
+
"name": "en.json",
|
|
212
|
+
"directoryId": folderId,
|
|
213
|
+
"context": null,
|
|
214
|
+
"type": "json",
|
|
215
|
+
"parserVersion": 1,
|
|
216
|
+
"importOptions": {
|
|
217
|
+
"contentSegmentation": false,
|
|
218
|
+
"customSegmentation": false
|
|
219
|
+
},
|
|
220
|
+
"exportOptions": {
|
|
221
|
+
"exportPattern": "%locale%.json"
|
|
222
|
+
},
|
|
223
|
+
"excludedTargetLanguages": null
|
|
224
|
+
}
|
|
225
|
+
return from(axios.post(url, body, { headers: { Authorization: AuthStr } })).pipe(tap({
|
|
226
|
+
next: response => {
|
|
227
|
+
if (response.data) {
|
|
228
|
+
console.log(`${chalk.green.bold('Translations uploaded to Crowdin')} ${chalk.yellow.bold(`[${crowdinPath}]`)}`);
|
|
229
|
+
} else {
|
|
230
|
+
console.error('Unexpected result');
|
|
231
|
+
console.log(response);
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
error: error => {
|
|
235
|
+
console.error('\nUnexpected error:');
|
|
236
|
+
console.error(error);
|
|
237
|
+
}
|
|
238
|
+
})).toPromise();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function fetchFileFromCrowdin(credentials, language, fileId) {
|
|
242
|
+
const url = `${CROWDIN_PROJECT_URL}/translations/exports`;
|
|
243
|
+
const AuthStr = 'Bearer '.concat(credentials.token);
|
|
244
|
+
const body = {
|
|
245
|
+
"targetLanguageId": language,
|
|
246
|
+
"fileIds": [fileId]
|
|
244
247
|
};
|
|
245
248
|
|
|
246
|
-
return axios.
|
|
249
|
+
return axios.post(url, body, { headers: { Authorization: AuthStr } });
|
|
247
250
|
}
|
|
248
251
|
|
|
249
252
|
function promptAddFile(crowdinPath) {
|
|
@@ -256,4 +259,4 @@ function promptAddFile(crowdinPath) {
|
|
|
256
259
|
}));
|
|
257
260
|
}
|
|
258
261
|
|
|
259
|
-
module.exports = { getCrowdinCredentials, getCrowdinConfig, findCrowdinAppDirectoryId, findCrowdinAppSubFolderId, getFileIdIfExists, uploadFileToCrowdinStorage, updateCrowdinFile, uploadFileToCrowdin, fetchFileFromCrowdin };
|
|
262
|
+
module.exports = { getCrowdinCredentials, getCrowdinConfig, findCrowdinAppDirectoryId, findCrowdinAppSubFolderId, getFileIdIfExists, uploadFileToCrowdinStorage, updateCrowdinFile, addCrowdinFile, uploadFileToCrowdin, fetchFileFromCrowdin };
|
|
@@ -5,7 +5,7 @@ const inquirer = require('inquirer');
|
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const path = require('path');
|
|
7
7
|
|
|
8
|
-
const { getCrowdinCredentials, getCrowdinConfig, findCrowdinAppDirectoryId, findCrowdinAppSubFolderId, getFileIdIfExists, uploadFileToCrowdinStorage, updateCrowdinFile, uploadFileToCrowdin, fetchFileFromCrowdin } = require('./crowdin');
|
|
8
|
+
const { getCrowdinCredentials, getCrowdinConfig, findCrowdinAppDirectoryId, findCrowdinAppSubFolderId, getFileIdIfExists, uploadFileToCrowdinStorage, updateCrowdinFile, addCrowdinFile, uploadFileToCrowdin, fetchFileFromCrowdin } = require('./crowdin');
|
|
9
9
|
const { checkKeys, validateTranslationFile } = require('./transloco');
|
|
10
10
|
const { uploadTranslationToS3 } = require('./translation-s3');
|
|
11
11
|
const getPackageJson = require('../getPackageJson');
|
|
@@ -61,34 +61,80 @@ async function syncTranslations(s3Client, bucket) {
|
|
|
61
61
|
await uploadTranslationToS3(s3Client, bucket, s3EnPath, enTranslation);
|
|
62
62
|
|
|
63
63
|
if (isProduction) {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
const crowdinPath = config.crowdinPath.startsWith('/') ? config.crowdinPath.substr(1) : config.crowdinPath;
|
|
65
|
+
const crowdinPathSections = crowdinPath.split('/');
|
|
66
|
+
const appName = crowdinPathSections[1];
|
|
67
|
+
const appDirectoryId = await findCrowdinAppDirectoryId(credentials, crowdinPath, appName);
|
|
68
|
+
if(appDirectoryId === undefined) {
|
|
69
|
+
console.error(`\n${chalk.red.bold('Directory does not exist')} ${chalk.yellow.bold(`${appName}`)}`);
|
|
70
|
+
console.log('Create the directory in the Crowdin panel first.');
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if(crowdinPathSections[0] === 'apps' && appDirectoryId) {
|
|
74
|
+
if(crowdinPathSections.length !== 4 && crowdinPathSections[3] !== 'en.json') {
|
|
75
|
+
console.error(`\n${chalk.red.bold('Crowdin path provided does not match defined format, make sure the path is as follows /apps/{app-id}/dashboard/en.json or /apps/{app-id}/app/en.json')}`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const subfolderName = crowdinPathSections[2]; //dashboard or app folder
|
|
69
79
|
const folderId = await findCrowdinAppSubFolderId(credentials, appDirectoryId, subfolderName);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const
|
|
80
|
+
if(folderId === undefined) {
|
|
81
|
+
console.error(`Could not find ${chalk.yellow.bold(`[${subfolderName}]`)} folder`);
|
|
82
|
+
}
|
|
83
|
+
const fileId = await getFileIdIfExists(credentials, folderId, crowdinPathSections[3]); // en.json file id to update
|
|
74
84
|
if(fileId) {
|
|
75
|
-
await
|
|
85
|
+
const storageId = await uploadFileToCrowdinStorage(credentials, config.localPath);
|
|
86
|
+
if(fileId && storageId) {
|
|
87
|
+
await updateCrowdinFile(credentials, crowdinPath, storageId.data.data.id, fileId);
|
|
88
|
+
await updateFrakeTranslations(credentials, fileId);
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
const storageId = await uploadFileToCrowdinStorage(credentials, config.localPath);
|
|
92
|
+
if(storageId) {
|
|
93
|
+
const result = await addCrowdinFile(credentials, crowdinPath, storageId.data.data.id, folderId);
|
|
94
|
+
console.log('add result', result.data);
|
|
95
|
+
// await updateFrakeTranslations(credentials, fileId);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} else if((crowdinPathSections[0] === 'dashboard' || crowdinPathSections[0] === 'player-web' || crowdinPathSections[0] === 'components') && appDirectoryId) {
|
|
99
|
+
if(crowdinPathSections[1] === 'en.json') {
|
|
100
|
+
const fileId = await getFileIdIfExists(credentials, appDirectoryId, crowdinPathSections[1]); // en.json file id to update
|
|
101
|
+
if(fileId) {
|
|
102
|
+
const storageId = await uploadFileToCrowdinStorage(credentials, config.localPath);
|
|
103
|
+
if(fileId && storageId) {
|
|
104
|
+
await updateCrowdinFile(credentials, crowdinPath, storageId.data.data.id, fileId);
|
|
105
|
+
await updateFrakeTranslations(credentials, fileId);
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
console.error(`Could not upload ${chalk.yellow.bold(`${rowdinPathSections[1]}`)}. Only en.json supported.`);
|
|
109
|
+
}
|
|
110
|
+
} else { // data-connector, regions-map and uploader in dashboard folder
|
|
111
|
+
const folderId = await findCrowdinAppDirectoryId(credentials, crowdinPath, crowdinPathSections[1]);
|
|
112
|
+
if(folderId === undefined) {
|
|
113
|
+
console.error(`Could not find ${chalk.yellow.bold(`${folderId}`)} folder`);
|
|
114
|
+
}
|
|
115
|
+
const fileId = await getFileIdIfExists(credentials, folderId, crowdinPathSections[2]); // en.json file id to update
|
|
116
|
+
const storageId = await uploadFileToCrowdinStorage(credentials, config.localPath);
|
|
117
|
+
if(fileId && storageId) {
|
|
118
|
+
await updateCrowdinFile(credentials, crowdinPath, storageId.data.data.id, fileId);
|
|
119
|
+
await updateFrakeTranslations(credentials, fileId);
|
|
120
|
+
}
|
|
76
121
|
}
|
|
77
|
-
} else {
|
|
78
|
-
// TODO Update dashboard transtlations file
|
|
79
122
|
}
|
|
80
|
-
// await uploadFileToCrowdin(credentials, config.crowdinPath, config.localPath);
|
|
81
|
-
// const { data: fakeTranslation } = await fetchFileFromCrowdin(credentials, config.crowdinPath, FAKE_IN_CONTEXT_LANGUAGE);
|
|
82
|
-
|
|
83
|
-
// const s3TranslationsPath = path.parse(s3EnPath).dir;
|
|
84
|
-
// const s3FakeTranslationPath = path.join(s3TranslationsPath, FAKE_IN_CONTEXT_LANGUAGE_FILE);
|
|
85
|
-
|
|
86
|
-
// await uploadTranslationToS3(s3Client, bucket, s3FakeTranslationPath, JSON.stringify(fakeTranslation));
|
|
87
123
|
}
|
|
88
124
|
}
|
|
89
125
|
}
|
|
90
126
|
}
|
|
91
127
|
|
|
128
|
+
async function updateFrakeTranslations(credentials, fileId) {
|
|
129
|
+
const { data: fakeTranslation } = await fetchFileFromCrowdin(credentials, FAKE_IN_CONTEXT_LANGUAGE, fileId);
|
|
130
|
+
console.log('eo data', fakeTranslation);
|
|
131
|
+
const s3TranslationsPath = path.parse(s3EnPath).dir;
|
|
132
|
+
console.log('s3TranslationsPath', s3TranslationsPath);
|
|
133
|
+
const s3FakeTranslationPath = path.join(s3TranslationsPath, FAKE_IN_CONTEXT_LANGUAGE_FILE);
|
|
134
|
+
console.log('s3FakeTranslationPath', s3FakeTranslationPath);
|
|
135
|
+
// await uploadTranslationToS3(s3Client, bucket, s3FakeTranslationPath, JSON.stringify(fakeTranslation));
|
|
136
|
+
}
|
|
137
|
+
|
|
92
138
|
async function promptForceContinue() {
|
|
93
139
|
return inquirer.prompt({
|
|
94
140
|
type: 'confirm',
|