import {default as addFormats} from 'ajv-formats' import * as AJV from 'ajv' import { extractJsonSchema } from './extract-json-schema.js' import { TJSONSchema } from './types.js' export type TSchemaParsed = { jsonSchema: { args?: TJSONSchema; data?: TJSONSchema } validation: { args?: (args: any) => { errors?: TSchemaValidationError[] } } } export type TSchemaValidationError = AJV.ErrorObject // @ts-ignore const ajv = addFormats( new AJV.Ajv({ allErrors: true, coerceTypes: true, removeAdditional: true, }), ) export function schemaParser( schema: { args?: unknown; data?: unknown }, onParseError: (errors: { args?: string; data?: string }) => void, ): TSchemaParsed { const jsonSchema: TSchemaParsed['jsonSchema'] = {} const validation: TSchemaParsed['validation'] = {} if (schema.args) { try { const extracted = extractJsonSchema(schema.args as TJSONSchema) if (extracted) { jsonSchema.args = extracted } } catch (e: any) { onParseError({ args: `Error extracting json schema schema.args - ${e.message}`, }) } if (!jsonSchema.args) { onParseError({ args: `Error extracting json schema schema.args - schema.args might be empty or it is not a valid suretype or typebox type`, }) } else { let argsValidator: AJV.ValidateFunction try { argsValidator = ajv.compile(jsonSchema.args as TJSONSchema) } catch (e: any) { onParseError({ args: `Error compiling schema.args for validator - ${e.message}`, }) } validation.args = (args: any) => { const valid = argsValidator(args) if (!valid) { const errors = argsValidator.errors return { errors: errors?.length ? errors : undefined, } } return {} } } } if (schema.data) { try { const extracted = extractJsonSchema(schema.data as TJSONSchema) jsonSchema.data = extracted } catch (e: any) { onParseError({ data: `Error extracting json schema schema.data - ${e.message}`, }) } if (!jsonSchema.data) { onParseError({ data: `Error extracting json schema schema.data - schema.data might be empty or it is not a valid suretype or typebox type`, }) } } return { jsonSchema, validation } }