Repository: cdimascio/express-openapi-validator
Pull request #872 (2023-10-28 17:40:24)

Update build and packaging scripts
- Add `compile:release` npm script to build the package without source maps. Decreases unpacked size from ~350KB to ~250KB.
- Remove `:windows` variants of npm scripts
  - Add rimraf to handle cross-platform dir removal
  - Set `"ts-node": { "files": true }` in `tsconfig.json` so that it's not necessary to set env var `TS_NODE_FILES`
- Remove unused `assets/README.md` (it does not appear to have been used for many years according to npmjs.com)
- Use includes `"files": [...]` property in `package.json` to indicate `dist/` should be included in the built npm package rather than maintaining a list of everything that should be excluded in `.npmignore` (which has been deleted)
- Incorporate above mentioned updates into build.sh


Patch:
diff --git a/.npmignore b/.npmignore
deleted file mode 100644
index f7d46c4..0000000
--- a/.npmignore
+++ /dev/null
@@ -1,41 +0,0 @@
-.github
-.vscode
-/assets
-/examples
-/example
-/packages
-/docs
-node_modules
-/src
-/test
-/packages
-/typings
-_config.yml
-.all-contributorsrc
-.codacy.yml
-.editorconfig
-.gitignore
-.gitpod.yml
-.nycrc
-.prettierrc.json
-.travis.yml
-CHANGE_HISTORY.md
-CODE_OF_CONDUCT.md
-CONTRIBUTING.md
-a_reference
-.nyc_output
-jest
-/coverage
-.coverall.yml
-/uploads
-/greenkeeper.json
-/sample
-.coveralls.yml
-secrets.zip
-.travis.yml
-secrets.zip.enc
-README.md
-tsconfig.json
-TODO.md
-build.sh
-launch.json
diff --git a/assets/README.md b/assets/README.md
deleted file mode 100644
index b5a31e4..0000000
--- a/assets/README.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# 🦋 express-openapi-validator
-
-**An OpenApi validator for ExpressJS** that automatically validates **API** _**requests**_ and _**responses**_ using an **OpenAPI 3** specification.
-
-[🦋express-openapi-validator](https://github.com/cdimascio/express-openapi-validator) is an unopinionated library that integrates with new and existing API applications. express-openapi-validator lets you write code the way you want; it does not impose any coding convention or project layout. Simply, install the validator onto your express app, point it to your OpenAPI 3 specification, then define and implement routes the way you prefer. See an [example](#example-express-api-server).
-
-**Features:**
-
-- ✔️ request validation
-- ✔️ response validation (json only)
-- 👮 security validation / custom security functions
-- 👽 3rd party / custom formats
-- 🧵 optionally auto-map OpenAPI endpoints to Express handler functions
-- ✂️ **\$ref** support; split specs over multiple files
-- 🎈 file upload
-
-## Install
-
-```shell
-npm install express-openapi-validator
-```
-
-## Usage
-
-1. Require/import the openapi validator
-
-```javascript
-const OpenApiValidator = require('express-openapi-validator');
-```
-
-2. Install the middleware
-
-```javascript
-app.use(
-  OpenApiValidator.middleware({
-    apiSpec: './openapi.yaml',
-    validateRequests: true, // (default)
-    validateResponses: true, // false by default
-  }),
-);
-```
-
-3. Register an error handler
-
-```javascript
-app.use((err, req, res, next) => {
-  // format error
-  res.status(err.status || 500).json({
-    message: err.message,
-    errors: err.errors,
-  });
-});
-```
-
-_**Important:** Ensure express is configured with all relevant body parsers. Body parser middleware functions must be specified prior to any validated routes. See an [example](#example-express-api-server)_.
-
-## [Documentation](https://github.com/cdimascio/express-openapi-validator#readme)
-
-See the [full documentation](https://github.com/cdimascio/express-openapi-validator#readme)
-
-## License
-
-MIT
diff --git a/build.sh b/build.sh
index 95de8b9..e87f6a9 100755
--- a/build.sh
+++ b/build.sh
@@ -1,16 +1,11 @@
 #!/bin/bash
 
 set -e
-trap 'mv _README.md README.md' EXIT
-
-mv README.md _README.md
-
-cp assets/README.md README.md
 
 rm -rf node_modules
 npm ci
 
-npm run compile
+npm run compile:release
 npm t
 
 echo 'publishing...'
diff --git a/package-lock.json b/package-lock.json
index d1ae7f2..14b1069 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -44,6 +44,7 @@
         "nodemon": "^2.0.20",
         "nyc": "^15.1.0",
         "prettier": "^2.5.1",
+        "rimraf": "^5.0.5",
         "source-map-support": "0.5.21",
         "supertest": "^6.2.2",
         "ts-node": "^10.7.0",
@@ -808,6 +809,102 @@
         "node": ">=12"
       }
     },
+    "node_modules/@isaacs/cliui": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+      "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^5.1.2",
+        "string-width-cjs": "npm:string-width@^4.2.0",
+        "strip-ansi": "^7.0.1",
+        "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+        "wrap-ansi": "^8.1.0",
+        "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+      "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+      "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+      "version": "9.2.2",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+      "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+      "dev": true
+    },
+    "node_modules/@isaacs/cliui/node_modules/string-width": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+      "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+      "dev": true,
+      "dependencies": {
+        "eastasianwidth": "^0.2.0",
+        "emoji-regex": "^9.2.2",
+        "strip-ansi": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+      "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+      "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^6.1.0",
+        "string-width": "^5.0.1",
+        "strip-ansi": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
     "node_modules/@istanbuljs/load-nyc-config": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@@ -918,6 +1015,16 @@
       "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
       "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="
     },
