/** * Content Item Fixture Generator * * Provides type-safe helpers for creating ContentItem objects in tests. */ import type { ContentItem } from '@wavespec/types'; /** * Content type discriminator */ export type ContentType = 'text' | 'image' | 'resource'; /** * Creates a ContentItem with type-specific defaults * * Generates a complete ContentItem object with sensible defaults based on the content type. * Override any field via the overrides parameter. * * @param type - Content type (text, image, resource) * @param overrides - Partial ContentItem to override defaults * @returns Complete ContentItem object * * @example * ```typescript * // Text content * const text = createContentItem('text', { * text: 'Hello, world!', * mimeType: 'text/plain' * }); * * // Image content with base64 data * const image = createContentItem('image', { * data: 'iVBORw0KGgoAAAANSUhEUgA...', * mimeType: 'image/png' * }); * * // Resource content * const resource = createContentItem('resource', { * data: 'eyJuYW1lIjoiQWxpY2UifQ==', * mimeType: 'application/json' * }); * ``` */ export function createContentItem( type: ContentType, overrides: Partial = {} ): ContentItem { const base: ContentItem = { type, ...overrides, }; // Apply type-specific defaults if fields not provided switch (type) { case 'text': return { ...base, text: overrides.text ?? 'Sample text content', mimeType: overrides.mimeType ?? 'text/plain', }; case 'image': return { ...base, data: overrides.data ?? 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==', // 1x1 transparent PNG mimeType: overrides.mimeType ?? 'image/png', }; case 'resource': return { ...base, data: overrides.data ?? 'eyJzYW1wbGUiOiJkYXRhIn0=', // {"sample":"data"} in base64 mimeType: overrides.mimeType ?? 'application/octet-stream', }; default: // TypeScript exhaustiveness check const _exhaustive: never = type; throw new Error(`Unknown content type: ${_exhaustive}`); } } /** * Helper: Creates a text ContentItem * * @param text - Text content * @param mimeType - MIME type (default: "text/plain") * @returns Text ContentItem * * @example * ```typescript * const text = text('Hello, world!'); * const markdown = text('# Title', 'text/markdown'); * const json = text('{"key": "value"}', 'application/json'); * ``` */ export function text(text: string, mimeType = 'text/plain'): ContentItem { return createContentItem('text', { text, mimeType }); } /** * Helper: Creates an image ContentItem * * @param data - Base64-encoded image data * @param mimeType - MIME type (default: "image/png") * @returns Image ContentItem * * @example * ```typescript * const png = image('iVBORw0KGgoAAAANSUhEUgA...'); * const jpg = image('data...', 'image/jpeg'); * ``` */ export function image(data: string, mimeType = 'image/png'): ContentItem { return createContentItem('image', { data, mimeType }); } /** * Helper: Creates a resource ContentItem * * @param data - Base64-encoded resource data * @param mimeType - MIME type (default: "application/octet-stream") * @returns Resource ContentItem * * @example * ```typescript * const binary = resource('SGVsbG8gV29ybGQh'); // "Hello World!" in base64 * const json = resource('eyJrZXkiOiJ2YWx1ZSJ9', 'application/json'); * ``` */ export function resource(data: string, mimeType = 'application/octet-stream'): ContentItem { return createContentItem('resource', { data, mimeType }); } /** * Helper: Creates a JSON text ContentItem from an object * * @param obj - Object to serialize as JSON * @returns Text ContentItem with JSON MIME type * * @example * ```typescript * const jsonContent = json({ name: 'Alice', age: 30 }); * // Returns: { type: 'text', text: '{"name":"Alice","age":30}', mimeType: 'application/json' } * ``` */ export function json(obj: unknown): ContentItem { return text(JSON.stringify(obj), 'application/json'); }