Skip to content

Commit 4ee5d26

Browse files
authored
Merge pull request #114 from builder-group/113-incompatible-with-express-5
Resolve #113
2 parents 55c390f + 2f239ff commit 4ee5d26

File tree

20 files changed

+794
-648
lines changed

20 files changed

+794
-648
lines changed

examples/openapi-ts-router/express/petstore/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"devDependencies": {
2222
"@blgc/config": "workspace:*",
2323
"@types/express": "^5.0.3",
24-
"@types/node": "^22.15.30",
24+
"@types/node": "^24.1.0",
2525
"nodemon": "^3.1.10",
2626
"openapi-typescript": "^7.8.0",
2727
"ts-node": "^10.9.2",

examples/openapi-ts-router/express/petstore/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const port = 3000;
77

88
app.use(express.json());
99

10-
app.get('/*', router);
10+
app.use(router);
1111

1212
app.use(invalidPathMiddleware);
1313
app.use(errorMiddleware);

examples/openapi-ts-router/express/petstore/src/router.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ openApiRouter.get('/pet/{petId}', {
2121
}
2222
],
2323
handler: (req, res) => {
24-
const { petId } = req.params;
25-
console.log('handler');
24+
const { petId } = req.valid.params;
25+
console.log('handler', petId, typeof petId);
2626

2727
res.send({
2828
name: 'Falko',

examples/openapi-ts-router/hono/petstore/src/router.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ openApiRouter.get('/pet/{petId}', {
2222
],
2323
handler: (c) => {
2424
const { petId } = c.req.valid('param');
25-
console.log('handler');
25+
console.log('handler', petId, typeof petId);
2626

2727
return c.json({
2828
name: 'Falko',

packages/feature-state/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "feature-state",
3-
"version": "0.0.56",
3+
"version": "0.0.57",
44
"private": false,
55
"description": "Straightforward, typesafe, and feature-based state management library for ReactJs",
66
"keywords": [],

packages/openapi-ts-router/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ openApiRouter.get('/pet/{petId}', {
6363
})
6464
),
6565
handler: (req, res) => {
66-
const { petId } = req.params; // Access validated params
66+
const { petId } = req.valid.params; // Access parsed & validated params
6767
res.send({ name: 'Falko', photoUrls: [] });
6868
}
6969
});

packages/openapi-ts-router/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "openapi-ts-router",
3-
"version": "0.2.14",
3+
"version": "0.3.2",
44
"private": false,
55
"description": "Thin wrapper around the router of web frameworks like Express and Hono, offering OpenAPI typesafety and seamless integration with validation libraries such as Valibot and Zod",
66
"keywords": [],

packages/openapi-ts-router/src/features/with-express/with-express.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { TEnforceFeatureConstraint, TFeatureDefinition } from '@blgc/types/features';
22
import { type TOperationPathParams, type TOperationQueryParams } from '@blgc/types/openapi';
33
import type * as express from 'express';
4-
import { type ParamsDictionary } from 'express-serve-static-core';
54
import { createValidationContext, type TValidationError } from 'validation-adapter';
6-
import { ValidationError } from '../../exceptions';
7-
import { formatPath, parseParams } from '../../helper';
5+
import { formatPath, parseParams, ValidationError } from '../../lib';
86
import {
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

1616
export 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';

packages/openapi-ts-router/src/features/with-hono/with-hono.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import { type TOperationPathParams, type TOperationQueryParams } from '@blgc/typ
33
import { type Hono } from 'hono';
44
import type * as hono from 'hono/types';
55
import { createValidationContext, type TValidationError } from 'validation-adapter';
6-
import { ValidationError } from '../../exceptions';
7-
import { formatPath, parseParams } from '../../helper';
6+
import { formatPath, parseParams, ValidationError } from '../../lib';
87
import {
98
TOpenApiHonoFeature,
109
type TOpenApiHonoParamsParserOptions,
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export * from './create-openapi-router';
2-
export * from './exceptions';
32
export * from './features';
3+
export * from './lib';
44
export * from './types';

0 commit comments

Comments
 (0)