diff --git a/src/lib/types/collection.ts b/src/lib/types/collection.ts new file mode 100644 index 0000000..79d4960 --- /dev/null +++ b/src/lib/types/collection.ts @@ -0,0 +1,21 @@ +/** + * Generic collection API response model + * Use this for APIs that return collections of items + * + * @template T - The type of items in the collection array + * @template K - The key used to access the collection array in the response + */ +export type CollectionApiModel = Record & { + /** + * Number of items returned in the current page/response + */ + count: number; + /** + * Total number of items available across all pages + */ + count_total: number; + /** + * Indicates if there are more items available beyond this page + */ + has_more: boolean; +}; diff --git a/src/lib/types/common.ts b/src/lib/types/common.ts new file mode 100644 index 0000000..2c1f8c8 --- /dev/null +++ b/src/lib/types/common.ts @@ -0,0 +1,37 @@ +/** + * Model of response with error + */ +export interface ApiErrorResponse { + /** + * Error text + */ + error: string; + /** + * Status + */ + status: number; + /** + * Status text + */ + statusText: string; +} + +/** + * Model of response with success + */ +export interface ApiSuccessResponse { + /** + * Data + */ + data: T; + /** + * Status + */ + status: number; + /** + * Status text + */ + statusText: string; +} + +export type ApiResponse = ApiErrorResponse | ApiSuccessResponse; diff --git a/src/lib/types/fontshare_fonts.ts b/src/lib/types/fontshare_fonts.ts new file mode 100644 index 0000000..9a407bf --- /dev/null +++ b/src/lib/types/fontshare_fonts.ts @@ -0,0 +1,439 @@ +import type { CollectionApiModel } from './collection'; + +/** + * Model of Fontshare API response + * @see https://fontshare.com + */ +export type FontshareApiModel = CollectionApiModel; + +/** + * Individual font metadata from Fontshare API + */ +export interface FontshareFont { + /** + * Unique identifier for the font + * UUID v4 format (e.g., "20e9fcdc-1e41-4559-a43d-1ede0adc8896") + */ + id: string; + + /** + * Display name of the font family + * Examples: "Satoshi", "General Sans", "Clash Display" + */ + name: string; + + /** + * Native/localized name of the font (if available) + * Often null for Latin-script fonts + */ + native_name: string | null; + + /** + * URL-friendly identifier for the font + * Used in URLs: e.g., "satoshi", "general-sans", "clash-display" + */ + slug: string; + + /** + * Font category classification + * Examples: "Sans", "Serif", "Display", "Script" + */ + category: string; + + /** + * Script/writing system supported by the font + * Examples: "latin", "arabic", "devanagari" + */ + script: string; + + /** + * Font publisher/foundry information + */ + publisher: FontsharePublisher; + + /** + * Array of designers who created this font + * Multiple designers may have collaborated on a single font + */ + designers: FontshareDesigner[]; + + /** + * Related font families (if any) + * Often null, as fonts are typically independent + */ + related_families: string | null; + + /** + * Whether to display publisher as the designer instead of individual designers + */ + display_publisher_as_designer: boolean; + + /** + * Whether trial downloads are enabled for this font + */ + trials_enabled: boolean; + + /** + * Whether to show Latin-specific metrics + */ + show_latin_metrics: boolean; + + /** + * Type of license for this font + * Examples: "itf_ffl" (ITF Free Font License) + */ + license_type: string; + + /** + * Comma-separated list of languages supported by this font + * Example: "Afar, Afrikaans, Albanian, Aranese, Aromanian, Aymara, ..." + */ + languages: string; + + /** + * ISO 8601 timestamp when the font was added to Fontshare + * Format: "2021-03-12T20:49:05Z" + */ + inserted_at: string; + + /** + * HTML-formatted story/description about the font + * Contains marketing text, design philosophy, and usage recommendations + */ + story: string; + + /** + * Version of the font family + * Format: "1.0", "1.2", etc. + */ + version: string; + + /** + * Total number of times this font has been viewed + */ + views: number; + + /** + * Number of views in the recent time period + */ + views_recent: number; + + /** + * Whether this font is marked as "hot"/trending + */ + is_hot: boolean; + + /** + * Whether this font is marked as new + */ + is_new: boolean; + + /** + * Whether this font is in the shortlisted collection + */ + is_shortlisted: boolean | null; + + /** + * Whether this font is marked as top/popular + */ + is_top: boolean; + + /** + * Variable font axes (for variable fonts) + * Empty array [] for static fonts + */ + axes: FontshareAxis[]; + + /** + * Tags/categories for this font + * Examples: ["Magazines", "Branding", "Logos", "Posters"] + */ + font_tags: FontshareTag[]; + + /** + * OpenType features available in this font + */ + features: FontshareFeature[]; + + /** + * Array of available font styles/variants + * Each style represents a different font file (weight, italic, variable) + */ + styles: FontshareStyle[]; +} + +/** + * Publisher/foundry information + */ +export interface FontsharePublisher { + /** + * Description/bio of the publisher + * Example: "Indian Type Foundry (ITF) creates retail and custom multilingual fonts..." + */ + bio: string; + + /** + * Publisher email (if available) + */ + email: string | null; + + /** + * Unique publisher identifier + * UUID format + */ + id: string; + + /** + * Publisher links (social media, website, etc.) + */ + links: FontshareLink[]; + + /** + * Publisher name + * Example: "Indian Type Foundry" + */ + name: string; +} + +/** + * Designer information + */ +export interface FontshareDesigner { + /** + * Designer bio/description + */ + bio: string; + + /** + * Designer links (Twitter, website, etc.) + */ + links: FontshareLink[]; + + /** + * Designer name + */ + name: string; +} + +/** + * Link information + */ +export interface FontshareLink { + /** + * Name of the link platform/site + * Examples: "Twitter", "GitHub", "Website" + */ + name: string; + + /** + * URL of the link (may be null) + */ + url: string | null; +} + +/** + * Font tag/category + */ +export interface FontshareTag { + /** + * Tag name + * Examples: "Magazines", "Branding", "Logos", "Posters" + */ + name: string; +} + +/** + * OpenType feature + */ +export interface FontshareFeature { + /** + * Feature name (descriptive name or null) + * Examples: "Alternate t", "All Alternates", or null + */ + name: string | null; + + /** + * Whether this feature is on by default + */ + on_by_default: boolean; + + /** + * OpenType feature tag (4-character code) + * Examples: "ss01", "frac", "liga", "aalt", "case" + */ + tag: string; +} + +/** + * Variable font axis (for variable fonts) + * Defines the range and properties of a variable font axis (e.g., weight) + */ +export interface FontshareAxis { + /** + * Name of the axis + * Example: "wght" (weight axis) + */ + name: string; + + /** + * CSS property name for the axis + * Example: "wght" + */ + property: string; + + /** + * Default value for the axis + * Example: 420.0, 650.0, 700.0 + */ + range_default: number; + + /** + * Minimum value for the axis + * Example: 300.0, 100.0, 200.0 + */ + range_left: number; + + /** + * Maximum value for the axis + * Example: 900.0, 700.0, 800.0 + */ + range_right: number; +} + +/** + * Individual font style/variant + * Each style represents a single downloadable font file + */ +export interface FontshareStyle { + /** + * Unique identifier for this style + * UUID format + */ + id: string; + + /** + * Whether this is the default style for the font family + * Typically, one style per font is marked as default + */ + default: boolean; + + /** + * CDN URL to the font file + * Protocol-relative URL: "//cdn.fontshare.com/wf/..." + * Note: URL starts with "//" (protocol-relative), may need protocol prepended + */ + file: string; + + /** + * Whether this style is italic + * false for upright, true for italic styles + */ + is_italic: boolean; + + /** + * Whether this is a variable font + * Variable fonts have adjustable axes (weight, slant, etc.) + */ + is_variable: boolean; + + /** + * Typography properties for this style + * Contains measurements like cap height, x-height, ascenders/descenders + * May be empty object {} for some styles + */ + properties: FontshareStyleProperties | Record; + + /** + * Weight information for this style + */ + weight: FontshareWeight; +} + +/** + * Typography/measurement properties for a font style + */ +export interface FontshareStyleProperties { + /** + * Distance from baseline to the top of ascenders + * Example: 1010, 990, 1000 + */ + ascending_leading: number | null; + + /** + * Height of uppercase letters (cap height) + * Example: 710, 680, 750 + */ + cap_height: number | null; + + /** + * Distance from baseline to the bottom of descenders (negative value) + * Example: -203, -186, -220 + */ + descending_leading: number | null; + + /** + * Body height of the font + * Often null in Fontshare data + */ + body_height: number | null; + + /** + * Maximum character width in the font + * Example: 1739, 1739, 1739 + */ + max_char_width: number | null; + + /** + * Height of lowercase x-height + * Example: 480, 494, 523 + */ + x_height: number | null; + + /** + * Maximum Y coordinate (top of ascenders) + * Example: 1010, 990, 1026 + */ + y_max: number | null; + + /** + * Minimum Y coordinate (bottom of descenders) + * Example: -240, -250, -280 + */ + y_min: number | null; +} + +/** + * Weight information for a font style + */ +export interface FontshareWeight { + /** + * Display label for the weight + * Examples: "Light", "Regular", "Bold", "Variable", "Variable Italic" + */ + label: string; + + /** + * Internal name for the weight + * Examples: "Light", "Regular", "Bold", "Variable", "VariableItalic" + */ + name: string; + + /** + * Native/localized name for the weight (if available) + * Often null for Latin-script fonts + */ + native_name: string | null; + + /** + * Numeric weight value + * Examples: 300, 400, 700, 0 (for variable fonts), 1, 2 + * Note: This matches the `weight` property + */ + number: number; + + /** + * Numeric weight value (duplicate of `number`) + * Appears to be redundant with `number` field + */ + weight: number; +} diff --git a/src/lib/types/google_fonts.ts b/src/lib/types/google_fonts.ts new file mode 100644 index 0000000..6dd253c --- /dev/null +++ b/src/lib/types/google_fonts.ts @@ -0,0 +1,104 @@ +/** + * Model of google fonts api response + */ +export interface GoogleFontsApiModel { + /** + * Array of font items returned by the Google Fonts API + * Contains all font families matching the requested query parameters + */ + items: FontItem[]; +} + +export interface FontItem { + /** + * Font family name (e.g., "Roboto", "Open Sans", "Lato") + * This is the name used in CSS font-family declarations + */ + family: string; + + /** + * Font category classification (e.g., "sans-serif", "serif", "display", "handwriting", "monospace") + * Useful for grouping and filtering fonts by style + */ + category: string; + + /** + * Available font variants for this font family + * Array of strings representing available weights and styles + * Examples: ["regular", "italic", "100", "200", "300", "400", "500", "600", "700", "800", "900", "100italic", "900italic"] + * The keys in the `files` object correspond to these variant values + */ + variants: FontVariant[]; + + /** + * Supported character subsets for this font + * Examples: ["latin", "latin-ext", "cyrillic", "greek", "arabic", "devanagari", "vietnamese", "hebrew", "thai", etc.] + * Determines which character sets are included in the font files + */ + subsets: string[]; + + /** + * Font version identifier + * Format: "v" followed by version number (e.g., "v31", "v20", "v1") + * Used to track font updates and cache busting + */ + version: string; + + /** + * Last modification date of the font + * Format: ISO 8601 date string (e.g., "2024-01-15", "2023-12-01") + * Indicates when the font was last updated by the font foundry + */ + lastModified: string; + + /** + * Mapping of font variants to their downloadable URLs + * Keys correspond to values in the `variants` array + * Examples: + * - "regular" → "https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Me4W..." + * - "700" → "https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlf..." + * - "700italic" → "https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzA..." + */ + files: FontFiles; + + /** + * URL to the font menu preview image + * Typically a PNG showing the font family name in the font + * Example: "https://fonts.gstatic.com/l/font?kit=KFOmCnqEu92Fr1Me4W...&s=i2" + */ + menu: string; +} + +/** + * Standard font weights that can appear in Google Fonts API + */ +export type FontWeight = '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'; + +/** + * Italic variant format: e.g., "100italic", "400italic", "700italic" + */ +export type FontWeightItalic = `${FontWeight}italic`; + +/** + * All possible font variants in Google Fonts API + * - Numeric weights: "400", "700", etc. + * - Italic variants: "400italic", "700italic", etc. + * - Legacy names: "regular", "italic", "bold", "bolditalic" + */ +export type FontVariant = + | FontWeight + | FontWeightItalic + | 'regular' + | 'italic' + | 'bold' + | 'bolditalic'; + +/** + * Google Fonts API file mapping + * Dynamic keys that match the variants array + * + * Examples: + * - { "regular": "...", "italic": "...", "700": "...", "700italic": "..." } + * - { "400": "...", "400italic": "...", "900": "..." } + */ +export type FontFiles = Partial>;