/** * Utility functions for normalizing and generating unique Piclet IDs */ /** * Normalize object name for use in unique ID * Examples: * "Eiffel Tower" -> "eiffel_tower" * "Coffee Mug!" -> "coffee_mug" * " Pillow " -> "pillow" */ export function normalizeObjectName(objectName: string): string { return objectName .toLowerCase() .trim() .replace(/[^a-z0-9\s]/g, '') // Remove special characters .replace(/\s+/g, '_') // Replace spaces with underscores .replace(/_+/g, '_') // Collapse multiple underscores .replace(/^_|_$/g, ''); // Remove leading/trailing underscores } /** * Normalize variation attribute for use in unique ID * Examples: * "Night Time" -> "night_time" * "Red & Blue" -> "red_blue" */ export function normalizeVariation(variation: string): string { return variation .toLowerCase() .trim() .replace(/[^a-z0-9\s]/g, '') // Remove special characters .replace(/\s+/g, '_') // Replace spaces with underscores .replace(/_+/g, '_') // Collapse multiple underscores .replace(/^_|_$/g, ''); // Remove leading/trailing underscores } /** * Generate unique Piclet ID from object name and optional variation * Examples: * generatePicletId("Eiffel Tower", "night") -> "eiffel_tower_night" * generatePicletId("Pillow", "") -> "pillow" * generatePicletId("Coffee Mug", undefined) -> "coffee_mug" */ export function generatePicletId(objectName: string, variation?: string): string { const normalizedObject = normalizeObjectName(objectName); if (!variation || variation.trim() === '') { return normalizedObject; } const normalizedVariation = normalizeVariation(variation); if (normalizedVariation === '') { return normalizedObject; } return `${normalizedObject}_${normalizedVariation}`; } /** * Parse a Piclet ID back into its components * Examples: * parsePicletId("eiffel_tower_night") -> { object: "eiffel tower", variation: "night" } * parsePicletId("pillow") -> { object: "pillow", variation: undefined } */ export function parsePicletId(picletId: string): { object: string; variation?: string } { const parts = picletId.split('_'); if (parts.length === 1) { return { object: parts[0].replace(/_/g, ' ') }; } // Last part is the variation, everything else is the object const variation = parts[parts.length - 1]; const object = parts.slice(0, -1).join(' '); return { object: object.replace(/_/g, ' '), variation: variation }; }