import { supabase } from '@/lib/supabaseClient'; import { handleError } from './errorHandler'; /** * Generate a URL-safe slug from a name * This is the canonical slug generation function used throughout the app */ export function generateSlugFromName(name: string): string { if (!name) return ''; return name .toLowerCase() .replace(/[^a-z0-9\s-]/g, '') // Remove non-alphanumeric except spaces and hyphens .replace(/\s+/g, '-') // Replace spaces with hyphens .replace(/-+/g, '-') // Replace multiple hyphens with single hyphen .replace(/^-+|-+$/g, '') // Remove leading/trailing hyphens .trim(); } /** * Validate that a user has permission to edit slugs * Only moderators should be able to manually edit slugs */ export function canEditSlug(isModerator: boolean): boolean { return isModerator; } /** * Ensure slug is unique by checking database and appending number if needed */ export async function ensureUniqueSlug( baseSlug: string, tableName: 'parks' | 'rides' | 'companies' | 'ride_models', excludeId?: string ): Promise { let slug = baseSlug; let counter = 1; while (true) { // Check if slug exists let query = supabase .from(tableName) .select('id') .eq('slug', slug); // Exclude current record when editing if (excludeId) { query = query.neq('id', excludeId); } const { data, error } = await query.limit(1); if (error) { handleError(error, { action: 'Check Slug Uniqueness', metadata: { tableName, slug } }); throw error; } // If no match found, slug is unique if (!data || data.length === 0) { return slug; } // Append counter and try again counter++; slug = `${baseSlug}-${counter}`; } } /** * Generate and ensure unique slug in one operation */ export async function generateUniqueSlug( name: string, tableName: 'parks' | 'rides' | 'companies' | 'ride_models', excludeId?: string ): Promise { const baseSlug = generateSlugFromName(name); return ensureUniqueSlug(baseSlug, tableName, excludeId); }