diff --git a/src/entities/Font/api/fontshare/fontshare.ts b/src/entities/Font/api/fontshare/fontshare.ts index ae8420a..0689d93 100644 --- a/src/entities/Font/api/fontshare/fontshare.ts +++ b/src/entities/Font/api/fontshare/fontshare.ts @@ -43,11 +43,9 @@ export interface FontshareParams extends QueryParams { /** * Fontshare API response wrapper - * Extends collection model with additional metadata + * Re-exported from model/types for backward compatibility */ -export interface FontshareResponse extends FontshareApiModel { - // Response structure matches FontshareApiModel -} +export type FontshareResponse = FontshareApiModel; /** * Fetch fonts from Fontshare API diff --git a/src/entities/Font/api/google/googleFonts.ts b/src/entities/Font/api/google/googleFonts.ts index de3295b..07ba6ad 100644 --- a/src/entities/Font/api/google/googleFonts.ts +++ b/src/entities/Font/api/google/googleFonts.ts @@ -7,6 +7,10 @@ * @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'; @@ -43,25 +47,15 @@ export interface GoogleFontsParams extends QueryParams { /** * Google Fonts API response wrapper + * Re-exported from model/types for backward compatibility */ -export interface GoogleFontsResponse { - kind: string; - items: GoogleFontItem[]; -} +export type GoogleFontsResponse = GoogleFontsApiModel; /** * Simplified font item from Google Fonts API + * Re-exported from model/types for backward compatibility */ -export interface GoogleFontItem { - family: string; - category: string; - variants: string[]; - subsets: string[]; - version: string; - lastModified: string; - files: Record; - menu: string; -} +export type GoogleFontItem = FontItem; /** * Google Fonts API base URL diff --git a/src/entities/Font/api/normalize/normalize.test.ts b/src/entities/Font/api/normalize/normalize.test.ts index f757d06..c1e5dd2 100644 --- a/src/entities/Font/api/normalize/normalize.test.ts +++ b/src/entities/Font/api/normalize/normalize.test.ts @@ -1,11 +1,13 @@ -import type { FontshareFont } from '$entities/Font'; +import type { + FontshareFont, + GoogleFontItem, + UnifiedFont, +} from '$entities/Font'; import { describe, expect, it, } from 'vitest'; -import type { GoogleFontItem } from '../google/googleFonts'; -import type { UnifiedFont } from './normalize'; import { normalizeFontshareFont, normalizeFontshareFonts, diff --git a/src/entities/Font/api/normalize/normalize.ts b/src/entities/Font/api/normalize/normalize.ts index f337043..2dda371 100644 --- a/src/entities/Font/api/normalize/normalize.ts +++ b/src/entities/Font/api/normalize/normalize.ts @@ -7,89 +7,16 @@ import type { FontCategory, + FontFeatures, + FontMetadata, FontProvider, + FontStyleUrls, FontSubset, -} from '$entities/Font'; -import type { FontshareFont } from '$entities/Font'; -import type { GoogleFontItem } from './googleFonts'; - -/** - * Font variant types (standardized) - */ -export type UnifiedFontVariant = string; - -/** - * Font style URLs - */ -export interface FontStyleUrls { - /** Regular weight URL */ - regular?: string; - /** Italic URL */ - italic?: string; - /** Bold weight URL */ - bold?: string; - /** Bold italic URL */ - boldItalic?: string; -} - -/** - * Font metadata - */ -export interface FontMetadata { - /** Timestamp when font was cached */ - cachedAt: number; - /** Font version from provider */ - version?: string; - /** Last modified date from provider */ - lastModified?: string; - /** Popularity rank (if available from provider) */ - popularity?: number; -} - -/** - * Font features (variable fonts, axes, tags) - */ -export interface FontFeatures { - /** Whether this is a variable font */ - isVariable?: boolean; - /** Variable font axes (for Fontshare) */ - axes?: Array<{ - name: string; - property: string; - default: number; - min: number; - max: number; - }>; - /** Usage tags (for Fontshare) */ - tags?: string[]; -} - -/** - * Unified font model - * - * Combines Google Fonts and Fontshare data into a common interface - * for consistent font handling across the application. - */ -export interface UnifiedFont { - /** Unique identifier (Google: family name, Fontshare: slug) */ - id: string; - /** Font display name */ - name: string; - /** Font provider (google | fontshare) */ - provider: FontProvider; - /** Font category classification */ - category: FontCategory; - /** Supported character subsets */ - subsets: FontSubset[]; - /** Available font variants (weights, styles) */ - variants: UnifiedFontVariant[]; - /** URL mapping for font file downloads */ - styles: FontStyleUrls; - /** Additional metadata */ - metadata: FontMetadata; - /** Advanced font features */ - features: FontFeatures; -} + FontshareFont, + GoogleFontItem, + UnifiedFont, + UnifiedFontVariant, +} from '../../model/types'; /** * Map Google Fonts category to unified FontCategory diff --git a/src/entities/Font/index.ts b/src/entities/Font/index.ts index eba2be9..dfd765f 100644 --- a/src/entities/Font/index.ts +++ b/src/entities/Font/index.ts @@ -23,31 +23,38 @@ export { normalizeGoogleFonts, } from './api/normalize'; export type { - FontFeatures, - FontMetadata, - FontStyleUrls, - UnifiedFont, - UnifiedFontVariant, -} from './api/normalize'; -export type { + // Domain types FontCategory, + FontCollectionFilters, + FontCollectionSort, + // Store types + FontCollectionState, + FontCollectionStore, + FontFeatures, + FontFiles, + FontItem, + FontMetadata, FontProvider, - FontSubset, -} from './model/types/font'; -export type { + // Fontshare API types FontshareApiModel, + FontshareAxis, FontshareDesigner, FontshareFeature, FontshareFont, + FontshareLink, FontsharePublisher, FontshareStyle, FontshareStyleProperties, FontshareTag, FontshareWeight, -} from './model/types/fontshare_fonts'; -export type { - FontFiles, - FontItem, + FontStyleUrls, + FontSubset, FontVariant, + FontWeight, + FontWeightItalic, + // Google Fonts API types GoogleFontsApiModel, -} from './model/types/google_fonts'; + // Normalization types + UnifiedFont, + UnifiedFontVariant, +} from './model/types'; diff --git a/src/entities/Font/model/stores/fontCollectionStore.ts b/src/entities/Font/model/stores/fontCollectionStore.ts index f9e1aa9..cff581a 100644 --- a/src/entities/Font/model/stores/fontCollectionStore.ts +++ b/src/entities/Font/model/stores/fontCollectionStore.ts @@ -7,7 +7,16 @@ * Provides derived stores for filtered/sorted fonts. */ -import type { UnifiedFont } from '$entities/Font/api/normalize'; +import type { + FontCategory, + FontCollectionFilters, + FontCollectionSort, + FontCollectionState, + FontCollectionStore, + FontProvider, + FontSubset, + UnifiedFont, +} from '$entities/Font'; import { createCollectionCache } from '$shared/fetch/collectionCache'; import type { Readable, @@ -18,84 +27,6 @@ import { get, writable, } from 'svelte/store'; -import type { - FontCategory, - FontProvider, -} from '../types/font'; - -/** - * Font collection state - */ -export interface FontCollectionState { - /** All cached fonts */ - fonts: Record; - /** Active filters */ - filters: FontCollectionFilters; - /** Sort configuration */ - sort: FontCollectionSort; -} - -/** - * Font collection filters - */ -export interface FontCollectionFilters { - /** Search query */ - searchQuery?: string; - /** Filter by provider */ - provider?: FontProvider; - /** Filter by category */ - category?: FontCategory; - /** Filter by subsets */ - subsets?: string[]; -} - -/** - * Font collection sort configuration - */ -export interface FontCollectionSort { - /** Sort field */ - field: 'name' | 'popularity' | 'category'; - /** Sort direction */ - direction: 'asc' | 'desc'; -} - -/** - * Font collection store interface - */ -export interface FontCollectionStore { - /** Main state store */ - state: Writable; - /** All fonts as array */ - fonts: Readable; - /** Filtered fonts as array */ - filteredFonts: Readable; - /** Number of fonts in collection */ - count: Readable; - /** Loading state */ - isLoading: Readable; - /** Error state */ - error: Readable; - /** Add fonts to collection */ - addFonts: (fonts: UnifiedFont[]) => void; - /** Add single font to collection */ - addFont: (font: UnifiedFont) => void; - /** Remove font from collection */ - removeFont: (fontId: string) => void; - /** Clear all fonts */ - clear: () => void; - /** Update filters */ - setFilters: (filters: Partial) => void; - /** Clear filters */ - clearFilters: () => void; - /** Update sort configuration */ - setSort: (sort: FontCollectionSort) => void; - /** Get font by ID */ - getFont: (fontId: string) => UnifiedFont | undefined; - /** Get fonts by provider */ - getFontsByProvider: (provider: FontProvider) => UnifiedFont[]; - /** Get fonts by category */ - getFontsByCategory: (category: FontCategory) => UnifiedFont[]; -} /** * Create font collection store @@ -172,7 +103,7 @@ export function createFontCollectionStore( // Apply subset filter if ($state.filters.subsets?.length) { filtered = filtered.filter(font => - $state.filters.subsets!.some(subset => font.subsets.includes(subset as any)) + $state.filters.subsets!.some(subset => font.subsets.includes(subset as FontSubset)) ); } diff --git a/src/entities/Font/model/types/fontshare_fonts.ts b/src/entities/Font/model/types.ts similarity index 51% rename from src/entities/Font/model/types/fontshare_fonts.ts rename to src/entities/Font/model/types.ts index da7da3e..9b8093f 100644 --- a/src/entities/Font/model/types/fontshare_fonts.ts +++ b/src/entities/Font/model/types.ts @@ -1,3 +1,144 @@ +/** + * ============================================================================ + * DOMAIN TYPES + * ============================================================================ + */ + +/** + * Font category + */ +export type FontCategory = 'sans-serif' | 'serif' | 'display' | 'handwriting' | 'monospace'; + +/** + * Font provider + */ +export type FontProvider = 'google' | 'fontshare'; + +/** + * Font subset + */ +export type FontSubset = 'latin' | 'latin-ext' | 'cyrillic' | 'greek' | 'arabic' | 'devanagari'; + +/** + * ============================================================================ + * GOOGLE FONTS API TYPES + * ============================================================================ + */ + +/** + * 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[]; +} + +/** + * Individual font from Google Fonts API + */ +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>; + +/** + * ============================================================================ + * FONTHARE API TYPES + * ============================================================================ + */ + import type { CollectionApiModel } from '$shared/types/collection'; export const FONTSHARE_API_URL = 'https://api.fontshare.com/v2' as const; @@ -439,3 +580,167 @@ export interface FontshareWeight { */ weight: number; } + +/** + * ============================================================================ + * NORMALIZATION TYPES + * ============================================================================ + */ + +/** + * Font variant types (standardized) + */ +export type UnifiedFontVariant = string; + +/** + * Font style URLs + */ +export interface FontStyleUrls { + /** Regular weight URL */ + regular?: string; + /** Italic URL */ + italic?: string; + /** Bold weight URL */ + bold?: string; + /** Bold italic URL */ + boldItalic?: string; +} + +/** + * Font metadata + */ +export interface FontMetadata { + /** Timestamp when font was cached */ + cachedAt: number; + /** Font version from provider */ + version?: string; + /** Last modified date from provider */ + lastModified?: string; + /** Popularity rank (if available from provider) */ + popularity?: number; +} + +/** + * Font features (variable fonts, axes, tags) + */ +export interface FontFeatures { + /** Whether this is a variable font */ + isVariable?: boolean; + /** Variable font axes (for Fontshare) */ + axes?: Array<{ + name: string; + property: string; + default: number; + min: number; + max: number; + }>; + /** Usage tags (for Fontshare) */ + tags?: string[]; +} + +/** + * Unified font model + * + * Combines Google Fonts and Fontshare data into a common interface + * for consistent font handling across the application. + */ +export interface UnifiedFont { + /** Unique identifier (Google: family name, Fontshare: slug) */ + id: string; + /** Font display name */ + name: string; + /** Font provider (google | fontshare) */ + provider: FontProvider; + /** Font category classification */ + category: FontCategory; + /** Supported character subsets */ + subsets: FontSubset[]; + /** Available font variants (weights, styles) */ + variants: UnifiedFontVariant[]; + /** URL mapping for font file downloads */ + styles: FontStyleUrls; + /** Additional metadata */ + metadata: FontMetadata; + /** Advanced font features */ + features: FontFeatures; +} + +/** + * ============================================================================ + * STORE TYPES + * ============================================================================ + */ + +/** + * Font collection state + */ +export interface FontCollectionState { + /** All cached fonts */ + fonts: Record; + /** Active filters */ + filters: FontCollectionFilters; + /** Sort configuration */ + sort: FontCollectionSort; +} + +/** + * Font collection filters + */ +export interface FontCollectionFilters { + /** Search query */ + searchQuery?: string; + /** Filter by provider */ + provider?: FontProvider; + /** Filter by category */ + category?: FontCategory; + /** Filter by subsets */ + subsets?: string[]; +} + +/** + * Font collection sort configuration + */ +export interface FontCollectionSort { + /** Sort field */ + field: 'name' | 'popularity' | 'category'; + /** Sort direction */ + direction: 'asc' | 'desc'; +} + +/** + * Font collection store interface + */ +export interface FontCollectionStore { + /** Main state store */ + state: import('svelte/store').Writable; + /** All fonts as array */ + fonts: import('svelte/store').Readable; + /** Filtered fonts as array */ + filteredFonts: import('svelte/store').Readable; + /** Number of fonts in collection */ + count: import('svelte/store').Readable; + /** Loading state */ + isLoading: import('svelte/store').Readable; + /** Error state */ + error: import('svelte/store').Readable; + /** Add fonts to collection */ + addFonts: (fonts: UnifiedFont[]) => void; + /** Add single font to collection */ + addFont: (font: UnifiedFont) => void; + /** Remove font from collection */ + removeFont: (fontId: string) => void; + /** Clear all fonts */ + clear: () => void; + /** Update filters */ + setFilters: (filters: Partial) => void; + /** Clear filters */ + clearFilters: () => void; + /** Update sort configuration */ + setSort: (sort: FontCollectionSort) => void; + /** Get font by ID */ + getFont: (fontId: string) => UnifiedFont | undefined; + /** Get fonts by provider */ + getFontsByProvider: (provider: FontProvider) => UnifiedFont[]; + /** Get fonts by category */ + getFontsByCategory: (category: FontCategory) => UnifiedFont[]; +} diff --git a/src/entities/Font/model/types/font.ts b/src/entities/Font/model/types/font.ts deleted file mode 100644 index 3222835..0000000 --- a/src/entities/Font/model/types/font.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Font category - */ -export type FontCategory = 'sans-serif' | 'serif' | 'display' | 'handwriting' | 'monospace'; - -/** - * Font provider - */ -export type FontProvider = 'google' | 'fontshare'; - -/** - * Font subset - */ -export type FontSubset = 'latin' | 'latin-ext' | 'cyrillic' | 'greek' | 'arabic' | 'devanagari'; diff --git a/src/entities/Font/model/types/google_fonts.ts b/src/entities/Font/model/types/google_fonts.ts deleted file mode 100644 index 6dd253c..0000000 --- a/src/entities/Font/model/types/google_fonts.ts +++ /dev/null @@ -1,104 +0,0 @@ -/** - * 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>;