import { ts, Plugin, CallExpressionShape, type Shape } from '@servicenow/sdk-build-core' import { getCallExpressionName } from './utils' export const CallExpressionPlugin = Plugin.create({ name: 'CallExpressionPlugin', noTelemetry: true, nodes: [ { node: 'CallExpression', fileTypes: ['fluent'], entryPoint: true, async toShape(node, { transform }) { const args: Shape[] = [] for (const arg of node.getArguments()) { const result = await transform.toShape(arg) if (!result.success) { return { success: false } } args.push(result.value) } return { success: true, value: new CallExpressionShape({ source: node, callee: getCallExpressionName(node), args, }), } }, }, ], shapes: [ { shape: CallExpressionShape, async commit(shape, target, { commit }) { if (target.isKind(ts.SyntaxKind.ExpressionStatement)) { target = target.getExpression() } if (!ts.Node.isCallExpression(target)) { target.replaceWithText(shape.getCode()) return { success: true } } const callee = target.getExpression() if (callee.getText() !== shape.getCallee()) { callee.replaceWithText(shape.getCallee()) } // Trim any excess arguments const targetArguments = target.getArguments() const shapeArguments = shape.getArguments(false) const excess = targetArguments.length - shapeArguments.length for (let i = 1; i <= excess; i++) { target.removeArgument(targetArguments.length - i) } // Commit existing arguments after trimming for (const [i, targetElement] of target.getArguments().entries()) { await commit(shape.getArgument(i, false), targetElement) } // Add new arguments all at once const argumentsToAdd = shapeArguments.slice(target.getArguments().length).map((e) => e.getCode()) if (argumentsToAdd.length > 0) { target.addArguments(argumentsToAdd) } return { success: true } }, }, ], })