@mastra/schema-compat 0.10.2-alpha.2 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
1
  import type { Schema, LanguageModelV1 } from 'ai';
2
2
  import type { JSONSchema7 } from 'json-schema';
3
- import { z } from 'zod';
3
+ import { z, ZodOptional, ZodObject, ZodArray, ZodUnion, ZodString, ZodNumber, ZodDate, ZodDefault } from 'zod';
4
+ import type { ZodTypeAny } from 'zod';
4
5
  import type { Targets } from 'zod-to-json-schema';
5
6
  import { convertZodSchemaToAISDKSchema } from './utils';
6
7
 
@@ -26,6 +27,15 @@ export const ALL_NUMBER_CHECKS = [
26
27
  */
27
28
  export const ALL_ARRAY_CHECKS = ['min', 'max', 'length'] as const;
28
29
 
30
+ export const isOptional = (v: ZodTypeAny): v is ZodOptional<any> => v instanceof ZodOptional;
31
+ export const isObj = (v: ZodTypeAny): v is ZodObject<any, any, any> => v instanceof ZodObject;
32
+ export const isArr = (v: ZodTypeAny): v is ZodArray<any, any> => v instanceof ZodArray;
33
+ export const isUnion = (v: ZodTypeAny): v is ZodUnion<[ZodTypeAny, ...ZodTypeAny[]]> => v instanceof ZodUnion;
34
+ export const isString = (v: ZodTypeAny): v is ZodString => v instanceof ZodString;
35
+ export const isNumber = (v: ZodTypeAny): v is ZodNumber => v instanceof ZodNumber;
36
+ export const isDate = (v: ZodTypeAny): v is ZodDate => v instanceof ZodDate;
37
+ export const isDefault = (v: ZodTypeAny): v is ZodDefault<any> => v instanceof ZodDefault;
38
+
29
39
  /**
30
40
  * Zod types that are not supported by most AI model providers and should be avoided.
31
41
  * @constant
@@ -214,30 +224,7 @@ export abstract class SchemaCompatLayer {
214
224
  * @returns The processed Zod type
215
225
  * @abstract
216
226
  */
217
- abstract processZodType<T extends z.AnyZodObject>(value: z.ZodTypeAny): ShapeValue<T>;
218
-
219
- /**
220
- * Applies compatibility transformations to a Zod object schema.
221
- *
222
- * @param zodSchema - The Zod object schema to transform
223
- * @returns Object containing the transformed schema
224
- * @private
225
- */
226
- private applyZodSchemaCompatibility(zodSchema: z.AnyZodObject): {
227
- schema: z.AnyZodObject;
228
- } {
229
- const newSchema = z.object(
230
- Object.entries<z.ZodTypeAny>(zodSchema.shape || {}).reduce(
231
- (acc, [key, value]) => ({
232
- ...acc,
233
- [key]: this.processZodType<any>(value),
234
- }),
235
- {},
236
- ),
237
- );
238
-
239
- return { schema: newSchema };
240
- }
227
+ abstract processZodType(value: ZodTypeAny): ZodTypeAny;
241
228
 
242
229
  /**
243
230
  * Default handler for Zod object types. Recursively processes all properties in the object.
@@ -245,22 +232,25 @@ export abstract class SchemaCompatLayer {
245
232
  * @param value - The Zod object to process
246
233
  * @returns The processed Zod object
247
234
  */
248
- public defaultZodObjectHandler<T extends z.AnyZodObject>(value: z.ZodTypeAny): ShapeValue<T> {
249
- const zodObject = value as z.ZodObject<any, any, any>;
250
- const processedShape = Object.entries(zodObject.shape || {}).reduce<Record<string, z.ZodTypeAny>>(
251
- (acc, [key, propValue]) => {
252
- const typedPropValue = propValue as z.ZodTypeAny;
253
- const processedValue = this.processZodType<T>(typedPropValue);
254
- acc[key] = processedValue;
255
- return acc;
256
- },
257
- {},
258
- );
259
- let result = z.object(processedShape);
235
+ public defaultZodObjectHandler(value: ZodObject<any, any, any>): ZodObject<any, any, any> {
236
+ const processedShape = Object.entries(value.shape).reduce<Record<string, ZodTypeAny>>((acc, [key, propValue]) => {
237
+ acc[key] = this.processZodType(propValue as ZodTypeAny);
238
+ return acc;
239
+ }, {});
240
+
241
+ let result: ZodObject<any, any, any> = z.object(processedShape);
242
+
243
+ if (value._def.unknownKeys === 'strict') {
244
+ result = result.strict();
245
+ }
246
+ if (value._def.catchall && !(value._def.catchall instanceof z.ZodNever)) {
247
+ result = result.catchall(value._def.catchall);
248
+ }
249
+
260
250
  if (value.description) {
261
251
  result = result.describe(value.description);
262
252
  }
263
- return result as ShapeValue<T>;
253
+ return result;
264
254
  }
265
255
 
266
256
  /**
@@ -314,40 +304,46 @@ export abstract class SchemaCompatLayer {
314
304
  * @param handleChecks - Array constraints to convert to descriptions vs keep as validation
315
305
  * @returns The processed Zod array
316
306
  */
317
- public defaultZodArrayHandler<T extends z.AnyZodObject>(
318
- value: z.ZodTypeAny,
307
+ public defaultZodArrayHandler(
308
+ value: ZodArray<any, any>,
319
309
  handleChecks: readonly ArrayCheckType[] = ALL_ARRAY_CHECKS,
320
- ): ShapeValue<T> {
321
- const zodArray = (value as z.ZodArray<any>)._def;
322
- const arrayType = zodArray.type;
323
- const constraints: ArrayConstraints = {};
324
- if (zodArray.minLength?.value !== undefined && handleChecks.includes('min')) {
325
- constraints.minLength = zodArray.minLength.value;
326
- }
327
- if (zodArray.maxLength?.value !== undefined && handleChecks.includes('max')) {
328
- constraints.maxLength = zodArray.maxLength.value;
329
- }
330
- if (zodArray.exactLength?.value !== undefined && handleChecks.includes('length')) {
331
- constraints.exactLength = zodArray.exactLength.value;
332
- }
333
- const processedType =
334
- arrayType._def.typeName === 'ZodObject' ? this.processZodType<T>(arrayType as z.ZodTypeAny) : arrayType;
310
+ ): ZodArray<any, any> {
311
+ const zodArrayDef = value._def;
312
+ const processedType = this.processZodType(zodArrayDef.type);
313
+
335
314
  let result = z.array(processedType);
336
- if (zodArray.minLength?.value !== undefined && !handleChecks.includes('min')) {
337
- result = result.min(zodArray.minLength.value);
315
+
316
+ const constraints: ArrayConstraints = {};
317
+
318
+ if (zodArrayDef.minLength?.value !== undefined) {
319
+ if (handleChecks.includes('min')) {
320
+ constraints.minLength = zodArrayDef.minLength.value;
321
+ } else {
322
+ result = result.min(zodArrayDef.minLength.value);
323
+ }
338
324
  }
339
- if (zodArray.maxLength?.value !== undefined && !handleChecks.includes('max')) {
340
- result = result.max(zodArray.maxLength.value);
325
+
326
+ if (zodArrayDef.maxLength?.value !== undefined) {
327
+ if (handleChecks.includes('max')) {
328
+ constraints.maxLength = zodArrayDef.maxLength.value;
329
+ } else {
330
+ result = result.max(zodArrayDef.maxLength.value);
331
+ }
341
332
  }
342
- if (zodArray.exactLength?.value !== undefined && !handleChecks.includes('length')) {
343
- result = result.length(zodArray.exactLength.value);
333
+
334
+ if (zodArrayDef.exactLength?.value !== undefined) {
335
+ if (handleChecks.includes('length')) {
336
+ constraints.exactLength = zodArrayDef.exactLength.value;
337
+ } else {
338
+ result = result.length(zodArrayDef.exactLength.value);
339
+ }
344
340
  }
345
341
 
346
342
  const description = this.mergeParameterDescription(value.description, constraints);
347
343
  if (description) {
348
344
  result = result.describe(description);
349
345
  }
350
- return result as ShapeValue<T>;
346
+ return result;
351
347
  }
352
348
 
353
349
  /**
@@ -357,15 +353,14 @@ export abstract class SchemaCompatLayer {
357
353
  * @returns The processed Zod union
358
354
  * @throws Error if union has fewer than 2 options
359
355
  */
360
- public defaultZodUnionHandler<T extends z.AnyZodObject>(value: z.ZodTypeAny): ShapeValue<T> {
361
- const zodUnion = value as z.ZodUnion<[z.ZodTypeAny, ...z.ZodTypeAny[]]>;
362
- const processedOptions = zodUnion._def.options.map((option: z.ZodTypeAny) => this.processZodType<T>(option));
356
+ public defaultZodUnionHandler(value: ZodUnion<[ZodTypeAny, ...ZodTypeAny[]]>): ZodTypeAny {
357
+ const processedOptions = value._def.options.map((option: ZodTypeAny) => this.processZodType(option));
363
358
  if (processedOptions.length < 2) throw new Error('Union must have at least 2 options');
364
- let result = z.union(processedOptions as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]);
359
+ let result = z.union(processedOptions as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]]);
365
360
  if (value.description) {
366
361
  result = result.describe(value.description);
367
362
  }
368
- return result as ShapeValue<T>;
363
+ return result;
369
364
  }
370
365
 
371
366
  /**
@@ -375,13 +370,12 @@ export abstract class SchemaCompatLayer {
375
370
  * @param handleChecks - String constraints to convert to descriptions vs keep as validation
376
371
  * @returns The processed Zod string
377
372
  */
378
- public defaultZodStringHandler<T extends z.AnyZodObject>(
379
- value: z.ZodTypeAny,
373
+ public defaultZodStringHandler(
374
+ value: ZodString,
380
375
  handleChecks: readonly StringCheckType[] = ALL_STRING_CHECKS,
381
- ): ShapeValue<T> {
382
- const zodString = value as z.ZodString;
376
+ ): ZodString {
383
377
  const constraints: StringConstraints = {};
384
- const checks = zodString._def.checks || [];
378
+ const checks = value._def.checks || [];
385
379
  type ZodStringCheck = (typeof checks)[number];
386
380
  const newChecks: ZodStringCheck[] = [];
387
381
  for (const check of checks) {
@@ -437,7 +431,7 @@ export abstract class SchemaCompatLayer {
437
431
  if (description) {
438
432
  result = result.describe(description);
439
433
  }
440
- return result as ShapeValue<T>;
434
+ return result;
441
435
  }
442
436
 
443
437
  /**
@@ -447,13 +441,12 @@ export abstract class SchemaCompatLayer {
447
441
  * @param handleChecks - Number constraints to convert to descriptions vs keep as validation
448
442
  * @returns The processed Zod number
449
443
  */
450
- public defaultZodNumberHandler<T extends z.AnyZodObject>(
451
- value: z.ZodTypeAny,
444
+ public defaultZodNumberHandler(
445
+ value: ZodNumber,
452
446
  handleChecks: readonly NumberCheckType[] = ALL_NUMBER_CHECKS,
453
- ): ShapeValue<T> {
454
- const zodNumber = value as z.ZodNumber;
447
+ ): ZodNumber {
455
448
  const constraints: NumberConstraints = {};
456
- const checks = zodNumber._def.checks || [];
449
+ const checks = value._def.checks || [];
457
450
  type ZodNumberCheck = (typeof checks)[number];
458
451
  const newChecks: ZodNumberCheck[] = [];
459
452
  for (const check of checks) {
@@ -501,7 +494,7 @@ export abstract class SchemaCompatLayer {
501
494
  if (description) {
502
495
  result = result.describe(description);
503
496
  }
504
- return result as ShapeValue<T>;
497
+ return result;
505
498
  }
506
499
 
507
500
  /**
@@ -510,10 +503,9 @@ export abstract class SchemaCompatLayer {
510
503
  * @param value - The Zod date to process
511
504
  * @returns A Zod string schema representing the date in ISO format
512
505
  */
513
- public defaultZodDateHandler<T extends z.AnyZodObject>(value: z.ZodTypeAny): ShapeValue<T> {
514
- const zodDate = value as z.ZodDate;
506
+ public defaultZodDateHandler(value: ZodDate): ZodString {
515
507
  const constraints: DateConstraints = {};
516
- const checks = zodDate._def.checks || [];
508
+ const checks = value._def.checks || [];
517
509
  type ZodDateCheck = (typeof checks)[number];
518
510
  const newChecks: ZodDateCheck[] = [];
519
511
  for (const check of checks) {
@@ -542,7 +534,7 @@ export abstract class SchemaCompatLayer {
542
534
  if (description) {
543
535
  result = result.describe(description);
544
536
  }
545
- return result as ShapeValue<T>;
537
+ return result;
546
538
  }
547
539
 
548
540
  /**
@@ -552,14 +544,14 @@ export abstract class SchemaCompatLayer {
552
544
  * @param handleTypes - Types that should be processed vs passed through
553
545
  * @returns The processed Zod optional
554
546
  */
555
- public defaultZodOptionalHandler<T extends z.AnyZodObject>(
556
- value: z.ZodTypeAny,
547
+ public defaultZodOptionalHandler(
548
+ value: ZodOptional<any>,
557
549
  handleTypes: readonly AllZodType[] = SUPPORTED_ZOD_TYPES,
558
- ): ShapeValue<T> {
550
+ ): ZodTypeAny {
559
551
  if (handleTypes.includes(value._def.innerType._def.typeName as AllZodType)) {
560
552
  return this.processZodType(value._def.innerType).optional();
561
553
  } else {
562
- return value as ShapeValue<T>;
554
+ return value;
563
555
  }
564
556
  }
565
557
 
@@ -569,10 +561,10 @@ export abstract class SchemaCompatLayer {
569
561
  * @param zodSchema - The Zod object schema to process
570
562
  * @returns An AI SDK Schema with provider-specific compatibility applied
571
563
  */
572
- public processToAISDKSchema(zodSchema: z.AnyZodObject): Schema {
573
- const { schema } = this.applyZodSchemaCompatibility(zodSchema);
564
+ public processToAISDKSchema(zodSchema: z.ZodSchema): Schema {
565
+ const processedSchema = this.processZodType(zodSchema);
574
566
 
575
- return convertZodSchemaToAISDKSchema(schema, this.getSchemaTarget());
567
+ return convertZodSchemaToAISDKSchema(processedSchema, this.getSchemaTarget());
576
568
  }
577
569
 
578
570
  /**
@@ -581,7 +573,7 @@ export abstract class SchemaCompatLayer {
581
573
  * @param zodSchema - The Zod object schema to process
582
574
  * @returns A JSONSchema7 object with provider-specific compatibility applied
583
575
  */
584
- public processToJSONSchema(zodSchema: z.AnyZodObject): JSONSchema7 {
576
+ public processToJSONSchema(zodSchema: z.ZodSchema): JSONSchema7 {
585
577
  return this.processToAISDKSchema(zodSchema).jsonSchema;
586
578
  }
587
579
  }
package/src/utils.test.ts CHANGED
@@ -31,6 +31,12 @@ class MockSchemaCompatibility extends SchemaCompatLayer {
31
31
  if (value._def.typeName === 'ZodString') {
32
32
  return z.string().describe('processed string');
33
33
  }
34
+ if (value instanceof z.ZodObject) {
35
+ return this.defaultZodObjectHandler(value);
36
+ }
37
+ if (value instanceof z.ZodArray) {
38
+ return this.defaultZodArrayHandler(value);
39
+ }
34
40
  return value;
35
41
  }
36
42
  }
@@ -97,6 +103,13 @@ describe('Builder Functions', () => {
97
103
  expect(result).toHaveProperty('jsonSchema');
98
104
  expect(result.jsonSchema).toHaveProperty('properties');
99
105
  });
106
+
107
+ it('should handle array schemas', () => {
108
+ const zodSchema = z.array(z.string());
109
+ const result = convertZodSchemaToAISDKSchema(zodSchema);
110
+ expect(result.jsonSchema.type).toBe('array');
111
+ expect((result.jsonSchema.items as any)?.type).toBe('string');
112
+ });
100
113
  });
101
114
 
102
115
  describe('convertSchemaToZod', () => {
@@ -158,6 +171,20 @@ describe('Builder Functions', () => {
158
171
  const parseResult = result.safeParse(validData);
159
172
  expect(parseResult.success).toBe(true);
160
173
  });
174
+
175
+ it('should convert AI SDK array schema to Zod', () => {
176
+ const aiSchema: Schema = jsonSchema({
177
+ type: 'array',
178
+ items: {
179
+ type: 'string',
180
+ },
181
+ });
182
+
183
+ const result = convertSchemaToZod(aiSchema);
184
+
185
+ expect(result).toBeInstanceOf(z.ZodArray);
186
+ expect((result as z.ZodArray<any>).element).toBeInstanceOf(z.ZodString);
187
+ });
161
188
  });
162
189
 
163
190
  describe('applyCompatLayer', () => {
@@ -275,29 +302,6 @@ describe('Builder Functions', () => {
275
302
  expect(result).toHaveProperty('validate');
276
303
  });
277
304
 
278
- it('should convert non-object AI SDK schema correctly', () => {
279
- const stringSchema: Schema = jsonSchema({ type: 'string' });
280
-
281
- const result = applyCompatLayer({
282
- schema: stringSchema,
283
- compatLayers: [mockCompatibility],
284
- mode: 'aiSdkSchema',
285
- });
286
-
287
- expect(result).toHaveProperty('jsonSchema');
288
- expect(result).toHaveProperty('validate');
289
-
290
- // Verify the schema structure shows the string was wrapped in a 'value' property
291
- const resultSchema = (result as Schema).jsonSchema;
292
- expect(resultSchema).toHaveProperty('type', 'object');
293
- expect(resultSchema).toHaveProperty('properties');
294
- expect(resultSchema.properties).toHaveProperty('value');
295
-
296
- // Verify the string property has the description added by the mock compatibility layer
297
- const valueProperty = resultSchema.properties!.value as any;
298
- expect(valueProperty).toHaveProperty('description', 'processed string');
299
- });
300
-
301
305
  it('should handle complex schema with multiple compatLayers', () => {
302
306
  const compat1 = new MockSchemaCompatibility(mockModel, false);
303
307
  const compat2 = new MockSchemaCompatibility(mockModel, true);
@@ -324,5 +328,107 @@ describe('Builder Functions', () => {
324
328
  expect(compat1.processZodType).not.toHaveBeenCalled();
325
329
  expect(compat2.processZodType).toHaveBeenCalled();
326
330
  });
331
+
332
+ it('should process Zod array schema with compatibility', () => {
333
+ const arraySchema = z.array(z.string());
334
+
335
+ const result = applyCompatLayer({
336
+ schema: arraySchema,
337
+ compatLayers: [mockCompatibility],
338
+ mode: 'aiSdkSchema',
339
+ });
340
+
341
+ expect(result.jsonSchema.type).toBe('array');
342
+ if (
343
+ result.jsonSchema.items &&
344
+ !Array.isArray(result.jsonSchema.items) &&
345
+ typeof result.jsonSchema.items === 'object'
346
+ ) {
347
+ expect(result.jsonSchema.items.type).toBe('string');
348
+ expect(result.jsonSchema.items.description).toBe('processed string');
349
+ } else {
350
+ expect.fail('items is not a single schema object');
351
+ }
352
+ });
353
+
354
+ it('should process AI SDK array schema with compatibility', () => {
355
+ const aiSchema: Schema = jsonSchema({
356
+ type: 'array',
357
+ items: {
358
+ type: 'string',
359
+ },
360
+ });
361
+
362
+ const result = applyCompatLayer({
363
+ schema: aiSchema,
364
+ compatLayers: [mockCompatibility],
365
+ mode: 'aiSdkSchema',
366
+ });
367
+
368
+ expect(result.jsonSchema.type).toBe('array');
369
+ if (
370
+ result.jsonSchema.items &&
371
+ !Array.isArray(result.jsonSchema.items) &&
372
+ typeof result.jsonSchema.items === 'object'
373
+ ) {
374
+ expect(result.jsonSchema.items.type).toBe('string');
375
+ expect(result.jsonSchema.items.description).toBe('processed string');
376
+ } else {
377
+ expect.fail('items is not a single schema object');
378
+ }
379
+ });
380
+
381
+ it('should handle a complex array of objects schema', () => {
382
+ const complexArraySchema = z.array(
383
+ z.object({
384
+ id: z.string(),
385
+ user: z.object({
386
+ name: z.string(),
387
+ }),
388
+ }),
389
+ );
390
+
391
+ const result = applyCompatLayer({
392
+ schema: complexArraySchema,
393
+ compatLayers: [mockCompatibility],
394
+ mode: 'aiSdkSchema',
395
+ });
396
+
397
+ const { jsonSchema } = result;
398
+ expect(jsonSchema.type).toBe('array');
399
+
400
+ const items = jsonSchema.items;
401
+ if (items && !Array.isArray(items) && typeof items === 'object') {
402
+ expect(items.type).toBe('object');
403
+ expect(items.properties).toHaveProperty('id');
404
+ expect(items.properties).toHaveProperty('user');
405
+
406
+ const idProperty = items.properties!.id as any;
407
+ expect(idProperty.description).toBe('processed string');
408
+
409
+ const userProperty = items.properties!.user as any;
410
+ expect(userProperty.type).toBe('object');
411
+ expect(userProperty.properties).toHaveProperty('name');
412
+
413
+ const nameProperty = userProperty.properties.name as any;
414
+ expect(nameProperty.description).toBe('processed string');
415
+ } else {
416
+ expect.fail('items is not a single schema object');
417
+ }
418
+ });
419
+
420
+ it('should handle a scalar zod schema', () => {
421
+ const scalarSchema = z.string().email();
422
+
423
+ const result = applyCompatLayer({
424
+ schema: scalarSchema,
425
+ compatLayers: [mockCompatibility],
426
+ mode: 'aiSdkSchema',
427
+ });
428
+
429
+ const { jsonSchema } = result;
430
+ expect(jsonSchema.type).toBe('string');
431
+ expect(jsonSchema.description).toBe('processed string');
432
+ });
327
433
  });
328
434
  });
package/src/utils.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import { jsonSchema } from 'ai';
2
2
  import type { Schema } from 'ai';
3
3
  import type { JSONSchema7 } from 'json-schema';
4
- import type { ZodSchema } from 'zod';
5
- import { z } from 'zod';
4
+ import type { z, ZodSchema } from 'zod';
6
5
  import { convertJsonSchemaToZod } from 'zod-from-json-schema';
7
6
  import type { JSONSchema as ZodFromJSONSchema_JSONSchema } from 'zod-from-json-schema';
8
7
  import type { Targets } from 'zod-to-json-schema';
@@ -118,7 +117,7 @@ export function convertSchemaToZod(schema: Schema | z.ZodSchema): z.ZodType {
118
117
  * @returns Processed schema as an AI SDK Schema
119
118
  */
120
119
  export function applyCompatLayer(options: {
121
- schema: Schema | z.AnyZodObject;
120
+ schema: Schema | z.ZodSchema;
122
121
  compatLayers: SchemaCompatLayer[];
123
122
  mode: 'aiSdkSchema';
124
123
  }): Schema;
@@ -133,7 +132,7 @@ export function applyCompatLayer(options: {
133
132
  * @returns Processed schema as a JSONSchema7
134
133
  */
135
134
  export function applyCompatLayer(options: {
136
- schema: Schema | z.AnyZodObject;
135
+ schema: Schema | z.ZodSchema;
137
136
  compatLayers: SchemaCompatLayer[];
138
137
  mode: 'jsonSchema';
139
138
  }): JSONSchema7;
@@ -178,29 +177,17 @@ export function applyCompatLayer({
178
177
  compatLayers,
179
178
  mode,
180
179
  }: {
181
- schema: Schema | z.AnyZodObject;
180
+ schema: Schema | z.ZodSchema;
182
181
  compatLayers: SchemaCompatLayer[];
183
182
  mode: 'jsonSchema' | 'aiSdkSchema';
184
183
  }): JSONSchema7 | Schema {
185
- let zodSchema: z.AnyZodObject;
184
+ let zodSchema: z.ZodSchema;
186
185
 
187
186
  if (!isZodType(schema)) {
188
- // Convert Schema to ZodObject
189
- const convertedSchema = convertSchemaToZod(schema);
190
- if (convertedSchema instanceof z.ZodObject) {
191
- zodSchema = convertedSchema;
192
- } else {
193
- // If it's not an object schema, wrap it in an object
194
- zodSchema = z.object({ value: convertedSchema });
195
- }
187
+ // Convert non-zod schema to Zod
188
+ zodSchema = convertSchemaToZod(schema);
196
189
  } else {
197
- // Ensure it's a ZodObject
198
- if (schema instanceof z.ZodObject) {
199
- zodSchema = schema;
200
- } else {
201
- // Wrap non-object schemas in an object
202
- zodSchema = z.object({ value: schema });
203
- }
190
+ zodSchema = schema;
204
191
  }
205
192
 
206
193
  for (const compat of compatLayers) {