From ff591b9aede9db73255be01d29a134df9f4c4f5b Mon Sep 17 00:00:00 2001 From: Manan Tank Date: Fri, 10 Jan 2025 17:20:41 +0530 Subject: [PATCH] [TOOL-3021] Insight Playground: Enforce chain query param to be required + support anyOf schema --- .../blueprint-playground.client.tsx | 59 +++++++++++-------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/[blueprint_slug]/blueprint-playground.client.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/[blueprint_slug]/blueprint-playground.client.tsx index d4cce813e2a..e48f4658729 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/[blueprint_slug]/blueprint-playground.client.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/[blueprint_slug]/blueprint-playground.client.tsx @@ -122,18 +122,11 @@ export function BlueprintPlayground(props: { function modifyParametersForPlayground(_parameters: BlueprintParameter[]) { const parameters = [..._parameters]; - // if chain parameter is not already mentioned - add it, its required + + // make chain query param required - its not required in open api spec - because it either has to be set in subdomain or as a query param const chainIdParameter = parameters.find((p) => p.name === "chain"); - if (!chainIdParameter) { - parameters.unshift({ - name: "chain", - in: "query", - required: true, - schema: { - type: "integer", - description: "Chain ID of the blockchain", - }, - }); + if (chainIdParameter) { + chainIdParameter.required = true; } // remove the client id parameter if it is present - we will always replace the parameter with project's client id @@ -814,31 +807,46 @@ function ResponseSection(props: { ); } -function openAPIV3ParamToZodFormSchema(param: BlueprintParameter) { - if (!param.schema) { +function openAPIV3ParamToZodFormSchema( + schema: BlueprintParameter["schema"], + isRequired: boolean, +): z.ZodTypeAny | undefined { + if (!schema) { return; } - if (!("type" in param.schema)) { + if ("anyOf" in schema) { + const anyOf = schema.anyOf; + if (!anyOf) { + return; + } + const anySchemas = anyOf + .map((s) => openAPIV3ParamToZodFormSchema(s, isRequired)) + .filter((x) => !!x); + // @ts-expect-error - Its ok, z.union is expecting tuple type but we have array + return z.union(anySchemas); + } + + if (!("type" in schema)) { return; } // if enum values - const enumValues = param.schema.enum; + const enumValues = schema.enum; if (enumValues) { const enumSchema = z.enum( // @ts-expect-error - Its correct enumValues, ); - if (param.required) { + if (isRequired) { return enumSchema; } return enumSchema.or(z.literal("")); } - switch (param.schema.type) { + switch (schema.type) { case "integer": { const intSchema = z.coerce .number({ @@ -847,7 +855,7 @@ function openAPIV3ParamToZodFormSchema(param: BlueprintParameter) { .int({ message: "Must be an integer", }); - return param.required + return isRequired ? intSchema.min(1, { message: "Required", }) @@ -856,7 +864,7 @@ function openAPIV3ParamToZodFormSchema(param: BlueprintParameter) { case "number": { const numberSchema = z.coerce.number(); - return param.required + return isRequired ? numberSchema.min(1, { message: "Required", }) @@ -865,13 +873,13 @@ function openAPIV3ParamToZodFormSchema(param: BlueprintParameter) { case "boolean": { const booleanSchema = z.coerce.boolean(); - return param.required ? booleanSchema : booleanSchema.optional(); + return isRequired ? booleanSchema : booleanSchema.optional(); } // everything else - just accept it as a string; default: { const stringSchema = z.string(); - return param.required + return isRequired ? stringSchema.min(1, { message: "Required", }) @@ -883,11 +891,16 @@ function openAPIV3ParamToZodFormSchema(param: BlueprintParameter) { function createParametersFormSchema(parameters: BlueprintParameter[]) { const shape: z.ZodRawShape = {}; for (const param of parameters) { - const paramSchema = openAPIV3ParamToZodFormSchema(param); + const paramSchema = openAPIV3ParamToZodFormSchema( + param.schema, + !!param.required, + ); if (paramSchema) { shape[param.name] = paramSchema; } else { - shape[param.name] = z.string(); + shape[param.name] = param.required + ? z.string().min(1, { message: "Required" }) + : z.string(); } }