11const assert = require ( 'assert' )
22
3- const invalidChars = / [ ^ a - z A - Z 0 - 9 : ] + / g
3+ // ------------------------------------------------------------------------------
4+ // Helpers
5+ // ------------------------------------------------------------------------------
6+
7+ /**
8+ * Capitalize a string.
9+ */
10+ function capitalize ( str ) {
11+ return str . charAt ( 0 ) . toUpperCase ( ) + str . slice ( 1 )
12+ }
13+ /**
14+ * Checks whether the given string has symbols.
15+ */
16+ function hasSymbols ( str ) {
17+ return / [ ! " # % & ' ( ) * + , . / : ; < = > ? @ [ \\ \] ^ ` { | } ] / u. exec ( str ) // without " ", "$", "-" and "_"
18+ }
19+ /**
20+ * Checks whether the given string has upper.
21+ */
22+ function hasUpper ( str ) {
23+ return / [ A - Z ] / u. exec ( str )
24+ }
425
526/**
627 * Convert text to kebab-case
@@ -9,39 +30,76 @@ const invalidChars = /[^a-zA-Z0-9:]+/g
930 */
1031function kebabCase ( str ) {
1132 return str
12- . replace ( / [ A - Z ] / g, match => '-' + match )
13- . replace ( / ( [ ^ a - z A - Z ] ) - ( [ A - Z ] ) / g, match => match [ 0 ] + match [ 2 ] )
14- . replace ( / ^ - / , '' )
15- . replace ( invalidChars , '-' )
33+ . replace ( / _ / gu, '-' )
34+ . replace ( / \B ( [ A - Z ] ) / gu, '-$1' )
1635 . toLowerCase ( )
1736}
1837
38+ /**
39+ * Checks whether the given string is kebab-case.
40+ */
41+ function isKebabCase ( str ) {
42+ if (
43+ hasUpper ( str ) ||
44+ hasSymbols ( str ) ||
45+ / ^ - / u. exec ( str ) || // starts with hyphen is not kebab-case
46+ / _ | - - | \s / u. exec ( str )
47+ ) {
48+ return false
49+ }
50+ return true
51+ }
52+
1953/**
2054 * Convert text to snake_case
2155 * @param {string } str Text to be converted
2256 * @return {string }
2357 */
2458function snakeCase ( str ) {
2559 return str
26- . replace ( / [ A - Z ] / g, match => '_' + match )
27- . replace ( / ( [ ^ a - z A - Z ] ) _ ( [ A - Z ] ) / g, match => match [ 0 ] + match [ 2 ] )
28- . replace ( / ^ _ / , '' )
29- . replace ( invalidChars , '_' )
60+ . replace ( / \B ( [ A - Z ] ) / gu, '_$1' )
61+ . replace ( / - / gu, '_' )
3062 . toLowerCase ( )
3163}
3264
65+ /**
66+ * Checks whether the given string is snake_case.
67+ */
68+ function isSnakeCase ( str ) {
69+ if (
70+ hasUpper ( str ) ||
71+ hasSymbols ( str ) ||
72+ / - | _ _ | \s / u. exec ( str )
73+ ) {
74+ return false
75+ }
76+ return true
77+ }
78+
3379/**
3480 * Convert text to camelCase
3581 * @param {string } str Text to be converted
3682 * @return {string } Converted string
3783 */
3884function camelCase ( str ) {
39- return str
40- . replace ( / _ / g, ( _ , index ) => index === 0 ? _ : '-' )
41- . replace ( / (?: ^ \w | [ A - Z ] | \b \w ) / g, ( letter , index ) =>
42- index === 0 ? letter . toLowerCase ( ) : letter . toUpperCase ( )
43- )
44- . replace ( invalidChars , '' )
85+ if ( isPascalCase ( str ) ) {
86+ return str . charAt ( 0 ) . toLowerCase ( ) + str . slice ( 1 )
87+ }
88+ return str . replace ( / [ - _ ] ( \w ) / gu, ( _ , c ) => c ? c . toUpperCase ( ) : '' )
89+ }
90+
91+ /**
92+ * Checks whether the given string is camelCase.
93+ */
94+ function isCamelCase ( str ) {
95+ if (
96+ hasSymbols ( str ) ||
97+ / ^ [ A - Z ] / u. exec ( str ) ||
98+ / - | _ | \s / u. exec ( str ) // kebab or snake or space
99+ ) {
100+ return false
101+ }
102+ return true
45103}
46104
47105/**
@@ -50,10 +108,21 @@ function camelCase (str) {
50108 * @return {string } Converted string
51109 */
52110function pascalCase ( str ) {
53- return str
54- . replace ( / _ / g, ( _ , index ) => index === 0 ? _ : '-' )
55- . replace ( / (?: ^ \w | [ A - Z ] | \b \w ) / g, ( letter , index ) => letter . toUpperCase ( ) )
56- . replace ( invalidChars , '' )
111+ return capitalize ( camelCase ( str ) )
112+ }
113+
114+ /**
115+ * Checks whether the given string is PascalCase.
116+ */
117+ function isPascalCase ( str ) {
118+ if (
119+ hasSymbols ( str ) ||
120+ / ^ [ a - z ] / u. exec ( str ) ||
121+ / - | _ | \s / u. exec ( str ) // kebab or snake or space
122+ ) {
123+ return false
124+ }
125+ return true
57126}
58127
59128const convertersMap = {
@@ -63,6 +132,34 @@ const convertersMap = {
63132 'PascalCase' : pascalCase
64133}
65134
135+ const checkersMap = {
136+ 'kebab-case' : isKebabCase ,
137+ 'snake_case' : isSnakeCase ,
138+ 'camelCase' : isCamelCase ,
139+ 'PascalCase' : isPascalCase
140+ }
141+ /**
142+ * Return case checker
143+ * @param {string } name type of checker to return ('camelCase', 'kebab-case', 'PascalCase')
144+ * @return {isKebabCase|isCamelCase|isPascalCase }
145+ */
146+ function getChecker ( name ) {
147+ assert ( typeof name === 'string' )
148+
149+ return checkersMap [ name ] || isPascalCase
150+ }
151+
152+ /**
153+ * Return case converter
154+ * @param {string } name type of converter to return ('camelCase', 'kebab-case', 'PascalCase')
155+ * @return {kebabCase|camelCase|pascalCase }
156+ */
157+ function getConverter ( name ) {
158+ assert ( typeof name === 'string' )
159+
160+ return convertersMap [ name ] || pascalCase
161+ }
162+
66163module . exports = {
67164 allowedCaseOptions : [
68165 'camelCase' ,
@@ -75,14 +172,37 @@ module.exports = {
75172 * @param {string } name type of converter to return ('camelCase', 'kebab-case', 'PascalCase')
76173 * @return {kebabCase|camelCase|pascalCase }
77174 */
78- getConverter ( name ) {
79- assert ( typeof name === 'string' )
175+ getConverter,
176+
177+ /**
178+ * Return case checker
179+ * @param {string } name type of checker to return ('camelCase', 'kebab-case', 'PascalCase')
180+ * @return {isKebabCase|isCamelCase|isPascalCase }
181+ */
182+ getChecker,
80183
81- return convertersMap [ name ] || pascalCase
184+ /**
185+ * Return case exact converter.
186+ * If the converted result is not the correct case, the original value is returned.
187+ * @param {string } name type of converter to return ('camelCase', 'kebab-case', 'PascalCase')
188+ * @return {kebabCase|camelCase|pascalCase }
189+ */
190+ getExactConverter ( name ) {
191+ const converter = getConverter ( name )
192+ const checker = getChecker ( name )
193+ return ( str ) => {
194+ const result = converter ( str )
195+ return checker ( result ) ? result : str /* cannot convert */
196+ }
82197 } ,
83198
84199 camelCase,
85200 pascalCase,
86201 kebabCase,
87- snakeCase
202+ snakeCase,
203+
204+ isCamelCase,
205+ isPascalCase,
206+ isKebabCase,
207+ isSnakeCase
88208}
0 commit comments