@crowdin/app-project-module 0.39.0 → 0.40.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/handlers/integration/crowdin-update.js +36 -17
- package/out/handlers/integration/integration-data.js +2 -0
- package/out/handlers/integration/integration-update.js +35 -17
- package/out/handlers/integration/integration-webhook.js +1 -1
- package/out/handlers/integration/job-cancel.d.ts +3 -0
- package/out/handlers/integration/job-cancel.js +28 -0
- package/out/handlers/integration/job-info.d.ts +3 -0
- package/out/handlers/integration/job-info.js +54 -0
- package/out/handlers/integration/main.js +6 -3
- package/out/handlers/integration/user-errors.d.ts +3 -0
- package/out/handlers/{user-errors.js → integration/user-errors.js} +5 -5
- package/out/index.d.ts +2 -1
- package/out/index.js +35 -27
- package/out/middlewares/crowdin-client.js +1 -0
- package/out/middlewares/ui-module.js +1 -0
- package/out/models/index.d.ts +48 -17
- package/out/models/index.js +1 -0
- package/out/models/job.d.ts +44 -0
- package/out/models/job.js +16 -0
- package/out/static/css/styles.css +1 -1
- package/out/static/js/form.js +17 -41
- package/out/static/js/main.js +1 -1
- package/out/storage/index.d.ts +6 -0
- package/out/storage/index.js +3 -0
- package/out/storage/mysql.d.ts +6 -0
- package/out/storage/mysql.js +106 -0
- package/out/storage/postgre.d.ts +6 -0
- package/out/storage/postgre.js +107 -0
- package/out/storage/sqlite.d.ts +6 -0
- package/out/storage/sqlite.js +96 -0
- package/out/util/cron.d.ts +1 -0
- package/out/util/cron.js +47 -3
- package/out/util/defaults.js +4 -11
- package/out/util/file-snapshot.js +2 -0
- package/out/util/files.d.ts +2 -1
- package/out/util/files.js +19 -1
- package/out/util/index.js +3 -1
- package/out/util/job.d.ts +12 -0
- package/out/util/job.js +88 -0
- package/out/util/logger.js +4 -0
- package/out/util/webhooks.js +50 -4
- package/out/views/main.handlebars +154 -6
- package/package.json +16 -15
- package/out/handlers/user-errors.d.ts +0 -3
package/out/static/js/main.js
CHANGED
package/out/storage/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Config, CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks, Provider, UserErrors } from '../models';
|
|
2
|
+
import { CreateJobParams, GetActiveJobsParams, GetJobParams, Job, UpdateJobParams } from '../models/job';
|
|
2
3
|
export interface Storage {
|
|
3
4
|
migrate(): Promise<void>;
|
|
4
5
|
saveCrowdinCredentials(credentials: CrowdinCredentials): Promise<void>;
|
|
@@ -32,6 +33,11 @@ export interface Storage {
|
|
|
32
33
|
getAllUserErrors(crowdinId: string, integrationId?: string): Promise<UserErrors[] | undefined>;
|
|
33
34
|
saveUserError(action: string, message: string, data: any, createdAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
34
35
|
deleteUserErrors(date: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
36
|
+
createJob(params: CreateJobParams): Promise<string>;
|
|
37
|
+
updateJob(params: UpdateJobParams): Promise<void>;
|
|
38
|
+
getJob(params: GetJobParams): Promise<Job | undefined>;
|
|
39
|
+
getActiveJobs(params: GetActiveJobsParams): Promise<Job[] | undefined>;
|
|
40
|
+
deleteFinishedJobs(): Promise<void>;
|
|
35
41
|
}
|
|
36
42
|
export declare function initialize(config: Config): Promise<void>;
|
|
37
43
|
export declare function getStorage(): Storage;
|
package/out/storage/index.js
CHANGED
package/out/storage/mysql.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Storage } from '.';
|
|
2
2
|
import { CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks, UserErrors } from '../models';
|
|
3
|
+
import { CreateJobParams, GetActiveJobsParams, GetJobParams, Job, UpdateJobParams } from '../models/job';
|
|
3
4
|
export interface MySQLStorageConfig {
|
|
4
5
|
uri?: string;
|
|
5
6
|
host?: string;
|
|
@@ -49,4 +50,9 @@ export declare class MySQLStorage implements Storage {
|
|
|
49
50
|
getAllUserErrors(crowdinId: string, integrationId?: string): Promise<UserErrors[] | undefined>;
|
|
50
51
|
saveUserError(action: string, message: string, data: any, createdAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
51
52
|
deleteUserErrors(createdAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
53
|
+
createJob({ integrationId, crowdinId, type, title, payload }: CreateJobParams): Promise<string>;
|
|
54
|
+
updateJob({ id, progress, status, info, data }: UpdateJobParams): Promise<void>;
|
|
55
|
+
getJob({ id }: GetJobParams): Promise<Job | undefined>;
|
|
56
|
+
getActiveJobs({ integrationId, crowdinId }: GetActiveJobsParams): Promise<Job[] | undefined>;
|
|
57
|
+
deleteFinishedJobs(): Promise<void>;
|
|
52
58
|
}
|
package/out/storage/mysql.js
CHANGED
|
@@ -13,6 +13,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.MySQLStorage = void 0;
|
|
16
|
+
const uuid_1 = require("uuid");
|
|
17
|
+
const job_1 = require("../models/job");
|
|
16
18
|
const util_1 = require("../util");
|
|
17
19
|
class MySQLStorage {
|
|
18
20
|
constructor(config) {
|
|
@@ -136,6 +138,25 @@ class MySQLStorage {
|
|
|
136
138
|
integration_id varchar(255)
|
|
137
139
|
)
|
|
138
140
|
`);
|
|
141
|
+
yield connection.execute(`
|
|
142
|
+
create table if not exists job
|
|
143
|
+
(
|
|
144
|
+
id varchar(255) not null primary key,
|
|
145
|
+
integration_id varchar(255) not null,
|
|
146
|
+
crowdin_id varchar(255) not null,
|
|
147
|
+
type varchar(255) not null,
|
|
148
|
+
payload text,
|
|
149
|
+
title text,
|
|
150
|
+
progress int 0,
|
|
151
|
+
status varchar(255) '${job_1.JobStatus.CREATED}',
|
|
152
|
+
payload text,
|
|
153
|
+
info text,
|
|
154
|
+
data text,
|
|
155
|
+
created_at varchar(255) not null,
|
|
156
|
+
updated_at varchar(255),
|
|
157
|
+
finished_at varchar(255)
|
|
158
|
+
)
|
|
159
|
+
`);
|
|
139
160
|
});
|
|
140
161
|
}
|
|
141
162
|
saveCrowdinCredentials(credentials) {
|
|
@@ -200,6 +221,7 @@ class MySQLStorage {
|
|
|
200
221
|
yield connection.execute('DELETE FROM files_snapshot WHERE crowdin_id = ?', [id]);
|
|
201
222
|
yield connection.execute('DELETE FROM webhooks WHERE crowdin_id = ?', [id]);
|
|
202
223
|
yield connection.execute('DELETE FROM user_errors WHERE crowdin_id = ?', [id]);
|
|
224
|
+
yield connection.execute('DELETE FROM job WHERE crowdin_id = ?', [id]);
|
|
203
225
|
}));
|
|
204
226
|
});
|
|
205
227
|
}
|
|
@@ -251,6 +273,7 @@ class MySQLStorage {
|
|
|
251
273
|
yield connection.execute('DELETE FROM sync_settings where integration_id = ?', [id]);
|
|
252
274
|
yield connection.execute('DELETE FROM files_snapshot where integration_id = ?', [id]);
|
|
253
275
|
yield connection.execute('DELETE FROM webhooks where integration_id = ?', [id]);
|
|
276
|
+
yield connection.execute('DELETE FROM job where integration_id = ?', [id]);
|
|
254
277
|
}));
|
|
255
278
|
});
|
|
256
279
|
}
|
|
@@ -263,6 +286,7 @@ class MySQLStorage {
|
|
|
263
286
|
yield connection.execute('DELETE FROM files_snapshot where crowdin_id = ?', [crowdinId]);
|
|
264
287
|
yield connection.execute('DELETE FROM webhooks where crowdin_id = ?', [crowdinId]);
|
|
265
288
|
yield connection.execute('DELETE FROM user_errors where crowdin_id = ?', [crowdinId]);
|
|
289
|
+
yield connection.execute('DELETE FROM job where crowdin_id = ?', [crowdinId]);
|
|
266
290
|
}));
|
|
267
291
|
});
|
|
268
292
|
}
|
|
@@ -429,5 +453,87 @@ class MySQLStorage {
|
|
|
429
453
|
});
|
|
430
454
|
});
|
|
431
455
|
}
|
|
456
|
+
createJob({ integrationId, crowdinId, type, title, payload }) {
|
|
457
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
458
|
+
const id = (0, uuid_1.v4)();
|
|
459
|
+
yield this.dbPromise;
|
|
460
|
+
yield this.executeQuery((connection) => connection.execute(`
|
|
461
|
+
INSERT INTO jobs(id, integration_id, crowdin_id, type, payload, title, created_at)
|
|
462
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
463
|
+
`, [id, integrationId, crowdinId, type, payload, title, Date.now().toString()]));
|
|
464
|
+
return id;
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
updateJob({ id, progress, status, info, data }) {
|
|
468
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
469
|
+
const updateFields = ['updated_at'];
|
|
470
|
+
const updateParams = [Date.now().toString()];
|
|
471
|
+
if (progress) {
|
|
472
|
+
updateFields.push('progress = ?');
|
|
473
|
+
updateParams.push(progress);
|
|
474
|
+
if (progress >= 100) {
|
|
475
|
+
updateFields.push('finished_at = ?');
|
|
476
|
+
updateParams.push(Date.now().toString());
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
if (status) {
|
|
480
|
+
updateFields.push('status = ?');
|
|
481
|
+
updateParams.push(status);
|
|
482
|
+
if (!updateFields.includes('finished_at = ?') && [job_1.JobStatus.FAILED, job_1.JobStatus.CANCELED].includes(status)) {
|
|
483
|
+
updateFields.push('finished_at = ?');
|
|
484
|
+
updateParams.push(Date.now().toString());
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
if (data) {
|
|
488
|
+
updateFields.push('data = ?');
|
|
489
|
+
updateParams.push(data);
|
|
490
|
+
}
|
|
491
|
+
if (info) {
|
|
492
|
+
updateFields.push('info = ?');
|
|
493
|
+
updateParams.push(info);
|
|
494
|
+
}
|
|
495
|
+
updateParams.push(id);
|
|
496
|
+
yield this.dbPromise;
|
|
497
|
+
yield this.executeQuery((connection) => connection.execute(`
|
|
498
|
+
UPDATE job
|
|
499
|
+
SET ${updateFields.join(', ')}
|
|
500
|
+
WHERE id = ?
|
|
501
|
+
`, updateParams));
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
getJob({ id }) {
|
|
505
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
506
|
+
yield this.dbPromise;
|
|
507
|
+
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
508
|
+
const [rows] = yield connection.execute(`
|
|
509
|
+
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
510
|
+
title, info, payload, data, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
511
|
+
FROM job
|
|
512
|
+
WHERE id = ?
|
|
513
|
+
`, [id]);
|
|
514
|
+
return (rows || [])[0];
|
|
515
|
+
}));
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
getActiveJobs({ integrationId, crowdinId }) {
|
|
519
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
520
|
+
yield this.dbPromise;
|
|
521
|
+
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
522
|
+
const [rows] = yield connection.execute(`
|
|
523
|
+
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
524
|
+
title, info, payload, data, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
525
|
+
FROM job
|
|
526
|
+
WHERE integration_id = ? AND crowdin_id = ? AND finished_at is NULL
|
|
527
|
+
`, [integrationId, crowdinId]);
|
|
528
|
+
return rows || [];
|
|
529
|
+
}));
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
deleteFinishedJobs() {
|
|
533
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
534
|
+
yield this.dbPromise;
|
|
535
|
+
yield this.executeQuery((connection) => connection.execute('DELETE FROM job WHERE finished_at is not NULL', []));
|
|
536
|
+
});
|
|
537
|
+
}
|
|
432
538
|
}
|
|
433
539
|
exports.MySQLStorage = MySQLStorage;
|
package/out/storage/postgre.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Client } from 'pg';
|
|
2
2
|
import { Storage } from '.';
|
|
3
3
|
import { CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks, UserErrors } from '../models';
|
|
4
|
+
import { CreateJobParams, GetActiveJobsParams, GetJobParams, Job, UpdateJobParams } from '../models/job';
|
|
4
5
|
export interface PostgreStorageConfig {
|
|
5
6
|
host?: string;
|
|
6
7
|
connectionString?: string;
|
|
@@ -54,4 +55,9 @@ export declare class PostgreStorage implements Storage {
|
|
|
54
55
|
getAllUserErrors(crowdinId: string, integrationId?: string): Promise<UserErrors[] | undefined>;
|
|
55
56
|
saveUserError(action: string, message: string, data: any, createdAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
56
57
|
deleteUserErrors(createdAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
58
|
+
createJob({ integrationId, crowdinId, type, payload, title }: CreateJobParams): Promise<string>;
|
|
59
|
+
updateJob({ id, progress, status, info, data }: UpdateJobParams): Promise<void>;
|
|
60
|
+
getJob({ id }: GetJobParams): Promise<Job | undefined>;
|
|
61
|
+
getActiveJobs({ integrationId, crowdinId }: GetActiveJobsParams): Promise<Job[] | undefined>;
|
|
62
|
+
deleteFinishedJobs(): Promise<void>;
|
|
57
63
|
}
|
package/out/storage/postgre.js
CHANGED
|
@@ -12,6 +12,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.PostgreStorage = void 0;
|
|
14
14
|
const pg_1 = require("pg");
|
|
15
|
+
const uuid_1 = require("uuid");
|
|
16
|
+
const job_1 = require("../models/job");
|
|
15
17
|
const util_1 = require("../util");
|
|
16
18
|
class PostgreStorage {
|
|
17
19
|
constructor(config) {
|
|
@@ -150,6 +152,25 @@ class PostgreStorage {
|
|
|
150
152
|
integration_id varchar
|
|
151
153
|
)
|
|
152
154
|
`);
|
|
155
|
+
yield client.query(`
|
|
156
|
+
create table if not exists job
|
|
157
|
+
(
|
|
158
|
+
id varchar not null primary key,
|
|
159
|
+
integration_id varchar not null,
|
|
160
|
+
crowdin_id varchar not null,
|
|
161
|
+
type varchar not null,
|
|
162
|
+
payload varchar null,
|
|
163
|
+
title varchar null,
|
|
164
|
+
progress int 0,
|
|
165
|
+
status varchar '${job_1.JobStatus.CREATED}',
|
|
166
|
+
payload varchar null,
|
|
167
|
+
info varchar null,
|
|
168
|
+
data varchar null,
|
|
169
|
+
created_at varchar not null,
|
|
170
|
+
updated_at varchar null,
|
|
171
|
+
finished_at varchar null
|
|
172
|
+
)
|
|
173
|
+
`);
|
|
153
174
|
});
|
|
154
175
|
}
|
|
155
176
|
saveCrowdinCredentials(credentials) {
|
|
@@ -214,6 +235,7 @@ class PostgreStorage {
|
|
|
214
235
|
yield client.query('DELETE FROM app_metadata WHERE crowdin_id = $1', [id]);
|
|
215
236
|
yield client.query('DELETE FROM webhooks WHERE crowdin_id = $1', [id]);
|
|
216
237
|
yield client.query('DELETE FROM user_errors WHERE crowdin_id = $1', [id]);
|
|
238
|
+
yield client.query('DELETE FROM job WHERE crowdin_id = $1', [id]);
|
|
217
239
|
}));
|
|
218
240
|
});
|
|
219
241
|
}
|
|
@@ -265,6 +287,7 @@ class PostgreStorage {
|
|
|
265
287
|
yield client.query('DELETE FROM sync_settings where integration_id = $1', [id]);
|
|
266
288
|
yield client.query('DELETE FROM files_snapshot where integration_id = $1', [id]);
|
|
267
289
|
yield client.query('DELETE FROM webhooks where integration_id = $1', [id]);
|
|
290
|
+
yield client.query('DELETE FROM job where integration_id = $1', [id]);
|
|
268
291
|
}));
|
|
269
292
|
});
|
|
270
293
|
}
|
|
@@ -277,6 +300,7 @@ class PostgreStorage {
|
|
|
277
300
|
yield client.query('DELETE FROM files_snapshot where crowdin_id = $1', [crowdinId]);
|
|
278
301
|
yield client.query('DELETE FROM webhooks where crowdin_id = $1', [crowdinId]);
|
|
279
302
|
yield client.query('DELETE FROM user_errors where crowdin_id = $1', [crowdinId]);
|
|
303
|
+
yield client.query('DELETE FROM job where crowdin_id = $1', [crowdinId]);
|
|
280
304
|
}));
|
|
281
305
|
});
|
|
282
306
|
}
|
|
@@ -444,5 +468,88 @@ class PostgreStorage {
|
|
|
444
468
|
});
|
|
445
469
|
});
|
|
446
470
|
}
|
|
471
|
+
createJob({ integrationId, crowdinId, type, payload, title }) {
|
|
472
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
473
|
+
const id = (0, uuid_1.v4)();
|
|
474
|
+
yield this.dbPromise;
|
|
475
|
+
yield this.executeQuery((client) => client.query(`
|
|
476
|
+
INSERT
|
|
477
|
+
INTO job(id, integration_id, crowdin_id, type, payload, title, created_at)
|
|
478
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
479
|
+
`, [id, integrationId, crowdinId, type, payload, title, Date.now().toString()]));
|
|
480
|
+
return id;
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
updateJob({ id, progress, status, info, data }) {
|
|
484
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
485
|
+
const updateFields = ['updated_at'];
|
|
486
|
+
const updateParams = [Date.now().toString()];
|
|
487
|
+
if (progress) {
|
|
488
|
+
updateFields.push('progress = $' + updateParams.length.toString());
|
|
489
|
+
updateParams.push(progress);
|
|
490
|
+
if (progress >= 100) {
|
|
491
|
+
updateFields.push('finished_at = $' + updateParams.length.toString());
|
|
492
|
+
updateParams.push(Date.now().toString());
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
if (status) {
|
|
496
|
+
updateFields.push('status = $' + updateParams.length.toString());
|
|
497
|
+
updateParams.push(status);
|
|
498
|
+
if ((!progress || progress <= 100) && [job_1.JobStatus.FAILED, job_1.JobStatus.CANCELED].includes(status)) {
|
|
499
|
+
updateFields.push('finished_at = $' + updateParams.length.toString());
|
|
500
|
+
updateParams.push(Date.now().toString());
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
if (data) {
|
|
504
|
+
updateFields.push('data = $' + updateParams.length.toString());
|
|
505
|
+
updateParams.push(data);
|
|
506
|
+
}
|
|
507
|
+
if (info) {
|
|
508
|
+
updateFields.push('info = $' + updateParams.length.toString());
|
|
509
|
+
updateParams.push(data);
|
|
510
|
+
}
|
|
511
|
+
updateParams.push(id);
|
|
512
|
+
yield this.dbPromise;
|
|
513
|
+
yield this.executeQuery((client) => client.query(`
|
|
514
|
+
UPDATE job
|
|
515
|
+
SET ${updateFields.join(', ')}
|
|
516
|
+
WHERE id = $${updateParams.length.toString()}
|
|
517
|
+
`, updateParams));
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
getJob({ id }) {
|
|
521
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
522
|
+
yield this.dbPromise;
|
|
523
|
+
return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
|
|
524
|
+
const res = yield client.query(`
|
|
525
|
+
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
526
|
+
title, info, payload, data, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
527
|
+
FROM jobs
|
|
528
|
+
WHERE id = $1
|
|
529
|
+
`, [id]);
|
|
530
|
+
return res === null || res === void 0 ? void 0 : res.rows[0];
|
|
531
|
+
}));
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
getActiveJobs({ integrationId, crowdinId }) {
|
|
535
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
536
|
+
yield this.dbPromise;
|
|
537
|
+
return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
|
|
538
|
+
const res = yield client.query(`
|
|
539
|
+
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
540
|
+
title, info, payload, data, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
541
|
+
FROM jobs
|
|
542
|
+
WHERE integration_id = $1 AND crowdin_id = $2 AND finished_at is NULL
|
|
543
|
+
`, [integrationId, crowdinId]);
|
|
544
|
+
return (res === null || res === void 0 ? void 0 : res.rows) || [];
|
|
545
|
+
}));
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
deleteFinishedJobs() {
|
|
549
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
550
|
+
yield this.dbPromise;
|
|
551
|
+
yield this.executeQuery((client) => client.query(' DELETE FROM job WHERE finished_at is not NULL', []));
|
|
552
|
+
});
|
|
553
|
+
}
|
|
447
554
|
}
|
|
448
555
|
exports.PostgreStorage = PostgreStorage;
|
package/out/storage/sqlite.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Storage } from '.';
|
|
2
2
|
import { CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks, UserErrors } from '../models';
|
|
3
|
+
import { CreateJobParams, GetActiveJobsParams, GetJobParams, Job, UpdateJobParams } from '../models/job';
|
|
3
4
|
export interface SQLiteStorageConfig {
|
|
4
5
|
dbFolder: string;
|
|
5
6
|
}
|
|
@@ -48,4 +49,9 @@ export declare class SQLiteStorage implements Storage {
|
|
|
48
49
|
getAllUserErrors(crowdinId: string, integrationId?: string): Promise<UserErrors[]>;
|
|
49
50
|
saveUserError(action: string, message: string, data: any, createdAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
50
51
|
deleteUserErrors(createAt: string, crowdinId: string, integrationId?: string): Promise<void>;
|
|
52
|
+
createJob({ integrationId, crowdinId, type, title, payload }: CreateJobParams): Promise<string>;
|
|
53
|
+
updateJob({ id, progress, status, info, data }: UpdateJobParams): Promise<void>;
|
|
54
|
+
getJob({ id }: GetJobParams): Promise<Job | undefined>;
|
|
55
|
+
getActiveJobs({ integrationId, crowdinId }: GetActiveJobsParams): Promise<Job[] | undefined>;
|
|
56
|
+
deleteFinishedJobs(): Promise<void>;
|
|
51
57
|
}
|
package/out/storage/sqlite.js
CHANGED
|
@@ -15,6 +15,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.SQLiteStorage = void 0;
|
|
17
17
|
const path_1 = require("path");
|
|
18
|
+
const uuid_1 = require("uuid");
|
|
19
|
+
const job_1 = require("../models/job");
|
|
18
20
|
class SQLiteStorage {
|
|
19
21
|
constructor(config) {
|
|
20
22
|
this.dbPromise = new Promise((res, rej) => {
|
|
@@ -207,6 +209,24 @@ class SQLiteStorage {
|
|
|
207
209
|
crowdin_id varchar not null,
|
|
208
210
|
integration_id varchar null
|
|
209
211
|
);
|
|
212
|
+
`, []);
|
|
213
|
+
yield this._run(`
|
|
214
|
+
create table if not exists job
|
|
215
|
+
(
|
|
216
|
+
id varchar not null primary key,
|
|
217
|
+
integration_id varchar not null,
|
|
218
|
+
crowdin_id varchar not null,
|
|
219
|
+
type varchar not null,
|
|
220
|
+
title varchar null,
|
|
221
|
+
progress integer DEFAULT 0,
|
|
222
|
+
status varchar DEFAULT '${job_1.JobStatus.CREATED}',
|
|
223
|
+
payload varchar null,
|
|
224
|
+
info varchar null,
|
|
225
|
+
data varchar null,
|
|
226
|
+
created_at varchar not null,
|
|
227
|
+
updated_at varchar null,
|
|
228
|
+
finished_at varchar null
|
|
229
|
+
);
|
|
210
230
|
`, []);
|
|
211
231
|
this._res && this._res();
|
|
212
232
|
// TODO: temporary code
|
|
@@ -264,6 +284,7 @@ class SQLiteStorage {
|
|
|
264
284
|
yield this.run('DELETE FROM files_snapshot WHERE crowdin_id = ?', [id]);
|
|
265
285
|
yield this.run('DELETE FROM webhooks WHERE crowdin_id = ?', [id]);
|
|
266
286
|
yield this.run('DELETE FROM user_errors WHERE crowdin_id = ?', [id]);
|
|
287
|
+
yield this.run('DELETE FROM job WHERE crowdin_id = ?', [id]);
|
|
267
288
|
});
|
|
268
289
|
}
|
|
269
290
|
saveIntegrationCredentials(id, credentials, crowdinId) {
|
|
@@ -296,6 +317,7 @@ class SQLiteStorage {
|
|
|
296
317
|
yield this.run('DELETE FROM sync_settings where integration_id = ?', [id]);
|
|
297
318
|
yield this.run('DELETE FROM files_snapshot where integration_id = ?', [id]);
|
|
298
319
|
yield this.run('DELETE FROM webhooks where integration_id = ?', [id]);
|
|
320
|
+
yield this.run('DELETE FROM job where integration_id = ?', [id]);
|
|
299
321
|
});
|
|
300
322
|
}
|
|
301
323
|
deleteAllIntegrationCredentials(crowdinId) {
|
|
@@ -305,6 +327,7 @@ class SQLiteStorage {
|
|
|
305
327
|
yield this.run('DELETE FROM files_snapshot where crowdin_id = ?', [crowdinId]);
|
|
306
328
|
yield this.run('DELETE FROM webhooks where crowdin_id = ?', [crowdinId]);
|
|
307
329
|
yield this.run('DELETE FROM user_errors where crowdin_id = ?', [crowdinId]);
|
|
330
|
+
yield this.run('DELETE FROM job where crowdin_id = ?', [crowdinId]);
|
|
308
331
|
});
|
|
309
332
|
}
|
|
310
333
|
saveMetadata(id, metadata, crowdinId) {
|
|
@@ -426,5 +449,78 @@ class SQLiteStorage {
|
|
|
426
449
|
return this.run(`DELETE FROM user_errors WHERE created_at < ? AND crowdin_id = ? AND ${whereIntegrationCondition}`, params);
|
|
427
450
|
});
|
|
428
451
|
}
|
|
452
|
+
createJob({ integrationId, crowdinId, type, title, payload }) {
|
|
453
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
454
|
+
const id = (0, uuid_1.v4)();
|
|
455
|
+
yield this.run(`
|
|
456
|
+
INSERT
|
|
457
|
+
INTO job(id, integration_id, crowdin_id, type, payload, title, created_at)
|
|
458
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
459
|
+
`, [id, integrationId, crowdinId, type, payload, title, Date.now().toString()]);
|
|
460
|
+
return id;
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
updateJob({ id, progress, status, info, data }) {
|
|
464
|
+
const updateFields = ['updated_at = ?'];
|
|
465
|
+
const updateParams = [Date.now().toString()];
|
|
466
|
+
if (progress) {
|
|
467
|
+
updateFields.push('progress = ?');
|
|
468
|
+
updateParams.push(Math.round(progress));
|
|
469
|
+
if (progress >= 100) {
|
|
470
|
+
updateFields.push('finished_at = ?');
|
|
471
|
+
updateParams.push(Date.now().toString());
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
if (status) {
|
|
475
|
+
updateFields.push('status = ?');
|
|
476
|
+
updateParams.push(status);
|
|
477
|
+
if (!updateFields.includes('finished_at = ?') && [job_1.JobStatus.FAILED, job_1.JobStatus.CANCELED].includes(status)) {
|
|
478
|
+
updateFields.push('finished_at = ?');
|
|
479
|
+
updateParams.push(Date.now().toString());
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
if (data) {
|
|
483
|
+
updateFields.push('data = ?');
|
|
484
|
+
updateParams.push(data);
|
|
485
|
+
}
|
|
486
|
+
if (info) {
|
|
487
|
+
updateFields.push('info = ?');
|
|
488
|
+
updateParams.push(info);
|
|
489
|
+
}
|
|
490
|
+
updateParams.push(id);
|
|
491
|
+
const query = `
|
|
492
|
+
UPDATE job
|
|
493
|
+
SET ${updateFields.join(', ')}
|
|
494
|
+
WHERE id = ?
|
|
495
|
+
`;
|
|
496
|
+
return this.run(query, updateParams);
|
|
497
|
+
}
|
|
498
|
+
getJob({ id }) {
|
|
499
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
500
|
+
const row = yield this.get(`
|
|
501
|
+
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
|
|
502
|
+
title, info, payload, data, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
503
|
+
FROM job
|
|
504
|
+
WHERE id = ?
|
|
505
|
+
`, [id]);
|
|
506
|
+
if (row) {
|
|
507
|
+
return row;
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
getActiveJobs({ integrationId, crowdinId }) {
|
|
512
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
513
|
+
return this.each(`
|
|
514
|
+
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status, title, info, payload, data, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
|
|
515
|
+
FROM job
|
|
516
|
+
WHERE integration_id = ? AND crowdin_id = ? AND finished_at is NULL
|
|
517
|
+
`, [integrationId, crowdinId]);
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
deleteFinishedJobs() {
|
|
521
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
522
|
+
yield this.run('DELETE FROM job WHERE finished_at is not NULL', []);
|
|
523
|
+
});
|
|
524
|
+
}
|
|
429
525
|
}
|
|
430
526
|
exports.SQLiteStorage = SQLiteStorage;
|
package/out/util/cron.d.ts
CHANGED
|
@@ -4,3 +4,4 @@ export declare function runJob(config: Config, integration: IntegrationLogic, jo
|
|
|
4
4
|
export declare function filesCron(config: Config, integration: IntegrationLogic, period: string): Promise<void>;
|
|
5
5
|
export declare function skipFoldersFromIntegrationRequest(config: Config, integration: IntegrationLogic, projectId: number, crowdinFiles: UpdateIntegrationRequest, crowdinClient: Crowdin): Promise<UpdateIntegrationRequest>;
|
|
6
6
|
export declare function createOrUpdateSyncSettings(config: Config, req: IntegrationRequest, files: any, provider: Provider, onlyCreate?: boolean): Promise<void>;
|
|
7
|
+
export declare function removeFinishedJobs(): Promise<void>;
|
package/out/util/cron.js
CHANGED
|
@@ -32,14 +32,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
32
32
|
});
|
|
33
33
|
};
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
-
exports.createOrUpdateSyncSettings = exports.skipFoldersFromIntegrationRequest = exports.filesCron = exports.runJob = void 0;
|
|
35
|
+
exports.removeFinishedJobs = exports.createOrUpdateSyncSettings = exports.skipFoldersFromIntegrationRequest = exports.filesCron = exports.runJob = void 0;
|
|
36
36
|
const crowdinAppFunctions = __importStar(require("@crowdin/crowdin-apps-functions"));
|
|
37
37
|
const models_1 = require("../models");
|
|
38
|
+
const job_1 = require("../models/job");
|
|
38
39
|
const storage_1 = require("../storage");
|
|
39
40
|
const connection_1 = require("./connection");
|
|
40
41
|
const defaults_1 = require("./defaults");
|
|
41
42
|
const file_snapshot_1 = require("./file-snapshot");
|
|
42
43
|
const logger_1 = require("./logger");
|
|
44
|
+
const job_2 = require("./job");
|
|
43
45
|
function runJob(config, integration, job) {
|
|
44
46
|
return __awaiter(this, void 0, void 0, function* () {
|
|
45
47
|
(0, logger_1.log)(`Starting cron job with expression [${job.expression}]`);
|
|
@@ -175,7 +177,24 @@ function filesCron(config, integration, period) {
|
|
|
175
177
|
}
|
|
176
178
|
const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
|
|
177
179
|
try {
|
|
178
|
-
yield
|
|
180
|
+
yield (0, job_2.runAsJob)({
|
|
181
|
+
integrationId: syncSettings.integrationId,
|
|
182
|
+
crowdinId: syncSettings.crowdinId,
|
|
183
|
+
type: job_1.JobType.UPDATE_TO_INTEGRATION,
|
|
184
|
+
title: `Sync files to ${config.name} [scheduled]`,
|
|
185
|
+
payload: filesToProcess,
|
|
186
|
+
jobCallback: (job) => __awaiter(this, void 0, void 0, function* () {
|
|
187
|
+
yield integration.updateIntegration({
|
|
188
|
+
projectId,
|
|
189
|
+
client: crowdinClient,
|
|
190
|
+
credentials: apiCredentials,
|
|
191
|
+
request: filesToProcess,
|
|
192
|
+
rootFolder,
|
|
193
|
+
appSettings: intConfig,
|
|
194
|
+
job,
|
|
195
|
+
});
|
|
196
|
+
}),
|
|
197
|
+
});
|
|
179
198
|
}
|
|
180
199
|
catch (e) {
|
|
181
200
|
(0, logger_1.logError)(e, context);
|
|
@@ -198,7 +217,24 @@ function filesCron(config, integration, period) {
|
|
|
198
217
|
(0, logger_1.log)(`Executing updateCrowdin task for files cron job with period [${period}] for project ${projectId}. Files ${intFiles.length}`);
|
|
199
218
|
const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
|
|
200
219
|
try {
|
|
201
|
-
yield
|
|
220
|
+
yield (0, job_2.runAsJob)({
|
|
221
|
+
integrationId: syncSettings.integrationId,
|
|
222
|
+
crowdinId: syncSettings.crowdinId,
|
|
223
|
+
type: job_1.JobType.UPDATE_TO_CROWDIN,
|
|
224
|
+
title: 'Sync files to Crowdin [scheduled]',
|
|
225
|
+
payload: intFiles,
|
|
226
|
+
jobCallback: (job) => __awaiter(this, void 0, void 0, function* () {
|
|
227
|
+
yield integration.updateCrowdin({
|
|
228
|
+
projectId,
|
|
229
|
+
client: crowdinClient,
|
|
230
|
+
credentials: apiCredentials,
|
|
231
|
+
request: intFiles,
|
|
232
|
+
rootFolder,
|
|
233
|
+
appSettings: intConfig,
|
|
234
|
+
job,
|
|
235
|
+
});
|
|
236
|
+
}),
|
|
237
|
+
});
|
|
202
238
|
}
|
|
203
239
|
catch (e) {
|
|
204
240
|
(0, logger_1.logError)(e, context);
|
|
@@ -311,3 +347,11 @@ function createOrUpdateSyncSettings(config, req, files, provider, onlyCreate = f
|
|
|
311
347
|
});
|
|
312
348
|
}
|
|
313
349
|
exports.createOrUpdateSyncSettings = createOrUpdateSyncSettings;
|
|
350
|
+
function removeFinishedJobs() {
|
|
351
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
352
|
+
(0, logger_1.log)('Removing all finished jobs');
|
|
353
|
+
yield (0, storage_1.getStorage)().deleteFinishedJobs();
|
|
354
|
+
(0, logger_1.log)('Removed all finished jobs');
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
exports.removeFinishedJobs = removeFinishedJobs;
|
package/out/util/defaults.js
CHANGED
|
@@ -149,17 +149,11 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
149
149
|
if (getUserSettings) {
|
|
150
150
|
fields = yield getUserSettings(projectId, crowdinClient, integrationCredentials);
|
|
151
151
|
}
|
|
152
|
-
const defaultSettings = [
|
|
153
|
-
{
|
|
154
|
-
label: 'Background synchronization',
|
|
155
|
-
},
|
|
156
|
-
];
|
|
152
|
+
const defaultSettings = [];
|
|
157
153
|
defaultSettings.push({
|
|
158
154
|
key: 'schedule',
|
|
159
|
-
label: '
|
|
160
|
-
helpText:
|
|
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',
|
|
155
|
+
label: 'Auto sync',
|
|
156
|
+
helpText: 'Adjust the update frequency for sources and translations. If enabled, make sure Auto Sync is enabled for your selected directories and files in the dual pane view.',
|
|
163
157
|
type: 'select',
|
|
164
158
|
defaultValue: '0',
|
|
165
159
|
options: [
|
|
@@ -282,11 +276,10 @@ function convertClientConfig(clientConfig) {
|
|
|
282
276
|
const clientSecret = clientConfig.clientSecret || process.env.CROWDIN_CLIENT_SECRET;
|
|
283
277
|
const port = clientConfig.port || process.env.PORT || 3000;
|
|
284
278
|
const { region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION, tmpBucketName = process.env.AWS_TMP_BUCKET_NAME, } = clientConfig.awsConfig || {};
|
|
285
|
-
const sentryDsn = clientConfig.sentryDsn || process.env.SENTRY_DSN;
|
|
286
279
|
if (!baseUrl || !clientId || !clientSecret) {
|
|
287
280
|
throw new Error('One of following parameters are not defined [baseUrl, clientId, clientSecret]');
|
|
288
281
|
}
|
|
289
|
-
return Object.assign(Object.assign({}, clientConfig), {
|
|
282
|
+
return Object.assign(Object.assign({}, clientConfig), { baseUrl: baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl, clientId,
|
|
290
283
|
clientSecret, awsConfig: {
|
|
291
284
|
tmpBucketName,
|
|
292
285
|
region,
|
|
@@ -14,6 +14,7 @@ const models_1 = require("../models");
|
|
|
14
14
|
const storage_1 = require("../storage");
|
|
15
15
|
const defaults_1 = require("./defaults");
|
|
16
16
|
const index_1 = require("./index");
|
|
17
|
+
const files_1 = require("./files");
|
|
17
18
|
function getFileDiff(currentFiles, savedFiles) {
|
|
18
19
|
return currentFiles.filter((x) => !savedFiles.some((x2) => x2.id === x.id));
|
|
19
20
|
}
|
|
@@ -117,6 +118,7 @@ function getIntegrationSnapshot(integration, integrationCredentials, integration
|
|
|
117
118
|
if (integration.integrationOneLevelFetching) {
|
|
118
119
|
files = yield getOneLevelFetchingFiles(integration, integrationCredentials, integrationSettings, files);
|
|
119
120
|
}
|
|
121
|
+
files = (0, files_1.skipFilesByRegex)(files, integration.skipIntegrationNodes);
|
|
120
122
|
// trick for compatibility in requests and set files
|
|
121
123
|
files = files.map((file) => (Object.assign(Object.assign({}, file), { parentId: file.parent_id || file.parentId,
|
|
122
124
|
// eslint-disable-next-line @typescript-eslint/camelcase
|