Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: honojs/hono
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.11.4
Choose a base ref
...
head repository: honojs/hono
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v3.11.5
Choose a head ref
  • 4 commits
  • 9 files changed
  • 2 contributors

Commits on Dec 12, 2023

  1. fix(context): set headers values correctly (#1808)

    * fix(context): set headers values correctly
    
    * denoify
    yusukebe authored Dec 12, 2023

    Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    hi-ogawa Hiroshi Ogawa
    Copy the full SHA
    0f33cf8 View commit details
  2. Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    hi-ogawa Hiroshi Ogawa
    Copy the full SHA
    87e256b View commit details

Commits on Dec 13, 2023

  1. fix(context): c.json() allows object and returns JSONParsed<T> (#1806)

    * fix(context): `c.json()` allows object and returns JSONParsed<T>
    
    * denoify
    yusukebe authored Dec 13, 2023

    Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    hi-ogawa Hiroshi Ogawa
    Copy the full SHA
    af8d16b View commit details
  2. v3.11.5

    yusukebe committed Dec 13, 2023

    Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    hi-ogawa Hiroshi Ogawa
    Copy the full SHA
    a86b75b View commit details
Showing with 38 additions and 33 deletions.
  1. +1 −1 README.md
  2. +1 −1 deno_dist/README.md
  3. +7 −12 deno_dist/context.ts
  4. +4 −1 deno_dist/utils/types.ts
  5. +1 −1 package.json
  6. +3 −4 src/client/client.test.ts
  7. +10 −0 src/context.test.ts
  8. +7 −12 src/context.ts
  9. +4 −1 src/utils/types.ts
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@ npm create hono@latest my-app
## Features

- **Ultrafast** 🚀 - The router `RegExpRouter` is really fast. Not using linear loops. Fast.
- **Lightweight** 🪶 - The `hono/tiny` preset is under 12kB. Hono has zero dependencies and uses only the Web Standard API.
- **Lightweight** 🪶 - The `hono/tiny` preset is under 14kB. Hono has zero dependencies and uses only the Web Standard API.
- **Multi-runtime** 🌍 - Works on Cloudflare Workers, Fastly Compute, Deno, Bun, Lagon, AWS Lambda, Lambda@Edge, or Node.js. The same code runs on all platforms.
- **Batteries Included** 🔋 - Hono has built-in middleware, custom middleware, and third-party middleware. Batteries included.
- **Delightful DX** 😃 - Super clean APIs. First-class TypeScript support. Now, we've got "Types".
2 changes: 1 addition & 1 deletion deno_dist/README.md
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@ npm create hono@latest my-app
## Features

- **Ultrafast** 🚀 - The router `RegExpRouter` is really fast. Not using linear loops. Fast.
- **Lightweight** 🪶 - The `hono/tiny` preset is under 12kB. Hono has zero dependencies and uses only the Web Standard API.
- **Lightweight** 🪶 - The `hono/tiny` preset is under 14kB. Hono has zero dependencies and uses only the Web Standard API.
- **Multi-runtime** 🌍 - Works on Cloudflare Workers, Fastly Compute, Deno, Bun, Lagon, AWS Lambda, Lambda@Edge, or Node.js. The same code runs on all platforms.
- **Batteries Included** 🔋 - Hono has built-in middleware, custom middleware, and third-party middleware. Batteries included.
- **Delightful DX** 😃 - Super clean APIs. First-class TypeScript support. Now, we've got "Types".
19 changes: 7 additions & 12 deletions deno_dist/context.ts
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import { serialize } from './utils/cookie.ts'
import { resolveStream } from './utils/html.ts'
import type { StatusCode } from './utils/http-status.ts'
import { StreamingApi } from './utils/stream.ts'
import type { JSONValue, InterfaceToType } from './utils/types.ts'
import type { JSONValue, InterfaceToType, JSONParsed } from './utils/types.ts'

type HeaderRecord = Record<string, string | string[]>
type Data = string | ArrayBuffer | ReadableStream
@@ -57,15 +57,15 @@ interface JSONRespond {
InterfaceToType<T> extends JSONValue
? JSONValue extends InterfaceToType<T>
? never
: T
: JSONParsed<T>
: never
>
<T>(object: InterfaceToType<T> extends JSONValue ? T : JSONValue, init?: ResponseInit): Response &
TypedResponse<
InterfaceToType<T> extends JSONValue
? JSONValue extends InterfaceToType<T>
? never
: T
: JSONParsed<T>
: never
>
}
@@ -230,17 +230,11 @@ export class Context<
})
}

// Return Response immediately if arg is ResponseInit.
if (arg && typeof arg !== 'number') {
const res = new Response(data, arg)
const contentType = this.#preparedHeaders?.['content-type']
if (contentType) {
res.headers.set('content-type', contentType)
}
return res
this.res = new Response(data, arg)
}

const status = arg ?? this.#status
let status = typeof arg === 'number' ? arg : this.#status
this.#preparedHeaders ??= {}

this.#headers ??= new Headers()
@@ -255,6 +249,7 @@ export class Context<
for (const [k, v] of Object.entries(this.#preparedHeaders)) {
this.#headers.set(k, v)
}
status = this.#res.status
}

