128 lines
3.5 KiB
TypeScript
128 lines
3.5 KiB
TypeScript
/**
|
|
* Google Fonts API client
|
|
*
|
|
* Handles API requests to Google Fonts API for fetching font metadata.
|
|
* Provides error handling, retry logic, and type-safe responses.
|
|
*
|
|
* Pagination: The Google Fonts API does NOT support pagination parameters.
|
|
* All fonts matching the query are returned in a single response.
|
|
* Use category, subset, or sort filters to reduce the result set if needed.
|
|
*
|
|
* @see https://developers.google.com/fonts/docs/developer_api
|
|
*/
|
|
|
|
import { api } from '$shared/api/api';
|
|
import { buildQueryString } from '$shared/lib/utils';
|
|
import type { QueryParams } from '$shared/lib/utils';
|
|
import type {
|
|
FontItem,
|
|
GoogleFontsApiModel,
|
|
} from '../../model/types/google';
|
|
|
|
/**
|
|
* Google Fonts API parameters
|
|
*/
|
|
export interface GoogleFontsParams extends QueryParams {
|
|
/**
|
|
* Google Fonts API key (required for Google Fonts API v1)
|
|
*/
|
|
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?: 'alpha' | 'date' | 'popularity' | 'style' | 'trending';
|
|
/**
|
|
* Cap the number of fonts returned
|
|
*/
|
|
capability?: 'VF' | 'WOFF2';
|
|
}
|
|
|
|
/**
|
|
* Google Fonts API response wrapper
|
|
* Re-exported from model/types/google for backward compatibility
|
|
*/
|
|
export type GoogleFontsResponse = GoogleFontsApiModel;
|
|
|
|
/**
|
|
* Simplified font item from Google Fonts API
|
|
* Re-exported from model/types/google for backward compatibility
|
|
*/
|
|
export type GoogleFontItem = FontItem;
|
|
|
|
/**
|
|
* Google Fonts API base URL
|
|
* Note: Google Fonts API v1 requires an API key. For development/testing without a key,
|
|
* fonts may not load properly.
|
|
*/
|
|
const GOOGLE_FONTS_API_URL = 'https://www.googleapis.com/webfonts/v1/webfonts' 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<GoogleFontsResponse> {
|
|
const queryString = buildQueryString(params);
|
|
const url = `${GOOGLE_FONTS_API_URL}${queryString}`;
|
|
|
|
try {
|
|
const response = await api.get<GoogleFontsResponse>(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<GoogleFontItem | undefined> {
|
|
const response = await fetchGoogleFonts({ family });
|
|
return response.items.find(item => item.family === family);
|
|
}
|