function lowerToPascalCase(str: string) { return str.replace(/(?:^|\s)\w/g, (match) => match.toUpperCase()).replaceAll( " ", "", ); } function lowerToTrainCase(str: string) { return str.replace(/(?:^|\s)\w/g, (match) => match.toUpperCase()).replaceAll( " ", "-", ); } function lowerToCamelCase(str: string) { return str.trim().replace(/(?:\s)\w/g, (match) => match.toUpperCase()) .replaceAll(" ", ""); } function lowerToSnakeCase(str: string) { return str.replace(" ", "_"); } function lowerToKebabCase(str: string) { return str.replace(" ", "-"); } function lowerToMacroCase(str: string) { return str.replace(/\w\S*/g, (match) => match.toUpperCase()).replaceAll( " ", "_", ); } function lowerToTitleCase(str: string) { return str.replace(/(?:^|\s)\w/g, (match) => match.toUpperCase()); } type CaseType = | "pascal" | "camel" | "snake" | "kebab" | "macro" | "upper" | "lower" | "train" | "title" | ""; function parseCase(str: string) { const isCaseMap = new Map boolean>([ ["pascal", (str: string) => { return /^[A-Z][a-zA-Z]*$/.test(str); }], ["camel", (str: string) => { return /^[a-z][a-zA-Z]*$/.test(str); }], ["snake", (str: string) => { return /^[a-z][a-z0-9_]*$/.test(str); }], ["kebab", (str: string) => { return /^[a-z][a-z0-9-]*$/.test(str); }], ["macro", (str: string) => { return /^[A-Z]*$/.test(str); }], ["upper", (str: string) => { return /^[A-Z]*$/.test(str); }], ["lower", (str: string) => { return /^[a-z]*$/.test(str); }], ["train", (str: string) => { return /([A-Z][a-z]*(?:-|$))+/.test(str); }], ]); for (const [key, value] of isCaseMap) { if (value(str)) return key; } return ""; } function coerceCaseToLower(str: string, caseType: CaseType) { switch (caseType) { case "pascal": case "camel": return str.replace(/[A-Z]/g, (match) => " " + match.toLowerCase().trim()); case "macro": case "snake": case "upper": return str.replace("_", " ").toLowerCase(); case "train": case "kebab": return str.replace("-", " ").toLowerCase(); default: return str.toLowerCase(); } } export function toCase(str: string, toCase: CaseType) { const caseType = parseCase(str) || ""; if (caseType === toCase) return str; const lowerStr = coerceCaseToLower(str, caseType); switch (toCase) { case "pascal": return lowerToPascalCase(lowerStr); case "camel": return lowerToCamelCase(lowerStr); case "snake": return lowerToSnakeCase(lowerStr); case "kebab": return lowerToKebabCase(lowerStr); case "macro": return lowerToMacroCase(lowerStr); case "upper": return lowerStr.toUpperCase(); case "lower": return lowerStr.toLowerCase(); case "train": return lowerToTrainCase(lowerStr); case "title": return lowerToTitleCase(lowerStr); default: return str; } }