@crowdin/app-project-module 0.35.1 → 0.37.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.
@@ -53,7 +53,6 @@ function catchRejection(e, message) {
53
53
  subscriptionModal.open();
54
54
  return;
55
55
  }
56
- console.error(e.message || message);
57
56
  showToast(e.message || message);
58
57
  }
59
58
 
@@ -1,4 +1,4 @@
1
- import { Config, CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, Provider } from '../models';
1
+ import { Config, CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks, Provider } from '../models';
2
2
  export interface Storage {
3
3
  migrate(): Promise<void>;
4
4
  saveCrowdinCredentials(credentials: CrowdinCredentials): Promise<void>;
@@ -25,6 +25,10 @@ export interface Storage {
25
25
  saveFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: Provider): Promise<void>;
26
26
  updateFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: Provider): Promise<void>;
27
27
  getFilesSnapshot(integrationId: string, crowdinId: string, provider: Provider): Promise<IntegrationFilesSnapshot | undefined>;
28
+ getAllWebhooks(integrationId: string, crowdinId: string, provider: Provider): Promise<IntegrationWebhooks[] | undefined>;
29
+ getWebhooks(fileId: string, integrationId: string, crowdinId: string, provider: Provider): Promise<IntegrationWebhooks | undefined>;
30
+ saveWebhooks(fileId: string, integrationId: string, crowdinId: string, provider: Provider): Promise<void>;
31
+ deleteWebhooks(fileIds: any[], integrationId: string, crowdinId: string, provider: Provider): Promise<void>;
28
32
  }
29
33
  export declare function initialize(config: Config): Promise<void>;
30
34
  export declare function getStorage(): Storage;
@@ -1,5 +1,5 @@
1
1
  import { Storage } from '.';
2
- import { CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings } from '../models';
2
+ import { CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks } from '../models';
3
3
  export interface MySQLStorageConfig {
4
4
  uri?: string;
5
5
  host?: string;
@@ -42,4 +42,8 @@ export declare class MySQLStorage implements Storage {
42
42
  saveFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: string): Promise<void>;
43
43
  updateFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: string): Promise<void>;
44
44
  getFilesSnapshot(integrationId: string, crowdinId: string, provider: string): Promise<IntegrationFilesSnapshot | undefined>;
45
+ getAllWebhooks(integrationId: string, crowdinId: string, provider: string): Promise<IntegrationWebhooks[] | undefined>;
46
+ getWebhooks(fileId: string, integrationId: string, crowdinId: string, provider: string): Promise<IntegrationWebhooks | undefined>;
47
+ saveWebhooks(fileId: string, integrationId: string, crowdinId: string, provider: string): Promise<void>;
48
+ deleteWebhooks(fileIds: any[], integrationId: string, crowdinId: string, provider: string): Promise<void>;
45
49
  }
@@ -114,6 +114,16 @@ class MySQLStorage {
114
114
  provider varchar(255) not null
115
115
  )
