0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HonoのマージされたPRを読んでいく#86 - #90

0
Last updated at Posted at 2025-12-17

この記事何?

エンジニア歴1年半。業務で利用しているHonoが大好きだが、TSもプログラミング知識も弱々すぎて上手く使いこなせない。速いはずが多分生かせてない。
ちゃんと理解するためにソースコードリーディングしたい。

でも目的なくソースコード眺めても意味ないし……ねむい……
そうだ!PRを全部読めば、変遷やなぜ変更されているかストーリー的に分かるのでは。
と思ったのでチャレンジしてみる。PR2000以上あるので、全部できるかは知らん。
https://github.com/honojs/hono

#86 feat: Basic-auth with polyfill

Basic Auth のポリフィル対応を強化。Fastly Compute@Edge など、より多くの環境で動作するように改善。

sha256 関数をutilsに追加し、関数が環境を自動判定してくれる

src/utils/buffer.ts:

  export const sha256 = async (a: string): Promise<string> => {
    // crypto.subtle を試す(Cloudflare Workers, ブラウザ)
    if (crypto && crypto.subtle) {
      const buffer = await crypto.subtle.digest(
        { name: 'SHA-256' },
        new TextEncoder().encode(String(a))
      )
      const hash = Array.prototype.map
        .call(new Uint8Array(buffer), (x) => ('00' + x.toString(16)).slice(-2))
        .join('')
      return hash
    }

    // crypto.subtle がなければ Node.js の crypto を試す
    try {
      const crypto = await import('crypto')
      const hash = crypto.createHash('sha256').update(a).digest('hex')
      return hash
    } catch (e) {
      console.error('If you want to do "sha256", polyfill "crypto" module.')
      throw e
    }
  }
環境 decodeBase64 sha256
Cloudflare Workers atob crypto.subtle
ブラウザ atob crypto.subtle
Node.js Buffer crypto.createHash
Fastly Compute@Edge atob (polyfill) crypto.subtle (polyfill)

#87 fix: use require

await import('crypto') を require('crypto') に変更。

#88 fix: default content-type

Content-Type ヘッダーを上書きしないように修正。ユーザーが明示的に設定した場合はそれを尊重。

  // 変更前:

  text(text: string, status: number = this._status, headers: Headers = {}): Response {
    if (typeof text !== 'string') {
      throw new TypeError('text method arg must be a string!')
    }
    headers['Content-Type'] = 'text/plain'  // 常に上書き
    return this.body(text, status, headers)
  }

修正

src/context.ts:

  text(text: string, status: number = this._status, headers: Headers = {}): Response {
    if (typeof text !== 'string') {
      throw new TypeError('text method arg must be a string!')
    }
  -  headers['Content-Type'] = 'text/plain'
  +  headers['Content-Type'] ||= 'text/plain; charset=UTF-8'
    return this.body(text, status, headers)
  }

  json(object: object, status: number = this._status, headers: Headers = {}): Response {
    if (typeof object !== 'object') {
      throw new TypeError('json method arg must be an object!')
    }
    const body = JSON.stringify(object)
  -  headers['Content-Type'] = 'application/json; charset=UTF-8'
  +  headers['Content-Type'] ||= 'application/json; charset=UTF-8'
    return this.body(body, status, headers)
  }

  html(html: string, status: number = this._status, headers: Headers = {}): Response {
    if (typeof html !== 'string') {
      throw new TypeError('html method arg must be a string!')
    }
  -  headers['Content-Type'] = 'text/html; charset=UTF-8'
  +  headers['Content-Type'] ||= 'text/html; charset=UTF-8'
    return this.body(html, status, headers)
  }

#89 feat: add root option on mustache middleware

Mustache ミドルウェアに root オプションを追加。テンプレートファイルのルートディレクトリを指定できるように。

src/middleware/mustache/mustache.ts:

  type Options = {
    root: string
  }

  // 変更前
  -export const mustache = () => {
  // 変更後
  +export const mustache = (opt: Options = { root: '' }) => {
  +  const { root } = opt

    return async (c: Context, next: Function) => {
      // ...

      c.render = async (filename, view = {}, options?) => {
        // 変更前: 直接ファイル名を使う
  -      const buffer = await getContentFromKVAsset(`${filename}${EXTENSION}`)

        // 変更後: getKVFilePath でパスを生成
  +      const path = getKVFilePath({
  +        filename: `${filename}${EXTENSION}`,
  +        root: root,
  +        defaultDocument: DEFAULT_DOCUMENT
  +      })
  +      const buffer = await getContentFromKVAsset(path)

        if (!buffer) {
  -        throw new Error(`Template "${filename}${EXTENSION}" is not found or blank.`)
  +        throw new Error(`Template "${path}" is not found or blank.`)
        }
        // ...
      }
    }
  }

#90: test: add default middleware test

デフォルトミドルウェアのテストを追加。

余裕がなくなってきた〜。終わり。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?