@crowdin/app-project-module 0.66.1 → 0.68.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.
Files changed (45) hide show
  1. package/README.md +3 -17
  2. package/out/index.js +25 -10
  3. package/out/middlewares/crowdin-client.d.ts +13 -2
  4. package/out/middlewares/crowdin-client.js +17 -3
  5. package/out/middlewares/ui-module.d.ts +5 -1
  6. package/out/middlewares/ui-module.js +5 -1
  7. package/out/modules/ai-prompt-provider/index.js +7 -2
  8. package/out/modules/ai-provider/handlers/chat-completions.js +75 -5
  9. package/out/modules/ai-provider/handlers/get-model-list.js +3 -2
  10. package/out/modules/ai-provider/index.js +13 -3
  11. package/out/modules/ai-provider/types.d.ts +5 -2
  12. package/out/modules/ai-tools/index.js +7 -2
  13. package/out/modules/ai-tools/types.d.ts +2 -2
  14. package/out/modules/api/api.js +66 -11
  15. package/out/modules/context-menu/index.js +1 -1
  16. package/out/modules/custom-mt/index.js +6 -1
  17. package/out/modules/custom-mt/types.d.ts +4 -2
  18. package/out/modules/custom-spell-check/index.js +14 -4
  19. package/out/modules/custom-spell-check/types.d.ts +2 -2
  20. package/out/modules/editor-right-panel/index.js +1 -1
  21. package/out/modules/external-qa-check/index.js +7 -2
  22. package/out/modules/external-qa-check/types.d.ts +2 -2
  23. package/out/modules/file-processing/index.js +30 -5
  24. package/out/modules/file-processing/types.d.ts +3 -2
  25. package/out/modules/file-processing/util/files.d.ts +1 -0
  26. package/out/modules/install.js +10 -2
  27. package/out/modules/integration/index.js +109 -18
  28. package/out/modules/integration/types.d.ts +2 -2
  29. package/out/modules/manifest.js +48 -22
  30. package/out/modules/modal/index.js +1 -1
  31. package/out/modules/organization-menu/index.js +1 -1
  32. package/out/modules/profile-resources-menu/index.js +1 -1
  33. package/out/modules/project-menu/index.js +1 -1
  34. package/out/modules/project-menu-crowdsource/index.js +1 -1
  35. package/out/modules/project-reports/index.js +1 -1
  36. package/out/modules/project-tools/index.js +1 -1
  37. package/out/static/css/crowdin-ui-colors.css +115 -0
  38. package/out/static/js/form.js +10 -10
  39. package/out/types.d.ts +16 -2
  40. package/out/util/handlebars.js +2 -2
  41. package/out/util/index.d.ts +0 -1
  42. package/out/util/index.js +1 -9
  43. package/out/views/main.handlebars +3 -19
  44. package/out/views/partials/head.handlebars +1 -0
  45. package/package.json +12 -12
@@ -17,14 +17,24 @@ function register({ config, app }) {
17
17
  }
18
18
  if ((0, util_1.isAuthorizedConfig)(config)) {
19
19
  if (config.customSpellchecker.settingsUiModule) {
20
- app.use('/settings', (0, ui_module_1.default)(config), (0, render_ui_module_1.default)(config.customSpellchecker.settingsUiModule));
20
+ app.use('/settings', (0, ui_module_1.default)({ config, moduleType: config.customSpellchecker.key }), (0, render_ui_module_1.default)(config.customSpellchecker.settingsUiModule));
21
21
  }
22
- app.get('/languages', json_response_1.default, (0, crowdin_client_1.default)(config), (0, get_languages_list_1.default)(config.customSpellchecker));
23
- app.post('/spellcheck', json_response_1.default, (0, crowdin_client_1.default)(config), (0, spell_check_1.default)(config.customSpellchecker));
22
+ app.get('/languages', json_response_1.default, (0, crowdin_client_1.default)({
23
+ config,
24
+ optional: false,
25
+ checkSubscriptionExpiration: true,
26
+ moduleKey: config.customSpellchecker.key,
27
+ }), (0, get_languages_list_1.default)(config.customSpellchecker));
28
+ app.post('/spellcheck', json_response_1.default, (0, crowdin_client_1.default)({
29
+ config,
30
+ optional: false,
31
+ checkSubscriptionExpiration: true,
32
+ moduleKey: config.customSpellchecker.key,
33
+ }), (0, spell_check_1.default)(config.customSpellchecker));
24
34
  return;
25
35
  }
26
36
  if (config.customSpellchecker.settingsUiModule) {
27
- app.use('/settings', (0, ui_module_1.default)(config, true), (0, render_ui_module_1.default)(config.customSpellchecker.settingsUiModule));
37
+ app.use('/settings', (0, ui_module_1.default)({ config, allowUnauthorized: true, moduleType: config.customSpellchecker.key }), (0, render_ui_module_1.default)(config.customSpellchecker.settingsUiModule));
28
38
  }
29
39
  app.get('/languages', json_response_1.default, (0, get_languages_list_1.default)(config.customSpellchecker));
30
40
  app.post('/spellcheck', json_response_1.default, (0, spell_check_1.default)(config.customSpellchecker));
@@ -1,5 +1,5 @@
1
1
  import Crowdin from '@crowdin/crowdin-api-client';
2
- import { CrowdinContextInfo, Environments, UiModule } from '../../types';
2
+ import { CrowdinContextInfo, Environments, ModuleKey, UiModule } from '../../types';
3
3
  export interface CustomSpellCheckRequest {
4
4
  language: string;
5
5
  texts: string[];
@@ -24,7 +24,7 @@ export interface CustomSpellCheckResponse {
24
24
  }[];
25
25
  error?: string;
26
26
  }
