mirror of
https://github.com/honojs/hono.git
synced 2024-11-24 19:26:56 +01:00
fix(client): return query params in $url (#3541)
This commit is contained in:
parent
267186d65e
commit
3d8abbc239
@ -847,6 +847,27 @@ describe('$url() with a param option', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('$url() with a query option', () => {
|
||||
const app = new Hono().get(
|
||||
'/posts',
|
||||
validator('query', () => {
|
||||
return {} as { filter: 'test' }
|
||||
}),
|
||||
(c) => c.json({ ok: true })
|
||||
)
|
||||
type AppType = typeof app
|
||||
const client = hc<AppType>('http://localhost')
|
||||
|
||||
it('Should return the correct path - /posts?filter=test', async () => {
|
||||
const url = client.posts.$url({
|
||||
query: {
|
||||
filter: 'test',
|
||||
},
|
||||
})
|
||||
expect(url.search).toBe('?filter=test')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Client can be awaited', () => {
|
||||
it('Can be awaited without side effects', async () => {
|
||||
const client = hc('http://localhost')
|
||||
|
@ -4,6 +4,7 @@ import { serialize } from '../utils/cookie'
|
||||
import type { UnionToIntersection } from '../utils/types'
|
||||
import type { Callback, Client, ClientRequestOptions } from './types'
|
||||
import {
|
||||
buildSearchParams,
|
||||
deepMerge,
|
||||
mergePath,
|
||||
removeIndexString,
|
||||
@ -49,20 +50,7 @@ class ClientRequestImpl {
|
||||
) => {
|
||||
if (args) {
|
||||
if (args.query) {
|
||||
for (const [k, v] of Object.entries(args.query)) {
|
||||
if (v === undefined) {
|
||||
continue
|
||||
}
|
||||
|
||||
this.queryParams ||= new URLSearchParams()
|
||||
if (Array.isArray(v)) {
|
||||
for (const v2 of v) {
|
||||
this.queryParams.append(k, v2)
|
||||
}
|
||||
} else {
|
||||
this.queryParams.set(k, v)
|
||||
}
|
||||
}
|
||||
this.queryParams = buildSearchParams(args.query)
|
||||
}
|
||||
|
||||
if (args.form) {
|
||||
@ -172,10 +160,16 @@ export const hc = <T extends Hono<any, any, any>>(
|
||||
const path = parts.join('/')
|
||||
const url = mergePath(baseUrl, path)
|
||||
if (method === 'url') {
|
||||
if (opts.args[0] && opts.args[0].param) {
|
||||
return new URL(replaceUrlParam(url, opts.args[0].param))
|
||||
let result = url
|
||||
if (opts.args[0]) {
|
||||
if (opts.args[0].param) {
|
||||
result = replaceUrlParam(url, opts.args[0].param)
|
||||
}
|
||||
return new URL(url)
|
||||
if (opts.args[0].query) {
|
||||
result = result + '?' + buildSearchParams(opts.args[0].query).toString()
|
||||
}
|
||||
}
|
||||
return new URL(result)
|
||||
}
|
||||
if (method === 'ws') {
|
||||
const webSocketUrl = replaceUrlProtocol(
|
||||
|
@ -38,7 +38,11 @@ export type ClientRequest<S extends Schema> = {
|
||||
$url: (
|
||||
arg?: S[keyof S] extends { input: infer R }
|
||||
? R extends { param: infer P }
|
||||
? { param: P }
|
||||
? R extends { query: infer Q }
|
||||
? { param: P; query: Q }
|
||||
: { param: P }
|
||||
: R extends { query: infer Q }
|
||||
? { query: Q }
|
||||
: {}
|
||||
: {}
|
||||
) => URL
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {
|
||||
buildSearchParams,
|
||||
deepMerge,
|
||||
mergePath,
|
||||
removeIndexString,
|
||||
@ -59,6 +60,18 @@ describe('replaceUrlParams', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('buildSearchParams', () => {
|
||||
it('Should build URLSearchParams correctly', () => {
|
||||
const query = {
|
||||
id: '123',
|
||||
type: 'test',
|
||||
tag: ['a', 'b'],
|
||||
}
|
||||
const searchParams = buildSearchParams(query)
|
||||
expect(searchParams.toString()).toBe('id=123&type=test&tag=a&tag=b')
|
||||
})
|
||||
})
|
||||
|
||||
describe('replaceUrlProtocol', () => {
|
||||
it('Should replace http to ws', () => {
|
||||
const url = 'http://localhost'
|
||||
|
@ -15,6 +15,26 @@ export const replaceUrlParam = (urlString: string, params: Record<string, string
|
||||
return urlString
|
||||
}
|
||||
|
||||
export const buildSearchParams = (query: Record<string, string | string[]>) => {
|
||||
const searchParams = new URLSearchParams()
|
||||
|
||||
for (const [k, v] of Object.entries(query)) {
|
||||
if (v === undefined) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (Array.isArray(v)) {
|
||||
for (const v2 of v) {
|
||||
searchParams.append(k, v2)
|
||||
}
|
||||
} else {
|
||||
searchParams.set(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
return searchParams
|
||||
}
|
||||
|
||||
export const replaceUrlProtocol = (urlString: string, protocol: 'ws' | 'http') => {
|
||||
switch (protocol) {
|
||||
case 'ws':
|
||||
|
Loading…
Reference in New Issue
Block a user