New Upstream Release - node-compare-versions

Ready changes

Summary

Merged new upstream version: 5.0.3 (was: 5.0.1).

Diff

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..553a934
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,22 @@
+name: build
+
+on: [push, pull_request]
+
+jobs:
+  build:
+
+    runs-on: ubuntu-latest
+
+    steps:
+    - uses: actions/checkout@v2
+    - name: Use Node.js 16.x
+      uses: actions/setup-node@v2
+      with:
+        node-version: 16.x
+    - run: npm ci
+    - run: npm test
+
+    - name: Coveralls
+      uses: coverallsapp/github-action@master
+      with:
+        github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..81def47
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.nyc_output/
+.vscode/
+coverage/
+lib/
+node_modules/
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 66ebd26..d771e71 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## [5.0.3](https://github.com/omichelsen/compare-versions/releases/tag/v5.0.3) - 2022-12-13
+- Fix npm build chache from 5.0.2.
+-
+## [5.0.2](https://github.com/omichelsen/compare-versions/releases/tag/v5.0.2) - 2022-12-13
+- Fix `satisfies()` handling of 0.x versions.
+
 ## [5.0.1](https://github.com/omichelsen/compare-versions/releases/tag/v5.0.1) - 2022-08-26
 - Include source file in npm bundle for source maps.
 
diff --git a/debian/changelog b/debian/changelog
index 84fd70e..3a75a15 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+node-compare-versions (5.0.3-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Mon, 19 Jun 2023 18:27:40 -0000
+
 node-compare-versions (5.0.1-2) unstable; urgency=medium
 
   [ Debian Janitor ]
diff --git a/debian/patches/fix-typescript.patch b/debian/patches/fix-typescript.patch
index bddd4d8..4733de2 100644
--- a/debian/patches/fix-typescript.patch
+++ b/debian/patches/fix-typescript.patch
@@ -3,8 +3,10 @@ Author: Yadd <yadd@debian.org>
 Forwarded: not-needed
 Last-Update: 2022-08-31
 
---- a/tsconfig.json
-+++ b/tsconfig.json
+Index: node-compare-versions.git/tsconfig.json
+===================================================================
+--- node-compare-versions.git.orig/tsconfig.json
++++ node-compare-versions.git/tsconfig.json
 @@ -1,5 +1,6 @@
  {
  	"compilerOptions": {
diff --git a/package-lock.json b/package-lock.json
index 74ad9e4..d1cc68f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,18 +1,18 @@
 {
   "name": "compare-versions",
-  "version": "5.0.0",
+  "version": "5.0.3",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "compare-versions",
-      "version": "5.0.0",
+      "version": "5.0.3",
       "license": "MIT",
       "devDependencies": {
-        "@types/mocha": "^9.1.0",
+        "@types/mocha": "^10.0.1",
         "c8": "^7.10.0",
         "mocha": "^10.0.0",
-        "rollup": "^2.78.1",
+        "rollup": "^3.7.4",
         "ts-node": "^10.7.0",
         "typescript": "^4.6.3"
       }
@@ -100,28 +100,22 @@
       "dev": true
     },
     "node_modules/@types/mocha": {
-      "version": "9.1.1",
-      "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz",
-      "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==",
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz",
+      "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==",
       "dev": true
     },
     "node_modules/@types/node": {
-      "version": "18.7.12",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.12.tgz",
-      "integrity": "sha512-caqFX7GwvZ4KLnhpI9CfiMkgHKp6kvFAIgpkha0cjO7bAQvB6dWe+q3fTHmm7fQvv59pd4tPj77nriq2M6U2dw==",
+      "version": "18.11.14",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.14.tgz",
+      "integrity": "sha512-0KXV57tENYmmJMl+FekeW9V3O/rlcqGQQJ/hNh9r8pKIj304pskWuEd8fCyNT86g/TpO0gcOTiLzsHLEURFMIQ==",
       "dev": true,
       "peer": true
     },
-    "node_modules/@ungap/promise-all-settled": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
-      "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
-      "dev": true
-    },
     "node_modules/acorn": {
-      "version": "8.8.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
-      "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
+      "version": "8.8.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+      "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
       "dev": true,
       "bin": {
         "acorn": "bin/acorn"
@@ -173,9 +167,9 @@
       }
     },
     "node_modules/anymatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
-      "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
       "dev": true,
       "dependencies": {
         "normalize-path": "^3.0.0",
@@ -356,18 +350,9 @@
       "dev": true
     },
     "node_modules/convert-source-map": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
-      "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "~5.1.1"
-      }
-    },
-    "node_modules/convert-source-map/node_modules/safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+      "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
       "dev": true
     },
     "node_modules/create-require": {
@@ -825,12 +810,11 @@
       }
     },
     "node_modules/mocha": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz",
