@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 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
- - [Custom login form](#customize-your-app-login-form)
35
- - [OAuth2 login](#oauth2-support)
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
- - [Error propagation](#error-propagation)
40
- - [Error interceptor](#error-interceptor)
41
- - [Debug mode](#debug-mode)
42
- - [Custom File Format](#custom-file-format)
43
- - [Custom MT](#custom-mt)
44
- - [Resources](#resources)
45
- - [Other modules](#other-modules)
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 app
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
- integration: {
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
- By default login page for your app will require only to enter `apiToken` to communicate with third party service.
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.integration.loginForm = {
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
- ## OAuth2 support
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.integration.oauthLogin = {
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.integration.oauthLogin = {
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 definied) with JSON body that will contain at least `clientId`, `clientSecret` and `refreshToken` (also possible to add extra fields via `extraRefreshTokenParameters` property)
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.integration.oauthLogin = {
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.integration.getConfiguration = (projectId, crowdinClient, integrationCredentials) => {
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.integration.infoModal = {
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.integration.cronJobs = [
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
- ## Error propagation
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.integration.checkConnection = (credentials) => {
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.integrartion.getIntegrationFiles = async (credentials, appSettings) => {
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
- ## Error interceptor
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
- ## Debug mode
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
- ## Custom File Format
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
- ## Custom MT
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
- ## Resources
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
- resources: {
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 resources module can work as an extension to other modules be something like a configuration UI for them.
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
- resources: {
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
- ## Other modules
631
+ ### Other modules
605
632
 
606
633
  Framework also supports following modules:
607
634
 
608
- - [editor-panels module](https://support.crowdin.com/crowdin-apps-modules/#editor-panels-module)
609
- - [project menu module](https://support.crowdin.com/crowdin-apps-modules/#project-menu-module)
610
- - [tools module](https://support.crowdin.com/crowdin-apps-modules/#tools-module)
611
- - [reports module](https://support.crowdin.com/crowdin-apps-modules/#reports-module)
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
- reports: { //can be editorPanels, projectMenu, tools
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, util_1.getRootFolder)(config, integration, req.crowdinApiClient, req.crowdinContext.jwtPayload.context.project_id);
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, util_1.getRootFolder)(config, integration, req.crowdinApiClient, projectId);
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, util_1.getRootFolder)(config, integration, req.crowdinApiClient, req.crowdinContext.jwtPayload.context.project_id);
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
  }
@@ -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, util_1.getOauthRoute)(integration)}`;
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
  }
@@ -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, util_1.getOauthRoute)(integration)}`;
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 util_1 = require("./util");
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, util_1.applyDefaults)(config, integrationLogic);
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, util_1.getOauthRoute)(integrationLogic), (0, oauth_login_1.default)(config, integrationLogic));
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, util_1.runJob)(config, integrationLogic, job).catch(console.error));
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, util_1.filesCron)(config, integrationLogic, '1').catch(console.error));
119
- cron.schedule('0 */3 * * *', () => (0, util_1.filesCron)(config, integrationLogic, '3').catch(console.error));
120
- cron.schedule('0 */6 * * *', () => (0, util_1.filesCron)(config, integrationLogic, '6').catch(console.error));
121
- cron.schedule('0 */12 * * *', () => (0, util_1.filesCron)(config, integrationLogic, '12').catch(console.error));
122
- cron.schedule('0 0 * * *', () => (0, util_1.filesCron)(config, integrationLogic, '24').catch(console.error));
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;