|
|
|
@@ -1,9 +1,8 @@ |
|
|
|
import { z } from 'zod' |
|
|
|
import { ArrayType, Type } from './types' |
|
|
|
import type { ArrayItems, Field, LLMNodeType } from './types' |
|
|
|
import type { Schema, ValidationError } from 'jsonschema' |
|
|
|
import { Validator } from 'jsonschema' |
|
|
|
import produce from 'immer' |
|
|
|
import { z } from 'zod' |
|
|
|
import { draft07Validator, forbidBooleanProperties } from '@/utils/validators' |
|
|
|
import type { ValidationError } from 'jsonschema' |
|
|
|
|
|
|
|
export const checkNodeValid = (_payload: LLMNodeType) => { |
|
|
|
return true |
|
|
|
@@ -14,7 +13,7 @@ export const getFieldType = (field: Field) => { |
|
|
|
if (type !== Type.array || !items) |
|
|
|
return type |
|
|
|
|
|
|
|
return ArrayType[items.type] |
|
|
|
return ArrayType[items.type as keyof typeof ArrayType] |
|
|
|
} |
|
|
|
|
|
|
|
export const getHasChildren = (schema: Field) => { |
|
|
|
@@ -115,191 +114,22 @@ export const findPropertyWithPath = (target: any, path: string[]) => { |
|
|
|
return current |
|
|
|
} |
|
|
|
|
|
|
|
const draft07MetaSchema = { |
|
|
|
$schema: 'http://json-schema.org/draft-07/schema#', |
|
|
|
$id: 'http://json-schema.org/draft-07/schema#', |
|
|
|
title: 'Core schema meta-schema', |
|
|
|
definitions: { |
|
|
|
schemaArray: { |
|
|
|
type: 'array', |
|
|
|
minItems: 1, |
|
|
|
items: { $ref: '#' }, |
|
|
|
}, |
|
|
|
nonNegativeInteger: { |
|
|
|
type: 'integer', |
|
|
|
minimum: 0, |
|
|
|
}, |
|
|
|
nonNegativeIntegerDefault0: { |
|
|
|
allOf: [ |
|
|
|
{ $ref: '#/definitions/nonNegativeInteger' }, |
|
|
|
{ default: 0 }, |
|
|
|
], |
|
|
|
}, |
|
|
|
simpleTypes: { |
|
|
|
enum: [ |
|
|
|
'array', |
|
|
|
'boolean', |
|
|
|
'integer', |
|
|
|
'null', |
|
|
|
'number', |
|
|
|
'object', |
|
|
|
'string', |
|
|
|
], |
|
|
|
}, |
|
|
|
stringArray: { |
|
|
|
type: 'array', |
|
|
|
items: { type: 'string' }, |
|
|
|
uniqueItems: true, |
|
|
|
default: [], |
|
|
|
}, |
|
|
|
}, |
|
|
|
type: ['object', 'boolean'], |
|
|
|
properties: { |
|
|
|
$id: { |
|
|
|
type: 'string', |
|
|
|
format: 'uri-reference', |
|
|
|
}, |
|
|
|
$schema: { |
|
|
|
type: 'string', |
|
|
|
format: 'uri', |
|
|
|
}, |
|
|
|
$ref: { |
|
|
|
type: 'string', |
|
|
|
format: 'uri-reference', |
|
|
|
}, |
|
|
|
title: { |
|
|
|
type: 'string', |
|
|
|
}, |
|
|
|
description: { |
|
|
|
type: 'string', |
|
|
|
}, |
|
|
|
default: true, |
|
|
|
readOnly: { |
|
|
|
type: 'boolean', |
|
|
|
default: false, |
|
|
|
}, |
|
|
|
examples: { |
|
|
|
type: 'array', |
|
|
|
items: true, |
|
|
|
}, |
|
|
|
multipleOf: { |
|
|
|
type: 'number', |
|
|
|
exclusiveMinimum: 0, |
|
|
|
}, |
|
|
|
maximum: { |
|
|
|
type: 'number', |
|
|
|
}, |
|
|
|
exclusiveMaximum: { |
|
|
|
type: 'number', |
|
|
|
}, |
|
|
|
minimum: { |
|
|
|
type: 'number', |
|
|
|
}, |
|
|
|
exclusiveMinimum: { |
|
|
|
type: 'number', |
|
|
|
}, |
|
|
|
maxLength: { $ref: '#/definitions/nonNegativeInteger' }, |
|
|
|
minLength: { $ref: '#/definitions/nonNegativeIntegerDefault0' }, |
|
|
|
pattern: { |
|
|
|
type: 'string', |
|
|
|
format: 'regex', |
|
|
|
}, |
|
|
|
additionalItems: { $ref: '#' }, |
|
|
|
items: { |
|
|
|
anyOf: [ |
|
|
|
{ $ref: '#' }, |
|
|
|
{ $ref: '#/definitions/schemaArray' }, |
|
|
|
], |
|
|
|
default: true, |
|
|
|
}, |
|
|
|
maxItems: { $ref: '#/definitions/nonNegativeInteger' }, |
|
|
|
minItems: { $ref: '#/definitions/nonNegativeIntegerDefault0' }, |
|
|
|
uniqueItems: { |
|
|
|
type: 'boolean', |
|
|
|
default: false, |
|
|
|
}, |
|
|
|
contains: { $ref: '#' }, |
|
|
|
maxProperties: { $ref: '#/definitions/nonNegativeInteger' }, |
|
|
|
minProperties: { $ref: '#/definitions/nonNegativeIntegerDefault0' }, |
|
|
|
required: { $ref: '#/definitions/stringArray' }, |
|
|
|
additionalProperties: { $ref: '#' }, |
|
|
|
definitions: { |
|
|
|
type: 'object', |
|
|
|
additionalProperties: { $ref: '#' }, |
|
|
|
default: {}, |
|
|
|
}, |
|
|
|
properties: { |
|
|
|
type: 'object', |
|
|
|
additionalProperties: { $ref: '#' }, |
|
|
|
default: {}, |
|
|
|
}, |
|
|
|
patternProperties: { |
|
|
|
type: 'object', |
|
|
|
additionalProperties: { $ref: '#' }, |
|
|
|
propertyNames: { format: 'regex' }, |
|
|
|
default: {}, |
|
|
|
}, |
|
|
|
dependencies: { |
|
|
|
type: 'object', |
|
|
|
additionalProperties: { |
|
|
|
anyOf: [ |
|
|
|
{ $ref: '#' }, |
|
|
|
{ $ref: '#/definitions/stringArray' }, |
|
|
|
], |
|
|
|
}, |
|
|
|
}, |
|
|
|
propertyNames: { $ref: '#' }, |
|
|
|
const: true, |
|
|
|
enum: { |
|
|
|
type: 'array', |
|
|
|
items: true, |
|
|
|
minItems: 1, |
|
|
|
uniqueItems: true, |
|
|
|
}, |
|
|
|
type: { |
|
|
|
anyOf: [ |
|
|
|
{ $ref: '#/definitions/simpleTypes' }, |
|
|
|
{ |
|
|
|
type: 'array', |
|
|
|
items: { $ref: '#/definitions/simpleTypes' }, |
|
|
|
minItems: 1, |
|
|
|
uniqueItems: true, |
|
|
|
}, |
|
|
|
], |
|
|
|
}, |
|
|
|
format: { type: 'string' }, |
|
|
|
allOf: { $ref: '#/definitions/schemaArray' }, |
|
|
|
anyOf: { $ref: '#/definitions/schemaArray' }, |
|
|
|
oneOf: { $ref: '#/definitions/schemaArray' }, |
|
|
|
not: { $ref: '#' }, |
|
|
|
}, |
|
|
|
default: true, |
|
|
|
} as unknown as Schema |
|
|
|
|
|
|
|
const validator = new Validator() |
|
|
|
|
|
|
|
export const validateSchemaAgainstDraft7 = (schemaToValidate: any) => { |
|
|
|
const schema = produce(schemaToValidate, (draft: any) => { |
|
|
|
// Make sure the schema has the $schema property for draft-07 |
|
|
|
if (!draft.$schema) |
|
|
|
draft.$schema = 'http://json-schema.org/draft-07/schema#' |
|
|
|
}) |
|
|
|
|
|
|
|
const result = validator.validate(schema, draft07MetaSchema, { |
|
|
|
nestedErrors: true, |
|
|
|
throwError: false, |
|
|
|
}) |
|
|
|
|
|
|
|
// Access errors from the validation result |
|
|
|
const errors = result.valid ? [] : result.errors || [] |
|
|
|
// First check against Draft-07 |
|
|
|
const result = draft07Validator(schemaToValidate) |
|
|
|
// Then apply custom rule |
|
|
|
const customErrors = forbidBooleanProperties(schemaToValidate) |
|
|
|
|
|
|
|
return errors |
|
|
|
return [...result.errors, ...customErrors] |
|
|
|
} |
|
|
|
|
|
|
|
export const getValidationErrorMessage = (errors: ValidationError[]) => { |
|
|
|
export const getValidationErrorMessage = (errors: Array<ValidationError | string>) => { |
|
|
|
const message = errors.map((error) => { |
|
|
|
return `Error: ${error.path.join('.')} ${error.message} Details: ${JSON.stringify(error.stack)}` |
|
|
|
}).join('; ') |
|
|
|
if (typeof error === 'string') |
|
|
|
return error |
|
|
|
else |
|
|
|
return `Error: ${error.stack}\n` |
|
|
|
}).join('') |
|
|
|
return message |
|
|
|
} |
|
|
|
|