| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 
 | import Ajv, { ValidateFunction } from 'ajv';
 const ajv = new Ajv();
 
 const schemaCache = new Map<string, ValidateFunction>();
 
 const validate = (schema: Record<string, unknown>) => {
 const validate = compileSchema(schema);
 return (input: unknown): boolean | string => {
 if (!input) return false;
 if (typeof input === 'string') {
 try {
 input = JSON.parse(input);
 } catch (err) {
 console.warn(err);
 return false;
 }
 }
 if (validate(input)) return true;
 const { errors } = validate;
 if (Array.isArray(errors)) {
 const [error] = errors;
 const { instancePath, message } = error;
 return instancePath
 ? `The property at path "${instancePath}" ${message}.`
 : `The json schema field ${message}.`;
 }
 return false;
 };
 };
 
 const compileSchema = (schema: Record<string, unknown>): ValidateFunction => {
 const cacheKey = JSON.stringify(schema);
 const cached = schemaCache.get(cacheKey);
 if (cached) return cached;
 try {
 const validate = ajv.compile(schema);
 schemaCache.set(cacheKey, validate);
 return validate;
 } catch (err) {
 throw new Error(`Invalid schema: ${(err as Error).message.replace('schema is invalid: ', '')}`);
 }
 };
 
 export default validate;
 
 |