/** * Google Fonts API client * * Handles API requests to Google Fonts API for fetching font metadata. * Provides error handling, retry logic, and type-safe responses. * * @see https://developers.google.com/fonts/docs/developer_api */ import type { FontItem, GoogleFontsApiModel, } from '$entities/Font'; import { api } from '$shared/api/api'; import { buildQueryString } from '$shared/utils'; import type { QueryParams } from '$shared/utils'; /** * Google Fonts API parameters */ export interface GoogleFontsParams extends QueryParams { /** * Google Fonts API key (optional for public endpoints) */ key?: string; /** * Font family name (to fetch specific font) */ family?: string; /** * Font category filter (e.g., "sans-serif", "serif", "display") */ category?: string; /** * Character subset filter (e.g., "latin", "latin-ext", "cyrillic") */ subset?: string; /** * Sort order for results */ sort?: 'popularity' | 'alpha' | 'date' | 'style'; /** * Cap the number of fonts returned */ capability?: string; } /** * Google Fonts API response wrapper * Re-exported from model/types for backward compatibility */ export type GoogleFontsResponse = GoogleFontsApiModel; /** * Simplified font item from Google Fonts API * Re-exported from model/types for backward compatibility */ export type GoogleFontItem = FontItem; /** * Google Fonts API base URL */ const GOOGLE_FONTS_API_URL = 'https://fonts.googleapis.com/v2/fonts' as const; /** * Fetch fonts from Google Fonts API * * @param params - Query parameters for filtering fonts * @returns Promise resolving to Google Fonts API response * @throws ApiError when request fails * * @example * ```ts * // Fetch all sans-serif fonts sorted by popularity * const response = await fetchGoogleFonts({ * category: 'sans-serif', * sort: 'popularity' * }); * * // Fetch specific font family * const robotoResponse = await fetchGoogleFonts({ * family: 'Roboto' * }); * ``` */ export async function fetchGoogleFonts( params: GoogleFontsParams = {}, ): Promise { const queryString = buildQueryString(params); const url = `${GOOGLE_FONTS_API_URL}${queryString}`; try { const response = await api.get(url); return response.data; } catch (error) { // Re-throw ApiError with context if (error instanceof Error) { throw error; } throw new Error(`Failed to fetch Google Fonts: ${String(error)}`); } } /** * Fetch font by family name * Convenience function for fetching a single font * * @param family - Font family name (e.g., "Roboto") * @returns Promise resolving to Google Font item * * @example * ```ts * const roboto = await fetchGoogleFontFamily('Roboto'); * ``` */ export async function fetchGoogleFontFamily( family: string, ): Promise { const response = await fetchGoogleFonts({ family }); return response.items.find(item => item.family === family); }