Ver código fonte

feat: compare schema type

tags/2.0.0-beta.1
Joel 2 meses atrás
pai
commit
2db699522c

+ 71
- 0
web/app/components/workflow/nodes/_base/components/variable/use-match-schema-type.spec.ts Ver arquivo

@@ -0,0 +1,71 @@
import { deepEqualByType } from './use-match-schema-type'

describe('deepEqualByType', () => {
it('should return true for identical primitive types', () => {
expect(deepEqualByType({ type: 'string' }, { type: 'string' })).toBe(true)
expect(deepEqualByType({ type: 'number' }, { type: 'number' })).toBe(true)
})

it('should return false for different primitive types', () => {
expect(deepEqualByType({ type: 'string' }, { type: 'number' })).toBe(false)
})

it('should ignore values and only compare types', () => {
expect(deepEqualByType({ type: 'string', value: 'hello' }, { type: 'string', value: 'world' })).toBe(true)
expect(deepEqualByType({ type: 'number', value: 42 }, { type: 'number', value: 100 })).toBe(true)
})

it('should return true for structural differences but no types', () => {
expect(deepEqualByType({ type: 'string', other: { b: 'xxx' } }, { type: 'string', other: 'xxx' })).toBe(true)
expect(deepEqualByType({ type: 'string', other: { b: 'xxx' } }, { type: 'string' })).toBe(true)
})

it('should handle nested objects with same structure and types', () => {
const obj1 = {
type: 'object',
properties: {
name: { type: 'string' },
age: { type: 'number' },
address: {
type: 'object',
properties: {
street: { type: 'string' },
city: { type: 'string' },
},
},
},
}
const obj2 = {
type: 'object',
properties: {
name: { type: 'string', value: 'Alice' },
age: { type: 'number', value: 30 },
address: {
type: 'object',
properties: {
street: { type: 'string', value: '123 Main St' },
city: { type: 'string', value: 'Wonderland' },
},
},
},
}
expect(deepEqualByType(obj1, obj2)).toBe(true)
})
it('should return false for nested objects with different structures', () => {
const obj1 = {
type: 'object',
properties: {
name: { type: 'string' },
age: { type: 'number' },
},
}
const obj2 = {
type: 'object',
properties: {
name: { type: 'string' },
address: { type: 'string' },
},
}
expect(deepEqualByType(obj1, obj2)).toBe(false)
})
})

+ 31
- 0
web/app/components/workflow/nodes/_base/components/variable/use-match-schema-type.ts Ver arquivo

@@ -0,0 +1,31 @@
type AnyObj = Record<string, any> | null

// only compare type in object
export function deepEqualByType(a: AnyObj, b: AnyObj): boolean {
const isObj = (x: any): x is object => x !== null && typeof x === 'object'

const cmp = (x: AnyObj, y: AnyObj): boolean => {
const ox = isObj(x)
const oy = isObj(y)
if (!ox && !oy) return true // both primitives → ignore values
if (ox !== oy) { // ignore the object without type
if(ox && !('type' in (x as object)))
return true
return !!(oy && !('type' in (y as object)))
}
// check current `type`
const tx = (x as any).type
const ty = (y as any).type
if (tx !== ty) return false

// recurse into all keys
const keys = new Set([...Object.keys(x as object), ...Object.keys(y as object)])
for (const k of keys) {
if (k === 'type') continue // already checked
if (!cmp((x as any)[k], (y as any)[k])) return false
}
return true
}

return cmp(a, b)
}

+ 1
- 0
web/app/components/workflow/utils/tool.ts Ver arquivo

@@ -62,6 +62,7 @@ export const getOutputVariableAlias = (variable: Record<string, any>) => {
}
export const wrapStructuredVarItem = (outputItem: any): StructuredOutput => {
const dataType = Type.object
// console.log(outputItem)
return {
schema: {
type: dataType,

Carregando…
Cancelar
Salvar