Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1031x 1031x 1031x 1031x 1031x 1031x 1031x 1031x 1031x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 4x 4x 4x 4x 1004x 1004x 1004x 1004x 1004x 1x 1x 1004x 3x 3x 3x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 1x 1x 1x 1x 1x 15x 15x 15x 15x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7x 7x 7x 7x | /**
* Slug Generation Utilities
* Generate URL-friendly slugs from strings
*/
/**
* Generate URL-friendly slug from string
* - Converts to lowercase
* - Removes special characters
* - Replaces spaces with hyphens
* - Removes consecutive hyphens
*
* @example
* generateSlug("Hello World!") // => "hello-world"
* generateSlug("Product #123") // => "product-123"
*/
export function generateSlug(text: string): string {
return text
.toLowerCase()
.trim()
.replace(/[^\w\s-]/g, '') // Remove special chars except word chars, spaces, and hyphens
.replace(/\s+/g, '-') // Replace spaces with hyphens
.replace(/-+/g, '-') // Replace multiple hyphens with single hyphen
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
}
/**
* Generate unique slug by appending number if slug already exists
* Useful for generating unique slugs for products, categories, etc.
*
* @param text - The text to generate slug from
* @param checkExists - Function that checks if a slug already exists
* @returns Unique slug
*
* @example
* const slug = await generateUniqueSlug(
* "My Product",
* async (slug) => {
* const existing = await prisma.product.findUnique({ where: { slug } });
* return !!existing;
* }
* );
*/
export async function generateUniqueSlug(
text: string,
checkExists: (slug: string) => Promise<boolean>
): Promise<string> {
let slug = generateSlug(text);
let counter = 1;
// Keep trying with incremented counter until we find a unique slug
while (await checkExists(slug)) {
slug = `${generateSlug(text)}-${counter}`;
counter++;
// Safety limit to prevent infinite loops
if (counter > 1000) {
throw new Error('Could not generate unique slug after 1000 attempts');
}
}
return slug;
}
/**
* Generate slug with date prefix (YYYY-MM-DD-slug-text)
* Useful for events or time-based content
*
* @example
* generateSlugWithDate("Summer Sale Event") // => "2025-11-21-summer-sale-event"
*/
export function generateSlugWithDate(text: string, date: Date = new Date()): string {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const datePrefix = `${year}-${month}-${day}`;
const slug = generateSlug(text);
return `${datePrefix}-${slug}`;
}
/**
* Validate if a string is a valid slug
* Checks if string contains only lowercase letters, numbers, and hyphens
*/
export function isValidSlug(slug: string): boolean {
const slugPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
return slugPattern.test(slug);
}
/**
* Extract slug from URL path
* Useful for parsing URLs
*
* @example
* extractSlugFromPath("/category/electronics") // => "electronics"
* extractSlugFromPath("/products/awesome-product/") // => "awesome-product"
*/
export function extractSlugFromPath(path: string): string {
const segments = path.split('/').filter(Boolean);
return segments[segments.length - 1] || '';
}
|