+    "node_modules/@pkgjs/parseargs": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+      "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=14"
+      }
+    },
     "node_modules/@tsconfig/node10": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
@@ -1649,9 +1756,9 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001466",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001466.tgz",
-      "integrity": "sha512-ewtFBSfWjEmxUgNBSZItFSmVtvk9zkwkl1OfRZlKA8slltRN+/C/tuGVrF9styXkN36Yu3+SeJ1qkXxDEyNZ5w==",
+      "version": "1.0.30001555",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001555.tgz",
+      "integrity": "sha512-NzbUFKUnJ3DTcq6YyZB6+qqhfD112uR3uoEnkmfzm2wVzUNsFkU7AwBjKQ654Sp5cau0JxhFyRSn/tQZ+XfygA==",
       "dev": true,
       "funding": [
         {
@@ -1661,6 +1768,10 @@
         {
           "type": "tidelift",
           "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
         }
       ]
     },
@@ -2280,6 +2391,12 @@
         "node": ">=0.3.1"
       }
     },
+    "node_modules/eastasianwidth": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+      "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+      "dev": true
+    },
     "node_modules/ecc-jsbn": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -3527,6 +3644,21 @@
         "node": ">=8"
       }
     },
+    "node_modules/istanbul-lib-processinfo/node_modules/rimraf": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/istanbul-lib-report": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
@@ -3621,6 +3753,24 @@
         "node": ">=8"
       }
     },
+    "node_modules/jackspeak": {
+      "version": "2.3.6",
+      "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
+      "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
+      "dev": true,
+      "dependencies": {
+        "@isaacs/cliui": "^8.0.2"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      },
+      "optionalDependencies": {
+        "@pkgjs/parseargs": "^0.11.0"
+      }
+    },
     "node_modules/jacoco-parse": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/jacoco-parse/-/jacoco-parse-2.0.1.tgz",
@@ -4200,6 +4350,15 @@
       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
       "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
     },
+    "node_modules/minipass": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
+      "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      }
+    },
     "node_modules/mkdirp": {
       "version": "0.5.6",
       "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
@@ -4698,6 +4857,21 @@
         "node": ">=8"
       }
     },
+    "node_modules/nyc/node_modules/rimraf": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/nyc/node_modules/wrap-ansi": {
       "version": "6.2.0",
       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
@@ -5077,6 +5251,31 @@
         "node": ">=8"
       }
     },
