{"id":17312601,"url":"https://github.com/ndaidong/bellajs","last_synced_at":"2025-04-09T20:13:09.724Z","repository":{"id":20755892,"uuid":"24040458","full_name":"ndaidong/bellajs","owner":"ndaidong","description":"Lightweight util for your Node.js and browser apps","archived":false,"fork":false,"pushed_at":"2025-03-09T03:14:28.000Z","size":4324,"stargazers_count":11,"open_issues_count":0,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-04-09T20:13:04.383Z","etag":null,"topics":["javascript","nodejs","type-detection","utility"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/bellajs","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/ndaidong.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":"2014-09-15T02:51:59.000Z","updated_at":"2024-10-26T09:07:16.000Z","dependencies_parsed_at":"2024-10-26T12:11:09.729Z","dependency_job_id":"295de579-7388-4e0e-8772-c3e1b57dc286","html_url":"https://github.com/ndaidong/bellajs","commit_stats":{"total_commits":124,"total_committers":2,"mean_commits":62.0,"dds":"0.016129032258064502","last_synced_commit":"3a05fa54815b1049124089408d1cc157ce22ec04"},"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndaidong%2Fbellajs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndaidong%2Fbellajs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndaidong%2Fbellajs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndaidong%2Fbellajs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ndaidong","download_url":"https://codeload.github.com/ndaidong/bellajs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248103872,"owners_count":21048245,"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","nodejs","type-detection","utility"],"created_at":"2024-10-15T12:44:02.017Z","updated_at":"2025-04-09T20:13:09.696Z","avatar_url":"https://github.com/ndaidong.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BellaJS\n\nLightweight util for handling data type, string... in your Node.js and browser\napps.\n\n![CodeQL](https://github.com/ndaidong/bellajs/workflows/CodeQL/badge.svg)\n[![CI test](https://github.com/ndaidong/bellajs/workflows/ci-test/badge.svg)](https://github.com/ndaidong/bellajs/actions)\n[![Coverage Status](https://coveralls.io/repos/github/ndaidong/bellajs/badge.svg)](https://coveralls.io/github/ndaidong/bellajs)\n[![NPM](https://img.shields.io/npm/v/%40ndaidong%2Fbellajs?color=32bb24)](https://www.npmjs.com/package/@ndaidong/bellajs)\n[![JSR](https://jsr.io/badges/@ndaidong/bellajs?color=32bb24)](https://jsr.io/@ndaidong/bellajs)\n\n## Contents\n\n- [Setup](#setup)\n- [APIs](#apis)\n  - [DataType detection](#datatype-detection)\n  - [String manipulation](#string-manipulation)\n  - [Data handling](#data-handling): [`clone`](#cloneanything-val),\n    [`copies`](#copiesobject-source-object-target-boolean-requirematching-array-excepts)\n  - [Array utils](#array-utils): [`pick`](#pickarray-arr--number-count--1),\n    [`sort`](#sortarray-arr--function-compare),\n    [`sortBy`](#sortbyarray-arr-number-order-string-property),\n    [`shuffle`](#shufflearray-arr), [`unique`](#uniquearray-arr)\n  - [Functional utils](#functional-utils): [`curry`](#curryfn),\n    [`compose`](#composef1-f2-fn), [`pipe`](#pipef1-f2-fn),\n  - [Date utils](#date-utils):\n    [`formatDateString`](#formatdatestringdate--timestamp--string-locale--object-options),\n    [`formatTimeAgo`](#formattimeagodate--timestamp--string-locale--string-justnow)\n  - [Random utils](#random-utils): [`randint`](#randintnumber-min--number-max),\n    [`genid`](#genidnumber-length--string-prefix)\n\n- [Development](#development)\n\n- [License](#license)\n\n## Setup \u0026 Usage\n\n### Deno\n\nhttps://jsr.io/@ndaidong/bellajs\n\n```ts\nimport { genid } from \"@ndaidong/bellajs\";\n\nfor (let i = 0; i \u003c 5; i++) {\n  console.log(genid());\n}\n```\n\nYou can use JSR packages without an install step using `jsr:` specifiers:\n\n```ts\nimport { genid } from \"jsr:@ndaidong/bellajs\";\n\nfor (let i = 0; i \u003c 5; i++) {\n  console.log(genid());\n}\n```\n\nYou can also use `npm:` specifiers as before:\n\n```ts\nimport { genid } from \"npm:@ndaidong/bellajs\";\n\nfor (let i = 0; i \u003c 5; i++) {\n  console.log(genid());\n}\n```\n\nOr import from esm.sh\n\n```ts\nimport { genid } from \"https://esm.sh/@ndaidong/bellajs\";\n\nfor (let i = 0; i \u003c 5; i++) {\n  console.log(genid());\n}\n```\n\n### Node.js \u0026 Bun\n\nhttps://www.npmjs.com/package/@ndaidong/bellajs\n\n```bash\nnpm i @ndaidong/bellajs\n# pnpm\npnpm i @ndaidong/bellajs\n# yarn\nyarn add @ndaidong/bellajs\n# bun\nbun add @ndaidong/bellajs\n```\n\n```js\nimport { genid } from \"@ndaidong/bellajs\";\n\nfor (let i = 0; i \u003c 5; i++) {\n  console.log(genid());\n}\n```\n\nYou can also use CJS style:\n\n```js\nconst { genid } = require(\"@ndaidong/bellajs\");\n\nfor (let i = 0; i \u003c 5; i++) {\n  console.log(genid());\n}\n```\n\n### Browsers:\n\n```html\n\u003cscript type=\"module\"\u003e\n  import { genid } from \"https://esm.sh/@ndaidong/bellajs\";\n  // import { genid } from 'https://unpkg.com/@ndaidong/bellajs/esm/mod.js';\n\n  for (let i = 0; i \u003c 5; i++) {\n    console.log(genid());\n  }\n\u003c/script\u003e\n```\n\n## APIs\n\n### DataType detection\n\n- `.isArray(Anything val)`\n- `.isBoolean(Anything val)`\n- `.isDate(Anything val)`\n- `.isEmail(Anything val)`\n- `.isEmpty(Anything val)`\n- `.isFunction(Anything val)`\n- `.isInteger(Anything val)`\n- `.isLetter(Anything val)`\n- `.isNil(Anything val)`\n- `.isNull(Anything val)`\n- `.isNumber(Anything val)`\n- `.isObject(Anything val)`\n- `.isString(Anything val)`\n- `.isUndefined(Anything val)`\n\n### String manipulation\n\n- `.ucfirst(String s)`\n- `.ucwords(String s)`\n- `.escapeHTML(String s)`\n- `.unescapeHTML(String s)`\n- `.slugify(String s)`\n- `.stripTags(String s)`\n- `.stripAccent(String s)`\n- `.truncate(String s, Number limit)`\n- `.replaceAll(String s, String|Array search, String|Array replace)`\n\n### Data handling\n\n#### `clone(Anything val)`\n\nMake a deep copy of a variable.\n\n```js\nimport { clone } from \"@ndaidong/bellajs\";\n\nconst b = [\n  1,\n  5,\n  0,\n  \"a\",\n  -10,\n  \"-10\",\n  \"\",\n  {\n    a: 1,\n    b: \"Awesome\",\n  },\n];\n\nconst cb = clone(b);\nconsole.log(cb);\n```\n\n_cb_ now has the same values as _b_, while the properties are standalone, not\nreference. So that:\n\n```js\ncb[7].a = 2;\ncb[7].b = \"Noop\";\n\nconsole.log(b[7]);\n```\n\nWhat you get is still:\n\n```js\n{\n  a: 1,\n  b: 'Awesome'\n}\n```\n\n#### `copies(Object source, Object target[[, Boolean requireMatching], Array excepts])`\n\nCopy the properties from _source_ to _target_.\n\n- _requireMatching_: if true, BellaJS only copies the properties that are\n  already exist in _target_.\n- _excepts_: array of the properties properties in _source_ that you don't want\n  to copy.\n\nAfter this action, target will be modified.\n\n```js\nimport { copies } from \"@ndaidong/bellajs\";\n\nconst a = {\n  name: \"Toto\",\n  age: 30,\n  level: 8,\n  nationality: {\n    name: \"America\",\n  },\n};\nconst b = {\n  level: 4,\n  IQ: 140,\n  epouse: {\n    name: \"Alice\",\n    age: 27,\n  },\n  nationality: {\n    long: \"18123.123123.12312\",\n    lat: \"98984771.134231.1234\",\n  },\n};\n\ncopies(a, b);\nconsole.log(b);\n```\n\nOutput:\n\n```js\n{\n  level: 8,\n  IQ: 140,\n  epouse: {\n    name: 'Alice',\n    age: 27\n  },\n  nationality: {\n    long: '18123.123123.12312',\n    lat: '98984771.134231.1234',\n    name: 'America'\n  },\n  name: 'Toto',\n  age: 30\n}\n```\n\n### Array utils\n\n#### `pick(Array arr [, Number count = 1])`\n\nRandomly choose N elements from array.\n\n```js\nimport { pick } from \"@ndaidong/bellajs\";\n\nconst arr = [1, 3, 8, 2, 5, 7];\npick(arr, 2); // --\u003e [3, 5]\npick(arr, 2); // --\u003e [8, 1]\npick(arr); // --\u003e [3]\npick(arr); // --\u003e [7]\n```\n\n#### `sort(Array arr [, Function compare])`\n\nSort the array using a function.\n\n```js\nimport { sort } from \"@ndaidong/bellajs\";\n\nconst fn = (a, b) =\u003e {\n  return a \u003c b ? 1 : a \u003e b ? -1 : 0;\n};\n\nsort([3, 1, 5, 2], fn); // =\u003e [ 1, 2, 3, 5 ]\n```\n\n#### `sortBy(Array arr, Number order, String property)`\n\nSort the array by specific property and direction.\n\n```js\nimport { sortBy } from \"@ndaidong/bellajs\";\n\nconst players = [\n  {\n    name: \"Jerome Nash\",\n    age: 24,\n  },\n  {\n    name: \"Jackson Valdez\",\n    age: 21,\n  },\n  {\n    name: \"Benjamin Cole\",\n    age: 23,\n  },\n  {\n    name: \"Manuel Delgado\",\n    age: 33,\n  },\n  {\n    name: \"Caleb McKinney\",\n    age: 28,\n  },\n];\n\nconst result = sortBy(players, -1, \"age\");\nconsole.log(result);\n```\n\n#### `shuffle(Array arr)`\n\nShuffle the positions of elements in an array.\n\n```js\nimport { shuffle } from \"@ndaidong/bellajs\";\n\nshuffle([1, 3, 8, 2, 5, 7]);\n```\n\n#### `unique(Array arr)`\n\nRemove all duplicate elements from an array.\n\n```js\nimport { unique } from \"@ndaidong/bellajs\";\n\nunique([1, 2, 3, 2, 3, 1, 5]); // =\u003e [ 1, 2, 3, 5 ]\n```\n\n### Functional utils\n\n#### `curry(fn)`\n\nMake a curried function.\n\n```js\nimport { curry } from \"@ndaidong/bellajs\";\n\nconst sum = curry((a, b, c) =\u003e {\n  return a + b + c;\n});\n\nsum(3)(2)(1); // =\u003e 6\nsum(1)(2)(3); // =\u003e 6\nsum(1, 2)(3); // =\u003e 6\nsum(1)(2, 3); // =\u003e 6\nsum(1, 2, 3); // =\u003e 6\n```\n\n#### `compose(f1, f2, ...fN)`\n\nPerforms right-to-left function composition.\n\n```js\nimport { compose } from \"@ndaidong/bellajs\";\n\nconst f1 = (name) =\u003e {\n  return `f1 ${name}`;\n};\nconst f2 = (name) =\u003e {\n  return `f2 ${name}`;\n};\nconst f3 = (name) =\u003e {\n  return `f3 ${name}`;\n};\n\nconst addF = compose(f1, f2, f3);\n\naddF(\"Hello\"); // =\u003e 'f1 f2 f3 Hello'\n\nconst add1 = (num) =\u003e {\n  return num + 1;\n};\n\nconst mult2 = (num) =\u003e {\n  return num * 2;\n};\n\nconst add1AndMult2 = compose(add1, mult2);\nadd1AndMult2(3); // =\u003e 7\n// because multiple to 2 first, then add 1 late =\u003e 3 * 2 + 1\n```\n\n#### `pipe(f1, f2, ...fN)`\n\nPerforms left-to-right function composition.\n\n```js\nimport { pipe } from \"@ndaidong/bellajs\";\n\nconst f1 = (name) =\u003e {\n  return `f1 ${name}`;\n};\nconst f2 = (name) =\u003e {\n  return `f2 ${name}`;\n};\nconst f3 = (name) =\u003e {\n  return `f3 ${name}`;\n};\n\nconst addF = pipe(f1, f2, f3);\n\naddF(\"Hello\"); // =\u003e 'f3 f2 f1 Hello'\n\nconst add1 = (num) =\u003e {\n  return num + 1;\n};\n\nconst mult2 = (num) =\u003e {\n  return num * 2;\n};\n\nconst add1AndMult2 = pipe(add1, mult2);\nadd1AndMult2(3); // =\u003e 8\n// because add 1 first, then multiple to 2 late =\u003e (3 + 1) * 2\n```\n\n### Date utils\n\n#### `formatDateString(Date | Timestamp [, String locale [, Object options]])`\n\n```js\nimport { formatDateString } from \"@ndaidong/bellajs\";\n\nconst today = new Date();\n\nformatDateString(today); // =\u003e Jan 3, 2022, 8:34:28 PM GMT+7\n\n// custom format\nformatDateString(today, {\n  dateStyle: \"short\",\n  timeStyle: \"short\",\n  hour12: true,\n}); // =\u003e 1/3/22, 8:34 PM\n\n// custom locale\nformatDateString(today, \"zh\"); // =\u003e 2022年1月3日 GMT+7 下午8:34:28\n\n// custom lang and format\nformatDateString(today, \"zh\", {\n  dateStyle: \"short\",\n  timeStyle: \"long\",\n  hour12: true,\n}); // =\u003e 2022/1/3 GMT+7 下午8:34:28\n\nformatDateString(today, \"vi\"); // =\u003e 20:34:28 GMT+7, 3 thg 1, 2022\nformatDateString(today, \"vi\", {\n  dateStyle: \"full\",\n  timeStyle: \"full\",\n}); // =\u003e 20:34:28 Giờ Đông Dương Thứ Hai, 3 tháng 1, 2022\n```\n\n#### `formatTimeAgo(Date | Timestamp [, String locale [, String justnow]])`\n\n```js\nimport { formatTimeAgo } from \"@ndaidong/bellajs\";\n\nconst today = new Date();\n\nconst yesterday = today.setDate(today.getDate() - 1);\nformatTimeAgo(yesterday); // =\u003e 1 day ago\n\nconst current = new Date();\nconst aLittleWhile = current.setHours(current.getHours() - 3);\nformatTimeAgo(aLittleWhile); // =\u003e 3 hours ago\n\n// change locale\nformatTimeAgo(aLittleWhile, \"zh\"); // =\u003e 3小时前\nformatTimeAgo(aLittleWhile, \"vi\"); // =\u003e 3 giờ trước\n```\n\nThe last param `justnow` can be used to display a custom 'just now' message,\nwhen the distance is lesser than 1s.\n\n```js\nconst now = new Date();\nconst aJiff = now.setTime(now.getTime() - 100);\nformatTimeAgo(aJiff); // =\u003e 'just now'\nformatTimeAgo(aJiff, \"fr\", \"à l'instant\"); // =\u003e à l'instant\nformatTimeAgo(aJiff, \"ja\", \"すこし前\"); // =\u003e すこし前\n```\n\nThese two functions based on recent features of built-in object `Intl`.\n\nPlease refer the following resources for more info:\n\n- [Intl.DateTimeFormat() constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat)\n- [Intl.RelativeTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat)\n- [Intl.Locale](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale)\n\n### Random utils\n\n#### `randint([Number min [, Number max]])`\n\nReturns a number between `min` and `max`\n\n```js\nimport { randint } from \"@ndaidong/bellajs\";\n\nrandint(); // =\u003e a random integer\nrandint(1, 5); // =\u003e a random integer between 3 and 5, including 1 and 5\n```\n\n#### `genid([Number length [, String prefix]])`\n\nCreate random ID string.\n\n```js\nimport { genid } from \"@ndaidong/bellajs\";\n\ngenid(); // =\u003e random 32 chars\ngenid(16); // =\u003e random 16 chars\ngenid(5); // =\u003e random 5 chars\ngenid(5, \"X_\"); // =\u003e X_{random 3 chars}\n```\n\n## Development\n\nSince v12.x.x, we switched to [Deno](https://docs.deno.com/runtime/manual/)\nplatform, and use [DNT](https://github.com/denoland/dnt) to build Node.js\npackages.\n\n```bash\ngit clone https://github.com/ndaidong/bellajs.git\ncd bellajs\n\n# test\ndeno test\n\n# build npm packages\ndeno task build\n\ncd npm\nnode test_runner.js\n```\n\n## License\n\nThe MIT License (MIT)\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fndaidong%2Fbellajs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fndaidong%2Fbellajs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fndaidong%2Fbellajs/lists"}