code: function snakeCase(str, { upperCase = false, underscoreBeforeDigits = false } = {}) {
    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) {
        // Multiple consecutive upper case characters shouldn't add underscores.
        // For example "fooBAR" should be converted to "foo_bar".
        if (prevChar === prevUpperChar && prevUpperChar !== prevLowerChar) {
          out += lowerChar;
        } else {
          out += '_' + lowerChar;
        }
      } else {
        out += char;
      }
    }
  
    if (upperCase) {
      return out.toUpperCase();
    } else {
      return out;
    }
  }
docs: camelCase to snake_case converter that also works with non-ascii characters This is needed especially so that aliases containing the `:` character, objection uses internally, work.