Skip to content

Commit 8176615

Browse files
authored
Merge pull request #131 from code0-tech/feat/#130
Suggestions aren't working in send webhook response payload
2 parents 527b02d + ab0fabb commit 8176615

2 files changed

Lines changed: 80 additions & 0 deletions

File tree

src/schema/getSignatureSchema.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,17 @@ const widenForSuggestions = (checker: ts.TypeChecker, type: ts.Type, node: ts.Va
393393
return checker.getAnyType()
394394
}
395395

396+
// A conditional type that still depends on a free type parameter cannot be
397+
// resolved to a single branch for suggestion scoping (e.g.
398+
// HTTP_PAYLOAD<S> = S extends 'application/json' ? OBJECT<{}> : … stays
399+
// unresolved while S is free, and isTypeAssignableTo against it is always
400+
// false). Its base constraint is the union of every branch
401+
// (string | OBJECT<{}> | undefined) — exactly the set of values the function
402+
// could accept here — so widen to that.
403+
if ((type.flags & ts.TypeFlags.Conditional) !== 0) {
404+
return checker.getBaseConstraintOfType(type) ?? checker.getAnyType()
405+
}
406+
396407
if ((type.flags & ts.TypeFlags.Object) !== 0 && hasFreeTypeParam(type, checker, new Set())) {
397408
const aliasName: string | undefined = (type as any).aliasSymbol?.getName()
398409
if (aliasName) {

test/schema/schema.test.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,4 +619,73 @@ describe("Schema", () => {
619619
expect(first.schema.input).toBe("text");
620620
});
621621

622+
it('offers a saved object as a ReferenceValue suggestion in rest::control::respond payload', () => {
623+
// Node 1: std::control::value<T>(value: T): T saves an object literal, so its
624+
// return type is an OBJECT.
625+
// Node 2: rest::control::respond
626+
// <S extends HTTP_SCHEMA>(http_status_code, headers: OBJECT<{}>, http_schema: S,
627+
// payload: HTTP_PAYLOAD<S>): void
628+
// With http_schema = "application/json", HTTP_PAYLOAD<S> resolves to OBJECT<{}>.
629+
//
630+
// Node 1 returns an object, which is assignable to OBJECT<{}>, so node 1 must be
631+
// offered as a ReferenceValue suggestion for the payload parameter.
632+
const flow: Flow = {
633+
id: "gid://sagittarius/Flow/1",
634+
startingNodeId: "gid://sagittarius/NodeFunction/1",
635+
signature: "(): void",
636+
nodes: {
637+
nodes: [
638+
{
639+
id: "gid://sagittarius/NodeFunction/1",
640+
functionDefinition: {identifier: "std::control::value"},
641+
nextNodeId: "gid://sagittarius/NodeFunction/2",
642+
parameters: {
643+
nodes: [
644+
{value: {__typename: "LiteralValue", value: {}}},
645+
],
646+
},
647+
},
648+
{
649+
id: "gid://sagittarius/NodeFunction/2",
650+
functionDefinition: {identifier: "rest::control::respond"},
651+
parameters: {
652+
nodes: [
653+
{value: {__typename: "LiteralValue", value: 200}},
654+
{value: {__typename: "LiteralValue", value: {}}},
655+
{value: {__typename: "LiteralValue", value: "application/json"}},
656+
{value: {__typename: "LiteralValue", value: {}}},
657+
],
658+
},
659+
},
660+
],
661+
},
662+
};
663+
664+
const result = getSignatureSchema(
665+
flow,
666+
DATA_TYPES,
667+
FUNCTION_SIGNATURES,
668+
"gid://sagittarius/NodeFunction/2",
669+
);
670+
671+
// payload is the 4th parameter of rest::control::respond.
672+
const payloadSchema = result[3];
673+
674+
// application/json → HTTP_PAYLOAD<S> = OBJECT<{}> → open object input.
675+
expect(payloadSchema.schema.input).toBe("data");
676+
677+
// Node 1 (std::control::value) returns an object assignable to OBJECT<{}>.
678+
// Its return value is a direct reference (no property path).
679+
const suggestions = (payloadSchema.schema.suggestions ?? []) as any[];
680+
expect(suggestions.length).toBeGreaterThan(0);
681+
expect(
682+
suggestions.some(
683+
(s) =>
684+
s.__typename === "ReferenceValue" &&
685+
s.nodeFunctionId === "gid://sagittarius/NodeFunction/1" &&
686+
!s.referencePath,
687+
),
688+
).toBe(true);
689+
});
690+
622691
})

0 commit comments

Comments
 (0)