@eclipse-scout/migrate 23.1.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.
package/src/common.js ADDED
@@ -0,0 +1,666 @@
1
+ /*
2
+ * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ */
10
+
11
+ /* eslint-disable indent */
12
+
13
+ import path from 'path';
14
+
15
+ export function lfToCrlf(text) {
16
+ return text.replace(/(?!\r)\n/gm, '\r\n');
17
+ }
18
+
19
+ export function crlfToLf(text) {
20
+ return text.replace(/\r\n/gm, '\n');
21
+ }
22
+
23
+ export function inConstructor(path) {
24
+ return !!findParentPath(path, parentPath => parentPath.node.type === 'ClassMethod' && parentPath.node.kind === 'constructor');
25
+ }
26
+
27
+ export function findParentClassBody(path) {
28
+ return findParentPath(path, parentPath => parentPath.node.type === 'ClassBody');
29
+ }
30
+
31
+ export function findClassName(path) {
32
+ return findParentPath(path, parentPath => parentPath.node.type === 'ClassDeclaration').value.id.name;
33
+ }
34
+
35
+ export function findParentPath(path, predicate) {
36
+ let cur = path;
37
+ while (cur.node.type !== 'Program') {
38
+ if (predicate(cur)) {
39
+ return cur;
40
+ }
41
+ cur = cur.parentPath;
42
+ }
43
+ return undefined;
44
+ }
45
+
46
+ export function findClassProperty(classBody, propertyName) {
47
+ return classBody.node.body.find(
48
+ n =>
49
+ n.type === 'ClassProperty' &&
50
+ n.key.type === 'Identifier' &&
51
+ n.key.name === propertyName
52
+ );
53
+ }
54
+
55
+ /**
56
+ * @typedef {object} TypeDesc
57
+ * @property type
58
+ * @property module?: string
59
+ */
60
+
61
+ /**
62
+ * @returns {TypeDesc}
63
+ */
64
+ export function getTypeFor(j, name, value, typeMaps) {
65
+ switch (value.type) {
66
+ case 'StringLiteral':
67
+ return {type: j.tsStringKeyword()};
68
+ case 'BooleanLiteral':
69
+ return {type: j.tsBooleanKeyword()};
70
+ case 'NumericLiteral':
71
+ return {type: j.tsNumberKeyword()};
72
+ case 'NewExpression':
73
+ return {type: j.tsTypeReference(j.identifier(value.callee.name))};
74
+ case 'ArrayExpression': {
75
+ if (value.elements.length === 0) {
76
+ // If element is empty, find type based on name.
77
+ return findTypeByName(j, typeMaps, name) || {type: j.tsArrayType(j.tsAnyKeyword())};
78
+ }
79
+ let elementType = getTypeFor(j, null, value.elements[0]).type;
80
+ return {type: j.tsArrayType(elementType)};
81
+ }
82
+ default: {
83
+ let typeDesc = findTypeByName(j, typeMaps, name);
84
+ if (typeDesc) {
85
+ return typeDesc;
86
+ }
87
+ return {type: j.tsAnyKeyword()};
88
+ }
89
+ }
90
+ }
91
+
92
+ export function getNameForType(j, type) {
93
+ if (!type) {
94
+ return null;
95
+ }
96
+ switch (type.type) {
97
+ case 'TSStringKeyword':
98
+ return 'string';
99
+ case 'TSBooleanKeyword':
100
+ return 'boolean';
101
+ case 'TSNumberKeyword':
102
+ return 'number';
103
+ case 'TSAnyKeyword':
104
+ return 'any';
105
+ case 'TSTypeReference':
106
+ return type.typeName.name;
107
+ case 'TSArrayType': {
108
+ return getNameForType(j, type.elementType) + '[]';
109
+ }
110
+ default: {
111
+ return null;
112
+ }
113
+ }
114
+ }
115
+
116
+ /**
117
+ * @returns {TypeDesc} the codeshift type for the string based names used in type maps.
118
+ */
119
+ export function mapType(j, name) {
120
+ if (name.endsWith('[]')) {
121
+ name = name.substring(0, name.length - 2);
122
+ let typeDesc = mapType(j, name);
123
+ if (typeDesc) {
124
+ return {type: j.tsArrayType(typeDesc.type), module: typeDesc.module};
125
+ }
126
+ }
127
+
128
+ let type;
129
+ let module;
130
+ switch (name) {
131
+ case 'string':
132
+ type = j.tsStringKeyword();
133
+ break;
134
+ case 'boolean':
135
+ type = j.tsBooleanKeyword();
136
+ break;
137
+ case 'number':
138
+ type = j.tsNumberKeyword();
139
+ break;
140
+ case 'any':
141
+ type = j.tsAnyKeyword();
142
+ break;
143
+ case 'void':
144
+ type = j.tsVoidKeyword();
145
+ break;
146
+ default:
147
+ if (name.indexOf('.') > -1) {
148
+ [module, name] = name.split('.');
149
+ }
150
+ type = j.tsTypeReference(j.identifier(name));
151
+ break;
152
+ }
153
+ return {type, module};
154
+ }
155
+
156
+ /**
157
+ * @returns {TypeDesc|null}
158
+ */
159
+ export function findTypeByName(j, typeMaps, name) {
160
+ if (!name) {
161
+ return null;
162
+ }
163
+ let type = _findTypeByName();
164
+ if (type) {
165
+ return type;
166
+ }
167
+ // Ignore leading _ and try again
168
+ if (name.startsWith('_')) {
169
+ name = name.substring(1, name.length);
170
+ }
171
+ return _findTypeByName();
172
+
173
+ function _findTypeByName() {
174
+ for (let map of typeMaps) {
175
+ if (map.predicate(name)) {
176
+ return mapType(j, map.type);
177
+ }
178
+ }
179
+ }
180
+ }
181
+
182
+ export function methodFilter(j, path) {
183
+ return path.node.type === j.ClassMethod.name ||
184
+ // All exported methods in a file that is not a class (e.g. utilities)
185
+ (!findParentClassBody(path) && path.node?.type === 'FunctionDeclaration' && path.parentPath.node.type === 'ExportNamedDeclaration');
186
+ }
187
+
188
+ export function isOneOf(value, ...args) {
189
+ if (args.length === 0) {
190
+ return false;
191
+ }
192
+ let argsToCheck = args;
193
+ if (args.length === 1 && Array.isArray(args[0])) {
194
+ argsToCheck = args[0];
195
+ }
196
+ return argsToCheck.indexOf(value) !== -1;
197
+ }
198
+
199
+ export function findIndex(arr, predicate) {
200
+ if (!arr || !predicate) {
201
+ return -1;
202
+ }
203
+ for (let i = 0; i < arr.length; i++) {
204
+ if (predicate(arr[i], i, arr)) {
205
+ return i;
206
+ }
207
+ }
208
+ return -1;
209
+ }
210
+
211
+ export function findLastIndex(arr, predicate) {
212
+ if (!arr || !predicate) {
213
+ return -1;
214
+ }
215
+ let index = -1;
216
+ for (let i = 0; i < arr.length; i++) {
217
+ if (predicate(arr[i], i, arr)) {
218
+ index = i;
219
+ }
220
+ }
221
+ return index;
222
+ }
223
+
224
+ /**
225
+ * @returns {Collection<ImportDeclaration>}
226
+ */
227
+ export function findImportDeclarations(j, source, predicate) {
228
+ return source
229
+ .find(j.ImportDeclaration)
230
+ .filter(path => predicate(path.node.source.value));
231
+ }
232
+
233
+ /**
234
+ * Returns the {@link ImportSpecifier}s for the given specifier name in the import declaration.
235
+ * E.g. if the specifierName is b and the import declaration `import {a, b} from 'module'`, the {@link ImportSpecifier} for b wil be returned because it is in the list.
236
+ * @param {Collection<ImportDeclaration>} importDeclaration
237
+ * @param {string} specifierName
238
+ * @returns {Collection<ImportSpecifier>}
239
+ */
240
+ export function findImportSpecifiers(j, importDeclaration, specifierName) {
241
+ return importDeclaration
242
+ .find(j.ImportSpecifier)
243
+ .filter(path => path.value.imported.name === specifierName);
244
+ }
245
+
246
+ /**
247
+ * @param {Collection<ImportDeclaration>} importDeclaration
248
+ * @param {string} specifierName
249
+ */
250
+ export function hasImportSpecifier(j, importDeclaration, specifierName) {
251
+ return !!findImportSpecifiers(j, importDeclaration, specifierName)?.length;
252
+ }
253
+
254
+ /**
255
+ * Inserts a new import to a declaration.
256
+ * E.g. if specifierName is b, it will add b to the list of imports (import {a} from 'module' -> import {a, b} from 'module')
257
+ * @param {Collection<ImportDeclaration>} importDeclaration
258
+ * @param {string} specifierName
259
+ */
260
+ export function insertImportSpecifier(j, importDeclaration, specifierName) {
261
+ const importSpecifier = j.importSpecifier(j.identifier(specifierName));
262
+
263
+ importDeclaration.forEach(declaration => {
264
+ j(declaration).replaceWith(
265
+ j.importDeclaration(
266
+ sortImportSpecifiers([...declaration.node.specifiers, importSpecifier]),
267
+ declaration.node.source
268
+ )
269
+ );
270
+ });
271
+ }
272
+
273
+ function getFirstNode(j, source) {
274
+ return source.find(j.Program).get('body', 0).node;
275
+ }
276
+
277
+ function getClassName(j, source) {
278
+ let declarations = source.find(j.ClassDeclaration);
279
+ if (declarations.length === 0) {
280
+ return null;
281
+ }
282
+ return declarations.get(0).parentPath.value.id.name;
283
+ }
284
+
285
+ export function sortImportSpecifiers(specifiers) {
286
+ return specifiers.sort((s1, s2) => {
287
+ if (!s1.imported || !s2.imported) {
288
+ return 0; // one specifier is probably an ImportDefaultSpecifier
289
+ }
290
+ return s1.imported.name.localeCompare(s2.imported.name);
291
+ });
292
+ }
293
+
294
+ /**
295
+ * @param {TypeDesc[]} typeDescriptors
296
+ * @param moduleMap
297
+ */
298
+ export function insertMissingImportsForTypes(j, source, typeDescriptors, moduleMap, currentFilePath) {
299
+ let modules = typeDescriptors.map(typeDesc => typeDesc.module);
300
+ if (modules.length === 0) {
301
+ return;
302
+ }
303
+
304
+ // Save the comments attached to the first node
305
+ const firstNode = getFirstNode(j, source);
306
+ const {comments} = firstNode;
307
+ const className = getClassName(j, source);
308
+
309
+ for (let i = 0; i < modules.length; i++) {
310
+ let module = modules[i];
311
+ let moduleName = moduleMap[module];
312
+ let predicate = name => name === moduleName;
313
+ if (typeof moduleName === 'function') {
314
+ predicate = moduleName;
315
+ } else if (typeof moduleName === 'string' && moduleName.startsWith('path:')) {
316
+ // Get relative path from current file to module
317
+ moduleName = path.relative(path.parse(currentFilePath).dir, path.resolve(moduleName.substring(moduleName.indexOf(':') + 1)));
318
+ // Remove file ending
319
+ moduleName = moduleName.substring(0, moduleName.lastIndexOf('.'));
320
+ // Always use forward slashes
321
+ moduleName = moduleName.replaceAll('\\', '/');
322
+ }
323
+ let declarations = findImportDeclarations(j, source, predicate);
324
+ if (declarations.length === 0) {
325
+ insertImportDeclaration(j, source, moduleName);
326
+ declarations = findImportDeclarations(j, source, predicate);
327
+ }
328
+
329
+ let typeDesc = typeDescriptors[i];
330
+ let typeName = getTypeName(typeDesc.type);
331
+ if (typeName !== className && !hasImportSpecifier(j, declarations, typeName)) {
332
+ insertImportSpecifier(j, declarations, typeName);
333
+ }
334
+ }
335
+
336
+ // When the imports are replaced, the comment on the first node (likely the copy right header) is removed -> Attach comment again
337
+ // See also https://github.com/facebook/jscodeshift/blob/master/recipes/retain-first-comment.md
338
+ const newFirstNode = getFirstNode(j, source);
339
+ if (newFirstNode !== firstNode) {
340
+ firstNode.comments = null; // Delete comment if another import was added before that will receive it
341
+ newFirstNode.comments = comments;
342
+ }
343
+ }
344
+
345
+ export function insertImportDeclaration(j, source, moduleName) {
346
+ if (typeof moduleName !== 'string') {
347
+ // Not possible to add an import declaration
348
+ return;
349
+ }
350
+ const declaration = j.importDeclaration(
351
+ [],
352
+ j.stringLiteral(moduleName)
353
+ );
354
+
355
+ let body = source.get().node.program.body;
356
+ let index = -1;
357
+ if (isFileImport(moduleName)) {
358
+ // Put file imports at the end (after imports form node_modules)
359
+ index = findLastIndex(body, node => node.type === 'ImportDeclaration');
360
+ } else {
361
+ // Put imports from node_modules before file imports
362
+ index = findLastIndex(body, node =>
363
+ node.type === 'ImportDeclaration' && !isFileImport(node.source.value));
364
+ }
365
+ if (index >= 0) {
366
+ body.splice(index + 1, 0, declaration);
367
+ } else {
368
+ // Insert it at the top of the file
369
+ body.unshift(declaration);
370
+ }
371
+ }
372
+
373
+ function isFileImport(importName) {
374
+ return importName.includes('./') || importName.includes('../');
375
+ }
376
+
377
+ export function removeEmptyLinesBetweenImports(text) {
378
+ return text.replaceAll(/\r\n\r\nimport /g, '\r\nimport ');
379
+ }
380
+
381
+ function getTypeName(type) {
382
+ if (type.type === 'TSArrayType') {
383
+ return type.elementType.typeName.name;
384
+ }
385
+ return type.typeName.name;
386
+ }
387
+
388
+ export function transformCommentLinesToJsDoc(j, comments) {
389
+ if (!comments) {
390
+ return null;
391
+ }
392
+ let commentTexts = [];
393
+ if (comments[0].type === 'CommentBlock') {
394
+ if (comments[0].value.startsWith('*')) {
395
+ // Already js doc
396
+ return comments;
397
+ }
398
+ // Convert regular block to lines first
399
+ commentTexts = comments[0].value.trim().split('\r\n').map(comment => ' ' + comment.trim());
400
+ } else {
401
+ commentTexts = comments.map(comment => comment.value);
402
+ }
403
+ let str = '';
404
+ if (commentTexts.length === 1) {
405
+ str += `*${commentTexts[0]} `;
406
+ } else {
407
+ str = '*\r\n';
408
+ for (let comment of commentTexts) {
409
+ str += ` *${comment}\r\n`;
410
+ }
411
+ }
412
+ return [j.commentBlock(str)];
413
+ }
414
+
415
+ export const defaultParamTypeMap = {
416
+ JQuery: {
417
+ predicate: name => name.startsWith('$') || name.startsWith('_$'), // check for _ explicitly to ensure no other predicate matches (e.g. FormField)
418
+ type: 'JQuery'
419
+ },
420
+ number: {
421
+ predicate: name => isOneOf(name, 'width', 'height', 'top', 'bottom', 'right', 'left', 'x', 'y', 'length', 'maximumUploadSize', 'viewRangeSize', 'count', 'selectionStart', 'selectionEnd',
422
+ 'sortCode', 'dense', 'delay', 'maxContentLines', 'useOnlyInVisibleColumns', 'index')
423
+ || name.endsWith('Length') || name.endsWith('Width') || name.endsWith('Height') || name.endsWith('WidthInPixel') || name.endsWith('Count')
424
+ || name.endsWith('Top') || name.endsWith('Left') || name.endsWith('Index') || name.endsWith('ingX') || name.endsWith('ingY') || name.endsWith('Delay'),
425
+ type: 'number'
426
+ },
427
+ boolean: {
428
+ predicate: name => isOneOf(name, 'loading', 'loaded', 'toggleAction', 'compact', 'exclusiveExpand', 'active', 'visible', 'enabled', 'checked', 'selected', 'selectable', 'hasText', 'invalidate', 'modal', 'closable', 'resizable',
429
+ 'movable', 'askIfNeedSave', 'showOnOpen', 'scrollable', 'updateDisplayTextOnModify', 'autoRemove', 'mandatory', 'stackable', 'shrinkable', 'required', 'collapsed', 'collapsible', 'expanded', 'expandable',
430
+ 'editable', 'preventDoubleClick', 'autoCloseExternalWindow', 'hasDate', 'hasTime', 'focused', 'responsive', 'wrapText', 'tabbable', 'virtual', 'busy', 'trimText', 'browseAutoExpandAll', 'browseLoadIncremental', 'browseHierarchy',
431
+ 'minimized', 'maximized', 'failed', 'running', 'stopped', 'requestPending', 'pending', 'inputMasked', 'formatLower', 'formatUpper', 'marked', 'overflown', 'multiSelect', 'multiCheck', 'scrollToSelection', 'trackLocation',
432
+ 'autoFit', 'multiline', 'multilineText', 'hierarchical', 'loadIncremental', 'hidden', 'hiddenByUi', 'shown', 'withArrow', 'trimWidth', 'trimHeight', 'autoResizeColumns', 'filterAccepted', 'withPlaceholders',
433
+ 'clickable', 'empty', 'changing', 'inheritAccessibility', 'embedDetailContent', 'displayable', 'compacted', 'autoOptimizeWidth')
434
+ || name.endsWith('Visible') || name.endsWith('Enabled') || name.endsWith('Focused') || name.endsWith('Required') || name.endsWith('Collapsed')
435
+ || name.endsWith('Minimized') || name.endsWith('Focusable') || name.endsWith('Active') || name.endsWith('Expanded'),
436
+ type: 'boolean'
437
+ },
438
+ string: {
439
+ predicate: name => isOneOf(name, 'displayText', 'text', 'cssClass', 'displayViewId', 'title', 'subTitle', 'subtitle', 'titleSuffix', 'iconId', 'label', 'subLabel', 'imageUrl', 'logoUrl', 'titleSuffix')
440
+ || name.endsWith('IconId') || name.endsWith('CssClass') || name.endsWith('Text'),
441
+ type: 'string'
442
+ },
443
+ Date: {
444
+ predicate: name => name.endsWith('Date') || name.endsWith('Time'),
445
+ type: 'Date'
446
+ },
447
+ HtmlComponent: {
448
+ predicate: name => isOneOf(name, 'htmlComp', 'htmlContainer', 'htmlBody', 'htmlChild'),
449
+ type: 'scout.HtmlComponent'
450
+ },
451
+ Session: {
452
+ predicate: name => name === 'session',
453
+ type: 'scout.Session'
454
+ },
455
+ Desktop: {
456
+ predicate: name => name === 'desktop',
457
+ type: 'scout.Desktop'
458
+ },
459
+ Actions: {
460
+ predicate: name => isOneOf(name, 'actions'),
461
+ type: 'scout.Action[]'
462
+ },
463
+ Popup: {
464
+ predicate: name => isOneOf(name, 'popup'),
465
+ type: 'scout.Popup'
466
+ },
467
+ Popups: {
468
+ predicate: name => isOneOf(name, 'popups'),
469
+ type: 'scout.Popup[]'
470
+ },
471
+ Insets: {
472
+ predicate: name => isOneOf(name, 'insets'),
473
+ type: 'scout.Insets'
474
+ },
475
+ IconDesc: {
476
+ predicate: name => isOneOf(name, 'iconDesc'),
477
+ type: 'scout.IconDesc'
478
+ },
479
+ Accordion: {
480
+ predicate: name => isOneOf(name, 'accordion'),
481
+ type: 'scout.Accordion'
482
+ },
483
+ BreadCrumbItem: {
484
+ predicate: name => isOneOf(name, 'breadCrumbItem'),
485
+ type: 'scout.BreadCrumbItem'
486
+ },
487
+ BreadCrumbItems: {
488
+ predicate: name => isOneOf(name, 'breadCrumbItems'),
489
+ type: 'scout.BreadCrumbItem[]'
490
+ },
491
+ Menu: {
492
+ predicate: name => isOneOf(name, 'menu', 'menuItem'),
493
+ type: 'scout.Menu'
494
+ },
495
+ Menus: {
496
+ predicate: name => isOneOf(name, 'menus', 'menuItems', 'staticMenus', 'detailMenus', 'nodeMenus'),
497
+ type: 'scout.Menu[]'
498
+ },
499
+ LookupCall: {
500
+ predicate: name => isOneOf(name, 'lookupCall'),
501
+ type: 'scout.LookupCall'
502
+ },
503
+ CodeType: {
504
+ predicate: name => isOneOf(name, 'codeType'),
505
+ type: 'scout.CodeType'
506
+ },
507
+ LookupRow: {
508
+ predicate: name => isOneOf(name, 'lookupRow'),
509
+ type: 'scout.LookupRow'
510
+ },
511
+ LookupRows: {
512
+ predicate: name => isOneOf(name, 'lookupRows'),
513
+ type: 'scout.LookupRow[]'
514
+ },
515
+ LookupResult: {
516
+ predicate: name => isOneOf(name, 'lookupResult'),
517
+ type: 'scout.LookupResult'
518
+ },
519
+ FormField: {
520
+ predicate: name => isOneOf(name, 'formField', 'field') || name.endsWith('Field'),
521
+ type: 'scout.FormField'
522
+ },
523
+ FormFields: {
524
+ predicate: name => isOneOf(name, 'formFields', 'fields') || name.endsWith('Fields'),
525
+ type: 'scout.FormField[]'
526
+ },
527
+ Column: {
528
+ predicate: name => isOneOf(name, 'column'),
529
+ type: 'scout.Column'
530
+ },
531
+ Columns: {
532
+ predicate: name => isOneOf(name, 'columns'),
533
+ type: 'scout.Column[]'
534
+ },
535
+ GridData: {
536
+ predicate: name => isOneOf(name, 'gridData', 'gridDataHints'),
537
+ type: 'scout.GridData'
538
+ },
539
+ Form: {
540
+ predicate: name => isOneOf(name, 'form', 'displayParent') || name.endsWith('Form'),
541
+ type: 'scout.Form'
542
+ },
543
+ Status: {
544
+ predicate: name => isOneOf(name, 'errorStatus'),
545
+ type: 'scout.Status'
546
+ },
547
+ Outline: {
548
+ predicate: name => isOneOf(name, 'outline'),
549
+ type: 'scout.Outline'
550
+ },
551
+ OutlineOverview: {
552
+ predicate: name => isOneOf(name, 'outlineOverview'),
553
+ type: 'scout.OutlineOverview'
554
+ },
555
+ Page: {
556
+ predicate: name => isOneOf(name, 'page'),
557
+ type: 'scout.Page'
558
+ },
559
+ TabItem: {
560
+ predicate: name => isOneOf(name, 'tabItem'),
561
+ type: 'scout.TabItem'
562
+ },
563
+ TabItems: {
564
+ predicate: name => isOneOf(name, 'tabItems'),
565
+ type: 'scout.TabItem[]'
566
+ },
567
+ KeyStroke: {
568
+ predicate: name => isOneOf(name, 'keyStroke'),
569
+ type: 'scout.KeyStroke'
570
+ },
571
+ Cell: {
572
+ predicate: name => isOneOf(name, 'cell', 'headerCell'),
573
+ type: 'scout.Cell'
574
+ },
575
+ Table: {
576
+ predicate: name => isOneOf(name, 'table', 'detailTable'),
577
+ type: 'scout.Table'
578
+ },
579
+ TableControl: {
580
+ predicate: name => isOneOf(name, 'tableControl'),
581
+ type: 'scout.TableControl'
582
+ },
583
+ TableControls: {
584
+ predicate: name => isOneOf(name, 'tableControls'),
585
+ type: 'scout.TableControl[]'
586
+ },
587
+ Tree: {
588
+ predicate: name => isOneOf(name, 'tree'),
589
+ type: 'scout.Tree'
590
+ },
591
+ TileGrid: {
592
+ predicate: name => isOneOf(name, 'tileGrid'),
593
+ type: 'scout.TileGrid'
594
+ },
595
+ Tile: {
596
+ predicate: name => isOneOf(name, 'tile', 'focusedTile'),
597
+ type: 'scout.Tile'
598
+ },
599
+ Tiles: {
600
+ predicate: name => isOneOf(name, 'tiles'),
601
+ type: 'scout.Tile[]'
602
+ },
603
+ Range: {
604
+ predicate: name => isOneOf(name, 'viewRange'),
605
+ type: 'scout.Range'
606
+ },
607
+ Widget: {
608
+ predicate: name => isOneOf(name, 'widget', 'displayParent') || name.endsWith('Widget'),
609
+ type: 'scout.Widget'
610
+ },
611
+ Widgets: {
612
+ predicate: name => isOneOf(name, 'widgets'),
613
+ type: 'scout.Widget[]'
614
+ }
615
+ };
616
+
617
+ export const defaultReturnTypeMap = {
618
+ JQuery: {
619
+ predicate: name => name.startsWith('$') || name.startsWith('get$'),
620
+ type: 'JQuery'
621
+ },
622
+ Dimension: {
623
+ predicate: name => isOneOf(name, 'prefSize', 'preferredLayoutSize'),
624
+ type: 'scout.Dimension'
625
+ },
626
+ KeyStrokeContext: {
627
+ predicate: name => name === '_createKeyStrokeContext',
628
+ type: 'scout.KeyStrokeContext'
629
+ },
630
+ boolean: {
631
+ predicate: name => isOneOf(name, 'equals') || name.match(/^is[A-Z]/) || name.match(/^has[A-Z]/),
632
+ type: 'boolean'
633
+ },
634
+ string: {
635
+ predicate: name => isOneOf(name, 'toString'),
636
+ type: 'string'
637
+ }
638
+ };
639
+
640
+ // Value may be a function as well
641
+ export const defaultModuleMap = {
642
+ scout: '@eclipse-scout/core'
643
+ };
644
+
645
+ export const defaultRecastOptions = {
646
+ quote: 'single',
647
+ objectCurlySpacing: false
648
+ };
649
+
650
+ export const defaultMenuTypesMap = {
651
+ 'Table.EmptySpace': {objectType: 'Table', menuTypes: 'MenuTypes', menuType: 'EmptySpace'},
652
+ 'Table.SingleSelection': {objectType: 'Table', menuTypes: 'MenuTypes', menuType: 'SingleSelection'},
653
+ 'Table.MultiSelection': {objectType: 'Table', menuTypes: 'MenuTypes', menuType: 'MultiSelection'},
654
+ 'Table.Header': {objectType: 'Table', menuTypes: 'MenuTypes', menuType: 'Header'},
655
+ 'TabBox.Header': {objectType: 'TabBox', menuTypes: 'MenuTypes', menuType: 'Header'},
656
+ 'Tree.EmptySpace': {objectType: 'Tree', menuTypes: 'MenuTypes', menuType: 'EmptySpace'},
657
+ 'Tree.SingleSelection': {objectType: 'Tree', menuTypes: 'MenuTypes', menuType: 'SingleSelection'},
658
+ 'Tree.MultiSelection': {objectType: 'Tree', menuTypes: 'MenuTypes', menuType: 'MultiSelection'},
659
+ 'Tree.Header': {objectType: 'Tree', menuTypes: 'MenuTypes', menuType: 'Header'},
660
+ 'Planner.Activity': {objectType: 'Planner', menuTypes: 'MenuTypes', menuType: 'Activity'},
661
+ 'Planner.EmptySpace': {objectType: 'Planner', menuTypes: 'MenuTypes', menuType: 'EmptySpace'},
662
+ 'Planner.Range': {objectType: 'Planner', menuTypes: 'MenuTypes', menuType: 'Range'},
663
+ 'Planner.Resource': {objectType: 'Planner', menuTypes: 'MenuTypes', menuType: 'Resource'},
664
+ 'Calendar.EmptySpace': {objectType: 'Calendar', menuTypes: 'MenuTypes', menuType: 'EmptySpace'},
665
+ 'Calendar.CalendarComponent': {objectType: 'Calendar', menuTypes: 'MenuTypes', menuType: 'CalendarComponent'}
666
+ };
@@ -0,0 +1,34 @@
1
+ /*
2
+ * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ */
10
+
11
+ /**
12
+ * @type import('ts-migrate-server').Plugin<unknown>
13
+ */
14
+ import {lfToCrlf} from './common.js';
15
+
16
+ let filesConvertedToCrLf = new Set();
17
+ /**
18
+ * @type import('ts-migrate-server').Plugin<{}>
19
+ */
20
+ const convertToCRLFPlugin = {
21
+ name: 'convert-to-crlf',
22
+
23
+ run({text, fileName}) {
24
+ // declareMissingClassPropertiesPlugin needs \r\n to work -> ensure crlf line breaks. The next regex also depends on that.
25
+ if (text.indexOf('\r\n') >= 0) {
26
+ return text;
27
+ }
28
+ filesConvertedToCrLf.add(fileName); // remember files for which the newlines have been changed. Required to only revert the ones that have been modified.
29
+ return lfToCrlf(text);
30
+ }
31
+ };
32
+
33
+ export default convertToCRLFPlugin;
34
+ export {filesConvertedToCrLf};