@crowdin/app-project-module 1.5.3 → 1.5.5
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-prompt-provider/types.d.ts +3 -3
- package/out/modules/integration/handlers/job-info-deprecated.js +10 -2
- package/out/modules/integration/handlers/sync-settings-save.js +1 -1
- package/out/modules/integration/util/files.js +4 -1
- package/out/modules/integration/util/snapshot.d.ts +4 -2
- package/out/modules/integration/util/snapshot.js +17 -7
- package/out/modules/manifest.js +2 -2
- package/package.json +1 -1
|
@@ -21,8 +21,8 @@ export interface AiPromptProviderModule extends UiModule {
|
|
|
21
21
|
*/
|
|
22
22
|
actions?: PromptActions[] | `custom:${string}`[];
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
* Default:
|
|
24
|
+
* Allow auto-retry on QA issues in user interface.
|
|
25
|
+
* Default: true
|
|
26
26
|
*/
|
|
27
|
-
|
|
27
|
+
allowRetryOnQaIssues?: boolean;
|
|
28
28
|
}
|
|
@@ -37,7 +37,7 @@ function getHumanETA(ms) {
|
|
|
37
37
|
}
|
|
38
38
|
function handle(config) {
|
|
39
39
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
40
|
-
var _a, _b;
|
|
40
|
+
var _a, _b, _c;
|
|
41
41
|
const isApi = req.isApiCall;
|
|
42
42
|
const id = ((_a = req.query) === null || _a === void 0 ? void 0 : _a.jobId) || ((_b = req.body) === null || _b === void 0 ? void 0 : _b.jobId);
|
|
43
43
|
if (!id) {
|
|
@@ -85,7 +85,15 @@ function handle(config) {
|
|
|
85
85
|
res.send([filteredJob]);
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
88
|
-
|
|
88
|
+
const jobTimestamp = (_c = job === null || job === void 0 ? void 0 : job.updatedAt) !== null && _c !== void 0 ? _c : job === null || job === void 0 ? void 0 : job.createdAt;
|
|
89
|
+
const isJobStuck = !!job && !!jobTimestamp && Date.now() - jobTimestamp >= MINUTES * 60 * 1000;
|
|
90
|
+
if (isJobStuck) {
|
|
91
|
+
const settingsJobTypes = [types_1.JobType.CROWDIN_SYNC_SETTINGS_SAVE, types_1.JobType.INTEGRATION_SYNC_SETTINGS_SAVE];
|
|
92
|
+
if (settingsJobTypes.includes(job.type)) {
|
|
93
|
+
req.logInfo(`Canceling stuck settings job '${job.id}' after no updates for more than '${MINUTES}' minutes.`);
|
|
94
|
+
yield (0, storage_1.getStorage)().updateJob({ id: job.id, status: types_1.JobStatus.CANCELED });
|
|
95
|
+
return res.send(Object.assign(Object.assign({}, job), { status: types_1.JobStatus.CANCELED }));
|
|
96
|
+
}
|
|
89
97
|
const context = req.crowdinContext;
|
|
90
98
|
const projectId = context.jwtPayload.context.project_id;
|
|
91
99
|
const integration = config.projectIntegration;
|
|
@@ -85,7 +85,7 @@ function handle(config, integration) {
|
|
|
85
85
|
((_a = integration.syncNewElements) === null || _a === void 0 ? void 0 : _a[provider]) &&
|
|
86
86
|
(settings[`new-${provider}-files`] || hasSyncedFolders);
|
|
87
87
|
if (needsSnapshot) {
|
|
88
|
-
yield (0, snapshot_1.createOrUpdateFileSnapshot)(config, integration, req, provider);
|
|
88
|
+
yield (0, snapshot_1.createOrUpdateFileSnapshot)(config, integration, req, provider, job);
|
|
89
89
|
}
|
|
90
90
|
}),
|
|
91
91
|
});
|
|
@@ -65,7 +65,7 @@ function expandFilesTree(nodes, req, integration, job) {
|
|
|
65
65
|
}
|
|
66
66
|
const files = nodes.filter((file) => file.nodeType === undefined || file.nodeType === '1');
|
|
67
67
|
const folders = nodes.filter((folder) => folder.nodeType === '0' && !nodes.find((node) => node.parentId === folder.id));
|
|
68
|
-
for (const { id } of folders) {
|
|
68
|
+
for (const { id, name } of folders) {
|
|
69
69
|
let integrationData = [];
|
|
70
70
|
try {
|
|
71
71
|
integrationData = yield integration.getIntegrationFiles({
|
|
@@ -75,6 +75,9 @@ function expandFilesTree(nodes, req, integration, job) {
|
|
|
75
75
|
settings: req.integrationSettings,
|
|
76
76
|
parentId: id,
|
|
77
77
|
});
|
|
78
|
+
if (job) {
|
|
79
|
+
yield job.update({ info: `Loading files from '${name}'` });
|
|
80
|
+
}
|
|
78
81
|
}
|
|
79
82
|
catch (e) {
|
|
80
83
|
if (job) {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import Crowdin from '@crowdin/crowdin-api-client';
|
|
2
2
|
import { Config } from '../../../types';
|
|
3
3
|
import { IntegrationLogic, IntegrationRequest, Provider, TreeItem } from '../types';
|
|
4
|
+
import { JobClient } from './types';
|
|
4
5
|
export declare function getCrowdinSnapshot(config: Config, integration: IntegrationLogic, crowdinApiClient: Crowdin, projectId: number, integrationSettings: any): Promise<TreeItem[]>;
|
|
5
|
-
export declare function getIntegrationSnapshot({ integration, integrationCredentials, integrationSettings, client, projectId, }: {
|
|
6
|
+
export declare function getIntegrationSnapshot({ integration, integrationCredentials, integrationSettings, client, projectId, job, }: {
|
|
6
7
|
integration: IntegrationLogic;
|
|
7
8
|
integrationCredentials: any;
|
|
8
9
|
integrationSettings: any;
|
|
9
10
|
client?: Crowdin;
|
|
10
11
|
projectId?: number;
|
|
12
|
+
job?: JobClient;
|
|
11
13
|
}): Promise<TreeItem[]>;
|
|
12
|
-
export declare function createOrUpdateFileSnapshot(config: Config, integration: IntegrationLogic, req: IntegrationRequest, provider: Provider): Promise<void>;
|
|
14
|
+
export declare function createOrUpdateFileSnapshot(config: Config, integration: IntegrationLogic, req: IntegrationRequest, provider: Provider, job?: JobClient): Promise<void>;
|
|
@@ -16,6 +16,7 @@ const types_1 = require("../types");
|
|
|
16
16
|
const storage_1 = require("../../../storage");
|
|
17
17
|
const defaults_1 = require("./defaults");
|
|
18
18
|
const files_1 = require("./files");
|
|
19
|
+
const types_2 = require("./types");
|
|
19
20
|
const DEFAULT_SNAPSHOT_FETCH_CONCURRENCY = 1;
|
|
20
21
|
function getCrowdinSnapshot(config, integration, crowdinApiClient, projectId, integrationSettings) {
|
|
21
22
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -42,10 +43,10 @@ function getTreeItems(integrationData) {
|
|
|
42
43
|
}
|
|
43
44
|
return files;
|
|
44
45
|
}
|
|
45
|
-
function getOneLevelFetchingFiles(
|
|
46
|
-
return __awaiter(this,
|
|
46
|
+
function getOneLevelFetchingFiles(integration_1, integrationCredentials_1, integrationSettings_1, parentFiles_1, client_1, projectId_1, job_1) {
|
|
47
|
+
return __awaiter(this, arguments, void 0, function* (integration, integrationCredentials, integrationSettings, parentFiles, client, projectId, job, visitedIds = new Set()) {
|
|
47
48
|
var _a;
|
|
48
|
-
const folders = parentFiles.filter((file) => !file.type);
|
|
49
|
+
const folders = parentFiles.filter((file) => !file.type && !visitedIds.has(file.id));
|
|
49
50
|
if (folders.length === 0) {
|
|
50
51
|
return parentFiles;
|
|
51
52
|
}
|
|
@@ -54,6 +55,11 @@ function getOneLevelFetchingFiles(integration, integrationCredentials, integrati
|
|
|
54
55
|
for (let i = 0; i < folders.length; i += concurrency) {
|
|
55
56
|
const batch = folders.slice(i, i + concurrency);
|
|
56
57
|
const batchResults = yield Promise.all(batch.map((folder) => __awaiter(this, void 0, void 0, function* () {
|
|
58
|
+
var _a;
|
|
59
|
+
if (job && types_2.JobStatus.CANCELED === ((_a = (yield job.get())) === null || _a === void 0 ? void 0 : _a.status)) {
|
|
60
|
+
throw new Error('Job canceled');
|
|
61
|
+
}
|
|
62
|
+
visitedIds.add(folder.id);
|
|
57
63
|
const childs = getTreeItems(yield integration.getIntegrationFiles({
|
|
58
64
|
credentials: integrationCredentials,
|
|
59
65
|
client,
|
|
@@ -63,10 +69,13 @@ function getOneLevelFetchingFiles(integration, integrationCredentials, integrati
|
|
|
63
69
|
search: '',
|
|
64
70
|
page: 0,
|
|
65
71
|
}));
|
|
72
|
+
if (job) {
|
|
73
|
+
yield job.update({ info: `Loading snapshot from ${folder.name}` });
|
|
74
|
+
}
|
|
66
75
|
if (childs.length === 0) {
|
|
67
76
|
return [];
|
|
68
77
|
}
|
|
69
|
-
return getOneLevelFetchingFiles(integration, integrationCredentials, integrationSettings, childs, client, projectId);
|
|
78
|
+
return getOneLevelFetchingFiles(integration, integrationCredentials, integrationSettings, childs, client, projectId, job, visitedIds);
|
|
70
79
|
})));
|
|
71
80
|
results.push(...batchResults.flat());
|
|
72
81
|
}
|
|
@@ -74,7 +83,7 @@ function getOneLevelFetchingFiles(integration, integrationCredentials, integrati
|
|
|
74
83
|
});
|
|
75
84
|
}
|
|
76
85
|
function getIntegrationSnapshot(_a) {
|
|
77
|
-
return __awaiter(this, arguments, void 0, function* ({ integration, integrationCredentials, integrationSettings, client, projectId, }) {
|
|
86
|
+
return __awaiter(this, arguments, void 0, function* ({ integration, integrationCredentials, integrationSettings, client, projectId, job, }) {
|
|
78
87
|
var _b;
|
|
79
88
|
let files = [];
|
|
80
89
|
let integrationData = [];
|
|
@@ -88,7 +97,7 @@ function getIntegrationSnapshot(_a) {
|
|
|
88
97
|
});
|
|
89
98
|
files = getTreeItems(integrationData);
|
|
90
99
|
if (integration.integrationOneLevelFetching) {
|
|
91
|
-
files = yield getOneLevelFetchingFiles(integration, integrationCredentials, integrationSettings, files, client, projectId);
|
|
100
|
+
files = yield getOneLevelFetchingFiles(integration, integrationCredentials, integrationSettings, files, client, projectId, job);
|
|
92
101
|
}
|
|
93
102
|
if ((integrationSettings === null || integrationSettings === void 0 ? void 0 : integrationSettings.skipIntegrationNodesToggle) === true ||
|
|
94
103
|
((integrationSettings === null || integrationSettings === void 0 ? void 0 : integrationSettings.skipIntegrationNodesToggle) === null && ((_b = integration.skipIntegrationNodesToggle) === null || _b === void 0 ? void 0 : _b.value))) {
|
|
@@ -99,7 +108,7 @@ function getIntegrationSnapshot(_a) {
|
|
|
99
108
|
return files;
|
|
100
109
|
});
|
|
101
110
|
}
|
|
102
|
-
function createOrUpdateFileSnapshot(config, integration, req, provider) {
|
|
111
|
+
function createOrUpdateFileSnapshot(config, integration, req, provider, job) {
|
|
103
112
|
return __awaiter(this, void 0, void 0, function* () {
|
|
104
113
|
let files = [];
|
|
105
114
|
const existingSnapshot = yield (0, storage_1.getStorage)().getFilesSnapshot(req.crowdinContext.clientId, req.crowdinContext.crowdinId, provider);
|
|
@@ -113,6 +122,7 @@ function createOrUpdateFileSnapshot(config, integration, req, provider) {
|
|
|
113
122
|
integrationSettings: req.integrationSettings,
|
|
114
123
|
client: req.crowdinApiClient,
|
|
115
124
|
projectId: req.crowdinContext.jwtPayload.context.project_id,
|
|
125
|
+
job,
|
|
116
126
|
});
|
|
117
127
|
}
|
|
118
128
|
if (existingSnapshot) {
|
package/out/modules/manifest.js
CHANGED
|
@@ -298,8 +298,8 @@ function handle(config) {
|
|
|
298
298
|
// prevent possible overrides of the other modules
|
|
299
299
|
config.aiPromptProvider = Object.assign(Object.assign({}, config.aiPromptProvider), { key: config.identifier + '-ai-prompt-provider' });
|
|
300
300
|
modules['ai-prompt-provider'] = [
|
|
301
|
-
Object.assign(Object.assign(Object.assign({ key: config.aiPromptProvider.key, name: config.aiPromptProvider.name || config.name, logo: (0, util_1.getLogoUrl)(config, config.aiPromptProvider, '/ai-prompt-provider'), compileUrl: '/prompt-provider/compile' }, ((0, util_1.isDefined)(config.aiPromptProvider.
|
|
302
|
-
|
|
301
|
+
Object.assign(Object.assign(Object.assign({ key: config.aiPromptProvider.key, name: config.aiPromptProvider.name || config.name, logo: (0, util_1.getLogoUrl)(config, config.aiPromptProvider, '/ai-prompt-provider'), compileUrl: '/prompt-provider/compile' }, ((0, util_1.isDefined)(config.aiPromptProvider.allowRetryOnQaIssues) && {
|
|
302
|
+
allowRetryOnQaIssues: config.aiPromptProvider.allowRetryOnQaIssues,
|
|
303
303
|
})), (config.aiPromptProvider.actions
|
|
304
304
|
? {
|
|
305
305
|
actions: config.aiPromptProvider.actions,
|
package/package.json
CHANGED