+    "node_modules/path-scurry": {
+      "version": "1.10.1",
+      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
+      "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
+      "dev": true,
+      "dependencies": {
+        "lru-cache": "^9.1.1 || ^10.0.0",
+        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/path-scurry/node_modules/lru-cache": {
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz",
+      "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==",
+      "dev": true,
+      "engines": {
+        "node": "14 || >=16.14"
+      }
+    },
     "node_modules/path-to-regexp": {
       "version": "6.2.0",
       "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.0.tgz",
@@ -5475,15 +5674,92 @@
       }
     },
     "node_modules/rimraf": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz",
+      "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==",
       "dev": true,
       "dependencies": {
-        "glob": "^7.1.3"
+        "glob": "^10.3.7"
       },
       "bin": {
-        "rimraf": "bin.js"
+        "rimraf": "dist/esm/bin.mjs"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/rimraf/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/rimraf/node_modules/foreground-child": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+      "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.0",
+        "signal-exit": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/rimraf/node_modules/glob": {
+      "version": "10.3.10",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
+      "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
+      "dev": true,
+      "dependencies": {
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^2.3.5",
+        "minimatch": "^9.0.1",
+        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
+        "path-scurry": "^1.10.1"
+      },
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/rimraf/node_modules/minimatch": {
+      "version": "9.0.3",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+      "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/rimraf/node_modules/signal-exit": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+      "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+      "dev": true,
+      "engines": {
+        "node": ">=14"
       },
       "funding": {
         "url": "https://github.com/sponsors/isaacs"
@@ -5706,6 +5982,21 @@
         "node": ">=8"
       }
     },
+    "node_modules/spawn-wrap/node_modules/rimraf": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -5785,6 +6076,21 @@
         "node": ">=8"
       }
     },
+    "node_modules/string-width-cjs": {
+      "name": "string-width",
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/strip-ansi": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -5797,6 +6103,19 @@
         "node": ">=8"
       }
     },
+    "node_modules/strip-ansi-cjs": {
+      "name": "strip-ansi",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/strip-bom": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
@@ -6356,6 +6675,57 @@
         "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
       }
     },
+    "node_modules/wrap-ansi-cjs": {
+      "name": "wrap-ansi",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
+    "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/wrap-ansi-cjs/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/wrap-ansi-cjs/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
+    },
     "node_modules/wrap-ansi/node_modules/ansi-styles": {
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -7119,6 +7489,71 @@
         "@cspotcode/source-map-consumer": "0.8.0"
       }
     },
+    "@isaacs/cliui": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+      "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+      "dev": true,
+      "requires": {
+        "string-width": "^5.1.2",
+        "string-width-cjs": "npm:string-width@^4.2.0",
+        "strip-ansi": "^7.0.1",
+        "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+        "wrap-ansi": "^8.1.0",
+        "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "6.0.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+          "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "6.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+          "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+          "dev": true
+        },
+        "emoji-regex": {
+          "version": "9.2.2",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+          "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+          "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+          "dev": true,
+          "requires": {
+            "eastasianwidth": "^0.2.0",
+            "emoji-regex": "^9.2.2",
+            "strip-ansi": "^7.0.1"
+          }
+        },
+        "strip-ansi": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+          "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^6.0.1"
+          }
+        },
+        "wrap-ansi": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+          "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^6.1.0",
+            "string-width": "^5.0.1",
+            "strip-ansi": "^7.0.1"
+          }
+        }
+      }
+    },
     "@istanbuljs/load-nyc-config": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@@ -7207,6 +7642,13 @@
       "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
       "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="
     },
+    "@pkgjs/parseargs": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+      "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+      "dev": true,
+      "optional": true
+    },
     "@tsconfig/node10": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
@@ -7791,9 +8233,9 @@
       "dev": true
     },
     "caniuse-lite": {
-      "version": "1.0.30001466",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001466.tgz",
-      "integrity": "sha512-ewtFBSfWjEmxUgNBSZItFSmVtvk9zkwkl1OfRZlKA8slltRN+/C/tuGVrF9styXkN36Yu3+SeJ1qkXxDEyNZ5w==",
+      "version": "1.0.30001555",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001555.tgz",
+      "integrity": "sha512-NzbUFKUnJ3DTcq6YyZB6+qqhfD112uR3uoEnkmfzm2wVzUNsFkU7AwBjKQ654Sp5cau0JxhFyRSn/tQZ+XfygA==",
       "dev": true
     },
     "caseless": {
@@ -8268,6 +8710,12 @@
       "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
       "dev": true
     },
