@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.
@@ -0,0 +1,31 @@
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 {crlfToLf} from './common.js';
15
+ import {filesConvertedToCrLf} from './convertToCRLFPlugin.js';
16
+
17
+ /**
18
+ * @type import('ts-migrate-server').Plugin<{}>
19
+ */
20
+ const convertToLFPlugin = {
21
+ name: 'convert-to-lf',
22
+
23
+ run({text, fileName}) {
24
+ if (filesConvertedToCrLf.has(fileName)) {
25
+ // revert line ending style to lf
26
+ return crlfToLf(text);
27
+ }
28
+ }
29
+ };
30
+
31
+ export default convertToLFPlugin;
@@ -0,0 +1,36 @@
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
+ import jscodeshift from 'jscodeshift';
11
+ import {methodFilter} from './common.js';
12
+
13
+ const j = jscodeshift.withParser('ts');
14
+ let total = 0;
15
+ /**
16
+ * @type import('ts-migrate-server').Plugin<unknown>
17
+ */
18
+ const countMethods = {
19
+ name: 'count-methods-plugin',
20
+
21
+ async run({text, fileName}) {
22
+ const root = j(text);
23
+ let count = 0;
24
+ root.find(j.Declaration)
25
+ .filter(path => methodFilter(j, path))
26
+ .forEach(expression => {
27
+ count++;
28
+ });
29
+ total += count;
30
+ console.log(fileName + ': ' + count);
31
+ console.log('Total: ' + total);
32
+ return text;
33
+ }
34
+ };
35
+
36
+ export default countMethods;
@@ -0,0 +1,139 @@
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
+ * Based on https://github.com/airbnb/ts-migrate/blob/master/packages/ts-migrate-plugins/src/plugins/declare-missing-class-properties.ts (MIT License)
13
+ * See readme.md for details.
14
+ */
15
+ import jscodeshift from 'jscodeshift';
16
+ import {validateAnyAliasOptions} from 'ts-migrate-plugins/build/src/utils/validateOptions.js';
17
+ import {isDiagnosticWithLinePosition} from 'ts-migrate-plugins/build/src/utils/type-guards.js';
18
+ import {defaultModuleMap, defaultParamTypeMap, defaultRecastOptions, findClassProperty, findIndex, findParentClassBody, findParentPath, getTypeFor, inConstructor, insertMissingImportsForTypes, removeEmptyLinesBetweenImports, transformCommentLinesToJsDoc} from './common.js';
19
+
20
+ const j = jscodeshift.withParser('ts');
21
+ let root;
22
+ let referencedTypes;
23
+ const propertyComparator = (a, b) => {
24
+ // Move $ and _ variables to the end
25
+ if (a.startsWith('_') && !b.startsWith('_')) {
26
+ return 1;
27
+ }
28
+ if (b.startsWith('_') && !a.startsWith('_')) {
29
+ return -1;
30
+ }
31
+ if (a.startsWith('$') && !b.startsWith('$')) {
32
+ return 1;
33
+ }
34
+ if (b.startsWith('$') && !a.startsWith('$')) {
35
+ return -1;
36
+ }
37
+ return 0;
38
+ };
39
+
40
+ /**
41
+ * @type import('ts-migrate-server').Plugin<{ anyAlias?: string, typeMap?: object, moduleMap?: object}>
42
+ */
43
+ const declareMissingClassPropertiesPlugin = {
44
+ name: 'declare-missing-class-properties',
45
+
46
+ async run({text, fileName, getLanguageService, options, sourceFile}) {
47
+ const diagnostics = getLanguageService()
48
+ .getSemanticDiagnostics(fileName)
49
+ .filter(isDiagnosticWithLinePosition)
50
+ .filter(diagnostic => diagnostic.code === 2339 || diagnostic.code === 2551); // 2339: Property_0_does_not_exist_on_type_1, 2551: Property_0_does_not_exist_on_type_1_Did_you_mean_
51
+
52
+ root = j(text);
53
+
54
+ const toAdd = [];
55
+ const typeMap = {...defaultParamTypeMap, ...options.typeMap};
56
+ const moduleMap = {...defaultModuleMap, ...options.moduleMap};
57
+ referencedTypes = new Set();
58
+
59
+ // Diagnostics are errors reported by typescript -> the plugin only processes missing properties
60
+ diagnostics.forEach(diagnostic => {
61
+ root
62
+ .find(j.Identifier)
63
+ .filter(
64
+ path =>
65
+ (path.node).start === diagnostic.start &&
66
+ (path.node).end === diagnostic.start + diagnostic.length &&
67
+ path.parentPath.node.type === 'MemberExpression' &&
68
+ path.parentPath.node.object.type === 'ThisExpression' &&
69
+ path.parentPath.parentPath.node.type === 'AssignmentExpression' && path.parentPath.parentPath.node.operator === '=' &&
70
+ inConstructor(path)
71
+ )
72
+ .forEach(path => {
73
+ const classBody = findParentClassBody(path);
74
+ if (!classBody) {
75
+ return;
76
+ }
77
+ let item = toAdd.find(cur => cur.classBody === classBody);
78
+ if (!item) {
79
+ item = {classBody, propertyNames: new Map()};
80
+ toAdd.push(item);
81
+ }
82
+
83
+ let assignment = findParentPath(path, parentPath => parentPath.node.type === 'AssignmentExpression');
84
+ let typeDesc = getTypeFor(j, path.node.name, assignment.node.right, Object.values(typeMap));
85
+ if (typeDesc && typeDesc.module) {
86
+ referencedTypes.add(typeDesc);
87
+ }
88
+ let property = {
89
+ type: typeDesc.type
90
+ };
91
+ if (assignment.parentPath.node.comments) {
92
+ property.comments = assignment.parentPath.node.comments;
93
+ // Remove comment from property assignment
94
+ assignment.parentPath.node.comments = null;
95
+ }
96
+ item.propertyNames.set(path.node.name, property);
97
+ });
98
+ });
99
+
100
+ toAdd.forEach(({classBody, propertyNames: properties}) => {
101
+ const /** @type {string[]}*/ propertyNames = Array.from(properties.keys())
102
+ .filter(propertyName => {
103
+ const existingProperty = findClassProperty(classBody, propertyName);
104
+ return existingProperty == null;
105
+ })
106
+ .sort(propertyComparator);
107
+
108
+ // Insert before constructor
109
+ let index = findIndex(classBody.node.body, node => node.type === 'ClassMethod' && node.kind === 'constructor');
110
+ if (index < 0) {
111
+ index = 0;
112
+ }
113
+ classBody.node.body.splice(
114
+ index,
115
+ 0,
116
+ ...propertyNames.map(propertyName => {
117
+ let propertyDesc = properties.get(propertyName);
118
+ let prop = j.classProperty(
119
+ j.identifier(propertyName),
120
+ null,
121
+ j.tsTypeAnnotation(propertyDesc.type)
122
+ );
123
+ let comments = transformCommentLinesToJsDoc(j, propertyDesc.comments);
124
+ if (comments) {
125
+ prop.comments = comments;
126
+ }
127
+ return prop;
128
+ })
129
+ );
130
+ });
131
+
132
+ insertMissingImportsForTypes(j, root, Array.from(referencedTypes), moduleMap, sourceFile.fileName);
133
+ return removeEmptyLinesBetweenImports(root.toSource(defaultRecastOptions));
134
+ },
135
+
136
+ validate: validateAnyAliasOptions
137
+ };
138
+
139
+ export default declareMissingClassPropertiesPlugin;
@@ -0,0 +1,51 @@
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
+ import jscodeshift from 'jscodeshift';
11
+ import {defaultRecastOptions} from './common.js';
12
+
13
+ const j = jscodeshift.withParser('ts');
14
+
15
+ /**
16
+ * @type import('ts-migrate-server').Plugin<unknown>
17
+ */
18
+ const memberAccessModifierPlugin = {
19
+ name: 'member-access-modifier-plugin',
20
+
21
+ async run({text}) {
22
+ const root = j(text);
23
+ // Declaration is base type for ClassMethod and ClassProperty according to https://github.com/benjamn/ast-types/tree/master/def
24
+ return root.find(j.Declaration)
25
+ .filter(path => path.node.type === j.ClassMethod.name || path.node.type === j.ClassProperty.name)
26
+ .forEach(expression => {
27
+ if (expression.node.accessibility) {
28
+ return;
29
+ }
30
+ let name = expression.node.key.name;
31
+ if (name && name.startsWith('_') && !containsInternalInJsDoc(expression.node)) {
32
+ expression.node.accessibility = 'protected';
33
+ }
34
+ }).toSource(defaultRecastOptions);
35
+ }
36
+ };
37
+
38
+ function containsInternalInJsDoc(node) {
39
+ let comments = node.comments;
40
+ if (!comments) {
41
+ return false;
42
+ }
43
+ return comments.some(comment => {
44
+ if (comment.type !== 'CommentBlock') {
45
+ return false;
46
+ }
47
+ return comment.value.includes('@internal');
48
+ });
49
+ }
50
+
51
+ export default memberAccessModifierPlugin;
@@ -0,0 +1,77 @@
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
+ // noinspection SpellCheckingInspection
12
+ import jscodeshift from 'jscodeshift';
13
+ import {defaultMenuTypesMap, defaultModuleMap, defaultRecastOptions, insertMissingImportsForTypes, mapType} from './common.js';
14
+
15
+ const j = jscodeshift.withParser('ts');
16
+
17
+ /**
18
+ * @type import('ts-migrate-server').Plugin<{menuTypesMap?: object, moduleMap?: object}>
19
+ */
20
+ const menuTypesPlugin = {
21
+ name: 'menu-types-plugin',
22
+
23
+ async run({text, fileName, options}) {
24
+ let root = j(text),
25
+ referencedTypes = new Set();
26
+ const menuTypesMap = {...defaultMenuTypesMap, ...options.menuTypesMap},
27
+ moduleMap = {...defaultModuleMap, ...options.moduleMap};
28
+
29
+ // noinspection JSCheckFunctionSignatures
30
+ root.find(j.ObjectProperty, {key: {name: 'menuTypes'}})
31
+ .forEach(/** NodePath<ObjectProperty, ObjectProperty> */path => {
32
+ let node = path.node;
33
+ if (!node.value || node.value.type !== 'ArrayExpression') {
34
+ return;
35
+ }
36
+ let elements = node.value.elements;
37
+ for (let i = 0; i < elements.length; i++) {
38
+ let element = elements[i];
39
+ if (!element || element.type !== 'StringLiteral') {
40
+ continue;
41
+ }
42
+ let menuType = getMenuTypeForStringMenuType(element.value, menuTypesMap, referencedTypes);
43
+ if (!menuType) {
44
+ continue;
45
+ }
46
+ elements.splice(i, 1, menuType);
47
+ }
48
+ });
49
+
50
+ insertMissingImportsForTypes(j, root, Array.from(referencedTypes), moduleMap, fileName);
51
+ return root.toSource(defaultRecastOptions);
52
+ }
53
+ };
54
+
55
+ function getMenuTypeForStringMenuType(menuTypeString, menuTypeMap, referencedTypes) {
56
+ let menuTypeInfo = menuTypeMap[menuTypeString];
57
+ if (!menuTypeInfo) {
58
+ return null;
59
+ }
60
+ let {objectType, menuTypes, menuType} = menuTypeInfo;
61
+ if (!objectType || !menuTypes || !menuType) {
62
+ return null;
63
+ }
64
+
65
+ // noinspection DuplicatedCode
66
+ let module = 'scout';
67
+ let name = objectType;
68
+ if (objectType.indexOf('.') > -1) {
69
+ [module, name] = objectType.split('.');
70
+ }
71
+ let type = mapType(j, module + '.' + name);
72
+ referencedTypes.add(type);
73
+
74
+ return j.memberExpression(j.memberExpression(j.identifier(name), j.identifier(menuTypes)), j.identifier(menuType));
75
+ }
76
+
77
+ export default menuTypesPlugin;
@@ -0,0 +1,143 @@
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
+ import jscodeshift from 'jscodeshift';
11
+ import {defaultModuleMap, defaultParamTypeMap, defaultRecastOptions, defaultReturnTypeMap, findTypeByName, insertMissingImportsForTypes, mapType, methodFilter, removeEmptyLinesBetweenImports} from './common.js';
12
+
13
+ const j = jscodeshift.withParser('ts');
14
+ let referencedTypes;
15
+
16
+ /**
17
+ * Processes class methods and exported functions of utilities.
18
+ *
19
+ * Adds parameter and return types based on naming rules defined in type maps (see {@link defaultParamTypeMap} and {@link defaultParamTypeMap}).
20
+ * Custom type rules can be specified with an option.
21
+ *
22
+ * Also adds required imports for the added types.
23
+ * The types in the type maps can be prefixed with a module name that will be mapped to a npm module by the provided moduleMap (see {@link defaultModuleMap}).
24
+ *
25
+ * Finally, the js doc comments are cleaned up, which means the type information is removed.
26
+ *
27
+ * @type import('ts-migrate-server').Plugin<{paramTypeMap?: object, returnTypeMap?: object, moduleMap?: object, defaultReturnType?: string, defaultParamType?: string}>
28
+ */
29
+ const methodsPlugin = {
30
+ name: 'methods-plugin',
31
+
32
+ async run({text, options, sourceFile}) {
33
+ let root = j(text);
34
+ const paramTypeMap = {...defaultParamTypeMap, ...options.paramTypeMap};
35
+ const returnTypeMap = {...defaultReturnTypeMap, ...options.returnTypeMap};
36
+ const moduleMap = {...defaultModuleMap, ...options.moduleMap};
37
+ const defaultReturnType = options.defaultReturnType;
38
+ const defaultParamType = options.defaultParamType;
39
+ referencedTypes = new Set();
40
+
41
+ root.find(j.Declaration)
42
+ .filter(path => methodFilter(j, path))
43
+ .forEach(expression => {
44
+ let node = expression.node;
45
+ if (node.params) {
46
+ for (let param of node.params) {
47
+ processParamType(param, Object.values(paramTypeMap), defaultParamType);
48
+ }
49
+ }
50
+ processReturnType(node, Object.values(returnTypeMap), defaultReturnType);
51
+ removeJsDocTypes(node);
52
+ });
53
+
54
+ insertMissingImportsForTypes(j, root, Array.from(referencedTypes), moduleMap, sourceFile.fileName);
55
+ return removeEmptyLinesBetweenImports(root.toSource(defaultRecastOptions));
56
+ }
57
+ };
58
+
59
+ function processReturnType(func, typeMaps, defaultReturnType) {
60
+ let name = func.key ? func.key.name : func.id.name;
61
+ if (func.returnType) {
62
+ return;
63
+ }
64
+ let typeDesc = findTypeByName(j, typeMaps, name);
65
+ if (!typeDesc && defaultReturnType && func.kind !== 'constructor' && func.kind !== 'set') {
66
+ typeDesc = mapType(j, defaultReturnType);
67
+ }
68
+ if (typeDesc) {
69
+ func.returnType = j.tsTypeAnnotation(typeDesc.type);
70
+ if (typeDesc.module) {
71
+ referencedTypes.add(typeDesc);
72
+ }
73
+ }
74
+ }
75
+
76
+ function processParamType(param, typeMaps, defaultParamType) {
77
+ let name = param.name;
78
+ if (param.typeAnnotation) {
79
+ return;
80
+ }
81
+ let typeDesc = findTypeByName(j, typeMaps, name);
82
+ if (!typeDesc && defaultParamType) {
83
+ typeDesc = mapType(j, defaultParamType);
84
+ }
85
+ if (typeDesc) {
86
+ param.typeAnnotation = j.tsTypeAnnotation(typeDesc.type);
87
+ if (typeDesc.module) {
88
+ referencedTypes.add(typeDesc);
89
+ }
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Removes all types form jsdoc if the types exist as TS types
95
+ */
96
+ function removeJsDocTypes(func) {
97
+ let comments = func.comments;
98
+ if (!comments) {
99
+ return;
100
+ }
101
+ let replaceReturnType = !!func.returnType;
102
+ let replaceParams = [];
103
+ if (func.params) {
104
+ replaceParams = func.params.filter(param => !!param.typeAnnotation);
105
+ }
106
+ if (!replaceReturnType && replaceParams.length === 0) {
107
+ return;
108
+ }
109
+ func.comments = comments.map(comment => {
110
+ if (comment.type !== 'CommentBlock') {
111
+ return comment;
112
+ }
113
+ let str = comment.value;
114
+ str = str.replaceAll(/ +\*/g, ''); // remove * at start of lines, makes the upcoming processing easier
115
+ let beforeReplace = str;
116
+ if (replaceReturnType) {
117
+ str = str.replace(/(@return[s]?) ({.*})/, '@returns'); // remove type from @return
118
+ str = str.replace(/@returns[\s]*$/, ''); // remove empty return at the end
119
+ }
120
+ for (let param of replaceParams) {
121
+ str = str.replace(new RegExp(`@param {.*} \\[?${param.name}\\]?`), `@param ${param.name}`); // remove type from @param
122
+ str = str.replace(new RegExp(`@param \\[?${param.name}\\]? {.*}`), `@param ${param.name}`); // consider reverse typing as well (@param [var] {type} instead of @param {type} [var]
123
+ str = str.replace(new RegExp(`@param \\[${param.name}\\]`), `@param ${param.name}`); // remove brackets even without type
124
+ str = str.replace(new RegExp(`@param ${param.name}[\\s]*$`), ''); // remove empty param at end
125
+ str = str.replace(new RegExp(`@param ${param.name}[\\s]*@param`), '@param'); // remove empty param before param
126
+ str = str.replace(new RegExp(`@param ${param.name}[\\s]*@return`), '@return'); // remove empty param before return
127
+ }
128
+ if (beforeReplace === str) {
129
+ // Do nothing if nothing was replaced
130
+ return comment;
131
+ }
132
+ str = str.replace(/\r\n +$/, '\r\n'); // remove whitespaces at the end (keep new line)
133
+ str = str.replaceAll(/\r\n/g, '\r\n *'); // add * again
134
+ str = str.replace(/\r\n \*$/, '\r\n'); // Remove last * that was added by the line before. It will be added automatically by the block comment.
135
+ if (str.trim() === '*') {
136
+ // Remove empty comments
137
+ return null;
138
+ }
139
+ return j.commentBlock(str);
140
+ }).filter(comment => comment !== null);
141
+ }
142
+
143
+ export default methodsPlugin;
@@ -0,0 +1,78 @@
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
+ import jscodeshift from 'jscodeshift';
11
+ import {findClassProperty, findParentClassBody, getNameForType, isOneOf} from './common.js';
12
+
13
+ const j = jscodeshift.withParser('ts');
14
+
15
+ /**
16
+ * @type import('ts-migrate-server').Plugin<{}>
17
+ */
18
+ const printEventMapsPlugin = {
19
+ name: 'print-event-maps-plugin',
20
+
21
+ async run({text, fileName, options}) {
22
+ let root = j(text);
23
+
24
+ let eventLines = new Set();
25
+ let propEvents = new Map();
26
+ let className = fileName.substring(fileName.lastIndexOf('/') + 1, fileName.lastIndexOf('.'));
27
+
28
+ root.find(j.CallExpression)
29
+ .filter(path =>
30
+ path.value.callee.type === 'MemberExpression'
31
+ && path.value.callee.object.type === 'ThisExpression'
32
+ && isOneOf(path.value.callee.property.name, 'setProperty', '_setProperty', 'trigger')
33
+ )
34
+ .forEach(expression => {
35
+ let funcName = expression.value.callee.property.name;
36
+ let eventName = expression.value.arguments[0]?.value;
37
+ if (isOneOf(funcName, 'setProperty', '_setProperty')) {
38
+ let type = '?';
39
+ let property = findClassProperty(findParentClassBody(expression), eventName);
40
+ if (property) {
41
+ let typeAnnotation = property.typeAnnotation;
42
+ type = typeAnnotation ? getNameForType(j, typeAnnotation?.typeAnnotation) || '?' : '?';
43
+ }
44
+ let value = propEvents.get(eventName);
45
+ if (value && !value.includes('<?>')) {
46
+ // Don't replace existing value if it already has a type
47
+ return;
48
+ }
49
+ propEvents.set(eventName, `'propertyChange:${eventName}': PropertyChangeEvent<${type}>;`);
50
+ } else {
51
+ let eventObj = expression.value.arguments[1];
52
+ let event = '?';
53
+ if (!eventObj) {
54
+ event = `Event<${className}>`;
55
+ }
56
+ if (!eventName) {
57
+ return;
58
+ }
59
+ eventLines.add(`'${eventName}': ${event};`);
60
+ }
61
+ });
62
+
63
+ if (eventLines.size > 0 || propEvents.size > 0) {
64
+ console.log(`${className}EventMap`);
65
+ if (eventLines.size > 0) {
66
+ console.log(Array.from(eventLines).sort().join('\n'));
67
+ }
68
+ if (propEvents.size > 0) {
69
+ console.log(Array.from(propEvents.values()).sort().join('\n'));
70
+ }
71
+ console.log('\n');
72
+ }
73
+
74
+ return text;
75
+ }
76
+ };
77
+
78
+ export default printEventMapsPlugin;
@@ -0,0 +1,64 @@
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
+ import jscodeshift from 'jscodeshift';
11
+ import {defaultModuleMap, defaultRecastOptions, insertMissingImportsForTypes, isOneOf, mapType, removeEmptyLinesBetweenImports} from './common.js';
12
+
13
+ const j = jscodeshift.withParser('ts');
14
+ let referencedTypes;
15
+
16
+ /**
17
+ * @type import('ts-migrate-server').Plugin<{moduleMap?: object}>
18
+ */
19
+ const typedObjectTypePlugin = {
20
+ name: 'typed-object-type-plugin',
21
+
22
+ async run({text, options, sourceFile}) {
23
+ let root = j(text);
24
+ const moduleMap = {...defaultModuleMap, ...options.moduleMap};
25
+ referencedTypes = new Set();
26
+
27
+ root.find(j.ObjectProperty)
28
+ .filter(path =>
29
+ isOneOf(path.value.key.name, 'objectType', 'logicalGrid', 'lookupCall') &&
30
+ path.value.value.type === j.StringLiteral.name)
31
+ .forEach(path => {
32
+ let objectType = path.value.value.value;
33
+ path.node.value = getTypeForStringObjectType(objectType);
34
+ });
35
+
36
+ root.find(j.CallExpression)
37
+ .filter(path =>
38
+ path.value.callee.type === j.MemberExpression.name &&
39
+ path.value.callee.object.name === 'scout' &&
40
+ path.value.callee.property.name === 'create' &&
41
+ path.value.arguments[0].type === j.StringLiteral.name)
42
+ .forEach(path => {
43
+ let objectType = path.value.arguments[0].value;
44
+ path.node.arguments[0] = getTypeForStringObjectType(objectType);
45
+ });
46
+
47
+ insertMissingImportsForTypes(j, root, Array.from(referencedTypes), moduleMap, sourceFile.fileName);
48
+ return removeEmptyLinesBetweenImports(root.toSource(defaultRecastOptions));
49
+ }
50
+ };
51
+
52
+ function getTypeForStringObjectType(objectType) {
53
+ // noinspection DuplicatedCode
54
+ let module = 'scout';
55
+ let name = objectType;
56
+ if (objectType.indexOf('.') > -1) {
57
+ [module, name] = objectType.split('.');
58
+ }
59
+ let type = mapType(j, module + '.' + name);
60
+ referencedTypes.add(type);
61
+ return j.identifier(name);
62
+ }
63
+
64
+ export default typedObjectTypePlugin;