33 lines
961 B
TypeScript
33 lines
961 B
TypeScript
/**
|
|
* URL slugs for records that have a title.
|
|
*
|
|
* @module
|
|
*/
|
|
|
|
/** A UUID, which a route parameter may carry instead of a slug. */
|
|
export const UUID_RE =
|
|
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
|
|
/**
|
|
* Turns `title` into a URL-safe slug: lowercase ASCII, dash-separated, at most
|
|
* 60 characters, `untitled` when nothing is left.
|
|
*/
|
|
export function slugify(title: string): string {
|
|
const slug = title
|
|
.toLowerCase()
|
|
.normalize("NFD")
|
|
.replace(/[\u0300-\u036f]/g, "") // strip diacritics
|
|
.replace(/[^a-z0-9]+/g, "-") // non-alphanumeric → dash
|
|
.replace(/^-+|-+$/g, "") // trim leading/trailing dashes
|
|
.substring(0, 60);
|
|
return slug || "untitled";
|
|
}
|
|
|
|
/**
|
|
* Returns the slug of a record: its title's slug followed by the start of its
|
|
* `id`, so it stays unique by construction.
|
|
*/
|
|
export function makeSlug(title: string, id: string): string {
|
|
return `${slugify(title)}-${id.substring(0, 8)}`;
|
|
}
|