{"version":3,"file":"underscore.mjs","names":[],"sources":["../src/underscore.ts"],"sourcesContent":["/**\n * Convert words to a sentence.\n *\n * @param items - An array of words to be joined.\n * @returns A string with the items joined by a comma and the last item joined by \", or\".\n */\nexport const toSentence = (items: string[]): string => {\n  // TODO: Once Safari supports it, use Intl.ListFormat\n  if (items.length == 0) {\n    return '';\n  }\n  if (items.length == 1) {\n    return items[0];\n  }\n  let sentence = items.slice(0, -1).join(', ');\n  sentence += `, or ${items.slice(-1)}`;\n  return sentence;\n};\n\nconst IP_V4_ADDRESS_REGEX =\n  /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;\n\n/**\n * Checks if a string is a valid IPv4 address.\n *\n * @returns True if the string is a valid IPv4 address, false otherwise.\n */\nexport function isIPV4Address(str: string | undefined | null): boolean {\n  return IP_V4_ADDRESS_REGEX.test(str || '');\n}\n\n/**\n * Converts the first character of a string to uppercase.\n *\n * @param str - The string to be converted.\n * @returns The modified string with the rest of the string unchanged.\n *\n * @example\n * ```ts\n * titleize('hello world') // 'Hello world'\n * ```\n */\nexport function titleize(str: string | undefined | null): string {\n  const s = str || '';\n  return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n/**\n * Converts a string from snake_case to camelCase.\n */\nexport function snakeToCamel(str: string | undefined): string {\n  return str ? str.replace(/([-_][a-z])/g, match => match.toUpperCase().replace(/-|_/, '')) : '';\n}\n\n/**\n * Converts a string from camelCase to snake_case.\n */\nexport function camelToSnake(str: string | undefined): string {\n  return str ? str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`) : '';\n}\n\nconst createDeepObjectTransformer = (transform: any) => {\n  const deepTransform = (obj: any): any => {\n    if (!obj) {\n      return obj;\n    }\n\n    if (Array.isArray(obj)) {\n      return obj.map(el => {\n        if (typeof el === 'object' || Array.isArray(el)) {\n          return deepTransform(el);\n        }\n        return el;\n      });\n    }\n\n    const copy = { ...obj };\n    const keys = Object.keys(copy);\n    for (const oldName of keys) {\n      const newName = transform(oldName.toString());\n      if (newName !== oldName) {\n        copy[newName] = copy[oldName];\n        delete copy[oldName];\n      }\n      if (typeof copy[newName] === 'object') {\n        copy[newName] = deepTransform(copy[newName]);\n      }\n    }\n    return copy;\n  };\n\n  return deepTransform;\n};\n\n/**\n * Transforms camelCased objects/ arrays to snake_cased.\n * This function recursively traverses all objects and arrays of the passed value\n * camelCased keys are removed.\n *\n * @function\n */\nexport const deepCamelToSnake = createDeepObjectTransformer(camelToSnake);\n\n/**\n * Transforms snake_cased objects/ arrays to camelCased.\n * This function recursively traverses all objects and arrays of the passed value\n * camelCased keys are removed.\n *\n * @function\n */\nexport const deepSnakeToCamel = createDeepObjectTransformer(snakeToCamel);\n\n/**\n * A function to determine if a value is truthy.\n *\n * @returns True for `true`, true, positive numbers. False for `false`, false, 0, negative integers and anything else.\n */\nexport function isTruthy(value: unknown): boolean {\n  // Return if Boolean\n  if (typeof value === `boolean`) {\n    return value;\n  }\n\n  // Return false if null or undefined\n  if (value === undefined || value === null) {\n    return false;\n  }\n\n  // If the String is true or false\n  if (typeof value === `string`) {\n    if (value.toLowerCase() === `true`) {\n      return true;\n    }\n\n    if (value.toLowerCase() === `false`) {\n      return false;\n    }\n  }\n\n  // Now check if it's a number\n  const number = parseInt(value as string, 10);\n  if (isNaN(number)) {\n    return false;\n  }\n\n  if (number > 0) {\n    return true;\n  }\n\n  // Default to false\n  return false;\n}\n\n/**\n * Get all non-undefined values from an object.\n */\nexport function getNonUndefinedValues<T extends object>(obj: T): Partial<T> {\n  return Object.entries(obj).reduce((acc, [key, value]) => {\n    if (value !== undefined) {\n      acc[key as keyof T] = value;\n    }\n    return acc;\n  }, {} as Partial<T>);\n}\n"],"mappings":";;;;;;;AAMA,MAAa,cAAc,UAA4B;CAErD,IAAI,MAAM,UAAU,GAClB,OAAO;CAET,IAAI,MAAM,UAAU,GAClB,OAAO,MAAM;CAEf,IAAI,WAAW,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,IAAI;CAC3C,YAAY,QAAQ,MAAM,MAAM,EAAE;CAClC,OAAO;AACT;AAEA,MAAM,sBACJ;;;;;;AAOF,SAAgB,cAAc,KAAyC;CACrE,OAAO,oBAAoB,KAAK,OAAO,EAAE;AAC3C;;;;;;;;;;;;AAaA,SAAgB,SAAS,KAAwC;CAC/D,MAAM,IAAI,OAAO;CACjB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,MAAM,CAAC;AAC9C;;;;AAKA,SAAgB,aAAa,KAAiC;CAC5D,OAAO,MAAM,IAAI,QAAQ,iBAAgB,UAAS,MAAM,YAAY,CAAC,CAAC,QAAQ,OAAO,EAAE,CAAC,IAAI;AAC9F;;;;AAKA,SAAgB,aAAa,KAAiC;CAC5D,OAAO,MAAM,IAAI,QAAQ,WAAU,WAAU,IAAI,OAAO,YAAY,GAAG,IAAI;AAC7E;AAEA,MAAM,+BAA+B,cAAmB;CACtD,MAAM,iBAAiB,QAAkB;EACvC,IAAI,CAAC,KACH,OAAO;EAGT,IAAI,MAAM,QAAQ,GAAG,GACnB,OAAO,IAAI,KAAI,OAAM;GACnB,IAAI,OAAO,OAAO,YAAY,MAAM,QAAQ,EAAE,GAC5C,OAAO,cAAc,EAAE;GAEzB,OAAO;EACT,CAAC;EAGH,MAAM,OAAO,EAAE,GAAG,IAAI;EACtB,MAAM,OAAO,OAAO,KAAK,IAAI;EAC7B,KAAK,MAAM,WAAW,MAAM;GAC1B,MAAM,UAAU,UAAU,QAAQ,SAAS,CAAC;GAC5C,IAAI,YAAY,SAAS;IACvB,KAAK,WAAW,KAAK;IACrB,OAAO,KAAK;GACd;GACA,IAAI,OAAO,KAAK,aAAa,UAC3B,KAAK,WAAW,cAAc,KAAK,QAAQ;EAE/C;EACA,OAAO;CACT;CAEA,OAAO;AACT;;;;;;;;AASA,MAAa,mBAAmB,4BAA4B,YAAY;;;;;;;;AASxE,MAAa,mBAAmB,4BAA4B,YAAY;;;;;;AAOxE,SAAgB,SAAS,OAAyB;CAEhD,IAAI,OAAO,UAAU,WACnB,OAAO;CAIT,IAAI,UAAU,UAAa,UAAU,MACnC,OAAO;CAIT,IAAI,OAAO,UAAU,UAAU;EAC7B,IAAI,MAAM,YAAY,MAAM,QAC1B,OAAO;EAGT,IAAI,MAAM,YAAY,MAAM,SAC1B,OAAO;CAEX;CAGA,MAAM,SAAS,SAAS,OAAiB,EAAE;CAC3C,IAAI,MAAM,MAAM,GACd,OAAO;CAGT,IAAI,SAAS,GACX,OAAO;CAIT,OAAO;AACT;;;;AAKA,SAAgB,sBAAwC,KAAoB;CAC1E,OAAO,OAAO,QAAQ,GAAG,CAAC,CAAC,QAAQ,KAAK,CAAC,KAAK,WAAW;EACvD,IAAI,UAAU,QACZ,IAAI,OAAkB;EAExB,OAAO;CACT,GAAG,CAAC,CAAe;AACrB"}