@@ -53,6 +53,12 @@ export interface ApiEndpointLayoutContext {
5353 responseKey : string | null
5454 responseType : string | null
5555 responsePath : string | null
56+ batchResources : Array < {
57+ batchKey : string
58+ resourceType : string
59+ escapedResourceType : string
60+ responsePath : string | null
61+ } > | null
5662 actionAttempt ?: Omit < ApiRouteResource , 'events' >
5763 }
5864 resourceSamples : ResourceSampleContext [ ]
@@ -156,6 +162,7 @@ export function setEndpointLayoutContext(
156162 responseKey : null ,
157163 responseType : null ,
158164 responsePath : null ,
165+ batchResources : null ,
159166 }
160167
161168 if ( endpoint . response . responseType !== 'void' ) {
@@ -177,6 +184,35 @@ export function setEndpointLayoutContext(
177184 file . response . responseKey = responseKey
178185 file . response . responseType = responseType
179186 file . response . responsePath = responsePath
187+
188+ // Handle batch resource types
189+ if (
190+ 'batchResourceTypes' in endpoint . response &&
191+ endpoint . response . batchResourceTypes != null
192+ ) {
193+ file . response . batchResources = endpoint . response . batchResourceTypes . map (
194+ ( batchResource ) => {
195+ const batchResourceDef = resources . find (
196+ ( r ) => r . resourceType === batchResource . resourceType ,
197+ )
198+ let batchResponsePath = null
199+ if ( batchResourceDef != null ) {
200+ batchResponsePath = path
201+ . relative ( endpoint . path , batchResourceDef . routePath )
202+ . replace ( '..' , '.' )
203+ }
204+ return {
205+ batchKey : batchResource . batchKey ,
206+ resourceType : batchResource . resourceType ,
207+ responsePath : batchResponsePath ,
208+ escapedResourceType : batchResource . resourceType . replaceAll (
209+ '_' ,
210+ '\\_' ,
211+ ) ,
212+ }
213+ } ,
214+ )
215+ }
180216 }
181217
182218 if (
@@ -318,8 +354,65 @@ const getResourceSamples = (
318354 )
319355 }
320356
321- if ( resource == null ) return [ ]
357+ // Manually build sample for batch resources by fetching each resource's sample
358+ // and then combining them in a batch with the correct batch keys.
359+ if (
360+ response . responseType === 'resource' &&
361+ response . batchResourceTypes != null
362+ ) {
363+ const batchResourceSamples = getBatchResourceSamples (
364+ response ,
365+ resources ,
366+ endpoint ,
367+ pathMetadata ,
368+ )
369+
370+ const batchResourceSamplesString = JSON . stringify (
371+ batchResourceSamples ,
372+ null ,
373+ 2 ,
374+ )
375+ return [
376+ {
377+ title : 'JSON' ,
378+ description : '' ,
379+ resource_type : 'batch' ,
380+ resource : {
381+ seam_cli : {
382+ title : 'JSON' ,
383+ resource_data : batchResourceSamplesString ,
384+ resource_data_syntax : 'json' as const ,
385+ } ,
386+ } ,
387+ properties : batchResourceSamples ,
388+ } ,
389+ ]
390+ }
391+
392+ if ( resource == null ) {
393+ return [ ]
394+ }
395+
396+ const sample = getResourceSample ( resource , endpoint , pathMetadata )
397+
398+ if ( sample == null ) {
399+ return [ ]
400+ }
322401
402+ return [
403+ {
404+ ...sample ,
405+ title : 'JSON' ,
406+ description : '' ,
407+ } ,
408+ ]
409+ }
410+
411+ function getResourceSample (
412+ resource : Resource | ActionAttempt ,
413+ endpoint : Endpoint ,
414+ pathMetadata : PathMetadata ,
415+ ) : ResourceSample | null {
323416 const endpointMetadata = pathMetadata [ resource . routePath ]
324417 const endpointSample = resource . resourceSamples . filter (
325418 resourceSampleFilter ( {
@@ -339,13 +432,57 @@ const getResourceSamples = (
339432
340433 const sample = parentSample ?? endpointSample
341434
342- if ( sample == null ) return [ ]
435+ if ( sample == null ) {
436+ return null
437+ }
343438
344- return [
345- {
346- ...sample ,
347- title : 'JSON' ,
348- description : '' ,
349- } ,
350- ]
439+ return {
440+ ...sample ,
441+ title : 'JSON' ,
442+ description : '' ,
443+ }
444+ }
445+
446+ function getBatchResourceSamples (
447+ response : Extract < Endpoint [ 'response' ] , { responseType : 'resource' } > ,
448+ resources : Resource [ ] ,
449+ endpoint : Endpoint ,
450+ pathMetadata : PathMetadata ,
451+ ) : Record < string , Array < any > > {
452+ // 'any' is inevitable here since the data is being parsed from a string
453+ // and every sample data is different.
454+ const batchResourceSamples : Record < string , Array < any > > = { }
455+
456+ if ( response . batchResourceTypes == null ) {
457+ return batchResourceSamples
458+ }
459+
460+ for ( const batchResourceType of response . batchResourceTypes ) {
461+ const batchResource = resources . find (
462+ ( r ) => r . resourceType === batchResourceType . resourceType ,
463+ )
464+
465+ if ( batchResource == null ) {
466+ continue
467+ }
468+
469+ const sample = getResourceSample ( batchResource , endpoint , pathMetadata )
470+ if ( sample == null ) {
471+ continue
472+ }
473+
474+ // Get the seam_cli resource data (sample object) for this batch resource
475+ const jsonSample = Object . entries ( sample . resource ) . find (
476+ ( [ k ] ) => ( k as SdkName ) === 'seam_cli' ,
477+ ) ?. [ 1 ]
478+
479+ if ( jsonSample != null ) {
480+ // Parse the resource_data to get the actual object
481+ const resourceData = JSON . parse ( jsonSample . resource_data )
482+ // Wrap in array since batch responses contain arrays
483+ batchResourceSamples [ batchResourceType . batchKey ] = [ resourceData ]
484+ }
485+ }
486+
487+ return batchResourceSamples
351488}
0 commit comments