116
116
  `);
117
+ yield connection.execute(`
118
+ create table if not exists webhooks
119
+ (
120
+ id int auto_increment primary key,
121
+ file_id varchar(255) not null,
122
+ integration_id varchar(255) not null,
123
+ crowdin_id varchar(255) not null,
124
+ provider varchar(255) not null
125
+ )
126
+ `);
117
127
  });
118
128
  }
119
129
  saveCrowdinCredentials(credentials) {
@@ -176,6 +186,7 @@ class MySQLStorage {
176
186
  yield connection.execute('DELETE FROM sync_settings WHERE crowdin_id = ?', [id]);
177
187
  yield connection.execute('DELETE FROM app_metadata WHERE crowdin_id = ?', [id]);
178
188
  yield connection.execute('DELETE FROM files_snapshot WHERE crowdin_id = ?', [id]);
189
+ yield connection.execute('DELETE FROM webhooks WHERE crowdin_id = ?', [id]);
179
190
  }));
180
191
  });
181
192
  }
@@ -226,6 +237,7 @@ class MySQLStorage {
226
237
  yield connection.execute('DELETE FROM integration_credentials where id = ?', [id]);
227
238
  yield connection.execute('DELETE FROM sync_settings where integration_id = ?', [id]);
228
239
  yield connection.execute('DELETE FROM files_snapshot where integration_id = ?', [id]);
240
+ yield connection.execute('DELETE FROM webhooks where integration_id = ?', [id]);
229
241
  }));
230
242
  });
231
243
  }
@@ -236,6 +248,7 @@ class MySQLStorage {
236
248
  yield connection.execute('DELETE FROM integration_credentials where crowdin_id = ?', [crowdinId]);
237
249
  yield connection.execute('DELETE FROM sync_settings where crowdin_id = ?', [crowdinId]);
238
250
  yield connection.execute('DELETE FROM files_snapshot where crowdin_id = ?', [crowdinId]);
251
+ yield connection.execute('DELETE FROM webhooks where crowdin_id = ?', [crowdinId]);
239
252
  }));
240
253
  });
241
254
  }
@@ -336,5 +349,36 @@ class MySQLStorage {
336
349
  }));
337
350
  });
338
351
  }
352
+ getAllWebhooks(integrationId, crowdinId, provider) {
353
+ return __awaiter(this, void 0, void 0, function* () {
354
+ yield this.dbPromise;
355
+ return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
356
+ const [rows] = yield connection.execute('SELECT id, file_id as "fileId", integration_id as "integrationId", crowdin_id as "crowdinId" FROM webhooks WHERE integration_id = ? AND crowdin_id = ? AND provider = ?', [integrationId, crowdinId, provider]);
357
+ return rows || [];
358
+ }));
359
+ });
360
+ }
361
+ getWebhooks(fileId, integrationId, crowdinId, provider) {
362
+ return __awaiter(this, void 0, void 0, function* () {
363
+ yield this.dbPromise;
364
+ return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
365
+ const [rows] = yield connection.execute('SELECT id, file_id as "fileId", integration_id as "integrationId", crowdin_id as "crowdinId" FROM webhooks WHERE file_id = ? AND integration_id = ? AND crowdin_id = ? AND provider = ?', [fileId, integrationId, crowdinId, provider]);
366
+ return (rows || [])[0];
367
+ }));
368
+ });
369
+ }
370
+ saveWebhooks(fileId, integrationId, crowdinId, provider) {
371
+ return __awaiter(this, void 0, void 0, function* () {
372
+ yield this.dbPromise;
373
+ yield this.executeQuery((connection) => connection.execute('INSERT INTO webhooks(file_id, integration_id, crowdin_id, provider) VALUES (?, ?, ?, ?)', [fileId, integrationId, crowdinId, provider]));
374
+ });
375
+ }
376
+ deleteWebhooks(fileIds, integrationId, crowdinId, provider) {
377
+ return __awaiter(this, void 0, void 0, function* () {
378
+ yield this.dbPromise;
379
+ const placeholders = fileIds.map(() => '?').join(',');
380
+ yield this.executeQuery((connection) => connection.execute(`DELETE FROM webhooks WHERE file_id IN (${placeholders}) AND integration_id = ? AND crowdin_id = ? AND provider = ?`, [...fileIds, integrationId, crowdinId, provider]));
381
+ });
382
+ }
339
383
  }
340
384
  exports.MySQLStorage = MySQLStorage;
@@ -1,6 +1,6 @@
1
1
  import { Client } from 'pg';
2
2
  import { Storage } from '.';
3
- import { CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings } from '../models';
3
+ import { CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks } from '../models';
4
4
  export interface PostgreStorageConfig {
5
5
  host?: string;
6
6
  connectionString?: string;
@@ -47,4 +47,8 @@ export declare class PostgreStorage implements Storage {
47
47
  saveFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: string): Promise<void>;
48
48
  updateFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: string): Promise<void>;
49
49
  getFilesSnapshot(integrationId: string, crowdinId: string, provider: string): Promise<IntegrationFilesSnapshot | undefined>;
50
+ getAllWebhooks(integrationId: string, crowdinId: string, provider: string): Promise<IntegrationWebhooks[] | undefined>;
51
+ getWebhooks(fileId: string, integrationId: string, crowdinId: string, provider: string): Promise<IntegrationWebhooks | undefined>;
52
+ saveWebhooks(fileId: string, integrationId: string, crowdinId: string, provider: string): Promise<void>;
53
+ deleteWebhooks(fileIds: any[], integrationId: string, crowdinId: string, provider: string): Promise<void>;
50
54
  }
@@ -128,6 +128,16 @@ class PostgreStorage {
128
128
  provider varchar not null
129
129
  )
130
130
  `);
