refactor(json): Consolidate JSON utilities and type definitions
Modified files: - client/src/components/DynamicJsonForm.tsx - client/src/components/JsonView.tsx - client/src/components/ToolsTab.tsx - client/src/components/__tests__/DynamicJsonForm.test.tsx - client/src/utils/__tests__/jsonPathUtils.test.ts → client/src/utils/__tests__/jsonUtils.test.ts - client/src/utils/__tests__/schemaUtils.test.ts - client/src/utils/jsonPathUtils.ts → client/src/utils/jsonUtils.ts - client/src/utils/schemaUtils.ts Descriptions: - Move JSON type definitions from DynamicJsonForm to centralized jsonUtils - Consolidate utility functions (getDataType, tryParseJson) into jsonUtils - Rename jsonPathUtils to jsonUtils for better semantic clarity - Add comprehensive test coverage for new utility functions - Update imports across all affected components - Improve type references consistency throughout the codebase
This commit is contained in:
@@ -3,33 +3,9 @@ import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import JsonEditor from "./JsonEditor";
|
||||
import { updateValueAtPath, JsonObject } from "@/utils/jsonPathUtils";
|
||||
import { updateValueAtPath } from "@/utils/jsonUtils";
|
||||
import { generateDefaultValue, formatFieldLabel } from "@/utils/schemaUtils";
|
||||
|
||||
export type JsonValue =
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null
|
||||
| undefined
|
||||
| JsonValue[]
|
||||
| { [key: string]: JsonValue };
|
||||
|
||||
export type JsonSchemaType = {
|
||||
type:
|
||||
| "string"
|
||||
| "number"
|
||||
| "integer"
|
||||
| "boolean"
|
||||
| "array"
|
||||
| "object"
|
||||
| "null";
|
||||
description?: string;
|
||||
required?: boolean;
|
||||
default?: JsonValue;
|
||||
properties?: Record<string, JsonSchemaType>;
|
||||
items?: JsonSchemaType;
|
||||
};
|
||||
import type { JsonValue, JsonSchemaType, JsonObject } from "@/utils/jsonUtils";
|
||||
|
||||
interface DynamicJsonFormProps {
|
||||
schema: JsonSchemaType;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { useState, memo, useMemo, useCallback, useEffect } from "react";
|
||||
import { JsonValue } from "./DynamicJsonForm";
|
||||
import type { JsonValue } from "@/utils/jsonUtils";
|
||||
import clsx from "clsx";
|
||||
import { Copy, CheckCheck } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { getDataType, tryParseJson } from "@/utils/jsonUtils";
|
||||
|
||||
interface JsonViewProps {
|
||||
data: unknown;
|
||||
@@ -13,21 +14,6 @@ interface JsonViewProps {
|
||||
withCopyButton?: boolean;
|
||||
}
|
||||
|
||||
function tryParseJson(str: string): { success: boolean; data: JsonValue } {
|
||||
const trimmed = str.trim();
|
||||
if (
|
||||
!(trimmed.startsWith("{") && trimmed.endsWith("}")) &&
|
||||
!(trimmed.startsWith("[") && trimmed.endsWith("]"))
|
||||
) {
|
||||
return { success: false, data: str };
|
||||
}
|
||||
try {
|
||||
return { success: true, data: JSON.parse(str) };
|
||||
} catch {
|
||||
return { success: false, data: str };
|
||||
}
|
||||
}
|
||||
|
||||
const JsonView = memo(
|
||||
({
|
||||
data,
|
||||
@@ -119,23 +105,15 @@ interface JsonNodeProps {
|
||||
const JsonNode = memo(
|
||||
({ data, name, depth = 0, initialExpandDepth }: JsonNodeProps) => {
|
||||
const [isExpanded, setIsExpanded] = useState(depth < initialExpandDepth);
|
||||
|
||||
const getDataType = (value: JsonValue): string => {
|
||||
if (Array.isArray(value)) return "array";
|
||||
if (value === null) return "null";
|
||||
return typeof value;
|
||||
};
|
||||
|
||||
const dataType = getDataType(data);
|
||||
|
||||
const typeStyleMap: Record<string, string> = {
|
||||
const [typeStyleMap] = useState<Record<string, string>>({
|
||||
number: "text-blue-600",
|
||||
boolean: "text-amber-600",
|
||||
null: "text-purple-600",
|
||||
undefined: "text-gray-600",
|
||||
string: "text-green-600 break-all whitespace-pre-wrap",
|
||||
default: "text-gray-700",
|
||||
};
|
||||
});
|
||||
const dataType = getDataType(data);
|
||||
|
||||
const renderCollapsible = (isArray: boolean) => {
|
||||
const items = isArray
|
||||
|
||||
@@ -5,7 +5,8 @@ import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { TabsContent } from "@/components/ui/tabs";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import DynamicJsonForm, { JsonSchemaType, JsonValue } from "./DynamicJsonForm";
|
||||
import DynamicJsonForm from "./DynamicJsonForm";
|
||||
import type { JsonValue, JsonSchemaType } from "@/utils/jsonUtils";
|
||||
import { generateDefaultValue } from "@/utils/schemaUtils";
|
||||
import {
|
||||
CallToolResultSchema,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { render, screen, fireEvent } from "@testing-library/react";
|
||||
import { describe, it, expect, jest } from "@jest/globals";
|
||||
import DynamicJsonForm from "../DynamicJsonForm";
|
||||
import type { JsonSchemaType } from "../DynamicJsonForm";
|
||||
import type { JsonSchemaType } from "@/utils/jsonUtils";
|
||||
|
||||
describe("DynamicJsonForm String Fields", () => {
|
||||
const renderForm = (props = {}) => {
|
||||
|
||||
Reference in New Issue
Block a user