メインコンテンツまでスキップ

Hono Client

Zeltは、Honoの hc client向けに型安全なclient型(AppType)を生成します — IDEの自動補完付きで、完全に型安全なAPI呼び出しを実現します。

概要

@zeltjs/hono-client パッケージは、controllerのシグネチャから AppType を生成します。この型はHonoの hc clientと統合し、以下を提供します:

  • リクエストパラメータとレスポンスボディの完全なTypeScript推論
  • APIエンドポイントのIDE自動補完
  • API呼び出しのコンパイル時型チェック

インストール

pnpm add @zeltjs/hono-client

設定(CLI Plugin)

zelt.config.tshonoClientPlugin を追加します:

export default defineConfig({
  entry: './dist/app.js',
  plugins: [
    honoClientPlugin({
      outDir: './generated',
      output: 'app-type.ts',
    }),
  ],
});

Pluginオプション

オプションデフォルト説明
entrystringconfig.entryビルド済みアプリモジュールへのパス
outDirstring'./generated'出力ディレクトリ
outputstring'app-type.ts'出力ファイル名

AppTypeの生成

型ファイルを生成するには zelt build を実行します:

pnpm zelt build

これにより、AppType を含む <outDir>/<output>(デフォルト: generated/app-type.ts)が生成されます。

プログラムからの生成

ビルドがZelt CLIによって駆動されない場合 — electron-viteパイプライン、カスタムビルドスクリプト、monorepoのタスクランナーなど — GeneratorService.generateFromApp() を直接使います。これはアプリの http featureを受け取り、生成された型ソースを文字列として返します:

const generator = new GeneratorService();
const content = await generator.generateFromApp(app.http, { distDir: './dist' });

writeFileSync('./dist/app-type.generated.ts', content, 'utf-8');

これは、アプリのモジュールがコンパイルされた後のビルドステップとして実行してください — 例えば、ビルドされた出力に対して node から実行するスクリプトや、electron-viteの buildStart フックなどです。

生成オプション

オプション説明
distDirstringビルド済みアプリ出力のディレクトリ。生成されたimportはこれを基準に解決される
portablebooleandistDir へのimportの代わりに、リテラル型を解決済みの自己完結型ファイルを出力する
tsconfigstringプロジェクトのtsconfigへのパス(portable: true の場合必須)
projectRootstringパス解決用のプロジェクトルート(portable: true の場合必須)

生成されたファイルがserverパッケージの外で消費される場合 — 例えばElectronのrendererや、serverの dist からimportできない別のフロントエンドworkspaceなど — portable: true を使ってください。

生成されるapp-type.ts

// このファイルは @zeltjs/hono-client によって生成されます。編集しないでください。

export type AppType = BuildAppType<[
  Route<'GET', '/hello/:name', () => { message: string }>,
  Route<'POST', '/hello', (input: { name: string }) => { id: string }>,
]>;

AppTypeの利用

型安全なAPI Client

const client = hc<AppType>('https://api.example.com');

// 完全に型付けされている - IDEの自動補完と型チェック
const response = await client.hello[':name'].$get({
  param: { name: 'world' },
});

if (response.ok) {
  const data = await response.json();
  // dataは { message: string } として型付けされる
  console.log(data.message);
}

型安全なClientでのテスト

describe('Hello API', () => {
  const client = hc<AppType>('http://localhost', {
    fetch: (input, init) => readyApp.http.fetch(new Request(input, init)),
  });

  it('should return greeting', async () => {
    const res = await client.hello[':name'].$get({
      param: { name: 'world' },
    });

    expect(res.status).toBe(200);
    const body = await res.json();
    expect(body.message).toBe('Hello, world!');
  });
});

仕組み

  1. メタデータ抽出 — build時にZeltアプリからroute metadataを読み取る
  2. 型生成 — 抽出されたroute情報から AppType を生成する
  3. Client統合 — 生成された型がHonoの hc clientと統合する

生成された AppType はcontrollerのrouteをHonoのroute型にマッピングし、hc clientがパラメータとレスポンスの型を自動的に推論できるようにします。