Comparing version 3.0.0-beta.0 to 3.0.0-beta.1
123
index.js
@@ -8,53 +8,48 @@ "use strict"; | ||
exports.revert = revert; | ||
exports.default = exports.UPPERCASE_TRANSFORMER = exports.TITLECASE_TRANSFORMER = exports.LOWERCASE_TRANSFORMER = void 0; | ||
exports.default = exports.UPPERCASE_TRANSFORMER = exports.TITLECASE_TRANSFORMER = exports.SENTENCECASE_TRANSFORMER = exports.LOWERCASE_TRANSFORMER = void 0; | ||
var COMBINING_CHARS = /[\u0300-\u036F\u1AB0-\u1AFF\u1DC0-\u1DFF]+/g; | ||
var INVALID_SEPARATOR = /[^-._~]/; | ||
var CAMELCASE_PATTERN = '(?:[a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))'; | ||
var CONVERT = /[A-Za-z\d]+/g; | ||
var CONVERT_CAMELCASE = new RegExp("[A-Za-z0-9]*?".concat(CAMELCASE_PATTERN, "|[A-Za-z0-9]+"), 'g'); | ||
var REVERT = /[^-._~]+/g; | ||
var CCASE = '(?:[a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))'; | ||
var CONVERT_CAMELCASE = new RegExp("[A-Za-z0-9]*?".concat(CCASE, "|[A-Za-z0-9]+"), 'g'); | ||
var REVERT_CAMELCASE = new RegExp("[^-._~]*?".concat(CCASE, "|[^-._~]+"), 'g'); | ||
var REVERT_CAMELCASE_WITH_EMPTY_SEPARATOR = new RegExp(".*?".concat(CCASE, "|.+"), 'g'); | ||
/* Parse options */ | ||
var REVERT_CAMELCASE = new RegExp("[^-._~]*?".concat(CAMELCASE_PATTERN, "|[^-._~]+"), 'g'); | ||
var REVERT_CAMELCASE_ONLY = new RegExp(".*?".concat(CAMELCASE_PATTERN, "|.+"), 'g'); | ||
/** | ||
* Validate options | ||
*/ | ||
function parseOptions(options) { | ||
var result = {}; | ||
function validate(_ref) { | ||
var camelCase = _ref.camelCase, | ||
separator = _ref.separator, | ||
transformer = _ref.transformer; | ||
var extra = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
if (options.hasOwnProperty('camelCase')) { | ||
var value = options.camelCase; | ||
if (typeof value !== 'boolean') { | ||
throw new Error("camelCase must be a boolean: \"".concat(value, "\".")); | ||
if (camelCase !== undefined) { | ||
if (typeof camelCase !== 'boolean') { | ||
throw new Error("camelCase must be a boolean: \"".concat(camelCase, "\".")); | ||
} | ||
result.camelCase = value; | ||
} | ||
if (options.hasOwnProperty('separator')) { | ||
var _value = options.separator; | ||
if (typeof _value !== 'string') { | ||
throw new Error("separator must be a string: \"".concat(_value, "\".")); | ||
} else if (INVALID_SEPARATOR.test(_value)) { | ||
var error = _value.match(INVALID_SEPARATOR)[0]; | ||
throw new Error("separator has an invalid character: \"".concat(error, "\".")); | ||
if (separator !== undefined && !('separator' in extra && separator === extra.separator)) { | ||
if (typeof separator !== 'string') { | ||
var error = 'separator' in extra ? " or ".concat(extra.separator) : ''; | ||
throw new Error("separator must be a string".concat(error, ": \"").concat(separator, "\".")); | ||
} else if (INVALID_SEPARATOR.test(separator)) { | ||
var _error = separator.match(INVALID_SEPARATOR)[0]; | ||
throw new Error("separator has an invalid character: \"".concat(_error, "\".")); | ||
} | ||
result.separator = _value; | ||
} | ||
if (options.hasOwnProperty('transformer')) { | ||
var _value2 = options.transformer; | ||
if (transformer !== undefined) { | ||
if (transformer !== false && typeof transformer !== 'function') { | ||
var _error2 = "transformer must be false or a function: \"".concat(transformer, "\"."); | ||
if (_value2 !== false && typeof _value2 !== 'function') { | ||
throw new Error("transformer must be false or a function: \"".concat(_value2, "\".")); | ||
throw new Error(_error2); | ||
} | ||
result.transformer = _value2; | ||
} | ||
return result; | ||
} | ||
/* Builtin transformers */ | ||
/** | ||
* Builtin transformers | ||
*/ | ||
@@ -68,2 +63,9 @@ | ||
var SENTENCECASE_TRANSFORMER = function SENTENCECASE_TRANSFORMER(fragments, separator) { | ||
var sentence = fragments.join(separator); | ||
return sentence.charAt(0).toUpperCase() + sentence.slice(1).toLowerCase(); | ||
}; | ||
exports.SENTENCECASE_TRANSFORMER = SENTENCECASE_TRANSFORMER; | ||
var TITLECASE_TRANSFORMER = function TITLECASE_TRANSFORMER(fragments, separator) { | ||
@@ -80,3 +82,5 @@ return fragments.map(function (fragment) { | ||
}; | ||
/* Converts a string into a slug */ | ||
/** | ||
* Converts a string into a slug | ||
*/ | ||
@@ -88,11 +92,9 @@ | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var _parseOptions = parseOptions(options), | ||
_parseOptions$camelCa = _parseOptions.camelCase, | ||
camelCase = _parseOptions$camelCa === void 0 ? true : _parseOptions$camelCa, | ||
_parseOptions$separat = _parseOptions.separator, | ||
separator = _parseOptions$separat === void 0 ? '-' : _parseOptions$separat, | ||
_parseOptions$transfo = _parseOptions.transformer, | ||
transformer = _parseOptions$transfo === void 0 ? LOWERCASE_TRANSFORMER : _parseOptions$transfo; | ||
validate(options); | ||
var _options$camelCase = options.camelCase, | ||
camelCase = _options$camelCase === void 0 ? true : _options$camelCase, | ||
_options$separator = options.separator, | ||
separator = _options$separator === void 0 ? '-' : _options$separator, | ||
_options$transformer = options.transformer, | ||
transformer = _options$transformer === void 0 ? LOWERCASE_TRANSFORMER : _options$transformer; | ||
var fragments = String(string).normalize('NFKD').replace(COMBINING_CHARS, '').match(camelCase ? CONVERT_CAMELCASE : CONVERT); | ||
@@ -106,3 +108,5 @@ | ||
} | ||
/* Reverts a slug back to a string */ | ||
/** | ||
* Reverts a slug back to a string | ||
*/ | ||
@@ -112,19 +116,20 @@ | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var _parseOptions2 = parseOptions(options), | ||
_parseOptions2$camelC = _parseOptions2.camelCase, | ||
camelCase = _parseOptions2$camelC === void 0 ? false : _parseOptions2$camelC, | ||
separator = _parseOptions2.separator, | ||
_parseOptions2$transf = _parseOptions2.transformer, | ||
transformer = _parseOptions2$transf === void 0 ? false : _parseOptions2$transf; | ||
validate(options, { | ||
separator: null | ||
}); | ||
var _options$camelCase2 = options.camelCase, | ||
camelCase = _options$camelCase2 === void 0 ? false : _options$camelCase2, | ||
separator = options.separator, | ||
_options$transformer2 = options.transformer, | ||
transformer = _options$transformer2 === void 0 ? false : _options$transformer2; | ||
var fragments; | ||
slug = String(slug); | ||
/* Determine which method will be used split the slug */ | ||
if ('' === separator) { | ||
fragments = camelCase ? String(slug).match(REVERT_CAMELCASE_WITH_EMPTY_SEPARATOR) : [String(slug)]; | ||
fragments = camelCase ? slug.match(REVERT_CAMELCASE_ONLY) : [String(slug)]; | ||
} else if ('string' === typeof separator) { | ||
fragments = String(slug).split(separator); | ||
fragments = slug.split(separator); | ||
} else { | ||
fragments = String(slug).match(camelCase ? REVERT_CAMELCASE : REVERT); | ||
fragments = slug.match(camelCase ? REVERT_CAMELCASE : REVERT); | ||
} | ||
@@ -138,3 +143,5 @@ | ||
} | ||
/* Sets convert() as the default export */ | ||
/** | ||
* Sets convert() as the default export | ||
*/ | ||
@@ -141,0 +148,0 @@ |
{ | ||
"name": "url-slug", | ||
"version": "3.0.0-beta.0", | ||
"version": "3.0.0-beta.1", | ||
"description": "RFC 3986 compliant slug generator with multiple language support", | ||
"main": "index.js", | ||
"module": "src/index.js", | ||
"types": "src/index.d.ts", | ||
"scripts": { | ||
@@ -16,7 +18,7 @@ "build": "./node_modules/.bin/babel src --out-dir .", | ||
"@babel/cli": "^7.8.4", | ||
"@babel/core": "^7.8.6", | ||
"@babel/preset-env": "^7.8.6", | ||
"@babel/core": "^7.8.7", | ||
"@babel/preset-env": "^7.8.7", | ||
"@babel/register": "^7.8.6", | ||
"chai": "^4.2.0", | ||
"cross-env": "^7.0.0", | ||
"cross-env": "^7.0.2", | ||
"mocha": "^7.1.0" | ||
@@ -23,0 +25,0 @@ }, |
184
README.md
@@ -22,3 +22,3 @@ # url-slug [![build status](https://img.shields.io/travis/stldo/url-slug.svg?style=flat)](https://travis-ci.org/stldo/url-slug) [![npm version](https://img.shields.io/npm/v/url-slug.svg?style=flat)](https://www.npmjs.com/package/url-slug) | ||
### urlSlug(string, [options]), urlSlug.convert(string, [options]) | ||
### urlSlug(string[, options]), urlSlug.convert(string[, options]) | ||
@@ -37,3 +37,3 @@ Returns the __string__ value converted to a slug. | ||
| separator | Character to split the string: `'-'`, `'.'`, `'_'`, `'~'` or `''` | '-' | | ||
| transformer | A built-in transformer or a custom function (set to `false` to keep the string unchanged) | `urlSlug.transformers.lowercase` | | ||
| transformer | A built-in transformer or a custom function (`false` to keep the string unchanged) | `urlSlug.LOWERCASE_TRANSFORMER` | | ||
@@ -43,62 +43,29 @@ #### Examples | ||
```javascript | ||
import urlSlug from 'url-slug' | ||
import { * as urlSlug, convert } from 'url-slug' | ||
urlSlug('Comfortably Numb', { | ||
transformer: urlSlug.transformers.uppercase | ||
convert('Comfortably Numb', { | ||
transformer: urlSlug.UPPERCASE_TRANSFORMER | ||
}) | ||
// COMFORTABLY-NUMB | ||
urlSlug('á é í ó ú Á É Í Ó Ú ç Ç æ Æ œ Œ ® © € ¥ ª º ¹ ² ½ ¼', { | ||
convert('á é í ó ú Á É Í Ó Ú ç Ç ª º ¹ ² ½ ¼', { | ||
separator: '_', | ||
transformer: false | ||
}) | ||
// a_e_i_o_u_A_E_I_O_U_c_C_ae_AE_oe_OE_r_c_EU_Y_a_o_1_2_1_2_1_4 | ||
// a_e_i_o_u_A_E_I_O_U_c_C_a_o_1_2_1_2_1_4 | ||
urlSlug('Red, red wine, stay close to me…', { | ||
convert('Red, red wine, stay close to me…', { | ||
separator: '', | ||
transformer: urlSlug.transformers.titlecase | ||
transformer: urlSlug.TITLECASE_TRANSFORMER | ||
}) | ||
// RedRedWineStayCloseToMe | ||
``` | ||
### urlSlug(string, [separator], [transformer]), urlSlug.convert(string, [separator], [transformer]) | ||
> ⚠️ __Warning__: This syntax will be deprecated | ||
Returns the __string__ value converted to a slug. | ||
#### string | ||
Type: `string` | ||
The string that'll be converted. | ||
#### separator | ||
Type: `string` | ||
The character used to separate the slug fragments, set to `'-'` by default. Can be set to `'-'`, `'.'`, `'_'`, `'~'` or `''`. | ||
#### transformer | ||
Type: `function` or `false` | ||
A function that receives the slug fragments and the current separator as arguments. It must return the slug string. Defaults to the built-in transformer `urlSlug.transformers.lowercase`. It can be set to `false` if no transformation is desirable. | ||
#### Examples | ||
```javascript | ||
import urlSlug from 'url-slug' | ||
urlSlug('Comfortably Numb', urlSlug.transformers.uppercase) | ||
// COMFORTABLY-NUMB | ||
urlSlug('á é í ó ú Á É Í Ó Ú ç Ç æ Æ œ Œ ® © € ¥ ª º ¹ ² ½ ¼', '_', false) | ||
// a_e_i_o_u_A_E_I_O_U_c_C_ae_AE_oe_OE_r_c_EU_Y_a_o_1_2_1_2_1_4 | ||
urlSlug('Red, red wine, stay close to me…', '', urlSlug.transformers.titlecase) | ||
// RedRedWineStayCloseToMe | ||
convert('Listen to Fito Páez in Madrid', { | ||
separator: '~', | ||
transformer: urlSlug.SENTENCECASE_TRANSFORMER | ||
}) | ||
// Listen~to~fito~paez~in~madrid | ||
``` | ||
### urlSlug.revert(slug, [options]) | ||
### urlSlug.revert(slug[, options]) | ||
@@ -116,4 +83,4 @@ Returns the __slug__ value converted to a regular string. | ||
| camelCase | Split camel case occurrences | `false` | | ||
| separator | Character to split the string: `'-'`, `'.'`, `'_'`, `'~'` or `''` (set to `null` to use all characters) | `null` | | ||
| transformer | A built-in transformer or a custom function (set to `false` to keep the string unchanged) | `false` | | ||
| separator | Character to split the string: `'-'`, `'.'`, `'_'`, `'~'` or `''` (`null` to use all characters) | `null` | | ||
| transformer | A built-in transformer or a custom function (`false` to keep the string unchanged) | `false` | | ||
@@ -123,86 +90,19 @@ #### Examples | ||
```javascript | ||
import urlSlug from 'url-slug' | ||
import { * as urlSlug, revert } from 'url-slug' | ||
urlSlug.revert('Replace-every_separator.allowed~andSplitCamelCaseToo') | ||
revert('Replace-every_separator.allowed~andSplitCamelCaseToo', { | ||
camelCase: true | ||
}) | ||
// Replace every separator allowed and Split Camel Case Too | ||
urlSlug.revert('this-title-needs-a-title_case', { | ||
revert('this-slug-needs-a-title_case', { | ||
separator: '-', | ||
transformer: urlSlug.transformers.titlecase | ||
transformer: urlSlug.TITLECASE_TRANSFORMER | ||
}) | ||
// This Title Needs A Title_case | ||
// This Slug Needs A Title_case | ||
``` | ||
### urlSlug.revert(slug, [separator], [transformer]) | ||
> ⚠️ __Warning__: This syntax will be deprecated | ||
Returns the __slug__ value converted to a regular string. | ||
#### slug | ||
Type: `string` | ||
The slug that'll be reverted. | ||
#### separator | ||
Type: `string` or `null` | ||
The value used to split the slug into fragments, set to `null` by default. Can be set to `null`, `'-'`, `'.'`, `'_'`, `'~'` or `''`. If set to `null`, the split will happen on any valid separator character or camel case occurrences. If set to an empty string, only camel case occurrences will be split. | ||
#### transformer | ||
Type: `function` or `false` | ||
A function that receives the string fragments and the current separator as arguments. Defaults to `false`, which means that no transformation will be made. | ||
#### Examples | ||
```javascript | ||
import urlSlug from 'url-slug' | ||
urlSlug.revert('Replace-every_separator.allowed~andSplitCamelCaseToo') | ||
// Replace every separator allowed and Split Camel Case Too | ||
urlSlug.revert( | ||
'this-title-needs-a-title_case', | ||
'-', | ||
urlSlug.transformers.titlecase | ||
) | ||
// This Title Needs A Title_case | ||
``` | ||
### urlSlug.UrlSlug([separator], [transformer]) | ||
> ⚠️ __Warning__: This syntax will be deprecated | ||
`url-slug` constructor, useful if you want to create more instances. If `separator` or `transform` are set, they will the default values of the instance. | ||
#### separator | ||
Type: `string` | ||
Defaults to `'-'`. Can be set to `'-'`, `'.'`, `'_'`, `'~'` or `''`. | ||
#### transformer | ||
Type: `function` or `false` | ||
Defaults to `urlSlug.transformers.lowercase`. Can be set to a function or `false`, if no transformation is desired. | ||
#### Examples | ||
```javascript | ||
import urlSlug from 'url-slug' | ||
const urlSlugInstance = new urlSlug.UrlSlug('~', urlSlug.transformers.uppercase) | ||
urlSlugInstance.convert('Listen to Fito Páez in Madrid') | ||
// LISTEN~TO~FITO~PAEZ~IN~MADRID | ||
``` | ||
### Custom transformers | ||
Custom transformers are expressed by a function which receives two arguments, __fragments__, an array with the resulting words of the conversion, and __separator__, the current separator string used to join the words. On revert, the __separator__ will always be a space character (`' '`). Transformers should always return a string. | ||
Custom transformers are expressed by a function which receives two arguments, __fragments__, an array with matching words from a sentence or a slug, and __separator__, the current separator string set in options. When `revert()` calls the transformer, the __separator__ will always be a space character (`' '`). Transformers should always return a string. | ||
@@ -212,17 +112,15 @@ #### Examples | ||
```javascript | ||
import urlSlug from 'url-slug' | ||
import { convert, revert } from 'url-slug' | ||
urlSlug( | ||
'O\'Neill is an American surfboard, surfwear and equipment brand', | ||
fragments => fragments.join('+').toUpperCase() | ||
) | ||
convert('O’Neill is an American surfboard, surfwear and equipment brand', { | ||
transformer: fragments => fragments.join('+').toUpperCase() | ||
}) | ||
// O+NEILL+IS+AN+AMERICAN+SURFBOARD+SURFWEAR+AND+EQUIPMENT+BRAND | ||
urlSlug.revert( | ||
'WEIrd_SNAke_CAse', | ||
'_', | ||
(fragments, separator) => fragments.map(fragment => ( | ||
revert('WEIrd_SNAke_CAse', { | ||
separator: '_', | ||
transformer: (fragments, separator) => fragments.map(fragment => ( | ||
fragment.slice(0, -2).toLowerCase() + fragment.slice(-2).toUpperCase() | ||
)).join(separator) | ||
) | ||
}) | ||
// weiRD snaKE caSE | ||
@@ -233,16 +131,20 @@ ``` | ||
#### urlSlug.transformers.lowercase | ||
#### urlSlug.LOWERCASE_TRANSFORMER | ||
Converts the result to lowercase. | ||
Converts the result to lowercase. E.g.: `// SOME WORDS >> some words` | ||
#### urlSlug.transformers.uppercase | ||
#### urlSlug.SENTENCECASE_TRANSFORMER | ||
Converts the result to uppercase. | ||
Converts the result to sentence case. E.g.: `// sOME WORDS >> Some words` | ||
#### urlSlug.transformers.titlecase | ||
#### urlSlug.UPPERCASE_TRANSFORMER | ||
Converts the result to title case. | ||
Converts the result to uppercase. E.g.: `// some words >> SOME WORDS` | ||
#### urlSlug.TITLECASE_TRANSFORMER | ||
Converts the result to title case. E.g.: `// sOME wORDS >> Some Words` | ||
## License | ||
[The MIT License](./LICENSE) |
@@ -11,2 +11,3 @@ import { expect } from 'chai' | ||
expect(typeof urlSlug.LOWERCASE_TRANSFORMER).to.be.equal('function') | ||
expect(typeof urlSlug.SENTENCECASE_TRANSFORMER).to.be.equal('function') | ||
expect(typeof urlSlug.TITLECASE_TRANSFORMER).to.be.equal('function') | ||
@@ -23,2 +24,9 @@ expect(typeof urlSlug.UPPERCASE_TRANSFORMER).to.be.equal('function') | ||
it('has a working sentence case transformer', () => { | ||
const fragments = ['aA', 'BB'] | ||
const separator = '-' | ||
const transformer = urlSlug.SENTENCECASE_TRANSFORMER | ||
expect(transformer(fragments, separator)).to.be.equal('Aa-bb') | ||
}) | ||
it('has a working tittle case transformer', () => { | ||
@@ -54,3 +62,3 @@ const fragments = ['aA', 'bB'] | ||
it('accepts only unreserved characters in RFC 3986 as separator', () => { | ||
it('accepts only hyphen, period, underscore and tilde as separator', () => { | ||
expect(() => urlSlug.convert('', { separator: '-._~' })) | ||
@@ -189,3 +197,8 @@ .to.not.throw() | ||
it('accepts only unreserved characters in RFC 3986 as separator', () => { | ||
it('accepts null as separator', () => { | ||
expect(() => urlSlug.revert('', { separator: null })) | ||
.to.not.throw() | ||
}) | ||
it('accepts only hyphen, period, underscore, and tilde as separator', () => { | ||
expect(() => urlSlug.revert('', { separator: '-._~' })) | ||
@@ -199,3 +212,3 @@ .to.not.throw() | ||
expect(() => urlSlug.revert('', { separator: 123 })) | ||
.to.throw('separator must be a string') | ||
.to.throw('separator must be a string or null') | ||
}) | ||
@@ -202,0 +215,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
9
0
24869
498
144