@crowdin/app-project-module 1.7.2 → 1.8.1

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.
@@ -4,6 +4,7 @@ exports.default = handle;
4
4
  const types_1 = require("../types");
5
5
  const util_1 = require("../util");
6
6
  const subscription_1 = require("../util/subscription");
7
+ const normalize_module_1 = require("../util/normalize-module");
7
8
  const api_1 = require("./api/api");
8
9
  const util_2 = require("./ai-tools/util");
9
10
  const util_3 = require("./workflow-step-type/util");
@@ -16,7 +17,6 @@ function normalizeEnvironments(environments) {
16
17
  return [environments];
17
18
  }
18
19
  function handle(config) {
19
- var _a, _b, _c;
20
20
  const modules = {};
21
21
  if (config.projectIntegration) {
22
22
  // prevent possible overrides of the other modules
@@ -28,190 +28,398 @@ function handle(config) {
28
28
  ];
29
29
  }
30
30
  if (config.customFileFormat) {
31
- // prevent possible overrides of the other modules
32
- config.customFileFormat = Object.assign(Object.assign({}, config.customFileFormat), { key: config.identifier + '-ff' });
33
- modules['custom-file-format'] = [
34
- {
35
- key: config.customFileFormat.key,
36
- type: config.customFileFormat.type,
37
- stringsExport: !!config.customFileFormat.stringsExport,
38
- multilingual: !!config.customFileFormat.multilingual,
39
- customSrxSupported: !!config.customFileFormat.customSrxSupported,
40
- extensions: config.customFileFormat.extensions,
41
- signaturePatterns: config.customFileFormat.signaturePatterns,
42
- multilingualExport: config.customFileFormat.multilingualExport,
43
- url: '/file/process',
44
- },
45
- ];
31
+ if (Array.isArray(config.customFileFormat)) {
32
+ config.customFileFormat = config.customFileFormat.map((item) => (Object.assign({}, item)));
33
+ }
34
+ else {
35
+ config.customFileFormat = Object.assign({}, config.customFileFormat);
36
+ }
37
+ const items = (0, normalize_module_1.normalizeToArray)(config.customFileFormat);
38
+ const isSingle = items.length === 1;
39
+ modules['custom-file-format'] = items.map((item, index) => {
40
+ const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'ff', item, index, isSingle });
41
+ item.key = key;
42
+ return {
43
+ key,
44
+ type: item.type,
45
+ stringsExport: !!item.stringsExport,
46
+ multilingual: !!item.multilingual,
47
+ customSrxSupported: !!item.customSrxSupported,
48
+ extensions: item.extensions,
49
+ signaturePatterns: item.signaturePatterns,
50
+ multilingualExport: item.multilingualExport,
51
+ url: isSingle ? '/file/process' : `/file/${key}/process`,
52
+ };
53
+ });
54
+ config.customFileFormat = isSingle ? items[0] : items;
46
55
  }
47
56
  if (config.filePreImport) {
48
- // prevent possible overrides of the other modules
49
- config.filePreImport = Object.assign(Object.assign({}, config.filePreImport), { key: config.identifier + '-pri' });
50
- modules['file-pre-import'] = [
51
- {
52
- key: config.filePreImport.key,
53
- signaturePatterns: config.filePreImport.signaturePatterns,
54
- url: '/pre-import',
55
- },
56
- ];
57
+ if (Array.isArray(config.filePreImport)) {
58
+ config.filePreImport = config.filePreImport.map((item) => (Object.assign({}, item)));
59
+ }
60
+ else {
61
+ config.filePreImport = Object.assign({}, config.filePreImport);
62
+ }
63
+ const items = (0, normalize_module_1.normalizeToArray)(config.filePreImport);
64
+ const isSingle = items.length === 1;
65
+ modules['file-pre-import'] = items.map((item, index) => {
66
+ const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'pri', item, index, isSingle });
67
+ item.key = key;
68
+ return {
69
+ key,
70
+ signaturePatterns: item.signaturePatterns,
71
+ url: isSingle ? '/pre-import' : `/pre-import/${key}`,
72
+ };
73
+ });
74
+ config.filePreImport = isSingle ? items[0] : items;
57
75
  }
58
76
  if (config.filePostImport) {
59
- // prevent possible overrides of the other modules
60
- config.filePostImport = Object.assign(Object.assign({}, config.filePostImport), { key: config.identifier + '-poi' });
61
- modules['file-post-import'] = [
62
- {
63
- key: config.filePostImport.key,
64
- signaturePatterns: config.filePostImport.signaturePatterns,
65
- url: '/post-import',
66
- },
67
- ];
77
+ if (Array.isArray(config.filePostImport)) {
78
+ config.filePostImport = config.filePostImport.map((item) => (Object.assign({}, item)));
79
+ }
80
+ else {
81
+ config.filePostImport = Object.assign({}, config.filePostImport);
82
+ }
83
+ const items = (0, normalize_module_1.normalizeToArray)(config.filePostImport);
84
+ const isSingle = items.length === 1;
85
+ modules['file-post-import'] = items.map((item, index) => {
86
+ const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'poi', item, index, isSingle });
87
+ item.key = key;
88
+ return {
89
+ key,
90
+ signaturePatterns: item.signaturePatterns,
91
+ url: isSingle ? '/post-import' : `/post-import/${key}`,
92
+ };
93
+ });
94
+ config.filePostImport = isSingle ? items[0] : items;
68
95
  }