+    "eastasianwidth": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+      "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+      "dev": true
+    },
     "ecc-jsbn": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -9203,6 +9651,17 @@
         "p-map": "^3.0.0",
         "rimraf": "^3.0.0",
         "uuid": "^3.3.3"
+      },
+      "dependencies": {
+        "rimraf": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        }
       }
     },
     "istanbul-lib-report": {
@@ -9277,6 +9736,16 @@
         "istanbul-lib-report": "^3.0.0"
       }
     },
+    "jackspeak": {
+      "version": "2.3.6",
+      "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
+      "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
+      "dev": true,
+      "requires": {
+        "@isaacs/cliui": "^8.0.2",
+        "@pkgjs/parseargs": "^0.11.0"
+      }
+    },
     "jacoco-parse": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/jacoco-parse/-/jacoco-parse-2.0.1.tgz",
@@ -9727,6 +10196,12 @@
       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
       "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
     },
+    "minipass": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
+      "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
+      "dev": true
+    },
     "mkdirp": {
       "version": "0.5.6",
       "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
@@ -10107,6 +10582,15 @@
             "p-limit": "^2.2.0"
           }
         },
+        "rimraf": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        },
         "wrap-ansi": {
           "version": "6.2.0",
           "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
@@ -10385,6 +10869,24 @@
       "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
       "dev": true
     },
+    "path-scurry": {
+      "version": "1.10.1",
+      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
+      "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
+      "dev": true,
+      "requires": {
+        "lru-cache": "^9.1.1 || ^10.0.0",
+        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "10.0.1",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz",
+          "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==",
+          "dev": true
+        }
+      }
+    },
     "path-to-regexp": {
       "version": "6.2.0",
       "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.0.tgz",
@@ -10686,12 +11188,61 @@
       }
     },
     "rimraf": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz",
+      "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==",
       "dev": true,
       "requires": {
-        "glob": "^7.1.3"
+        "glob": "^10.3.7"
+      },
+      "dependencies": {
+        "brace-expansion": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+          "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+          "dev": true,
+          "requires": {
+            "balanced-match": "^1.0.0"
+          }
+        },
+        "foreground-child": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+          "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.0",
+            "signal-exit": "^4.0.1"
+          }
+        },
+        "glob": {
+          "version": "10.3.10",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
+          "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
+          "dev": true,
+          "requires": {
+            "foreground-child": "^3.1.0",
+            "jackspeak": "^2.3.5",
+            "minimatch": "^9.0.1",
+            "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
+            "path-scurry": "^1.10.1"
+          }
+        },
+        "minimatch": {
+          "version": "9.0.3",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+          "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        },
+        "signal-exit": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+          "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+          "dev": true
+        }
       }
     },
     "run-async": {
@@ -10879,6 +11430,17 @@
         "rimraf": "^3.0.0",
         "signal-exit": "^3.0.2",
         "which": "^2.0.1"
+      },
+      "dependencies": {
+        "rimraf": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        }
       }
     },
     "sprintf-js": {
@@ -10940,6 +11502,17 @@
         "strip-ansi": "^6.0.1"
       }
     },
+    "string-width-cjs": {
+      "version": "npm:string-width@4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dev": true,
+      "requires": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      }
+    },
     "strip-ansi": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -10949,6 +11522,15 @@
         "ansi-regex": "^5.0.1"
       }
     },
+    "strip-ansi-cjs": {
+      "version": "npm:strip-ansi@6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "^5.0.1"
+      }
+    },
     "strip-bom": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
@@ -11390,6 +11972,43 @@
         }
       }
     },
+    "wrap-ansi-cjs": {
+      "version": "npm:wrap-ansi@7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        }
+      }
+    },
     "wrappy": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
