63 lines
3.3 KiB
JavaScript
63 lines
3.3 KiB
JavaScript
import path from "path";
|
|
import ts from "typescript";
|
|
export default function stripServerSideLogic({ txt_code, file_path }) {
|
|
const sourceFile = ts.createSourceFile("file.tsx", txt_code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
const printer = ts.createPrinter();
|
|
const file_fir_name = path.dirname(file_path);
|
|
const transformer = (context) => (rootNode) => {
|
|
const visitor = (node) => {
|
|
// 1. Strip the 'server' export
|
|
if (ts.isVariableStatement(node) &&
|
|
node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword)) {
|
|
const isServer = node.declarationList.declarations.some((d) => ts.isIdentifier(d.name) && d.name.text === "server");
|
|
if (isServer)
|
|
return undefined;
|
|
}
|
|
// 2. Convert relative imports to absolute imports
|
|
if (ts.isImportDeclaration(node)) {
|
|
const moduleSpecifier = node.moduleSpecifier;
|
|
if (ts.isStringLiteral(moduleSpecifier) &&
|
|
moduleSpecifier.text.startsWith(".")) {
|
|
// Resolve the relative path to an absolute filesystem path
|
|
const absolutePath = path.resolve(file_fir_name, moduleSpecifier.text);
|
|
return ts.factory.updateImportDeclaration(node, node.modifiers, node.importClause, ts.factory.createStringLiteral(absolutePath), node.attributes);
|
|
}
|
|
}
|
|
return ts.visitEachChild(node, visitor, context);
|
|
};
|
|
return ts.visitNode(rootNode, visitor);
|
|
};
|
|
const result = ts.transform(sourceFile, [transformer]);
|
|
const intermediate = printer.printFile(result.transformed[0]);
|
|
// Pass 2: Cleanup unused imports (Same logic as before)
|
|
const cleanSource = ts.createSourceFile("clean.tsx", intermediate, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
const cleanup = (context) => (rootNode) => {
|
|
const visitor = (node) => {
|
|
if (ts.isImportDeclaration(node)) {
|
|
const clause = node.importClause;
|
|
if (!clause)
|
|
return node;
|
|
if (clause.namedBindings &&
|
|
ts.isNamedImports(clause.namedBindings)) {
|
|
const used = clause.namedBindings.elements.filter((el) => {
|
|
const regex = new RegExp(`\\b${el.name.text}\\b`, "g");
|
|
return ((intermediate.match(regex) || []).length > 1);
|
|
});
|
|
if (used.length === 0)
|
|
return undefined;
|
|
return ts.factory.updateImportDeclaration(node, node.modifiers, ts.factory.updateImportClause(clause, clause.isTypeOnly, clause.name, ts.factory.createNamedImports(used)), node.moduleSpecifier, node.attributes);
|
|
}
|
|
if (clause.name) {
|
|
const regex = new RegExp(`\\b${clause.name.text}\\b`, "g");
|
|
if ((intermediate.match(regex) || []).length <= 1)
|
|
return undefined;
|
|
}
|
|
}
|
|
return ts.visitEachChild(node, visitor, context);
|
|
};
|
|
return ts.visitNode(rootNode, visitor);
|
|
};
|
|
const final = ts.transform(cleanSource, [cleanup]);
|
|
return printer.printFile(final.transformed[0]);
|
|
}
|