@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 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 project = yield req.crowdinApiClient.projectsGroupsApi.getProject(req.crowdinContext.jwtPayload.context.project_id);
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 rootFolder = yield (0, util_1.getRootFolder)(config, integration, req.crowdinApiClient, req.crowdinContext.jwtPayload.context.project_id);
16
- yield integration.updateCrowdin(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings);
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') {
@@ -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);
@@ -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) {
@@ -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 {};
@@ -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: 24 };
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crowdin/app-project-module",
3
- "version": "0.13.3",
3
+ "version": "0.14.1",
4
4
  "description": "Module that generates for you all common endpoints for serving standalone Crowdin App",
5
5
  "main": "out/index.js",
6
6
  "types": "out/index.d.ts",