diff --git a/src/index.ts b/src/index.ts index 37ae063..204d6a4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -167,6 +167,7 @@ export { truncate, htmlEscape, htmlUnescape, + slugify, } from './strings'; export { parseMs, since, blockTimer } from './time'; diff --git a/src/strings/index.ts b/src/strings/index.ts index 50fefec..25cc364 100644 --- a/src/strings/index.ts +++ b/src/strings/index.ts @@ -3,6 +3,7 @@ import { capitalize } from '..'; export { capitalize, capitalizeWords } from './capitalize'; export { truncate } from './truncate'; export { htmlEscape, htmlUnescape } from './escape'; +export { slugify } from './slugify'; /** * Formats the given string in camel case fashion diff --git a/src/strings/slugify.spec.ts b/src/strings/slugify.spec.ts new file mode 100644 index 0000000..399a43e --- /dev/null +++ b/src/strings/slugify.spec.ts @@ -0,0 +1,24 @@ +import { describe, expect, test } from 'bun:test'; +import { slugify } from './slugify'; + +describe('slugify', () => { + test('should return the original string if it is already slug compliant', () => { + expect(slugify('hello')).toBe('hello'); + }); + + test('should replace spaces with hyphens', () => { + expect(slugify('hello world')).toBe('hello-world'); + }); + + test('should remove consecutive hyphens', () => { + expect(slugify('hello world')).toBe('hello-world'); + }); + + test('should remove left and right hyphens', () => { + expect(slugify(' hello world ')).toBe('hello-world'); + }); + + test('should remove accentued and special characters', () => { + expect(slugify("Bonsoir l'Amérique")).toBe('bonsoir-lamerique'); + }); +}); diff --git a/src/strings/slugify.ts b/src/strings/slugify.ts new file mode 100644 index 0000000..b3cb3c9 --- /dev/null +++ b/src/strings/slugify.ts @@ -0,0 +1,23 @@ +/** + * Formats the given string in slug url compatible fashion + * + * slugify('hello world') -> 'hello-world' + * slugify('va va_VOOM') -> 'va-va-voom' + * slugify('bonjour l\'Amérique !') -> 'bonjour-lamerique' + * slugify('helloWord 11') -> 'hello-word-11' + * @param {string} str The String to format + * @param text + * @returns {string} The formatted String + */ +export const slugify = (text: string) => { + return text + .normalize('NFD') + .replaceAll(/[\u0300-\u036F]/g, '') + .toLowerCase() + .trim() + .replaceAll(/\s+/g, '-') + .replaceAll(/[^\w-]+/g, '') + .replaceAll(/-{2,}/g, '-') + .replace(/^-+/, '') + .replace(/-+$/, ''); +};