27
- export interface CustomSpellcheckerModule extends Environments {
27
+ export interface CustomSpellcheckerModule extends Environments, ModuleKey {
28
28
  /**
29
29
  * module description
30
30
  */
@@ -12,6 +12,6 @@ function register({ config, app }) {
12
12
  return;
13
13
  }
14
14
  const allowUnauthorized = !(0, util_1.isAuthorizedConfig)(config);
15
- app.use('/editor-panels', (0, ui_module_1.default)(config, allowUnauthorized), (0, render_ui_module_1.default)(config.editorRightPanel));
15
+ app.use('/editor-panels', (0, ui_module_1.default)({ config, allowUnauthorized, moduleType: config.editorRightPanel.key }), (0, render_ui_module_1.default)(config.editorRightPanel));
16
16
  }
17
17
  exports.register = register;
@@ -19,9 +19,14 @@ function register({ config, app }) {
19
19
  res.send({ data: { size: qaCheck.batchSize } });
20
20
  });
21
21
  }
22
- app.use('/validate', json_response_1.default, (0, crowdin_client_1.default)(config), (0, validate_1.default)(qaCheck));
22
+ app.use('/validate', json_response_1.default, (0, crowdin_client_1.default)({
23
+ config,
24
+ optional: false,
25
+ checkSubscriptionExpiration: true,
26
+ moduleKey: qaCheck.key,
27
+ }), (0, validate_1.default)(qaCheck));
23
28
  if (qaCheck.settingsUiModule) {
24
- app.use('/settings', (0, ui_module_1.default)(config, true), (0, render_ui_module_1.default)(qaCheck.settingsUiModule));
29
+ app.use('/settings', (0, ui_module_1.default)({ config, allowUnauthorized: true, moduleType: qaCheck.key }), (0, render_ui_module_1.default)(qaCheck.settingsUiModule));
25
30
  }
26
31
  }
27
32
  exports.register = register;
@@ -1,6 +1,6 @@
1
- import { CrowdinContextInfo, Environments, UiModule } from '../../types';
1
+ import { CrowdinContextInfo, Environments, ModuleKey, UiModule } from '../../types';
2
2
  import Crowdin, { SourceFilesModel, ProjectsGroupsModel, LanguagesModel, SourceStringsModel, StringTranslationsModel } from '@crowdin/crowdin-api-client';
3
- export interface ExternalQaCheckModule extends Environments {
3
+ export interface ExternalQaCheckModule extends Environments, ModuleKey {
4
4
  /**
5
5
  * module description
6
6
  */
@@ -15,7 +15,12 @@ function registerCustomFileFormat({ config, app }) {
15
15
  return;
16
16
  }
17
17
  (0, defaults_1.applyFileProcessorsModuleDefaults)(config, config.customFileFormat);
18
- app.post('/process', (0, crowdin_client_1.default)(config), (0, custom_file_format_1.default)(config.baseUrl, config.customFileFormat.filesFolder || config.dbFolder, config.customFileFormat));
18
+ app.post('/process', (0, crowdin_client_1.default)({
19
+ config,
20
+ optional: false,
21
+ checkSubscriptionExpiration: true,
22
+ moduleKey: config.customFileFormat.key,
23
+ }), (0, custom_file_format_1.default)(config.baseUrl, config.customFileFormat.filesFolder || config.dbFolder, config.customFileFormat));
19
24
  app.get('/file/download', (0, file_download_1.default)(config, config.customFileFormat, 'custom-file-format'));
20
25
  }
21
26
  exports.registerCustomFileFormat = registerCustomFileFormat;
@@ -24,7 +29,12 @@ function registerFilePreImport({ config, app }) {
24
29
  return;
25
30
  }
26
31
  (0, defaults_1.applyFileProcessorsModuleDefaults)(config, config.filePreImport);
27
- app.post('/pre-import', (0, crowdin_client_1.default)(config), (0, pre_post_process_1.default)(config, config.filePreImport, types_1.ProcessFileJobType.PRE_IMPORT));
32
+ app.post('/pre-import', (0, crowdin_client_1.default)({
33
+ config,
34
+ optional: false,
35
+ checkSubscriptionExpiration: true,
36
+ moduleKey: config.filePreImport.key,
37
+ }), (0, pre_post_process_1.default)(config, config.filePreImport, types_1.ProcessFileJobType.PRE_IMPORT));
28
38
  app.get(`/file/download/${types_1.ProcessFileJobType.PRE_IMPORT}`, (0, file_download_1.default)(config, config.filePreImport, types_1.ProcessFileJobType.PRE_IMPORT));
29
39
  }
30
40
  exports.registerFilePreImport = registerFilePreImport;
@@ -33,7 +43,12 @@ function registerFilePostImport({ config, app }) {
33
43
  return;
34
44
  }
35
45
  (0, defaults_1.applyFileProcessorsModuleDefaults)(config, config.filePostImport);
36
- app.post('/post-import', (0, crowdin_client_1.default)(config), (0, pre_post_process_1.default)(config, config.filePostImport, types_1.ProcessFileJobType.POST_IMPORT));
46
+ app.post('/post-import', (0, crowdin_client_1.default)({
47
+ config,
48
+ optional: false,
49
+ checkSubscriptionExpiration: true,
50
+ moduleKey: config.filePostImport.key,
51
+ }), (0, pre_post_process_1.default)(config, config.filePostImport, types_1.ProcessFileJobType.POST_IMPORT));
37
52
  app.get(`/file/download/${types_1.ProcessFileJobType.POST_IMPORT}`, (0, file_download_1.default)(config, config.filePostImport, types_1.ProcessFileJobType.POST_IMPORT));