131
+ yield client.query(`
132
+ create table if not exists webhooks
133
+ (
134
+ id serial primary key,
135
+ file_id varchar not null,
136
+ integration_id varchar not null,
137
+ crowdin_id varchar not null,
138
+ provider varchar not null
139
+ )
140
+ `);
131
141
  });
132
142
  }
133
143
  saveCrowdinCredentials(credentials) {
@@ -190,6 +200,7 @@ class PostgreStorage {
190
200
  yield client.query('DELETE FROM sync_settings WHERE crowdin_id = $1', [id]);
191
201
  yield client.query('DELETE FROM files_snapshot WHERE crowdin_id = $1', [id]);
192
202
  yield client.query('DELETE FROM app_metadata WHERE crowdin_id = $1', [id]);
203
+ yield client.query('DELETE FROM webhooks WHERE crowdin_id = $1', [id]);
193
204
  }));
194
205
  });
195
206
  }
@@ -240,6 +251,7 @@ class PostgreStorage {
240
251
  yield client.query('DELETE FROM integration_credentials where id = $1', [id]);
241
252
  yield client.query('DELETE FROM sync_settings where integration_id = $1', [id]);
242
253
  yield client.query('DELETE FROM files_snapshot where integration_id = $1', [id]);
254
+ yield client.query('DELETE FROM webhooks where integration_id = $1', [id]);
243
255
  }));
244
256
  });
245
257
  }
@@ -250,6 +262,7 @@ class PostgreStorage {
250
262
  yield client.query('DELETE FROM integration_credentials where crowdin_id = $1', [crowdinId]);
251
263
  yield client.query('DELETE FROM sync_settings where crowdin_id = $1', [crowdinId]);
252
264
  yield client.query('DELETE FROM files_snapshot where crowdin_id = $1', [crowdinId]);
265
+ yield client.query('DELETE FROM webhooks where crowdin_id = $1', [crowdinId]);
253
266
  }));
254
267
  });
255
268
  }
@@ -350,5 +363,37 @@ class PostgreStorage {
350
363
  }));
351
364
  });
352
365
  }
366
+ getAllWebhooks(integrationId, crowdinId, provider) {
367
+ return __awaiter(this, void 0, void 0, function* () {
368
+ yield this.dbPromise;
369
+ return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
370
+ const res = yield client.query('SELECT id, file_id as "fileId", integration_id as "integrationId", crowdin_id as "crowdinId" FROM webhooks WHERE integration_id = $1 AND crowdin_id = $2 AND provider = $3', [integrationId, crowdinId, provider]);
371
+ return (res === null || res === void 0 ? void 0 : res.rows) || [];
372
+ }));
373
+ });
374
+ }
375
+ getWebhooks(fileId, integrationId, crowdinId, provider) {
376
+ return __awaiter(this, void 0, void 0, function* () {
377
+ yield this.dbPromise;
378
+ return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
379
+ const res = yield client.query('SELECT id, file_id as "fileId", integration_id as "integrationId", crowdin_id as "crowdinId" FROM webhooks WHERE file_id = $1 AND integration_id = $2 AND crowdin_id = $3 AND provider = $4', [fileId, integrationId, crowdinId, provider]);
380
+ return res === null || res === void 0 ? void 0 : res.rows[0];
381
+ }));
382
+ });
383
+ }
384
+ saveWebhooks(fileId, integrationId, crowdinId, provider) {
385
+ return __awaiter(this, void 0, void 0, function* () {
386
+ yield this.dbPromise;
387
+ yield this.executeQuery((client) => client.query('INSERT INTO webhooks(file_id, integration_id, crowdin_id, provider) VALUES ($1, $2, $3, $4)', [fileId, integrationId, crowdinId, provider]));
388
+ });
389
+ }
390
+ deleteWebhooks(fileIds, integrationId, crowdinId, provider) {
391
+ return __awaiter(this, void 0, void 0, function* () {
392
+ let index = 0;
393
+ const placeholders = fileIds.map(() => `$${++index}`).join(',');
394
+ yield this.dbPromise;
395
+ yield this.executeQuery((client) => client.query(`DELETE FROM webhooks WHERE file_id IN ${placeholders} AND integration_id = $${++index} AND crowdin_id = $${++index} AND provider = $${++index}`, [...fileIds, integrationId, crowdinId, provider]));
396
+ });
397
+ }
353
398
  }
