@@ -99,6 +99,78 @@ const detector = (id: string, confidence: SourceDetectionResult["confidence"]) =
9999 ) ,
100100 } ) ) ( ) ;
101101
102+ const schemaProbePlugin = definePlugin ( ( ) => ( {
103+ id : "schemaProbe" as const ,
104+ storage : ( ) => ( { } ) ,
105+ extension : ( ctx ) => ( {
106+ registerSource : ( ) =>
107+ ctx . transaction (
108+ Effect . gen ( function * ( ) {
109+ const scope = String ( ctx . scopes [ 0 ] ! . id ) ;
110+ yield * ctx . core . sources . register ( {
111+ id : "schema-source" ,
112+ scope,
113+ kind : "schema" ,
114+ name : "Schema Source" ,
115+ tools : [
116+ {
117+ name : "inspect" ,
118+ description : "inspect" ,
119+ inputSchema : {
120+ type : "object" ,
121+ properties : {
122+ pet : { $ref : "#/$defs/Pet" } ,
123+ } ,
124+ required : [ "pet" ] ,
125+ } ,
126+ outputSchema : { $ref : "#/$defs/Owner" } ,
127+ } ,
128+ ] ,
129+ } ) ;
130+ yield * ctx . core . definitions . register ( {
131+ sourceId : "schema-source" ,
132+ scope,
133+ definitions : {
134+ Pet : {
135+ anyOf : [ { $ref : "#/$defs/Dog" } , { $ref : "#/$defs/Cat" } ] ,
136+ } ,
137+ Dog : {
138+ type : "object" ,
139+ properties : {
140+ collar : { $ref : "#/$defs/Collar" } ,
141+ } ,
142+ } ,
143+ Cat : {
144+ type : "object" ,
145+ properties : {
146+ lives : { type : "number" } ,
147+ } ,
148+ } ,
149+ Collar : {
150+ type : "object" ,
151+ properties : {
152+ id : { type : "string" } ,
153+ } ,
154+ } ,
155+ Owner : {
156+ type : "object" ,
157+ properties : {
158+ pet : { $ref : "#/$defs/Pet" } ,
159+ } ,
160+ } ,
161+ Unused : {
162+ type : "object" ,
163+ properties : {
164+ value : { type : "string" } ,
165+ } ,
166+ } ,
167+ } ,
168+ } ) ;
169+ } ) ,
170+ ) ,
171+ } ) ,
172+ } ) ) ( ) ;
173+
102174describe ( "createExecutor" , ( ) => {
103175 it . effect ( "rolls back plugin and core writes from ctx.transaction failures" , ( ) =>
104176 Effect . gen ( function * ( ) {
@@ -204,4 +276,46 @@ describe("createExecutor", () => {
204276 expect ( called ) . toBe ( false ) ;
205277 } ) ,
206278 ) ;
279+
280+ it . effect ( "returns schema roots with shared reachable definitions" , ( ) =>
281+ Effect . gen ( function * ( ) {
282+ const executor = yield * makeTestExecutor ( { plugins : [ schemaProbePlugin ] as const } ) ;
283+
284+ yield * executor . schemaProbe . registerSource ( ) ;
285+
286+ const schema = yield * executor . tools . schema ( "schema-source.inspect" , {
287+ includeTypeScript : false ,
288+ } ) ;
289+
290+ expect ( schema ?. inputSchema ) . toEqual ( {
291+ type : "object" ,
292+ properties : {
293+ pet : { $ref : "#/$defs/Pet" } ,
294+ } ,
295+ required : [ "pet" ] ,
296+ } ) ;
297+ expect ( schema ?. outputSchema ) . toEqual ( { $ref : "#/$defs/Owner" } ) ;
298+ expect ( schema ?. schemaDefinitions ) . toEqual ( {
299+ Cat : expect . any ( Object ) ,
300+ Collar : expect . any ( Object ) ,
301+ Dog : expect . any ( Object ) ,
302+ Owner : expect . any ( Object ) ,
303+ Pet : expect . any ( Object ) ,
304+ } ) ;
305+ expect ( schema ?. schemaDefinitions ) . not . toHaveProperty ( "Unused" ) ;
306+ expect ( schema ?. inputTypeScript ) . toBeUndefined ( ) ;
307+ expect ( schema ?. outputTypeScript ) . toBeUndefined ( ) ;
308+ expect ( schema ?. typeScriptDefinitions ) . toBeUndefined ( ) ;
309+
310+ const schemaWithTypes = yield * executor . tools . schema ( "schema-source.inspect" ) ;
311+ expect ( schemaWithTypes ?. inputTypeScript ) . toContain ( "pet: Pet" ) ;
312+ expect ( schemaWithTypes ?. outputTypeScript ) . toBe ( "Owner" ) ;
313+ expect ( schemaWithTypes ?. typeScriptDefinitions ) . toEqual (
314+ expect . objectContaining ( {
315+ Pet : expect . any ( String ) ,
316+ Owner : expect . any ( String ) ,
317+ } ) ,
318+ ) ;
319+ } ) ,
320+ ) ;
207321} ) ;
0 commit comments