-      "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==",
+      "version": "10.2.0",
+      "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
+      "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
       "dev": true,
       "dependencies": {
-        "@ungap/promise-all-settled": "1.1.2",
         "ansi-colors": "4.1.1",
         "browser-stdout": "1.3.1",
         "chokidar": "3.5.3",
@@ -1040,15 +1024,16 @@
       }
     },
     "node_modules/rollup": {
-      "version": "2.78.1",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz",
-      "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==",
+      "version": "3.7.4",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.7.4.tgz",
+      "integrity": "sha512-jN9rx3k5pfg9H9al0r0y1EYKSeiRANZRYX32SuNXAnKzh6cVyf4LZVto1KAuDnbHT03E1CpsgqDKaqQ8FZtgxw==",
       "dev": true,
       "bin": {
         "rollup": "dist/bin/rollup"
       },
       "engines": {
-        "node": ">=10.0.0"
+        "node": ">=14.18.0",
+        "npm": ">=8.0.0"
       },
       "optionalDependencies": {
         "fsevents": "~2.3.2"
@@ -1270,9 +1255,9 @@
       }
     },
     "node_modules/typescript": {
-      "version": "4.7.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
-      "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
+      "version": "4.9.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
+      "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
       "dev": true,
       "bin": {
         "tsc": "bin/tsc",
@@ -1303,13 +1288,13 @@
       }
     },
     "node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": {
-      "version": "0.3.15",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz",
-      "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==",
+      "version": "0.3.17",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+      "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/resolve-uri": "^3.0.3",
-        "@jridgewell/sourcemap-codec": "^1.4.10"
+        "@jridgewell/resolve-uri": "3.1.0",
+        "@jridgewell/sourcemap-codec": "1.4.14"
       }
     },
     "node_modules/which": {
@@ -1504,28 +1489,22 @@
       "dev": true
     },
     "@types/mocha": {
-      "version": "9.1.1",
-      "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz",
-      "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==",
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz",
+      "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==",
       "dev": true
     },
     "@types/node": {
-      "version": "18.7.12",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.12.tgz",
-      "integrity": "sha512-caqFX7GwvZ4KLnhpI9CfiMkgHKp6kvFAIgpkha0cjO7bAQvB6dWe+q3fTHmm7fQvv59pd4tPj77nriq2M6U2dw==",
+      "version": "18.11.14",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.14.tgz",
+      "integrity": "sha512-0KXV57tENYmmJMl+FekeW9V3O/rlcqGQQJ/hNh9r8pKIj304pskWuEd8fCyNT86g/TpO0gcOTiLzsHLEURFMIQ==",
       "dev": true,
       "peer": true
     },
-    "@ungap/promise-all-settled": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
-      "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
-      "dev": true
-    },
     "acorn": {
-      "version": "8.8.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
-      "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
+      "version": "8.8.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+      "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
       "dev": true
     },
     "acorn-walk": {
@@ -1556,9 +1535,9 @@
       }
     },
     "anymatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
-      "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
       "dev": true,
       "requires": {
         "normalize-path": "^3.0.0",
@@ -1698,21 +1677,10 @@
       "dev": true
     },
     "convert-source-map": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
-      "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "~5.1.1"
-      },
-      "dependencies": {
-        "safe-buffer": {
-          "version": "5.1.2",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-          "dev": true
-        }
-      }
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+      "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+      "dev": true
     },
     "create-require": {
       "version": "1.1.1",
@@ -2044,12 +2012,11 @@
       }
     },
     "mocha": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz",
