web-utils-kit
v1.1.5
Published
The web-utils-kit package provides a collection of well-tested and thoroughly documented utility functions for various web development needs. Each function adheres to a strict coding style and best practices to ensure consistency and maintainability.
Maintainers
Readme
Web Utils Kit
The web-utils-kit package provides a collection of well-tested and thoroughly documented utility functions for various web development needs. Each function adheres to a strict coding style and best practices to ensure consistency and maintainability.
Getting Started
Install the package:
npm i -S web-utils-kitExamples
Validate a password:
import { isPasswordValid } from 'web-utils-kit';
isPasswordValid('zR<q%+r2C,&fy.SE&~.(REXTqe4K[?>G'); // true
isPasswordValid('some-weak-password'); // falseSort a list of records:
import { sortRecords } from 'web-utils-kit';
[{ v: 1 }, { v: 2 }, { v: 3 }].sort(sortRecords('v', 'desc'));
// [{ v: 3 }, { v: 2 }, { v: 1 }]Execute an asynchronous function persistently:
import { retryAsyncFunction } from 'web-utils-kit';
const res = await retryAsyncFunction(() => fetch('https://api.example.com/user/1')[(3, 5)]);
await res.json();
// {
// uid: '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
// nickname: 'PythonWiz333'
// }API Reference
Validations
Verifies if a value is a valid string and its length is within a range (optional).
import { isStringValid } from 'web-utils-kit';
isStringValid('Hello world!'); // true
isStringValid('', 1, 5); // false
isStringValid('abcde', 1, 5); // true
isStringValid('abcdef', 1, 5); // false
isStringValid(' '); // false
isStringValid(' ', undefined, undefined, false); // trueVerifies if a value is a valid number and is within a range (optional). The minimum value defaults to Number.MIN_SAFE_INTEGER (-9007199254740991) while the maximum value defaults to Number.MAX_SAFE_INTEGER (9007199254740991).
import { isNumberValid } from 'web-utils-kit';
isNumberValid(1); // true
isNumberValid(2, 3, 5); // false
isNumberValid(3, 3, 5); // true
isNumberValid(6, 3, 5); // falseVerifies if a value is a valid integer and is within a range (optional). If a range is not provided, it will use the properties Number.MIN_SAFE_INTEGER & Number.MAX_SAFE_INTEGER.
import { isIntegerValid } from 'web-utils-kit';
isIntegerValid(1); // true
isIntegerValid(1.5); // falseVerifies if a value is a valid unix timestamp in milliseconds. The smallest value is set for the beginning of the Unix epoch (January 1st, 1970 - 14400000) on the numeric limit established by JavaScript (9007199254740991).
import { isTimestampValid } from 'web-utils-kit';
isTimestampValid(Date.now()); // true
isTimestampValid(14399999); // false
isTimestampValid(Number.MIN_SAFE_INTEGER + 1); // falseVerifies if a value is a valid numeric string.
import { isNumeric } from 'web-utils-kit';
isNumeric('14400000'); // true
isNumeric('123.55'); // true
isNumeric('6,555.85'); // false
isNumeric('Hello world!'); // falseVerifies if a value is an actual object. It also validates if it has keys (optional).
import { isObjectValid } from 'web-utils-kit';
isObjectValid({}); // false
isObjectValid({}, true); // true
isObjectValid({ auth: 123, isAdmin: true }); // true
isObjectValid([0, 1, { foo: 'bar' }]); // falseVerifies if a value is an array. It also validates if it has elements inside (optional).
import { isArrayValid } from 'web-utils-kit';
isArrayValid([]); // false
isArrayValid([], true); // true
isArrayValid({ auth: 123, isAdmin: true }); // falseVerifies if a value is a valid email address.
import { isEmailValid } from 'web-utils-kit';
isEmailValid('[email protected]'); // true
isEmailValid('jesus@graterol'); // false
// forbid certain extensions
isEmailValid('[email protected]', ['.con']); // falseVerifies if a slug meets the following requirements:
- Accepts any Alpha Characters (lower and upper case)
- Accepts any digits
- Accepts
-,.and/or_ - Meets a length range (Defaults to 2 - 16)
import { isSlugValid } from 'web-utils-kit';
isSlugValid('PythonWiz333'); // true
isSlugValid('hello-world', true); // true
isSlugValid('jesus@graterol'); // falseVerifies if a password meets the following requirements:
- Meets a length range (Defaults to 8 - 2048)
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
import { isPasswordValid } from 'web-utils-kit';
isPasswordValid('zR<q%+r2C,&fy.SE&~.(REXTqe4K[?>G'); // true
isPasswordValid('some-weak-password'); // falseVerifies if a value has the correct OTP Secret Format.
import { isOTPSecretValid } from 'web-utils-kit';
isOTPSecretValid('NB2RGV2KAY2CMACD'); // trueVerifies if a value has the correct OTP Token Format.
import { isOTPTokenValid } from 'web-utils-kit';
isOTPTokenValid('123456'); // true
isOTPTokenValid('1234567'); // falseVerifies if a value has a correct JWT Format: [Base64-URL Encoded Header].[Base64-URL Encoded Payload].[Signature]
import { isJWTValid } from 'web-utils-kit';
isJWTValid('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIzNDU2Nzg5LCJuYW1lIjoiSm9zZXBoIn0.OpOSSw7e485LOP5PrzScxHb7SR6sAOMRckfFwi4rp7o');
// trueVerifies if a value has a valid Authorization Header format based on the RFC6750. Example:
Authorization: Bearer eyJhbGciOiJIUzI1NiIXVCJ9TJV...r7E20RMHrHDcEfxjoYZgeFONFh7HgQ
import { isAuthorizationHeaderValid } from 'web-utils-kit';
isAuthorizationHeaderValid('Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIzNDU2Nzg5LCJuYW1lIjoiSm9zZXBoIn0.OpOSSw7e485LOP5PrzScxHb7SR6sAOMRckfFwi4rp7o');
// trueVerifies if a value complies with semantic versioning.
import { isSemverValid } from 'web-utils-kit';
isSemverValid('1.0.0'); // trueVerifies if a value is a valid URL.
import { isURLValid } from 'web-utils-kit';
isURLValid('https://jesusgraterol.dev'); // true
isURLValid('jesusgraterol.dev'); // falseVerifies if a value is a valid UUID and that it matches a specific version.
import { isUUIDValid } from 'web-utils-kit';
isUUIDValid('9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d', 4); // true
isUUIDValid('01695553-c90c-705a-b56d-778dfbbd4bed', 7); // trueTransformers
Verifies if a value is a valid UUID and that it matches a specific version.
import { prettifyNumber } from 'web-utils-kit';
prettifyNumber(1000.583); // '1,000.58'
prettifyNumber(2654.69642236, { maximumFractionDigits: 8, suffix: ' BTC' });
// '2,654.69642236 BTC'
prettifyNumber(1000, { minimumFractionDigits: 2, prefix: '$' });
// '$1,000.00'Formats a date instance based on a template.
date-short-> 12/05/2024 (Default)date-medium-> December 5, 2024date-long-> Thursday, December 5, 2024time-short-> 12:05 PMtime-medium-> 12:05:20 PMdatetime-short-> 12/5/2024, 12:05 PMdatetime-medium-> December 5, 2024 at 12:05 PMdatetime-long-> Thursday, December 5, 2024 at 12:05:20 PM
import { prettifyDate } from 'web-utils-kit';
prettifyDate(new Date(), 'datetime-long');
// 'Thursday, December 5, 2024 at 12:05:20 PM'
prettifyDate(Date.now(), 'date-medium');
// 'December 5, 2024'Formats a bytes value into a human readable format.
import { prettifyFileSize } from 'web-utils-kit';
prettifyFileSize(85545, 6); // '83.540039 kB'
prettifyFileSize(79551423); // '75.87 MB'Formats the number that will be inserted in a badge so it doesn't take too much space. If the current count is 0, it returns undefined as the badge shouldn't be displayed.
import { prettifyBadgeCount } from 'web-utils-kit';
prettifyBadgeCount(0); // undefined
prettifyBadgeCount(11); // '9+'
prettifyBadgeCount(135, 99); // '99+'Capitalizes the first letter of a string and returns the new value.
import { capitalizeFirst } from 'web-utils-kit';
capitalizeFirst('hello world'); // 'Hello world'Converts a string value into Title Case.
import { toTitleCase } from 'web-utils-kit';
toTitleCase('hello world'); // 'Hello World'Converts a string value into a slug.
import { toSlug } from 'web-utils-kit';
toSlug('HELLO WORLD!!@'); // 'hello-world'Truncates a string to a specified length and appends an ellipsis if it exceeds that length.
import { truncateText } from 'web-utils-kit';
truncateText('This is a message', 18); // 'This is a message'
truncateText('This is a message', 17); // 'This is a message'
truncateText('This is a message', 16); // 'This is a mes...'
truncateText('This is a message', 15); // 'This is a me...'Masks the middle of a string, keeping a specified number of visible characters at the start and end.
import { maskMiddle } from 'web-utils-kit';
maskMiddle('01021234567890123456', 4); // '0102...3456'
maskMiddle('01021234567890123456', 6, '********'); // '010212********123456'Applies substitutions to a string based on a provided object. The string can contain placeholders in the format of {{key}}, which will be replaced by the corresponding value from the substitutions object. If a placeholder does not have a corresponding key in the substitutions object, it will remain unchanged in the output string.
import { applySubstitutions } from 'web-utils-kit';
applySubstitutions('Hello, {{name}}! You have {{count}} new messages.', {
name: 'John',
count: 5,
});
// 'Hello, John! You have 5 new messages.'Converts a time string into milliseconds. The time string should be in the format of "{value} {unit}", where the value is a number and the unit can be milliseconds, seconds, minutes, hours, days, weeks, months, or years. For example: "2 days", "5 minutes", "2 hours".
import { toMS } from 'web-utils-kit';
toMS('53 years'); // 1672552800000
toMS('53 days'); // 4579200000Serializes a JSON object with the JSON.stringify method.
import { stringifyJSON } from 'web-utils-kit';
stringifyJSON({ c: 8, b: [{ z: 6, y: 5, x: 4 }, 7], a: 3 });
// '{"c":8,"b":[{"z":6,"y":5,"x":4},7],"a":3}'Stringifies a JSON object in a deterministic way, ensuring that the keys are sorted and the output is consistent.
import { stringifyJSONDeterministically } from 'web-utils-kit';
stringifyJSONDeterministically({ c: 8, b: [{ z: 6, y: 5, x: 4 }, 7], a: 3 });
// '{"a":3,"b":[{"x":4,"y":5,"z":6},7],"c":8}'Deserializes a JSON string with the JSON.parse method.
import { parseJSON } from 'web-utils-kit';
parseJSON('{ c: 8, b: [{ z: 6, y: 5, x: 4 }, 7], a: 3 }');
// {"c":8,"b":[{"z":6,"y":5,"x":4},7],"a":3}Creates a deep clone of an object by using the JSON.stringify and JSON.parse methods.
import { createDeepClone } from 'web-utils-kit';
const a = { a: 'Hello', b: { c: 'World' } };
const b = createDeepClone(a);
b.b.c = 'Universe';
console.log(a.b.c); // 'World'
console.log(b.b.c); // 'Universe'Removes null, undefined, empty objects ({}), and empty arrays ([]) from the given data recursively.
import { pruneJSON } from 'web-utils-kit';
pruneJSON({
a: { b: { c: { d: {} }, x: undefined } },
z: null,
y: [[], [null, { foo: { x: { a: null } } }], {}],
});
// null
pruneJSON({
a: { b: { c: { d: { z: undefined, x: [], p: { a: 1 } } }, x: undefined } },
z: null,
y: [[], [null, { foo: { x: { a: null } } }], {}],
})
// { a: { b: { c: { d: { p: { a: 1 } } } } } }Utils
Generates a UUID based on a version.
import { generateUUID } from 'web-utils-kit';
generateUUID(4); // '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'
generateUUID(7); // '01695553-c90c-705a-b56d-778dfbbd4bed'Generates a string from randomly picked characters based on the length.
import { generateRandomString } from 'web-utils-kit';
generateRandomString(15); // 'IbnqwSPvZdXxVyS'Generates a random number (decimal) constrained by the range.
import { generateRandomFloat } from 'web-utils-kit';
generateRandomFloat(1, 100); // 67.551Generates a random number (integer) constrained by the range.
import { generateRandomInteger } from 'web-utils-kit';
generateRandomInteger(1, 100); // 71Generates a sequence of numbers within a range based on a number of steps.
import { generateSequence } from 'web-utils-kit';
generateSequence(1, 10); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
generateSequence(1, 10, 2); // [1, 3, 5, 7, 9]Sorts a list of primitive values based on their type and a sort direction.
import { sortPrimitives } from 'web-utils-kit';
[1, 2, 3, 4, 5].sort(sortPrimitives('asc'));
// [1, 2, 3, 4, 5]
[1, 2, 3, 4, 5].sort(sortPrimitives('desc'));
// [5, 4, 3, 2, 1]
['a', 'b', 'c'].sort(sortPrimitives('asc'));
// ['a', 'b', 'c']
['a', 'b', 'c'].sort(sortPrimitives('desc'));
// ['c', 'b', 'a']Sorts a list of record values by key based on their type and a sort direction.
import { sortRecords } from 'web-utils-kit';
[{ v: 1 }, { v: 2 }, { v: 3 }].sort(sortRecords('v', 'asc'));
// [1, 2, 3, 4, 5]
[{ v: 1 }, { v: 2 }, { v: 3 }].sort(sortRecords('v', 'desc'));
// [{ v: 3 }, { v: 2 }, { v: 1 }]
[{ v: 'a' }, { v: 'b' }, { v: 'c' }].sort(sortRecords('v', 'asc'));
// [{ v: 'a' }, { v: 'b' }, { v: 'c' }]
[{ v: 'a' }, { v: 'b' }, { v: 'c' }].sort(sortRecords('v', 'desc'));
// [{ v: 'c' }, { v: 'b' }, { v: 'a' }]Creates a shallow copy of the input array and shuffles it, using a version of the Fisher-Yates algorithm.
import { shuffleArray } from 'web-utils-kit';
shuffleArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
// [4, 7, 5, 3, 6, 8, 9, 1, 2, 10]
shuffleArray(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
// ['d', 'j', 'c', 'a', 'g', 'e', 'b', 'f', 'i', 'h']
shuffleArray([{ a: 1 }, { b: 2 }, { c: 3 }, { d: 4 }, { e: 5 }])
// [ { c: 3 }, { d: 4 }, { a: 1 }, { b: 2 }, { e: 5 } ]Splits an array into smaller arrays (batches) of a given size.
import { splitArrayIntoBatches } from 'web-utils-kit';
splitArrayIntoBatches(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
3
)
// [
// [1, 2, 3],
// [4, 5, 6],
// [7, 8, 9],
// [10],
// ]Picks a list of properties from an object and returns a new object (shallow) with the provided keys.
import { pickProps } from 'web-utils-kit';
pickProps({ a: 1, b: 2, c: 3, d: 4 }, ['b', 'd'])
// { b: 2, d: 4 }Omits a list of properties from an object and returns a new object (shallow) with only those keys that weren't omitted.
import { omitProps } from 'web-utils-kit';
omitProps({ a: 1, b: 2, c: 3, d: 4 }, ['b', 'd'])
// { a: 1, c: 3 }Compares two objects or arrays deeply and returns true if they are equals.
import { isEqual } from 'web-utils-kit';
isEqual({ a: 2, c: 5, b: 3 }, { c: 5, b: 3, a: 2 });
// true
isEqual([{ a: 1, b: 2 }], [{ b: 2, a: 1 }]);
// trueFilters an array of primitives based on a given query and returns a shallow copy. IMPORTANT: Providing the queryProp makes the query very efficient as it only attempts to match the value of that property, instead of the whole item.
import { filterByQuery } from 'web-utils-kit';
filterByQuery(
[
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Chalie' },
{ id: 4, name: 'David' },
],
'ali',
{ queryProp: 'name' }
);
// [
// { id: 1, name: 'Alice' },
// { id: 3, name: 'Chalie' },
// ]
filterByQuery(
[
{ a: { x: 'Hello', y: ['yak', 123], p: { a: { b: 'croatoan' } }, z: { foo: 'bar' } } },
{ a: { x: 'Bye', y: ['Kok', 456], p: { a: { b: ['xaax'] } }, z: { foo: 'Haj' } } },
],
'croatoan'
);
// [{ a: { x: 'Hello', y: ['yak', 123], p: { a: { b: 'croatoan' } }, z: { foo: 'bar' } } }]Creates an asynchronous delay that resolves once the provided seconds have passed.
import { delay } from 'web-utils-kit';
await delay(3);
// ~3 seconds laterExecutes an asynchronous function persistently, retrying on error with incremental delays defined in retryScheduleDuration (seconds).
import { retryAsyncFunction } from 'web-utils-kit';
const res = await retryAsyncFunction(
() => fetch('https://api.example.com/user/1'),
[3, 5],
);
await res.json();
// {
// uid: '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
// nickname: 'PythonWiz333'
// }Executes an external request persistently, retrying on error with incremental delays defined in retryScheduleDuration (seconds).
import { retryExternalRequest } from 'web-utils-kit';
const res = await retryExternalRequest(
() => fetch('https://api.example.com/user/1'),
[404],
[3, 5],
);
await res.json();
// {
// uid: '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
// nickname: 'PythonWiz333'
// }Validates the format of an authorization header and extracts the token from it.
import { extractTokenFromAuthorizationHeader } from 'web-utils-kit';
extractTokenFromAuthorizationHeader('Bearer my-secret-token')
// my-secret-tokenValidates the format of an email address and extracts the username from it.
import { extractEmailUsername } from 'web-utils-kit';
extractEmailUsername('[email protected]')
// johndoeTypes
The UUID versions supported by this library.
type IUUIDVersion = 4 | 7;The sort direction that can be applied to a list.
type ISortDirection = 'asc' | 'desc';The configuration that will be used to prettify a number.
type INumberFormatConfig = {
minimumFractionDigits: number; // Default: 0
maximumFractionDigits: number; // Default: 2
prefix: string; // Default: ''
suffix: string; // Default: ''
};A date can be prettified by choosing a template that meets the user's requirements.
date-short-> 12/05/2024 (Default)date-medium-> December 5, 2024date-long-> Thursday, December 5, 2024time-short-> 12:05 PMtime-medium-> 12:05:20 PMdatetime-short-> 12/5/2024, 12:05 PMdatetime-medium-> December 5, 2024 at 12:05 PMdatetime-long-> Thursday, December 5, 2024 at 12:05:20 PM
type IDateTemplate = 'date-short' | 'date-medium' | 'date-long' | 'time-short' | 'time-medium' | 'datetime-short' | 'datetime-medium' | 'datetime-long';A duration string composed of a numeric value followed by a supported time unit, with or without a space.
type IYears = 'years' | 'year';
type IMonths = 'months' | 'month';
type IWeeks = 'weeks' | 'week';
type IDays = 'days' | 'day';
type IHours = 'hours' | 'hour';
type IMinutes = 'minutes' | 'minute';
type ISeconds = 'seconds' | 'second';
type IMilliseconds = 'milliseconds' | 'millisecond';
export type IUnit =
| IYears
| IMonths
| IWeeks
| IDays
| IHours
| IMinutes
| ISeconds
| IMilliseconds;
export type ITimeString = `${number} ${IUnit}`;Built With
- TypeScript
Running the Tests
# integration & unit tests
npm run test
# integration tests
npm run test:integration
# unit tests
npm run test:unit
# benchmarks
npm run test:bench