Skip to content

Commit 8e25299

Browse files
authored
Merge pull request #235 from AthennaIO/develop
fix(openapi): remove auto coerce
2 parents 6868932 + 8ff0e99 commit 8e25299

2 files changed

Lines changed: 7 additions & 84 deletions

File tree

src/router/RouteSchema.ts

Lines changed: 2 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,11 @@ export async function parseRequestWithZod(
8888
}
8989

9090
if (requestSchemas.params) {
91-
req.params = await parseSchema(
92-
requestSchemas.params,
93-
coerceDataForValidation(requestSchemas.params, req.params)
94-
)
91+
req.params = await parseSchema(requestSchemas.params, req.params)
9592
}
9693

9794
if (requestSchemas.querystring) {
98-
req.query = await parseSchema(
99-
requestSchemas.querystring,
100-
coerceDataForValidation(requestSchemas.querystring, req.query)
101-
)
95+
req.query = await parseSchema(requestSchemas.querystring, req.query)
10296
}
10397
}
10498

@@ -160,77 +154,6 @@ function toJsonSchema(schema: ZodAny, io: 'input' | 'output') {
160154
return jsonSchema
161155
}
162156

163-
function coerceDataForValidation(schema: ZodAny, data: any) {
164-
return coerceDataByJsonSchema(toJsonSchema(schema, 'input'), data)
165-
}
166-
167-
function coerceDataByJsonSchema(schema: any, data: any): any {
168-
if (Is.Undefined(data) || Is.Null(data) || !schema) {
169-
return data
170-
}
171-
172-
if (schema.anyOf) {
173-
return coerceWithAlternatives(schema.anyOf, data)
174-
}
175-
176-
if (schema.oneOf) {
177-
return coerceWithAlternatives(schema.oneOf, data)
178-
}
179-
180-
if (schema.type === 'object' && Is.Object(data)) {
181-
const coerced = { ...data }
182-
const properties = schema.properties || {}
183-
184-
Object.entries(properties).forEach(([key, childSchema]) => {
185-
if (!Object.hasOwn(coerced, key)) {
186-
return
187-
}
188-
189-
coerced[key] = coerceDataByJsonSchema(childSchema, coerced[key])
190-
})
191-
192-
return coerced
193-
}
194-
195-
if (schema.type === 'array' && Is.Array(data) && schema.items) {
196-
return data.map(item => coerceDataByJsonSchema(schema.items, item))
197-
}
198-
199-
if (schema.type === 'number' || schema.type === 'integer') {
200-
return coerceNumber(data, schema.type === 'integer')
201-
}
202-
203-
return data
204-
}
205-
206-
function coerceWithAlternatives(schemas: any[], data: any) {
207-
let coerced = data
208-
209-
schemas.forEach(schema => {
210-
coerced = coerceDataByJsonSchema(schema, coerced)
211-
})
212-
213-
return coerced
214-
}
215-
216-
function coerceNumber(value: any, integerOnly: boolean) {
217-
if (!Is.String(value) || value.trim() === '') {
218-
return value
219-
}
220-
221-
const parsed = integerOnly ? Number.parseInt(value, 10) : Number(value)
222-
223-
if (Number.isNaN(parsed)) {
224-
return value
225-
}
226-
227-
if (integerOnly && !Number.isInteger(parsed)) {
228-
return value
229-
}
230-
231-
return parsed
232-
}
233-
234157
function isZodSchema(value: any): value is ZodAny {
235158
return (
236159
Is.Defined(value) &&

tests/unit/router/RouteTest.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,15 @@ export default class RouteTest {
144144
}
145145

146146
@Test()
147-
public async shouldAutomaticallyCoerceZodQuerystringAndParams({ assert }: Context) {
147+
public async shouldBeAbleToUseExplicitZodCoercionForQuerystringAndParams({ assert }: Context) {
148148
Route.get('users/:id', async ctx => {
149149
await ctx.response.send({
150150
id: ctx.request.param('id'),
151151
limit: ctx.request.query('limit')
152152
})
153153
}).schema({
154-
params: z.object({ id: z.number() }),
155-
querystring: z.object({ limit: z.number() }),
154+
params: z.object({ id: z.coerce.number() }),
155+
querystring: z.object({ limit: z.coerce.number() }),
156156
response: {
157157
200: z.object({
158158
id: z.number(),
@@ -178,8 +178,8 @@ export default class RouteTest {
178178
Config.set('openapi.paths', {
179179
'/users/{id}': {
180180
get: {
181-
params: z.object({ id: z.number() }),
182-
querystring: z.object({ limit: z.number() }),
181+
params: z.object({ id: z.coerce.number() }),
182+
querystring: z.object({ limit: z.coerce.number() }),
183183
response: {
184184
200: z.object({
185185
id: z.number(),

0 commit comments

Comments
 (0)