UNPKG

kysely

Version:
106 lines (105 loc) 3.66 kB
/// <reference types="./camel-case.d.ts" /> /** * Creates a function that transforms camel case strings to snake case. */ export function createSnakeCaseMapper({ upperCase = false, underscoreBeforeDigits = false, underscoreBetweenUppercaseLetters = false, } = {}) { return memoize((str) => { if (str.length === 0) { return str; } const upper = str.toUpperCase(); const lower = str.toLowerCase(); let out = lower[0]; for (let i = 1, l = str.length; i < l; ++i) { const char = str[i]; const prevChar = str[i - 1]; const upperChar = upper[i]; const prevUpperChar = upper[i - 1]; const lowerChar = lower[i]; const prevLowerChar = lower[i - 1]; // If underScoreBeforeDigits is true then, well, insert an underscore // before digits :). Only the first digit gets an underscore if // there are multiple. if (underscoreBeforeDigits && isDigit(char) && !isDigit(prevChar)) { out += '_' + char; continue; } // Test if `char` is an upper-case character and that the character // actually has different upper and lower case versions. if (char === upperChar && upperChar !== lowerChar) { const prevCharacterIsUppercase = prevChar === prevUpperChar && prevUpperChar !== prevLowerChar; // If underscoreBetweenUppercaseLetters is true, we always place an underscore // before consecutive uppercase letters (e.g. "fooBAR" becomes "foo_b_a_r"). // Otherwise, we don't (e.g. "fooBAR" becomes "foo_bar"). if (underscoreBetweenUppercaseLetters || !prevCharacterIsUppercase) { out += '_' + lowerChar; } else { out += lowerChar; } } else { out += char; } } if (upperCase) { return out.toUpperCase(); } else { return out; } }); } /** * Creates a function that transforms snake case strings to camel case. */ export function createCamelCaseMapper({ upperCase = false, } = {}) { return memoize((str) => { if (str.length === 0) { return str; } if (upperCase && isAllUpperCaseSnakeCase(str)) { // Only convert to lower case if the string is all upper // case snake_case. This allows camelCase strings to go // through without changing. str = str.toLowerCase(); } let out = str[0]; for (let i = 1, l = str.length; i < l; ++i) { const char = str[i]; const prevChar = str[i - 1]; if (char !== '_') { if (prevChar === '_') { out += char.toUpperCase(); } else { out += char; } } } return out; }); } function isAllUpperCaseSnakeCase(str) { for (let i = 1, l = str.length; i < l; ++i) { const char = str[i]; if (char !== '_' && char !== char.toUpperCase()) { return false; } } return true; } function isDigit(char) { return char >= '0' && char <= '9'; } function memoize(func) { const cache = new Map(); return (str) => { let mapped = cache.get(str); if (!mapped) { mapped = func(str); cache.set(str, mapped); } return mapped; }; }