@crowdin/app-project-module 0.39.1 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/out/handlers/integration/crowdin-update.js +36 -17
  2. package/out/handlers/integration/integration-data.js +2 -0
  3. package/out/handlers/integration/integration-update.js +35 -17
  4. package/out/handlers/integration/integration-webhook.js +1 -1
  5. package/out/handlers/integration/job-cancel.d.ts +3 -0
  6. package/out/handlers/integration/job-cancel.js +28 -0
  7. package/out/handlers/integration/job-info.d.ts +3 -0
  8. package/out/handlers/integration/job-info.js +54 -0
  9. package/out/handlers/integration/main.js +6 -3
  10. package/out/handlers/integration/settings-save.js +8 -1
  11. package/out/handlers/integration/user-errors.d.ts +3 -0
  12. package/out/handlers/{user-errors.js → integration/user-errors.js} +2 -2
  13. package/out/handlers/uninstall.js +4 -2
  14. package/out/index.d.ts +2 -1
  15. package/out/index.js +35 -27
  16. package/out/middlewares/crowdin-client.js +1 -0
  17. package/out/middlewares/integration-credentials.js +3 -2
  18. package/out/middlewares/ui-module.js +1 -0
  19. package/out/models/index.d.ts +54 -18
  20. package/out/models/index.js +1 -0
  21. package/out/models/job.d.ts +44 -0
  22. package/out/models/job.js +16 -0
  23. package/out/static/js/form.js +13 -13
  24. package/out/static/js/main.js +1 -1
  25. package/out/storage/index.d.ts +11 -2
  26. package/out/storage/index.js +3 -0
  27. package/out/storage/mysql.d.ts +11 -2
  28. package/out/storage/mysql.js +155 -10
  29. package/out/storage/postgre.d.ts +11 -2
  30. package/out/storage/postgre.js +153 -9
  31. package/out/storage/sqlite.d.ts +14 -3
  32. package/out/storage/sqlite.js +160 -14
  33. package/out/util/cron.d.ts +1 -0
  34. package/out/util/cron.js +53 -6
  35. package/out/util/defaults.js +4 -11
  36. package/out/util/file-snapshot.js +2 -0
  37. package/out/util/files.d.ts +2 -1
  38. package/out/util/files.js +19 -1
  39. package/out/util/index.js +3 -1
  40. package/out/util/job.d.ts +12 -0
  41. package/out/util/job.js +88 -0
  42. package/out/util/logger.js +4 -0
  43. package/out/util/webhooks.js +53 -6
  44. package/out/views/main.handlebars +153 -5
  45. package/package.json +16 -15
  46. package/out/handlers/user-errors.d.ts +0 -3
@@ -9,9 +9,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
+ const job_1 = require("../../models/job");
12
13
  const util_1 = require("../../util");
13
14
  const defaults_1 = require("../../util/defaults");
14
15
  const logger_1 = require("../../util/logger");
16
+ const job_2 = require("../../util/job");
15
17
  function handle(config, integration) {
16
18
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
17
19
  var _a, _b;
@@ -26,23 +28,40 @@ function handle(config, integration) {
26
28
  if (((_b = config.api) === null || _b === void 0 ? void 0 : _b.default) && req.body.files) {
27
29
  req.body = req.body.files;
28
30
  }
29
- let message;
30
- try {
31
- const result = yield integration.updateCrowdin(projectId, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings, uploadTranslations);
32
- if ((0, util_1.isExtendedResultType)(result)) {
33
- message = result.message;
34
- }
35
- }
36
- catch (e) {
37
- yield (0, logger_1.handleUserError)({
38
- action: 'Sync files to Crowdin',
39
- error: e,
40
- crowdinId: req.crowdinContext.crowdinId,
41
- clientId: req.crowdinContext.clientId,
42
- });
43
- throw e;
44
- }
45
- res.send({ message });
31
+ yield (0, job_2.runAsJob)({
32
+ integrationId: req.crowdinContext.clientId,
33
+ crowdinId: req.crowdinContext.crowdinId,
34
+ type: job_1.JobType.UPDATE_TO_CROWDIN,
35
+ title: 'Sync files to Crowdin',
36
+ payload: req.body,
37
+ res,
38
+ jobCallback: (job) => __awaiter(this, void 0, void 0, function* () {
39
+ const result = yield integration.updateCrowdin({
40
+ projectId,
41
+ client: req.crowdinApiClient,
42
+ credentials: req.integrationCredentials,
43
+ request: req.body,
44
+ rootFolder,
45
+ appSettings: req.integrationSettings,
46
+ uploadTranslations,
47
+ job,
48
+ });
49
+ let message;
50
+ if ((0, util_1.isExtendedResultType)(result)) {
51
+ message = result.message;
52
+ }
53
+ return { message };
54
+ }),
55
+ onError: (e) => __awaiter(this, void 0, void 0, function* () {
56
+ yield (0, logger_1.handleUserError)({
57
+ action: 'Sync files to Crowdin',
58
+ error: e,
59
+ crowdinId: req.crowdinContext.crowdinId,
60
+ clientId: req.crowdinContext.clientId,
61
+ });
62
+ throw e;
63
+ }),
64
+ });
46
65
  }));