354
399
  exports.PostgreStorage = PostgreStorage;
@@ -1,5 +1,5 @@
1
1
  import { Storage } from '.';
2
- import { CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings } from '../models';
2
+ import { CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks } from '../models';
3
3
  export interface SQLiteStorageConfig {
4
4
  dbFolder: string;
5
5
  }
@@ -41,4 +41,8 @@ export declare class SQLiteStorage implements Storage {
41
41
  saveFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: string): Promise<void>;
42
42
  updateFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: string): Promise<void>;
43
43
  getFilesSnapshot(integrationId: string, crowdinId: string, provider: string): Promise<IntegrationFilesSnapshot | undefined>;
44
+ getAllWebhooks(integrationId: string, crowdinId: string, provider: string): Promise<IntegrationWebhooks[]>;
45
+ getWebhooks(fileId: string, integrationId: string, crowdinId: string, provider: string): Promise<IntegrationWebhooks | undefined>;
46
+ saveWebhooks(fileId: string, integrationId: string, crowdinId: string, provider: string): Promise<void>;
47
+ deleteWebhooks(fileIds: any[], integrationId: string, crowdinId: string, provider: string): Promise<void>;
44
48
  }
@@ -185,6 +185,16 @@ class SQLiteStorage {
185
185
  files varchar null,
186
186
  provider varchar not null
187
187
  );
