@crowdin/app-project-module 0.13.3 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/out/handlers/crowdin-file-progress.js +2 -0
- package/out/handlers/crowdin-files.js +3 -0
- package/out/handlers/crowdin-project.js +4 -1
- package/out/handlers/crowdin-update.js +7 -2
- package/out/handlers/custom-file-format/download.js +1 -0
- package/out/handlers/custom-file-format/process.js +2 -0
- package/out/handlers/custom-mt/translate.js +3 -0
- package/out/handlers/install.js +3 -0
- package/out/handlers/integration-data.js +2 -0
- package/out/handlers/integration-login.js +3 -0
- package/out/handlers/integration-logout.js +1 -0
- package/out/handlers/integration-update.js +4 -0
- package/out/handlers/main.js +3 -0
- package/out/handlers/oauth-login.js +9 -1
- package/out/handlers/settings-save.js +1 -0
- package/out/handlers/sync-settings-save.js +2 -0
- package/out/handlers/sync-settings.js +2 -0
- package/out/handlers/uninstall.js +2 -0
- package/out/middlewares/crowdin-client.js +15 -0
- package/out/middlewares/integration-credentials.js +1 -0
- package/out/models/index.d.ts +8 -0
- package/out/util/index.d.ts +2 -1
- package/out/util/index.js +34 -2
- package/out/views/main.handlebars +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,6 +38,7 @@ In both options you will need to provide Crowdin App configuration file. Please
|
|
|
38
38
|
- [Background tasks](#background-tasks)
|
|
39
39
|
- [Error propagation](#error-propagation)
|
|
40
40
|
- [Error interceptor](#error-interceptor)
|
|
41
|
+
- [Debug mode](#debug-mode)
|
|
41
42
|
- [Custom File Format](#custom-file-format)
|
|
42
43
|
- [Custom MT](#custom-mt)
|
|
43
44
|
- [Resources](#resources)
|
|
@@ -412,6 +413,27 @@ configuration.onError = (error) => {
|
|
|
412
413
|
};
|
|
413
414
|
```
|
|
414
415
|
|
|
416
|
+
## Debug mode
|
|
417
|
+
|
|
418
|
+
Also you can turn on the debug mode and application will log everything (useful of debugging).
|
|
419
|
+
|
|
420
|
+
```javascript
|
|
421
|
+
configuration.logger = {
|
|
422
|
+
enabled: true
|
|
423
|
+
};
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Or even you can pass you own function to log messages (e.g. send them to external monitoring system).
|
|
427
|
+
|
|
428
|
+
```javascript
|
|
429
|
+
configuration.logger = {
|
|
430
|
+
enabled: true,
|
|
431
|
+
log: (message) => {
|
|
432
|
+
console.log(message);
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
```
|
|
436
|
+
|
|
415
437
|
## Custom File Format
|
|
416
438
|
|
|
417
439
|
Example of [custom file format module](https://support.crowdin.com/crowdin-apps-modules/#custom-file-format-module).
|
|
@@ -13,7 +13,9 @@ const util_1 = require("../util");
|
|
|
13
13
|
function handle(config) {
|
|
14
14
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
15
15
|
const fileId = Number(req.params.fileId);
|
|
16
|
+
(0, util_1.log)(`Loading translation progress for file ${fileId}`, config.logger);
|
|
16
17
|
const progress = yield req.crowdinApiClient.translationStatusApi.getFileProgress(req.crowdinContext.jwtPayload.context.project_id, fileId);
|
|
18
|
+
(0, util_1.log)(`Translation progress for file ${fileId} ${JSON.stringify(progress.data, null, 2)}`, config.logger);
|
|
17
19
|
res.send({ [fileId]: progress.data.map(e => e.data) });
|
|
18
20
|
}), config.onError);
|
|
19
21
|
}
|
|
@@ -12,11 +12,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
const util_1 = require("../util");
|
|
13
13
|
function handle(config, integration) {
|
|
14
14
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
15
|
+
(0, util_1.log)('Loading crowdin files', config.logger);
|
|
15
16
|
if (integration.getCrowdinFiles) {
|
|
16
17
|
const rootFolder = yield (0, util_1.getRootFolder)(config, integration, req.crowdinApiClient, req.crowdinContext.jwtPayload.context.project_id);
|
|
18
|
+
(0, util_1.log)(`Loading files ${rootFolder ? `from folder ${rootFolder.id}` : 'from root'}`, config.logger);
|
|
17
19
|
const files = integration.getCrowdinFiles
|
|
18
20
|
? yield integration.getCrowdinFiles(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, rootFolder, req.integrationSettings)
|
|
19
21
|
: [];
|
|
22
|
+
(0, util_1.log)(`Returning files ${JSON.stringify(files, null, 2)}`, config.logger);
|
|
20
23
|
res.send(files);
|
|
21
24
|
}
|
|
22
25
|
else {
|
|
@@ -12,7 +12,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
const util_1 = require("../util");
|
|
13
13
|
function handle(config) {
|
|
14
14
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
15
|
-
const
|
|
15
|
+
const projectId = req.crowdinContext.jwtPayload.context.project_id;
|
|
16
|
+
(0, util_1.log)(`Loading crowdin project ${projectId}`, config.logger);
|
|
17
|
+
const project = yield req.crowdinApiClient.projectsGroupsApi.getProject(projectId);
|
|
18
|
+
(0, util_1.log)(`Loaded crowdin project ${JSON.stringify(project, null, 2)}`, config.logger);
|
|
16
19
|
res.send(project.data);
|
|
17
20
|
}), config.onError);
|
|
18
21
|
}
|
|
@@ -12,8 +12,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
const util_1 = require("../util");
|
|
13
13
|
function handle(config, integration) {
|
|
14
14
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
15
|
-
const
|
|
16
|
-
|
|
15
|
+
const projectId = req.crowdinContext.jwtPayload.context.project_id;
|
|
16
|
+
(0, util_1.log)(`Upading crowdin project ${projectId}`, config.logger);
|
|
17
|
+
const rootFolder = yield (0, util_1.getRootFolder)(config, integration, req.crowdinApiClient, projectId);
|
|
18
|
+
if (rootFolder) {
|
|
19
|
+
(0, util_1.log)(`Upading crowdin files under folder ${rootFolder.id}`, config.logger);
|
|
20
|
+
}
|
|
21
|
+
yield integration.updateCrowdin(projectId, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings);
|
|
17
22
|
res.status(204).end();
|
|
18
23
|
}), config.onError);
|
|
19
24
|
}
|
|
@@ -18,6 +18,7 @@ const util_1 = require("../../util");
|
|
|
18
18
|
function handle(config, folder) {
|
|
19
19
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
20
20
|
const filePath = path_1.default.join(folder, 'custom-file-format', req.query.file);
|
|
21
|
+
(0, util_1.log)(`Downloading file ${filePath}`, config.logger);
|
|
21
22
|
res.download(filePath, function (err) {
|
|
22
23
|
if (err) {
|
|
23
24
|
console.error(err);
|
|
@@ -98,6 +98,7 @@ function handle(baseConfig, baseUrl, folder, config) {
|
|
|
98
98
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
99
99
|
const baseFilesUrl = `${baseUrl}/file/download`;
|
|
100
100
|
const body = req.body;
|
|
101
|
+
(0, util_1.log)(`Recieved request to process file ${JSON.stringify(body, null, 2)}`, baseConfig.logger);
|
|
101
102
|
let file;
|
|
102
103
|
if (body.file.content) {
|
|
103
104
|
file = Buffer.from(body.file.content, 'base64').toString();
|
|
@@ -114,6 +115,7 @@ function handle(baseConfig, baseUrl, folder, config) {
|
|
|
114
115
|
response = yield handleParseFile(baseFilesUrl, folder, config, file, body, req.crowdinApiClient, req.crowdinContext, req.crowdinContext.jwtPayload.context.project_id);
|
|
115
116
|
break;
|
|
116
117
|
}
|
|
118
|
+
(0, util_1.log)(`Returning response from process file action ${JSON.stringify(response, null, 2)}`, baseConfig.logger);
|
|
117
119
|
res.send({ data: response });
|
|
118
120
|
}), baseConfig.onError);
|
|
119
121
|
}
|
|
@@ -15,6 +15,9 @@ function handle(baseConfig, config) {
|
|
|
15
15
|
const source = req.query.source;
|
|
16
16
|
const target = req.query.target;
|
|
17
17
|
const body = req.body;
|
|
18
|
+
(0, util_1.log)('Recieved request for custom mt', baseConfig.logger);
|
|
19
|
+
(0, util_1.log)(`Source language ${source}, target language ${target}`, baseConfig.logger);
|
|
20
|
+
(0, util_1.log)(`Payload ${JSON.stringify(body, null, 2)}`, baseConfig.logger);
|
|
18
21
|
const projectId = Number(req.query.project_id);
|
|
19
22
|
try {
|
|
20
23
|
if (source === 'en' && target === 'de' && body.strings && body.strings[0] === 'validation') {
|
package/out/handlers/install.js
CHANGED
|
@@ -16,6 +16,7 @@ const util_1 = require("../util");
|
|
|
16
16
|
function handle(config) {
|
|
17
17
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
18
18
|
const event = req.body;
|
|
19
|
+
(0, util_1.log)(`Recieved install request ${JSON.stringify(event, null, 2)}`, config.logger);
|
|
19
20
|
const token = yield (0, crowdin_apps_functions_1.generateOAuthToken)(config.clientId, config.clientSecret, event.code);
|
|
20
21
|
const credentials = {
|
|
21
22
|
id: (event.domain || event.organizationId).toString(),
|
|
@@ -27,9 +28,11 @@ function handle(config) {
|
|
|
27
28
|
const existingCredentials = yield (0, storage_1.getCrowdinCredentials)(credentials.id);
|
|
28
29
|
if (!!existingCredentials) {
|
|
29
30
|
yield (0, storage_1.updateCrowdinCredentials)(credentials);
|
|
31
|
+
(0, util_1.log)('An existing App has been reinstalled', config.logger);
|
|
30
32
|
}
|
|
31
33
|
else {
|
|
32
34
|
yield (0, storage_1.saveCrowdinCredentials)(credentials);
|
|
35
|
+
(0, util_1.log)('A new App has been installed', config.logger);
|
|
33
36
|
}
|
|
34
37
|
res.status(204).end();
|
|
35
38
|
}), config.onError);
|
|
@@ -12,7 +12,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
const util_1 = require("../util");
|
|
13
13
|
function handle(config, integration) {
|
|
14
14
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
15
|
+
(0, util_1.log)('Recieved request to get integration data', config.logger);
|
|
15
16
|
const files = yield integration.getIntegrationFiles(req.integrationCredentials, req.integrationSettings);
|
|
17
|
+
(0, util_1.log)(`Integration data response ${JSON.stringify(files, null, 2)}`, config.logger);
|
|
16
18
|
res.send(files);
|
|
17
19
|
}), config.onError);
|
|
18
20
|
}
|
|
@@ -13,11 +13,14 @@ const storage_1 = require("../storage");
|
|
|
13
13
|
const util_1 = require("../util");
|
|
14
14
|
function handle(config, integration) {
|
|
15
15
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
(0, util_1.log)('Recieved integration login request', config.logger);
|
|
16
17
|
if (integration.checkConnection) {
|
|
18
|
+
(0, util_1.log)('Checking the integration credentials', config.logger);
|
|
17
19
|
yield integration.checkConnection(req.body.credentials);
|
|
18
20
|
}
|
|
19
21
|
const existing = yield (0, storage_1.getIntegrationCredentials)(req.crowdinContext.clientId);
|
|
20
22
|
if (!!existing) {
|
|
23
|
+
(0, util_1.log)('Deleting old credentials', config.logger);
|
|
21
24
|
yield (0, storage_1.deleteIntegrationCredentials)(req.crowdinContext.clientId);
|
|
22
25
|
}
|
|
23
26
|
yield (0, storage_1.saveIntegrationCredentials)(req.crowdinContext.clientId, (0, util_1.encryptData)(config.clientSecret, JSON.stringify(req.body.credentials)), req.crowdinContext.crowdinId);
|
|
@@ -13,6 +13,7 @@ const storage_1 = require("../storage");
|
|
|
13
13
|
const util_1 = require("../util");
|
|
14
14
|
function handle(config) {
|
|
15
15
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
(0, util_1.log)('Recieved integration logout request', config.logger);
|
|
16
17
|
yield (0, storage_1.deleteIntegrationCredentials)(req.crowdinContext.clientId);
|
|
17
18
|
res.status(204).end();
|
|
18
19
|
}), config.onError);
|
|
@@ -12,7 +12,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
const util_1 = require("../util");
|
|
13
13
|
function handle(config, integration) {
|
|
14
14
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
15
|
+
(0, util_1.log)('Upading integratino data', config.logger);
|
|
15
16
|
const rootFolder = yield (0, util_1.getRootFolder)(config, integration, req.crowdinApiClient, req.crowdinContext.jwtPayload.context.project_id);
|
|
17
|
+
if (rootFolder) {
|
|
18
|
+
(0, util_1.log)(`Upading integration data for crowding root folder ${rootFolder.id}`, config.logger);
|
|
19
|
+
}
|
|
16
20
|
yield integration.updateIntegration(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings);
|
|
17
21
|
res.status(204).end();
|
|
18
22
|
}), config.onError);
|
package/out/handlers/main.js
CHANGED
|
@@ -41,16 +41,19 @@ function handle(config, integration) {
|
|
|
41
41
|
options.loginFields = (_a = integration.loginForm) === null || _a === void 0 ? void 0 : _a.fields;
|
|
42
42
|
if (integration.oauthLogin) {
|
|
43
43
|
options.oauthUrl = constructOauthUrl(config, integration);
|
|
44
|
+
(0, util_1.log)(`Adding oauth url ${options.oauthUrl}`, config.logger);
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
else if (integration.getConfiguration) {
|
|
47
48
|
const configurationFields = yield integration.getConfiguration(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, req.integrationCredentials);
|
|
48
49
|
options.configurationFields = configurationFields;
|
|
49
50
|
options.config = JSON.stringify(req.integrationSettings || {});
|
|
51
|
+
(0, util_1.log)(`Adding configuration fields ${JSON.stringify(configurationFields, null, 2)}`, config.logger);
|
|
50
52
|
}
|
|
51
53
|
options.infoModal = integration.infoModal;
|
|
52
54
|
options.withCronSync = integration.withCronSync;
|
|
53
55
|
options.withWebhookSync = integration.withWebhookSync;
|
|
56
|
+
(0, util_1.log)(`Routing user to ${view} view`, config.logger);
|
|
54
57
|
return res.render(view, options);
|
|
55
58
|
}), config.onError);
|
|
56
59
|
}
|
|
@@ -20,11 +20,13 @@ function handle(config, integration) {
|
|
|
20
20
|
const message = {
|
|
21
21
|
uid: 'oauth_popup',
|
|
22
22
|
};
|
|
23
|
+
const code = req.query[((_b = (_a = integration.oauthLogin) === null || _a === void 0 ? void 0 : _a.fieldsMapping) === null || _b === void 0 ? void 0 : _b.code) || 'code'];
|
|
24
|
+
(0, util_1.log)(`Recieved request from OAuth login callback. Code ${code}`, config.logger);
|
|
23
25
|
try {
|
|
24
|
-
const code = req.query[((_b = (_a = integration.oauthLogin) === null || _a === void 0 ? void 0 : _a.fieldsMapping) === null || _b === void 0 ? void 0 : _b.code) || 'code'];
|
|
25
26
|
const oauthLogin = integration.oauthLogin;
|
|
26
27
|
let credentials;
|
|
27
28
|
if (oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.performGetTokenRequest) {
|
|
29
|
+
(0, util_1.log)('Performing custom get bearer token request', config.logger);
|
|
28
30
|
credentials = yield oauthLogin.performGetTokenRequest(code);
|
|
29
31
|
}
|
|
30
32
|
else {
|
|
@@ -52,6 +54,12 @@ function handle(config, integration) {
|
|
|
52
54
|
return res.render('oauth', { message: JSON.stringify(message) });
|
|
53
55
|
}
|
|
54
56
|
catch (e) {
|
|
57
|
+
if (config.onError) {
|
|
58
|
+
config.onError(e);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
console.error(e);
|
|
62
|
+
}
|
|
55
63
|
message.data = { error: (0, util_1.getMessage)(e) };
|
|
56
64
|
return res.render('oauth', { message: JSON.stringify(message) });
|
|
57
65
|
}
|
|
@@ -13,6 +13,7 @@ const storage_1 = require("../storage");
|
|
|
13
13
|
const util_1 = require("../util");
|
|
14
14
|
function handle(config) {
|
|
15
15
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
(0, util_1.log)(`Saving settings ${JSON.stringify(req.body.config, null, 2)}`, config.logger);
|
|
16
17
|
yield (0, storage_1.updateIntegrationConfig)(req.crowdinContext.clientId, JSON.stringify(req.body.config));
|
|
17
18
|
res.status(204).end();
|
|
18
19
|
}), config.onError);
|
|
@@ -16,9 +16,11 @@ function handle(config) {
|
|
|
16
16
|
const { files, type, provider } = req.body;
|
|
17
17
|
const existingSettings = yield (0, storage_1.getSyncSettings)(req.crowdinContext.clientId, req.crowdinContext.crowdinId, type, provider);
|
|
18
18
|
if (existingSettings) {
|
|
19
|
+
(0, util_1.log)(`Updating sync settings for type ${type} and provider ${provider} ${JSON.stringify(files, null, 2)}`, config.logger);
|
|
19
20
|
yield (0, storage_1.updateSyncSettings)(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, type, provider);
|
|
20
21
|
}
|
|
21
22
|
else {
|
|
23
|
+
(0, util_1.log)(`Saving sync settings for type ${type} and provider ${provider} ${JSON.stringify(files, null, 2)}`, config.logger);
|
|
22
24
|
yield (0, storage_1.saveSyncSettings)(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, type, provider);
|
|
23
25
|
}
|
|
24
26
|
res.status(204).end();
|
|
@@ -15,10 +15,12 @@ function handle(config) {
|
|
|
15
15
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
16
|
let files = {};
|
|
17
17
|
const provider = req.params.provider;
|
|
18
|
+
(0, util_1.log)(`Loading sync settings for provider ${provider}`, config.logger);
|
|
18
19
|
const syncSettings = yield (0, storage_1.getSyncSettingsByProvider)(req.crowdinContext.clientId, provider);
|
|
19
20
|
if (syncSettings) {
|
|
20
21
|
files = JSON.parse(syncSettings.files) || [];
|
|
21
22
|
}
|
|
23
|
+
(0, util_1.log)(`Returning sync settings ${JSON.stringify(files, null, 2)}`, config.logger);
|
|
22
24
|
res.send(files);
|
|
23
25
|
}), config.onError);
|
|
24
26
|
}
|
|
@@ -14,11 +14,13 @@ const util_1 = require("../util");
|
|
|
14
14
|
function handle(config) {
|
|
15
15
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
16
|
const event = req.body;
|
|
17
|
+
(0, util_1.log)(`Recieved uninstall request ${JSON.stringify(event, null, 2)}`, config.logger);
|
|
17
18
|
const organization = (event.domain || event.organizationId).toString();
|
|
18
19
|
yield (0, storage_1.deleteCrowdinCredentials)(organization);
|
|
19
20
|
if (config.onUninstall) {
|
|
20
21
|
yield config.onUninstall(organization);
|
|
21
22
|
}
|
|
23
|
+
(0, util_1.log)('App has been uninstalled', config.logger);
|
|
22
24
|
res.status(204).end();
|
|
23
25
|
}), config.onError);
|
|
24
26
|
}
|
|
@@ -29,6 +29,7 @@ function prepareCrowdinRequest(jwtToken, config, optional = false) {
|
|
|
29
29
|
let context;
|
|
30
30
|
let client;
|
|
31
31
|
try {
|
|
32
|
+
(0, util_1.log)('Validating jwt token from incoming request', config.logger);
|
|
32
33
|
const jwtPayload = yield (0, crowdin_apps_functions_1.validateJwtToken)(jwtToken, config.clientSecret);
|
|
33
34
|
context = {
|
|
34
35
|
jwtPayload,
|
|
@@ -37,9 +38,16 @@ function prepareCrowdinRequest(jwtToken, config, optional = false) {
|
|
|
37
38
|
};
|
|
38
39
|
}
|
|
39
40
|
catch (e) {
|
|
41
|
+
if (config.onError) {
|
|
42
|
+
config.onError(e);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.error(e);
|
|
46
|
+
}
|
|
40
47
|
throw new Error("Can't verify");
|
|
41
48
|
}
|
|
42
49
|
try {
|
|
50
|
+
(0, util_1.log)('Loading crowdin credentials', config.logger);
|
|
43
51
|
const credentials = yield (0, storage_1.getCrowdinCredentials)(context.crowdinId);
|
|
44
52
|
if (!credentials) {
|
|
45
53
|
if (optional) {
|
|
@@ -47,9 +55,16 @@ function prepareCrowdinRequest(jwtToken, config, optional = false) {
|
|
|
47
55
|
}
|
|
48
56
|
throw new Error("Can't find organization by id");
|
|
49
57
|
}
|
|
58
|
+
(0, util_1.log)('Building crowdin client instance', config.logger);
|
|
50
59
|
client = yield (0, util_1.prepareCrowdinClient)(config, credentials);
|
|
51
60
|
}
|
|
52
61
|
catch (e) {
|
|
62
|
+
if (config.onError) {
|
|
63
|
+
config.onError(e);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.error(e);
|
|
67
|
+
}
|
|
53
68
|
throw new Error('Access denied');
|
|
54
69
|
}
|
|
55
70
|
return { context, client };
|
|
@@ -14,6 +14,7 @@ const util_1 = require("../util");
|
|
|
14
14
|
function handle(config, integration, optional = false) {
|
|
15
15
|
return (0, util_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
16
16
|
const clientId = req.crowdinContext.clientId;
|
|
17
|
+
(0, util_1.log)(`Loading integration credentials for client ${clientId}`, config.logger);
|
|
17
18
|
const integrationCredentials = yield (0, storage_1.getIntegrationCredentials)(clientId);
|
|
18
19
|
if (!integrationCredentials) {
|
|
19
20
|
if (optional) {
|
package/out/models/index.d.ts
CHANGED
|
@@ -102,6 +102,10 @@ export interface Config extends ImagePath {
|
|
|
102
102
|
* Error interceptor (can be used to log error in centralized place)
|
|
103
103
|
*/
|
|
104
104
|
onError?: (error: any) => void;
|
|
105
|
+
/**
|
|
106
|
+
* Configuration to log everything that are happening in the app
|
|
107
|
+
*/
|
|
108
|
+
logger?: Logger;
|
|
105
109
|
}
|
|
106
110
|
export declare enum Scope {
|
|
107
111
|
ALL_SCOPES = "all",
|
|
@@ -488,4 +492,8 @@ interface ImagePath {
|
|
|
488
492
|
*/
|
|
489
493
|
imagePath?: string;
|
|
490
494
|
}
|
|
495
|
+
export interface Logger {
|
|
496
|
+
enabled: boolean;
|
|
497
|
+
log?: (message: string) => void;
|
|
498
|
+
}
|
|
491
499
|
export {};
|
package/out/util/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import Crowdin, { SourceFilesModel } from '@crowdin/crowdin-api-client';
|
|
2
2
|
import { Request, Response } from 'express';
|
|
3
|
-
import { Config, CronJob, CrowdinCredentials, IntegrationCredentials, IntegrationLogic } from '../models';
|
|
3
|
+
import { Config, CronJob, CrowdinCredentials, IntegrationCredentials, IntegrationLogic, Logger } from '../models';
|
|
4
4
|
export declare class CodeError extends Error {
|
|
5
5
|
code: number | undefined;
|
|
6
6
|
constructor(message: string, code?: number);
|
|
7
7
|
}
|
|
8
|
+
export declare function log(message: string, logger?: Logger): void;
|
|
8
9
|
export declare function getMessage(err: any): any;
|
|
9
10
|
export declare function runAsyncWrapper(callback: Function, onError?: (e: any) => void): (req: Request, res: Response, next: Function) => void;
|
|
10
11
|
export declare function encryptData(secret: string, data: string): string;
|
package/out/util/index.js
CHANGED
|
@@ -31,7 +31,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
31
31
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
32
|
};
|
|
33
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
-
exports.filesCron = exports.runJob = exports.prepareIntegrationCredentials = exports.prepareCrowdinClient = exports.applyDefaults = exports.getRootFolder = exports.getOauthRoute = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.getMessage = exports.CodeError = void 0;
|
|
34
|
+
exports.filesCron = exports.runJob = exports.prepareIntegrationCredentials = exports.prepareCrowdinClient = exports.applyDefaults = exports.getRootFolder = exports.getOauthRoute = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.getMessage = exports.log = exports.CodeError = void 0;
|
|
35
35
|
const crowdin_api_client_1 = __importDefault(require("@crowdin/crowdin-api-client"));
|
|
36
36
|
const crowdinAppFunctions = __importStar(require("@crowdin/crowdin-apps-functions"));
|
|
37
37
|
const axios_1 = __importDefault(require("axios"));
|
|
@@ -45,6 +45,19 @@ class CodeError extends Error {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
exports.CodeError = CodeError;
|
|
48
|
+
function log(message, logger) {
|
|
49
|
+
if (logger === null || logger === void 0 ? void 0 : logger.enabled) {
|
|
50
|
+
if (logger.log) {
|
|
51
|
+
logger.log(message);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
const timestamp = new Date().toISOString();
|
|
55
|
+
// eslint-disable-next-line no-console
|
|
56
|
+
console.log(`[${timestamp}] ${message}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.log = log;
|
|
48
61
|
function isCrowdinClientRequest(req) {
|
|
49
62
|
return req.crowdinContext;
|
|
50
63
|
}
|
|
@@ -178,6 +191,10 @@ function applyDefaults(config, integration) {
|
|
|
178
191
|
helpText: 'Set the frequency for pushing sources and translations',
|
|
179
192
|
type: 'select',
|
|
180
193
|
options: [
|
|
194
|
+
{
|
|
195
|
+
value: '0',
|
|
196
|
+
label: 'Disabled',
|
|
197
|
+
},
|
|
181
198
|
{
|
|
182
199
|
value: '1',
|
|
183
200
|
label: '1 hour',
|
|
@@ -222,7 +239,9 @@ function prepareCrowdinClient(config, credentials) {
|
|
|
222
239
|
});
|
|
223
240
|
}
|
|
224
241
|
else {
|
|
242
|
+
log('Crowdin credentials have expired. Requesting a new credentials', config.logger);
|
|
225
243
|
const newCredentials = yield crowdinAppFunctions.refreshOAuthToken(config.clientId, config.clientSecret, decryptData(config.clientSecret, credentials.refreshToken));
|
|
244
|
+
log('Saving updated crowdin credentials in the database', config.logger);
|
|
226
245
|
yield (0, storage_1.updateCrowdinCredentials)({
|
|
227
246
|
id: credentials.id,
|
|
228
247
|
refreshToken: encryptData(config.clientSecret, newCredentials.refreshToken),
|
|
@@ -243,11 +262,13 @@ function prepareIntegrationCredentials(config, integration, integrationCredentia
|
|
|
243
262
|
return __awaiter(this, void 0, void 0, function* () {
|
|
244
263
|
const credentials = JSON.parse(decryptData(config.clientSecret, integrationCredentials.credentials));
|
|
245
264
|
if ((_a = integration.oauthLogin) === null || _a === void 0 ? void 0 : _a.refresh) {
|
|
265
|
+
log('Checking if integration credentials need to be refreshed', config.logger);
|
|
246
266
|
const oauthLogin = integration.oauthLogin;
|
|
247
267
|
const { expireIn } = credentials;
|
|
248
268
|
//2 min as an extra buffer
|
|
249
269
|
const isExpired = expireIn + 120 < Date.now() / 1000;
|
|
250
270
|
if (isExpired) {
|
|
271
|
+
log('Integration credentials have expired. Requesting a new credentials', config.logger);
|
|
251
272
|
let newCredentials;
|
|
252
273
|
if (oauthLogin.performRefreshTokenRequest) {
|
|
253
274
|
newCredentials = yield oauthLogin.performRefreshTokenRequest(credentials);
|
|
@@ -271,6 +292,7 @@ function prepareIntegrationCredentials(config, integration, integrationCredentia
|
|
|
271
292
|
if (newCredentials[((_g = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _g === void 0 ? void 0 : _g.refreshToken) || 'refresh_token']) {
|
|
272
293
|
credentials.refreshToken = newCredentials[((_h = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _h === void 0 ? void 0 : _h.refreshToken) || 'refresh_token'];
|
|
273
294
|
}
|
|
295
|
+
log('Saving updated integration credentials in the database', config.logger);
|
|
274
296
|
yield (0, storage_1.updateIntegrationCredentials)(integrationCredentials.id, encryptData(config.clientSecret, JSON.stringify(credentials)));
|
|
275
297
|
}
|
|
276
298
|
}
|
|
@@ -280,6 +302,7 @@ function prepareIntegrationCredentials(config, integration, integrationCredentia
|
|
|
280
302
|
exports.prepareIntegrationCredentials = prepareIntegrationCredentials;
|
|
281
303
|
function runJob(config, integration, job) {
|
|
282
304
|
return __awaiter(this, void 0, void 0, function* () {
|
|
305
|
+
log(`Starting cron job with expression [${job.expression}]`, config.logger);
|
|
283
306
|
const crowdinCredentialsList = yield (0, storage_1.getAllCrowdinCredentials)();
|
|
284
307
|
yield Promise.all(crowdinCredentialsList.map((crowdinCredentials) => __awaiter(this, void 0, void 0, function* () {
|
|
285
308
|
const crowdinClient = yield prepareCrowdinClient(config, crowdinCredentials);
|
|
@@ -291,14 +314,18 @@ function runJob(config, integration, job) {
|
|
|
291
314
|
const intConfig = integrationCredentials.config
|
|
292
315
|
? JSON.parse(integrationCredentials.config)
|
|
293
316
|
: undefined;
|
|
317
|
+
log(`Executing task for cron job with expression [${job.expression}] for project ${projectId}`, config.logger);
|
|
294
318
|
yield job.task(projectId, crowdinClient, apiCredentials, rootFolder, intConfig);
|
|
319
|
+
log(`Task for cron job with expression [${job.expression}] for project ${projectId} completed`, config.logger);
|
|
295
320
|
})));
|
|
296
321
|
})));
|
|
322
|
+
log(`Cron job with expression [${job.expression}] completed`, config.logger);
|
|
297
323
|
});
|
|
298
324
|
}
|
|
299
325
|
exports.runJob = runJob;
|
|
300
326
|
function filesCron(config, integration, period) {
|
|
301
327
|
return __awaiter(this, void 0, void 0, function* () {
|
|
328
|
+
log(`Starting files cron job with period [${period}]`, config.logger);
|
|
302
329
|
const syncSettingsList = yield (0, storage_1.getAllSyncSettingsByType)('schedule');
|
|
303
330
|
yield Promise.all(syncSettingsList.map((syncSettings) => __awaiter(this, void 0, void 0, function* () {
|
|
304
331
|
const files = JSON.parse(syncSettings.files);
|
|
@@ -307,21 +334,26 @@ function filesCron(config, integration, period) {
|
|
|
307
334
|
if (crowdinCredentials && integrationCredentials) {
|
|
308
335
|
const intConfig = integrationCredentials.config
|
|
309
336
|
? JSON.parse(integrationCredentials.config)
|
|
310
|
-
: { schedule:
|
|
337
|
+
: { schedule: '0' };
|
|
311
338
|
if (period === intConfig.schedule) {
|
|
312
339
|
const projectId = crowdinAppFunctions.getProjectId(integrationCredentials.id);
|
|
313
340
|
const crowdinClient = yield prepareCrowdinClient(config, crowdinCredentials);
|
|
314
341
|
const apiCredentials = yield prepareIntegrationCredentials(config, integration, integrationCredentials);
|
|
315
342
|
const rootFolder = yield getRootFolder(config, integration, crowdinClient, projectId);
|
|
316
343
|
if (syncSettings.provider === 'crowdin') {
|
|
344
|
+
log(`Executing updateIntegration task for files cron job with period [${period}] for project ${projectId} and request ${JSON.stringify(files, null, 2)}`, config.logger);
|
|
317
345
|
yield integration.updateIntegration(projectId, crowdinClient, apiCredentials, files, rootFolder, intConfig);
|
|
346
|
+
log(`updateIntegration task for files cron job with period [${period}] for project ${projectId} completed`, config.logger);
|
|
318
347
|
}
|
|
319
348
|
else {
|
|
349
|
+
log(`Executing updateCrowdin task for files cron job with period [${period}] for project ${projectId} and request ${JSON.stringify(files, null, 2)}`, config.logger);
|
|
320
350
|
yield integration.updateCrowdin(projectId, crowdinClient, apiCredentials, files, rootFolder, intConfig);
|
|
351
|
+
log(`updateCrowdin task for files cron job with period [${period}] for project ${projectId} completed`, config.logger);
|
|
321
352
|
}
|
|
322
353
|
}
|
|
323
354
|
}
|
|
324
355
|
})));
|
|
356
|
+
log(`Files cron job with period [${period}] completed`, config.logger);
|
|
325
357
|
});
|
|
326
358
|
}
|
|
327
359
|
exports.filesCron = filesCron;
|
|
@@ -294,6 +294,12 @@
|
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
296
|
});
|
|
297
|
+
{{#if withCronSync}}
|
|
298
|
+
const sheduleSettings = document.querySelector('#schedule-settings');
|
|
299
|
+
if (JSON.parse(sheduleSettings.value).length <= 0) {
|
|
300
|
+
sheduleSettings.value = JSON.stringify(["0"]);
|
|
301
|
+
}
|
|
302
|
+
{{/if}}
|
|
297
303
|
}
|
|
298
304
|
|
|
299
305
|
function saveSettings() {
|
package/package.json
CHANGED