UNPKG

@tevari/helpers

Version:

Collection of various small helpers for javascript and typescript based projects

1,544 lines (1,538 loc) 84 kB
// src/exceptions.ts var NoSuchElementException = class extends Error { constructor(message) { super(message); } }; // src/optional.ts var Optional = class _Optional { constructor(value) { this.value = value; } /** * Returns an empty Optional instance. */ static empty() { return new _Optional(); } /** * Returns an Optional with the specified present non-null value. * * @param value The value to fill the Optional with. * @returns an Optional with the given value. */ static filled(value) { return new _Optional(value); } /** * Returns an Optional with the specified present value if non-null, otherwise returns an empty Optional. * * @param value The value to fill the Optional with. * @returns an Optional with the given value if non-null, an empty Optional otherwise. */ static of(value) { if (value === void 0 || value === null) return _Optional.empty(); return new _Optional(value); } /** * Indicates whether some other object is "equal to" this Optional. * * @param other Object to compare this optional value with. * @param comparator The predicate used to compare the values. * @returns `true`if the two values are equal, `false` otherwise. */ equals(other, comparator) { if (this.isEmpty()) return false; if (comparator) return comparator(this.value, other); return this.value === other; } /** * Casts this Optional to the given type. * * @returns a new optional typed as the given type. */ as() { return _Optional.of(this.value); } /** * Sets the given value. If a value is already present, this method replaces it. * * @param value The value to set. */ set(value) { this.value = value; return this; } /** * If a value is present in this Optional, returns the value, otherwise throws NoSuchElementException. * * @returns the value if present, throws NoSuchElementException otherwise. */ get() { if (this.isEmpty()) throw new NoSuchElementException( "[Optional] You are trying to get an empty value." ); return this.value; } /** * If a value is present, and the value matches the given predicate, return an Optional describing the value, otherwise return an empty Optional. * * @param predicate To filter the value with if present. * @returns a filled Optional if a value is present and it matches the given predicate, and emlpty Optional otherwise. */ filter(predicate) { if (this.isEmpty() || !predicate(this.value)) return _Optional.empty(); return _Optional.of(this.value); } /** * If a value is present, apply the provided mapping function to it, and if the result is non-null, return an Optional describing the result. * * @param mapper The mapper function. * @returns the result Optional if a value is present, an empty Optional otherwise. */ map(mapper) { if (this.isEmpty()) return _Optional.empty(); return _Optional.of(mapper(this.value)); } /** * If a value is present, apply the provided Optional-bearing mapping function to it, return that result, otherwise return an empty Optional. * * @param mapper The mapper function. * @returns the result Optional if a value is present, an empty Optional otherwise. */ flatMap(mapper) { if (this.isEmpty()) return _Optional.empty(); return mapper(this.value); } /** * Tests whether this optional is empty. * * @returns `true` if there is no present value, otherwise `false`. */ isEmpty() { if (this.value === void 0 || this.value === null) return true; return false; } /** * Tests whether a value is present. * * @returns `true` if there is a value present, otherwise `false`. */ isPresent() { if (this.isEmpty()) return false; return true; } /** * If a value is present, invoke the specified consumer with the value, otherwise do nothing. * * @param consumer The consumer to invoke if a value is present. * @returns itself for chaining purposes. */ ifPresent(consumer) { if (this.isEmpty()) return this; consumer(this.value); return this; } /** * Return the value if present, otherwise return other. * * @param other The default value to return if this Optional is empty. * @returns the value if present, otherwise `other`. */ orElse(other) { if (this.isEmpty()) return other; return this.value; } /** * If the optional is empty, invokes the specified supplier, otherwise do nothing. * * @param other The default value to return if this Optional is empty. * @returns itself for chaining purposes. */ orElseInvoke(procedure) { if (this.isPresent()) return this; procedure(); return this; } /** * Return the value if present, otherwise return `undefined`. * * @returns the value if present, otherwise `undefined`. */ orUndefined() { if (this.isEmpty()) return void 0; return this.value; } /** * Return the value if present, otherwise return `null`. * * @returns the value if present, otherwise `null`. */ orNull() { if (this.isEmpty()) return null; return this.value; } /** * Return the value if present, otherwise invoke other and return the result of that invocation. * * @param supplier The supplier to invoke when the value is not present. * @returns either the value if present, the result of the given supplier otherwise. */ orElseGet(supplier) { if (this.isEmpty()) return supplier(); return this.value; } /** * Return the contained value, if present, otherwise throw an exception to be created by the provided supplier. * * @param exceptionSupplier * @returns */ orElseThrow(exceptionSupplier) { if (this.isEmpty()) throw exceptionSupplier(); return this.value; } /** * If a value is present, apply the provided resolver function to it, and if the result is non-null, return an Optional describing the result. * * @param resolver The resolver function. * @param other The value to return if the Optional is empty. * @returns the result Optional if a value is present, the given `other` parameter otherwise. */ resolve(resolver, other) { if (this.isEmpty()) return other; return resolver(this.value); } }; // src/strings.ts var EMPTY = ""; var FORWARD_SLASH = "/"; var BACKSLASH = "\\"; var HASHTAG = "#"; var SPACE = " "; var TAB = " "; var NEW_LINE = "\n"; var UNDERSCORE = "_"; var MINUS = "-"; var PLUS = "+"; var DOT = "."; var COLON = ":"; var SEMI_COLON = ";"; var WILDCARD = "*"; var PERCENTAGE = "%"; var COMMA = ","; var QUESTION_MARK = "?"; var UNIT_NORMAL_METRIC = "Nm"; var UNIT_MASS = "g/m\xB2"; var UNIT_WEIGHT = "g"; var THREE_DOTS = "\u2026"; var STRING_ONLY_ALPHA_CHARS_REGEX = /^[a-z]+$/i; var STRING_ONLY_NUMERIC_CHARS_REGEX = /^[1-9]+$/i; var STRING_EMAIL_VALIDATION_REGEXP = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; var SPECIALS_TO_PLAIN_CHARS = /* @__PURE__ */ new Map([ ["\xE1", "a"], ["\xE0", "a"], ["\xE2", "a"], ["\xE6", "a"], ["\xAA", "a"], ["\xE4", "a"], ["\xE3", "a"], ["\xE5", "a"], ["\u0101", "a"], ["\xE7", "c"], ["\u0107", "c"], ["\u010D", "c"], ["\xE9", "e"], ["\xE8", "e"], ["\xEA", "e"], ["\xEB", "e"], ["\u0119", "e"], ["\u0117", "e"], ["\u0113", "e"], ["\xEE", "i"], ["\xEF", "i"], ["\xEC", "i"], ["\xED", "i"], ["\u012F", "i"], ["\u012B", "i"], ["\xF1", "n"], ["\u0144", "n"], ["\xF4", "o"], ["\u0153", "o"], ["\xBA", "o"], ["\xF6", "o"], ["\xF2", "o"], ["\xF3", "o"], ["\xF5", "o"], ["\xF8", "o"], ["\xFB", "u"], ["\xF9", "u"], ["\xFC", "u"], ["\xFA", "u"], ["\u016B", "u"], ["\xFF", "y"], ["\u2026", "..."] ]); var stringPlainify = (value) => { const result = []; for (let i = 0; i < value.length; i++) { const char = value.charAt(i); const plainChar = SPECIALS_TO_PLAIN_CHARS.get(char); result.push(plainChar ? plainChar : char); } return result.join(EMPTY); }; var stringIsAlpha = (value) => { return value.match(STRING_ONLY_ALPHA_CHARS_REGEX) !== null; }; var stringIsNumeric = (value) => { return value.match(STRING_ONLY_NUMERIC_CHARS_REGEX) !== null; }; var stringGetNaturalComparator = (order = "desc") => (a, b) => { if (order === "asc") { return stringPlainify(a.toLowerCase()).localeCompare(stringPlainify(b.toLowerCase())); } return stringPlainify(b.toLowerCase()).localeCompare(stringPlainify(a.toLowerCase())); }; var stringGetNaturalValueComparator = (order = "desc", extractor) => (a, b) => { const stringA = extractor(a); const stringB = extractor(b); if (order === "asc") { return stringPlainify(stringA.toLowerCase()).localeCompare(stringPlainify(stringB.toLowerCase())); } return stringPlainify(stringB.toLowerCase()).localeCompare(stringPlainify(stringA.toLowerCase())); }; var STRING_NATURAL_COMPARATOR_ASC = stringGetNaturalComparator("asc"); var STRING_NATURAL_COMPARATOR_DESC = stringGetNaturalComparator("desc"); var STRING_NATURAL_VALUE_COMPARATOR_ASC = (extractor) => stringGetNaturalValueComparator("asc", extractor); var STRING_NATURAL_VALUE_COMPARATOR_DESC = (extractor) => stringGetNaturalValueComparator("desc", extractor); var stringIsEmpty = (value) => { return value === EMPTY; }; var stringIsBlank = (value) => { return value === void 0 || value === null || stringIsEmpty(value); }; var stringIsFilled = (value) => { return !stringIsBlank(value); }; var stringReplaceAll = (value, pattern, replaceValue) => { return value.replace(new RegExp(pattern, "g"), replaceValue); }; var stringCamelCaseToSnakeCase = (text) => { return text.split(/(?=[A-Z])/).join("_").toLowerCase(); }; var stringCamelCaseToKebabCase = (text) => { return text.split(/(?=[A-Z])/).join("-").toLowerCase(); }; var stringSnakeCaseToCamelCase = (text, options) => { const { firstLetter = "lower" } = options ?? {}; const result = text.replace(/(?!^)_(.)/g, (_, char) => char.toUpperCase()); return firstLetter === "lower" ? result : stringCapitalize(result); }; var stringKebabCaseToCamelCase = (text, options) => { const { firstLetter = "lower" } = options ?? {}; const result = text.replace(/-./g, (x) => x[1].toUpperCase()); return firstLetter === "lower" ? result : stringCapitalize(result); }; var stringIsCamelCase = (value) => { const lowerCamelCase = stringCamelize(value); if (value === lowerCamelCase) return true; return value === stringCapitalize(lowerCamelCase); }; var stringIsPascalCase = (value) => { const pascalized = stringPascalize(value); return value === pascalized; }; var stringIsKebabCase = (value) => { const kebabized = stringKebabize(value); return value === kebabized; }; var stringIsSnakeCase = (value) => { const snakized = stringSnakize(value); return value === snakized; }; var stringIsString = (data) => { return typeof data === "string"; }; var stringHumanize = (value) => { const words = value.match(/[A-Za-z][a-z]*|[0-9]+/g) || []; return words.map((word) => word.toLowerCase()).join(" "); }; var stringCamelize = (value, options) => { const { firstLetter = "lower" } = options ?? {}; const result = value.replace(/[_-]+/g, " ").replace(/\s./g, (x) => x[1].toUpperCase()).replace(/\s+/g, ""); return firstLetter === "lower" ? result : stringCapitalize(result); }; var stringPascalize = (value) => { return stringCamelize(value, { firstLetter: "upper" }); }; var stringKebabize = (text) => { return text.replace(/[\s_]+/g, "-").split(/(?=[A-Z])/).join("-").toLowerCase(); }; var stringSnakize = (text) => { return text.replace(/[\s-]+/g, "_").split(/(?=[A-Z])/).join("_").toLowerCase(); }; var stringParseBoolean = (input) => { if (!input) return; try { return JSON.parse(input.toLowerCase()); } catch (e) { return; } }; var stringPad = (value, nbOfCharacters, paddingCharacter = EMPTY) => { const val = value; if (Math.abs(nbOfCharacters) <= val.length) { return val; } const m = Math.max(Math.abs(nbOfCharacters) - value.length || 0, 0); const pad = Array(m + 1).join(String(paddingCharacter).charAt(0)); return nbOfCharacters < 0 ? pad + val : val + pad; }; var stringEquals = (value1, value2) => { return value1.trim() === value2?.trim(); }; var stringValueOrEmpty = (value) => { if (value === false || stringIsBlank(value)) return EMPTY; return value; }; var stringExtractEmailDomain = (email) => { const results = email.toLowerCase().match(/.*@(.*)\..*/); if (results?.length === 2) return results[1]; }; var stringCapitalizeAll = (string) => { return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); }; var stringCapitalize = (string) => { return string.charAt(0).toUpperCase() + string.slice(1); }; var stringCapitalizeEachWord = (string) => { const eachWord = string.split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()); return eachWord.join(" "); }; var StringHelpers = { /** * Plainify the given string, converting every special character into its plain brother. * * @param value The string to convert. * @returns a plainified string. */ plainify: stringPlainify, /** * Tests whether the given data parameter is a string. * * @param data The data to test. * @returns `true` if the given data is a string, `false` otherwise. */ isString: stringIsString, /** * Replace all occurrences. * * @param value The string to compute. * @param pattern The pattern to look for. * @param replaceValue The replacer. * @returns the result. */ replaceAll: stringReplaceAll, /** * Converts the given snake case formatted string into a camel case format. * * @param text The string to convert. * @param options The converter options. * @returns the converted string result. * @deprecated use `camelize` instead. */ snakeCaseToCamelCase: stringSnakeCaseToCamelCase, /** * Converts the given camel case formatted string into a kebab case format. * * @param text The string to convert. * @returns the converted string result. * @deprecated use `kebabize` instead. */ camelCaseToKebabCase: stringCamelCaseToKebabCase, /** * Converts the given kebab case formatted string into a camel case format. * * @param text The string to convert. * @param options The converter options. * @returns the converted string result. * @deprecated use `camelize` instead. */ kebabCaseToCamelCase: stringKebabCaseToCamelCase, /** * Converts the given camel case formatted string into a snake case format. * * @param text The string to convert. * @returns the converted string result. * @deprecated use `snakize` instead. */ camelCaseToSnakeCase: stringCamelCaseToSnakeCase, /** * Humanize the given string. * * @param value the string to humanize. * @returns the formatted result. */ humanize: stringHumanize, /** * Camelize the given string. * * @param value the string to camelize. * @param options The converter options. * @returns the formatted result. */ camelize: stringCamelize, /** * Pascalize the given string. * * @param value the string to convert to PascalCase format. * @returns the formatted result. */ pascalize: stringPascalize, /** * Converts the given string into a kebab-case format. * * @param text The string to convert. * @returns the converted string result. */ kebabize: stringKebabize, /** * Converts the given string into a snake_case format. * * @param text The string to convert. * @returns the converted string result. */ snakize: stringSnakize, /** * Tests whether the given data parameter is a camel case formatted string. * * @param data The string to test. * @returns `true` if the given data is camel case, `false` otherwise. */ isCamelCase: stringIsCamelCase, /** * Tests whether the given data parameter is a pascal case formatted string. * * @param data The string to test. * @returns `true` if the given data is camel case, `false` otherwise. */ isPascalCase: stringIsPascalCase, /** * Tests whether the given data parameter is a kebab case formatted string. * * @param data The string to test. * @returns `true` if the given data is kebab case, `false` otherwise. */ isKebabCase: stringIsKebabCase, /** * Tests whether the given data parameter is a snake case formatted string. * * @param data The string to test. * @returns `true` if the given data is snake case, `false` otherwise. */ isSnakeCase: stringIsSnakeCase, /** * Tests whether the given string contains only alpha characters. * * @param value The string to check. * @returns `true` if the given string only contains alpha characters, `false` otherwise. */ isAlpha: stringIsAlpha, /** * Tests whether the given string contains only numeric characters. * * @param value The string to check. * @returns `true` if the given string only contains numeric characters, `false` otherwise. */ isNumeric: stringIsNumeric, /** * Test whether the two given string trimed value are equal. * @param value1 The first value to compare. * @param value2 The second value to compare. * @returns `true` if the two values are equal once trimed, `false` otherwise. */ equals: stringEquals, /** * Converted any given blank values to an empty string (""). If the given value contains a string, the method will return it unarmed. * * @param value The value to convert. * @returns the exact given string if not blank, an empty string otherwise. */ valueOrEmpty: stringValueOrEmpty, /** * Formats the given string value to contain at least the given number of characters, * adding the given padding character at the end of the value if needed. * * @param value the value to format. * @param nbOfCharacters The desired minimum number of characters. * @param paddingCharacter The padding character. * @returns the formatted result. */ pad: stringPad, /** * Test whether the given string is strictly equal to an empty string. * * @param value The string to test. * @returns `true` if the given string is empty, `false` otherwise. */ isEmpty: stringIsEmpty, /** * Test whether the given string is either `undefined`, `null` or equal to an empty string. * * @param value The string to test. * @returns `true` if the given string is blank, `false` otherwise. */ isBlank: stringIsBlank, /** * Test whether the given string is neither `undefined`, `null` nor equal to an empty string. * * @param value The string to test. * @returns `true` if the given string is filled, `false` otherwise. */ isFilled: stringIsFilled, /** * Extract the domain name from the given email address. * * @param email The email address. * @returns the corresponding domain name. */ extractEmailDomain: stringExtractEmailDomain, /** * Capitalizes the first letter of the given string and lower everything else. * * @param string the string to compute. * @returns the result string. */ capitalizeAll: stringCapitalizeAll, /** * Capitalizes the first letter of the given string. * * @param string the string to compute. * @returns the result string. */ capitalize: stringCapitalize, /** * Capitalizes the first letter of each word of the given string. * * @param string the string to compute. * @returns the result string. */ capitalizeEachWord: stringCapitalizeEachWord }; var StringComparators = { /** * An ascendent natural string comparator. */ naturalAsc: STRING_NATURAL_COMPARATOR_ASC, /** * An descendent natural string comparator. */ naturalDesc: STRING_NATURAL_COMPARATOR_DESC, /** * An ascendent natural string comparator from extracted values. */ naturalValueAsc: STRING_NATURAL_VALUE_COMPARATOR_ASC, /** * An descendent natural string comparator from extracted values. */ naturalValueDesc: STRING_NATURAL_VALUE_COMPARATOR_DESC }; var StringParsers = { /** * Extract a boolean value from the given string. * * @param input The boolean-string to parse. * @returns the boolean value corresponding to the given string. If the given input is `null`, this methid resturns `undefined`. */ parseBoolean: stringParseBoolean }; var StringRegexs = { /** * Regex pattern that matches string containing only alpha characters. */ alpha: STRING_ONLY_ALPHA_CHARS_REGEX, /** * Regex pattern that matches string containing only numeric characters. */ numeric: STRING_ONLY_NUMERIC_CHARS_REGEX, /** * Regex pattern that matches an email addess. */ email: STRING_EMAIL_VALIDATION_REGEXP }; var StringSymbols = { EMPTY, FORWARD_SLASH, HASHTAG, SPACE, UNDERSCORE, MINUS, PLUS, DOT, COLON, WILDCARD, PERCENTAGE, COMMA, QUESTION_MARK, UNIT_NORMAL_METRIC, UNIT_MASS, UNIT_WEIGHT, THREE_DOTS }; var Strings = { /** * String symbols. */ symbol: StringSymbols, /** * String helper methods. */ helper: StringHelpers, /** * String comparators. */ comparator: StringComparators, /** * String parsers. */ parser: StringParsers, /** * String regexs. */ regex: StringRegexs }; var TString = class _TString { constructor(value) { this.value = value; } /** * Tests whether the given data parameter is a string. * * @returns `true` if the given data is a string, `false` otherwise. */ isString() { return stringIsString(this.value); } /** * Gets the value as plain string. * * @returns the string value. */ get() { if (!this.isString()) throw Error("[TString] value is not a string."); return this.value; } /** * Plainify the given string, converting every special character into its plain brother. * * @returns a plainified string. */ plainify() { if (!this.isString()) throw Error("[TString] value is not a string."); return new _TString(stringPlainify(this.value)); } /** * Replace all occurrences. * * @param pattern The pattern to look for. * @param replaceValue The replacer. * @returns the result. */ replaceAll(pattern, replaceValue) { if (!this.isString()) throw Error("[TString] value is not a string."); return new _TString(stringReplaceAll(this.value, pattern, replaceValue)); } /** * Humanize the given string. * * @returns the formatted result. */ humanize() { if (!this.isString()) throw Error("[TString] value is not a string."); return new _TString(stringHumanize(this.value)); } /** * Camelize the given string. * * @param options The converter options. * @returns the formatted result. */ camelize(options) { if (!this.isString()) throw Error("[TString] value is not a string."); return new _TString(stringCamelize(this.value, options)); } /** * Pascalize the given string. * * @returns the formatted result. */ pascalize() { if (!this.isString()) throw Error("[TString] value is not a string."); return new _TString(stringPascalize(this.value)); } /** * Converts the given string into a kebab-case format. * * @returns the formatted result. */ kebabize() { if (!this.isString()) throw Error("[TString] value is not a string."); return new _TString(stringKebabize(this.value)); } /** * Converts the given string into a snake_case format. * * @returns the formatted result. */ snakize() { if (!this.isString()) throw Error("[TString] value is not a string."); return new _TString(stringSnakize(this.value)); } /** * Tests whether the given data parameter is a camel case formatted string. * * @returns `true` if the given data is camel case, `false` otherwise. */ isCamelCase() { if (!this.isString()) throw Error("[TString] value is not a string."); return stringIsCamelCase(this.value); } /** * Tests whether the given data parameter is a pascal case formatted string. * * @returns `true` if the given data is spacal case, `false` otherwise. */ isPascalCase() { if (!this.isString()) throw Error("[TString] value is not a string."); return stringIsPascalCase(this.value); } /** * Tests whether the given data parameter is a kebab case formatted string. * * @returns `true` if the given data is kebab case, `false` otherwise. */ isKebabCase() { if (!this.isString()) throw Error("[TString] value is not a string."); return stringIsKebabCase(this.value); } /** * Tests whether the given data parameter is a snake case formatted string. * * @returns `true` if the given data is snake case, `false` otherwise. */ isSnakeCase() { if (!this.isString()) throw Error("[TString] value is not a string."); return stringIsSnakeCase(this.value); } /** * Tests whether the given string contains only alpha characters. * * @returns `true` if the given string only contains alpha characters, `false` otherwise. */ isAlpha() { if (!this.isString()) throw Error("[TString] value is not a string."); return stringIsAlpha(this.value); } /** * Tests whether the given string contains only numeric characters. * * @returns `true` if the given string only contains numeric characters, `false` otherwise. */ isNumeric() { if (!this.isString()) throw Error("[TString] value is not a string."); return stringIsNumeric(this.value); } /** * Test whether the given string is strictly equal to an empty string. * * @returns `true` if the given string is empty, `false` otherwise. */ isEmpty() { if (!this.isString()) throw Error("[TString] value is not a string."); return stringIsEmpty(this.value); } /** * Test whether the given string is either `undefined`, `null` or equal to an empty string. * * @returns `true` if the given string is blank, `false` otherwise. */ isBlank() { if (!this.isString()) throw Error("[TString] value is not a string."); return stringIsBlank(this.value); } /** * Test whether the given string is neither `undefined`, `null` nor equal to an empty string. * * @returns `true` if the given string is filled, `false` otherwise. */ isFilled() { if (!this.isString()) throw Error("[TString] value is not a string."); return stringIsFilled(this.value); } /** * Test whether the two given string trimed value are equal. * * @param value The value to compare with. * @returns `true` if the two values are equal once trimed, `false` otherwise. */ equals(value) { if (!this.isString()) throw Error("[TString] value is not a string."); return stringEquals(this.value, value); } /** * Converted any given blank values to an empty string (""). If the given value contains a string, the method will return it unarmed. * * @returns the exact given string if not blank, an empty string otherwise. */ valueOrEmpty() { return new _TString(stringValueOrEmpty(this.value)); } /** * Formats the given string value to contain at least the given number of characters, * adding the given padding character at the end of the value if needed. * * @param nbOfCharacters The desired minimum number of characters. * @param paddingCharacter The padding character. * @returns the formatted result. */ pad(nbOfCharacters, paddingCharacter = EMPTY) { if (!this.isString()) throw Error("[TString] value is not a string."); return new _TString(stringPad(this.value, nbOfCharacters, paddingCharacter)); } /** * Extract the domain name from the given email address. * * @returns the corresponding domain name. */ extractEmailDomain() { if (!this.isString()) throw Error("[TString] value is not a string."); return new _TString(stringExtractEmailDomain(this.value)); } /** * Capitalizes the first letter of the given string and lower everything else. * * @returns the result string. */ capitalizeAll() { if (!this.isString()) throw Error("[TString] value is not a string."); return new _TString(stringCapitalizeAll(this.value)); } /** * Capitalizes the first letter of the given string. * * @returns the result string. */ capitalize() { if (!this.isString()) throw Error("[TString] value is not a string."); return new _TString(stringCapitalize(this.value)); } /** * Capitalizes the first letter of each word of the given string. * * @returns the result string. */ capitalizeEachWord() { if (!this.isString()) throw Error("[TString] value is not a string."); return new _TString(stringCapitalizeEachWord(this.value)); } /** * Extract a boolean value from the given string. * * @returns the boolean value corresponding to the given string. If the given input is `null`, this methid resturns `undefined`. */ parseBoolean() { if (!this.isString()) throw Error("[TString] value is not a string."); return stringParseBoolean(this.value); } }; // src/arrays.ts var arrayMatchOneOrMore = (array, predicate) => { return array.filter((value) => !!value).filter(predicate).length > 0; }; var arrayMatchOneExactly = (array, predicate) => { return array.filter((value) => !!value).filter(predicate).length === 1; }; var arrayMatchAll = (array, predicate) => { const cleanedArray = array.filter((value) => !!value); return cleanedArray.length > 0 && cleanedArray.filter(predicate).length === cleanedArray.length; }; var arraysAreSame = (array1, array2, comparator) => { return array1.length == array2.length && array1.every( (element, index) => comparator !== void 0 ? comparator(element, array2[index]) : element === array2[index] ); }; var arrayCreateSuite = (length, offset = 1, step = 1) => { return Array.from({ length }, (_, i) => offset + i * step); }; var EMPTY_ARRAY = []; var arrayCleanStringArray = (array) => { if (!array) return; return array.filter((value) => !stringIsBlank(value)); }; var arrayShuffle = (array) => { let currentIndex = array.length; let temporaryValue, randomIndex; while (currentIndex) { randomIndex = Math.floor(Math.random() * currentIndex); currentIndex--; temporaryValue = array[currentIndex]; array[currentIndex] = array[randomIndex]; array[randomIndex] = temporaryValue; } return array; }; var arrayUniq = (array) => { return array.filter((v, i, a) => a.indexOf(v) === i); }; var arrayUniqObjectsByProperty = (array, property, comparator) => { return array.filter( (obj, i) => array.findIndex( (a) => comparator ? comparator(a[property], obj[property]) : a[property] === obj[property] ) === i ); }; var arrayLast = (array) => { const length = array.length; if (length === 0) return; return array[array.length - 1]; }; var arrayLastOptional = (array) => { const length = array.length; if (length === 0) return Optional.empty(); return Optional.filled(array[array.length - 1]); }; var arrayFirst = (array) => { if (array.length === 0) return; return array[0]; }; var arraySum = (array, valueExtractor) => { if (array.length === 0) return 0; return array.filter((v) => v !== null && v !== void 0).map((value) => valueExtractor ? valueExtractor(value) : Number(value)).reduce((total, current) => total + current, 0); }; var arrayAverage = (array, valueExtractor, rounded = true) => { if (array.length === 0) return 0; const total = arraySum(array, valueExtractor); const average = total / array.length; const finalAverage = rounded ? Math.round(average) : average; return finalAverage >= 0 ? finalAverage : 0; }; var arrayFirstOptional = (array) => { if (array.length === 0) return Optional.empty(); return Optional.filled(array[0]); }; var arrayPushNewValue = (array, newValue, valueComparator) => { if (array.length === 0) { array.push(newValue); return; } if (!array.find( (value) => valueComparator ? valueComparator(value, newValue) : value === newValue )) { array.push(newValue); } }; var arrayPushNewValues = (array, newValues, valueComparator) => { if (array.length === 0) { array.push(...newValues); return; } for (const newValue of newValues) { arrayPushNewValue(array, newValue, valueComparator); } }; var ArrayHelpers = { /** * Tests if all elements of the given array match the predicate. * * @param array The array to test * @param predicate The predicate used to test each element of the given array * @returns `true` if all of the elements match the given predicate, `false` otherwise. */ matchAll: arrayMatchAll, /** * Tests if exactly one element of the given array matches the predicate. * * @param array The array to test * @param predicate The predicate used to test each element of the given array * @returns `true` if one element only matches the given predicate, `false` otherwise. */ matchOneExactly: arrayMatchOneExactly, /** * Tests if at least one element of the given array matches the predicate. * * @param array The array to test * @param predicate The predicate used to test each element of the given array * @returns `true` if at leat one element matches the given predicate, `false` otherwise. */ matchOneOrMore: arrayMatchOneOrMore, /** * Tests whether the given arrays are exactly the same in length and content. * If no predicate is given to compare the elements of the arrays, `===` will be used. * * @param array1 The first array to test * @param array2 The second array to test * @param comparator The predicate used to compare each element of the given arrays. * @returns `true` if both arrays are equal, `false` otherwise. */ same: arraysAreSame, /** * Strips the given string array of any blank values (either `null`, `undefined` of empty string). * * @param array The string array to be cleaned. * @returns `undefined` if the given array was undefined, the cleaned up array otherwise. */ cleanStringArray: arrayCleanStringArray, /** * Creates an array of the given length composed of a suite of numbers from `offset` to `offset + (length * step)`. * * @param length The length of the array to be created. * @param offset The starting offset of the suite to be created. `1` is set by default. * @returns the suite array from `offset` to `offset + (length * step)`. */ createSuite: arrayCreateSuite, /** * Shuffles the elements of the given array to a random order. * * @param array The array to shuffle. * @returns An array with every elements of the given array but in a random order. */ shuffle: arrayShuffle, /** * Strips the given array of duplicate values. * * @param array The array with potential duplicates. * @returns An array where of elements are uniq. */ uniq: arrayUniq, /** * Strips the given array of duplicate property values. * * @param array The array with potential duplicates. * @param property The property to extract for the comparaison. * @param comparator The predicate used to compare each element of the given arrays. * @returns An array where of elements are uniq. */ uniqObjectsByProperty: arrayUniqObjectsByProperty, /** * Extracts the last element from the given array. * * @param array The array to extract the last element from. * @returns the last element. */ last: arrayLast, /** * Extracts the last element from the given array as an optional. * * @param array The array to extract the last element from. * @returns the last element as an optional. */ lastOptional: arrayLastOptional, /** * Extracts the first element from the given array. * * @param array The array to extract the first element from. * @returns the first element. */ first: arrayFirst, /** * Extracts the first element from the given array as an optional. * * @param array The array to extract the first element from. * @returns the first element as an optional. */ firstOptional: arrayFirstOptional, /** * Calculate the sum of the extracted values. * * @param array The array. * @param valueExtractor The extractor used to retrieve values to be sum up. * @returns the total. */ sum: arraySum, /** * Calculate the average of the extracted values. * * @param array The array. * @param valueExtractor The extractor used to retrieve values to be averaged up. * @returns the average. */ average: arrayAverage, /** * Push the given value to the given array only if the value is not already present in the given array. * * @param array The array in which to insert the new value. * @param newValue The new value to insert. * @param valueComparator The comparator used to compare values from the array. */ pushNewValue: arrayPushNewValue, /** * Push the given values to the given array only if the values are not already present in the given array. * The duplicate values will not be pushed but any other values will be. * * @param array The array in which to insert the new value. * @param newValue The new values to insert. * @param valueComparator The comparator used to compare values from the array. */ pushNewValues: arrayPushNewValues }; var ArraySymbols = { /** * An empty array. */ empty: EMPTY_ARRAY }; var Arrays = { /** * Array helper methods. */ helper: ArrayHelpers, /** * Array symbols. */ symbol: ArraySymbols }; // src/dates.ts import moment from "moment"; var DATE_DEFAULT_SEPARATOR = FORWARD_SLASH; var TIME_DEFAULT_SEPARATOR = COLON; var DATE_TO_FORMATED = { ["short-date-fr"]: (moment2, dateSeparator) => moment2.format(`DD[${dateSeparator}]MM[${dateSeparator}]YYYY`), ["short-date-us"]: (moment2, dateSeparator) => moment2.format(`MM[${dateSeparator}]DD[${dateSeparator}]YYYY`), ["short-date-time-fr"]: (moment2, dateSeparator, timeSeparator) => moment2.format(`DD[${dateSeparator}]MM[${dateSeparator}]YYYY HH[${timeSeparator}]mm`), ["short-date-time-us"]: (moment2, dateSeparator, timeSeparator) => moment2.format(`MM[${dateSeparator}]DD[${dateSeparator}]YYYY HH[${timeSeparator}]mm`), ["basic-date"]: (moment2, dateSeparator) => moment2.format(`YYYY[${dateSeparator}]MM[${dateSeparator}]dd`), ["basic-date-time"]: (moment2, dateSeparator, timeSeparator) => moment2.format(`YYYY[${dateSeparator}]MM[${dateSeparator}]DDTHH[${timeSeparator}]mm[${timeSeparator}]ss.SSSZ`), ["reverse"]: (moment2, dateSeparator) => moment2.format(`YYYY[${dateSeparator}]MM[${dateSeparator}]DD`), ["time"]: (moment2, _, timeSeparator) => moment2.format(`HH[${timeSeparator}]mm`) }; var dateFormat = (date, options) => { const { separator, dateSeparator, timeSeparator, format = "short-date-fr" } = options ?? {}; if (!date) { return "-"; } return DATE_TO_FORMATED[format]( moment(date), dateSeparator ?? separator ?? DATE_DEFAULT_SEPARATOR, timeSeparator ?? separator ?? TIME_DEFAULT_SEPARATOR ); }; var dateTodayAsString = (options) => { const now = new Date(Date.now()); return dateFormat(now, options); }; var dateGetComparator = (order = "desc") => (a, b) => { const aTime = a.getTime(); const bTime = b.getTime(); if (order === "asc") return aTime - bTime; return bTime - aTime; }; var DATE_COMPARATOR_ASC = dateGetComparator("asc"); var DATE_COMPARATOR_DESC = dateGetComparator("desc"); var dateGetAsStringComparator = (dateFormat2, order = "desc") => (a, b) => { const date1 = moment(a, dateFormat2).toDate(); const date2 = moment(b, dateFormat2).toDate(); return dateGetComparator(order)(date1, date2); }; var DATE_AS_STRING_COMPARATOR_ASC = dateGetAsStringComparator("asc"); var DATE_AS_STRING_COMPARATOR_DESC = dateGetAsStringComparator("desc"); var dateNow = () => moment(Date.now()).toDate(); var dateDaysAgo = (nbOfDays = 1) => { const today = dateNow(); today.setDate(today.getDate() - nbOfDays); return today; }; var dateInDays = (nbOfDays = 1) => { const today = dateNow(); today.setDate(today.getDate() + nbOfDays); return today; }; var dateYesterday = () => dateDaysAgo(); var dateTomorrow = () => dateInDays(); var dateIsBefore = (date1, date2) => date1 < date2; var dateIsAfter = (date1, date2) => date1 > date2; var dateIsSameDay = (date1, date2) => { return date1.getDay() === date2.getDay() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear(); }; var dateIsBeforeInDays = (date, nbOfDays = 1) => dateIsBefore(date, dateInDays(nbOfDays)); var dateIsAfterInDays = (date, nbOfDays = 1) => dateIsAfter(date, dateInDays(nbOfDays)); var dateIsBeforeDaysAgo = (date, nbOfDays = 1) => dateIsBefore(date, dateDaysAgo(nbOfDays)); var dateIsAfterDaysAgo = (date, nbOfDays = 1) => dateIsAfter(date, dateDaysAgo(nbOfDays)); var dateIsToday = (date) => dateIsSameDay(date, dateNow()); var dateIsPast = (date) => !dateIsToday(date) && dateIsBefore(date, dateNow()); var dateIsFuture = (date) => !dateIsToday(date) && dateIsAfter(date, dateNow()); var dateIsTomorrow = (date) => dateIsSameDay(date, dateTomorrow()); var dateIsYesterday = (date) => dateIsSameDay(date, dateYesterday()); var dateIsDaysAgo = (date, nbOfDays = 1) => dateIsSameDay(date, dateDaysAgo(nbOfDays)); var dateIsInDays = (date, nbOfDays = 1) => dateIsSameDay(date, dateInDays(nbOfDays)); var DateHelpers = { /** * Formats a date. * * @param date The date to format. * @param options Options. * @returns The given date formated accordingly to the given options. */ format: dateFormat, /** * Gets today's date as a string formated in the format specified in the given options parameter. * * @param separator The separator between day, month and year. * @returns today's date as a string. */ today: dateTodayAsString, /** * Gets a Date corresponding to now. * * @returns a `Date` object. */ now: dateNow, /** * Gets a Date corresponding to the given number of days in the past. * * @param nbOfDays The number of days in the past. * @returns a `Date` object. */ daysAgo: dateDaysAgo, /** * Gets a Date corresponding to the given number of days in the future. * * @param nbOfDays The number of days in the future. * @returns a `Date` object. */ inDays: dateInDays, /** * Gets a Date corresponding to yesterday. * * @returns a `Date` object. */ yesterday: dateYesterday, /** * Gets a Date corresponding to yesterday. * * @returns a `Date` object. */ tomorrow: dateTomorrow, /** * Tests whether the first given date is before the second given date. * * @param date The first date to compare. * @param date The second date to compare. * @returns `true` if the first given date is before the second given date, `false` otherwise. */ isBefore: dateIsBefore, /** * Tests whether the first given date is after the second given date. * * @param date The first date to compare. * @param date The second date to compare. * @returns `true` if the first given date is after the second given date, `false` otherwise. */ isAfter: dateIsAfter, /** * Tests whether the first given date is the same as the second given date. * * @param date The first date to compare. * @param date The second date to compare. * @returns `true` if the first given date is the same as the second given date, `false` otherwise. */ isSameDay: dateIsSameDay, /** * Tests whether the given date happened before the given number of days in the future relatively to today. * * @param date The date to compare. * @param nbOfDays The number of days in the future. * @returns `true` if the given date happened before `today + nbOfDays`, `false` otherwise. */ isBeforeInDays: dateIsBeforeInDays, /** * Tests whether the given date happens after the given number of days in the future relatively to today. * * @param date The date to compare. * @param nbOfDays The number of days in the future. * @returns `true` if the given date happens after `today + nbOfDays`, `false` otherwise. */ isAfterInDays: dateIsAfterInDays, /** * Tests whether the given date happened before the given number of days in the past relatively to today. * * @param date The date to compare. * @param nbOfDays The number of days in the future. * @returns `true` if the given date happened before `today - nbOfDays`, `false` otherwise. */ isBeforeDaysAgo: dateIsBeforeDaysAgo, /** * Tests whether the given date happens after the given number of days in the past relatively to today. * * @param date The date to compare. * @param nbOfDays The number of days in the future. * @returns `true` if the given date happens after `today - nbOfDays`, `false` otherwise. */ isAfterDaysAgo: dateIsAfterDaysAgo, /** * Tests whether the given date happens today. * * @param date The date to compare. * @returns `true` if the given date happens today, `false` otherwise. */ isToday: dateIsToday, /** * Tests whether the given date happened before today. * * @param date The date to compare. * @returns `true` if the given date happened before today, `false` otherwise. */ isPast: dateIsPast, /** * Tests whether the given date happens after today. * * @param date The date to compare. * @returns `true` if the given date happens after today, `false` otherwise. */ isFuture: dateIsFuture, /** * Tests whether the given date happens tomorrow. * * @param date The date to compare. * @returns `true` if the given date happens tomorrow, `false` otherwise. */ isTomorrow: dateIsTomorrow, /** * Tests whether the given date happened yesterday. * * @param date The date to compare. * @returns `true` if the given date happened yesterday, `false` otherwise. */ isYesterday: dateIsYesterday, /** * Tests whether the given date happened the given number of days in the past. * * @param date The date to compare. * @returns `true` if the given date happened `today - nbOfDays`, `false` otherwise. */ isDaysAgo: dateIsDaysAgo, /** * Tests whether the given date happens the given number of days in the future. * * @param date The date to compare. * @returns `true` if the given date happens `today + nbOfDays`, `false` otherwise. */ isInDays: dateIsInDays }; var DateComparators = { /** * An ascendent date comparator. */ asc: DATE_COMPARATOR_ASC, /** * An descendent date comparator. */ desc: DATE_COMPARATOR_DESC, /** * An ascendent formated date comparator. */ asStringAsc: DATE_AS_STRING_COMPARATOR_ASC, /** * An descendent formated date comparator. */ asStringDesc: DATE_AS_STRING_COMPARATOR_DESC }; var Dates = { /** * Date helper methods. */ helper: DateHelpers, /** * Date comparators. */ comparator: DateComparators }; // src/functions.ts var functionIdentity = () => (value) => value; var functionIdentityAs = () => (value) => value; var functionAttribute = (attributeName) => { return (value) => { const propertyDescriptor = Object.getOwnPropertyDescriptor( value, attributeName ); if (propertyDescriptor !== void 0 && propertyDescriptor.value !== null) { return propertyDescriptor.value; } }; }; var functionVoid = () => () => { }; var FunctionHelpers = { /** * A function that returns the exact given value. * * @param value The value parameter of the function. * @returns a function that returns the exact given value. */ identity: functionIdentity, /** * A function that returns the given value casted to the given type. * * @param value The value parameter of the function. * @returns a function that returns the given value casted to the given type. */ identityAs: functionIdentityAs, /** * A function that extracts an attribute from the given value. * * @param attributeName The name of the attribute to extract. * @returns a function that extract the attrobute from the given object. */ attribute: functionAttribute, /** * A void function. * * @returns a void function. */ void: functionVoid }; var Functions = { /** * Function helper methods. */ helper: FunctionHelpers }; // src/indexSignatures.ts var indexSignatureFromArray = (array, idExtractor) => { const result = {}; for (const element of array) { result[idExtractor(element)] = element; } return result; }; var indexSignatureFromArrayValues = (array, idExtractor, valueExtractor) => { const result = {}; for (const element of array) { result[idExtractor(element)] = valueExtractor(element); } return result; }; var indexSignatureMapToArray = (indexSignature, mapper, filter) => { const result = []; for (const [id, element] of Object.entries(indexSignature).filter( ([id2, element2]) => !filter || filter(id2, element2) )) { result.push(mapper(id, element)); } return result; }; var indexSignatureMapValues = (indexSignature, mapper, filter) => { const result = {}; for (const [id, element] of Object.entries(indexSignature).filter(([, element2]) => !filter || filter(element2))) { result[id] = mapper(element); } return result; }; var indexSignaturesAreSame = (indexSignature1, indexSignature2) => { if (!arraysAreSame(Object.keys(indexSignature1), Object.keys(indexSignature2))) return false; if (!arraysAreSame(Object.values(indexSignature1), Object.values(indexSignature2))) return false; return true; }; var