{"id":22436680,"url":"https://github.com/jesusgraterol/web-utils-kit","last_synced_at":"2025-03-27T08:43:13.333Z","repository":{"id":266284194,"uuid":"897892119","full_name":"jesusgraterol/web-utils-kit","owner":"jesusgraterol","description":"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.","archived":false,"fork":false,"pushed_at":"2025-02-11T22:25:07.000Z","size":181,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-14T20:39:34.649Z","etag":null,"topics":["javascript","typescript","utilities","utils","validation","web"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/web-utils-kit","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jesusgraterol.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-03T12:27:24.000Z","updated_at":"2025-02-11T22:24:52.000Z","dependencies_parsed_at":"2025-01-14T13:41:30.104Z","dependency_job_id":"92be7d44-33b3-4368-b611-72497b9a0159","html_url":"https://github.com/jesusgraterol/web-utils-kit","commit_stats":null,"previous_names":["jesusgraterol/web-utils","jesusgraterol/webdev-utils"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jesusgraterol%2Fweb-utils-kit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jesusgraterol%2Fweb-utils-kit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jesusgraterol%2Fweb-utils-kit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jesusgraterol%2Fweb-utils-kit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jesusgraterol","download_url":"https://codeload.github.com/jesusgraterol/web-utils-kit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245813169,"owners_count":20676763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","typescript","utilities","utils","validation","web"],"created_at":"2024-12-06T00:08:52.291Z","updated_at":"2025-03-27T08:43:13.324Z","avatar_url":"https://github.com/jesusgraterol.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Web Utils Kit\n\nThe `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.\n\n\n\n\n\n\u003c/br\u003e\n\n## Getting Started\n\nInstall the package:\n```bash\nnpm install -S web-utils-kit\n```\n\n\n## Examples\n\nValidate a password:\n\n```typescript\nimport { isPasswordValid } from 'web-utils-kit';\n\nisPasswordValid('zR\u003cq%+r2C,\u0026fy.SE\u0026~.(REXTqe4K[?\u003eG'); // true\nisPasswordValid('some-weak-password'); // false\n```\n\n\nSort a list of records:\n\n```typescript\nimport { sortRecords } from 'web-utils-kit';\n\n[{ v: 1 }, { v: 2 }, { v: 3 }].sort(sortRecords('v', 'desc')); \n// [{ v: 3 }, { v: 2 }, { v: 1 }]\n```\n\nExecute an asynchronous function persistently:\n\n```typescript\nimport { retryAsyncFunction } from 'web-utils-kit';\n\nconst res = await retryAsyncFunction(\n  () =\u003e fetch('https://api.example.com/user/1')\n  [3, 5]\n);\nawait res.json();\n// {\n//   uid: '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',\n//   nickname: 'PythonWiz333'\n// }\n```\n\n\n\u003cbr/\u003e\n\n## API Reference\n\n### Validations\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisStringValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a value is a valid string and its length is within a range (optional).\n  ```typescript\n  import { isStringValid } from 'web-utils-kit';\n\n  isStringValid(''); // true\n  isStringValid('', 1, 5); // false\n  isStringValid('abcde', 1, 5); // true\n  isStringValid('abcdef', 1, 5); // false\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisNumberValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies 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).\n  ```typescript\n  import { isNumberValid } from 'web-utils-kit';\n\n  isNumberValid(1); // true\n  isNumberValid(2, 3, 5); // false\n  isNumberValid(3, 3, 5); // true\n  isNumberValid(6, 3, 5); // false\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisIntegerValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies 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` \u0026 `Number.MAX_SAFE_INTEGER`.\n  ```typescript\n  import { isIntegerValid } from 'web-utils-kit';\n\n  isIntegerValid(1); // true\n  isIntegerValid(1.5); // false\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisTimestampValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies 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).\n  ```typescript\n  import { isTimestampValid } from 'web-utils-kit';\n\n  isTimestampValid(Date.now()); // true\n  isTimestampValid(14399999); // false\n  isTimestampValid(Number.MIN_SAFE_INTEGER + 1); // false\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisObjectValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a value is an actual object. It also validates if it has keys (optional).\n  ```typescript\n  import { isObjectValid } from 'web-utils-kit';\n\n  isObjectValid({}); // false\n  isObjectValid({}, true); // true\n  isObjectValid({ auth: 123, isAdmin: true }); // true\n  isObjectValid([0, 1, { foo: 'bar' }]); // false\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisArrayValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a value is an array. It also validates if it has elements inside (optional).\n  ```typescript\n  import { isArrayValid } from 'web-utils-kit';\n\n  isArrayValid([]); // false\n  isArrayValid([], true); // true\n  isArrayValid({ auth: 123, isAdmin: true }); // false\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisEmailValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a value is a valid email address.\n  ```typescript\n  import { isEmailValid } from 'web-utils-kit';\n\n  isEmailValid('jesusgraterol@gmail.com'); // true\n  isEmailValid('jesus@graterol'); // false\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisSlugValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a slug meets the following requirements:\n   - Accepts any Alpha Characters (lower and upper case)\n   - Accepts any digits\n   - Accepts `-` `,` `.` and/or `_`\n   - Meets a length range (Defaults to 2 - 16)\n  ```typescript\n  import { isSlugValid } from 'web-utils-kit';\n\n  isSlugValid('PythonWiz333'); // true\n  isSlugValid('hello-world', true); // true\n  isSlugValid('jesus@graterol'); // false\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisPasswordValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a password meets the following requirements:\n   - Meets a length range (Defaults to 8 - 2048)\n   - At least one uppercase letter\n   - At least one lowercase letter\n   - At least one number\n   - At least one special character\n  ```typescript\n  import { isPasswordValid } from 'web-utils-kit';\n\n  isPasswordValid('zR\u003cq%+r2C,\u0026fy.SE\u0026~.(REXTqe4K[?\u003eG'); // true\n  isPasswordValid('some-weak-password'); // false\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisOTPSecretValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a value has the correct OTP Secret Format.\n  ```typescript\n  import { isOTPSecretValid } from 'web-utils-kit';\n\n  isOTPSecretValid('NB2RGV2KAY2CMACD'); // true\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisOTPTokenValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a value has the correct OTP Token Format.\n  ```typescript\n  import { isOTPTokenValid } from 'web-utils-kit';\n\n  isOTPTokenValid('123456'); // true\n  isOTPTokenValid('1234567'); // false\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisJWTValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a value has a correct JWT Format: `[Base64-URL Encoded Header].[Base64-URL Encoded Payload].[Signature]`\n  ```typescript\n  import { isJWTValid } from 'web-utils-kit';\n\n  isJWTValid('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIzNDU2Nzg5LCJuYW1lIjoiSm9zZXBoIn0.OpOSSw7e485LOP5PrzScxHb7SR6sAOMRckfFwi4rp7o'); \n  // true\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisAuthorizationHeaderValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a value has a valid Authorization Header format based on the RFC6750. Example: \n  `Authorization: Bearer eyJhbGciOiJIUzI1NiIXVCJ9TJV...r7E20RMHrHDcEfxjoYZgeFONFh7HgQ`\n  ```typescript\n  import { isAuthorizationHeaderValid } from 'web-utils-kit';\n\n  isAuthorizationHeaderValid('Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIzNDU2Nzg5LCJuYW1lIjoiSm9zZXBoIn0.OpOSSw7e485LOP5PrzScxHb7SR6sAOMRckfFwi4rp7o'); \n  // true\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisSemverValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a value complies with semantic versioning.\n  ```typescript\n  import { isSemverValid } from 'web-utils-kit';\n\n  isSemverValid('1.0.0'); // true\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisURLValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a value is a valid URL.\n  ```typescript\n  import { isURLValid } from 'web-utils-kit';\n\n  isURLValid('https://jesusgraterol.dev'); // true\n  isURLValid('jesusgraterol.dev'); // false\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisUUIDValid\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a value is a valid UUID and that it matches a specific version.\n  ```typescript\n  import { isUUIDValid } from 'web-utils-kit';\n\n  isUUIDValid('9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d', 4); // true\n  isUUIDValid('01695553-c90c-705a-b56d-778dfbbd4bed', 7); // true\n  ```\n\u003c/details\u003e\n\n\n\n### Transformers\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eprettifyNumber\u003c/code\u003e\u003c/summary\u003e\n  \n  Verifies if a value is a valid UUID and that it matches a specific version.\n  ```typescript\n  import { prettifyNumber } from 'web-utils-kit';\n\n  prettifyNumber(1000.583); // '1,000.58'\n  prettifyNumber(2654.69642236, { maximumFractionDigits: 8, suffix: ' BTC' }); \n  // '2,654.69642236 BTC'\n  prettifyNumber(1000, { minimumFractionDigits: 2, prefix: '$' }); \n  // '$1,000.00'\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eprettifyDate\u003c/code\u003e\u003c/summary\u003e\n  \n  Formats a date instance based on a template.\n  - `date-short` -\u003e 12/05/2024 (Default)\n  - `date-medium` -\u003e December 5, 2024\n  - `date-long` -\u003e Thursday, December 5, 2024\n  - `time-short` -\u003e 12:05 PM\n  - `time-medium` -\u003e 12:05:20 PM\n  - `datetime-short` -\u003e 12/5/2024, 12:05 PM\n  - `datetime-medium` -\u003e December 5, 2024 at 12:05 PM\n  - `datetime-long` -\u003e Thursday, December 5, 2024 at 12:05:20 PM\n  ```typescript\n  import { prettifyDate } from 'web-utils-kit';\n\n  prettifyDate(new Date(), 'datetime-long'); \n  // 'Thursday, December 5, 2024 at 12:05:20 PM'\n  prettifyDate(Date.now(), 'date-medium'); \n  // 'December 5, 2024'\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eprettifyFileSize\u003c/code\u003e\u003c/summary\u003e\n  \n  Formats a bytes value into a human readable format.\n  ```typescript\n  import { prettifyFileSize } from 'web-utils-kit';\n\n  prettifyFileSize(85545, 6); // '83.540039 kB'\n  prettifyFileSize(79551423); // '75.87 MB'\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eprettifyBadgeCount\u003c/code\u003e\u003c/summary\u003e\n  \n  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.\n  ```typescript\n  import { prettifyBadgeCount } from 'web-utils-kit';\n\n  prettifyBadgeCount(0); // undefined\n  prettifyBadgeCount(11); // '9+'\n  prettifyBadgeCount(135, 99); // '99+'\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003ecapitalizeFirst\u003c/code\u003e\u003c/summary\u003e\n  \n  Capitalizes the first letter of a string and returns the new value.\n  ```typescript\n  import { capitalizeFirst } from 'web-utils-kit';\n\n  capitalizeFirst('hello world'); // 'Hello world'\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003etoTitleCase\u003c/code\u003e\u003c/summary\u003e\n  \n  Converts a string value into Title Case.\n  ```typescript\n  import { toTitleCase } from 'web-utils-kit';\n\n  toTitleCase('hello world'); // 'Hello World'\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003etoSlug\u003c/code\u003e\u003c/summary\u003e\n  \n  Converts a string value into a slug.\n  ```typescript\n  import { toSlug } from 'web-utils-kit';\n\n  toSlug('HELLO WORLD!!@'); // 'hello-world'\n  ```\n\u003c/details\u003e\n\n\n\n### Utils\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003egenerateUUID\u003c/code\u003e\u003c/summary\u003e\n  \n  Generates a UUID based on a version.\n  ```typescript\n  import { generateUUID } from 'web-utils-kit';\n\n  generateUUID(4); // '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'\n  generateUUID(7); // '01695553-c90c-705a-b56d-778dfbbd4bed'\n  ```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003egenerateRandomString\u003c/code\u003e\u003c/summary\u003e\n  \n  Generates a string from randomly picked characters based on the length.\n  ```typescript\n  import { generateRandomString } from 'web-utils-kit';\n\n  generateRandomString(15); // 'IbnqwSPvZdXxVyS'\n  ```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003egenerateRandomFloat\u003c/code\u003e\u003c/summary\u003e\n  \n  Generates a random number (decimal) constrained by the range.\n  ```typescript\n  import { generateRandomFloat } from 'web-utils-kit';\n\n  generateRandomFloat(1, 100); // 67.551\n  ```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003egenerateRandomInteger\u003c/code\u003e\u003c/summary\u003e\n  \n  Generates a random number (integer) constrained by the range.\n  ```typescript\n  import { generateRandomInteger } from 'web-utils-kit';\n\n  generateRandomInteger(1, 100); // 71\n  ```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003egenerateSequence\u003c/code\u003e\u003c/summary\u003e\n  \n  Generates a sequence of numbers within a range based on a number of steps.\n  ```typescript\n  import { generateSequence } from 'web-utils-kit';\n\n  generateSequence(1, 10); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n  generateSequence(1, 10, 2); // [1, 3, 5, 7, 9]\n  ```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003esortPrimitives\u003c/code\u003e\u003c/summary\u003e\n  \n  Sorts a list of primitive values based on their type and a sort direction.\n  ```typescript\n  import { sortPrimitives } from 'web-utils-kit';\n\n  [1, 2, 3, 4, 5].sort(sortPrimitives('asc')); \n  // [1, 2, 3, 4, 5]\n  [1, 2, 3, 4, 5].sort(sortPrimitives('desc')); \n  // [5, 4, 3, 2, 1]\n  ['a', 'b', 'c'].sort(sortPrimitives('asc')); \n  // ['a', 'b', 'c']\n  ['a', 'b', 'c'].sort(sortPrimitives('desc')); \n  // ['c', 'b', 'a']\n  ```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003esortRecords\u003c/code\u003e\u003c/summary\u003e\n  \n  Sorts a list of record values by key based on their type and a sort direction.\n  ```typescript\n  import { sortRecords } from 'web-utils-kit';\n\n  [{ v: 1 }, { v: 2 }, { v: 3 }].sort(sortRecords('v', 'asc')); \n  // [1, 2, 3, 4, 5]\n  [{ v: 1 }, { v: 2 }, { v: 3 }].sort(sortRecords('v', 'desc')); \n  // [{ v: 3 }, { v: 2 }, { v: 1 }]\n  [{ v: 'a' }, { v: 'b' }, { v: 'c' }].sort(sortRecords('v', 'asc')); \n  // [{ v: 'a' }, { v: 'b' }, { v: 'c' }]\n  [{ v: 'a' }, { v: 'b' }, { v: 'c' }].sort(sortRecords('v', 'desc')); \n  // [{ v: 'c' }, { v: 'b' }, { v: 'a' }]\n  ```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eshuffleArray\u003c/code\u003e\u003c/summary\u003e\n  \n  Creates a shallow copy of the input array and shuffles it, using a version of the Fisher-Yates algorithm.\n  ```typescript\n  import { shuffleArray } from 'web-utils-kit';\n\n  shuffleArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])\n  // [4, 7, 5, 3,  6, 8, 9, 1, 2, 10]\n  shuffleArray(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])\n  // ['d', 'j', 'c', 'a', 'g', 'e', 'b', 'f', 'i', 'h']\n  shuffleArray([{ a: 1 }, { b: 2 }, { c: 3 }, { d: 4 }, { e: 5 }])\n  // [ { c: 3 }, { d: 4 }, { a: 1 }, { b: 2 }, { e: 5 } ]\n  ```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003epickProps\u003c/code\u003e\u003c/summary\u003e\n  \n  Picks a list of properties from an object and returns a new object (shallow) with the provided keys.\n  ```typescript\n  import { pickProps } from 'web-utils-kit';\n\n  pickProps({ a: 1, b: 2, c: 3, d: 4 }, ['b', 'd'])\n  // { b: 2, d: 4 }\n  ```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eomitProps\u003c/code\u003e\u003c/summary\u003e\n  \n  Omits a list of properties from an object and returns a new object (shallow) with only those keys that weren't omitted.\n  ```typescript\n  import { omitProps } from 'web-utils-kit';\n\n  omitProps({ a: 1, b: 2, c: 3, d: 4 }, ['b', 'd'])\n  // { a: 1, c: 3 }\n  ```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eisEqual\u003c/code\u003e\u003c/summary\u003e\n  \n  Compares two objects or arrays deeply and returns true if they are equals.\n  ```typescript\n  import { isEqual } from 'web-utils-kit';\n\n  isEqual({ a: 2, c: 5, b: 3 }, { c: 5, b: 3, a: 2 });\n  // true\n  isEqual([{ a: 1, b: 2 }], [{ b: 2, a: 1 }]);\n  // true\n  ```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003edelay\u003c/code\u003e\u003c/summary\u003e\n  \n  Creates an asynchronous delay that resolves once the provided seconds have passed.\n  ```typescript\n  import { delay } from 'web-utils-kit';\n\n  await delay(3);\n  // ~3 seconds later\n  ```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eretryAsyncFunction\u003c/code\u003e\u003c/summary\u003e\n  \n  Executes an asynchronous function persistently, retrying on error with incremental delays defined in retryScheduleDuration (seconds).\n  ```typescript\n  import { retryAsyncFunction } from 'web-utils-kit';\n\n  const res = await retryAsyncFunction(\n    () =\u003e fetch('https://api.example.com/user/1'),\n    [3, 5],\n  );\n  await res.json();\n  // {\n  //   uid: '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',\n  //   nickname: 'PythonWiz333'\n  // }\n  ```\n\u003c/details\u003e\n\n\n\n\n\n\n\n\n\n\u003cbr/\u003e\n\n## Types\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eIUUIDVersion\u003c/code\u003e\u003c/summary\u003e\n  \n  The UUID versions supported by this library.\n  ```typescript\n  type IUUIDVersion = 4 | 7;\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eISortDirection\u003c/code\u003e\u003c/summary\u003e\n  \n  The sort direction that can be applied to a list\n  ```typescript\n  type ISortDirection = 'asc' | 'desc';\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eINumberFormatConfig\u003c/code\u003e\u003c/summary\u003e\n  \n  The configuration that will be used to prettify a number.\n  ```typescript\n  type INumberFormatConfig = {\n    minimumFractionDigits: number; // Default: 0\n    maximumFractionDigits: number; // Default: 2\n    prefix: string; // Default: ''\n    suffix: string; // Default: ''\n  };\n  ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eIDateTemplate\u003c/code\u003e\u003c/summary\u003e\n  \n  A date can be prettified by choosing a template that meets the user's requirements.\n  - `date-short` -\u003e 12/05/2024 (Default)\n  - `date-medium` -\u003e December 5, 2024\n  - `date-long` -\u003e Thursday, December 5, 2024\n  - `time-short` -\u003e 12:05 PM\n  - `time-medium` -\u003e 12:05:20 PM\n  - `datetime-short` -\u003e 12/5/2024, 12:05 PM\n  - `datetime-medium` -\u003e December 5, 2024 at 12:05 PM\n  - `datetime-long` -\u003e Thursday, December 5, 2024 at 12:05:20 PM\n  ```typescript\n  type IDateTemplate = 'date-short' | 'date-medium' | 'date-long' | 'time-short' | 'time-medium' | 'datetime-short' | 'datetime-medium' | 'datetime-long';\n  ```\n\u003c/details\u003e\n\n\n\n\n\n\u003cbr/\u003e\n\n## Built With\n\n- TypeScript\n\n\n\n\n\u003cbr/\u003e\n\n## Running the Tests\n\n```bash\n# integration tests\nnpm run test:integration\n\n# unit tests\nnpm run test:unit\n\n# benchmarks\nnpm run test:bench\n```\n\n\n\n\n\n\u003cbr/\u003e\n\n## License\n\n[MIT](https://choosealicense.com/licenses/mit/)\n\n\n\n\n\n\u003cbr/\u003e\n\n## Deployment\n\nInstall dependencies:\n```bash\nnpm install\n```\n\n\nBuild the library:\n```bash\nnpm start\n```\n\n\nPublish to `npm`:\n```bash\nnpm publish\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjesusgraterol%2Fweb-utils-kit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjesusgraterol%2Fweb-utils-kit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjesusgraterol%2Fweb-utils-kit/lists"}