38
53
  }
39
54
  exports.registerFilePostImport = registerFilePostImport;
@@ -42,7 +57,12 @@ function registerFilePreExport({ config, app }) {
42
57
  return;
43
58
  }
44
59
  (0, defaults_1.applyFileProcessorsModuleDefaults)(config, config.filePreExport);
45
- app.post('/pre-export', (0, crowdin_client_1.default)(config), (0, pre_post_process_1.default)(config, config.filePreExport, types_1.ProcessFileJobType.PRE_EXPORT));
60
+ app.post('/pre-export', (0, crowdin_client_1.default)({
61
+ config,
62
+ optional: false,
63
+ checkSubscriptionExpiration: true,
64
+ moduleKey: config.filePreExport.key,
65
+ }), (0, pre_post_process_1.default)(config, config.filePreExport, types_1.ProcessFileJobType.PRE_EXPORT));
46
66
  app.get(`/file/download/${types_1.ProcessFileJobType.PRE_EXPORT}`, (0, file_download_1.default)(config, config.filePreExport, types_1.ProcessFileJobType.PRE_EXPORT));
47
67
  }
48
68
  exports.registerFilePreExport = registerFilePreExport;
@@ -51,7 +71,12 @@ function registerFilePostExport({ config, app }) {
51
71
  return;
52
72
  }
53
73
  (0, defaults_1.applyFileProcessorsModuleDefaults)(config, config.filePostExport);
54
- app.post('/post-export', (0, crowdin_client_1.default)(config), (0, pre_post_process_1.default)(config, config.filePostExport, types_1.ProcessFileJobType.POST_EXPORT));
74
+ app.post('/post-export', (0, crowdin_client_1.default)({
75
+ config,
76
+ optional: false,
77
+ checkSubscriptionExpiration: true,
78
+ moduleKey: config.filePostExport.key,
79
+ }), (0, pre_post_process_1.default)(config, config.filePostExport, types_1.ProcessFileJobType.POST_EXPORT));
55
80
  app.get(`/file/download/${types_1.ProcessFileJobType.POST_EXPORT}`, (0, file_download_1.default)(config, config.filePostExport, types_1.ProcessFileJobType.POST_EXPORT));
56
81
  }
57
82
  exports.registerFilePostExport = registerFilePostExport;
@@ -1,7 +1,8 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import Crowdin, { LanguagesModel, SourceStringsModel } from '@crowdin/crowdin-api-client';
3
- import { CrowdinContextInfo, SignaturePatterns } from '../../types';
4
- export interface FileProcessLogic {
4
+ import { CrowdinContextInfo, ModuleKey, SignaturePatterns } from '../../types';
5
+ export interface FileProcessLogic extends ModuleKey {
5
6
  /**
6
7
  * Folder where larger file will be temporary stored (default "{@link dbFolder}/custom-file-format")
7
8
  */
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { ProcessFileString } from '../types';
3
4
  export declare const MAX_BODY_SIZE: number;
4
5
  export declare function storeFile(fileContent: Buffer, folder: string): Promise<string>;
@@ -14,16 +14,19 @@ const types_1 = require("../types");
14
14
  const storage_1 = require("../storage");
15
15
  const util_1 = require("../util");
16
16
  const logger_1 = require("../util/logger");
17
+ const connection_1 = require("../util/connection");
17
18
  function handle(config) {
18
19
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
19
20
  const event = req.body;
20
21
  (0, logger_1.log)(`Received install request ${JSON.stringify(event, null, 2)}`);
21
22
  const token = yield fetchToken(config, event);
23
+ const userId = event.userId;
24
+ const organization = (event.domain || event.organizationId).toString();
22
25
  const credentials = {
23
- id: (event.domain || event.organizationId).toString(),
26
+ id: organization,
24
27
  appSecret: event.appSecret,
25
28
  domain: event.domain,
26
- userId: event.userId,
29
+ userId,
27
30
  agentId: event.agentId,
28
31
  organizationId: event.organizationId,
29
32
  baseUrl: event.baseUrl,
@@ -41,6 +44,11 @@ function handle(config) {
41
44
  yield (0, storage_1.getStorage)().saveCrowdinCredentials(credentials);
42
45
  (0, logger_1.log)('A new App has been installed');
43
46
  }
47
+ if (config.onInstall) {
48
+ const { client } = yield (0, connection_1.prepareCrowdinClient)({ config, credentials, autoRenew: true });
49
+ (0, logger_1.log)('Invoking onInstall hook');
50
+ yield config.onInstall({ organization, userId, client });
51
+ }
44
52
  res.status(204).end();
45
53
  }));
46
54
  }
@@ -74,26 +74,111 @@ function register({ config, app }) {
74
74
  }
75
75
  (0, defaults_1.applyIntegrationModuleDefaults)(config, integrationLogic);
76
76
  app.get((0, util_1.getLogoUrl)(integrationLogic, '/integration'), (req, res) => res.sendFile(integrationLogic.imagePath || config.imagePath));