47
66
  }
48
67
  exports.default = handle;
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const util_1 = require("../../util");
13
13
  const logger_1 = require("../../util/logger");
14
+ const files_1 = require("../../util/files");
14
15
  function handle(integration) {
15
16
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
16
17
  const { parent_id: parentId, search, page } = req.query;
@@ -28,6 +29,7 @@ function handle(integration) {
28
29
  else {
29
30
  files = result;
30
31
  }
32
+ files = (0, files_1.skipFilesByRegex)(files, integration.skipIntegrationNodes);
31
33
  }
32
34
  catch (e) {
33
35
  yield (0, logger_1.handleUserError)({
@@ -9,8 +9,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
+ const job_1 = require("../../models/job");
12
13
  const util_1 = require("../../util");
13
14
  const defaults_1 = require("../../util/defaults");
15
+ const job_2 = require("../../util/job");
14
16
  const logger_1 = require("../../util/logger");
15
17
  function handle(config, integration) {
16
18
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
@@ -24,23 +26,39 @@ function handle(config, integration) {
24
26
  if (((_a = config.api) === null || _a === void 0 ? void 0 : _a.default) && req.body.files) {
25
27
  req.body = req.body.files;
26
28
  }
27
- let message;
28
- try {
29
- const result = yield integration.updateIntegration(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings);
30
- if ((0, util_1.isExtendedResultType)(result)) {
31
- message = result.message;
32
- }
33
- }
34
- catch (e) {
35
- yield (0, logger_1.handleUserError)({
36
- action: 'Sync files to External Service',
37
- error: e,
38
- crowdinId: req.crowdinContext.crowdinId,
39
- clientId: req.crowdinContext.clientId,
40
- });
41
- throw e;
42
- }
43
- res.send({ message });
29
+ yield (0, job_2.runAsJob)({
30
+ integrationId: req.crowdinContext.clientId,
31
+ crowdinId: req.crowdinContext.crowdinId,
32
+ type: job_1.JobType.UPDATE_TO_INTEGRATION,
33
+ title: 'Sync files to ' + config.name,
34
+ payload: req.body,
35
+ res,
36
+ jobCallback: (job) => __awaiter(this, void 0, void 0, function* () {
37
+ const result = yield integration.updateIntegration({
38
+ projectId: req.crowdinContext.jwtPayload.context.project_id,
39
+ client: req.crowdinApiClient,
40
+ credentials: req.integrationCredentials,
41
+ request: req.body,
42
+ rootFolder,
43
+ appSettings: req.integrationSettings,
44
+ job,
45
+ });
46
+ let message;
47
+ if ((0, util_1.isExtendedResultType)(result)) {
48
+ message = result.message;
49
+ }
50
+ return { message };
51
+ }),
52
+ onError: (e) => __awaiter(this, void 0, void 0, function* () {
53
+ yield (0, logger_1.handleUserError)({
54
+ action: 'Sync files to External Service',
55
+ error: e,
56
+ crowdinId: req.crowdinContext.crowdinId,
57
+ clientId: req.crowdinContext.clientId,
58
+ });
59
+ throw e;
60
+ }),
61
+ });
44
62
  }));
45
63
  }
46
64
  exports.default = handle;
@@ -25,7 +25,7 @@ function handle(config, integration) {
25
25
  if (!webhookData.syncSettings) {
26
26
  return res.status(200).send({ message: 'Sync is not configured' });
27
27
  }
28
- yield (0, webhooks_1.updateCrowdinFromWebhookRequest)({ integration, webhookData, req });
28
+ yield (0, webhooks_1.updateCrowdinFromWebhookRequest)({ integration, webhookData, req: [req] });
29
29
  res.send({});
30
30
  }
31
31
  else {
@@ -0,0 +1,3 @@
1
+ /// <reference types="qs" />
2
+ import { Response } from 'express';
3
+ export default function handle(): (req: import("../../models").CrowdinClientRequest | import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const job_1 = require("../../models/job");
13
+ const util_1 = require("../../util");
14
+ const storage_1 = require("../../storage");
15
+ function handle() {
16
+ return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
17
+ const id = req.query.job_id || req.body.job_id;
18
+ if (!id) {
19
+ req.logInfo('Job id is absent');
20
+ res.status(400).send('Job id is required');
21
+ return;
22
+ }
23
+ req.logInfo(`User has been canceled the job id: ${id}`);
24
+ yield (0, storage_1.getStorage)().updateJob({ id, status: job_1.JobStatus.CANCELED });
25
+ res.sendStatus(204);
26
+ }));
27
+ }
28
+ exports.default = handle;
@@ -0,0 +1,3 @@
1
+ /// <reference types="qs" />
2
+ import { Response } from 'express';
3
+ export default function handle(): (req: import("../../models").CrowdinClientRequest | import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const job_1 = require("../../models/job");
13
+ const util_1 = require("../../util");
14
+ const storage_1 = require("../../storage");
15
+ function getHumanETA(ms) {
16
+ const seconds = Math.floor(ms / 1000);
17
+ let minutes = Math.floor(seconds / 60);
18
+ const hours = Math.floor(minutes / 60);
19
+ if (seconds < 60) {
20
+ return 'Less than a minute remaining';
21
+ }
22
+ minutes = minutes % 60;
23
+ const timeParts = [];
24
+ if (hours) {
25
+ timeParts.push(`${hours} ${hours > 1 ? 'hours' : 'hour'}`);
26
+ }
27
+ if (minutes) {
28
+ timeParts.push(`${minutes} ${minutes > 1 ? 'minutes' : 'minute'}`);
29
+ }
30
+ return `About ${timeParts.join(' and ')} remaining`;
31
+ }
32
+ function handle() {
33
+ return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
34
+ const id = req.query.job_id || req.body.job_id;
35
+ if (!id) {
36
+ req.logInfo('Get active jobs');
37
+ const jobs = yield (0, storage_1.getStorage)().getActiveJobs({
38
+ integrationId: req.crowdinContext.clientId,
39
+ crowdinId: req.crowdinContext.crowdinId,
40
+ });
41
+ res.send(jobs);
42
+ return;
43
+ }
44
+ req.logInfo(`Get job info for id ${id}`);
45
+ const job = yield (0, storage_1.getStorage)().getJob({ id });
46
+ if (job && job.status === job_1.JobStatus.IN_PROGRESS && job.progress > 5 && job.updatedAt) {
47
+ job.eta = ((Date.now() - job.createdAt) / job.progress) * (100 - job.progress);
48
+ job.info = getHumanETA(job.eta) + (job.info ? `\n${job.info}` : '');
49
+ }
50
+ req.logInfo(`Returning job info ${JSON.stringify(job, null, 2)}`);
51
+ res.send(job);
52
+ }));
53
+ }
54
+ exports.default = handle;
@@ -15,7 +15,7 @@ const defaults_1 = require("../../util/defaults");
15
15
  const logger_1 = require("../../util/logger");
