Skip to content

Commit bd07ae2

Browse files
author
nicosammito
committed
feat: enhance reference suggestion tests and improve type handling in flow processing
1 parent 1ea6083 commit bd07ae2

4 files changed

Lines changed: 140 additions & 6 deletions

File tree

src/extraction/getTypesFromNode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const getTypesFromNode = (
3232
nodes: node.parameters?.nodes?.map(p => {
3333
if (p?.value) return p;
3434
// If value is missing, we still want the compiler to see the argument position
35-
return { ...p, value: { __typename: "LiteralValue", value: null } };
35+
return { ...p, value: null };
3636
}) || []
3737
}
3838
};

src/suggestion/getReferenceSuggestions.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ export const getReferenceSuggestions = (
2727
const typeDefs = getSharedTypeDeclarations(dataTypes);
2828
const inferred = getInferredTypesFromFlow(flow, functions, dataTypes);
2929

30+
console.log(inferred)
31+
3032
// Helper to check if a type is assignable to the required type
3133
const isAssignable = (inferredType: string, path?: string): boolean => {
3234
const fileName = `index.ts`;
@@ -115,7 +117,7 @@ export const getReferenceSuggestions = (
115117
// Suggestions from node return values
116118
if (node.id !== nodeId) {
117119
const nodeType = inferred.nodes.get(sId);
118-
if (nodeType && isNodeBefore(flow, node.id, nodeId)) {
120+
if (nodeType !== "void" && nodeType && isNodeBefore(flow, node.id, nodeId)) {
119121
suggestions.push(...getValidPaths(nodeType, {
120122
__typename: "ReferenceValue",
121123
nodeFunctionId: node.id,
@@ -129,6 +131,7 @@ export const getReferenceSuggestions = (
129131
if (pTypes) {
130132
pTypes.forEach((pType, idx) => {
131133
if (isParentScope(flow, node.id!, nodeId!)) {
134+
132135
// Extract T from CONSUMER<T> or similar if needed
133136
let actualPType = pType;
134137
if (pType.startsWith("CONSUMER<") && pType.endsWith(">")) {

src/utils.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ export function generateFlowSourceCode(
146146
const params = (node.parameters?.nodes as NodeParameter[]) || [];
147147
const args = params.map((p, paramIdx) => {
148148
const val = p.value;
149-
if (!val) return `/* @pos ${nodeId} ${paramIdx} */ undefined`;
149+
if (!val) return isForInference ? `/* @pos ${nodeId} ${paramIdx} */ ({} as any)` : `/* @pos ${nodeId} ${paramIdx} */ undefined`;
150150
if (val.__typename === "ReferenceValue") {
151151
const ref = val as ReferenceValue;
152152
if (!ref.nodeFunctionId) return `/* @pos ${nodeId} ${paramIdx} */ undefined`;
@@ -161,7 +161,7 @@ export function generateFlowSourceCode(
161161
const wrapper = val as NodeFunctionIdWrapper;
162162
return generateNodeCall(wrapper.id!, nodeId, paramIdx);
163163
}
164-
return `/* @pos ${nodeId} ${paramIdx} */ undefined`;
164+
return isForInference ? `/* @pos ${nodeId} ${paramIdx} */ ({} as any)` : `/* @pos ${nodeId} ${paramIdx} */ undefined`;
165165
}).join(", ");
166166

167167
const funcName = `fn_${node.functionDefinition.identifier.replace(/::/g, '_')}`;
@@ -191,7 +191,7 @@ export function generateFlowSourceCode(
191191
const params = (node.parameters?.nodes as NodeParameter[]) || [];
192192
const args = params.map((p, index) => {
193193
const val = p.value;
194-
if (!val) return `/* @pos ${nodeId} ${index} */ undefined`;
194+
if (!val) return isForInference ? `/* @pos ${nodeId} ${index} */ ({} as any)` : `/* @pos ${nodeId} ${index} */ undefined`;
195195
if (val.__typename === "ReferenceValue") {
196196
const ref = val as ReferenceValue;
197197
if (!ref.nodeFunctionId) return `/* @pos ${nodeId} ${index} */ undefined`;
@@ -225,7 +225,7 @@ export function generateFlowSourceCode(
225225
return `/* @pos ${nodeId} ${index} */ (...${lambdaArgName}) => {\n${subTreeCode}${indent}}`;
226226
}
227227
}
228-
return `/* @pos ${nodeId} ${index} */ undefined`;
228+
return isForInference ? `/* @pos ${nodeId} ${index} */ ({} as any)` : `/* @pos ${nodeId} ${index} */ undefined`;
229229
}).join(", ");
230230

231231
const varName = `node_${sanitizeId(node.id!)}`;
@@ -268,6 +268,7 @@ export function getInferredTypesFromFlow(
268268
dataTypes?: DataType[]
269269
): InferredTypes {
270270
const sourceCode = generateFlowSourceCode(flow, functions, dataTypes, true);
271+
console.log("Generated source code for inference:\n", sourceCode);
271272
const fileName = "index.ts";
272273
const host = createCompilerHost(fileName, sourceCode);
273274
const sourceFile = host.getSourceFile(fileName)!;

test/getReferenceSuggestions.test.ts

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {describe, expect, it} from 'vitest';
22
import {getReferenceSuggestions} from '../src/suggestion/getReferenceSuggestions';
33
import {Flow} from "@code0-tech/sagittarius-graphql-types";
44
import {DATA_TYPES, FUNCTION_SIGNATURES} from "./data";
5+
import {getTypesFromNode} from "../src";
56

67
const node1Id = "gid://sagittarius/NodeFunction/1" as any;
78
const node2Id = "gid://sagittarius/NodeFunction/2" as any;
@@ -201,4 +202,133 @@ describe('getReferenceSuggestions', () => {
201202

202203
expect(suggestions.some(s => s.nodeFunctionId === node1Id)).toBe(false);
203204
});
205+
206+
it('sd', () => {
207+
const flow: Flow = {
208+
"__typename": "Flow",
209+
"id": "gid://sagittarius/Flow/1",
210+
"createdAt": "2026-03-17T14:02:31Z",
211+
"name": "Test",
212+
"inputType": "REST_ADAPTER_INPUT",
213+
"returnType": "HTTP_RESPONSE",
214+
"nodes": {
215+
"__typename": "NodeFunctionConnection",
216+
"nodes": [
217+
{
218+
"__typename": "NodeFunction",
219+
"id": "gid://sagittarius/NodeFunction/3",
220+
"functionDefinition": {
221+
"__typename": "FunctionDefinition",
222+
"id": "gid://sagittarius/FunctionDefinition/7",
223+
"identifier": "std::list::for_each"
224+
},
225+
"parameters": {
226+
"__typename": "NodeParameterConnection",
227+
"nodes": [
228+
{
229+
"__typename": "NodeParameter",
230+
"parameterDefinition": {
231+
"__typename": "ParameterDefinition",
232+
"id": "gid://sagittarius/ParameterDefinition/10",
233+
"identifier": "list"
234+
},
235+
"value": {
236+
"__typename": "LiteralValue",
237+
"value": [
238+
1,
239+
2,
240+
3,
241+
4,
242+
5
243+
]
244+
}
245+
},
246+
{
247+
"__typename": "NodeParameter",
248+
"parameterDefinition": {
249+
"__typename": "ParameterDefinition",
250+
"id": "gid://sagittarius/ParameterDefinition/11",
251+
"identifier": "consumer"
252+
},
253+
"value": {
254+
"id": "gid://sagittarius/NodeFunction/4",
255+
"__typename": "NodeFunctionIdWrapper"
256+
}
257+
}
258+
]
259+
}
260+
},
261+
{
262+
"__typename": "NodeFunction",
263+
"id": "gid://sagittarius/NodeFunction/4",
264+
"functionDefinition": {
265+
"__typename": "FunctionDefinition",
266+
"id": "gid://sagittarius/FunctionDefinition/112",
267+
"identifier": "std::control::value"
268+
},
269+
"parameters": {
270+
"__typename": "NodeParameterConnection",
271+
"nodes": [
272+
{
273+
"__typename": "NodeParameter",
274+
"parameterDefinition": {
275+
"__typename": "ParameterDefinition",
276+
"id": "gid://sagittarius/ParameterDefinition/174",
277+
"identifier": "value"
278+
},
279+
"value": null
280+
}
281+
]
282+
}
283+
}
284+
]
285+
},
286+
"project": {
287+
"__typename": "NamespaceProject",
288+
"id": "gid://sagittarius/NamespaceProject/1"
289+
},
290+
"settings": {
291+
"__typename": "FlowSettingConnection",
292+
"count": 2,
293+
"nodes": [
294+
{
295+
"__typename": "FlowSetting",
296+
"id": "gid://sagittarius/FlowSetting/1",
297+
"createdAt": "2026-03-17T14:17:48Z",
298+
"updatedAt": "2026-03-17T14:17:48Z",
299+
"flowSettingIdentifier": "HTTP_METHOD",
300+
"value": ""
301+
},
302+
{
303+
"__typename": "FlowSetting",
304+
"id": "gid://sagittarius/FlowSetting/2",
305+
"createdAt": "2026-03-17T14:17:48Z",
306+
"updatedAt": "2026-03-17T14:17:48Z",
307+
"flowSettingIdentifier": "HTTP_URL",
308+
"value": ""
309+
}
310+
],
311+
"pageInfo": {
312+
"__typename": "PageInfo",
313+
"endCursor": "Mg",
314+
"hasNextPage": false
315+
}
316+
},
317+
"startingNodeId": "gid://sagittarius/NodeFunction/3",
318+
"type": {
319+
"__typename": "FlowType",
320+
"id": "gid://sagittarius/FlowType/1"
321+
},
322+
"userAbilities": {
323+
"__typename": "FlowUserAbilities",
324+
"deleteFlow": true
325+
}
326+
};
327+
328+
const suggestions = getReferenceSuggestions(flow, "gid://sagittarius/NodeFunction/4", "any", FUNCTION_SIGNATURES, DATA_TYPES);
329+
330+
console.log(JSON.stringify(suggestions))
331+
332+
expect(suggestions.some(s => !s.nodeFunctionId)).toBe(true);
333+
});
204334
});

0 commit comments

Comments
 (0)