11import { TEnforceFeatureConstraint , TFeatureDefinition } from '@blgc/types/features' ;
22import { type TOperationPathParams , type TOperationQueryParams } from '@blgc/types/openapi' ;
33import type * as express from 'express' ;
4- import { type ParamsDictionary } from 'express-serve-static-core' ;
54import { createValidationContext , type TValidationError } from 'validation-adapter' ;
6- import { ValidationError } from '../../exceptions' ;
7- import { formatPath , parseParams } from '../../helper' ;
5+ import { formatPath , parseParams , ValidationError } from '../../lib' ;
86import {
97 TOpenApiExpressFeature ,
8+ TOpenApiExpressParsedData ,
9+ TParams ,
1010 type TOpenApiExpressParamsParserOptions ,
11+ type TOpenApiExpressRequest ,
1112 type TOpenApiExpressValidators ,
12- type TOpenApiRouter ,
13- type TParams
13+ type TOpenApiRouter
1414} from '../../types' ;
1515
1616export function withExpress < GPaths extends object , GFeatures extends TFeatureDefinition [ ] > (
@@ -77,7 +77,7 @@ export function withExpress<GPaths extends object, GFeatures extends TFeatureDef
7777 > ;
7878}
7979
80- function parseParamsMiddleware (
80+ function parseParamsMiddleware < GPathOperation > (
8181 paramsParser : TOpenApiExpressParamsParserOptions = { }
8282) : express . RequestHandler {
8383 const {
@@ -88,23 +88,19 @@ function parseParamsMiddleware(
8888 parseQueryParamsBlacklist
8989 } = paramsParser ;
9090
91- if ( shouldParseParams ) {
92- return ( req , _res , next ) => {
93- // Extend Express query params & path params parsing to handle numbers and booleans
94- // as primitive type instead of string.
95- // See: https://expressjs.com/en/5x/api.html#req.query
96- // https://github.com/ljharb/qs/issues/91
97- req . query = parseQueryParams ( req . query as TParams , parseQueryParamsBlacklist ) as TParams ;
98- req . params = parsePathParams (
99- req . params as TParams ,
100- parsePathParamsBlacklist
101- ) as ParamsDictionary ;
102-
103- next ( ) ;
104- } ;
105- }
106-
107- return ( _req , _res , next ) => {
91+ return ( req , _res , next ) => {
92+ if ( shouldParseParams ) {
93+ ( req as TOpenApiExpressRequest < GPathOperation > ) . valid = {
94+ query : parseQueryParams (
95+ req . query as TParams ,
96+ parseQueryParamsBlacklist
97+ ) as TOperationQueryParams < GPathOperation > ,
98+ params : parsePathParams (
99+ req . params as TParams ,
100+ parsePathParamsBlacklist
101+ ) as TOperationPathParams < GPathOperation >
102+ } as TOpenApiExpressParsedData < GPathOperation > ;
103+ }
108104 next ( ) ;
109105 } ;
110106}
@@ -128,8 +124,10 @@ function validationMiddleware<GPathOperation>(
128124 }
129125
130126 if ( pathValidator != null ) {
127+ const pathParams =
128+ ( req as TOpenApiExpressRequest < GPathOperation > ) . valid ?. params ?? req . params ;
131129 const pathValidationContext = createValidationContext < TOperationPathParams < GPathOperation > > (
132- req . params as TOperationPathParams < GPathOperation >
130+ pathParams as TOperationPathParams < GPathOperation >
133131 ) ;
134132 await pathValidator . validate ( pathValidationContext ) ;
135133 for ( const error of pathValidationContext . errors ) {
@@ -139,9 +137,11 @@ function validationMiddleware<GPathOperation>(
139137 }
140138
141139 if ( queryValidator != null ) {
140+ const queryParams =
141+ ( req as TOpenApiExpressRequest < GPathOperation > ) . valid ?. query ?? req . query ;
142142 const queryValidationContext = createValidationContext <
143143 TOperationQueryParams < GPathOperation >
144- > ( req . query as TOperationQueryParams < GPathOperation > ) ;
144+ > ( queryParams as TOperationQueryParams < GPathOperation > ) ;
145145 await queryValidator . validate ( queryValidationContext ) ;
146146 for ( const error of queryValidationContext . errors ) {
147147 error [ 'source' ] = 'query' ;
0 commit comments