-      "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==",
+      "version": "10.2.0",
+      "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
+      "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
       "dev": true,
       "requires": {
-        "@ungap/promise-all-settled": "1.1.2",
         "ansi-colors": "4.1.1",
         "browser-stdout": "1.3.1",
         "chokidar": "3.5.3",
@@ -2193,9 +2160,9 @@
       }
     },
     "rollup": {
-      "version": "2.78.1",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz",
-      "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==",
+      "version": "3.7.4",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.7.4.tgz",
+      "integrity": "sha512-jN9rx3k5pfg9H9al0r0y1EYKSeiRANZRYX32SuNXAnKzh6cVyf4LZVto1KAuDnbHT03E1CpsgqDKaqQ8FZtgxw==",
       "dev": true,
       "requires": {
         "fsevents": "~2.3.2"
@@ -2349,9 +2316,9 @@
       }
     },
     "typescript": {
-      "version": "4.7.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
-      "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
+      "version": "4.9.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
+      "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
       "dev": true
     },
     "v8-compile-cache-lib": {
@@ -2372,13 +2339,13 @@
       },
       "dependencies": {
         "@jridgewell/trace-mapping": {
-          "version": "0.3.15",
-          "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz",
-          "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==",
+          "version": "0.3.17",
+          "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+          "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
           "dev": true,
           "requires": {
-            "@jridgewell/resolve-uri": "^3.0.3",
-            "@jridgewell/sourcemap-codec": "^1.4.10"
+            "@jridgewell/resolve-uri": "3.1.0",
+            "@jridgewell/sourcemap-codec": "1.4.14"
           }
         }
       }
diff --git a/package.json b/package.json
index 5708fa5..b4b8393 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "compare-versions",
-  "version": "5.0.1",
+  "version": "5.0.3",
   "description": "Compare semver version strings to find greater, equal or lesser.",
   "repository": {
     "type": "git",
@@ -34,10 +34,10 @@
     "src"
   ],
   "devDependencies": {
-    "@types/mocha": "^9.1.0",
+    "@types/mocha": "^10.0.1",
     "c8": "^7.10.0",
     "mocha": "^10.0.0",
-    "rollup": "^2.78.1",
+    "rollup": "^3.7.4",
     "ts-node": "^10.7.0",
     "typescript": "^4.6.3"
   }