69
96
  if (config.filePreExport) {
70
- // prevent possible overrides of the other modules
71
- config.filePreExport = Object.assign(Object.assign({}, config.filePreExport), { key: config.identifier + '-pre' });
72
- modules['file-pre-export'] = [
73
- {
74
- key: config.filePreExport.key,
75
- signaturePatterns: config.filePreExport.signaturePatterns,
76
- url: '/pre-export',
77
- },
78
- ];
97
+ if (Array.isArray(config.filePreExport)) {
98
+ config.filePreExport = config.filePreExport.map((item) => (Object.assign({}, item)));
99
+ }
100
+ else {
101
+ config.filePreExport = Object.assign({}, config.filePreExport);
102
+ }
103
+ const items = (0, normalize_module_1.normalizeToArray)(config.filePreExport);
104
+ const isSingle = items.length === 1;
105
+ modules['file-pre-export'] = items.map((item, index) => {
106
+ const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'pre', item, index, isSingle });
107
+ item.key = key;
108
+ return {
109
+ key,
110
+ signaturePatterns: item.signaturePatterns,
111
+ url: isSingle ? '/pre-export' : `/pre-export/${key}`,
112
+ };
113
+ });
114
+ config.filePreExport = isSingle ? items[0] : items;
79
115
  }
80
116
  if (config.filePostExport) {
81
- // prevent possible overrides of the other modules
82
- config.filePostExport = Object.assign(Object.assign({}, config.filePostExport), { key: config.identifier + '-poe' });
83
- modules['file-post-export'] = [
84
- {
85
- key: config.filePostExport.key,
86
- signaturePatterns: config.filePostExport.signaturePatterns,
87
- url: '/post-export',
88
- },
89
- ];
117
+ if (Array.isArray(config.filePostExport)) {
118
+ config.filePostExport = config.filePostExport.map((item) => (Object.assign({}, item)));
119
+ }
120
+ else {
121
+ config.filePostExport = Object.assign({}, config.filePostExport);
122
+ }
123
+ const items = (0, normalize_module_1.normalizeToArray)(config.filePostExport);
124
+ const isSingle = items.length === 1;
125
+ modules['file-post-export'] = items.map((item, index) => {
126
+ const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'poe', item, index, isSingle });
127
+ item.key = key;
128
+ return {
129
+ key,
130
+ signaturePatterns: item.signaturePatterns,
131
+ url: isSingle ? '/post-export' : `/post-export/${key}`,
132
+ };
133
+ });
134
+ config.filePostExport = isSingle ? items[0] : items;
90
135
  }
91
136
  if (config.fileTranslationsAlignmentExport) {
92
- // prevent possible overrides of the other modules
93
- config.fileTranslationsAlignmentExport = Object.assign(Object.assign({}, config.fileTranslationsAlignmentExport), { key: config.identifier + '-ftae' });
94
- modules['file-translations-alignment'] = [
95
- {
96
- key: config.fileTranslationsAlignmentExport.key,
97
- signaturePatterns: config.fileTranslationsAlignmentExport.signaturePatterns,
98
- url: '/translations-alignment',
99
- },
100
- ];
137
+ if (Array.isArray(config.fileTranslationsAlignmentExport)) {
138
+ config.fileTranslationsAlignmentExport = config.fileTranslationsAlignmentExport.map((item) => (Object.assign({}, item)));
139
+ }
140
+ else {
141
+ config.fileTranslationsAlignmentExport = Object.assign({}, config.fileTranslationsAlignmentExport);
142
+ }
143
+ const items = (0, normalize_module_1.normalizeToArray)(config.fileTranslationsAlignmentExport);
144
+ const isSingle = items.length === 1;
145
+ modules['file-translations-alignment'] = items.map((item, index) => {
146
+ const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'ftae', item, index, isSingle });
147
+ item.key = key;
148
+ return {
149
+ key,
150
+ signaturePatterns: item.signaturePatterns,
151
+ url: isSingle ? '/translations-alignment' : `/translations-alignment/${key}`,
152
+ };
153
+ });
154
+ config.fileTranslationsAlignmentExport = isSingle ? items[0] : items;
101
155
  }
102
156
  if (config.customMT) {
103
- // prevent possible overrides of the other modules
104
- config.customMT = Object.assign(Object.assign({}, config.customMT), { key: config.identifier + '-mt' });
105
- modules['custom-mt'] = [
106
- Object.assign(Object.assign(Object.assign(Object.assign({ key: config.customMT.key, name: config.name, logo: (0, util_1.getLogoUrl)(config, config.customMT, '/mt'), url: '/mt/translate', withContext: !!config.customMT.withContext }, ((0, util_1.isDefined)(config.customMT.splitStringsIntoChunks) && {
107
- splitStringsIntoChunks: config.customMT.splitStringsIntoChunks,
108
- })), ((0, util_1.isDefined)(config.customMT.batchSize) && {
109
- batchSize: config.customMT.batchSize,
110
- })), ((0, util_1.isDefined)(config.customMT.maskEntities) && {
111
- maskEntities: config.customMT.maskEntities,
112
- })), (!!config.customMT.environments && {
113
- environments: normalizeEnvironments(config.customMT.environments),
114
- })),
115
- ];
157
+ if (Array.isArray(config.customMT)) {
158
+ config.customMT = config.customMT.map((item) => (Object.assign({}, item)));
159
+ }
160
+ else {
161
+ config.customMT = Object.assign({}, config.customMT);
162
+ }
163
+ const items = (0, normalize_module_1.normalizeToArray)(config.customMT);
164
+ const isSingle = items.length === 1;
165
+ modules['custom-mt'] = items.map((item, index) => {
166
+ const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'mt', item, index, isSingle });
167
+ item.key = key;
168
+ return Object.assign(Object.assign(Object.assign(Object.assign({ key, name: config.name, logo: (0, util_1.getLogoUrl)(config, item, isSingle ? '/mt' : `/mt-${key}`), url: isSingle ? '/mt/translate' : `/mt/${key}/translate`, withContext: !!item.withContext }, ((0, util_1.isDefined)(item.splitStringsIntoChunks) && {
169
+ splitStringsIntoChunks: item.splitStringsIntoChunks,
170
+ })), ((0, util_1.isDefined)(item.batchSize) && {
171
+ batchSize: item.batchSize,
172
+ })), ((0, util_1.isDefined)(item.maskEntities) && {
173
+ maskEntities: item.maskEntities,
174
+ })), (!!item.environments && {
175
+ environments: normalizeEnvironments(item.environments),
176
+ }));
177
+ });
178
+ config.customMT = isSingle ? items[0] : items;
116
179
  }
