@crowdin/app-project-module 0.63.2 → 0.65.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.
- package/out/index.d.ts +2 -0
- package/out/index.js +4 -2
- package/out/modules/integration/handlers/crowdin-project.js +8 -1
- package/out/modules/integration/handlers/user-errors.js +8 -1
- package/out/modules/integration/index.js +15 -1
- package/out/modules/integration/types.d.ts +4 -0
- package/out/modules/integration/util/cron.d.ts +19 -2
- package/out/modules/integration/util/cron.js +59 -39
- package/out/modules/integration/util/defaults.js +3 -0
- package/out/modules/integration/util/job.d.ts +4 -1
- package/out/modules/integration/util/job.js +155 -29
- package/out/modules/integration/util/types.d.ts +12 -6
- package/out/modules/integration/util/types.js +1 -0
- package/out/storage/index.d.ts +5 -2
- package/out/storage/mysql.d.ts +6 -3
- package/out/storage/mysql.js +42 -4
- package/out/storage/postgre.d.ts +7 -3
- package/out/storage/postgre.js +55 -5
- package/out/storage/sqlite.d.ts +7 -3
- package/out/storage/sqlite.js +42 -4
- package/out/util/credentials-masker.d.ts +1 -1
- package/out/util/credentials-masker.js +34 -32
- package/out/util/index.d.ts +3 -0
- package/out/util/index.js +25 -1
- package/out/util/logger.js +0 -6
- package/out/util/terminus-express.js +4 -2
- package/out/views/main.handlebars +11 -2
- package/package.json +1 -1
package/out/storage/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IntegrationConfig, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks, Provider } from '../modules/integration/types';
|
|
2
2
|
import { Config, CrowdinCredentials, UnauthorizedConfig } from '../types';
|
|
3
|
-
import { CreateJobParams, GetActiveJobsParams, GetJobParams,
|
|
3
|
+
import { CreateJobParams, GetActiveJobsParams, GetJobParams, GetFileTranslationCacheByLanguageParams, Job, TranslationCache, UpdateJobParams, UpdateTranslationCacheParams, GetFileTranslationCache } from '../modules/integration/util/types';
|
|
4
4
|
import { UserErrors } from './types';
|
|
5
5
|
export interface Storage {
|
|
6
6
|
migrate(): Promise<void>;
|
|
@@ -34,6 +34,7 @@ export interface Storage {
|
|
|
34
34
|
getAllUserErrors(crowdinId: string, integrationId?: string): Promise<UserErrors[] | undefined>;
|
|
35
35
|
saveUserError(action: string, message: string, data: any, createdAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
36
36
|
deleteUserErrors(date: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
37
|
+
deleteAllUsersErrorsOlderThan(date: string): Promise<void>;
|
|
37
38
|
saveIntegrationConfig(integrationId: string, crowdinId: string, config: any): Promise<void>;
|
|
38
39
|
getAllIntegrationConfigs(crowdinId: string): Promise<IntegrationConfig[]>;
|
|
39
40
|
getIntegrationConfig(integrationId: string): Promise<IntegrationConfig | undefined>;
|
|
@@ -43,8 +44,10 @@ export interface Storage {
|
|
|
43
44
|
getJob(params: GetJobParams): Promise<Job | undefined>;
|
|
44
45
|
getActiveJobs(params: GetActiveJobsParams): Promise<Job[] | undefined>;
|
|
45
46
|
deleteFinishedJobs(): Promise<void>;
|
|
47
|
+
getAllInProgressJobs(): Promise<Job[] | undefined>;
|
|
46
48
|
saveTranslationCache(params: TranslationCache): Promise<void>;
|
|
47
|
-
|
|
49
|
+
getFileTranslationCache(params: GetFileTranslationCache): Promise<TranslationCache[] | undefined>;
|
|
50
|
+
getFileTranslationCacheByLanguage(params: GetFileTranslationCacheByLanguageParams): Promise<TranslationCache | undefined>;
|
|
48
51
|
updateTranslationCache(params: UpdateTranslationCacheParams): Promise<void>;
|
|
49
52
|
}
|
|
50
53
|
export declare function initialize(config: Config | UnauthorizedConfig): Promise<void>;
|
package/out/storage/mysql.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Storage } from '.';
|
|
2
2
|
import { CrowdinCredentials } from '../types';
|
|
3
|
-
import { CreateJobParams, GetActiveJobsParams, GetJobParams,
|
|
3
|
+
import { CreateJobParams, GetActiveJobsParams, GetJobParams, GetFileTranslationCacheByLanguageParams, Job, TranslationCache, UpdateJobParams, UpdateTranslationCacheParams, GetFileTranslationCache } from '../modules/integration/util/types';
|
|
4
4
|
import { IntegrationConfig, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks } from '../modules/integration/types';
|
|
5
5
|
import { UserErrors } from './types';
|
|
6
6
|
export interface MySQLStorageConfig {
|
|
@@ -51,16 +51,19 @@ export declare class MySQLStorage implements Storage {
|
|
|
51
51
|
getAllUserErrors(crowdinId: string, integrationId?: string): Promise<UserErrors[] | undefined>;
|
|
52
52
|
saveUserError(action: string, message: string, data: any, createdAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
53
53
|
deleteUserErrors(createdAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
54
|
+
deleteAllUsersErrorsOlderThan(createdAt: string): Promise<void>;
|
|
54
55
|
saveIntegrationConfig(integrationId: string, crowdinId: string, config: any): Promise<void>;
|
|
55
56
|
getAllIntegrationConfigs(crowdinId: string): Promise<IntegrationConfig[]>;
|
|
56
57
|
getIntegrationConfig(integrationId: string): Promise<IntegrationConfig | undefined>;
|
|
57
58
|
updateIntegrationConfig(integrationId: string, config: any): Promise<void>;
|
|
58
59
|
createJob({ integrationId, crowdinId, type, title, payload }: CreateJobParams): Promise<string>;
|
|
59
|
-
updateJob({ id, progress, status, info, data }: UpdateJobParams): Promise<void>;
|
|
60
|
+
updateJob({ id, progress, status, info, data, attempt }: UpdateJobParams): Promise<void>;
|
|
60
61
|
getJob({ id }: GetJobParams): Promise<Job | undefined>;
|
|
61
62
|
getActiveJobs({ integrationId, crowdinId }: GetActiveJobsParams): Promise<Job[] | undefined>;
|
|
62
63
|
deleteFinishedJobs(): Promise<void>;
|
|
64
|
+
getAllInProgressJobs(): Promise<Job[] | undefined>;
|
|
63
65
|
saveTranslationCache({ integrationId, crowdinId, fileId, languageId, etag, }: TranslationCache): Promise<void>;
|
|
64
|
-
|
|
66
|
+
getFileTranslationCache({ integrationId, crowdinId, fileId, }: GetFileTranslationCache): Promise<TranslationCache[] | undefined>;
|
|
67
|
+
getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }: GetFileTranslationCacheByLanguageParams): Promise<TranslationCache | undefined>;
|
|
65
68
|
updateTranslationCache({ integrationId, crowdinId, fileId, languageId, etag, }: UpdateTranslationCacheParams): Promise<void>;
|
|
66
69
|
}
|
package/out/storage/mysql.js
CHANGED
|
@@ -161,6 +161,7 @@ class MySQLStorage {
|
|
|
161
161
|
payload text,
|
|
162
162
|
info text,
|
|
163
163
|
data text,
|
|
164
|
+
attempt int 0,
|
|
164
165
|
created_at varchar(255) not null,
|
|
165
166
|
updated_at varchar(255),
|
|
166
167
|
finished_at varchar(255)
|
|
@@ -471,6 +472,12 @@ class MySQLStorage {
|
|
|
471
472
|
});
|
|
472
473
|
});
|
|
473
474
|
}
|
|
475
|
+
deleteAllUsersErrorsOlderThan(createdAt) {
|
|
476
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
477
|
+
yield this.dbPromise;
|
|
478
|
+
yield this.executeQuery((connection) => connection.execute('DELETE FROM user_errors WHERE created_at < ?', [createdAt]));
|
|
479
|
+
});
|
|
480
|
+
}
|
|
474
481
|
saveIntegrationConfig(integrationId, crowdinId, config) {
|
|
475
482
|
return __awaiter(this, void 0, void 0, function* () {
|
|
476
483
|
yield this.dbPromise;
|
|
@@ -518,7 +525,7 @@ class MySQLStorage {
|
|
|
518
525
|
return id;
|
|
519
526
|
});
|
|
520
527
|
}
|
|
521
|
-
updateJob({ id, progress, status, info, data }) {
|
|
528
|
+
updateJob({ id, progress, status, info, data, attempt }) {
|
|
522
529
|
return __awaiter(this, void 0, void 0, function* () {
|
|
523
530
|
const updateFields = ['updated_at'];
|
|
524
531
|
const updateParams = [Date.now().toString()];
|
|
@@ -546,6 +553,10 @@ class MySQLStorage {
|
|
|
546
553
|
updateFields.push('info = ?');
|
|
547
554
|
updateParams.push(info);
|
|
548
555
|
}
|
|
556
|
+
if (attempt) {
|
|
557
|
+
updateFields.push('attempt = ?');
|
|
558
|
+
updateParams.push(attempt);
|
|
559
|
+
}
|
|
549
560
|
updateParams.push(id);
|
|
550
561
|
yield this.dbPromise;
|
|
551
562
|
yield this.executeQuery((connection) => connection.execute(`
|
|
@@ -561,7 +572,7 @@ class MySQLStorage {
|
|
|
561
572
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
562
573
|
const [rows] = yield connection.execute(`
|
|
563
574
|
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
564
|
-
title, info,
|
|
575
|
+
title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
565
576
|
FROM job
|
|
566
577
|
WHERE id = ?
|
|
567
578
|
`, [id]);
|
|
@@ -575,7 +586,7 @@ class MySQLStorage {
|
|
|
575
586
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
576
587
|
const [rows] = yield connection.execute(`
|
|
577
588
|
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
578
|
-
title, info,
|
|
589
|
+
title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
579
590
|
FROM job
|
|
580
591
|
WHERE integration_id = ? AND crowdin_id = ? AND finished_at is NULL
|
|
581
592
|
`, [integrationId, crowdinId]);
|
|
@@ -589,6 +600,20 @@ class MySQLStorage {
|
|
|
589
600
|
yield this.executeQuery((connection) => connection.execute('DELETE FROM job WHERE finished_at is not NULL', []));
|
|
590
601
|
});
|
|
591
602
|
}
|
|
603
|
+
getAllInProgressJobs() {
|
|
604
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
605
|
+
yield this.dbPromise;
|
|
606
|
+
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
607
|
+
const [rows] = yield connection.execute(`
|
|
608
|
+
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
609
|
+
title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
610
|
+
FROM job
|
|
611
|
+
WHERE status = ? AND finished_at is NULL
|
|
612
|
+
`, [types_1.JobStatus.IN_PROGRESS]);
|
|
613
|
+
return rows || [];
|
|
614
|
+
}));
|
|
615
|
+
});
|
|
616
|
+
}
|
|
592
617
|
saveTranslationCache({ integrationId, crowdinId, fileId, languageId, etag, }) {
|
|
593
618
|
return __awaiter(this, void 0, void 0, function* () {
|
|
594
619
|
yield this.dbPromise;
|
|
@@ -598,7 +623,20 @@ class MySQLStorage {
|
|
|
598
623
|
`, [integrationId, crowdinId, fileId, languageId, etag]));
|
|
599
624
|
});
|
|
600
625
|
}
|
|
601
|
-
|
|
626
|
+
getFileTranslationCache({ integrationId, crowdinId, fileId, }) {
|
|
627
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
628
|
+
yield this.dbPromise;
|
|
629
|
+
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
630
|
+
const [rows] = yield connection.execute(`
|
|
631
|
+
SELECT integration_id as integrationId, crowdin_id as crowdinId, file_id as fileId, language_id as languageId, etag
|
|
632
|
+
FROM translation_file_cache
|
|
633
|
+
WHERE integration_id = ? AND crowdin_id = ? AND file_id = ?
|
|
634
|
+
`, [integrationId, crowdinId, fileId]);
|
|
635
|
+
return rows || [];
|
|
636
|
+
}));
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }) {
|
|
602
640
|
return __awaiter(this, void 0, void 0, function* () {
|
|
603
641
|
yield this.dbPromise;
|
|
604
642
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
package/out/storage/postgre.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Client } from 'pg';
|
|
|
2
2
|
import { Storage } from '.';
|
|
3
3
|
import { CrowdinCredentials } from '../types';
|
|
4
4
|
import { IntegrationConfig, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks } from '../modules/integration/types';
|
|
5
|
-
import { CreateJobParams, GetActiveJobsParams, GetJobParams,
|
|
5
|
+
import { CreateJobParams, GetActiveJobsParams, GetJobParams, GetFileTranslationCacheByLanguageParams, Job, TranslationCache, UpdateJobParams, UpdateTranslationCacheParams, GetFileTranslationCache } from '../modules/integration/util/types';
|
|
6
6
|
import { UserErrors } from './types';
|
|
7
7
|
export interface PostgreStorageConfig {
|
|
8
8
|
host?: string;
|
|
@@ -26,6 +26,7 @@ export declare class PostgreStorage implements Storage {
|
|
|
26
26
|
migrate(): Promise<void>;
|
|
27
27
|
alterTables(client: Client): Promise<void>;
|
|
28
28
|
addColumns(client: Client, newColumns: string[], tableName: string): Promise<void>;
|
|
29
|
+
addColumn(client: Client, columnName: string, tableName: string, columnType: string): Promise<void>;
|
|
29
30
|
addTables(client: Client): Promise<void>;
|
|
30
31
|
saveCrowdinCredentials(credentials: CrowdinCredentials): Promise<void>;
|
|
31
32
|
updateCrowdinCredentials(credentials: CrowdinCredentials): Promise<void>;
|
|
@@ -57,16 +58,19 @@ export declare class PostgreStorage implements Storage {
|
|
|
57
58
|
getAllUserErrors(crowdinId: string, integrationId?: string): Promise<UserErrors[] | undefined>;
|
|
58
59
|
saveUserError(action: string, message: string, data: any, createdAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
59
60
|
deleteUserErrors(createdAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
61
|
+
deleteAllUsersErrorsOlderThan(createdAt: string): Promise<void>;
|
|
60
62
|
saveIntegrationConfig(integrationId: string, crowdinId: string, config: any): Promise<void>;
|
|
61
63
|
getAllIntegrationConfigs(crowdinId: string): Promise<IntegrationConfig[]>;
|
|
62
64
|
getIntegrationConfig(integrationId: string): Promise<IntegrationConfig | undefined>;
|
|
63
65
|
updateIntegrationConfig(integrationId: string, config: any): Promise<void>;
|
|
64
66
|
createJob({ integrationId, crowdinId, type, payload, title }: CreateJobParams): Promise<string>;
|
|
65
|
-
updateJob({ id, progress, status, info, data }: UpdateJobParams): Promise<void>;
|
|
67
|
+
updateJob({ id, progress, status, info, data, attempt }: UpdateJobParams): Promise<void>;
|
|
66
68
|
getJob({ id }: GetJobParams): Promise<Job | undefined>;
|
|
67
69
|
getActiveJobs({ integrationId, crowdinId }: GetActiveJobsParams): Promise<Job[] | undefined>;
|
|
68
70
|
deleteFinishedJobs(): Promise<void>;
|
|
71
|
+
getAllInProgressJobs(): Promise<Job[] | undefined>;
|
|
69
72
|
saveTranslationCache({ integrationId, crowdinId, fileId, languageId, etag, }: TranslationCache): Promise<void>;
|
|
70
|
-
|
|
73
|
+
getFileTranslationCache({ integrationId, crowdinId, fileId, }: GetFileTranslationCache): Promise<TranslationCache[] | undefined>;
|
|
74
|
+
getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }: GetFileTranslationCacheByLanguageParams): Promise<TranslationCache | undefined>;
|
|
71
75
|
updateTranslationCache({ integrationId, crowdinId, fileId, languageId, etag, }: UpdateTranslationCacheParams): Promise<void>;
|
|
72
76
|
}
|
package/out/storage/postgre.js
CHANGED
|
@@ -51,7 +51,7 @@ class PostgreStorage {
|
|
|
51
51
|
yield this.executeQuery(this.addTables);
|
|
52
52
|
this._res && this._res();
|
|
53
53
|
// TODO: temporary code
|
|
54
|
-
yield this.executeQuery(this.alterTables);
|
|
54
|
+
yield this.executeQuery((client) => this.alterTables(client));
|
|
55
55
|
}
|
|
56
56
|
catch (e) {
|
|
57
57
|
console.error(e);
|
|
@@ -63,6 +63,7 @@ class PostgreStorage {
|
|
|
63
63
|
return __awaiter(this, void 0, void 0, function* () {
|
|
64
64
|
yield this.addColumns(client, ['crowdin_id'], 'app_metadata');
|
|
65
65
|
yield this.addColumns(client, ['agent_id'], 'crowdin_credentials');
|
|
66
|
+
yield this.addColumn(client, 'attempt', 'job', 'int default 0');
|
|
66
67
|
});
|
|
67
68
|
}
|
|
68
69
|
addColumns(client, newColumns, tableName) {
|
|
@@ -79,6 +80,15 @@ class PostgreStorage {
|
|
|
79
80
|
}
|
|
80
81
|
});
|
|
81
82
|
}
|
|
83
|
+
addColumn(client, columnName, tableName, columnType) {
|
|
84
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
const tableInfo = yield client.query('SELECT column_name FROM information_schema.columns WHERE table_name = $1', [tableName]);
|
|
86
|
+
const exists = tableInfo.rows.some((columnInfo) => columnInfo.column_name === columnName);
|
|
87
|
+
if (!exists) {
|
|
88
|
+
yield client.query(`ALTER TABLE ${tableName} ADD COLUMN ${columnName} ${columnType};`);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
82
92
|
addTables(client) {
|
|
83
93
|
return __awaiter(this, void 0, void 0, function* () {
|
|
84
94
|
yield client.query(`
|
|
@@ -178,6 +188,7 @@ class PostgreStorage {
|
|
|
178
188
|
payload varchar null,
|
|
179
189
|
info varchar null,
|
|
180
190
|
data varchar null,
|
|
191
|
+
attempt int default 0,
|
|
181
192
|
created_at varchar not null,
|
|
182
193
|
updated_at varchar null,
|
|
183
194
|
finished_at varchar null
|
|
@@ -489,6 +500,14 @@ class PostgreStorage {
|
|
|
489
500
|
});
|
|
490
501
|
});
|
|
491
502
|
}
|
|
503
|
+
deleteAllUsersErrorsOlderThan(createdAt) {
|
|
504
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
505
|
+
yield this.dbPromise;
|
|
506
|
+
yield this.executeQuery((client) => {
|
|
507
|
+
return client.query('DELETE FROM user_errors WHERE created_at < $1', [createdAt]);
|
|
508
|
+
});
|
|
509
|
+
});
|
|
510
|
+
}
|
|
492
511
|
saveIntegrationConfig(integrationId, crowdinId, config) {
|
|
493
512
|
return __awaiter(this, void 0, void 0, function* () {
|
|
494
513
|
yield this.dbPromise;
|
|
@@ -538,7 +557,7 @@ class PostgreStorage {
|
|
|
538
557
|
return id;
|
|
539
558
|
});
|
|
540
559
|
}
|
|
541
|
-
updateJob({ id, progress, status, info, data }) {
|
|
560
|
+
updateJob({ id, progress, status, info, data, attempt }) {
|
|
542
561
|
return __awaiter(this, void 0, void 0, function* () {
|
|
543
562
|
const updateFields = ['updated_at'];
|
|
544
563
|
const updateParams = [Date.now().toString()];
|
|
@@ -566,6 +585,10 @@ class PostgreStorage {
|
|
|
566
585
|
updateFields.push('info = $' + updateParams.length.toString());
|
|
567
586
|
updateParams.push(info);
|
|
568
587
|
}
|
|
588
|
+
if (attempt) {
|
|
589
|
+
updateFields.push('attempt = $' + updateParams.length.toString());
|
|
590
|
+
updateParams.push(attempt);
|
|
591
|
+
}
|
|
569
592
|
updateParams.push(id);
|
|
570
593
|
yield this.dbPromise;
|
|
571
594
|
yield this.executeQuery((client) => client.query(`
|
|
@@ -581,7 +604,7 @@ class PostgreStorage {
|
|
|
581
604
|
return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
|
|
582
605
|
const res = yield client.query(`
|
|
583
606
|
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
584
|
-
title, info,
|
|
607
|
+
title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
585
608
|
FROM job
|
|
586
609
|
WHERE id = $1
|
|
587
610
|
`, [id]);
|
|
@@ -595,7 +618,7 @@ class PostgreStorage {
|
|
|
595
618
|
return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
|
|
596
619
|
const res = yield client.query(`
|
|
597
620
|
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
598
|
-
title, info,
|
|
621
|
+
title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
599
622
|
FROM job
|
|
600
623
|
WHERE integration_id = $1 AND crowdin_id = $2 AND finished_at is NULL
|
|
601
624
|
`, [integrationId, crowdinId]);
|
|
@@ -609,6 +632,20 @@ class PostgreStorage {
|
|
|
609
632
|
yield this.executeQuery((client) => client.query(' DELETE FROM job WHERE finished_at is not NULL', []));
|
|
610
633
|
});
|
|
611
634
|
}
|
|
635
|
+
getAllInProgressJobs() {
|
|
636
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
637
|
+
yield this.dbPromise;
|
|
638
|
+
return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
|
|
639
|
+
const res = yield client.query(`
|
|
640
|
+
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
641
|
+
title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
642
|
+
FROM job
|
|
643
|
+
WHERE status = $1 AND finished_at is NULL
|
|
644
|
+
`, [types_1.JobStatus.IN_PROGRESS]);
|
|
645
|
+
return (res === null || res === void 0 ? void 0 : res.rows) || [];
|
|
646
|
+
}));
|
|
647
|
+
});
|
|
648
|
+
}
|
|
612
649
|
saveTranslationCache({ integrationId, crowdinId, fileId, languageId, etag, }) {
|
|
613
650
|
return __awaiter(this, void 0, void 0, function* () {
|
|
614
651
|
yield this.dbPromise;
|
|
@@ -619,7 +656,20 @@ class PostgreStorage {
|
|
|
619
656
|
`, [integrationId, crowdinId, fileId, languageId, etag]));
|
|
620
657
|
});
|
|
621
658
|
}
|
|
622
|
-
|
|
659
|
+
getFileTranslationCache({ integrationId, crowdinId, fileId, }) {
|
|
660
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
661
|
+
yield this.dbPromise;
|
|
662
|
+
return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
|
|
663
|
+
const res = yield client.query(`
|
|
664
|
+
SELECT integration_id as integrationId, crowdin_id as crowdinId, file_id as fileId, language_id as languageId, etag
|
|
665
|
+
FROM translation_file_cache
|
|
666
|
+
WHERE integration_id = $1 AND crowdin_id = $2 AND file_id = $3
|
|
667
|
+
`, [integrationId, crowdinId, fileId]);
|
|
668
|
+
return (res === null || res === void 0 ? void 0 : res.rows) || [];
|
|
669
|
+
}));
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }) {
|
|
623
673
|
return __awaiter(this, void 0, void 0, function* () {
|
|
624
674
|
yield this.dbPromise;
|
|
625
675
|
return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
|
package/out/storage/sqlite.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Storage } from '.';
|
|
2
2
|
import { CrowdinCredentials } from '../types';
|
|
3
3
|
import { IntegrationConfig, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks } from '../modules/integration/types';
|
|
4
|
-
import { CreateJobParams, GetActiveJobsParams, GetJobParams,
|
|
4
|
+
import { CreateJobParams, GetActiveJobsParams, GetJobParams, GetFileTranslationCacheByLanguageParams, Job, TranslationCache, UpdateJobParams, UpdateTranslationCacheParams, GetFileTranslationCache } from '../modules/integration/util/types';
|
|
5
5
|
import { UserErrors } from './types';
|
|
6
6
|
export interface SQLiteStorageConfig {
|
|
7
7
|
dbFolder: string;
|
|
@@ -19,6 +19,7 @@ export declare class SQLiteStorage implements Storage {
|
|
|
19
19
|
private each;
|
|
20
20
|
private removeColumns;
|
|
21
21
|
private addColumns;
|
|
22
|
+
private addColumn;
|
|
22
23
|
private updateTables;
|
|
23
24
|
private moveIntegrationSettings;
|
|
24
25
|
migrate(): Promise<void>;
|
|
@@ -52,16 +53,19 @@ export declare class SQLiteStorage implements Storage {
|
|
|
52
53
|
getAllUserErrors(crowdinId: string, integrationId?: string): Promise<UserErrors[]>;
|
|
53
54
|
saveUserError(action: string, message: string, data: any, createdAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
54
55
|
deleteUserErrors(createAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
56
|
+
deleteAllUsersErrorsOlderThan(createAt: string): Promise<void>;
|
|
55
57
|
saveIntegrationConfig(integrationId: string, crowdinId: string, config: any): Promise<void>;
|
|
56
58
|
getAllIntegrationConfigs(crowdinId: string): Promise<IntegrationConfig[]>;
|
|
57
59
|
getIntegrationConfig(integrationId: string): Promise<IntegrationConfig | undefined>;
|
|
58
60
|
updateIntegrationConfig(integrationId: string, config: any): Promise<void>;
|
|
59
61
|
createJob({ integrationId, crowdinId, type, title, payload }: CreateJobParams): Promise<string>;
|
|
60
|
-
updateJob({ id, progress, status, info, data }: UpdateJobParams): Promise<void>;
|
|
62
|
+
updateJob({ id, progress, status, info, data, attempt }: UpdateJobParams): Promise<void>;
|
|
61
63
|
getJob({ id }: GetJobParams): Promise<Job | undefined>;
|
|
62
64
|
getActiveJobs({ integrationId, crowdinId }: GetActiveJobsParams): Promise<Job[] | undefined>;
|
|
63
65
|
deleteFinishedJobs(): Promise<void>;
|
|
66
|
+
getAllInProgressJobs(): Promise<Job[] | undefined>;
|
|
64
67
|
saveTranslationCache({ integrationId, crowdinId, fileId, languageId, etag }: TranslationCache): Promise<void>;
|
|
65
|
-
|
|
68
|
+
getFileTranslationCache({ integrationId, crowdinId, fileId, }: GetFileTranslationCache): Promise<TranslationCache[] | undefined>;
|
|
69
|
+
getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }: GetFileTranslationCacheByLanguageParams): Promise<TranslationCache | undefined>;
|
|
66
70
|
updateTranslationCache({ integrationId, crowdinId, fileId, languageId, etag, }: UpdateTranslationCacheParams): Promise<void>;
|
|
67
71
|
}
|
package/out/storage/sqlite.js
CHANGED
|
@@ -118,10 +118,20 @@ class SQLiteStorage {
|
|
|
118
118
|
}
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
|
+
addColumn(tableName, column, defaultValue) {
|
|
122
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
123
|
+
const tableInfo = yield this.each(`PRAGMA table_info(${tableName});`, []);
|
|
124
|
+
const exists = tableInfo.some((columnInfo) => columnInfo.name === column);
|
|
125
|
+
if (!exists) {
|
|
126
|
+
yield this.run(`ALTER TABLE ${tableName} ADD COLUMN ${column} varchar ${defaultValue};`, []);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
121
130
|
updateTables() {
|
|
122
131
|
return __awaiter(this, void 0, void 0, function* () {
|
|
123
132
|
yield this.addColumns(['app_secret', 'domain', 'user_id', 'agent_id', 'organization_id', 'base_url'], 'crowdin_credentials');
|
|
124
133
|
yield this.addColumns(['crowdin_id'], 'app_metadata');
|
|
134
|
+
yield this.addColumn('job', 'attempt', 'DEFAULT 0');
|
|
125
135
|
});
|
|
126
136
|
}
|
|
127
137
|
moveIntegrationSettings() {
|
|
@@ -252,6 +262,7 @@ class SQLiteStorage {
|
|
|
252
262
|
payload varchar null,
|
|
253
263
|
info varchar null,
|
|
254
264
|
data varchar null,
|
|
265
|
+
attempt varchar DEFAULT 0,
|
|
255
266
|
created_at varchar not null,
|
|
256
267
|
updated_at varchar null,
|
|
257
268
|
finished_at varchar null
|
|
@@ -491,6 +502,11 @@ class SQLiteStorage {
|
|
|
491
502
|
return this.run(`DELETE FROM user_errors WHERE created_at < ? AND crowdin_id = ? AND ${whereIntegrationCondition}`, params);
|
|
492
503
|
});
|
|
493
504
|
}
|
|
505
|
+
deleteAllUsersErrorsOlderThan(createAt) {
|
|
506
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
507
|
+
yield this.run('DELETE FROM user_errors where created_at < ?', [createAt]);
|
|
508
|
+
});
|
|
509
|
+
}
|
|
494
510
|
saveIntegrationConfig(integrationId, crowdinId, config) {
|
|
495
511
|
return this.run('INSERT INTO integration_settings(integration_id, crowdin_id, config) VALUES (?, ?, ?)', [
|
|
496
512
|
integrationId,
|
|
@@ -525,7 +541,7 @@ class SQLiteStorage {
|
|
|
525
541
|
return id;
|
|
526
542
|
});
|
|
527
543
|
}
|
|
528
|
-
updateJob({ id, progress, status, info, data }) {
|
|
544
|
+
updateJob({ id, progress, status, info, data, attempt }) {
|
|
529
545
|
const updateFields = ['updated_at = ?'];
|
|
530
546
|
const updateParams = [Date.now().toString()];
|
|
531
547
|
if (progress) {
|
|
@@ -552,6 +568,10 @@ class SQLiteStorage {
|
|
|
552
568
|
updateFields.push('info = ?');
|
|
553
569
|
updateParams.push(info);
|
|
554
570
|
}
|
|
571
|
+
if (attempt) {
|
|
572
|
+
updateFields.push('attempt = ?');
|
|
573
|
+
updateParams.push(attempt);
|
|
574
|
+
}
|
|
555
575
|
updateParams.push(id);
|
|
556
576
|
const query = `
|
|
557
577
|
UPDATE job
|
|
@@ -564,7 +584,7 @@ class SQLiteStorage {
|
|
|
564
584
|
return __awaiter(this, void 0, void 0, function* () {
|
|
565
585
|
const row = yield this.get(`
|
|
566
586
|
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
567
|
-
title, info,
|
|
587
|
+
title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
568
588
|
FROM job
|
|
569
589
|
WHERE id = ?
|
|
570
590
|
`, [id]);
|
|
@@ -576,7 +596,7 @@ class SQLiteStorage {
|
|
|
576
596
|
getActiveJobs({ integrationId, crowdinId }) {
|
|
577
597
|
return __awaiter(this, void 0, void 0, function* () {
|
|
578
598
|
return this.each(`
|
|
579
|
-
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status, title, info,
|
|
599
|
+
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status, title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
580
600
|
FROM job
|
|
581
601
|
WHERE integration_id = ? AND crowdin_id = ? AND finished_at is NULL
|
|
582
602
|
`, [integrationId, crowdinId]);
|
|
@@ -587,6 +607,15 @@ class SQLiteStorage {
|
|
|
587
607
|
yield this.run('DELETE FROM job WHERE finished_at is not NULL', []);
|
|
588
608
|
});
|
|
589
609
|
}
|
|
610
|
+
getAllInProgressJobs() {
|
|
611
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
612
|
+
return this.each(`
|
|
613
|
+
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status, title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
614
|
+
FROM job
|
|
615
|
+
WHERE status = ? AND finished_at is NULL
|
|
616
|
+
`, [types_1.JobStatus.IN_PROGRESS]);
|
|
617
|
+
});
|
|
618
|
+
}
|
|
590
619
|
saveTranslationCache({ integrationId, crowdinId, fileId, languageId, etag }) {
|
|
591
620
|
return this.run(`
|
|
592
621
|
INSERT
|
|
@@ -594,7 +623,16 @@ class SQLiteStorage {
|
|
|
594
623
|
VALUES (?, ?, ?, ?, ?)
|
|
595
624
|
`, [integrationId, crowdinId, fileId, languageId, etag]);
|
|
596
625
|
}
|
|
597
|
-
|
|
626
|
+
getFileTranslationCache({ integrationId, crowdinId, fileId, }) {
|
|
627
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
628
|
+
return this.each(`
|
|
629
|
+
SELECT integration_id as integrationId, crowdin_id as crowdinId, file_id as fileId, language_id as languageId, etag
|
|
630
|
+
FROM translation_file_cache
|
|
631
|
+
WHERE integration_id = ? AND crowdin_id = ? AND file_id = ?
|
|
632
|
+
`, [integrationId, crowdinId, fileId]);
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }) {
|
|
598
636
|
return __awaiter(this, void 0, void 0, function* () {
|
|
599
637
|
const row = yield this.get(`
|
|
600
638
|
SELECT integration_id as integrationId, crowdin_id as crowdinId, file_id as fileId, language_id as languageId, etag
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="qs" />
|
|
2
2
|
import { CrowdinClientRequest, UiModule } from '../types';
|
|
3
3
|
import { Request, Response } from 'express';
|
|
4
|
-
declare function postRequestCredentialsMasker(moduleConfig?: UiModule, credentialsExtractor?: Function): (req: CrowdinClientRequest | Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
|
|
5
4
|
declare function getRequestCredentialsMasker(moduleConfig?: UiModule): (req: Request | CrowdinClientRequest, res: Response, next: Function) => any;
|
|
5
|
+
declare function postRequestCredentialsMasker(moduleConfig?: UiModule, credentialsExtractor?: Function): (req: CrowdinClientRequest | Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
|
|
6
6
|
export { getRequestCredentialsMasker, postRequestCredentialsMasker };
|
|
@@ -32,8 +32,39 @@ function getMaskableFieldsKeys(moduleConfig) {
|
|
|
32
32
|
return (0, lodash_get_1.default)(moduleConfig, `formUiSchema[${fieldKey}]['ui:widget']`) === 'password';
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
|
+
function getRequestCredentialsMasker(moduleConfig) {
|
|
36
|
+
return function (req, res, next) {
|
|
37
|
+
// we can't find "password" fields without ui schema
|
|
38
|
+
if (!moduleConfig || !moduleConfig.formSchema || !moduleConfig.formUiSchema) {
|
|
39
|
+
return next();
|
|
40
|
+
}
|
|
41
|
+
// temporary
|
|
42
|
+
if (!moduleConfig.maskPasswords) {
|
|
43
|
+
return next();
|
|
44
|
+
}
|
|
45
|
+
const maskableFieldsKeys = getMaskableFieldsKeys(moduleConfig);
|
|
46
|
+
if (!maskableFieldsKeys.length) {
|
|
47
|
+
return next();
|
|
48
|
+
}
|
|
49
|
+
const originalSend = res.send;
|
|
50
|
+
res.send = function (body) {
|
|
51
|
+
if (body.formData) {
|
|
52
|
+
maskableFieldsKeys.forEach((fieldKey) => {
|
|
53
|
+
if (!body.formData[fieldKey]) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
body.formData[fieldKey] = maskKey(body.formData[fieldKey]);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return originalSend.apply(res, [body]);
|
|
60
|
+
};
|
|
61
|
+
return next();
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
exports.getRequestCredentialsMasker = getRequestCredentialsMasker;
|
|
35
65
|
function postRequestCredentialsMasker(moduleConfig, credentialsExtractor) {
|
|
36
66
|
return (0, index_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
67
|
+
var _a;
|
|
37
68
|
if (!moduleConfig || !moduleConfig.formSchema || !moduleConfig.formUiSchema) {
|
|
38
69
|
return next();
|
|
39
70
|
}
|
|
@@ -41,7 +72,7 @@ function postRequestCredentialsMasker(moduleConfig, credentialsExtractor) {
|
|
|
41
72
|
if (!moduleConfig.maskPasswords) {
|
|
42
73
|
return next();
|
|
43
74
|
}
|
|
44
|
-
const fieldsKeysInRequest = Object.keys(req.body.data);
|
|
75
|
+
const fieldsKeysInRequest = Object.keys(((_a = req.body) === null || _a === void 0 ? void 0 : _a.data) || []);
|
|
45
76
|
let unmaskedFields = {};
|
|
46
77
|
if (credentialsExtractor) {
|
|
47
78
|
unmaskedFields = yield credentialsExtractor(req, res);
|
|
@@ -66,37 +97,8 @@ function postRequestCredentialsMasker(moduleConfig, credentialsExtractor) {
|
|
|
66
97
|
}
|
|
67
98
|
return acc;
|
|
68
99
|
}, {}));
|
|
69
|
-
|
|
100
|
+
// run getRequestCredentialsMasker to mask fields that can be in response
|
|
101
|
+
return getRequestCredentialsMasker(moduleConfig)(req, res, next);
|
|
70
102
|
}));
|
|
71
103
|
}
|
|
72
104
|
exports.postRequestCredentialsMasker = postRequestCredentialsMasker;
|
|
73
|
-
function getRequestCredentialsMasker(moduleConfig) {
|
|
74
|
-
return function (req, res, next) {
|
|
75
|
-
// we can't find "password" fields without ui schema
|
|
76
|
-
if (!moduleConfig || !moduleConfig.formSchema || !moduleConfig.formUiSchema) {
|
|
77
|
-
return next();
|
|
78
|
-
}
|
|
79
|
-
// temporary
|
|
80
|
-
if (!moduleConfig.maskPasswords) {
|
|
81
|
-
return next();
|
|
82
|
-
}
|
|
83
|
-
const maskableFieldsKeys = getMaskableFieldsKeys(moduleConfig);
|
|
84
|
-
if (!maskableFieldsKeys.length) {
|
|
85
|
-
return next();
|
|
86
|
-
}
|
|
87
|
-
const originalSend = res.send;
|
|
88
|
-
res.send = function (body) {
|
|
89
|
-
if (body.formData) {
|
|
90
|
-
maskableFieldsKeys.forEach((fieldKey) => {
|
|
91
|
-
if (!body.formData[fieldKey]) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
body.formData[fieldKey] = maskKey(body.formData[fieldKey]);
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
return originalSend.apply(res, [body]);
|
|
98
|
-
};
|
|
99
|
-
return next();
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
exports.getRequestCredentialsMasker = getRequestCredentialsMasker;
|
package/out/util/index.d.ts
CHANGED
|
@@ -10,3 +10,6 @@ export declare function decryptData(config: Config, data: string): string;
|
|
|
10
10
|
export declare function executeWithRetry<T>(func: () => Promise<T>, numOfRetries?: number): Promise<T>;
|
|
11
11
|
export declare function getLogoUrl(moduleConfig?: ImagePath, modulePath?: string): string;
|
|
12
12
|
export declare function isAuthorizedConfig(config: Config | UnauthorizedConfig): config is Config;
|
|
13
|
+
export declare function hasFormSchema(moduleConfig: any): boolean;
|
|
14
|
+
export declare function isJson(string: string): boolean;
|
|
15
|
+
export declare function getPreviousDate(days: number): Date;
|
package/out/util/index.js
CHANGED
|
@@ -32,7 +32,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
32
32
|
});
|
|
33
33
|
};
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
-
exports.isAuthorizedConfig = exports.getLogoUrl = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.CodeError = void 0;
|
|
35
|
+
exports.getPreviousDate = exports.isJson = exports.hasFormSchema = exports.isAuthorizedConfig = exports.getLogoUrl = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.CodeError = void 0;
|
|
36
36
|
const crypto = __importStar(require("crypto-js"));
|
|
37
37
|
const storage_1 = require("../storage");
|
|
38
38
|
const types_1 = require("../types");
|
|
@@ -118,3 +118,27 @@ function isAuthorizedConfig(config) {
|
|
|
118
118
|
return !!config.clientId && !!config.clientSecret && config.authenticationType !== types_1.AuthenticationType.NONE;
|
|
119
119
|
}
|
|
120
120
|
exports.isAuthorizedConfig = isAuthorizedConfig;
|
|
121
|
+
function hasFormSchema(moduleConfig) {
|
|
122
|
+
var _a;
|
|
123
|
+
if (typeof moduleConfig === 'object' && moduleConfig !== null) {
|
|
124
|
+
return moduleConfig.formSchema || ((_a = moduleConfig.settingsUiModule) === null || _a === void 0 ? void 0 : _a.formSchema);
|
|
125
|
+
}
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
exports.hasFormSchema = hasFormSchema;
|
|
129
|
+
function isJson(string) {
|
|
130
|
+
try {
|
|
131
|
+
JSON.parse(string);
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
exports.isJson = isJson;
|
|
139
|
+
function getPreviousDate(days) {
|
|
140
|
+
const date = new Date();
|
|
141
|
+
date.setDate(date.getDate() - days);
|
|
142
|
+
return date;
|
|
143
|
+
}
|
|
144
|
+
exports.getPreviousDate = getPreviousDate;
|
package/out/util/logger.js
CHANGED
|
@@ -224,11 +224,6 @@ function storeUserError({ action, error, crowdinId, clientId, }) {
|
|
|
224
224
|
yield (0, storage_1.getStorage)().saveUserError(action, (error === null || error === void 0 ? void 0 : error.message) || JSON.stringify(error, null, 2), JSON.stringify(data), `${Date.now()}`, crowdinId, clientId);
|
|
225
225
|
});
|
|
226
226
|
}
|
|
227
|
-
function clearOldUserErrors(crowdinId, clientId) {
|
|
228
|
-
const date = new Date();
|
|
229
|
-
date.setMonth(date.getMonth() - 1); // previous month
|
|
230
|
-
(0, storage_1.getStorage)().deleteUserErrors(`${date.getTime()}`, crowdinId, clientId);
|
|
231
|
-
}
|
|
232
227
|
function mergeAppModuleAggregateErrors(errors) {
|
|
233
228
|
const result = [];
|
|
234
229
|
const mergedData = {};
|
|
@@ -269,7 +264,6 @@ function handleUserError({ action, error, crowdinId, clientId, }) {
|
|
|
269
264
|
}
|
|
270
265
|
else {
|
|
271
266
|
yield storeUserError({ action, error, crowdinId, clientId });
|
|
272
|
-
clearOldUserErrors(crowdinId, clientId);
|
|
273
267
|
}
|
|
274
268
|
});
|
|
275
269
|
}
|