-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathreplaceModuleExports.ts
More file actions
114 lines (99 loc) · 4.42 KB
/
replaceModuleExports.ts
File metadata and controls
114 lines (99 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import {SourceFile, SyntaxKind} from 'ts-morph';
import {NodeUtil} from '../../util/NodeUtil.js';
// module.exports = Benny
// Binary Expression > PropertyAccessExpression + Identifier
// module.exports = function some()
// Binary Expression > PropertyAccessExpression + FunctionExpression
export function replaceModuleExports(sourceFile: SourceFile) {
let foundDefaultExport: boolean = false;
let foundNamedExport: boolean = false;
sourceFile.getStatements().forEach(statement => {
try {
const expressionStatement = statement.asKind(SyntaxKind.ExpressionStatement);
if (!expressionStatement) {
return;
}
const binaryExpression = expressionStatement.getExpression().asKind(SyntaxKind.BinaryExpression);
if (!binaryExpression) {
return;
}
const left = binaryExpression.getLeft().asKind(SyntaxKind.PropertyAccessExpression);
if (!left) {
return;
}
const right = binaryExpression.getRight();
const leftText = left.getText();
const rightText = right.getText();
const isDefaultExport = leftText === 'module.exports';
const isNamedExport = leftText.startsWith('module.exports.');
const isExportingFunction = right.getKind() === SyntaxKind.FunctionExpression;
const isExportingIdentifier = right.getKind() === SyntaxKind.Identifier;
const isExportingObjectLiteral = right.getKind() === SyntaxKind.ObjectLiteralExpression;
const {comment} = NodeUtil.extractComment(left);
switch (true) {
case isDefaultExport: {
foundDefaultExport = true;
const position = expressionStatement.getChildIndex();
if (isExportingIdentifier) {
sourceFile.insertExportAssignment(position, {
expression: rightText,
isExportEquals: false,
});
} else if (isExportingFunction) {
// @see https://github.com/dsherret/ts-morph/issues/1586
sourceFile.insertStatements(position, `${comment}export default ${rightText};`);
} else if (isExportingObjectLiteral) {
// Handle object literal expressions like module.exports = { c0, c1 }
foundNamedExport = true;
const objectLiteral = right.asKind(SyntaxKind.ObjectLiteralExpression);
if (objectLiteral) {
const exportNames: string[] = [];
const properties = objectLiteral.getProperties();
for (const property of properties) {
if (property.getKind() === SyntaxKind.ShorthandPropertyAssignment) {
// For shorthand properties like { c0, c1 }, export the name directly
const shorthandProperty = property.asKind(SyntaxKind.ShorthandPropertyAssignment);
if (shorthandProperty) {
const name = shorthandProperty.getName();
exportNames.push(name);
}
} else if (property.getKind() === SyntaxKind.PropertyAssignment) {
// For regular properties like { a: c0, b: c1 }, export with alias
const propAssignment = property.asKind(SyntaxKind.PropertyAssignment);
if (propAssignment) {
const name = propAssignment.getName();
const initializer = propAssignment.getInitializer();
if (initializer && initializer.getKind() === SyntaxKind.Identifier) {
const identifier = initializer.getText();
exportNames.push(`${identifier} as ${name}`);
}
}
}
}
if (exportNames.length > 0) {
sourceFile.insertExportDeclaration(position, {
namedExports: exportNames,
});
}
}
}
expressionStatement.remove();
break;
}
case isNamedExport: {
foundNamedExport = true;
const position = expressionStatement.getChildIndex();
sourceFile.insertExportDeclaration(position, {
namedExports: [rightText],
});
expressionStatement.remove();
break;
}
}
} catch (error: unknown) {
console.error(` There was an issue with "${sourceFile.getFilePath()}":`, error);
}
});
const madeChanges = foundDefaultExport || foundNamedExport;
return madeChanges;
}