@crowdin/app-project-module 0.14.1 → 0.15.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/README.md +69 -41
- package/out/handlers/crowdin-files.js +2 -1
- package/out/handlers/crowdin-update.js +2 -1
- package/out/handlers/integration-update.js +2 -1
- package/out/handlers/main.js +2 -1
- package/out/handlers/manifest.js +0 -72
- package/out/handlers/oauth-login.js +2 -1
- package/out/index.js +20 -41
- package/out/middlewares/crowdin-client.d.ts +2 -2
- package/out/middlewares/crowdin-client.js +32 -40
- package/out/middlewares/integration-credentials.js +2 -1
- package/out/middlewares/ui-module.d.ts +4 -0
- package/out/middlewares/ui-module.js +39 -0
- package/out/models/index.d.ts +11 -0
- package/out/static/js/main.js +7 -0
- package/out/util/connection.d.ts +11 -0
- package/out/util/connection.js +186 -0
- package/out/util/cron.d.ts +3 -0
- package/out/util/cron.js +103 -0
- package/out/util/defaults.d.ts +5 -0
- package/out/util/defaults.js +150 -0
- package/out/util/index.d.ts +1 -9
- package/out/util/index.js +1 -255
- package/out/views/main.handlebars +11 -0
- package/out/views/partials/head.handlebars +18 -13
- package/out/views/subscription.handlebars +26 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -30,19 +30,23 @@ In both options you will need to provide Crowdin App configuration file. Please
|
|
|
30
30
|
## Table of Contents
|
|
31
31
|
|
|
32
32
|
- [Installation](#installation)
|
|
33
|
-
- [Sample App](#sample-app)
|
|
34
|
-
- [
|
|
35
|
-
- [
|
|
33
|
+
- [Sample Project Integration App](#sample-project-integration-app)
|
|
34
|
+
- [Payment](#payment)
|
|
35
|
+
- [Authorization](#authorization)
|
|
36
|
+
- [Custom login form](#customize-your-app-login-form)
|
|
37
|
+
- [OAuth2 login](#oauth2-support)
|
|
36
38
|
- [Settings window](#settings-window)
|
|
37
39
|
- [Info window](#info-window)
|
|
38
40
|
- [Background tasks](#background-tasks)
|
|
39
|
-
- [
|
|
40
|
-
- [Error
|
|
41
|
-
- [
|
|
42
|
-
- [
|
|
43
|
-
- [
|
|
44
|
-
- [
|
|
45
|
-
- [
|
|
41
|
+
- [Errors handling](#errors-handling)
|
|
42
|
+
- [Error propagation](#error-propagation)
|
|
43
|
+
- [Error interceptor](#error-interceptor)
|
|
44
|
+
- [Debug mode](#debug-mode)
|
|
45
|
+
- [Modules](#modules)
|
|
46
|
+
- [Custom File Format](#custom-file-format)
|
|
47
|
+
- [Custom MT](#custom-mt)
|
|
48
|
+
- [Profile Resources Menu](#profile-resources-menu)
|
|
49
|
+
- [Other modules](#other-modules)
|
|
46
50
|
- [Contributing](#contributing)
|
|
47
51
|
- [Seeking Assistance](#seeking-assistance)
|
|
48
52
|
- [License](#license)
|
|
@@ -57,7 +61,7 @@ In both options you will need to provide Crowdin App configuration file. Please
|
|
|
57
61
|
|
|
58
62
|
`yarn add @crowdin/app-project-module`
|
|
59
63
|
|
|
60
|
-
## Sample
|
|
64
|
+
## Sample Project Integration App
|
|
61
65
|
|
|
62
66
|
```javascript
|
|
63
67
|
const crowdinModule = require('@crowdin/app-project-module');
|
|
@@ -77,7 +81,7 @@ const configuration = {
|
|
|
77
81
|
description: 'Sample App description',
|
|
78
82
|
dbFolder: __dirname,
|
|
79
83
|
imagePath: __dirname + '/' + 'logo.png',
|
|
80
|
-
|
|
84
|
+
projectIntegration: {
|
|
81
85
|
withRootFolder: true,
|
|
82
86
|
withCronSync: {
|
|
83
87
|
crowdin: true,
|
|
@@ -169,13 +173,32 @@ const configuration = {
|
|
|
169
173
|
crowdinModule.createApp(configuration);
|
|
170
174
|
```
|
|
171
175
|
|
|
172
|
-
## Customize your app login form
|
|
173
176
|
|
|
174
|
-
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
## Payment
|
|
180
|
+
|
|
181
|
+
By default App does not have any subscription and it's free to use. But you can override this.
|
|
182
|
+
|
|
183
|
+
```javascript
|
|
184
|
+
configuration.pricing = {
|
|
185
|
+
plantType: 'recurring',
|
|
186
|
+
trial: 14, //amount of days to use app for free
|
|
187
|
+
trialCrowdin: 14, //amount of days specifically in crowdin workspace
|
|
188
|
+
trialEnterprise: 30 //amount of days specifically for enterprise
|
|
189
|
+
cachingSeconds: 12 * 60 * 60 //time in seconds of how long to cache subscription info
|
|
190
|
+
};
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Authorization
|
|
194
|
+
|
|
195
|
+
### Customize your app login form
|
|
196
|
+
|
|
197
|
+
By default, login page for your app will require only to enter `apiToken` to communicate with third party service.
|
|
175
198
|
But there is also a possibility to customize it.
|
|
176
199
|
|
|
177
200
|
```javascript
|
|
178
|
-
configuration.
|
|
201
|
+
configuration.projectIntegration.loginForm = {
|
|
179
202
|
fields: [
|
|
180
203
|
{
|
|
181
204
|
key: 'username',
|
|
@@ -195,7 +218,7 @@ configuration.integration.loginForm = {
|
|
|
195
218
|
};
|
|
196
219
|
```
|
|
197
220
|
|
|
198
|
-
|
|
221
|
+
### OAuth2 support
|
|
199
222
|
|
|
200
223
|
In case if third party service uses OAuth2 for authorization use `oauthLogin` field to configure it.
|
|
201
224
|
`loginForm` **in this case should remain undefined**.
|
|
@@ -203,7 +226,7 @@ In case if third party service uses OAuth2 for authorization use `oauthLogin` fi
|
|
|
203
226
|
Github example:
|
|
204
227
|
|
|
205
228
|
```javascript
|
|
206
|
-
configuration.
|
|
229
|
+
configuration.projectIntegration.oauthLogin = {
|
|
207
230
|
authorizationUrl: 'https://github.com/login/oauth/authorize',
|
|
208
231
|
clientId: 'github_app_client_id',
|
|
209
232
|
clientSecret: 'github_app_client_secret',
|
|
@@ -214,7 +237,7 @@ configuration.integration.oauthLogin = {
|
|
|
214
237
|
Google example:
|
|
215
238
|
|
|
216
239
|
```javascript
|
|
217
|
-
configuration.
|
|
240
|
+
configuration.projectIntegration.oauthLogin = {
|
|
218
241
|
scope: 'https%3A//www.googleapis.com/auth/userinfo.email',
|
|
219
242
|
authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
220
243
|
clientId: 'google_web_app_client_id',
|
|
@@ -249,7 +272,7 @@ Main default values:
|
|
|
249
272
|
This module rely that OAuth2 protocol is implemented by third party service in this way:
|
|
250
273
|
|
|
251
274
|
- request for access token should be done via POST request to `accessTokenUrl` with JSON body that will contain at least `clientId`, `clientSecret`, `code` and `redirectUri` (also possible to add extra fields via `extraAccessTokenParameters` property)
|
|
252
|
-
- request to refresh token should be done via POST request to `accessTokenUrl` (or `refreshTokenUrl` if
|
|
275
|
+
- request to refresh token should be done via POST request to `accessTokenUrl` (or `refreshTokenUrl` if defined) with JSON body that will contain at least `clientId`, `clientSecret` and `refreshToken` (also possible to add extra fields via `extraRefreshTokenParameters` property)
|
|
253
276
|
- both requests will return JSON response with body that contains `accessToken` and, if enabled, `refreshToken` (optional) and `expireIn`
|
|
254
277
|
|
|
255
278
|
To override those requests please use `performGetTokenRequest` and `performRefreshTokenRequest` (e.g. when requests should be done with different HTTP methods or data should be tranfered as query string or form data).
|
|
@@ -261,7 +284,7 @@ const clientId = 'client_id';
|
|
|
261
284
|
const clientSecret = 'client_secret';
|
|
262
285
|
const tokenUrl = 'https://services.mailup.com/Authorization/OAuth/Token';
|
|
263
286
|
|
|
264
|
-
configuration.
|
|
287
|
+
configuration.projectIntegration.oauthLogin = {
|
|
265
288
|
authorizationUrl: 'https://services.mailup.com/Authorization/OAuth/LogOn',
|
|
266
289
|
clientId,
|
|
267
290
|
clientSecret,
|
|
@@ -301,7 +324,7 @@ Please refer to jsdoc for more details.
|
|
|
301
324
|
It is also possible to define settings window for your app where users can customize integration flow.
|
|
302
325
|
|
|
303
326
|
```javascript
|
|
304
|
-
configuration.
|
|
327
|
+
configuration.projectIntegration.getConfiguration = (projectId, crowdinClient, integrationCredentials) => {
|
|
305
328
|
return [
|
|
306
329
|
{
|
|
307
330
|
key: 'flag',
|
|
@@ -334,7 +357,7 @@ configuration.integration.getConfiguration = (projectId, crowdinClient, integrat
|
|
|
334
357
|
You also can define section with some information notes or help section for your app.
|
|
335
358
|
|
|
336
359
|
```javascript
|
|
337
|
-
configuration.
|
|
360
|
+
configuration.projectIntegration.infoModal = {
|
|
338
361
|
title: 'Info',
|
|
339
362
|
content: `
|
|
340
363
|
<h1>This is your app help section</h1>
|
|
@@ -349,7 +372,7 @@ configuration.integration.infoModal = {
|
|
|
349
372
|
In order to register background tasks that app will invoke periodically invoke you can use `cronJobs` field.
|
|
350
373
|
|
|
351
374
|
```javascript
|
|
352
|
-
configuration.
|
|
375
|
+
configuration.projectIntegration.cronJobs = [
|
|
353
376
|
{
|
|
354
377
|
//every 10 seconds
|
|
355
378
|
expression: '*/10 * * * * *',
|
|
@@ -365,13 +388,15 @@ configuration.integration.cronJobs = [
|
|
|
365
388
|
|
|
366
389
|
For cron syntax guide please refer to this [documentation](https://github.com/node-cron/node-cron#cron-syntax).
|
|
367
390
|
|
|
368
|
-
##
|
|
391
|
+
## Errors Handling
|
|
392
|
+
|
|
393
|
+
### Error propagation
|
|
369
394
|
|
|
370
395
|
In case if something is wrong with app settings or credentials are invalid you can throw an explanation message that will be then visible on the UI side.
|
|
371
396
|
e.g. check if entered credentials are valid:
|
|
372
397
|
|
|
373
398
|
```javascript
|
|
374
|
-
configuration.
|
|
399
|
+
configuration.projectIntegration.checkConnection = (credentials) => {
|
|
375
400
|
if (!credentials.password || credentials.password.length < 6) {
|
|
376
401
|
throw 'Password is too weak';
|
|
377
402
|
}
|
|
@@ -383,7 +408,7 @@ Or if you need to manually control users liveness session you can throw an error
|
|
|
383
408
|
e.g. when your service has some specific session duration timeout or extra conditions which are not covered by this framework
|
|
384
409
|
|
|
385
410
|
```javascript
|
|
386
|
-
configuration.
|
|
411
|
+
configuration.projectIntegration.getIntegrationFiles = async (credentials, appSettings) => {
|
|
387
412
|
//do a request/custom logic here
|
|
388
413
|
const sessionStillValid = false;
|
|
389
414
|
if (!sessionStillValid) {
|
|
@@ -396,7 +421,7 @@ configuration.integrartion.getIntegrationFiles = async (credentials, appSettings
|
|
|
396
421
|
}
|
|
397
422
|
```
|
|
398
423
|
|
|
399
|
-
|
|
424
|
+
### Error interceptor
|
|
400
425
|
|
|
401
426
|
You can also provide interceptor to catch errors and process them (e.g. to log them in the centralized place).
|
|
402
427
|
|
|
@@ -413,7 +438,7 @@ configuration.onError = (error) => {
|
|
|
413
438
|
};
|
|
414
439
|
```
|
|
415
440
|
|
|
416
|
-
|
|
441
|
+
### Debug mode
|
|
417
442
|
|
|
418
443
|
Also you can turn on the debug mode and application will log everything (useful of debugging).
|
|
419
444
|
|
|
@@ -434,7 +459,9 @@ configuration.logger = {
|
|
|
434
459
|
};
|
|
435
460
|
```
|
|
436
461
|
|
|
437
|
-
##
|
|
462
|
+
## Modules
|
|
463
|
+
|
|
464
|
+
### Custom File Format
|
|
438
465
|
|
|
439
466
|
Example of [custom file format module](https://support.crowdin.com/crowdin-apps-modules/#custom-file-format-module).
|
|
440
467
|
|
|
@@ -485,7 +512,7 @@ const configuration = {
|
|
|
485
512
|
crowdinModule.createApp(configuration);
|
|
486
513
|
```
|
|
487
514
|
|
|
488
|
-
|
|
515
|
+
### Custom MT
|
|
489
516
|
|
|
490
517
|
Example of [custom mt module](https://support.crowdin.com/crowdin-apps-modules/#custom-mt-machine-translation-module).
|
|
491
518
|
|
|
@@ -516,7 +543,7 @@ const configuration = {
|
|
|
516
543
|
crowdinModule.createApp(configuration);
|
|
517
544
|
```
|
|
518
545
|
|
|
519
|
-
|
|
546
|
+
### Profile Resources Menu
|
|
520
547
|
|
|
521
548
|
Example of [resources module](https://support.crowdin.com/crowdin-apps-modules/#resources-module).
|
|
522
549
|
|
|
@@ -532,7 +559,7 @@ const configuration = {
|
|
|
532
559
|
description: 'Sample App description',
|
|
533
560
|
dbFolder: __dirname,
|
|
534
561
|
imagePath: __dirname + '/' + 'logo.png',
|
|
535
|
-
|
|
562
|
+
profileResourcesMenu: {
|
|
536
563
|
fileName: 'setup.html',
|
|
537
564
|
uiPath: __dirname + '/' + 'public'
|
|
538
565
|
},
|
|
@@ -541,7 +568,7 @@ const configuration = {
|
|
|
541
568
|
crowdinModule.createApp(configuration);
|
|
542
569
|
```
|
|
543
570
|
|
|
544
|
-
The
|
|
571
|
+
The `profileResourcesMenu` module can work as an extension to other modules be something like a configuration UI for them.
|
|
545
572
|
|
|
546
573
|
```javascript
|
|
547
574
|
const crowdinModule = require('@crowdin/app-project-module');
|
|
@@ -558,7 +585,7 @@ const configuration = {
|
|
|
558
585
|
description: 'Sample App description',
|
|
559
586
|
dbFolder: __dirname,
|
|
560
587
|
imagePath: __dirname + '/' + 'logo.png',
|
|
561
|
-
|
|
588
|
+
profileResourcesMenu: {
|
|
562
589
|
fileName: 'setup.html',
|
|
563
590
|
uiPath: __dirname + '/' + 'public'
|
|
564
591
|
},
|
|
@@ -601,16 +628,17 @@ app.get('/metadata', async (req, res) => {
|
|
|
601
628
|
app.listen(3000, () => console.log('Crowdin app started'));
|
|
602
629
|
```
|
|
603
630
|
|
|
604
|
-
|
|
631
|
+
### Other modules
|
|
605
632
|
|
|
606
633
|
Framework also supports following modules:
|
|
607
634
|
|
|
608
|
-
- [
|
|
609
|
-
- [
|
|
610
|
-
- [
|
|
611
|
-
- [
|
|
635
|
+
- [organization-menu module](https://support.crowdin.com/enterprise/crowdin-apps-modules/#organization-menu-module)
|
|
636
|
+
- [editor-right-panel module](https://support.crowdin.com/crowdin-apps-modules/#editor-panels-module)
|
|
637
|
+
- [project-menu module](https://support.crowdin.com/crowdin-apps-modules/#project-menu-module)
|
|
638
|
+
- [project-tools module](https://support.crowdin.com/crowdin-apps-modules/#tools-module)
|
|
639
|
+
- [project-reports module](https://support.crowdin.com/crowdin-apps-modules/#reports-module)
|
|
612
640
|
|
|
613
|
-
Example of Reports Module:
|
|
641
|
+
Example of Project Reports Module:
|
|
614
642
|
|
|
615
643
|
```javascript
|
|
616
644
|
const crowdinModule = require('@crowdin/app-project-module');
|
|
@@ -624,7 +652,7 @@ const configuration = {
|
|
|
624
652
|
description: 'Sample App description',
|
|
625
653
|
dbFolder: __dirname,
|
|
626
654
|
imagePath: __dirname + '/' + 'logo.png',
|
|
627
|
-
|
|
655
|
+
projectReports: { //can be editorRightPanel, projectMenu, projectTools
|
|
628
656
|
imagePath: __dirname + '/' + 'reports.png',
|
|
629
657
|
fileName: 'reports.html', //optional, only needed if file is not index.html
|
|
630
658
|
uiPath: __dirname + '/' + 'public' // folder where UI of the module is located (js, html, css files)
|
|
@@ -10,11 +10,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const util_1 = require("../util");
|
|
13
|
+
const defaults_1 = require("../util/defaults");
|
|
13
14
|
function handle(config, integration) {
|
|
14
15
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
15
16
|
(0, util_1.log)('Loading crowdin files', config.logger);
|
|
16
17
|
if (integration.getCrowdinFiles) {
|
|
17
|
-
const rootFolder = yield (0,
|
|
18
|
+
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, req.crowdinApiClient, req.crowdinContext.jwtPayload.context.project_id);
|
|
18
19
|
(0, util_1.log)(`Loading files ${rootFolder ? `from folder ${rootFolder.id}` : 'from root'}`, config.logger);
|
|
19
20
|
const files = integration.getCrowdinFiles
|
|
20
21
|
? yield integration.getCrowdinFiles(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, rootFolder, req.integrationSettings)
|
|
@@ -10,11 +10,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const util_1 = require("../util");
|
|
13
|
+
const defaults_1 = require("../util/defaults");
|
|
13
14
|
function handle(config, integration) {
|
|
14
15
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
15
16
|
const projectId = req.crowdinContext.jwtPayload.context.project_id;
|
|
16
17
|
(0, util_1.log)(`Upading crowdin project ${projectId}`, config.logger);
|
|
17
|
-
const rootFolder = yield (0,
|
|
18
|
+
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, req.crowdinApiClient, projectId);
|
|
18
19
|
if (rootFolder) {
|
|
19
20
|
(0, util_1.log)(`Upading crowdin files under folder ${rootFolder.id}`, config.logger);
|
|
20
21
|
}
|
|
@@ -10,10 +10,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const util_1 = require("../util");
|
|
13
|
+
const defaults_1 = require("../util/defaults");
|
|
13
14
|
function handle(config, integration) {
|
|
14
15
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
15
16
|
(0, util_1.log)('Upading integratino data', config.logger);
|
|
16
|
-
const rootFolder = yield (0,
|
|
17
|
+
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, req.crowdinApiClient, req.crowdinContext.jwtPayload.context.project_id);
|
|
17
18
|
if (rootFolder) {
|
|
18
19
|
(0, util_1.log)(`Upading integration data for crowding root folder ${rootFolder.id}`, config.logger);
|
|
19
20
|
}
|
package/out/handlers/main.js
CHANGED
|
@@ -10,12 +10,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const util_1 = require("../util");
|
|
13
|
+
const defaults_1 = require("../util/defaults");
|
|
13
14
|
function constructOauthUrl(config, integration) {
|
|
14
15
|
var _a, _b, _c;
|
|
15
16
|
const oauth = integration.oauthLogin;
|
|
16
17
|
let url = (oauth === null || oauth === void 0 ? void 0 : oauth.authorizationUrl) || '';
|
|
17
18
|
url += `?${((_a = oauth === null || oauth === void 0 ? void 0 : oauth.fieldsMapping) === null || _a === void 0 ? void 0 : _a.clientId) || 'client_id'}=${oauth === null || oauth === void 0 ? void 0 : oauth.clientId}`;
|
|
18
|
-
url += `&${((_b = oauth === null || oauth === void 0 ? void 0 : oauth.fieldsMapping) === null || _b === void 0 ? void 0 : _b.redirectUri) || 'redirect_uri'}=${config.baseUrl}${(0,
|
|
19
|
+
url += `&${((_b = oauth === null || oauth === void 0 ? void 0 : oauth.fieldsMapping) === null || _b === void 0 ? void 0 : _b.redirectUri) || 'redirect_uri'}=${config.baseUrl}${(0, defaults_1.getOauthRoute)(integration)}`;
|
|
19
20
|
if (oauth === null || oauth === void 0 ? void 0 : oauth.scope) {
|
|
20
21
|
url += `&${((_c = oauth === null || oauth === void 0 ? void 0 : oauth.fieldsMapping) === null || _c === void 0 ? void 0 : _c.scope) || 'scope'}=${oauth === null || oauth === void 0 ? void 0 : oauth.scope}`;
|
|
21
22
|
}
|
package/out/handlers/manifest.js
CHANGED
|
@@ -3,19 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const models_1 = require("../models");
|
|
4
4
|
function handle(config) {
|
|
5
5
|
const modules = {};
|
|
6
|
-
// TEMPORARY CODE drop on step 3 of CN-30453
|
|
7
|
-
if (config.integration) {
|
|
8
|
-
modules.integrations = [
|
|
9
|
-
{
|
|
10
|
-
key: config.identifier + '-int',
|
|
11
|
-
name: config.name,
|
|
12
|
-
description: config.description,
|
|
13
|
-
logo: '/logo/integration/logo.png',
|
|
14
|
-
url: '/',
|
|
15
|
-
},
|
|
16
|
-
];
|
|
17
|
-
}
|
|
18
|
-
// END OF TEMPORARY CODE
|
|
19
6
|
if (config.projectIntegration) {
|
|
20
7
|
modules['project-integrations'] = [
|
|
21
8
|
{
|
|
@@ -46,26 +33,6 @@ function handle(config) {
|
|
|
46
33
|
},
|
|
47
34
|
];
|
|
48
35
|
}
|
|
49
|
-
// TEMPORARY CODE drop on step 3 of CN-30453
|
|
50
|
-
if (config.resources) {
|
|
51
|
-
modules['organization-menu'] = [
|
|
52
|
-
{
|
|
53
|
-
key: config.identifier + '-resources',
|
|
54
|
-
name: config.name,
|
|
55
|
-
url: '/resources/' + (config.resources.fileName || 'index.html'),
|
|
56
|
-
icon: '/logo/resources/logo.png',
|
|
57
|
-
},
|
|
58
|
-
];
|
|
59
|
-
modules['resources'] = [
|
|
60
|
-
{
|
|
61
|
-
key: config.identifier + '-resources',
|
|
62
|
-
name: config.name,
|
|
63
|
-
url: '/resources/' + (config.resources.fileName || 'index.html'),
|
|
64
|
-
icon: '/logo/resources/logo.png',
|
|
65
|
-
},
|
|
66
|
-
];
|
|
67
|
-
}
|
|
68
|
-
// END OF TEMPORARY CODE
|
|
69
36
|
if (config.organizationMenu) {
|
|
70
37
|
modules['organization-menu'] = [
|
|
71
38
|
{
|
|
@@ -86,19 +53,6 @@ function handle(config) {
|
|
|
86
53
|
},
|
|
87
54
|
];
|
|
88
55
|
}
|
|
89
|
-
// TEMPORARY CODE drop on step 3 of CN-30453
|
|
90
|
-
if (config.editorPanels) {
|
|
91
|
-
modules['editor-panels'] = [
|
|
92
|
-
{
|
|
93
|
-
key: config.identifier + '-editor-panels',
|
|
94
|
-
name: config.name,
|
|
95
|
-
position: 'right',
|
|
96
|
-
url: '/editor-panels/' + (config.editorPanels.fileName || 'index.html'),
|
|
97
|
-
modes: config.editorPanels.modes,
|
|
98
|
-
},
|
|
99
|
-
];
|
|
100
|
-
}
|
|
101
|
-
// END OF TEMPORARY CODE
|
|
102
56
|
if (config.editorRightPanel) {
|
|
103
57
|
modules['editor-right-panel'] = [
|
|
104
58
|
{
|
|
@@ -118,19 +72,6 @@ function handle(config) {
|
|
|
118
72
|
},
|
|
119
73
|
];
|
|
120
74
|
}
|
|
121
|
-
// TEMPORARY CODE drop on step 3 of CN-30453
|
|
122
|
-
if (config.tools) {
|
|
123
|
-
modules['tools'] = [
|
|
124
|
-
{
|
|
125
|
-
key: config.identifier + '-tools',
|
|
126
|
-
name: config.name,
|
|
127
|
-
description: config.description,
|
|
128
|
-
logo: '/logo/tools/logo.png',
|
|
129
|
-
url: '/tools/' + (config.tools.fileName || 'index.html'),
|
|
130
|
-
},
|
|
131
|
-
];
|
|
132
|
-
}
|
|
133
|
-
// END OF TEMPORARY CODE
|
|
134
75
|
if (config.projectTools) {
|
|
135
76
|
modules['project-tools'] = [
|
|
136
77
|
{
|
|
@@ -142,19 +83,6 @@ function handle(config) {
|
|
|
142
83
|
},
|
|
143
84
|
];
|
|
144
85
|
}
|
|
145
|
-
// TEMPORARY CODE drop on step 3 of CN-30453
|
|
146
|
-
if (config.reports) {
|
|
147
|
-
modules['reports'] = [
|
|
148
|
-
{
|
|
149
|
-
key: config.identifier + '-reports',
|
|
150
|
-
name: config.name,
|
|
151
|
-
description: config.description,
|
|
152
|
-
logo: '/logo/reports/logo.png',
|
|
153
|
-
url: '/reports/' + (config.reports.fileName || 'index.html'),
|
|
154
|
-
},
|
|
155
|
-
];
|
|
156
|
-
}
|
|
157
|
-
// END OF TEMPORARY CODE
|
|
158
86
|
if (config.projectReports) {
|
|
159
87
|
modules['project-reports'] = [
|
|
160
88
|
{
|
|
@@ -14,6 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
const axios_1 = __importDefault(require("axios"));
|
|
16
16
|
const util_1 = require("../util");
|
|
17
|
+
const defaults_1 = require("../util/defaults");
|
|
17
18
|
function handle(config, integration) {
|
|
18
19
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
19
20
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
@@ -35,7 +36,7 @@ function handle(config, integration) {
|
|
|
35
36
|
request[((_c = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _c === void 0 ? void 0 : _c.code) || 'code'] = code;
|
|
36
37
|
request[((_d = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _d === void 0 ? void 0 : _d.clientId) || 'client_id'] = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.clientId;
|
|
37
38
|
request[((_e = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _e === void 0 ? void 0 : _e.clientSecret) || 'client_secret'] = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.clientSecret;
|
|
38
|
-
request[((_f = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _f === void 0 ? void 0 : _f.redirectUri) || 'redirect_uri'] = `${config.baseUrl}${(0,
|
|
39
|
+
request[((_f = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _f === void 0 ? void 0 : _f.redirectUri) || 'redirect_uri'] = `${config.baseUrl}${(0, defaults_1.getOauthRoute)(integration)}`;
|
|
39
40
|
if (oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.extraAccessTokenParameters) {
|
|
40
41
|
Object.entries(oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.extraAccessTokenParameters).forEach(([key, value]) => (request[key] = value));
|
|
41
42
|
}
|
package/out/index.js
CHANGED
|
@@ -58,8 +58,10 @@ const uninstall_1 = __importDefault(require("./handlers/uninstall"));
|
|
|
58
58
|
const crowdin_client_1 = __importStar(require("./middlewares/crowdin-client"));
|
|
59
59
|
const integration_credentials_1 = __importDefault(require("./middlewares/integration-credentials"));
|
|
60
60
|
const json_response_1 = __importDefault(require("./middlewares/json-response"));
|
|
61
|
+
const ui_module_1 = __importDefault(require("./middlewares/ui-module"));
|
|
61
62
|
const storage = __importStar(require("./storage"));
|
|
62
|
-
const
|
|
63
|
+
const cron_1 = require("./util/cron");
|
|
64
|
+
const defaults_1 = require("./util/defaults");
|
|
63
65
|
var models_1 = require("./models");
|
|
64
66
|
Object.defineProperty(exports, "Scope", { enumerable: true, get: function () { return models_1.Scope; } });
|
|
65
67
|
function addCrowdinEndpoints(app, config) {
|
|
@@ -92,12 +94,12 @@ function addCrowdinEndpoints(app, config) {
|
|
|
92
94
|
app.get('/manifest.json', json_response_1.default, (0, manifest_1.default)(config));
|
|
93
95
|
const integrationLogic = config.integration || config.projectIntegration;
|
|
94
96
|
if (integrationLogic) {
|
|
95
|
-
(0,
|
|
97
|
+
(0, defaults_1.applyDefaults)(config, integrationLogic);
|
|
96
98
|
app.get('/logo/integration/logo.png', (req, res) => res.sendFile(integrationLogic.imagePath || config.imagePath || (0, path_1.join)(__dirname, 'logo.png')));
|
|
97
|
-
app.get('/', (0, crowdin_client_1.default)(config, true), (0, integration_credentials_1.default)(config, integrationLogic, true), (0, main_1.default)(config, integrationLogic));
|
|
99
|
+
app.get('/', (0, crowdin_client_1.default)(config, true, false), (0, integration_credentials_1.default)(config, integrationLogic, true), (0, main_1.default)(config, integrationLogic));
|
|
98
100
|
app.post('/api/settings', (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, settings_save_1.default)(config));
|
|
99
|
-
app.post('/api/login', (0, crowdin_client_1.default)(config), (0, integration_login_1.default)(config, integrationLogic));
|
|
100
|
-
app.post('/api/logout', (0, crowdin_client_1.default)(config), (0, integration_logout_1.default)(config));
|
|
101
|
+
app.post('/api/login', (0, crowdin_client_1.default)(config, false, false), (0, integration_login_1.default)(config, integrationLogic));
|
|
102
|
+
app.post('/api/logout', (0, crowdin_client_1.default)(config, false, false), (0, integration_logout_1.default)(config));
|
|
101
103
|
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));
|
|
102
104
|
app.get('/api/crowdin/project', json_response_1.default, (0, crowdin_client_1.default)(config), (0, crowdin_project_1.default)(config));
|
|
103
105
|
app.get('/api/crowdin/file-progress/:fileId', (0, crowdin_client_1.default)(config), (0, crowdin_file_progress_1.default)(config));
|
|
@@ -107,19 +109,19 @@ function addCrowdinEndpoints(app, config) {
|
|
|
107
109
|
app.get('/api/sync-settings/:provider', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, sync_settings_1.default)(config));
|
|
108
110
|
app.post('/api/sync-settings', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, sync_settings_save_1.default)(config));
|
|
109
111
|
if (integrationLogic.oauthLogin) {
|
|
110
|
-
app.get((0,
|
|
112
|
+
app.get((0, defaults_1.getOauthRoute)(integrationLogic), (0, oauth_login_1.default)(config, integrationLogic));
|
|
111
113
|
}
|
|
112
114
|
if (integrationLogic.cronJobs) {
|
|
113
115
|
integrationLogic.cronJobs.forEach(job => {
|
|
114
|
-
cron.schedule(job.expression, () => (0,
|
|
116
|
+
cron.schedule(job.expression, () => (0, cron_1.runJob)(config, integrationLogic, job).catch(console.error));
|
|
115
117
|
});
|
|
116
118
|
}
|
|
117
119
|
if (integrationLogic.withCronSync) {
|
|
118
|
-
cron.schedule('0 * * * *', () => (0,
|
|
119
|
-
cron.schedule('0 */3 * * *', () => (0,
|
|
120
|
-
cron.schedule('0 */6 * * *', () => (0,
|
|
121
|
-
cron.schedule('0 */12 * * *', () => (0,
|
|
122
|
-
cron.schedule('0 0 * * *', () => (0,
|
|
120
|
+
cron.schedule('0 * * * *', () => (0, cron_1.filesCron)(config, integrationLogic, '1').catch(console.error));
|
|
121
|
+
cron.schedule('0 */3 * * *', () => (0, cron_1.filesCron)(config, integrationLogic, '3').catch(console.error));
|
|
122
|
+
cron.schedule('0 */6 * * *', () => (0, cron_1.filesCron)(config, integrationLogic, '6').catch(console.error));
|
|
123
|
+
cron.schedule('0 */12 * * *', () => (0, cron_1.filesCron)(config, integrationLogic, '12').catch(console.error));
|
|
124
|
+
cron.schedule('0 0 * * *', () => (0, cron_1.filesCron)(config, integrationLogic, '24').catch(console.error));
|
|
123
125
|
}
|
|
124
126
|
}
|
|
125
127
|
if (config.customFileFormat) {
|
|
@@ -129,50 +131,27 @@ function addCrowdinEndpoints(app, config) {
|
|
|
129
131
|
if (config.customMT) {
|
|
130
132
|
app.post('/translate', (0, crowdin_client_1.default)(config), (0, translate_1.default)(config, config.customMT));
|
|
131
133
|
}
|
|
132
|
-
// TEMPORARY CODE drop on step 3 of CN-30453
|
|
133
|
-
if (config.resources) {
|
|
134
|
-
app.get('/logo/resources/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.resources) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath || (0, path_1.join)(__dirname, 'logo.png')); });
|
|
135
|
-
app.use('/resources', express_1.default.static(config.resources.uiPath));
|
|
136
|
-
}
|
|
137
|
-
// END OF TEMPORARY CODE
|
|
138
134
|
if (config.profileResourcesMenu) {
|
|
139
135
|
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')); });
|
|
140
|
-
app.use('/resources', express_1.default.static(config.profileResourcesMenu.uiPath));
|
|
136
|
+
app.use('/resources', (0, ui_module_1.default)(config), express_1.default.static(config.profileResourcesMenu.uiPath));
|
|
141
137
|
}
|
|
142
138
|
if (config.organizationMenu) {
|
|
143
139
|
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')); });
|
|
144
|
-
app.use('/resources', express_1.default.static(config.organizationMenu.uiPath));
|
|
145
|
-
}
|
|
146
|
-
// TEMPORARY CODE drop on step 3 of CN-30453
|
|
147
|
-
if (config.editorPanels) {
|
|
148
|
-
app.use('/editor-panels', express_1.default.static(config.editorPanels.uiPath));
|
|
140
|
+
app.use('/resources', (0, ui_module_1.default)(config), express_1.default.static(config.organizationMenu.uiPath));
|
|
149
141
|
}
|
|
150
|
-
// END OF TEMPORARY CODE
|
|
151
142
|
if (config.editorRightPanel) {
|
|
152
|
-
app.use('/editor-panels', express_1.default.static(config.editorRightPanel.uiPath));
|
|
143
|
+
app.use('/editor-panels', (0, ui_module_1.default)(config), express_1.default.static(config.editorRightPanel.uiPath));
|
|
153
144
|
}
|
|
154
145
|
if (config.projectMenu) {
|
|
155
|
-
app.use('/project-menu', express_1.default.static(config.projectMenu.uiPath));
|
|
146
|
+
app.use('/project-menu', (0, ui_module_1.default)(config), express_1.default.static(config.projectMenu.uiPath));
|
|
156
147
|
}
|
|
157
|
-
// TEMPORARY CODE drop on step 3 of CN-30453
|
|
158
|
-
if (config.tools) {
|
|
159
|
-
app.get('/logo/tools/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.tools) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath || (0, path_1.join)(__dirname, 'logo.png')); });
|
|
160
|
-
app.use('/tools', express_1.default.static(config.tools.uiPath));
|
|
161
|
-
}
|
|
162
|
-
// END OF TEMPORARY CODE
|
|
163
148
|
if (config.projectTools) {
|
|
164
149
|
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')); });
|
|
165
|
-
app.use('/tools', express_1.default.static(config.projectTools.uiPath));
|
|
166
|
-
}
|
|
167
|
-
// TEMPORARY CODE drop on step 3 of CN-30453
|
|
168
|
-
if (config.reports) {
|
|
169
|
-
app.get('/logo/reports/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.reports) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath || (0, path_1.join)(__dirname, 'logo.png')); });
|
|
170
|
-
app.use('/reports', express_1.default.static(config.reports.uiPath));
|
|
150
|
+
app.use('/tools', (0, ui_module_1.default)(config), express_1.default.static(config.projectTools.uiPath));
|
|
171
151
|
}
|
|
172
|
-
// END OF TEMPORARY CODE
|
|
173
152
|
if (config.projectReports) {
|
|
174
153
|
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')); });
|
|
175
|
-
app.use('/reports', express_1.default.static(config.projectReports.uiPath));
|
|
154
|
+
app.use('/reports', (0, ui_module_1.default)(config), express_1.default.static(config.projectReports.uiPath));
|
|
176
155
|
}
|
|
177
156
|
return {
|
|
178
157
|
getMetadata: storage.getMetadata,
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import Crowdin from '@crowdin/crowdin-api-client';
|
|
3
3
|
import { Response } from 'express';
|
|
4
4
|
import { Config, CrowdinContextInfo } from '../models';
|
|
5
|
-
export declare function prepareCrowdinRequest(jwtToken: string, config: Config, optional?: boolean): Promise<{
|
|
5
|
+
export declare function prepareCrowdinRequest(jwtToken: string, config: Config, optional?: boolean, checkSubscriptionExpiration?: boolean): Promise<{
|
|
6
6
|
context: CrowdinContextInfo;
|
|
7
7
|
client?: Crowdin;
|
|
8
8
|
}>;
|
|
9
|
-
export default function handle(config: Config, optional?: boolean): (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;
|
|
9
|
+
export default function handle(config: Config, optional?: boolean, checkSubscriptionExpiration?: boolean): (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;
|