mirror of
https://github.com/honojs/hono.git
synced 2024-11-22 11:17:33 +01:00
feat(hc): add init
option (#2592)
This commit is contained in:
parent
11a20a7db3
commit
fb07fb4012
@ -123,6 +123,7 @@ class ClientRequestImpl {
|
||||
body: setBody ? this.rBody : undefined,
|
||||
method: methodUpperCase,
|
||||
headers: headers,
|
||||
...opt?.init,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -5,17 +5,24 @@ import type { HasRequiredKeys } from '../utils/types.ts'
|
||||
|
||||
type HonoRequest = (typeof Hono.prototype)['request']
|
||||
|
||||
export type ClientRequestOptions<T = unknown> = keyof T extends never
|
||||
export type ClientRequestOptions<T = unknown> = {
|
||||
fetch?: typeof fetch | HonoRequest
|
||||
/**
|
||||
* Standard `RequestInit`, caution that this take highest priority
|
||||
* and could be used to overwrite things that Hono sets for you, like `body | method | headers`.
|
||||
*
|
||||
* If you want to add some headers, use in `headers` instead of `init`
|
||||
*/
|
||||
init?: RequestInit
|
||||
} & (keyof T extends never
|
||||
? {
|
||||
headers?:
|
||||
| Record<string, string>
|
||||
| (() => Record<string, string> | Promise<Record<string, string>>)
|
||||
fetch?: typeof fetch | HonoRequest
|
||||
}
|
||||
: {
|
||||
headers: T | (() => T | Promise<T>)
|
||||
fetch?: typeof fetch | HonoRequest
|
||||
}
|
||||
})
|
||||
|
||||
export type ClientRequest<S extends Schema> = {
|
||||
[M in keyof S]: S[M] extends Endpoint & { input: infer R }
|
||||
|
@ -828,6 +828,97 @@ describe('Dynamic headers', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('RequestInit work as expected', () => {
|
||||
const app = new Hono()
|
||||
|
||||
const route = app
|
||||
.get('/credentials', (c) => {
|
||||
return c.text('' as RequestCredentials)
|
||||
})
|
||||
.get('/headers', (c) => {
|
||||
return c.json({} as Record<string, string>)
|
||||
})
|
||||
.post('/headers', (c) => c.text('Not found', 404))
|
||||
|
||||
type AppType = typeof route
|
||||
|
||||
const server = setupServer(
|
||||
rest.get('http://localhost/credentials', async (req, res, ctx) => {
|
||||
return res(ctx.status(200), ctx.text(req.credentials))
|
||||
}),
|
||||
rest.get('http://localhost/headers', async (req, res, ctx) => {
|
||||
const allHeaders: Record<string, string> = {}
|
||||
for (const [k, v] of req.headers.entries()) {
|
||||
allHeaders[k] = v
|
||||
}
|
||||
|
||||
return res(ctx.status(200), ctx.json(allHeaders))
|
||||
}),
|
||||
rest.post('http://localhost/headers', async (req, res, ctx) => {
|
||||
return res(ctx.status(400), ctx.text('Should not be here'))
|
||||
})
|
||||
)
|
||||
|
||||
beforeAll(() => server.listen())
|
||||
afterEach(() => server.resetHandlers())
|
||||
afterAll(() => server.close())
|
||||
|
||||
const client = hc<AppType>('http://localhost', {
|
||||
headers: { 'x-hono': 'fire' },
|
||||
init: {
|
||||
credentials: 'include',
|
||||
},
|
||||
})
|
||||
|
||||
it('Should overwrite method and fail', async () => {
|
||||
const res = await client.headers.$get(undefined, { init: { method: 'POST' } })
|
||||
|
||||
expect(res.ok).toBe(false)
|
||||
})
|
||||
|
||||
it('Should clear headers', async () => {
|
||||
const res = await client.headers.$get(undefined, { init: { headers: undefined } })
|
||||
|
||||
expect(res.ok).toBe(true)
|
||||
const data = await res.json()
|
||||
expect(data).toEqual({})
|
||||
})
|
||||
|
||||
it('Should overwrite headers', async () => {
|
||||
const res = await client.headers.$get(undefined, {
|
||||
init: { headers: new Headers({ 'x-hono': 'awesome' }) },
|
||||
})
|
||||
|
||||
expect(res.ok).toBe(true)
|
||||
const data = await res.json()
|
||||
expect(data).toEqual({ 'x-hono': 'awesome' })
|
||||
})
|
||||
|
||||
it('credentials is include', async () => {
|
||||
const res = await client.credentials.$get()
|
||||
|
||||
expect(res.ok).toBe(true)
|
||||
const data = await res.text()
|
||||
expect(data).toEqual('include')
|
||||
})
|
||||
|
||||
it('deepMerge should works and not unset credentials', async () => {
|
||||
const res = await client.credentials.$get(undefined, { init: { headers: { hi: 'hello' } } })
|
||||
|
||||
expect(res.ok).toBe(true)
|
||||
const data = await res.text()
|
||||
expect(data).toEqual('include')
|
||||
})
|
||||
|
||||
it('Should unset credentials', async () => {
|
||||
const res = await client.credentials.$get(undefined, { init: { credentials: undefined } })
|
||||
|
||||
expect(res.ok).toBe(true)
|
||||
const data = await res.text()
|
||||
expect(data).toEqual('same-origin')
|
||||
})
|
||||
})
|
||||
|
||||
describe('WebSocket URL Protocol Translation', () => {
|
||||
const app = new Hono()
|
||||
const route = app.get(
|
||||
|
@ -123,6 +123,7 @@ class ClientRequestImpl {
|
||||
body: setBody ? this.rBody : undefined,
|
||||
method: methodUpperCase,
|
||||
headers: headers,
|
||||
...opt?.init,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -5,17 +5,24 @@ import type { HasRequiredKeys } from '../utils/types'
|
||||
|
||||
type HonoRequest = (typeof Hono.prototype)['request']
|
||||
|
||||
export type ClientRequestOptions<T = unknown> = keyof T extends never
|
||||
export type ClientRequestOptions<T = unknown> = {
|
||||
fetch?: typeof fetch | HonoRequest
|
||||
/**
|
||||
* Standard `RequestInit`, caution that this take highest priority
|
||||
* and could be used to overwrite things that Hono sets for you, like `body | method | headers`.
|
||||
*
|
||||
* If you want to add some headers, use in `headers` instead of `init`
|
||||
*/
|
||||
init?: RequestInit
|
||||
} & (keyof T extends never
|
||||
? {
|
||||
headers?:
|
||||
| Record<string, string>
|
||||
| (() => Record<string, string> | Promise<Record<string, string>>)
|
||||
fetch?: typeof fetch | HonoRequest
|
||||
}
|
||||
: {
|
||||
headers: T | (() => T | Promise<T>)
|
||||
fetch?: typeof fetch | HonoRequest
|
||||
}
|
||||
})
|
||||
|
||||
export type ClientRequest<S extends Schema> = {
|
||||
[M in keyof S]: S[M] extends Endpoint & { input: infer R }
|
||||
|
Loading…
Reference in New Issue
Block a user