@crowdin/app-project-module 0.64.0 → 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 +7 -0
- 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 +136 -18
- package/out/modules/integration/util/types.d.ts +5 -2
- package/out/modules/integration/util/types.js +1 -0
- package/out/storage/index.d.ts +2 -0
- package/out/storage/mysql.d.ts +3 -1
- package/out/storage/mysql.js +28 -3
- package/out/storage/postgre.d.ts +4 -1
- package/out/storage/postgre.js +40 -3
- package/out/storage/sqlite.d.ts +4 -1
- package/out/storage/sqlite.js +32 -3
- 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 +6 -2
- package/package.json +1 -1
package/out/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Express } from 'express';
|
|
2
2
|
import { ClientConfig, Config, CrowdinAppUtilities, CrowdinMetadataStore } from './types';
|
|
3
3
|
import express from './util/terminus-express';
|
|
4
|
+
import { getRequestCredentialsMasker, postRequestCredentialsMasker } from './util/credentials-masker';
|
|
5
|
+
export { getRequestCredentialsMasker, postRequestCredentialsMasker };
|
|
4
6
|
export { ProjectPermissions, Scope, UserPermissions } from './types';
|
|
5
7
|
export { express };
|
|
6
8
|
export declare const metadataStore: CrowdinMetadataStore;
|
package/out/index.js
CHANGED
|
@@ -35,7 +35,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
35
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
36
|
};
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.addCrowdinEndpoints = exports.createApp = exports.metadataStore = exports.express = exports.UserPermissions = exports.Scope = exports.ProjectPermissions = void 0;
|
|
38
|
+
exports.addCrowdinEndpoints = exports.createApp = exports.metadataStore = exports.express = exports.UserPermissions = exports.Scope = exports.ProjectPermissions = exports.postRequestCredentialsMasker = exports.getRequestCredentialsMasker = void 0;
|
|
39
39
|
const logsFormatter = __importStar(require("@crowdin/logs-formatter"));
|
|
40
40
|
const path_1 = require("path");
|
|
41
41
|
const crowdin_client_1 = __importStar(require("./middlewares/crowdin-client"));
|
|
@@ -57,6 +57,8 @@ const logger_1 = require("./util/logger");
|
|
|
57
57
|
const terminus_express_1 = __importDefault(require("./util/terminus-express"));
|
|
58
58
|
exports.express = terminus_express_1.default;
|
|
59
59
|
const credentials_masker_1 = require("./util/credentials-masker");
|
|
60
|
+
Object.defineProperty(exports, "getRequestCredentialsMasker", { enumerable: true, get: function () { return credentials_masker_1.getRequestCredentialsMasker; } });
|
|
61
|
+
Object.defineProperty(exports, "postRequestCredentialsMasker", { enumerable: true, get: function () { return credentials_masker_1.postRequestCredentialsMasker; } });
|
|
60
62
|
//apps
|
|
61
63
|
const apiApp = __importStar(require("./modules/api"));
|
|
62
64
|
const contextMenuApp = __importStar(require("./modules/context-menu"));
|
|
@@ -109,7 +111,7 @@ function createApp(clientConfig) {
|
|
|
109
111
|
const config = convertClientConfig(clientConfig);
|
|
110
112
|
addCrowdinEndpoints(app, config);
|
|
111
113
|
/* eslint no-console: "off" */
|
|
112
|
-
app.listen(config
|
|
114
|
+
app.listen(config, () => console.log(`App started on port ${config.port}`));
|
|
113
115
|
}
|
|
114
116
|
exports.createApp = createApp;
|
|
115
117
|
function addCrowdinEndpoints(app, clientConfig) {
|
|
@@ -15,8 +15,15 @@ function handle() {
|
|
|
15
15
|
const projectId = req.crowdinContext.jwtPayload.context.project_id;
|
|
16
16
|
req.logInfo(`Loading crowdin project ${projectId}`);
|
|
17
17
|
const project = yield req.crowdinApiClient.projectsGroupsApi.getProject(projectId);
|
|
18
|
+
let projectEditorLink;
|
|
19
|
+
if (req.crowdinContext.jwtPayload.domain) {
|
|
20
|
+
projectEditorLink = `https://${req.crowdinContext.jwtPayload.domain}.crowdin.com/editor/${project.data.id}`;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
projectEditorLink = `https://crowdin.com/editor/${project.data.identifier}`;
|
|
24
|
+
}
|
|
18
25
|
req.logInfo(`Loaded crowdin project ${projectId}`);
|
|
19
|
-
res.send(project.data);
|
|
26
|
+
res.send(Object.assign(Object.assign({}, project.data), { projectEditorLink }));
|
|
20
27
|
}));
|
|
21
28
|
}
|
|
22
29
|
exports.default = handle;
|
|
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const storage_1 = require("../../../storage");
|
|
13
13
|
const util_1 = require("../../../util");
|
|
14
|
+
const logger_1 = require("../../../util/logger");
|
|
14
15
|
function handle() {
|
|
15
16
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
17
|
var _a;
|
|
@@ -20,6 +21,12 @@ function handle() {
|
|
|
20
21
|
}
|
|
21
22
|
req.logInfo(`Loading user errors for crowdinId ${req.crowdinContext.crowdinId} and integrationId ${req.crowdinContext.clientId}`);
|
|
22
23
|
const userErrors = (_a = (yield (0, storage_1.getStorage)().getAllUserErrors(req.crowdinContext.crowdinId, req.crowdinContext.clientId))) === null || _a === void 0 ? void 0 : _a.map((userError) => {
|
|
24
|
+
if (!(0, util_1.isJson)(userError.data)) {
|
|
25
|
+
(0, logger_1.logError)(userError);
|
|
26
|
+
userError.data = JSON.stringify({
|
|
27
|
+
appData: { Warning: 'Invalid response data. Please contact the Crowdin support manager.' },
|
|
28
|
+
});
|
|
29
|
+
}
|
|
23
30
|
const date = new Date(+userError.createdAt);
|
|
24
31
|
// Format the date as 'MMM DD, YYYY HH:mm'
|
|
25
32
|
const formattedDate = new Intl.DateTimeFormat('en-US', {
|
|
@@ -22,6 +22,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
25
34
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
36
|
};
|
|
@@ -56,6 +65,7 @@ const sync_settings_1 = __importDefault(require("./handlers/sync-settings"));
|
|
|
56
65
|
const sync_settings_save_1 = __importDefault(require("./handlers/sync-settings-save"));
|
|
57
66
|
const user_errors_1 = __importDefault(require("./handlers/user-errors"));
|
|
58
67
|
const cron_1 = require("./util/cron");
|
|
68
|
+
const storage_1 = require("../../storage");
|
|
59
69
|
function register({ config, app }) {
|
|
60
70
|
var _a, _b, _c;
|
|
61
71
|
const integrationLogic = config.projectIntegration;
|
|
@@ -96,8 +106,12 @@ function register({ config, app }) {
|
|
|
96
106
|
cron.schedule('0 */3 * * *', () => (0, cron_1.filesCron)({ config, integration: integrationLogic, period: '3' }).catch(console.error));
|
|
97
107
|
cron.schedule('0 */6 * * *', () => (0, cron_1.filesCron)({ config, integration: integrationLogic, period: '6' }).catch(console.error));
|
|
98
108
|
cron.schedule('0 */12 * * *', () => (0, cron_1.filesCron)({ config, integration: integrationLogic, period: '12' }).catch(console.error));
|
|
99
|
-
cron.schedule('0 0 * * *', () => (0, cron_1.filesCron)({ config, integration: integrationLogic, period: '24' }).catch(console.error));
|
|
100
109
|
}
|
|
110
|
+
// remove user errors
|
|
111
|
+
cron.schedule('0 0 * * *', () => __awaiter(this, void 0, void 0, function* () {
|
|
112
|
+
const date = (0, util_1.getPreviousDate)(integrationLogic.userErrorLifetimeDays);
|
|
113
|
+
yield (0, storage_1.getStorage)().deleteAllUsersErrorsOlderThan(`${date.getTime()}`);
|
|
114
|
+
}));
|
|
101
115
|
if (integrationLogic.webhooks) {
|
|
102
116
|
app.post(`${integrationLogic.webhooks.crowdinWebhookUrl
|
|
103
117
|
? integrationLogic.webhooks.crowdinWebhookUrl
|
|
@@ -142,6 +142,10 @@ export interface IntegrationLogic {
|
|
|
142
142
|
asyncProgress?: {
|
|
143
143
|
checkInterval?: number;
|
|
144
144
|
};
|
|
145
|
+
/**
|
|
146
|
+
* The duration for storing user errors, default is 30 days.
|
|
147
|
+
*/
|
|
148
|
+
userErrorLifetimeDays: number;
|
|
145
149
|
}
|
|
146
150
|
export interface LoginForm {
|
|
147
151
|
fields: FormEntity[];
|
|
@@ -1,11 +1,28 @@
|
|
|
1
|
-
import Crowdin from '@crowdin/crowdin-api-client';
|
|
2
|
-
import { Config } from '../../../types';
|
|
1
|
+
import Crowdin, { SourceFilesModel } from '@crowdin/crowdin-api-client';
|
|
2
|
+
import { Config, CrowdinContextInfo } from '../../../types';
|
|
3
3
|
import { CronJob, IntegrationLogic, IntegrationRequest, Provider, UpdateIntegrationRequest } from '../types';
|
|
4
|
+
import { JobClientType, JobType } from './types';
|
|
4
5
|
export declare function runJob({ config, integration, job, }: {
|
|
5
6
|
config: Config;
|
|
6
7
|
integration: IntegrationLogic;
|
|
7
8
|
job: CronJob;
|
|
8
9
|
}): Promise<void>;
|
|
10
|
+
export declare function runUpdateProviderJob({ integrationId, crowdinId, type, title, payload, jobType, projectId, client, integration, context, credentials, rootFolder, appSettings, reRunJobId, }: {
|
|
11
|
+
integrationId: string;
|
|
12
|
+
crowdinId: string;
|
|
13
|
+
type: JobType;
|
|
14
|
+
title?: string;
|
|
15
|
+
payload?: any;
|
|
16
|
+
jobType: JobClientType;
|
|
17
|
+
projectId: number;
|
|
18
|
+
client: Crowdin;
|
|
19
|
+
integration: IntegrationLogic;
|
|
20
|
+
context: CrowdinContextInfo;
|
|
21
|
+
credentials: any;
|
|
22
|
+
rootFolder?: SourceFilesModel.Directory;
|
|
23
|
+
appSettings?: any;
|
|
24
|
+
reRunJobId?: string;
|
|
25
|
+
}): Promise<void>;
|
|
9
26
|
export declare function filesCron({ config, integration, period, }: {
|
|
10
27
|
config: Config;
|
|
11
28
|
integration: IntegrationLogic;
|
|
@@ -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.removeFinishedJobs = exports.createOrUpdateSyncSettings = exports.skipFoldersFromIntegrationRequest = exports.filesCron = exports.runJob = void 0;
|
|
35
|
+
exports.removeFinishedJobs = exports.createOrUpdateSyncSettings = exports.skipFoldersFromIntegrationRequest = exports.filesCron = exports.runUpdateProviderJob = exports.runJob = void 0;
|
|
36
36
|
const crowdinAppFunctions = __importStar(require("@crowdin/crowdin-apps-functions"));
|
|
37
37
|
const storage_1 = require("../../../storage");
|
|
38
38
|
const connection_1 = require("../../../util/connection");
|
|
@@ -80,6 +80,52 @@ function runJob({ config, integration, job, }) {
|
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
exports.runJob = runJob;
|
|
83
|
+
function runUpdateProviderJob({ integrationId, crowdinId, type, title, payload, jobType, projectId, client, integration, context, credentials, rootFolder, appSettings, reRunJobId, }) {
|
|
84
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
try {
|
|
86
|
+
yield (0, job_1.runAsJob)({
|
|
87
|
+
integrationId,
|
|
88
|
+
crowdinId,
|
|
89
|
+
type,
|
|
90
|
+
title,
|
|
91
|
+
payload,
|
|
92
|
+
jobType,
|
|
93
|
+
projectId,
|
|
94
|
+
client,
|
|
95
|
+
reRunJobId,
|
|
96
|
+
jobCallback: (job) => __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
const updateParams = {
|
|
98
|
+
projectId,
|
|
99
|
+
client,
|
|
100
|
+
credentials,
|
|
101
|
+
request: payload,
|
|
102
|
+
rootFolder,
|
|
103
|
+
appSettings,
|
|
104
|
+
job,
|
|
105
|
+
};
|
|
106
|
+
if (type === types_2.JobType.UPDATE_TO_CROWDIN) {
|
|
107
|
+
yield integration.updateCrowdin(updateParams);
|
|
108
|
+
}
|
|
109
|
+
else if (type === types_2.JobType.UPDATE_TO_INTEGRATION) {
|
|
110
|
+
yield integration.updateIntegration(updateParams);
|
|
111
|
+
}
|
|
112
|
+
}),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
const action = type === types_2.JobType.UPDATE_TO_CROWDIN ? 'Auto sync files to Crowdin' : 'Auto sync files to External Service';
|
|
117
|
+
yield (0, logger_1.handleUserError)({
|
|
118
|
+
action,
|
|
119
|
+
error: e,
|
|
120
|
+
crowdinId: crowdinId,
|
|
121
|
+
clientId: integrationId,
|
|
122
|
+
});
|
|
123
|
+
(0, logger_1.logError)(e, context);
|
|
124
|
+
throw e;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
exports.runUpdateProviderJob = runUpdateProviderJob;
|
|
83
129
|
function filesCron({ config, integration, period, }) {
|
|
84
130
|
return __awaiter(this, void 0, void 0, function* () {
|
|
85
131
|
(0, logger_1.log)(`Starting files cron job with period [${period}]`);
|
|
@@ -237,7 +283,7 @@ function processSyncSettings({ config, integration, period, syncSettings, }) {
|
|
|
237
283
|
removeInContextLanguage(filesToProcess, projectData);
|
|
238
284
|
}
|
|
239
285
|
try {
|
|
240
|
-
yield (
|
|
286
|
+
yield runUpdateProviderJob({
|
|
241
287
|
integrationId: syncSettings.integrationId,
|
|
242
288
|
crowdinId: syncSettings.crowdinId,
|
|
243
289
|
type: types_2.JobType.UPDATE_TO_INTEGRATION,
|
|
@@ -246,27 +292,14 @@ function processSyncSettings({ config, integration, period, syncSettings, }) {
|
|
|
246
292
|
jobType: types_2.JobClientType.CRON,
|
|
247
293
|
projectId: projectId,
|
|
248
294
|
client: crowdinClient,
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
request: filesToProcess,
|
|
255
|
-
rootFolder,
|
|
256
|
-
appSettings: intConfig,
|
|
257
|
-
job,
|
|
258
|
-
});
|
|
259
|
-
}),
|
|
295
|
+
integration,
|
|
296
|
+
context,
|
|
297
|
+
credentials: apiCredentials,
|
|
298
|
+
rootFolder,
|
|
299
|
+
appSettings: intConfig,
|
|
260
300
|
});
|
|
261
301
|
}
|
|
262
302
|
catch (e) {
|
|
263
|
-
yield (0, logger_1.handleUserError)({
|
|
264
|
-
action: 'Auto sync files to External Service',
|
|
265
|
-
error: e,
|
|
266
|
-
crowdinId: syncSettings.crowdinId,
|
|
267
|
-
clientId: syncSettings.integrationId,
|
|
268
|
-
});
|
|
269
|
-
(0, logger_1.logError)(e, context);
|
|
270
303
|
return;
|
|
271
304
|
}
|
|
272
305
|
if (Object.keys(newFiles).length) {
|
|
@@ -289,7 +322,7 @@ function processSyncSettings({ config, integration, period, syncSettings, }) {
|
|
|
289
322
|
(0, logger_1.log)(`Executing updateCrowdin task for files cron job with period [${period}] for project ${projectId}. Files ${intFiles.length}`);
|
|
290
323
|
const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
|
|
291
324
|
try {
|
|
292
|
-
yield (
|
|
325
|
+
yield runUpdateProviderJob({
|
|
293
326
|
integrationId: syncSettings.integrationId,
|
|
294
327
|
crowdinId: syncSettings.crowdinId,
|
|
295
328
|
type: types_2.JobType.UPDATE_TO_CROWDIN,
|
|
@@ -298,27 +331,14 @@ function processSyncSettings({ config, integration, period, syncSettings, }) {
|
|
|
298
331
|
jobType: types_2.JobClientType.CRON,
|
|
299
332
|
projectId: projectId,
|
|
300
333
|
client: crowdinClient,
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
request: intFiles,
|
|
307
|
-
rootFolder,
|
|
308
|
-
appSettings: intConfig,
|
|
309
|
-
job,
|
|
310
|
-
});
|
|
311
|
-
}),
|
|
334
|
+
integration,
|
|
335
|
+
context,
|
|
336
|
+
credentials: apiCredentials,
|
|
337
|
+
rootFolder,
|
|
338
|
+
appSettings: intConfig,
|
|
312
339
|
});
|
|
313
340
|
}
|
|
314
341
|
catch (e) {
|
|
315
|
-
yield (0, logger_1.handleUserError)({
|
|
316
|
-
action: 'Auto sync files to Crowdin',
|
|
317
|
-
error: e,
|
|
318
|
-
crowdinId: syncSettings.crowdinId,
|
|
319
|
-
clientId: syncSettings.integrationId,
|
|
320
|
-
});
|
|
321
|
-
(0, logger_1.logError)(e, context);
|
|
322
342
|
return;
|
|
323
343
|
}
|
|
324
344
|
if (Object.keys(newFiles).length) {
|
|
@@ -255,6 +255,9 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
255
255
|
if (!((_b = integration.filtering) === null || _b === void 0 ? void 0 : _b.hasOwnProperty('crowdinLanguages'))) {
|
|
256
256
|
integration.filtering = Object.assign(Object.assign({}, (integration.filtering || {})), { crowdinLanguages: true });
|
|
257
257
|
}
|
|
258
|
+
if (!integration.userErrorLifetimeDays) {
|
|
259
|
+
integration.userErrorLifetimeDays = 30;
|
|
260
|
+
}
|
|
258
261
|
}
|
|
259
262
|
exports.applyIntegrationModuleDefaults = applyIntegrationModuleDefaults;
|
|
260
263
|
function constructOauthUrl({ config, integration, clientId, loginForm, }) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { JobClient, JobClientType, JobType } from './types';
|
|
2
2
|
import { Response } from 'express';
|
|
3
3
|
import Crowdin from '@crowdin/crowdin-api-client';
|
|
4
|
-
|
|
4
|
+
import { Config } from '../../../types';
|
|
5
|
+
export declare function runAsJob({ integrationId, crowdinId, type, title, payload, res, projectId, client, jobType, jobCallback, onError, reRunJobId, }: {
|
|
5
6
|
integrationId: string;
|
|
6
7
|
crowdinId: string;
|
|
7
8
|
type: JobType;
|
|
@@ -13,4 +14,6 @@ export declare function runAsJob({ integrationId, crowdinId, type, title, payloa
|
|
|
13
14
|
jobType: JobClientType;
|
|
14
15
|
jobCallback: (arg1: JobClient) => Promise<any>;
|
|
15
16
|
onError?: (e: any) => Promise<void>;
|
|
17
|
+
reRunJobId?: string;
|
|
16
18
|
}): Promise<void>;
|
|
19
|
+
export declare function reRunInProgressJobs(config: Config): Promise<void>;
|
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
26
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
27
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -9,37 +32,48 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
32
|
});
|
|
10
33
|
};
|
|
11
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.runAsJob = void 0;
|
|
35
|
+
exports.reRunInProgressJobs = exports.runAsJob = void 0;
|
|
13
36
|
const types_1 = require("./types");
|
|
14
37
|
const storage_1 = require("../../../storage");
|
|
15
38
|
const logger_1 = require("../../../util/logger");
|
|
39
|
+
const crowdinAppFunctions = __importStar(require("@crowdin/crowdin-apps-functions"));
|
|
40
|
+
const connection_1 = require("../../../util/connection");
|
|
41
|
+
const defaults_1 = require("./defaults");
|
|
42
|
+
const cron_1 = require("./cron");
|
|
16
43
|
const blockingJobs = {
|
|
17
44
|
[types_1.JobType.UPDATE_TO_CROWDIN]: [types_1.JobType.UPDATE_TO_CROWDIN, types_1.JobType.UPDATE_TO_INTEGRATION],
|
|
18
45
|
[types_1.JobType.UPDATE_TO_INTEGRATION]: [types_1.JobType.UPDATE_TO_CROWDIN, types_1.JobType.UPDATE_TO_INTEGRATION],
|
|
19
46
|
[types_1.JobType.CROWDIN_SYNC_SETTINGS_SAVE]: [types_1.JobType.CROWDIN_SYNC_SETTINGS_SAVE],
|
|
20
47
|
[types_1.JobType.INTEGRATION_SYNC_SETTINGS_SAVE]: [types_1.JobType.INTEGRATION_SYNC_SETTINGS_SAVE],
|
|
21
48
|
};
|
|
22
|
-
|
|
49
|
+
const maxAttempts = 3;
|
|
50
|
+
function runAsJob({ integrationId, crowdinId, type, title, payload, res, projectId, client, jobType, jobCallback, onError, reRunJobId, }) {
|
|
23
51
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
let jobId;
|
|
24
53
|
const storage = (0, storage_1.getStorage)();
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
res
|
|
54
|
+
if (!reRunJobId) {
|
|
55
|
+
const activeJobs = yield storage.getActiveJobs({ integrationId, crowdinId });
|
|
56
|
+
if (activeJobs === null || activeJobs === void 0 ? void 0 : activeJobs.length) {
|
|
57
|
+
const existingJob = activeJobs.find((job) => blockingJobs[type].includes(job.type));
|
|
58
|
+
if (existingJob === null || existingJob === void 0 ? void 0 : existingJob.id) {
|
|
59
|
+
if (res) {
|
|
60
|
+
res.status(202).send({ jobId: existingJob.id, message: 'Another sync is running' });
|
|
61
|
+
}
|
|
62
|
+
(0, logger_1.log)(`Unable to run new job '${type}', with title '${title}', already running jobId ${existingJob.id}.`);
|
|
63
|
+
return;
|
|
31
64
|
}
|
|
32
|
-
(0, logger_1.log)(`Unable to run new job '${type}', with title '${title}', already running jobId ${existingJob.id}.`);
|
|
33
|
-
return;
|
|
34
65
|
}
|
|
66
|
+
jobId = yield storage.createJob({
|
|
67
|
+
integrationId,
|
|
68
|
+
crowdinId,
|
|
69
|
+
type,
|
|
70
|
+
title: title || '',
|
|
71
|
+
payload: JSON.stringify(payload),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
jobId = reRunJobId;
|
|
35
76
|
}
|
|
36
|
-
const jobId = yield storage.createJob({
|
|
37
|
-
integrationId,
|
|
38
|
-
crowdinId,
|
|
39
|
-
type,
|
|
40
|
-
title: title || '',
|
|
41
|
-
payload: JSON.stringify(payload),
|
|
42
|
-
});
|
|
43
77
|
if (res) {
|
|
44
78
|
res.status(202).send({ jobId });
|
|
45
79
|
}
|
|
@@ -49,7 +83,7 @@ function runAsJob({ integrationId, crowdinId, type, title, payload, res, project
|
|
|
49
83
|
return yield storage.getJob({ id: jobId });
|
|
50
84
|
});
|
|
51
85
|
},
|
|
52
|
-
update: function updateProgress({ progress, status, info, data }) {
|
|
86
|
+
update: function updateProgress({ progress, status, info, data, attempt }) {
|
|
53
87
|
return __awaiter(this, void 0, void 0, function* () {
|
|
54
88
|
const prevData = yield this.get();
|
|
55
89
|
if ((prevData === null || prevData === void 0 ? void 0 : prevData.status) === types_1.JobStatus.CANCELED) {
|
|
@@ -61,6 +95,7 @@ function runAsJob({ integrationId, crowdinId, type, title, payload, res, project
|
|
|
61
95
|
status: status || types_1.JobStatus.IN_PROGRESS,
|
|
62
96
|
info,
|
|
63
97
|
data: JSON.stringify(data),
|
|
98
|
+
attempt,
|
|
64
99
|
});
|
|
65
100
|
return { isCanceled: false };
|
|
66
101
|
});
|
|
@@ -136,3 +171,86 @@ function runAsJob({ integrationId, crowdinId, type, title, payload, res, project
|
|
|
136
171
|
});
|
|
137
172
|
}
|
|
138
173
|
exports.runAsJob = runAsJob;
|
|
174
|
+
function reRunInProgressJobs(config) {
|
|
175
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
176
|
+
const storage = (0, storage_1.getStorage)();
|
|
177
|
+
const inProgressJobs = yield storage.getAllInProgressJobs();
|
|
178
|
+
if (!(inProgressJobs === null || inProgressJobs === void 0 ? void 0 : inProgressJobs.length)) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
yield Promise.all(inProgressJobs.map((activeJob) => __awaiter(this, void 0, void 0, function* () {
|
|
182
|
+
if (activeJob && activeJob.status !== types_1.JobStatus.IN_PROGRESS) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (activeJob.attempt && activeJob.attempt >= maxAttempts) {
|
|
186
|
+
yield storage.updateJob({ id: activeJob.id, status: types_1.JobStatus.FAILED });
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const { integrationId, crowdinId, type, title, payload } = activeJob;
|
|
190
|
+
const integration = config.projectIntegration;
|
|
191
|
+
let crowdinClient;
|
|
192
|
+
const integrationCredentials = yield (0, storage_1.getStorage)().getIntegrationCredentials(integrationId);
|
|
193
|
+
const crowdinCredentials = yield (0, storage_1.getStorage)().getCrowdinCredentials(crowdinId);
|
|
194
|
+
const integrationConfig = yield (0, storage_1.getStorage)().getIntegrationConfig(integrationId);
|
|
195
|
+
if (!integrationCredentials || !crowdinCredentials) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const projectId = crowdinAppFunctions.getProjectId(integrationCredentials.id);
|
|
199
|
+
const context = {
|
|
200
|
+
jwtPayload: {
|
|
201
|
+
context: {
|
|
202
|
+
// eslint-disable-next-line @typescript-eslint/camelcase
|
|
203
|
+
project_id: projectId,
|
|
204
|
+
// eslint-disable-next-line @typescript-eslint/camelcase
|
|
205
|
+
organization_id: crowdinCredentials.organizationId,
|
|
206
|
+
// eslint-disable-next-line @typescript-eslint/camelcase
|
|
207
|
+
organization_domain: crowdinCredentials.domain,
|
|
208
|
+
// eslint-disable-next-line @typescript-eslint/camelcase
|
|
209
|
+
user_id: crowdinCredentials.userId,
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
try {
|
|
214
|
+
const preparedCrowdinClient = yield (0, connection_1.prepareCrowdinClient)({
|
|
215
|
+
config,
|
|
216
|
+
credentials: crowdinCredentials,
|
|
217
|
+
autoRenew: true,
|
|
218
|
+
context,
|
|
219
|
+
});
|
|
220
|
+
crowdinClient = preparedCrowdinClient.client;
|
|
221
|
+
}
|
|
222
|
+
catch (e) {
|
|
223
|
+
(0, logger_1.logError)(e);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
|
|
227
|
+
const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
|
|
228
|
+
const intConfig = (integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.config)
|
|
229
|
+
? JSON.parse(integrationConfig.config)
|
|
230
|
+
: { schedule: '0', condition: '0' };
|
|
231
|
+
yield storage.updateJob({ attempt: +(activeJob.attempt || 0) + 1, id: activeJob.id });
|
|
232
|
+
if ([types_1.JobType.UPDATE_TO_CROWDIN, types_1.JobType.UPDATE_TO_INTEGRATION].includes(type)) {
|
|
233
|
+
yield (0, cron_1.runUpdateProviderJob)({
|
|
234
|
+
integrationId,
|
|
235
|
+
crowdinId,
|
|
236
|
+
type,
|
|
237
|
+
title,
|
|
238
|
+
payload: JSON.parse(payload),
|
|
239
|
+
jobType: types_1.JobClientType.RERUN,
|
|
240
|
+
projectId,
|
|
241
|
+
client: crowdinClient,
|
|
242
|
+
integration,
|
|
243
|
+
context,
|
|
244
|
+
credentials: apiCredentials,
|
|
245
|
+
rootFolder,
|
|
246
|
+
appSettings: intConfig,
|
|
247
|
+
reRunJobId: activeJob.id,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
else if ([types_1.JobType.CROWDIN_SYNC_SETTINGS_SAVE, types_1.JobType.INTEGRATION_SYNC_SETTINGS_SAVE].includes(type)) {
|
|
251
|
+
yield storage.updateJob({ status: types_1.JobStatus.CANCELED, id: activeJob.id });
|
|
252
|
+
}
|
|
253
|
+
})));
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
exports.reRunInProgressJobs = reRunInProgressJobs;
|
|
@@ -18,7 +18,8 @@ export declare enum JobStatus {
|
|
|
18
18
|
}
|
|
19
19
|
export declare enum JobClientType {
|
|
20
20
|
CRON = "cron",
|
|
21
|
-
MANUAL = "manual"
|
|
21
|
+
MANUAL = "manual",
|
|
22
|
+
RERUN = "rerun"
|
|
22
23
|
}
|
|
23
24
|
export interface Job {
|
|
24
25
|
id: string;
|
|
@@ -35,6 +36,7 @@ export interface Job {
|
|
|
35
36
|
finishedAt?: number;
|
|
36
37
|
eta?: number;
|
|
37
38
|
info?: string;
|
|
39
|
+
attempt?: number;
|
|
38
40
|
}
|
|
39
41
|
export type GetJobParams = Pick<Job, 'id'>;
|
|
40
42
|
export type GetActiveJobsParams = Pick<Job, 'integrationId' | 'crowdinId'>;
|
|
@@ -45,6 +47,7 @@ export type UpdateJobParams = {
|
|
|
45
47
|
status?: JobStatus;
|
|
46
48
|
info?: string;
|
|
47
49
|
data?: string;
|
|
50
|
+
attempt?: number;
|
|
48
51
|
};
|
|
49
52
|
export type JobClient = {
|
|
50
53
|
get: () => Promise<Job | undefined>;
|
|
@@ -53,7 +56,7 @@ export type JobClient = {
|
|
|
53
56
|
translationUploaded: SaveUploadedFileTranslation;
|
|
54
57
|
fetchTranslation: FetchTranslation;
|
|
55
58
|
};
|
|
56
|
-
export type UpdateJobProgress = ({ progress, status, info, data, }: Omit<UpdateJobParams, 'id'>) => Promise<{
|
|
59
|
+
export type UpdateJobProgress = ({ progress, status, info, data, attempt, }: Omit<UpdateJobParams, 'id'>) => Promise<{
|
|
57
60
|
isCanceled: boolean;
|
|
58
61
|
}>;
|
|
59
62
|
export interface GetAllNewFilesArgs {
|
package/out/storage/index.d.ts
CHANGED
|
@@ -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,6 +44,7 @@ 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>;
|
|
48
50
|
getFileTranslationCacheByLanguage(params: GetFileTranslationCacheByLanguageParams): Promise<TranslationCache | undefined>;
|
package/out/storage/mysql.d.ts
CHANGED
|
@@ -51,15 +51,17 @@ 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>;
|
|
65
67
|
getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }: GetFileTranslationCacheByLanguageParams): Promise<TranslationCache | undefined>;
|
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;
|
package/out/storage/postgre.d.ts
CHANGED
|
@@ -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,15 +58,17 @@ 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>;
|
|
71
74
|
getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }: GetFileTranslationCacheByLanguageParams): Promise<TranslationCache | undefined>;
|
package/out/storage/postgre.js
CHANGED
|
@@ -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;
|
package/out/storage/sqlite.d.ts
CHANGED
|
@@ -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,15 +53,17 @@ 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>;
|
|
66
69
|
getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }: GetFileTranslationCacheByLanguageParams): Promise<TranslationCache | undefined>;
|
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
|
|
@@ -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
|
}
|
|
@@ -5,12 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const express_1 = __importDefault(require("express"));
|
|
7
7
|
const terminus_1 = require("@godaddy/terminus");
|
|
8
|
+
const job_1 = require("../modules/integration/util/job");
|
|
8
9
|
express_1.default.application.baseListen = express_1.default.application.listen;
|
|
9
10
|
express_1.default.application.listen = function (...args) {
|
|
10
|
-
const [
|
|
11
|
-
const server = this.baseListen.call(this, port);
|
|
11
|
+
const [config, callback] = args;
|
|
12
|
+
const server = this.baseListen.call(this, config.port);
|
|
12
13
|
if (callback) {
|
|
13
14
|
callback();
|
|
15
|
+
(0, job_1.reRunInProgressJobs)(config);
|
|
14
16
|
}
|
|
15
17
|
(0, terminus_1.createTerminus)(server, {
|
|
16
18
|
timeout: Infinity,
|
|
@@ -418,7 +418,11 @@
|
|
|
418
418
|
.then(checkResponse)
|
|
419
419
|
.then((res) => {
|
|
420
420
|
project = res;
|
|
421
|
-
const languagesSorted = project.targetLanguages.
|
|
421
|
+
const languagesSorted = project.targetLanguages.map(language => ({
|
|
422
|
+
sourceLanguageId: res.sourceLanguage.editorCode,
|
|
423
|
+
projectEditorLink: res.projectEditorLink,
|
|
424
|
+
...language,
|
|
425
|
+
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
422
426
|
|
|
423
427
|
if (project.inContext && config?.inContext) {
|
|
424
428
|
languagesSorted.push({...project.inContextPseudoLanguage, inContext: true});
|
|
@@ -1204,7 +1208,7 @@
|
|
|
1204
1208
|
} else {
|
|
1205
1209
|
html += `<tr><td>Message</td><td>${sanitizeHTML(error.message)}</td></tr>`;
|
|
1206
1210
|
}
|
|
1207
|
-
html += `<tr><td>Date/time</td><td>${sanitizeHTML(error.
|
|
1211
|
+
html += `<tr><td>Date/time</td><td>${sanitizeHTML(error.formattedDate)}</td></tr>`;
|
|
1208
1212
|
|
|
1209
1213
|
if (data.requestParams) {
|
|
1210
1214
|
html += `<tr><td>Method</td><td>${sanitizeHTML(data.requestParams.method)}</td></tr>`;
|
package/package.json
CHANGED