{"id":18396699,"url":"https://github.com/igorskyflyer/npm-keppo","last_synced_at":"2026-05-10T03:02:01.453Z","repository":{"id":50614541,"uuid":"519578182","full_name":"igorskyflyer/npm-keppo","owner":"igorskyflyer","description":"🎡 Parse, manage, compare and output SemVer-compatible version numbers with Keppo. 🧮","archived":false,"fork":false,"pushed_at":"2023-07-03T20:30:20.000Z","size":36,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-05T17:13:40.868Z","etag":null,"topics":["back-end","compare","diff","difference","igorskyflyer","javascript","keppo","library","manage","node","nodejs","npm","output","parse","print","semver","version"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@igor.dvlpr/keppo","language":"JavaScript","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/igorskyflyer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2022-07-30T17:20:43.000Z","updated_at":"2022-10-20T18:40:41.000Z","dependencies_parsed_at":"2024-10-30T03:53:58.855Z","dependency_job_id":null,"html_url":"https://github.com/igorskyflyer/npm-keppo","commit_stats":{"total_commits":33,"total_committers":1,"mean_commits":33.0,"dds":0.0,"last_synced_commit":"fddd2c2d541dbdbd882acdb6d77d461af4778873"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/igorskyflyer/npm-keppo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorskyflyer%2Fnpm-keppo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorskyflyer%2Fnpm-keppo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorskyflyer%2Fnpm-keppo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorskyflyer%2Fnpm-keppo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/igorskyflyer","download_url":"https://codeload.github.com/igorskyflyer/npm-keppo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorskyflyer%2Fnpm-keppo/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267759242,"owners_count":24140023,"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","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["back-end","compare","diff","difference","igorskyflyer","javascript","keppo","library","manage","node","nodejs","npm","output","parse","print","semver","version"],"created_at":"2024-11-06T02:14:36.427Z","updated_at":"2026-05-10T03:02:01.445Z","avatar_url":"https://github.com/igorskyflyer.png","language":"JavaScript","funding_links":["https://ko-fi.com/igorskyflyer"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/igorskyflyer/npm-keppo/main/media/keppo.png\" alt=\"Icon of Keppo\" width=\"256\" height=\"256\"\u003e\n  \u003ch1\u003eKeppo\u003c/h1\u003e\n\u003c/div\u003e\n\n\u003cbr\u003e\n\n\u003ch4 align=\"center\"\u003e\n  🎡 A SemVer engine with a fluent API to parse, manage, compare, and output version numbers. 🧮\n\u003c/h4\u003e\n\n\u003cbr\u003e\n\n## 📃 Table of Contents\n\n- [**Features**](#-features)\n- [**Usage**](#-usage)\n- [**API**](#-api)\n- [**Examples**](#️-examples)\n- [**Changelog**](#-changelog)\n- [**Support**](#-support)\n- [**License**](#-license)\n- [**Related**](#-related)\n- [**Author**](#-author)\n\n\u003cbr\u003e\n\n## 🤖 Features\n\n`Keppo` is a fluent SemVer engine, every method returns the instance, so you can chain mutations like *poetry*:\n\n`keppo.ts`\n```ts\nnew Keppo('1.2.3-alpha')\n  .increaseMajor()\n  .setLabel('beta')\n  .decreasePatch()\n  .toString() // → '2.2.2-beta'\n```\n\n- 🔢 Parses \u0026 validates **SemVer** strings like `'1.2.3'`, `'v2.0.0-alpha'`\n- 🧠 Strict \u0026 loose mode support for flexible parsing\n- ⬆️ Increments major, minor, or patch with auto-reset and safety checks for overflows\n- ⬇️ Decrements safely, never underflows\n- 🏷️ Sets \u0026 formats labels like `'alpha'`, `'beta.1'`\n- 🔍 Compares versions and returns `-1`, `0`, or `1`\n- 🧪 Validates version strings before use\n- 🧮 Calculates max safe increment for each component\n- 🧾 Prints version with optional `'v'` prefix\n- 🛡️ Guards against unsafe integers and malformed input\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 🕵🏼 Usage\n\nInstall it by executing any of the following, depending on your preferred package manager:\n\n```bash\npnpm add @igorskyflyer/keppo\n```\n\n```bash\nyarn add @igorskyflyer/keppo\n```\n\n```bash\nnpm i @igorskyflyer/keppo\n```\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 🤹🏼 API\n\nThere are 2 available constructors:\n\n```ts\nconstructor(\n  major: number,\n  minor: number,\n  patch: number,\n  strict?: boolean,\n  label?: string\n)\n```\n\n`major: number` - major version number (default: `0`).\n\n`minor: number` - minor version number (default: `0`).\n\n`patch: number` - patch version number (default: `0`).\n\n`strict?: boolean = true` - enables strict parsing mode (default: `true`).\n\n`label?: string = ''` - optional label (e.g. `'alpha'`, `'beta.1'`), no dash prefix needed.\n\n\u003cbr\u003e\n\n\u003e Throws if any component is invalid or violates SemVer rules.  \n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nconstructor(version: string)\n```\n\n`version: string` - a valid SemVer string (e.g. `'1.2.3'`, `'v2.0.0-alpha'`).\n\n\u003cbr\u003e\n\n\u003e Throws if the string is invalid or fails SemVer parsing.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nstatic VERSION: string\n```\n\nReturns the internal version of the Keppo engine.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nstatic from(version: string, strict?: boolean): Keppo\n```\n\nCreates a new `Keppo` instance from a valid SemVer string.  \nEquivalent to `new Keppo(...).setVersion(version)` but more fluent.\n\n`version: string` - a valid SemVer string (e.g. `'1.2.3'`, `'v2.0.0-alpha'`).\n\n`strict?: boolean` - optional flag to enable strict parsing mode.\n\n\u003cbr\u003e\n\n\u003e Throws if the version string is invalid.\n\nReturns a fully initialized `Keppo` instance.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nstatic isValid(version: string, isStrict: boolean = true): boolean\n```\n\nChecks whether a given string is a valid SemVer version.  \nUseful for validating a version before calling `setVersion()` or instantiating a `Keppo` instance.\n\n`version: string` - a SemVer string (e.g. `'1.2.3'`, `'v2.0.0-alpha'`)\n\n`isStrict: boolean` - whether to enable strict parsing (default: `true`)\n\nReturns `true` if the version is valid; otherwise `false`\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nsetStrict(isStrict: boolean = true): Keppo\n```\n\nSets the strict mode for SemVer parsing.  \n\nWhen enabled, version strings must follow strict SemVer format (e.g. no `v` prefix).  \nWhen disabled, relaxed formats like `v1.0.0` are accepted.  \n\n`isStrict: boolean` - whether to enable strict mode (default: `true`)  \n\nReturns the current `Keppo` instance.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nincreaseMajor(major: number = 1): Keppo\n```\n\nIncreases the `major` version number by the specified amount.  \nResets the `minor` and `patch` components to `0` after incrementing.\n\n`major: number = 1` - the amount to increase by (default: `1`)\n\n\u003cbr\u003e\n\n\u003e Throws if the value is invalid or exceeds safe integer limits.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nincreaseMinor(minor?: number = 1): Keppo\n```\n\nIncreases the `minor` version number by the specified amount.  \nResets the `patch` component to `0` after incrementing.\n\n`minor: number = 1` - the amount to increase by (default: `1`).\n\n\u003cbr\u003e\n\n\u003e Throws if the value is invalid or exceeds safe integer limits.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nincreasePatch(patch?: number = 1): Keppo\n```\n\nIncreases the patch version number by the specified amount.\n\n`patch: number = 1` - The amount to increase by (default: `1`).\n\n\u003cbr\u003e\n\n\u003e Throws if the value is invalid or exceeds safe integer limits.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\ndecreaseMajor(major?: number = 1): Keppo\n```\n\nDecreases the major version number by the specified amount.  \nResets the minor and patch components to `0` after decrementing.\n\n`major: number = 1` - the amount to decrease by (default: `1`).\n\n\u003cbr\u003e\n\n\u003e Throws if the value is invalid or results in a negative version.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\ndecreaseMinor(minor?: number = 1): Keppo\n```\n\nDecreases the minor version number by the specified amount.  \nResets the patch component to `0` after decrementing.\n\n`minor: number = 1` - the amount to decrease by (default: `1`).\n\n\u003cbr\u003e\n\n\u003e Throws an exception if the passed parameter is not valid.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\ndecreasePatch(patch?: number = 1): Keppo\n```\n\nDecreases the patch version number by the specified amount.\n\n`patch: number = 1` - the amount to decrease by (default: `1`).\n\n\u003cbr\u003e\n\n\u003e Throws if the value is invalid or results in a negative patch version.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nsetMajor(major: number): Keppo\n```\n\nSets the major version number for the current Keppo instance.\n\n`major: number ` - the major version as a number (e.g. `2`).\n\n\u003cbr\u003e\n\n\u003e Throws if the value is invalid, non-numeric, or negative.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nsetMinor(minor: number): Keppo\n```\n\nSets the minor version number for the current `Keppo` instance.\n\n`minor: number` - the minor version, as a number (e.g. `3`).\n\n\u003cbr\u003e\n\n\u003e Throws if the value is invalid, non-numeric, or negative.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nsetPatch(patch: number): Keppo\n```\n\nSets the patch version number for the current `Keppo` instance.\n\n`patch: number` - the patch version, as a number (e.g. `4`).\n\n\u003cbr\u003e\n\n\u003e Throws if the value is invalid, non-numeric, or negative.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nsetLabel(label: string): Keppo\n```\n\nSets the version label for the current `Keppo` instance.  \nThe label will be appended to the version string with a dash (e.g. `'alpha'` → `0.1.0-alpha`).  \nNo need to include the dash manually.\n\n`label: string` - a valid label string (e.g. `'alpha'`, `'beta.1'`).\n\n\u003cbr\u003e\n\n\u003e Throws if the label is invalid or fails pattern validation.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nclearLabel(): Keppo\n```\n\nClears the label of the current Keppo instance.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\ncompareWith(version: Keppo): KeppoComparison\n```\n\nCompares the current `Keppo` version against another `Keppo` instance.  \n\nFor improved readability, use the `KeppoComparison` enum.\n\n`version: Keppo` - another `Keppo` instance to compare against.\n\n\u003cbr\u003e\n\n\u003e Throws if the input is invalid.\n\nReturns a value of `KeppoComparison` defined as:\n\n- `-1` if the current version is older\n- `0` if both versions are equal,\n- `1` if the current version is newer.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nenum KeppoComparison {\n  Older = -1, // the current version is less than the compared version\n  Current = 0, // both versions are equal\n  Newer = 1 // the current version is greater than the compared version\n}\n```\n\nEnum representing the result of a version comparison.  \nUsed by `compareWith()` to indicate whether the current version is older, equal to, or newer than the target version.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\ncompareWith(version: string): KeppoComparison\n```\n\nCompares the current `Keppo` version against a SemVer string.  \n\nFor improved readability, use the `KeppoComparison` enum.\n\n`version: string` - a valid SemVer string (e.g. `'1.2.3-beta.1'`) to compare against.\n\n\u003cbr\u003e\n\n\u003e Throws if the input is not a valid SemVer string.\n\nReturns a value of `KeppoComparison` defined as:\n\n- `-1` if the current version is older\n- `0` if both versions are equal,\n- `1` if the current version is newer.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\noutput(): void\n```\n\nPrints to console the String representation of the current `Keppo` object.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n\u003ca id=\"set-version\"\u003e\u003c/a\u003e\n\n```ts\nsetVersion(version: string): Keppo\n```\n\nSets the current version for the `Keppo` instance.  \nReplaces all existing version components and label with values parsed from the provided SemVer string.\n\n\u003cbr\u003e\n\n\u003e Throws an exception if the passed parameter is not valid or the passed parameter is not a valid SemVer version.\n\n`version: string` - a valid SemVer string (e.g. `'1.2.3'`, `'v2.0.0-beta.1'`).\n\nThrows if the string is invalid or fails SemVer parsing.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nreset(): Keppo\n```\n\nResets the current Keppo instance's SemVer version to `0.0.0` and label to an empty string.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\ntoString(): string\n```\n\nFormats the current `Keppo` object as a String.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\ncanIncreaseMajor(major: number = 1): boolean\n```\n\nChecks whether the major version can be safely increased by the given amount.  \nUses `Number.isSafeInteger()` to ensure the result stays within JavaScript's safe integer range.\n\n`major: number = 1` - the amount to increase by (default: `1`).\n\nReturns `true` if the increment is safe; otherwise `false`.\n\nRead more about Integer safety on [**MDN**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger).\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\ncanIncreaseMinor(minor: number = 1): boolean\n```\n\nChecks whether the minor version can be safely increased by the given amount.  \nUses `Number.isSafeInteger()` to ensure the result remains within JavaScript's safe integer range.\n\n`minor: number = 1` - the amount to increase by (default: `1`).\n\nReturns `true` if the increment is safe; otherwise `false`.\n\nRead more about Integer safety on [**MDN**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger).\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\ncanIncreasePatch(patch: number = 1): boolean\n```\n\nChecks whether the patch version can be safely increased by the given amount.  \nUses `Number.isSafeInteger()` to ensure the result remains within JavaScript's safe integer range.\n\n`patch: number = 1` - the amount to increase by (default: `1`).\n\nReturns `true` if the increment is safe; otherwise `false`.\n\nRead more about Integer safety on [**MDN**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger).\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nmaxIncreaseMajor(): number\n```\n\nReturns the maximum safe value that can be used to increase the major version number.  \nBased on JavaScript's `Number.MAX_SAFE_INTEGER`, which ensures arithmetic remains precise.\n\nRead more about Integer safety on [**MDN**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger).\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nmaxIncreaseMinor(): number\n```\n\nReturns the maximum safe value that can be used to increase the minor version number.  \nBased on JavaScript’s `Number.MAX_SAFE_INTEGER`, ensuring arithmetic remains precise.\n\nRead more about Integer safety on [**MDN**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger).\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```ts\nmaxIncreasePatch(): number\n```\n\nReturns the maximum safe value that can be used to increase the patch version number.  \nBased on JavaScript’s `Number.MAX_SAFE_INTEGER`, ensuring arithmetic remains precise.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 🗒️ Examples\n\n\n```ts\nimport { Keppo } from '@igorskyflyer/keppo'\n\nnew Keppo(1, 0, 0).toString() // returns '1.0.0'\nnew Keppo(1, 0, 0, true, 'alpha').toString() // returns '1.0.0-alpha'\nnew Keppo('1.0.0').increaseMajor(2).toString() // returns '3.0.0'\nnew Keppo(1, 0, 0).compareWith('2.0.0') // returns  -1\nnew Keppo('1.0.32').maxIncreasePatch() // returns 9007199254740959\nnew Keppo('1.0.1').canIncreasePatch(1) // returns true\n// static method\nKeppo.isValid('v1.0.0', false) //returns true\nKeppo.isValid('v1.0.0') // returns false\n```\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 📝 Changelog\n\n📑 The changelog is available here, [**CHANGELOG**](https://github.com/igorskyflyer/npm-keppo/blob/main/CHANGELOG.md).\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 🪪 License\n\nLicensed under the [**MIT license**](https://github.com/igorskyflyer/npm-keppo/blob/main/LICENSE).\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 💖 Support\n\n\u003cdiv align=\"center\"\u003e\n  I work hard for every project, including this one and your support means a lot to me!\n  \u003cbr\u003e\n  Consider buying me a coffee. ☕\n  \u003cbr\u003e\n  \u003cbr\u003e\n  \u003ca href=\"https://ko-fi.com/igorskyflyer\" target=\"_blank\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/igorskyflyer/igorskyflyer/main/assets/ko-fi.png\" alt=\"Donate to igorskyflyer\" width=\"180\" height=\"46\"\u003e\u003c/a\u003e\n  \u003cbr\u003e\n  \u003cbr\u003e\n  \u003cem\u003eThank you for supporting my efforts!\u003c/em\u003e 🙏😊\n\u003c/div\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 🧬 Related\n\n[**@igorskyflyer/common-color**](https://www.npmjs.com/package/@igorskyflyer/common-color)\n\n\u003e _🎨 Provides common Color-related TypeScript types. 🌈_\n\n\u003cbr\u003e\n\n[**@igorskyflyer/rawelement**](https://www.npmjs.com/package/@igorskyflyer/rawelement)\n\n\u003e _🐯 A utility that lets you manipulate HTML elements, their attributes and innerHTML as strings, on the go and then render the modified HTML. Very useful in SSG projects. 💤_\n\n\u003cbr\u003e\n\n[**@igorskyflyer/str-is-in**](https://www.npmjs.com/package/@igorskyflyer/str-is-in)\n\n\u003e _🧵 Provides ways of checking whether a String is present in an Array of Strings using custom Comparators. 🔍_\n\n\u003cbr\u003e\n\n[**@igorskyflyer/recursive-readdir**](https://www.npmjs.com/package/@igorskyflyer/recursive-readdir)\n\n\u003e _📖 Provides recursive readdir() and readdirSync() functions. 📁_\n\n\u003cbr\u003e\n\n[**@igorskyflyer/clone**](https://www.npmjs.com/package/@igorskyflyer/clone)\n\n\u003e _🧬 A lightweight JavaScript utility allowing deep copy-by-value of nested objects, arrays and arrays of objects. 🪁_\n\n\u003cbr\u003e\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 👨🏻‍💻 Author\nCreated by **Igor Dimitrijević** ([*@igorskyflyer*](https://github.com/igorskyflyer/)).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figorskyflyer%2Fnpm-keppo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Figorskyflyer%2Fnpm-keppo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figorskyflyer%2Fnpm-keppo/lists"}