{"_id":"@amitdhoju/js-utils","_rev":"2-c34afd33d43e5104f60f0c5248d1623b","name":"@amitdhoju/js-utils","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"@amitdhoju/js-utils","version":"0.0.1","keywords":["utils","utilities","string","number","array","object","typescript"],"author":{"name":"amitdhoju"},"license":"MIT","_id":"@amitdhoju/js-utils@0.0.1","maintainers":[{"name":"amitdhoju","email":"amitdhoju@gmail.com"}],"dist":{"shasum":"c3244c5a35e1a5e9f47101b8c4e129a1418eaf98","tarball":"https://registry.npmjs.org/@amitdhoju/js-utils/-/js-utils-0.0.1.tgz","fileCount":8,"integrity":"sha512-g88lYrj8ZzweA1UQM4W7S6hWwCQzzrHXC0t0GrlWLKDAJUj1KGqSV4ccSePVKK0nsa7da4WmXBQGSTw1N0q8qQ==","signatures":[{"sig":"MEUCIQCs97DW8Gv+wk3o9Y8Tm0ZcMNjYliFJWft7lb6rIn0qkgIgFE7s42XX/e0WcBtb9alKRw1Y6p8LtMk1yMw883DjNG4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":66012},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"dev":"tsup --watch","lint":"biome check .","test":"vitest run","build":"tsup","check":"biome check --write .","format":"biome format --write .","example":"npx tsx examples/demo.ts","release":"npm run build && changeset publish","version":"changeset version","changeset":"changeset","test:watch":"vitest"},"_npmUser":{"name":"amitdhoju","email":"amitdhoju@gmail.com"},"_npmVersion":"10.9.4","description":"String, number, array, and object utilities missing from native JavaScript","directories":{},"_nodeVersion":"22.21.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.2","@biomejs/biome":"^1.9.4","@changesets/cli":"^2.27.10"},"_npmOperationalInternal":{"tmp":"tmp/js-utils_0.0.1_1780126289349_0.5153292370558646","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@amitdhoju/js-utils","version":"0.0.2","description":"String, number, array, and object utilities missing from native JavaScript","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","lint":"biome check .","format":"biome format --write .","check":"biome check --write .","changeset":"changeset","version":"changeset version","release":"npm run build && changeset publish","example":"npx tsx examples/demo.ts"},"keywords":["utils","utilities","string","number","array","object","typescript"],"author":{"name":"amitdhoju"},"license":"MIT","devDependencies":{"@biomejs/biome":"^1.9.4","@changesets/cli":"^2.27.10","tsup":"^8.3.5","typescript":"^5.7.2","vitest":"^2.1.8"},"engines":{"node":">=20"},"publishConfig":{"access":"public"},"_id":"@amitdhoju/js-utils@0.0.2","gitHead":"2b44be8add44b19867f69b4fb6f9bfb3e4173b35","_nodeVersion":"22.21.1","_npmVersion":"10.9.4","dist":{"integrity":"sha512-Uc8p2+YteMyQUkO5Fe9/GkilRY9zXJv13IIMPVbQpsyC6V1nDkitz/6wC6ZZPtBl3XeDpS2sUMqvGn6IpEfPfQ==","shasum":"57149dfbce9346e7b6773e31bd7ae0786fca8168","tarball":"https://registry.npmjs.org/@amitdhoju/js-utils/-/js-utils-0.0.2.tgz","fileCount":8,"unpackedSize":66061,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCXS07Nbp+f0tyhU85oxp+ZeexKwjP+CjntN+j0cVjNqQIhALdN3F5U4RVBiFjxkDHO+tKWeD7d8fCYK2uz7fkmm5f+"}]},"_npmUser":{"name":"amitdhoju","email":"amitdhoju@gmail.com"},"directories":{},"maintainers":[{"name":"amitdhoju","email":"amitdhoju@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/js-utils_0.0.2_1780126737222_0.8084616929923538"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-30T07:31:29.114Z","modified":"2026-05-30T07:38:57.488Z","0.0.1":"2026-05-30T07:31:29.511Z","0.0.2":"2026-05-30T07:38:57.372Z"},"author":{"name":"amitdhoju"},"license":"MIT","keywords":["utils","utilities","string","number","array","object","typescript"],"description":"String, number, array, and object utilities missing from native JavaScript","maintainers":[{"name":"amitdhoju","email":"amitdhoju@gmail.com"}],"readme":"# @amitdhoju/js-utils\n\nA collection of string, number, array, and object utilities missing from native JavaScript.\n\n- **Zero dependencies**\n- **Dual ESM + CJS** — works in Node.js, bundlers, and modern browsers\n- **Fully typed** — ships with `.d.ts` declarations\n- **Tree-shakeable** — import only what you use\n\n## Installation\n\n```sh\nnpm install @amitdhoju/js-utils\n```\n\n## Usage\n\n```ts\nimport { capitalize, chunk, deepMerge } from \"@amitdhoju/js-utils\";\n```\n\n---\n\n## String\n\n### `capitalize(str)`\nCapitalizes the first letter of a string.\n```ts\ncapitalize(\"hello world\") // → \"Hello world\"\n```\n\n### `truncate(str, maxLength, suffix?)`\nTruncates a string to a max length, appending a suffix (default `\"...\"`) if cut.\n```ts\ntruncate(\"Hello World\", 7)        // → \"Hell...\"\ntruncate(\"Hello World\", 8, \"…\")   // → \"Hello W…\"\n```\n\n### `camelToKebab(str)`\nConverts camelCase to kebab-case.\n```ts\ncamelToKebab(\"myVariableName\") // → \"my-variable-name\"\n```\n\n### `kebabToCamel(str)`\nConverts kebab-case to camelCase.\n```ts\nkebabToCamel(\"my-variable-name\") // → \"myVariableName\"\n```\n\n### `slugify(str)`\nConverts a string to a URL-friendly slug.\n```ts\nslugify(\"Hello, World! 2024\") // → \"hello-world-2024\"\n```\n\n### `countOccurrences(str, substring)`\nCounts non-overlapping occurrences of a substring.\n```ts\ncountOccurrences(\"banana\", \"an\") // → 2\n```\n\n### `isPalindrome(str)`\nReturns `true` if the string is a palindrome (ignores case and non-alphanumeric characters).\n```ts\nisPalindrome(\"racecar\")                      // → true\nisPalindrome(\"A man a plan a canal Panama\")  // → true\nisPalindrome(\"hello\")                        // → false\n```\n\n### `padCenter(str, width, fill?)`\nPads both sides of a string to center it within a given width (default fill `\" \"`).\n```ts\npadCenter(\"hi\", 10)      // → \"    hi    \"\npadCenter(\"hi\", 10, \"*\") // → \"****hi****\"\n```\n\n---\n\n## Number\n\n### `clamp(value, min, max)`\nClamps a number between a minimum and maximum.\n```ts\nclamp(15, 0, 10)  // → 10\nclamp(-5, 0, 10)  // → 0\nclamp(5,  0, 10)  // → 5\n```\n\n### `randomInt(min, max)`\nReturns a random integer between `min` and `max` (both inclusive).\n```ts\nrandomInt(1, 6) // → 4\n```\n\n### `roundTo(value, decimals)`\nRounds a number to a specified number of decimal places.\n```ts\nroundTo(3.14159, 2) // → 3.14\nroundTo(1000.5, 0)  // → 1001\n```\n\n### `isEven(n)` / `isOdd(n)`\nChecks whether a number is even or odd.\n```ts\nisEven(4) // → true\nisOdd(7)  // → true\n```\n\n### `lerp(start, end, t)`\nLinearly interpolates between two values. `t` should be between `0` and `1`.\n```ts\nlerp(0, 100, 0)    // → 0\nlerp(0, 100, 0.5)  // → 50\nlerp(0, 100, 1)    // → 100\n```\n\n### `toOrdinal(n)`\nConverts a number to its ordinal string.\n```ts\ntoOrdinal(1)  // → \"1st\"\ntoOrdinal(2)  // → \"2nd\"\ntoOrdinal(3)  // → \"3rd\"\ntoOrdinal(11) // → \"11th\"\ntoOrdinal(21) // → \"21st\"\n```\n\n### `isFiniteNumber(value)`\nType-safe check that a value is a finite number (not `NaN`, not `Infinity`).\n```ts\nisFiniteNumber(42)       // → true\nisFiniteNumber(NaN)      // → false\nisFiniteNumber(Infinity) // → false\nisFiniteNumber(\"42\")     // → false\n```\n\n---\n\n## Array\n\n### `chunk(arr, size)`\nSplits an array into chunks of a given size.\n```ts\nchunk([1, 2, 3, 4, 5], 2) // → [[1, 2], [3, 4], [5]]\n```\n\n### `unique(arr)`\nReturns a new array with duplicates removed (first occurrence wins).\n```ts\nunique([1, 2, 2, 3, 1]) // → [1, 2, 3]\n```\n\n### `groupBy(arr, keyFn)`\nGroups array elements by a derived key.\n```ts\nconst items = [\n  { type: \"fruit\", name: \"apple\" },\n  { type: \"veg\",   name: \"carrot\" },\n  { type: \"fruit\", name: \"banana\" },\n];\ngroupBy(items, (x) => x.type);\n// → { fruit: [{...}, {...}], veg: [{...}] }\n```\n\n### `intersection(a, b)`\nReturns elements present in both arrays.\n```ts\nintersection([1, 2, 3], [2, 3, 4]) // → [2, 3]\n```\n\n### `difference(a, b)`\nReturns elements in `a` that are not in `b`.\n```ts\ndifference([1, 2, 3], [2, 3]) // → [1]\n```\n\n### `shuffle(arr)`\nReturns a new randomly shuffled array (Fisher-Yates). Does not mutate the original.\n```ts\nshuffle([1, 2, 3, 4, 5]) // → [3, 1, 5, 2, 4]  (random)\n```\n\n### `range(start, end, step?)`\nGenerates an array of numbers from `start` (inclusive) to `end` (exclusive).\n```ts\nrange(0, 5)       // → [0, 1, 2, 3, 4]\nrange(0, 10, 2)   // → [0, 2, 4, 6, 8]\nrange(5, 0, -1)   // → [5, 4, 3, 2, 1]\n```\n\n### `sum(arr)`\nReturns the sum of all numbers in an array.\n```ts\nsum([1, 2, 3, 4, 5]) // → 15\n```\n\n### `average(arr)`\nReturns the arithmetic mean of all numbers in an array.\n```ts\naverage([1, 2, 3, 4, 5]) // → 3\n```\n\n---\n\n## Object\n\n### `deepMerge(target, source)`\nDeep merges two objects. Source values overwrite target values recursively.\n```ts\ndeepMerge({ a: { b: 1 } }, { a: { c: 2 } })\n// → { a: { b: 1, c: 2 } }\n```\n\n### `pick(obj, keys)`\nReturns a new object containing only the specified keys.\n```ts\npick({ a: 1, b: 2, c: 3 }, [\"a\", \"c\"]) // → { a: 1, c: 3 }\n```\n\n### `omit(obj, keys)`\nReturns a new object with the specified keys removed.\n```ts\nomit({ a: 1, b: 2, c: 3 }, [\"b\"]) // → { a: 1, c: 3 }\n```\n\n### `deepClone(value)`\nDeep clones any value using the native `structuredClone` API.\n```ts\nconst clone = deepClone({ a: { b: 1 } });\nclone.a.b = 99; // original is unaffected\n```\n\n### `isEmpty(obj)`\nReturns `true` if an object has no own enumerable properties.\n```ts\nisEmpty({})       // → true\nisEmpty({ a: 1 }) // → false\n```\n\n### `flattenObject(obj)`\nFlattens a nested object into dot-notation keys.\n```ts\nflattenObject({ a: { b: { c: 1 } }, d: 2 })\n// → { \"a.b.c\": 1, \"d\": 2 }\n```\n\n### `invertObject(obj)`\nSwaps the keys and values of a flat string object.\n```ts\ninvertObject({ a: \"x\", b: \"y\" }) // → { x: \"a\", y: \"b\" }\n```\n\n---\n\n## Development\n\n```sh\nnpm install          # install dependencies\nnpm test             # run tests (Vitest)\nnpm run build        # build ESM + CJS output (tsup)\nnpm run lint         # lint and format check (Biome)\nnpm run example      # run the demo script\n```\n\n### Adding a changeset before releasing\n\n```sh\nnpx changeset        # describe your change + pick semver bump\nnpm run version      # apply version bump + update CHANGELOG.md\ngit add . && git commit -m \"release: vX.Y.Z\"\nnpm run release      # build + publish to npm\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}