77
- app.get('/', (0, crowdin_client_1.default)(config, true, false), (0, integration_credentials_1.default)(config, integrationLogic, true), (0, main_1.default)(config, integrationLogic));
78
- app.get('/api/subscription-info', json_response_1.default, (0, crowdin_client_1.default)(config), (0, subscription_info_1.default)(config));
79
- app.get('/api/jobs', json_response_1.default, (0, crowdin_client_1.default)(config), (0, job_info_1.default)());
80
- app.delete('/api/jobs', json_response_1.default, (0, crowdin_client_1.default)(config), (0, job_cancel_1.default)());
81
- app.post('/api/settings', (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, settings_save_1.default)(config, integrationLogic));
82
- app.post('/api/login', (0, crowdin_client_1.default)(config, false, false), (0, integration_login_1.default)(config, integrationLogic));
83
- 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));
84
- 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));
85
- app.get('/api/crowdin/project', json_response_1.default, (0, crowdin_client_1.default)(config), (0, crowdin_project_1.default)());
86
- app.get('/api/crowdin/file-progress/:fileId', (0, crowdin_client_1.default)(config), (0, crowdin_file_progress_1.default)(integrationLogic));
87
- app.get('/api/integration/data', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, integration_data_1.default)(integrationLogic));
88
- app.post('/api/crowdin/update', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, crowdin_update_1.default)(config, integrationLogic));
89
- app.post('/api/integration/update', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, integration_update_1.default)(config, integrationLogic));
90
- 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)());
91
- 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, integrationLogic));
77
+ app.get('/', (0, crowdin_client_1.default)({
78
+ config,
79
+ optional: true,
80
+ checkSubscriptionExpiration: false,
81
+ moduleKey: integrationLogic.key,
82
+ }), (0, integration_credentials_1.default)(config, integrationLogic, true), (0, main_1.default)(config, integrationLogic));
83
+ app.get('/api/subscription-info', json_response_1.default, (0, crowdin_client_1.default)({
84
+ config,
85
+ optional: false,
86
+ checkSubscriptionExpiration: true,
87
+ moduleKey: integrationLogic.key,
88
+ }), (0, subscription_info_1.default)(config));
89
+ app.get('/api/jobs', json_response_1.default, (0, crowdin_client_1.default)({
90
+ config,
91
+ optional: false,
92
+ checkSubscriptionExpiration: true,
93
+ moduleKey: integrationLogic.key,
94
+ }), (0, job_info_1.default)());
95
+ app.delete('/api/jobs', json_response_1.default, (0, crowdin_client_1.default)({
96
+ config,
97
+ optional: false,
98
+ checkSubscriptionExpiration: true,
99
+ moduleKey: integrationLogic.key,
100
+ }), (0, job_cancel_1.default)());
101
+ app.post('/api/settings', (0, crowdin_client_1.default)({
102
+ config,
103
+ optional: false,
104
+ checkSubscriptionExpiration: true,
105
+ moduleKey: integrationLogic.key,
106
+ }), (0, integration_credentials_1.default)(config, integrationLogic), (0, settings_save_1.default)(config, integrationLogic));
107
+ app.post('/api/login', (0, crowdin_client_1.default)({
108
+ config,
109
+ optional: false,
110
+ checkSubscriptionExpiration: false,
111
+ moduleKey: integrationLogic.key,
112
+ }), (0, integration_login_1.default)(config, integrationLogic));
113
+ app.post('/api/logout', (0, crowdin_client_1.default)({
114
+ config,
115
+ optional: false,
116
+ checkSubscriptionExpiration: false,
117
+ moduleKey: integrationLogic.key,
118
+ }), (0, integration_credentials_1.default)(config, integrationLogic), (0, integration_logout_1.default)(config, integrationLogic));
119
+ app.get('/api/crowdin/files', json_response_1.default, (0, crowdin_client_1.default)({
120
+ config,
121
+ optional: false,
122
+ checkSubscriptionExpiration: true,
123
+ moduleKey: integrationLogic.key,
124
+ }), (0, integration_credentials_1.default)(config, integrationLogic), (0, crowdin_files_1.default)(config, integrationLogic));
125
+ app.get('/api/crowdin/project', json_response_1.default, (0, crowdin_client_1.default)({
126
+ config,
127
+ optional: false,
128
+ checkSubscriptionExpiration: true,
129
+ moduleKey: integrationLogic.key,
130
+ }), (0, crowdin_project_1.default)());
131
+ app.get('/api/crowdin/file-progress/:fileId', (0, crowdin_client_1.default)({
132
+ config,
133
+ optional: false,
134
+ checkSubscriptionExpiration: true,
135
+ moduleKey: integrationLogic.key,
136
+ }), (0, crowdin_file_progress_1.default)(integrationLogic));
137
+ app.get('/api/integration/data', json_response_1.default, (0, crowdin_client_1.default)({
138
+ config,
139
+ optional: false,
140
+ checkSubscriptionExpiration: true,
141
+ moduleKey: integrationLogic.key,
142
+ }), (0, integration_credentials_1.default)(config, integrationLogic), (0, integration_data_1.default)(integrationLogic));
143
+ app.post('/api/crowdin/update', json_response_1.default, (0, crowdin_client_1.default)({
144
+ config,
145
+ optional: false,
146
+ checkSubscriptionExpiration: true,
147
+ moduleKey: integrationLogic.key,
148
+ }), (0, integration_credentials_1.default)(config, integrationLogic), (0, crowdin_update_1.default)(config, integrationLogic));
149
+ app.post('/api/integration/update', json_response_1.default, (0, crowdin_client_1.default)({
150
+ config,
151
+ optional: false,
152
+ checkSubscriptionExpiration: true,
153
+ moduleKey: integrationLogic.key,
154
+ }), (0, integration_credentials_1.default)(config, integrationLogic), (0, integration_update_1.default)(config, integrationLogic));
155
+ app.get('/api/sync-settings/:provider', json_response_1.default, (0, crowdin_client_1.default)({
156
+ config,
157
+ optional: false,
158
+ checkSubscriptionExpiration: true,
159
+ moduleKey: integrationLogic.key,
160
+ }), (0, integration_credentials_1.default)(config, integrationLogic), (0, sync_settings_1.default)());
161
+ app.post('/api/sync-settings', json_response_1.default, (0, crowdin_client_1.default)({
162
+ config,
163
+ optional: false,
164
+ checkSubscriptionExpiration: true,
165
+ moduleKey: integrationLogic.key,
166
+ }), (0, integration_credentials_1.default)(config, integrationLogic), (0, sync_settings_save_1.default)(config, integrationLogic));
92
167
  if (integrationLogic.oauthLogin) {
93
168
  app.get((0, defaults_1.getOauthRoute)(integrationLogic), (0, oauth_login_1.default)(config, integrationLogic));
94
- app.post('/api/oauth-url', json_response_1.default, (0, crowdin_client_1.default)(config, false, false), (0, oauth_url_1.default)(config, integrationLogic));
169
+ app.post('/api/oauth-url', json_response_1.default, (0, crowdin_client_1.default)({
170
+ config,
171
+ optional: false,
172
+ checkSubscriptionExpiration: false,
173
+ moduleKey: integrationLogic.key,
174
+ }), (0, oauth_url_1.default)(config, integrationLogic));
95
175
  if (integrationLogic.oauthLogin.mode === 'polling') {
96
- app.post('/api/oauth-polling', json_response_1.default, (0, crowdin_client_1.default)(config, false, false), (0, oauth_polling_1.default)(integrationLogic));
176
+ app.post('/api/oauth-polling', json_response_1.default, (0, crowdin_client_1.default)({
177
+ config,
178
+ optional: false,
179
+ checkSubscriptionExpiration: false,
180
+ moduleKey: integrationLogic.key,
181
+ }), (0, oauth_polling_1.default)(integrationLogic));
97
182
  }
98
183
  }
