| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 | 
							- const unidecode = require('unidecode');
 
- const INVALID_SEPARATOR_REGEXP = /[^-._~]/;
 
- const TITLE_CASE_REGEXP = /(?:^| )[a-z]/g;
 
- const CONVERT_REGEXP = /[^A-Za-z0-9]+|([a-z])([A-Z])/g;
 
- const CONVERT_SEPARATOR_REGEXP = / /g;
 
- const REVERT_REGEXP = {}; /* RegExp intances are based on the separator and then cached */
 
- const REVERT_AUTO_REGEXP = /[-._~]+|([a-z])([A-Z])/g;
 
- const REVERT_CAMEL_CASE_REGEXP = /([a-z])([A-Z])/g;
 
- /**
 
-  * Creates a new instance of url-slug
 
-  */
 
- function UrlSlug(separator, transform) {
 
-     /* Set defaults */
 
-     separator = null == separator ? '-' : separator;
 
-     transform = null == transform ? 'lowercase' : transform;
 
-     /* Validate through prepare method */
 
-     var options = this.prepare(separator, transform);
 
-     this.separator = options.separator;
 
-     this.transform = options.transform;
 
- }
 
- /**
 
-  * Builtin transformers
 
-  */
 
- UrlSlug.prototype.transformers = {
 
-     lowercase: function (string) {
 
-         return string.toLowerCase();
 
-     },
 
-     uppercase: function (string) {
 
-         return string.toUpperCase();
 
-     },
 
-     titlecase: function (string) {
 
-         return string.toLowerCase().replace(TITLE_CASE_REGEXP, function (character) {
 
-             return character.toUpperCase();
 
-         });
 
-     },
 
- };
 
- /**
 
-  * Check and return validated options
 
-  */
 
- UrlSlug.prototype.prepare = function (separator, transform) {
 
-     if (null == separator) {
 
-         separator = this.separator;
 
-     } else if ('string' !== typeof separator) {
 
-         throw new Error('Invalid separator, must be a string: "' + separator + '".');
 
-     } else if (INVALID_SEPARATOR_REGEXP.test(separator)) {
 
-         throw new Error('Invalid separator, has invalid characters: "' + separator + '".');
 
-     }
 
-     if (null == transform) {
 
-         transform = this.transform;
 
-     } else if (false === transform) {
 
-         transform = false;
 
-     } else if (this.transformers[transform]) {
 
-         transform = this.transformers[transform];
 
-     } else if ('function' !== typeof transform) {
 
-         throw new Error('Invalid transform, must be a builtin transform or a function: "' + transform + '".');
 
-     }
 
-     return {
 
-         separator: separator,
 
-         transform: transform,
 
-     }
 
- }
 
- /**
 
-  * Converts a string into a slug
 
-  */
 
- UrlSlug.prototype.convert = function (string, separator, transform) {
 
-     if ('string' !== typeof string) {
 
-         throw new Error('Invalid value, must be a string: "' + string + '".');
 
-     }
 
-     options = this.prepare(separator, transform);
 
-     /* Transliterate and replace invalid characters, then replace non alphanumeric characters with spaces */
 
-     string = unidecode(string).replace('[?]', '').replace(CONVERT_REGEXP, '$1 $2').trim();
 
-     /* Pass string through transform function */
 
-     if (options.transform) {
 
-         string = options.transform(string);
 
-     }
 
-     /* Replace spaces with separator and return */
 
-     return string.replace(CONVERT_SEPARATOR_REGEXP, options.separator);
 
- };
 
- /**
 
-  * Reverts a slug back to a string
 
-  */
 
- UrlSlug.prototype.revert = function (slug, separator, transform) {
 
-     if ('string' !== typeof slug) {
 
-         throw new Error('Invalid value, must be a string: "' + slug + '".');
 
-     }
 
-     options = this.prepare(separator, transform);
 
-     /* Determine which regular expression will be used to—and—remove separators */
 
-     if ('' === options.separator) {
 
-         slug = slug.replace(REVERT_CAMEL_CASE_REGEXP, '$1 $2');
 
-     } else if ('string' === typeof separator) {
 
-         /* If separator argument was set as string, don't check options.separator,
 
-         it can return the default separator (this.separator) */
 
-         REVERT_REGEXP[separator] = REVERT_REGEXP[separator] || new RegExp('\\' + separator.split('').join('\\'), 'g');
 
-         slug = slug.replace(REVERT_REGEXP[separator], ' ');
 
-     } else {
 
-         slug = slug.replace(REVERT_AUTO_REGEXP, '$1 $2');
 
-     }
 
-     /* Pass slug through transform function and return. Check if transform
 
-     was set in arguments, to avoid using the default transform. */
 
-     return transform && options.transform ? options.transform(slug) : slug;
 
- };
 
- /* Prepare the global instance and export it */
 
- var urlSlug = new UrlSlug;
 
- var globalInstance = urlSlug.convert.bind(urlSlug);
 
- globalInstance.UrlSlug = UrlSlug;
 
- globalInstance.convert = globalInstance;
 
- globalInstance.revert = urlSlug.revert.bind(urlSlug);
 
- module.exports = globalInstance;
 
 
  |