@crowdin/app-project-module 0.35.1 → 0.36.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/file-processing/pre-post-process.js +4 -0
- package/out/handlers/integration/crowdin-webhook.js +77 -14
- package/out/handlers/integration/integration-webhook.js +2 -6
- package/out/handlers/integration/settings-save.js +7 -5
- package/out/models/index.d.ts +37 -11
- package/out/models/index.js +6 -7
- package/out/static/js/form.js +13 -13
- package/out/storage/index.d.ts +5 -1
- package/out/storage/mysql.d.ts +5 -1
- package/out/storage/mysql.js +44 -0
- package/out/storage/postgre.d.ts +5 -1
- package/out/storage/postgre.js +45 -0
- package/out/storage/sqlite.d.ts +5 -1
- package/out/storage/sqlite.js +38 -0
- package/out/util/api/components.d.ts +1 -1
- package/out/util/api/components.js +1 -1
- package/out/util/cron.js +24 -7
- package/out/util/defaults.js +31 -61
- package/out/util/logger.d.ts +1 -1
- package/out/util/logger.js +5 -5
- package/out/util/webhooks.d.ts +6 -7
- package/out/util/webhooks.js +38 -57
- package/out/views/main.handlebars +2 -1
- package/package.json +11 -11
|
@@ -52,6 +52,10 @@ function handle(baseConfig, config, folderName) {
|
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
const fileProcessResult = yield config.fileProcess(body, fileContent, req.crowdinApiClient, req.crowdinContext, req.crowdinContext.jwtPayload.context.project_id);
|
|
55
|
+
if (fileProcessResult.notModified) {
|
|
56
|
+
res.sendStatus(304);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
55
59
|
switch (body.jobType) {
|
|
56
60
|
case models_1.ProcessFileJobType.PRE_IMPORT:
|
|
57
61
|
case models_1.ProcessFileJobType.POST_EXPORT:
|
|
@@ -9,12 +9,61 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const models_1 = require("../../models");
|
|
13
12
|
const storage_1 = require("../../storage");
|
|
13
|
+
const logger_1 = require("../../util/logger");
|
|
14
14
|
const util_1 = require("../../util");
|
|
15
15
|
const cron_1 = require("../../util/cron");
|
|
16
|
-
const file_snapshot_1 = require("../../util/file-snapshot");
|
|
17
16
|
const webhooks_1 = require("../../util/webhooks");
|
|
17
|
+
const models_1 = require("../../models");
|
|
18
|
+
function filterSyncFiles(args) {
|
|
19
|
+
var _a, _b;
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
const { projectId, crowdinClient, events, syncFileSettings, appSettings } = args;
|
|
22
|
+
const files = {};
|
|
23
|
+
let projectData;
|
|
24
|
+
const addFileToResponse = (fileId, languages) => {
|
|
25
|
+
if (files[fileId]) {
|
|
26
|
+
files[fileId] = [...new Set([...files[fileId], ...languages])];
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
files[fileId] = languages;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
for (const event of events) {
|
|
33
|
+
const fileId = event.fileId;
|
|
34
|
+
const language = event.language;
|
|
35
|
+
// sync all new files
|
|
36
|
+
if (event.event === webhooks_1.HookEvents.fileAdded && appSettings['new-crowdin-files']) {
|
|
37
|
+
if (!projectData) {
|
|
38
|
+
projectData = yield crowdinClient.projectsGroupsApi.getProject(projectId);
|
|
39
|
+
}
|
|
40
|
+
addFileToResponse(fileId, projectData.data.targetLanguageIds);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
// sync file that was selected for sync schedule
|
|
44
|
+
if (syncFileSettings[fileId]) {
|
|
45
|
+
if (!syncFileSettings[fileId].includes(language)) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
addFileToResponse(fileId, [language]);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
try {
|
|
52
|
+
const crowdinFile = yield crowdinClient.sourceFilesApi.getFile(projectId, fileId);
|
|
53
|
+
// sync file that in selected for sync schedule directory
|
|
54
|
+
if (syncFileSettings[(_a = crowdinFile === null || crowdinFile === void 0 ? void 0 : crowdinFile.data) === null || _a === void 0 ? void 0 : _a.directoryId] &&
|
|
55
|
+
syncFileSettings[(_b = crowdinFile === null || crowdinFile === void 0 ? void 0 : crowdinFile.data) === null || _b === void 0 ? void 0 : _b.directoryId].includes(language)) {
|
|
56
|
+
addFileToResponse(fileId, [language]);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
(0, logger_1.logError)(e);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return files;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
18
67
|
function handle(config, integration) {
|
|
19
68
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
20
69
|
var _a, _b;
|
|
@@ -22,31 +71,45 @@ function handle(config, integration) {
|
|
|
22
71
|
const webhookUrlParam = req.query[urlParam];
|
|
23
72
|
let filesToSync;
|
|
24
73
|
if (webhookUrlParam) {
|
|
25
|
-
const { projectId, crowdinClient,
|
|
74
|
+
const { projectId, crowdinClient, rootFolder, appSettings, syncSettings } = yield (0, webhooks_1.prepareWebhookData)(config, integration, webhookUrlParam, models_1.Provider.CROWDIN);
|
|
26
75
|
if (!crowdinClient) {
|
|
27
76
|
return res.status(403).send({ error: 'Access denied' });
|
|
28
77
|
}
|
|
29
78
|
if (!syncSettings) {
|
|
30
79
|
return res.status(200).send({ message: 'Sync is not configured' });
|
|
31
80
|
}
|
|
81
|
+
const syncFileSettings = JSON.parse(syncSettings.files);
|
|
32
82
|
if ((_b = integration.webhooks) === null || _b === void 0 ? void 0 : _b.crowdinWebhookInterceptor) {
|
|
33
83
|
filesToSync = yield integration.webhooks.crowdinWebhookInterceptor(projectId, crowdinClient.client, rootFolder, appSettings, syncSettings, req.body);
|
|
34
84
|
}
|
|
35
85
|
else {
|
|
36
|
-
filesToSync =
|
|
86
|
+
filesToSync = yield filterSyncFiles({
|
|
87
|
+
projectId,
|
|
88
|
+
crowdinClient: crowdinClient.client,
|
|
89
|
+
events: req.body.events,
|
|
90
|
+
syncFileSettings,
|
|
91
|
+
appSettings,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
for (const eventPayload of req.body.events) {
|
|
95
|
+
if (eventPayload.event === webhooks_1.HookEvents.fileDeleted) {
|
|
96
|
+
yield (0, storage_1.getStorage)().deleteWebhooks([eventPayload.fileId], syncSettings.integrationId, syncSettings.crowdinId, syncSettings.provider);
|
|
97
|
+
delete filesToSync[eventPayload.fileId];
|
|
98
|
+
delete syncFileSettings[eventPayload.fileId];
|
|
99
|
+
}
|
|
37
100
|
}
|
|
38
|
-
const crowdinFiles = yield (0, cron_1.skipFoldersFromIntegrationRequest)(config, integration, projectId,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
101
|
+
const crowdinFiles = yield (0, cron_1.skipFoldersFromIntegrationRequest)(config, integration, projectId, filesToSync, crowdinClient.client);
|
|
102
|
+
for (const fileId in crowdinFiles) {
|
|
103
|
+
const webhook = yield (0, storage_1.getStorage)().getWebhooks(fileId, syncSettings.integrationId, syncSettings.crowdinId, syncSettings.provider);
|
|
104
|
+
if (!webhook) {
|
|
105
|
+
yield (0, storage_1.getStorage)().saveWebhooks(fileId, syncSettings.integrationId, syncSettings.crowdinId, syncSettings.provider);
|
|
106
|
+
}
|
|
44
107
|
}
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
|
|
108
|
+
const newFileIds = Object.keys(crowdinFiles).filter((fileId) => !syncFileSettings[fileId]);
|
|
109
|
+
if (newFileIds.length) {
|
|
110
|
+
yield (0, storage_1.getStorage)().updateSyncSettings(JSON.stringify(Object.assign(Object.assign({}, syncFileSettings), crowdinFiles)), syncSettings.integrationId, syncSettings.crowdinId, 'schedule', syncSettings.provider);
|
|
48
111
|
}
|
|
49
|
-
res.send({
|
|
112
|
+
res.send({});
|
|
50
113
|
}
|
|
51
114
|
}));
|
|
52
115
|
}
|
|
@@ -25,12 +25,8 @@ function handle(config, integration) {
|
|
|
25
25
|
if (!webhookData.syncSettings) {
|
|
26
26
|
return res.status(200).send({ message: 'Sync is not configured' });
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if ((0, util_1.isExtendedResultType)(result)) {
|
|
31
|
-
message = result.message;
|
|
32
|
-
}
|
|
33
|
-
res.send({ message });
|
|
28
|
+
yield (0, webhooks_1.updateCrowdinFromWebhookRequest)({ integration, webhookData, req });
|
|
29
|
+
res.send({});
|
|
34
30
|
}
|
|
35
31
|
else {
|
|
36
32
|
return res.status(403).send({ error: 'Access denied' });
|
|
@@ -23,11 +23,13 @@ function handle(config, integration) {
|
|
|
23
23
|
if (integration.webhooks) {
|
|
24
24
|
yield (0, webhooks_1.registerWebhooks)(config, integration, req.crowdinApiClient, req.crowdinContext, req.integrationCredentials, appSettings);
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
else {
|
|
27
|
+
if (appSettings['new-crowdin-files']) {
|
|
28
|
+
(0, file_snapshot_1.createOrUpdateFileSnapshot)(config, integration, req, models_1.Provider.CROWDIN);
|
|
29
|
+
}
|
|
30
|
+
if (appSettings['new-integration-files']) {
|
|
31
|
+
(0, file_snapshot_1.createOrUpdateFileSnapshot)(config, integration, req, models_1.Provider.INTEGRATION);
|
|
32
|
+
}
|
|
31
33
|
}
|
|
32
34
|
if (integration.syncNewElements) {
|
|
33
35
|
yield (0, cron_1.createOrUpdateSyncSettings)(config, req, {}, models_1.Provider.CROWDIN, true);
|
package/out/models/index.d.ts
CHANGED
|
@@ -618,16 +618,16 @@ export interface CustomFileFormatLogic extends FileProcessLogic {
|
|
|
618
618
|
export type FileImportExportLogic = FilePreImportLogic | FilePostImportLogic | FilePreExportLogic | FilePostExportLogic;
|
|
619
619
|
export type FileImportExportContent = ProcessFileString[] | Buffer | undefined;
|
|
620
620
|
export interface FilePreImportLogic extends FileProcessLogic {
|
|
621
|
-
fileProcess: (req: ProcessFileRequest, content: FileImportExportContent, client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<
|
|
621
|
+
fileProcess: (req: ProcessFileRequest, content: FileImportExportContent, client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<ContentFileResponse>;
|
|
622
622
|
}
|
|
623
623
|
export interface FilePostImportLogic extends FileProcessLogic {
|
|
624
|
-
fileProcess: (req: ProcessFileRequest, content: FileImportExportContent, client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<
|
|
624
|
+
fileProcess: (req: ProcessFileRequest, content: FileImportExportContent, client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<StringsFileResponse>;
|
|
625
625
|
}
|
|
626
626
|
export interface FilePreExportLogic extends FileProcessLogic {
|
|
627
|
-
fileProcess: (req: ProcessFileRequest, content: FileImportExportContent, client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<
|
|
627
|
+
fileProcess: (req: ProcessFileRequest, content: FileImportExportContent, client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<StringsFileResponse>;
|
|
628
628
|
}
|
|
629
629
|
export interface FilePostExportLogic extends FileProcessLogic {
|
|
630
|
-
fileProcess: (req: ProcessFileRequest, content: FileImportExportContent, client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<
|
|
630
|
+
fileProcess: (req: ProcessFileRequest, content: FileImportExportContent, client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<ContentFileResponse>;
|
|
631
631
|
}
|
|
632
632
|
export interface SignaturePatterns {
|
|
633
633
|
fileName?: string;
|
|
@@ -668,6 +668,12 @@ export interface BuildFileResponse {
|
|
|
668
668
|
fileName?: string;
|
|
669
669
|
fileType?: string;
|
|
670
670
|
}
|
|
671
|
+
export interface StringsFileResponse extends Omit<ParseFileResponse, 'previewFile'> {
|
|
672
|
+
notModified?: boolean;
|
|
673
|
+
}
|
|
674
|
+
export interface ContentFileResponse extends BuildFileResponse {
|
|
675
|
+
notModified?: boolean;
|
|
676
|
+
}
|
|
671
677
|
export interface ProcessFileString {
|
|
672
678
|
previewId?: number;
|
|
673
679
|
id: number;
|
|
@@ -827,6 +833,13 @@ export interface IntegrationFilesSnapshot {
|
|
|
827
833
|
crowdinId: string;
|
|
828
834
|
provider: Provider;
|
|
829
835
|
}
|
|
836
|
+
export interface IntegrationWebhooks {
|
|
837
|
+
id: number;
|
|
838
|
+
fileId: number;
|
|
839
|
+
integrationId: string;
|
|
840
|
+
crowdinId: string;
|
|
841
|
+
provider: Provider;
|
|
842
|
+
}
|
|
830
843
|
export interface ImagePath {
|
|
831
844
|
/**
|
|
832
845
|
* path to app logo (e.g. {@example join(__dirname, 'logo.png')})
|
|
@@ -869,10 +882,10 @@ export interface Webhooks {
|
|
|
869
882
|
crowdinWebhookUrl?: string;
|
|
870
883
|
integrationWebhookUrl?: string;
|
|
871
884
|
urlParam?: string;
|
|
872
|
-
crowdinWebhooks?: (client: Crowdin, projectId: number, available: boolean, config?:
|
|
873
|
-
integrationWebhooks?: (apiCredentials: any, urlParam: string, available: boolean, config?:
|
|
885
|
+
crowdinWebhooks?: (client: Crowdin, projectId: number, available: boolean, config?: AppSettings) => Promise<void>;
|
|
886
|
+
integrationWebhooks?: (apiCredentials: any, urlParam: string, available: boolean, config?: AppSettings, syncSettings?: any) => Promise<void>;
|
|
874
887
|
crowdinWebhookInterceptor?: (projectId: number, client: Crowdin, appRootFolder?: SourceFilesModel.Directory, config?: any, syncSettings?: any, webhookRequest?: any) => Promise<UpdateIntegrationRequest>;
|
|
875
|
-
integrationWebhookInterceptor?: (projectId: number, client: Crowdin, apiCredentials: any, appRootFolder?: SourceFilesModel.Directory, config?:
|
|
888
|
+
integrationWebhookInterceptor?: (projectId: number, client: Crowdin, apiCredentials: any, appRootFolder?: SourceFilesModel.Directory, config?: AppSettings, syncSettings?: any, webhookRequest?: any) => Promise<IntegrationFile[]>;
|
|
876
889
|
queueUrl: string;
|
|
877
890
|
}
|
|
878
891
|
export declare enum SyncCondition {
|
|
@@ -880,10 +893,9 @@ export declare enum SyncCondition {
|
|
|
880
893
|
TRANSLATED = 1,
|
|
881
894
|
APPROVED = 2
|
|
882
895
|
}
|
|
883
|
-
export declare enum
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
WEBHOOKS = 2
|
|
896
|
+
export declare enum SyncSchedule {
|
|
897
|
+
DISABLED = 0,
|
|
898
|
+
ACTIVE
|
|
887
899
|
}
|
|
888
900
|
export type Payload = {
|
|
889
901
|
event: string;
|
|
@@ -912,6 +924,20 @@ export interface UpdateCrowdinWebhookPayloadsArgs {
|
|
|
912
924
|
webhookData: any;
|
|
913
925
|
req: Request;
|
|
914
926
|
}
|
|
927
|
+
export interface FilterSyncFilesArgs {
|
|
928
|
+
projectId: number;
|
|
929
|
+
crowdinClient: Crowdin;
|
|
930
|
+
events: Payload[];
|
|
931
|
+
syncFileSettings: UpdateIntegrationRequest;
|
|
932
|
+
appSettings: AppSettings;
|
|
933
|
+
}
|
|
934
|
+
export interface AppSettings {
|
|
935
|
+
schedule?: number;
|
|
936
|
+
condition?: number;
|
|
937
|
+
'new-crowdin-files'?: boolean;
|
|
938
|
+
'new-integration-files'?: boolean;
|
|
939
|
+
[key: string]: any;
|
|
940
|
+
}
|
|
915
941
|
export declare enum UserPermissions {
|
|
916
942
|
OWNER = "owner",
|
|
917
943
|
MANAGERS = "managers",
|
package/out/models/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ProjectPermissions = exports.UserPermissions = exports.
|
|
3
|
+
exports.ProjectPermissions = exports.UserPermissions = exports.SyncSchedule = exports.SyncCondition = exports.RequestMethods = exports.Provider = exports.ContextOptionsTypes = exports.ContextOptionsLocations = exports.EditorPanelsMode = exports.ProcessFileJobType = exports.SubscriptionInfoType = exports.AccountType = exports.Scope = exports.AuthenticationType = void 0;
|
|
4
4
|
var AuthenticationType;
|
|
5
5
|
(function (AuthenticationType) {
|
|
6
6
|
AuthenticationType["CODE"] = "authorization_code";
|
|
@@ -85,12 +85,11 @@ var SyncCondition;
|
|
|
85
85
|
SyncCondition[SyncCondition["TRANSLATED"] = 1] = "TRANSLATED";
|
|
86
86
|
SyncCondition[SyncCondition["APPROVED"] = 2] = "APPROVED";
|
|
87
87
|
})(SyncCondition = exports.SyncCondition || (exports.SyncCondition = {}));
|
|
88
|
-
var
|
|
89
|
-
(function (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
})(SyncType = exports.SyncType || (exports.SyncType = {}));
|
|
88
|
+
var SyncSchedule;
|
|
89
|
+
(function (SyncSchedule) {
|
|
90
|
+
SyncSchedule[SyncSchedule["DISABLED"] = 0] = "DISABLED";
|
|
91
|
+
SyncSchedule[SyncSchedule["ACTIVE"] = 1 || 3 || 6 || 12 || 24] = "ACTIVE";
|
|
92
|
+
})(SyncSchedule = exports.SyncSchedule || (exports.SyncSchedule = {}));
|
|
94
93
|
var UserPermissions;
|
|
95
94
|
(function (UserPermissions) {
|
|
96
95
|
UserPermissions["OWNER"] = "owner";
|