99
184
  if (integrationLogic.cronJobs) {
@@ -106,6 +191,7 @@ function register({ config, app }) {
106
191
  cron.schedule('0 */3 * * *', () => (0, cron_1.filesCron)({ config, integration: integrationLogic, period: '3' }).catch(console.error));
107
192
  cron.schedule('0 */6 * * *', () => (0, cron_1.filesCron)({ config, integration: integrationLogic, period: '6' }).catch(console.error));
108
193
  cron.schedule('0 */12 * * *', () => (0, cron_1.filesCron)({ config, integration: integrationLogic, period: '12' }).catch(console.error));
194
+ cron.schedule('0 0 * * *', () => (0, cron_1.filesCron)({ config, integration: integrationLogic, period: '24' }).catch(console.error));
109
195
  }
110
196
  // remove user errors
111
197
  cron.schedule('0 0 * * *', () => __awaiter(this, void 0, void 0, function* () {
@@ -130,7 +216,12 @@ function register({ config, app }) {
130
216
  });
131
217
  }
132
218
  }
133
- app.get('/api/user-errors', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, user_errors_1.default)());
219
+ app.get('/api/user-errors', json_response_1.default, (0, crowdin_client_1.default)({
220
+ config,
221
+ optional: false,
222
+ checkSubscriptionExpiration: true,
223
+ moduleKey: integrationLogic.key,
224
+ }), (0, integration_credentials_1.default)(config, integrationLogic), (0, user_errors_1.default)());
134
225
  cron.schedule('0 0 1 * *', () => (0, cron_1.removeFinishedJobs)());
135
226
  }
136
227
  exports.register = register;
@@ -1,8 +1,8 @@
1
1
  import Crowdin, { SourceFilesModel, TranslationStatusModel } from '@crowdin/crowdin-api-client';
2
2
  import { Request } from 'express';
3
- import { CrowdinClientRequest } from '../../types';
3
+ import { CrowdinClientRequest, ModuleKey } from '../../types';
4
4
  import { JobClient } from './util/types';