headers ??= {}
@@ -313,7 +308,7 @@ export class Context<
InterfaceToType<T> extends JSONValue
? JSONValue extends InterfaceToType<T>
? never
: T
: JSONParsed<T>
: never
> => {
const body = JSON.stringify(object)
5 changes: 4 additions & 1 deletion deno_dist/utils/types.ts
Original file line number Diff line number Diff line change
@@ -25,8 +25,11 @@ export type IntersectNonAnyTypes<T extends any[]> = T extends [infer Head, ...in

export type JSONPrimitive = string | boolean | number | null | undefined
export type JSONArray = (JSONPrimitive | JSONObject | JSONArray)[]
export type JSONObject = { [key: string]: JSONPrimitive | JSONArray | JSONObject }
export type JSONObject = { [key: string]: JSONPrimitive | JSONArray | JSONObject | object }
export type JSONValue = JSONObject | JSONArray | JSONPrimitive
export type JSONParsed<T> = {
[k in keyof T]: T[k] extends JSONValue ? T[k] : string
}

export type InterfaceToType<T> = T extends Function ? T : { [K in keyof T]: InterfaceToType<T[K]> }

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hono",
"version": "3.11.4",
"version": "3.11.5",
"description": "Ultrafast web framework for the Edges",
"main": "dist/cjs/index.js",
"type": "module",
7 changes: 3 additions & 4 deletions src/client/client.test.ts
Original file line number Diff line number Diff line change
@@ -500,15 +500,14 @@ describe('Merge path with `app.route()`', () => {
expect(data.ok).toBe(true)
})

it('Should not allow the incorrect JSON type', async () => {
it('Should allow a Date object and return it as a string', async () => {
const app = new Hono()
// @ts-expect-error
const route = app.get('/api/foo', (c) => c.json({ datetime: new Date() }))
type AppType = typeof route
const client = hc<AppType>('http://localhost')
const res = await client.api.foo.$get()
const data = await res.json()
type verify = Expect<Equal<never, typeof data>>
const { datetime } = await res.json()
type verify = Expect<Equal<string, typeof datetime>>
})

describe('Multiple endpoints', () => {
10 changes: 10 additions & 0 deletions src/context.test.ts
Original file line number Diff line number Diff line change
@@ -205,6 +205,16 @@ describe('Context header', () => {
const res = c.text('foo')
expect(res.headers.get('Content-Type')).toMatch(/^text\/plain/)
})

it('Should set header values if the #this.headers is set and the arg is ResponseInit', async () => {
c.header('foo', 'bar')
const res = c.body('foo', {
headers: {
'Content-Type': 'text/plain',
},
})
expect(res.headers.get('foo')).toBe('bar')
})
})

describe('Pass a ResponseInit to respond methods', () => {
19 changes: 7 additions & 12 deletions src/context.ts
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import { serialize } from './utils/cookie'
import { resolveStream } from './utils/html'
import type { StatusCode } from './utils/http-status'
import { StreamingApi } from './utils/stream'
import type { JSONValue, InterfaceToType } from './utils/types'
import type { JSONValue, InterfaceToType, JSONParsed } from './utils/types'

type HeaderRecord = Record<string, string | string[]>
type Data = string | ArrayBuffer | ReadableStream
@@ -57,15 +57,15 @@ interface JSONRespond {
InterfaceToType<T> extends JSONValue
? JSONValue extends InterfaceToType<T>
? never
: T
: JSONParsed<T>
: never
>
<T>(object: InterfaceToType<T> extends JSONValue ? T : JSONValue, init?: ResponseInit): Response &
TypedResponse<
InterfaceToType<T> extends JSONValue
? JSONValue extends InterfaceToType<T>
? never
: T
: JSONParsed<T>
: never
>
}
@@ -230,17 +230,11 @@ export class Context<
})
}

// Return Response immediately if arg is ResponseInit.
if (arg && typeof arg !== 'number') {
const res = new Response(data, arg)
const contentType = this.#preparedHeaders?.['content-type']
if (contentType) {
res.headers.set('content-type', contentType)
}
return res
this.res = new Response(data, arg)
}

const status = arg ?? this.#status
let status = typeof arg === 'number' ? arg : this.#status
this.#preparedHeaders ??= {}

this.#headers ??= new Headers()
@@ -255,6 +249,7 @@ export class Context<
for (const [k, v] of Object.entries(this.#preparedHeaders)) {
this.#headers.set(k, v)
}
status = this.#res.status
}

headers ??= {}
@@ -313,7 +308,7 @@ export class Context<
InterfaceToType<T> extends JSONValue
? JSONValue extends InterfaceToType<T>
? never
: T
: JSONParsed<T>
: never
> => {
const body = JSON.stringify(object)
5 changes: 4 additions & 1 deletion src/utils/types.ts
Original file line number Diff line number Diff line change
@@ -25,8 +25,11 @@ export type IntersectNonAnyTypes<T extends any[]> = T extends [infer Head, ...in

export type JSONPrimitive = string | boolean | number | null | undefined
export type JSONArray = (JSONPrimitive | JSONObject | JSONArray)[]
export type JSONObject = { [key: string]: JSONPrimitive | JSONArray | JSONObject }
export type JSONObject = { [key: string]: JSONPrimitive | JSONArray | JSONObject | object }
export type JSONValue = JSONObject | JSONArray | JSONPrimitive
export type JSONParsed<T> = {
[k in keyof T]: T[k] extends JSONValue ? T[k] : string
}

export type InterfaceToType<T> = T extends Function ? T : { [K in keyof T]: InterfaceToType<T[K]> }