188
+ `, []);
189
+ yield this._run(`
190
+ create table if not exists webhooks
191
+ (
192
+ id integer not null primary key autoincrement,
193
+ file_id varchar not null,
194
+ integration_id varchar not null,
195
+ crowdin_id varchar not null,
196
+ provider varchar not null
197
+ );
188
198
  `, []);
189
199
  this._res && this._res();
190
200
  // TODO: temporary code
@@ -240,6 +250,7 @@ class SQLiteStorage {
240
250
  yield this.run('DELETE FROM sync_settings WHERE crowdin_id = ?', [id]);
241
251
  yield this.run('DELETE FROM app_metadata WHERE crowdin_id = ?', [id]);
242
252
  yield this.run('DELETE FROM files_snapshot WHERE crowdin_id = ?', [id]);
253
+ yield this.run('DELETE FROM webhooks WHERE crowdin_id = ?', [id]);
243
254
  });
244
255
  }
245
256
  saveIntegrationCredentials(id, credentials, crowdinId) {
@@ -271,6 +282,7 @@ class SQLiteStorage {
271
282
  yield this.run('DELETE FROM integration_credentials where id = ?', [id]);
272
283
  yield this.run('DELETE FROM sync_settings where integration_id = ?', [id]);
273
284
  yield this.run('DELETE FROM files_snapshot where integration_id = ?', [id]);
285
+ yield this.run('DELETE FROM webhooks where integration_id = ?', [id]);
274
286
  });
275
287
  }
276
288
  deleteAllIntegrationCredentials(crowdinId) {
@@ -278,6 +290,7 @@ class SQLiteStorage {
278
290
  yield this.run('DELETE FROM integration_credentials where crowdin_id = ?', [crowdinId]);
279
291
  yield this.run('DELETE FROM sync_settings where crowdin_id = ?', [crowdinId]);
280
292
  yield this.run('DELETE FROM files_snapshot where crowdin_id = ?', [crowdinId]);
293
+ yield this.run('DELETE FROM webhooks where crowdin_id = ?', [crowdinId]);
281
294
  });
282
295
  }
283
296
  saveMetadata(id, metadata, crowdinId) {
@@ -351,5 +364,30 @@ class SQLiteStorage {
351
364
  }
352
365
  });
353
366
  }
367
+ getAllWebhooks(integrationId, crowdinId, provider) {
368
+ return this.each('SELECT id, file_id as fileId, integration_id as integrationId, crowdin_id as crowdinId, provider FROM webhooks WHERE integration_id = ? AND crowdin_id = ? AND provider = ?', [integrationId, crowdinId, provider]);
369
+ }
370
+ getWebhooks(fileId, integrationId, crowdinId, provider) {
371
+ return __awaiter(this, void 0, void 0, function* () {
372
+ const row = yield this.get('SELECT id, file_id as fileId, integration_id as integrationId, crowdin_id as crowdinId, provider FROM webhooks WHERE file_id = ? AND integration_id = ? AND crowdin_id = ? AND provider = ?', [fileId, integrationId, crowdinId, provider]);
373
+ if (row) {
374
+ return row;
375
+ }
376
+ });
377
+ }
378
+ saveWebhooks(fileId, integrationId, crowdinId, provider) {
379
+ return this.run('INSERT INTO webhooks(file_id, integration_id, crowdin_id, provider) VALUES (?, ?, ?, ?)', [
380
+ fileId,
381
+ integrationId,
382
+ crowdinId,
383
+ provider,
384
+ ]);
385
+ }
386
+ deleteWebhooks(fileIds, integrationId, crowdinId, provider) {
387
+ return __awaiter(this, void 0, void 0, function* () {
388
+ const placeholders = fileIds.map(() => '?').join(',');
389
+ return this.run(`DELETE FROM webhooks WHERE file_id IN (${placeholders}) AND integration_id = ? AND crowdin_id = ? AND provider = ?`, [...fileIds, integrationId, crowdinId, provider]);
390
+ });
391
+ }
354
392
  }
355
393
  exports.SQLiteStorage = SQLiteStorage;
@@ -91,7 +91,7 @@
91
91
  * example: 'File 102 Not Found'
92
92
  * SettingsData:
93
93
  * type: object
94
- * example: {syncType: 0, schedule: 0, condition: 0}
94
+ * example: {schedule: 0, condition: 0}
95
95
  * additionalProperties:
96
96
  * type: string
97
97
  * UpdateSettingsData:
@@ -92,7 +92,7 @@
92
92
  * example: 'File 102 Not Found'
93
93
  * SettingsData:
94
94
  * type: object
95
- * example: {syncType: 0, schedule: 0, condition: 0}
95
+ * example: {schedule: 0, condition: 0}
96
96
  * additionalProperties:
97
97
  * type: string
98
98
  * UpdateSettingsData:
@@ -1,9 +1,10 @@
1
1
  import Crowdin from '@crowdin/crowdin-api-client';
2
- import { AccountType, Config, CrowdinCredentials, IntegrationCredentials, IntegrationLogic, SubscriptionInfo } from '../models';
3
- export declare function prepareCrowdinClient({ config, credentials, autoRenew, }: {
2
+ import { AccountType, Config, CrowdinContextInfo, CrowdinCredentials, IntegrationCredentials, IntegrationLogic, SubscriptionInfo } from '../models';
3
+ export declare function prepareCrowdinClient({ config, credentials, autoRenew, context, }: {
4
4
  config: Config;
5
5
  credentials: CrowdinCredentials;
6
6
  autoRenew?: boolean;
7
+ context?: CrowdinContextInfo;
7
8
  }): Promise<{
8
9
  client: Crowdin;
9
10
  token: string;
@@ -54,7 +54,7 @@ function refreshToken(config, credentials) {
54
54
  };
55
55
  });
56
56
  }
57
- function prepareCrowdinClient({ config, credentials, autoRenew = false, }) {
57
+ function prepareCrowdinClient({ config, credentials, autoRenew = false, context, }) {
58
58
  var _a, _b;
59
59
  return __awaiter(this, void 0, void 0, function* () {
60
60
  //2 min as an extra buffer
@@ -114,6 +114,7 @@ function prepareCrowdinClient({ config, credentials, autoRenew = false, }) {
114
114
  const res = yield axiosCustom.get(url, getHttpConfig(httpConfig));
115
115
  return res.data;
116
116
  }
117
+ (0, logger_1.logError)(e, context);
117
118
  throw e;
118
119
  }
119
120
  });
@@ -130,6 +131,7 @@ function prepareCrowdinClient({ config, credentials, autoRenew = false, }) {
130
131
  const res = yield axiosCustom.delete(url, getHttpConfig(httpConfig));
131
132
  return res.data;
132
133
  }
134
+ (0, logger_1.logError)(e, context);
133
135
  throw e;
134
136
  }
135
137
  });
@@ -146,6 +148,7 @@ function prepareCrowdinClient({ config, credentials, autoRenew = false, }) {
146
148
  const res = yield axiosCustom.head(url, getHttpConfig(httpConfig));
147
149
  return res.data;
148
150
  }
151
+ (0, logger_1.logError)(e, context);
149
152
  throw e;
150
153
  }
151
154
  });
@@ -162,6 +165,7 @@ function prepareCrowdinClient({ config, credentials, autoRenew = false, }) {
162
165
  const res = yield axiosCustom.patch(url, data, getHttpConfig(httpConfig));
163
166
  return res.data;
164
167
  }
168
+ (0, logger_1.logError)(e, context);
165
169
  throw e;
166
170
  }
167
171
  });
@@ -178,6 +182,7 @@ function prepareCrowdinClient({ config, credentials, autoRenew = false, }) {
178
182
  const res = yield axiosCustom.post(url, data, getHttpConfig(httpConfig));
179
183
  return res.data;
180
184
  }
185
+ (0, logger_1.logError)(e, context);
181
186
  throw e;
182
187
  }
183
188
  });
@@ -194,6 +199,7 @@ function prepareCrowdinClient({ config, credentials, autoRenew = false, }) {
194
199
  const res = yield axiosCustom.put(url, data, getHttpConfig(httpConfig));
195
200
  return res.data;
196
201
  }
202
+ (0, logger_1.logError)(e, context);
197
203
  throw e;
198
204
  }
199
205
  });
package/out/util/cron.js CHANGED
@@ -81,7 +81,7 @@ function filesCron(config, integration, period) {
81
81
  const syncSettingsList = yield (0, storage_1.getStorage)().getAllSyncSettingsByType('schedule');
82
82
  yield Promise.all(syncSettingsList.map((syncSettings) => __awaiter(this, void 0, void 0, function* () {
83
83
  var _a;
84
- const files = JSON.parse(syncSettings.files);
84
+ let files = JSON.parse(syncSettings.files);
85
85
  let newFiles = [];
86
86
  const crowdinCredentials = yield (0, storage_1.getStorage)().getCrowdinCredentials(syncSettings.crowdinId);
87
87
  const integrationCredentials = yield (0, storage_1.getStorage)().getIntegrationCredentials(syncSettings.integrationId);
@@ -90,15 +90,28 @@ function filesCron(config, integration, period) {
90
90
  }
91
91
  const intConfig = integrationCredentials.config
92
92
  ? JSON.parse(integrationCredentials.config)
93
- : { syncType: '0', schedule: '0', condition: '0' };
94
- if (period !== intConfig.schedule || intConfig.syncType !== '1') {
93
+ : { schedule: '0', condition: '0' };
94
+ if (period !== intConfig.schedule) {
95
95
  return;
96
96
  }
97
97
  const projectId = crowdinAppFunctions.getProjectId(integrationCredentials.id);
98
+ const context = {
99
+ jwtPayload: {
100
+ context: {
101
+ // eslint-disable-next-line @typescript-eslint/camelcase
102
+ project_id: projectId,
103
+ // eslint-disable-next-line @typescript-eslint/camelcase
104
+ organization_id: crowdinCredentials.organizationId,
105
+ // eslint-disable-next-line @typescript-eslint/camelcase
106
+ user_id: crowdinCredentials.userId,
107
+ },
108
+ },
109
+ };
98
110
  const { client: crowdinClient, token } = yield (0, connection_1.prepareCrowdinClient)({
99
111
  config,
100
112
  credentials: crowdinCredentials,
101
113
  autoRenew: true,
114
+ context,
102
115
  });
103
116
  const { expired } = yield (0, connection_1.checkSubscription)({
104
117
  config,
@@ -112,7 +125,8 @@ function filesCron(config, integration, period) {
112
125
  }
113
126
  const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
114
127
  const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
115
- if (((_a = integration.syncNewElements) === null || _a === void 0 ? void 0 : _a[syncSettings.provider]) &&
128
+ if (!integration.webhooks &&
129
+ ((_a = integration.syncNewElements) === null || _a === void 0 ? void 0 : _a[syncSettings.provider]) &&
116
130
  intConfig[`new-${syncSettings.provider}-files`]) {
117
131
  newFiles = yield (0, file_snapshot_1.getAllNewFiles)({
118
132
  config,
@@ -126,6 +140,22 @@ function filesCron(config, integration, period) {
126
140
  syncSettings,
127
141
  });
128
142
  }
143
+ if (integration.webhooks) {
144
+ const webhooks = yield (0, storage_1.getStorage)().getAllWebhooks(syncSettings.integrationId, syncSettings.crowdinId, syncSettings.provider);
145
+ const webhooksFileIds = (webhooks || []).map((webhook) => webhook.fileId);
146
+ if (syncSettings.provider === models_1.Provider.CROWDIN) {
147
+ files = webhooksFileIds.reduce((acc, fileId) => {
148
+ if (files[fileId]) {
149
+ acc[fileId] = files[fileId];
150
+ }
151
+ return acc;
152
+ }, {});
153
+ }
154
+ else {
155
+ files = files.filter((file) => webhooksFileIds.includes(file.id));
156
+ }
157
+ yield (0, storage_1.getStorage)().deleteWebhooks(webhooksFileIds, syncSettings.integrationId, syncSettings.crowdinId, syncSettings.provider);
158
+ }
129
159
  if (syncSettings.provider === models_1.Provider.CROWDIN) {
130
160
  const crowdinFiles = yield skipFoldersFromIntegrationRequest(config, integration, projectId, Object.assign(Object.assign({}, files), newFiles), crowdinClient);
131
161
  const onlyTranslated = +intConfig.condition === models_1.SyncCondition.TRANSLATED;
@@ -142,8 +172,14 @@ function filesCron(config, integration, period) {
142
172
  }
143
173
  }
144
174
  const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
145
- yield integration.updateIntegration(projectId, crowdinClient, apiCredentials, filesToProcess, rootFolder, intConfig);
146
- if (newFiles) {
175
+ try {
176
+ yield integration.updateIntegration(projectId, crowdinClient, apiCredentials, filesToProcess, rootFolder, intConfig);
177
+ }
178
+ catch (e) {
179
+ (0, logger_1.logError)(e, context);
180
+ throw e;
181
+ }
182
+ if (Object.keys(newFiles).length) {
147
183
  yield (0, storage_1.getStorage)().updateSyncSettings(JSON.stringify(Object.assign(Object.assign({}, files), newFiles)), syncSettings.integrationId, syncSettings.crowdinId, 'schedule', syncSettings.provider);
148
184
  const currentFileSnapshot = yield (0, file_snapshot_1.getCrowdinSnapshot)(config, integration, crowdinClient, projectId, intConfig);
149
185
  yield (0, storage_1.getStorage)().updateFilesSnapshot(JSON.stringify(currentFileSnapshot), syncSettings.integrationId, syncSettings.crowdinId, syncSettings.provider);
@@ -159,10 +195,16 @@ function filesCron(config, integration, period) {
159
195
  const intFiles = allIntFiles.filter((file) => 'type' in file);
160
196
  (0, logger_1.log)(`Executing updateCrowdin task for files cron job with period [${period}] for project ${projectId}. Files ${intFiles.length}`);
161
197
  const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
162
- yield integration.updateCrowdin(projectId, crowdinClient, apiCredentials, intFiles, rootFolder, intConfig);
163
- const newSyncSettingsFiels = allIntFiles.map((file) => (Object.assign(Object.assign({}, file), { schedule: true, sync: false })));
198
+ try {
199
+ yield integration.updateCrowdin(projectId, crowdinClient, apiCredentials, intFiles, rootFolder, intConfig);
200
+ }
201
+ catch (e) {
202
+ (0, logger_1.logError)(e, context);
203
+ throw e;
204
+ }
164
205
  if (Object.keys(newFiles).length) {
165
- yield (0, storage_1.getStorage)().updateSyncSettings(JSON.stringify(newSyncSettingsFiels), syncSettings.integrationId, syncSettings.crowdinId, 'schedule', syncSettings.provider);
206
+ const newSyncSettingsFields = allIntFiles.map((file) => (Object.assign(Object.assign({}, file), { schedule: true, sync: false })));
207
+ yield (0, storage_1.getStorage)().updateSyncSettings(JSON.stringify(newSyncSettingsFields), syncSettings.integrationId, syncSettings.crowdinId, 'schedule', syncSettings.provider);
166
208
  const currentFileSnapshot = yield (0, file_snapshot_1.getIntegrationSnapshot)(integration, apiCredentials, intConfig);
167
209
  yield (0, storage_1.getStorage)().updateFilesSnapshot(JSON.stringify(currentFileSnapshot), syncSettings.integrationId, syncSettings.crowdinId, syncSettings.provider);
168
210
  }
@@ -154,73 +154,47 @@ function applyIntegrationModuleDefaults(config, integration) {
154
154
  label: 'Background synchronization',
155
155
  },
156
156
  ];
157
- const syncType = {
158
- key: 'syncType',
159
- label: 'Type of synchronization',
157
+ defaultSettings.push({
158
+ key: 'schedule',
159
+ label: 'Sync schedule',
160
+ helpText: integration.webhooks
161
+ ? 'Set the frequency for pushing sources and translations. The source file changes made in integration will be synced with Crowdin continuously.'
162
+ : 'Set the frequency for pushing sources and translations',
160
163
  type: 'select',
161
164
  defaultValue: '0',
162
165
  options: [
163
166
  {
164
167
  value: '0',
165
- label: 'None',
168
+ label: 'Disabled',
169
+ },
170
+ {
171
+ value: '1',
172
+ label: '1 hour',
173
+ },
174
+ {
175
+ value: '3',
176
+ label: '3 hours',
177
+ },
178
+ {
179
+ value: '6',
180
+ label: '6 hours',
181
+ },
182
+ {
183
+ value: '12',
184
+ label: '12 hours',
185
+ },
186
+ {
187
+ value: '24',
188
+ label: '24 hours',
166
189
  },
167
190
  ],
168
- };
169
- defaultSettings.push(syncType);
170
- if (integration.withCronSync) {
171
- syncType.options.push({
172
- value: '1',
173
- label: 'Schedule',
174
- });
175
- defaultSettings.push({
176
- key: 'schedule',
177
- label: 'Sync schedule',
178
- helpText: 'Set the frequency for pushing sources and translations',
179
- type: 'select',
180
- defaultValue: '0',
181
- dependencySettings: JSON.stringify([{ '#syncType-settings': { type: 'equal', value: ['1'] } }]),
182
- options: [
183
- {
184
- value: '0',
185
- label: 'Disabled',
186
- },
187
- {
188
- value: '1',
189
- label: '1 hour',
190
- },
191
- {
192
- value: '3',
193
- label: '3 hours',
194
- },
195
- {
196
- value: '6',
197
- label: '6 hours',
198
- },
199
- {
200
- value: '12',
201
- label: '12 hours',
202
- },
203
- {
204
- value: '24',
205
- label: '24 hours',
206
- },
207
- ],
208
- });
209
- }
210
- if (integration.webhooks) {
211
- syncType.options.push({
212
- value: '2',
213
- label: 'Webhooks',
214
- });
215
- }
191
+ });
216
192
  if ((_c = integration.syncNewElements) === null || _c === void 0 ? void 0 : _c.crowdin) {
217
193
  defaultSettings.push({
218
194
  key: 'new-crowdin-files',
219
195
  label: 'Sync all new items from Crowdin',
220
196
  type: 'checkbox',
221
- dependencySettings: JSON.stringify([
222
- { '#syncType-settings': { type: 'equal', value: ['1', '2'] } },
223
- ]),
197
+ dependencySettings: JSON.stringify([{ '#schedule-settings': { type: '!equal', value: ['0'] } }]),
224
198
  });
225
199
  }
226
200
  if ((_d = integration.syncNewElements) === null || _d === void 0 ? void 0 : _d.integration) {
@@ -228,9 +202,7 @@ function applyIntegrationModuleDefaults(config, integration) {
228
202
  key: 'new-integration-files',
229
203
  label: `Sync all new items from ${config.name}`,
230
204
  type: 'checkbox',
231
- dependencySettings: JSON.stringify([
232
- { '#syncType-settings': { type: 'equal', value: ['1', '2'] } },
233
- ]),
205
+ dependencySettings: JSON.stringify([{ '#schedule-settings': { type: '!equal', value: ['0'] } }]),
234
206
  });
235
207
  }
236
208
  return [
@@ -240,9 +212,7 @@ function applyIntegrationModuleDefaults(config, integration) {
240
212
  label: 'Files export settings',
241
213
  type: 'select',
242
214
  defaultValue: '0',
243
- dependencySettings: JSON.stringify([
244
- { '#syncType-settings': { type: 'equal', value: ['1', '2'] } },
245
- ]),
215
+ dependencySettings: JSON.stringify([{ '#schedule-settings': { type: '!equal', value: ['0'] } }]),
246
216
  options: [
247
217
  {
248
218
  value: '0',