@@ -25,6 +25,7 @@ import {
2525 PlayIcon ,
2626} from "lucide-react" ;
2727import Link from "next/link" ;
28+ import type { OpenAPIV3 } from "openapi-types" ;
2829import { useEffect , useMemo , useState } from "react" ;
2930import { type UseFormReturn , useForm } from "react-hook-form" ;
3031import { z } from "zod" ;
@@ -118,8 +119,10 @@ function modifyParametersForPlayground(_parameters: BlueprintParameter[]) {
118119 name : "chainId" ,
119120 in : "path" ,
120121 required : true ,
121- description : "Chain ID" ,
122- type : "integer" ,
122+ schema : {
123+ type : "integer" ,
124+ description : "Chain ID of the blockchain" ,
125+ } ,
123126 } ) ;
124127 }
125128
@@ -156,7 +159,10 @@ export function BlueprintPlaygroundUI(props: {
156159} ) {
157160 const trackEvent = useTrack ( ) ;
158161 const parameters = useMemo ( ( ) => {
159- return modifyParametersForPlayground ( props . metadata . parameters ) ;
162+ const filteredParams = props . metadata . parameters ?. filter (
163+ isOpenAPIV3ParameterObject ,
164+ ) ;
165+ return modifyParametersForPlayground ( filteredParams || [ ] ) ;
160166 } , [ props . metadata . parameters ] ) ;
161167
162168 const formSchema = useMemo ( ( ) => {
@@ -166,7 +172,11 @@ export function BlueprintPlaygroundUI(props: {
166172 const defaultValues = useMemo ( ( ) => {
167173 const values : Record < string , string | number > = { } ;
168174 for ( const param of parameters ) {
169- values [ param . name ] = param . default || "" ;
175+ if ( param . schema && "type" in param . schema && param . schema . default ) {
176+ values [ param . name ] = param . schema . default ;
177+ } else {
178+ values [ param . name ] = "" ;
179+ }
170180 }
171181 return values ;
172182 } , [ parameters ] ) ;
@@ -200,7 +210,7 @@ export function BlueprintPlaygroundUI(props: {
200210 < form onSubmit = { form . handleSubmit ( onSubmit ) } >
201211 < div className = "flex grow flex-col" >
202212 < BlueprintMetaHeader
203- title = { props . metadata . summary }
213+ title = { props . metadata . summary || "Blueprint Playground" }
204214 description = { props . metadata . description }
205215 backLink = { props . backLink }
206216 />
@@ -263,7 +273,7 @@ export function BlueprintPlaygroundUI(props: {
263273
264274function BlueprintMetaHeader ( props : {
265275 title : string ;
266- description : string ;
276+ description : string | undefined ;
267277 backLink : string ;
268278} ) {
269279 return (
@@ -285,9 +295,11 @@ function BlueprintMetaHeader(props: {
285295 < h1 className = "font-semibold text-2xl tracking-tight lg:text-3xl" >
286296 { props . title }
287297 </ h1 >
288- < p className = "mt-1 text-muted-foreground text-sm" >
289- { props . description }
290- </ p >
298+ { props . description && (
299+ < p className = "mt-1 text-muted-foreground text-sm" >
300+ { props . description }
301+ </ p >
302+ ) }
291303 </ div >
292304 </ div >
293305 </ div >
@@ -457,6 +469,11 @@ function ParameterSection(props: {
457469 < h3 className = "mb-3 font-medium text-sm" > { props . title } </ h3 >
458470 < div className = "overflow-hidden rounded-lg border" >
459471 { props . parameters . map ( ( param , i ) => {
472+ const description =
473+ param . schema && "type" in param . schema
474+ ? param . schema . description
475+ : undefined ;
476+
460477 const hasError = ! ! props . form . formState . errors [ param . name ] ;
461478 return (
462479 < FormField
@@ -517,7 +534,7 @@ function ParameterSection(props: {
517534 { ...field }
518535 className = { cn (
519536 "h-auto truncate rounded-none border-0 bg-transparent py-3 font-mono text-sm focus-visible:ring-0 focus-visible:ring-offset-0" ,
520- param . description && "lg:pr-10" ,
537+ description && "lg:pr-10" ,
521538 hasError && "text-destructive-text" ,
522539 ) }
523540 placeholder = {
@@ -528,8 +545,8 @@ function ParameterSection(props: {
528545 : "Value"
529546 }
530547 />
531- { param . description && (
532- < ToolTipLabel label = { param . description } >
548+ { description && (
549+ < ToolTipLabel label = { description } >
533550 < Button
534551 asChild
535552 variant = "ghost"
@@ -651,32 +668,63 @@ function ResponseSection(props: {
651668 ) ;
652669}
653670
654- function createParametersFormSchema ( parameters : BlueprintParameter [ ] ) {
655- const shape : z . ZodRawShape = { } ;
656- for ( const param of parameters ) {
657- // integer
658- if ( param . type === "integer" ) {
671+ function openAPIV3ParamToZodFormSchema ( param : BlueprintParameter ) {
672+ if ( ! param . schema ) {
673+ return ;
674+ }
675+
676+ if ( ! ( "type" in param . schema ) ) {
677+ return ;
678+ }
679+
680+ switch ( param . schema . type ) {
681+ case "integer" : {
659682 const intSchema = z . coerce
660683 . number ( {
661684 message : "Must be an integer" ,
662685 } )
663686 . int ( {
664687 message : "Must be an integer" ,
665688 } ) ;
666- shape [ param . name ] = param . required
689+ return param . required
667690 ? intSchema . min ( 1 , {
668691 message : "Required" ,
669692 } )
670693 : intSchema . optional ( ) ;
671694 }
672695
673- // default: string
674- else {
675- shape [ param . name ] = param . required
676- ? z . string ( ) . min ( 1 , {
696+ case "number" : {
697+ const numberSchema = z . coerce . number ( ) ;
698+ return param . required
699+ ? numberSchema . min ( 1 , {
677700 message : "Required" ,
678701 } )
679- : z . string ( ) . optional ( ) ;
702+ : numberSchema . optional ( ) ;
703+ }
704+
705+ case "boolean" : {
706+ const booleanSchema = z . coerce . boolean ( ) ;
707+ return param . required ? booleanSchema : booleanSchema . optional ( ) ;
708+ }
709+
710+ // everything else - just accept it as a string;
711+ default : {
712+ const stringSchema = z . string ( ) ;
713+ return param . required
714+ ? stringSchema . min ( 1 , {
715+ message : "Required" ,
716+ } )
717+ : stringSchema . optional ( ) ;
718+ }
719+ }
720+ }
721+
722+ function createParametersFormSchema ( parameters : BlueprintParameter [ ] ) {
723+ const shape : z . ZodRawShape = { } ;
724+ for ( const param of parameters ) {
725+ const paramSchema = openAPIV3ParamToZodFormSchema ( param ) ;
726+ if ( paramSchema ) {
727+ shape [ param . name ] = paramSchema ;
680728 }
681729 }
682730
@@ -747,3 +795,9 @@ function ElapsedTimeCounter() {
747795 </ span >
748796 ) ;
749797}
798+
799+ function isOpenAPIV3ParameterObject (
800+ x : OpenAPIV3 . ParameterObject | OpenAPIV3 . ReferenceObject ,
801+ ) : x is OpenAPIV3 . ParameterObject {
802+ return ! ( "$ref" in x ) ;
803+ }
0 commit comments