1717 ***********************************************************************/
1818
1919import type { Disposable } from '@podman-desktop/api' ;
20- import type { Request , Response } from 'express' ;
20+ import type { NextFunction , Request , Response } from 'express' ;
2121import express from 'express' ;
2222import type { Server } from 'http' ;
2323import path from 'node:path' ;
@@ -30,6 +30,8 @@ import type { components } from '../../src-generated/openapi';
3030import type { ModelInfo } from '@shared/src/models/IModelInfo' ;
3131import type { ConfigurationRegistry } from '../registries/ConfigurationRegistry' ;
3232import { getFreeRandomPort } from '../utils/ports' ;
33+ import * as OpenApiValidator from 'express-openapi-validator' ;
34+ import { HttpError , OpenApiRequest } from 'express-openapi-validator/dist/framework/types' ;
3335
3436const SHOW_API_INFO_COMMAND = 'ai-lab.show-api-info' ;
3537const SHOW_API_ERROR_COMMAND = 'ai-lab.show-api-error' ;
@@ -68,6 +70,29 @@ export class ApiServer implements Disposable {
6870 const router = express . Router ( ) ;
6971 router . use ( express . json ( ) ) ;
7072
73+ // validate requests / responses based on openapi spec
74+ router . use (
75+ OpenApiValidator . middleware ( {
76+ apiSpec : this . getSpecFile ( ) ,
77+ validateRequests : true ,
78+ validateResponses : {
79+ onError : ( error , body , req ) => {
80+ console . error ( `Response body fails validation: ` , error ) ;
81+ console . error ( `Emitted from:` , req . originalUrl ) ;
82+ console . error ( body ) ;
83+ } ,
84+ } ,
85+ } ) ,
86+ ) ;
87+
88+ router . use ( ( err : HttpError , _req : OpenApiRequest , res : Response , _next : NextFunction ) => {
89+ // format errors from validator
90+ res . status ( err . status || 500 ) . json ( {
91+ message : err . message ,
92+ errors : err . errors ,
93+ } ) ;
94+ } ) ;
95+
7196 // declare routes
7297 router . get ( '/version' , this . getVersion . bind ( this ) ) ;
7398 router . get ( '/tags' , this . getModels . bind ( this ) ) ;
0 commit comments