UNPKG

@ai-growth/nextjs

Version:

Seamlessly integrate Sanity CMS with Next.js applications for automated blog routing and rendering

441 lines 11.4 kB
/** * @fileoverview TypeScript interfaces for Sanity CMS document types * * This module provides comprehensive type definitions for Sanity documents, * including base types, content types, and utility types for GROQ queries. * * @example * ```typescript * import { SanityPost, SanityPage } from '@ai-growth/nextjs/types'; * * const post: SanityPost = { * _id: 'post-123', * _type: 'post', * title: 'My Blog Post', * slug: { current: 'my-blog-post' }, * // ... other fields * }; * ``` */ /** * Base interface for all Sanity documents. * Every document in Sanity extends this base structure. */ export interface SanityDocument { /** Unique document identifier */ _id: string; /** Document type identifier matching the schema */ _type: string; /** ISO timestamp when document was created */ _createdAt: string; /** ISO timestamp when document was last updated */ _updatedAt: string; /** Document revision identifier for optimistic locking */ _rev: string; } /** * Generic base interface for extending with specific document types * * @template T Additional fields for the specific document type * * @example * ```typescript * interface CustomPost extends SanityDocumentBase<{ * title: string; * content: string; * }> { * _type: 'customPost'; * } * ``` */ export type SanityDocumentBase<T = Record<string, unknown>> = SanityDocument & T; /** * Reference to another Sanity document * * @template T The type of document being referenced */ export interface SanityReference<T extends SanityDocument = SanityDocument> { _type: 'reference'; _ref: string; /** Weak reference that won't prevent document deletion */ _weak?: boolean; /** Referenced document data (when populated in queries) */ _referenceData?: T; } /** * Sanity slug field structure */ export interface SanitySlug { _type: 'slug'; /** Current slug value */ current: string; /** Source field used to generate the slug */ source?: string; } /** * Sanity image asset reference */ export interface SanityImageAsset extends SanityDocument { _type: 'sanity.imageAsset'; url: string; /** Original filename */ originalFilename?: string; /** File size in bytes */ size?: number; /** Image dimensions */ metadata?: { dimensions: { width: number; height: number; aspectRatio: number; }; /** EXIF data and other metadata */ [key: string]: unknown; }; } /** * Sanity image field with asset reference and optional metadata */ export interface SanityImage { _type: 'image'; /** Reference to image asset */ asset: SanityReference<SanityImageAsset>; /** Alternative text for accessibility */ alt?: string; /** Image caption */ caption?: string; /** Crop coordinates */ crop?: { top: number; bottom: number; left: number; right: number; }; /** Hotspot for responsive cropping */ hotspot?: { x: number; y: number; height: number; width: number; }; /** Custom metadata */ [key: string]: unknown; } /** * Sanity file asset reference */ export interface SanityFileAsset extends SanityDocument { _type: 'sanity.fileAsset'; url: string; /** Original filename */ originalFilename?: string; /** File size in bytes */ size?: number; /** MIME type */ mimeType?: string; } /** * Sanity file field with asset reference */ export interface SanityFile { _type: 'file'; /** Reference to file asset */ asset: SanityReference<SanityFileAsset>; /** File title or description */ title?: string; } /** * Base block content structure for Sanity's Portable Text */ export interface SanityBlock { _type: 'block'; _key: string; /** Block style (e.g., 'normal', 'h1', 'h2', etc.) */ style?: string; /** List item information */ listItem?: string; /** List nesting level */ level?: number; /** Array of inline content (spans, inline objects) */ children: SanitySpan[]; /** Block-level marks/annotations */ markDefs?: SanityMarkDef[]; } /** * Inline text span within a block */ export interface SanitySpan { _type: 'span'; _key: string; /** The actual text content */ text: string; /** Applied text marks (bold, italic, links, etc.) */ marks?: string[]; } /** * Mark definition for text annotations (links, custom marks) */ export interface SanityMarkDef { _type: string; _key: string; /** Additional properties based on mark type */ [key: string]: unknown; } /** * Link mark definition */ export interface SanityLinkMark extends SanityMarkDef { _type: 'link'; href: string; /** Open link in new tab */ blank?: boolean; } /** * Array of portable text content (blocks and inline objects) */ export type SanityPortableText = Array<SanityBlock | SanityCustomBlock>; /** * Custom block object (images, videos, custom components) */ export interface SanityCustomBlock { _type: string; _key: string; /** Additional properties based on block type */ [key: string]: unknown; } /** * SEO metadata structure */ export interface SanitySEO { /** Page title for search engines */ title?: string; /** Meta description */ description?: string; /** Canonical URL */ canonical?: string; /** Open Graph image */ image?: SanityImage; /** Additional meta tags */ keywords?: string[]; /** Robots directive */ noIndex?: boolean; /** Prevent following links */ noFollow?: boolean; } /** * Author/User document */ export interface SanityAuthor extends SanityDocument { _type: 'author'; /** Author's full name */ name: string; /** URL-friendly identifier */ slug: SanitySlug; /** Author profile image */ image?: SanityImage; /** Short biography */ bio?: SanityPortableText; /** Email address */ email?: string; /** Website URL */ website?: string; /** Social media links */ social?: { twitter?: string; linkedin?: string; github?: string; [platform: string]: string | undefined; }; } /** * Category/Tag document for content organization */ export interface SanityCategory extends SanityDocument { _type: 'category'; /** Category name */ title: string; /** URL-friendly identifier */ slug: SanitySlug; /** Category description */ description?: string; /** Category color for UI */ color?: string; /** Parent category for hierarchical organization */ parent?: SanityReference<SanityCategory>; } /** * Blog post document */ export interface SanityPost extends SanityDocument { _type: 'post'; /** Post title */ title: string; /** URL-friendly identifier */ slug: SanitySlug; /** Post excerpt/summary */ excerpt?: string; /** Featured image */ mainImage?: SanityImage; /** Post content in Portable Text format */ body?: SanityPortableText; /** Post author */ author?: SanityReference<SanityAuthor>; /** Post categories */ categories?: SanityReference<SanityCategory>[]; /** Publication date */ publishedAt?: string; /** Featured post flag */ featured?: boolean; /** Post status */ status?: 'draft' | 'published' | 'archived'; /** SEO metadata */ seo?: SanitySEO; /** Estimated reading time in minutes */ readingTime?: number; } /** * Static page document */ export interface SanityPage extends SanityDocument { _type: 'page'; /** Page title */ title: string; /** URL-friendly identifier */ slug: SanitySlug; /** Page content in Portable Text format */ body?: SanityPortableText; /** Featured image */ mainImage?: SanityImage; /** Page template/layout identifier */ template?: string; /** Parent page for hierarchical organization */ parent?: SanityReference<SanityPage>; /** Page order for navigation */ order?: number; /** Show in navigation menu */ showInNavigation?: boolean; /** SEO metadata */ seo?: SanitySEO; /** Page status */ status?: 'draft' | 'published' | 'archived'; } /** * Navigation menu document */ export interface SanityNavigation extends SanityDocument { _type: 'navigation'; /** Menu title/identifier */ title: string; /** Menu items */ items: SanityNavigationItem[]; } /** * Navigation menu item */ export interface SanityNavigationItem { _type: 'navigationItem'; _key: string; /** Menu item label */ title: string; /** Link URL */ url?: string; /** Internal page reference */ page?: SanityReference<SanityPage>; /** External link flag */ external?: boolean; /** Open in new tab */ newTab?: boolean; /** Nested menu items */ children?: SanityNavigationItem[]; } /** * Site settings document */ export interface SanitySiteSettings extends SanityDocument { _type: 'siteSettings'; /** Site title */ title: string; /** Site description */ description: string; /** Site logo */ logo?: SanityImage; /** Site favicon */ favicon?: SanityImage; /** Default SEO settings */ defaultSeo?: SanitySEO; /** Social media links */ social?: { [platform: string]: string; }; /** Contact information */ contact?: { email?: string; phone?: string; address?: string; }; /** Google Analytics tracking ID */ googleAnalyticsId?: string; } /** * Union type of all document types for type-safe queries */ export type SanityDocumentType = SanityPost | SanityPage | SanityAuthor | SanityCategory | SanityNavigation | SanitySiteSettings; /** * Extract document type string from document interfaces */ export type SanityDocumentTypeName = SanityDocumentType['_type']; /** * Utility type for GROQ query results with projection * * @template T The base document type * @template P The projected fields */ export type SanityProjection<T, P extends keyof T> = Pick<T, P>; /** * Common projection for list views (id, type, title, slug) */ export type SanityListItem<T extends SanityDocument> = SanityProjection<T, '_id' | '_type'> & { title?: string; slug?: SanitySlug; }; /** * Query result with pagination metadata */ export interface SanityQueryResult<T> { /** Query results */ documents: T[]; /** Total number of documents (if requested) */ total?: number; /** Pagination offset */ offset?: number; /** Page size limit */ limit?: number; } /** * Error structure for Sanity API responses */ export interface SanityError { message: string; statusCode?: number; details?: unknown; } /** * Query parameters for GROQ queries */ export interface SanityQueryParams { [key: string]: string | number | boolean | null | undefined; } /** * Options for Sanity client fetch operations */ export interface SanityFetchOptions { /** Query parameters for GROQ variables */ params?: SanityQueryParams; /** Use CDN for faster response */ useCdn?: boolean; /** Request timeout in milliseconds */ timeout?: number; /** Additional request headers */ headers?: Record<string, string>; } //# sourceMappingURL=sanity.d.ts.map