{"id":18930025,"url":"https://github.com/labd/js-toolkit","last_synced_at":"2026-02-22T08:39:39.153Z","repository":{"id":222949121,"uuid":"758819552","full_name":"labd/js-toolkit","owner":"labd","description":"@labdigital/toolkit package for typescript development","archived":false,"fork":false,"pushed_at":"2024-10-15T18:59:51.000Z","size":161,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-10-03T05:01:50.144Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/labd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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-02-17T07:02:29.000Z","updated_at":"2024-10-15T18:58:54.000Z","dependencies_parsed_at":"2024-02-17T08:23:51.920Z","dependency_job_id":"7560e427-31bd-4212-9c3f-d02034a350b7","html_url":"https://github.com/labd/js-toolkit","commit_stats":{"total_commits":23,"total_committers":3,"mean_commits":7.666666666666667,"dds":0.5217391304347826,"last_synced_commit":"32068cc5ec57c16d20a5749165602e66ca7f0786"},"previous_names":["labd/commerce-utils"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/labd/js-toolkit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labd%2Fjs-toolkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labd%2Fjs-toolkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labd%2Fjs-toolkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labd%2Fjs-toolkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/labd","download_url":"https://codeload.github.com/labd/js-toolkit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labd%2Fjs-toolkit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29707063,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-22T05:59:28.568Z","status":"ssl_error","status_checked_at":"2026-02-22T05:58:46.208Z","response_time":110,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2024-11-08T11:36:15.937Z","updated_at":"2026-02-22T08:39:39.132Z","avatar_url":"https://github.com/labd.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @labdigital/toolkit\n\nThis package contains a set of common utility functions we use for most of our\ntypescript projects. It is unopinionated, should have almost no dependencies and\nis meant to be used in any project.\n\n## Installation\n\n```\npnpm add @labdigital/toolkit\n```\n\n## API\n\n\u003c!-- INSERT GENERATED DOCS START --\u003e\n\n### `isValue` (function)\n\nUtility for lists to ensure there are no empty values.\n\n```ts\nconst products = [\n\t{ id: \"a\", price: { centAmount: 20 } },\n\t{ id: \"b\", price: null },\n\t{ id: \"c\", price: { centAmount: 30 } },\n];\nproducts\n\t.map((x) =\u003e x.price)\n\t.filter(isValue)\n\t.map((p) =\u003e p.centAmount)[\n\t// results in\n\t(20, 30)\n];\n```\n\n### `unique` (function)\n\nFilter utility to filter out duplicate values\n\n```ts\nconst names = [\"john\", \"john\", \"jane\"].filter(unique); // ['john', 'jane']\n```\n\n### `uniqueBy` (function)\n\n### `groupByMap` (function)\n\nGroups a list based on a callback.\nReturns a Map where the keys are the result of the callback.\n\n```ts\ngroupByMap(\n  [{age: 18, name: 'John'}, {age: 18, name: 'Joe'}, {age: 16, name: 'Jack'}],\n  p =\u003e p.age,\n)\n\n// results in\nMap {\n 16: [{age: 16, name: 'Jack'}],\n 18: [{age: 18, name: 'John'}, {age: 18, name: 'Joe'}],\n}\n```\n\n### `groupBy` (function)\n\nGroups a list based on a callback.\nReturns a Map where the keys are the result of the callback.\n\n```ts\ngroupBy(\n  [{age: 18, name: 'John'}, {age: 18, name: 'Joe'}, {age: 16, name: 'Jack'}],\n  p =\u003e p.age,\n)\n\n// results in\n[\n [16, [{age: 16, name: 'Jack'}]],\n [18, [{age: 18, name: 'John'}, {age: 18, name: 'Joe'}]],\n]\n```\n\n### `findFirst` (function)\n\nFinds the first item in a list of items by a list of ids.\n\n````ts\nconst products = [\n{id: 'a', price: 1},\n{id: 'b', price: 1},\n{id: 'c', price: 1}\n]\nfindFirst(['x', 'b'], products, p =\u003e p.id) // {id: 'b', price: 1}\n\n\n### `range` (function)\n\nCreates a range of numbers, staring at `start` and ending at `end` .\n\n```ts\nrange({start: 0, end: 3}) // [0, 1, 2]\nrange({start: 1, end: 3}) // [1, 2]\n````\n\n### `zip` (function)\n\nMerges two arrays, creating a single array with tuples from both arrays.\n\n```ts\nconst a = [1, 2, 3];\nconst b = [\"a\", \"b\", \"c\"];\n\nzip(a, b); // [[1, 'a'], [2, 'b'], [3, 'c']]\n```\n\n### `getLocalizedValue` (function)\n\nAttempts to find a matching value for the provided locale by trying the given\nlocale and its language tag, followed by locale without subtags and then by\nany additional fallback locales specified.\n\nIt performs both an exact case-sensitive match and a case-insensitive match\nto ensure compatibility with different case conventions. Notably, if a\nspecific locale (e.g., 'en-GB') does not have a direct match, the function\nwill try to fall back to a more general locale (e.g., 'en') before moving on\nto the next fallback locales.\n\n```tsx\n// Define a map of localized values\nconst greetings = {\n\ten: \"Hello\",\n\t\"en-US\": \"Howdy\",\n\tfr: \"Bonjour\",\n};\n\n// Get localized value for British English without an explicit entry, falling\n// back to generic English\ngetLocalizedValue(greetings, \"en-GB\");\n```\n\n```tsx\n// Get localized value for American English specifically\ngetLocalizedValue(greetings, \"en-US\");\n```\n\n```tsx\n// Attempt to get a localized value for an unsupported locale with fallbacks\ngetLocalizedValue(greetings, \"es\", \"en\");\n```\n\n### `parseLocale` (function)\n\nParses a locale string and extracts the primary language tag and an optional\nsubtag. According to the IETF language tag standard (see\nhttps://en.wikipedia.org/wiki/IETF_language_tag), a locale can consist of a\nprimary language tag followed by optional subtags, separated by hyphens. This\nfunction specifically extracts the primary language tag and the first subtag\nif present. Subsequent subtags are not considered in the current\nimplementation.\n\n**Parameters:**\n\n- locale (`string`) - The locale string to parse. Expected format:\n  'language[-subtag]', where 'language' is a 2 or 3 letter language code, and\n  'subtag' is an optional additional identifier, such as a country code or\n  script.\n\n```tsx\n// Parsing a simple language tag\nparseLocale(\"en\");\n// Returns: { languageTag: 'en', subTag: undefined }\n```\n\n```tsx\n// Parsing a locale with a subtag\nparseLocale(\"en-US\");\n// Returns: { languageTag: 'en', subTag: 'US' }\n```\n\n```tsx\n// Parsing a locale with multiple subtags, note that subsequent subtags are ignored\nparseLocale(\"zh-Hant-HK\");\n// Returns: { languageTag: 'zh', subTag: 'Hant' }\n```\n\n### `formatFullname` (function)\n\nFormats a full name based on locale-specific conventions.\n\nCertain locales place the family name (last name) before the given name\n(first name), while others place the given name first. This function formats\nthe full name accordingly.\n\n**Parameters:**\n\n- givenName (`string`) - The given (first) name of the person.\n- familyName (`string`) - The family (last) name of the person.\n- locale (`string`) - The locale to format the name in (e.g., 'en-US', 'ja-JP').\n\n```tsx\n// Returns \"John Doe\" for US locale\nformatFullname(\"John\", \"Doe\", \"en-US\");\n```\n\n```tsx\n// Returns \"Doe John\" for Japanese locale\nformatFullname(\"John\", \"Doe\", \"ja-JP\");\n```\n\n### `sum` (function)\n\nSums the values of a list of objects calculated by a callback.\n\n```js\nsum([{ price: 1 }, { price: 2 }], (x) =\u003e x.price); // 3\n```\n\n### `byMin` (function)\n\nReducer callback to find object with some minimum value.\n\n```ts\n[{ price: 1 }, { price: 2 }].reduce(byMin((x) =\u003e x.price)); // {price: 1}\n```\n\n### `byMax` (function)\n\nReducer callback to find object with some maximum value.\n\n```ts\n[{ price: 1 }, { price: 2 }].reduce(byMax((x) =\u003e x.price)); // {price: 2}\n```\n\n### `clamp` (function)\n\nClamps the value between `min` and `max`.\n\nI.e. returns `min` if `value \u003c min`, or `max` if value \u003e `max`, or the value\nitself otherwise.\n\n### `roundHalfEven` (function)\n\nRounds a number to the nearest integer using the \"half to even\" strategy,\nalso known as \"bankers' rounding\". This method minimizes bias in rounding\nover a large set of numbers. When the fractional part of the number is\nexactly 0.5, it rounds to the nearest even number.\n\n**Parameters:**\n\n- value (`number`) - The number to round.\n\n```tsx\n// When rounding 2.5, it rounds to 2, because 2 is even\nroundHalfEven(2.5); // Returns: 2\n```\n\n```tsx\n// When rounding 3.5, it rounds to 4, because 4 is even\nroundHalfEven(3.5); // Returns: 4\n```\n\n### `roundHalfUp` (function)\n\nRounds a number to the nearest integer using the \"half up\" strategy. This\nmethod rounds up when the fractional part of the number is 0.5 or greater.\nIt's the most common form of rounding.\n\n**Parameters:**\n\n- value (`number`) - The number to round.\n\n```tsx\nroundHalfUp(2.5); // Returns: 3\n```\n\n```tsx\nroundHalfUp(2.4); // Returns: 2\n```\n\n### `roundHalfDown` (function)\n\nRounds a number to the nearest integer using the \"half down\" strategy. This\nmethod rounds down when the fractional part of the number is exactly 0.5,\ncontrary to the \"half up\" method.\n\n**Parameters:**\n\n- value (`number`) - The number to round.\n\n```tsx\nroundHalfDown(2.5); // Returns: 2\n```\n\n```tsx\nroundHalfDown(2.6); // Returns: 3\n```\n\n### `pruneObject` (function)\n\nRemoves all undefined properties\n\n```ts\npruneObject({\n\ta: 1,\n\tb: undefined,\n});\n// { a: 1 }\n```\n\n### `pick` (function)\n\nPick a subset of items from an object\n\n**Parameters:**\n\n- base (`T`) - The object\n- keys (`K[]`) - A list of keys to pick\n\n**returns:** Pick\u003cT, K\u003e\n\n```tsx\npick({ a: 1, b: 2, c: 3 }, \"a\", \"c\"); // { a: 1, c: 3 }\n```\n\n### `objectMap` (function)\n\nTransforms an object using the given value and or key transformers.\n\n```ts\nobjectMap(\n\t{\n\t\ta: 1,\n\t\tb: 2,\n\t\tc: 3,\n\t},\n\t{\n\t\tgetKey: (key, value) =\u003e key.toUpperCase(),\n\t\tgetValue: (value, key) =\u003e value * 2,\n\t},\n); // { A: 2, B: 4, C: 6 }\n```\n\n### `createObjectHash` (function)\n\nGenerates a deterministic key for an object ignoring the order of the fields.\n\nJSON stringifies the object and generates a base64 SHA-256 hash.\nThe keys of the object are sorted in order to get a deterministic key.\n\n### `equalsIgnoringCase` (function)\n\nCompares two strings for equality, ignoring case sensitivity.\n\n**Parameters:**\n\n- value (`string`) - The first string to compare.\n- other (`string`) - The second string to compare.\n\n### `DeepPartial` (type)\n\n\u003c!-- INSERT GENERATED DOCS END --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flabd%2Fjs-toolkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flabd%2Fjs-toolkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flabd%2Fjs-toolkit/lists"}