-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
67 lines (54 loc) · 2.59 KB
/
index.js
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
'use strict';
const deburr = require('lodash.deburr');
const escapeStringRegexp = require('escape-string-regexp');
const builtinReplacements = require('./replacements');
const builtinOverridableReplacements = require('./overridable-replacements');
const decamelize = string => {
return string
.replace(/([a-z\d])([A-Z])/g, '$1 $2')
.replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1 $2');
};
const doCustomReplacements = (string, replacements) => {
for (const [key, value] of replacements) {
string = string.replace(new RegExp(escapeStringRegexp(key), 'g'), value);
}
return string;
};
const removeMootSeparators = (string, separator) => {
return string
.replace(new RegExp(`${separator}{2,}`, 'g'), separator)
.replace(new RegExp(`^${separator}|${separator}$`, 'g'), '');
};
module.exports = (string, options) => {
if (typeof string !== 'string') {
throw new TypeError(`Expected a string, got \`${typeof string}\``);
}
options = Object.assign({
separator: '-',
lowercase: true,
decamelize: true,
customReplacements: []
}, options);
const separator = escapeStringRegexp(options.separator);
const customReplacements = new Map([
...builtinOverridableReplacements,
...options.customReplacements,
...builtinReplacements
]);
string = doCustomReplacements(string, customReplacements);
string = deburr(string);
string = string.normalize('NFKD');
if (options.decamelize) {
string = decamelize(string);
}
// CJK Letter Charset via https://github.com/ikatyang/cjk-regex
let patternSlug = /[^a-zA-Z\d\u1100-\u11ff\u2e80-\u2e99\u2e9b-\u2ef3\u2f00-\u2fd5\u3005\u3007\u3021-\u3029\u3038-\u303b\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fd-\u30ff\u3105-\u312e\u3131-\u318e\u31a0-\u31ba\u31f0-\u321e\u3260-\u327e\u32d0-\u32fe\u3300-\u3357\u3400-\u4db5\u4e00-\u9fea\ua960-\ua97c\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\uff66-\uff6f\uff71-\uff9d\uffa0-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]+/g;
if (options.lowercase) {
string = string.toLowerCase();
patternSlug = /[^a-z\d\u1100-\u11ff\u2e80-\u2e99\u2e9b-\u2ef3\u2f00-\u2fd5\u3005\u3007\u3021-\u3029\u3038-\u303b\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fd-\u30ff\u3105-\u312e\u3131-\u318e\u31a0-\u31ba\u31f0-\u321e\u3260-\u327e\u32d0-\u32fe\u3300-\u3357\u3400-\u4db5\u4e00-\u9fea\ua960-\ua97c\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\uff66-\uff6f\uff71-\uff9d\uffa0-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]+/g;
}
string = string.replace(patternSlug, separator);
string = string.replace(/\\/g, '');
string = removeMootSeparators(string, separator);
return string;
};