Skip to content

Commit

Permalink
fix(context): fix queries and headers types
Browse files Browse the repository at this point in the history
  • Loading branch information
termosa committed Feb 19, 2024
1 parent f87373e commit 4762a80
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 23 deletions.
6 changes: 3 additions & 3 deletions deno_dist/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export class HonoRequest<P extends string = '/', I extends Input['out'] = {}> {
* @see https://hono.dev/api/request#query
*/
query(key: string): string | undefined
query(): Record<string, string>
query(): Record<string, string | undefined>
query(key?: string) {
return getQueryParam(this.url, key)
}
Expand All @@ -143,7 +143,7 @@ export class HonoRequest<P extends string = '/', I extends Input['out'] = {}> {
* @see https://hono.dev/api/request#queries
*/
queries(key: string): string[] | undefined
queries(): Record<string, string[]>
queries(): Record<string, string[] | undefined>
queries(key?: string) {
return getQueryParams(this.url, key)
}
Expand All @@ -159,7 +159,7 @@ export class HonoRequest<P extends string = '/', I extends Input['out'] = {}> {
* @see https://hono.dev/api/request#header
*/
header(name: string): string | undefined
header(): Record<string, string>
header(): Record<string, string | undefined>
header(name?: string) {
if (name) {
return this.raw.headers.get(name.toLowerCase()) ?? undefined
Expand Down
18 changes: 13 additions & 5 deletions deno_dist/utils/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,12 @@ const _getQueryParam = (
url: string,
key?: string,
multiple?: boolean
): string | undefined | Record<string, string> | string[] | Record<string, string[]> => {
):
| string
| undefined
| Record<string, string | undefined>
| string[]
| Record<string, string[] | undefined> => {
let encoded

if (!multiple && key && !/[%+]/.test(key)) {
Expand Down Expand Up @@ -250,16 +255,19 @@ const _getQueryParam = (
export const getQueryParam: (
url: string,
key?: string
) => string | undefined | Record<string, string> = _getQueryParam as (
) => string | undefined | Record<string, string | undefined> = _getQueryParam as (
url: string,
key?: string
) => string | undefined | Record<string, string>
) => string | undefined | Record<string, string | undefined>

export const getQueryParams = (
url: string,
key?: string
): string[] | undefined | Record<string, string[]> => {
return _getQueryParam(url, key, true) as string[] | undefined | Record<string, string[]>
): string[] | undefined | Record<string, string[] | undefined> => {
return _getQueryParam(url, key, true) as
| string[]
| undefined
| Record<string, string[] | undefined>
}

// `decodeURIComponent` is a long name.
Expand Down
10 changes: 7 additions & 3 deletions deno_dist/validator/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,13 @@ export const validator = <
}
case 'query':
value = Object.fromEntries(
Object.entries(c.req.queries()).map(([k, v]) => {
return v.length === 1 ? [k, v[0]] : [k, v]
})
Object.entries(c.req.queries())
.filter((query): query is [string, string[]] => {
return typeof query[1] !== 'undefined'
})
.map(([k, v]) => {
return v.length === 1 ? [k, v[0]] : [k, v]
})
)
break
case 'param':
Expand Down
24 changes: 23 additions & 1 deletion src/hono.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,11 @@ describe('param and query', () => {
return c.text(`q is ${queries[0]} and ${queries[1]}, limit is ${limit[0]}`)
})

app.get('/optional-values', (c) => {
const { q } = c.req.queries()
return c.text(`q is ${typeof q === 'undefined' ? 'not ' : ''}present`)
})

app.get('/add-header', (c) => {
const bar = c.req.header('X-Foo')
return c.text(`foo is ${bar}`)
Expand Down Expand Up @@ -788,7 +793,12 @@ describe('param and query', () => {

app.get('/multiple-values', (c) => {
const { q, limit } = c.req.queries()
return c.text(`q is ${q[0]} and ${q[1]}, limit is ${limit[0]}`)
return c.text(`q is ${q?.[0]} and ${q?.[1]}, limit is ${limit?.[0]}`)
})

app.get('/optional-values', (c) => {
const { q } = c.req.queries()
return c.text(`q is ${typeof q === 'undefined' ? 'not ' : ''}present`)
})

app.get('/add-header', (c) => {
Expand Down Expand Up @@ -844,6 +854,18 @@ describe('param and query', () => {
expect(await res.text()).toBe('q is foo and bar, limit is 10')
})

it('query of /optional-values?q=foo is found', async () => {
const res = await app.request('http://localhost/optional-values?q=foo')
expect(res.status).toBe(200)
expect(await res.text()).toBe('q is present')
})

it('query of /optional-values is not found', async () => {
const res = await app.request('http://localhost/optional-values')
expect(res.status).toBe(200)
expect(await res.text()).toBe('q is not present')
})

it('/add-header header - X-Foo is Bar', async () => {
const req = new Request('http://localhost/add-header')
req.headers.append('X-Foo', 'Bar')
Expand Down
6 changes: 3 additions & 3 deletions src/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export class HonoRequest<P extends string = '/', I extends Input['out'] = {}> {
* @see https://hono.dev/api/request#query
*/
query(key: string): string | undefined
query(): Record<string, string>
query(): Record<string, string | undefined>
query(key?: string) {
return getQueryParam(this.url, key)
}
Expand All @@ -143,7 +143,7 @@ export class HonoRequest<P extends string = '/', I extends Input['out'] = {}> {
* @see https://hono.dev/api/request#queries
*/
queries(key: string): string[] | undefined
queries(): Record<string, string[]>
queries(): Record<string, string[] | undefined>
queries(key?: string) {
return getQueryParams(this.url, key)
}
Expand All @@ -159,7 +159,7 @@ export class HonoRequest<P extends string = '/', I extends Input['out'] = {}> {
* @see https://hono.dev/api/request#header
*/
header(name: string): string | undefined
header(): Record<string, string>
header(): Record<string, string | undefined>
header(name?: string) {
if (name) {
return this.raw.headers.get(name.toLowerCase()) ?? undefined
Expand Down
18 changes: 13 additions & 5 deletions src/utils/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,12 @@ const _getQueryParam = (
url: string,
key?: string,
multiple?: boolean
): string | undefined | Record<string, string> | string[] | Record<string, string[]> => {
):
| string
| undefined
| Record<string, string | undefined>
| string[]
| Record<string, string[] | undefined> => {
let encoded

if (!multiple && key && !/[%+]/.test(key)) {
Expand Down Expand Up @@ -250,16 +255,19 @@ const _getQueryParam = (
export const getQueryParam: (
url: string,
key?: string
) => string | undefined | Record<string, string> = _getQueryParam as (
) => string | undefined | Record<string, string | undefined> = _getQueryParam as (
url: string,
key?: string
) => string | undefined | Record<string, string>
) => string | undefined | Record<string, string | undefined>

export const getQueryParams = (
url: string,
key?: string
): string[] | undefined | Record<string, string[]> => {
return _getQueryParam(url, key, true) as string[] | undefined | Record<string, string[]>
): string[] | undefined | Record<string, string[] | undefined> => {
return _getQueryParam(url, key, true) as
| string[]
| undefined
| Record<string, string[] | undefined>
}

// `decodeURIComponent` is a long name.
Expand Down
10 changes: 7 additions & 3 deletions src/validator/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,13 @@ export const validator = <
}
case 'query':
value = Object.fromEntries(
Object.entries(c.req.queries()).map(([k, v]) => {
return v.length === 1 ? [k, v[0]] : [k, v]
})
Object.entries(c.req.queries())
.filter((query): query is [string, string[]] => {
return typeof query[1] !== 'undefined'
})
.map(([k, v]) => {
return v.length === 1 ? [k, v[0]] : [k, v]
})
)
break
case 'param':
Expand Down

0 comments on commit 4762a80

Please sign in to comment.