@crowdin/app-project-module 2.8.0 → 2.9.1
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/modules/ai-provider/handlers/chat-completions.js +9 -1
- package/out/modules/ai-provider/handlers/get-model-list.js +3 -0
- package/out/modules/ai-provider/types.d.ts +38 -1
- package/out/modules/integration/handlers/invite-users.js +30 -1
- package/out/modules/integration/handlers/users.js +3 -0
- package/out/modules/integration/util/cron.js +44 -33
- package/out/modules/integration/util/job.js +78 -67
- package/out/static/css/styles.css +1 -1
- package/out/static/ui/form.bundle.js +2331 -723
- package/out/static/ui/form.bundle.js.map +1 -1
- package/out/static/ui/main.bundle.js +150 -35
- package/out/static/ui/main.bundle.js.map +1 -1
- package/out/storage/drizzle/index.d.ts +3 -1
- package/out/storage/drizzle/index.js +104 -66
- package/out/util/connection.js +89 -56
- package/out/util/index.d.ts +1 -0
- package/out/util/index.js +6 -0
- package/package.json +1 -1
|
@@ -27,6 +27,10 @@ const getErrorCode = (e) => {
|
|
|
27
27
|
}
|
|
28
28
|
return undefined;
|
|
29
29
|
};
|
|
30
|
+
const normalizeUsage = (usage) => {
|
|
31
|
+
const values = Array.isArray(usage) ? usage : Object.values(usage !== null && usage !== void 0 ? usage : {});
|
|
32
|
+
return values.some(util_1.isDefined) ? usage : undefined;
|
|
33
|
+
};
|
|
30
34
|
function handle(aiProvider) {
|
|
31
35
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
32
36
|
let isStream = false;
|
|
@@ -85,8 +89,12 @@ function handle(aiProvider) {
|
|
|
85
89
|
res.write(`data: ${JSON.stringify(message)}\n\n`);
|
|
86
90
|
}),
|
|
87
91
|
});
|
|
92
|
+
const usage = normalizeUsage(!Array.isArray(result) ? result === null || result === void 0 ? void 0 : result.usage : undefined);
|
|
88
93
|
if (isStream) {
|
|
89
94
|
startStream();
|
|
95
|
+
if (usage) {
|
|
96
|
+
res.write(`data: ${JSON.stringify({ choices: [], usage })}\n\n`);
|
|
97
|
+
}
|
|
90
98
|
res.write('[DONE]');
|
|
91
99
|
res.end();
|
|
92
100
|
return;
|
|
@@ -110,7 +118,7 @@ function handle(aiProvider) {
|
|
|
110
118
|
},
|
|
111
119
|
}));
|
|
112
120
|
}
|
|
113
|
-
res.send({ choices, message });
|
|
121
|
+
res.send({ choices, message, usage });
|
|
114
122
|
}
|
|
115
123
|
catch (e) {
|
|
116
124
|
if (req.logError) {
|
|
@@ -15,6 +15,7 @@ const util_1 = require("../../../util");
|
|
|
15
15
|
const logger_1 = require("../../../util/logger");
|
|
16
16
|
const util_2 = require("../util");
|
|
17
17
|
exports.CONTEXT_WINDOW_LIMIT = 4096;
|
|
18
|
+
const sanitizePrice = (price) => typeof price === 'number' && Number.isFinite(price) && price >= 0 ? price : undefined;
|
|
18
19
|
function handle(aiProvider) {
|
|
19
20
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
20
21
|
try {
|
|
@@ -33,6 +34,8 @@ function handle(aiProvider) {
|
|
|
33
34
|
supportsVision: (_e = model.supportsVision) !== null && _e !== void 0 ? _e : false,
|
|
34
35
|
contextWindowLimit: (_f = model.contextWindowLimit) !== null && _f !== void 0 ? _f : exports.CONTEXT_WINDOW_LIMIT,
|
|
35
36
|
outputLimit: (_g = model.outputLimit) !== null && _g !== void 0 ? _g : exports.CONTEXT_WINDOW_LIMIT,
|
|
37
|
+
priceInput: sanitizePrice(model.priceInput),
|
|
38
|
+
priceOutput: sanitizePrice(model.priceOutput),
|
|
36
39
|
});
|
|
37
40
|
});
|
|
38
41
|
res.send({ data });
|
|
@@ -26,6 +26,8 @@ export interface AiProviderModule extends Environments, ModuleKey {
|
|
|
26
26
|
settingsUiModule?: UiModule;
|
|
27
27
|
/**
|
|
28
28
|
* processes a sequence of conversation messages and generates responses from the assistant
|
|
29
|
+
*
|
|
30
|
+
* in stream mode only `usage` is read from the returned result, `data` and `message` are ignored
|
|
29
31
|
*/
|
|
30
32
|
chatCompletions: ({ messages, model, action, responseFormat, jsonSchema, client, context, request, isStream, sendEvent, tools, toolChoice, }: {
|
|
31
33
|
messages: ChatCompletionMessage[];
|
|
@@ -40,7 +42,7 @@ export interface AiProviderModule extends Environments, ModuleKey {
|
|
|
40
42
|
sendEvent: (chunk: ChatCompletionChunkMessage) => Promise<void>;
|
|
41
43
|
tools?: ChatCompletionTool[];
|
|
42
44
|
toolChoice?: string | AiToolChoice;
|
|
43
|
-
}) => Promise<ChatCompletionResponseMessage[] |
|
|
45
|
+
}) => Promise<ChatCompletionResponseMessage[] | ChatCompletionResult | void>;
|
|
44
46
|
/**
|
|
45
47
|
* provides a list of available model
|
|
46
48
|
*/
|
|
@@ -58,6 +60,41 @@ export interface SupportedModels {
|
|
|
58
60
|
supportsVision?: boolean;
|
|
59
61
|
contextWindowLimit?: number;
|
|
60
62
|
outputLimit?: number;
|
|
63
|
+
/**
|
|
64
|
+
* price of the input tokens, USD per 1M tokens, must be >= 0.
|
|
65
|
+
* a price above 0 makes the provider priceable - its reported costs count toward the organization's AI quota limits
|
|
66
|
+
*/
|
|
67
|
+
priceInput?: number;
|
|
68
|
+
/**
|
|
69
|
+
* price of the output tokens, USD per 1M tokens, must be >= 0
|
|
70
|
+
*/
|
|
71
|
+
priceOutput?: number;
|
|
72
|
+
}
|
|
73
|
+
export interface ChatCompletionUsage {
|
|
74
|
+
/**
|
|
75
|
+
* integer, non-integer values are ignored by Crowdin
|
|
76
|
+
*/
|
|
77
|
+
prompt_tokens?: number;
|
|
78
|
+
/**
|
|
79
|
+
* integer, non-integer values are ignored by Crowdin
|
|
80
|
+
*/
|
|
81
|
+
completion_tokens?: number;
|
|
82
|
+
/**
|
|
83
|
+
* cost in USD, takes precedence over the token count multiplied by the model price
|
|
84
|
+
*/
|
|
85
|
+
cost?: number;
|
|
86
|
+
}
|
|
87
|
+
export interface ChatCompletionModelUsage extends ChatCompletionUsage {
|
|
88
|
+
/**
|
|
89
|
+
* non-empty model id, max 255 characters
|
|
90
|
+
*/
|
|
91
|
+
model: string;
|
|
92
|
+
}
|
|
93
|
+
export interface ChatCompletionResult extends ExtendedResult<ChatCompletionResponseMessage[]> {
|
|
94
|
+
/**
|
|
95
|
+
* flat report when a single model served the request, or a per-model split report
|
|
96
|
+
*/
|
|
97
|
+
usage?: ChatCompletionUsage | ChatCompletionModelUsage[];
|
|
61
98
|
}
|
|
62
99
|
export interface ChatCompletionTool {
|
|
63
100
|
type: 'function';
|
|
@@ -12,17 +12,46 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.default = handle;
|
|
13
13
|
const util_1 = require("../../../util");
|
|
14
14
|
const storage_1 = require("../../../storage");
|
|
15
|
+
const token_1 = require("../../../util/app-functions/token");
|
|
16
|
+
const users_1 = require("./users");
|
|
15
17
|
function handle() {
|
|
16
18
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
// The middleware resolves clientId to the owner connection, which is the one that
|
|
20
|
+
// stores the managers list.
|
|
17
21
|
const clientId = req.crowdinContext.clientId;
|
|
18
22
|
const users = req.body.users;
|
|
23
|
+
const allowSelfRemoval = req.body.allowSelfRemoval === true;
|
|
24
|
+
const actingUserId = req.crowdinContext.jwtPayload.context.user_id;
|
|
25
|
+
// Derived from the connection being written, never from a body-supplied project.
|
|
26
|
+
const projectId = (0, token_1.parseCrowdinId)(clientId).projectId;
|
|
19
27
|
if (!users) {
|
|
20
28
|
return res.send({
|
|
21
29
|
success: false,
|
|
22
30
|
message: 'No users provided',
|
|
23
31
|
});
|
|
24
32
|
}
|
|
25
|
-
|
|
33
|
+
// The UI already hides Share behind the same check; this blocks direct API calls
|
|
34
|
+
// from users who merely happen to be in the managers list.
|
|
35
|
+
const canManage = yield (0, users_1.isManager)({
|
|
36
|
+
client: req.crowdinApiClient,
|
|
37
|
+
projectId,
|
|
38
|
+
memberId: actingUserId,
|
|
39
|
+
}).catch(() => false);
|
|
40
|
+
if (!canManage) {
|
|
41
|
+
return res.status(403).send({
|
|
42
|
+
success: false,
|
|
43
|
+
message: 'Access denied',
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const managerIds = new Set(users.map((user) => `${user.id}`));
|
|
47
|
+
// Kept by default, so a list that omits them (failed load, missing from the member
|
|
48
|
+
// list) can't cost the sharer their own access.
|
|
49
|
+
if (!allowSelfRemoval) {
|
|
50
|
+
managerIds.add(`${actingUserId}`);
|
|
51
|
+
}
|
|
52
|
+
// The integration owner (installer) can never be removed.
|
|
53
|
+
managerIds.add(`${(0, token_1.parseCrowdinId)(clientId).userId}`);
|
|
54
|
+
yield (0, storage_1.getStorage)().updateIntegrationManagers(clientId, JSON.stringify([...managerIds]));
|
|
26
55
|
return res.send({
|
|
27
56
|
success: true,
|
|
28
57
|
});
|
|
@@ -13,6 +13,7 @@ exports.default = handle;
|
|
|
13
13
|
exports.isManager = isManager;
|
|
14
14
|
const util_1 = require("../../../util");
|
|
15
15
|
const storage_1 = require("../../../storage");
|
|
16
|
+
const token_1 = require("../../../util/app-functions/token");
|
|
16
17
|
const MANAGER_ROLES = ['owner', 'manager'];
|
|
17
18
|
function handle() {
|
|
18
19
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -24,6 +25,8 @@ function handle() {
|
|
|
24
25
|
res.json({
|
|
25
26
|
data: {
|
|
26
27
|
managers: integrationManagers,
|
|
28
|
+
// Exposed so the UI can keep the owner's chip locked.
|
|
29
|
+
ownerId: `${(0, token_1.parseCrowdinId)(req.crowdinContext.clientId).userId}`,
|
|
27
30
|
},
|
|
28
31
|
});
|
|
29
32
|
}));
|
|
@@ -27,45 +27,56 @@ const files_1 = require("./files");
|
|
|
27
27
|
const job_1 = require("./job");
|
|
28
28
|
const snapshot_1 = require("./snapshot");
|
|
29
29
|
const types_2 = require("./types");
|
|
30
|
+
// Maximum number of organizations processed concurrently during a cron run.
|
|
31
|
+
// Keeps DB connection and API usage bounded regardless of how many orgs are registered.
|
|
32
|
+
const CRON_ORG_CONCURRENCY = (0, util_1.getEnvInt)('CRON_ORG_CONCURRENCY', 5);
|
|
30
33
|
function runJob(_a) {
|
|
31
34
|
return __awaiter(this, arguments, void 0, function* ({ config, integration, job, }) {
|
|
32
35
|
(0, logger_1.log)(`Starting cron job with expression [${job.expression}]`);
|
|
33
36
|
const crowdinCredentialsList = yield (0, storage_1.getStorage)().getAllCrowdinCredentials();
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
config,
|
|
42
|
-
token,
|
|
43
|
-
organization: crowdinCredentials.id,
|
|
44
|
-
accountType: crowdinCredentials.type,
|
|
45
|
-
});
|
|
46
|
-
if (expired) {
|
|
47
|
-
(0, logger_1.log)(`Subscription expired. Skipping job [${job.expression}] for organization ${crowdinCredentials.id}`);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
const integrationCredentialsList = yield (0, storage_1.getStorage)().getAllIntegrationCredentials(crowdinCredentials.id);
|
|
51
|
-
const allIntegrationConfigs = yield (0, storage_1.getStorage)().getAllIntegrationConfigs(crowdinCredentials.id);
|
|
52
|
-
for (const integrationCredentials of integrationCredentialsList) {
|
|
53
|
-
const integrationConfig = allIntegrationConfigs.find(({ integrationId }) => integrationId === integrationCredentials.id);
|
|
54
|
-
const projectId = (0, token_1.getProjectId)(integrationCredentials.id);
|
|
55
|
-
const credentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
|
|
56
|
-
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
|
|
57
|
-
const intConfig = (integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.config) ? JSON.parse(integrationConfig.config) : undefined;
|
|
58
|
-
(0, logger_1.log)(`Executing task for cron job with expression [${job.expression}] for project ${projectId}`);
|
|
59
|
-
yield job.task({
|
|
60
|
-
projectId,
|
|
61
|
-
client: crowdinClient,
|
|
62
|
-
credentials,
|
|
63
|
-
rootFolder,
|
|
64
|
-
settings: intConfig,
|
|
37
|
+
for (let i = 0; i < crowdinCredentialsList.length; i += CRON_ORG_CONCURRENCY) {
|
|
38
|
+
const batch = crowdinCredentialsList.slice(i, i + CRON_ORG_CONCURRENCY);
|
|
39
|
+
const results = yield Promise.allSettled(batch.map((crowdinCredentials) => __awaiter(this, void 0, void 0, function* () {
|
|
40
|
+
const { token, client: crowdinClient } = yield (0, connection_1.prepareCrowdinClient)({
|
|
41
|
+
config,
|
|
42
|
+
credentials: crowdinCredentials,
|
|
43
|
+
autoRenew: true,
|
|
65
44
|
});
|
|
66
|
-
|
|
45
|
+
const { expired } = yield (0, subscription_1.checkSubscription)({
|
|
46
|
+
config,
|
|
47
|
+
token,
|
|
48
|
+
organization: crowdinCredentials.id,
|
|
49
|
+
accountType: crowdinCredentials.type,
|
|
50
|
+
});
|
|
51
|
+
if (expired) {
|
|
52
|
+
(0, logger_1.log)(`Subscription expired. Skipping job [${job.expression}] for organization ${crowdinCredentials.id}`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const integrationCredentialsList = yield (0, storage_1.getStorage)().getAllIntegrationCredentials(crowdinCredentials.id);
|
|
56
|
+
const allIntegrationConfigs = yield (0, storage_1.getStorage)().getAllIntegrationConfigs(crowdinCredentials.id);
|
|
57
|
+
for (const integrationCredentials of integrationCredentialsList) {
|
|
58
|
+
const integrationConfig = allIntegrationConfigs.find(({ integrationId }) => integrationId === integrationCredentials.id);
|
|
59
|
+
const projectId = (0, token_1.getProjectId)(integrationCredentials.id);
|
|
60
|
+
const credentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
|
|
61
|
+
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
|
|
62
|
+
const intConfig = (integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.config) ? JSON.parse(integrationConfig.config) : undefined;
|
|
63
|
+
(0, logger_1.log)(`Executing task for cron job with expression [${job.expression}] for project ${projectId}`);
|
|
64
|
+
yield job.task({
|
|
65
|
+
projectId,
|
|
66
|
+
client: crowdinClient,
|
|
67
|
+
credentials,
|
|
68
|
+
rootFolder,
|
|
69
|
+
settings: intConfig,
|
|
70
|
+
});
|
|
71
|
+
(0, logger_1.log)(`Task for cron job with expression [${job.expression}] for project ${projectId} completed`);
|
|
72
|
+
}
|
|
73
|
+
})));
|
|
74
|
+
for (const result of results) {
|
|
75
|
+
if (result.status === 'rejected') {
|
|
76
|
+
(0, logger_1.logError)(result.reason);
|
|
77
|
+
}
|
|
67
78
|
}
|
|
68
|
-
}
|
|
79
|
+
}
|
|
69
80
|
(0, logger_1.log)(`Cron job with expression [${job.expression}] completed`);
|
|
70
81
|
});
|
|
71
82
|
}
|
|
@@ -14,6 +14,7 @@ exports.reRunInProgressJobs = reRunInProgressJobs;
|
|
|
14
14
|
const storage_1 = require("../../../storage");
|
|
15
15
|
const token_1 = require("../../../util/app-functions/token");
|
|
16
16
|
const connection_1 = require("../../../util/connection");
|
|
17
|
+
const util_1 = require("../../../util");
|
|
17
18
|
const logger_1 = require("../../../util/logger");
|
|
18
19
|
const cron_1 = require("./cron");
|
|
19
20
|
const defaults_1 = require("./defaults");
|
|
@@ -27,6 +28,8 @@ const blockingJobs = {
|
|
|
27
28
|
[types_1.JobType.INTEGRATION_SETTINGS_SAVE]: [types_1.JobType.INTEGRATION_SETTINGS_SAVE],
|
|
28
29
|
};
|
|
29
30
|
const maxAttempts = 3;
|
|
31
|
+
// Maximum number of in-progress jobs retried concurrently on startup.
|
|
32
|
+
const RERUN_JOB_CONCURRENCY = (0, util_1.getEnvInt)('RERUN_JOB_CONCURRENCY', 5);
|
|
30
33
|
const store = {};
|
|
31
34
|
function runAsJob(_a) {
|
|
32
35
|
return __awaiter(this, arguments, void 0, function* ({ integrationId, crowdinId, type, title, payload, res, projectId, client, jobType, jobStoreType, responseData, jobCallback, onError, reRunJobId, forcePushTranslations, initiatedBy, }) {
|
|
@@ -219,74 +222,82 @@ function reRunInProgressJobs(config) {
|
|
|
219
222
|
if (!(inProgressJobs === null || inProgressJobs === void 0 ? void 0 : inProgressJobs.length)) {
|
|
220
223
|
return;
|
|
221
224
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
225
|
+
for (let i = 0; i < inProgressJobs.length; i += RERUN_JOB_CONCURRENCY) {
|
|
226
|
+
const batch = inProgressJobs.slice(i, i + RERUN_JOB_CONCURRENCY);
|
|
227
|
+
const results = yield Promise.allSettled(batch.map((activeJob) => __awaiter(this, void 0, void 0, function* () {
|
|
228
|
+
if (activeJob && ![types_1.JobStatus.IN_PROGRESS, types_1.JobStatus.CREATED].includes(activeJob.status)) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (activeJob.attempt && activeJob.attempt >= maxAttempts) {
|
|
232
|
+
yield storage.updateJob({ id: activeJob.id, status: types_1.JobStatus.FAILED });
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const { integrationId, crowdinId, type, title, payload } = activeJob;
|
|
236
|
+
const integration = config.projectIntegration;
|
|
237
|
+
let crowdinClient;
|
|
238
|
+
const integrationCredentials = yield (0, storage_1.getStorage)().getIntegrationCredentials(integrationId);
|
|
239
|
+
const crowdinCredentials = yield (0, storage_1.getStorage)().getCrowdinCredentials(crowdinId);
|
|
240
|
+
const integrationConfig = yield (0, storage_1.getStorage)().getIntegrationConfig(integrationId);
|
|
241
|
+
if (!integrationCredentials || !crowdinCredentials) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const projectId = (0, token_1.getProjectId)(integrationCredentials.id);
|
|
245
|
+
const context = {
|
|
246
|
+
jwtPayload: {
|
|
247
|
+
context: {
|
|
248
|
+
project_id: projectId,
|
|
249
|
+
organization_id: crowdinCredentials.organizationId,
|
|
250
|
+
organization_domain: crowdinCredentials.domain,
|
|
251
|
+
user_id: crowdinCredentials.userId,
|
|
252
|
+
},
|
|
247
253
|
},
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
254
|
+
};
|
|
255
|
+
try {
|
|
256
|
+
const preparedCrowdinClient = yield (0, connection_1.prepareCrowdinClient)({
|
|
257
|
+
config,
|
|
258
|
+
credentials: crowdinCredentials,
|
|
259
|
+
autoRenew: true,
|
|
260
|
+
context,
|
|
261
|
+
});
|
|
262
|
+
crowdinClient = preparedCrowdinClient.client;
|
|
263
|
+
}
|
|
264
|
+
catch (e) {
|
|
265
|
+
(0, logger_1.logError)(e);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
|
|
269
|
+
const credentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
|
|
270
|
+
const intConfig = (integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.config)
|
|
271
|
+
? JSON.parse(integrationConfig.config)
|
|
272
|
+
: { schedule: '0', condition: '0' };
|
|
273
|
+
yield storage.updateJob({ attempt: +(activeJob.attempt || 0) + 1, id: activeJob.id });
|
|
274
|
+
if ([types_1.JobType.UPDATE_TO_CROWDIN, types_1.JobType.UPDATE_TO_INTEGRATION].includes(type)) {
|
|
275
|
+
yield (0, cron_1.runUpdateProviderJob)({
|
|
276
|
+
integrationId,
|
|
277
|
+
crowdinId,
|
|
278
|
+
type,
|
|
279
|
+
title,
|
|
280
|
+
payload: JSON.parse(payload),
|
|
281
|
+
jobType: types_1.JobClientType.RERUN,
|
|
282
|
+
projectId,
|
|
283
|
+
client: crowdinClient,
|
|
284
|
+
integration,
|
|
285
|
+
context,
|
|
286
|
+
credentials,
|
|
287
|
+
rootFolder,
|
|
288
|
+
settings: intConfig,
|
|
289
|
+
reRunJobId: activeJob.id,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
else if ([types_1.JobType.CROWDIN_SYNC_SETTINGS_SAVE, types_1.JobType.INTEGRATION_SYNC_SETTINGS_SAVE].includes(type)) {
|
|
293
|
+
yield storage.updateJob({ status: types_1.JobStatus.CANCELED, id: activeJob.id });
|
|
294
|
+
}
|
|
295
|
+
})));
|
|
296
|
+
for (const result of results) {
|
|
297
|
+
if (result.status === 'rejected') {
|
|
298
|
+
(0, logger_1.logError)(result.reason);
|
|
299
|
+
}
|
|
289
300
|
}
|
|
290
|
-
}
|
|
301
|
+
}
|
|
291
302
|
});
|
|
292
303
|
}
|