diff --git a/package.json b/package.json
index 77f00a6..5876b46 100644
--- a/package.json
+++ b/package.json
@@ -4,21 +4,22 @@
   "description": "Automatically validate API requests and responses with OpenAPI 3 and Express.",
   "main": "dist/index.js",
   "scripts": {
-    "compile": "rm -rf dist/ && tsc",
-    "compile:windows": "rmdir dist /s /q & tsc",
-    "test": "TS_NODE_FILES=true mocha -r source-map-support/register -r ts-node/register  --files --recursive -R spec test/**/*.spec.ts",
-    "test:debug": "TS_NODE_FILES=true mocha -r source-map-support/register -r ts-node/register --inspect-brk --files --recursive test/**/*.spec.ts",
-    "test:windows": "set TS_NODE_FILES=true & mocha -r source-map-support/register -r ts-node/register  --files --recursive test/**/*.spec.ts",
-    "test:coverage": "TS_NODE_FILES=true nyc mocha -r source-map-support/register -r ts-node/register --recursive test/**/*.spec.ts",
-    "test:coverage:windows": "set TS_NODE_FILES=true & nyc mocha -r source-map-support/register -r ts-node/register --recursive test/**/*.spec.ts",
+    "compile": "rimraf dist && tsc",
+    "compile:release": "rimraf dist && tsc --sourceMap false",
+    "test": "mocha -r source-map-support/register -r ts-node/register --files --recursive -R spec test/**/*.spec.ts",
+    "test:debug": "mocha -r source-map-support/register -r ts-node/register --inspect-brk --files --recursive test/**/*.spec.ts",
+    "test:coverage": "nyc mocha -r source-map-support/register -r ts-node/register --recursive test/**/*.spec.ts",
+    "test:reset": "rimraf node_modules && npm i && npm run compile && npm t",
     "coveralls": "cat coverage/lcov.info | coveralls -v",
     "codacy": "cat coverage/lcov.info | codacy-coverage",
-    "test:reset": "rm -rf node_modules && npm i && npm run compile && npm t",
     "commit": "cz"
   },
   "repository": {
     "url": "https://github.com/cdimascio/express-openapi-validator"
   },
