148 lines
3.5 KiB
TypeScript
148 lines
3.5 KiB
TypeScript
import type * as ts from 'typescript';
|
|
import { ChangeType, StringChange } from '@nx/devkit';
|
|
import { findNodes } from '@nx/js';
|
|
|
|
import {
|
|
findClosestOpening,
|
|
findElements,
|
|
addImport,
|
|
} from '../utils/ast-utils';
|
|
import { ensureTypescript } from '@nx/js/src/utils/typescript/ensure-typescript';
|
|
|
|
let tsModule: typeof import('typescript');
|
|
|
|
export function addRemoteToConfig(
|
|
source: ts.SourceFile,
|
|
app: string
|
|
): StringChange[] {
|
|
if (!tsModule) {
|
|
tsModule = ensureTypescript();
|
|
}
|
|
|
|
const assignments = findNodes(
|
|
source,
|
|
tsModule.SyntaxKind.PropertyAssignment
|
|
) as ts.PropertyAssignment[];
|
|
|
|
const remotesAssignment = assignments.find(
|
|
(s) => s.name.getText() === 'remotes'
|
|
);
|
|
|
|
if (remotesAssignment) {
|
|
const arrayExpression =
|
|
remotesAssignment.initializer as ts.ArrayLiteralExpression;
|
|
|
|
if (!arrayExpression.elements) return [];
|
|
|
|
const lastElement =
|
|
arrayExpression.elements[arrayExpression.elements.length - 1];
|
|
return [
|
|
lastElement && !arrayExpression.elements.hasTrailingComma
|
|
? {
|
|
type: ChangeType.Insert,
|
|
index: lastElement.end,
|
|
text: `,`,
|
|
}
|
|
: null,
|
|
{
|
|
type: ChangeType.Insert,
|
|
index: remotesAssignment.end - 1,
|
|
text: `'${app}',\n`,
|
|
},
|
|
].filter(Boolean) as StringChange[];
|
|
}
|
|
|
|
const binaryExpressions = findNodes(
|
|
source,
|
|
tsModule.SyntaxKind.BinaryExpression
|
|
) as ts.BinaryExpression[];
|
|
const exportExpression = binaryExpressions.find((b) => {
|
|
if (b.left.kind === tsModule.SyntaxKind.PropertyAccessExpression) {
|
|
const pae = b.left as ts.PropertyAccessExpression;
|
|
return (
|
|
pae.expression.getText() === 'module' &&
|
|
pae.name.getText() === 'exports'
|
|
);
|
|
}
|
|
});
|
|
|
|
if (
|
|
exportExpression?.right.kind === tsModule.SyntaxKind.ObjectLiteralExpression
|
|
) {
|
|
const ole = exportExpression.right as ts.ObjectLiteralExpression;
|
|
return [
|
|
{
|
|
type: ChangeType.Insert,
|
|
index: ole.end - 1,
|
|
text: `remotes: ['${app}']\n`,
|
|
},
|
|
];
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
export function addRemoteDefinition(
|
|
source: ts.SourceFile,
|
|
app: string
|
|
): StringChange[] {
|
|
return [
|
|
{
|
|
type: ChangeType.Insert,
|
|
index: source.end,
|
|
text: `\ndeclare module '${app}/Module';`,
|
|
},
|
|
];
|
|
}
|
|
|
|
export function addRemoteRoute(
|
|
source: ts.SourceFile,
|
|
names: {
|
|
fileName: string;
|
|
className: string;
|
|
}
|
|
): StringChange[] {
|
|
const routes = findElements(source, 'Route');
|
|
const links = findElements(source, 'Link');
|
|
|
|
if (routes.length === 0) {
|
|
return [];
|
|
} else {
|
|
const changes: StringChange[] = [];
|
|
const firstRoute = routes[0];
|
|
const firstLink = links[0];
|
|
|
|
changes.push(
|
|
...addImport(
|
|
source,
|
|
`const ${names.className} = React.lazy(() => import('${names.fileName}/Module'));`
|
|
)
|
|
);
|
|
|
|
changes.push({
|
|
type: ChangeType.Insert,
|
|
index: firstRoute.end,
|
|
text: `\n<Route path="/${names.fileName}" element={<${names.className} />} />`,
|
|
});
|
|
|
|
if (firstLink) {
|
|
const parentLi = findClosestOpening('li', firstLink);
|
|
if (parentLi) {
|
|
changes.push({
|
|
type: ChangeType.Insert,
|
|
index: parentLi.end,
|
|
text: `\n<li><Link to="/${names.fileName}">${names.className}</Link></li>`,
|
|
});
|
|
} else {
|
|
changes.push({
|
|
type: ChangeType.Insert,
|
|
index: firstLink.parent.end,
|
|
text: `\n<Link to="/${names.fileName}">${names.className}</Link>`,
|
|
});
|
|
}
|
|
}
|
|
|
|
return changes;
|
|
}
|
|
}
|