// /** // * Example: Using the Type-Safe RPC Client // * // * This file demonstrates how to use the Hono RPC client for type-safe API calls // * from a frontend application or another service. // * // * Based on: https://hono.dev/docs/guides/rpc // */ // import { hc } from "hono/client"; // import type { ApiRoutes } from "../src/client.js"; // // ============================================================================ // // 1. Basic Setup // // ============================================================================ // // Create a typed client pointing to your API // const client = hc("https://api.yourdomain.com/api/v1", { // headers: { // // Add any default headers here // "Content-Type": "application/json", // }, // }); // // ============================================================================ // // 2. Making Authenticated Requests // // ============================================================================ // async function getUserProfile(token: string) { // // The client knows all available routes and their types! // const res = await client.users.me.$get( // {}, // { // headers: { // Authorization: `Bearer ${token}`, // }, // } // ); // if (!res.ok) { // throw new Error(`Failed to fetch user: ${res.status}`); // } // // Response is fully typed - TypeScript knows the shape! // const data = await res.json(); // return data; // TypeScript knows: { user: User } // } // // ============================================================================ // // 3. POST Requests with Body // // ============================================================================ // async function createTablo(token: string, tabloData: { name: string; color: string }) { // const res = await client.tablos.create.$post( // { // json: tabloData, // Typed request body // }, // { // headers: { // Authorization: `Bearer ${token}`, // }, // } // ); // if (!res.ok) { // const error = await res.json(); // throw new Error(`Failed to create tablo: ${error.error}`); // } // return await res.json(); // Typed response // } // // ============================================================================ // // 4. Route Parameters // // ============================================================================ // async function getTabloNotes(token: string, tabloId: string) { // // TypeScript will ensure tabloId is provided and typed correctly // const res = await client.notes[":tabloId"].$get( // { // param: { tabloId }, // Type-checked parameter // }, // { // headers: { // Authorization: `Bearer ${token}`, // }, // } // ); // if (!res.ok) { // throw new Error("Failed to fetch notes"); // } // const data = await res.json(); // return data.notes; // Fully typed array of notes // } // // ============================================================================ // // 5. Query Parameters // // ============================================================================ // async function searchPublicSlots(shortUserId: string, standardName: string) { // // Public routes don't need authentication // const publicClient = hc("https://api.yourdomain.com/api/public"); // const res = await publicClient.slots[":shortUserId"][":standardName"].$get({ // param: { // shortUserId, // standardName, // }, // }); // if (!res.ok) { // throw new Error("Failed to fetch slots"); // } // return await res.json(); // } // // ============================================================================ // // 6. Error Handling with Type Safety // // ============================================================================ // type ApiError = { // error: string; // }; // async function safeApiCall( // apiCall: () => Promise // ): Promise<{ data?: T; error?: string }> { // try { // const res = await apiCall(); // if (!res.ok) { // const errorData = (await res.json()) as ApiError; // return { error: errorData.error }; // } // const data = (await res.json()) as T; // return { data }; // } catch (err) { // return { // error: err instanceof Error ? err.message : "Unknown error", // }; // } // } // // Usage // async function example(token: string) { // const result = await safeApiCall(() => // client.users.me.$get( // {}, // { // headers: { Authorization: `Bearer ${token}` }, // } // ) // ); // if (result.error) { // console.error("API Error:", result.error); // return; // } // console.log("User data:", result.data); // } // // ============================================================================ // // 7. React Hook Example // // ============================================================================ // /* // import { useState, useEffect } from 'react'; // function useUser(token: string | null) { // const [user, setUser] = useState(null); // const [loading, setLoading] = useState(true); // const [error, setError] = useState(null); // useEffect(() => { // if (!token) { // setLoading(false); // return; // } // getUserProfile(token) // .then(data => { // setUser(data.user); // setError(null); // }) // .catch(err => { // setError(err.message); // }) // .finally(() => { // setLoading(false); // }); // }, [token]); // return { user, loading, error }; // } // */ // // ============================================================================ // // 8. Advanced: Custom Fetch with Interceptors // // ============================================================================ // // You can customize the fetch function for things like: // // - Adding auth tokens automatically // // - Logging requests // // - Retry logic // // - Error handling // function createAuthenticatedClient(getToken: () => string) { // return hc("https://api.yourdomain.com/api/v1", { // fetch: async (input, init) => { // // Add token to every request // const token = getToken(); // const headers = new Headers(init?.headers); // headers.set("Authorization", `Bearer ${token}`); // // Log requests in development // if (process.env.NODE_ENV === "development") { // console.log(`API Request: ${input}`); // } // // Make the request // const response = await fetch(input, { ...init, headers }); // // Log responses in development // if (process.env.NODE_ENV === "development") { // console.log(`API Response: ${response.status}`); // } // return response; // }, // }); // } // // Usage // const authenticatedClient = createAuthenticatedClient(() => { // // Get token from your auth system // return localStorage.getItem("auth_token") || ""; // }); // // Now all requests automatically include the token! // async function autoAuthExample() { // const res = await authenticatedClient.users.me.$get({}); // // Token is automatically added // } // // ============================================================================ // // 9. Type Exports for Props/State // // ============================================================================ // // You can extract types from the API responses for use in your components // type User = Awaited>["user"]; // type TabloNotes = Awaited>; // // Usage in React props // /* // interface UserProfileProps { // user: User; // } // function UserProfile({ user }: UserProfileProps) { // return
{user.name}
; // } // */ // // ============================================================================ // // Export for use in your app // // ============================================================================ // export { // client, // getUserProfile, // createTablo, // getTabloNotes, // searchPublicSlots, // safeApiCall, // createAuthenticatedClient, // }; // export type { User, TabloNotes };