From ae5f96e4ffb1a66544248a4d3c7317a16c61ed0a Mon Sep 17 00:00:00 2001 From: Travis Fischer Date: Tue, 3 Jun 2025 20:02:08 +0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/lib/validate-json-schema-object.ts | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 apps/gateway/src/lib/validate-json-schema-object.ts diff --git a/apps/gateway/src/lib/validate-json-schema-object.ts b/apps/gateway/src/lib/validate-json-schema-object.ts new file mode 100644 index 00000000..28f50b5a --- /dev/null +++ b/apps/gateway/src/lib/validate-json-schema-object.ts @@ -0,0 +1,47 @@ +import { HttpError } from '@agentic/platform-core' +import { Validator } from '@cfworker/json-schema' +import plur from 'plur' + +export function validateJsonSchemaObject< + T extends Record = Record +>({ + schema, + data, + errorMessage +}: { + schema: any + data: unknown + errorMessage?: string +}): T { + // Special-case check for required fields to give better error messages + if (Array.isArray(schema.required)) { + const missingRequiredFields: string[] = schema.required.filter( + (field: string) => (data as T)[field] === undefined + ) + + if (missingRequiredFields.length > 0) { + throw new HttpError({ + statusCode: 400, + message: `${errorMessage ? errorMessage + ': ' : ''}Missing required ${plur('field', missingRequiredFields.length)}: ${missingRequiredFields.map((field) => `"${field}"`).join(', ')}` + }) + } + } + + const validator = new Validator(schema) + + const result = validator.validate(data) + if (result.valid) { + return data as T + } + + const finalErrorMessage = `${ + errorMessage ? errorMessage + ': ' : '' + }${result.errors + .map(({ keyword, error }) => `keyword "${keyword}" error ${error}`) + .join(' ')}` + + throw new HttpError({ + statusCode: 400, + message: finalErrorMessage + }) +}