sussy-util
Version:
Util package made by me
492 lines (491 loc) • 20.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.slugify = exports.randomString = exports.isEmpty = exports.reverse = void 0;
const _1 = require(".");
class StringUtil {
static dedupeChars(s) {
return Array.from(new Set(s.split(''))).join('');
}
static safeCharset(charset) {
return charset && charset.length > 0
? StringUtil.dedupeChars(charset)
: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
}
/**
* It takes a string, splits it into an array of characters, reverses the array, and joins the
* array back into a string
* @param {string} input - The string to be reversed.
* @returns The reverse of the input string.
*/
static reverse(input) {
return input.split('').reverse().join('');
}
/**
* It takes a string of characters and returns a random character from that string.
* @param {string} [charset] - The characters to choose from. Defaults to all alphanumeric
* characters.
* @returns A random character from the charset.
*/
static randomCharacter(charset) {
const cs = StringUtil.safeCharset(charset);
const idx = _1.Random.randomInt(0, cs.length);
return cs.charAt(idx);
}
/**
* Generate a random string of a given length, using a given character set.
* @param {number} length - number - The length of the string to generate
* @param {string} [characterset] - The characterset to use for the random string.
* @returns A string of random characters.
*/
static randomString(length, characterset) {
if (!Number.isFinite(length) || length <= 0)
return '';
const cs = StringUtil.safeCharset(characterset);
return Array.from({ length }, () => StringUtil.randomCharacter(cs)).join('');
}
/**
* It generates a random string, checks if it's a valid discord username, if it's not, it generates
* another one, if it is, it returns it.
* @param [withSuffix=false] - boolean
* @returns A random string that is a valid discord username.
* @deprecated
*/
static randomDiscordUsername(withSuffix = false) {
const length = _1.Random.randomInt(4, 33);
let name = StringUtil.randomString(length);
if (!StringUtil.isDiscordUsername(`${name}#0000`)) {
name = StringUtil.randomDiscordUsername(false);
}
if (!withSuffix)
return name;
return `${name}#${_1.Random.randomInt(0, 10)}${_1.Random.randomInt(0, 10)}${_1.Random.randomInt(0, 10)}${_1.Random.randomInt(0, 10)}`;
}
/**
* It returns true if the username is a valid Discord username, and false if it isn't
* @param {string} username - The username to check.
* @returns A boolean value.
* @deprecated
*/
static isDiscordUsername(username) {
return !!username.match(/^.{4,32}#\d{4}$/);
}
/**
* If the value is a string, and the string contains only digits, then return true. Otherwise,
* return false
* @param {string} value - The value to be tested.
* @returns A boolean value.
*/
static isInteger(value) {
return /^(-)?\d+$/.test(value);
}
/**
* It returns true if the value is a float, otherwise it returns false
* @param {string} value - string - The value to check
* @returns A boolean value.
*/
static isFloat(value) {
return /^-?(?:\d+|\d+\.\d+|\.\d+)$/.test(value);
}
/**
* The password must be at least eight characters long and contain at least one lowercase letter,
* one uppercase letter, one numeric digit, and one special character
* @param {string} value - string - The value to check
* @returns A boolean value.
*/
static isStrongPassword(value) {
return /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/.test(value);
}
/**
* If the password is not strong, then it is weak.
* @param {string} value - string - The value to check.
* @returns The return value is a boolean.
*/
static isWeakPassword(value) {
return !StringUtil.isStrongPassword(value);
}
/**
* It checks if the value is a string, and if it is, it checks if the string is at least 4
* characters long, contains an @ symbol, and ends with a . followed by at least 2 characters
* @param {string} value - string - The value to be tested.
* @returns A boolean value.
*/
static isEmail(value) {
return /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(value);
}
/**
* It checks if the value is a valid HTTP URL.
* @param {string} value - The value to be tested.
* @returns A boolean value.
*/
static isHTTPUrl(value) {
if (!value)
return false;
try {
const u = new URL(value);
return u.protocol === 'http:' || u.protocol === 'https:';
}
catch (_a) {
return false;
}
}
/**
* It checks if the value is a valid URL without the HTTP or HTTPS prefix
* @param {string} value - string - The value to be tested.
* @returns A boolean value.
*/
static isUrlWithoutHTTP(value) {
return /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)/.test(value);
}
/**
* If the string is a URL, return true, otherwise return false.
* @param {string} value - string
* @returns A boolean value.
*/
static isURL(value) {
return StringUtil.isHTTPUrl(value) || StringUtil.isUrlWithoutHTTP(value);
}
/**
* It takes a string, a length, and an ellipsis count, and returns a string that is the original
* string shortened to the length, with the ellipsis count number of ellipses appended to the end.
*
* @param {string} value - The string to shorten
* @param {number} length - The length of the string you want to return.
* @param {number} ellipsisCount - The number of dots to use in the ellipsis.
* @returns The value of the string is being returned.
*/
static shorten(value, length, ellipsisCount) {
if (length >= value.length)
return value;
const ellipsis = '.'.repeat(Math.max(0, ellipsisCount));
return value.substring(0, length) + ellipsis;
}
/**
* It takes a string, converts it to lowercase, trims it, removes all non-word characters, replaces
* all whitespace and underscores with a dash, and removes all leading and trailing dashes
* @param {string} str - string - The string to slugify
* @returns A string
*/
static slugify(str) {
return str
.toLowerCase()
.trim()
.replace(/[^\w\s-]/g, '')
.replace(/[\s_-]+/g, '-')
.replace(/^-+|-+$/g, '');
}
/**
* Capitalize the first letter of a string and lowercase the rest.
* @param {string} value - string - The string to be capitalized.
* @returns The first character of the string is being returned in uppercase and the rest of the
* string is being returned in lowercase.
*/
static capitalize(value) {
return value.charAt(0).toUpperCase() + value.slice(1).toLowerCase();
}
/**
* It takes a string and returns the same string with the first letter lowercase.
* @param {string} value - string - The string to uncapitalize.
* @returns The first character of the string is converted to lowercase and then concatenated with
* the rest of the string.
*/
static uncapitalize(value) {
return value.charAt(0).toLowerCase() + value.slice(1);
}
/**
* It returns true if the value is a valid IPv4 address, otherwise it returns false.
* @param {string} value - The value to check.
* @returns A boolean value.
*/
static isIPv4(value) {
return /^(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(value);
}
/**
* It checks if the value is a valid IPv6 address.
* @param {string} value - The value to check.
* @returns A boolean value.
*/
static isIPv6(value) {
return /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))$/.test(value);
}
/**
* If the value is an IPv4 address, return true. Otherwise, if the value is an IPv6 address,
* return true. Otherwise, return false.
* @param {string} value - string
* @returns A boolean value.
*/
static isIP(value) {
return StringUtil.isIPv4(value) || StringUtil.isIPv6(value);
}
/**
* It returns true if the value is a valid MAC address, otherwise it returns false
* @param {string} value - The value to check.
* @returns A boolean value.
*/
static isMacAddress(value) {
return /^(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}$/.test(value);
}
/**
* If the value is a string that matches the regular expression, then return true, otherwise return
* false.
* @param {string} value - string - The value to be tested.
* @returns A boolean value.
*/
static isPhoneNumber(value) {
return /^[\\(]\d{3}[\\)]\s\d{3}-\d{4}$/.test(value);
}
/**
* It takes a string, gets the first character, makes it uppercase, and then adds the rest of the
* string to it
* @param {string} str - string - The string to be converted.
* @returns The first character of the string is being returned in uppercase, and the rest of the
* string is being returned in lowercase.
*/
static upperFirst(str) {
return str.charAt(0).toUpperCase() + str.substring(1);
}
/**
* It takes a string, and returns a new string with the first character lowercased
* @param {string} str - string - The string to be converted.
* @returns The first character of the string is being returned in lowercase, and the rest of the
* string is being returned in its original case.
*/
static lowerFirst(str) {
return str.charAt(0).toLowerCase() + str.substring(1);
}
/**
* It takes a string, splits it on non-word characters and underscores, capitalizes each word, and
* joins them together
* @param {string} str - string - The string to be converted to camelCase
* @returns The first letter of the string is being returned in lowercase.
*/
static camelCase(str) {
return StringUtil.lowerFirst(str
.split(/[^\w]|_+/)
.map((val) => StringUtil.capitalize(val))
.join(''));
}
/**
* It takes a string, trims it, splits it into an array of words, filters out any empty words, and
* then joins the array back into a string
* @param {string} str - string - The string to be collapsed.
* @returns A string
*/
static collaps(str) {
return str
.trim()
.split(' ')
.filter((part) => part.length > 0)
.join(' ');
}
/**
* It takes a string, trims it, splits it into an array of strings, and then joins it back together
* @param {string} str - string - The string to be trimmed.
* @returns The string with no spaces.
*/
static noSpaces(str) {
return str.trim().split(' ').join('');
}
/**
* It takes a string, splits it into an array of characters, maps each character to its charCode,
* and then joins the array of charCodes into a string
* @param {string} str - string - The string to convert to char codes.
* @returns The charCodeAt() method returns an integer between 0 and 65535 representing the UTF-16
* code unit at the given index.
*/
static toCharCode(str) {
return str
.split('')
.map((val) => val.charCodeAt(0))
.join('');
}
/**
* It takes a string, checks if it's an email, splits it in half, shortens the first half, and
* returns the result.
* @param {string} str - string - The string to protect
* @returns The email address with the first half of the email address shortened to 3 characters.
*/
static protectEmail(str) {
if (!StringUtil.isEmail(str))
return str;
const half = str.split('@');
half[0] = StringUtil.shorten(half[0], half[0].length / 2, 3);
return half.join('@');
}
/**
* It takes a string, and returns a string with the first letter of each word capitalized, and the
* rest of the letters lowercase.
* @param {string} str - string - The string to be swapped.
* @returns the string with the first letter of each word capitalized.
*/
static swapCase(str) {
return str
.split('')
.map((ch) => {
if (ch >= 'a' && ch <= 'z')
return ch.toUpperCase();
if (ch >= 'A' && ch <= 'Z')
return ch.toLowerCase();
return ch;
})
.join('');
}
/**
* It generates a random string of a given length, using a given set of characters, and if the
* generated string is not strong enough, it generates another one
* @param {number} length - number - The length of the password to generate
* @param {string} [characters] - string =
* "ascdefghijklmnopqrstuvwxyzABCDEFGHIJLMOPRSTUVWXYZ1234567890!$$%&?#*+~'"
* @returns A string of length `length` that is a strong password.
*/
static generatePassword(length, characters) {
characters =
characters || "ascdefghijklmnopqrstuvwxyzABCDEFGHIJLMOPRSTUVWXYZ1234567890!§$%&?#*+~'";
const uniqueChars = [...new Set(characters.split(''))].join('');
if (uniqueChars.length < 8)
throw new Error('Not enough characters to generate password');
const maxAttempts = 500;
for (let attempt = 0; attempt < maxAttempts; attempt++) {
const result = StringUtil.randomString(length, characters);
if (StringUtil.isStrongPassword(result))
return result;
}
throw new Error('Failed to generate a strong password');
}
/**
* It returns a random color code in hexadecimal format.
* @returns A random color code.
*/
static randomColorCode() {
const num = Math.floor(Math.random() * 0xffffff);
return `#${num.toString(16).padStart(6, '0')}`;
}
/**
* It returns the number of words in a string.
* @param {string} str - string - The string to count the words in.
* @returns The number of words in the string.
*/
static wordCount(str) {
const words = str.match(/\b\w+\b/g);
if (!words) {
return 0;
}
return words.length;
}
static getRatingString(rate) {
return '★'.repeat(rate) + '☆'.repeat(5 - rate);
}
/**
* It replaces all line breaks with the lineEnd parameter.
* @param {string} str - string - The string to normalize.
* @param {string} [lineEnd] - The line ending to normalize to (defaults to \n).
* @returns A string with all line breaks normalized to the specified lineEnd string, or the
* default lineEnd string.
*/
static normalizeLineBreaks(str, lineEnd) {
lineEnd = lineEnd || '\n';
return str.replace(/\r\n/g, lineEnd).replace(/\r/g, lineEnd).replace(/\n/g, lineEnd);
}
/**
* It returns true if the string contains the substring, otherwise it returns false
* @param {string} str - The string to search in.
* @param {string} substring - The substring to search for.
* @param {number} fromIndex - The index at which to begin searching the String object. If omitted,
* search starts at the beginning of the string.
* @returns The index of the first occurrence of the specified substring, or -1 if there is no such
* occurrence.
*/
static contains(str, substring, fromIndex) {
return str.indexOf(substring, fromIndex) !== -1;
}
/**
* @param {string} str - string - The string to pad.
* @param {number} minLen - The minimum length of the string.
* @param {string} [ch] - The character to pad the string with.
* @returns The string with the padding added to it.
*/
static rpad(str, minLen, ch) {
ch = ch || ' ';
return str.length < minLen ? str + ch.repeat(minLen - str.length) : str;
}
/**
* @param {string} str - string - The string to pad.
* @param {number} minLen - The minimum length of the string.
* @param {string} [ch] - The character to pad the string with.
* @returns The string with the padding.
*/
static lpad(str, minLen, ch) {
ch = ch || ' ';
return str.length < minLen ? ch.repeat(minLen - str.length) + str : str;
}
/**
* It takes a string, an offset, a removeCount, and a text, and returns a string.
* @param {string} str - string - The string to be spliced.
* @param {number} offset - The index of the string to start replacing at.
* @param {number | undefined} removeCount - The amount of characters to remove from the string.
* @param [text] - The text to insert into the string.
* @returns The string with the text inserted at the offset.
*/
static splice(str, offset, removeCount, text = '') {
if (offset > str.length)
return '';
const calculatedOffset = offset < 0 ? StringUtil.length + offset : offset;
return (str.substring(0, calculatedOffset) +
text +
str.substring(calculatedOffset + (removeCount ? removeCount : 0)));
}
/**
* If the string is null, empty, or equal to an empty string, then it is empty
* @param {string} str - string - The string to check if it's empty.
* @returns a boolean value.
*/
static isEmpty(str) {
return !str || str.length === 0 || str === '';
}
/**
* It removes all the leading white spaces from a string.
* @param {string} str - The string to be trimmed.
* @returns The string with the leading whitespace removed.
*/
static ltrim(str) {
return str.replace(/^\s+/, '');
}
/**
* It replaces all the spaces at the end of the string with nothing
* @param {string} str - The string to trim.
* @returns The string with the whitespace removed from the end.
*/
static rtrim(str) {
return str.replace(/\s+$/, '');
}
/**
* It takes a string and replaces any lowercase letter followed by an uppercase letter with the
* lowercase letter followed by a dash followed by the uppercase letter.
* @param {string} str - string - The string to convert
* @returns The string with the first letter lowercase.
*/
static camelToKebab(str) {
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}
/**
* We take a string, convert it to lowercase, split it into an array, reverse the array, join the
* array back into a string, and then compare the reversed string to the original string.
* @param {string} str - string - the string to check if it's a palindrome
* @returns A boolean value.
*/
static isPalindrome(str) {
const lowerCaseStr = str.toLowerCase();
const strArray = lowerCaseStr.split('');
const reversedArray = strArray.reverse();
const reversedStr = reversedArray.join('');
return reversedStr === lowerCaseStr;
}
}
exports.default = StringUtil;
const reverse = (s) => StringUtil.reverse(s);
exports.reverse = reverse;
const isEmpty = (s) => StringUtil.isEmpty(s);
exports.isEmpty = isEmpty;
const randomString = (len, cs) => StringUtil.randomString(len, cs);
exports.randomString = randomString;
const slugify = (s) => StringUtil.slugify(s);
exports.slugify = slugify;