158 lines
3.8 KiB
TypeScript
158 lines
3.8 KiB
TypeScript
/**
|
|
* Fontshare API client
|
|
*
|
|
* Handles API requests to Fontshare API for fetching font metadata.
|
|
* Provides error handling, pagination support, and type-safe responses.
|
|
*
|
|
* @see https://fontshare.com
|
|
*/
|
|
|
|
import { api } from '$shared/api/api';
|
|
import { buildQueryString } from '$shared/lib/utils';
|
|
import type { QueryParams } from '$shared/lib/utils';
|
|
import type {
|
|
FontshareApiModel,
|
|
FontshareFont,
|
|
} from '../../model/types/fontshare';
|
|
|
|
/**
|
|
* Fontshare API parameters
|
|
*/
|
|
export interface FontshareParams extends QueryParams {
|
|
/**
|
|
* Filter by categories (e.g., ["Sans", "Serif", "Display"])
|
|
*/
|
|
categories?: string[];
|
|
/**
|
|
* Filter by tags (e.g., ["Magazines", "Branding", "Logos"])
|
|
*/
|
|
tags?: string[];
|
|
/**
|
|
* Page number for pagination (1-indexed)
|
|
*/
|
|
page?: number;
|
|
/**
|
|
* Number of items per page
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* Search query to filter fonts
|
|
*/
|
|
search?: string;
|
|
}
|
|
|
|
/**
|
|
* Fontshare API response wrapper
|
|
* Re-exported from model/types/fontshare for backward compatibility
|
|
*/
|
|
export type FontshareResponse = FontshareApiModel;
|
|
|
|
/**
|
|
* Fetch fonts from Fontshare API
|
|
*
|
|
* @param params - Query parameters for filtering fonts
|
|
* @returns Promise resolving to Fontshare API response
|
|
* @throws ApiError when request fails
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* // Fetch all Sans category fonts
|
|
* const response = await fetchFontshareFonts({
|
|
* categories: ['Sans'],
|
|
* limit: 50
|
|
* });
|
|
*
|
|
* // Fetch fonts with specific tags
|
|
* const response = await fetchFontshareFonts({
|
|
* tags: ['Branding', 'Logos']
|
|
* });
|
|
*
|
|
* // Search fonts
|
|
* const response = await fetchFontshareFonts({
|
|
* search: 'Satoshi'
|
|
* });
|
|
* ```
|
|
*/
|
|
export async function fetchFontshareFonts(
|
|
params: FontshareParams = {},
|
|
): Promise<FontshareResponse> {
|
|
const queryString = buildQueryString(params);
|
|
const url = `https://api.fontshare.com/v2${queryString}`;
|
|
|
|
try {
|
|
const response = await api.get<FontshareResponse>(url);
|
|
return response.data;
|
|
} catch (error) {
|
|
// Re-throw ApiError with context
|
|
if (error instanceof Error) {
|
|
throw error;
|
|
}
|
|
throw new Error(`Failed to fetch Fontshare fonts: ${String(error)}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetch font by slug
|
|
* Convenience function for fetching a single font
|
|
*
|
|
* @param slug - Font slug (e.g., "satoshi", "general-sans")
|
|
* @returns Promise resolving to Fontshare font item
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* const satoshi = await fetchFontshareFontBySlug('satoshi');
|
|
* ```
|
|
*/
|
|
export async function fetchFontshareFontBySlug(
|
|
slug: string,
|
|
): Promise<FontshareFont | undefined> {
|
|
const response = await fetchFontshareFonts();
|
|
return response.items.find(font => font.slug === slug);
|
|
}
|
|
|
|
/**
|
|
* Fetch all fonts from Fontshare
|
|
* Convenience function for fetching all available fonts
|
|
* Uses pagination to get all items
|
|
*
|
|
* @returns Promise resolving to all Fontshare fonts
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* const allFonts = await fetchAllFontshareFonts();
|
|
* console.log(`Found ${allFonts.items.length} fonts`);
|
|
* ```
|
|
*/
|
|
export async function fetchAllFontshareFonts(
|
|
params: FontshareParams = {},
|
|
): Promise<FontshareResponse> {
|
|
const allFonts: FontshareFont[] = [];
|
|
let page = 1;
|
|
const limit = 100; // Max items per page
|
|
|
|
while (true) {
|
|
const response = await fetchFontshareFonts({
|
|
...params,
|
|
page,
|
|
limit,
|
|
});
|
|
|
|
allFonts.push(...response.items);
|
|
|
|
// Check if we've fetched all items
|
|
if (response.items.length < limit) {
|
|
break;
|
|
}
|
|
|
|
page++;
|
|
}
|
|
|
|
// Return first response with all items combined
|
|
const firstResponse = await fetchFontshareFonts({ ...params, page: 1, limit });
|
|
|
|
return {
|
|
...firstResponse,
|
|
items: allFonts,
|
|
};
|
|
}
|