-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathcase-conversions.ts
101 lines (94 loc) · 2.98 KB
/
case-conversions.ts
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import type { CamelCaseToKebabCase, KebabCaseToCamelCase } from './types.js';
/**
* Converts a kebab-case string to camelCase.
* @param string - The kebab-case string to convert.
* @returns The camelCase string.
*/
export function kebabCaseToCamelCase<T extends string>(
string: T,
): KebabCaseToCamelCase<T> {
return string
.split('-')
.map((segment, index) => (index === 0 ? segment : capitalize(segment)))
.join('') as KebabCaseToCamelCase<T>;
}
/**
* Converts a camelCase string to kebab-case.
* @param input - The camelCase string to convert.
* @returns The kebab-case string.
*/
export function camelCaseToKebabCase<T extends string>(
input: T,
): CamelCaseToKebabCase<T> {
return input
.replace(/([a-z])([A-Z])/g, '$1-$2') // Insert dash before uppercase letters
.replace(/([A-Z])([A-Z][a-z])/g, '$1-$2') // Handle consecutive uppercase letters
.toLowerCase() as CamelCaseToKebabCase<T>;
}
/**
* Converts a string to Title Case.
* - Capitalizes the first letter of each major word.
* - Keeps articles, conjunctions, and short prepositions in lowercase unless they are the first word.
*
* @param input - The string to convert.
* @returns The formatted title case string.
*/
export function toTitleCase(input: string): string {
const minorWords = new Set([
'a',
'an',
'the',
'and',
'or',
'but',
'for',
'nor',
'on',
'in',
'at',
'to',
'by',
'of',
]);
return input
.replace(/([a-z])([A-Z])/g, '$1 $2') // Split PascalCase & camelCase
.replace(/[_-]/g, ' ') // Replace kebab-case and snake_case with spaces
.replace(/(\d+)/g, ' $1 ') // Add spaces around numbers
.replace(/\s+/g, ' ') // Remove extra spaces
.trim()
.split(' ')
.map((word, index) => {
// Preserve uppercase acronyms (e.g., API, HTTP)
if (/^[A-Z]{2,}$/.test(word)) {
return word;
}
// Capitalize first word or non-minor words
if (index === 0 || !minorWords.has(word.toLowerCase())) {
return capitalize(word);
}
return word.toLowerCase();
})
.join(' ');
}
/**
* Converts a string to Sentence Case.
* - Capitalizes only the first letter of the sentence.
* - Retains case of proper nouns.
*
* @param input - The string to convert.
* @returns The formatted sentence case string.
*/
export function toSentenceCase(input: string): string {
return input
.replace(/([a-z])([A-Z])/g, '$1 $2') // Split PascalCase & camelCase
.replace(/[_-]/g, ' ') // Replace kebab-case and snake_case with spaces
.replace(/(\d+)/g, ' $1 ') // Add spaces around numbers
.replace(/\s+/g, ' ') // Remove extra spaces
.trim()
.toLowerCase()
.replace(/^(\w)/, match => match.toUpperCase()) // Capitalize first letter
.replace(/\b([A-Z]{2,})\b/g, match => match); // Preserve uppercase acronyms
}
export function capitalize<T extends string>(text: T): Capitalize<T> {
return `${text.charAt(0).toLocaleUpperCase()}${text.slice(1).toLowerCase()}` as Capitalize<T>;
}