@crowdin/app-project-module 0.27.0 → 0.28.0-10
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/CONTRIBUTING.md +19 -1
- package/README.md +1 -877
- package/out/handlers/crowdin-update.js +4 -3
- package/out/handlers/crowdin-webhook.d.ts +4 -0
- package/out/handlers/crowdin-webhook.js +43 -0
- package/out/handlers/form-data-display.d.ts +3 -0
- package/out/handlers/form-data-display.js +46 -0
- package/out/handlers/form-data-save.d.ts +3 -0
- package/out/handlers/form-data-save.js +56 -0
- package/out/handlers/integration-logout.js +4 -0
- package/out/handlers/integration-webhook.d.ts +4 -0
- package/out/handlers/integration-webhook.js +39 -0
- package/out/handlers/main.js +7 -1
- package/out/handlers/settings-save.d.ts +2 -2
- package/out/handlers/settings-save.js +8 -3
- package/out/handlers/uninstall.js +4 -0
- package/out/index.js +49 -9
- package/out/middlewares/render-ui-module.d.ts +4 -0
- package/out/middlewares/render-ui-module.js +33 -0
- package/out/models/index.d.ts +72 -6
- package/out/models/index.js +13 -1
- package/out/static/css/styles.css +96 -0
- package/out/static/js/dependent.js +307 -0
- package/out/static/js/form.js +115 -0
- package/out/static/js/main.js +11 -1
- package/out/util/cron.js +9 -10
- package/out/util/defaults.js +49 -12
- package/out/util/index.js +5 -1
- package/out/util/webhooks.d.ts +29 -0
- package/out/util/webhooks.js +308 -0
- package/out/views/form.handlebars +29 -0
- package/out/views/login.handlebars +84 -16
- package/out/views/main.handlebars +171 -88
- package/out/views/partials/head.handlebars +5 -4
- package/package.json +37 -23
|
@@ -14,12 +14,13 @@ const defaults_1 = require("../util/defaults");
|
|
|
14
14
|
function handle(config, integration) {
|
|
15
15
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
16
|
const projectId = req.crowdinContext.jwtPayload.context.project_id;
|
|
17
|
-
|
|
17
|
+
const uploadTranslations = req.query.uploadTranslations === 'true';
|
|
18
|
+
(0, util_1.log)(`Updating crowdin project ${projectId}`, config.logger);
|
|
18
19
|
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, req.crowdinApiClient, projectId);
|
|
19
20
|
if (rootFolder) {
|
|
20
|
-
(0, util_1.log)(`
|
|
21
|
+
(0, util_1.log)(`Updating crowdin files under folder ${rootFolder.id}`, config.logger);
|
|
21
22
|
}
|
|
22
|
-
const result = yield integration.updateCrowdin(projectId, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings);
|
|
23
|
+
const result = yield integration.updateCrowdin(projectId, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings, uploadTranslations);
|
|
23
24
|
let message;
|
|
24
25
|
if ((0, util_1.isExtendedResultType)(result)) {
|
|
25
26
|
message = result.message;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/// <reference types="qs" />
|
|
2
|
+
import { Config, IntegrationLogic } from '../models';
|
|
3
|
+
import { Request, Response } from 'express';
|
|
4
|
+
export default function handle(config: Config, integration: IntegrationLogic): (req: Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
const util_1 = require("../util");
|
|
13
|
+
const webhooks_1 = require("../util/webhooks");
|
|
14
|
+
function handle(config, integration) {
|
|
15
|
+
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
var _a, _b;
|
|
17
|
+
const urlParam = (_a = integration.webhooks) === null || _a === void 0 ? void 0 : _a.urlParam;
|
|
18
|
+
const webhookUrlParam = req.query[urlParam];
|
|
19
|
+
let filesToSync;
|
|
20
|
+
if (webhookUrlParam) {
|
|
21
|
+
const { projectId, crowdinClient, preparedIntegrationCredentials, rootFolder, appSettings, syncSettings } = yield (0, webhooks_1.prepareWebhookData)(config, integration, webhookUrlParam, 'crowdin');
|
|
22
|
+
if (!crowdinClient) {
|
|
23
|
+
return res.status(403).send({ error: 'Access denied' });
|
|
24
|
+
}
|
|
25
|
+
if (!syncSettings) {
|
|
26
|
+
return res.status(200).send({ message: 'Sync is not configured' });
|
|
27
|
+
}
|
|
28
|
+
if ((_b = integration.webhooks) === null || _b === void 0 ? void 0 : _b.crowdinWebhookInterceptor) {
|
|
29
|
+
filesToSync = yield integration.webhooks.crowdinWebhookInterceptor(projectId, crowdinClient.client, rootFolder, appSettings, syncSettings, req.body);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
filesToSync = (0, webhooks_1.filterSyncFiles)(req.body.events, JSON.parse(syncSettings.files));
|
|
33
|
+
}
|
|
34
|
+
const result = yield integration.updateIntegration(projectId, crowdinClient.client, preparedIntegrationCredentials, filesToSync, rootFolder, appSettings);
|
|
35
|
+
let message;
|
|
36
|
+
if ((0, util_1.isExtendedResultType)(result)) {
|
|
37
|
+
message = result.message;
|
|
38
|
+
}
|
|
39
|
+
res.send({ message });
|
|
40
|
+
}
|
|
41
|
+
}), config.onError);
|
|
42
|
+
}
|
|
43
|
+
exports.default = handle;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/// <reference types="qs" />
|
|
2
|
+
import { Response } from 'express';
|
|
3
|
+
export default function handle(): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
};
|
|
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
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
const util_1 = require("../util");
|
|
36
|
+
const storage = __importStar(require("../storage"));
|
|
37
|
+
function handle() {
|
|
38
|
+
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
const id = req.query.id;
|
|
40
|
+
const data = (yield storage.getStorage().getMetadata(id)) || {};
|
|
41
|
+
return res.send({
|
|
42
|
+
formData: data,
|
|
43
|
+
});
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
exports.default = handle;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/// <reference types="qs" />
|
|
2
|
+
import { Response } from 'express';
|
|
3
|
+
export default function handle(): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
|
|
@@ -0,0 +1,56 @@
|
|
|
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
|
+
};
|
|
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
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
const util_1 = require("../util");
|
|
36
|
+
const storage = __importStar(require("../storage"));
|
|
37
|
+
function handle() {
|
|
38
|
+
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
const id = req.query.id;
|
|
40
|
+
const metadata = req.body.data;
|
|
41
|
+
const existing = yield storage.getStorage().getMetadata(id);
|
|
42
|
+
try {
|
|
43
|
+
if (!!existing) {
|
|
44
|
+
yield storage.getStorage().updateMetadata(id, metadata);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
yield storage.getStorage().saveMetadata(id, metadata);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
res.status(500).end();
|
|
52
|
+
}
|
|
53
|
+
res.status(204).end();
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
exports.default = handle;
|
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
const storage_1 = require("../storage");
|
|
13
13
|
const util_1 = require("../util");
|
|
14
14
|
const connection_1 = require("../util/connection");
|
|
15
|
+
const webhooks_1 = require("../util/webhooks");
|
|
15
16
|
function handle(config, integration) {
|
|
16
17
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
17
18
|
(0, util_1.log)('Received integration logout request', config.logger);
|
|
@@ -22,6 +23,9 @@ function handle(config, integration) {
|
|
|
22
23
|
(0, util_1.log)(`Deleting integration credentials for ${req.crowdinContext.clientId} client`, config.logger);
|
|
23
24
|
yield (0, storage_1.getStorage)().deleteIntegrationCredentials(req.crowdinContext.clientId);
|
|
24
25
|
(0, connection_1.clearCache)(req.crowdinContext.crowdinId);
|
|
26
|
+
if (integration.webhooks) {
|
|
27
|
+
yield (0, webhooks_1.unregisterWebhooks)(config, integration, req.crowdinApiClient, req.crowdinContext, req.integrationCredentials, req.integrationSettings);
|
|
28
|
+
}
|
|
25
29
|
res.status(204).end();
|
|
26
30
|
}), config.onError);
|
|
27
31
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/// <reference types="qs" />
|
|
2
|
+
import { Config, IntegrationLogic } from '../models';
|
|
3
|
+
import { Request, Response } from 'express';
|
|
4
|
+
export default function handle(config: Config, integration: IntegrationLogic): (req: Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
|
|
@@ -0,0 +1,39 @@
|
|
|
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
|
+
const util_1 = require("../util");
|
|
13
|
+
const webhooks_1 = require("../util/webhooks");
|
|
14
|
+
function handle(config, integration) {
|
|
15
|
+
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
var _a, _b;
|
|
17
|
+
const urlParam = (_a = integration.webhooks) === null || _a === void 0 ? void 0 : _a.urlParam;
|
|
18
|
+
const webhookUrlParam = req.query[urlParam];
|
|
19
|
+
if (((_b = integration.webhooks) === null || _b === void 0 ? void 0 : _b.integrationWebhookInterceptor) && webhookUrlParam) {
|
|
20
|
+
const webhookData = yield (0, webhooks_1.prepareWebhookData)(config, integration, webhookUrlParam, 'integration');
|
|
21
|
+
if (!webhookData.crowdinClient) {
|
|
22
|
+
return res.status(403).send({ error: 'Access denied' });
|
|
23
|
+
}
|
|
24
|
+
if (!webhookData.syncSettings) {
|
|
25
|
+
return res.status(200).send({ message: 'Sync is not configured' });
|
|
26
|
+
}
|
|
27
|
+
const result = yield (0, webhooks_1.updateCrowdinFromWebhookRequest)(integration, webhookData, req);
|
|
28
|
+
let message;
|
|
29
|
+
if ((0, util_1.isExtendedResultType)(result)) {
|
|
30
|
+
message = result.message;
|
|
31
|
+
}
|
|
32
|
+
res.send({ message });
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
return res.status(403).send({ error: 'Access denied' });
|
|
36
|
+
}
|
|
37
|
+
}), config.onError);
|
|
38
|
+
}
|
|
39
|
+
exports.default = handle;
|
package/out/handlers/main.js
CHANGED
|
@@ -45,10 +45,16 @@ function handle(config, integration) {
|
|
|
45
45
|
}
|
|
46
46
|
options.infoModal = integration.infoModal;
|
|
47
47
|
options.withCronSync = integration.withCronSync;
|
|
48
|
-
options.
|
|
48
|
+
options.webhooks = integration.webhooks
|
|
49
|
+
? {
|
|
50
|
+
crowdin: true,
|
|
51
|
+
integration: !!integration.webhooks.integrationWebhookInterceptor,
|
|
52
|
+
}
|
|
53
|
+
: {};
|
|
49
54
|
options.integrationOneLevelFetching = integration.integrationOneLevelFetching;
|
|
50
55
|
options.integrationSearchListener = integration.integrationSearchListener;
|
|
51
56
|
options.checkSubscription = !(0, connection_1.isAppFree)(config);
|
|
57
|
+
options.uploadTranslations = integration.uploadTranslations;
|
|
52
58
|
(0, util_1.log)(`Routing user to ${view} view`, config.logger);
|
|
53
59
|
return res.render(view, options);
|
|
54
60
|
}), config.onError);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/// <reference types="qs" />
|
|
2
2
|
import { Response } from 'express';
|
|
3
|
-
import { Config } from '../models';
|
|
4
|
-
export default function handle(config: Config): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
|
|
3
|
+
import { Config, IntegrationLogic } from '../models';
|
|
4
|
+
export default function handle(config: Config, integration: IntegrationLogic): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
|
|
@@ -11,10 +11,15 @@ 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
|
-
|
|
14
|
+
const webhooks_1 = require("../util/webhooks");
|
|
15
|
+
function handle(config, integration) {
|
|
15
16
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
const appSettings = req.body.config;
|
|
18
|
+
(0, util_1.log)(`Saving settings ${JSON.stringify(appSettings, null, 2)}`, config.logger);
|
|
19
|
+
yield (0, storage_1.getStorage)().updateIntegrationConfig(req.crowdinContext.clientId, JSON.stringify(appSettings));
|
|
20
|
+
if (integration.webhooks) {
|
|
21
|
+
yield (0, webhooks_1.registerWebhooks)(config, integration, req.crowdinApiClient, req.crowdinContext, req.integrationCredentials, appSettings);
|
|
22
|
+
}
|
|
18
23
|
res.status(204).end();
|
|
19
24
|
}), config.onError);
|
|
20
25
|
}
|
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
const storage_1 = require("../storage");
|
|
13
13
|
const util_1 = require("../util");
|
|
14
14
|
const connection_1 = require("../util/connection");
|
|
15
|
+
const webhooks_1 = require("../util/webhooks");
|
|
15
16
|
function handle(config) {
|
|
16
17
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
17
18
|
const event = req.body;
|
|
@@ -35,6 +36,9 @@ function handle(config) {
|
|
|
35
36
|
yield config.onUninstall(organization, allCredentials);
|
|
36
37
|
}
|
|
37
38
|
if (projectIntegration) {
|
|
39
|
+
if (projectIntegration.webhooks) {
|
|
40
|
+
yield (0, webhooks_1.unregisterAllCrowdinWebhooks)(config, projectIntegration, organization);
|
|
41
|
+
}
|
|
38
42
|
(0, util_1.log)(`Deleting all integration credentials for ${organization} organization`, config.logger);
|
|
39
43
|
yield (0, storage_1.getStorage)().deleteAllIntegrationCredentials(organization);
|
|
40
44
|
}
|
package/out/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -40,6 +44,8 @@ const crowdin_file_progress_1 = __importDefault(require("./handlers/crowdin-file
|
|
|
40
44
|
const crowdin_files_1 = __importDefault(require("./handlers/crowdin-files"));
|
|
41
45
|
const crowdin_project_1 = __importDefault(require("./handlers/crowdin-project"));
|
|
42
46
|
const crowdin_update_1 = __importDefault(require("./handlers/crowdin-update"));
|
|
47
|
+
const crowdin_webhook_1 = __importDefault(require("./handlers/crowdin-webhook"));
|
|
48
|
+
const integration_webhook_1 = __importDefault(require("./handlers/integration-webhook"));
|
|
43
49
|
const download_1 = __importDefault(require("./handlers/custom-file-format/download"));
|
|
44
50
|
const process_1 = __importDefault(require("./handlers/custom-file-format/process"));
|
|
45
51
|
const translate_1 = __importDefault(require("./handlers/custom-mt/translate"));
|
|
@@ -53,6 +59,8 @@ const manifest_1 = __importDefault(require("./handlers/manifest"));
|
|
|
53
59
|
const oauth_login_1 = __importDefault(require("./handlers/oauth-login"));
|
|
54
60
|
const oauth_url_1 = __importDefault(require("./handlers/oauth-url"));
|
|
55
61
|
const settings_save_1 = __importDefault(require("./handlers/settings-save"));
|
|
62
|
+
const form_data_display_1 = __importDefault(require("./handlers/form-data-display"));
|
|
63
|
+
const form_data_save_1 = __importDefault(require("./handlers/form-data-save"));
|
|
56
64
|
const subscription_info_1 = __importDefault(require("./handlers/subscription-info"));
|
|
57
65
|
const subscription_paid_1 = __importDefault(require("./handlers/subscription-paid"));
|
|
58
66
|
const sync_settings_1 = __importDefault(require("./handlers/sync-settings"));
|
|
@@ -62,14 +70,17 @@ const crowdin_client_1 = __importStar(require("./middlewares/crowdin-client"));
|
|
|
62
70
|
const integration_credentials_1 = __importDefault(require("./middlewares/integration-credentials"));
|
|
63
71
|
const json_response_1 = __importDefault(require("./middlewares/json-response"));
|
|
64
72
|
const ui_module_1 = __importDefault(require("./middlewares/ui-module"));
|
|
73
|
+
const render_ui_module_1 = __importDefault(require("./middlewares/render-ui-module"));
|
|
65
74
|
const storage = __importStar(require("./storage"));
|
|
66
75
|
const util_1 = require("./util");
|
|
67
76
|
const connection_1 = require("./util/connection");
|
|
68
77
|
const cron_1 = require("./util/cron");
|
|
69
78
|
const defaults_1 = require("./util/defaults");
|
|
79
|
+
const webhooks_1 = require("./util/webhooks");
|
|
70
80
|
var models_1 = require("./models");
|
|
71
81
|
Object.defineProperty(exports, "Scope", { enumerable: true, get: function () { return models_1.Scope; } });
|
|
72
82
|
function addCrowdinEndpoints(app, plainConfig) {
|
|
83
|
+
var _a, _b, _c;
|
|
73
84
|
if (!plainConfig.disableGlobalErrorHandling) {
|
|
74
85
|
handleUncaughtErrors(plainConfig);
|
|
75
86
|
}
|
|
@@ -94,6 +105,15 @@ function addCrowdinEndpoints(app, plainConfig) {
|
|
|
94
105
|
}
|
|
95
106
|
return options.inverse(this);
|
|
96
107
|
},
|
|
108
|
+
in: function (a, b, options) {
|
|
109
|
+
if (a.includes(b)) {
|
|
110
|
+
return options.fn(this);
|
|
111
|
+
}
|
|
112
|
+
return options.inverse(this);
|
|
113
|
+
},
|
|
114
|
+
or: function (a, b, options) {
|
|
115
|
+
return a || b ? options.fn(this) : options.inverse(this);
|
|
116
|
+
},
|
|
97
117
|
},
|
|
98
118
|
}));
|
|
99
119
|
app.set('view engine', 'handlebars');
|
|
@@ -110,7 +130,7 @@ function addCrowdinEndpoints(app, plainConfig) {
|
|
|
110
130
|
app.get('/logo/integration/logo.png', (req, res) => res.sendFile(integrationLogic.imagePath || config.imagePath || (0, path_1.join)(__dirname, 'logo.png')));
|
|
111
131
|
app.get('/', (0, crowdin_client_1.default)(config, true, false), (0, integration_credentials_1.default)(config, integrationLogic, true), (0, main_1.default)(config, integrationLogic));
|
|
112
132
|
app.get('/api/subscription-info', json_response_1.default, (0, crowdin_client_1.default)(config), (0, subscription_info_1.default)(config));
|
|
113
|
-
app.post('/api/settings', (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, settings_save_1.default)(config));
|
|
133
|
+
app.post('/api/settings', (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, settings_save_1.default)(config, integrationLogic));
|
|
114
134
|
app.post('/api/login', (0, crowdin_client_1.default)(config, false, false), (0, integration_login_1.default)(config, integrationLogic));
|
|
115
135
|
app.post('/api/logout', (0, crowdin_client_1.default)(config, false, false), (0, integration_credentials_1.default)(config, integrationLogic), (0, integration_logout_1.default)(config, integrationLogic));
|
|
116
136
|
app.get('/api/crowdin/files', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, crowdin_files_1.default)(config, integrationLogic));
|
|
@@ -137,6 +157,19 @@ function addCrowdinEndpoints(app, plainConfig) {
|
|
|
137
157
|
cron.schedule('0 */12 * * *', () => (0, cron_1.filesCron)(config, integrationLogic, '12').catch(console.error));
|
|
138
158
|
cron.schedule('0 0 * * *', () => (0, cron_1.filesCron)(config, integrationLogic, '24').catch(console.error));
|
|
139
159
|
}
|
|
160
|
+
if (integrationLogic.webhooks) {
|
|
161
|
+
app.post(`${integrationLogic.webhooks.crowdinWebhookUrl
|
|
162
|
+
? integrationLogic.webhooks.crowdinWebhookUrl
|
|
163
|
+
: '/api/crowdin/webhook'}`, json_response_1.default, (0, crowdin_webhook_1.default)(config, integrationLogic));
|
|
164
|
+
if (((_a = integrationLogic.webhooks) === null || _a === void 0 ? void 0 : _a.integrationWebhookInterceptor) && !((_b = integrationLogic.webhooks) === null || _b === void 0 ? void 0 : _b.queueUrl)) {
|
|
165
|
+
app.post(`${integrationLogic.webhooks.integrationWebhookUrl
|
|
166
|
+
? integrationLogic.webhooks.integrationWebhookUrl
|
|
167
|
+
: '/api/integration/webhook'}`, (0, integration_webhook_1.default)(config, integrationLogic));
|
|
168
|
+
}
|
|
169
|
+
if ((_c = integrationLogic.webhooks) === null || _c === void 0 ? void 0 : _c.queueUrl) {
|
|
170
|
+
(0, webhooks_1.listenQueueMessage)(config, integrationLogic, integrationLogic.webhooks.queueUrl, config.identifier);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
140
173
|
}
|
|
141
174
|
if (config.customFileFormat) {
|
|
142
175
|
app.post('/process', (0, crowdin_client_1.default)(config), (0, process_1.default)(config, config.baseUrl, config.customFileFormat.filesFolder || config.dbFolder || '/', config.customFileFormat));
|
|
@@ -148,28 +181,35 @@ function addCrowdinEndpoints(app, plainConfig) {
|
|
|
148
181
|
}
|
|
149
182
|
if (config.profileResourcesMenu) {
|
|
150
183
|
app.get('/logo/resources/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.profileResourcesMenu) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath || (0, path_1.join)(__dirname, 'logo.png')); });
|
|
151
|
-
app.use('/resources', (0, ui_module_1.default)(config, config.profileResourcesMenu.allowUnauthorized),
|
|
184
|
+
app.use('/resources', (0, ui_module_1.default)(config, config.profileResourcesMenu.allowUnauthorized), (0, render_ui_module_1.default)(config, config.profileResourcesMenu));
|
|
152
185
|
}
|
|
153
186
|
if (config.organizationMenu) {
|
|
154
187
|
app.get('/logo/resources/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.organizationMenu) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath || (0, path_1.join)(__dirname, 'logo.png')); });
|
|
155
|
-
app.use('/resources', (0, ui_module_1.default)(config, config.organizationMenu.allowUnauthorized),
|
|
188
|
+
app.use('/resources', (0, ui_module_1.default)(config, config.organizationMenu.allowUnauthorized), (0, render_ui_module_1.default)(config, config.organizationMenu));
|
|
156
189
|
}
|
|
157
190
|
if (config.editorRightPanel) {
|
|
158
|
-
app.use('/editor-panels', (0, ui_module_1.default)(config, config.editorRightPanel.allowUnauthorized),
|
|
191
|
+
app.use('/editor-panels', (0, ui_module_1.default)(config, config.editorRightPanel.allowUnauthorized), (0, render_ui_module_1.default)(config, config.editorRightPanel));
|
|
159
192
|
}
|
|
160
193
|
if (config.projectMenu) {
|
|
161
|
-
app.use('/project-menu', (0, ui_module_1.default)(config, config.projectMenu.allowUnauthorized),
|
|
194
|
+
app.use('/project-menu', (0, ui_module_1.default)(config, config.projectMenu.allowUnauthorized), (0, render_ui_module_1.default)(config, config.projectMenu));
|
|
162
195
|
}
|
|
163
196
|
if (config.projectMenuCrowdsource) {
|
|
164
|
-
app.use('/project-menu-crowdsource', (0, ui_module_1.default)(config, config.projectMenuCrowdsource.allowUnauthorized),
|
|
197
|
+
app.use('/project-menu-crowdsource', (0, ui_module_1.default)(config, config.projectMenuCrowdsource.allowUnauthorized), (0, render_ui_module_1.default)(config, config.projectMenuCrowdsource));
|
|
165
198
|
}
|
|
166
199
|
if (config.projectTools) {
|
|
167
200
|
app.get('/logo/tools/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.projectTools) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath || (0, path_1.join)(__dirname, 'logo.png')); });
|
|
168
|
-
app.use('/tools', (0, ui_module_1.default)(config, config.projectTools.allowUnauthorized),
|
|
201
|
+
app.use('/tools', (0, ui_module_1.default)(config, config.projectTools.allowUnauthorized), (0, render_ui_module_1.default)(config, config.projectTools));
|
|
169
202
|
}
|
|
170
203
|
if (config.projectReports) {
|
|
171
204
|
app.get('/logo/reports/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.projectReports) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath || (0, path_1.join)(__dirname, 'logo.png')); });
|
|
172
|
-
app.use('/reports', (0, ui_module_1.default)(config, config.projectReports.allowUnauthorized),
|
|
205
|
+
app.use('/reports', (0, ui_module_1.default)(config, config.projectReports.allowUnauthorized), (0, render_ui_module_1.default)(config, config.projectReports));
|
|
206
|
+
}
|
|
207
|
+
if (Object.keys(config).some((moduleKey) => {
|
|
208
|
+
const moduleConfig = config[moduleKey];
|
|
209
|
+
return typeof moduleConfig === 'object' && moduleConfig.hasOwnProperty('formSchema');
|
|
210
|
+
})) {
|
|
211
|
+
app.get('/api/form-data', json_response_1.default, (0, crowdin_client_1.default)(config), (0, form_data_display_1.default)());
|
|
212
|
+
app.post('/api/form-data', (0, crowdin_client_1.default)(config), (0, form_data_save_1.default)());
|
|
173
213
|
}
|
|
174
214
|
return {
|
|
175
215
|
getMetadata: storage.getStorage().getMetadata.bind(storage.getStorage()),
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/// <reference types="qs" />
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import { Config, UiModule } from '../models';
|
|
4
|
+
export default function handle(config: Config, moduleConfig: UiModule): (req: express.Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: express.Response<any, Record<string, any>>, next: Function) => void;
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const express_1 = __importDefault(require("express"));
|
|
16
|
+
const util_1 = require("../util");
|
|
17
|
+
function handle(config, moduleConfig) {
|
|
18
|
+
return (0, util_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
if (moduleConfig.formSchema) {
|
|
20
|
+
return res.render('form', {
|
|
21
|
+
formGetDataUrl: moduleConfig.formGetDataUrl ? moduleConfig.formGetDataUrl : '/api/form-data',
|
|
22
|
+
formPostDataUrl: moduleConfig.formPostDataUrl ? moduleConfig.formPostDataUrl : '/api/form-data',
|
|
23
|
+
formSchema: JSON.stringify(moduleConfig.formSchema),
|
|
24
|
+
formUiSchema: moduleConfig.formUiSchema ? JSON.stringify(moduleConfig.formUiSchema) : '{}',
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
if (moduleConfig.uiPath) {
|
|
28
|
+
return express_1.default.static(moduleConfig.uiPath)(req, res, next);
|
|
29
|
+
}
|
|
30
|
+
throw new Error('uiPath or formSchema should be provided for module');
|
|
31
|
+
}), config.onError);
|
|
32
|
+
}
|
|
33
|
+
exports.default = handle;
|
package/out/models/index.d.ts
CHANGED
|
@@ -187,7 +187,7 @@ export interface IntegrationLogic {
|
|
|
187
187
|
/**
|
|
188
188
|
* function to update crowdin files (e.g. pull integration data to crowdin source files)
|
|
189
189
|
*/
|
|
190
|
-
updateCrowdin: (projectId: number, client: Crowdin, apiCredentials: any, request: IntegrationFile[], appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<void | ExtendedResult<void>>;
|
|
190
|
+
updateCrowdin: (projectId: number, client: Crowdin, apiCredentials: any, request: IntegrationFile[], appRootFolder?: SourceFilesModel.Directory, config?: any, uploadTranslations?: boolean) => Promise<void | ExtendedResult<void>>;
|
|
191
191
|
/**
|
|
192
192
|
* function to update integration content (e.g. load crowdin translations and push them to integration service)
|
|
193
193
|
*/
|
|
@@ -235,14 +235,22 @@ export interface IntegrationLogic {
|
|
|
235
235
|
* Enable integration next page event
|
|
236
236
|
*/
|
|
237
237
|
integrationPagination?: boolean;
|
|
238
|
+
/**
|
|
239
|
+
* Enable the option to upload translations to crowdin that are already present in the integration.
|
|
240
|
+
*/
|
|
241
|
+
uploadTranslations?: boolean;
|
|
238
242
|
/**
|
|
239
243
|
* function to get crowdin file translation progress
|
|
240
244
|
*/
|
|
241
245
|
getFileProgress?: (projectId: number, client: Crowdin, fileId: number) => Promise<{
|
|
242
246
|
[key: number]: TranslationStatusModel.LanguageProgress[];
|
|
243
247
|
}>;
|
|
248
|
+
/**
|
|
249
|
+
* Register Crowdin webhook to get notified when translations are ready
|
|
250
|
+
*/
|
|
251
|
+
webhooks?: Webhooks;
|
|
244
252
|
}
|
|
245
|
-
export
|
|
253
|
+
export type FormEntity = FormField | FormDelimeter;
|
|
246
254
|
export interface FormDelimeter {
|
|
247
255
|
label: string;
|
|
248
256
|
}
|
|
@@ -364,7 +372,7 @@ export interface FormField {
|
|
|
364
372
|
helpText?: string;
|
|
365
373
|
helpTextHtml?: string;
|
|
366
374
|
label: string;
|
|
367
|
-
type?: 'text' | 'password' | 'checkbox' | 'select';
|
|
375
|
+
type?: 'text' | 'password' | 'checkbox' | 'select' | 'textarea' | 'file';
|
|
368
376
|
defaultValue?: any;
|
|
369
377
|
/**
|
|
370
378
|
* only for select
|
|
@@ -381,19 +389,27 @@ export interface FormField {
|
|
|
381
389
|
label: string;
|
|
382
390
|
value: string;
|
|
383
391
|
}[];
|
|
392
|
+
/**
|
|
393
|
+
* only for type file
|
|
394
|
+
*/
|
|
395
|
+
accept?: string;
|
|
396
|
+
/**
|
|
397
|
+
* field dependency settings
|
|
398
|
+
*/
|
|
399
|
+
dependencySettings?: string;
|
|
384
400
|
}
|
|
385
401
|
export interface ExtendedResult<T> {
|
|
386
402
|
data?: T;
|
|
387
403
|
message?: string;
|
|
388
404
|
stopPagination?: boolean;
|
|
389
405
|
}
|
|
390
|
-
export
|
|
406
|
+
export type TreeItem = File | Folder;
|
|
391
407
|
/**
|
|
392
408
|
* 0 - folder
|
|
393
409
|
* 1 - file
|
|
394
410
|
* 2 - branch
|
|
395
411
|
*/
|
|
396
|
-
|
|
412
|
+
type IntegrationTreeElementType = '0' | '1' | '2';
|
|
397
413
|
export interface File {
|
|
398
414
|
id: string;
|
|
399
415
|
name: string;
|
|
@@ -580,10 +596,29 @@ export interface CustomMTRequest {
|
|
|
580
596
|
strings: string[];
|
|
581
597
|
}
|
|
582
598
|
export interface UiModule {
|
|
599
|
+
/**
|
|
600
|
+
* Form schema for react-jsonschema-doc to be used as front-end
|
|
601
|
+
* https://rjsf-team.github.io/react-jsonschema-form/docs
|
|
602
|
+
*/
|
|
603
|
+
formSchema?: object;
|
|
604
|
+
/**
|
|
605
|
+
* URL to custom endpoint that can be used instead of default one to save form data.
|
|
606
|
+
* Endpoint should accept POST requests.
|
|
607
|
+
*/
|
|
608
|
+
formPostDataUrl?: string;
|
|
609
|
+
/**
|
|
610
|
+
* URL to custom endpoint that can be used instead of default one to retrieve form data.
|
|
611
|
+
* Endpoint should accept GET requests.
|
|
612
|
+
*/
|
|
613
|
+
formGetDataUrl?: string;
|
|
614
|
+
/**
|
|
615
|
+
* Additional attributes for react-jsonschema-doc
|
|
616
|
+
*/
|
|
617
|
+
formUiSchema?: object;
|
|
583
618
|
/**
|
|
584
619
|
* path to ui folder (e.g. {@example join(__dirname, 'public')})
|
|
585
620
|
*/
|
|
586
|
-
uiPath
|
|
621
|
+
uiPath?: string;
|
|
587
622
|
/**
|
|
588
623
|
* page name (default index.html)
|
|
589
624
|
*/
|
|
@@ -643,4 +678,35 @@ export interface Pricing {
|
|
|
643
678
|
cachingSeconds?: number;
|
|
644
679
|
infoDisplayDaysThreshold?: number;
|
|
645
680
|
}
|
|
681
|
+
export interface Webhooks {
|
|
682
|
+
crowdinWebhookUrl?: string;
|
|
683
|
+
integrationWebhookUrl?: string;
|
|
684
|
+
urlParam?: string;
|
|
685
|
+
crowdinWebhooks?: (client: Crowdin, projectId: number, available: boolean, config?: any) => Promise<void>;
|
|
686
|
+
integrationWebhooks?: (apiCredentials: any, urlParam: string, available: boolean, config?: any, syncSettings?: any) => Promise<void>;
|
|
687
|
+
crowdinWebhookInterceptor?: (projectId: number, client: Crowdin, appRootFolder?: SourceFilesModel.Directory, config?: any, syncSettings?: any, webhookRequest?: any) => Promise<UpdateIntegrationRequest>;
|
|
688
|
+
integrationWebhookInterceptor?: (projectId: number, client: Crowdin, apiCredentials: any, appRootFolder?: SourceFilesModel.Directory, config?: any, syncSettings?: any, webhookRequest?: any) => Promise<IntegrationFile[]>;
|
|
689
|
+
queueUrl: string;
|
|
690
|
+
}
|
|
691
|
+
export declare enum SyncCondition {
|
|
692
|
+
ALL = 0,
|
|
693
|
+
TRANSLATED = 1,
|
|
694
|
+
APPROVED = 2
|
|
695
|
+
}
|
|
696
|
+
export declare enum SyncType {
|
|
697
|
+
NONE = 0,
|
|
698
|
+
SCHEDULE = 1,
|
|
699
|
+
WEBHOOKS = 2
|
|
700
|
+
}
|
|
701
|
+
export type Payload = {
|
|
702
|
+
event: string;
|
|
703
|
+
projectId: string;
|
|
704
|
+
language: string;
|
|
705
|
+
fileId: string;
|
|
706
|
+
};
|
|
707
|
+
export type WebhookUrlParams = {
|
|
708
|
+
projectId: number;
|
|
709
|
+
crowdinId: string;
|
|
710
|
+
clientId: string;
|
|
711
|
+
};
|
|
646
712
|
export {};
|