All Downloads are FREE. Search and download functionalities are using the official Maven repository.

helpers.formatter.ts Maven / Gradle / Ivy

import { env } from 'utils/utils'

const SHOW_KEYS: boolean = env('SHOW_KEYS') == "true"

export type FormatFunction = (_ :string) => string

export type Matches = IterableIterator 

class Formatter {

  /* ========= api string manipulation functions ======= */

  static toBraceless: FormatFunction = (str: string): string => 
    str.replace(/[{}]/g, '')

  static toMultiSentenceCase: FormatFunction = (str: string): string =>
    str.split('. ').map(Formatter.toSentenceCase).join('. ')

  static toSentenceCase: FormatFunction = (str: string): string =>
    Formatter.apply(str, Formatter.toSentenceCaseFunction)

  static toTitleCase: FormatFunction = (str: string): string =>
    Formatter.apply(str, Formatter.toTitleCaseFunction)
 
  static toLowerCase: FormatFunction = (str: string): string =>
    Formatter.apply(str, Formatter.toLowerCaseFunction)
    
  static toList(list: string[], lastSeparator: string = " and ", limit: number = 0, separator: string = ", ") {
    if (list.length <= 1)
      return list.join(separator)
    else if (limit == 1)
      return list[0] + separator + "..."
    else {
      const [last] = list.splice(-1,1)
      if (limit > 0 && list.length >= limit) {
        list = list.slice(0, limit-1)
        list.push("...")
      }
  
      return list.join(separator) + (list.length + 1 > 1 ? lastSeparator : "") + last
    }
  }


  /* =========== where the magic happens =========== */

  // apply a string manipulation function and restore the casing for each { ... } group
  static apply(str: string, f: FormatFunction): string {
    if (SHOW_KEYS)
      return str

    const trimmed = Formatter.toTrimmedFunction(str) 

    return Formatter.restore(
      f(Formatter.toBraceless(trimmed)),  
      Formatter.getMatches(trimmed)
    ) 
  }

  private static restore(str: string, matches: Matches): string {
    var result = str
    // insert the original matched groups. This restores casing
    var i = 0
    for (const match of matches) {
      result = Formatter.splice(result, (match.index as number) - (i * 2), match['1'].length, match['1']) 
      i++
    }
    return result 
  }

  private static getMatches(str: string): Matches {
    const regexp  = /{([^}]*)}/g;
    return str.matchAll(regexp)
  } 

  private static splice(str: string, start: number, delCount: number, newSubStr: string) {
    return str.slice(0, start) + newSubStr + str.slice(start + Math.abs(delCount));
  }

  /* ========== internally used string manipulation functions ========= */

  private static toSentenceCaseFunction: FormatFunction = (str) => 
    str.charAt(0).toUpperCase() + str.substring(1).toLowerCase() 
  
  private static toTitleCaseFunction: FormatFunction = (str) => 
    str.replace(/\p{L}+'\p{L}+|\p{L}+/ug, (word) => word.charAt(0).toUpperCase() + word.substring(1).toLowerCase())    
  
  private static toLowerCaseFunction: FormatFunction = (str) => 
    str.toLowerCase() 

  private static toTrimmedFunction: FormatFunction = (str: string): string =>
    str.replace(/\s+/g,' ').replace(/^\s+|\s+$/g,'');

};

export { Formatter as F }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy