@@ -293,22 +293,29 @@ import * as t from 'io-ts';
293293import * as h from '@api-ts/io-ts-http';
294294
295295/**
296- * Route with multipart/form-data content type
296+ * Route with per-schema content types
297297 *
298- * @contentType multipart/form-data
299298 * @operationId api.v1.uploadDocument
300299 * @tag Document Upload
301300 */
302301export const uploadRoute = h.httpRoute({
303302 path: '/upload',
304303 method: 'POST',
305304 request: h.httpRequest({
305+ /**
306+ * File upload data
307+ * @contentType multipart/form-data
308+ */
306309 body: t.type({
307310 file: t.unknown,
308311 documentType: t.string,
309312 }),
310313 }),
311314 response: {
315+ /**
316+ * Upload success response
317+ * @contentType application/xml
318+ */
312319 201: t.type({
313320 id: t.string,
314321 success: t.boolean,
@@ -340,7 +347,7 @@ export const createUserRoute = h.httpRoute({
340347});
341348` ;
342349
343- testCase ( 'route with contentType tag uses multipart/form-data ' , CONTENT_TYPE_TEST , {
350+ testCase ( 'route with per-schema contentType tags ' , CONTENT_TYPE_TEST , {
344351 openapi : '3.0.3' ,
345352 info : {
346353 title : 'Test' ,
@@ -349,14 +356,15 @@ testCase('route with contentType tag uses multipart/form-data', CONTENT_TYPE_TES
349356 paths : {
350357 '/upload' : {
351358 post : {
352- summary : 'Route with multipart/form-data content type ' ,
359+ summary : 'Route with per-schema content types ' ,
353360 operationId : 'api.v1.uploadDocument' ,
354361 tags : [ 'Document Upload' ] ,
355362 parameters : [ ] ,
356363 requestBody : {
357364 content : {
358365 'multipart/form-data' : {
359366 schema : {
367+ description : 'File upload data' ,
360368 type : 'object' ,
361369 properties : {
362370 file : { } ,
@@ -371,8 +379,9 @@ testCase('route with contentType tag uses multipart/form-data', CONTENT_TYPE_TES
371379 201 : {
372380 description : 'Created' ,
373381 content : {
374- 'multipart/form-data ' : {
382+ 'application/xml ' : {
375383 schema : {
384+ description : 'Upload success response' ,
376385 type : 'object' ,
377386 properties : {
378387 id : { type : 'string' } ,
@@ -428,3 +437,200 @@ testCase('route with contentType tag uses multipart/form-data', CONTENT_TYPE_TES
428437 } ,
429438 components : { schemas : { } } ,
430439} ) ;
440+
441+ const PER_RESPONSE_CONTENT_TYPE_TEST = `
442+ import * as t from 'io-ts';
443+ import * as h from '@api-ts/io-ts-http';
444+
445+ /**
446+ * Upload document with different response content types per status code
447+ * @operationId api.v1.uploadDocumentAdvanced
448+ * @tag Document Upload
449+ */
450+ export const uploadAdvancedRoute = h.httpRoute({
451+ path: '/upload-advanced',
452+ method: 'POST',
453+ request: h.httpRequest({
454+ /**
455+ * Multipart form data for file upload
456+ * @contentType multipart/form-data
457+ */
458+ body: t.type({
459+ file: t.unknown,
460+ documentType: t.string,
461+ }),
462+ }),
463+ response: {
464+ /**
465+ * Success response with JSON data
466+ * @contentType application/json
467+ */
468+ 200: t.type({
469+ id: t.string,
470+ success: t.boolean,
471+ }),
472+
473+ /**
474+ * Plain text error message
475+ * @contentType text/plain
476+ */
477+ 400: t.string,
478+
479+ /**
480+ * File download response
481+ * @contentType application/octet-stream
482+ */
483+ 201: t.unknown,
484+ },
485+ });
486+
487+ /**
488+ * Standard route with default content types
489+ * @operationId api.v1.createUserStandard
490+ * @tag User Management
491+ */
492+ export const createUserStandardRoute = h.httpRoute({
493+ path: '/users-standard',
494+ method: 'POST',
495+ request: h.httpRequest({
496+ body: t.type({
497+ name: t.string,
498+ email: t.string,
499+ }),
500+ }),
501+ response: {
502+ 200: t.type({
503+ id: t.string,
504+ name: t.string,
505+ }),
506+ 400: t.type({
507+ error: t.string,
508+ }),
509+ },
510+ });
511+ ` ;
512+
513+ testCase ( 'routes with per-response content types' , PER_RESPONSE_CONTENT_TYPE_TEST , {
514+ openapi : '3.0.3' ,
515+ info : {
516+ title : 'Test' ,
517+ version : '1.0.0' ,
518+ } ,
519+ paths : {
520+ '/upload-advanced' : {
521+ post : {
522+ summary :
523+ 'Upload document with different response content types per status code' ,
524+ operationId : 'api.v1.uploadDocumentAdvanced' ,
525+ tags : [ 'Document Upload' ] ,
526+ parameters : [ ] ,
527+ requestBody : {
528+ content : {
529+ 'multipart/form-data' : {
530+ schema : {
531+ description : 'Multipart form data for file upload' ,
532+ type : 'object' ,
533+ properties : {
534+ file : { } ,
535+ documentType : { type : 'string' } ,
536+ } ,
537+ required : [ 'file' , 'documentType' ] ,
538+ } ,
539+ } ,
540+ } ,
541+ } ,
542+ responses : {
543+ 200 : {
544+ description : 'OK' ,
545+ content : {
546+ 'application/json' : {
547+ schema : {
548+ description : 'Success response with JSON data' ,
549+ type : 'object' ,
550+ properties : {
551+ id : { type : 'string' } ,
552+ success : { type : 'boolean' } ,
553+ } ,
554+ required : [ 'id' , 'success' ] ,
555+ } ,
556+ } ,
557+ } ,
558+ } ,
559+ 201 : {
560+ description : 'Created' ,
561+ content : {
562+ 'application/octet-stream' : {
563+ schema : { } ,
564+ } ,
565+ } ,
566+ } ,
567+ 400 : {
568+ description : 'Bad Request' ,
569+ content : {
570+ 'text/plain' : {
571+ schema : {
572+ description : 'Plain text error message' ,
573+ type : 'string' ,
574+ } ,
575+ } ,
576+ } ,
577+ } ,
578+ } ,
579+ } ,
580+ } ,
581+ '/users-standard' : {
582+ post : {
583+ summary : 'Standard route with default content types' ,
584+ operationId : 'api.v1.createUserStandard' ,
585+ tags : [ 'User Management' ] ,
586+ parameters : [ ] ,
587+ requestBody : {
588+ content : {
589+ 'application/json' : {
590+ schema : {
591+ type : 'object' ,
592+ properties : {
593+ name : { type : 'string' } ,
594+ email : { type : 'string' } ,
595+ } ,
596+ required : [ 'name' , 'email' ] ,
597+ } ,
598+ } ,
599+ } ,
600+ } ,
601+ responses : {
602+ 200 : {
603+ description : 'OK' ,
604+ content : {
605+ 'application/json' : {
606+ schema : {
607+ type : 'object' ,
608+ properties : {
609+ id : { type : 'string' } ,
610+ name : { type : 'string' } ,
611+ } ,
612+ required : [ 'id' , 'name' ] ,
613+ } ,
614+ } ,
615+ } ,
616+ } ,
617+ 400 : {
618+ description : 'Bad Request' ,
619+ content : {
620+ 'application/json' : {
621+ schema : {
622+ type : 'object' ,
623+ properties : {
624+ error : { type : 'string' } ,
625+ } ,
626+ required : [ 'error' ] ,
627+ } ,
628+ } ,
629+ } ,
630+ } ,
631+ } ,
632+ } ,
633+ } ,
634+ } ,
635+ components : { schemas : { } } ,
636+ } ) ;
0 commit comments