From 4028eb95190854b21d57d2fcb98e95219f272490 Mon Sep 17 00:00:00 2001 From: jZonG Date: Sat, 26 Apr 2025 16:17:46 +0800 Subject: [PATCH] json editor update --- .../workflow/variable-inspect/utils.tsx | 31 ++++++++- .../variable-inspect/value-content.tsx | 63 ++++++++++--------- 2 files changed, 63 insertions(+), 31 deletions(-) diff --git a/web/app/components/workflow/variable-inspect/utils.tsx b/web/app/components/workflow/variable-inspect/utils.tsx index 521a6c03ec..482ed46c68 100644 --- a/web/app/components/workflow/variable-inspect/utils.tsx +++ b/web/app/components/workflow/variable-inspect/utils.tsx @@ -1,8 +1,33 @@ import { z } from 'zod' const arrayStringSchemaParttern = z.array(z.string()) +const arrayNumberSchemaParttern = z.array(z.number()) -export const validateArrayString = (schema: any) => { - const result = arrayStringSchemaParttern.safeParse(schema) - return result +// # jsonSchema from https://zod.dev/?id=json-type +const literalSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]) +type Literal = z.infer +type Json = Literal | { [key: string]: Json } | Json[] +const jsonSchema: z.ZodType = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)])) +const arrayJsonSchema: z.ZodType = z.lazy(() => z.array(jsonSchema)) + +export const validateJSONSchema = (schema: any, type: string) => { + if (type === 'array[string]') { + const result = arrayStringSchemaParttern.safeParse(schema) + return result + } + else if (type === 'array[number]') { + const result = arrayNumberSchemaParttern.safeParse(schema) + return result + } + else if (type === 'object') { + const result = jsonSchema.safeParse(schema) + return result + } + else if (type === 'array[object]') { + const result = arrayJsonSchema.safeParse(schema) + return result + } + else { + return { success: true } as any + } } diff --git a/web/app/components/workflow/variable-inspect/value-content.tsx b/web/app/components/workflow/variable-inspect/value-content.tsx index cce0e9b6b9..5b158d4e50 100644 --- a/web/app/components/workflow/variable-inspect/value-content.tsx +++ b/web/app/components/workflow/variable-inspect/value-content.tsx @@ -1,12 +1,18 @@ import { useEffect, useRef, useState } from 'react' // import { useTranslation } from 'react-i18next' +import { debounce } from 'lodash-es' import Textarea from '@/app/components/base/textarea' import SchemaEditor from '@/app/components/workflow/nodes/llm/components/json-schema-config-modal/schema-editor' import ErrorMessage from '@/app/components/workflow/nodes/llm/components/json-schema-config-modal/error-message' import { - validateArrayString, + checkJsonSchemaDepth, + getValidationErrorMessage, + validateSchemaAgainstDraft7, +} from '@/app/components/workflow/nodes/llm/utils' +import { + validateJSONSchema, } from '@/app/components/workflow/variable-inspect/utils' -import { debounce } from 'lodash-es' +import { JSON_SCHEMA_MAX_DEPTH } from '@/config' import cn from '@/utils/classnames' export const currentVar = { @@ -17,19 +23,19 @@ export const currentVar = { name: 'out_put', // var_type: 'string', // var_type: 'number', - // var_type: 'object', - var_type: 'array[string]', + var_type: 'object', + // var_type: 'array[string]', // var_type: 'array[number]', // var_type: 'array[object]', // var_type: 'file', // var_type: 'array[file]', // value: 'tuituitui', - value: ['aaa', 'bbb', 'ccc'], - // value: { - // abc: '123', - // def: 456, - // fff: true, - // }, + // value: ['aaa', 'bbb', 'ccc'], + value: { + abc: '123', + def: 456, + fff: true, + }, edited: true, } @@ -58,15 +64,27 @@ const ValueContent = () => { } } - const arrayStringValidate = (value: string) => { + const jsonValueValidate = (value: string, type: string) => { try { const newJSONSchema = JSON.parse(value) setParseError(null) - const result = validateArrayString(newJSONSchema) + const result = validateJSONSchema(newJSONSchema, type) if (!result.success) { setValidationError(result.error.message) return false } + if (type === 'object' || type === 'array[object]') { + const schemaDepth = checkJsonSchemaDepth(newJSONSchema) + if (schemaDepth > JSON_SCHEMA_MAX_DEPTH) { + setValidationError(`Schema exceeds maximum depth of ${JSON_SCHEMA_MAX_DEPTH}.`) + return false + } + const validationErrors = validateSchemaAgainstDraft7(newJSONSchema) + if (validationErrors.length > 0) { + setValidationError(getValidationErrorMessage(validationErrors)) + return false + } + } setValidationError('') return true } @@ -84,22 +102,11 @@ const ValueContent = () => { } const handleEditorChange = (value: string) => { - if (current.var_type === 'array[string]') { - setJson(value) - if (arrayStringValidate(value)) { - const parsed = JSON.parse(value) - setJsonSchema(parsed) - } - return - } - if (current.var_type === 'array[number]') { - // TODO update array[number] - } - if (current.var_type === 'object') { - // TODO update object - } - if (current.var_type === 'array[object]') { - // TODO update array[object] + setJson(value) + if (jsonValueValidate(value, current.var_type)) { + const parsed = JSON.parse(value) + setJsonSchema(parsed) + // TODO call api of value update } }