117
180
  if (config.organizationMenu) {
118
- // prevent possible overrides of the other modules
119
- config.organizationMenu = Object.assign(Object.assign({}, config.organizationMenu), { key: config.identifier + '-resources' });
120
- modules['organization-menu'] = [
121
- {
122
- key: config.organizationMenu.key,
123
- name: config.organizationMenu.name || config.name,
124
- url: '/organization-menu/' + (config.organizationMenu.fileName || 'index.html'),
125
- icon: (0, util_1.getLogoUrl)(config, config.organizationMenu, '/resources'),
126
- },
127
- ];
181
+ if (Array.isArray(config.organizationMenu)) {
182
+ config.organizationMenu = config.organizationMenu.map((item) => (Object.assign({}, item)));
183
+ }
184
+ else {
185
+ config.organizationMenu = Object.assign({}, config.organizationMenu);
186
+ }
187
+ const items = (0, normalize_module_1.normalizeToArray)(config.organizationMenu);
188
+ const isSingle = items.length === 1;
189
+ modules['organization-menu'] = items.map((item, index) => {
190
+ const key = (0, normalize_module_1.resolveInstanceKey)({
191
+ identifier: config.identifier,
192
+ suffix: 'resources',
193
+ item,
194
+ index,
195
+ isSingle,
196
+ });
197
+ item.key = key;
198
+ const basePath = isSingle ? '/organization-menu' : `/organization-menu-${key}`;
199
+ return {
200
+ key,
201
+ name: item.name || config.name,
202
+ url: basePath + '/' + (item.fileName || 'index.html'),
203
+ icon: (0, util_1.getLogoUrl)(config, item, isSingle ? '/resources' : `/organization-menu-${key}`),
204
+ };
205
+ });
206
+ config.organizationMenu = isSingle ? items[0] : items;
128
207
  }
129
208
  if (config.organizationSettingsMenu) {
130
- // prevent possible overrides of the other modules
131
- config.organizationSettingsMenu = Object.assign(Object.assign({}, config.organizationSettingsMenu), { key: config.identifier + '-organization-settings-menu' });
132
- modules['organization-settings-menu'] = [
133
- {
134
- key: config.organizationSettingsMenu.key,
135
- name: config.organizationSettingsMenu.name || config.name,
136
- url: '/organization-settings/' + (config.organizationSettingsMenu.fileName || 'index.html'),
137
- icon: (0, util_1.getLogoUrl)(config, config.organizationSettingsMenu, '/organization-settings'),
138
- },
139
- ];
209
+ if (Array.isArray(config.organizationSettingsMenu)) {
210
+ config.organizationSettingsMenu = config.organizationSettingsMenu.map((item) => (Object.assign({}, item)));
211
+ }
212
+ else {
213
+ config.organizationSettingsMenu = Object.assign({}, config.organizationSettingsMenu);
214
+ }
215
+ const items = (0, normalize_module_1.normalizeToArray)(config.organizationSettingsMenu);
216
+ const isSingle = items.length === 1;
217
+ modules['organization-settings-menu'] = items.map((item, index) => {
218
+ const key = (0, normalize_module_1.resolveInstanceKey)({
219
+ identifier: config.identifier,
220
+ suffix: 'organization-settings-menu',
221
+ item,
222
+ index,
223
+ isSingle,
224
+ });
225
+ item.key = key;
226
+ const basePath = isSingle ? '/organization-settings' : `/organization-settings-${key}`;
227
+ return {
228
+ key,
229
+ name: item.name || config.name,
230
+ url: basePath + '/' + (item.fileName || 'index.html'),
231
+ icon: (0, util_1.getLogoUrl)(config, item, isSingle ? '/organization-settings' : `/organization-settings-${key}`),
232
+ };
233
+ });
234
+ config.organizationSettingsMenu = isSingle ? items[0] : items;
140
235
  }
141
236
  if (config.profileResourcesMenu) {
142
- // prevent possible overrides of the other modules
143
- config.profileResourcesMenu = Object.assign(Object.assign({}, config.profileResourcesMenu), { key: config.identifier + '-profile-resources-menu' });
144
- modules['profile-resources-menu'] = [
145
- Object.assign({ key: config.profileResourcesMenu.key, name: config.profileResourcesMenu.name || config.name, url: '/profile-resources/' + (config.profileResourcesMenu.fileName || 'index.html'), icon: (0, util_1.getLogoUrl)(config, config.profileResourcesMenu, '/profile-resources') }, (!!config.profileResourcesMenu.environments && {
146
- environments: normalizeEnvironments(config.profileResourcesMenu.environments),
147
- })),
148
- ];
237
+ if (Array.isArray(config.profileResourcesMenu)) {
238
+ config.profileResourcesMenu = config.profileResourcesMenu.map((item) => (Object.assign({}, item)));
239
+ }
240
+ else {
241
+ config.profileResourcesMenu = Object.assign({}, config.profileResourcesMenu);
242
+ }
243
+ const items = (0, normalize_module_1.normalizeToArray)(config.profileResourcesMenu);
244
+ const isSingle = items.length === 1;
245
+ modules['profile-resources-menu'] = items.map((item, index) => {
246
+ const key = (0, normalize_module_1.resolveInstanceKey)({
247
+ identifier: config.identifier,
248
+ suffix: 'profile-resources-menu',
249
+ item,
250
+ index,
251
+ isSingle,
252
+ });
253
+ item.key = key;
254
+ const basePath = isSingle ? '/profile-resources' : `/profile-resources-${key}`;
255
+ return Object.assign({ key, name: item.name || config.name, url: basePath + '/' + (item.fileName || 'index.html'), icon: (0, util_1.getLogoUrl)(config, item, isSingle ? '/profile-resources' : `/profile-resources-${key}`) }, (!!item.environments && {
256
+ environments: normalizeEnvironments(item.environments),
257
+ }));
258
+ });
259
+ config.profileResourcesMenu = isSingle ? items[0] : items;
149
260
  }
