aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/client/api
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-12-31 19:51:21 +0900
committernsfisis <nsfisis@gmail.com>2025-12-31 19:51:21 +0900
commitc915c21d47a2b417979b20e9e9d9b6ff30a03c0d (patch)
tree643ba4e499bae8a541d77f299837361a75890b10 /src/client/api
parent73ee02825f57d971f6f660fc5277d4aa268702ff (diff)
downloadkioku-c915c21d47a2b417979b20e9e9d9b6ff30a03c0d.tar.gz
kioku-c915c21d47a2b417979b20e9e9d9b6ff30a03c0d.tar.zst
kioku-c915c21d47a2b417979b20e9e9d9b6ff30a03c0d.zip
refactor(client): use Hono InferResponseType for API response types
Replace manually defined AuthResponse and User types with Hono's InferResponseType to automatically derive types from server definitions. This ensures client types stay in sync with server responses. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src/client/api')
-rw-r--r--src/client/api/client.test.ts30
-rw-r--r--src/client/api/client.ts15
-rw-r--r--src/client/api/index.ts4
-rw-r--r--src/client/api/types.ts11
4 files changed, 44 insertions, 16 deletions
diff --git a/src/client/api/client.test.ts b/src/client/api/client.test.ts
index 5489547..27c3a0a 100644
--- a/src/client/api/client.test.ts
+++ b/src/client/api/client.test.ts
@@ -13,8 +13,10 @@ import {
import {
ApiClient,
ApiClientError,
+ type LoginResponse,
localStorageTokenStorage,
type TokenStorage,
+ type User,
} from "./client";
function createMockTokenStorage(): TokenStorage & {
@@ -209,3 +211,31 @@ describe("localStorageTokenStorage", () => {
expect(localStorageTokenStorage.getTokens()).toBeNull();
});
});
+
+describe("InferResponseType types", () => {
+ it("LoginResponse has expected properties", () => {
+ // This test verifies the inferred types have the correct structure
+ // The type assertions will fail at compile time if the types are wrong
+ const mockResponse: LoginResponse = {
+ accessToken: "access-token",
+ refreshToken: "refresh-token",
+ user: { id: "123", username: "testuser" },
+ };
+
+ expect(mockResponse.accessToken).toBe("access-token");
+ expect(mockResponse.refreshToken).toBe("refresh-token");
+ expect(mockResponse.user.id).toBe("123");
+ expect(mockResponse.user.username).toBe("testuser");
+ });
+
+ it("User type is correctly derived from LoginResponse", () => {
+ // Verify User type has expected structure
+ const user: User = {
+ id: "user-1",
+ username: "testuser",
+ };
+
+ expect(user.id).toBe("user-1");
+ expect(user.username).toBe("testuser");
+ });
+});
diff --git a/src/client/api/client.ts b/src/client/api/client.ts
index 7741942..7607eb6 100644
--- a/src/client/api/client.ts
+++ b/src/client/api/client.ts
@@ -1,6 +1,13 @@
-import { hc } from "hono/client";
+import { hc, type InferResponseType } from "hono/client";
import type { AppType } from "../../server/index.js";
-import type { ApiError, AuthResponse, Tokens } from "./types";
+import type { ApiError, Tokens } from "./types";
+
+// Create a temporary client just for type inference
+const _rpc = hc<AppType>("");
+
+// Infer response types from server definitions
+export type LoginResponse = InferResponseType<typeof _rpc.api.auth.login.$post>;
+export type User = LoginResponse["user"];
export class ApiClientError extends Error {
constructor(
@@ -120,12 +127,12 @@ export class ApiClient {
}
}
- async login(username: string, password: string): Promise<AuthResponse> {
+ async login(username: string, password: string): Promise<LoginResponse> {
const res = await this.rpc.api.auth.login.$post({
json: { username, password },
});
- const data = await this.handleResponse<AuthResponse>(res);
+ const data = await this.handleResponse<LoginResponse>(res);
this.tokenStorage.setTokens({
accessToken: data.accessToken,
diff --git a/src/client/api/index.ts b/src/client/api/index.ts
index fb26b70..63d0a40 100644
--- a/src/client/api/index.ts
+++ b/src/client/api/index.ts
@@ -3,7 +3,9 @@ export {
ApiClientError,
type ApiClientOptions,
apiClient,
+ type LoginResponse,
localStorageTokenStorage,
type TokenStorage,
+ type User,
} from "./client";
-export type { ApiError, AuthResponse, Tokens, User } from "./types";
+export type { ApiError, Tokens } from "./types";
diff --git a/src/client/api/types.ts b/src/client/api/types.ts
index eaf69eb..70918fe 100644
--- a/src/client/api/types.ts
+++ b/src/client/api/types.ts
@@ -1,14 +1,3 @@
-export interface User {
- id: string;
- username: string;
-}
-
-export interface AuthResponse {
- accessToken: string;
- refreshToken: string;
- user: User;
-}
-
export interface ApiError {
error: {
message: string;