1+ import type { StandardSchemaV1 } from '@standard-schema/spec'
12import * as v from 'valibot'
23import { describe , expect , it } from 'vitest'
3- import { valibotArgsToJsonSchema , valibotReturnToJsonSchema } from '../to-json-schema'
4+ import { argsToJsonSchema , returnToJsonSchema } from '../to-json-schema'
45
5- describe ( 'valibotArgsToJsonSchema' , ( ) => {
6+ /** Minimal Standard Schema implementation that never validates, for exercising the JSON Schema dispatch. */
7+ function fakeSchema ( options : { jsonSchema ?: ( options : { target : string } ) => unknown } = { } ) : StandardSchemaV1 {
8+ return {
9+ '~standard' : {
10+ version : 1 ,
11+ vendor : 'fake' ,
12+ validate : ( value : unknown ) => ( { value } ) ,
13+ ...( options . jsonSchema
14+ ? { jsonSchema : { input : options . jsonSchema , output : options . jsonSchema } }
15+ : { } ) ,
16+ } ,
17+ } as StandardSchemaV1
18+ }
19+
20+ describe ( 'argsToJsonSchema' , ( ) => {
621 it ( 'returns an empty object schema when no args' , ( ) => {
7- const { schema, unwrapped } = valibotArgsToJsonSchema ( undefined )
22+ const { schema, unwrapped } = argsToJsonSchema ( undefined )
823 expect ( unwrapped ) . toBe ( false )
924 expect ( schema ) . toEqual ( { type : 'object' , properties : { } } )
1025 } )
1126
1227 it ( 'wraps multiple positional args under arg0/arg1/...' , ( ) => {
13- const { schema, unwrapped } = valibotArgsToJsonSchema ( [ v . string ( ) , v . number ( ) ] )
28+ const { schema, unwrapped } = argsToJsonSchema ( [ v . string ( ) , v . number ( ) ] )
1429 expect ( unwrapped ) . toBe ( false )
1530 expect ( schema ) . toMatchObject ( {
1631 type : 'object' ,
@@ -23,7 +38,7 @@ describe('valibotArgsToJsonSchema', () => {
2338 } )
2439
2540 it ( 'unwraps a single object schema for nicer agent UX' , ( ) => {
26- const { schema, unwrapped } = valibotArgsToJsonSchema ( [
41+ const { schema, unwrapped } = argsToJsonSchema ( [
2742 v . object ( { name : v . string ( ) , age : v . number ( ) } ) ,
2843 ] )
2944 expect ( unwrapped ) . toBe ( true )
@@ -34,20 +49,41 @@ describe('valibotArgsToJsonSchema', () => {
3449 } )
3550
3651 it ( 'keeps arg0 shape when the single arg is a primitive' , ( ) => {
37- const { schema, unwrapped } = valibotArgsToJsonSchema ( [ v . string ( ) ] )
52+ const { schema, unwrapped } = argsToJsonSchema ( [ v . string ( ) ] )
3853 expect ( unwrapped ) . toBe ( false )
3954 expect ( schema ) . toMatchObject ( { type : 'object' , required : [ 'arg0' ] } )
4055 } )
4156} )
4257
43- describe ( 'valibotReturnToJsonSchema ' , ( ) => {
58+ describe ( 'returnToJsonSchema ' , ( ) => {
4459 it ( 'returns undefined when no schema is provided' , ( ) => {
45- expect ( valibotReturnToJsonSchema ( undefined ) ) . toBeUndefined ( )
60+ expect ( returnToJsonSchema ( undefined ) ) . toBeUndefined ( )
4661 } )
4762
48- it ( 'converts a simple schema' , ( ) => {
49- const schema = valibotReturnToJsonSchema ( v . object ( { ok : v . boolean ( ) } ) )
63+ it ( 'converts a simple valibot schema' , ( ) => {
64+ const schema = returnToJsonSchema ( v . object ( { ok : v . boolean ( ) } ) )
5065 expect ( ( schema as any ) . type ) . toBe ( 'object' )
5166 expect ( ( schema as any ) . properties . ok ) . toMatchObject ( { type : 'boolean' } )
5267 } )
68+
69+ it ( 'uses the schema\'s own Standard Schema JSON Schema converter when present' , ( ) => {
70+ const schema = returnToJsonSchema ( fakeSchema ( {
71+ jsonSchema : ( ) => ( { type : 'string' , format : 'email' } ) ,
72+ } ) )
73+ expect ( schema ) . toEqual ( { type : 'string' , format : 'email' } )
74+ } )
75+
76+ it ( 'falls back to the generic object schema when no converter is available' , ( ) => {
77+ const schema = returnToJsonSchema ( fakeSchema ( ) )
78+ expect ( schema ) . toEqual ( { type : 'object' , additionalProperties : true } )
79+ } )
80+
81+ it ( 'falls back to the generic object schema when the converter throws' , ( ) => {
82+ const schema = returnToJsonSchema ( fakeSchema ( {
83+ jsonSchema : ( ) => {
84+ throw new Error ( 'unsupported' )
85+ } ,
86+ } ) )
87+ expect ( schema ) . toEqual ( { type : 'object' , additionalProperties : true } )
88+ } )
5389} )
0 commit comments