150
261
  if (config.profileSettingsMenu) {
151
- // prevent possible overrides of the other modules
152
- config.profileSettingsMenu = Object.assign(Object.assign({}, config.profileSettingsMenu), { key: config.identifier + '-profile-settings-menu' });
153
- modules['profile-settings-menu'] = [
154
- Object.assign({ key: config.profileSettingsMenu.key, name: config.profileSettingsMenu.name || config.name, url: '/profile-settings/' + (config.profileSettingsMenu.fileName || 'index.html'), icon: (0, util_1.getLogoUrl)(config, config.profileSettingsMenu, '/profile-settings') }, (!!config.profileSettingsMenu.environments && {
155
- environments: normalizeEnvironments(config.profileSettingsMenu.environments),
156
- })),
157
- ];
262
+ if (Array.isArray(config.profileSettingsMenu)) {
263
+ config.profileSettingsMenu = config.profileSettingsMenu.map((item) => (Object.assign({}, item)));
264
+ }
265
+ else {
266
+ config.profileSettingsMenu = Object.assign({}, config.profileSettingsMenu);
267
+ }
268
+ const items = (0, normalize_module_1.normalizeToArray)(config.profileSettingsMenu);
269
+ const isSingle = items.length === 1;
270
+ modules['profile-settings-menu'] = items.map((item, index) => {
271
+ const key = (0, normalize_module_1.resolveInstanceKey)({
272
+ identifier: config.identifier,
273
+ suffix: 'profile-settings-menu',
274
+ item,
275
+ index,
276
+ isSingle,
277
+ });
278
+ item.key = key;
279
+ const basePath = isSingle ? '/profile-settings' : `/profile-settings-${key}`;
280
+ return Object.assign({ key, name: item.name || config.name, url: basePath + '/' + (item.fileName || 'index.html'), icon: (0, util_1.getLogoUrl)(config, item, isSingle ? '/profile-settings' : `/profile-settings-${key}`) }, (!!item.environments && {
281
+ environments: normalizeEnvironments(item.environments),
282
+ }));
283
+ });
284
+ config.profileSettingsMenu = isSingle ? items[0] : items;
158
285
  }
159
286
  if (config.editorRightPanel) {
160
- // prevent possible overrides of the other modules
161
- config.editorRightPanel = Object.assign(Object.assign({}, config.editorRightPanel), { key: config.identifier + '-editor-panels' });
162
- modules['editor-right-panel'] = [
163
- Object.assign({ key: config.editorRightPanel.key, name: config.editorRightPanel.name || config.name, url: '/editor-panels/' + (config.editorRightPanel.fileName || 'index.html'), supportsMultipleStrings: (_a = config.editorRightPanel.supportsMultipleStrings) !== null && _a !== void 0 ? _a : false, modes: config.editorRightPanel.modes }, (!!config.editorRightPanel.environments && {
164
- environments: normalizeEnvironments(config.editorRightPanel.environments),
165
- })),
166
- ];
287
+ if (Array.isArray(config.editorRightPanel)) {
288
+ config.editorRightPanel = config.editorRightPanel.map((item) => (Object.assign({}, item)));
289
+ }
290
+ else {
291
+ config.editorRightPanel = Object.assign({}, config.editorRightPanel);
292
+ }
293
+ const items = (0, normalize_module_1.normalizeToArray)(config.editorRightPanel);
294
+ const isSingle = items.length === 1;
295
+ modules['editor-right-panel'] = items.map((item, index) => {
296
+ var _a;
297
+ const key = (0, normalize_module_1.resolveInstanceKey)({
298
+ identifier: config.identifier,
299
+ suffix: 'editor-panels',
300
+ item,
301
+ index,
302
+ isSingle,
303
+ });
304
+ item.key = key;
305
+ const basePath = isSingle ? '/editor-panels' : `/editor-panels-${key}`;
306
+ return Object.assign({ key, name: item.name || config.name, url: basePath + '/' + (item.fileName || 'index.html'), supportsMultipleStrings: (_a = item.supportsMultipleStrings) !== null && _a !== void 0 ? _a : false, modes: item.modes }, (!!item.environments && {
307
+ environments: normalizeEnvironments(item.environments),
308
+ }));
309
+ });
310
+ config.editorRightPanel = isSingle ? items[0] : items;
167
311
  }
