-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgetTypesFromNode.ts
More file actions
88 lines (75 loc) · 3.02 KB
/
Copy pathgetTypesFromNode.ts
File metadata and controls
88 lines (75 loc) · 3.02 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
import ts from "typescript";
import {DataType, Flow, FunctionDefinition, NodeFunction, NodeParameter} from "@code0-tech/sagittarius-graphql-types";
import {createCompilerHost, getParameterCode, getSharedTypeDeclarations,} from "../utils";
import {getNodeValidation} from "../validation/getNodeValidation"; // Wieder hinzugefügt
export interface NodeTypes {
parameters: string[];
returnType: string;
}
/**
* Resolves the types of the parameters and the return type of a NodeFunction.
*/
export const getTypesFromNode = (
node: NodeFunction,
functions: FunctionDefinition[],
dataTypes: DataType[]
): NodeTypes => {
const funcMap = new Map(functions.map(f => [f.identifier, f]));
const funcDef = funcMap.get(node.functionDefinition?.identifier);
if (!funcDef) {
return {
parameters: [],
returnType: "any",
};
}
const mockFlow: Flow = {
id: "gid://sagittarius/Flow/0" as any,
nodes: {__typename: "NodeFunctionConnection", nodes: [node]}
} as Flow;
const params = (node.parameters?.nodes as NodeParameter[]) || [];
const paramCodes = params.map(param => getParameterCode(param, mockFlow, (f, n) => getNodeValidation(f, n, functions, dataTypes)));
const funcCallArgs = paramCodes.map(code => code === 'undefined' ? '({} as any)' : code).join(", ");
const signature = funcDef.signature;
const sourceCode = `
${getSharedTypeDeclarations(dataTypes)}
declare function testFunc${signature};
const result = testFunc(${funcCallArgs});
`;
const fileName = "index.ts";
const host = createCompilerHost(fileName, sourceCode);
const sourceFile = host.getSourceFile(fileName)!;
const program = host.languageService.getProgram()!;
const checker = program.getTypeChecker();
let inferredReturnType = "any";
let inferredParameterTypes: string[] = [];
const visitor = (n: ts.Node) => {
if (ts.isVariableDeclaration(n) && n.name.getText() === "result") {
const resultType = checker.getTypeAtLocation(n);
inferredReturnType = checker.typeToString(
resultType,
n,
ts.TypeFormatFlags.NoTruncation
);
if (ts.isCallExpression(n.initializer!)) {
const callExpr = n.initializer;
const signature = checker.getResolvedSignature(callExpr);
if (signature) {
inferredParameterTypes = signature.getParameters().map(p => {
const type = checker.getTypeOfSymbolAtLocation(p, callExpr);
return checker.typeToString(
type,
callExpr,
ts.TypeFormatFlags.NoTruncation
);
});
}
}
}
ts.forEachChild(n, visitor);
};
visitor(sourceFile);
return {
parameters: inferredParameterTypes,
returnType: inferredReturnType,
};
};