16
16
  function handle(config, integration) {
17
17
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
18
- var _a;
18
+ var _a, _b;
19
19
  const logger = req.logInfo || logger_1.log;
20
20
  const installed = !!req.crowdinApiClient;
21
21
  const loggedIn = !!req.integrationCredentials;
@@ -59,13 +59,16 @@ function handle(config, integration) {
59
59
  options.integrationSearchListener = integration.integrationSearchListener;
60
60
  options.checkSubscription = !(0, connection_1.isAppFree)(config);
61
61
  options.uploadTranslations = integration.uploadTranslations;
62
- options.sentryData = config.sentryDsn
62
+ options.sentryData = process.env.SENTRY_DSN
63
63
  ? {
64
- dsn: config.sentryDsn,
64
+ dsn: process.env.SENTRY_DSN,
65
65
  appIdentifier: config.identifier,
66
66
  }
67
67
  : null;
68
68
  options.notice = integration.notice;
69
+ options.asyncProgress = {
70
+ checkInterval: ((_b = integration.asyncProgress) === null || _b === void 0 ? void 0 : _b.checkInterval) || 1000,
71
+ };
69
72
  logger(`Routing user to ${view} view`);
70
73
  return res.render(view, options);
71
74
  }));
@@ -18,8 +18,15 @@ const webhooks_1 = require("../../util/webhooks");
18
18
  function handle(config, integration) {
19
19
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
20
20
  const appSettings = req.body.config;
21
+ const clientId = req.crowdinContext.clientId;
21
22
  req.logInfo(`Saving settings ${JSON.stringify(appSettings, null, 2)}`);
22
- yield (0, storage_1.getStorage)().updateIntegrationConfig(req.crowdinContext.clientId, JSON.stringify(appSettings));
23
+ const integrationConfig = yield (0, storage_1.getStorage)().getIntegrationConfig(clientId);
24
+ if (!integrationConfig) {
25
+ yield (0, storage_1.getStorage)().saveIntegrationConfig(clientId, req.crowdinContext.crowdinId, JSON.stringify(appSettings));
26
+ }
27
+ else {
28
+ yield (0, storage_1.getStorage)().updateIntegrationConfig(clientId, JSON.stringify(appSettings));
29
+ }
23
30
  if (integration.webhooks) {
24
31
  yield (0, webhooks_1.registerWebhooks)(config, integration, req.crowdinApiClient, req.crowdinContext, req.integrationCredentials, appSettings);
25
32
  }
@@ -0,0 +1,3 @@
1
+ /// <reference types="qs" />
2
+ import { Response } from 'express';
3
+ export default function handle(): (req: import("../../models").CrowdinClientRequest | import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- const storage_1 = require("../storage");
13
- const util_1 = require("../util");
12
+ const storage_1 = require("../../storage");
13
+ const util_1 = require("../../util");
14
14
  function handle() {
15
15
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
16
16
  var _a;
@@ -24,10 +24,12 @@ function handle(config) {
24
24
  let allCredentials = [];
25
25
  if (projectIntegration) {
26
26
  const loadedCredentials = yield (0, storage_1.getStorage)().getAllIntegrationCredentials(organization);
27
+ const allIntegrationConfigs = yield (0, storage_1.getStorage)().getAllIntegrationConfigs(organization);
27
28
  allCredentials = yield Promise.all(loadedCredentials.map((creds) => __awaiter(this, void 0, void 0, function* () {
28
29
  let settings;
29
- if (creds.config) {
30
- settings = JSON.parse(creds.config);
30
+ const integrationConfig = allIntegrationConfigs.find(({ integrationId }) => integrationId === creds.id);
31
+ if (integrationConfig) {
32
+ settings = JSON.parse(integrationConfig.config);
31
33
  }
32
34
  const credentials = yield (0, connection_1.prepareIntegrationCredentials)(config, projectIntegration, creds);
33
35
  return { settings, credentials };
package/out/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { Express } from 'express';
2
- import { ClientConfig, Config, CrowdinAppUtilities } from './models';
2
+ import { ClientConfig, Config, CrowdinAppUtilities, CrowdinMetadataStore } from './models';
3
3
  import express from './util/terminus-express';
4
4
  export { ProjectPermissions, Scope, UserPermissions } from './models';
5
5
  export { express };
6
+ export declare const metadataStore: CrowdinMetadataStore;
6
7
  export declare function addCrowdinEndpoints(app: Express, clientConfig: Config | ClientConfig): CrowdinAppUtilities;
7
8
  export declare function createApp(clientConfig: ClientConfig): void;
package/out/index.js CHANGED
@@ -35,11 +35,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
35
35
  return (mod && mod.__esModule) ? mod : { "default": mod };
36
36
  };
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.createApp = exports.addCrowdinEndpoints = exports.express = exports.UserPermissions = exports.Scope = exports.ProjectPermissions = void 0;
38
+ exports.createApp = exports.addCrowdinEndpoints = exports.metadataStore = exports.express = exports.UserPermissions = exports.Scope = exports.ProjectPermissions = void 0;
39
+ const logsFormatter = __importStar(require("@crowdin/logs-formatter"));
39
40
  const express_handlebars_1 = __importDefault(require("express-handlebars"));
40
41
  const cron = __importStar(require("node-cron"));
41
42
  const path_1 = require("path");
42
- const logsFormatter = __importStar(require("@crowdin/logs-formatter"));
43
43
  const translate_1 = __importDefault(require("./handlers/custom-mt/translate"));
44
44
  const custom_file_format_1 = __importDefault(require("./handlers/file-processing/custom-file-format"));
45
45
  const file_download_1 = __importDefault(require("./handlers/file-processing/file-download"));
@@ -62,12 +62,14 @@ const oauth_login_1 = __importDefault(require("./handlers/integration/oauth-logi
62
62
  const oauth_url_1 = __importDefault(require("./handlers/integration/oauth-url"));
63
63
  const settings_save_1 = __importDefault(require("./handlers/integration/settings-save"));
64
64
  const subscription_info_1 = __importDefault(require("./handlers/integration/subscription-info"));
65
+ const job_info_1 = __importDefault(require("./handlers/integration/job-info"));
66
+ const job_cancel_1 = __importDefault(require("./handlers/integration/job-cancel"));
65
67
  const sync_settings_1 = __importDefault(require("./handlers/integration/sync-settings"));
66
68
  const sync_settings_save_1 = __importDefault(require("./handlers/integration/sync-settings-save"));
69
+ const user_errors_1 = __importDefault(require("./handlers/integration/user-errors"));
67
70
  const manifest_1 = __importDefault(require("./handlers/manifest"));
68
71
  const subscription_paid_1 = __importDefault(require("./handlers/subscription-paid"));
69
72
  const uninstall_1 = __importDefault(require("./handlers/uninstall"));
70
- const user_errors_1 = __importDefault(require("./handlers/user-errors"));
71
73
  const crowdin_client_1 = __importStar(require("./middlewares/crowdin-client"));
72
74
  const integration_credentials_1 = __importDefault(require("./middlewares/integration-credentials"));
73
75
  const json_response_1 = __importDefault(require("./middlewares/json-response"));
@@ -89,6 +91,29 @@ var models_2 = require("./models");
89
91
  Object.defineProperty(exports, "ProjectPermissions", { enumerable: true, get: function () { return models_2.ProjectPermissions; } });
90
92
  Object.defineProperty(exports, "Scope", { enumerable: true, get: function () { return models_2.Scope; } });
91
93
  Object.defineProperty(exports, "UserPermissions", { enumerable: true, get: function () { return models_2.UserPermissions; } });
94
+ exports.metadataStore = {
95
+ getMetadata: (id) => {
96
+ return storage.getStorage().getMetadata(id);
97
+ },
98
+ saveMetadata: (id, metadata, crowdinId) => __awaiter(void 0, void 0, void 0, function* () {
99
+ const existing = yield storage.getStorage().getMetadata(id);
100
+ if (existing) {
101
+ yield storage.getStorage().updateMetadata(id, metadata, crowdinId);
102
+ }
103
+ else {
104
+ yield storage.getStorage().saveMetadata(id, metadata, crowdinId);
105
+ }
106
+ }),
107
+ deleteMetadata: (id) => {
108
+ return storage.getStorage().deleteMetadata(id);
109
+ },
110
+ getUserSettings: (clientId) => __awaiter(void 0, void 0, void 0, function* () {
111
+ const integrationCredentials = yield storage.getStorage().getIntegrationConfig(clientId);
112
+ if (integrationCredentials === null || integrationCredentials === void 0 ? void 0 : integrationCredentials.config) {
113
+ return JSON.parse(integrationCredentials.config);
114
+ }
115
+ }),
116
+ };
92
117
  function addCrowdinEndpoints(app, clientConfig) {
93
118
  var _a, _b, _c, _d, _e, _f, _g;
94
119
  const config = (0, defaults_1.convertClientConfig)(clientConfig);
@@ -100,6 +125,7 @@ function addCrowdinEndpoints(app, clientConfig) {
100
125
  app.use(terminus_express_1.default.json({ limit: '50mb' }));
101
126
  if (!config.disableLogsFormatter) {
102
127
  logsFormatter.setup();
128
+ app.use(logsFormatter.contextResolverMiddleware());
103
129
  app.use(logsFormatter.expressMiddleware());
104
130
  }
105
131
  app.use('/assets', terminus_express_1.default.static((0, path_1.join)(__dirname, 'static')));
@@ -145,6 +171,8 @@ function addCrowdinEndpoints(app, clientConfig) {
145
171
  app.get((0, util_1.getLogoUrl)(integrationLogic, '/integration'), (req, res) => res.sendFile(integrationLogic.imagePath || config.imagePath));
146
172
  app.get('/', (0, crowdin_client_1.default)(config, true, false), (0, integration_credentials_1.default)(config, integrationLogic, true), (0, main_1.default)(config, integrationLogic));
147
173
  app.get('/api/subscription-info', json_response_1.default, (0, crowdin_client_1.default)(config), (0, subscription_info_1.default)(config));
174
+ app.get('/api/jobs', json_response_1.default, (0, crowdin_client_1.default)(config), (0, job_info_1.default)());
175
+ app.delete('/api/jobs', json_response_1.default, (0, crowdin_client_1.default)(config), (0, job_cancel_1.default)());
148
176
  app.post('/api/settings', (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, settings_save_1.default)(config, integrationLogic));
149
177
  app.post('/api/login', (0, crowdin_client_1.default)(config, false, false), (0, integration_login_1.default)(config, integrationLogic));
150
178
  app.post('/api/logout', (0, crowdin_client_1.default)(config, false, false), (0, integration_credentials_1.default)(config, integrationLogic), (0, integration_logout_1.default)(config, integrationLogic));
@@ -186,6 +214,7 @@ function addCrowdinEndpoints(app, clientConfig) {
186
214
  }
187
215
  }
188
216
  app.get('/api/user-errors', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, user_errors_1.default)());
217
+ cron.schedule('0 0 1 * *', () => (0, cron_1.removeFinishedJobs)());
189
218
  }
190
219
  if (config.customFileFormat) {
191
220
  (0, defaults_1.applyFileProcessorsModuleDefaults)(config, config.customFileFormat);
@@ -263,25 +292,7 @@ function addCrowdinEndpoints(app, clientConfig) {
263
292
  app.get('/api/form-data', json_response_1.default, (0, crowdin_client_1.default)(config), (0, form_data_display_1.default)());
264
293
  app.post('/api/form-data', (0, crowdin_client_1.default)(config), (0, form_data_save_1.default)());
265
294
  }
266
- return {
267
- getMetadata: storage.getStorage().getMetadata.bind(storage.getStorage()),
268
- saveMetadata: (id, metadata, crowdinId) => __awaiter(this, void 0, void 0, function* () {
269
- const existing = yield storage.getStorage().getMetadata(id);
270
- if (existing) {
271
- yield storage.getStorage().updateMetadata(id, metadata, crowdinId);
272
- }
273
- else {
274
- yield storage.getStorage().saveMetadata(id, metadata, crowdinId);
275
- }
276
- }),
277
- deleteMetadata: storage.getStorage().deleteMetadata.bind(storage.getStorage()),
278
- getUserSettings: (clientId) => __awaiter(this, void 0, void 0, function* () {
279
- const integrationCredentials = yield storage.getStorage().getIntegrationCredentials(clientId);
280
- if (integrationCredentials === null || integrationCredentials === void 0 ? void 0 : integrationCredentials.config) {
281
- return JSON.parse(integrationCredentials.config);
282
- }
283
- }),
284
- establishCrowdinConnection: (authRequest) => {
295
+ return Object.assign(Object.assign({}, exports.metadataStore), { establishCrowdinConnection: (authRequest) => {
285
296
  let jwtToken = '';
286
297
  if (typeof authRequest === 'string') {
287
298
  jwtToken = authRequest;
@@ -290,9 +301,7 @@ function addCrowdinEndpoints(app, clientConfig) {
290
301
  jwtToken = (0, crowdin_client_1.getToken)(authRequest);
291
302
  }
292
303
  return (0, crowdin_client_1.prepareCrowdinRequest)(jwtToken, config);
293
- },
294
- encryptCrowdinConnection: (data) => (0, util_1.encryptData)(config, JSON.stringify(data)),
295
- dencryptCrowdinConnection: (hash) => __awaiter(this, void 0, void 0, function* () {
304
+ }, encryptCrowdinConnection: (data) => (0, util_1.encryptData)(config, JSON.stringify(data)), dencryptCrowdinConnection: (hash) => __awaiter(this, void 0, void 0, function* () {
296
305
  const { crowdinId, extra } = JSON.parse((0, util_1.decryptData)(config, hash));
297
306
  const credentials = yield storage.getStorage().getCrowdinCredentials(crowdinId);
298
307
  if (!credentials) {
@@ -300,8 +309,7 @@ function addCrowdinEndpoints(app, clientConfig) {
300
309
  }
301
310
  const { client } = yield (0, connection_1.prepareCrowdinClient)({ config, credentials });
302
311
  return { client, extra };
303
- }),
304
- };
312
+ }) });
305
313
  }
306
314
  exports.addCrowdinEndpoints = addCrowdinEndpoints;
307
315
  function createApp(clientConfig) {
@@ -24,6 +24,7 @@ function prepareCrowdinRequest(jwtToken, config, optional = false, checkSubscrip
24
24
  jwtPayload,
25
25
  clientId: (0, crowdin_apps_functions_1.constructCrowdinIdFromJwtPayload)(jwtPayload),
26
26
  crowdinId: `${jwtPayload.domain || jwtPayload.context.organization_id}`,
27
+ appIdentifier: config.identifier,
27
28
  };
28
29
  const logInfo = (0, logger_1.withContext)(context);
29
30
  const logError = (0, logger_1.withContextError)(context);
@@ -17,14 +17,15 @@ function handle(config, integration, optional = false) {
17
17
  const clientId = req.crowdinContext.clientId;
18
18
  req.logInfo(`Loading integration credentials for client ${clientId}`);
19
19
  const integrationCredentials = yield (0, storage_1.getStorage)().getIntegrationCredentials(clientId);
20
+ const integrationConfig = yield (0, storage_1.getStorage)().getIntegrationConfig(clientId);
20
21
  if (!integrationCredentials) {
21
22
  if (optional) {
22
23
  return next();
23
24
  }
24
25
  return res.status(403).send({ error: 'Access denied' });
25
26
  }
26
- if (integrationCredentials.config) {
27
- req.integrationSettings = JSON.parse(integrationCredentials.config);
27
+ if (integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.config) {
28
+ req.integrationSettings = JSON.parse(integrationConfig.config);
28
29
  }
29
30
  try {
30
31
  req.integrationCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
@@ -31,6 +31,7 @@ function handle(config, allowUnauthorized = false) {
31
31
  jwtPayload,
32
32
  clientId: (0, crowdin_apps_functions_1.constructCrowdinIdFromJwtPayload)(jwtPayload),
33
33
  crowdinId: id,
34
+ appIdentifier: config.identifier,
34
35
  };
35
36
  const logInfo = (0, logger_1.withContext)(context);
36
37
  logInfo('Loading crowdin credentials');