0
0
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:
Trung Dang 2024-05-03 07:02:54 +07:00 committed by GitHub
parent 11a20a7db3
commit fb07fb4012
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 115 additions and 8 deletions

View File

@ -123,6 +123,7 @@ class ClientRequestImpl {
body: setBody ? this.rBody : undefined,
method: methodUpperCase,
headers: headers,
...opt?.init,
})
}
}

View File

@ -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 }

View File

@ -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(

View File

@ -123,6 +123,7 @@ class ClientRequestImpl {
body: setBody ? this.rBody : undefined,
method: methodUpperCase,
headers: headers,
...opt?.init,
})
}
}

View File

@ -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 }