index.js
1 'use strict'; 2 3 const preserveCamelCase = (string, locale) => { 4 let isLastCharLower = false; 5 let isLastCharUpper = false; 6 let isLastLastCharUpper = false; 7 8 for (let i = 0; i < string.length; i++) { 9 const character = string[i]; 10 11 if (isLastCharLower && /[\p{Lu}]/u.test(character)) { 12 string = string.slice(0, i) + '-' + string.slice(i); 13 isLastCharLower = false; 14 isLastLastCharUpper = isLastCharUpper; 15 isLastCharUpper = true; 16 i++; 17 } else if (isLastCharUpper && isLastLastCharUpper && /[\p{Ll}]/u.test(character)) { 18 string = string.slice(0, i - 1) + '-' + string.slice(i - 1); 19 isLastLastCharUpper = isLastCharUpper; 20 isLastCharUpper = false; 21 isLastCharLower = true; 22 } else { 23 isLastCharLower = character.toLocaleLowerCase(locale) === character && character.toLocaleUpperCase(locale) !== character; 24 isLastLastCharUpper = isLastCharUpper; 25 isLastCharUpper = character.toLocaleUpperCase(locale) === character && character.toLocaleLowerCase(locale) !== character; 26 } 27 } 28 29 return string; 30 }; 31 32 const preserveConsecutiveUppercase = input => { 33 return input.replace(/^[\p{Lu}](?![\p{Lu}])/gu, m1 => m1.toLowerCase()); 34 }; 35 36 const postProcess = (input, options) => { 37 return input.replace(/[_.\- ]+([\p{Alpha}\p{N}_]|$)/gu, (_, p1) => p1.toLocaleUpperCase(options.locale)) 38 .replace(/\d+([\p{Alpha}\p{N}_]|$)/gu, m => m.toLocaleUpperCase(options.locale)); 39 }; 40 41 const camelCase = (input, options) => { 42 if (!(typeof input === 'string' || Array.isArray(input))) { 43 throw new TypeError('Expected the input to be `string | string[]`'); 44 } 45 46 options = { 47 pascalCase: false, 48 preserveConsecutiveUppercase: false, 49 ...options 50 }; 51 52 if (Array.isArray(input)) { 53 input = input.map(x => x.trim()) 54 .filter(x => x.length) 55 .join('-'); 56 } else { 57 input = input.trim(); 58 } 59 60 if (input.length === 0) { 61 return ''; 62 } 63 64 if (input.length === 1) { 65 return options.pascalCase ? input.toLocaleUpperCase(options.locale) : input.toLocaleLowerCase(options.locale); 66 } 67 68 const hasUpperCase = input !== input.toLocaleLowerCase(options.locale); 69 70 if (hasUpperCase) { 71 input = preserveCamelCase(input, options.locale); 72 } 73 74 input = input.replace(/^[_.\- ]+/, ''); 75 76 if (options.preserveConsecutiveUppercase) { 77 input = preserveConsecutiveUppercase(input); 78 } else { 79 input = input.toLocaleLowerCase(); 80 } 81 82 if (options.pascalCase) { 83 input = input.charAt(0).toLocaleUpperCase(options.locale) + input.slice(1); 84 } 85 86 return postProcess(input, options); 87 }; 88 89 module.exports = camelCase; 90 // TODO: Remove this for the next major release 91 module.exports.default = camelCase;