168
312
  if (config.projectMenu) {
169
- // prevent possible overrides of the other modules
170
- config.projectMenu = Object.assign(Object.assign({}, config.projectMenu), { key: config.identifier + '-project-menu' });
171
- modules['project-menu'] = [
172
- Object.assign({ key: config.projectMenu.key, name: config.projectMenu.name || config.name, url: '/project-menu/' + (config.projectMenu.fileName || 'index.html') }, (!!config.projectMenu.environments && {
173
- environments: normalizeEnvironments(config.projectMenu.environments),
174
- })),
175
- ];
313
+ if (Array.isArray(config.projectMenu)) {
314
+ config.projectMenu = config.projectMenu.map((item) => (Object.assign({}, item)));
315
+ }
316
+ else {
317
+ config.projectMenu = Object.assign({}, config.projectMenu);
318
+ }
319
+ const items = (0, normalize_module_1.normalizeToArray)(config.projectMenu);
320
+ const isSingle = items.length === 1;
321
+ modules['project-menu'] = items.map((item, index) => {
322
+ const key = (0, normalize_module_1.resolveInstanceKey)({
323
+ identifier: config.identifier,
324
+ suffix: 'project-menu',
325
+ item,
326
+ index,
327
+ isSingle,
328
+ });
329
+ item.key = key;
330
+ const basePath = isSingle ? '/project-menu' : `/project-menu-${key}`;
331
+ return Object.assign({ key, name: item.name || config.name, url: basePath + '/' + (item.fileName || 'index.html') }, (!!item.environments && {
332
+ environments: normalizeEnvironments(item.environments),
333
+ }));
334
+ });
335
+ config.projectMenu = isSingle ? items[0] : items;
176
336
  }
177
337
  if (config.projectMenuCrowdsource) {
178
- // prevent possible overrides of the other modules
179
- config.projectMenuCrowdsource = Object.assign(Object.assign({}, config.projectMenuCrowdsource), { key: config.identifier + '-project-menu-crowdsource' });
180
- modules['project-menu-crowdsource'] = [
181
- {
182
- key: config.projectMenuCrowdsource.key,
183
- name: config.projectMenuCrowdsource.name || config.name,
184
- url: '/project-menu-crowdsource/' + (config.projectMenuCrowdsource.fileName || 'index.html'),
185
- },
186
- ];
338
+ if (Array.isArray(config.projectMenuCrowdsource)) {
339
+ config.projectMenuCrowdsource = config.projectMenuCrowdsource.map((item) => (Object.assign({}, item)));
340
+ }
341
+ else {
342
+ config.projectMenuCrowdsource = Object.assign({}, config.projectMenuCrowdsource);
343
+ }
344
+ const items = (0, normalize_module_1.normalizeToArray)(config.projectMenuCrowdsource);
345
+ const isSingle = items.length === 1;
346
+ modules['project-menu-crowdsource'] = items.map((item, index) => {
347
+ const key = (0, normalize_module_1.resolveInstanceKey)({
348
+ identifier: config.identifier,
349
+ suffix: 'project-menu-crowdsource',
350
+ item,
351
+ index,
352
+ isSingle,
353
+ });
354
+ item.key = key;
355
+ const basePath = isSingle ? '/project-menu-crowdsource' : `/project-menu-crowdsource-${key}`;
356
+ return {
357
+ key,
358
+ name: item.name || config.name,
359
+ url: basePath + '/' + (item.fileName || 'index.html'),
360
+ };
361
+ });
362
+ config.projectMenuCrowdsource = isSingle ? items[0] : items;
187
363
  }
188
364
  if (config.projectTools) {
189
- // prevent possible overrides of the other modules
190
- config.projectTools = Object.assign(Object.assign({}, config.projectTools), { key: config.identifier + '-tools' });
191
- modules['project-tools'] = [
192
- Object.assign({ key: config.projectTools.key, name: config.projectTools.name || config.name, description: config.description, logo: (0, util_1.getLogoUrl)(config, config.projectTools, '/tools'), url: '/tools/' + (config.projectTools.fileName || 'index.html') }, (!!config.projectTools.environments && {
193
- environments: normalizeEnvironments(config.projectTools.environments),
194
- })),
195
- ];
365
+ if (Array.isArray(config.projectTools)) {
366
+ config.projectTools = config.projectTools.map((item) => (Object.assign({}, item)));
367
+ }
368
+ else {
369
+ config.projectTools = Object.assign({}, config.projectTools);
370
+ }
371
+ const items = (0, normalize_module_1.normalizeToArray)(config.projectTools);
372
+ const isSingle = items.length === 1;
373
+ modules['project-tools'] = items.map((item, index) => {
374
+ const key = (0, normalize_module_1.resolveInstanceKey)({
375
+ identifier: config.identifier,
376
+ suffix: 'tools',
377
+ item,
378
+ index,
379
+ isSingle,
380
+ });
381
+ item.key = key;
382
+ const basePath = isSingle ? '/tools' : `/tools-${key}`;
383
+ return Object.assign({ key, name: item.name || config.name, description: config.description, logo: (0, util_1.getLogoUrl)(config, item, isSingle ? '/tools' : `/tools-${key}`), url: basePath + '/' + (item.fileName || 'index.html') }, (!!item.environments && {
384
+ environments: normalizeEnvironments(item.environments),
385
+ }));
386
+ });
387
+ config.projectTools = isSingle ? items[0] : items;
196
388
  }
