@@ -19,6 +19,12 @@ import {getSubFlows} from "./subflows.util";
1919export interface Input {
2020 /** The type of input (string representation) */
2121 input ?: string ;
22+ /**
23+ * The underlying TypeScript type rendered as a string
24+ * (e.g. "NUMBER", "LIST<TEXT>", "string | undefined"), as produced by the
25+ * type checker for the type this schema node was generated from.
26+ */
27+ type ?: string ;
2228 /** Array of suggested values (functions, references, or literals) */
2329 suggestions ?: ( NodeFunction | ReferenceValue | LiteralValue | SubFlowValue ) [ ] ;
2430}
@@ -148,6 +154,10 @@ export const getSchema = (
148154 }
149155 }
150156
157+ // The raw TypeScript type as a string, carried on every schema node so the
158+ // consumer knows the concrete type each input was derived from.
159+ const type = checker . typeToString ( parameterType ) ;
160+
151161 // Suggestions are filtered by what the surrounding function accepts, not by
152162 // the narrower type a current value happens to narrow the node-side to.
153163 // Example: `<T>(value: T)` with a current boolean literal must still surface
@@ -188,33 +198,33 @@ export const getSchema = (
188198 )
189199 if ( nonNullish . length === 1 ) {
190200 const baseSchema = getSchema ( checker , node , nonNullish [ 0 ] , functionDeclarations , functions , false , undefined , visited , recursionCache )
191- return { ...baseSchema , ...combinedSuggestions }
201+ return { ...baseSchema , type , ...combinedSuggestions }
192202 }
193203 }
194204
195205 // Boolean is internally represented by TypeScript as the union `true | false`,
196206 // so it must be detected before the primitive-literal-union check below; otherwise
197207 // `boolean` (and `true | false`) would incorrectly surface as a select.
198208 if ( isBoolean ( parameterType ) ) {
199- return { input : "boolean" , ...combinedSuggestions } ;
209+ return { input : "boolean" , type , ...combinedSuggestions } ;
200210 }
201211
202212 // Check primitive literal union first (e.g., "a" | "b" | "c") or a single
203213 // string/number literal (e.g., "GET"). A bare literal has only one allowed
204214 // value, so it should still surface as a select rather than a free-form text/number input.
205215 if ( isPrimitiveLiteralUnion ( parameterType ) || isStringOrNumberLiteral ( parameterType ) ) {
206- return { input : "select" , ...combinedSuggestions } ;
216+ return { input : "select" , type , ...combinedSuggestions } ;
207217 }
208218 if ( isNumber ( parameterType ) ) {
209- return { input : "number" , ...combinedSuggestions } ;
219+ return { input : "number" , type , ...combinedSuggestions } ;
210220 }
211221 if ( isString ( parameterType ) ) {
212- return { input : "text" , ...combinedSuggestions } ;
222+ return { input : "text" , type , ...combinedSuggestions } ;
213223 }
214224
215225 // Check if type has call signatures (is callable/sub-flow)
216226 if ( isSubFlow ( parameterType ) ) {
217- return { input : "sub-flow" , ...combinedSuggestions } ;
227+ return { input : "sub-flow" , type , ...combinedSuggestions } ;
218228 }
219229
220230 // Handle array and tuple types
@@ -233,6 +243,7 @@ export const getSchema = (
233243
234244 return {
235245 input : "list" ,
246+ type,
236247 items : itemSchemas ,
237248 ...combinedSuggestions ,
238249 } ;
@@ -252,7 +263,7 @@ export const getSchema = (
252263 ( visited . size >= MAX_SCHEMA_DEPTH &&
253264 isRecursiveType ( parameterType , checker , recursionCache ) )
254265 ) {
255- return { input : "data" , ...combinedSuggestions } ;
266+ return { input : "data" , type , ...combinedSuggestions } ;
256267 }
257268 visited . add ( parameterType ) ;
258269
@@ -304,6 +315,7 @@ export const getSchema = (
304315
305316 return {
306317 input : "data" ,
318+ type,
307319 properties,
308320 required,
309321 ...combinedSuggestions ,
@@ -314,6 +326,7 @@ export const getSchema = (
314326 // suggestions (e.g. references in scope) so the UI is never silently empty.
315327 return {
316328 input : "generic" ,
329+ type,
317330 ...combinedSuggestions ,
318331 } ;
319332} ;
@@ -435,6 +448,7 @@ const liftGenericIfValued = (schema: Schema, valueProvided: boolean): Schema =>
435448 if ( ! valueProvided || schema . input !== "generic" ) return schema ;
436449 return {
437450 input : "data" ,
451+ ...( schema . type ? { type : schema . type } : { } ) ,
438452 properties : { } ,
439453 required : [ ] ,
440454 ...( schema . suggestions ? { suggestions : schema . suggestions } : { } ) ,
@@ -464,6 +478,7 @@ const demoteSelect = (schema: Schema): Schema => {
464478 : "text" ;
465479 return {
466480 input : target ,
481+ ...( schema . type ? { type : schema . type } : { } ) ,
467482 ...( suggestions . length > 0 ? { suggestions} : { } ) ,
468483 } ;
469484} ;
0 commit comments