casing.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /**
  2. * Capitalize a string.
  3. * @param {string} str
  4. */
  5. function capitalize(str) {
  6. return str.charAt(0).toUpperCase() + str.slice(1)
  7. }
  8. /**
  9. * Checks whether the given string has symbols.
  10. * @param {string} str
  11. */
  12. function hasSymbols(str) {
  13. return /[!"#%&'()*+,./:;<=>?@[\\\]^`{|}]/u.exec(str) // without " ", "$", "-" and "_"
  14. }
  15. /**
  16. * Checks whether the given string has upper.
  17. * @param {string} str
  18. */
  19. function hasUpper(str) {
  20. return /[A-Z]/u.exec(str)
  21. }
  22. /**
  23. * Convert text to kebab-case
  24. * @param {string} str Text to be converted
  25. * @return {string}
  26. */
  27. function kebabCase(str) {
  28. return str
  29. .replace(/_/gu, '-')
  30. .replace(/\B([A-Z])/gu, '-$1')
  31. .toLowerCase()
  32. }
  33. /**
  34. * Checks whether the given string is kebab-case.
  35. * @param {string} str
  36. */
  37. function isKebabCase(str) {
  38. return (
  39. !hasUpper(str) &&
  40. !hasSymbols(str) &&
  41. !str.startsWith('-') && // starts with hyphen is not kebab-case
  42. !/_|--|\s/u.test(str)
  43. )
  44. }
  45. /**
  46. * Convert text to snake_case
  47. * @param {string} str Text to be converted
  48. * @return {string}
  49. */
  50. function snakeCase(str) {
  51. return str
  52. .replace(/\B([A-Z])/gu, '_$1')
  53. .replace(/-/gu, '_')
  54. .toLowerCase()
  55. }
  56. /**
  57. * Checks whether the given string is snake_case.
  58. * @param {string} str
  59. */
  60. function isSnakeCase(str) {
  61. return !hasUpper(str) && !hasSymbols(str) && !/-|__|\s/u.test(str)
  62. }
  63. /**
  64. * Convert text to camelCase
  65. * @param {string} str Text to be converted
  66. * @return {string} Converted string
  67. */
  68. function camelCase(str) {
  69. if (isPascalCase(str)) {
  70. return str.charAt(0).toLowerCase() + str.slice(1)
  71. }
  72. return str.replace(/[-_](\w)/gu, (_, c) => (c ? c.toUpperCase() : ''))
  73. }
  74. /**
  75. * Checks whether the given string is camelCase.
  76. * @param {string} str
  77. */
  78. function isCamelCase(str) {
  79. return !hasSymbols(str) && !/^[A-Z]/u.test(str) && !/-|_|\s/u.test(str)
  80. }
  81. /**
  82. * Convert text to PascalCase
  83. * @param {string} str Text to be converted
  84. * @return {string} Converted string
  85. */
  86. function pascalCase(str) {
  87. return capitalize(camelCase(str))
  88. }
  89. /**
  90. * Checks whether the given string is PascalCase.
  91. * @param {string} str
  92. */
  93. function isPascalCase(str) {
  94. return !hasSymbols(str) && !/^[a-z]/u.test(str) && !/-|_|\s/u.test(str)
  95. }
  96. const convertersMap = {
  97. 'kebab-case': kebabCase,
  98. snake_case: snakeCase,
  99. camelCase,
  100. PascalCase: pascalCase
  101. }
  102. const checkersMap = {
  103. 'kebab-case': isKebabCase,
  104. snake_case: isSnakeCase,
  105. camelCase: isCamelCase,
  106. PascalCase: isPascalCase
  107. }
  108. /**
  109. * Return case checker
  110. * @param { 'camelCase' | 'kebab-case' | 'PascalCase' | 'snake_case' } name type of checker to return ('camelCase', 'kebab-case', 'PascalCase')
  111. * @return {isKebabCase|isCamelCase|isPascalCase|isSnakeCase}
  112. */
  113. function getChecker(name) {
  114. return checkersMap[name] || isPascalCase
  115. }
  116. /**
  117. * Return case converter
  118. * @param { 'camelCase' | 'kebab-case' | 'PascalCase' | 'snake_case' } name type of converter to return ('camelCase', 'kebab-case', 'PascalCase')
  119. * @return {kebabCase|camelCase|pascalCase|snakeCase}
  120. */
  121. function getConverter(name) {
  122. return convertersMap[name] || pascalCase
  123. }
  124. module.exports = {
  125. allowedCaseOptions: ['camelCase', 'kebab-case', 'PascalCase'],
  126. /**
  127. * Return case converter
  128. * @param {string} name type of converter to return ('camelCase', 'kebab-case', 'PascalCase')
  129. * @return {kebabCase|camelCase|pascalCase|snakeCase}
  130. */
  131. getConverter,
  132. /**
  133. * Return case checker
  134. * @param {string} name type of checker to return ('camelCase', 'kebab-case', 'PascalCase')
  135. * @return {isKebabCase|isCamelCase|isPascalCase|isSnakeCase}
  136. */
  137. getChecker,
  138. /**
  139. * Return case exact converter.
  140. * If the converted result is not the correct case, the original value is returned.
  141. * @param { 'camelCase' | 'kebab-case' | 'PascalCase' | 'snake_case' } name type of converter to return ('camelCase', 'kebab-case', 'PascalCase')
  142. * @return {kebabCase|camelCase|pascalCase|snakeCase}
  143. */
  144. getExactConverter(name) {
  145. const converter = getConverter(name)
  146. const checker = getChecker(name)
  147. return (str) => {
  148. const result = converter(str)
  149. return checker(result) ? result : str /* cannot convert */
  150. }
  151. },
  152. camelCase,
  153. pascalCase,
  154. kebabCase,
  155. snakeCase,
  156. isCamelCase,
  157. isPascalCase,
  158. isKebabCase,
  159. isSnakeCase,
  160. capitalize
  161. }