197
389
  if (config.projectReports) {
198
- // prevent possible overrides of the other modules
199
- config.projectReports = Object.assign(Object.assign({}, config.projectReports), { key: config.identifier + '-project-reports' });
200
- modules['project-reports'] = [
201
- {
202
- key: config.projectReports.key,
203
- name: config.projectReports.name || config.name,
390
+ if (Array.isArray(config.projectReports)) {
391
+ config.projectReports = config.projectReports.map((item) => (Object.assign({}, item)));
392
+ }
393
+ else {
394
+ config.projectReports = Object.assign({}, config.projectReports);
395
+ }
396
+ const items = (0, normalize_module_1.normalizeToArray)(config.projectReports);
397
+ const isSingle = items.length === 1;
398
+ modules['project-reports'] = items.map((item, index) => {
399
+ const key = (0, normalize_module_1.resolveInstanceKey)({
400
+ identifier: config.identifier,
401
+ suffix: 'project-reports',
402
+ item,
403
+ index,
404
+ isSingle,
405
+ });
406
+ item.key = key;
407
+ const basePath = isSingle ? '/reports' : `/reports-${key}`;
408
+ return {
409
+ key,
410
+ name: item.name || config.name,
204
411
  description: config.description,
205
- logo: (0, util_1.getLogoUrl)(config, config.projectReports, '/reports'),
206
- url: '/reports/' + (config.projectReports.fileName || 'index.html'),
207
- },
208
- ];
412
+ logo: (0, util_1.getLogoUrl)(config, item, isSingle ? '/reports' : `/reports-${key}`),
413
+ url: basePath + '/' + (item.fileName || 'index.html'),
414
+ };
415
+ });
416
+ config.projectReports = isSingle ? items[0] : items;
209
417
  }