+  "files": [
+    "/dist"
+  ],
   "keywords": [
     "openapi",
     "openapi 3",
@@ -67,6 +68,7 @@
     "nodemon": "^2.0.20",
     "nyc": "^15.1.0",
     "prettier": "^2.5.1",
+    "rimraf": "^5.0.5",
     "source-map-support": "0.5.21",
     "supertest": "^6.2.2",
     "ts-node": "^10.7.0",
diff --git a/src/framework/openapi.context.ts b/src/framework/openapi.context.ts
index 254ed37..2df421f 100644
--- a/src/framework/openapi.context.ts
+++ b/src/framework/openapi.context.ts
@@ -11,16 +11,23 @@ export class OpenApiContext {
   public readonly openApiRouteMap = {};
   public readonly routes: RouteMetadata[] = [];
   public readonly ignoreUndocumented: boolean;
+  public readonly useRequestUrl: boolean;
   private readonly basePaths: string[];
   private readonly ignorePaths: RegExp | Function;
 
-  constructor(spec: Spec, ignorePaths: RegExp | Function, ignoreUndocumented: boolean = false) {
+  constructor(
+    spec: Spec,
+    ignorePaths: RegExp | Function,
+    ignoreUndocumented: boolean = false,
+    useRequestUrl = false,
+  ) {
     this.apiDoc = spec.apiDoc;
     this.basePaths = spec.basePaths;
     this.routes = spec.routes;
     this.ignorePaths = ignorePaths;
     this.ignoreUndocumented = ignoreUndocumented;
     this.buildRouteMaps(spec.routes);
+    this.useRequestUrl = useRequestUrl;
   }
 
   public isManagedRoute(path: string): boolean {
diff --git a/src/framework/types.ts b/src/framework/types.ts
index 6f7c58a..201e6fb 100644
--- a/src/framework/types.ts
+++ b/src/framework/types.ts
@@ -118,6 +118,7 @@ export interface OpenApiValidatorOpts {
   ignoreUndocumented?: boolean;
   securityHandlers?: SecurityHandlers;
   coerceTypes?: boolean | 'array';
+  useRequestUrl?: boolean;
   /**
    * @deprecated
    * Use `formats` + `validateFormats` to ignore specified formats
diff --git a/src/middlewares/openapi.metadata.ts b/src/middlewares/openapi.metadata.ts
index 85f2e9c..2dae08a 100644
--- a/src/middlewares/openapi.metadata.ts
+++ b/src/middlewares/openapi.metadata.ts
@@ -25,12 +25,12 @@ export function applyOpenApiMetadata(
     if (openApiContext.shouldIgnoreRoute(path)) {
       return next();
     }
-    const matched = lookupRoute(req);
+    const matched = lookupRoute(req, openApiContext.useRequestUrl);
     if (matched) {
       const { expressRoute, openApiRoute, pathParams, schema } = matched;
       if (!schema) {
         // Prevents validation for routes which match on path but mismatch on method
-        if(openApiContext.ignoreUndocumented) {
+        if (openApiContext.ignoreUndocumented) {
           return next();
         }
         throw new MethodNotAllowed({
@@ -54,7 +54,10 @@ export function applyOpenApiMetadata(
         // add the response schema if validating responses
         (<any>req.openapi)._responseSchema = (<any>matched)._responseSchema;
       }
-    } else if (openApiContext.isManagedRoute(path) && !openApiContext.ignoreUndocumented) {
+    } else if (
+      openApiContext.isManagedRoute(path) &&
+      !openApiContext.ignoreUndocumented
+    ) {
       throw new NotFound({
         path: req.path,
         message: 'not found',
@@ -63,8 +66,11 @@ export function applyOpenApiMetadata(
     next();
   };
 
-  function lookupRoute(req: OpenApiRequest): OpenApiRequestMetadata {
-    const path = req.originalUrl.split('?')[0];
+  function lookupRoute(
+    req: OpenApiRequest,
+    useRequestUrl: boolean,
+  ): OpenApiRequestMetadata {
+    const path = useRequestUrl ? req.url : req.originalUrl.split('?')[0];
     const method = req.method;
     const routeEntries = Object.entries(openApiContext.expressRouteMap);
     for (const [expressRoute, methods] of routeEntries) {
diff --git a/src/openapi.validator.ts b/src/openapi.validator.ts
index a578ef5..dd12fed 100644
--- a/src/openapi.validator.ts
+++ b/src/openapi.validator.ts
@@ -49,6 +49,7 @@ export class OpenApiValidator {
     if (options.$refParser == null) options.$refParser = { mode: 'bundle' };
     if (options.validateFormats == null) options.validateFormats = true;
     if (options.formats == null) options.formats = {};
+    if (options.useRequestUrl == null) options.useRequestUrl = false;
 
     if (typeof options.operationHandlers === 'string') {
       /**
@@ -103,7 +104,12 @@ export class OpenApiValidator {
           resOpts,
         ).preProcess();
         return {
-          context: new OpenApiContext(spec, this.options.ignorePaths, this.options.ignoreUndocumented),
+          context: new OpenApiContext(
+            spec,
+            this.options.ignorePaths,
+            this.options.ignoreUndocumented,
+            this.options.useRequestUrl,
+          ),
           responseApiDoc: sp.apiDocRes,
           error: null,
         };
@@ -149,19 +155,6 @@ export class OpenApiValidator {
         .catch(next);
     });
 
-    if (this.options.fileUploader) {
-      // multipart middleware
-      let fumw;
-      middlewares.push(function multipartMiddleware(req, res, next) {
-        return pContext
-          .then(({ context: { apiDoc } }) => {
-            fumw = fumw || self.multipartMiddleware(apiDoc);
-            return fumw(req, res, next);
-          })
-          .catch(next);
-      });
-    }
-
     // security middlware
     let scmw;
     middlewares.push(function securityMiddleware(req, res, next) {
@@ -178,6 +171,19 @@ export class OpenApiValidator {
         .catch(next);
     });
 
+    if (this.options.fileUploader) {
+      // multipart middleware
+      let fumw;
+      middlewares.push(function multipartMiddleware(req, res, next) {
+        return pContext
+          .then(({ context: { apiDoc } }) => {
+            fumw = fumw || self.multipartMiddleware(apiDoc);
+            return fumw(req, res, next);
+          })
+          .catch(next);
+      });
+    }
+
     // request middlweare
     if (this.options.validateRequests) {
       let reqmw;
@@ -201,7 +207,7 @@ export class OpenApiValidator {
             return resmw(req, res, next);
           })
           .catch(next);
-      })
+      });
     }
 
     // op handler middleware
diff --git a/tsconfig.json b/tsconfig.json
index 44ce237..22f73d9 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -10,6 +10,9 @@
     "resolveJsonModule": true,
     "typeRoots": ["./node_modules/@types", "./typings"]
   },
+  "ts-node": {
+    "files": true
+  },
   "exclude": ["node_modules"],
   "include": [
     "typings/**/*.d.ts",


Test patch:
diff --git a/test/user-request-url.router.spec.ts b/test/user-request-url.router.spec.ts
new file mode 100644
index 0000000..4bba5de
--- /dev/null
+++ b/test/user-request-url.router.spec.ts
@@ -0,0 +1,272 @@
+import { expect } from 'chai';
+import type {
+  Express,
+  IRouter,
+  Response,
+  NextFunction,
+  Request,
+} from 'express';
+import * as express from 'express';
+import { OpenAPIV3 } from '../src/framework/types';
+import * as request from 'supertest';
+import { createApp } from './common/app';
+
+import * as OpenApiValidator from '../src';
+import { Server } from 'http';
+
+interface HTTPError extends Error {
+  status: number;
+  text: string;
+  method: string;
+  path: string;
+}
+
+describe('when useRequestUrl is set to "true" on the child router', async () => {
+  let app: Express & { server?: Server };
+
+  before(async () => {
+    const router = makeRouter({ useRequestUrl: true });
+    app = await makeMainApp();
+    app.use(router);
+  });
+
+  after(() => app?.server?.close());
+
+  it('should apply parent app schema to requests', async () => {
+    const result = await request(app).get('/api/pets/1');
+    const error = result.error as HTTPError;
+    expect(result.statusCode).to.equal(400);
+    expect(error.path).to.equal('/api/pets/1');
+    expect(error.text).to.contain(
+      'Bad Request: request/params/petId must NOT have fewer than 3 characters',
+    );
+  });
+
+  it('should apply child router schema to requests', async () => {
+    const result = await request(app).get('/api/pets/not-uuid');
+    const error = result.error as HTTPError;
+    expect(result.statusCode).to.equal(400);
+    expect(error.path).to.equal('/api/pets/not-uuid');
+    expect(error.text).to.contain(
+      'Bad Request: request/params/petId must match format &quot;uuid&quot',
+    );
+  });
+
+  it('should return a reponse if request is valid', async () => {
+    const validId = 'f627f309-cae3-46d2-84f7-d03856c84b02';
+    const result = await request(app).get(`/api/pets/${validId}`);
+    expect(result.statusCode).to.equal(200);
+    expect(result.body).to.deep.equal({
+      id: 'f627f309-cae3-46d2-84f7-d03856c84b02',
+      name: 'Mr Sparky',
+      tag: "Ain't nobody tags me",
+    });
+  });
+});
+
+describe('when useRequestUrl is set to "false" on the child router', async () => {
+  let app: Express & { server?: Server };
+
+  before(async () => {
+    const router = makeRouter({ useRequestUrl: false });
+    app = await makeMainApp();
+    app.use(router);
+  });
+
+  after(() => app?.server?.close());
+
+  it('should throw not found', async () => {
+    const result = await request(app).get('/api/pets/valid-pet-id');
+    const error = result.error as HTTPError;
+    expect(result.statusCode).to.equal(404);
+    expect(error.path).to.equal('/api/pets/valid-pet-id');
+    expect(error.text).to.contain('Not Found');
+  });
+});
+
+function defaultResponse(): OpenAPIV3.ResponseObject {
+  return {
+    description: 'unexpected error',
+    content: {
+      'application/json': {
+        schema: {
+          type: 'object',
+          required: ['code', 'message'],
+          properties: {
+            code: {
+              type: 'integer',
+              format: 'int32',
+            },
+            message: {
+              type: 'string',
+            },
+          },
+        },
+      },
+    },
+  };
+}
+
+/* 
+   represents spec of the "public" entrypoint to our application e.g gateway. The
+   type of id in path and id in the response here defined as simple string
+   with minLength
+ */
+const gatewaySpec: OpenAPIV3.Document = {
+  openapi: '3.0.0',
+  info: { version: '1.0.0', title: 'test bug OpenApiValidator' },
+  servers: [{ url: 'http://localhost:3000/api' }],
+  paths: {
+    '/pets/{petId}': {
+      get: {
+        summary: 'Info for a specific pet',
+        operationId: 'showPetById',
+        tags: ['pets'],
+        parameters: [
+          {
+            name: 'petId',
+            in: 'path',
+            required: true,
+            description: 'The id of the pet to retrieve',
+            schema: {
+              type: 'string',
+              minLength: 3,
+            },
+          },
+        ],
+        responses: {
+          '200': {
+            description: 'Expected response to a valid request',
+            content: {
+              'application/json': {
+                schema: {
+                  type: 'object',
+                  required: ['id', 'name'],
+                  properties: {
+                    id: {
+                      type: 'string',
+                    },
+                    name: {
+                      type: 'string',
+                    },
+                    tag: {
+                      type: 'string',
+                    },
+                  },
+                },
+              },
+            },
+          },
+          default: defaultResponse(),
+        },
+      },
+    },
+  },
+};
+
+/*
+ represents spec of the child router. We route request from main app (gateway) to this router.
+ This router has its own schema, routes and validation formats. In particular, we force id in the path and id in the response to be uuid.
+ */
+const childRouterSpec: OpenAPIV3.Document = {
+  openapi: '3.0.0',
+  info: { version: '1.0.0', title: 'test bug OpenApiValidator' },
+  servers: [{ url: 'http://localhost:3000/' }],
+  paths: {
+    '/internal/api/pets/{petId}': {
+      get: {
+        summary: 'Info for a specific pet',
+        operationId: 'showPetById',
+        tags: ['pets'],
+        parameters: [
+          {
+            name: 'petId',
+            in: 'path',
+            required: true,
+            description: 'The id of the pet to retrieve',
+            schema: {
+              type: 'string',
+              format: 'uuid',
+            },
+          },
+        ],
+        responses: {
+          '200': {
+            description: 'Expected response to a valid request',
+            content: {
+              'application/json': {
+                schema: {
+                  type: 'object',
+                  required: ['id', 'name'],
+                  properties: {
+                    id: {
+                      type: 'string',
+                      format: 'uuid',
+                    },
+                    name: {
+                      type: 'string',
+                    },
+                    tag: {
+                      type: 'string',
+                    },
+                  },
+                },
+              },
+            },
+          },
+        },
+      },
+    },
+  },
+};
+
+function redirectToInternalService(
+  req: Request,
+  _res: Response,
+  next: NextFunction,
+): void {
+  req.url = `/internal${req.originalUrl}`;
+  next();
+}
+
+function makeMainApp(): ReturnType<typeof createApp> {
+  return createApp(
+    {
+      apiSpec: gatewaySpec,
+      validateResponses: true,
+      validateRequests: true,
+    },
+    3000,
+    (app) => {
+      app
+        .get(
+          '/api/pets/:petId',
+          function (_req: Request, _res: Response, next: NextFunction) {
+            next();
+          },
+        )
+        .use(redirectToInternalService);
+    },
+    false,
+  );
+}
+
+function makeRouter({ useRequestUrl }: { useRequestUrl: boolean }): IRouter {
+  return express
+    .Router()
+    .use(
+      OpenApiValidator.middleware({
+        apiSpec: childRouterSpec,
+        validateRequests: true,
+        validateResponses: true,
+        useRequestUrl,
+      }),
+    )
+    .get('/internal/api/pets/:petId', function (req, res) {
+      res.json({
+        id: req.params.petId,
+        name: 'Mr Sparky',
+        tag: "Ain't nobody tags me",
+      });
+    });
+}