5
- export interface IntegrationLogic {
5
+ export interface IntegrationLogic extends ModuleKey {
6
6
  /**
7
7
  * Customize your app login form
8
8
  */
@@ -14,16 +14,18 @@ function normalizeEnvironments(environments) {
14
14
  function handle(config) {
15
15
  const modules = {};
16
16
  if (config.projectIntegration) {
17
+ config.projectIntegration.key = config.identifier + '-int';
17
18
  modules['project-integrations'] = [
18
- Object.assign({ key: config.identifier + '-int', name: config.name, description: config.description, logo: (0, util_1.getLogoUrl)(config.projectIntegration, '/integration'), url: '/' }, (!!config.projectIntegration.environments && {
19
+ Object.assign({ key: config.projectIntegration.key, name: config.name, description: config.description, logo: (0, util_1.getLogoUrl)(config.projectIntegration, '/integration'), url: '/' }, (!!config.projectIntegration.environments && {
19
20
  environments: normalizeEnvironments(config.projectIntegration.environments),
20
21
  })),
21
22
  ];
22
23
  }
23
24
  if (config.customFileFormat) {
25
+ config.customFileFormat.key = config.identifier + '-ff';
24
26
  modules['custom-file-format'] = [
25
27
  {
26
- key: config.identifier + '-ff',
28
+ key: config.customFileFormat.key,
27
29
  type: config.customFileFormat.type,
28
30
  stringsExport: !!config.customFileFormat.stringsExport,
29
31
  multilingual: !!config.customFileFormat.multilingual,
@@ -36,52 +38,62 @@ function handle(config) {
36
38
  ];
37
39
  }
38
40
  if (config.filePreImport) {
41
+ config.filePreImport.key = config.identifier + '-pri';
39
42
  modules['file-pre-import'] = [
40
43
  {
41
- key: config.identifier + '-pri',
44
+ key: config.filePreImport.key,
42
45
  signaturePatterns: config.filePreImport.signaturePatterns,
43
46
  url: '/pre-import',
44
47
  },
45
48
  ];
46
49
  }
47
50
  if (config.filePostImport) {
51
+ config.filePostImport.key = config.identifier + '-poi';
48
52
  modules['file-post-import'] = [
49
53
  {
50
- key: config.identifier + '-poi',
54
+ key: config.filePostImport.key,
51
55
  signaturePatterns: config.filePostImport.signaturePatterns,
52
56
  url: '/post-import',
53
57
  },
54
58
  ];
55
59
  }
56
60
  if (config.filePreExport) {
61
+ config.filePreExport.key = config.identifier + '-pre';
57
62
  modules['file-pre-export'] = [
58
63
  {
59
- key: config.identifier + '-pre',
64
+ key: config.filePreExport.key,
60
65
  signaturePatterns: config.filePreExport.signaturePatterns,
61
66
  url: '/pre-export',
62
67
  },
63
68
  ];
64
69
  }
65
70
  if (config.filePostExport) {
71
+ config.filePostExport.key = config.identifier + '-poe';
66
72
  modules['file-post-export'] = [
67
73
  {
68
- key: config.identifier + '-poe',
74
+ key: config.filePostExport.key,
69
75
  signaturePatterns: config.filePostExport.signaturePatterns,
70
76
  url: '/post-export',
71
77
  },
72
78
  ];
73
79
  }
74
80
  if (config.customMT) {
81
+ config.customMT.key = config.identifier + '-mt';
75
82
  modules['custom-mt'] = [
76
- Object.assign({ key: config.identifier + '-mt', name: config.name, logo: (0, util_1.getLogoUrl)(config.customMT, '/mt'), url: '/translate', withContext: !!config.customMT.withContext }, (!!config.customMT.environments && {
83
+ Object.assign(Object.assign(Object.assign({ key: config.customMT.key, name: config.name, logo: (0, util_1.getLogoUrl)(config.customMT, '/mt'), url: '/translate', withContext: !!config.customMT.withContext }, (config.customMT.batchSize !== null && {
84
+ batchSize: config.customMT.batchSize,
85
+ })), (config.customMT.maskEntities !== null && {
86
+ maskEntities: config.customMT.maskEntities,
87
+ })), (!!config.customMT.environments && {
77
88
  environments: normalizeEnvironments(config.customMT.environments),
78
89
  })),
79
90
  ];
80
91
  }
81
92
  if (config.organizationMenu) {
93
+ config.organizationMenu.key = config.identifier + '-resources';
82
94
  modules['organization-menu'] = [
83
95
  {
84
- key: config.identifier + '-resources',
96
+ key: config.organizationMenu.key,
85
97
  name: config.organizationMenu.name || config.name,
86
98
  url: '/resources/' + (config.organizationMenu.fileName || 'index.html'),
87
99
  icon: (0, util_1.getLogoUrl)(config.organizationMenu, '/resources'),
@@ -89,46 +101,52 @@ function handle(config) {
89
101
  ];
90
102
  }
91
103
  if (config.profileResourcesMenu) {
104
+ config.profileResourcesMenu.key = config.identifier + '-profile-resources-menu';
92
105
  modules['profile-resources-menu'] = [
93
- Object.assign({ key: config.identifier + '-profile-resources-menu', name: config.profileResourcesMenu.name || config.name, url: '/resources/' + (config.profileResourcesMenu.fileName || 'index.html'), icon: (0, util_1.getLogoUrl)(config.profileResourcesMenu, '/resources') }, (!!config.profileResourcesMenu.environments && {
106
+ Object.assign({ key: config.profileResourcesMenu.key, name: config.profileResourcesMenu.name || config.name, url: '/resources/' + (config.profileResourcesMenu.fileName || 'index.html'), icon: (0, util_1.getLogoUrl)(config.profileResourcesMenu, '/resources') }, (!!config.profileResourcesMenu.environments && {
94
107
  environments: normalizeEnvironments(config.profileResourcesMenu.environments),
95
108
  })),
96
109
  ];
97
110
  }
98
111
  if (config.editorRightPanel) {
112
+ config.editorRightPanel.key = config.identifier + '-editor-panels';
99
113
  modules['editor-right-panel'] = [
100
- Object.assign({ key: config.identifier + '-editor-panels', name: config.editorRightPanel.name || config.name, url: '/editor-panels/' + (config.editorRightPanel.fileName || 'index.html'), modes: config.editorRightPanel.modes }, (!!config.editorRightPanel.environments && {
114
+ Object.assign({ key: config.editorRightPanel.key, name: config.editorRightPanel.name || config.name, url: '/editor-panels/' + (config.editorRightPanel.fileName || 'index.html'), modes: config.editorRightPanel.modes }, (!!config.editorRightPanel.environments && {
101
115
  environments: normalizeEnvironments(config.editorRightPanel.environments),
102
116
  })),
103
117
  ];
104
118
  }
105
119
  if (config.projectMenu) {
120
+ config.projectMenu.key = config.identifier + '-project-menu';
106
121
  modules['project-menu'] = [
107
- Object.assign({ key: config.identifier + '-project-menu', name: config.projectMenu.name || config.name, url: '/project-menu/' + (config.projectMenu.fileName || 'index.html') }, (!!config.projectMenu.environments && {
122
+ Object.assign({ key: config.projectMenu.key, name: config.projectMenu.name || config.name, url: '/project-menu/' + (config.projectMenu.fileName || 'index.html') }, (!!config.projectMenu.environments && {
108
123
  environments: normalizeEnvironments(config.projectMenu.environments),
109
124
  })),
110
125
  ];
111
126
  }
112
127
  if (config.projectMenuCrowdsource) {
128
+ config.projectMenuCrowdsource.key = config.identifier + '-project-menu-crowdsource';
113
129
  modules['project-menu-crowdsource'] = [
114
130
  {
115
- key: config.identifier + '-project-menu-crowdsource',
131
+ key: config.projectMenuCrowdsource.key,
116
132
  name: config.projectMenuCrowdsource.name || config.name,
117
133
  url: '/project-menu-crowdsource/' + (config.projectMenuCrowdsource.fileName || 'index.html'),
118
134
  },
119
135
  ];
120
136
  }
121
137
  if (config.projectTools) {
138
+ config.projectTools.key = config.identifier + '-tools';
122
139
  modules['project-tools'] = [
123
- Object.assign({ key: config.identifier + '-tools', name: config.projectTools.name || config.name, description: config.description, logo: (0, util_1.getLogoUrl)(config.projectTools, '/tools'), url: '/tools/' + (config.projectTools.fileName || 'index.html') }, (!!config.projectTools.environments && {
140
+ Object.assign({ key: config.projectTools.key, name: config.projectTools.name || config.name, description: config.description, logo: (0, util_1.getLogoUrl)(config.projectTools, '/tools'), url: '/tools/' + (config.projectTools.fileName || 'index.html') }, (!!config.projectTools.environments && {
124
141
  environments: normalizeEnvironments(config.projectTools.environments),
125
142
  })),
126
143
  ];
127
144
  }
128
145
  if (config.projectReports) {
146
+ config.projectReports.key = config.identifier + '-project-reports';
129
147
  modules['project-reports'] = [
130
148
  {
131
- key: config.identifier + '-project-reports',
149
+ key: config.projectReports.key,
132
150
  name: config.projectReports.name || config.name,
133
151
  description: config.description,
134
152
  logo: (0, util_1.getLogoUrl)(config.projectReports, '/reports'),
@@ -137,13 +155,15 @@ function handle(config) {
137
155
  ];
138
156
  }
139
157
  if (config.modal) {
158
+ config.modal.key = config.identifier + '-modal';
140
159
  modules['modal'] = [
141
- Object.assign({ key: config.identifier + '-modal', name: config.modal.name || config.name, url: config.modal.url || '/modal/' + (config.modal.fileName || 'index.html') }, (!!config.modal.environments && { environments: normalizeEnvironments(config.modal.environments) })),
160
+ Object.assign({ key: config.modal.key, name: config.modal.name || config.name, url: config.modal.url || '/modal/' + (config.modal.fileName || 'index.html') }, (!!config.modal.environments && { environments: normalizeEnvironments(config.modal.environments) })),
142
161
  ];
143
162
  }
144
163
  if (config.contextMenu) {
164
+ config.contextMenu.key = config.identifier + '-context-menu';
145
165
  modules['context-menu'] = [
146
- Object.assign({ key: config.identifier + '-context-menu', name: config.contextMenu.name || config.name, description: config.description, options: Object.assign(Object.assign({ location: config.contextMenu.location, type: config.contextMenu.type }, (config.contextMenu.module
166
+ Object.assign({ key: config.contextMenu.key, name: config.contextMenu.name || config.name, description: config.description, options: Object.assign(Object.assign({ location: config.contextMenu.location, type: config.contextMenu.type }, (config.contextMenu.module
147
167
  ? {
148
168
  module: {
149
169
  [config.contextMenu.module]: modules[config.contextMenu.module][0].key,
@@ -158,24 +178,27 @@ function handle(config) {
158
178
  modules['api'] = (0, api_1.getApiManifest)(config, config.api);
159
179
  }
160
180
  if (config.customSpellchecker) {
181
+ config.customSpellchecker.key = config.identifier + '-spellchecker';
161
182
  const uiModule = config.customSpellchecker.settingsUiModule;
162
183
  modules['custom-spellchecker'] = [
163
- Object.assign(Object.assign({ key: config.identifier + '-spellchecker', name: config.customSpellchecker.name || config.name, description: config.customSpellchecker.description || config.description, listSupportedLanguagesUrl: '/languages', checkSpellingUrl: '/spellcheck' }, (!!config.customSpellchecker.environments && {
184
+ Object.assign(Object.assign({ key: config.customSpellchecker.key, name: config.customSpellchecker.name || config.name, description: config.customSpellchecker.description || config.description, listSupportedLanguagesUrl: '/languages', checkSpellingUrl: '/spellcheck' }, (!!config.customSpellchecker.environments && {
164
185
  environments: normalizeEnvironments(config.customSpellchecker.environments),
165
186
  })), (uiModule ? { url: '/settings/' + (uiModule.fileName || 'index.html') } : {})),
166
187
  ];
167
188
  }
168
189
  if (config.aiProvider) {
190
+ config.aiProvider.key = config.identifier + '-aiprovider';
169
191
  const uiModule = config.aiProvider.settingsUiModule;
170
192
  modules['ai-provider'] = [
171
- Object.assign(Object.assign({ key: config.identifier + '-aiprovider', name: config.aiProvider.name || config.name, description: config.aiProvider.description || config.description, logo: (0, util_1.getLogoUrl)(config.aiProvider, '/aiprovider'), chatCompletionsUrl: '/completions', modelsUrl: '/models' }, (!!config.aiProvider.environments && {
193
+ Object.assign(Object.assign({ key: config.aiProvider.key, name: config.aiProvider.name || config.name, description: config.aiProvider.description || config.description, logo: (0, util_1.getLogoUrl)(config.aiProvider, '/aiprovider'), chatCompletionsUrl: '/completions', modelsUrl: '/models' }, (!!config.aiProvider.environments && {
172
194
  environments: normalizeEnvironments(config.aiProvider.environments),
173
195
  })), (uiModule ? { url: '/settings/' + (uiModule.fileName || 'index.html') } : {})),
174
196
  ];
175
197
  }
176
198
  if (config.aiPromptProvider) {
199
+ config.aiPromptProvider.key = config.identifier + '-ai-prompt-provider';
177
200
  modules['ai-prompt-provider'] = [
178
- Object.assign({ key: config.identifier + '-ai-prompt-provider', name: config.aiPromptProvider.name || config.name, logo: (0, util_1.getLogoUrl)(config.aiPromptProvider, '/ai-prompt-provider'), compileUrl: '/prompt-provider/compile' }, (!!config.aiPromptProvider.formSchema
201
+ Object.assign({ key: config.aiPromptProvider.key, name: config.aiPromptProvider.name || config.name, logo: (0, util_1.getLogoUrl)(config.aiPromptProvider, '/ai-prompt-provider'), compileUrl: '/prompt-provider/compile' }, (!!config.aiPromptProvider.formSchema
179
202
  ? {
180
203
  configuratorUrl: '/prompt-provider/settings/' + (config.aiPromptProvider.fileName || 'index.html'),
181
204
  }
@@ -186,7 +209,8 @@ function handle(config) {
186
209
  const tools = Array.isArray(config.aiTools) ? config.aiTools : [config.aiTools];
187
210
  modules['ai-tools'] = [];
188
211
  for (const tool of tools) {
189
- modules['ai-tools'].push(Object.assign({ key: config.identifier + '-' + (0, util_2.getAiToolName)(tool), toolType: tool.toolType || 'function', function: tool.function, url: (0, util_2.getAiToolUrl)(tool) }, (!!tool.environments && {
212
+ tool.key = config.identifier + '-' + (0, util_2.getAiToolName)(tool);
213
+ modules['ai-tools'].push(Object.assign({ key: tool.key, toolType: tool.toolType || 'function', function: tool.function, url: (0, util_2.getAiToolUrl)(tool) }, (!!tool.environments && {
190
214
  environments: normalizeEnvironments(tool.environments),
191
215
  })));
192
216
  }
@@ -195,15 +219,17 @@ function handle(config) {
195
219
  const tools = Array.isArray(config.aiToolsWidget) ? config.aiToolsWidget : [config.aiToolsWidget];
196
220
  modules['ai-tools-widget'] = [];
197
221
  for (const tool of tools) {
198
- modules['ai-tools-widget'].push(Object.assign({ key: config.identifier + '-' + (0, util_2.getAiToolName)(tool), toolType: tool.toolType || 'function', function: tool.function, url: (0, util_2.getAiToolWidgetUrl)(tool, true) }, (!!tool.environments && {
222
+ tool.key = config.identifier + '-' + (0, util_2.getAiToolName)(tool);
223
+ modules['ai-tools-widget'].push(Object.assign({ key: tool.key, toolType: tool.toolType || 'function', function: tool.function, url: (0, util_2.getAiToolWidgetUrl)(tool, true) }, (!!tool.environments && {
199
224
  environments: normalizeEnvironments(tool.environments),
200
225
  })));
201
226
  }
202
227
  }
203
228
  if (config.externalQaCheck) {
229
+ config.externalQaCheck.key = config.identifier + '-qa-check';
204
230
  const uiModule = config.externalQaCheck.settingsUiModule;
205
231
  modules['external-qa-check'] = [
206
- Object.assign(Object.assign({ key: config.identifier + '-qa-check', name: config.externalQaCheck.name || config.name, description: config.externalQaCheck.description || config.description, runQaCheckUrl: '/validate' }, (config.externalQaCheck.batchSize ? { getBatchSizeUrl: '/batch-size' } : {})), (uiModule ? { url: '/settings/' + (uiModule.fileName || 'index.html') } : {})),
232
+ Object.assign(Object.assign({ key: config.externalQaCheck.key, name: config.externalQaCheck.name || config.name, description: config.externalQaCheck.description || config.description, runQaCheckUrl: '/validate' }, (config.externalQaCheck.batchSize ? { getBatchSizeUrl: '/batch-size' } : {})), (uiModule ? { url: '/settings/' + (uiModule.fileName || 'index.html') } : {})),
207
233
  ];
208
234
  }
209
235
  const events = {
@@ -11,7 +11,7 @@ function register({ config, app }) {
11
11
  var _a, _b;
12
12
  const allowUnauthorized = !(0, util_1.isAuthorizedConfig)(config);
13
13
  if (((_a = config.modal) === null || _a === void 0 ? void 0 : _a.uiPath) || ((_b = config.modal) === null || _b === void 0 ? void 0 : _b.formSchema)) {
14
- app.use('/modal', (0, ui_module_1.default)(config, allowUnauthorized), (0, render_ui_module_1.default)(config.modal));
14
+ app.use('/modal', (0, ui_module_1.default)({ config, allowUnauthorized, moduleType: config.modal.key }), (0, render_ui_module_1.default)(config.modal));
15
15
  }
16
16
  }
17
17
  exports.register = register;
@@ -13,6 +13,6 @@ function register({ config, app }) {
13
13
  }
14
14
  const allowUnauthorized = !(0, util_1.isAuthorizedConfig)(config);
15
15
  app.get((0, util_1.getLogoUrl)(config.organizationMenu, '/resources'), (req, res) => { var _a; return res.sendFile(((_a = config.organizationMenu) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath); });
16
- app.use('/resources', (0, ui_module_1.default)(config, allowUnauthorized), (0, render_ui_module_1.default)(config.organizationMenu));
16
+ app.use('/resources', (0, ui_module_1.default)({ config, allowUnauthorized, moduleType: config.organizationMenu.key }), (0, render_ui_module_1.default)(config.organizationMenu));
17
17
  }
18
18
  exports.register = register;