@@ -41,6 +41,10 @@ export type ConformanceApiPluginOptions = RegisterOptions & {
41
41
export const conformanceApiPlugin : FastifyPluginAsync < ConformanceApiPluginOptions > = async ( fastify , opts ) => {
42
42
const { api, caseInsenstiveQueryStringKeys, includeErrorDetails } = opts ;
43
43
44
+ for ( const jsonSchema of jsonSchemas ) {
45
+ fastify . addSchema ( jsonSchema ) ;
46
+ }
47
+
44
48
fastify . setErrorHandler ( ( error , req , res ) => {
45
49
req . log . error ( error ) ;
46
50
if ( includeErrorDetails ) {
@@ -76,6 +80,17 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
76
80
fastify . route ( {
77
81
url : '/' ,
78
82
method : 'GET' ,
83
+ schema : {
84
+ response : {
85
+ 200 : {
86
+ type : 'object' ,
87
+ properties : {
88
+ service : { type : 'string' } ,
89
+ version : { type : 'string' } ,
90
+ } ,
91
+ } ,
92
+ } ,
93
+ } ,
79
94
handler : async function ( req , res ) {
80
95
const request : IGetApiInfoRequest = { } ;
81
96
@@ -99,6 +114,16 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
99
114
fastify . route ( {
100
115
url : '/widgets' ,
101
116
method : 'GET' ,
117
+ schema : {
118
+ response : {
119
+ 200 : {
120
+ type : 'object' ,
121
+ properties : {
122
+ widgets : { type : 'array' , items : { $ref : 'Widget' } } ,
123
+ } ,
124
+ } ,
125
+ } ,
126
+ } ,
102
127
handler : async function ( req , res ) {
103
128
const request : IGetWidgetsRequest = { } ;
104
129
@@ -125,6 +150,11 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
125
150
fastify . route ( {
126
151
url : '/widgets' ,
127
152
method : 'POST' ,
153
+ schema : {
154
+ response : {
155
+ 201 : { $ref : 'Widget' } ,
156
+ } ,
157
+ } ,
128
158
handler : async function ( req , res ) {
129
159
const request : ICreateWidgetRequest = { } ;
130
160
@@ -155,6 +185,12 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
155
185
fastify . route ( {
156
186
url : '/widgets/:id' ,
157
187
method : 'GET' ,
188
+ schema : {
189
+ response : {
190
+ 200 : { $ref : 'Widget' } ,
191
+ 304 : { type : 'boolean' } ,
192
+ } ,
193
+ } ,
158
194
handler : async function ( req , res ) {
159
195
const request : IGetWidgetRequest = { } ;
160
196
@@ -193,6 +229,13 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
193
229
fastify . route ( {
194
230
url : '/widgets/:id' ,
195
231
method : 'DELETE' ,
232
+ schema : {
233
+ response : {
234
+ 204 : { type : 'object' , additionalProperties : false } ,
235
+ 404 : { type : 'boolean' } ,
236
+ 409 : { type : 'boolean' } ,
237
+ } ,
238
+ } ,
196
239
handler : async function ( req , res ) {
197
240
const request : IDeleteWidgetRequest = { } ;
198
241
@@ -232,6 +275,11 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
232
275
fastify . route ( {
233
276
url : '/widgets/get' ,
234
277
method : 'POST' ,
278
+ schema : {
279
+ response : {
280
+ 200 : { type : 'array' , items : { type : 'object' , properties : { value : { $ref : 'Widget' } , error : { $ref : '_error' } } } } ,
281
+ } ,
282
+ } ,
235
283
handler : async function ( req , res ) {
236
284
const request : IGetWidgetBatchRequest = { } ;
237
285
@@ -259,6 +307,17 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
259
307
fastify . route ( {
260
308
url : '/mirrorFields' ,
261
309
method : 'POST' ,
310
+ schema : {
311
+ response : {
312
+ 200 : {
313
+ type : 'object' ,
314
+ properties : {
315
+ field : { $ref : 'Any' } ,
316
+ matrix : { type : 'array' , items : { type : 'array' , items : { type : 'array' , items : { type : 'number' } } } } ,
317
+ } ,
318
+ } ,
319
+ } ,
320
+ } ,
262
321
handler : async function ( req , res ) {
263
322
const request : IMirrorFieldsRequest = { } ;
264
323
@@ -286,6 +345,11 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
286
345
fastify . route ( {
287
346
url : '/checkQuery' ,
288
347
method : 'GET' ,
348
+ schema : {
349
+ response : {
350
+ 200 : { type : 'object' , additionalProperties : false } ,
351
+ } ,
352
+ } ,
289
353
handler : async function ( req , res ) {
290
354
const request : ICheckQueryRequest = { } ;
291
355
@@ -319,6 +383,11 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
319
383
fastify . route ( {
320
384
url : '/checkPath/:string/:boolean/:double/:int32/:int64/:decimal/:enum/:datetime' ,
321
385
method : 'GET' ,
386
+ schema : {
387
+ response : {
388
+ 200 : { type : 'object' , additionalProperties : false } ,
389
+ } ,
390
+ } ,
322
391
handler : async function ( req , res ) {
323
392
const request : ICheckPathRequest = { } ;
324
393
@@ -352,6 +421,11 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
352
421
fastify . route ( {
353
422
url : '/mirrorHeaders' ,
354
423
method : 'GET' ,
424
+ schema : {
425
+ response : {
426
+ 200 : { type : 'object' , additionalProperties : false } ,
427
+ } ,
428
+ } ,
355
429
handler : async function ( req , res ) {
356
430
const request : IMirrorHeadersRequest = { } ;
357
431
@@ -394,6 +468,18 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
394
468
fastify . route ( {
395
469
url : '/mixed/:path' ,
396
470
method : 'POST' ,
471
+ schema : {
472
+ response : {
473
+ 200 : {
474
+ type : 'object' ,
475
+ properties : {
476
+ normal : { type : 'string' } ,
477
+ } ,
478
+ } ,
479
+ 202 : { type : 'object' , additionalProperties : true } ,
480
+ 204 : { type : 'boolean' } ,
481
+ } ,
482
+ } ,
397
483
handler : async function ( req , res ) {
398
484
const request : IMixedRequest = { } ;
399
485
@@ -441,6 +527,16 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
441
527
fastify . route ( {
442
528
url : '/required' ,
443
529
method : 'POST' ,
530
+ schema : {
531
+ response : {
532
+ 200 : {
533
+ type : 'object' ,
534
+ properties : {
535
+ normal : { type : 'string' } ,
536
+ } ,
537
+ } ,
538
+ } ,
539
+ } ,
444
540
handler : async function ( req , res ) {
445
541
const request : IRequiredRequest = { } ;
446
542
@@ -478,6 +574,11 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
478
574
fastify . route ( {
479
575
url : '/mirrorBytes' ,
480
576
method : 'POST' ,
577
+ schema : {
578
+ response : {
579
+ 200 : { type : 'string' } ,
580
+ } ,
581
+ } ,
481
582
handler : async function ( req , res ) {
482
583
const request : IMirrorBytesRequest = { } ;
483
584
@@ -510,6 +611,11 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
510
611
fastify . route ( {
511
612
url : '/mirrorText' ,
512
613
method : 'POST' ,
614
+ schema : {
615
+ response : {
616
+ 200 : { type : 'string' } ,
617
+ } ,
618
+ } ,
513
619
handler : async function ( req , res ) {
514
620
const request : IMirrorTextRequest = { } ;
515
621
@@ -542,6 +648,11 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
542
648
fastify . route ( {
543
649
url : '/bodyTypes' ,
544
650
method : 'POST' ,
651
+ schema : {
652
+ response : {
653
+ 200 : { type : 'string' } ,
654
+ } ,
655
+ } ,
545
656
handler : async function ( req , res ) {
546
657
const request : IBodyTypesRequest = { } ;
547
658
@@ -567,6 +678,148 @@ export const conformanceApiPlugin: FastifyPluginAsync<ConformanceApiPluginOption
567
678
} ) ;
568
679
}
569
680
681
+ const jsonSchemas = [
682
+ {
683
+ $id : '_error' ,
684
+ type : 'object' ,
685
+ properties : {
686
+ code : { type : 'string' } ,
687
+ message : { type : 'string' } ,
688
+ details : { type : 'object' , additionalProperties : true } ,
689
+ innerError : { $ref : '_error' } ,
690
+ }
691
+ } as const ,
692
+ {
693
+ $id : 'Widget' ,
694
+ type : 'object' ,
695
+ properties : {
696
+ id : { type : 'integer' } ,
697
+ name : { type : 'string' } ,
698
+ }
699
+ } as const ,
700
+ {
701
+ $id : 'Any' ,
702
+ type : 'object' ,
703
+ properties : {
704
+ string : { type : 'string' } ,
705
+ boolean : { type : 'boolean' } ,
706
+ double : { type : 'number' } ,
707
+ int32 : { type : 'integer' } ,
708
+ int64 : { type : 'integer' } ,
709
+ decimal : { type : 'number' } ,
710
+ datetime : { type : 'string' } ,
711
+ bytes : { type : 'string' } ,
712
+ object : { type : 'object' , additionalProperties : true } ,
713
+ error : { $ref : '_error' } ,
714
+ data : { $ref : 'Any' } ,
715
+ enum : { $ref : 'Answer' } ,
716
+ array : { $ref : 'AnyArray' } ,
717
+ map : { $ref : 'AnyMap' } ,
718
+ result : { $ref : 'AnyResult' } ,
719
+ nullable : { $ref : 'AnyNullable' } ,
720
+ }
721
+ } as const ,
722
+ {
723
+ $id : 'AnyArray' ,
724
+ type : 'object' ,
725
+ properties : {
726
+ string : { type : 'array' , items : { type : 'string' } } ,
727
+ boolean : { type : 'array' , items : { type : 'boolean' } } ,
728
+ double : { type : 'array' , items : { type : 'number' } } ,
729
+ int32 : { type : 'array' , items : { type : 'integer' } } ,
730
+ int64 : { type : 'array' , items : { type : 'integer' } } ,
731
+ decimal : { type : 'array' , items : { type : 'number' } } ,
732
+ datetime : { type : 'array' , items : { type : 'string' } } ,
733
+ bytes : { type : 'array' , items : { type : 'string' } } ,
734
+ object : { type : 'array' , items : { type : 'object' , additionalProperties : true } } ,
735
+ error : { type : 'array' , items : { $ref : '_error' } } ,
736
+ data : { type : 'array' , items : { $ref : 'Any' } } ,
737
+ enum : { type : 'array' , items : { $ref : 'Answer' } } ,
738
+ array : { type : 'array' , items : { type : 'array' , items : { type : 'integer' } } } ,
739
+ map : { type : 'array' , items : { type : 'object' , additionalProperties : { type : 'integer' } } } ,
740
+ result : { type : 'array' , items : { type : 'object' , properties : { value : { type : 'integer' } , error : { $ref : '_error' } } } } ,
741
+ nullable : { type : 'array' , items : { oneOf : [ { type : 'integer' } , { type : 'null' } ] } } ,
742
+ }
743
+ } as const ,
744
+ {
745
+ $id : 'AnyMap' ,
746
+ type : 'object' ,
747
+ properties : {
748
+ string : { type : 'object' , additionalProperties : { type : 'string' } } ,
749
+ boolean : { type : 'object' , additionalProperties : { type : 'boolean' } } ,
750
+ double : { type : 'object' , additionalProperties : { type : 'number' } } ,
751
+ int32 : { type : 'object' , additionalProperties : { type : 'integer' } } ,
752
+ int64 : { type : 'object' , additionalProperties : { type : 'integer' } } ,
753
+ decimal : { type : 'object' , additionalProperties : { type : 'number' } } ,
754
+ datetime : { type : 'object' , additionalProperties : { type : 'string' } } ,
755
+ bytes : { type : 'object' , additionalProperties : { type : 'string' } } ,
756
+ object : { type : 'object' , additionalProperties : { type : 'object' , additionalProperties : true } } ,
757
+ error : { type : 'object' , additionalProperties : { $ref : '_error' } } ,
758
+ data : { type : 'object' , additionalProperties : { $ref : 'Any' } } ,
759
+ enum : { type : 'object' , additionalProperties : { $ref : 'Answer' } } ,
760
+ array : { type : 'object' , additionalProperties : { type : 'array' , items : { type : 'integer' } } } ,
761
+ map : { type : 'object' , additionalProperties : { type : 'object' , additionalProperties : { type : 'integer' } } } ,
762
+ result : { type : 'object' , additionalProperties : { type : 'object' , properties : { value : { type : 'integer' } , error : { $ref : '_error' } } } } ,
763
+ nullable : { type : 'object' , additionalProperties : { oneOf : [ { type : 'integer' } , { type : 'null' } ] } } ,
764
+ }
765
+ } as const ,
766
+ {
767
+ $id : 'AnyResult' ,
768
+ type : 'object' ,
769
+ properties : {
770
+ string : { type : 'object' , properties : { value : { type : 'string' } , error : { $ref : '_error' } } } ,
771
+ boolean : { type : 'object' , properties : { value : { type : 'boolean' } , error : { $ref : '_error' } } } ,
772
+ double : { type : 'object' , properties : { value : { type : 'number' } , error : { $ref : '_error' } } } ,
773
+ int32 : { type : 'object' , properties : { value : { type : 'integer' } , error : { $ref : '_error' } } } ,
774
+ int64 : { type : 'object' , properties : { value : { type : 'integer' } , error : { $ref : '_error' } } } ,
775
+ decimal : { type : 'object' , properties : { value : { type : 'number' } , error : { $ref : '_error' } } } ,
776
+ datetime : { type : 'object' , properties : { value : { type : 'string' } , error : { $ref : '_error' } } } ,
777
+ bytes : { type : 'object' , properties : { value : { type : 'string' } , error : { $ref : '_error' } } } ,
778
+ object : { type : 'object' , properties : { value : { type : 'object' , additionalProperties : true } , error : { $ref : '_error' } } } ,
779
+ error : { type : 'object' , properties : { value : { $ref : '_error' } , error : { $ref : '_error' } } } ,
780
+ data : { type : 'object' , properties : { value : { $ref : 'Any' } , error : { $ref : '_error' } } } ,
781
+ enum : { type : 'object' , properties : { value : { $ref : 'Answer' } , error : { $ref : '_error' } } } ,
782
+ array : { type : 'object' , properties : { value : { type : 'array' , items : { type : 'integer' } } , error : { $ref : '_error' } } } ,
783
+ map : { type : 'object' , properties : { value : { type : 'object' , additionalProperties : { type : 'integer' } } , error : { $ref : '_error' } } } ,
784
+ result : { type : 'object' , properties : { value : { type : 'object' , properties : { value : { type : 'integer' } , error : { $ref : '_error' } } } , error : { $ref : '_error' } } } ,
785
+ nullable : { type : 'object' , properties : { value : { oneOf : [ { type : 'integer' } , { type : 'null' } ] } , error : { $ref : '_error' } } } ,
786
+ }
787
+ } as const ,
788
+ {
789
+ $id : 'AnyNullable' ,
790
+ type : 'object' ,
791
+ properties : {
792
+ string : { oneOf : [ { type : 'string' } , { type : 'null' } ] } ,
793
+ boolean : { oneOf : [ { type : 'boolean' } , { type : 'null' } ] } ,
794
+ double : { oneOf : [ { type : 'number' } , { type : 'null' } ] } ,
795
+ int32 : { oneOf : [ { type : 'integer' } , { type : 'null' } ] } ,
796
+ int64 : { oneOf : [ { type : 'integer' } , { type : 'null' } ] } ,
797
+ decimal : { oneOf : [ { type : 'number' } , { type : 'null' } ] } ,
798
+ datetime : { oneOf : [ { type : 'string' } , { type : 'null' } ] } ,
799
+ bytes : { oneOf : [ { type : 'string' } , { type : 'null' } ] } ,
800
+ object : { oneOf : [ { type : 'object' , additionalProperties : true } , { type : 'null' } ] } ,
801
+ error : { oneOf : [ { $ref : '_error' } , { type : 'null' } ] } ,
802
+ data : { oneOf : [ { $ref : 'Any' } , { type : 'null' } ] } ,
803
+ enum : { oneOf : [ { $ref : 'Answer' } , { type : 'null' } ] } ,
804
+ array : { oneOf : [ { type : 'array' , items : { type : 'integer' } } , { type : 'null' } ] } ,
805
+ map : { oneOf : [ { type : 'object' , additionalProperties : { type : 'integer' } } , { type : 'null' } ] } ,
806
+ result : { oneOf : [ { type : 'object' , properties : { value : { type : 'integer' } , error : { $ref : '_error' } } } , { type : 'null' } ] } ,
807
+ }
808
+ } as const ,
809
+ {
810
+ $id : 'HasWidget' ,
811
+ type : 'object' ,
812
+ properties : {
813
+ widget : { $ref : 'Widget' } ,
814
+ }
815
+ } as const ,
816
+ {
817
+ $id : 'Answer' ,
818
+ type : 'string' ,
819
+ enum : [ 'yes' , 'no' , 'maybe' ] ,
820
+ } as const ,
821
+ ] as const ;
822
+
570
823
/** API for a Facility test server. */
571
824
export interface IConformanceApi {
572
825
/** Gets API information. */
0 commit comments