@tevari/helpers
Version:
Collection of various small helpers for javascript and typescript based projects
1,544 lines (1,538 loc) • 84 kB
JavaScript
// 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