79 lines
No EOL
3.1 KiB
TypeScript
Executable file
79 lines
No EOL
3.1 KiB
TypeScript
Executable file
import { Project, SyntaxKind } from 'ts-morph';
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
|
|
const project = new Project({ tsConfigFilePath: 'C:/ScriptoriumAI/scriptoriumai-ui/tsconfig.json' });
|
|
const sourceFile = project.getSourceFileOrThrow('C:/ScriptoriumAI/scriptoriumai-ui/src/pages/Runboard.tsx');
|
|
|
|
const pagesDir = 'C:/ScriptoriumAI/scriptoriumai-ui/src/pages/Runboard';
|
|
if (!fs.existsSync(pagesDir)) fs.mkdirSync(pagesDir, { recursive: true });
|
|
|
|
// 1. Extract purely logic helpers into Runboard/utils.tsx
|
|
const utilsFile = project.createSourceFile(pagesDir + '/utils.tsx', '', { overwrite: true });
|
|
|
|
// Collect all top-level functions (except Runboard)
|
|
const stmts = sourceFile.getStatements();
|
|
const toMove = stmts.filter(s =>
|
|
s.getKindName() !== 'ImportDeclaration' &&
|
|
s.getKindName() !== 'ExportDeclaration' &&
|
|
!(s.isKind(SyntaxKind.FunctionDeclaration) && s.getName() === 'Runboard')
|
|
);
|
|
|
|
toMove.forEach(s => {
|
|
// Ensure exported
|
|
if (s.isKind(SyntaxKind.FunctionDeclaration) || s.isKind(SyntaxKind.VariableStatement) || s.isKind(SyntaxKind.TypeAliasDeclaration) || s.isKind(SyntaxKind.InterfaceDeclaration)) {
|
|
if (!s.hasExportKeyword()) {
|
|
(s as any).setIsExported(true);
|
|
}
|
|
}
|
|
utilsFile.addStatements(s.getText());
|
|
s.remove();
|
|
});
|
|
|
|
// Steal imports
|
|
sourceFile.getImportDeclarations().forEach(imp => {
|
|
utilsFile.addImportDeclaration({
|
|
isTypeOnly: imp.isTypeOnly(),
|
|
defaultImport: imp.getDefaultImport()?.getText(),
|
|
namedImports: imp.getNamedImports().map(n => ({ name: n.getName(), alias: n.getAliasNode()?.getText() })),
|
|
moduleSpecifier: imp.getModuleSpecifierValue().startsWith('./') ? '../../' + imp.getModuleSpecifierValue().substring(2) : (imp.getModuleSpecifierValue().startsWith('../') ? '../../../' + imp.getModuleSpecifierValue().substring(3) : imp.getModuleSpecifierValue())
|
|
});
|
|
});
|
|
|
|
// Import them back into sourceFile
|
|
const namesToImport: string[] = [];
|
|
utilsFile.getStatements().forEach(s => {
|
|
if (s.isKind(SyntaxKind.FunctionDeclaration) || s.isKind(SyntaxKind.TypeAliasDeclaration) || s.isKind(SyntaxKind.InterfaceDeclaration)) {
|
|
const n = (s as any).getName?.();
|
|
if (n) namesToImport.push(n);
|
|
}
|
|
if (s.isKind(SyntaxKind.VariableStatement)) {
|
|
s.getDeclarations().forEach(d => namesToImport.push(d.getName()));
|
|
}
|
|
});
|
|
sourceFile.addImportDeclaration({
|
|
namedImports: namesToImport,
|
|
moduleSpecifier: './Runboard/utils'
|
|
});
|
|
|
|
// 2. Componentize the Layout shell:
|
|
// Let's create Layout.tsx which exports the wrapper
|
|
const layoutFile = project.createSourceFile(pagesDir + '/Layout.tsx', '', { overwrite: true });
|
|
layoutFile.addStatements(`
|
|
import React from 'react';
|
|
import { PlatformAuthProvider } from '../../auth/platform-auth';
|
|
import { SubscriptionGate } from '../../components/SubscriptionGate';
|
|
|
|
export function RunboardLayout({ children }: { children: React.ReactNode }) {
|
|
return (
|
|
<PlatformAuthProvider>
|
|
<SubscriptionGate>
|
|
{children}
|
|
</SubscriptionGate>
|
|
</PlatformAuthProvider>
|
|
);
|
|
}
|
|
`);
|
|
|
|
project.saveSync();
|
|
console.log('Runboard Componentization Phase 1 done: Splitting shell utils and wrappers.'); |