package utils import ( "fmt" "regexp" "strings" ) var ( slugRegex = regexp.MustCompile(`^[a-z0-9-]+$`) reservedSlugs = map[string]bool{ "admin": true, "api": true, "auth": true, "system": true, "root": true, "super": true, "public": true, "internal": true, "baron": true, "sso": true, "login": true, "logout": true, "signup": true, "register": true, "tenant": true, "user": true, "dev": true, "stage": true, "prod": true, "test": true, "static": true, "assets": true, "image": true, "img": true, "mail": true, "smtp": true, "pop": true, "imap": true, "ns": true, "mx": true, "webmaster": true, "security": true, "support": true, "help": true, "billing": true, "account": true, "config": true, "status": true, "health": true, "metrics": true, "grafana": true, "prometheus": true, } ) // ValidateSlug checks if a slug meets requirements and is not reserved. func ValidateSlug(slug string) (bool, string) { s := strings.ToLower(strings.TrimSpace(slug)) if len(s) < 3 || len(s) > 32 { return false, "slug must be between 3 and 32 characters" } if !slugRegex.MatchString(s) { return false, "slug can only contain lowercase letters, numbers, and hyphens" } if strings.HasPrefix(s, "-") || strings.HasSuffix(s, "-") { return false, "slug cannot start or end with a hyphen" } if reservedSlugs[s] { return false, "slug is a reserved keyword" } return true, "" } // GenerateSlug generates a base slug from a given string. // It removes special characters, replaces spaces with hyphens, and converts to lowercase. func GenerateSlug(name string) string { // Convert to lowercase s := strings.ToLower(strings.TrimSpace(name)) // Replace non-alphanumeric characters (including spaces) with a hyphen re := regexp.MustCompile(`[^a-z0-9]+`) s = re.ReplaceAllString(s, "-") // Remove leading and trailing hyphens s = strings.Trim(s, "-") // Handle empty slug if s == "" { s = "tenant" } // Truncate to maximum length of 32 (reserving space for suffixes) if len(s) > 25 { s = s[:25] s = strings.TrimSuffix(s, "-") } return s } // GenerateUniqueSlug generates a unique slug by appending a suffix if the base slug exists. // It takes the base name and a checker function that returns true if the slug already exists. func GenerateUniqueSlug(name string, exists func(string) bool) string { baseSlug := GenerateSlug(name) slug := baseSlug counter := 1 for reservedSlugs[slug] || exists(slug) { slug = fmt.Sprintf("%s-%d", baseSlug, counter) counter++ } return slug }