Skip to content

Commit

Permalink
[TOOL-2801] Insight Playground: Use OpenAPIV3 types (#5804)
Browse files Browse the repository at this point in the history
## Problem solved

Short description of the bug fixed or feature added

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the handling of OpenAPI specifications within the codebase, improving type definitions, and refining the UI components to accommodate optional fields and better manage parameters.

### Detailed summary
- Added `openapi-types` dependency in `package.json`.
- Updated `blueprintSpec` to use optional chaining for safer access.
- Modified `BlueprintCard` to handle optional `description` and `title`.
- Changed `BlueprintParameter` type to use `OpenAPIV3.ParameterObject`.
- Enhanced `BlueprintPlaygroundUI` to filter and manage parameters more effectively.
- Updated parameter handling in forms to leverage new schema definitions.
- Refined UI components to conditionally render descriptions and titles.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
  • Loading branch information
MananTank committed Dec 19, 2024
1 parent b2a52d9 commit d7d9415
Show file tree
Hide file tree
Showing 7 changed files with 613 additions and 301 deletions.
1 change: 1 addition & 0 deletions apps/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"next-seo": "^6.5.0",
"next-themes": "^0.4.4",
"nextjs-toploader": "^1.6.12",
"openapi-types": "^12.1.3",
"papaparse": "^5.4.1",
"pluralize": "^8.0.0",
"posthog-js": "1.67.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
PlayIcon,
} from "lucide-react";
import Link from "next/link";
import type { OpenAPIV3 } from "openapi-types";
import { useEffect, useMemo, useState } from "react";
import { type UseFormReturn, useForm } from "react-hook-form";
import { z } from "zod";
Expand Down Expand Up @@ -118,8 +119,10 @@ function modifyParametersForPlayground(_parameters: BlueprintParameter[]) {
name: "chainId",
in: "path",
required: true,
description: "Chain ID",
type: "integer",
schema: {
type: "integer",
description: "Chain ID of the blockchain",
},
});
}

Expand Down Expand Up @@ -156,7 +159,10 @@ export function BlueprintPlaygroundUI(props: {
}) {
const trackEvent = useTrack();
const parameters = useMemo(() => {
return modifyParametersForPlayground(props.metadata.parameters);
const filteredParams = props.metadata.parameters?.filter(
isOpenAPIV3ParameterObject,
);
return modifyParametersForPlayground(filteredParams || []);
}, [props.metadata.parameters]);

const formSchema = useMemo(() => {
Expand All @@ -166,7 +172,11 @@ export function BlueprintPlaygroundUI(props: {
const defaultValues = useMemo(() => {
const values: Record<string, string | number> = {};
for (const param of parameters) {
values[param.name] = param.default || "";
if (param.schema && "type" in param.schema && param.schema.default) {
values[param.name] = param.schema.default;
} else {
values[param.name] = "";
}
}
return values;
}, [parameters]);
Expand Down Expand Up @@ -200,7 +210,7 @@ export function BlueprintPlaygroundUI(props: {
<form onSubmit={form.handleSubmit(onSubmit)}>
<div className="flex grow flex-col">
<BlueprintMetaHeader
title={props.metadata.summary}
title={props.metadata.summary || "Blueprint Playground"}
description={props.metadata.description}
backLink={props.backLink}
/>
Expand Down Expand Up @@ -263,7 +273,7 @@ export function BlueprintPlaygroundUI(props: {

function BlueprintMetaHeader(props: {
title: string;
description: string;
description: string | undefined;
backLink: string;
}) {
return (
Expand All @@ -285,9 +295,11 @@ function BlueprintMetaHeader(props: {
<h1 className="font-semibold text-2xl tracking-tight lg:text-3xl">
{props.title}
</h1>
<p className="mt-1 text-muted-foreground text-sm">
{props.description}
</p>
{props.description && (
<p className="mt-1 text-muted-foreground text-sm">
{props.description}
</p>
)}
</div>
</div>
</div>
Expand Down Expand Up @@ -457,6 +469,11 @@ function ParameterSection(props: {
<h3 className="mb-3 font-medium text-sm"> {props.title} </h3>
<div className="overflow-hidden rounded-lg border">
{props.parameters.map((param, i) => {
const description =
param.schema && "type" in param.schema
? param.schema.description
: undefined;

const hasError = !!props.form.formState.errors[param.name];
return (
<FormField
Expand Down Expand Up @@ -517,7 +534,7 @@ function ParameterSection(props: {
{...field}
className={cn(
"h-auto truncate rounded-none border-0 bg-transparent py-3 font-mono text-sm focus-visible:ring-0 focus-visible:ring-offset-0",
param.description && "lg:pr-10",
description && "lg:pr-10",
hasError && "text-destructive-text",
)}
placeholder={
Expand All @@ -528,8 +545,8 @@ function ParameterSection(props: {
: "Value"
}
/>
{param.description && (
<ToolTipLabel label={param.description}>
{description && (
<ToolTipLabel label={description}>
<Button
asChild
variant="ghost"
Expand Down Expand Up @@ -651,32 +668,63 @@ function ResponseSection(props: {
);
}

function createParametersFormSchema(parameters: BlueprintParameter[]) {
const shape: z.ZodRawShape = {};
for (const param of parameters) {
// integer
if (param.type === "integer") {
function openAPIV3ParamToZodFormSchema(param: BlueprintParameter) {
if (!param.schema) {
return;
}

if (!("type" in param.schema)) {
return;
}

switch (param.schema.type) {
case "integer": {
const intSchema = z.coerce
.number({
message: "Must be an integer",
})
.int({
message: "Must be an integer",
});
shape[param.name] = param.required
return param.required
? intSchema.min(1, {
message: "Required",
})
: intSchema.optional();
}

// default: string
else {
shape[param.name] = param.required
? z.string().min(1, {
case "number": {
const numberSchema = z.coerce.number();
return param.required
? numberSchema.min(1, {
message: "Required",
})
: z.string().optional();
: numberSchema.optional();
}

case "boolean": {
const booleanSchema = z.coerce.boolean();
return param.required ? booleanSchema : booleanSchema.optional();
}

// everything else - just accept it as a string;
default: {
const stringSchema = z.string();
return param.required
? stringSchema.min(1, {
message: "Required",
})
: stringSchema.optional();
}
}
}

function createParametersFormSchema(parameters: BlueprintParameter[]) {
const shape: z.ZodRawShape = {};
for (const param of parameters) {
const paramSchema = openAPIV3ParamToZodFormSchema(param);
if (paramSchema) {
shape[param.name] = paramSchema;
}
}

Expand Down Expand Up @@ -747,3 +795,9 @@ function ElapsedTimeCounter() {
</span>
);
}

function isOpenAPIV3ParameterObject(
x: OpenAPIV3.ParameterObject | OpenAPIV3.ReferenceObject,
): x is OpenAPIV3.ParameterObject {
return !("$ref" in x);
}
Loading

0 comments on commit d7d9415

Please sign in to comment.