Skip to content
This repository has been archived by the owner on Jun 27, 2024. It is now read-only.

feat: c.req.param() schema validation #176

Merged
merged 1 commit into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,16 @@ export function handler<T>() {
pathname: Pathname,
// deno-lint-ignore no-unused-vars
...handler: (
| {
| ({
body?: ValidatedBody
cookies?: ValidatedCookies
headers?: ValidatedHeaders
query?: ValidatedQuery
/** @deprecated please pass this option to the `c.req.body()` method! */
transform?: boolean // TODO remove at v2.0
cors?: string
}
params?: Partial<Record<keyof ExtractParams<Pathname>, ZodType>>
})
| Handler<
Pathname,
ValidatedBody,
Expand Down Expand Up @@ -124,6 +125,7 @@ export function bodylessHandler<T>() {
headers?: ValidatedHeaders
query?: ValidatedQuery
cors?: string
params?: Partial<Record<keyof ExtractParams<Pathname>, ZodType>>
}
| BodylessHandler<
Pathname,
Expand All @@ -147,6 +149,7 @@ export type HandlerOrSchema =
/** @deprecated please pass this option to the `c.req.body()` method! */
transform?: boolean // TODO remove at v2.0
cors?: string
params?: Record<string, ZodType>
}
| Handler<unknown>
| BodylessHandler<unknown>
14 changes: 12 additions & 2 deletions request_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export class RequestContext<
cookies?: ObjectType | undefined
headers?: ObjectType | undefined
query?: ObjectType | undefined
params?: Record<string, ZodType>
[key: string]: unknown
} | null,
e: Context['exception'],
Expand Down Expand Up @@ -70,8 +71,17 @@ export class RequestContext<
* A method to retrieve the corresponding value of a parameter.
*/
param<T extends keyof Params>(name: T): Params[T] {
// @ts-ignore:
return this.#p[name]
if (this.#s?.params && this.#s.params[name as string]) {
const result = this.#s.params[name as string].safeParse(this.#p[name])

if (!result.success) {
throw this.#e('Bad Request')
}

return result.data as Params[T]
} else {
return this.#p[name as string] as Params[T]
}
}

/**
Expand Down
34 changes: 34 additions & 0 deletions test/validation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,4 +215,38 @@ Deno.test('Validation', async (t) => {
{ second: false, third: 69 },
)
})

await t.step('params', async () => {
const app = new cheetah()

app.get(
'/animals/:name',
{
params: {
name: z.union([z.literal('cat'), z.literal('dog')]),
},
},
(c) => {
return c.req.param('name')
},
)

const res1 = await app.fetch(
new Request('http://localhost/animals/cat'),
)

assertEquals(res1.status, 200)

const res2 = await app.fetch(
new Request('http://localhost/animals/dog'),
)

assertEquals(res2.status, 200)

const res3 = await app.fetch(
new Request('http://localhost/animals/rabbit'),
)

assertEquals(res3.status, 400)
})
})