@crowdin/app-project-module 1.9.0 → 1.10.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.
@@ -8,6 +8,7 @@ const crowdin_client_1 = __importDefault(require("../../middlewares/crowdin-clie
8
8
  const util_1 = require("../../util");
9
9
  const normalize_module_1 = require("../../util/normalize-module");
10
10
  const file_download_1 = __importDefault(require("../file-processing/handlers/file-download"));
11
+ const folder_1 = require("../file-processing/util/folder");
11
12
  const translate_1 = __importDefault(require("./handlers/translate"));
12
13
  function register({ config, app }) {
13
14
  var _a;
@@ -18,7 +19,7 @@ function register({ config, app }) {
18
19
  const isSingle = items.length === 1;
19
20
  for (const [index, mt] of items.entries()) {
20
21
  const key = (_a = mt.key) !== null && _a !== void 0 ? _a : (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'mt', item: mt, index, isSingle });
21
- const folder = mt.filesFolder || config.dbFolder;
22
+ const folder = (0, folder_1.resolveModuleFilesFolder)(config.dbFolder, mt.filesFolder);
22
23
  const logoPath = isSingle ? '/logo/mt' : `/logo/mt-${key}`;
23
24
  const translatePath = isSingle ? '/mt/translate' : `/mt/${key}/translate`;
24
25
  const downloadPath = isSingle ? '/file/download/custom-mt' : `/file/download/custom-mt-${key}`;
@@ -17,8 +17,9 @@ const fs_1 = __importDefault(require("fs"));
17
17
  const path_1 = __importDefault(require("path"));
18
18
  const util_1 = require("../../../util");
19
19
  const logger_1 = require("../../../util/logger");
20
+ const folder_1 = require("../util/folder");
20
21
  function handle(config, processingConfig, folderName) {
21
- const folder = processingConfig.filesFolder || config.dbFolder;
22
+ const folder = (0, folder_1.resolveModuleFilesFolder)(config.dbFolder, processingConfig.filesFolder);
22
23
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
23
24
  if (config.fileStore) {
24
25
  const fileContent = yield config.fileStore.getFile(req.query.file);
@@ -17,9 +17,10 @@ const fs_1 = __importDefault(require("fs"));
17
17
  const path_1 = __importDefault(require("path"));
18
18
  const util_1 = require("../../../util");
19
19
  const types_1 = require("../types");
20
+ const folder_1 = require("../util/folder");
20
21
  const files_1 = require("../util/files");
21
22
  function handle(baseConfig, config, folderName) {
22
- const folderPath = config.filesFolder || baseConfig.dbFolder;
23
+ const folderPath = (0, folder_1.resolveModuleFilesFolder)(baseConfig.dbFolder, config.filesFolder);
23
24
  if (!baseConfig.fileStore) {
24
25
  if (!fs_1.default.existsSync(path_1.default.join(folderPath, folderName))) {
25
26
  fs_1.default.mkdirSync(path_1.default.join(folderPath, folderName), { recursive: true });
@@ -16,9 +16,10 @@ exports.default = handle;
16
16
  const fs_1 = __importDefault(require("fs"));
17
17
  const path_1 = __importDefault(require("path"));
18
18
  const util_1 = require("../../../util");
19
+ const folder_1 = require("../util/folder");
19
20
  const files_1 = require("../util/files");
20
21
  function handle(baseConfig, config, folderName) {
21
- const folderPath = config.filesFolder || baseConfig.dbFolder;
22
+ const folderPath = (0, folder_1.resolveModuleFilesFolder)(baseConfig.dbFolder, config.filesFolder);
22
23
  if (!fs_1.default.existsSync(path_1.default.join(folderPath, folderName))) {
23
24
  fs_1.default.mkdirSync(path_1.default.join(folderPath, folderName), { recursive: true });
24
25
  }
@@ -17,6 +17,7 @@ const pre_post_process_1 = __importDefault(require("./handlers/pre-post-process"
17
17
  const translations_alignment_1 = __importDefault(require("./handlers/translations-alignment"));
18
18
  const types_1 = require("./types");
19
19
  const defaults_1 = require("./util/defaults");
20
+ const folder_1 = require("./util/folder");
20
21
  function registerCustomFileFormat({ config, app }) {
21
22
  var _a;
22
23
  if (!config.customFileFormat) {
@@ -35,7 +36,7 @@ function registerCustomFileFormat({ config, app }) {
35
36
  moduleKey: key,
36
37
  }), (0, custom_file_format_1.default)({
37
38
  baseUrl: config.baseUrl,
38
- folder: ff.filesFolder || config.dbFolder,
39
+ folder: (0, folder_1.resolveModuleFilesFolder)(config.dbFolder, ff.filesFolder),
39
40
  config: ff,
40
41
  fileStore: config.fileStore,
41
42
  }));
@@ -50,7 +51,7 @@ function registerCustomFileFormat({ config, app }) {
50
51
  checkSubscriptionExpiration: true,
51
52
  }), (0, custom_file_format_1.default)({
52
53
  baseUrl: config.baseUrl,
53
- folder: ff.filesFolder || config.dbFolder,
54
+ folder: (0, folder_1.resolveModuleFilesFolder)(config.dbFolder, ff.filesFolder),
54
55
  config: ff,
55
56
  fileStore: config.fileStore,
56
57
  }));
@@ -0,0 +1 @@
1
+ export declare function resolveModuleFilesFolder(dbFolder: string, filesFolder?: string): string;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveModuleFilesFolder = resolveModuleFilesFolder;
4
+ const LAMBDA_TMP_FOLDER = '/tmp';
5
+ function resolveModuleFilesFolder(dbFolder, filesFolder) {
6
+ if (filesFolder) {
7
+ return filesFolder;
8
+ }
9
+ if (process.env.AWS_LAMBDA_FUNCTION_NAME) {
10
+ return LAMBDA_TMP_FOLDER;
11
+ }
12
+ return dbFolder;
13
+ }
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.default = handle;
13
13
  const util_1 = require("../../../util");
14
14
  const storage_1 = require("../../../storage");
15
+ const types_1 = require("../util/types");
15
16
  function handle() {
16
17
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
17
18
  const limit = req.query.limit ? parseInt(req.query.limit, 10) : 25;
@@ -28,7 +29,9 @@ function handle() {
28
29
  res.send([]);
29
30
  return;
30
31
  }
31
- const filteredJobs = jobs.map((job) => {
32
+ const filteredJobs = jobs
33
+ .filter((job) => job.type !== types_1.JobType.INTEGRATION_SETTINGS_SAVE)
34
+ .map((job) => {
32
35
  var _a;
33
36
  const baseJob = {
34
37
  id: job.id,
@@ -16,6 +16,8 @@ const snapshot_1 = require("../util/snapshot");
16
16
  const webhooks_1 = require("../util/webhooks");
17
17
  const types_1 = require("../types");
18
18
  const cron_1 = require("../util/cron");
19
+ const job_1 = require("../util/job");
20
+ const types_2 = require("../util/types");
19
21
  function handle(config, integration) {
20
22
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
21
23
  const settings = req.body.config;
@@ -42,46 +44,59 @@ function handle(config, integration) {
42
44
  }
43
45
  }
44
46
  const clientId = req.crowdinContext.clientId;
45
- req.logInfo(`Saving settings ${JSON.stringify(settings, null, 2)}`);
46
- const integrationConfig = yield (0, storage_1.getStorage)().getIntegrationConfig(clientId);
47
- if (!integrationConfig) {
48
- yield (0, storage_1.getStorage)().saveIntegrationConfig(clientId, req.crowdinContext.crowdinId, JSON.stringify(settings));
49
- }
50
- else {
51
- yield (0, storage_1.getStorage)().updateIntegrationConfig(clientId, JSON.stringify(settings));
52
- }
53
- if (integration.webhooks) {
54
- yield (0, webhooks_1.registerWebhooks)({
55
- config,
56
- integration,
57
- client: req.crowdinApiClient,
58
- crowdinContext: req.crowdinContext,
59
- credentials: req.integrationCredentials,
60
- settings,
61
- });
62
- }
63
- else {
64
- if (settings === null || settings === void 0 ? void 0 : settings['new-crowdin-files']) {
65
- (0, snapshot_1.createOrUpdateFileSnapshot)(config, integration, req, types_1.Provider.CROWDIN);
66
- }
67
- if (settings === null || settings === void 0 ? void 0 : settings['new-integration-files']) {
68
- (0, snapshot_1.createOrUpdateFileSnapshot)(config, integration, req, types_1.Provider.INTEGRATION);
69
- }
70
- }
71
- if (integration.syncNewElements) {
72
- yield (0, cron_1.createOrUpdateSyncSettings)({
73
- req,
74
- files: {},
75
- provider: types_1.Provider.CROWDIN,
76
- onlyCreate: true,
77
- });
78
- yield (0, cron_1.createOrUpdateSyncSettings)({
79
- req,
80
- files: [],
81
- provider: types_1.Provider.INTEGRATION,
82
- onlyCreate: true,
83
- });
84
- }
85
- res.status(204).end();
47
+ yield (0, job_1.runAsJob)({
48
+ integrationId: clientId,
49
+ crowdinId: req.crowdinContext.crowdinId,
50
+ type: types_2.JobType.INTEGRATION_SETTINGS_SAVE,
51
+ title: 'Save settings',
52
+ payload: req.body,
53
+ res,
54
+ projectId: req.crowdinContext.jwtPayload.context.project_id,
55
+ client: req.crowdinApiClient,
56
+ jobType: types_2.JobClientType.HIDDEN,
57
+ jobStoreType: integration.jobStoreType,
58
+ jobCallback: () => __awaiter(this, void 0, void 0, function* () {
59
+ req.logInfo(`Saving settings ${JSON.stringify(settings, null, 2)}`);
60
+ const integrationConfig = yield (0, storage_1.getStorage)().getIntegrationConfig(clientId);
61
+ if (!integrationConfig) {
62
+ yield (0, storage_1.getStorage)().saveIntegrationConfig(clientId, req.crowdinContext.crowdinId, JSON.stringify(settings));
63
+ }
64
+ else {
65
+ yield (0, storage_1.getStorage)().updateIntegrationConfig(clientId, JSON.stringify(settings));
66
+ }
67
+ if (integration.webhooks) {
68
+ yield (0, webhooks_1.registerWebhooks)({
69
+ config,
70
+ integration,
71
+ client: req.crowdinApiClient,
72
+ crowdinContext: req.crowdinContext,
73
+ credentials: req.integrationCredentials,
74
+ settings,
75
+ });
76
+ }
77
+ else {
78
+ if (settings === null || settings === void 0 ? void 0 : settings['new-crowdin-files']) {
79
+ (0, snapshot_1.createOrUpdateFileSnapshot)(config, integration, req, types_1.Provider.CROWDIN);
80
+ }
81
+ if (settings === null || settings === void 0 ? void 0 : settings['new-integration-files']) {
82
+ (0, snapshot_1.createOrUpdateFileSnapshot)(config, integration, req, types_1.Provider.INTEGRATION);
83
+ }
84
+ }
85
+ if (integration.syncNewElements) {
86
+ yield (0, cron_1.createOrUpdateSyncSettings)({
87
+ req,
88
+ files: {},
89
+ provider: types_1.Provider.CROWDIN,
90
+ onlyCreate: true,
91
+ });
92
+ yield (0, cron_1.createOrUpdateSyncSettings)({
93
+ req,
94
+ files: [],
95
+ provider: types_1.Provider.INTEGRATION,
96
+ onlyCreate: true,
97
+ });
98
+ }
99
+ }),
100
+ });
86
101
  }));
87
102
  }
@@ -11,15 +11,33 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.default = handle;
13
13
  const util_1 = require("../../../util");
14
+ const storage_1 = require("../../../storage");
14
15
  const cron_1 = require("../util/cron");
15
16
  const snapshot_1 = require("../util/snapshot");
16
17
  const files_1 = require("../util/files");
17
18
  const job_1 = require("../util/job");
18
19
  const types_1 = require("../util/types");
19
20
  const types_2 = require("../types");
21
+ const SUPPORTED_SCHEDULE_VALUES = new Set(['0', '1', '3', '6', '12', '24']);
22
+ function isScheduleDisabled(schedule) {
23
+ return schedule === undefined || schedule === null || String(schedule) === '0';
24
+ }
25
+ function getAutoEnabledSchedule(integration) {
26
+ var _a;
27
+ const configuredValue = String((_a = integration.autoEnableScheduleOnAutoSync) !== null && _a !== void 0 ? _a : '12');
28
+ return SUPPORTED_SCHEDULE_VALUES.has(configuredValue) ? configuredValue : '12';
29
+ }
30
+ function getScheduleLabel(schedule) {
31
+ return schedule === '1' ? '1 hour' : `${schedule} hours`;
32
+ }
20
33
  function handle(config, integration) {
21
34
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
35
+ var _a;
22
36
  const { files, provider, expandIntegrationFolders, hasLoadMoreElements, folderIds } = req.body;
37
+ const clientId = req.crowdinContext.clientId;
38
+ const autoEnabledSchedule = getAutoEnabledSchedule(integration);
39
+ let scheduleAutoEnabled = false;
40
+ const scheduleMessage = `Auto Sync requires a sync schedule. It has been automatically set to every ${getScheduleLabel(autoEnabledSchedule)}. You can adjust this in the app settings.`;
23
41
  if (req.isApiCall) {
24
42
  if (!files || !provider) {
25
43
  return res.status(400).json({
@@ -36,8 +54,23 @@ function handle(config, integration) {
36
54
  });
37
55
  }
38
56
  }
57
+ if (autoEnabledSchedule !== '0' && isScheduleDisabled((_a = req.integrationSettings) === null || _a === void 0 ? void 0 : _a.schedule)) {
58
+ const integrationConfig = yield (0, storage_1.getStorage)().getIntegrationConfig(clientId);
59
+ const currentSettings = (integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.config)
60
+ ? JSON.parse(integrationConfig.config)
61
+ : req.integrationSettings || {};
62
+ const nextSettings = Object.assign(Object.assign({}, currentSettings), { schedule: autoEnabledSchedule });
63
+ if (!integrationConfig) {
64
+ yield (0, storage_1.getStorage)().saveIntegrationConfig(clientId, req.crowdinContext.crowdinId, JSON.stringify(nextSettings));
65
+ }
66
+ else {
67
+ yield (0, storage_1.getStorage)().updateIntegrationConfig(clientId, JSON.stringify(nextSettings));
68
+ }
69
+ req.integrationSettings = nextSettings;
70
+ scheduleAutoEnabled = true;
71
+ }
39
72
  yield (0, job_1.runAsJob)({
40
- integrationId: req.crowdinContext.clientId,
73
+ integrationId: clientId,
41
74
  crowdinId: req.crowdinContext.crowdinId,
42
75
  type: `${provider}SyncSettingsSave`,
43
76
  title: 'Save sync settings',
@@ -49,7 +82,16 @@ function handle(config, integration) {
49
82
  jobStoreType: integration.jobStoreType,
50
83
  initiatedBy: String(req.crowdinContext.jwtPayload.context.user_id),
51
84
  jobCallback: (job) => __awaiter(this, void 0, void 0, function* () {
52
- var _a;
85
+ var _a, _b, _c, _d, _e;
86
+ if (scheduleAutoEnabled) {
87
+ const { isCanceled } = yield job.update({ info: scheduleMessage });
88
+ if (isCanceled) {
89
+ return;
90
+ }
91
+ }
92
+ if (types_1.JobStatus.CANCELED === ((_a = (yield job.get())) === null || _a === void 0 ? void 0 : _a.status)) {
93
+ return;
94
+ }
53
95
  if (Array.isArray(expandIntegrationFolders) && expandIntegrationFolders.length) {
54
96
  const expandedFiles = hasLoadMoreElements
55
97
  ? yield (0, files_1.expandFilesTreeWithPagination)(expandIntegrationFolders, req, integration, job)
@@ -64,6 +106,9 @@ function handle(config, integration) {
64
106
  type: node.type,
65
107
  }));
66
108
  req.logInfo(`Expanded ${allFiles.length} files for auto-sync`);
109
+ if (types_1.JobStatus.CANCELED === ((_b = (yield job.get())) === null || _b === void 0 ? void 0 : _b.status)) {
110
+ return;
111
+ }
67
112
  yield (0, cron_1.createOrUpdateSyncSettings)({
68
113
  req,
69
114
  files: (0, util_1.uniqBy)([...files, ...allFiles], 'id'),
@@ -71,6 +116,9 @@ function handle(config, integration) {
71
116
  });
72
117
  }
73
118
  else {
119
+ if (types_1.JobStatus.CANCELED === ((_c = (yield job.get())) === null || _c === void 0 ? void 0 : _c.status)) {
120
+ return;
121
+ }
74
122
  yield (0, cron_1.createOrUpdateSyncSettings)({
75
123
  req,
76
124
  files: (0, files_1.prepareSyncFiles)(files),
@@ -83,11 +131,17 @@ function handle(config, integration) {
83
131
  ? (0, files_1.hasFolders)(syncFiles)
84
132
  : Array.isArray(folderIds) && folderIds.length > 0;
85
133
  const needsSnapshot = !integration.webhooks &&
86
- ((_a = integration.syncNewElements) === null || _a === void 0 ? void 0 : _a[provider]) &&
134
+ ((_d = integration.syncNewElements) === null || _d === void 0 ? void 0 : _d[provider]) &&
87
135
  (settings[`new-${provider}-files`] || hasSyncedFolders);
88
136
  if (needsSnapshot) {
137
+ if (types_1.JobStatus.CANCELED === ((_e = (yield job.get())) === null || _e === void 0 ? void 0 : _e.status)) {
138
+ return;
139
+ }
89
140
  yield (0, snapshot_1.createOrUpdateFileSnapshot)(config, integration, req, provider, job);
90
141
  }
142
+ if (scheduleAutoEnabled) {
143
+ yield job.update({ info: scheduleMessage });
144
+ }
91
145
  }),
92
146
  });
93
147
  }));
@@ -157,6 +157,13 @@ export interface IntegrationLogic extends ModuleKey {
157
157
  crowdin: boolean;
158
158
  integration: boolean;
159
159
  };
160
+ /**
161
+ * Schedule value that will be auto-applied when user enables Auto Sync while current schedule is disabled.
162
+ * Supported values are: '0', '1', '3', '6', '12', '24'.
163
+ * Use '0' to disable this auto-apply behavior.
164
+ * @default '12'
165
+ */
166
+ autoEnableScheduleOnAutoSync?: '0' | '1' | '3' | '6' | '12' | '24';
160
167
  /**
161
168
  * Enable file filtering
162
169
  */
@@ -59,13 +59,16 @@ function skipFilesByRegex(files, skipIntegrationNodes) {
59
59
  }
60
60
  function expandFilesTree(nodes, req, integration, job) {
61
61
  return __awaiter(this, void 0, void 0, function* () {
62
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
62
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
63
63
  if (job && types_2.JobStatus.CANCELED === ((_a = (yield job.get())) === null || _a === void 0 ? void 0 : _a.status)) {
64
64
  throw new Error('Job canceled');
65
65
  }
66
66
  const files = nodes.filter((file) => file.nodeType === undefined || file.nodeType === '1');
67
67
  const folders = nodes.filter((folder) => folder.nodeType === '0' && !nodes.find((node) => node.parentId === folder.id));
68
68
  for (const { id, name } of folders) {
69
+ if (job && types_2.JobStatus.CANCELED === ((_b = (yield job.get())) === null || _b === void 0 ? void 0 : _b.status)) {
70
+ throw new Error('Job canceled');
71
+ }
69
72
  let integrationData = [];
70
73
  try {
71
74
  integrationData = yield integration.getIntegrationFiles({
@@ -95,13 +98,16 @@ function expandFilesTree(nodes, req, integration, job) {
95
98
  const checkNodes = integrationTreeItems
96
99
  .filter((item) => item.id !== id)
97
100
  .map((item) => (Object.assign(Object.assign({}, item), { nodeType: item.nodeType || ('type' in item ? '1' : '0') })));
101
+ if (job && types_2.JobStatus.CANCELED === ((_c = (yield job.get())) === null || _c === void 0 ? void 0 : _c.status)) {
102
+ throw new Error('Job canceled');
103
+ }
98
104
  const expandedResult = yield expandFilesTree(checkNodes, req, integration, job);
99
105
  files.push(...expandedResult);
100
106
  }
101
- const needsFileStatus = ((_c = (_b = integration.filtering) === null || _b === void 0 ? void 0 : _b.integrationFileStatus) === null || _c === void 0 ? void 0 : _c.isNew) ||
102
- ((_e = (_d = integration.filtering) === null || _d === void 0 ? void 0 : _d.integrationFileStatus) === null || _e === void 0 ? void 0 : _e.isUpdated) ||
103
- ((_g = (_f = integration.filtering) === null || _f === void 0 ? void 0 : _f.integrationFileStatus) === null || _g === void 0 ? void 0 : _g.notSynced) ||
104
- ((_j = (_h = integration.filtering) === null || _h === void 0 ? void 0 : _h.integrationFileStatus) === null || _j === void 0 ? void 0 : _j.synced) ||
107
+ const needsFileStatus = ((_e = (_d = integration.filtering) === null || _d === void 0 ? void 0 : _d.integrationFileStatus) === null || _e === void 0 ? void 0 : _e.isNew) ||
108
+ ((_g = (_f = integration.filtering) === null || _f === void 0 ? void 0 : _f.integrationFileStatus) === null || _g === void 0 ? void 0 : _g.isUpdated) ||
109
+ ((_j = (_h = integration.filtering) === null || _h === void 0 ? void 0 : _h.integrationFileStatus) === null || _j === void 0 ? void 0 : _j.notSynced) ||
110
+ ((_l = (_k = integration.filtering) === null || _k === void 0 ? void 0 : _k.integrationFileStatus) === null || _l === void 0 ? void 0 : _l.synced) ||
105
111
  integration.forcePushSources === true;
106
112
  if (needsFileStatus) {
107
113
  const { crowdinId, clientId } = req.crowdinContext;
@@ -159,19 +165,22 @@ function attachFileStatus(files, clientId, crowdinId, integration) {
159
165
  }
160
166
  function expandFilesTreeWithPagination(nodes, req, integration, job) {
161
167
  return __awaiter(this, void 0, void 0, function* () {
162
- var _a, _b;
168
+ var _a, _b, _c, _d;
163
169
  if (job && types_2.JobStatus.CANCELED === ((_a = (yield job.get())) === null || _a === void 0 ? void 0 : _a.status)) {
164
170
  throw new Error('Job canceled');
165
171
  }
166
172
  const files = nodes.filter((file) => file.nodeType === undefined || file.nodeType === '1');
167
173
  const folders = nodes.filter((folder) => folder.nodeType === '0' && !nodes.find((node) => node.parentId === folder.id));
168
174
  for (const folder of folders) {
175
+ if (job && types_2.JobStatus.CANCELED === ((_b = (yield job.get())) === null || _b === void 0 ? void 0 : _b.status)) {
176
+ throw new Error('Job canceled');
177
+ }
169
178
  const allFolderFiles = [];
170
179
  let paginationData = undefined;
171
180
  let hasMore = true;
172
181
  let pageCount = 0;
173
182
  while (hasMore) {
174
- if (job && types_2.JobStatus.CANCELED === ((_b = (yield job.get())) === null || _b === void 0 ? void 0 : _b.status)) {
183
+ if (job && types_2.JobStatus.CANCELED === ((_c = (yield job.get())) === null || _c === void 0 ? void 0 : _c.status)) {
175
184
  throw new Error('Job canceled');
176
185
  }
177
186
  pageCount++;
@@ -225,6 +234,9 @@ function expandFilesTreeWithPagination(nodes, req, integration, job) {
225
234
  const checkNodes = allFolderFiles
226
235
  .filter((item) => item.id !== folder.id)
227
236
  .map((item) => (Object.assign(Object.assign({}, item), { nodeType: item.nodeType || ('type' in item ? '1' : '0') })));
237
+ if (job && types_2.JobStatus.CANCELED === ((_d = (yield job.get())) === null || _d === void 0 ? void 0 : _d.status)) {
238
+ throw new Error('Job canceled');
239
+ }
228
240
  const expandedResult = yield expandFilesTreeWithPagination(checkNodes, req, integration, job);
229
241
  files.push(...expandedResult);
230
242
  }
@@ -2,7 +2,7 @@ import Crowdin from '@crowdin/crowdin-api-client';
2
2
  import { Response } from 'express';
3
3
  import { Config } from '../../../types';
4
4
  import { JobClient, JobClientType, JobStoreType, JobType } from './types';
5
- export declare function runAsJob({ integrationId, crowdinId, type, title, payload, res, projectId, client, jobType, jobStoreType, jobCallback, onError, reRunJobId, forcePushTranslations, initiatedBy, }: {
5
+ export declare function runAsJob({ integrationId, crowdinId, type, title, payload, res, projectId, client, jobType, jobStoreType, responseData, jobCallback, onError, reRunJobId, forcePushTranslations, initiatedBy, }: {
6
6
  integrationId: string;
7
7
  crowdinId: string;
8
8
  type: JobType;
@@ -13,6 +13,7 @@ export declare function runAsJob({ integrationId, crowdinId, type, title, payloa
13
13
  client: Crowdin;
14
14
  jobType: JobClientType;
15
15
  jobStoreType: JobStoreType;
16
+ responseData?: Record<string, any>;
16
17
  jobCallback: (arg1: JobClient) => Promise<any>;
17
18
  onError?: (e: any, job: JobClient) => Promise<void>;
18
19
  reRunJobId?: string;
@@ -24,11 +24,12 @@ const blockingJobs = {
24
24
  [types_1.JobType.UPDATE_TARGET_LANGUAGES]: [types_1.JobType.UPDATE_TARGET_LANGUAGES],
25
25
  [types_1.JobType.CROWDIN_SYNC_SETTINGS_SAVE]: [types_1.JobType.CROWDIN_SYNC_SETTINGS_SAVE],
26
26
  [types_1.JobType.INTEGRATION_SYNC_SETTINGS_SAVE]: [types_1.JobType.INTEGRATION_SYNC_SETTINGS_SAVE],
27
+ [types_1.JobType.INTEGRATION_SETTINGS_SAVE]: [types_1.JobType.INTEGRATION_SETTINGS_SAVE],
27
28
  };
28
29
  const maxAttempts = 3;
29
30
  const store = {};
30
31
  function runAsJob(_a) {
31
- return __awaiter(this, arguments, void 0, function* ({ integrationId, crowdinId, type, title, payload, res, projectId, client, jobType, jobStoreType, jobCallback, onError, reRunJobId, forcePushTranslations, initiatedBy, }) {
32
+ return __awaiter(this, arguments, void 0, function* ({ integrationId, crowdinId, type, title, payload, res, projectId, client, jobType, jobStoreType, responseData, jobCallback, onError, reRunJobId, forcePushTranslations, initiatedBy, }) {
32
33
  let jobId;
33
34
  const storage = (0, storage_1.getStorage)();
34
35
  if (!reRunJobId) {
@@ -56,7 +57,7 @@ function runAsJob(_a) {
56
57
  jobId = reRunJobId;
57
58
  }
58
59
  if (res) {
59
- res.status(202).send({ jobId });
60
+ res.status(202).send(Object.assign({ jobId }, responseData));
60
61
  }
61
62
  const isDbStore = jobStoreType === 'db';
62
63
  const job = {
@@ -9,7 +9,8 @@ export declare enum JobType {
9
9
  UPDATE_TO_INTEGRATION = "updateIntegration",
10
10
  UPDATE_TARGET_LANGUAGES = "updateTargetLanguages",
11
11
  CROWDIN_SYNC_SETTINGS_SAVE = "crowdinSyncSettingsSave",
12
- INTEGRATION_SYNC_SETTINGS_SAVE = "integrationSyncSettingsSave"
12
+ INTEGRATION_SYNC_SETTINGS_SAVE = "integrationSyncSettingsSave",
13
+ INTEGRATION_SETTINGS_SAVE = "integrationSettingsSave"
13
14
  }
14
15
  export declare enum JobStatus {
15
16
  CREATED = "created",
@@ -21,7 +22,8 @@ export declare enum JobStatus {
21
22
  export declare enum JobClientType {
22
23
  CRON = "cron",
23
24
  MANUAL = "manual",
24
- RERUN = "rerun"
25
+ RERUN = "rerun",
26
+ HIDDEN = "hidden"
25
27
  }
26
28
  export type JobStoreType = 'db' | 'in-memory';
27
29
  export interface Job {
@@ -8,6 +8,7 @@ var JobType;
8
8
  JobType["UPDATE_TARGET_LANGUAGES"] = "updateTargetLanguages";
9
9
  JobType["CROWDIN_SYNC_SETTINGS_SAVE"] = "crowdinSyncSettingsSave";
10
10
  JobType["INTEGRATION_SYNC_SETTINGS_SAVE"] = "integrationSyncSettingsSave";
11
+ JobType["INTEGRATION_SETTINGS_SAVE"] = "integrationSettingsSave";
11
12
  })(JobType || (exports.JobType = JobType = {}));
12
13
  var JobStatus;
13
14
  (function (JobStatus) {
@@ -22,4 +23,5 @@ var JobClientType;
22
23
  JobClientType["CRON"] = "cron";
23
24
  JobClientType["MANUAL"] = "manual";
24
25
  JobClientType["RERUN"] = "rerun";
26
+ JobClientType["HIDDEN"] = "hidden";
25
27
  })(JobClientType || (exports.JobClientType = JobClientType = {}));