diff --git a/web/app/components/app/configuration/config-var/config-modal/__tests__/index-logic.spec.tsx b/web/app/components/app/configuration/config-var/config-modal/__tests__/index-logic.spec.tsx index 603d5991704..16f22f59f78 100644 --- a/web/app/components/app/configuration/config-var/config-modal/__tests__/index-logic.spec.tsx +++ b/web/app/components/app/configuration/config-var/config-modal/__tests__/index-logic.spec.tsx @@ -176,4 +176,26 @@ describe('ConfigModal logic', () => { expect(latestFormProps?.modelId).toBe('model-1') }) + + it('should pass object json_schema to the editor as JSON text', () => { + const jsonSchema = { + type: 'object', + properties: { + id: { type: 'string' }, + name: { type: 'string' }, + }, + required: ['id', 'name'], + } + + renderConfigModal( + createPayload({ + type: InputVarType.jsonObject, + label: 'dsmworksheet', + variable: 'dsmworksheet', + json_schema: jsonSchema as InputVar['json_schema'], + }), + ) + + expect(latestFormProps?.jsonSchemaStr).toBe(JSON.stringify(jsonSchema, null, 2)) + }) }) diff --git a/web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/index.spec.tsx b/web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/index.spec.tsx new file mode 100644 index 00000000000..41083443e2e --- /dev/null +++ b/web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/index.spec.tsx @@ -0,0 +1,26 @@ +import { render, screen } from '@testing-library/react' +import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' +import CodeEditor from '..' + +vi.mock('@/hooks/use-theme', () => ({ + default: () => ({ theme: 'light' }), +})) + +const jsonObjectSchema = { + type: 'object', + properties: { + id: { type: 'string' }, + name: { type: 'string' }, + }, + required: ['id', 'name'], +} + +describe('CodeEditor', () => { + it('serializes object JSON values so Monaco receives text instead of a buffer factory', () => { + render() + + expect(screen.getByTestId('monaco-editor')).toHaveValue( + JSON.stringify(jsonObjectSchema, null, 2), + ) + }) +}) diff --git a/web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/utils.spec.ts b/web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/utils.spec.ts new file mode 100644 index 00000000000..747dd1a40ab --- /dev/null +++ b/web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/utils.spec.ts @@ -0,0 +1,16 @@ +import { serializeCodeEditorValue } from '../utils' + +describe('serializeCodeEditorValue', () => { + it('turns object values into JSON text so Monaco does not treat them as a buffer factory', () => { + const schema = { + type: 'object', + properties: { id: { type: 'string' } }, + } + + expect(serializeCodeEditorValue(schema)).toBe(JSON.stringify(schema, null, 2)) + expect(serializeCodeEditorValue(schema, true)).toBe(JSON.stringify(schema, null, 2)) + expect(serializeCodeEditorValue('{"type":"object"}')).toBe('{"type":"object"}') + expect(serializeCodeEditorValue(undefined)).toBe('') + expect(serializeCodeEditorValue(null as never)).toBe('') + }) +}) diff --git a/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx b/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx index 2fb7fe4ae58..893cf6d1e29 100644 --- a/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx +++ b/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx @@ -11,6 +11,7 @@ import useTheme from '@/hooks/use-theme' import { Theme } from '@/types/app' import { basePath } from '@/utils/var' import Base from '../base' +import { serializeCodeEditorValue } from './utils' import './style.css' // load file from local instead of cdn https://github.com/suren-atoyan/monaco-react/issues/482 @@ -117,14 +118,7 @@ const CodeEditor: FC = ({ setIsMounted(true) } - const outPutValue = (() => { - if (!isJSONStringifyBeauty) return value as string - try { - return JSON.stringify(value as object, null, 2) - } catch { - return value as string - } - })() + const outPutValue = serializeCodeEditorValue(value, isJSONStringifyBeauty) const theme = useMemo(() => { if (appTheme === Theme.light) return 'light' diff --git a/web/app/components/workflow/nodes/_base/components/editor/code-editor/utils.ts b/web/app/components/workflow/nodes/_base/components/editor/code-editor/utils.ts new file mode 100644 index 00000000000..6d5ae777931 --- /dev/null +++ b/web/app/components/workflow/nodes/_base/components/editor/code-editor/utils.ts @@ -0,0 +1,21 @@ +export const serializeCodeEditorValue = ( + value?: string | object, + isJSONStringifyBeauty?: boolean, +): string => { + if (value == null) return '' + + if (!isJSONStringifyBeauty) { + if (typeof value === 'string') return value + try { + return JSON.stringify(value, null, 2) + } catch { + return '' + } + } + + try { + return JSON.stringify(value, null, 2) + } catch { + return typeof value === 'string' ? value : '' + } +}