@crowdin/app-project-module 0.28.11 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/handlers/crowdin-file-progress.js +1 -1
- package/out/handlers/crowdin-update.js +7 -2
- package/out/handlers/crowdin-webhook.js +4 -3
- package/out/handlers/integration-update.js +5 -0
- package/out/handlers/integration-webhook.js +2 -1
- package/out/handlers/main.js +1 -0
- package/out/handlers/manifest.js +4 -0
- package/out/handlers/settings-save.js +11 -0
- package/out/handlers/settings.d.ts +4 -0
- package/out/handlers/settings.js +22 -0
- package/out/handlers/sync-settings-save.d.ts +2 -2
- package/out/handlers/sync-settings-save.js +8 -11
- package/out/handlers/sync-settings.js +1 -1
- package/out/index.js +8 -1
- package/out/middlewares/crowdin-client.js +5 -0
- package/out/models/index.d.ts +56 -3
- package/out/models/index.js +14 -1
- package/out/static/js/dependent.js +1 -2
- package/out/storage/index.d.ts +8 -5
- package/out/storage/mysql.d.ts +4 -1
- package/out/storage/mysql.js +35 -1
- package/out/storage/postgre.d.ts +4 -1
- package/out/storage/postgre.js +35 -1
- package/out/storage/sqlite.d.ts +4 -1
- package/out/storage/sqlite.js +33 -1
- package/out/util/api/api.d.ts +6 -0
- package/out/util/api/api.js +452 -0
- package/out/util/api/base.d.ts +7 -0
- package/out/util/api/base.js +8 -0
- package/out/util/api/components.d.ts +227 -0
- package/out/util/api/components.js +228 -0
- package/out/util/cron.d.ts +2 -1
- package/out/util/cron.js +76 -9
- package/out/util/defaults.js +26 -3
- package/out/util/file-snapshot.d.ts +7 -0
- package/out/util/file-snapshot.js +144 -0
- package/out/util/webhooks.d.ts +4 -3
- package/out/util/webhooks.js +29 -5
- package/out/views/main.handlebars +140 -8
- package/package.json +5 -1
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.createOrUpdateFileSnapshot = exports.getIntegrationSnapshot = exports.getCrowdinSnapshot = exports.getAllNewFiles = exports.getFileDiff = void 0;
|
|
13
|
+
const models_1 = require("../models");
|
|
14
|
+
const index_1 = require("./index");
|
|
15
|
+
const defaults_1 = require("./defaults");
|
|
16
|
+
const storage_1 = require("../storage");
|
|
17
|
+
function getFileDiff(currentFiles, savedFiles) {
|
|
18
|
+
return currentFiles.filter((x) => !savedFiles.some((x2) => x2.id === x.id));
|
|
19
|
+
}
|
|
20
|
+
exports.getFileDiff = getFileDiff;
|
|
21
|
+
function getAllNewFiles(args) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
const { config, integration, crowdinApiClient, crowdinId, integrationCredentials, integrationId, projectId, integrationSettings, syncSettings, } = args;
|
|
24
|
+
let currentFileSnapshot = [];
|
|
25
|
+
const fileSnapshotData = yield (0, storage_1.getStorage)().getFilesSnapshot(integrationId, crowdinId, syncSettings.provider);
|
|
26
|
+
const snapshotFiles = (fileSnapshotData === null || fileSnapshotData === void 0 ? void 0 : fileSnapshotData.files) ? JSON.parse(fileSnapshotData.files) : [];
|
|
27
|
+
if (syncSettings.provider === models_1.Provider.CROWDIN) {
|
|
28
|
+
currentFileSnapshot = yield getCrowdinSnapshot(config, integration, crowdinApiClient, projectId, integrationSettings);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
currentFileSnapshot = yield getIntegrationSnapshot(integration, integrationCredentials, integrationSettings);
|
|
32
|
+
}
|
|
33
|
+
const difference = getFileDiff(currentFileSnapshot, snapshotFiles);
|
|
34
|
+
const onlyFiles = difference.filter((file) => 'type' in file);
|
|
35
|
+
const synFiles = JSON.parse(syncSettings.files);
|
|
36
|
+
if (syncSettings.provider === models_1.Provider.INTEGRATION) {
|
|
37
|
+
if (integrationSettings[`new-${syncSettings.provider}-files`]) {
|
|
38
|
+
return onlyFiles;
|
|
39
|
+
}
|
|
40
|
+
const syncFolders = synFiles.filter((file) => !('type' in file));
|
|
41
|
+
return getNewFoldersFile(syncFolders, difference);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const files = {};
|
|
45
|
+
const projectData = yield crowdinApiClient.projectsGroupsApi.getProject(projectId);
|
|
46
|
+
const targetLanguages = projectData.data.targetLanguageIds;
|
|
47
|
+
if (integrationSettings[`new-${syncSettings.provider}-files`]) {
|
|
48
|
+
for (const file of onlyFiles) {
|
|
49
|
+
files[file.id] = targetLanguages;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
const syncFolders = currentFileSnapshot.filter((file) => !('type' in file) && Object.keys(synFiles).includes(file.id));
|
|
54
|
+
const newFiles = getNewFoldersFile(syncFolders, difference);
|
|
55
|
+
for (const file of newFiles) {
|
|
56
|
+
files[file.id] = targetLanguages;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return files;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
exports.getAllNewFiles = getAllNewFiles;
|
|
64
|
+
function getNewFoldersFile(folders, snapshotFiles) {
|
|
65
|
+
let files = [];
|
|
66
|
+
for (const folder of folders) {
|
|
67
|
+
const newFiles = snapshotFiles.find((file) => file.parentId === folder.id);
|
|
68
|
+
if (newFiles) {
|
|
69
|
+
files = files.concat(newFiles);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
files = files.filter((file) => 'type' in file);
|
|
73
|
+
return files;
|
|
74
|
+
}
|
|
75
|
+
function getCrowdinSnapshot(config, integration, crowdinApiClient, projectId, integrationSettings) {
|
|
76
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
77
|
+
let files = [];
|
|
78
|
+
if (integration.getCrowdinFiles) {
|
|
79
|
+
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinApiClient, projectId);
|
|
80
|
+
files = yield integration.getCrowdinFiles(projectId, crowdinApiClient, rootFolder, integrationSettings);
|
|
81
|
+
}
|
|
82
|
+
return files;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
exports.getCrowdinSnapshot = getCrowdinSnapshot;
|
|
86
|
+
function getTreeItems(integrationData) {
|
|
87
|
+
let files = [];
|
|
88
|
+
if ((0, index_1.isExtendedResultType)(integrationData)) {
|
|
89
|
+
files = integrationData.data;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
files = integrationData;
|
|
93
|
+
}
|
|
94
|
+
return files;
|
|
95
|
+
}
|
|
96
|
+
function getOneLevelFetchingFiles(integration, integrationCredentials, integrationSettings, parentFiles) {
|
|
97
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
98
|
+
for (const file of parentFiles) {
|
|
99
|
+
if (!('type' in file)) {
|
|
100
|
+
let childs = yield integration.getIntegrationFiles(integrationCredentials, integrationSettings, file.id, '', 0);
|
|
101
|
+
childs = getTreeItems(childs);
|
|
102
|
+
if (childs.length > 0) {
|
|
103
|
+
const childFiles = yield getOneLevelFetchingFiles(integration, integrationCredentials, integrationSettings, childs);
|
|
104
|
+
parentFiles = [...parentFiles, ...childFiles];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return parentFiles;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function getIntegrationSnapshot(integration, integrationCredentials, integrationSettings) {
|
|
112
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
+
let files = [];
|
|
114
|
+
let integrationData = [];
|
|
115
|
+
integrationData = yield integration.getIntegrationFiles(integrationCredentials, integrationSettings, '', '', 0);
|
|
116
|
+
files = getTreeItems(integrationData);
|
|
117
|
+
if (integration.integrationOneLevelFetching) {
|
|
118
|
+
files = yield getOneLevelFetchingFiles(integration, integrationCredentials, integrationSettings, files);
|
|
119
|
+
}
|
|
120
|
+
return files;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
exports.getIntegrationSnapshot = getIntegrationSnapshot;
|
|
124
|
+
function createOrUpdateFileSnapshot(config, integration, req, provider) {
|
|
125
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
126
|
+
let files = [];
|
|
127
|
+
const existingSnapshot = yield (0, storage_1.getStorage)().getFilesSnapshot(req.crowdinContext.clientId, req.crowdinContext.crowdinId, provider);
|
|
128
|
+
if (provider === models_1.Provider.CROWDIN) {
|
|
129
|
+
files = yield getCrowdinSnapshot(config, integration, req.crowdinApiClient, req.crowdinContext.jwtPayload.context.project_id, req.integrationSettings);
|
|
130
|
+
}
|
|
131
|
+
if (provider === models_1.Provider.INTEGRATION) {
|
|
132
|
+
files = yield getIntegrationSnapshot(integration, req.integrationCredentials, req.integrationSettings);
|
|
133
|
+
}
|
|
134
|
+
if (existingSnapshot) {
|
|
135
|
+
(0, index_1.log)(`Updating file snapshot for provider ${provider} ${JSON.stringify(files, null, 2)}`, config.logger);
|
|
136
|
+
yield (0, storage_1.getStorage)().updateFilesSnapshot(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, provider);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
(0, index_1.log)(`Saving file snapshot for provider ${provider} ${JSON.stringify(files, null, 2)}`, config.logger);
|
|
140
|
+
yield (0, storage_1.getStorage)().saveFilesSnapshot(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, provider);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
exports.createOrUpdateFileSnapshot = createOrUpdateFileSnapshot;
|
package/out/util/webhooks.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Crowdin from '@crowdin/crowdin-api-client';
|
|
2
|
-
import { Config, CrowdinContextInfo, IntegrationLogic, Payload, UpdateIntegrationRequest, WebhookUrlParams } from '../models';
|
|
2
|
+
import { Config, CrowdinContextInfo, IntegrationLogic, IntegrationSyncSettings, Payload, Provider, TreeItem, UpdateIntegrationRequest, WebhookUrlParams } from '../models';
|
|
3
3
|
import { WebhooksModel } from '@crowdin/crowdin-api-client/out/webhooks';
|
|
4
4
|
import { Request } from 'express';
|
|
5
5
|
export declare function encodedUrlParam(config: Config, integration: IntegrationLogic, crowdinContext: CrowdinContextInfo): string;
|
|
@@ -14,7 +14,7 @@ export declare function updateCrowdinWebhooks(config: Config, client: Crowdin, p
|
|
|
14
14
|
export declare function unregisterCrowdinWebhooks(config: Config, client: Crowdin, projectId: number, webhook: WebhooksModel.Webhook): Promise<void>;
|
|
15
15
|
export declare function unregisterAllCrowdinWebhooks(config: Config, integration: IntegrationLogic, crowdinId: string): Promise<void>;
|
|
16
16
|
export declare function filterSyncFiles(events: Payload[], syncFileSettings: UpdateIntegrationRequest): UpdateIntegrationRequest;
|
|
17
|
-
export declare function prepareWebhookData(config: Config, integration: IntegrationLogic, webhookUrlParam: string, provider:
|
|
17
|
+
export declare function prepareWebhookData(config: Config, integration: IntegrationLogic, webhookUrlParam: string, provider: Provider): Promise<{
|
|
18
18
|
projectId: number;
|
|
19
19
|
crowdinClient: {
|
|
20
20
|
client: Crowdin;
|
|
@@ -23,7 +23,8 @@ export declare function prepareWebhookData(config: Config, integration: Integrat
|
|
|
23
23
|
preparedIntegrationCredentials: any;
|
|
24
24
|
rootFolder: import("@crowdin/crowdin-api-client").SourceFilesModel.Directory | undefined;
|
|
25
25
|
appSettings: any;
|
|
26
|
-
syncSettings:
|
|
26
|
+
syncSettings: IntegrationSyncSettings | null;
|
|
27
|
+
newFiles: TreeItem[] | UpdateIntegrationRequest;
|
|
27
28
|
}>;
|
|
28
29
|
export declare function updateCrowdinFromWebhookRequest(integration: IntegrationLogic, webhookData: any, req: Request): Promise<void | import("../models").ExtendedResult<void>>;
|
|
29
30
|
export declare function listenQueueMessage(config: Config, integration: IntegrationLogic, queueUrl: string, queueName: string): Promise<void>;
|
package/out/util/webhooks.js
CHANGED
|
@@ -44,6 +44,7 @@ const connection_1 = require("./connection");
|
|
|
44
44
|
const storage_1 = require("../storage");
|
|
45
45
|
const defaults_1 = require("./defaults");
|
|
46
46
|
const util_1 = require("../util");
|
|
47
|
+
const file_snapshot_1 = require("./file-snapshot");
|
|
47
48
|
const HookEvents = {
|
|
48
49
|
ALL: ['file.translated', 'file.approved'],
|
|
49
50
|
TRANSLATED: ['file.translated'],
|
|
@@ -227,10 +228,12 @@ function filterSyncFiles(events, syncFileSettings) {
|
|
|
227
228
|
}
|
|
228
229
|
exports.filterSyncFiles = filterSyncFiles;
|
|
229
230
|
function prepareWebhookData(config, integration, webhookUrlParam, provider) {
|
|
231
|
+
var _a;
|
|
230
232
|
return __awaiter(this, void 0, void 0, function* () {
|
|
231
233
|
let rootFolder = undefined;
|
|
232
234
|
let appSettings = null;
|
|
233
235
|
let syncSettings = null;
|
|
236
|
+
let newFiles = [];
|
|
234
237
|
const { projectId, crowdinId, clientId } = decodedUrlParam(config, webhookUrlParam);
|
|
235
238
|
const crowdinCredentials = yield (0, storage_1.getStorage)().getCrowdinCredentials(crowdinId);
|
|
236
239
|
const crowdinClient = yield (0, connection_1.prepareCrowdinClient)(config, crowdinCredentials);
|
|
@@ -240,11 +243,32 @@ function prepareWebhookData(config, integration, webhookUrlParam, provider) {
|
|
|
240
243
|
appSettings = JSON.parse(integrationCredentials.config);
|
|
241
244
|
const isWebhookSync = +appSettings.syncType === models_1.SyncType.WEBHOOKS;
|
|
242
245
|
if (isWebhookSync) {
|
|
243
|
-
syncSettings = yield (0, storage_1.getStorage)().getSyncSettings(clientId, crowdinId, 'schedule', provider);
|
|
246
|
+
syncSettings = (yield (0, storage_1.getStorage)().getSyncSettings(clientId, crowdinId, 'schedule', provider));
|
|
244
247
|
rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient.client, projectId);
|
|
248
|
+
if ((_a = integration.syncNewElements) === null || _a === void 0 ? void 0 : _a[provider]) {
|
|
249
|
+
newFiles = yield (0, file_snapshot_1.getAllNewFiles)({
|
|
250
|
+
config,
|
|
251
|
+
integration,
|
|
252
|
+
crowdinApiClient: crowdinClient.client,
|
|
253
|
+
crowdinId,
|
|
254
|
+
integrationCredentials: preparedIntegrationCredentials,
|
|
255
|
+
integrationId: clientId,
|
|
256
|
+
projectId,
|
|
257
|
+
integrationSettings: appSettings,
|
|
258
|
+
syncSettings,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
245
261
|
}
|
|
246
262
|
}
|
|
247
|
-
return {
|
|
263
|
+
return {
|
|
264
|
+
projectId,
|
|
265
|
+
crowdinClient,
|
|
266
|
+
preparedIntegrationCredentials,
|
|
267
|
+
rootFolder,
|
|
268
|
+
appSettings,
|
|
269
|
+
syncSettings,
|
|
270
|
+
newFiles,
|
|
271
|
+
};
|
|
248
272
|
});
|
|
249
273
|
}
|
|
250
274
|
exports.prepareWebhookData = prepareWebhookData;
|
|
@@ -252,9 +276,9 @@ function updateCrowdinFromWebhookRequest(integration, webhookData, req) {
|
|
|
252
276
|
var _a, _b;
|
|
253
277
|
return __awaiter(this, void 0, void 0, function* () {
|
|
254
278
|
let filesToSync = [];
|
|
255
|
-
const { projectId, crowdinClient, preparedIntegrationCredentials, rootFolder, appSettings, syncSettings } = webhookData;
|
|
279
|
+
const { projectId, crowdinClient, preparedIntegrationCredentials, rootFolder, appSettings, syncSettings, newFiles, } = webhookData;
|
|
256
280
|
if ((_a = integration.webhooks) === null || _a === void 0 ? void 0 : _a.integrationWebhookInterceptor) {
|
|
257
|
-
filesToSync = yield ((_b = integration.webhooks) === null || _b === void 0 ? void 0 : _b.integrationWebhookInterceptor(projectId, crowdinClient.client, preparedIntegrationCredentials, rootFolder, appSettings, syncSettings, req));
|
|
281
|
+
filesToSync = yield ((_b = integration.webhooks) === null || _b === void 0 ? void 0 : _b.integrationWebhookInterceptor(projectId, crowdinClient.client, preparedIntegrationCredentials, rootFolder, appSettings, syncSettings, req, newFiles));
|
|
258
282
|
}
|
|
259
283
|
return yield integration.updateCrowdin(projectId, crowdinClient.client, preparedIntegrationCredentials, filesToSync, rootFolder, appSettings);
|
|
260
284
|
});
|
|
@@ -296,7 +320,7 @@ function consumer(channel, config, integration) {
|
|
|
296
320
|
const data = JSON.parse(msg.content.toString());
|
|
297
321
|
const urlParam = (_a = integration.webhooks) === null || _a === void 0 ? void 0 : _a.urlParam;
|
|
298
322
|
const webhookUrlParam = data.query[urlParam];
|
|
299
|
-
const webhookData = yield prepareWebhookData(config, integration, webhookUrlParam,
|
|
323
|
+
const webhookData = yield prepareWebhookData(config, integration, webhookUrlParam, models_1.Provider.INTEGRATION);
|
|
300
324
|
yield updateCrowdinFromWebhookRequest(integration, webhookData, data);
|
|
301
325
|
}
|
|
302
326
|
catch (e) {
|
|
@@ -34,6 +34,12 @@
|
|
|
34
34
|
{{/if}}
|
|
35
35
|
</div>
|
|
36
36
|
<crowdin-simple-integration
|
|
37
|
+
{{#if syncNewElements.crowdin}}
|
|
38
|
+
skip-crowdin-auto-schedule
|
|
39
|
+
{{/if}}
|
|
40
|
+
{{#if syncNewElements.integration}}
|
|
41
|
+
skip-integration-auto-schedule
|
|
42
|
+
{{/if}}
|
|
37
43
|
{{#or withCronSync.crowdin webhooks.crowdin}}
|
|
38
44
|
crowdin-schedule="true"
|
|
39
45
|
{{/or}}
|
|
@@ -170,7 +176,12 @@
|
|
|
170
176
|
<crowdin-p>{{label}}</crowdin-p>
|
|
171
177
|
{{/if}}
|
|
172
178
|
{{/if}}
|
|
173
|
-
<div
|
|
179
|
+
<div
|
|
180
|
+
style="padding: 8px"
|
|
181
|
+
{{#if dependencySettings}}
|
|
182
|
+
data-dependency="{{dependencySettings}}"
|
|
183
|
+
{{/if}}
|
|
184
|
+
></div>
|
|
174
185
|
{{/each}}
|
|
175
186
|
</div>
|
|
176
187
|
<div slot="footer">
|
|
@@ -178,6 +189,36 @@
|
|
|
178
189
|
</div>
|
|
179
190
|
</crowdin-modal>
|
|
180
191
|
{{/if}}
|
|
192
|
+
{{#or syncNewElements.crowdin syncNewElements.integration}}
|
|
193
|
+
<crowdin-modal
|
|
194
|
+
id="confirm-schedule-modal"
|
|
195
|
+
modal-width="50"
|
|
196
|
+
modal-title="Synchronization options"
|
|
197
|
+
close-button-title="Close"
|
|
198
|
+
close-button="true"
|
|
199
|
+
body-overflow-unset
|
|
200
|
+
>
|
|
201
|
+
<crowdin-checkbox
|
|
202
|
+
id="selected-files"
|
|
203
|
+
name="selected-files"
|
|
204
|
+
label="Selected files"
|
|
205
|
+
class="hydrated"
|
|
206
|
+
onchange="onChangeAutoSynchronizationOptions(this)"
|
|
207
|
+
>
|
|
208
|
+
</crowdin-checkbox>
|
|
209
|
+
<crowdin-checkbox
|
|
210
|
+
id="new-files"
|
|
211
|
+
name="new-files"
|
|
212
|
+
label="New files"
|
|
213
|
+
class="hydrated"
|
|
214
|
+
onchange="onChangeAutoSynchronizationOptions(this)"
|
|
215
|
+
>
|
|
216
|
+
</crowdin-checkbox>
|
|
217
|
+
<div slot="footer">
|
|
218
|
+
<crowdin-button outlined id="save-schedule-sync" onclick="saveScheduleSync()">Save</crowdin-button>
|
|
219
|
+
</div>
|
|
220
|
+
</crowdin-modal>
|
|
221
|
+
{{/or}}
|
|
181
222
|
</body>
|
|
182
223
|
<script type="text/javascript">
|
|
183
224
|
document.body.addEventListener('refreshFilesList', (e) => {
|
|
@@ -267,7 +308,7 @@
|
|
|
267
308
|
function getIntegrationData(hardReload = false, parentId = '', search = '', page = 0) {
|
|
268
309
|
appComponent.setAttribute('is-integration-loading', true);
|
|
269
310
|
checkOrigin()
|
|
270
|
-
.then(restParams => fetch(`api/integration/data${restParams}&parent_id=${parentId}&search=${search}&page=${page}`))
|
|
311
|
+
.then(restParams => fetch(`api/integration/data${restParams}&parent_id=${encodeURIComponent(parentId)}&search=${encodeURIComponent(search)}&page=${page}`))
|
|
271
312
|
.then(checkResponse)
|
|
272
313
|
.then((res) => {
|
|
273
314
|
const files = res.data;
|
|
@@ -317,9 +358,18 @@
|
|
|
317
358
|
.then(checkResponse)
|
|
318
359
|
.then((res) => {
|
|
319
360
|
if (provider === 'crowdin') {
|
|
320
|
-
|
|
361
|
+
{{#if syncNewElements.crowdin}}
|
|
362
|
+
appComponent.setCrowdinScheduleSync(res, true, true);
|
|
363
|
+
{{else}}
|
|
364
|
+
appComponent.setCrowdinScheduleSync(res);
|
|
365
|
+
{{/if}}
|
|
321
366
|
} else {
|
|
322
|
-
|
|
367
|
+
{{#if syncNewElements.integration}}
|
|
368
|
+
appComponent.setIntegrationScheduleSync(res, true, true);
|
|
369
|
+
{{else}}
|
|
370
|
+
appComponent.setIntegrationScheduleSync(res);
|
|
371
|
+
{{/if}}
|
|
372
|
+
|
|
323
373
|
}
|
|
324
374
|
})
|
|
325
375
|
.catch(e => catchRejection(e, 'Can\'t fetch file progress'));
|
|
@@ -521,19 +571,91 @@
|
|
|
521
571
|
{{/if}}
|
|
522
572
|
|
|
523
573
|
{{#or withCronSync webhooks}}
|
|
574
|
+
const scheduleModal = document.getElementById('confirm-schedule-modal');
|
|
575
|
+
let syncData;
|
|
576
|
+
|
|
524
577
|
document.body.addEventListener('integrationScheduleSync', setIntegrationScheduleSync);
|
|
525
578
|
document.body.addEventListener('crowdinScheduleSync', setCrowdinScheduleSync);
|
|
526
579
|
document.body.addEventListener('crowdinDisableSync', disableCrowdinSync);
|
|
527
580
|
document.body.addEventListener('integrationDisableSync', disableIntegrationSync);
|
|
528
581
|
|
|
582
|
+
async function saveScheduleSync() {
|
|
583
|
+
const newFile = scheduleModal.querySelector('#new-files').checked || false;
|
|
584
|
+
const selectedFiles = scheduleModal.querySelector('#selected-files').checked || false;
|
|
585
|
+
|
|
586
|
+
const type = scheduleModal.getAttribute('data-type');
|
|
587
|
+
|
|
588
|
+
if (type === 'crowdin') {
|
|
589
|
+
appComponent.setCrowdinScheduleSync(syncData, newFile, selectedFiles);
|
|
590
|
+
const syncedFiles = await appComponent.getCrowdinScheduleSync(true);
|
|
591
|
+
appComponent.setAttribute('is-crowdin-loading', true);
|
|
592
|
+
updateSyncSettings(syncedFiles, 'schedule', 'crowdin');
|
|
593
|
+
} else if (type === 'integration') {
|
|
594
|
+
appComponent.setIntegrationScheduleSync(syncData, newFile, selectedFiles);
|
|
595
|
+
const syncedFiles = await appComponent.getIntegrationScheduleSync(true);
|
|
596
|
+
appComponent.setAttribute('is-integration-loading', true);
|
|
597
|
+
updateSyncSettings(syncedFiles, 'schedule', 'integration');
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
scheduleModal.close();
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
function openScheduleModal(type) {
|
|
604
|
+
const newFile = scheduleModal.querySelector('#new-files')
|
|
605
|
+
const selectedFiles = scheduleModal.querySelector('#selected-files');
|
|
606
|
+
|
|
607
|
+
newFile.checked = false;
|
|
608
|
+
newFile.value = false;
|
|
609
|
+
selectedFiles.checked = true;
|
|
610
|
+
selectedFiles.value = true;
|
|
611
|
+
scheduleModal.querySelector('#save-schedule-sync').setAttribute('disabled', false);
|
|
612
|
+
scheduleModal.setAttribute('data-type', type);
|
|
613
|
+
scheduleModal.open();
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
function onChangeAutoSynchronizationOptions() {
|
|
617
|
+
const newFiles = document.getElementById('new-files').checked || false;
|
|
618
|
+
const selectedFiles = document.getElementById('selected-files').checked || false;
|
|
619
|
+
const buttonSaveScheduleSync = document.getElementById('save-schedule-sync');
|
|
620
|
+
|
|
621
|
+
if (newFiles || selectedFiles) {
|
|
622
|
+
buttonSaveScheduleSync.removeAttribute('disabled');
|
|
623
|
+
} else {
|
|
624
|
+
buttonSaveScheduleSync.setAttribute('disabled', true);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
async function hasFolder(selectedFiles) {
|
|
629
|
+
let isFolder;
|
|
630
|
+
if (Array.isArray(selectedFiles)) {
|
|
631
|
+
isFolder = selectedFiles.find((file) => file.node_type === folderType || file.node_type === branchType);
|
|
632
|
+
} else {
|
|
633
|
+
const files = await appComponent.getCrowdinFilesData();
|
|
634
|
+
const folders = files.filter((file) => file.node_type === folderType || file.node_type === branchType);
|
|
635
|
+
isFolder = folders.find((folder) => selectedFiles.hasOwnProperty(folder.id));
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
return isFolder !== undefined;
|
|
639
|
+
}
|
|
640
|
+
|
|
529
641
|
async function setIntegrationScheduleSync(e) {
|
|
530
642
|
if (e.detail.length === 0) {
|
|
531
643
|
showToast('Select templates which will be pushed to Crowdin');
|
|
532
644
|
return;
|
|
533
645
|
}
|
|
534
|
-
appComponent.setAttribute('is-integration-loading', true);
|
|
535
|
-
const syncedFiles = await appComponent.getIntegrationScheduleSync();
|
|
536
646
|
|
|
647
|
+
{{#if syncNewElements.integration}}
|
|
648
|
+
syncData = e.detail;
|
|
649
|
+
const isFolder = await hasFolder(e.detail);
|
|
650
|
+
if (isFolder) {
|
|
651
|
+
openScheduleModal('integration');
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
appComponent.setIntegrationScheduleSync(e.detail);
|
|
656
|
+
{{/if}}
|
|
657
|
+
const syncedFiles = await appComponent.getIntegrationScheduleSync();
|
|
658
|
+
appComponent.setAttribute('is-integration-loading', true);
|
|
537
659
|
updateSyncSettings(syncedFiles, 'schedule', 'integration');
|
|
538
660
|
}
|
|
539
661
|
|
|
@@ -542,9 +664,19 @@
|
|
|
542
664
|
showToast('Select templates which will be pushed to Crowdin');
|
|
543
665
|
return;
|
|
544
666
|
}
|
|
545
|
-
appComponent.setAttribute('is-crowdin-loading', true);
|
|
546
|
-
const syncedFiles = await appComponent.getCrowdinScheduleSync();
|
|
547
667
|
|
|
668
|
+
{{#if syncNewElements.crowdin}}
|
|
669
|
+
syncData = e.detail;
|
|
670
|
+
const isFolder = await hasFolder(e.detail);
|
|
671
|
+
if (isFolder) {
|
|
672
|
+
openScheduleModal('crowdin');
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
appComponent.setCrowdinScheduleSync(e.detail);
|
|
677
|
+
{{/if}}
|
|
678
|
+
const syncedFiles = await appComponent.getCrowdinScheduleSync();
|
|
679
|
+
appComponent.setAttribute('is-crowdin-loading', true);
|
|
548
680
|
updateSyncSettings(syncedFiles, 'schedule', 'crowdin');
|
|
549
681
|
}
|
|
550
682
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crowdin/app-project-module",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0",
|
|
4
4
|
"description": "Module that generates for you all common endpoints for serving standalone Crowdin App",
|
|
5
5
|
"main": "out/index.js",
|
|
6
6
|
"types": "out/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc -p ./ && cp -R views out && cp -R static out && cp logo.png out && rollup -c rollup.config.mjs",
|
|
9
|
+
"build-main": "tsc -p ./ && cp -R views out && cp -R static out && cp logo.png out",
|
|
9
10
|
"lint": "eslint --fix \"{src,tests}/**/*.{js,ts}\"",
|
|
10
11
|
"prettier": "prettier --config .prettierrc src/**/*.ts --write",
|
|
11
12
|
"lint-ci": "eslint \"{src,tests}/**/*.{js,ts}\"",
|
|
@@ -22,7 +23,9 @@
|
|
|
22
23
|
"mysql2": "^2.3.3",
|
|
23
24
|
"node-cron": "^3.0.2",
|
|
24
25
|
"pg": "^8.10.0",
|
|
26
|
+
"redoc-express": "^2.1.0",
|
|
25
27
|
"sqlite3": "^5.1.6",
|
|
28
|
+
"swagger-jsdoc": "^6.2.8",
|
|
26
29
|
"uuid": "^8.3.2"
|
|
27
30
|
},
|
|
28
31
|
"devDependencies": {
|
|
@@ -48,6 +51,7 @@
|
|
|
48
51
|
"@types/jest": "^29.5.2",
|
|
49
52
|
"@types/node": "^12.20.55",
|
|
50
53
|
"@types/node-cron": "^3.0.7",
|
|
54
|
+
"@types/swagger-jsdoc": "^6.0.1",
|
|
51
55
|
"@typescript-eslint/eslint-plugin": "^2.3.1",
|
|
52
56
|
"@typescript-eslint/parser": "^2.3.1",
|
|
53
57
|
"eslint": "^6.4.0",
|