diff --git a/src/index.ts b/src/index.ts
index 48d5156..f813b44 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -100,14 +100,31 @@ export const satisfies = (version: string, range: string) => {
     return compare(version, range, op as CompareOperator);
 
   // else range of either "~" or "^" is assumed
-  const [v1, v2, v3] = validateAndParse(version);
-  const [r1, r2, r3] = validateAndParse(range);
-  if (compareStrings(v1, r1) !== 0) return false;
-  if (op === '^') {
-    return compareSegments([v2, v3], [r2, r3]) >= 0;
+  const [v1, v2, v3, , vp] = validateAndParse(version);
+  const [r1, r2, r3, , rp] = validateAndParse(range);
+  const v = [v1, v2, v3];
+  const r = [r1, r2 ?? 'x', r3 ?? 'x'];
+
+  // validate pre-release
+  if (rp) {
+    if (!vp) return false;
+    if (compareSegments(v, r) !== 0) return false;
+    if (compareSegments(vp.split('.'), rp.split('.')) === -1) return false;
   }
-  if (compareStrings(v2, r2) !== 0) return false;
-  return compareStrings(v3, r3) >= 0;
+
+  // first non-zero number
+  const nonZero = r.findIndex((v) => v !== '0') + 1;
+
+  // pointer to where segments can be >=
+  const i = op === '~' ? 2 : nonZero > 1 ? nonZero : 1;
+
+  // before pointer must be equal
+  if (compareSegments(v.slice(0, i), r.slice(0, i)) !== 0) return false;
+
+  // after pointer must be >=
+  if (compareSegments(v.slice(i), r.slice(i)) === -1) return false;
+
+  return true;
 };
 
 const semver =
@@ -146,8 +163,8 @@ const compareStrings = (a: string, b: string) => {
 };
 
 const compareSegments = (
-  a: string | RegExpMatchArray,
-  b: string | RegExpMatchArray
+  a: string | string[] | RegExpMatchArray,
+  b: string | string[] | RegExpMatchArray
 ) => {
   for (let i = 0; i < Math.max(a.length, b.length); i++) {
     const r = compareStrings(a[i] || '0', b[i] || '0');
diff --git a/test/satisfies.ts b/test/satisfies.ts
index 93ffc46..0db2d41 100644
--- a/test/satisfies.ts
+++ b/test/satisfies.ts
@@ -1,9 +1,37 @@
 import assert from 'assert';
 import { satisfies } from '../src/index';
 
-describe('validate versions', () => {
-  (
-    [
+describe('satisfies versions', () => {
+  const runTests = (dataSet: Array<[string, string, boolean]>) => {
+    dataSet.forEach(([v, m, expected]) => {
+      it(`${v} ${expected ? 'satisfies' : 'violates'} ${m}`, () => {
+        assert.strictEqual(satisfies(v, m), expected);
+      });
+    });
+  };
+
+  describe('tilde - https://docs.npmjs.com/cli/v6/using-npm/semver#tilde-ranges-123-12-1', () => {
+    runTests([
+      ['1.0.0', '~1.0.1', false],
+      ['1.0.1', '~1.0.1', true],
+      ['1.2.5', '~1.2.3', true],
+      ['1.3.0', '~1.2.3', false],
+      ['1.2.5', '~1.2', true], // (Same as 1.2.x)
+      ['1.3.0', '~1.2', false], // (Same as 1.2.x)
+      ['1.0.0', '~1', true], // (Same as 1.x)
+      ['2.0.0', '~1', false], // (Same as 1.x)
+      ['0.2.5', '~0.2.3', true],
+      ['0.3.0', '~0.2.3', false],
+      ['0.2.5', '~0.2', true], // (Same as 0.2.x)
+      ['0.3.0', '~0.2', false], // (Same as 0.2.x)
+      ['0.0.0', '~0', true], // (Same as 0.x)
+      ['0.1.2', '~0', true], // (Same as 0.x)
+      ['1.0.0', '~0', false], // (Same as 0.x)
+    ]);
+  });
+
+  describe('caret - https://docs.npmjs.com/cli/v6/using-npm/semver#caret-ranges-123-025-004', () => {
+    runTests([
       ['1.0.0', '^1', true],
       ['1.0.0', '^1.0', true],
       ['1.0.0', '^1.0.0', true],
@@ -12,51 +40,60 @@ describe('validate versions', () => {
       ['2.0.0', '^1.0.0', false],
       ['1.0.0', '^1.2.0', false],
       ['1.0.1', '^1.2.0', false],
-      ['1.3.4', '^1.2.5', true],
-      ['1.0.0', '~1.2.0', false],
-      ['1.0.0', '~1.0.1', false],
-      ['1.0.1', '~1.0.0', true],
-      ['1.3.4', '~1.2.5', false],
-      ['1.0.0', '~1.0.0', true],
-      ['1.0.0-alpha.1', '^1.0.0', true],
-      ['1.1.0-alpha.1', '^1.0.0', true],
-      ['1.2.0', '>1.0.0', true],
-      ['1.2.0', '<1.0.0', false],
-      ['1.0.0', '<=1.0.0', true],
-      ['1.0.0', '<=2.0.0', true],
-      ['1.0.1', '1.0.0', false],
-      ['1.0.0', '1.0.0', true],
-      ['10.1.8', '>10.0.4', true],
-      ['10.1.8', '>=10.0.4', true],
-      ['10.0.1', '=10.0.1', true],
-      ['10.0.1', '=10.1.*', false],
-      ['10.1.1', '<10.2.2', true],
-      ['10.1.1', '<10.0.2', false],
-      ['10.1.1', '<=10.2.2', true],
-      ['10.1.1', '<=10.1.1', true],
-      ['10.1.1', '<=10.0.2', false],
-      ['10.1.1', '>=10.0.2', true],
-      ['10.1.1', '>=10.1.1', true],
-      ['10.1.1', '>=10.2.2', false],
-      ['11.0.0', '>=10.1.1', true],
-      ['3', '3.x.x', true],
-      ['3.3', '3.x.x', true],
-      ['3.3.3', '3.x.x', true],
-      ['3.x.x', '3.3.3', true],
-      ['3.3.3', '3.X.X', true],
-      ['3.3.3', '3.3.x', true],
-      ['3.3.3', '3.*.*', true],
-      ['3.3.3', '3.3.*', true],
-      ['3.0.3', '3.0.*', true],
-      ['1.1.0', '1.2.x', false],
-      ['1.1.0', '2.x.x', false],
-      ['2.0.0', '<2.x.x', false],
-      ['2.0.0', '<=2.x.x', true],
-      ['2.0.0', '>2.x.x', false],
-    ] as const
-  ).forEach(([v, m, expected]) => {
-    it(`${v} satisfies ${m}`, () => {
-      assert.equal(satisfies(v, m), expected);
-    });
+      ['1.3.4', '^1.2.3', true],
+      ['2.0.0', '^1.2.3', false],
+      ['0.3.0', '^0.2.3', false],
+      ['0.0.4', '^0.0.3', false],
+    ]);
+  });
+
+  runTests([
+    ['1.2.0', '>1.0.0', true],
+    ['1.2.0', '<1.0.0', false],
+    ['1.0.0', '<=1.0.0', true],
+    ['1.0.0', '<=2.0.0', true],
+    ['1.0.1', '1.0.0', false],
+    ['1.0.0', '1.0.0', true],
+    ['10.1.8', '>10.0.4', true],
+    ['10.1.8', '>=10.0.4', true],
+    ['10.0.1', '=10.0.1', true],
+    ['10.0.1', '=10.1.*', false],
+    ['10.1.1', '<10.2.2', true],
+    ['10.1.1', '<10.0.2', false],
+    ['10.1.1', '<=10.2.2', true],
+    ['10.1.1', '<=10.1.1', true],
+    ['10.1.1', '<=10.0.2', false],
+    ['10.1.1', '>=10.0.2', true],
+    ['10.1.1', '>=10.1.1', true],
+    ['10.1.1', '>=10.2.2', false],
+    ['11.0.0', '>=10.1.1', true],
+    ['3', '3.x.x', true],
+    ['3.3', '3.x.x', true],
+    ['3.3.3', '3.x.x', true],
+    ['3.x.x', '3.3.3', true],
+    ['3.3.3', '3.X.X', true],
+    ['3.3.3', '3.3.x', true],
+    ['3.3.3', '3.*.*', true],
+    ['3.3.3', '3.3.*', true],
+    ['3.0.3', '3.0.*', true],
+    ['1.1.0', '1.2.x', false],
+    ['1.1.0', '2.x.x', false],
+    ['2.0.0', '<2.x.x', false],
+    ['2.0.0', '<=2.x.x', true],
+    ['2.0.0', '>2.x.x', false],
+  ]);
+
+  describe('pre-release versions - https://semver.org/#spec-item-9', () => {
+    runTests([
+      ['1.2.3-beta.4', '~1.2.3-beta.2', true],
+      ['1.2.3-beta.1', '~1.2.3-beta.2', false],
+      ['1.2.4-beta.2', '~1.2.3-beta.2', false],
+      ['1.2.3-beta.4', '^1.2.3-beta.2', true],
+      ['1.2.4-beta.2', '^1.2.3-beta.2', false],
+      ['2.0.0', '^1.2.3-beta.2', false],
+      ['0.0.3-beta.2', '^0.0.3-beta', true],
+      ['0.0.3-pr.2', '^0.0.3-beta', true],
+      ['0.0.4', '^0.0.3-beta', false],
+    ]);
   });
 });

More details

Full run details

Historical runs