From 77c280cf56dfdd6732f7e771c4bd50eb176d9955 Mon Sep 17 00:00:00 2001 From: INeedJobToStartWork Date: Fri, 25 Oct 2024 23:07:42 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=89=20Feat(@betternpm/semver):=20Publi?= =?UTF-8?q?shing=201.0.0-prerelease!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/pre.json | 9 + .husky/pre-commit | 1 + CODE_OF_CONDUCT.md | 2 +- README.md | 4 +- package.json | 7 +- packages/semver/.env.template | 1 + packages/semver/.npmignore | 2 + packages/semver/.npmrc | 3 + packages/semver/LICENSE | 27 + packages/semver/README.md | 415 +++++++ packages/semver/clean-package.config.json | 20 + packages/semver/config/tsuprc/tsup.base.ts | 25 + packages/semver/config/tsuprc/tsup.dev.ts | 8 + packages/semver/config/tsuprc/tsup.prod.ts | 41 + packages/semver/eslint.config.js | 41 + packages/semver/package.json | 68 + packages/semver/prettier.config.mjs | 4 + packages/semver/src/classes/index.ts | 1 + packages/semver/src/classes/semVer.test.ts | 34 + packages/semver/src/classes/semVer.ts | 156 +++ .../semver/src/functions/compare.bench.ts | 14 + packages/semver/src/functions/compare.test.ts | 358 ++++++ packages/semver/src/functions/compare.ts | 238 ++++ .../semver/src/functions/difference.test.ts | 76 ++ packages/semver/src/functions/difference.ts | 60 + .../semver/src/functions/increase.test.ts | 252 ++++ packages/semver/src/functions/increase.ts | 162 +++ packages/semver/src/functions/index.ts | 8 + .../semver/src/functions/minVersion.test.ts | 108 ++ packages/semver/src/functions/minVersion.ts | 99 ++ .../semver/src/functions/parseSemVer.test.ts | 131 ++ packages/semver/src/functions/parseSemVer.ts | 187 +++ .../semver/src/functions/satisfies.test.ts | 353 ++++++ packages/semver/src/functions/satisfies.ts | 125 ++ .../src/functions/simplifyRange.test.ts | 87 ++ .../semver/src/functions/simplifyRange.ts | 63 + .../src/functions/versionValidator.test.ts | 73 ++ .../semver/src/functions/versionValidator.ts | 144 +++ packages/semver/src/index.ts | 2 + packages/semver/src/internals/constants.ts | 46 + packages/semver/src/internals/index.ts | 1 + packages/semver/src/types.ts | 0 packages/semver/src/utils/index.ts | 3 + packages/semver/src/utils/isSet.ts | 5 + packages/semver/src/utils/isX.ts | 5 + packages/semver/src/utils/validation.test.ts | 133 ++ packages/semver/src/utils/validation.ts | 36 + packages/semver/tsconfig.json | 18 + packages/semver/vitest.config.ts | 14 + .../eslint.config.js | 3 +- .../src/functions/name/isScopedPackage.ts | 2 +- .../src/functions/name/nameValidator.ts | 12 +- .../validate-npm-package-name/tsconfig.json | 3 +- pnpm-lock.yaml | 1106 ++++++++++++----- turbo.json | 1 + 55 files changed, 4492 insertions(+), 305 deletions(-) create mode 100644 .changeset/pre.json create mode 100644 packages/semver/.env.template create mode 100644 packages/semver/.npmignore create mode 100644 packages/semver/.npmrc create mode 100644 packages/semver/LICENSE create mode 100644 packages/semver/README.md create mode 100644 packages/semver/clean-package.config.json create mode 100644 packages/semver/config/tsuprc/tsup.base.ts create mode 100644 packages/semver/config/tsuprc/tsup.dev.ts create mode 100644 packages/semver/config/tsuprc/tsup.prod.ts create mode 100644 packages/semver/eslint.config.js create mode 100644 packages/semver/package.json create mode 100644 packages/semver/prettier.config.mjs create mode 100644 packages/semver/src/classes/index.ts create mode 100644 packages/semver/src/classes/semVer.test.ts create mode 100644 packages/semver/src/classes/semVer.ts create mode 100644 packages/semver/src/functions/compare.bench.ts create mode 100644 packages/semver/src/functions/compare.test.ts create mode 100644 packages/semver/src/functions/compare.ts create mode 100644 packages/semver/src/functions/difference.test.ts create mode 100644 packages/semver/src/functions/difference.ts create mode 100644 packages/semver/src/functions/increase.test.ts create mode 100644 packages/semver/src/functions/increase.ts create mode 100644 packages/semver/src/functions/index.ts create mode 100644 packages/semver/src/functions/minVersion.test.ts create mode 100644 packages/semver/src/functions/minVersion.ts create mode 100644 packages/semver/src/functions/parseSemVer.test.ts create mode 100644 packages/semver/src/functions/parseSemVer.ts create mode 100644 packages/semver/src/functions/satisfies.test.ts create mode 100644 packages/semver/src/functions/satisfies.ts create mode 100644 packages/semver/src/functions/simplifyRange.test.ts create mode 100644 packages/semver/src/functions/simplifyRange.ts create mode 100644 packages/semver/src/functions/versionValidator.test.ts create mode 100644 packages/semver/src/functions/versionValidator.ts create mode 100644 packages/semver/src/index.ts create mode 100644 packages/semver/src/internals/constants.ts create mode 100644 packages/semver/src/internals/index.ts create mode 100644 packages/semver/src/types.ts create mode 100644 packages/semver/src/utils/index.ts create mode 100644 packages/semver/src/utils/isSet.ts create mode 100644 packages/semver/src/utils/isX.ts create mode 100644 packages/semver/src/utils/validation.test.ts create mode 100644 packages/semver/src/utils/validation.ts create mode 100644 packages/semver/tsconfig.json create mode 100644 packages/semver/vitest.config.ts diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 0000000..57d6ae2 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,9 @@ +{ + "mode": "pre", + "tag": "1.0.0", + "initialVersions": { + "@betternpm/semver": "1.0.0-prerelease", + "@betternpm/validate-npm-package-name": "1.0.0" + }, + "changesets": [] +} diff --git a/.husky/pre-commit b/.husky/pre-commit index e69de29..8b13789 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -0,0 +1 @@ + diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 56315cb..0f27543 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -15,7 +15,7 @@ Examples of behavior that contributes to creating a positive environment include: - Using welcoming and inclusive language -- Being respectful of differing viewpoints and experiences +- Being respectful of differenceering viewpoints and experiences - Gracefully accepting constructive criticism - Focusing on what is best for the community - Showing empathy towards other community members diff --git a/README.md b/README.md index 6e00ad9..ae7599f 100644 --- a/README.md +++ b/README.md @@ -63,11 +63,11 @@ About packages: | πŸ“¦ Package Management | πŸ”§ Normalize package metadata | [normalize-package-data](https://www.npmjs.com/package/normalize-package-data) | [@betternpm/normalize-package-data](https://www.npmjs.com/package/@betternpm/normalize-package-data) | πŸ’€ | | πŸ“¦ Package Management | πŸ” Validates NPM package names | [validate-npm-package-name](https://www.npmjs.com/package/validate-npm-package-name) | [@betternpm/validate-npm-package-name](https://www.npmjs.com/package/@betternpm/validate-npm-package-name) | πŸ’€ | | 🌐 Registry and API Interaction | πŸ›οΈ NPM organization management | [libnpmorg](https://www.npmjs.com/package/libnpmorg) | [@betternpm/libnpmorg](https://www.npmjs.com/package/@betternpm/libnpmorg) | πŸ’€ | -| 🌐 Registry and API Interaction | πŸ” Compare NPM packages | [libnpmdiff](https://www.npmjs.com/package/libnpmdiff) | [@betternpm/libnpmdiff](https://www.npmjs.com/package/@betternpm/libnpmdiff) | πŸ’€ | +| 🌐 Registry and API Interaction | πŸ” Compare NPM packages | [libnpmdifference](https://www.npmjs.com/package/libnpmdifference) | [@betternpm/libnpmdifference](https://www.npmjs.com/package/@betternpm/libnpmdifference) | πŸ’€ | | 🌐 Registry and API Interaction | πŸ•΅οΈ Search NPM packages | [libnpmsearch](https://www.npmjs.com/package/libnpmsearch) | [@betternpm/libnpmsearch](https://www.npmjs.com/package/@betternpm/libnpmsearch) | πŸ’€ | | 🌐 Registry and API Interaction | πŸš€ Publish NPM packages | [libnpmpublish](https://www.npmjs.com/package/libnpmpublish) | [@betternpm/libnpmpublish](https://www.npmjs.com/package/@betternpm/libnpmpublish) | πŸ’€ | | 🌐 Registry and API Interaction | πŸ”„ Interact with npm registry API | [npm-registry-fetch](https://www.npmjs.com/package/npm-registry-fetch) | [@betternpm/npm-registry-fetch](https://www.npmjs.com/package/@betternpm/npm-registry-fetch) | πŸ’€ | -| πŸ”’ Version Management | πŸ“Š Semantic versioning utility | [semver](https://www.npmjs.com/package/semver) | [@betternpm/semver](https://www.npmjs.com/package/@betternpm/semver) | πŸ’€ | +| πŸ”’ Version Management | πŸ“Š Semantic versioning utility | [semver](https://www.npmjs.com/package/semver) | [@betternpm/semver](https://www.npmjs.com/package/@betternpm/semver) | πŸ› οΈ | | πŸ”’ Version Management | 🏷️ NPM package versioning | [libnpmversion](https://www.npmjs.com/package/libnpmversion) | [@betternpm/libnpmversion](https://www.npmjs.com/package/@betternpm/libnpmversion) | πŸ’€ | | πŸ” Security and Access Control | πŸ”’ Subresource Integrity | [ssri](https://www.npmjs.com/package/ssri) | [@betternpm/ssri](https://www.npmjs.com/package/@betternpm/ssri) | πŸ’€ | | πŸ” Security and Access Control | πŸ”‘ NPM package access management | [libnpmaccess](https://www.npmjs.com/package/libnpmaccess) | [@betternpm/libnpmaccess](https://www.npmjs.com/package/@betternpm/libnpmaccess) | πŸ’€ | diff --git a/package.json b/package.json index 580038e..443a29c 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "lint:fix": "turbo lint:fix", "lint:test": "turbo lint:fix", "format": "turbo format", + "bench": "turbo bench", "clean": "turbo clean", "npm:prepack": "turbo npm:prepack", "npm:postpack": "turbo npm:postpack", @@ -33,12 +34,12 @@ "test": "turbo test" }, "devDependencies": { - "@changesets/cli": "^2.27.7", + "@changesets/cli": "^2.27.8", "@types/lint-staged": "~13.3.0", "commitsmile": "^0.6.1", "globals": "^15.9.0", - "husky": "^9.1.5", - "lint-staged": "^15.2.9", + "husky": "^9.1.6", + "lint-staged": "^15.2.10", "turbo": "latest" }, "engines": { diff --git a/packages/semver/.env.template b/packages/semver/.env.template new file mode 100644 index 0000000..b8ac4a2 --- /dev/null +++ b/packages/semver/.env.template @@ -0,0 +1 @@ +ESLINT_USE_FLAT_CONFIG = true diff --git a/packages/semver/.npmignore b/packages/semver/.npmignore new file mode 100644 index 0000000..a720c6b --- /dev/null +++ b/packages/semver/.npmignore @@ -0,0 +1,2 @@ +.npmignore +.npmrc \ No newline at end of file diff --git a/packages/semver/.npmrc b/packages/semver/.npmrc new file mode 100644 index 0000000..7494f72 --- /dev/null +++ b/packages/semver/.npmrc @@ -0,0 +1,3 @@ +//registry.npmjs.org/:_authToken=${NPM_TOKEN} +registry=https://registry.npmjs.org/ +always-auth=true \ No newline at end of file diff --git a/packages/semver/LICENSE b/packages/semver/LICENSE new file mode 100644 index 0000000..328fb9c --- /dev/null +++ b/packages/semver/LICENSE @@ -0,0 +1,27 @@ +/* + Portions of this code are derived from validate-npm-package-name, + Copyright (c) 2015, npm, Inc + Licensed under the ISC License. See LICENSE file in the project root for full license information. +*/ + +MIT License + +Copyright (c) 2024 INeedJobToStartWork + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/semver/README.md b/packages/semver/README.md new file mode 100644 index 0000000..1a48389 --- /dev/null +++ b/packages/semver/README.md @@ -0,0 +1,415 @@ +![image](https://github.com/user-attachments/assets/985f8c86-4dad-400f-a5fa-16f57d0546d8) + +

Semver versioning handler

+

semver

+

This package exports version utils functions.

+ + +
+ +# πŸ“œ List of Contest + +- [πŸ“œ List of Contest](#-list-of-contest) + - [Install](#install) + - [TLDR (Only Most Important!)](#tldr-only-most-important) + - [Functions](#functions) + - [Classes](#classes) + - [Types](#types) + - [Variables](#variables) + - [Table of Compatibility](#table-of-compatibility) + - [Status](#status) + - [Table](#table) + - [Classes](#classes-1) + - [SemVer](#semver) + - [Functions](#functions-1) + - [parseSemVer](#parsesemver) + - [compareSemver](#comparesemver) + - [compareMinorMajorPatch](#compareminormajorpatch) + - [comparePrerelease](#compareprerelease) + - [compareBuild](#comparebuild) + - [satisfies](#satisfies) + - [increase](#increase) + - [difference](#difference) + - [minVersion](#minversion) + - [simplifyRange](#simplifyrange) + - [Types](#types-1) + - [TReleases](#treleases) + - [Variables](#variables-1) + - [RELEASE\_TYPES](#release_types) + +## Install + +NPM + +```bash copy +npm install @betternpm/semver +``` + +PNPM + +```bash copy +pnpm add @betternpm/semver +``` + +Yarn + +```bash copy +yarn add @betternpm/semver +``` + +## TLDR (Only Most Important!) + +### Functions + +| Name | Description | +| ------------------------------- | --------------------------------------------------------------------------------------- | +| [parseSemVer](#parsesemver) | Parse and validate into semver object | +| [compareSemver](#comparesemver) | Compare versions and return result ` 1 \| 0 \| -1` | +| [satisfies](#satisfies) | Check that version pass range ex `>=1.0.0 \|\| 0.5.0` | +| [increase](#increase) | Increase semver `major/minor/patch/prerelease/buildmetadata/premajor/preminor/premajor` | +| [difference](#difference) | Show most important differenceerence between versions | +| [minVersion](#) | Show minimum version which pass range. | +| [simplifyRange](#simplifyRange) | Simplify Range for inputed versions | + +### Classes + +| Name | Description | +| ----------------- | ----------------------------------------------- | +| [SemVer](#semver) | Represents a class SemVer version with methods. | + +### Types + +| Name | Description | +| ----------------------- | --------------------------- | +| [TReleases](#treleases) | Represents a release types. | + +### Variables + +| Name | Description | +| ------------------------------- | ----------------------------------- | +| [RELEASE_TYPES](#release_types) | Represents a release type as Array. | + +## Table of Compatibility + +Table of compatibility of functionalities with the official list of exports from the npm package `semver` with day of +commit. + +> [!IMPORTANT] +> There you not gonna find all `@betternpm/semver` package functions! + +### Status + +| Emoji | Meaning | +| ----- | ----------------------------------------------------- | +| βœ… | Completed | +| ⏸️ | Paused | +| 🟧 | exist/you can use differenceerent function / no alias | +| ❌ | Aborted | +| πŸ› οΈ | In Progress | +| πŸ’€ | Not Yet Started | +| ℹ️ | Additional Comment | + +### Table + +| Export | Progress Status | +| ------------------- | ------------------------------------------------------------------------ | +| parse | βœ…πŸŸ§ [parseSemVer](#parsesemver) | +| valid | βœ…πŸŸ§ [parseSemVer](#parsesemver) | +| clean | 🟧 [SemVer](#semver).format | +| inc | 🟧 [increase](#increase) | +| difference | βœ… | +| major | ❌🟧 [parseSemVer](#parsesemver) | +| minor | ❌🟧 [parseSemVer](#parsesemver) | +| patch | ❌🟧 [parseSemVer](#parsesemver) | +| prerelease | ❌🟧 [parseSemVer](#parsesemver) | +| compare | βœ… | +| rcompare | ❌🟧 [compareSemver](#comparesemver)) | +| compareLoose | ❌🟧 [compareSemver](#comparesemver)) | +| compareBuild | βœ… | +| sort | ❌ ℹ️ You can do it with sort algo using [compareSemver](#comparesemver) | +| rsort | ❌ | +| gt | ❌🟧 [compareSemver](#comparesemver) | +| lt | ❌🟧 [compareSemver](#comparesemver) | +| eq | ❌🟧 [compareSemver](#comparesemver) | +| neq | ❌🟧 [compareSemver](#comparesemver) | +| gte | ❌🟧 [compareSemver](#comparesemver) | +| lte | ❌🟧 [compareSemver](#comparesemver) | +| cmp | ❌🟧 [compareSemver](#comparesemver) | +| coerce | ❌🟧 [parseSemVer](#parsesemver) | +| Comparator | ❌ | +| Range | ❌ | +| satisfies | βœ… | +| toComparators | ❌ | +| maxSatisfying | βŒβ„ΉοΈ You can do this with loop and `satisfies` | +| minSatisfying | βŒβ„ΉοΈ You can do this with loop and `satisfies` | +| minVersion | βœ… | +| validRange | ❌🟧 [parseSemVer](#parsesemver) with rangeMode at options | +| outside | ❌🟧 [satisfies](#satisfies) | +| gtr | ❌🟧 [compareSemver](#comparesemver) | +| ltr | ❌🟧 [compareSemver](#comparesemver) | +| intersects | ❌🟧 [satisfies](#satisfies) | +| simplifyRange | βœ… | +| subset | βŒβ„ΉοΈ (Didn't see need of this, maybe add in future) | +| SemVer | βœ… | +| re | βŒβ„ΉοΈ (Didn't see need of this) | +| src | βŒβ„ΉοΈ (Didn't see need of this) | +| tokens | βŒβ„ΉοΈ (Didn't see need of this) | +| SEMVER_SPEC_VERSION | ❌ | +| RELEASE_TYPES | βœ… | +| compareIdentifiers | ❌🟧 [compareSemver](#comparesemver) | +| rcompareIdentifiers | ❌🟧 [compareSemver](#comparesemver) | + +## Classes + +### SemVer + +Class creating SemVer object which has own methods. + +**Links:**
+[[πŸ“„File]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/classes/semVer.ts) +[[πŸ’TESTS]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/classes/semVer.test.ts) + +[Scroll to List of Contest](#-list-of-contest) + +## Functions + +### parseSemVer + +Parses a semantic version string or range (options). + +```typescript +import { parseSemVer } from "@betternpm/semver"; + +const version = parseSemVer("1.2.3-prerelease.0+20241025"); +console.log(version.major); // 1 +console.log(version.minor); // 2 +console.log(version.patch); // 3 +console.log(version.prerelease); // ["prerelease",0] +console.log(version.buildmetadata); // [20241025] +console.log(version.version()); // "1.2.3-prerelease.0+20241025" +``` + +**Links:**
+[[πŸ“„File]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/parseSemVer.ts) +[[πŸ’TESTS]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/parseSemVer.test.ts) + +[Scroll to List of Contest](#-list-of-contest) + +### compareSemver + +Compare A to B in full scope. + +```typescript +import { compareSemver } from "@betternpm/semver"; + +console.log(compareSemver("1.3.0", "1.2.3")); // 1 - because A is bigger than B +console.log(compareSemver("1.3.0", "1.3.0")); // 0 - because A is same as B +console.log(compareSemver("1.2.3", "1.3.0")); // -1 - because A is smaller than B +``` + +**Links:**
+[[πŸ“„File]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/compare.ts) +[[πŸ’TESTS]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/compare.test.ts) + +[Scroll to List of Contest](#-list-of-contest) + +#### compareMinorMajorPatch + +Compare A to B but **ONLY** in Major/Minor/Patch scope. + +```typescript +import { compareMinorMajorPatch } from "@betternpm/semver"; + +console.log(compareMinorMajorPatch("1.3.0", "1.2.3")); // 1 - because A is bigger than B +console.log(compareMinorMajorPatch("1.3.0-alpha", "1.3.0")); // 0 - because A is same as B (We care only about MMP) +console.log(compareMinorMajorPatch("1.2.3", "1.3.0")); // -1 - because A is smaller than B +``` + +**Links:**
+[[πŸ“„File]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/compare.ts) +[[πŸ’TESTS]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/compare.test.ts) + +[Scroll to List of Contest](#-list-of-contest) + +#### comparePrerelease + +Compare A to B but **ONLY** in prerelease scope. + +```typescript +import { comparePrerelease } from "@betternpm/semver"; +// am > alpha.1 > alpha.0 > alpha +console.log(comparePrerelease("1.3.0-alpha.1", "1.2.3-alpha.0")); // 1 - because A is bigger than B +console.log(comparePrerelease("1.3.0-alpha", "1.2.0-alpha")); // 0 - because A is same as B (We care only about MMP) +console.log(comparePrerelease("1.3.0-alpha", "1.2.0")); // -1 - because A is smaller than B (no prereleases > prereleases) + +console.log(comparePrerelease("1.3.0-alpha", "1.2.0-am")); // -1 - In this case just comparing them to first differenceerence v1[i] > v2[i]. +console.log(comparePrerelease("1.3.0-alpha", "1.2.0-alphaa")); // -1 - Same as above but ends at last element in v1 or v2 (longer one). +``` + +**Links:**
+[[πŸ“„File]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/compare.ts) +[[πŸ’TESTS]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/compare.test.ts) + +[Scroll to List of Contest](#-list-of-contest) + +#### compareBuild + +Compare A to B but **ONLY** in buildmetadata. + +```typescript +import { compareBuild } from "@betternpm/semver"; + +console.log(compareBuild("1.3.0+124", "1.2.3+123")); // 1 - because A is bigger than B +console.log(compareBuild("1.3.0+123", "1.2.0+123")); // 0 - because A is same as B (We care only about MMP) +console.log(compareBuild("1.3.0+1.2.2", "1.2.0+123")); // -1 - because A is smaller than B (no prereleases > prerelease) +console.log(compareBuild("1.3.0", "1.2.0+123")); // -1 - because A is smaller than B (no prereleases > prerelease) +console.log(compareBuild("1.3.0+a", "1.2.0+b")); // -1 In this case just comparing them to first differenceerence v1[i] > v2[i]. +console.log(compareBuild("1.3.0+a", "1.2.0+aa")); // -1 - Same as above but comparing to last element in v1 or v2 (longer one). +``` + +**Links:**
+[[πŸ“„File]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/compare.ts) +[[πŸ’TESTS]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/compare.test.ts) + +[Scroll to List of Contest](#-list-of-contest) + +### satisfies + +Checks that version pass range ex `>=1.0.0 || 0.5.0` + +```typescript +import { satisfies } from "@betternpm/semver"; + +console.log(satisfies("1.2.3", ">=1.0.0 || 0.5.0")); // true - Must be equal or higher than 1.0.0 or equal 0.5.0 +console.log(satisfies("0.5.0", ">=1.0.0 || 0.5.0")); // true - Must be equal or higher than 1.0.0 or equal 0.5.0 +console.log(satisfies("0.4.0", ">=1.0.0 || 0.5.0")); // false - Must be equal or higher than 1.0.0 or equal 0.5.0 +console.log(satisfies("0.1.3", ">2.0.0")); // false - Must be higher than 2.0.0 +``` + +**Links:**
+[[πŸ“„File]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/satisfies.ts) +[[πŸ’TESTS]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/satisfies.test.ts) + +[Scroll to List of Contest](#-list-of-contest) + +### increase + +Increase semver `major/minor/patch/prerelease/buildmetadata/premajor/preminor/premajor + +> [!IMPORTANT] +> At `prerelease` and `buildmetadata` always increase last found number. + +```typescript +import { increase } from "@betternpm/semver"; + +console.log(increase("1.2.3", "major", "string")); // 2.0.0 +console.log(increase("1.2.3", "minor", "string")); // 1.3.0 +console.log(increase("1.2.3", "patch", "string")); // 1.2.4 + +console.log(increase("1.2.3", "prerelease", "string")); //1.2.3-0 +console.log(increase("1.2.3-0", "prerelease", "string")); //1.2.3-1 +console.log(increase("1.2.3", "prerelease", "string", { value: "alpha" })); // 1.2.3-alpha +console.log(increase("1.2.3-alpha", "prerelease", "string")); // 1.2.3-alpha.0 + +console.log(increase("1.2.3", "buildmetadata", "string")); //1.2.3+0 +console.log(increase("1.2.3+0", "buildmetadata", "string")); //1.2.3+1 +console.log(increase("1.2.3", "buildmetadata", "string", { value: "build" })); // 1.2.3+build +console.log(increase("1.2.3+build", "buildmetadata", "string")); // 1.2.3+build.0 + +console.log(increase("1.2.3", "premajor", "string")); // 2.0.0-0 +console.log(increase("1.2.3", "preminor", "string")); // 1.3.0-0 +console.log(increase("1.2.3", "premajor", "string")); // 1.2.4-0 +// etc... +``` + +**Links:**
+[[πŸ“„File]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/increase.ts) +[[πŸ’TESTS]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/increase.test.ts) + +[Scroll to List of Contest](#-list-of-contest) + +### difference + +Show most important differenceerence between versions + +```ts +import { difference } from "@betternpm/semver"; + +console.log(difference("1.0.0", "2.5.0")); // "major" +console.log(difference("1.1.0", "1.2.0")); // "minor" +console.log(difference("1.1.1", "1.1.2")); // "patch" +console.log(difference("0.0.0", "0.0.0")); // undefined + +console.log(difference("1.0.0", "2.0.0-prerelease")); // "premajor" +console.log(difference("1.0.0", "1.1.0-prerelease")); // "preminor" +console.log(difference("1.0.0", "1.0.1-prerelease")); // "prepatch" +console.log(difference("1.0.0-alpha", "1.0.0-beta")); // "prerelease" +``` + +**Links:**
+[[πŸ“„File]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/difference.ts) +[[πŸ’TESTS]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/difference.test.ts) + +[Scroll to List of Contest](#-list-of-contest) + +### minVersion + +Show minimum version which pass range. + +```ts +import { minVersion } from "@betternpm/semver"; + +console.log(minVersion(">=1.0.0 || 0.5.0")); // 0.5.0 +console.log(minVersion(">=1.0.0")); // 1.0.0 +console.log(minVersion("<=1.0.0")); // 0.0.0 +console.log(minVersion(">2.0.0")); // 2.0.1 +``` + +**Links:**
+[[πŸ“„File]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/minVersion.ts) +[[πŸ’TESTS]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/minVersion.test.ts) + +[Scroll to List of Contest](#-list-of-contest) + +### simplifyRange + +Simplify Range for inputed versions + +```ts +import { simplifyRange } from "@betternpm/semver"; + +console.log(simplifyRange(["0.0.0", "1.0.0", "0.5.0", "2.0.1"], ">=1.0.0 || 0.5.0")); // >=0.5.0 +console.log(simplifyRange(["0.0.0", "1.0.0", "0.5.0", "2.0.1"], ">=1.0.0")); // >=1.0.0 +console.log(simplifyRange(["0.0.0", "1.0.0", "0.5.0", "2.0.1"], "<=1.0.0")); // <=1.0.0 +console.log(simplifyRange(["2.0.1"], ">2.0.0")); // * +``` + +**Links:**
+[[πŸ“„File]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/simplifyRange.ts) +[[πŸ’TESTS]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/functions/simplifyRange.test.ts) + +[Scroll to List of Contest](#-list-of-contest) + +## Types + +### TReleases + +type with every possible release (from variable [RELEASE_TYPES](###RELEASE_TYPES)) + +**Links:**
+[[πŸ“„File]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/internals/constants.ts) +[[πŸ’TESTS]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/internals/constants.test.ts) + +[Scroll to List of Contest](#-list-of-contest) + +## Variables + +### RELEASE_TYPES + +Array with every possible + +**Links:**
+[[πŸ“„File]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/internals/constants.ts) +[[πŸ’TESTS]](https://github.com/INeedJobToStartWork/BetterNPM/tree/main/packages/semver/src/internals/constants.test.ts) + +[Scroll to List of Contest](#-list-of-contest) diff --git a/packages/semver/clean-package.config.json b/packages/semver/clean-package.config.json new file mode 100644 index 0000000..5843a4b --- /dev/null +++ b/packages/semver/clean-package.config.json @@ -0,0 +1,20 @@ +{ + "indent": 4, + "remove": ["devDependencies", "lint-staged", "bin"], + "replace": { + "type": "commonjs", + "scripts": { + "npm:postpack": "clean-package restore" + }, + "exports": { + ".": { + "types": { + "import": "./index.d.mts", + "require": "./index.d.ts" + }, + "import": "./index.mjs", + "require": "./index.js" + } + } + } +} diff --git a/packages/semver/config/tsuprc/tsup.base.ts b/packages/semver/config/tsuprc/tsup.base.ts new file mode 100644 index 0000000..18ddfdd --- /dev/null +++ b/packages/semver/config/tsuprc/tsup.base.ts @@ -0,0 +1,25 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + target: "es2022", + format: ["esm"], + clean: true, + splitting: false, + platform: "node", + keepNames: true, + + dts: true, + tsconfig: "./tsconfig.json", + + banner: ({ format }) => { + if (format === "esm") { + const banner = ` +import { createRequire } from "node:module"; +const require = createRequire(import.meta.url); + `; + + return { js: banner }; + } + } +}); diff --git a/packages/semver/config/tsuprc/tsup.dev.ts b/packages/semver/config/tsuprc/tsup.dev.ts new file mode 100644 index 0000000..0ccbdd5 --- /dev/null +++ b/packages/semver/config/tsuprc/tsup.dev.ts @@ -0,0 +1,8 @@ +import config from "./tsup.base"; +import { defineConfig } from "tsup"; + +export default defineConfig({ + ...config, + outDir: "lib", + watch: ["src"] +}); diff --git a/packages/semver/config/tsuprc/tsup.prod.ts b/packages/semver/config/tsuprc/tsup.prod.ts new file mode 100644 index 0000000..093473f --- /dev/null +++ b/packages/semver/config/tsuprc/tsup.prod.ts @@ -0,0 +1,41 @@ +import config from "./tsup.base"; +import { copy } from "esbuild-plugin-copy"; +import noInternalExportsPlugin from "@esplugins/no-internal-exports"; + +import { defineConfig } from "tsup"; + +export default defineConfig({ + ...config, + + bundle: true, + splitting: true, + minify: true, + shims: true, + sourcemap: true, + + minifyIdentifiers: true, + minifySyntax: true, + minifyWhitespace: true, + + metafile: false, + treeshake: true, + external: ["oh-my-error"], + + outDir: "dist", + + format: ["esm", "cjs"], + + esbuildPlugins: [ + copy({ + assets: [ + { from: "./package.json", to: "./package.json" }, + { from: "./.npmrc", to: "./.npmrc" }, + { from: "./.npmignore", to: "./.npmignore" }, + { from: "./README.md", to: "./README.md" }, + { from: "./LICENSE", to: "./" } + ] + }), + noInternalExportsPlugin + ] + // external: ['eslint'], +}); diff --git a/packages/semver/eslint.config.js b/packages/semver/eslint.config.js new file mode 100644 index 0000000..f7c9eaf --- /dev/null +++ b/packages/semver/eslint.config.js @@ -0,0 +1,41 @@ +import ineedj from "@ineedj/eslintrc"; + +export default ineedj({ + formatters: { + json: true, + stylistic: false, + stylisticJSX: false, + stylisticTS: false, + perfectionistSorters: false + }, + modifiers: { + commands: true + }, + syntax: { + mdx: true, + vitest: true, + eslint: true, + jsx: false, + next: false, + node: true, + react: false, + storybook: false, + tailwindcss: false, + typescript: true, + toml: true, + yaml: true, + turbo: false, + ignoreGlobalFiles: { + gitIgnore: true, + basicIgnores: true + } + } +}).removeRules( + "@EslintSecurity/detect-object-injection", + "@typescript-eslint/no-throw-literal", + "@EslintImports/namespace", + "@EslintPii/no-phone-number", + "@typescript-eslint/explicit-module-boundary-types" +); + +// export default []; diff --git a/packages/semver/package.json b/packages/semver/package.json new file mode 100644 index 0000000..c5d4fde --- /dev/null +++ b/packages/semver/package.json @@ -0,0 +1,68 @@ +{ + "name": "@betternpm/semver", + "version": "1.0.0-prerelease", + "description": "Rewritten semver by @betternpm", + "keywords": [ + "semver", + "betternpm", + "package", + "version", + "validation" + ], + "homepage": "https://github.com/INeedJobToStartWork/BetterNPM", + "bugs": "https://github.com/INeedJobToStartWork/BetterNPM/issues/new/choose", + "repository": { + "type": "git", + "url": "git+https://github.com/INeedJobToStartWork/BetterNPM", + "directory": "packages/semver" + }, + "license": "MIT", + "author": "ineedjobtostartwork", + "type": "module", + "main": "index.js", + "scripts": { + "bench": "vitest bench", + "build": "pnpm tsup --config ./config/tsuprc/tsup.prod.ts ", + "build:npm": "pnpm npm:prepack && pnpm tsup --config ./config/tsuprc/tsup.prod.ts && pnpm npm:postpack", + "dev": "pnpm tsup --config ./config/tsuprc/tsup.dev.ts", + "format": "pnpm prettier . --write && pnpm prettier . --check", + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "npm:postpack": "clean-package restore", + "npm:prepack": "clean-package", + "prepublishOnly": "pnpm build:npm", + "test": "vitest" + }, + "lint-staged": { + "*": [ + "pnpm format --", + "pnpm lint:fix --", + "pnpm lint --" + ] + }, + "dependencies": { + "oh-my-error": "2.0.0-prerelease.0" + }, + "devDependencies": { + "@esplugins/no-internal-exports": "1.0.0-prerelease.1", + "@ineedj/eslintrc": "~1.2.2", + "@ineedj/prettierrc": "^2.0.0", + "@ineedj/tsconfig": "^1.0.0", + "@types/eslint": "~8.56.12", + "@types/node": "^22.2.0", + "@types/safe-regex": "^1.1.6", + "clean-package": "^2.2.0", + "esbuild-plugin-copy": "^2.1.1", + "eslint": "~8.57.0", + "prettier": "^3.3.3", + "tsup": "^8.1.0", + "typescript": "^5.6.2", + "vitest": "^2.0.5" + }, + "publishConfig": { + "access": "public", + "directory": "dist", + "provenance": true, + "tag": "latest" + } +} diff --git a/packages/semver/prettier.config.mjs b/packages/semver/prettier.config.mjs new file mode 100644 index 0000000..db83184 --- /dev/null +++ b/packages/semver/prettier.config.mjs @@ -0,0 +1,4 @@ +import prettierConfig from "@ineedj/prettierrc"; +export default { + ...prettierConfig +}; diff --git a/packages/semver/src/classes/index.ts b/packages/semver/src/classes/index.ts new file mode 100644 index 0000000..ad2fc3a --- /dev/null +++ b/packages/semver/src/classes/index.ts @@ -0,0 +1 @@ +export * from "./semVer"; diff --git a/packages/semver/src/classes/semVer.test.ts b/packages/semver/src/classes/semVer.test.ts new file mode 100644 index 0000000..b0d8f46 --- /dev/null +++ b/packages/semver/src/classes/semVer.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, test } from "vitest"; +import SemVer from "./semVer"; + +describe("Version Validators", () => { + describe("[FUNCTION] versionPreValidator", () => { + // describe("[ERROR]", () => {} + describe("[PASS]", () => { + test("String as Input", () => { + const text = new SemVer("1.2.3"); + expect(text).instanceOf(SemVer); + }); + test("SemVer as Input", () => { + const vers1 = new SemVer("1.2.3"); + const vers2 = new SemVer(vers1); + expect(vers2).instanceOf(SemVer); + }); + test("SemVer as Input", () => { + const vers1 = new SemVer("1.2.3"); + const vers2 = new SemVer(vers1); + expect(vers2).instanceOf(SemVer); + }); + }); + describe("[SCENARIOS]", () => { + test("Format() check", () => { + const text = new SemVer("1.2.3"); + const expectedOutput = "v1.2.3"; + expect(text).instanceOf(SemVer); + + expect(text.format(({ major, minor, patch }) => `v${major}.${minor}.${patch}`)).toEqual(expectedOutput); + expect(text.versionFormat).toEqual(expectedOutput); + }); + }); + }); +}); diff --git a/packages/semver/src/classes/semVer.ts b/packages/semver/src/classes/semVer.ts new file mode 100644 index 0000000..6b54be7 --- /dev/null +++ b/packages/semver/src/classes/semVer.ts @@ -0,0 +1,156 @@ +/* eslint-disable @EslintImports/no-deprecated */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +import type { TOptionsSemVer } from "@/functions"; +import { + compareSemver, + compareBuild, + comparePrerelease, + compareMinorMajorPatch, + OptionsSemVerDefaults, + parseSemVer, + increase +} from "@/functions"; +import { myError, myErrorWrapper } from "oh-my-error"; + +export default class SemVer { + public options; + public raw: string; + public version: ReturnType>["version"]; + public versionFormat: string; + public major: ReturnType>["major"]; + public minor: ReturnType>["minor"]; + public patch: ReturnType>["patch"]; + public prerelease: ReturnType>["prerelease"]; + public buildmetadata: ReturnType>["buildmetadata"]; + + constructor(inputVersion: Parameters[0], options: TOptionsSemVer = OptionsSemVerDefaults) { + const isSemVer = inputVersion instanceof SemVer; + const mergedOptions: TOptionsSemVer = { ...OptionsSemVerDefaults, ...options, rangeMode: false }; + + this.options = mergedOptions; + // eslint-disable-next-line no-nested-ternary, @EslintUnicorn/no-nested-ternary + this.raw = isSemVer ? inputVersion.raw : typeof inputVersion == "string" ? inputVersion : inputVersion.version(); + // eslint-disable-next-line no-nested-ternary + this.versionFormat = isSemVer + ? inputVersion.versionFormat + : // eslint-disable-next-line @EslintUnicorn/no-nested-ternary + typeof inputVersion == "string" + ? inputVersion + : inputVersion.version(); + + // SPLITTING + // const { patch, buildmetadata, major, minor, prerelease, version } = isSemVer + // ? inputVersion + // : parseSemVer(this.raw, { rangeMode: false }); + + const { patch, buildmetadata, major, minor, prerelease, version } = isSemVer + ? inputVersion + : (parseSemVer(this.raw, mergedOptions) as ReturnType>); //TODO:fix + this.version = version; + this.major = major; + this.minor = minor; + this.patch = patch; + this.prerelease = prerelease; + this.buildmetadata = buildmetadata; + } + + /** + * Set and return `versionFormat` property of class. + * + * @param cb - Function to format which get `this` from class + * @returns string + */ + format(cb: (arg1: this) => string): string { + const [data, isError] = myErrorWrapper(cb)(this); + if (isError) { + throw myError({ + code: "CALLBACK_ERROR", + name: "Callback throw Error", + hint: { dev: "Callback Function throws error.", user: "" }, + message: {} + }); + } + this.versionFormat = data; + return this.versionFormat; + } + + /** + * Compares the release portion of two versions. + * + * @returns + * - `0` if `this` == `other` + * - `1` if `this` is greater + * - `-1` if `other` is greater. + */ + compare( + other: Parameters[1], + options: Parameters[2] = this.options + ): -1 | 0 | 1 { + const mergedOptions: TOptionsSemVer = { ...OptionsSemVerDefaults, ...options }; + return compareSemver(this.version(), other, mergedOptions); + } + /** + * Compares the release portion of two versions. + * + * @returns + * - `0` if `this` == `other` + * - `1` if `this` is greater + * - `-1` if `other` is greater. + */ + compareMinorMajorPatch(other: Parameters[1], options = this.options): -1 | 0 | 1 { + const mergedOptions: TOptionsSemVer = { ...OptionsSemVerDefaults, ...options }; + return compareMinorMajorPatch(this.version(), other, mergedOptions); + } + /** + * Compares the prerelease portion of two versions. + * + * @returns + * - `0` if `this` == `other` + * - `1` if `this` is greater + * - `-1` if `other` is greater. + */ + // comparePre(other: string | SemVer): 1 | 0 | -1 {} + comparePrerelease(other: Parameters[1], options = this.options): -1 | 0 | 1 { + const mergedOptions: TOptionsSemVer = { ...OptionsSemVerDefaults, ...options }; + return comparePrerelease(this.version(), other, mergedOptions); + } + /** + * Compares the build identifier of two versions. + * + * @returns + * - `0` if `this` == `other` + * - `1` if `this` is greater + * - `-1` if `other` is greater. + */ + compareBuild(other: Parameters[1], options = this.options): -1 | 0 | 1 { + const mergedOptions: TOptionsSemVer = { ...OptionsSemVerDefaults, ...options }; + return compareBuild(this.version(), other, mergedOptions); + } + + /** + * Increases the version number of a semantic version string. + * + * @example + * ``` + * // Increase major version for "1.2.3" + * increase("major", "string") // Returns "2.0.0" + * + * // Increase minor version with custom prerelease for "1.2.3" + * increase("preminor", "string", { value: "alpha" }) // Returns "1.3.0-alpha" + * ``` + */ + increase(update: Parameters[1], options: Parameters[3] = OptionsSemVerDefaults) { + const result = increase(this.version(), update, "SemVer", options) as SemVer; + const { version, prerelease, patch, raw, minor, major, buildmetadata } = result; + + this.version = version; + this.prerelease = prerelease; + this.patch = patch; + this.raw = raw; + this.minor = minor; + this.major = major; + this.buildmetadata = buildmetadata; + } +} + +export { SemVer }; diff --git a/packages/semver/src/functions/compare.bench.ts b/packages/semver/src/functions/compare.bench.ts new file mode 100644 index 0000000..5e534ca --- /dev/null +++ b/packages/semver/src/functions/compare.bench.ts @@ -0,0 +1,14 @@ +import { bench, describe } from "vitest"; +import compareSemver, { compareMinorMajorPatch } from "./compare"; + +describe("BenchmarkTEST", () => { + bench("tescik predkosci2", () => { + compareSemver("1.2.3", "1.2.3"); + }); + bench("tescik predkosci5", () => { + compareSemver("1.2.3", "1.2.3", { compare: "majorMinorPatch" }); + }); + bench("tescik predkosci", () => { + compareMinorMajorPatch("1.2.3", "1.2.3"); + }); +}); diff --git a/packages/semver/src/functions/compare.test.ts b/packages/semver/src/functions/compare.test.ts new file mode 100644 index 0000000..5c9a665 --- /dev/null +++ b/packages/semver/src/functions/compare.test.ts @@ -0,0 +1,358 @@ +/* eslint-disable @EslintSonar/no-duplicate-string */ +import { describe, expect, it } from "vitest"; +import compareSemver, { compareBuild, compareMinorMajorPatch, comparePrerelease } from "./compare"; +import { myErrorWrapper } from "oh-my-error"; + +describe("SemVer Comparison Functions", () => { + describe("[FUNCTION] compareMinorMajorPatch", () => { + describe("[SCENARIOS]", () => { + it("Return 0 - Equal Versions", () => { + expect(compareMinorMajorPatch("1.2.3", "1.2.3")).toBe(0); + }); + it("Return 1 - First version is greater", () => { + expect(compareMinorMajorPatch("2.0.0", "1.9.9")).toBe(1); + expect(compareMinorMajorPatch("1.3.0", "1.2.9")).toBe(1); + expect(compareMinorMajorPatch("1.2.4", "1.2.3")).toBe(1); + }); + it("Return -1 - First version is smaller", () => { + expect(compareMinorMajorPatch("1.9.9", "2.0.0")).toBe(-1); + expect(compareMinorMajorPatch("1.2.9", "1.3.0")).toBe(-1); + expect(compareMinorMajorPatch("1.2.3", "1.2.4")).toBe(-1); + }); + }); + + it("should ignore prerelease and build metadata", () => { + expect(compareMinorMajorPatch("1.2.3-alpha", "1.2.3")).toBe(0); + expect(compareMinorMajorPatch("1.2.3+build.1", "1.2.3")).toBe(0); + }); + }); +}); +describe("[FUNCTION] comparePrerelease", () => { + describe("[SCENARIOS]", () => { + it("Return 0 - for versions without prerelease", () => { + expect(comparePrerelease("1.2.3", "1.2.3")).toBe(0); + }); + + it("Return 1 - when first prerelease is greater", () => { + expect(comparePrerelease("1.2.3-beta", "1.2.3-alpha")).toBe(1); + expect(comparePrerelease("1.2.3-alpha.2", "1.2.3-alpha.1")).toBe(1); + }); + + it("Return -1 - first prerelease is smaller", () => { + expect(comparePrerelease("1.2.3-alpha", "1.2.3-beta")).toBe(-1); + expect(comparePrerelease("1.2.3-alpha.1", "1.2.3-alpha.2")).toBe(-1); + }); + + it("Return 1 - Handle numeric and string prereleases correctly", () => { + expect(comparePrerelease("1.2.3-2", "1.2.3-1")).toBe(1); + expect(comparePrerelease("1.2.3-alpha.10", "1.2.3-alpha.2")).toBe(1); + }); + }); +}); + +describe("[FUNCTION] compareBuild", () => { + describe("[SCENARIOS]", () => { + it("Return 0 - for versions without build metadata", () => { + expect(compareBuild("1.2.3", "1.2.3")).toBe(0); + }); + + it("Return 1 - when first build is greater", () => { + expect(compareBuild("1.2.3+build.2", "1.2.3+build.1")).toBe(1); + }); + + it("Return -1 - when first build is smaller", () => { + expect(compareBuild("1.2.3+build.1", "1.2.3+build.2")).toBe(-1); + }); + + it("should handle numeric and string build metadata correctly", () => { + expect(compareBuild("1.2.3+2", "1.2.3+1")).toBe(1); + expect(compareBuild("1.2.3+build.10", "1.2.3+build.2")).toBe(1); + }); + }); +}); + +describe("[FUNCTION] compareSemver", () => { + describe("[SCENARIOS]", () => { + it("should compare major.minor.patch correctly", () => { + expect(compareSemver("2.0.0", "1.9.9", { compare: "majorMinorPatch" })).toBe(1); + expect(compareSemver("1.2.3", "1.2.4", { compare: "majorMinorPatch" })).toBe(-1); + }); + + it("should compare prereleases correctly", () => { + expect(compareSemver("1.2.3-beta", "1.2.3-alpha", { compare: "prereleases" })).toBe(1); + expect(compareSemver("1.2.3-alpha", "1.2.3-beta", { compare: "prereleases" })).toBe(-1); + }); + + it("should compare builds correctly", () => { + expect(compareSemver("1.2.3+build.2", "1.2.3+build.1", { compare: "builds" })).toBe(1); + expect(compareSemver("1.2.3+build.1", "1.2.3+build.2", { compare: "builds" })).toBe(-1); + }); + + it('should compare all components when compare option is "all"', () => { + expect(compareSemver("1.2.3-alpha+build.1", "1.2.3-beta+build.2", { compare: "all" })).toBe(-1); + expect(compareSemver("1.2.3-alpha+build.2", "1.2.3-alpha+build.1", { compare: "all" })).toBe(1); + expect(compareSemver("1.2.4-alpha+build.1", "1.2.3-beta+build.2", { compare: "all" })).toBe(1); + }); + + it("hardTest", () => { + expect(compareSemver("1.0.0-beta.2", "1.0.0-beta.11")).toBe(-1); + expect(compareSemver("1.0.0-beta.11", "1.0.0-rc.1")).toBe(-1); + expect(compareSemver("1.0.0-rc.1", "1.0.0")).toBe(-1); + expect(compareSemver("1.0.0", "1.0.0+build")).toBe(-1); + expect(compareSemver("1.0.0-alpha.beta", "1.0.0-beta")).toBe(-1); + expect(compareSemver("1.0.0-alpha", "1.0.0-alpha+asdaddwa", { ignoreBuild: true, compare: "all" })).toBe(0); + expect(compareSemver("1.0.0-x.7.z.92", "1.0.0-x.7.z.93")).toBe(-1); + expect(compareSemver("1.0.0-x.7.z.92", "1.0.0-x.8.z.0")).toBe(-1); + }); + + describe("[FUNCTION] compareMinorMajorPatch XXX", () => { + it("1.2.0 and 1.2.x", () => { + const [data, isError] = myErrorWrapper(compareMinorMajorPatch)("1.2.0", "1.2.x", { rangeMode: true }); + expect(isError).toBe(false); + expect(data).toBe(0); + }); + it("1.2.0 and 1.x.x", () => { + const [data, isError] = myErrorWrapper(compareMinorMajorPatch)("1.2.0", "1.x.x", { rangeMode: true }); + expect(isError).toBe(false); + expect(data).toBe(0); + }); + it("1.2.0 and x.x.x", () => { + const [data, isError] = myErrorWrapper(compareMinorMajorPatch)("1.2.0", "x.x.x", { rangeMode: true }); + expect(isError).toBe(false); + expect(data).toBe(0); + }); + it("1.2.0 and 2.x.x", () => { + const [data, isError] = myErrorWrapper(compareMinorMajorPatch)("1.2.0", "2.x.x", { rangeMode: true }); + expect(isError).toBe(false); + expect(data).toBe(-1); + }); + it("x.2.0 and x.x.5", () => { + const [data, isError] = myErrorWrapper(compareMinorMajorPatch)("x.2.0", "x.x.5", { rangeMode: true }); + expect(isError).toBe(false); + expect(data).toBe(-1); + }); + }); + describe("[FUNCTION] compareSemVer XXX", () => { + it("1.2.0 and 1.2.x", () => { + const [data, isError] = myErrorWrapper(compareSemver)("1.2.0", "1.2.x", { rangeMode: true }); + expect(isError).toBe(false); + expect(data).toBe(0); + }); + it("1.2.0 and 1.x.x", () => { + const [data, isError] = myErrorWrapper(compareSemver)("1.2.0", "1.x.x", { rangeMode: true }); + expect(isError).toBe(false); + expect(data).toBe(0); + }); + it("1.2.0 and x.x.x", () => { + const [data, isError] = myErrorWrapper(compareSemver)("1.2.0", "x.x.x", { rangeMode: true }); + expect(isError).toBe(false); + expect(data).toBe(0); + }); + it("1.2.0 and 2.x.x", () => { + const [data, isError] = myErrorWrapper(compareSemver)("1.2.0", "2.x.x", { rangeMode: true }); + expect(isError).toBe(false); + expect(data).toBe(-1); + }); + it("x.2.0 and x.x.5", () => { + const [data, isError] = myErrorWrapper(compareSemver)("x.2.0", "x.x.5", { rangeMode: true }); + expect(isError).toBe(false); + expect(data).toBe(-1); + }); + it("x.2.0 and x.x.5-x", () => { + const [data, isError] = myErrorWrapper(compareSemver)("1.2.3", "x.x.5-x", { rangeMode: true }); + expect(isError).toBe(false); + expect(data).toBe(-1); + }); + it("1.2.3 and x.X.x", () => { + const [data, isError] = myErrorWrapper(compareSemver)("1.2.3", "x.X.x", { rangeMode: true }); + expect(isError).toBe(false); + expect(data).toBe(0); + }); + it("1.0.0-prerelease+asd and 1.x.x", () => { + const [data, isError] = myErrorWrapper(compareSemver)("1.0.0-prerelease+asd", "1.x.x", { rangeMode: true }); + expect(isError).toBe(false); + expect(data).toBe(-1); + }); + it("19.0.0-rc-3edc000d-20240926 and 19.0.0", () => { + const [data, isError] = myErrorWrapper(compareSemver)("19.0.0-rc-3edc000d-20240926", "19.0.0", { + rangeMode: true + }); + expect(isError).toBe(false); + expect(data).toBe(-1); + }); + }); + }); +}); + +it("TEST CALOSCI", () => { + const inputRange = "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-0 <19.0.0"; + const test = [ + // "16.8.0", + // "16.8.1", + // "16.8.2", + // "16.8.3", + // "16.8.4", + // "16.8.5", + // "16.8.6", + // "16.9.0", + // "16.10.0", + // "16.10.1", + // "16.10.2", + // "16.11.0", + // "16.12.0", + // "16.13.0", + // "16.13.1", + // "16.14.0", + // "17.0.0", + // "17.0.1", + // "17.0.2", + // "18.0.0", + // "18.1.0", + // "18.2.0", + // "18.3.0", + // "18.3.1", + "19.0.0-canary-2b036d3f1-20240327", + "19.0.0-canary-05797cceb-20240328", + "19.0.0-canary-a73c3450e-20240329", + "19.0.0-canary-95e6f032c-20240401", + "19.0.0-canary-48ec17b86-20240402", + "19.0.0-canary-7a2609eed-20240403", + "19.0.0-canary-fd0da3eef-20240404", + "19.0.0-canary-e3ebcd54b-20240405", + "19.0.0-canary-4c12339ce-20240408", + "19.0.0-canary-adb717393-20240411", + "19.0.0-canary-96c584661-20240412", + "19.0.0-canary-8afa144bd-20240416", + "19.0.0-canary-657428a9e-20240416", + "19.0.0-canary-36e62c603-20240418", + "19.0.0-canary-33a32441e9-20240418", + "19.0.0-canary-db913d8e17-20240422", + "19.0.0-canary-cb151849e1-20240424", + "19.0.0-canary-cf5ab8b8b2-20240425", + "19.0.0-beta-94eed63c49-20240425", + "19.0.0-beta-4508873393-20240430", + "19.0.0-beta-73bcdfbae5-20240502", + "19.0.0-beta-1beb73de0f-20240503", + "19.0.0-beta-5d29478716-20240506", + "19.0.0-beta-b498834eab-20240506", + "19.0.0-beta-e7d213dfb0-20240507", + "19.0.0-beta-6946ebe620-20240508", + "19.0.0-beta-04b058868c-20240508", + "19.0.0-beta-9d76c954cf-20240510", + "19.0.0-beta-26f2496093-20240514", + "19.0.0-rc-915b914b3a-20240515", + "19.0.0-rc-3f1436cca1-20240516", + "19.0.0-rc-57fbe3ba37-20240520", + "19.0.0-rc-d3ce0d3ea9-20240520", + "19.0.0-rc-8f3c0525f9-20240521", + "19.0.0-rc-81c5ff2e04-20240521", + "19.0.0-rc-3ac551e855-20240522", + "19.0.0-rc-f994737d14-20240522", + "19.0.0-rc-4c2e457c7c-20240522", + "19.0.0-rc-935180c7e0-20240524", + "19.0.0-rc-6f23540c7d-20240528", + "19.0.0-rc-38e3b23483-20240529", + "19.0.0-rc-9d4fba0788-20240530", + "19.0.0-rc-6d3110b4d9-20240531", + "19.0.0-rc-9598c41a20-20240603", + "19.0.0-rc.0", + "19.0.0-rc-bf3a29d097-20240603", + "19.0.0-rc-1df34bdf62-20240605", + "19.0.0-rc-eb259b5d3b-20240605", + "19.0.0-rc-99da76f23a-20240606", + "19.0.0-rc-827cbea417-20240606", + "19.0.0-rc-cc1ec60d0d-20240607", + "19.0.0-rc-20b6f4c0e8-20240607", + "19.0.0-rc-a532d91d01-20240610", + "19.0.0-rc-34d0c5e357-20240607", + "19.0.0-rc-6230622a1a-20240610", + "19.0.0-rc-a26e3f403e-20240611", + "19.0.0-rc-f3e09d6328-20240612", + "19.0.0-rc-dfd30974ab-20240613", + "19.0.0-rc-fb9a90fa48-20240614", + "19.0.0-rc-107a2f8c3e-20240617", + "19.0.0-rc-1434af3d22-20240618", + "19.0.0-rc-e684ca66ab-20240619", + "19.0.0-rc-6fb39ec9e9-20240621", + "19.0.0-rc-3563387fe3-20240621", + "19.0.0-rc-c21bcd627b-20240624", + "19.0.0-rc-8971381549-20240625", + "19.0.0-rc-e02baf6c92-20240627", + "19.0.0-rc-58af67a8f8-20240628", + "19.0.0-rc-100dfd7dab-20240701", + "19.0.0-rc-9c6806964f-20240703", + "19.0.0-rc-3da26163a3-20240704", + "19.0.0-rc-f38c22b244-20240704", + "19.0.0-rc-df783f9ea1-20240708", + "19.0.0-rc-c3cdbec0a7-20240708", + "19.0.0-rc-378b305958-20240710", + "19.0.0-rc-85acf2d195-20240711", + "19.0.0-rc-df5f2736-20240712", + "19.0.0-rc-8b08e99e-20240713", + "19.0.0-rc-01172397-20240716", + "19.0.0-rc-163365a0-20240717", + "19.0.0-rc-512b09b2-20240718", + "19.0.0-rc-d025ddd3-20240722", + "19.0.0-rc-f6cce072-20240723", + "19.0.0-rc-ab2135c7-20240724", + "19.0.0-rc-76002254-20240724", + "19.0.0-rc-14a4699f-20240725", + "19.0.0-rc-941e1b4a-20240729", + "19.0.0-rc-ab7c1663-20240730", + "19.0.0-rc-3208e73e-20240730", + "19.0.0-rc-a7d1240c-20240731", + "19.0.0-rc-06d0b89e-20240801", + "19.0.0-rc-8269d55d-20240802", + "19.0.0-rc-65903583-20240805", + "19.0.0-rc-187dd6a7-20240806", + "19.0.0-rc-e948a5ac-20240807", + "19.0.0-rc-9d2da591-20240808", + "19.0.0-rc-2d2cc042-20240809", + "19.0.0-rc-68dbd84b-20240812", + "19.0.0-rc-d48603a5-20240813", + "19.0.0-rc-49496d49-20240814", + "19.0.0-rc-19bd26be-20240815", + "19.0.0-rc-fa6eab58-20240815", + "19.0.0-rc-1eaccd82-20240816", + "19.0.0-rc-6ebfd5b0-20240818", + "19.0.0-rc-a960b92c-20240819", + "19.0.0-rc-1d989965-20240821", + "19.0.0-rc-eb3ad065-20240822", + "19.0.0-rc-b57d2823-20240822", + "19.0.0-rc-f65ac7bd-20240826", + "19.0.0-rc-f90a6bcc-20240827", + "19.0.0-rc-7771d3a7-20240827", + "19.0.0-rc-a19a8ab4-20240829", + "19.0.0-rc-e56f4ae3-20240830", + "19.0.0-rc-4f604941-20240830", + "19.0.0-rc-d1afcb43-20240903", + "19.0.0-rc-4c58fce7-20240904", + "19.0.0-rc-a03254bc-20240905", + "19.0.0-rc-e210d081-20240909", + "19.0.0-rc-3dfd5d9e-20240910", + "19.0.0-rc-d6cb4e77-20240911", + "19.0.0-rc-47352209-20240912", + "19.0.0-rc-94e652d5-20240912", + "19.0.0-rc-206df66e-20240912", + "19.0.0-rc-ee1a403a-20240916", + "19.0.0-rc-f2df5694-20240916", + "19.0.0-rc-a99d8e8d-20240916", + "19.0.0-rc-5dcb0097-20240918", + "19.0.0-rc-e740d4b1-20240919", + "19.0.0-rc-e4953922-20240919", + "19.0.0-rc-5d19e1c8-20240923", + "19.0.0-rc-04bd67a4-20240924", + "19.0.0-rc-f9ebd85a-20240925", + "19.0.0-rc-778e1ed2-20240926", + "19.0.0-rc-204a551e-20240926", + "19.0.0-rc-67fee58b-20240926", + "19.0.0-rc-3edc000d-20240926" + ]; + + // const [data, isError] = myErrorWrapper(compareSemver)("1.0.0-prerelease+asd", "1.x.x", { rangeMode: true }); + const [data, isError] = myErrorWrapper(() => + test.filter(item => compareSemver(item, "19.0.0", { rangeMode: true }) == -1) + )(); + expect(isError).toBe(false); + expect(data).toEqual(test); +}); diff --git a/packages/semver/src/functions/compare.ts b/packages/semver/src/functions/compare.ts new file mode 100644 index 0000000..cc97068 --- /dev/null +++ b/packages/semver/src/functions/compare.ts @@ -0,0 +1,238 @@ +/* eslint-disable curly */ +/* eslint-disable complexity */ +import type { TOptionsSemVer } from "./parseSemVer"; +import { OptionsSemVerDefaults, parseSemVer } from "./parseSemVer"; +import { isX } from "@/utils"; + +//---------------------- +// Global CONST +//---------------------- + +/** @internal Default options for all Compares */ +const DEFAULT_OPTIONS: TOptionsSemVer = OptionsSemVerDefaults; + +//---------------------- +// Types +//---------------------- + +type TCompareMode = "all" | "builds" | "majorMinorPatch" | "prereleases"; + +//---------------------- +// Functions +//---------------------- + +/** + * Comparing SemVer **ONLY** in `MinorMajorPatch` + * + * Example format: `1.2.3-prerelease+build` + * - `1.2.3` - majorMinorPatch + * - `['prerelease']` - prereleases + * - `['build']` - builds + * + * @returns + * - `1` if `this` is greater + * - `0` if `this` == `other` + * - `-1` if `this` is smaller. + * + * @param options - Passing into `parseSemVer` function. + * @example + * ``` + * compareMinorMajorPatch("1.2.3","1.2.2") // 1 + * compareMinorMajorPatch("1.2.3","1.2.3") // 0 + * compareMinorMajorPatch("1.2.3","1.2.4") // -1 + * ``` + */ + +export const compareMinorMajorPatch = ( + InputVersion1: Parameters[0], + InputVersion2: Parameters[0], + options: Partial = DEFAULT_OPTIONS +): -1 | 0 | 1 => { + // DEFAULTS + const mergedOptions = { ...DEFAULT_OPTIONS, ...options }; + + const [version1, version2] = [parseSemVer(InputVersion1, mergedOptions), parseSemVer(InputVersion2, mergedOptions)]; + // 1.2.3 1.x.x - 2.0.x + + const checkX = (val1: number | string, val2: number | string): boolean => + Boolean((mergedOptions.rangeMode && isX(val1)) || isX(val2)); + + if (!checkX(version1.major, version2.major) && version1.major !== version2.major) + return version1.major > version2.major ? 1 : -1; + if (!checkX(version1.minor, version2.minor) && version1.minor !== version2.minor) + return version1.minor > version2.minor ? 1 : -1; + if (!checkX(version1.patch, version2.patch) && version1.patch !== version2.patch) + return version1.patch > version2.patch ? 1 : -1; + + return 0; +}; + +/** + * Comparing SemVer **ONLY** in `prereleases` + * + * Example format: `1.2.3-prerelease+build` + * - `1.2.3` - majorMinorPatch + * - `['prerelease']` - prereleases + * - `['build']` - builds + * + * @param options - Passing into `parseSemVer` function. + * @returns + * - `0` if `this` == `other` + * - `1` if `this` is greater + * - `-1` if `this` is smaller. + * + * @example + * ``` + * comparePrerelease("1.2.3","1.2.4") // -1 + * comparePrerelease("1.2.3","1.2.3") // 0 + * comparePrerelease("1.2.3","1.2.2") // 1 + * ``` + */ + +export const comparePrerelease = ( + InputVersion1: Parameters[0], + InputVersion2: Parameters[0], + options: Partial = DEFAULT_OPTIONS +): -1 | 0 | 1 => { + // DEFAULTS + const mergedOptions = { ...DEFAULT_OPTIONS, ...options }; + const [version1, version2] = [parseSemVer(InputVersion1, mergedOptions), parseSemVer(InputVersion2, mergedOptions)]; + + if (version1.prerelease.length === 0 && version2.prerelease.length > 0) return 1; + if (version1.prerelease.length > 0 && version2.prerelease.length === 0) return -1; + + return compareComponents(version1.prerelease, version2.prerelease, mergedOptions.rangeMode); +}; + +/** + * Comparing SemVer **ONLY** in `builds` + * + * Example format: `1.2.3-prerelease+build` + * - `1.2.3` - majorMinorPatch + * - `['prerelease']` - prereleases + * - `['build']` - builds + * + * @param options - Passing into `parseSemVer` function. + * @returns + * - `0` if `this` == `other` + * - `1` if `this` is greater + * - `-1` if `this` is smaller. + * + * @example + * ``` + * compareBuild("1.2.3","1.2.4") // -1 + * compareBuild("1.2.3","1.2.3") // 0 + * compareBuild("1.2.3","1.2.2") // 1 + * ``` + */ + +export const compareBuild = ( + InputVersion1: Parameters[0], + InputVersion2: Parameters[0], + options: Partial = DEFAULT_OPTIONS +): -1 | 0 | 1 => { + // DEFAULTS + const mergedOptions = { ...DEFAULT_OPTIONS, ...options }; + + const [version1, version2] = [parseSemVer(InputVersion1, mergedOptions), parseSemVer(InputVersion2, mergedOptions)]; + + return compareComponents(version1.buildmetadata, version2.buildmetadata, mergedOptions.rangeMode); +}; + +/** + * + * To compare Build and Prereleases + * + * @internal + */ +const compareComponents = ( + a: ReadonlyArray, + b: ReadonlyArray, + rangeMode = false +): -1 | 0 | 1 => { + const len = Math.max(a.length, b.length); + for (let i = 0; i < len; i++) { + if (i >= a.length) return -1; + if (i >= b.length) return 1; + if (a[i] === b[i]) continue; + + const aNum = Number.parseInt(a[i] as string); + const bNum = Number.parseInt(b[i] as string); + + if (rangeMode && (isX(a[i]) || isX(b[i]))) return 0; + + if (!Number.isNaN(aNum) && !Number.isNaN(bNum)) return aNum > bNum ? 1 : -1; + + return a[i] > b[i] ? 1 : -1; + } + return 0; +}; + +/** + * Comparing SemVer depends from `options.compare` + * + * + * Example format: `1.2.3-prerelease+build` + * - `1.2.3` - majorMinorPatch + * - `['prerelease']` - prereleases + * - `['build']` - builds + * + * @param options - Passing into `parseSemVer` function. + * @returns + * - `0` if `this` == `other` + * - `1` if `this` is greater + * - `-1` if `this` is smaller. + * + * @example + * ``` + * compareSemver("1.2.3","1.2.4") // -1 + * compareSemver("1.2.3","1.2.3") // 0 + * compareSemver("1.2.3","1.2.2") // 1 + * ``` + */ + +export const compareSemver = ( + InputVersion1: Parameters[0], + InputVersion2: Parameters[0], + options: Partial & + ({ compare: "all"; ignoreBuild?: boolean } | { compare?: Exclude }) = { + ...DEFAULT_OPTIONS, + compare: "all", + ignoreBuild: false + } +): -1 | 0 | 1 => { + // DEFAULTS + const mergedOptions: Parameters[2] = { + ...DEFAULT_OPTIONS, + ...(options.compare === "all" ? { ignoreBuild: false } : {}), + ...options + }; + + const [version1, version2] = [parseSemVer(InputVersion1, mergedOptions), parseSemVer(InputVersion2, mergedOptions)]; + + switch (mergedOptions.compare) { + // eslint-disable-next-line default-case-last + default: + case "all": { + const majorMinorPatchResult = compareMinorMajorPatch(version1, version2, mergedOptions); + if (majorMinorPatchResult !== 0) return majorMinorPatchResult; + const prereleaseResult = comparePrerelease(version1, version2, mergedOptions); + if (prereleaseResult !== 0) return prereleaseResult; + if (mergedOptions.compare === "all" && !mergedOptions.ignoreBuild) { + return compareBuild(version1, version2, mergedOptions); + } + return 0; + } + case "majorMinorPatch": { + return compareMinorMajorPatch(version1, version2, mergedOptions); + } + case "prereleases": { + return comparePrerelease(version1, version2, mergedOptions); + } + case "builds": { + return compareBuild(version1, version2, mergedOptions); + } + } +}; + +export default compareSemver; diff --git a/packages/semver/src/functions/difference.test.ts b/packages/semver/src/functions/difference.test.ts new file mode 100644 index 0000000..621a236 --- /dev/null +++ b/packages/semver/src/functions/difference.test.ts @@ -0,0 +1,76 @@ +/* eslint-disable @EslintSonar/no-duplicate-string */ +import { describe, expect, test } from "vitest"; +import { difference } from "./difference"; + +describe("difference", () => { + describe("regular version comparisons", () => { + test("returns null when versions are equal", () => { + expect(difference("1.0.0", "1.0.0")).toBe(void 0); + expect(difference("2.1.3", "2.1.3")).toBe(void 0); + }); + + test("detects major version changes", () => { + expect(difference("1.0.0", "2.0.0")).toBe("major"); + expect(difference("2.0.0", "1.0.0")).toBe("major"); + expect(difference("1.2.3", "2.0.0")).toBe("major"); + }); + + test("detects minor version changes", () => { + expect(difference("1.0.0", "1.1.0")).toBe("minor"); + expect(difference("1.1.0", "1.0.0")).toBe("minor"); + expect(difference("1.2.3", "1.3.0")).toBe("minor"); + }); + + test("detects patch version changes", () => { + expect(difference("1.0.0", "1.0.1")).toBe("patch"); + expect(difference("1.0.1", "1.0.0")).toBe("patch"); + expect(difference("1.2.3", "1.2.4")).toBe("patch"); + }); + }); + + describe("prerelease version comparisons", () => { + test("handles prerelease transitions", () => { + expect(difference("1.0.0-alpha", "1.0.0")).toBe("major"); + expect(difference("1.0.0-beta", "1.0.0")).toBe("major"); + expect(difference("2.0.0-alpha", "2.0.0")).toBe("major"); + }); + + test("detects prerelease changes", () => { + expect(difference("1.0.0-alpha.1", "1.0.0-alpha.2")).toBe("prerelease"); + expect(difference("1.0.0-beta.1", "1.0.0-beta.2")).toBe("prerelease"); + }); + + test("handles premajor versions", () => { + expect(difference("1.0.0", "2.0.0-alpha")).toBe("premajor"); + expect(difference("2.0.0-alpha", "1.0.0")).toBe("premajor"); + }); + + test("handles preminor versions", () => { + expect(difference("1.0.0", "1.1.0-alpha")).toBe("preminor"); + expect(difference("1.1.0-alpha", "1.0.0")).toBe("preminor"); + }); + + test("handles prepatch versions", () => { + expect(difference("1.0.0", "1.0.1-alpha")).toBe("prepatch"); + expect(difference("1.0.1-alpha", "1.0.0")).toBe("prepatch"); + }); + }); + + describe("edge cases", () => { + test("handles major-only prerelease transitions", () => { + expect(difference("1.0.0-alpha", "1.0.0")).toBe("major"); + expect(difference("1.0.0-alpha", "2.0.0")).toBe("major"); + }); + + test("handles invalid versions", () => { + expect(() => difference("invalid", "1.0.0")).toThrow(); + expect(() => difference("1.0.0", "invalid")).toThrow(); + }); + + test("handles complex prerelease patterns", () => { + expect(difference("1.0.0-alpha.1", "1.0.0-beta.1")).toBe("prerelease"); + expect(difference("1.0.0-alpha.1", "1.0.0")).toBe("major"); + expect(difference("1.0.0-alpha.1", "1.1.0")).toBe("major"); + }); + }); +}); diff --git a/packages/semver/src/functions/difference.ts b/packages/semver/src/functions/difference.ts new file mode 100644 index 0000000..3c2ce54 --- /dev/null +++ b/packages/semver/src/functions/difference.ts @@ -0,0 +1,60 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +import { parseSemVer } from "./parseSemVer"; +import compareSemver from "./compare"; +import type { TReleases } from "@/internals"; + +//---------------------- +// Types +//---------------------- + +type differenceReturn = TReleases | undefined; + +//---------------------- +// Functions +//---------------------- + +/** + * Determines the type of version differenceerence between two semantic versions. + * @returns Returns a string indicating the type of differenceerence: + * - `"major"` - Major version differenceerence + * - `"minor"` - Minor version differenceerence + * - `"patch"` - Patch version differenceerence + * - `"premajor"` - Major version differenceerence with prerelease + * - `"preminor"` - Minor version differenceerence with prerelease + * - `"prepatch"` - Patch version differenceerence with prerelease + * - `"prerelease"` - Only prerelease differenceerence + * - `undefined` - Versions are identical + * @example + * // Regular version differenceerences + * difference("1.0.0", "2.0.0") // Returns "major" + * difference("1.1.0", "1.2.0") // Returns "minor" + * difference("1.1.1", "1.1.2") // Returns "patch" + */ +// eslint-disable-next-line complexity +export const difference = ( + version1: Parameters[0], + version2: Parameters[0], + options: Parameters[1] = {} +): differenceReturn => { + const [v1, v2] = [parseSemVer(version1, options), parseSemVer(version2, options)]; + + const comparison = compareSemver(v1, v2); + if (comparison === 0) return void 0; + + const [higher, lower] = comparison > 0 ? [v1, v2] : [v2, v1]; + const [highHasPre, lowHasPre] = [Boolean(higher.prerelease.length), Boolean(lower.prerelease.length)]; + + if (lowHasPre && !highHasPre) { + if (!lower.patch && !lower.minor) return "major"; + if (higher.patch) return "patch"; + if (higher.minor) return "minor"; + return "major"; + } + const prefix = highHasPre ? "pre" : ""; + if (v1.major !== v2.major) return `${prefix}major`; + if (v1.minor !== v2.minor) return `${prefix}minor`; + if (v1.patch !== v2.patch) return `${prefix}patch`; + return "prerelease"; +}; + +export default difference; diff --git a/packages/semver/src/functions/increase.test.ts b/packages/semver/src/functions/increase.test.ts new file mode 100644 index 0000000..4988660 --- /dev/null +++ b/packages/semver/src/functions/increase.test.ts @@ -0,0 +1,252 @@ +/* eslint-disable @EslintSonar/no-duplicate-string */ +// import { SemVer } from "@/classes"; +// import type { TOptionsSemVer } from "./parseSemVer"; +// import { OptionsSemVerDefaults } from "./parseSemVer"; + +import { describe, expect, it } from "vitest"; +import increase from "./increase"; +import parseSemVer, { MYERRORLIST } from "./parseSemVer"; +import { myError, myErrorWrapper } from "oh-my-error"; +import { SemVer } from "@/classes"; + +describe("[FUNCTION] increase", () => { + describe("[ERROR]", () => { + it("INVALID_VERSION - for input `null`", () => { + const [error, isError] = myErrorWrapper(parseSemVer)("1.ASD.4"); + expect(isError).toEqual(true); + expect(error).toEqual(myError(MYERRORLIST.INVALID_VERSION, { message: { dev: ["1.ASD.4"] } })); + }); + }); + describe("[PASS]", () => { + describe("Bump Major Version - '1.2.3' 'major'", () => { + it("returnType - 'string'", () => { + const result = increase("1.2.3", "major", "string"); + + expect(typeof result === "string").toEqual(true); + expect(result).toEqual("2.0.0"); + }); + it("returnType - 'SemVer'", () => { + const result = increase("1.2.3", "major", "SemVer"); + expect(result).instanceOf(SemVer); + expect(String(result)).toEqual(String(new SemVer("2.0.0"))); + }); + it("returnType - 'object'", () => { + const result = increase("1.2.3", "major", "object"); + + expect(typeof result === "object").toEqual(true); + expect(result).toEqual({ + major: 2, + minor: 0, + patch: 0, + prerelease: [], + buildmetadata: [], + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + version: expect.any(Function) + }); + }); + }); + describe("Bump Minor Version - '1.2.3' 'minor'", () => { + it("returnType - 'string'", () => { + const result = increase("1.2.3", "minor", "string"); + + expect(typeof result === "string").toEqual(true); + expect(result).toEqual("1.3.0"); + }); + it("returnType - 'SemVer'", () => { + const result = increase("1.2.3", "minor", "SemVer"); + expect(result).instanceOf(SemVer); + expect(String(result)).toEqual(String(new SemVer("1.3.0"))); + }); + it("returnType - 'object'", () => { + const result = increase("1.2.3", "minor", "object"); + + expect(typeof result === "object").toEqual(true); + expect(result).toEqual({ + major: 1, + minor: 3, + patch: 0, + prerelease: [], + buildmetadata: [], + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + version: expect.any(Function) + }); + }); + }); + describe("Bump Patch Version - '1.2.3' 'patch'", () => { + it("returnType - 'string'", () => { + const result = increase("1.2.3", "patch", "string"); + + expect(typeof result === "string").toEqual(true); + expect(result).toEqual("1.2.4"); + }); + it("returnType - 'SemVer'", () => { + const result = increase("1.2.3", "patch", "SemVer"); + expect(result).instanceOf(SemVer); + expect(String(result)).toEqual(String(new SemVer("1.2.4"))); + }); + it("returnType - 'object'", () => { + const result = increase("1.2.3", "patch", "object"); + + expect(typeof result === "object").toEqual(true); + expect(result).toEqual({ + major: 1, + minor: 2, + patch: 4, + prerelease: [], + buildmetadata: [], + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + version: expect.any(Function) + }); + }); + }); + }); + describe("[SCENARIOS]", () => { + describe("Major", () => { + it("1.2.3 => 2.0.0", () => {}); + it("5.2.3 => 6.0.0", () => {}); + }); + describe("PRERELEASES", () => { + describe("PreMajor", () => { + it("1.2.3 => 2.0.0-0 - string - check correctness", () => { + const result = increase("1.2.3", "premajor", "string"); + expect(typeof result == "string").toEqual(true); + expect(result).toEqual("2.0.0-0"); + }); + it("1.2.3 => 2.0.0-alpha", () => { + const result = increase("1.2.3", "premajor", "string", { value: "alpha" }); + expect(typeof result == "string").toEqual(true); + expect(result).toEqual("2.0.0-alpha"); + }); + }); + describe("PreMinor", () => { + it("1.2.3 => 1.3.0-0", () => { + const result = increase("1.2.3", "preminor", "string"); + expect(typeof result == "string").toEqual(true); + expect(result).toEqual("1.3.0-0"); + }); + it("1.2.3 => 1.3.0-alpha", () => { + const result = increase("1.2.3", "preminor", "string", { value: "alpha" }); + expect(typeof result == "string").toEqual(true); + expect(result).toEqual("1.3.0-alpha"); + }); + }); + describe("PrePatch", () => { + it("1.2.3 => 1.2.4-0", () => { + const result = increase("1.2.3", "prepatch", "string"); + expect(typeof result == "string").toEqual(true); + expect(result).toEqual("1.2.4-0"); + }); + it("1.2.3 => 1.2.4-alpha", () => { + const result = increase("1.2.3", "prepatch", "string", { value: "alpha" }); + expect(typeof result == "string").toEqual(true); + expect(result).toEqual("1.2.4-alpha"); + }); + }); + }); + describe("Prerelease update", () => { + it("1.0.0-x.7.z.92 => 1.0.0-x.7.z.93", () => { + const result = increase("1.0.0-x.7.z.92", "prerelease", "string"); + expect(typeof result === "string").toEqual(true); + expect(result).toEqual("1.0.0-x.7.z.93"); + }); + it("1.2.3-alpha => 1.2.3-alpha.0 - returnType - 'string'", () => { + const result = increase("1.2.3-alpha", "prerelease", "string"); + expect(typeof result === "string").toEqual(true); + expect(result).toEqual("1.2.3-alpha.0"); + }); + describe("1.2.3-alpha.0 => 1.2.3-alpha.1", () => { + it("returnType - 'string'", () => { + const result = increase("1.2.3-alpha.0", "prerelease", "string"); + expect(typeof result === "string").toEqual(true); + expect(result).toEqual("1.2.3-alpha.1"); + }); + it("returnType - 'Semver'", () => { + const result = increase("1.2.3-alpha.0", "prerelease", "SemVer"); + expect(result).instanceOf(SemVer); + expect(String(result)).toEqual(String(new SemVer("1.2.3-alpha.1"))); + }); + it("returnType - 'object'", () => { + const result = increase("1.2.3-alpha.0", "prerelease", "object"); + expect(typeof result === "object").toEqual(true); + expect(result).toEqual({ + major: 1, + minor: 2, + patch: 3, + prerelease: ["alpha", 1], + buildmetadata: [], + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + version: expect.any(Function) + }); + }); + }); + // it("1.2.3 => 1.2.3.beta - returnType - 'string'", () => { + // const result = increase("1.2.3", "prerelease", "string", "beta"); + // expect(typeof result === "string").toEqual(true); + // expect(result).toEqual("1.2.3.beta"); + // }); + // it("returnType - 'object'", () => { + // const result = increase("1.2.3", "patch", "object"); + // expect(typeof result === "object").toEqual(true); + // expect(result).toEqual({ + // major: 1, + // minor: 2, + // patch: 4, + // prerelease: [], + // buildmetadata: [], + // // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + // version: expect.any(Function) + // }); + // }); + }); + describe("Builds update", () => { + it("1.2.3-alpha+build => 1.2.3-alpha.0 - returnType - 'string'", () => { + const result = increase("1.2.3-alpha+build", "prerelease", "string"); + expect(typeof result === "string").toEqual(true); + expect(result).toEqual("1.2.3-alpha.0"); + }); + describe("1.2.3-alpha.0+build.0 => 1.2.3-alpha.0+build.1", () => { + it("returnType - 'string'", () => { + const result = increase("1.2.3-alpha.0+build.0", "buildmetadata", "string"); + expect(typeof result === "string").toEqual(true); + expect(result).toEqual("1.2.3-alpha.0+build.1"); + }); + it("returnType - 'Semver'", () => { + const result = increase("1.2.3-alpha.0+build.0", "buildmetadata", "SemVer"); + expect(result).instanceOf(SemVer); + expect(String(result)).toEqual(String(new SemVer("1.2.3-alpha.0+build.1"))); + }); + it("returnType - 'object'", () => { + const result = increase("1.2.3-alpha.0+build.0", "buildmetadata", "object"); + expect(typeof result === "object").toEqual(true); + expect(result).toEqual({ + major: 1, + minor: 2, + patch: 3, + prerelease: ["alpha", 0], + buildmetadata: ["build", 1], + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + version: expect.any(Function) + }); + }); + }); + // it("1.2.3 => 1.2.3.beta - returnType - 'string'", () => { + // const result = increase("1.2.3", "prerelease", "string", "beta"); + // expect(typeof result === "string").toEqual(true); + // expect(result).toEqual("1.2.3.beta"); + // }); + // it("returnType - 'object'", () => { + // const result = increase("1.2.3", "patch", "object"); + // expect(typeof result === "object").toEqual(true); + // expect(result).toEqual({ + // major: 1, + // minor: 2, + // patch: 4, + // prerelease: [], + // buildmetadata: [], + // // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + // version: expect.any(Function) + // }); + // }); + }); + }); +}); diff --git a/packages/semver/src/functions/increase.ts b/packages/semver/src/functions/increase.ts new file mode 100644 index 0000000..8b25157 --- /dev/null +++ b/packages/semver/src/functions/increase.ts @@ -0,0 +1,162 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +import { SemVer } from "@/classes"; +import type { TOptionsSemVer } from "./parseSemVer"; +import { parseSemVer, OptionsSemVerDefaults } from "./parseSemVer"; +import { myError } from "oh-my-error"; +import type { TMyErrorList } from "oh-my-error"; + +//---------------------- +// Global CONST +//---------------------- + +const DEFAULT_OPTIONS = { ...OptionsSemVerDefaults }; + +//---------------------- +// Errors +//---------------------- + +/** + * @internal + */ +const MYERRORLIST = { + WRONG_UPDATE_OPTION: { + code: "WRONG_UPDATE_OPTION", + name: "Wrong update option", + message: { + dev: "Wrong `update` option" + }, + hint: { + dev: "Check passed `update`" + } + } +} as const satisfies TMyErrorList; + +//---------------------- +// Types +//---------------------- + +/** + * Possible update types for version increment. + * @intelType //TODO: no-internal-exports plugin need update to fix it + */ +type UpdateType = "buildmetadata" | "major" | "minor" | "patch" | "premajor" | "preminor" | "prepatch" | "prerelease"; + +/** + * Possible return types for the increase function. + * @intelType + */ +type ReturnTypes = "object" | "SemVer" | "string"; + +/** @intelType */ +type TTTTT = "premajor" | "preminor" | "prepatch" | "prerelease"; + +/** @intelType */ +// eslint-disable-next-line @typescript-eslint/ban-types +type TOptionsForPrerelease = TOptionsSemVer & { value?: "alpha" | "beta" | "rc" | (Object & string) }; + +/** @intelType */ +// eslint-disable-next-line @typescript-eslint/ban-types +type OptionsForBuild = TOptionsSemVer & { value?: "BUILD" | (Object & string) }; + +//---------------------- +// Functions +//---------------------- + +/** + * Increases the version number of a semantic version string. + * + * @example + * // Increase major version + * increase("1.2.3", "major", "string") // Returns "2.0.0" + * + * // Increase minor version with custom prerelease + * increase("1.2.3", "preminor", "string", { value: "alpha" }) // Returns "1.3.0-alpha" + */ +// eslint-disable-next-line complexity +export const increase = ( + inputVersion: Parameters[0], + update: T, + returnType: ReturnTypes = "SemVer" as const, + options: T extends TTTTT + ? TOptionsForPrerelease + : T extends "buildmetadata" + ? OptionsForBuild + : TOptionsSemVer = DEFAULT_OPTIONS as any +) => { + const mergedOptions = { ...OptionsSemVerDefaults, ...options }; + let version = parseSemVer(inputVersion, mergedOptions); + + const updatePreOrBuild = (stage: "buildmetadata" | "prerelease"): void => { + if (Object.hasOwn(options, "value")) { + // @ts-expect-error Because Object.hasOwn(options, "value") doesnt narrow type line `in`, but we dont want to use `in` to not check proto chain + version[stage] = [options.value as string]; + return; + } + + const indexOfNumber = version[stage].findLastIndex((item: number | string) => Number.isInteger(item)); + if (indexOfNumber == -1) version[stage].push(0); + else if (typeof version[stage][indexOfNumber] == "number") version[stage][indexOfNumber] += 1; + }; + + const resetRest = (choiceInput: UpdateType) => { + const updateOrder = ["major", "minor", "patch", "prerelease", "buildmetadata"] as const; + const choice: (typeof updateOrder)[number] = updateOrder.find(v => v === choiceInput) ?? "buildmetadata"; + + const startFrom = updateOrder.indexOf(choice); + if (startFrom === -1) throw new Error(`Invalid update type: ${update}`); + + for (let i = startFrom + 1; i < updateOrder.length; i++) { + const key: (typeof updateOrder)[number] = updateOrder[i]; + // version[key] = Array.isArray(version[key]) ? [] : 0; + // eslint-disable-next-line @EslintUnicorn/prefer-ternary + if (key === "prerelease" || key === "buildmetadata") { + version[key] = []; + } else { + version[key] = 0; + } + } + }; + + switch (update) { + case "major": + case "minor": + case "patch": { + const updateKey = update as keyof Pick; + + if (typeof version[updateKey] === "number") version[updateKey] += 1; + + resetRest(update); + break; + } + case "premajor": + case "preminor": + case "prepatch": { + const upd = { + premajor: "major", + preminor: "minor", + prepatch: "patch" + } as const; + + const updateKey = upd[update as keyof typeof upd] as keyof Pick; + if (typeof version[updateKey] === "number") version[updateKey] += 1; + resetRest(upd[update as "premajor" | "preminor" | "prepatch"] as "premajor"); + updatePreOrBuild("prerelease"); + + break; + } + case "prerelease": + case "buildmetadata": { + updatePreOrBuild(update); + resetRest(update); + break; + } + default: { + throw myError(MYERRORLIST.WRONG_UPDATE_OPTION); + } + } + + if (returnType === "string") return version.version(); + if (returnType === "SemVer") return new SemVer(version); + return version; +}; +export default increase; diff --git a/packages/semver/src/functions/index.ts b/packages/semver/src/functions/index.ts new file mode 100644 index 0000000..7efda8b --- /dev/null +++ b/packages/semver/src/functions/index.ts @@ -0,0 +1,8 @@ +export * from "./versionValidator"; +export * from "./parseSemVer"; +export * from "./compare"; +export * from "./increase"; +export * from "./satisfies"; +export * from "./difference"; +export * from "./minVersion"; +export * from "./simplifyRange"; diff --git a/packages/semver/src/functions/minVersion.test.ts b/packages/semver/src/functions/minVersion.test.ts new file mode 100644 index 0000000..9a33d7d --- /dev/null +++ b/packages/semver/src/functions/minVersion.test.ts @@ -0,0 +1,108 @@ +/* eslint-disable @EslintSonar/no-duplicate-string */ +import { describe, it, expect } from "vitest"; +import minVersion from "./minVersion"; + +describe("minVersion", () => { + // Podstawowe przypadki + it("should handle simple version ranges", () => { + expect(minVersion("^1.0.0")).toBe("1.0.0"); + expect(minVersion("~2.0.0")).toBe("2.0.0"); + expect(minVersion(">=3.0.0")).toBe("3.0.0"); + }); + + // ZΕ‚oΕΌone zakresy + it("should handle complex version ranges", () => { + expect(minVersion("^1.2.3 || ^2.0.0")).toBe("1.2.3"); + expect(minVersion(">=1.0.0 <2.0.0")).toBe("1.0.0"); + expect(minVersion("~1.2.3 || ~1.3.0")).toBe("1.2.3"); + }); + + // Prerelease wersje + it("should handle prerelease versions", () => { + expect(minVersion("^1.0.0-alpha")).toBe("1.0.0-alpha"); + expect(minVersion(">=1.0.0-beta.1")).toBe("1.0.0-beta.1"); + expect(minVersion("^2.0.0-alpha || ^2.0.0")).toBe("2.0.0-alpha"); + }); + + // // Edge cases + // it("should handle edge cases", () => { + // // expect(minVersion("*")).toBe("0.0.0"); + // // expect(minVersion("")).toBe("0.0.0"); + // // expect(minVersion("invalid")).toThrow(); + // }); + + // // Zakresy z gwiazdkami + it("should handle wildcard ranges", () => { + expect(minVersion("1.x")).toBe("1.0.0"); + expect(minVersion("1.2.x")).toBe("1.2.0"); + expect(minVersion("1.*")).toBe("1.0.0"); + }); + + // // Zakresy z operatorami + it("should handle hyphens ranges with differenceerent operators", () => { + expect(minVersion("1.0.0 - 2.0.0")).toBe("1.0.0"); + expect(minVersion(">1.0.0 - 2.0.0")).toBe("1.0.1"); + expect(minVersion("2.0.0 - 1.0.0")).toBe("1.0.0"); + expect(minVersion("3.0.0 - 5.0.0")).toBe("3.0.0"); + }); + + it("should handle ranges with differenceerent operators", () => { + expect(minVersion(">=1.0.0 <=2.0.0")).toBe("1.0.0"); + expect(minVersion(">1.0.0 <2.0.0")).toBe("1.0.1"); + expect(minVersion(">=1.0.0 <2.0.0")).toBe("1.0.0"); + }); + + // // NieprawidΕ‚owe dane wejΕ›ciowe + it("should handle invalid inputs gracefully", () => { + //TODO: should return error prob + expect(minVersion(undefined as any)).toBe("0.0.0"); + expect(minVersion(null as any)).toBe("0.0.0"); + expect(minVersion(null as any)).toBe("0.0.0"); + }); + + // // Skomplikowane zakresy + it("should handle complex range combinations", () => { + expect(minVersion("^1.2.3 || ~2.0.0 || >=3.0.0 <=4.0.0")).toBe("1.2.3"); + expect(minVersion(">=1.0.0 <2.0.0 || >=2.0.0 <3.0.0")).toBe("1.0.0"); + expect(minVersion("^1.0.0 || ^2.0.0-beta || ^2.0.0")).toBe("1.0.0"); + }); + + // // Testy negatywne + it("should handle invalid version ranges", () => { + expect(() => { + minVersion("invalid range"); + }).toThrow(); + expect(() => { + minVersion(">>1.0.0"); + }).toThrow(); + expect(() => { + minVersion("1.0.0 ||| 2.0.0"); + }).toThrow(); + }); + // }); + + // // Dodatkowe testy dla edge cases z rΓ³ΕΌnymi opcjami + describe("minVersion with options", () => { + const options = { + includePrerelease: true, + loose: true + }; + + it("should handle loose versioning", () => { + expect(minVersion("~1.2", options)).toBe("1.2.0"); + expect(minVersion("1.2.x", options)).toBe("1.2.0"); + expect(minVersion("1.x.x", options)).toBe("1.0.0"); + }); + + it("should handle prerelease versions with options", () => { + expect(minVersion("^1.0.0-alpha", options)).toBe("1.0.0-alpha"); + expect(minVersion(">=1.0.0-0", options)).toBe("1.0.0-0"); + expect(minVersion(">=1.0.0-alpha.1", options)).toBe("1.0.0-alpha.1"); + }); + + it("should handle complex ranges with options", () => { + expect(minVersion("^1.0.0-alpha || >=2.0.0", options)).toBe("1.0.0-alpha"); + expect(minVersion(">=1.0.0-beta <2.0.0", options)).toBe("1.0.0-beta"); + }); + }); +}); diff --git a/packages/semver/src/functions/minVersion.ts b/packages/semver/src/functions/minVersion.ts new file mode 100644 index 0000000..a35bb6b --- /dev/null +++ b/packages/semver/src/functions/minVersion.ts @@ -0,0 +1,99 @@ +/* eslint-disable complexity */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +import type { IparseRange, satisfies, TCondition } from "@/functions"; +import { compareSemver, increase, parseRange, parseSemVer } from "@/functions"; +import { isX } from "@/utils"; + +//---------------------- +// Functions (Main) +//---------------------- + +/** + * Finds the minimum valid version that satisfies the given semver range. + * @param range - A semver range string (e.g. "^1.2.3", "1.x", ">=2.0.0") + * @example + * minVersion("^1.2.3") // Returns "1.2.3" + * minVersion(">=2.0.0") // Returns "2.0.0" + * minVersion("1.x || 2.x") // Returns "1.0.0" + * + * @returns The minimum valid version as a string that satisfies the range. + * If no range is provided, returns "0.0.0" + */ +export const minVersion = (range: Parameters[1]) => { + if (!range) return parseSemVer("0.0.0").version(); + let result: Required | undefined = void 0; + + const parsedRanges = parseRange(range); + + for (const subRange of parsedRanges) { + if (subRange.length == 1) { + const range = subRange[0]; + const minVersionFromRange = minFromIt(range); + if (result == void 0) result = minVersionFromRange; + else result = compareSemver(minVersionFromRange, result) == -1 ? minVersionFromRange : result; + } else if (subRange.length == 2) { + const [range1, range2] = [subRange[0], subRange[1]]; + const [minRange1, minRange2] = [minFromIt(range1), minFromIt(range2)]; + const higher = compareSemver(minRange1, minRange2) == 1 ? minRange1 : minRange2; // highest from 2 && - lowest possible + if (result == void 0) result = higher; + else result = compareSemver(higher, result) == -1 ? higher : result; + } else { + const [start, hyphen, end] = subRange; + if (hyphen[0] === "-") { + const [range1, range2] = [start, end]; + const [minRange1, minRange2] = [minFromIt(range1), minFromIt(range2)]; + const lower = compareSemver(minRange1, minRange2) == -1 ? minRange1 : minRange2; // highest from 2 && - lowest possible + if (result == void 0) result = lower; + else result = compareSemver(lower, result) == -1 ? lower : result; + } + } + } + + return result?.version(); +}; + +export default minVersion; + +//---------------------- +// Functions +//---------------------- + +/** @internal */ +const changeXT0 = (versionInp: Parameters[0]) => { + const version = parseSemVer(versionInp, { rangeMode: true }); + version.major = isX(version.major) ? 0 : version.major; + version.minor = isX(version.minor) ? 0 : version.minor; + version.patch = isX(version.patch) ? 0 : version.patch; + return version; +}; +/** @internal */ +const minFromIt = (cond: TCondition) => { + let version = changeXT0(cond[1]); + + switch (cond[0]) { + case "^": { + return version; + } + case "<": + case "<=": { + return parseSemVer("0.0.0"); + } + case ">=": + case "=": { + return version; + } + case ">": { + //TODO: prerelease? + return version.prerelease.length > 0 + ? parseSemVer(increase(version, "prerelease")) + : parseSemVer(increase(version, "patch")); + } + case "~": { + // return parseSemVer(`${version.major}.${version.minor}.0`); + return version; + } + default: { + return version; + } + } +}; diff --git a/packages/semver/src/functions/parseSemVer.test.ts b/packages/semver/src/functions/parseSemVer.test.ts new file mode 100644 index 0000000..ad9af0b --- /dev/null +++ b/packages/semver/src/functions/parseSemVer.test.ts @@ -0,0 +1,131 @@ +import { describe, expect, it } from "vitest"; + +import { SemVer } from "@/classes"; +import { myError, myErrorWrapper } from "oh-my-error"; +import parseSemVer, { MYERRORLIST } from "./parseSemVer"; + +describe("Parse SemVer", () => { + describe("[FUNCTION] parseSemVer", () => { + // describe("[ERROR]", () => { + // it("INVALID_VERSION - for input `null`", () => { + // const [error, isError] = myErrorWrapper(parseSemVer)("1.ASD.4"); + // expect(isError).toEqual(true); + // expect(error).toEqual(MYERRORLIST.INVALID_VERSION); + // }); + // }); + describe("[PASS]", () => { + it("SemVer as Input", () => { + const Input = new SemVer("1.2.3"); + + // expect(Input.major).toEqual(1); + const [data, isError] = myErrorWrapper(parseSemVer)(Input); + expect(isError).toEqual(false); + const { version } = data; + expect(data).toEqual({ + major: 1, + minor: 2, + patch: 3, + prerelease: [], + buildmetadata: [], + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + version: expect.any(Function) + }); + }); + describe("rangeMode", () => { + it("1.X.X", () => { + const [result, isError] = myErrorWrapper(parseSemVer)("1.X.X", { rangeMode: true }); + expect(isError).toBe(false); + expect(result).toEqual({ + version: expect.any(Function), + major: 1, + minor: "x", + patch: "x", + prerelease: [], + buildmetadata: [] + }); + }); + it("X.X.X", () => { + const [result, isError] = myErrorWrapper(parseSemVer)("X.X.X", { rangeMode: true }); + expect(isError).toBe(false); + expect(result).toEqual({ + version: expect.any(Function), + major: "x", + minor: "x", + patch: "x", + prerelease: [], + buildmetadata: [] + }); + }); + it("x.X.x", () => { + const [result, isError] = myErrorWrapper(parseSemVer)("x.X.x", { rangeMode: true }); + expect(isError).toBe(false); + expect(result).toEqual({ + version: expect.any(Function), + major: "x", + minor: "x", + patch: "x", + prerelease: [], + buildmetadata: [] + }); + }); + it("*", () => { + const [result, isError] = myErrorWrapper(parseSemVer)("*", { rangeMode: true }); + expect(isError).toBe(false); + expect(result).toEqual({ + version: expect.any(Function), + major: "x", + minor: "x", + patch: "x", + prerelease: [], + buildmetadata: [] + }); + }); + }); + }); + describe("[SCENARIOS]", () => { + describe("1.2 - X.Y.Z form", () => { + it("1.2 => 1.2.0 - loose:true (default)", () => { + const Input = "1.2"; + + // expect(Input.major).toEqual(1); + const [data, isError] = myErrorWrapper(parseSemVer)(Input); + expect(isError).toEqual(false); + expect(data).toEqual({ + major: 1, + minor: 2, + patch: 0, + prerelease: [], + buildmetadata: [], + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + version: expect.any(Function) + }); + }); + it("1.2 => ERROR - loose: false", () => { + const Input = "1.2"; + + // expect(Input.major).toEqual(1); + const [data, isError] = myErrorWrapper(parseSemVer)(Input, { loose: false }); + expect(isError).toEqual(true); + expect(data).toEqual(myError(MYERRORLIST.INVALID_VERSION, { message: { dev: ["1.2"] } })); + }); + }); + it("SemVer as Input", () => { + const Input = new SemVer("1.2.3-alpha.1+build.32"); + + // expect(Input.major).toEqual(1); + const [data, isError] = myErrorWrapper(parseSemVer)(Input); + expect(isError).toEqual(false); + + expect(data).toEqual({ + major: 1, + minor: 2, + patch: 3, + prerelease: ["alpha", 1], + buildmetadata: ["build", 32], + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + version: expect.any(Function) + }); + }); + }); + }); +}); diff --git a/packages/semver/src/functions/parseSemVer.ts b/packages/semver/src/functions/parseSemVer.ts new file mode 100644 index 0000000..f7e98ca --- /dev/null +++ b/packages/semver/src/functions/parseSemVer.ts @@ -0,0 +1,187 @@ +// TODO: optimize regex? +/* eslint-disable @EslintImports/no-deprecated */ +/* eslint-disable @EslintOptRegConf/optimize-regex */ +/* eslint-disable curly */ +/* eslint-disable complexity */ +/* eslint-disable no-nested-ternary */ +/* eslint-disable @EslintUnicorn/no-nested-ternary */ +/* eslint-disable @EslintSecurity/detect-unsafe-regex */ +import { SemVer } from "@/classes"; +import type { TMyErrorList } from "oh-my-error"; +import { myError } from "oh-my-error"; + +import { versionPostValidator, versionPreValidator } from "./versionValidator"; + +//---------------------- +// Global CONST +//---------------------- +/** + * @internal + */ +export const PATTERN_STRICT_SEMVER = + /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][\dA-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][\dA-Za-z-]*))*))?(?:\+([\dA-Za-z-]+(?:\.[\dA-Za-z-]+)*))?$/u; +/** + * @internal + */ +export const PATTERN_LOOSE_SEMVER = + /^v?(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?(?:\.(0|[1-9]\d*))?(?:-((?:0|[1-9]\d*|\d*[a-z-][\da-z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-z-][\da-z-]*))*))?(?:\+([\da-z-]+(?:\.[\da-z-]+)*))?$/iu; +/** + * @internal + */ +export const PATTERN_RANGE_MODE = + /^v?(0|[1-9]\d*|x|X|\*)(?:\.(0|[1-9]\d*|x|X|\*))?(?:\.(0|[1-9]\d*|x|X|\*))?(?:-((?:0|[1-9]\d*|\d*[a-z-][\da-z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-z-][\da-z-]*))*))?(?:\+([\da-z-]+(?:\.[\da-z-]+)*))?$/iu; + +//---------------------- +// Errors +//---------------------- + +/** + * @internal + */ +export const MYERRORLIST = { + INVALID_VERSION: { + code: "INVALID_VERSION", + name: "Invalid version string", + hint: {}, + message: { + dev: (inp: string) => `Inputed string is not recognized by RegEx - ${inp}`, + user: "Version string is invalid and can't be parsed." + } + } +} as const satisfies TMyErrorList; + +//---------------------- +// Functions +//---------------------- + +/** @internal */ +export const formatVersion = (version: Required | Required): string => { + const base = `${version.major}.${version.minor}.${version.patch}`; + const prerelease = version.prerelease.length ? `-${version.prerelease.join(".")}` : ""; + const buildmetadata = version.buildmetadata.length ? `+${version.buildmetadata.join(".")}` : ""; + + return `${base}${prerelease}${buildmetadata}`; +}; + +export interface IparseSemVer { + buildmetadata?: Array; + major?: number; + minor?: number; + patch?: number; + prerelease?: Array; + + version?: () => string; +} + +export interface IparseRange extends Omit { + major?: number | "*" | "X" | "x"; + minor?: number | "*" | "X" | "x"; + patch?: number | "*" | "X" | "x"; +} + +/** + * Options for parsing a semantic version string or range. + */ +export type TOptionsSemVer = { + /** Accept and parse versions like `v1.2.3` etc*/ + /** If true, the parsing will be loose. Accept and parse versions like `v1.2.3` or `1.2` */ + loose?: boolean; + /** If true, the parsing will be in range mode and accept `x` | `*` etc */ + rangeMode?: boolean; + /** + * `boolean` - return true or false + * `errorThrow` - throw error + * `errorList` - throw list of errors + */ + returnType?: "boolean" | "errorList" | "errorThrow"; + /** If true, the validators will be applied. */ + validators?: boolean | "Post" | "Pre"; +}; + +/** + * @internal + */ +export const OptionsSemVerDefaults: Required = { + loose: true, + returnType: "errorThrow", + validators: true, + rangeMode: false +}; + +// TODO: returnType work properly (validator) + +/** + * Parses a semantic version string or SemVer into object. + * + * @param version - The semantic version to parse. Can be a string or a SemVer object. + * @param options - Parsing options. + * @example + * ``` + * parseSemVer("'1.2.3-beta.1+build.123'") + * ``` + */ +// eslint-disable-next-line complexity + +export function parseSemVer( + inputVersion: Required | Required | SemVer | string, + options: T = OptionsSemVerDefaults as T +): T | boolean extends { rangeMode: false } ? Required : Required { + if (typeof inputVersion != "string" && inputVersion instanceof SemVer) + return resultsFormat(inputVersion) as Required; + + const mergedOptions: Required = { ...OptionsSemVerDefaults, ...options }; + const version = typeof inputVersion === "object" ? formatVersion(inputVersion) : inputVersion; + + // PRE VALIDATION + if (mergedOptions.validators == true || mergedOptions.validators == "Pre") + versionPreValidator(version, { returnType: mergedOptions.returnType }); + + // PARSING + const versionTrimmed = version.trim(); + + const pattrn = (() => { + if (mergedOptions.rangeMode) return PATTERN_RANGE_MODE; + if (mergedOptions.loose) return PATTERN_LOOSE_SEMVER; + return PATTERN_STRICT_SEMVER; + })(); + const match = pattrn.exec(versionTrimmed); + if (!match) throw myError(MYERRORLIST.INVALID_VERSION, { message: { dev: [inputVersion.toString()] } }); + + // POST VALIDATION + const mmpFormat = (value: string): number | "x" => { + if (mergedOptions.rangeMode) return Number.isNaN(Number.parseInt(value, 10)) ? "x" : Number.parseInt(value, 10); + return Number.parseInt(mergedOptions.loose ? value || "0" : value, 10); + }; + + const result = resultsFormat({ + major: mmpFormat(match[1]), + minor: mmpFormat(match[2]), + patch: mmpFormat(match[3]), + prerelease: match[4] + ? match[4].split(".").map(part => (Number.isNaN(Number.parseInt(part)) ? part : Number.parseInt(part, 10))) + : [], + buildmetadata: match[5] + ? match[5].split(".").map(part => (Number.isNaN(Number.parseInt(part)) ? part : Number.parseInt(part, 10))) + : [] + }) as typeof mergedOptions extends { rangeMode: false } ? Required : Required; + + if (mergedOptions.validators == true || mergedOptions.validators == "Pre") + versionPostValidator(result, { returnType: mergedOptions.returnType }); + + return result; +} + +const resultsFormat = ( + data: Omit, "version"> +): Required | Required => ({ + version: function () { + return formatVersion(this); + }, + major: data.major, + minor: data.minor, + patch: data.patch, + prerelease: data.prerelease, + buildmetadata: data.buildmetadata +}); + +export default parseSemVer; diff --git a/packages/semver/src/functions/satisfies.test.ts b/packages/semver/src/functions/satisfies.test.ts new file mode 100644 index 0000000..91a9703 --- /dev/null +++ b/packages/semver/src/functions/satisfies.test.ts @@ -0,0 +1,353 @@ +/* eslint-disable @EslintSonar/no-duplicate-string */ +import { describe, it, expect } from "vitest"; +import satisfies from "./satisfies"; +import { myErrorWrapper } from "oh-my-error"; + +describe("[FUNCTION] satisfies", () => { + describe("TEST", () => { + // it("",()=>{}) + it("1.2.3 satisfies x.X.x", () => { + const [result, isError] = myErrorWrapper(satisfies)("1.2.3", "x.X.x"); + expect(isError).toBe(false); + expect(result).toBe(true); + }); + it("1.2.3 satisfies 1.2.3 || 1.2.4", () => { + const [result, isError] = myErrorWrapper(satisfies)("1.2.3", "1.2.3 || 1.2.4"); + expect(isError).toBe(false); + expect(result).toBe(true); + }); + }); + + describe("[PASS]", () => { + describe("Operators", () => { + it("19.0.1 satisfies >=19.0.0-x", () => { + const [data, isError] = myErrorWrapper(satisfies)("19.0.1", ">=19.0.0-x"); + expect(isError).toEqual(false); + expect(data).toEqual(true); + }); + it("1.2.3", () => { + expect(satisfies("1.2.3", "1.2.3 || 1.2.4")).toEqual(true); + }); + }); + + describe("...", () => { + describe("1.2.3", () => { + it("satisfies 1.2.3 || 1.2.4", () => { + const [data, isError] = myErrorWrapper(satisfies)("1.2.3", "1.2.3 || 1.2.4"); + expect(isError).toBe(false); + expect(data).toEqual(true); + }); + it("satisfies x.x.x", () => { + const [data, isError] = myErrorWrapper(satisfies)("1.2.3", "x.x.x"); + expect(isError).toBe(false); + expect(data).toEqual(true); + }); + it("satisfies 1.x.x", () => { + const [data, isError] = myErrorWrapper(satisfies)("1.2.3", "1.x.x"); + expect(isError).toBe(false); + expect(data).toEqual(true); + }); + it("satisfies 1.2.x", () => { + const [data, isError] = myErrorWrapper(satisfies)("1.2.3", "1.2.x"); + expect(isError).toBe(false); + expect(data).toEqual(true); + }); + it("satisfies 1.x.3", () => { + const [data, isError] = myErrorWrapper(satisfies)("1.2.3", "1.x.3"); + expect(isError).toBe(false); + expect(data).toEqual(true); + }); + it("satisfies x.2.3", () => { + const [data, isError] = myErrorWrapper(satisfies)("1.2.3", "x.2.3"); + expect(isError).toBe(false); + expect(data).toEqual(true); + }); + it("satisfies 1.2.3", () => { + const [data, isError] = myErrorWrapper(satisfies)("1.2.3", "1.2.3"); + expect(isError).toBe(false); + expect(data).toEqual(true); + }); + it("satisfies 1.x.x-x", () => { + const [data, isError] = myErrorWrapper(satisfies)("1.2.3", "1.x.x || 1.x.x-x"); + expect(isError).toBe(false); + expect(data).toEqual(true); + }); + it("satisfies 1.x.x-x+x", () => { + const [data, isError] = myErrorWrapper(satisfies)("1.2.3-prerelease+asd", "1.x.x-x+x"); + expect(isError).toBe(false); + expect(data).toEqual(true); + }); + it("satisfies 1.x.x-x+x", () => { + const [data, isError] = myErrorWrapper(satisfies)("1.2.3-prerelease+asd", "1.x.x"); + expect(isError).toBe(false); + expect(data).toEqual(false); + }); + it("satisfies 1.2.2 - 1.2.5", () => { + const [data, isError] = myErrorWrapper(satisfies)("1.2.3", "1.2.2 - 1.2.5"); + expect(isError).toBe(false); + expect(data).toEqual(true); + }); + // it("satisfies 1.x.x-x+x", () => { + // const [data, isError] = myErrorWrapper(satisfies)("1.0.0-prerelease+asd", "<1.x.x"); + // expect(isError).toBe(false); + // expect(data).toEqual(true); + // }); + }); + }); + }); +}); + +it("ARRAY SATISFIES TEST", () => { + const inputRange = "16.8.0 - 18.3.1"; + + const test = [ + "16.8.0", + "16.8.1", + "16.8.2", + "16.8.3", + "16.8.4", + "16.8.5", + "16.8.6", + "16.9.0", + "16.10.0", + "16.10.1", + "16.10.2", + "16.11.0", + "16.12.0", + "16.13.0", + "16.13.1", + "16.14.0", + "17.0.0", + "17.0.1", + "17.0.2", + "18.0.0", + "18.1.0", + "18.2.0", + "18.3.0", + "18.3.1" + ]; + + const [data, isError] = myErrorWrapper(() => test.filter(item => satisfies(item, inputRange)))(); + + expect(isError).toEqual(false); + expect(data.length).toEqual(test.length); +}); +it("REACT SATISFIES TEST", () => { + const inputRange = "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-x <19.0.0"; + + const test = [ + "16.8.0", + "16.8.1", + "16.8.2", + "16.8.3", + "16.8.4", + "16.8.5", + "16.8.6", + "16.9.0", + "16.10.0", + "16.10.1", + "16.10.2", + "16.11.0", + "16.12.0", + "16.13.0", + "16.13.1", + "16.14.0", + "17.0.0", + "17.0.1", + "17.0.2", + "18.0.0", + "18.1.0", + "18.2.0", + "18.3.0", + "18.3.1", + "19.0.0-canary-2b036d3f1-20240327", + "19.0.0-canary-05797cceb-20240328", + "19.0.0-canary-a73c3450e-20240329", + "19.0.0-canary-95e6f032c-20240401", + "19.0.0-canary-48ec17b86-20240402", + "19.0.0-canary-7a2609eed-20240403", + "19.0.0-canary-fd0da3eef-20240404", + "19.0.0-canary-e3ebcd54b-20240405", + "19.0.0-canary-4c12339ce-20240408", + "19.0.0-canary-adb717393-20240411", + "19.0.0-canary-96c584661-20240412", + "19.0.0-canary-8afa144bd-20240416", + "19.0.0-canary-657428a9e-20240416", + "19.0.0-canary-36e62c603-20240418", + "19.0.0-canary-33a32441e9-20240418", + "19.0.0-canary-db913d8e17-20240422", + "19.0.0-canary-cb151849e1-20240424", + "19.0.0-canary-cf5ab8b8b2-20240425", + "19.0.0-beta-94eed63c49-20240425", + "19.0.0-beta-4508873393-20240430", + "19.0.0-beta-73bcdfbae5-20240502", + "19.0.0-beta-1beb73de0f-20240503", + "19.0.0-beta-5d29478716-20240506", + "19.0.0-beta-b498834eab-20240506", + "19.0.0-beta-e7d213dfb0-20240507", + "19.0.0-beta-6946ebe620-20240508", + "19.0.0-beta-04b058868c-20240508", + "19.0.0-beta-9d76c954cf-20240510", + "19.0.0-beta-26f2496093-20240514", + "19.0.0-rc-915b914b3a-20240515", + "19.0.0-rc-3f1436cca1-20240516", + "19.0.0-rc-57fbe3ba37-20240520", + "19.0.0-rc-d3ce0d3ea9-20240520", + "19.0.0-rc-8f3c0525f9-20240521", + "19.0.0-rc-81c5ff2e04-20240521", + "19.0.0-rc-3ac551e855-20240522", + "19.0.0-rc-f994737d14-20240522", + "19.0.0-rc-4c2e457c7c-20240522", + "19.0.0-rc-935180c7e0-20240524", + "19.0.0-rc-6f23540c7d-20240528", + "19.0.0-rc-38e3b23483-20240529", + "19.0.0-rc-9d4fba0788-20240530", + "19.0.0-rc-6d3110b4d9-20240531", + "19.0.0-rc-9598c41a20-20240603", + "19.0.0-rc.0", + "19.0.0-rc-bf3a29d097-20240603", + "19.0.0-rc-1df34bdf62-20240605", + "19.0.0-rc-eb259b5d3b-20240605", + "19.0.0-rc-99da76f23a-20240606", + "19.0.0-rc-827cbea417-20240606", + "19.0.0-rc-cc1ec60d0d-20240607", + "19.0.0-rc-20b6f4c0e8-20240607", + "19.0.0-rc-a532d91d01-20240610", + "19.0.0-rc-34d0c5e357-20240607", + "19.0.0-rc-6230622a1a-20240610", + "19.0.0-rc-a26e3f403e-20240611", + "19.0.0-rc-f3e09d6328-20240612", + "19.0.0-rc-dfd30974ab-20240613", + "19.0.0-rc-fb9a90fa48-20240614", + "19.0.0-rc-107a2f8c3e-20240617", + "19.0.0-rc-1434af3d22-20240618", + "19.0.0-rc-e684ca66ab-20240619", + "19.0.0-rc-6fb39ec9e9-20240621", + "19.0.0-rc-3563387fe3-20240621", + "19.0.0-rc-c21bcd627b-20240624", + "19.0.0-rc-8971381549-20240625", + "19.0.0-rc-e02baf6c92-20240627", + "19.0.0-rc-58af67a8f8-20240628", + "19.0.0-rc-100dfd7dab-20240701", + "19.0.0-rc-9c6806964f-20240703", + "19.0.0-rc-3da26163a3-20240704", + "19.0.0-rc-f38c22b244-20240704", + "19.0.0-rc-df783f9ea1-20240708", + "19.0.0-rc-c3cdbec0a7-20240708", + "19.0.0-rc-378b305958-20240710", + "19.0.0-rc-85acf2d195-20240711", + "19.0.0-rc-df5f2736-20240712", + "19.0.0-rc-8b08e99e-20240713", + "19.0.0-rc-01172397-20240716", + "19.0.0-rc-163365a0-20240717", + "19.0.0-rc-512b09b2-20240718", + "19.0.0-rc-d025ddd3-20240722", + "19.0.0-rc-f6cce072-20240723", + "19.0.0-rc-ab2135c7-20240724", + "19.0.0-rc-76002254-20240724", + "19.0.0-rc-14a4699f-20240725", + "19.0.0-rc-941e1b4a-20240729", + "19.0.0-rc-ab7c1663-20240730", + "19.0.0-rc-3208e73e-20240730", + "19.0.0-rc-a7d1240c-20240731", + "19.0.0-rc-06d0b89e-20240801", + "19.0.0-rc-8269d55d-20240802", + "19.0.0-rc-65903583-20240805", + "19.0.0-rc-187dd6a7-20240806", + "19.0.0-rc-e948a5ac-20240807", + "19.0.0-rc-9d2da591-20240808", + "19.0.0-rc-2d2cc042-20240809", + "19.0.0-rc-68dbd84b-20240812", + "19.0.0-rc-d48603a5-20240813", + "19.0.0-rc-49496d49-20240814", + "19.0.0-rc-19bd26be-20240815", + "19.0.0-rc-fa6eab58-20240815", + "19.0.0-rc-1eaccd82-20240816", + "19.0.0-rc-6ebfd5b0-20240818", + "19.0.0-rc-a960b92c-20240819", + "19.0.0-rc-1d989965-20240821", + "19.0.0-rc-eb3ad065-20240822", + "19.0.0-rc-b57d2823-20240822", + "19.0.0-rc-f65ac7bd-20240826", + "19.0.0-rc-f90a6bcc-20240827", + "19.0.0-rc-7771d3a7-20240827", + "19.0.0-rc-a19a8ab4-20240829", + "19.0.0-rc-e56f4ae3-20240830", + "19.0.0-rc-4f604941-20240830", + "19.0.0-rc-d1afcb43-20240903", + "19.0.0-rc-4c58fce7-20240904", + "19.0.0-rc-a03254bc-20240905", + "19.0.0-rc-e210d081-20240909", + "19.0.0-rc-3dfd5d9e-20240910", + "19.0.0-rc-d6cb4e77-20240911", + "19.0.0-rc-47352209-20240912", + "19.0.0-rc-94e652d5-20240912", + "19.0.0-rc-206df66e-20240912", + "19.0.0-rc-ee1a403a-20240916", + "19.0.0-rc-f2df5694-20240916", + "19.0.0-rc-a99d8e8d-20240916", + "19.0.0-rc-5dcb0097-20240918", + "19.0.0-rc-e740d4b1-20240919", + "19.0.0-rc-e4953922-20240919", + "19.0.0-rc-5d19e1c8-20240923", + "19.0.0-rc-04bd67a4-20240924", + "19.0.0-rc-f9ebd85a-20240925", + "19.0.0-rc-778e1ed2-20240926", + "19.0.0-rc-204a551e-20240926", + "19.0.0-rc-67fee58b-20240926", + "19.0.0-rc-3edc000d-20240926" + ]; + + const [data, isError] = myErrorWrapper(() => test.filter(item => satisfies(item, inputRange)))(); + + expect(isError).toEqual(false); + expect(data.length).toEqual(test.length); +}); + +it("2.0.0 does not satisfy 1.x.x", () => { + expect(satisfies("2.0.0", "1.x.x")).toEqual(false); +}); +it("1.2.3 satisfies 1.2.*", () => { + expect(satisfies("1.2.3", "1.2.*")).toEqual(true); +}); +it("1.3.0 does not satisfy 1.2.*", () => { + expect(satisfies("1.3.0", "1.2.*")).toEqual(false); +}); +it("1.2.3 satisfies *", () => { + expect(satisfies("1.2.3", "*")).toEqual(true); +}); +it("1.2.3 satisfies x.x.x", () => { + expect(satisfies("1.2.3", "x.x.x")).toEqual(true); +}); +it("array satisfies 1.0.0 - 2.0.0", () => { + // const testArray = ["1.0.0", "1.0.1", "1.1.0", "1.1.1", "1.2.0", "1.2.1", "1.3.0", "1.3.1", "2.0.0", "1.0.2"]; + const range = "1.0.0 - 2.0.0"; + const [result, isError] = myErrorWrapper(satisfies)("1.0.0", range); + expect(isError).toBe(false); + expect(result).toEqual(true); +}); +// }); +describe("Mixed patterns", () => { + it("1.2.3 satisfies >1.0.0 <2.x.x", () => { + expect(satisfies("1.2.3", ">1.0.0 <2.x.x")).toEqual(true); + }); + it("2.0.0 does not satisfy >1.0.0 <2.x.x", () => { + expect(satisfies("2.0.0", ">1.0.0 <2.x.x")).toEqual(false); + }); + it("1.2.3 satisfies 1.x.x || >2.0.0", () => { + expect(satisfies("1.2.3", "1.x.x || >2.0.0")).toEqual(true); + }); + it("3.0.0 satisfies 1.x.x || >2.0.0", () => { + expect(satisfies("3.0.0", "1.x.x || >2.0.0")).toEqual(true); + }); +}); +// // }); + +// // describe("[ERROR]", () => { +// // // ... (poprzednie testy bΕ‚Δ™dΓ³w pozostajΔ… bez zmian) + +// // it("Throws error for invalid wildcard pattern", () => { +// // expect(() => satisfies("1.0.0", "1.*.2")).toThrow(); +// // }); +// // }); +// }); diff --git a/packages/semver/src/functions/satisfies.ts b/packages/semver/src/functions/satisfies.ts new file mode 100644 index 0000000..ff095f8 --- /dev/null +++ b/packages/semver/src/functions/satisfies.ts @@ -0,0 +1,125 @@ +/* eslint-disable complexity */ +import type { TOptionsSemVer } from "@/functions"; +import { compareSemver, OptionsSemVerDefaults, parseSemVer } from "@/functions"; + +//------------------------- +// Types +//------------------------- + +/** @internal */ +export type TOperator = "-" | "*" | "^" | "<" | "<=" | "=" | ">" | ">=" | "~" | "x"; + +/** @internal */ +export type TCondition = [TOperator, string]; + +//------------------------- +// Functions +//------------------------- + +/** + * Determines whether a version satisfies a specified version range. + * + * @description + * This function checks if a given version number meets the constraints specified in a version range string. + * It supports various range formats including: + * - Hyphenated ranges (e.g., "1.2.3 - 2.0.0") + * - Multiple conditions (e.g., ">=1.2.3 <2.0.0") + * - Simple comparisons (e.g., ">=1.2.3") + * + * @param versionInput - The version number to check. Can be a string or any valid input accepted by parseSemVer. + * @param range - A string specifying the version range to test against. + * Examples: "1.2.3", ">=1.2.3", "1.2.3 - 2.0.0", ">=1.2.3 <2.0.0" + * @param options - Optional configuration options for version parsing and comparison. + * + * @returns boolean - Returns true if the version satisfies the range, false otherwise. + * + * @example + * ```typescript + * satisfies('1.2.3', '>=1.0.0'); // true + * satisfies('2.0.0', '1.0.0 - 3.0.0'); // true + * satisfies('1.2.3', '>2.0.0'); // false + * ``` + */ +export function satisfies( + versionInput: Parameters>[0], + range: string, + options: TOptionsSemVer = OptionsSemVerDefaults +): boolean { + const mergedOptions = { ...OptionsSemVerDefaults, ...options, rangeMode: true }; + + const version = parseSemVer(versionInput, mergedOptions); + const parsedRanges = parseRange(range); + + return parsedRanges.some(subRange => { + if (subRange.length === 3) { + const [start, hyphen, end] = subRange; + if (hyphen[0] === "-") { + const result = + checkCondition(version, [">=", start[1]], mergedOptions) && + checkCondition(version, ["<=", end[1]], mergedOptions); + return result; + } + } else if (subRange.length == 2) { + const [start, end] = subRange; + const result = checkCondition(version, start, mergedOptions) && checkCondition(version, end, mergedOptions); + return result; + } + return subRange.every(condition => checkCondition(version, condition, mergedOptions)); + }); +} + +/** + * @internal + */ +export function parseRange(range: string): TCondition[][] { + return range.split(/\s*\|\|\s*/u).map(subRange => + subRange.split(/\s+/u).map(part => { + const match = /^(>=|<=|[<=>^~-])?\s*(.*)$/u.exec(part); + return match ? ([match[1] || "=", match[2]] as TCondition) : ["=", part]; + }) + ); +} + +/** + * @internal + */ +export function checkCondition( + version: ReturnType, + range: TCondition, + options: TOptionsSemVer = OptionsSemVerDefaults +): boolean { + const [operator, versionString] = range; + const version2 = parseSemVer(versionString, options); + + const comparison = compareSemver(version, versionString, options); + switch (operator) { + case "*": + case "x": + case "=": { + return comparison === 0; + } + case ">": { + return comparison > 0; + } + case ">=": { + return comparison >= 0; + } + case "<": { + return comparison < 0; + } + case "<=": { + return comparison <= 0; + } + case "^": { + return version.major == version2.major; + } + case "~": { + return version.major == version2.major && version.minor == version2.minor && comparison === 0; + } + default: { + return true; + } + } +} + +export default satisfies; diff --git a/packages/semver/src/functions/simplifyRange.test.ts b/packages/semver/src/functions/simplifyRange.test.ts new file mode 100644 index 0000000..889a2d0 --- /dev/null +++ b/packages/semver/src/functions/simplifyRange.test.ts @@ -0,0 +1,87 @@ +import { describe, expect, it } from "vitest"; +import simplifyRange from "./simplifyRange"; +import type { TOptionsSemVer } from "./parseSemVer"; + +describe("simplifyRange", () => { + // Basic functionality tests + it("should handle empty version array", () => { + const versions: string[] = []; + const range = ">=1.0.0"; + expect(simplifyRange(versions, range)).toBe(""); + }); + + it("should return single version for matching consecutive versions", () => { + const versions = ["1.0.0", "1.0.0"]; + const range = ">=1.0.0"; + const result = simplifyRange(versions, range); + expect(result).toBe("*"); + }); + + it("should return * for all versions matching from start", () => { + const versions = ["1.0.0", "1.1.0", "1.2.0"]; + const range = ">=0.0.0 <=2.0.0"; + expect(simplifyRange(versions, range)).toBe("*"); + }); + + it("should handle mixed matching and non-matching versions", () => { + const versions = ["1.0.0", "2.0.0", "3.0.0", "4.0.0"]; + const range = ">=1.0.0 <=2.0.0"; + const result = simplifyRange(versions, range); + expect(result).toBe("<=2.0.0"); + }); + + it("should create >= range for versions matching to end", () => { + const versions = ["1.0.0", "1.1.0", "1.2.0"]; + const range = ">=1.0.0"; + const result = simplifyRange(versions, range); + expect(result).toBe("*"); + }); + + it("should create <= range for versions matching from start", () => { + const versions = ["1.0.0", "1.1.0", "1.2.0"]; + const range = "<=1.2.0"; + const result = simplifyRange(versions, range); + expect(result).toBe("*"); + }); + + it("should handle multiple ranges with ||", () => { + const versions = ["1.0.0", "1.1.0", "2.0.0", "2.1.0", "3.0.0"]; + const range = ">=1.0.0 <=1.1.0 || >=2.0.0 <=2.1.0"; + const result = simplifyRange(versions, range); + expect(result).toBe("<=2.1.0"); + }); + + it("should keep original range if simplified version would be longer", () => { + const versions = ["1.0.0", "1.1.0", "1.2.0"]; + const range = "^1.0.0"; + expect(simplifyRange(versions, range)).toBe("*"); + }); + + it("should handle versions with pre-release tags", () => { + const versions = ["1.0.0-alpha", "1.0.0-beta", "1.0.0"]; + const range = ">=1.0.0-alpha <=1.0.0"; + const result = simplifyRange(versions, range); + expect(result).toBe("*"); + }); + + it("should respect options in version comparison", () => { + const versions = ["1.0", "1.1", "1.2"]; + const range = ">=1.0.0 <=1.2.0"; + const options: Partial = { loose: true }; + const result = simplifyRange(versions, range, options); + expect(result).toBe("*"); + }); + + it("should handle non-matching versions", () => { + const versions = ["1.0.0", "2.0.0", "3.0.0"]; + const range = ">=4.0.0"; + expect(simplifyRange(versions, range)).toBe(""); + }); + + it("should handle disjoint ranges properly", () => { + const versions = ["1.0.0", "1.1.0", "2.0.0", "2.1.0", "3.0.0"]; + const range = ">=1.0.0 <1.2.0 || >=2.0.0 <2.2.0"; + const result = simplifyRange(versions, range); + expect(result).toBe("<=2.1.0"); + }); +}); diff --git a/packages/semver/src/functions/simplifyRange.ts b/packages/semver/src/functions/simplifyRange.ts new file mode 100644 index 0000000..87f8083 --- /dev/null +++ b/packages/semver/src/functions/simplifyRange.ts @@ -0,0 +1,63 @@ +/* eslint-disable complexity */ +import { satisfies } from "./satisfies"; +import { compareSemver } from "./compare"; +import { OptionsSemVerDefaults } from "./parseSemVer"; +import type { TOptionsSemVer } from "./parseSemVer"; + +//---------------------- +// Functions +//---------------------- + +/** + * Simplifies a version range by creating the shortest possible range expression that matches + * the same set of versions as the input range. + * + * @param versions - Array of version strings to consider + * @param range - Original version range to simplify + * @param options - Options for version parsing and comparison + * + * @returns The simplified range if shorter than original, otherwise the original range + * + * @example + * // Returns "*" + * simplifyRange(["1.0.0", "1.1.0", "1.2.0"], ">=1.0.0 <=1.2.0") + * + */ +export function simplifyRange( + versions: string[], + range: string, + options: Partial = OptionsSemVerDefaults +): string { + const set: Array<[string, string | undefined]> = []; + let first: string | undefined = void 0; + let prev: string | undefined = void 0; + + const sortedVersions = versions.sort((a, b) => compareSemver(a, b, options)); + + for (const version of sortedVersions) { + const included = satisfies(version, range, options); + if (included) { + prev = version; + if (!first) first = version; + } else { + if (prev) set.push([first!, prev]); + [prev, first] = [void 0, void 0]; + } + } + + if (first) set.push([first, undefined]); + + const ranges: string[] = []; + for (const [min, max] of set) { + if (min === max) ranges.push(min); + else if (!max && min === sortedVersions[0]) ranges.push("*"); + else if (!max) ranges.push(`>=${min}`); + else if (min === sortedVersions[0]) ranges.push(`<=${max}`); + else ranges.push(`${min} - ${max}`); + } + + const simplified = ranges.join(" || "); + return simplified.length < range.length ? simplified : range; +} + +export default simplifyRange; diff --git a/packages/semver/src/functions/versionValidator.test.ts b/packages/semver/src/functions/versionValidator.test.ts new file mode 100644 index 0000000..e06ce0e --- /dev/null +++ b/packages/semver/src/functions/versionValidator.test.ts @@ -0,0 +1,73 @@ +import { describe, expect, it, test } from "vitest"; +import { versionPreValidator, MYERRORLIST_PRE, MYERRORLIST_POST, versionPostValidator } from "./versionValidator"; +import { myErrorWrapper } from "oh-my-error"; +import { MAX_SAFE_BUILD_LENGTH, MAX_SAFE_INTEGER } from "@/internals/constants"; +import { SemVer } from "@/classes"; + +describe("Version Validators", () => { + describe("[FUNCTION] versionPreValidator", () => { + describe("[ERROR]", () => { + it("NULL_VERSION - for input `null`", () => { + const [error, isError] = myErrorWrapper(versionPreValidator)(null); + expect(isError).toEqual(true); + expect(error).toEqual(MYERRORLIST_PRE.NULL_VERSION); + }); + it("UNDEFINED_VERSION - for input `void 0` (basic undefined)", () => { + const [error, isError] = myErrorWrapper(versionPreValidator)(void 0); + expect(isError).toEqual(true); + expect(error).toEqual(MYERRORLIST_PRE.UNDEFINED_VERSION); + }); + it(`TOO_LONG_LENGTH_VERSION - for input string longer than ${MAX_SAFE_BUILD_LENGTH}`, () => { + const [error, isError] = myErrorWrapper(versionPreValidator)("a".repeat(MAX_SAFE_BUILD_LENGTH + 1)); + + expect(isError).toEqual(true); + expect(error).toEqual(MYERRORLIST_PRE.TOO_LONG_LENGTH_VERSION); + }); + it(`INVALID_TYPE - for input which is not Parameters[0]`, () => { + const [error, isError] = myErrorWrapper(versionPreValidator)(13); + + expect(isError).toEqual(true); + expect(error).toEqual(MYERRORLIST_PRE.INVALID_TYPE); + }); + }); + describe("[PASS]", () => { + test("SemVer as Input", () => { + const Input = new SemVer("1.2.3"); + + const [data, isError] = myErrorWrapper(versionPreValidator)(Input); + expect(isError).toEqual(false); + expect(data).toEqual(true); + }); + }); + }); + describe("[FUNCTION] versionPostValidator", () => { + describe("[ERROR]", () => { + describe("INVALID_VERSION_MAJOR", () => { + it(`Inputed Major smaller than 0`, () => { + const [error, isError] = myErrorWrapper(versionPostValidator)({ + buildmetadata: [], + major: -1, + minor: 2, + patch: 3, + prerelease: [], + version: () => "" + }); + expect(isError).toEqual(true); + expect(error).toEqual(MYERRORLIST_POST.INVALID_VERSION_MAJOR); + }); + it(`Input bigger than ${MAX_SAFE_INTEGER} (MAX_SAFE_INTEGER)`, () => { + const [error, isError] = myErrorWrapper(versionPostValidator)({ + buildmetadata: [], + major: MAX_SAFE_INTEGER + 1, + minor: 2, + patch: 3, + prerelease: [], + version: () => "" + }); + expect(isError).toEqual(true); + expect(error).toEqual(MYERRORLIST_POST.INVALID_VERSION_MAJOR); + }); + }); + }); + }); +}); diff --git a/packages/semver/src/functions/versionValidator.ts b/packages/semver/src/functions/versionValidator.ts new file mode 100644 index 0000000..3713b4c --- /dev/null +++ b/packages/semver/src/functions/versionValidator.ts @@ -0,0 +1,144 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable complexity */ +/* eslint-disable @EslintSonar/no-duplicate-string */ +import { MAX_SAFE_BUILD_LENGTH, MAX_SAFE_INTEGER } from "@/internals/constants"; +import type { TValidationList } from "@/utils"; +import { isX, validator } from "@/utils"; +import type { TMyErrorList } from "oh-my-error"; +import type parseSemVer from "./parseSemVer"; + +//---------------------- +// Errors +//---------------------- + +/** + * @internal + */ +export const MYERRORLIST_PRE = { + NULL_VERSION: { + code: "NULL_VERSION", + hint: { user: "Provide a non-null version", dev: "Check input to function it's not null." }, + name: "Null Version Error", + message: { + dev: "Version cannot be null.", + user: "Please provide a valid version - can't be null." + } + }, + INVALID_TYPE: { + code: "INVALID_TYPE", + hint: { dev: "Check input to function it's string", user: "Input correct version input type." }, + message: { dev: "Version is not a string", user: "Version must be a string." }, + name: "Invalid Type Error" + }, + UNDEFINED_VERSION: { + code: "UNDEFINED_VERSION", + hint: { user: "Missing version" }, + name: "Undefined Version Error", + message: { + dev: "Version cannot be undefined", + user: "Please provide a valid version." + } + }, + TOO_LONG_LENGTH_VERSION: { + code: "TOO_LONG_LENGTH_VERSION", + hint: { user: `Shorten the name to ${MAX_SAFE_BUILD_LENGTH} characters or less` }, + message: { + dev: `Name cannot contain more than ${MAX_SAFE_BUILD_LENGTH} characters`, + user: `The name is too long. Please use ${MAX_SAFE_BUILD_LENGTH} characters or less.` + }, + name: "Too Long Name Error" + } +} as const satisfies TMyErrorList; + +const templateInvalidVersion = (part: "Major" | "Minor" | "Patch") => + `${part} version is not in range 0 to ${MAX_SAFE_INTEGER}` as const; + +/** + * @internal + */ +export const MYERRORLIST_POST = { + INVALID_VERSION_MINOR: { + code: "INVALID_VERSION_MINOR", + name: "Invalid version number", + hint: {}, + message: { user: (() => templateInvalidVersion("Minor"))() } + }, + INVALID_VERSION_MAJOR: { + code: "INVALID_VERSION_MAJOR", + name: "Invalid version number", + hint: {}, + message: { user: (() => templateInvalidVersion("Major"))() } + }, + INVALID_VERSION_PATCH: { + code: "INVALID_VERSION_PATCH", + name: "Invalid version number", + hint: {}, + message: { user: (() => templateInvalidVersion("Patch"))() } + } +} as const satisfies TMyErrorList; + +//---------------------- +// Functions +//---------------------- + +/** + * @internal + */ +export const versionPreValidator = (version: unknown, options?: Parameters[0]["options"]) => { + const ValidationList: TValidationList = { + NULL_VERSION: { condition: (version): version is null => version === null, exit: true }, + UNDEFINED_VERSION: { condition: (version): version is undefined => version === undefined, exit: true }, + INVALID_TYPE: { + // condition: version => !(version instanceof SemVer) && typeof version !== "string", + condition: version => + !(typeof version === "object" && version !== null && "format" in version) && typeof version !== "string", + exit: true + }, + TOO_LONG_LENGTH_VERSION: { + condition: (version): boolean => typeof version === "string" && version.length > MAX_SAFE_BUILD_LENGTH + } + } as const; + + return validator({ + data: version, + options, + MyErrorList: MYERRORLIST_PRE, + ValidationList: ValidationList + }); +}; + +/** + * @internal + */ +export const versionPostValidator = ( + version: ReturnType, + options?: Parameters[0]["options"], + rangeMode = false +) => { + const isInValidVersionNumber = (num: any): boolean => { + if (rangeMode && isX(num)) { + return false; + } + return num > MAX_SAFE_INTEGER || num < 0; + }; + // const isInValidVersionNumber = (num: number): boolean => num > MAX_SAFE_INTEGER || num < 0; + const ValidationList: TValidationList< + typeof MYERRORLIST_POST, + ReturnType> + > = { + // TODO: Change this version:any to Generic, problem in validation.ts + INVALID_VERSION_MAJOR: { + condition: (version): boolean => isInValidVersionNumber(version.major) + }, + INVALID_VERSION_MINOR: { condition: version => isInValidVersionNumber(version.minor) }, + INVALID_VERSION_PATCH: { condition: version => isInValidVersionNumber(version.patch) } + } as const; + + return validator({ + data: version, + options, + MyErrorList: MYERRORLIST_POST, + ValidationList: ValidationList + }); +}; diff --git a/packages/semver/src/index.ts b/packages/semver/src/index.ts new file mode 100644 index 0000000..c0493d0 --- /dev/null +++ b/packages/semver/src/index.ts @@ -0,0 +1,2 @@ +export * from "@/functions"; +export * from "@/internals"; diff --git a/packages/semver/src/internals/constants.ts b/packages/semver/src/internals/constants.ts new file mode 100644 index 0000000..271b3f0 --- /dev/null +++ b/packages/semver/src/internals/constants.ts @@ -0,0 +1,46 @@ +// Explanatory comment +/** + * This module implements the semver.org version 2.0.0 specification. + * Note: The version here refers to the spec, not necessarily the package version of this code. + * @packageDocumentation semver-constants + */ + +/** + * The version of the SemVer specification that this module implements. + * @internal + */ +export const SEMVER_SPEC_VERSION = "2.0.0" as const; + +/** + * The maximum length allowed for a SemVer string. + * @internal + */ +export const MAX_LENGTH = 256 as const; + +/** + * The maximum safe integer value in JavaScript. + * @internal + */ +export const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9_007_199_254_740_991; + +/** + * Constants for safe lengths and component sizes + * @internal + */ +export const MAX_SAFE_COMPONENT_LENGTH = 16; + +/** + * Max safe length for a build identifier. + * The max length minus 6 characters for the shortest version with a build 0.0.0+BUILD. + * @internal + */ +export const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6; + +/** + * Valid release types in SemVer. + */ +export type TReleases = (typeof RELEASE_TYPES)[number]; +/** + * Valid release types in SemVer. + */ +export const RELEASE_TYPES = ["major", "premajor", "minor", "preminor", "patch", "prepatch", "prerelease"] as const; // Maybe change on `new Set`? diff --git a/packages/semver/src/internals/index.ts b/packages/semver/src/internals/index.ts new file mode 100644 index 0000000..b04bfcf --- /dev/null +++ b/packages/semver/src/internals/index.ts @@ -0,0 +1 @@ +export * from "./constants"; diff --git a/packages/semver/src/types.ts b/packages/semver/src/types.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/semver/src/utils/index.ts b/packages/semver/src/utils/index.ts new file mode 100644 index 0000000..6f82562 --- /dev/null +++ b/packages/semver/src/utils/index.ts @@ -0,0 +1,3 @@ +export * from "./validation"; +export * from "./isSet"; +export * from "./isX"; diff --git a/packages/semver/src/utils/isSet.ts b/packages/semver/src/utils/isSet.ts new file mode 100644 index 0000000..5df087f --- /dev/null +++ b/packages/semver/src/utils/isSet.ts @@ -0,0 +1,5 @@ +import { SemVer } from "@/classes"; + +export const isSemVer = (variable: unknown): boolean => variable instanceof SemVer; + +export default isSemVer; diff --git a/packages/semver/src/utils/isX.ts b/packages/semver/src/utils/isX.ts new file mode 100644 index 0000000..1dfcac3 --- /dev/null +++ b/packages/semver/src/utils/isX.ts @@ -0,0 +1,5 @@ +export const rangeArrayToInclude = ["x", "X", "*"] as const; + +export const isX = (value: unknown[] | number | string): boolean => /[*Xx]/u.test(String(value)); +// export const isX = (value: number | string): boolean => +// Array.isArray(value) ? arrayToInclude.includes(()=>{}) : arrayToInclude.includes(String(value)); diff --git a/packages/semver/src/utils/validation.test.ts b/packages/semver/src/utils/validation.test.ts new file mode 100644 index 0000000..b7fedcc --- /dev/null +++ b/packages/semver/src/utils/validation.test.ts @@ -0,0 +1,133 @@ +import { describe, expect, it } from "vitest"; +import type { TValidationList } from "./validation"; +import { validator } from "./validation"; +import { myErrorWrapper } from "oh-my-error"; +import type { TMyErrorList } from "oh-my-error"; + +describe("validator function", () => { + const MyErrorList = { + INVALID_TYPE: { + code: "INVALID_TYPE", + hint: {}, + message: { dev: "Input is not a string", user: "Input must be a string." }, + name: "Invalid Type Error" + }, + TOO_SHORT: { + code: "TOO_SHORT", + hint: {}, + message: { dev: "Input is too short", user: "Input must be at least 3 characters long." }, + name: "Too Short Error" + }, + CONTAINS_SPECIAL_CHAR: { + code: "CONTAINS_SPECIAL_CHAR", + hint: {}, + message: { dev: "Input contains special characters", user: "Input must not contain special characters." }, + name: "Special Character Error" + } + } as const satisfies TMyErrorList; + + const ValidationList: TValidationList = { + INVALID_TYPE: { + condition: version => typeof version !== "string", + exit: true + }, + TOO_SHORT: { + condition: version => typeof version === "string" && version.length < 3 + }, + CONTAINS_SPECIAL_CHAR: { + condition: version => typeof version === "string" && /[!"#$%&()*,.:<>?@^{|}]/u.test(version) + } + }; + + it("[ERROR TEST] - returnType:'boolean' - Invalid type - return false", () => { + expect( + validator({ + MyErrorList: MyErrorList, + ValidationList: ValidationList, + options: { returnType: "boolean" }, + data: 3333 + }) + ).toEqual(false); + }); + + it("[ERROR TEST] - returnType:'errorList' - Invalid type - return { errors: [MyErrorList.INVALID_TYPE] }", () => { + expect( + validator({ + MyErrorList: MyErrorList, + ValidationList: ValidationList, + options: { returnType: "errorList" }, + data: 3333 + }) + ).toEqual({ errors: [MyErrorList.INVALID_TYPE] }); + }); + + it("[ERROR TEST] - returnType:'errorThrow' - Invalid type - throw myError", () => { + const [data, isError] = myErrorWrapper(validator)({ + MyErrorList: MyErrorList, + ValidationList: ValidationList, + options: { returnType: "errorThrow" }, + data: 3333 + }); + + expect(isError).toBe(true); + expect(data).toEqual(MyErrorList.INVALID_TYPE); + }); + + // Nowe testy + + it("[SUCCESS TEST] - returnType:'boolean' - Valid input - return true", () => { + expect( + validator({ + MyErrorList: MyErrorList, + ValidationList: ValidationList, + options: { returnType: "boolean" }, + data: "valid string" + }) + ).toEqual(true); + }); + + it("[ERROR TEST] - returnType:'errorList' - Multiple errors - return all errors", () => { + expect( + validator({ + MyErrorList: MyErrorList, + ValidationList: ValidationList, + options: { returnType: "errorList" }, + data: "a!" + }) + ).toEqual({ errors: [MyErrorList.TOO_SHORT, MyErrorList.CONTAINS_SPECIAL_CHAR] }); + }); + + it("[SUCCESS TEST] - returnType:'errorList' - Valid input - return empty errors array", () => { + expect( + validator({ + MyErrorList: MyErrorList, + ValidationList: ValidationList, + options: { returnType: "errorList" }, + data: "valid string" + }) + ).toEqual({ errors: [] }); + }); + + it("[ERROR TEST] - returnType:'errorThrow' - First error throws - other errors are not checked", () => { + const [data, isError] = myErrorWrapper(validator)({ + MyErrorList: MyErrorList, + ValidationList: ValidationList, + options: { returnType: "errorThrow" }, + data: "a!" + }); + + expect(isError).toBe(true); + expect(data).toEqual(MyErrorList.TOO_SHORT); + }); + + it("[TEST] - Default returnType is 'errorThrow'", () => { + const [data, isError] = myErrorWrapper(validator)({ + MyErrorList: MyErrorList, + ValidationList: ValidationList, + data: 3333 + }); + + expect(isError).toBe(true); + expect(data).toEqual(MyErrorList.INVALID_TYPE); + }); +}); diff --git a/packages/semver/src/utils/validation.ts b/packages/semver/src/utils/validation.ts new file mode 100644 index 0000000..8d83d05 --- /dev/null +++ b/packages/semver/src/utils/validation.ts @@ -0,0 +1,36 @@ +import type { IMyError, TMyErrorList } from "oh-my-error"; +import { myError } from "oh-my-error"; + +//---------------------- +// Interfaces & Types +//---------------------- + +// export type TValidationList = Record boolean; exit?: boolean }>; +export type TValidationList = Record boolean; exit?: boolean }>; + +//---------------------- +// Functions +//---------------------- + +export const validator = (props: { + MyErrorList: TMyErrorList; + ValidationList: TValidationList; + data: unknown; + options?: { returnType: "boolean" | "errorList" | "errorThrow" }; +}): boolean | { errors: TMyErrorList } => { + const { data, MyErrorList, ValidationList, options = { returnType: "errorThrow" } } = props; + + const result = options.returnType === "errorList" ? { errors: [] } : true; + // eslint-disable-next-line guard-for-in + for (const key in ValidationList) { + const currentValidation = ValidationList[key]; + if (Object.hasOwn(ValidationList, key) && currentValidation.condition(data as any)) { + if (options.returnType === "boolean") return false; + if (options.returnType === "errorThrow") throw myError(MyErrorList[key]); + + (result as { errors: IMyError[] }).errors.push(MyErrorList[key]); + if (currentValidation.exit) return result as any; + } + } + return result as any; +}; diff --git a/packages/semver/tsconfig.json b/packages/semver/tsconfig.json new file mode 100644 index 0000000..98ebf0c --- /dev/null +++ b/packages/semver/tsconfig.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json.schemastore.org/tsconfig", + "compilerOptions": { + "outDir": "./dist", + "baseUrl": "./src", + "paths": { + "@/*": ["*"] + }, + "skipLibCheck": true, + "esModuleInterop": true, + "isolatedModules": true, + "noEmit": true, + "stripInternal": true + }, + "include": ["src", "eslint.config.js", "vite.config.ts"], + "exclude": ["node_modules", "dist"], + "extends": "@ineedj/tsconfig/base.json" +} diff --git a/packages/semver/vitest.config.ts b/packages/semver/vitest.config.ts new file mode 100644 index 0000000..bb18bf2 --- /dev/null +++ b/packages/semver/vitest.config.ts @@ -0,0 +1,14 @@ +import { defineConfig } from "vitest/config"; +import { resolve } from "path"; + +export default defineConfig({ + test: { + include: [ + "./src/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}", + "./src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}" + ], + alias: { + "@": resolve(__dirname, "./src") + } + } +}); diff --git a/packages/validate-npm-package-name/eslint.config.js b/packages/validate-npm-package-name/eslint.config.js index de41b1f..6ecc9e2 100644 --- a/packages/validate-npm-package-name/eslint.config.js +++ b/packages/validate-npm-package-name/eslint.config.js @@ -33,7 +33,8 @@ export default ineedj({ }).removeRules( "@EslintSecurity/detect-object-injection", "@typescript-eslint/no-throw-literal", - "@EslintImports/namespace" + "@EslintImports/namespace", + "@EslintUnicorn/no-nested-ternary" ); // export default []; diff --git a/packages/validate-npm-package-name/src/functions/name/isScopedPackage.ts b/packages/validate-npm-package-name/src/functions/name/isScopedPackage.ts index 966ab8b..e9f4b33 100644 --- a/packages/validate-npm-package-name/src/functions/name/isScopedPackage.ts +++ b/packages/validate-npm-package-name/src/functions/name/isScopedPackage.ts @@ -9,7 +9,7 @@ export const SCOPED_PACKAGE_PATTERN = /^(?:@([^/]+?)\/)?([^/]+?)$/u; * * NPM package name Scope Validator * - * @example isScopedPackage("@scope/example") + * @example isScopedPackage("\@scope/example") * @param name - NPM package name * @returns Boolean */ diff --git a/packages/validate-npm-package-name/src/functions/name/nameValidator.ts b/packages/validate-npm-package-name/src/functions/name/nameValidator.ts index 591d0b1..c074b45 100644 --- a/packages/validate-npm-package-name/src/functions/name/nameValidator.ts +++ b/packages/validate-npm-package-name/src/functions/name/nameValidator.ts @@ -1,7 +1,7 @@ /* eslint-disable guard-for-in */ /* eslint-disable @typescript-eslint/no-unnecessary-condition , @EslintSonar/no-duplicate-string */ import type { TMyError, TMyErrorList } from "oh-my-error"; -import { MyError } from "oh-my-error"; +import { myError } from "oh-my-error"; import { builtinModules } from "node:module"; import isScopedPackage from "./isScopedPackage"; @@ -90,19 +90,19 @@ export const MyErrorList = { }, CORE_MODULE_NAME: { code: "CORE_MODULE_NAME", - hint: { user: "Choose a different name that is not a core module name" }, + hint: { user: "Choose a differenceerent name that is not a core module name" }, message: { dev: "Name cannot be a core module name", - user: "This name is reserved. Please choose a different name." + user: "This name is reserved. Please choose a differenceerent name." }, name: "Reserved Name Error" }, BLACK_LISTED: { code: "BLACKLISTED", - hint: { user: "Choose a different name that is not blacklisted" }, + hint: { user: "Choose a differenceerent name that is not blacklisted" }, message: { dev: "Name is blacklisted", - user: "This name is not allowed. Please choose a different name." + user: "This name is not allowed. Please choose a differenceerent name." }, name: "Prohibited Name Error" }, @@ -216,7 +216,7 @@ export function nameValidator( for (const key in ValidationList) { const currentValidation = ValidationList[key as keyof typeof ValidationList]; if (Object.hasOwn(ValidationList, key) && currentValidation?.condition()) { - if (errorThrow) throw new MyError(MyErrorList[key as keyof typeof MyErrorList] as Required); + if (errorThrow) throw myError(MyErrorList[key as keyof typeof MyErrorList] as Required); if (currentValidation.type == "error") { problems.errors.push(MyErrorList[key as keyof typeof MyErrorList] as Required); } diff --git a/packages/validate-npm-package-name/tsconfig.json b/packages/validate-npm-package-name/tsconfig.json index dcef0c0..31ad8c7 100644 --- a/packages/validate-npm-package-name/tsconfig.json +++ b/packages/validate-npm-package-name/tsconfig.json @@ -9,7 +9,8 @@ "skipLibCheck": true, "esModuleInterop": true, "isolatedModules": true, - "noEmit": true + "noEmit": true, + "stripInternal": true }, "include": ["src", "eslint.config.js"], "exclude": ["node_modules", "**/*.spec.ts", "dist"], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d533d16..71023f4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,11 @@ importers: .: devDependencies: '@changesets/cli': - specifier: ^2.27.7 - version: 2.27.7 + specifier: ^2.27.8 + version: 2.27.8 + '@types/lint-staged': + specifier: ~13.3.0 + version: 13.3.0 commitsmile: specifier: ^0.6.1 version: 0.6.1 @@ -18,35 +21,70 @@ importers: specifier: ^15.9.0 version: 15.9.0 husky: - specifier: ^9.1.5 - version: 9.1.5 + specifier: ^9.1.6 + version: 9.1.6 lint-staged: - specifier: ^15.2.9 - version: 15.2.9 + specifier: ^15.2.10 + version: 15.2.10 turbo: specifier: latest - version: 2.0.12 + version: 2.2.3 + + packages/semver: + dependencies: + oh-my-error: + specifier: 2.0.0-prerelease.0 + version: 2.0.0-prerelease.0 + devDependencies: + '@esplugins/no-internal-exports': + specifier: 1.0.0-prerelease.1 + version: 1.0.0-prerelease.1 + '@ineedj/eslintrc': + specifier: ~1.2.2 + version: 1.2.2(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(tailwindcss@3.4.10)(typescript@5.6.2)(vitest@2.0.5(@types/node@22.5.1)) + '@ineedj/prettierrc': + specifier: ^2.0.0 + version: 2.0.0(prettier-plugin-packagejson@2.5.2(prettier@3.3.3))(prettier@3.3.3) + '@ineedj/tsconfig': + specifier: ^1.0.0 + version: 1.0.0 + '@types/eslint': + specifier: ~8.56.12 + version: 8.56.12 + '@types/node': + specifier: ^22.2.0 + version: 22.5.1 + '@types/safe-regex': + specifier: ^1.1.6 + version: 1.1.6 + clean-package: + specifier: ^2.2.0 + version: 2.2.0 + esbuild-plugin-copy: + specifier: ^2.1.1 + version: 2.1.1(esbuild@0.23.1) + eslint: + specifier: ~8.57.0 + version: 8.57.0 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + tsup: + specifier: ^8.1.0 + version: 8.2.4(jiti@1.21.6)(postcss@8.4.47)(typescript@5.6.2)(yaml@2.5.1) + typescript: + specifier: ^5.6.2 + version: 5.6.2 + vitest: + specifier: ^2.0.5 + version: 2.0.5(@types/node@22.5.1) + publishDirectory: dist packages/validate-npm-package-name: dependencies: - '@npmcli/package-json': - specifier: ^5.2.0 - version: 5.2.0 - '@types/init-package-json': - specifier: ^1.10.3 - version: 1.10.3 - '@types/npmcli__package-json': - specifier: ^4.0.4 - version: 4.0.4 - init-package-json: - specifier: ^6.0.3 - version: 6.0.3 oh-my-error: specifier: 1.1.1 version: 1.1.1 - semver: - specifier: ^7.6.3 - version: 7.6.3 devDependencies: '@ineedj/eslintrc': specifier: ~1.2.0 @@ -57,15 +95,12 @@ importers: '@ineedj/tsconfig': specifier: ^1.0.0 version: 1.0.0 + '@types/eslint': + specifier: ~8.56.12 + version: 8.56.12 '@types/node': specifier: ^22.2.0 version: 22.5.1 - '@types/semver': - specifier: ^7.5.8 - version: 7.5.8 - '@types/validate-npm-package-name': - specifier: ^4.0.2 - version: 4.0.2 clean-package: specifier: ^2.2.0 version: 2.2.0 @@ -80,13 +115,10 @@ importers: version: 3.3.3 tsup: specifier: ^8.1.0 - version: 8.2.4(jiti@1.21.6)(postcss@8.4.41)(typescript@5.5.4)(yaml@2.5.0) + version: 8.2.4(jiti@1.21.6)(postcss@8.4.47)(typescript@5.5.4)(yaml@2.5.1) typescript: specifier: ^5.5.4 version: 5.5.4 - validate-npm-package-name: - specifier: ^5.0.1 - version: 5.0.1 vitest: specifier: ^2.0.5 version: 2.0.5(@types/node@22.5.1) @@ -114,55 +146,55 @@ packages: resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.25.0': - resolution: {integrity: sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==} + '@babel/runtime@7.25.6': + resolution: {integrity: sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==} engines: {node: '>=6.9.0'} - '@changesets/apply-release-plan@7.0.4': - resolution: {integrity: sha512-HLFwhKWayKinWAul0Vj+76jVx1Pc2v55MGPVjZ924Y/ROeSsBMFutv9heHmCUj48lJyRfOTJG5+ar+29FUky/A==} + '@changesets/apply-release-plan@7.0.5': + resolution: {integrity: sha512-1cWCk+ZshEkSVEZrm2fSj1Gz8sYvxgUL4Q78+1ZZqeqfuevPTPk033/yUZ3df8BKMohkqqHfzj0HOOrG0KtXTw==} - '@changesets/assemble-release-plan@6.0.3': - resolution: {integrity: sha512-bLNh9/Lgl1VwkjWZTq8JmRqH+hj7/Yzfz0jsQ/zJJ+FTmVqmqPj3szeKOri8O/hEM8JmHW019vh2gTO9iq5Cuw==} + '@changesets/assemble-release-plan@6.0.4': + resolution: {integrity: sha512-nqICnvmrwWj4w2x0fOhVj2QEGdlUuwVAwESrUo5HLzWMI1rE5SWfsr9ln+rDqWB6RQ2ZyaMZHUcU7/IRaUJS+Q==} '@changesets/changelog-git@0.2.0': resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} - '@changesets/cli@2.27.7': - resolution: {integrity: sha512-6lr8JltiiXPIjDeYg4iM2MeePP6VN/JkmqBsVA5XRiy01hGS3y629LtSDvKcycj/w/5Eur1rEwby/MjcYS+e2A==} + '@changesets/cli@2.27.8': + resolution: {integrity: sha512-gZNyh+LdSsI82wBSHLQ3QN5J30P4uHKJ4fXgoGwQxfXwYFTJzDdvIJasZn8rYQtmKhyQuiBj4SSnLuKlxKWq4w==} hasBin: true - '@changesets/config@3.0.2': - resolution: {integrity: sha512-cdEhS4t8woKCX2M8AotcV2BOWnBp09sqICxKapgLHf9m5KdENpWjyrFNMjkLqGJtUys9U+w93OxWT0czorVDfw==} + '@changesets/config@3.0.3': + resolution: {integrity: sha512-vqgQZMyIcuIpw9nqFIpTSNyc/wgm/Lu1zKN5vECy74u95Qx/Wa9g27HdgO4NkVAaq+BGA8wUc/qvbvVNs93n6A==} '@changesets/errors@0.2.0': resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} - '@changesets/get-dependents-graph@2.1.1': - resolution: {integrity: sha512-LRFjjvigBSzfnPU2n/AhFsuWR5DK++1x47aq6qZ8dzYsPtS/I5mNhIGAS68IAxh1xjO9BTtz55FwefhANZ+FCA==} + '@changesets/get-dependents-graph@2.1.2': + resolution: {integrity: sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==} - '@changesets/get-release-plan@4.0.3': - resolution: {integrity: sha512-6PLgvOIwTSdJPTtpdcr3sLtGatT+Jr22+cQwEBJBy6wP0rjB4yJ9lv583J9fVpn1bfQlBkDa8JxbS2g/n9lIyA==} + '@changesets/get-release-plan@4.0.4': + resolution: {integrity: sha512-SicG/S67JmPTrdcc9Vpu0wSQt7IiuN0dc8iR5VScnnTVPfIaLvKmEGRvIaF0kcn8u5ZqLbormZNTO77bCEvyWw==} '@changesets/get-version-range-type@0.4.0': resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} - '@changesets/git@3.0.0': - resolution: {integrity: sha512-vvhnZDHe2eiBNRFHEgMiGd2CT+164dfYyrJDhwwxTVD/OW0FUD6G7+4DIx1dNwkwjHyzisxGAU96q0sVNBns0w==} + '@changesets/git@3.0.1': + resolution: {integrity: sha512-pdgHcYBLCPcLd82aRcuO0kxCDbw/yISlOtkmwmE8Odo1L6hSiZrBOsRl84eYG7DRCab/iHnOkWqExqc4wxk2LQ==} - '@changesets/logger@0.1.0': - resolution: {integrity: sha512-pBrJm4CQm9VqFVwWnSqKEfsS2ESnwqwH+xR7jETxIErZcfd1u2zBSqrHbRHR7xjhSgep9x2PSKFKY//FAshA3g==} + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} '@changesets/parse@0.4.0': resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==} - '@changesets/pre@2.0.0': - resolution: {integrity: sha512-HLTNYX/A4jZxc+Sq8D1AMBsv+1qD6rmmJtjsCJa/9MSRybdxh0mjbTvE6JYZQ/ZiQ0mMlDOlGPXTm9KLTU3jyw==} + '@changesets/pre@2.0.1': + resolution: {integrity: sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==} - '@changesets/read@0.6.0': - resolution: {integrity: sha512-ZypqX8+/im1Fm98K4YcZtmLKgjs1kDQ5zHpc2U1qdtNBmZZfo/IBiG162RoP0CUF05tvp2y4IspH11PLnPxuuw==} + '@changesets/read@0.6.1': + resolution: {integrity: sha512-jYMbyXQk3nwP25nRzQQGa1nKLY0KfoOV7VLgwucI0bUO8t8ZLCr6LZmgjXsiKuRDc+5A6doKPr9w2d+FEJ55zQ==} - '@changesets/should-skip-package@0.1.0': - resolution: {integrity: sha512-FxG6Mhjw7yFStlSM7Z0Gmg3RiyQ98d/9VpQAZ3Fzr59dCOM9G6ZdYbjiSAt0XtFr9JR5U2tBaJWPjrkGGc618g==} + '@changesets/should-skip-package@0.1.1': + resolution: {integrity: sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==} '@changesets/types@4.1.0': resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} @@ -170,13 +202,17 @@ packages: '@changesets/types@6.0.0': resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==} - '@changesets/write@0.3.1': - resolution: {integrity: sha512-SyGtMXzH3qFqlHKcvFY2eX+6b0NGiFcNav8AFsYwy5l8hejOeoeTDemu5Yjmke2V5jpzY+pBvM0vCCQ3gdZpfw==} + '@changesets/write@0.3.2': + resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} '@es-joy/jsdoccomment@0.43.1': resolution: {integrity: sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==} engines: {node: '>=16'} + '@es-joy/jsdoccomment@0.48.0': + resolution: {integrity: sha512-G6QUWIcC+KvSwXNsJyDTHvqUdNoAVJPPgkc3+Uk4WBKqZvoXhlvazOgm9aL0HwihJLQf0l+tOE2UFzXBqCqgDw==} + engines: {node: '>=16'} + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -481,6 +517,9 @@ packages: resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@esplugins/no-internal-exports@1.0.0-prerelease.1': + resolution: {integrity: sha512-CHhtavI0MdUJGyldy7+XJLuC47LBoEemniflVsBml4gT2yeTPSQ4THhDnlm48pO4hK9PYFVR+BvwLsPFIyxu5A==} + '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} @@ -497,6 +536,9 @@ packages: '@ineedj/eslintrc@1.2.0': resolution: {integrity: sha512-FsSbSIveNnGHmUKQj8dw3oGIpQPXt90fu+KWFBCOoMRiGEiKZ2J93qX687GWjB/50R3UTSQEfUurnNIH5eVp6Q==} + '@ineedj/eslintrc@1.2.2': + resolution: {integrity: sha512-I+gu4NKwMJ3+jEdXpkAT9PFj+v9SRcvq4sCXfbdcMq4XsPxF65dIUP+lY6PUEKOYHvSsFGCiAHMeNfK1tc7ldg==} + '@ineedj/prettierrc@2.0.0': resolution: {integrity: sha512-Ag8uMZajNVq0XUY26LG2pnYxYf11tKWm/pCSa9h7e/6oaOfXGF+PovMV5tmImLIbyiyEmJgaqkJFJD6hqtx3Bw==} peerDependencies: @@ -729,9 +771,6 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - '@types/init-package-json@1.10.3': - resolution: {integrity: sha512-nZtRYXcRpfJW4cObdbf/MuWFN89081ghRku18i8xE9bDmlTjhtmoVMx9SGiy4WCvfrfMpriDvoIQf56Xm3eylA==} - '@types/is-empty@1.2.3': resolution: {integrity: sha512-4J1l5d79hoIvsrKh5VUKVRA1aIdsOb10Hu5j3J2VfP/msDnfTdGPmNp2E1Wg+vs97Bktzo+MZePFFXSGoykYJw==} @@ -741,6 +780,9 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/lint-staged@13.3.0': + resolution: {integrity: sha512-WxGjVP+rA4OJlEdbZdT9MS9PFKQ7kVPhLn26gC+2tnBWBEFEj/KW+IbFfz6sxdxY5U6V7BvyF+3BzCGsAMHhNg==} + '@types/mdast@3.0.15': resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} @@ -762,8 +804,8 @@ packages: '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} - '@types/npmcli__package-json@4.0.4': - resolution: {integrity: sha512-6QjlFUSHBmZJWuC08bz1ZCx6tm4t+7+OJXAdvM6tL2pI7n6Bh5SIp/YxQvnOLFf8MzCXs2ijyFgrzaiu1UFBGA==} + '@types/safe-regex@1.1.6': + resolution: {integrity: sha512-CQ/uPB9fLOPKwDsrTeVbNIkwfUthTWOx0l6uIGwVFjZxv7e68pCW5gtTYFzdJi3EBJp8h8zYhJbTasAbX7gEMQ==} '@types/semver@7.5.8': resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} @@ -777,9 +819,6 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - '@types/validate-npm-package-name@4.0.2': - resolution: {integrity: sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==} - '@typescript-eslint/eslint-plugin@6.21.0': resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} engines: {node: ^16.0.0 || >=18.0.0} @@ -966,8 +1005,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} engines: {node: '>=12'} ansi-styles@3.2.1: @@ -1296,6 +1335,15 @@ packages: supports-color: optional: true + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decode-named-character-reference@1.0.2: resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} @@ -1373,8 +1421,8 @@ packages: electron-to-chromium@1.5.13: resolution: {integrity: sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==} - emoji-regex@10.3.0: - resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + emoji-regex@10.4.0: + resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1522,6 +1570,11 @@ packages: peerDependencies: eslint: '*' + eslint-plugin-command@0.2.6: + resolution: {integrity: sha512-T0bHZ1oblW1xUHUVoBKZJR2osSNNGkfZuK4iqboNwuNS/M7tdp3pmURaJtTi/XDzitxaQ02lvOdFH0mUd5QLvQ==} + peerDependencies: + eslint: '*' + eslint-plugin-compat@6.0.0: resolution: {integrity: sha512-oIynkQYqGnW9ibHl1cGLER8XkUlKaOI8bS80Qz7CjKROvbQm4oN8fWb5l2cG9GJJ4h5eFIHPqkB9ZJuMzwpPFQ==} engines: {node: '>=18.x'} @@ -1819,6 +1872,7 @@ packages: eslint@8.57.0: resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true espree@10.1.0: @@ -1920,9 +1974,6 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - find-yarn-workspace-root2@1.2.16: - resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} - flat-cache@3.2.0: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} @@ -2111,8 +2162,8 @@ packages: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} - husky@9.1.5: - resolution: {integrity: sha512-rowAVRUBfI0b4+niA4SJMhfQwc107VLkBUgEYYAOQAbqDCnra1nYh83hF/MDmhYs9t9n1E3DuKOrs2LYNC+0Ag==} + husky@9.1.6: + resolution: {integrity: sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==} engines: {node: '>=18'} hasBin: true @@ -2124,6 +2175,10 @@ packages: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -2150,10 +2205,6 @@ packages: resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - init-package-json@6.0.3: - resolution: {integrity: sha512-Zfeb5ol+H+eqJWHTaGca9BovufyGeIfr4zaaBorPmJBMrJ+KBnN+kQx2ZtXdsotUTgldHmHQV44xvUWOUA7E2w==} - engines: {node: ^16.14.0 || >=18.0.0} - internal-slot@1.0.7: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} @@ -2383,6 +2434,10 @@ packages: resolution: {integrity: sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==} engines: {node: '>=12.0.0'} + jsdoc-type-pratt-parser@4.1.0: + resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==} + engines: {node: '>=12.0.0'} + jsesc@0.5.0: resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} hasBin: true @@ -2468,8 +2523,8 @@ packages: linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - lint-staged@15.2.9: - resolution: {integrity: sha512-BZAt8Lk3sEnxw7tfxM7jeZlPRuT4M68O0/CwZhhaw6eeWu0Lz5eERE3m386InivXB64fp/mDID452h48tvKlRQ==} + lint-staged@15.2.10: + resolution: {integrity: sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==} engines: {node: '>=18.12.0'} hasBin: true @@ -2484,10 +2539,6 @@ packages: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - load-yaml-file@0.2.0: - resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} - engines: {node: '>=6'} - local-pkg@0.5.0: resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} @@ -2535,6 +2586,9 @@ packages: lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + magic-regexp@0.8.0: + resolution: {integrity: sha512-lOSLWdE156csDYwCTIGiAymOLN7Epu/TU5e/oAnISZfU6qP+pgjkE+xbVjVn3yLPKN8n1G2yIAYTAM5KRk6/ow==} + magic-string@0.30.11: resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} @@ -2681,6 +2735,10 @@ packages: resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} engines: {node: '>=8.6'} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -2725,9 +2783,8 @@ packages: ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - mute-stream@1.0.0: - resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -2830,6 +2887,10 @@ packages: resolution: {integrity: sha512-bt8NkFwdnS4h23S7p2oxJWOTK9IRWPYEpz1xzo/BubKZxwUCBxwm2ZRx2UOs2NPt+hjonuLMfPecxzwtj6gNsQ==} engines: {node: '>=18'} + oh-my-error@2.0.0-prerelease.0: + resolution: {integrity: sha512-+c+9jL0H+ZKmxkCdUMsnEhjKnNOfditA9ikCnbNLN4uCtl29hQg1UuU3+f/Hm/PmORA1RqtbYd2PgRzOjl8gbA==} + engines: {node: '>=18'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2887,6 +2948,9 @@ packages: package-json-from-dist@1.0.0: resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + package-manager-detector@0.2.0: + resolution: {integrity: sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2946,6 +3010,9 @@ packages: picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -2971,10 +3038,6 @@ packages: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} - pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - pkg-types@1.2.0: resolution: {integrity: sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==} @@ -3045,9 +3108,9 @@ packages: resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} engines: {node: ^10 || ^12 || >=14} - preferred-pm@3.1.4: - resolution: {integrity: sha512-lEHd+yEm22jXdCphDrkvIJQU66EuLojPPtvZkpKIkiD+l0DMThF/niqZKJSoU8Vl7iuvtmzyMhir9LdVy5WMnA==} - engines: {node: '>=10'} + postcss@8.4.47: + resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} + engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -3087,10 +3150,6 @@ packages: resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} engines: {node: '>=10'} - promzard@1.0.2: - resolution: {integrity: sha512-2FPputGL+mP3jJ3UZg/Dl9YOkovB7DX0oOr+ck5QbZ5MtORtds8k/BZdn+02peDLI8/YWbmzx34k5fA+fHvCVQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -3130,10 +3189,6 @@ packages: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} engines: {node: '>=6'} - read@3.0.1: - resolution: {integrity: sha512-SLBrDU/Srs/9EoWhU5GdbAoxG1GzpQHo/6qiGItaoLJ1thmYpcNIM1qISEUvyHBzfGlWIyd6p2DNi1oV1VmAuw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -3328,6 +3383,10 @@ packages: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} @@ -3571,38 +3630,38 @@ packages: peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - turbo-darwin-64@2.0.12: - resolution: {integrity: sha512-NAgfgbXxX/JScWQmmQnGbPuFZq7LIswHfcMk5JwyBXQM/xmklNOxxac7MnGGIOf19Z2f6S3qHy17VIj0SeGfnA==} + turbo-darwin-64@2.2.3: + resolution: {integrity: sha512-Rcm10CuMKQGcdIBS3R/9PMeuYnv6beYIHqfZFeKWVYEWH69sauj4INs83zKMTUiZJ3/hWGZ4jet9AOwhsssLyg==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.0.12: - resolution: {integrity: sha512-cP02uer5KSJ+fXL+OfRRk5hnVjV0c60hxDgNcJxrZpfhun7HHoKDDR7w2xhQntiA45aC6ZZEXRqMKpj6GAmKbg==} + turbo-darwin-arm64@2.2.3: + resolution: {integrity: sha512-+EIMHkuLFqUdJYsA3roj66t9+9IciCajgj+DVek+QezEdOJKcRxlvDOS2BUaeN8kEzVSsNiAGnoysFWYw4K0HA==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.0.12: - resolution: {integrity: sha512-+mQgGfg1eq5qF+wenK/FKJaNMNAo5DQLC4htQy+8osW+fx6U+8+6UlPQPaycAWDEqwOI7NwuqkeHfkEQLQUTyQ==} + turbo-linux-64@2.2.3: + resolution: {integrity: sha512-UBhJCYnqtaeOBQLmLo8BAisWbc9v9daL9G8upLR+XGj6vuN/Nz6qUAhverN4Pyej1g4Nt1BhROnj6GLOPYyqxQ==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.0.12: - resolution: {integrity: sha512-KFyEZDXfPU1DK4zimxdCcqAcK7IIttX4mfsgB7NsSEOmH0dhHOih/YFYiyEDC1lTRx0C2RlzQ0Kjjdz48AN5Eg==} + turbo-linux-arm64@2.2.3: + resolution: {integrity: sha512-hJYT9dN06XCQ3jBka/EWvvAETnHRs3xuO/rb5bESmDfG+d9yQjeTMlhRXKrr4eyIMt6cLDt1LBfyi+6CQ+VAwQ==} cpu: [arm64] os: [linux] - turbo-windows-64@2.0.12: - resolution: {integrity: sha512-kJj4KCkZTkDTDCqsSw1m1dbO4WeoQq1mYUm/thXOH0OkeqYbSMt0EyoTcJOgKUDsrMnzZD2gPfYrlYHtV69lVA==} + turbo-windows-64@2.2.3: + resolution: {integrity: sha512-NPrjacrZypMBF31b4HE4ROg4P3nhMBPHKS5WTpMwf7wydZ8uvdEHpESVNMOtqhlp857zbnKYgP+yJF30H3N2dQ==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.0.12: - resolution: {integrity: sha512-TY3ROxguDilN2olCwcZMaePdW01Xhma0pZU7bNhsQEqca9RGAmsZBuzfGnTMcWPmv4tpnb/PlX1hrt1Hod/44Q==} + turbo-windows-arm64@2.2.3: + resolution: {integrity: sha512-fnNrYBCqn6zgKPKLHu4sOkihBI/+0oYFr075duRxqUZ+1aLWTAGfHZLgjVeLh3zR37CVzuerGIPWAEkNhkWEIw==} cpu: [arm64] os: [win32] - turbo@2.0.12: - resolution: {integrity: sha512-8s2KwqjwQj7z8Z53SUZSKVkQOZ2/Sl4D2F440oaBY/k2lGju60dW6srEpnn8/RIDeICZmQn3pQHF79Jfnc5Skw==} + turbo@2.2.3: + resolution: {integrity: sha512-5lDvSqIxCYJ/BAd6rQGK/AzFRhBkbu4JHVMLmGh/hCb7U3CqSnr5Tjwfy9vc+/5wG2DJ6wttgAaA7MoCgvBKZQ==} hasBin: true type-check@0.4.0: @@ -3625,6 +3684,9 @@ packages: resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} engines: {node: '>=14.16'} + type-level-regexp@0.1.17: + resolution: {integrity: sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==} + typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -3649,6 +3711,16 @@ packages: engines: {node: '>=14.17'} hasBin: true + typescript@5.6.2: + resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + uc.micro@2.1.0: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} @@ -3696,6 +3768,15 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + unplugin@1.14.1: + resolution: {integrity: sha512-lBlHbfSFPToDYp9pjXlUEFVxYLaue9f9T1HC+4OHlmj+HnMDdz9oZY+erXfoCe/5V/7gKUSY2jpXPb9S7f0f/w==} + engines: {node: '>=14.0.0'} + peerDependencies: + webpack-sources: ^3 + peerDependenciesMeta: + webpack-sources: + optional: true + update-browserslist-db@1.1.0: resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} hasBin: true @@ -3805,6 +3886,9 @@ packages: webidl-conversions@4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + whatwg-url@7.1.0: resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} @@ -3819,10 +3903,6 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-pm@2.2.0: - resolution: {integrity: sha512-MOiaDbA5ZZgUjkeMWM5EkJp4loW5ZRoa5bc3/aeMox/PJelMhE6t7S/mLuiY43DBupyxH+S0U1bTui9kWUlmsw==} - engines: {node: '>=8.15'} - which-typed-array@1.1.15: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} @@ -3877,6 +3957,11 @@ packages: engines: {node: '>= 14'} hasBin: true + yaml@2.5.1: + resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==} + engines: {node: '>= 14'} + hasBin: true + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -3896,7 +3981,7 @@ snapshots: '@babel/code-frame@7.24.7': dependencies: '@babel/highlight': 7.24.7 - picocolors: 1.0.1 + picocolors: 1.1.0 '@babel/helper-validator-identifier@7.24.7': {} @@ -3905,19 +3990,18 @@ snapshots: '@babel/helper-validator-identifier': 7.24.7 chalk: 2.4.2 js-tokens: 4.0.0 - picocolors: 1.0.1 + picocolors: 1.1.0 - '@babel/runtime@7.25.0': + '@babel/runtime@7.25.6': dependencies: regenerator-runtime: 0.14.1 - '@changesets/apply-release-plan@7.0.4': + '@changesets/apply-release-plan@7.0.5': dependencies: - '@babel/runtime': 7.25.0 - '@changesets/config': 3.0.2 + '@changesets/config': 3.0.3 '@changesets/get-version-range-type': 0.4.0 - '@changesets/git': 3.0.0 - '@changesets/should-skip-package': 0.1.0 + '@changesets/git': 3.0.1 + '@changesets/should-skip-package': 0.1.1 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 detect-indent: 6.1.0 @@ -3928,12 +4012,11 @@ snapshots: resolve-from: 5.0.0 semver: 7.6.3 - '@changesets/assemble-release-plan@6.0.3': + '@changesets/assemble-release-plan@6.0.4': dependencies: - '@babel/runtime': 7.25.0 '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.1 - '@changesets/should-skip-package': 0.1.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/should-skip-package': 0.1.1 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 semver: 7.6.3 @@ -3942,116 +4025,107 @@ snapshots: dependencies: '@changesets/types': 6.0.0 - '@changesets/cli@2.27.7': + '@changesets/cli@2.27.8': dependencies: - '@babel/runtime': 7.25.0 - '@changesets/apply-release-plan': 7.0.4 - '@changesets/assemble-release-plan': 6.0.3 + '@changesets/apply-release-plan': 7.0.5 + '@changesets/assemble-release-plan': 6.0.4 '@changesets/changelog-git': 0.2.0 - '@changesets/config': 3.0.2 + '@changesets/config': 3.0.3 '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.1 - '@changesets/get-release-plan': 4.0.3 - '@changesets/git': 3.0.0 - '@changesets/logger': 0.1.0 - '@changesets/pre': 2.0.0 - '@changesets/read': 0.6.0 - '@changesets/should-skip-package': 0.1.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/get-release-plan': 4.0.4 + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 + '@changesets/should-skip-package': 0.1.1 '@changesets/types': 6.0.0 - '@changesets/write': 0.3.1 + '@changesets/write': 0.3.2 '@manypkg/get-packages': 1.1.3 '@types/semver': 7.5.8 ansi-colors: 4.1.3 - chalk: 2.4.2 ci-info: 3.9.0 enquirer: 2.4.1 external-editor: 3.1.0 fs-extra: 7.0.1 - human-id: 1.0.2 mri: 1.2.0 outdent: 0.5.0 p-limit: 2.3.0 - preferred-pm: 3.1.4 + package-manager-detector: 0.2.0 + picocolors: 1.1.0 resolve-from: 5.0.0 semver: 7.6.3 spawndamnit: 2.0.0 term-size: 2.2.1 - '@changesets/config@3.0.2': + '@changesets/config@3.0.3': dependencies: '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.1 - '@changesets/logger': 0.1.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/logger': 0.1.1 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - micromatch: 4.0.7 + micromatch: 4.0.8 '@changesets/errors@0.2.0': dependencies: extendable-error: 0.1.7 - '@changesets/get-dependents-graph@2.1.1': + '@changesets/get-dependents-graph@2.1.2': dependencies: '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 - chalk: 2.4.2 - fs-extra: 7.0.1 + picocolors: 1.1.0 semver: 7.6.3 - '@changesets/get-release-plan@4.0.3': + '@changesets/get-release-plan@4.0.4': dependencies: - '@babel/runtime': 7.25.0 - '@changesets/assemble-release-plan': 6.0.3 - '@changesets/config': 3.0.2 - '@changesets/pre': 2.0.0 - '@changesets/read': 0.6.0 + '@changesets/assemble-release-plan': 6.0.4 + '@changesets/config': 3.0.3 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 '@changesets/get-version-range-type@0.4.0': {} - '@changesets/git@3.0.0': + '@changesets/git@3.0.1': dependencies: - '@babel/runtime': 7.25.0 '@changesets/errors': 0.2.0 - '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 is-subdir: 1.2.0 - micromatch: 4.0.7 + micromatch: 4.0.8 spawndamnit: 2.0.0 - '@changesets/logger@0.1.0': + '@changesets/logger@0.1.1': dependencies: - chalk: 2.4.2 + picocolors: 1.1.0 '@changesets/parse@0.4.0': dependencies: '@changesets/types': 6.0.0 js-yaml: 3.14.1 - '@changesets/pre@2.0.0': + '@changesets/pre@2.0.1': dependencies: - '@babel/runtime': 7.25.0 '@changesets/errors': 0.2.0 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - '@changesets/read@0.6.0': + '@changesets/read@0.6.1': dependencies: - '@babel/runtime': 7.25.0 - '@changesets/git': 3.0.0 - '@changesets/logger': 0.1.0 + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 '@changesets/parse': 0.4.0 '@changesets/types': 6.0.0 - chalk: 2.4.2 fs-extra: 7.0.1 p-filter: 2.1.0 + picocolors: 1.1.0 - '@changesets/should-skip-package@0.1.0': + '@changesets/should-skip-package@0.1.1': dependencies: - '@babel/runtime': 7.25.0 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 @@ -4059,9 +4133,8 @@ snapshots: '@changesets/types@6.0.0': {} - '@changesets/write@0.3.1': + '@changesets/write@0.3.2': dependencies: - '@babel/runtime': 7.25.0 '@changesets/types': 6.0.0 fs-extra: 7.0.1 human-id: 1.0.2 @@ -4076,6 +4149,12 @@ snapshots: esquery: 1.6.0 jsdoc-type-pratt-parser: 4.0.0 + '@es-joy/jsdoccomment@0.48.0': + dependencies: + comment-parser: 1.4.1 + esquery: 1.6.0 + jsdoc-type-pratt-parser: 4.1.0 + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -4254,6 +4333,14 @@ snapshots: '@eslint/js@8.57.0': {} + '@esplugins/no-internal-exports@1.0.0-prerelease.1': + dependencies: + magic-regexp: 0.8.0 + oh-my-error: 2.0.0-prerelease.0 + typescript: 5.6.3 + transitivePeerDependencies: + - webpack-sources + '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 @@ -4337,6 +4424,77 @@ snapshots: - vitest - vue-eslint-parser + '@ineedj/eslintrc@1.2.2(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(tailwindcss@3.4.10)(typescript@5.6.2)(vitest@2.0.5(@types/node@22.5.1))': + dependencies: + '@next/eslint-plugin-next': 14.2.7 + '@rushstack/eslint-patch': 1.10.4 + '@stylistic/eslint-plugin': 2.3.0(eslint@8.57.0)(typescript@5.6.2) + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2) + confusing-browser-globals: 1.0.11 + eslint: 8.57.0 + eslint-config-flat-gitignore: 0.1.8 + eslint-flat-config-utils: 0.3.1 + eslint-import-resolver-node: 0.3.9 + eslint-plugin-array-func: 5.0.2(eslint@8.57.0) + eslint-plugin-ban: 1.6.0 + eslint-plugin-command: 0.2.6(eslint@8.57.0) + eslint-plugin-compat: 6.0.0(eslint@8.57.0) + eslint-plugin-css-modules: 2.12.0(eslint@8.57.0) + eslint-plugin-deprecation: 3.0.0(eslint@8.57.0)(typescript@5.6.2) + eslint-plugin-header: 3.1.1(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0) + eslint-plugin-jsonc: 2.16.0(eslint@8.57.0) + eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0) + eslint-plugin-markdownlint: 0.6.0(eslint@8.57.0) + eslint-plugin-mdx: 3.1.5(eslint@8.57.0) + eslint-plugin-n: 17.9.0(eslint@8.57.0) + eslint-plugin-no-explicit-type-exports: 0.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2) + eslint-plugin-no-unsanitized: 4.0.2(eslint@8.57.0) + eslint-plugin-only-error: 1.0.2 + eslint-plugin-only-warn: 1.1.0 + eslint-plugin-optimize-regex: 1.2.1 + eslint-plugin-perfectionist: 2.11.0(eslint@8.57.0)(typescript@5.6.2) + eslint-plugin-pii: 1.0.2(eslint@8.57.0) + eslint-plugin-promise: 6.5.1(eslint@8.57.0) + eslint-plugin-react: 7.35.0(eslint@8.57.0) + eslint-plugin-react-form-fields: 1.2.22(eslint@8.57.0)(typescript@5.6.2) + eslint-plugin-react-hook-form: 0.3.0 + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) + eslint-plugin-react-perf: 3.3.2(eslint@8.57.0) + eslint-plugin-react-prefer-function-component: 3.3.0 + eslint-plugin-react-refresh: 0.4.11(eslint@8.57.0) + eslint-plugin-readable-tailwind: 1.5.3(eslint@8.57.0)(tailwindcss@3.4.10) + eslint-plugin-security: 3.0.1 + eslint-plugin-sonarjs: 1.0.4(eslint@8.57.0) + eslint-plugin-ssr-friendly: 1.3.0(eslint@8.57.0) + eslint-plugin-storybook: 0.8.0(eslint@8.57.0)(typescript@5.6.2) + eslint-plugin-tailwindcss: 3.17.4(tailwindcss@3.4.10) + eslint-plugin-toml: 0.11.1(eslint@8.57.0) + eslint-plugin-tsdoc: 0.3.0 + eslint-plugin-turbo: 2.0.14(eslint@8.57.0) + eslint-plugin-typescript-compat: 1.0.2(eslint@8.57.0)(typescript@5.6.2) + eslint-plugin-typescript-sort-keys: 3.2.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2) + eslint-plugin-unicorn: 54.0.0(eslint@8.57.0) + eslint-plugin-unused-imports: 3.2.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0) + eslint-plugin-validate-jsx-nesting: 0.1.1(eslint@8.57.0) + eslint-plugin-vitest: 0.5.4(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2)(vitest@2.0.5(@types/node@22.5.1)) + eslint-plugin-yml: 1.14.0(eslint@8.57.0) + globals: 15.8.0 + local-pkg: 0.5.0 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - astro-eslint-parser + - bluebird + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + - svelte + - svelte-eslint-parser + - tailwindcss + - typescript + - vitest + - vue-eslint-parser + '@ineedj/prettierrc@2.0.0(prettier-plugin-packagejson@2.5.2(prettier@3.3.3))(prettier@3.3.3)': dependencies: prettier: 3.3.3 @@ -4372,14 +4530,14 @@ snapshots: '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.25.0 + '@babel/runtime': 7.25.6 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 '@manypkg/get-packages@1.1.3': dependencies: - '@babel/runtime': 7.25.0 + '@babel/runtime': 7.25.6 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -4549,6 +4707,15 @@ snapshots: - supports-color - typescript + '@stylistic/eslint-plugin-plus@2.3.0(eslint@8.57.0)(typescript@5.6.2)': + dependencies: + '@types/eslint': 8.56.12 + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.6.2) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + '@stylistic/eslint-plugin-ts@2.3.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@stylistic/eslint-plugin-js': 2.3.0(eslint@8.57.0) @@ -4559,6 +4726,16 @@ snapshots: - supports-color - typescript + '@stylistic/eslint-plugin-ts@2.3.0(eslint@8.57.0)(typescript@5.6.2)': + dependencies: + '@stylistic/eslint-plugin-js': 2.3.0(eslint@8.57.0) + '@types/eslint': 8.56.12 + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.6.2) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + '@stylistic/eslint-plugin@2.3.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@stylistic/eslint-plugin-js': 2.3.0(eslint@8.57.0) @@ -4571,6 +4748,18 @@ snapshots: - supports-color - typescript + '@stylistic/eslint-plugin@2.3.0(eslint@8.57.0)(typescript@5.6.2)': + dependencies: + '@stylistic/eslint-plugin-js': 2.3.0(eslint@8.57.0) + '@stylistic/eslint-plugin-jsx': 2.3.0(eslint@8.57.0) + '@stylistic/eslint-plugin-plus': 2.3.0(eslint@8.57.0)(typescript@5.6.2) + '@stylistic/eslint-plugin-ts': 2.3.0(eslint@8.57.0)(typescript@5.6.2) + '@types/eslint': 8.56.12 + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + '@types/acorn@4.0.6': dependencies: '@types/estree': 1.0.5 @@ -4603,14 +4792,14 @@ snapshots: dependencies: '@types/unist': 3.0.3 - '@types/init-package-json@1.10.3': {} - '@types/is-empty@1.2.3': {} '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} + '@types/lint-staged@13.3.0': {} + '@types/mdast@3.0.15': dependencies: '@types/unist': 2.0.11 @@ -4633,7 +4822,7 @@ snapshots: '@types/normalize-package-data@2.4.4': {} - '@types/npmcli__package-json@4.0.4': {} + '@types/safe-regex@1.1.6': {} '@types/semver@7.5.8': {} @@ -4643,8 +4832,6 @@ snapshots: '@types/unist@3.0.3': {} - '@types/validate-npm-package-name@4.0.2': {} - '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@eslint-community/regexpp': 4.11.0 @@ -4665,6 +4852,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2)': + dependencies: + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.6.2) + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.0)(typescript@5.6.2) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.6.2) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.6 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.6.2) + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/experimental-utils@2.34.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@types/json-schema': 7.0.15 @@ -4676,6 +4883,17 @@ snapshots: - supports-color - typescript + '@typescript-eslint/experimental-utils@2.34.0(eslint@8.57.0)(typescript@5.6.2)': + dependencies: + '@types/json-schema': 7.0.15 + '@typescript-eslint/typescript-estree': 2.34.0(typescript@5.6.2) + eslint: 8.57.0 + eslint-scope: 5.1.1 + eslint-utils: 2.1.0 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.5.4) @@ -4684,19 +4902,40 @@ snapshots: - supports-color - typescript + '@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.0)(typescript@5.6.2)': + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.6.2) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.5.4) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.3.6 + debug: 4.3.7 eslint: 8.57.0 optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2)': + dependencies: + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.2) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.7 + eslint: 8.57.0 + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/scope-manager@5.62.0': dependencies: '@typescript-eslint/types': 5.62.0 @@ -4724,6 +4963,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/type-utils@6.21.0(eslint@8.57.0)(typescript@5.6.2)': + dependencies: + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.2) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.6.2) + debug: 4.3.6 + eslint: 8.57.0 + ts-api-utils: 1.3.0(typescript@5.6.2) + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/types@5.62.0': {} '@typescript-eslint/types@6.21.0': {} @@ -4732,7 +4983,7 @@ snapshots: '@typescript-eslint/typescript-estree@2.34.0(typescript@5.5.4)': dependencies: - debug: 4.3.6 + debug: 4.3.7 eslint-visitor-keys: 1.3.0 glob: 7.2.3 is-glob: 4.0.3 @@ -4744,11 +4995,25 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@2.34.0(typescript@5.6.2)': + dependencies: + debug: 4.3.7 + eslint-visitor-keys: 1.3.0 + glob: 7.2.3 + is-glob: 4.0.3 + lodash: 4.17.21 + semver: 7.6.3 + tsutils: 3.21.0(typescript@5.6.2) + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.5.4)': dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.3.6 + debug: 4.3.7 globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.3 @@ -4758,9 +5023,23 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@6.21.0(typescript@5.5.4)': + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.6.2)': dependencies: - '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.3.7 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.6.3 + tsutils: 3.21.0(typescript@5.6.2) + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@6.21.0(typescript@5.5.4)': + dependencies: + '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.6 globby: 11.1.0 @@ -4773,11 +5052,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@6.21.0(typescript@5.6.2)': + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.6 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.6.2) + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.5.4)': dependencies: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.3.6 + debug: 4.3.7 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.5 @@ -4788,6 +5082,21 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.6.2)': + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.3.7 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.6.2) + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@5.62.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) @@ -4803,6 +5112,21 @@ snapshots: - supports-color - typescript + '@typescript-eslint/utils@5.62.0(eslint@8.57.0)(typescript@5.6.2)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.6.2) + eslint: 8.57.0 + eslint-scope: 5.1.1 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/utils@6.21.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) @@ -4817,6 +5141,20 @@ snapshots: - supports-color - typescript + '@typescript-eslint/utils@6.21.0(eslint@8.57.0)(typescript@5.6.2)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.2) + eslint: 8.57.0 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) @@ -4828,6 +5166,17 @@ snapshots: - supports-color - typescript + '@typescript-eslint/utils@7.18.0(eslint@8.57.0)(typescript@5.6.2)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/visitor-keys@5.62.0': dependencies: '@typescript-eslint/types': 5.62.0 @@ -4908,7 +5257,7 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.0.1: {} + ansi-regex@6.1.0: {} ansi-styles@3.2.1: dependencies: @@ -5236,6 +5585,10 @@ snapshots: dependencies: ms: 2.1.2 + debug@4.3.7: + dependencies: + ms: 2.1.3 + decode-named-character-reference@1.0.2: dependencies: character-entities: 2.0.2 @@ -5317,7 +5670,7 @@ snapshots: electron-to-chromium@1.5.13: {} - emoji-regex@10.3.0: {} + emoji-regex@10.4.0: {} emoji-regex@8.0.0: {} @@ -5568,6 +5921,16 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-module-utils@2.8.2(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.6.2) + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + eslint-plugin-array-func@5.0.2(eslint@8.57.0): dependencies: eslint: 8.57.0 @@ -5581,6 +5944,11 @@ snapshots: '@es-joy/jsdoccomment': 0.43.1 eslint: 8.57.0 + eslint-plugin-command@0.2.6(eslint@8.57.0): + dependencies: + '@es-joy/jsdoccomment': 0.48.0 + eslint: 8.57.0 + eslint-plugin-compat@6.0.0(eslint@8.57.0): dependencies: '@mdn/browser-compat-data': 5.5.49 @@ -5609,6 +5977,16 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-plugin-deprecation@3.0.0(eslint@8.57.0)(typescript@5.6.2): + dependencies: + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.6.2) + eslint: 8.57.0 + ts-api-utils: 1.3.0(typescript@5.6.2) + tslib: 2.7.0 + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + eslint-plugin-es-x@7.8.0(eslint@8.57.0): dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) @@ -5647,6 +6025,33 @@ snapshots: - eslint-import-resolver-webpack - supports-color + eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0): + dependencies: + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.2(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.15.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.6.2) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + eslint-plugin-jsonc@2.16.0(eslint@8.57.0): dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) @@ -5730,6 +6135,19 @@ snapshots: - supports-color - typescript + eslint-plugin-no-explicit-type-exports@0.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2): + dependencies: + '@typescript-eslint/experimental-utils': 2.34.0(eslint@8.57.0)(typescript@5.6.2) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.6.2) + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.2(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + - typescript + eslint-plugin-no-unsanitized@4.0.2(eslint@8.57.0): dependencies: eslint: 8.57.0 @@ -5752,6 +6170,16 @@ snapshots: - supports-color - typescript + eslint-plugin-perfectionist@2.11.0(eslint@8.57.0)(typescript@5.6.2): + dependencies: + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.6.2) + eslint: 8.57.0 + minimatch: 9.0.5 + natural-compare-lite: 1.4.0 + transitivePeerDependencies: + - supports-color + - typescript + eslint-plugin-pii@1.0.2(eslint@8.57.0): dependencies: escape-string-regexp: 4.0.0 @@ -5772,6 +6200,15 @@ snapshots: - supports-color - typescript + eslint-plugin-react-form-fields@1.2.22(eslint@8.57.0)(typescript@5.6.2): + dependencies: + '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.0)(typescript@5.6.2) + eslint: 8.57.0 + jsx-ast-utils: 3.3.5 + transitivePeerDependencies: + - supports-color + - typescript + eslint-plugin-react-hook-form@0.3.0: dependencies: requireindex: 1.1.0 @@ -5841,6 +6278,17 @@ snapshots: - supports-color - typescript + eslint-plugin-storybook@0.8.0(eslint@8.57.0)(typescript@5.6.2): + dependencies: + '@storybook/csf': 0.0.1 + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.6.2) + eslint: 8.57.0 + requireindex: 1.2.0 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + - typescript + eslint-plugin-tailwindcss@3.17.4(tailwindcss@3.4.10): dependencies: fast-glob: 3.3.2 @@ -5878,6 +6326,17 @@ snapshots: - eslint - supports-color + eslint-plugin-typescript-compat@1.0.2(eslint@8.57.0)(typescript@5.6.2): + dependencies: + '@mdn/browser-compat-data': 5.5.49 + '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.0)(typescript@5.6.2) + browserslist: 4.23.3 + semver: 7.6.3 + typescript: 5.6.2 + transitivePeerDependencies: + - eslint + - supports-color + eslint-plugin-typescript-sort-keys@3.2.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4): dependencies: '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.0)(typescript@5.5.4) @@ -5889,6 +6348,17 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-plugin-typescript-sort-keys@3.2.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2): + dependencies: + '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.0)(typescript@5.6.2) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.6.2) + eslint: 8.57.0 + json-schema: 0.4.0 + natural-compare-lite: 1.4.0 + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + eslint-plugin-unicorn@54.0.0(eslint@8.57.0): dependencies: '@babel/helper-validator-identifier': 7.24.7 @@ -5918,6 +6388,13 @@ snapshots: optionalDependencies: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) + eslint-plugin-unused-imports@3.2.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + eslint-rule-composer: 0.3.0 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2) + eslint-plugin-validate-jsx-nesting@0.1.1(eslint@8.57.0): dependencies: eslint: 8.57.0 @@ -5934,6 +6411,17 @@ snapshots: - supports-color - typescript + eslint-plugin-vitest@0.5.4(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2)(vitest@2.0.5(@types/node@22.5.1)): + dependencies: + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.6.2) + eslint: 8.57.0 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2) + vitest: 2.0.5(@types/node@22.5.1) + transitivePeerDependencies: + - supports-color + - typescript + eslint-plugin-yml@1.14.0(eslint@8.57.0): dependencies: debug: 4.3.6 @@ -6123,11 +6611,6 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - find-yarn-workspace-root2@1.2.16: - dependencies: - micromatch: 4.0.7 - pkg-dir: 4.2.0 - flat-cache@3.2.0: dependencies: flatted: 3.3.1 @@ -6271,7 +6754,7 @@ snapshots: dependencies: dir-glob: 3.0.1 fast-glob: 3.3.2 - ignore: 5.3.1 + ignore: 5.3.2 merge2: 1.4.1 slash: 4.0.0 @@ -6321,7 +6804,7 @@ snapshots: human-signals@5.0.0: {} - husky@9.1.5: {} + husky@9.1.6: {} iconv-lite@0.4.24: dependencies: @@ -6329,6 +6812,8 @@ snapshots: ignore@5.3.1: {} + ignore@5.3.2: {} + import-fresh@3.3.0: dependencies: parent-module: 1.0.1 @@ -6349,18 +6834,6 @@ snapshots: ini@4.1.3: {} - init-package-json@6.0.3: - dependencies: - '@npmcli/package-json': 5.2.0 - npm-package-arg: 11.0.3 - promzard: 1.0.2 - read: 3.0.1 - semver: 7.6.3 - validate-npm-package-license: 3.0.4 - validate-npm-package-name: 5.0.1 - transitivePeerDependencies: - - bluebird - internal-slot@1.0.7: dependencies: es-errors: 1.3.0 @@ -6565,6 +7038,8 @@ snapshots: jsdoc-type-pratt-parser@4.0.0: {} + jsdoc-type-pratt-parser@4.1.0: {} + jsesc@0.5.0: {} jsesc@3.0.2: {} @@ -6640,18 +7115,18 @@ snapshots: dependencies: uc.micro: 2.1.0 - lint-staged@15.2.9: + lint-staged@15.2.10: dependencies: chalk: 5.3.0 commander: 12.1.0 - debug: 4.3.6 + debug: 4.3.7 execa: 8.0.1 lilconfig: 3.1.2 listr2: 8.2.4 - micromatch: 4.0.7 + micromatch: 4.0.8 pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.5.0 + yaml: 2.5.1 transitivePeerDependencies: - supports-color @@ -6673,13 +7148,6 @@ snapshots: load-tsconfig@0.2.5: {} - load-yaml-file@0.2.0: - dependencies: - graceful-fs: 4.2.11 - js-yaml: 3.14.1 - pify: 4.0.1 - strip-bom: 3.0.0 - local-pkg@0.5.0: dependencies: mlly: 1.7.1 @@ -6728,6 +7196,18 @@ snapshots: pseudomap: 1.0.2 yallist: 2.1.2 + magic-regexp@0.8.0: + dependencies: + estree-walker: 3.0.3 + magic-string: 0.30.11 + mlly: 1.7.1 + regexp-tree: 0.1.27 + type-level-regexp: 0.1.17 + ufo: 1.5.4 + unplugin: 1.14.1 + transitivePeerDependencies: + - webpack-sources + magic-string@0.30.11: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -7038,7 +7518,7 @@ snapshots: micromark@2.11.4: dependencies: - debug: 4.3.6 + debug: 4.3.7 parse-entities: 2.0.0 transitivePeerDependencies: - supports-color @@ -7046,7 +7526,7 @@ snapshots: micromark@4.0.0: dependencies: '@types/debug': 4.1.12 - debug: 4.3.6 + debug: 4.3.7 decode-named-character-reference: 1.0.2 devlop: 1.1.0 micromark-core-commonmark: 2.0.1 @@ -7070,6 +7550,11 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + mimic-fn@2.1.0: {} mimic-fn@4.0.0: {} @@ -7105,7 +7590,7 @@ snapshots: ms@2.1.2: {} - mute-stream@1.0.0: {} + ms@2.1.3: {} mz@2.7.0: dependencies: @@ -7215,6 +7700,8 @@ snapshots: oh-my-error@1.1.1: {} + oh-my-error@2.0.0-prerelease.0: {} + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -7270,6 +7757,8 @@ snapshots: package-json-from-dist@1.0.0: {} + package-manager-detector@0.2.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -7334,6 +7823,8 @@ snapshots: picocolors@1.0.1: {} + picocolors@1.1.0: {} + picomatch@2.3.1: {} picomatch@4.0.2: {} @@ -7346,10 +7837,6 @@ snapshots: pirates@4.0.6: {} - pkg-dir@4.2.0: - dependencies: - find-up: 4.1.0 - pkg-types@1.2.0: dependencies: confbox: 0.1.7 @@ -7360,36 +7847,36 @@ snapshots: possible-typed-array-names@1.0.0: {} - postcss-import@15.1.0(postcss@8.4.41): + postcss-import@15.1.0(postcss@8.4.47): dependencies: - postcss: 8.4.41 + postcss: 8.4.47 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 - postcss-js@4.0.1(postcss@8.4.41): + postcss-js@4.0.1(postcss@8.4.47): dependencies: camelcase-css: 2.0.1 - postcss: 8.4.41 + postcss: 8.4.47 - postcss-load-config@4.0.2(postcss@8.4.41): + postcss-load-config@4.0.2(postcss@8.4.47): dependencies: lilconfig: 3.1.2 - yaml: 2.5.0 + yaml: 2.5.1 optionalDependencies: - postcss: 8.4.41 + postcss: 8.4.47 - postcss-load-config@6.0.1(jiti@1.21.6)(postcss@8.4.41)(yaml@2.5.0): + postcss-load-config@6.0.1(jiti@1.21.6)(postcss@8.4.47)(yaml@2.5.1): dependencies: lilconfig: 3.1.2 optionalDependencies: jiti: 1.21.6 - postcss: 8.4.41 - yaml: 2.5.0 + postcss: 8.4.47 + yaml: 2.5.1 - postcss-nested@6.2.0(postcss@8.4.41): + postcss-nested@6.2.0(postcss@8.4.47): dependencies: - postcss: 8.4.41 + postcss: 8.4.47 postcss-selector-parser: 6.1.2 postcss-selector-parser@6.1.2: @@ -7405,12 +7892,11 @@ snapshots: picocolors: 1.0.1 source-map-js: 1.2.0 - preferred-pm@3.1.4: + postcss@8.4.47: dependencies: - find-up: 5.0.0 - find-yarn-workspace-root2: 1.2.16 - path-exists: 4.0.0 - which-pm: 2.2.0 + nanoid: 3.3.7 + picocolors: 1.1.0 + source-map-js: 1.2.1 prelude-ls@1.2.1: {} @@ -7434,10 +7920,6 @@ snapshots: err-code: 2.0.3 retry: 0.12.0 - promzard@1.0.2: - dependencies: - read: 3.0.1 - prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -7483,10 +7965,6 @@ snapshots: pify: 4.0.1 strip-bom: 3.0.0 - read@3.0.1: - dependencies: - mute-stream: 1.0.0 - readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -7710,6 +8188,8 @@ snapshots: source-map-js@1.2.0: {} + source-map-js@1.2.1: {} + source-map@0.8.0-beta.0: dependencies: whatwg-url: 7.1.0 @@ -7760,12 +8240,12 @@ snapshots: string-width@6.1.0: dependencies: eastasianwidth: 0.2.0 - emoji-regex: 10.3.0 + emoji-regex: 10.4.0 strip-ansi: 7.1.0 string-width@7.2.0: dependencies: - emoji-regex: 10.3.0 + emoji-regex: 10.4.0 get-east-asian-width: 1.2.0 strip-ansi: 7.1.0 @@ -7828,7 +8308,7 @@ snapshots: strip-ansi@7.1.0: dependencies: - ansi-regex: 6.0.1 + ansi-regex: 6.1.0 strip-bom@3.0.0: {} @@ -7885,15 +8365,15 @@ snapshots: is-glob: 4.0.3 jiti: 1.21.6 lilconfig: 2.1.0 - micromatch: 4.0.7 + micromatch: 4.0.8 normalize-path: 3.0.0 object-hash: 3.0.0 - picocolors: 1.0.1 - postcss: 8.4.41 - postcss-import: 15.1.0(postcss@8.4.41) - postcss-js: 4.0.1(postcss@8.4.41) - postcss-load-config: 4.0.2(postcss@8.4.41) - postcss-nested: 6.2.0(postcss@8.4.41) + picocolors: 1.1.0 + postcss: 8.4.47 + postcss-import: 15.1.0(postcss@8.4.47) + postcss-js: 4.0.1(postcss@8.4.47) + postcss-load-config: 4.0.2(postcss@8.4.47) + postcss-nested: 6.2.0(postcss@8.4.47) postcss-selector-parser: 6.1.2 resolve: 1.22.8 sucrase: 3.35.0 @@ -7946,6 +8426,10 @@ snapshots: dependencies: typescript: 5.5.4 + ts-api-utils@1.3.0(typescript@5.6.2): + dependencies: + typescript: 5.6.2 + ts-dedent@2.2.0: {} ts-interface-checker@0.1.13: {} @@ -7961,7 +8445,7 @@ snapshots: tslib@2.7.0: {} - tsup@8.2.4(jiti@1.21.6)(postcss@8.4.41)(typescript@5.5.4)(yaml@2.5.0): + tsup@8.2.4(jiti@1.21.6)(postcss@8.4.47)(typescript@5.5.4)(yaml@2.5.1): dependencies: bundle-require: 5.0.0(esbuild@0.23.1) cac: 6.7.14 @@ -7973,14 +8457,14 @@ snapshots: globby: 11.1.0 joycon: 3.1.1 picocolors: 1.0.1 - postcss-load-config: 6.0.1(jiti@1.21.6)(postcss@8.4.41)(yaml@2.5.0) + postcss-load-config: 6.0.1(jiti@1.21.6)(postcss@8.4.47)(yaml@2.5.1) resolve-from: 5.0.0 rollup: 4.21.2 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tree-kill: 1.2.2 optionalDependencies: - postcss: 8.4.41 + postcss: 8.4.47 typescript: 5.5.4 transitivePeerDependencies: - jiti @@ -7988,37 +8472,69 @@ snapshots: - tsx - yaml + tsup@8.2.4(jiti@1.21.6)(postcss@8.4.47)(typescript@5.6.2)(yaml@2.5.1): + dependencies: + bundle-require: 5.0.0(esbuild@0.23.1) + cac: 6.7.14 + chokidar: 3.6.0 + consola: 3.2.3 + debug: 4.3.6 + esbuild: 0.23.1 + execa: 5.1.1 + globby: 11.1.0 + joycon: 3.1.1 + picocolors: 1.0.1 + postcss-load-config: 6.0.1(jiti@1.21.6)(postcss@8.4.47)(yaml@2.5.1) + resolve-from: 5.0.0 + rollup: 4.21.2 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tree-kill: 1.2.2 + optionalDependencies: + postcss: 8.4.47 + typescript: 5.6.2 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + tsutils@3.21.0(typescript@5.5.4): dependencies: tslib: 1.14.1 typescript: 5.5.4 - turbo-darwin-64@2.0.12: + tsutils@3.21.0(typescript@5.6.2): + dependencies: + tslib: 1.14.1 + typescript: 5.6.2 + + turbo-darwin-64@2.2.3: optional: true - turbo-darwin-arm64@2.0.12: + turbo-darwin-arm64@2.2.3: optional: true - turbo-linux-64@2.0.12: + turbo-linux-64@2.2.3: optional: true - turbo-linux-arm64@2.0.12: + turbo-linux-arm64@2.2.3: optional: true - turbo-windows-64@2.0.12: + turbo-windows-64@2.2.3: optional: true - turbo-windows-arm64@2.0.12: + turbo-windows-arm64@2.2.3: optional: true - turbo@2.0.12: + turbo@2.2.3: optionalDependencies: - turbo-darwin-64: 2.0.12 - turbo-darwin-arm64: 2.0.12 - turbo-linux-64: 2.0.12 - turbo-linux-arm64: 2.0.12 - turbo-windows-64: 2.0.12 - turbo-windows-arm64: 2.0.12 + turbo-darwin-64: 2.2.3 + turbo-darwin-arm64: 2.2.3 + turbo-linux-64: 2.2.3 + turbo-linux-arm64: 2.2.3 + turbo-windows-64: 2.2.3 + turbo-windows-arm64: 2.2.3 type-check@0.4.0: dependencies: @@ -8032,6 +8548,8 @@ snapshots: type-fest@3.13.1: {} + type-level-regexp@0.1.17: {} + typed-array-buffer@1.0.2: dependencies: call-bind: 1.0.7 @@ -8068,6 +8586,10 @@ snapshots: typescript@5.5.4: {} + typescript@5.6.2: {} + + typescript@5.6.3: {} + uc.micro@2.1.0: {} ufo@1.5.4: {} @@ -8089,7 +8611,7 @@ snapshots: '@types/node': 20.16.2 '@types/unist': 3.0.3 concat-stream: 2.0.0 - debug: 4.3.6 + debug: 4.3.7 extend: 3.0.2 glob: 10.4.5 ignore: 5.3.1 @@ -8103,7 +8625,7 @@ snapshots: vfile-message: 4.0.2 vfile-reporter: 8.1.1 vfile-statistics: 3.0.0 - yaml: 2.5.0 + yaml: 2.5.1 transitivePeerDependencies: - bluebird - supports-color @@ -8153,11 +8675,16 @@ snapshots: universalify@2.0.1: {} + unplugin@1.14.1: + dependencies: + acorn: 8.12.1 + webpack-virtual-modules: 0.6.2 + update-browserslist-db@1.1.0(browserslist@4.23.3): dependencies: browserslist: 4.23.3 escalade: 3.2.0 - picocolors: 1.0.1 + picocolors: 1.1.0 uri-js@4.4.1: dependencies: @@ -8276,6 +8803,8 @@ snapshots: webidl-conversions@4.0.2: {} + webpack-virtual-modules@0.6.2: {} + whatwg-url@7.1.0: dependencies: lodash.sortby: 4.7.0 @@ -8312,11 +8841,6 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.3 - which-pm@2.2.0: - dependencies: - load-yaml-file: 0.2.0 - path-exists: 4.0.0 - which-typed-array@1.1.15: dependencies: available-typed-arrays: 1.0.7 @@ -8374,6 +8898,8 @@ snapshots: yaml@2.5.0: {} + yaml@2.5.1: {} + yocto-queue@0.1.0: {} zwitch@2.0.4: {} diff --git a/turbo.json b/turbo.json index 40dcf95..80d34ee 100644 --- a/turbo.json +++ b/turbo.json @@ -3,6 +3,7 @@ "tasks": { "pre": {}, "start": {}, + "bench": {}, "build": {}, "build:npm": { "inputs": ["*", "!dist"]