210
418
  if (config.modal) {
211
419
  let modals = [];
212
420
  if (Array.isArray(config.modal)) {
213
- modals = config.modal.map((modal, i) => {
214
- const moduleKey = modal.key || `${config.identifier}-modal-${i}`;
421
+ modals = config.modal.map((modal, index) => {
422
+ const moduleKey = modal.key || `${config.identifier}-modal-${index}`;
215
423
  return Object.assign({ key: moduleKey, name: modal.name || config.name, url: modal.url || `/modal-${moduleKey}/` + (modal.fileName || 'index.html') }, (!!modal.environments && { environments: normalizeEnvironments(modal.environments) }));
216
424
  });
217
425
  }
@@ -227,8 +435,8 @@ function handle(config) {
227
435
  if (config.contextMenu) {
228
436
  let contextMenus = [];
229
437
  if (Array.isArray(config.contextMenu)) {
230
- contextMenus = config.contextMenu.map((contextMenu, i) => {
231
- const moduleKey = contextMenu.key || `${config.identifier}-context-menu-${i}`;
438
+ contextMenus = config.contextMenu.map((contextMenu, index) => {
439
+ const moduleKey = contextMenu.key || `${config.identifier}-context-menu-${index}`;
232
440
  return Object.assign({ key: moduleKey, name: contextMenu.name || config.name, description: config.description, options: Object.assign(Object.assign({ location: contextMenu.location, type: contextMenu.type }, (contextMenu.module && contextMenu.moduleKey
233
441
  ? {
234
442
  module: {
@@ -259,57 +467,121 @@ function handle(config) {
259
467
  modules['api'] = (0, api_1.getApiManifest)(config, config.api);
260
468
  }
261
469
  if (config.customSpellchecker) {
262
- // prevent possible overrides of the other modules
263
- config.customSpellchecker = Object.assign(Object.assign({}, config.customSpellchecker), { key: config.identifier + '-spellchecker' });
264
- const uiModule = config.customSpellchecker.settingsUiModule;
265
- modules['custom-spellchecker'] = [
266
- Object.assign(Object.assign({ key: config.customSpellchecker.key, name: config.customSpellchecker.name || config.name, description: config.customSpellchecker.description || config.description, listSupportedLanguagesUrl: '/spellchecker/languages', checkSpellingUrl: '/spellchecker/spellcheck' }, (!!config.customSpellchecker.environments && {
267
- environments: normalizeEnvironments(config.customSpellchecker.environments),
268
- })), (uiModule ? { url: '/spellchecker/settings/' + (uiModule.fileName || 'index.html') } : {})),
269
- ];
470
+ if (Array.isArray(config.customSpellchecker)) {
471
+ config.customSpellchecker = config.customSpellchecker.map((item) => (Object.assign({}, item)));
472
+ }
473
+ else {
474
+ config.customSpellchecker = Object.assign({}, config.customSpellchecker);
475
+ }
476
+ const items = (0, normalize_module_1.normalizeToArray)(config.customSpellchecker);
477
+ const isSingle = items.length === 1;
478
+ modules['custom-spellchecker'] = items.map((item, index) => {
479
+ const key = (0, normalize_module_1.resolveInstanceKey)({
480
+ identifier: config.identifier,
481
+ suffix: 'spellchecker',
482
+ item,
483
+ index,
484
+ isSingle,
485
+ });
486
+ item.key = key;
487
+ const base = isSingle ? '/spellchecker' : `/spellchecker/${key}`;
488
+ const uiModule = item.settingsUiModule;
489
+ return Object.assign(Object.assign({ key, name: item.name || config.name, description: item.description || config.description, listSupportedLanguagesUrl: `${base}/languages`, checkSpellingUrl: `${base}/spellcheck` }, (!!item.environments && {
490
+ environments: normalizeEnvironments(item.environments),
491
+ })), (uiModule ? { url: `${base}/settings/` + (uiModule.fileName || 'index.html') } : {}));
492
+ });
493
+ config.customSpellchecker = isSingle ? items[0] : items;
270
494
  }
271
495
  if (config.aiProvider) {
272
- // prevent possible overrides of the other modules
273
- config.aiProvider = Object.assign(Object.assign({}, config.aiProvider), { key: config.identifier + '-aiprovider' });
274
- const uiModule = config.aiProvider.settingsUiModule;
275
- modules['ai-provider'] = [
276
- 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, config.aiProvider, '/aiprovider'), chatCompletionsUrl: '/ai-provider/completions', modelsUrl: '/ai-provider/models' }, (!!config.aiProvider.environments && {
277
- environments: normalizeEnvironments(config.aiProvider.environments),
278
- })), (uiModule ? { url: '/settings/' + (uiModule.fileName || 'index.html') } : {})),
279
- ];
496
+ if (Array.isArray(config.aiProvider)) {
497
+ config.aiProvider = config.aiProvider.map((item) => (Object.assign({}, item)));
498
+ }
499
+ else {
500
+ config.aiProvider = Object.assign({}, config.aiProvider);
501
+ }
502
+ const items = (0, normalize_module_1.normalizeToArray)(config.aiProvider);
503
+ const isSingle = items.length === 1;
504
+ modules['ai-provider'] = items.map((item, index) => {
505
+ const key = (0, normalize_module_1.resolveInstanceKey)({
506
+ identifier: config.identifier,
507
+ suffix: 'aiprovider',
508
+ item,
509
+ index,
510
+ isSingle,
511
+ });
512
+ item.key = key;
513
+ const base = isSingle ? '/ai-provider' : `/ai-provider/${key}`;
514
+ const logoPath = isSingle ? '/aiprovider' : `/aiprovider-${key}`;
515
+ const settingsBase = isSingle ? '' : `/${key}`;
516
+ const uiModule = item.settingsUiModule;
517
+ return Object.assign(Object.assign({ key, name: item.name || config.name, description: item.description || config.description, logo: (0, util_1.getLogoUrl)(config, item, logoPath), chatCompletionsUrl: `${base}/completions`, modelsUrl: `${base}/models` }, (!!item.environments && {
518
+ environments: normalizeEnvironments(item.environments),
519
+ })), (uiModule ? { url: `/settings${settingsBase}/` + (uiModule.fileName || 'index.html') } : {}));
520
+ });
521
+ config.aiProvider = isSingle ? items[0] : items;
280
522
  }
281
523
  [
282
524
  ...Object.values(ai_request_processors_1.AiRequestProcessorModuleWithoutStream),
283
525
  ...Object.values(ai_request_processors_1.AiRequestProcessorModuleWithStream),
284
526
  ].forEach((moduleType) => {
285
- const module = config[moduleType];
286
- if (!module) {
527
+ const moduleValue = config[moduleType];
528
+ if (!moduleValue) {
287
529
  return;
288
530
  }
289
531
  const moduleSlug = (0, ai_request_processors_1.generateModuleSlugFromType)(moduleType);
290
- modules[moduleSlug] = [
291
- {
292
- key: config.identifier + '-' + moduleSlug,
293
- processorUrl: '/ai-request-processor/' + moduleSlug,
294
- },
295
- ];
532
+ if (Array.isArray(moduleValue)) {
533
+ config[moduleType] = moduleValue.map((item) => (Object.assign({}, item)));
534
+ }
535
+ else {
536
+ config[moduleType] = Object.assign({}, moduleValue);
537
+ }
538
+ const items = (0, normalize_module_1.normalizeToArray)(config[moduleType]);
539
+ const isSingle = items.length === 1;
540
+ modules[moduleSlug] = items.map((item, index) => {
541
+ const key = (0, normalize_module_1.resolveInstanceKey)({
542
+ identifier: config.identifier,
543
+ suffix: moduleSlug,
544
+ item,
545
+ index,
546
+ isSingle,
547
+ });
548
+ item.key = key;
549
+ return {
550
+ key,
551
+ processorUrl: isSingle
552
+ ? '/ai-request-processor/' + moduleSlug
553
+ : `/ai-request-processor/${moduleSlug}/${key}`,
554
+ };
555
+ });
556
+ config[moduleType] = isSingle ? items[0] : items;
296
557
  });
297
558
  if (config.aiPromptProvider) {
298
- // prevent possible overrides of the other modules
299
- config.aiPromptProvider = Object.assign(Object.assign({}, config.aiPromptProvider), { key: config.identifier + '-ai-prompt-provider' });
300
- modules['ai-prompt-provider'] = [
301
- Object.assign(Object.assign(Object.assign({ key: config.aiPromptProvider.key, name: config.aiPromptProvider.name || config.name, logo: (0, util_1.getLogoUrl)(config, config.aiPromptProvider, '/ai-prompt-provider'), compileUrl: '/prompt-provider/compile' }, ((0, util_1.isDefined)(config.aiPromptProvider.allowRetryOnQaIssues) && {
302
- allowRetryOnQaIssues: config.aiPromptProvider.allowRetryOnQaIssues,
303
- })), (config.aiPromptProvider.actions
304
- ? {
305
- actions: config.aiPromptProvider.actions,
306
- }
307
- : {})), (config.aiPromptProvider.formSchema || config.aiPromptProvider.uiPath
308
- ? {
309
- configuratorUrl: '/prompt-provider/settings/' + (config.aiPromptProvider.fileName || 'index.html'),
310
- }
311
- : {})),
312
- ];
559
+ if (Array.isArray(config.aiPromptProvider)) {
560
+ config.aiPromptProvider = config.aiPromptProvider.map((item) => (Object.assign({}, item)));
561
+ }
562
+ else {
563
+ config.aiPromptProvider = Object.assign({}, config.aiPromptProvider);
564
+ }
565
+ const items = (0, normalize_module_1.normalizeToArray)(config.aiPromptProvider);
566
+ const isSingle = items.length === 1;
567
+ modules['ai-prompt-provider'] = items.map((item, index) => {
568
+ const key = (0, normalize_module_1.resolveInstanceKey)({
569
+ identifier: config.identifier,
570
+ suffix: 'ai-prompt-provider',
571
+ item,
572
+ index,
573
+ isSingle,
574
+ });
575
+ item.key = key;
576
+ const base = isSingle ? '/prompt-provider' : `/prompt-provider/${key}`;
577
+ const logoPath = isSingle ? '/ai-prompt-provider' : `/ai-prompt-provider-${key}`;
578
+ return Object.assign(Object.assign(Object.assign({ key, name: item.name || config.name, logo: (0, util_1.getLogoUrl)(config, item, logoPath), compileUrl: `${base}/compile` }, ((0, util_1.isDefined)(item.allowRetryOnQaIssues) && {
579
+ allowRetryOnQaIssues: item.allowRetryOnQaIssues,
580
+ })), (item.actions ? { actions: item.actions } : {})), (item.formSchema || item.uiPath
581
+ ? { configuratorUrl: `${base}/settings/` + (item.fileName || 'index.html') }
582
+ : {}));
583
+ });
584
+ config.aiPromptProvider = isSingle ? items[0] : items;
313
585
  }
314
586
  if (config.aiTools) {
315
587
  // prevent possible overrides of the other modules
@@ -365,12 +637,28 @@ function handle(config) {
365
637
  }
366
638
  }
367
639
  if (config.externalQaCheck) {
368
- // prevent possible overrides of the other modules
369
- config.externalQaCheck = Object.assign(Object.assign({}, config.externalQaCheck), { key: config.identifier + '-qa-check' });
370
- const uiModule = config.externalQaCheck.settingsUiModule;
371
- modules['external-qa-check'] = [
372
- Object.assign(Object.assign({ key: config.externalQaCheck.key, name: config.externalQaCheck.name || config.name, description: config.externalQaCheck.description || config.description, runQaCheckUrl: '/qa-check/validate' }, (config.externalQaCheck.batchSize ? { getBatchSizeUrl: '/qa-check/batch-size' } : {})), (uiModule ? { url: '/qa-check/settings/' + (uiModule.fileName || 'index.html') } : {})),
373
- ];
640
+ if (Array.isArray(config.externalQaCheck)) {
641
+ config.externalQaCheck = config.externalQaCheck.map((item) => (Object.assign({}, item)));
642
+ }
643
+ else {
644
+ config.externalQaCheck = Object.assign({}, config.externalQaCheck);
645
+ }
646
+ const items = (0, normalize_module_1.normalizeToArray)(config.externalQaCheck);
647
+ const isSingle = items.length === 1;
648
+ modules['external-qa-check'] = items.map((item, index) => {
649
+ const key = (0, normalize_module_1.resolveInstanceKey)({
650
+ identifier: config.identifier,
651
+ suffix: 'qa-check',
652
+ item,
653
+ index,
654
+ isSingle,
655
+ });
656
+ item.key = key;
657
+ const base = isSingle ? '/qa-check' : `/qa-check/${key}`;
658
+ const uiModule = item.settingsUiModule;
659
+ return Object.assign(Object.assign({ key, name: item.name || config.name, description: item.description || config.description, runQaCheckUrl: `${base}/validate` }, (item.batchSize ? { getBatchSizeUrl: `${base}/batch-size` } : {})), (uiModule ? { url: `${base}/settings/` + (uiModule.fileName || 'index.html') } : {}));
660
+ });
661
+ config.externalQaCheck = isSingle ? items[0] : items;
374
662
  }
375
663
  if (config.workflowStepType) {
376
664
  // prevent possible overrides of the other modules
@@ -388,10 +676,14 @@ function handle(config) {
388
676
  if (!workflowStep.key) {
389
677
  workflowStep.key = config.identifier + '-' + (0, util_3.getWorkflowStepKey)(workflowStep);
390
678
  }
391
- const uiModule = ((_b = workflowStep === null || workflowStep === void 0 ? void 0 : workflowStep.settingsUiModule) === null || _b === void 0 ? void 0 : _b.formSchema) || ((_c = workflowStep === null || workflowStep === void 0 ? void 0 : workflowStep.settingsUiModule) === null || _c === void 0 ? void 0 : _c.fileName);
679
+ const uiModule = workflowStep === null || workflowStep === void 0 ? void 0 : workflowStep.settingsUiModule;
392
680
  modules['workflow-step-type'].push(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ key: workflowStep.key, name: workflowStep.name || config.name }, (workflowStep.imageUrl || workflowStep.imagePath
393
681
  ? { logo: (0, util_1.getLogoUrl)(config, workflowStep, `-${workflowStep.key}`) }
394
- : {})), { description: workflowStep.description || config.description, boundaries: workflowStep.boundaries }), (workflowStep.editorMode ? { editorMode: workflowStep.editorMode } : {})), { updateSettingsUrl: (0, util_3.getWorkflowStepUrl)('/workflow-step/settings', workflowStep), deleteSettingsUrl: (0, util_3.getWorkflowStepUrl)('/workflow-step/delete', workflowStep) }), (uiModule ? { url: (0, util_3.getWorkflowStepUrl)('/workflow-step', workflowStep) } : {})));
682
+ : {})), { description: workflowStep.description || config.description, boundaries: workflowStep.boundaries }), (workflowStep.editorMode ? { editorMode: workflowStep.editorMode } : {})), { updateSettingsUrl: (0, util_3.getWorkflowStepUrl)('/workflow-step/settings', workflowStep), deleteSettingsUrl: (0, util_3.getWorkflowStepUrl)('/workflow-step/delete', workflowStep) }), ((uiModule === null || uiModule === void 0 ? void 0 : uiModule.formSchema)
683
+ ? {
684
+ url: `${(0, util_3.getWorkflowStepUrl)('/workflow-step', workflowStep)}/${uiModule.fileName || 'index.html'}`,
685
+ }
686
+ : {})));
395
687
  }
396
688
  }
397
689
  if (config.automationAction) {