From 456b0a878a173d812c9f261e285993f23deacd2b Mon Sep 17 00:00:00 2001 From: carmine Date: Fri, 27 Dec 2024 20:08:16 -0500 Subject: [PATCH 01/44] handle req.query mutations for express 5 --- package-lock.json | 445 +++++++++++++------ package.json | 2 +- src/middlewares/openapi.request.validator.ts | 13 +- 3 files changed, 330 insertions(+), 130 deletions(-) diff --git a/package-lock.json b/package-lock.json index ee7fb2b3..e8d61dca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,7 @@ "commitizen": "^4.2.5", "cookie-parser": "^1.4.6", "coveralls": "^3.1.1", - "express": "^4.21.2", + "express": "^5.0.1", "mocha": "^9.2.2", "morgan": "^1.10.0", "nodemon": "^3.0.1", @@ -1254,34 +1254,34 @@ "dev": true }, "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "dev": true, "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/accepts/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", + "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/accepts/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.0.tgz", + "integrity": "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==", "dev": true, "dependencies": { - "mime-db": "1.52.0" + "mime-db": "^1.53.0" }, "engines": { "node": ">= 0.6" @@ -1475,9 +1475,9 @@ } }, "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-3.0.0.tgz", + "integrity": "sha512-zPMVc3ZYlGLNk4mpK1NzP2wg0ml9t7fUgDsayR5Y5rSzxQilzR9FGu/EH2jQOcKSAeAfWeylyW8juy3OkWRvNA==", "dev": true }, "node_modules/asap": { @@ -2096,9 +2096,9 @@ } }, "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", + "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", "dev": true, "dependencies": { "safe-buffer": "5.2.1" @@ -2155,7 +2155,6 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2480,6 +2479,15 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2576,59 +2584,184 @@ } }, "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.0.1.tgz", + "integrity": "sha512-ORF7g6qGnD+YtUG9yx4DFoqCShNMmUKiXuT5oWMHiOvt/4WFbHC6yCwQMTSBMno7AqntNCAzzcnnjowRkTL9eQ==", "dev": true, - "license": "MIT", "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", + "accepts": "^2.0.0", + "body-parser": "^2.0.1", + "content-disposition": "^1.0.0", "content-type": "~1.0.4", "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", + "cookie-signature": "^1.2.1", + "debug": "4.3.6", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", + "finalhandler": "^2.0.0", + "fresh": "2.0.0", "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", + "merge-descriptors": "^2.0.0", "methods": "~1.1.2", + "mime-types": "^3.0.0", "on-finished": "2.4.1", + "once": "1.4.0", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", + "router": "^2.0.0", "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", + "send": "^1.1.0", + "serve-static": "^2.1.0", "setprototypeof": "1.2.0", "statuses": "2.0.1", - "type-is": "~1.6.18", + "type-is": "^2.0.0", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "engines": { - "node": ">= 0.10.0" + "node": ">= 18" + } + }, + "node_modules/express/node_modules/body-parser": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.0.2.tgz", + "integrity": "sha512-SNMk0OONlQ01uk8EPeiBvTW7W4ovpL5b1O3t1sjpPgfxOQ6BqQJ6XjxinDPR79Z6HdcD5zBBwr5ssiTlgdNztQ==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "3.1.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.5.2", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "^3.0.0", + "type-is": "~1.6.18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "engines": { + "node": ">=18" } }, - "node_modules/express/node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "node_modules/express/node_modules/body-parser/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/body-parser/node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, "engines": { - "node": ">= 0.8" + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/body-parser/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/body-parser/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/body-parser/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "dev": true, + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/express/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/express/node_modules/iconv-lite": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", + "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/express/node_modules/mime-db": { + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", + "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/mime-types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.0.tgz", + "integrity": "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==", + "dev": true, + "dependencies": { + "mime-db": "^1.53.0" + }, + "engines": { + "node": ">= 0.6" } }, "node_modules/express/node_modules/on-finished": { @@ -2643,12 +2776,32 @@ "node": ">= 0.8" } }, - "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "node_modules/express/node_modules/raw-body": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", + "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", "dev": true, - "license": "MIT" + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.6.3", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", @@ -2670,6 +2823,20 @@ } ] }, + "node_modules/express/node_modules/type-is": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.0.tgz", + "integrity": "sha512-gd0sGezQYCbWSbkZr75mln4YBidWUN60+devscpLF5mtRDUpiaTvKpBNrdaCvel1NdR2k6vclXybU5fBd2i+nw==", + "dev": true, + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -2750,13 +2917,13 @@ } }, "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.0.0.tgz", + "integrity": "sha512-MX6Zo2adDViYh+GcxxB1dpO43eypOGUOL12rLCOTMQv/DfIbpSJUy4oQIIZhVZkH9e+bZWKMon0XHFEju16tkQ==", "dev": true, "dependencies": { "debug": "2.6.9", - "encodeurl": "~2.0.0", + "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -2768,9 +2935,9 @@ } }, "node_modules/finalhandler/node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, "engines": { "node": ">= 0.8" @@ -2922,12 +3089,12 @@ } }, "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/fromentries": { @@ -3648,6 +3815,12 @@ "node": ">=8" } }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -4229,10 +4402,13 @@ "dev": true }, "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", "dev": true, + "engines": { + "node": ">=18" + }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -4271,32 +4447,20 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "mime-db": "1.49.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" @@ -4576,9 +4740,9 @@ } }, "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "dev": true, "engines": { "node": ">= 0.6" @@ -5714,6 +5878,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/router": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.0.0.tgz", + "integrity": "sha512-dIM5zVoG8xhC6rnSN8uoAgFARwTE7BQs8YwHEvK0VCmfxQXMaOuA1uiR1IPwsW7JyK5iTt7Od/TC9StasS2NPQ==", + "dev": true, + "dependencies": { + "array-flatten": "3.0.0", + "is-promise": "4.0.0", + "methods": "~1.1.2", + "parseurl": "~1.3.3", + "path-to-regexp": "^8.0.0", + "setprototypeof": "1.2.0", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -5759,36 +5941,52 @@ } }, "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.1.0.tgz", + "integrity": "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==", "dev": true, "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" + "debug": "^4.3.5", + "destroy": "^1.2.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^0.5.2", + "http-errors": "^2.0.0", + "mime-types": "^2.1.35", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 18" } }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "node_modules/send/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, "engines": { - "node": ">= 0.8" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/send/node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" } }, "node_modules/send/node_modules/ms": { @@ -5819,27 +6017,18 @@ } }, "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.1.0.tgz", + "integrity": "sha512-A3We5UfEjG8Z7VkDv6uItWw6HY2bBSBJT1KtVESn6EOoOr2jAxNhxWCLY3jDE2WcuHXByWju74ck3ZgLwL8xmA==", "dev": true, "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.0.0" }, "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-static/node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "dev": true, - "engines": { - "node": ">= 0.8" + "node": ">= 18" } }, "node_modules/set-blocking": { @@ -6498,7 +6687,7 @@ "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, "engines": { "node": ">= 0.4.0" @@ -6523,7 +6712,7 @@ "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, "engines": { "node": ">= 0.8" diff --git a/package.json b/package.json index 92b9ea9c..226f774e 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "commitizen": "^4.2.5", "cookie-parser": "^1.4.6", "coveralls": "^3.1.1", - "express": "^4.21.2", + "express": "^5.0.1", "mocha": "^9.2.2", "morgan": "^1.10.0", "nodemon": "^3.0.1", diff --git a/src/middlewares/openapi.request.validator.ts b/src/middlewares/openapi.request.validator.ts index c675e0d6..64e9ad99 100644 --- a/src/middlewares/openapi.request.validator.ts +++ b/src/middlewares/openapi.request.validator.ts @@ -139,7 +139,12 @@ export class RequestValidator { } req.params = openapi.pathParams ?? req.params; } - + // HACK for express 5, temporarily make req.query mutable + const reqQueryDescriptor = Object.getOwnPropertyDescriptor(req, 'query'); + Object.defineProperty(req, 'query', { + writable: true, + value: { ...req.query }, + }) const schemaProperties = validator.allSchemaProperties; const mutator = new RequestParameterMutator( this.ajv, @@ -158,6 +163,12 @@ export class RequestValidator { ); } + // HACK for express 5, Restore the original descriptor + if (reqQueryDescriptor) { + Object.defineProperty(req, 'query', reqQueryDescriptor); + console.log('Query property restored to original descriptor.'); + } + const cookies = req.cookies ? { ...req.cookies, From 1d69d8a6703120f42bf6c99121658cbf2d827fad Mon Sep 17 00:00:00 2001 From: carmine Date: Fri, 27 Dec 2024 20:08:16 -0500 Subject: [PATCH 02/44] handle req.query mutations for express 5 --- src/middlewares/openapi.request.validator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middlewares/openapi.request.validator.ts b/src/middlewares/openapi.request.validator.ts index 64e9ad99..b57cb08f 100644 --- a/src/middlewares/openapi.request.validator.ts +++ b/src/middlewares/openapi.request.validator.ts @@ -139,6 +139,7 @@ export class RequestValidator { } req.params = openapi.pathParams ?? req.params; } + // HACK for express 5, temporarily make req.query mutable const reqQueryDescriptor = Object.getOwnPropertyDescriptor(req, 'query'); Object.defineProperty(req, 'query', { @@ -166,7 +167,6 @@ export class RequestValidator { // HACK for express 5, Restore the original descriptor if (reqQueryDescriptor) { Object.defineProperty(req, 'query', reqQueryDescriptor); - console.log('Query property restored to original descriptor.'); } const cookies = req.cookies From f9d67479af373d923fb9d8af3cd8a1aa1d8f9634 Mon Sep 17 00:00:00 2001 From: Carmine DiMascio Date: Sun, 26 Jan 2025 08:19:36 -0500 Subject: [PATCH 03/44] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0ad1a377..67b6f20a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # 🦋 express-openapi-validator -[![example workflow](https://github.com/cdimascio/express-openapi-validator/actions/workflows/default.yml/badge.svg)](#) [![](https://img.shields.io/npm/v/express-openapi-validator.svg)](https://www.npmjs.com/package/express-openapi-validator) [![](https://img.shields.io/npm/dm/express-openapi-validator?color=blue)](https://www.npmjs.com/package/express-openapi-validator) [![All Contributors](https://img.shields.io/github/contributors/cdimascio/express-openapi-validator -)](#contributors) [![Coverage Status](https://coveralls.io/repos/github/cdimascio/express-openapi-validator/badge.svg?branch=master)](https://coveralls.io/github/cdimascio/express-openapi-validator?branch=master) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/1570a06f609345ddb237114bbd6ceed7)](https://www.codacy.com/manual/cdimascio/express-openapi-validator?utm_source=github.com&utm_medium=referral&utm_content=cdimascio/express-openapi-validator&utm_campaign=Badge_Grade) [![](https://img.shields.io/gitter/room/cdimascio-oss/community?color=%23eb205a)](https://gitter.im/cdimascio-oss/community) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/cdimascio/express-openapi-validator) [![](https://img.shields.io/badge/documentation-yes-informational)](https://cdimascio.github.io/express-openapi-validator-documentation/) [![](https://img.shields.io/badge/license-MIT-blue.svg)](#license) +[![build workflow](https://github.com/cdimascio/express-openapi-validator/actions/workflows/default.yml/badge.svg)](#) [![](https://img.shields.io/npm/v/express-openapi-validator.svg)](https://www.npmjs.com/package/express-openapi-validator) [![](https://img.shields.io/npm/dm/express-openapi-validator?color=blue)](https://www.npmjs.com/package/express-openapi-validator) [![All Contributors](https://img.shields.io/github/contributors/cdimascio/express-openapi-validator +)](#contributors) [![Coverage Status](https://coveralls.io/repos/github/cdimascio/express-openapi-validator/badge.svg?branch=master)](https://coveralls.io/github/cdimascio/express-openapi-validator?branch=master) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/1570a06f609345ddb237114bbd6ceed7)](https://www.codacy.com/manual/cdimascio/express-openapi-validator?utm_source=github.com&utm_medium=referral&utm_content=cdimascio/express-openapi-validator&utm_campaign=Badge_Grade) [![](https://img.shields.io/gitter/room/cdimascio-oss/community?color=%23eb205a)](https://gitter.im/cdimascio-oss/community) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/cdimascio/express-openapi-validator) +[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9407/badge)](https://www.bestpractices.dev/projects/9407) [![](https://img.shields.io/badge/documentation-yes-informational)](https://cdimascio.github.io/express-openapi-validator-documentation/) [![](https://img.shields.io/badge/license-MIT-blue.svg)](#license) **An OpenApi validator for ExpressJS** that automatically validates **API** _**requests**_ and _**responses**_ using an **OpenAPI 3** specification. From 5e8e01b50c21e7dc7344f00d878f2ca1bfe5729a Mon Sep 17 00:00:00 2001 From: Carmine DiMascio Date: Sun, 26 Jan 2025 08:21:23 -0500 Subject: [PATCH 04/44] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 67b6f20a..637ea1b7 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ # 🦋 express-openapi-validator [![build workflow](https://github.com/cdimascio/express-openapi-validator/actions/workflows/default.yml/badge.svg)](#) [![](https://img.shields.io/npm/v/express-openapi-validator.svg)](https://www.npmjs.com/package/express-openapi-validator) [![](https://img.shields.io/npm/dm/express-openapi-validator?color=blue)](https://www.npmjs.com/package/express-openapi-validator) [![All Contributors](https://img.shields.io/github/contributors/cdimascio/express-openapi-validator -)](#contributors) [![Coverage Status](https://coveralls.io/repos/github/cdimascio/express-openapi-validator/badge.svg?branch=master)](https://coveralls.io/github/cdimascio/express-openapi-validator?branch=master) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/1570a06f609345ddb237114bbd6ceed7)](https://www.codacy.com/manual/cdimascio/express-openapi-validator?utm_source=github.com&utm_medium=referral&utm_content=cdimascio/express-openapi-validator&utm_campaign=Badge_Grade) [![](https://img.shields.io/gitter/room/cdimascio-oss/community?color=%23eb205a)](https://gitter.im/cdimascio-oss/community) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/cdimascio/express-openapi-validator) -[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9407/badge)](https://www.bestpractices.dev/projects/9407) [![](https://img.shields.io/badge/documentation-yes-informational)](https://cdimascio.github.io/express-openapi-validator-documentation/) [![](https://img.shields.io/badge/license-MIT-blue.svg)](#license) +)](#contributors) [![Coverage Status](https://coveralls.io/repos/github/cdimascio/express-openapi-validator/badge.svg?branch=master)](https://coveralls.io/github/cdimascio/express-openapi-validator?branch=master) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/1570a06f609345ddb237114bbd6ceed7)](https://www.codacy.com/manual/cdimascio/express-openapi-validator?utm_source=github.com&utm_medium=referral&utm_content=cdimascio/express-openapi-validator&utm_campaign=Badge_Grade) [![](https://img.shields.io/gitter/room/cdimascio-oss/community?color=%23eb205a)](https://gitter.im/cdimascio-oss/community) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/cdimascio/express-openapi-validator) [![](https://img.shields.io/badge/documentation-yes-informational)](https://cdimascio.github.io/express-openapi-validator-documentation/) [![](https://img.shields.io/badge/license-MIT-blue.svg)](#license) **An OpenApi validator for ExpressJS** that automatically validates **API** _**requests**_ and _**responses**_ using an **OpenAPI 3** specification. From a84f6111fd75db85a1c0742362dbaef27d64ee36 Mon Sep 17 00:00:00 2001 From: Carmine DiMascio Date: Sun, 9 Feb 2025 13:34:57 -0500 Subject: [PATCH 05/44] allow mutation for express 5 validaiton (#1043) Co-authored-by: carmine --- src/middlewares/openapi.request.validator.ts | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/middlewares/openapi.request.validator.ts b/src/middlewares/openapi.request.validator.ts index b57cb08f..dc10e9e4 100644 --- a/src/middlewares/openapi.request.validator.ts +++ b/src/middlewares/openapi.request.validator.ts @@ -1,26 +1,26 @@ import Ajv, { ValidateFunction } from 'ajv'; -import { createRequestAjv } from '../framework/ajv'; -import { - ContentType, - ajvErrorsToValidatorError, - augmentAjvErrors, -} from './util'; import { NextFunction, RequestHandler, Response } from 'express'; +import { createRequestAjv } from '../framework/ajv'; import { + BadRequest, + BodySchema, + NotFound, OpenAPIV3, OpenApiRequest, - RequestValidatorOptions, - ValidateRequestOpts, OpenApiRequestMetadata, - NotFound, - BadRequest, ParametersSchema, - BodySchema, + RequestValidatorOptions, + ValidateRequestOpts, ValidationSchema, } from '../framework/types'; import { BodySchemaParser } from './parsers/body.parse'; -import { ParametersSchemaParser } from './parsers/schema.parse'; import { RequestParameterMutator } from './parsers/req.parameter.mutator'; +import { ParametersSchemaParser } from './parsers/schema.parse'; +import { + ContentType, + ajvErrorsToValidatorError, + augmentAjvErrors, +} from './util'; type OperationObject = OpenAPIV3.OperationObject; type SchemaObject = OpenAPIV3.SchemaObject; @@ -144,7 +144,7 @@ export class RequestValidator { const reqQueryDescriptor = Object.getOwnPropertyDescriptor(req, 'query'); Object.defineProperty(req, 'query', { writable: true, - value: { ...req.query }, + value: req.query, }) const schemaProperties = validator.allSchemaProperties; const mutator = new RequestParameterMutator( @@ -166,7 +166,7 @@ export class RequestValidator { // HACK for express 5, Restore the original descriptor if (reqQueryDescriptor) { - Object.defineProperty(req, 'query', reqQueryDescriptor); + Object.defineProperty(req, 'query', reqQueryDescriptor); } const cookies = req.cookies From c7d61e462724931e5a2b4e989b0b4388df1cca9c Mon Sep 17 00:00:00 2001 From: carmine Date: Sun, 9 Feb 2025 10:36:00 -0800 Subject: [PATCH 06/44] v5.4.3 --- CHANGE_HISTORY.md | 9 +++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGE_HISTORY.md b/CHANGE_HISTORY.md index 3ac84267..d51e8711 100644 --- a/CHANGE_HISTORY.md +++ b/CHANGE_HISTORY.md @@ -1,3 +1,12 @@ +## (2025-02-09) + +* allow mutation for express 5 validaiton (#1043) ([0439224](https://github.com/cdimascio/express-openapi-validator/commit/0439224)), closes [#1043](https://github.com/cdimascio/express-openapi-validator/issues/1043) +* fix test ([97158fd](https://github.com/cdimascio/express-openapi-validator/commit/97158fd)) +* Update README.md ([405a9ff](https://github.com/cdimascio/express-openapi-validator/commit/405a9ff)) +* Update README.md ([64582e9](https://github.com/cdimascio/express-openapi-validator/commit/64582e9)) + + + ## (2024-12-27) * re-enable keywords now properly supported (#1031) ([83dac8a](https://github.com/cdimascio/express-openapi-validator/commit/83dac8a)), closes [#1031](https://github.com/cdimascio/express-openapi-validator/issues/1031) diff --git a/package-lock.json b/package-lock.json index e8d61dca..c714cf62 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "express-openapi-validator", - "version": "5.4.2", + "version": "5.4.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "express-openapi-validator", - "version": "5.4.2", + "version": "5.4.3", "license": "MIT", "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.7.2", diff --git a/package.json b/package.json index 226f774e..c3d30fe6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-openapi-validator", - "version": "5.4.2", + "version": "5.4.3", "description": "Automatically validate API requests and responses with OpenAPI 3 and Express.", "main": "dist/index.js", "scripts": { From 4edacd82f611c2addd32df4869a91125ae42e216 Mon Sep 17 00:00:00 2001 From: carmine Date: Sun, 9 Feb 2025 10:41:11 -0800 Subject: [PATCH 07/44] update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 637ea1b7..ce15bafa 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ - ✂️ **\$ref** support; split specs over multiple files - 🎈 file upload +_Express 5 support is in progress--a subset of functionality is working. Try it out and provide feedback!_ + **Docs:** - 📖 [documentation](https://cdimascio.github.io/express-openapi-validator-documentation/) From 86374a395beeda394d4ee4a8483e3a42cecb7253 Mon Sep 17 00:00:00 2001 From: carmine Date: Fri, 27 Dec 2024 20:08:16 -0500 Subject: [PATCH 08/44] handle req.query mutations for express 5 --- src/middlewares/openapi.request.validator.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/middlewares/openapi.request.validator.ts b/src/middlewares/openapi.request.validator.ts index dc10e9e4..de5254b5 100644 --- a/src/middlewares/openapi.request.validator.ts +++ b/src/middlewares/openapi.request.validator.ts @@ -139,13 +139,12 @@ export class RequestValidator { } req.params = openapi.pathParams ?? req.params; } - // HACK for express 5, temporarily make req.query mutable const reqQueryDescriptor = Object.getOwnPropertyDescriptor(req, 'query'); Object.defineProperty(req, 'query', { writable: true, value: req.query, - }) + }); const schemaProperties = validator.allSchemaProperties; const mutator = new RequestParameterMutator( this.ajv, From 2e0265349e119df45dad65d88a19ba7793dc8bf7 Mon Sep 17 00:00:00 2001 From: carmine Date: Fri, 27 Dec 2024 20:08:16 -0500 Subject: [PATCH 09/44] handle req.query mutations for express 5 --- src/middlewares/openapi.request.validator.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/middlewares/openapi.request.validator.ts b/src/middlewares/openapi.request.validator.ts index de5254b5..c0396490 100644 --- a/src/middlewares/openapi.request.validator.ts +++ b/src/middlewares/openapi.request.validator.ts @@ -139,6 +139,7 @@ export class RequestValidator { } req.params = openapi.pathParams ?? req.params; } + // HACK for express 5, temporarily make req.query mutable const reqQueryDescriptor = Object.getOwnPropertyDescriptor(req, 'query'); Object.defineProperty(req, 'query', { From 536e0b073b2b1417158abec47ccd44fa5f291b1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Ferreira?= <10375710+SF97@users.noreply.github.com> Date: Sun, 6 Apr 2025 01:54:53 +0100 Subject: [PATCH 10/44] test(express-5): change routes in tests to new path route syntax (#1036) --- test/1022.spec.ts | 4 ++-- test/699.spec.ts | 4 ++-- test/multipart.spec.ts | 2 +- test/path.params.spec.ts | 4 ++-- test/serdes.spec.ts | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/1022.spec.ts b/test/1022.spec.ts index 0c770fa9..e61eaafb 100644 --- a/test/1022.spec.ts +++ b/test/1022.spec.ts @@ -125,10 +125,10 @@ describe(packageJson.name, () => { .get(`/api/test/:id`, (req, res) => res.status(200).json({ id: 'id-test', label: 'label' }), ) - .post(`/api/test/:id:clone`, (req, res) => + .post(`/api/test/:id\\:clone`, (req, res) => res.status(200).json({ ...req.body, id: 'id-test' }), ) - .get('/api/some/:wildcard(*)', (req, res) => { + .get('/api/some/:wildcard(*wildcardSuffix)', (req, res) => { const wildcard = req.params.wildcard; console.log(`Wildcard: ${wildcard}`); res.status(200).send(`Matched wildcard: ${wildcard}`); diff --git a/test/699.spec.ts b/test/699.spec.ts index 4e3399e2..873b06a2 100644 --- a/test/699.spec.ts +++ b/test/699.spec.ts @@ -53,7 +53,7 @@ describe('699', () => { }, 3005, (app) => { - app.get([`${app.basePath}/users/:id?`], (req, res) => { + app.get([`${app.basePath}/users/{:id}`], (req, res) => { if (typeof req.params.id !== 'object') { throw new Error("Should be deserialized to ObjectId object"); } @@ -181,7 +181,7 @@ describe('699 serialize response components only', () => { }, 3005, (app) => { - app.get([`${app.basePath}/users/:id?`], (req, res) => { + app.get([`${app.basePath}/users/{:id}`], (req, res) => { if (typeof req.params.id !== 'string') { throw new Error("Should be not be deserialized to ObjectId object"); } diff --git a/test/multipart.spec.ts b/test/multipart.spec.ts index 807e3759..b42cc64e 100644 --- a/test/multipart.spec.ts +++ b/test/multipart.spec.ts @@ -33,7 +33,7 @@ describe('a multipart request', () => { metadata: req.body.metadata, }); }) - .post(`/sample_*`, (req, res) => res.json(req.body)), + .post(`/sample_*suffix`, (req, res) => res.json(req.body)), ), ); }); diff --git a/test/path.params.spec.ts b/test/path.params.spec.ts index 57bde2e7..b91360cf 100644 --- a/test/path.params.spec.ts +++ b/test/path.params.spec.ts @@ -18,7 +18,7 @@ describe('path params', () => { 3005, (app) => { app.get( - [`${app.basePath}/users/:id?`, `${app.basePath}/users_alt/:id?`], + [`${app.basePath}/users/{:id}`, `${app.basePath}/users_alt/{:id}`], (req, res) => { res.json({ id: req.params.id, @@ -30,7 +30,7 @@ describe('path params', () => { id: req.params.name, }); }); - app.get(`${app.basePath}/multi_users/:ids?`, (req, res) => { + app.get(`${app.basePath}/multi_users/{:ids}`, (req, res) => { res.json({ ids: req.params.ids, }); diff --git a/test/serdes.spec.ts b/test/serdes.spec.ts index 25774403..d68b25c7 100644 --- a/test/serdes.spec.ts +++ b/test/serdes.spec.ts @@ -62,7 +62,7 @@ describe('serdes', () => { }, 3005, (app) => { - app.get([`${app.basePath}/users/:id?`], (req, res) => { + app.get([`${app.basePath}/users/{:id}`], (req, res) => { if (typeof req.params.id !== 'object') { throw new Error("Should be deserialized to ObjectId object"); } @@ -237,7 +237,7 @@ describe('serdes serialize response components only', () => { }, 3005, (app) => { - app.get([`${app.basePath}/users/:id?`], (req, res) => { + app.get([`${app.basePath}/users/{:id}`], (req, res) => { if (typeof req.params.id !== 'string') { throw new Error("Should be not be deserialized to ObjectId object"); } @@ -431,7 +431,7 @@ describe('serdes with array type string-list', () => { }, 3005, (app) => { - app.get([`${app.basePath}/users/:id?`], (req, res) => { + app.get([`${app.basePath}/users/{:id}`], (req, res) => { if (typeof req.params.id !== 'object') { throw new Error("Should be deserialized to ObjectId object"); } From 85a29200a57333a5904f4d417a6b379e694b803b Mon Sep 17 00:00:00 2001 From: carmine Date: Sun, 23 Feb 2025 10:56:40 -0500 Subject: [PATCH 11/44] caches pre-processed resolved schemas --- src/middlewares/parsers/schema.preprocessor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middlewares/parsers/schema.preprocessor.ts b/src/middlewares/parsers/schema.preprocessor.ts index 36b0e315..1cd106e3 100644 --- a/src/middlewares/parsers/schema.preprocessor.ts +++ b/src/middlewares/parsers/schema.preprocessor.ts @@ -490,7 +490,7 @@ export class SchemaPreprocessor { delete object?.examples; } - private handleReadonly( +private handleReadonly( parent: OpenAPIV3.SchemaObject, schema: OpenAPIV3.SchemaObject, opts, From 7b81407dcd5375c1a3cd0e924d78e41347241716 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sat, 5 Apr 2025 21:06:13 -0400 Subject: [PATCH 12/44] update change history --- CHANGE_HISTORY.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CHANGE_HISTORY.md b/CHANGE_HISTORY.md index d51e8711..fac394e3 100644 --- a/CHANGE_HISTORY.md +++ b/CHANGE_HISTORY.md @@ -1,3 +1,25 @@ +## (2025-04-06) + +* allow mutation for express 5 validaiton (#1043) ([a84f611](https://github.com/cdimascio/express-openapi-validator/commit/a84f611)), closes [#1043](https://github.com/cdimascio/express-openapi-validator/issues/1043) +* caches pre-processed resolved schemas ([85a2920](https://github.com/cdimascio/express-openapi-validator/commit/85a2920)) +* handle req.query mutations for express 5 ([2e02653](https://github.com/cdimascio/express-openapi-validator/commit/2e02653)) +* handle req.query mutations for express 5 ([86374a3](https://github.com/cdimascio/express-openapi-validator/commit/86374a3)) +* handle req.query mutations for express 5 ([1d69d8a](https://github.com/cdimascio/express-openapi-validator/commit/1d69d8a)) +* handle req.query mutations for express 5 ([456b0a8](https://github.com/cdimascio/express-openapi-validator/commit/456b0a8)) +* update README ([4edacd8](https://github.com/cdimascio/express-openapi-validator/commit/4edacd8)) +* Update README.md ([5e8e01b](https://github.com/cdimascio/express-openapi-validator/commit/5e8e01b)) +* Update README.md ([f9d6747](https://github.com/cdimascio/express-openapi-validator/commit/f9d6747)) +* v5.4.3 ([c7d61e4](https://github.com/cdimascio/express-openapi-validator/commit/c7d61e4)) +* test(express-5): change routes in tests to new path route syntax (#1036) ([536e0b0](https://github.com/cdimascio/express-openapi-validator/commit/536e0b0)), closes [#1036](https://github.com/cdimascio/express-openapi-validator/issues/1036) + + + +## (2025-02-23) + +* caches pre-processed resolved schemas ([ac02bdf](https://github.com/cdimascio/express-openapi-validator/commit/ac02bdf)) + + + ## (2025-02-09) * allow mutation for express 5 validaiton (#1043) ([0439224](https://github.com/cdimascio/express-openapi-validator/commit/0439224)), closes [#1043](https://github.com/cdimascio/express-openapi-validator/issues/1043) From ab173b90bb8e8d002d20acb700e8b92c033a77c1 Mon Sep 17 00:00:00 2001 From: Carmine DiMascio Date: Sun, 23 Feb 2025 11:35:03 -0500 Subject: [PATCH 13/44] Update README.md (#1033) * Update README.md * Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 2e2d3569..2efe039a 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,6 @@ _Express 5 support is in progress--a subset of functionality is working. Try it out and provide feedback!_ -_Express 5 support is in progress--a subset of functionality is working. Try it out and provide feedback!_ - **Docs:** - 📖 [documentation](https://cdimascio.github.io/express-openapi-validator-documentation/) From b3ce8f90820d568e76def70ae854c0cf511dee42 Mon Sep 17 00:00:00 2001 From: Carmine DiMascio Date: Sat, 1 Mar 2025 21:55:34 -0500 Subject: [PATCH 14/44] Fix history (#1049) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * change log * deps + change log * docs: add robertjustjones as a contributor for code, test (#659) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Carmine DiMascio * if requestBody required is false, allow empty requests (#665) * if requestBody required is false, allow empty requests * add test * v4.13.2 * update examples deps * audit fix lock * audit fix lock * update examples * (doc) describe detailed coercion behaviors * (chore) upgrade deps * Update openapi.validator.ts * chore(deps): bump normalize-url in /examples/8-top-level-discriminator (#673) Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 4.5.0 to 4.5.1. - [Release notes](https://github.com/sindresorhus/normalize-url/releases) - [Commits](https://github.com/sindresorhus/normalize-url/commits) --- updated-dependencies: - dependency-name: normalize-url dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump glob-parent in /examples/8-top-level-discriminator (#674) Bumps [glob-parent](https://github.com/gulpjs/glob-parent) from 5.1.1 to 5.1.2. - [Release notes](https://github.com/gulpjs/glob-parent/releases) - [Changelog](https://github.com/gulpjs/glob-parent/blob/main/CHANGELOG.md) - [Commits](https://github.com/gulpjs/glob-parent/compare/v5.1.1...v5.1.2) --- updated-dependencies: - dependency-name: glob-parent dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * default export in handler #671 (#675) * v.4.13.4 * (doc) change history * fix json syntax in allcontributors file (#676) * docs: add zzgab as a contributor for code, test (#680) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> * Fixes on SerDes (#682) * Try catch serdes serialize and deserialize in order to avoid Internal Server Error and return BadRequest errors #601 * Fix incorrect serDes example #569 * Patch on serdes test and allow to use generated AJV out of Express usage (#684) * Try catch serdes serialize and deserialize in order to avoid Internal Server Error and return BadRequest errors #601 * Fix incorrect serDes example #569 * fix the unit test and change message to a more human friendly description of the error #601 * Allow to get the generated request AJV object in order to use it out of an OpenAPI and express usage (websocket...) #683 * Add documentation for OpenApiValidator.ajv function initialization usage #683 * ResponseValidator's Ajv can be useful too. So we return an object that contains both request ajv and response ajv : ```javascript ajvs = { req : 'Ajv object' res : 'Ajv object' } ``` #683 * fix the unit test and change message to a more human friendly description of the error #601 * Allow to get the generated request AJV object in order to use it out of an OpenAPI and express usage (websocket...) #683 * Add documentation for OpenApiValidator.ajv function initialization usage #683 * ResponseValidator's Ajv can be useful too. So we return an object that contains both request ajv and response ajv : ```javascript ajvs = { req : 'Ajv object' res : 'Ajv object' } ``` #683 * Revert commits in order to push only bug fixes #601 * Revert "ResponseValidator's Ajv can be useful too." This reverts commit 677cacfdde64eac870e54bdd3a07e2c2572e5daf. * Revert "Add documentation for OpenApiValidator.ajv function initialization usage" This reverts commit a727f2d20693601074c797a354bfb1f5bc7ed4ef. * Revert "Allow to get the generated request AJV object in order to use it out of an OpenAPI and express usage (websocket...)" This reverts commit ad3e785c9c1e441d13c589534a3a3c3cd33cfb18. * Revert "ResponseValidator's Ajv can be useful too. So we return an object that contains both request ajv and response ajv : ```javascript ajvs = { req : 'Ajv object' res : 'Ajv object' } ``` #683" This reverts commit 8fc7226e * Revert "Add documentation for OpenApiValidator.ajv function initialization usage" This reverts commit ecb8424da785f36e6910f160315c45f38d0cb64e. * Revert "Allow to get the generated request AJV object in order to use it out of an OpenAPI and express usage (websocket...)" This reverts commit 52429c529c844f523a3e28f4a13927344bdac8cc. Co-authored-by: Carmine DiMascio * v4.13.5 * v4.13.6 * Update README migrate documentation to wiki * migrate README to wiki * chore(deps): bump follow-redirects in /examples/9-nestjs (#705) Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.4 to 1.14.8. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.4...v1.14.8) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump node-fetch from 2.6.1 to 2.6.7 in /examples/9-nestjs (#711) Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7. - [Release notes](https://github.com/node-fetch/node-fetch/releases) - [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7) --- updated-dependencies: - dependency-name: node-fetch dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimist from 1.2.5 to 1.2.6 in /examples/1-standard (#714) Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6. - [Release notes](https://github.com/substack/minimist/releases) - [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6) --- updated-dependencies: - dependency-name: minimist dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimist in /examples/3-eov-operations (#715) Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6. - [Release notes](https://github.com/substack/minimist/releases) - [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6) --- updated-dependencies: - dependency-name: minimist dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimist in /examples/2-standard-multiple-api-specs (#716) Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6. - [Release notes](https://github.com/substack/minimist/releases) - [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6) --- updated-dependencies: - dependency-name: minimist dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimist in /examples/4-eov-operations-babel (#717) Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6. - [Release notes](https://github.com/substack/minimist/releases) - [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6) --- updated-dependencies: - dependency-name: minimist dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimist in /examples/5-custom-operation-resolver (#718) Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6. - [Release notes](https://github.com/substack/minimist/releases) - [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6) --- updated-dependencies: - dependency-name: minimist dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump ansi-regex in /examples/8-top-level-discriminator (#719) Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/chalk/ansi-regex/releases) - [Commits](https://github.com/chalk/ansi-regex/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: ansi-regex dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimist in /examples/8-top-level-discriminator (#720) Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6. - [Release notes](https://github.com/substack/minimist/releases) - [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6) --- updated-dependencies: - dependency-name: minimist dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimist in /examples/7-response-date-serialization (#721) Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6. - [Release notes](https://github.com/substack/minimist/releases) - [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6) --- updated-dependencies: - dependency-name: minimist dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump ansi-regex in /examples/7-response-date-serialization (#722) Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/chalk/ansi-regex/releases) - [Commits](https://github.com/chalk/ansi-regex/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: ansi-regex dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump ansi-regex in /examples/6-multi-file-spec (#723) Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/chalk/ansi-regex/releases) - [Commits](https://github.com/chalk/ansi-regex/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: ansi-regex dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimist in /examples/6-multi-file-spec (#724) Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6. - [Release notes](https://github.com/substack/minimist/releases) - [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6) --- updated-dependencies: - dependency-name: minimist dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump ansi-regex in /examples/5-custom-operation-resolver (#725) Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/chalk/ansi-regex/releases) - [Commits](https://github.com/chalk/ansi-regex/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: ansi-regex dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump ansi-regex in /examples/3-eov-operations (#726) Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/chalk/ansi-regex/releases) - [Commits](https://github.com/chalk/ansi-regex/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: ansi-regex dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump ansi-regex in /examples/2-standard-multiple-api-specs (#727) Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/chalk/ansi-regex/releases) - [Commits](https://github.com/chalk/ansi-regex/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: ansi-regex dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump AJV to v8 (#713) * try upgrading to OAPIv3.1 * Remove 3.1-support related files * Const typings on formats * Set _discriminator as non-enumerable hide it from AJV (unknown keyword) * Refactor `x-eov-serdes` to ensure order of validation * Update AJV options handling * Update read/write only keywords * Add noop keywords * Use AJV Draft 4 to validate OpenAPI doc * Use `must` keyword to match AJV validations * Expected validation errors prefer `must` over `should`, `/` over `.` * Update README to reflect expected validation errors * Explicitly pass formats to ignore * Serdes validation errors contain more errors * Update example with expected AJV errors * Drop noisy test logs * Restore previous `Format` version * Add failing tests for undeclared x-* keywords Schema declares these are valid (via `patternProperties`) but AJV rejects on any unknown keywords * Detect `x-*` prefixes and declare as noop for Ajv * Update README to declare reserved vendor extension prefix * readOnly+writeOnly do not modify, and do attach errors * Remove test enforcing `x-eov-*` usage README still "reserves" these keywords, but do not explicitly enforce it * Rely on strictSchema=false to handle unknown keywords Remove all NOOP keywords * Explicitly pass strict=false to response validator test Options are usually set internally * Add types to serdes validator, auto-true if missing method * Rework serdes schema processor _slightly_ simplify schema, and document why complexity is necessary. Use custom keywords to allow "redacting" of confusing errors during validation Remove `jsonType` from serdes options (unused) * Update serdes test to reflect simpler validation messages * Consistent usage of / over . for json path Mirroring format of AJV * Add `eov` prefix to unknown query parameters flag Deprecate old version with console.warn * Create "normalized options" type that has stricter format Omits deprecated types/attributes. Allows skipping redundant checks/transforms that were already performed * Set defaults in one place * Add warnings for deprecated usage of options * Move options handling to `normalizeOptions`, add `ajvFormats` option * Update README to reflect new options behavior * Consistent `/` over `.` Matching AJV's internal json path errors * Remove unnecessary serDesInternal check `xEovAnyOf` effectively hides internal schemas and prevents infinite loop * Add `anyOf` test with serdes, expose all relevant errors * Simplify format overriding by applying in order, remove constant * Move redactable error to common types file * Tweak error redacting to only expose most relevant If request is not a string, message should not expose string-centric validations like format (even those "format" is invalid via serialization). Was wrongly exposed in 992cde00b2add2f6b5f59ba83cfd3bbac658bb38 * Refactor serdes (again...) to use keyword execution order So apparently AJV _does_ have some ability to enforce keyword ordering via `before`/`post`! Using those options, serdes schema gets a lot simpler and has more trivial error redacting * v4.14.0-beta.1 Co-authored-by: Essential Randomness Co-authored-by: Carmine DiMascio * v4.14.0-beta.1 * Update README.md * Bump multer to version that removes dicer as sub-dependency (#739) * Bump multer to version that removes dicer as sub-dependency * use lockfile that gets us 1.4.4-lts.1 and not just 1.4.4 * Revert "use lockfile that gets us 1.4.4-lts.1 and not just 1.4.4" This reverts commit 0f1934ea485684bdc292e35ca68b6431e378adeb. * Update lockfile without upgrading lockfileVersion * Bump multer to 1.4.5 * v4.14.0-beta.2 * update ansi-regex * fixed router parameters (#762) * Fix #699 serdes missed on items in a collection, with tests. (#704) Thanks @Fabiencdp. * v5.0.0 with ajv8 * Update README.md * Update README.md * chore(deps): bump minimatch in /examples/4-eov-operations-babel (#768) Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2. - [Release notes](https://github.com/isaacs/minimatch/releases) - [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2) --- updated-dependencies: - dependency-name: minimatch dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimatch in /examples/6-multi-file-spec (#767) Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2. - [Release notes](https://github.com/isaacs/minimatch/releases) - [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2) --- updated-dependencies: - dependency-name: minimatch dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimatch in /examples/3-eov-operations (#766) Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2. - [Release notes](https://github.com/isaacs/minimatch/releases) - [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2) --- updated-dependencies: - dependency-name: minimatch dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimatch in /examples/5-custom-operation-resolver (#765) Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2. - [Release notes](https://github.com/isaacs/minimatch/releases) - [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2) --- updated-dependencies: - dependency-name: minimatch dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimatch from 3.0.4 to 3.1.2 in /examples/1-standard (#764) Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2. - [Release notes](https://github.com/isaacs/minimatch/releases) - [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2) --- updated-dependencies: - dependency-name: minimatch dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimatch in /examples/2-standard-multiple-api-specs (#763) Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2. - [Release notes](https://github.com/isaacs/minimatch/releases) - [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2) --- updated-dependencies: - dependency-name: minimatch dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimatch in /examples/8-top-level-discriminator (#761) Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2. - [Release notes](https://github.com/isaacs/minimatch/releases) - [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2) --- updated-dependencies: - dependency-name: minimatch dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimatch from 3.0.4 to 3.1.2 in /examples/9-nestjs (#760) Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2. - [Release notes](https://github.com/isaacs/minimatch/releases) - [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2) --- updated-dependencies: - dependency-name: minimatch dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump minimatch in /examples/7-response-date-serialization (#759) Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2. - [Release notes](https://github.com/isaacs/minimatch/releases) - [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2) --- updated-dependencies: - dependency-name: minimatch dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump terser from 5.7.2 to 5.14.2 in /examples/9-nestjs (#750) Bumps [terser](https://github.com/terser/terser) from 5.7.2 to 5.14.2. - [Release notes](https://github.com/terser/terser/releases) - [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md) - [Commits](https://github.com/terser/terser/commits) --- updated-dependencies: - dependency-name: terser dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump ansi-regex from 3.0.0 to 3.0.1 in /examples/9-nestjs (#738) Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 3.0.0 to 3.0.1. - [Release notes](https://github.com/chalk/ansi-regex/releases) - [Commits](https://github.com/chalk/ansi-regex/compare/v3.0.0...v3.0.1) --- updated-dependencies: - dependency-name: ansi-regex dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: upgrade body-parser from 1.19.0 to 1.19.1 (#691) Snyk has created this PR to upgrade body-parser from 1.19.0 to 1.19.1. See this package in npm: https://www.npmjs.com/package/body-parser See this project in Snyk: https://app.snyk.io/org/cdimascio/project/dc56b04d-b132-445b-bde8-64211be844c7?utm_source=github&utm_medium=referral&page=upgrade-pr * fix: upgrade body-parser from 1.19.0 to 1.19.1 (#690) Snyk has created this PR to upgrade body-parser from 1.19.0 to 1.19.1. See this package in npm: https://www.npmjs.com/package/body-parser See this project in Snyk: https://app.snyk.io/org/cdimascio/project/0ac9a5bd-9a7f-4c0e-bf8b-51d0bd4c4448?utm_source=github&utm_medium=referral&page=upgrade-pr * fix: upgrade body-parser from 1.19.0 to 1.19.1 (#689) Snyk has created this PR to upgrade body-parser from 1.19.0 to 1.19.1. See this package in npm: https://www.npmjs.com/package/body-parser See this project in Snyk: https://app.snyk.io/org/cdimascio/project/53639b22-8ff0-4bd5-97c3-ae30b20a20f4?utm_source=github&utm_medium=referral&page=upgrade-pr * chore(deps): bump minimist and @nestjs/cli in /examples/9-nestjs (#769) Bumps [minimist](https://github.com/minimistjs/minimist) to 1.2.6 and updates ancestor dependency [@nestjs/cli](https://github.com/nestjs/nest-cli). These dependencies need to be updated together. Updates `minimist` from 1.2.5 to 1.2.6 - [Release notes](https://github.com/minimistjs/minimist/releases) - [Changelog](https://github.com/minimistjs/minimist/blob/main/CHANGELOG.md) - [Commits](https://github.com/minimistjs/minimist/compare/v1.2.5...v1.2.6) Updates `@nestjs/cli` from 8.1.2 to 8.2.8 - [Release notes](https://github.com/nestjs/nest-cli/releases) - [Changelog](https://github.com/nestjs/nest-cli/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/nest-cli/compare/8.1.2...8.2.8) --- updated-dependencies: - dependency-name: minimist dependency-type: indirect - dependency-name: "@nestjs/cli" dependency-type: direct:development ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * implement github actions workflow (#793) * implement github actions workflow * fix target * enhance SchemaObject type (#697) - Composition types: allOf, anyOf, oneOf and not are valid SchemaObjects * v5.0.1 * fix: objects in form-data (#730) Co-authored-by: dj <> * v5.0.2 * v5.0.2 * Rename field `error_code` to `errorCode` in `ValidationErrorItem` (#819) * FIx serialization/deserialization in additionalProperties (#822) * chore(deps): bump http-cache-semantics (#817) Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/kornelski/http-cache-semantics/releases) - [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: http-cache-semantics dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: upgrade content-type from 1.0.4 to 1.0.5 (#818) Snyk has created this PR to upgrade content-type from 1.0.4 to 1.0.5. See this package in npm: https://www.npmjs.com/package/content-type See this project in Snyk: https://app.snyk.io/org/cdimascio/project/f63fb44e-f154-45ba-b1f0-20d49ea578ce?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * chore(deps): bump http-cache-semantics (#816) Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/kornelski/http-cache-semantics/releases) - [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: http-cache-semantics dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump http-cache-semantics in /examples/6-multi-file-spec (#815) Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/kornelski/http-cache-semantics/releases) - [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: http-cache-semantics dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump http-cache-semantics (#814) Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/kornelski/http-cache-semantics/releases) - [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: http-cache-semantics dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump http-cache-semantics (#813) Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/kornelski/http-cache-semantics/releases) - [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: http-cache-semantics dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump http-cache-semantics in /examples/3-eov-operations (#812) Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/kornelski/http-cache-semantics/releases) - [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: http-cache-semantics dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump http-cache-semantics (#811) Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/kornelski/http-cache-semantics/releases) - [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: http-cache-semantics dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump http-cache-semantics in /examples/1-standard (#810) Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/kornelski/http-cache-semantics/releases) - [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: http-cache-semantics dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump cookiejar from 2.1.3 to 2.1.4 (#806) Bumps [cookiejar](https://github.com/bmeck/node-cookiejar) from 2.1.3 to 2.1.4. - [Release notes](https://github.com/bmeck/node-cookiejar/releases) - [Commits](https://github.com/bmeck/node-cookiejar/commits) --- updated-dependencies: - dependency-name: cookiejar dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump cookiejar from 2.1.2 to 2.1.4 in /examples/9-nestjs (#805) Bumps [cookiejar](https://github.com/bmeck/node-cookiejar) from 2.1.2 to 2.1.4. - [Release notes](https://github.com/bmeck/node-cookiejar/releases) - [Commits](https://github.com/bmeck/node-cookiejar/commits) --- updated-dependencies: - dependency-name: cookiejar dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump json5 in /examples/4-eov-operations-babel (#799) Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3. - [Release notes](https://github.com/json5/json5/releases) - [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md) - [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3) --- updated-dependencies: - dependency-name: json5 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: upgrade body-parser from 1.19.0 to 1.20.1 (#798) Snyk has created this PR to upgrade body-parser from 1.19.0 to 1.20.1. See this package in npm: https://www.npmjs.com/package/body-parser See this project in Snyk: https://app.snyk.io/org/cdimascio/project/c52478e1-4b5f-464b-9b43-e11455d66bba?utm_source=github&utm_medium=referral&page=upgrade-pr * fix: upgrade ajv from 8.11.0 to 8.11.2 (#797) Snyk has created this PR to upgrade ajv from 8.11.0 to 8.11.2. See this package in npm: https://www.npmjs.com/package/ajv See this project in Snyk: https://app.snyk.io/org/cdimascio/project/f63fb44e-f154-45ba-b1f0-20d49ea578ce?utm_source=github&utm_medium=referral&page=upgrade-pr * chore(deps): bump json5 from 1.0.1 to 1.0.2 in /examples/9-nestjs (#801) Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2. - [Release notes](https://github.com/json5/json5/releases) - [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md) - [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2) --- updated-dependencies: - dependency-name: json5 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * v5.0.3 * Switch json-schema-ref-parser to non-deprecated package (#829) * switch json-schema-ref-parser to new package @apidevtools/json-schema-ref-parser * revert lockfile version to 1 * fix: Deserialize custom types with inline schemas (#823) * v5.0.4 * fix documentation links * Remove examples from apiDoc when validating requests (#774) Co-authored-by: Michael Eller * Resolve "reference resolves to more than one schema" errors when AJV processes OpenAPI document and encounters unknown properties whose values include an `id` parameter. (#853) * Fails to get past AJV error when schema includes `x-stoplight` property and is referenced. * Traverse the OpenAPI document, stripping all x-stoplight values. * fixing default export function issue (#846) Co-authored-by: Kesha Shah * #841 return error thrown in serDes deserializer (#842) * Remove body-parser deps in example (#845) * chore: remove unused body-parser for examples/1-standard * chore: remove body-parser for examples/2-standard-multiple-api-specs * chore: remove unused body-parser for examples/3-eov-operations * chore: remove unused body-parser for examples/4-eov-operations-babel * chore: remove body-parser for examples/5-custom-operation-resolver * chore: remove body-parser for examples/6-multi-file-spec * chore: remove body-parser for examples/7-response-date-serialization * chore: remove body-parser for examples/8-top-level-discriminator * fix example schema removal and upgrade patch version * v5.0.5 change history * update version locks * Allow optional use of `req.url` (#857) * test: add test cases for new feature * feat: allow using req.url based on config --------- Co-authored-by: nikkegg * Reorder upload and security middlewares (#866) - Move multipart middleware after security middleware so that security handlers can abort request pipeline before uploads are processed. Fixes #865 * Update build and packaging scripts (#872) - 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 * v5.1.0 * v5.1.0 * Pass-through HttpError caught in multipart handler (#867) - Consumers of express-openapi-validator have access to the custom error types via exported object: error (e.g. error.BadRequest). - If the multipart handler throws, for example from the multer storage engine, check whether the err instance is already an HttpError. If so, it can be passed-through as is. This is mostly useful for setting the HTTP status code. * v5.1.1 * Safer handling of multipart nested JSON body props (#878) If a multipart request body has schema oneOf, anyOf, or allOf, then automatic parsing of JSON properties throws. An object is expected. Fix the error today and add a TODO to add support for nested JSON props in multipart requests that utilize oneOf, anyOf, or allOf. * Normalize request body ContentTypes (#863) Co-authored-by: Ray Vincent * v5.1.1 * CLS Context is lost after using multer middleware (#695) related issue: https://github.com/expressjs/multer/issues/814 Used the solution described in the above link to fix the issue Co-authored-by: Alan Wang * remove examples from schema (#890) * v5.1.3 * v5.1.3 * add cookies to examples 1 and 2 (#891) * remove examples from schema * add cookies to example 1 and 2 * docs: fix doc typo in README.md (#885) * npm audit fix (#892) * remove examples from schema * add cookies to example 1 and 2 * audit-fix * removes lodash.uniq and lodash.zipobject dependencies (#893) * fixes badging for build and test * Remove read only and write only fields (#895) * Fix problems in current test read.only according to the schema * #627 Remove readonly fields in : - requests if ``validateRequest.removeAdditional`` configuration equals ``true`` or ```'all'`` or ``'failing'`` - responses if ``validateResponse.removeAdditional`` configuration equals ``true`` or ```'all'`` or ``'failing'`` No changes if ``validateRequest = true``, ``validateResponse = true``, ``validateRequest.removeAdditional : false``, ``validateResponse.removeAdditional : false`` Unit tests added to check the behaviour with removeAdditional : true. Fields removed and no error in response. * Update README.md (#896) * Update CONTRIBUTING.md * Update README.md * Update README.md * fix: #887 allow multiple params with wildcard (#898) * Add multiple path parameters with wildcard tests * Change regex to support multiple params when including file path params (#1) * Change regex to support multiple params when including URI path param * Update regex, remove unnecessary bracket --------- Co-authored-by: Guillermo Recalde * Direct example broken link to the guide * v5.1.4 * v5.1.4 * Support writeOnly + required combination #149 (#756) * fixes write-only tests * v5.1.5 * Fixes for 881 - multiple specs w/validateRequests fail (#903) * v5.1.6 * fix: upgrade @types/multer from 1.4.7 to 1.4.11 (#897) Snyk has created this PR to upgrade @types/multer from 1.4.7 to 1.4.11. See this package in npm: https://www.npmjs.com/package/@types/multer See this project in Snyk: https://app.snyk.io/org/cdimascio/project/f63fb44e-f154-45ba-b1f0-20d49ea578ce?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * Add multipart fix when does not exist any body (#905) * fix: upgrade path-to-regexp from 6.2.0 to 6.2.2 (#914) * fix: examples/4-eov-operations-babel/package.json & examples/4-eov-operations-babel/package-lock.json to reduce vulnerabilities (#911) * Add `express` as peer dependency (#907) * Support async operation handler resolver (#921) - Let users define operationHandlers.resolver as a synchronous or asynchronous function that returns a request handler - Make installOperationHandlers and asynchronous function that awaits a resolver promise (automatically wraps resolver with promise if needed) - Update operation handlers middleware to handle an async installOperationHandlers. * fix: package.json & package-lock.json to reduce vulnerabilities (#920) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-EXPRESS-6474509 Co-authored-by: snyk-bot * chore(deps): bump webpack and @nestjs/cli in /examples/9-nestjs (#831) Bumps [webpack](https://github.com/webpack/webpack) to 5.76.2 and updates ancestor dependency [@nestjs/cli](https://github.com/nestjs/nest-cli). These dependencies need to be updated together. Updates `webpack` from 5.73.0 to 5.76.2 - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.73.0...v5.76.2) Updates `@nestjs/cli` from 8.2.8 to 9.3.0 - [Release notes](https://github.com/nestjs/nest-cli/releases) - [Changelog](https://github.com/nestjs/nest-cli/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/nest-cli/compare/8.2.8...9.3.0) --- updated-dependencies: - dependency-name: webpack dependency-type: indirect - dependency-name: "@nestjs/cli" dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(dependencies): bump @apidevtools/json-schema-ref-parser to 11.6.2 to prevent vulnerability (#918) * chore(deps): bump axios, @nestjs/common, @nestjs/core, @nestjs/platform-express and @nestjs/testing (#925) Removes [axios](https://github.com/axios/axios). It's no longer used after updating ancestor dependencies [axios](https://github.com/axios/axios), [@nestjs/common](https://github.com/nestjs/nest/tree/HEAD/packages/common), [@nestjs/core](https://github.com/nestjs/nest/tree/HEAD/packages/core), [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express) and [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing). These dependencies need to be updated together. Removes `axios` Updates `@nestjs/common` from 8.0.11 to 10.3.8 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.3.8/packages/common) Updates `@nestjs/core` from 8.4.7 to 10.3.8 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.3.8/packages/core) Updates `@nestjs/platform-express` from 8.4.7 to 10.3.8 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.3.8/packages/platform-express) Updates `@nestjs/testing` from 8.4.7 to 10.3.8 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.3.8/packages/testing) --- updated-dependencies: - dependency-name: axios dependency-type: indirect - dependency-name: "@nestjs/common" dependency-type: direct:production - dependency-name: "@nestjs/core" dependency-type: direct:production - dependency-name: "@nestjs/platform-express" dependency-type: direct:production - dependency-name: "@nestjs/testing" dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @babel/traverse (#924) Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.15.4 to 7.24.6. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.24.6/packages/babel-traverse) --- updated-dependencies: - dependency-name: "@babel/traverse" dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * upgrade example 4 * upgrade example 3 * upgrade ajv * chore: apiSpec may be const literal (#854) Co-authored-by: Carmine DiMascio * pass coerceTypes through (#809) Co-authored-by: Carmine DiMascio * add reponse serializer tests for arrays * v5.2.0 * v5.2.0 * Update LICENSE * chore(deps-dev): bump braces from 3.0.2 to 3.0.3 (#928) Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Stripped query params for req.url branch arm (#942) Co-authored-by: g-radam <859802+g-radam@users.noreply.github.com> * fix: upgrade ajv from 8.14.0 to 8.15.0 (#938) Snyk has created this PR to upgrade ajv from 8.14.0 to 8.15.0. See this package in npm: ajv See this project in Snyk: https://app.snyk.io/org/cdimascio/project/f63fb44e-f154-45ba-b1f0-20d49ea578ce?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * fix: upgrade @apidevtools/json-schema-ref-parser from 11.6.2 to 11.6.4 (#937) Snyk has created this PR to upgrade @apidevtools/json-schema-ref-parser from 11.6.2 to 11.6.4. See this package in npm: @apidevtools/json-schema-ref-parser See this project in Snyk: https://app.snyk.io/org/cdimascio/project/f63fb44e-f154-45ba-b1f0-20d49ea578ce?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * fix: upgrade express-openapi-validator from 5.1.6 to 5.2.0 (#936) Snyk has created this PR to upgrade express-openapi-validator from 5.1.6 to 5.2.0. See this package in npm: express-openapi-validator See this project in Snyk: https://app.snyk.io/org/cdimascio/project/0ac9a5bd-9a7f-4c0e-bf8b-51d0bd4c4448?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * FIX: issue #917 (#935) Co-authored-by: Dušan Miška * version 5.2.1 * version 5.3.1 * fix: upgrade express-openapi-validator from 5.1.6 to 5.2.0 (#944) Snyk has created this PR to upgrade express-openapi-validator from 5.1.6 to 5.2.0. See this package in npm: express-openapi-validator See this project in Snyk: https://app.snyk.io/org/cdimascio/project/dc56b04d-b132-445b-bde8-64211be844c7?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * fix: correct security schema logic for OR verification (#946) * version 5.3.2 * fix: upgrade @apidevtools/json-schema-ref-parser from 11.6.4 to 11.7.0 (#947) Snyk has created this PR to upgrade @apidevtools/json-schema-ref-parser from 11.6.4 to 11.7.0. See this package in npm: @apidevtools/json-schema-ref-parser See this project in Snyk: https://app.snyk.io/org/cdimascio/project/f63fb44e-f154-45ba-b1f0-20d49ea578ce?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * chore(deps-dev): bump ws from 7.5.5 to 7.5.10 in /examples/9-nestjs (#930) Bumps [ws](https://github.com/websockets/ws) from 7.5.5 to 7.5.10. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/7.5.5...7.5.10) --- updated-dependencies: - dependency-name: ws dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump braces in /examples/8-top-level-discriminator (#929) Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: upgrade ajv from 8.15.0 to 8.17.1 (#945) Snyk has created this PR to upgrade ajv from 8.15.0 to 8.17.1. See this package in npm: ajv See this project in Snyk: https://app.snyk.io/org/cdimascio/project/f63fb44e-f154-45ba-b1f0-20d49ea578ce?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * chore(deps-dev): bump @babel/traverse in /examples/9-nestjs (#948) Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.15.4 to 7.25.4. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.25.4/packages/babel-traverse) --- updated-dependencies: - dependency-name: "@babel/traverse" dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * version 5.3.3 * Update README.md * Use lenient resolver type (#956) In #921, a stronger type applied to OperationHandlerOptions['resolver'] so that end users would have an idea of what the parameters are for their custom resolvers. It went too far in stipulating a return type. Set the return type to unknown and let users decide how much type safety they need in their resolver. Fixes #952 * Change AJV allErrors default and support user setting (#955) * Support setting allErrors for AJV validation AJV recommends setting option `allErrors` to `false` in production. pdate `createAjv()` to respect the user's setting. Avoid introducing a breaking change by defaulting to `true` when not defined by the user. Add tests: 1. Make sure `AjvOptions` sets the value appropriately based on whether the end user defined `allErrors` or not. 2. When validating requests, make sure the number of errors reported (when multiple occur) is 1 when `allErrors` is `false`. The `allErrors` configuration for OpenAPISchemaValidator is not changed by this commit since that validation is for trusted content. Fixes #954 * (Revisions) Support setting allErrors for AJV validation - Do not set allErrors by default **breaking change** * (Revisions) Support setting allErrors for AJV validation - Allow allErrors to be set on requests and responses independently * v5.3.4 * update README * [StepSecurity] ci: Harden GitHub Actions (#959) Signed-off-by: StepSecurity Bot * chore(deps): bump webpack and @nestjs/cli in /examples/9-nestjs (#953) Bumps [webpack](https://github.com/webpack/webpack) to 5.94.0 and updates ancestor dependency [@nestjs/cli](https://github.com/nestjs/nest-cli). These dependencies need to be updated together. Updates `webpack` from 5.76.2 to 5.94.0 - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.76.2...v5.94.0) Updates `@nestjs/cli` from 9.3.0 to 10.4.5 - [Release notes](https://github.com/nestjs/nest-cli/releases) - [Changelog](https://github.com/nestjs/nest-cli/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/nest-cli/compare/9.3.0...10.4.5) --- updated-dependencies: - dependency-name: webpack dependency-type: indirect - dependency-name: "@nestjs/cli" dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump braces in /examples/4-eov-operations-babel (#957) Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump braces in /examples/5-custom-operation-resolver (#958) Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: upgrade express-openapi-validator from 5.2.0 to 5.3.1 (#951) Snyk has created this PR to upgrade express-openapi-validator from 5.2.0 to 5.3.1. See this package in npm: express-openapi-validator See this project in Snyk: https://app.snyk.io/org/cdimascio/project/0ac9a5bd-9a7f-4c0e-bf8b-51d0bd4c4448?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * Fix changelog breaking changes notice (#961) The breaking change included in entry (2024-08-31) was not added correctly. Fix it. * fix: Dereference path parameters (#962) The OpenAPI spec loader has a `discoverRoutes` method which explores an OpenAPI document and gathers information about the paths and parameters used. The list of discovered path parameters is used to install parameter-specific middleware in `src/openapi.validator.ts#installPathParams` Path parameters declared with `$ref` were not detected in the `discoverRoutes` implementation, leading to the un-coerced values being used. By dereferencing each path parameter when building this list, we should see the same behavior for referenced path parameters and for inline path parameters. Closes https://github.com/cdimascio/express-openapi-validator/issues/803 * v5.3.5 * chore(deps-dev): bump braces from 3.0.2 to 3.0.3 in /examples/9-nestjs (#964) Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump braces in /examples/7-response-date-serialization (#963) Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: upgrade express-openapi-validator from 5.2.0 to 5.3.1 (#960) Snyk has created this PR to upgrade express-openapi-validator from 5.2.0 to 5.3.1. See this package in npm: express-openapi-validator See this project in Snyk: https://app.snyk.io/org/cdimascio/project/dc56b04d-b132-445b-bde8-64211be844c7?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * Update README.md * Update README.md * bodyParsers is deprecated so update with expess bodyParsers (#974) * Change path-to-regexp 6.2.2 to 6.3.0 * express version update * bodyParsers is deprecated so update with expess bodyParsers * update express to 4.21.0 * v5.3.6 * feat(path-to-regexp): path-to-regexp 8.1.0 update (#976) * feat(path-to-regexp): path-to-regexp update to 8.1.0 * feat(path-to-regexp): cleanup notes for PR * feat(path-to-regexp): potential version bump if approved * feat(path-to-regexp): pr change request + added notes for changes --------- Co-authored-by: fkeefer Co-authored-by: Carmine DiMascio * fix: upgrade @types/multer from 1.4.11 to 1.4.12 (#983) Snyk has created this PR to upgrade @types/multer from 1.4.11 to 1.4.12. See this package in npm: @types/multer See this project in Snyk: https://app.snyk.io/org/cdimascio/project/f63fb44e-f154-45ba-b1f0-20d49ea578ce?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * v5.3.7 * fix: examples/3-eov-operations/package.json & examples/3-eov-operations/package-lock.json to reduce vulnerabilities (#989) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-PATHTOREGEXP-7925106 Co-authored-by: snyk-bot * fix: examples/4-eov-operations-babel/package.json & examples/4-eov-operations-babel/package-lock.json to reduce vulnerabilities (#988) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-PATHTOREGEXP-7925106 Co-authored-by: snyk-bot * fix: examples/2-standard-multiple-api-specs/package.json & examples/2-standard-multiple-api-specs/package-lock.json to reduce vulnerabilities (#987) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-PATHTOREGEXP-7925106 Co-authored-by: snyk-bot * fix: examples/1-standard/package.json & examples/1-standard/package-lock.json to reduce vulnerabilities (#986) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-PATHTOREGEXP-7925106 Co-authored-by: snyk-bot * Update README.md * Update README.md * chore(deps): bump body-parser and @nestjs/platform-express (#990) Bumps [body-parser](https://github.com/expressjs/body-parser) to 1.20.3 and updates ancestor dependency [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express). These dependencies need to be updated together. Updates `body-parser` from 1.20.2 to 1.20.3 - [Release notes](https://github.com/expressjs/body-parser/releases) - [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md) - [Commits](https://github.com/expressjs/body-parser/compare/1.20.2...1.20.3) Updates `@nestjs/platform-express` from 10.3.8 to 10.4.3 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.4.3/packages/platform-express) --- updated-dependencies: - dependency-name: body-parser dependency-type: indirect - dependency-name: "@nestjs/platform-express" dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: package.json & package-lock.json to reduce vulnerabilities (#993) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-COOKIE-8163060 Co-authored-by: snyk-bot * fix: upgrade express-openapi-validator from 5.3.6 to 5.3.7 (#995) Snyk has created this PR to upgrade express-openapi-validator from 5.3.6 to 5.3.7. See this package in npm: https://www.npmjs.com/package/express-openapi-validator See this project in Snyk: https://app.snyk.io/org/cdimascio/project/dc56b04d-b132-445b-bde8-64211be844c7?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * chore(deps): bump cookie and cookie-parser (#996) Bumps [cookie](https://github.com/jshttp/cookie) to 0.7.1 and updates ancestor dependency [cookie-parser](https://github.com/expressjs/cookie-parser). These dependencies need to be updated together. Updates `cookie` from 0.4.1 to 0.7.1 - [Release notes](https://github.com/jshttp/cookie/releases) - [Commits](https://github.com/jshttp/cookie/compare/v0.4.1...v0.7.1) Updates `cookie-parser` from 1.4.6 to 1.4.7 - [Release notes](https://github.com/expressjs/cookie-parser/releases) - [Changelog](https://github.com/expressjs/cookie-parser/blob/master/HISTORY.md) - [Commits](https://github.com/expressjs/cookie-parser/compare/1.4.6...1.4.7) --- updated-dependencies: - dependency-name: cookie dependency-type: indirect - dependency-name: cookie-parser dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump path-to-regexp (#997) Bumps [path-to-regexp](https://github.com/pillarjs/path-to-regexp) from 6.2.0 to 6.3.0. - [Release notes](https://github.com/pillarjs/path-to-regexp/releases) - [Changelog](https://github.com/pillarjs/path-to-regexp/blob/master/History.md) - [Commits](https://github.com/pillarjs/path-to-regexp/compare/v6.2.0...v6.3.0) --- updated-dependencies: - dependency-name: path-to-regexp dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: examples/4-eov-operations-babel/package.json & examples/4-eov-operations-babel/package-lock.json to reduce vulnerabilities (#994) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-COOKIE-8163060 Co-authored-by: snyk-bot * example 6 enhancements * Create SECURITY.md (#999) * fix: add cookie support for HTTP bearer authentication (#949) * fix: add cookie support for HTTP bearer authentication - Updated validateHttp() to handle bearer tokens in both authorization header and cookies. - Adapted logic to ensure flexibility for projects using HTTP-only cookies instead of headers for authentication. * fix: Refine HTTP authentication validation based on code review feedback - Maintain existing error for missing Authorization header - Add specific error for cookie authentication when specified in security scheme - Consider both Authorization header and cookie for bearer token validation * fix: Revert unintended code style changes made during previous commit * fix: Revert unintended code style changes made during previous commit * fix: fix: update validateHttp to handle missing auth headers properly - Restructure Basic auth validation to check header existence first - Maintain original error messages for non-cookie authentication - Add proper cookie authentication check when specified - Fix undefined.includes() error in Basic auth validation * v5.3.8 * chore(deps): bump cookie and express in /examples/3-eov-operations (#1002) Bumps [cookie](https://github.com/jshttp/cookie) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together. Updates `cookie` from 0.6.0 to 0.7.1 - [Release notes](https://github.com/jshttp/cookie/releases) - [Commits](https://github.com/jshttp/cookie/compare/v0.6.0...v0.7.1) Updates `express` from 4.19.2 to 4.21.1 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/4.21.1/History.md) - [Commits](https://github.com/expressjs/express/compare/4.19.2...4.21.1) --- updated-dependencies: - dependency-name: cookie dependency-type: indirect - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: fix authHeader without `cookie-parser` middleware (#1003) [express-openapi-validator v5.8.3][1] and 79424b2 (fix: add cookie support for HTTP bearer authentication (#949), 2024-10-27) breaks HTTP bearer authentication when the `cookie-parser` middleware is not present (and therefore `req.cookies` is not present). [1]: https://github.com/cdimascio/express-openapi-validator/releases/tag/v5.3.8 Fixes: 79424b26137fd0ad2e73f37b689e9ade2618bbc4 * v5.3.9 * fix: upgrade express-openapi-validator from 5.3.6 to 5.3.7 (#1001) Snyk has created this PR to upgrade express-openapi-validator from 5.3.6 to 5.3.7. See this package in npm: https://www.npmjs.com/package/express-openapi-validator See this project in Snyk: https://app.snyk.io/org/cdimascio/project/53639b22-8ff0-4bd5-97c3-ae30b20a20f4?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * fix: upgrade path-to-regexp from 8.1.0 to 8.2.0 (#1000) Snyk has created this PR to upgrade path-to-regexp from 8.1.0 to 8.2.0. See this package in npm: https://www.npmjs.com/package/path-to-regexp See this project in Snyk: https://app.snyk.io/org/cdimascio/project/f63fb44e-f154-45ba-b1f0-20d49ea578ce?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * fix: examples/4-eov-operations-babel/package.json & examples/4-eov-operations-babel/package-lock.json to reduce vulnerabilities (#972) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-BODYPARSER-7926860 - https://snyk.io/vuln/SNYK-JS-EXPRESS-7926867 - https://snyk.io/vuln/SNYK-JS-SEND-7926862 - https://snyk.io/vuln/SNYK-JS-SERVESTATIC-7926865 Co-authored-by: snyk-bot * update alpha 3.1 version * fix: examples/4-eov-operations-babel/package.json & examples/4-eov-operations-babel/package-lock.json to reduce vulnerabilities (#1021) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-PATHTOREGEXP-8482416 Co-authored-by: snyk-bot * fix: package.json & package-lock.json to reduce vulnerabilities (#1017) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-PATHTOREGEXP-8482416 Co-authored-by: snyk-bot * chore(deps): bump path-to-regexp and express in /examples/1-standard (#1016) Bumps [path-to-regexp](https://github.com/pillarjs/path-to-regexp) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together. Updates `path-to-regexp` from 0.1.10 to 0.1.12 - [Release notes](https://github.com/pillarjs/path-to-regexp/releases) - [Changelog](https://github.com/pillarjs/path-to-regexp/blob/master/History.md) - [Commits](https://github.com/pillarjs/path-to-regexp/compare/v0.1.10...v0.1.12) Updates `express` from 4.21.0 to 4.21.2 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/4.21.2/History.md) - [Commits](https://github.com/expressjs/express/compare/4.21.0...4.21.2) --- updated-dependencies: - dependency-name: path-to-regexp dependency-type: indirect - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: upgrade express-openapi-validator from 5.3.7 to 5.3.8 (#1011) Snyk has created this PR to upgrade express-openapi-validator from 5.3.7 to 5.3.8. See this package in npm: express-openapi-validator See this project in Snyk: https://app.snyk.io/org/cdimascio/project/53639b22-8ff0-4bd5-97c3-ae30b20a20f4?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * fix: upgrade express-openapi-validator from 5.3.6 to 5.3.7 (#1008) Snyk has created this PR to upgrade express-openapi-validator from 5.3.6 to 5.3.7. See this package in npm: express-openapi-validator See this project in Snyk: https://app.snyk.io/org/cdimascio/project/0ac9a5bd-9a7f-4c0e-bf8b-51d0bd4c4448?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * fix: upgrade @apidevtools/json-schema-ref-parser from 11.7.0 to 11.7.2 (#1006) Snyk has created this PR to upgrade @apidevtools/json-schema-ref-parser from 11.7.0 to 11.7.2. See this package in npm: @apidevtools/json-schema-ref-parser See this project in Snyk: https://app.snyk.io/org/cdimascio/project/f63fb44e-f154-45ba-b1f0-20d49ea578ce?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * feat(openapi): support OpenAPI version 3.1 (extends PR #882) (#1027) * feat(openapi): support version 3.1 * test(openapi_3.1): ensure that an API with webhooks and no routes is supported * feat(openapi_3.1): adds open api 3.1 type * chore(test-scripts): run mocha with --extension instead of glob to pick up subdirectories Mocha was not picking up the tests in subdirectories with the provided glob. Adding --extension with the tests extension and setting the root test folder in tests fixed it * test(openapi-3.1): adds test to ensure an API with only components is considered valid * test(openapi-3.1): remove unnecessary import * test(openapi-3.1): add support for summary in info object * test(openapi-3.1): add support for identifier in license * test(openapi_3.1): ensure API with type set to null works correctly * test(open_api3.1): ensure that methods with non-explicit semantics allow request body * test(open_api3.1): ensure 500 is returned when server variable has no default * feat(openapi_3.1): ensure API supports an endpoint without response * feat(openapi_3.1): add full type support for open api 3.1 * test(openapi_3.1): adds test for path item support in components * fix(openapi_3.1_schema): update schema to fix bug * feat(openapi_3.1): support reusable path items * style(linting): fix linting issues * style(openapi): improve readability of version validation * docs(schema-validator): clearly state why media-range attribute is not defined * version 6.0.0-alpha.1 with initial OAS-3.1 support (from PR https://github.com/cdimascio/express-openapi-validator/pull/882) * v6.0.0-alpha.2 * feat(openapi): support version 3.1 * test(openapi_3.1): ensure that an API with webhooks and no routes is supported * feat(openapi_3.1): adds open api 3.1 type * chore(test-scripts): run mocha with --extension instead of glob to pick up subdirectories Mocha was not picking up the tests in subdirectories with the provided glob. Adding --extension with the tests extension and setting the root test folder in tests fixed it * test(openapi-3.1): adds test to ensure an API with only components is considered valid * test(openapi-3.1): remove unnecessary import * test(openapi-3.1): add support for summary in info object * test(openapi-3.1): add support for identifier in license * test(openapi_3.1): ensure API with type set to null works correctly * test(open_api3.1): ensure that methods with non-explicit semantics allow request body * test(open_api3.1): ensure 500 is returned when server variable has no default * feat(openapi_3.1): ensure API supports an endpoint without response * feat(openapi_3.1): add full type support for open api 3.1 * test(openapi_3.1): adds test for path item support in components * fix(openapi_3.1_schema): update schema to fix bug * feat(openapi_3.1): support reusable path items * style(linting): fix linting issues * style(openapi): improve readability of version validation * docs(schema-validator): clearly state why media-range attribute is not defined * version 6.0.0-alpha.1 with initial OAS-3.1 support (from PR https://github.com/cdimascio/express-openapi-validator/pull/882) * v6.0.0-alpha.2 * alpha.3 * feat(openapi): support version 3.1 * feat(openapi_3.1): adds open api 3.1 type * fix(openapi_3.1_schema): update schema to fix bug * style(linting): fix linting issues * fix: instantiate Ajv2020 for OAS 3.1 (#1009) * chore: create factories for ajvInstance and schema * test: writing some tests * chore: removing ts from editorconfig * chore: add eslint * update alpha 3.1 version * fix: examples/4-eov-operations-babel/package.json & examples/4-eov-operations-babel/package-lock.json to reduce vulnerabilities (#1021) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-PATHTOREGEXP-8482416 Co-authored-by: snyk-bot * fix: package.json & package-lock.json to reduce vulnerabilities (#1017) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-PATHTOREGEXP-8482416 Co-authored-by: snyk-bot * chore(deps): bump path-to-regexp and express in /examples/1-standard (#1016) Bumps [path-to-regexp](https://github.com/pillarjs/path-to-regexp) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together. Updates `path-to-regexp` from 0.1.10 to 0.1.12 - [Release notes](https://github.com/pillarjs/path-to-regexp/releases) - [Changelog](https://github.com/pillarjs/path-to-regexp/blob/master/History.md) - [Commits](https://github.com/pillarjs/path-to-regexp/compare/v0.1.10...v0.1.12) Updates `express` from 4.21.0 to 4.21.2 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/4.21.2/History.md) - [Commits](https://github.com/expressjs/express/compare/4.21.0...4.21.2) --- updated-dependencies: - dependency-name: path-to-regexp dependency-type: indirect - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: upgrade express-openapi-validator from 5.3.7 to 5.3.8 (#1011) Snyk has created this PR to upgrade express-openapi-validator from 5.3.7 to 5.3.8. See this package in npm: express-openapi-validator See this project in Snyk: https://app.snyk.io/org/cdimascio/project/53639b22-8ff0-4bd5-97c3-ae30b20a20f4?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * fix: upgrade express-openapi-validator from 5.3.6 to 5.3.7 (#1008) Snyk has created this PR to upgrade express-openapi-validator from 5.3.6 to 5.3.7. See this package in npm: express-openapi-validator See this project in Snyk: https://app.snyk.io/org/cdimascio/project/0ac9a5bd-9a7f-4c0e-bf8b-51d0bd4c4448?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * fix: upgrade @apidevtools/json-schema-ref-parser from 11.7.0 to 11.7.2 (#1006) Snyk has created this PR to upgrade @apidevtools/json-schema-ref-parser from 11.7.0 to 11.7.2. See this package in npm: @apidevtools/json-schema-ref-parser See this project in Snyk: https://app.snyk.io/org/cdimascio/project/f63fb44e-f154-45ba-b1f0-20d49ea578ce?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * adds standard example for oas-3.1 * v6.0.0.alpha.6 * update oas3.1 example * v5.4.0 - adds initial oas3.1 support * updates readme for oas3.1 --------- Signed-off-by: dependabot[bot] Co-authored-by: Sergio Ferreira Co-authored-by: carmine Co-authored-by: Luis Philipe Fidelis Co-authored-by: snyk-bot Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * v5.4.0 * v5.4.0 * Update README.md * fixes method res with path params (#1032) * fixes method res with path params * fixes method res with path params --------- Co-authored-by: carmine * v5.4.1 * re-enable keywords now properly supported (#1031) * update deps * v5.4.2 * v5.4.2 * fix test * Update README.md * Update README.md * allow mutation for express 5 validaiton (#1043) Co-authored-by: carmine * v5.4.3 * update README * caches pre-processed resolved schemas * v5.4.4 * Update README.md (#1033) * Update README.md * Update README.md * removes example and examples from all schemas, not just object types * v5.4.5 --------- Signed-off-by: dependabot[bot] Signed-off-by: StepSecurity Bot Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Sam <3194321+SamHellawell@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gabriel Zerbib Co-authored-by: Pierre Le Roux Co-authored-by: Jacob Ley <37151850+JacobLey@users.noreply.github.com> Co-authored-by: Essential Randomness Co-authored-by: finpingvin Co-authored-by: MaksSlesarenko Co-authored-by: Robert Jones Co-authored-by: Snyk bot Co-authored-by: Ulf Winkelvos Co-authored-by: ownagedj Co-authored-by: Lasse Hyldahl Jensen Co-authored-by: leonardo-speranzon <46976486+leonardo-speranzon@users.noreply.github.com> Co-authored-by: Peter <16038050+gitschwifty@users.noreply.github.com> Co-authored-by: Duncan Beevers Co-authored-by: Mike Eller Co-authored-by: Michael Eller Co-authored-by: Dustin Wheeler Co-authored-by: Kesha Shah Co-authored-by: Kesha Shah Co-authored-by: Marco Castignoli Co-authored-by: yutak23 <79501292+yutak23@users.noreply.github.com> Co-authored-by: nikkegg <64557473+nikkegg@users.noreply.github.com> Co-authored-by: nikkegg Co-authored-by: Matt Mower Co-authored-by: Matt Mower Co-authored-by: rayvincent2 Co-authored-by: Ray Vincent Co-authored-by: yidongw Co-authored-by: Alan Wang Co-authored-by: Carina Chenot Co-authored-by: Mitchell Co-authored-by: Guillermo Recalde Co-authored-by: pdhau Co-authored-by: mzbik Co-authored-by: Nicolas Walter Araya Co-authored-by: Marvin A. Ruder Co-authored-by: Matt Mower <135273348+mdmower-csnw@users.noreply.github.com> Co-authored-by: Sérgio Ferreira Co-authored-by: Joan Gallego Girona Co-authored-by: g-radam <4859802+g-radam@users.noreply.github.com> Co-authored-by: g-radam <859802+g-radam@users.noreply.github.com> Co-authored-by: dusanmi Co-authored-by: Dušan Miška Co-authored-by: Luke Bellamy Co-authored-by: StepSecurity Bot Co-authored-by: Chirag Chauhan <49244615+cvchauhan@users.noreply.github.com> Co-authored-by: Frank Keefer <83428590+frankkeefer@users.noreply.github.com> Co-authored-by: fkeefer Co-authored-by: Dorong <126848879+SeokHoChoi@users.noreply.github.com> Co-authored-by: Alois Klink Co-authored-by: carmine Co-authored-by: Luis Philipe Fidelis Co-authored-by: Ulf Winkelvos From 4fb992ef0c899e98b5434808b0340803952cda4a Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sun, 2 Mar 2025 17:17:05 -0500 Subject: [PATCH 15/44] enhances example(s) removal for api requests --- src/middlewares/parsers/schema.preprocessor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middlewares/parsers/schema.preprocessor.ts b/src/middlewares/parsers/schema.preprocessor.ts index 1cd106e3..36b0e315 100644 --- a/src/middlewares/parsers/schema.preprocessor.ts +++ b/src/middlewares/parsers/schema.preprocessor.ts @@ -490,7 +490,7 @@ export class SchemaPreprocessor { delete object?.examples; } -private handleReadonly( + private handleReadonly( parent: OpenAPIV3.SchemaObject, schema: OpenAPIV3.SchemaObject, opts, From 778e99e2a1f1f23b29654cf401c0b399c6c5b400 Mon Sep 17 00:00:00 2001 From: Carmine DiMascio Date: Sun, 2 Mar 2025 17:40:28 -0500 Subject: [PATCH 16/44] Cmd/fixhist (#1050) * Fixup history * enhances example(s) removal for api requests * v5.4.6 From a8c825353f267f6a9750a5d7ff9891f2359e1389 Mon Sep 17 00:00:00 2001 From: Carmine DiMascio Date: Sat, 1 Mar 2025 21:55:34 -0500 Subject: [PATCH 17/44] Fixup history From 9ba09a3b71d92e2356d127150731b8f15be5d436 Mon Sep 17 00:00:00 2001 From: Carmine DiMascio Date: Tue, 3 Dec 2019 18:21:32 -0500 Subject: [PATCH 18/44] Update README.md From 93604cc74bca66e82e34a406a7072f6b86ab0eb4 Mon Sep 17 00:00:00 2001 From: Carmine DiMascio Date: Mon, 9 Dec 2019 00:13:22 -0500 Subject: [PATCH 19/44] Update README.md From d44ea90842e79428d34e43f9ad9649d07ca5faef Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sun, 8 Nov 2020 20:42:26 -0500 Subject: [PATCH 20/44] docs: add LEI as a contributor (#453) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> From 4accc8682d5e77dc17f2156bde06b5187186b97f Mon Sep 17 00:00:00 2001 From: cdimascio Date: Fri, 27 Dec 2024 20:08:16 -0500 Subject: [PATCH 21/44] handle req.query mutations for express 5 --- package-lock.json | 328 +++++++++---------- src/middlewares/openapi.request.validator.ts | 1 - 2 files changed, 157 insertions(+), 172 deletions(-) diff --git a/package-lock.json b/package-lock.json index eed10777..7b84f59b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -219,15 +219,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -237,12 +228,6 @@ "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, "node_modules/@babel/helper-module-imports": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", @@ -688,9 +673,9 @@ } }, "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==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, "engines": { "node": ">=12" @@ -1018,7 +1003,6 @@ "version": "1.4.12", "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.12.tgz", "integrity": "sha512-pQ2hoqvXiJt2FP9WQVLPRO+AmiIm/ZYkavPlIQnx282u4ZrVdztx0pkh3jjpQt0Kz+YI0YhSG264y08UJKoUQg==", - "license": "MIT", "dependencies": { "@types/express": "*" } @@ -1181,7 +1165,6 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -1227,7 +1210,6 @@ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -1557,21 +1539,6 @@ "node": ">= 0.8" } }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "dev": true, - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/body-parser/node_modules/type-is": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", @@ -1597,12 +1564,12 @@ } }, "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "dependencies": { - "fill-range": "^7.1.1" + "fill-range": "^7.0.1" }, "engines": { "node": ">=8" @@ -1914,7 +1881,6 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -1994,6 +1960,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -2098,9 +2065,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "engines": { "node": ">= 0.6" @@ -2119,15 +2086,6 @@ "node": ">= 0.8.0" } }, - "node_modules/cookie-parser/node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -2371,7 +2329,6 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -2595,6 +2552,15 @@ "node": ">= 18" } }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/express/node_modules/cookie-signature": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", @@ -2628,21 +2594,21 @@ "dev": true }, "node_modules/express/node_modules/mime-db": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", - "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/express/node_modules/mime-types": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.0.tgz", - "integrity": "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", "dev": true, "dependencies": { - "mime-db": "^1.53.0" + "mime-db": "^1.54.0" }, "engines": { "node": ">= 0.6" @@ -2660,6 +2626,21 @@ "node": ">= 0.8" } }, + "node_modules/express/node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2753,10 +2734,19 @@ "dev": true }, "node_modules/fast-uri": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", - "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", - "license": "MIT" + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] }, "node_modules/figures": { "version": "3.2.0", @@ -2774,9 +2764,9 @@ } }, "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -2808,10 +2798,24 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, "engines": { - "node": ">= 0.8" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, "node_modules/finalhandler/node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -3007,9 +3011,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "hasInstallScript": true, "optional": true, @@ -3048,9 +3052,9 @@ } }, "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true, "engines": { "node": "*" @@ -3115,6 +3119,7 @@ "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -3485,6 +3490,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "dependencies": { "once": "^1.3.0", @@ -3810,6 +3816,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -3916,18 +3923,18 @@ } }, "node_modules/jackspeak": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz", - "integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": "20 || >=22" - }, "funding": { "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/js-tokens": { @@ -4070,7 +4077,7 @@ "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" }, "node_modules/lodash.flattendeep": { "version": "4.4.0", @@ -4081,7 +4088,8 @@ "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead." }, "node_modules/lodash.map": { "version": "4.6.0", @@ -4197,21 +4205,19 @@ "version": "2.3.4", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "deprecated": "Please upgrade to 2.3.7 which fixes GHSA-4q6p-r6v2-jvc5", "dev": true, "dependencies": { "get-func-name": "^2.0.0" } }, "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "yallist": "^3.0.2" } }, "node_modules/make-dir": { @@ -4230,9 +4236,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -4282,19 +4288,19 @@ "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.3", + "braces": "^3.0.2", "picomatch": "^2.3.1" }, "engines": { @@ -4313,6 +4319,18 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -4366,7 +4384,6 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } @@ -4387,7 +4404,6 @@ "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz", "integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==", "dev": true, - "license": "MIT", "dependencies": { "ansi-colors": "^4.1.3", "browser-stdout": "^1.3.1", @@ -4429,7 +4445,6 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -4439,7 +4454,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -4465,13 +4479,12 @@ } }, "node_modules/mocha/node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dev": true, - "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { @@ -4486,7 +4499,6 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, - "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -4507,7 +4519,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -4527,22 +4538,6 @@ "node": ">=8" } }, - "node_modules/mocha/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/mocha/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -4560,7 +4555,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -4579,7 +4573,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "license": "ISC", "engines": { "node": ">=14" }, @@ -4879,6 +4872,7 @@ "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -4938,6 +4932,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -5258,8 +5253,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" + "dev": true }, "node_modules/parent-module": { "version": "1.0.1", @@ -5343,7 +5337,6 @@ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, - "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -5359,14 +5352,12 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/path-to-regexp": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", - "license": "MIT", "engines": { "node": ">=16" } @@ -5545,12 +5536,12 @@ } }, "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", "dev": true, "dependencies": { - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" @@ -5564,7 +5555,6 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } @@ -5664,9 +5654,9 @@ } }, "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true, "engines": { "node": ">=0.6" @@ -5810,6 +5800,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/jackspeak": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz", + "integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rimraf/node_modules/lru-cache": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", @@ -5910,13 +5915,10 @@ "dev": true }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -5996,7 +5998,6 @@ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } @@ -6179,6 +6180,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -6373,18 +6375,6 @@ "node": ">= 6" } }, - "node_modules/superagent/node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/superagent/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -6793,9 +6783,9 @@ "dev": true }, "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true, "engines": { "node": ">=0.10.0" @@ -6805,8 +6795,7 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", - "dev": true, - "license": "Apache-2.0" + "dev": true }, "node_modules/wrap-ansi": { "version": "7.0.0", @@ -6940,15 +6929,14 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "node_modules/yaml": { @@ -6966,7 +6954,6 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -6985,7 +6972,6 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, - "license": "ISC", "engines": { "node": ">=12" } diff --git a/src/middlewares/openapi.request.validator.ts b/src/middlewares/openapi.request.validator.ts index ceaafa14..d5579e81 100644 --- a/src/middlewares/openapi.request.validator.ts +++ b/src/middlewares/openapi.request.validator.ts @@ -139,7 +139,6 @@ export class RequestValidator { } req.params = openapi.pathParams ?? req.params; } - // HACK for express 5, temporarily make req.query mutable const reqQueryDescriptor = Object.getOwnPropertyDescriptor(req, 'query'); Object.defineProperty(req, 'query', { From 2c0259c5a0c98f544a50f13c750188a5c4dd07ac Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sat, 5 Apr 2025 21:29:13 -0400 Subject: [PATCH 22/44] upgrade to express 5.1.0 --- package-lock.json | 263 ++++++++++++++++++++-------------------------- package.json | 2 +- 2 files changed, 113 insertions(+), 152 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7b84f59b..5625d14e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,7 @@ "commitizen": "^4.3.1", "cookie-parser": "^1.4.7", "coveralls": "^3.1.1", - "express": "^5.0.1", + "express": "^5.1.0", "mocha": "^11.1.0", "morgan": "^1.10.0", "nodemon": "^3.1.9", @@ -1313,12 +1313,6 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/array-flatten": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-3.0.0.tgz", - "integrity": "sha512-zPMVc3ZYlGLNk4mpK1NzP2wg0ml9t7fUgDsayR5Y5rSzxQilzR9FGu/EH2jQOcKSAeAfWeylyW8juy3OkWRvNA==", - "dev": true - }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -2286,16 +2280,6 @@ "node": ">= 0.8" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -2510,55 +2494,45 @@ } }, "node_modules/express": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/express/-/express-5.0.1.tgz", - "integrity": "sha512-ORF7g6qGnD+YtUG9yx4DFoqCShNMmUKiXuT5oWMHiOvt/4WFbHC6yCwQMTSBMno7AqntNCAzzcnnjowRkTL9eQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", + "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", "dev": true, "dependencies": { "accepts": "^2.0.0", - "body-parser": "^2.0.1", + "body-parser": "^2.2.0", "content-disposition": "^1.0.0", - "content-type": "~1.0.4", - "cookie": "0.7.1", + "content-type": "^1.0.5", + "cookie": "^0.7.1", "cookie-signature": "^1.2.1", - "debug": "4.3.6", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "^2.0.0", - "fresh": "2.0.0", - "http-errors": "2.0.0", + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", - "methods": "~1.1.2", "mime-types": "^3.0.0", - "on-finished": "2.4.1", - "once": "1.4.0", - "parseurl": "~1.3.3", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "router": "^2.0.0", - "safe-buffer": "5.2.1", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", "send": "^1.1.0", - "serve-static": "^2.1.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "^2.0.0", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" }, "engines": { "node": ">= 18" - } - }, - "node_modules/express/node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", - "dev": true, - "engines": { - "node": ">= 0.6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/cookie-signature": { @@ -2571,12 +2545,12 @@ } }, "node_modules/express/node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -2587,12 +2561,6 @@ } } }, - "node_modules/express/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/express/node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", @@ -2614,6 +2582,12 @@ "node": ">= 0.6" } }, + "node_modules/express/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, "node_modules/express/node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -2626,45 +2600,10 @@ "node": ">= 0.8" } }, - "node_modules/express/node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/express/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/express/node_modules/type-is": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.0.tgz", - "integrity": "sha512-gd0sGezQYCbWSbkZr75mln4YBidWUN60+devscpLF5mtRDUpiaTvKpBNrdaCvel1NdR2k6vclXybU5fBd2i+nw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "dev": true, "dependencies": { "content-type": "^1.0.5", @@ -2776,27 +2715,26 @@ } }, "node_modules/finalhandler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.0.0.tgz", - "integrity": "sha512-MX6Zo2adDViYh+GcxxB1dpO43eypOGUOL12rLCOTMQv/DfIbpSJUy4oQIIZhVZkH9e+bZWKMon0XHFEju16tkQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", + "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", "dev": true, "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" }, "engines": { "node": ">= 0.8" } }, - "node_modules/finalhandler/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "node_modules/finalhandler/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "dependencies": { "ms": "^2.1.3" @@ -5868,23 +5806,44 @@ } }, "node_modules/router": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.0.0.tgz", - "integrity": "sha512-dIM5zVoG8xhC6rnSN8uoAgFARwTE7BQs8YwHEvK0VCmfxQXMaOuA1uiR1IPwsW7JyK5iTt7Od/TC9StasS2NPQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", "dev": true, "dependencies": { - "array-flatten": "3.0.0", - "is-promise": "4.0.0", - "methods": "~1.1.2", - "parseurl": "~1.3.3", - "path-to-regexp": "^8.0.0", - "setprototypeof": "1.2.0", - "utils-merge": "1.0.1" + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 18" } }, + "node_modules/router/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/router/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -5927,19 +5886,18 @@ } }, "node_modules/send": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.1.0.tgz", - "integrity": "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", "dev": true, "dependencies": { "debug": "^4.3.5", - "destroy": "^1.2.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", - "fresh": "^0.5.2", + "fresh": "^2.0.0", "http-errors": "^2.0.0", - "mime-types": "^2.1.35", + "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", @@ -5966,11 +5924,23 @@ } } }, - "node_modules/send/node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "node_modules/send/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/send/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", "dev": true, + "dependencies": { + "mime-db": "^1.54.0" + }, "engines": { "node": ">= 0.6" } @@ -6003,15 +5973,15 @@ } }, "node_modules/serve-static": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.1.0.tgz", - "integrity": "sha512-A3We5UfEjG8Z7VkDv6uItWw6HY2bBSBJT1KtVESn6EOoOr2jAxNhxWCLY3jDE2WcuHXByWju74ck3ZgLwL8xmA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", "dev": true, "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", - "send": "^1.0.0" + "send": "^1.2.0" }, "engines": { "node": ">= 18" @@ -6698,15 +6668,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", diff --git a/package.json b/package.json index 901a1eb6..2ea77aa1 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "commitizen": "^4.3.1", "cookie-parser": "^1.4.7", "coveralls": "^3.1.1", - "express": "^5.0.1", + "express": "^5.1.0", "mocha": "^11.1.0", "morgan": "^1.10.0", "nodemon": "^3.1.9", From 27290a7d60a885532e39619461a7ca8139be8aeb Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sat, 5 Apr 2025 21:39:25 -0400 Subject: [PATCH 23/44] fixes test 1022.spec.ts --- test/1022.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/1022.spec.ts b/test/1022.spec.ts index 863b87e0..a576d40e 100644 --- a/test/1022.spec.ts +++ b/test/1022.spec.ts @@ -90,7 +90,7 @@ describe(packageJson.name, () => { }, }, - '/some/{wildcard}*': { + '/some/*wildcard': { parameters: [ { name: 'wildcard', @@ -129,8 +129,8 @@ describe(packageJson.name, () => { .post(`/api/test/:id\\:clone`, (req, res) => { res.status(200).json({ ...req.body, id: 'id-test' }); }) - .get('/api/some/:wildcard(*wildcardSuffix)', (req, res) => { - const wildcard = req.params.wildcard; + .get('/api/some/*wildcard', (req, res) => { + const wildcard = (req.params as { wildcard: string }).wildcard; console.log(`Wildcard: ${wildcard}`); res.status(200).send(`Matched wildcard: ${wildcard}`); }), From 2842be719e9c07a702a2cae044dad47b2173ac14 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sun, 6 Apr 2025 17:07:53 -0400 Subject: [PATCH 24/44] fix types --- test/699.spec.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/699.spec.ts b/test/699.spec.ts index 873b06a2..78b98b18 100644 --- a/test/699.spec.ts +++ b/test/699.spec.ts @@ -4,6 +4,7 @@ import * as request from 'supertest'; import { createApp } from './common/app'; import { date, dateTime } from '../src/framework/base.serdes'; +import { AppWithServer } from './common/app.common'; const apiSpecPath = path.join('test', 'resources', '699.yaml'); @@ -27,7 +28,7 @@ class BadDate extends Date { } describe('699', () => { - let app = null; + let app: AppWithServer; before(async () => { // set up express app @@ -156,7 +157,7 @@ describe('699', () => { describe('699 serialize response components only', () => { - let app = null; + let app: AppWithServer; before(async () => { // set up express app @@ -174,7 +175,7 @@ describe('699 serialize response components only', () => { dateTime.serializer, { format: "mongo-objectid", - serialize: (o) => o.toString(), + serialize: (o: any) => o.toString(), }, ], unknownFormats: ['mongo-objectid', 'string-list'], From 0050de2ddd6e17b8e541136811f11185f7d687c9 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sun, 13 Apr 2025 19:51:27 -0400 Subject: [PATCH 25/44] implements handling for bracket notation query strings, fixes related tests --- src/middlewares/openapi.request.validator.ts | 49 ++++-- test/coercion.spec.ts | 4 +- test/query.str.to.json.spec.ts | 159 +++++++++++++++++++ 3 files changed, 202 insertions(+), 10 deletions(-) create mode 100644 test/query.str.to.json.spec.ts diff --git a/src/middlewares/openapi.request.validator.ts b/src/middlewares/openapi.request.validator.ts index d5579e81..cb5f3dfb 100644 --- a/src/middlewares/openapi.request.validator.ts +++ b/src/middlewares/openapi.request.validator.ts @@ -1,4 +1,5 @@ import Ajv, { ValidateFunction } from 'ajv'; +import { parse } from 'qs'; import { NextFunction, RequestHandler, Response } from 'express'; import { createRequestAjv } from '../framework/ajv'; import { @@ -142,9 +143,11 @@ export class RequestValidator { // HACK for express 5, temporarily make req.query mutable const reqQueryDescriptor = Object.getOwnPropertyDescriptor(req, 'query'); Object.defineProperty(req, 'query', { - writable: true, - value: req.query, + writable: true, + value: req.query, }); + // TODO should be in RequestParameterMutator? + req.query = this.normalizeQueryFields(req.query); const schemaProperties = validator.allSchemaProperties; const mutator = new RequestParameterMutator( this.ajv, @@ -163,6 +166,13 @@ export class RequestValidator { ); } + const schemaBody = validator?.schemaBody; + if (contentType.mediaType === 'multipart/form-data') { + // make req.body {} + req.body ??= {}; + this.multipartNested(req, schemaBody); + } + // HACK for express 5, Restore the original descriptor if (reqQueryDescriptor) { Object.defineProperty(req, 'query', reqQueryDescriptor); @@ -182,11 +192,6 @@ export class RequestValidator { cookies, body: req.body, }; - const schemaBody = validator?.schemaBody; - - if (contentType.mediaType === 'multipart/form-data') { - this.multipartNested(req, schemaBody); - } const discriminator = schemaBody?.properties?.body?._discriminator; const discriminatorValidator = this.discriminatorValidator( @@ -285,6 +290,28 @@ export class RequestValidator { } } } + + /** + * Mutates and normalizes the req.query object by parsing braket notation query string key values pairs + * into its corresponding key= and update req.query with the parsed value + * for instance, req.query that equals { filter[name]: test} is translated into { filter: { name: 'test' }, where + * the query string field is set as filter and its value is the full javascript object (translated from bracket notation) + * @param keys + * @returns + */ + private normalizeQueryFields(query: { [key: string]: any }): { + [key: string]: any; + } { + Object.keys(query).forEach((key) => { + const bracketNotation = key.includes('['); + if (bracketNotation) { + const normalizedKey = key.split('[')[0]; + query[normalizedKey] = parse(`${key}=${query[key]}`)[normalizedKey]; + delete query[key]; + } + }); + return query; + } } class Validator { @@ -353,8 +380,12 @@ class Security { apiDocs: OpenAPIV3.DocumentV3 | OpenAPIV3.DocumentV3_1, schema: OperationObject, ): string[] { - const hasPathSecurity = schema.security ? schema.security.length > 0 : false; - const hasRootSecurity = apiDocs.security ? apiDocs.security.length > 0 : false; + const hasPathSecurity = schema.security + ? schema.security.length > 0 + : false; + const hasRootSecurity = apiDocs.security + ? apiDocs.security.length > 0 + : false; let usedSecuritySchema: SecurityRequirementObject[] = []; if (hasPathSecurity) { diff --git a/test/coercion.spec.ts b/test/coercion.spec.ts index f5f85e24..3977641e 100644 --- a/test/coercion.spec.ts +++ b/test/coercion.spec.ts @@ -123,7 +123,9 @@ describe(packageJson.name, () => { expect(r.body.message).to.contain('request/body/is_cat must be string'); })); - it('should return 200 when names is a string and coerce names to be an array', async () => + // TODO - can get this behavior by configuring qs -- https://github.com/expressjs/express/issues/3039 + // do we actually want to? the qs behavior is more akin to deepObject + it.skip('should return 200 when names is a string and coerce names to be an array', async () => request(arrayCoercedApp) .get(`${arrayCoercedApp.basePath}/coercion/pets_as_array_parameter`) .query({ diff --git a/test/query.str.to.json.spec.ts b/test/query.str.to.json.spec.ts new file mode 100644 index 00000000..2cc4c32c --- /dev/null +++ b/test/query.str.to.json.spec.ts @@ -0,0 +1,159 @@ +const { expect } = require('chai'); + +// The function to test +function parseQueryString(queryString) { + // Remove leading ? if present + if (queryString.startsWith('?')) { + queryString = queryString.substring(1); + } + + // Return empty object for empty strings + if (!queryString) { + return {}; + } + + const params = queryString.split('&'); + const result = {}; + + params.forEach(param => { + // Skip empty parameters + if (!param) return; + + const [key, value] = param.split('=').map(part => decodeURIComponent(part || '')); + + // Match keys with square brackets pattern: something[property] + const matches = key.match(/^([^\[]+)\[([^\]]+)\]$/); + + if (matches) { + const mainKey = matches[1]; + const subKey = matches[2]; + + // Create nested object if it doesn't exist + if (!result[mainKey]) { + result[mainKey] = {}; + } + + // Handle array values if needed + if (value && value.includes(',')) { + result[mainKey][subKey] = value.split(','); + } else { + result[mainKey][subKey] = value; + } + } else { + // Handle regular key-value pairs + result[key] = value; + } + }); + + return result; +} + +describe.only('Query String Parser', () => { + describe('Basic functionality', () => { + it('should handle empty strings', () => { + expect(parseQueryString('')).to.deep.equal({}); + expect(parseQueryString('?')).to.deep.equal({}); + }); + + it('should parse simple key-value pairs', () => { + expect(parseQueryString('name=value')).to.deep.equal({ name: 'value' }); + expect(parseQueryString('a=1&b=2')).to.deep.equal({ a: '1', b: '2' }); + }); + + it('should handle question mark prefix', () => { + expect(parseQueryString('?name=value')).to.deep.equal({ name: 'value' }); + }); + }); + + describe('Bracket notation', () => { + it('should parse single bracket notation', () => { + expect(parseQueryString('filter[name]=test')).to.deep.equal({ + filter: { name: 'test' } + }); + }); + + it('should parse multiple bracket notations for the same key', () => { + expect(parseQueryString('filter[name]=test&filter[age]=25')).to.deep.equal({ + filter: { name: 'test', age: '25' } + }); + }); + + it('should handle multiple main keys with bracket notation', () => { + expect(parseQueryString('filter[name]=test&sort[field]=created_at')).to.deep.equal({ + filter: { name: 'test' }, + sort: { field: 'created_at' } + }); + }); + }); + + describe('Array values', () => { + it('should parse comma-separated values as arrays', () => { + expect(parseQueryString('filter[colors]=red,green,blue')).to.deep.equal({ + filter: { colors: ['red', 'green', 'blue'] } + }); + }); + + it('should handle mixed array and scalar values', () => { + expect(parseQueryString('filter[colors]=red,green,blue&filter[name]=product')).to.deep.equal({ + filter: { + colors: ['red', 'green', 'blue'], + name: 'product' + } + }); + }); + }); + + describe('Edge cases', () => { + it('should handle URL encoded characters', () => { + expect(parseQueryString('filter[name]=test%20product&filter[category]=books%20%26%20media')).to.deep.equal({ + filter: { + name: 'test product', + category: 'books & media' + } + }); + }); + + it('should handle empty values', () => { + expect(parseQueryString('filter[name]=&filter[category]=')).to.deep.equal({ + filter: { + name: '', + category: '' + } + }); + }); + + it('should handle parameters without values', () => { + expect(parseQueryString('filter[name]&filter[active]')).to.deep.equal({ + filter: { + name: '', + active: '' + } + }); + }); + + it('should handle malformed input', () => { + expect(parseQueryString('&&filter[name]=test&&')).to.deep.equal({ + filter: { name: 'test' } + }); + }); + }); + + describe('Complex examples', () => { + it('should parse a complex query string', () => { + const complexQuery = '?filter[name]=Product%20Name&filter[categories]=electronics,gadgets&sort[field]=price&sort[direction]=desc&page=2&limit=20'; + + expect(parseQueryString(complexQuery)).to.deep.equal({ + filter: { + name: 'Product Name', + categories: ['electronics', 'gadgets'] + }, + sort: { + field: 'price', + direction: 'desc' + }, + page: '2', + limit: '20' + }); + }); + }); +}); \ No newline at end of file From 35a93770d483a325f6b1e95ef335a05dac43c4ff Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sun, 13 Apr 2025 19:55:43 -0400 Subject: [PATCH 26/44] update temp test suit --- test/query.str.to.json.spec.ts | 432 +++++++++++++++++++++++++-------- 1 file changed, 337 insertions(+), 95 deletions(-) diff --git a/test/query.str.to.json.spec.ts b/test/query.str.to.json.spec.ts index 2cc4c32c..101e0dd0 100644 --- a/test/query.str.to.json.spec.ts +++ b/test/query.str.to.json.spec.ts @@ -1,159 +1,401 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; +import { describe, it } from 'mocha'; -// The function to test -function parseQueryString(queryString) { - // Remove leading ? if present + +// TODO THIS TEST SUITE IS LIKELY TO BE UNNEDESSARY. DELETE + +/** + * Generic JSON value type that can represent any valid JSON structure + */ +type JsonValue = string | number | boolean | null | JsonArray | JsonObject; +type JsonObject = { [key: string]: JsonValue }; +type JsonArray = JsonValue[]; +/** + * Enhanced parseQueryString function that handles: + * - Arbitrary depth objects + * - Arrays through comma-separated values + * - Arrays through indexed notation + * - Type conversion for numeric values + * - URL encoding + */ +export function parseQueryString(queryString: string): JsonObject { if (queryString.startsWith('?')) { queryString = queryString.substring(1); } - - // Return empty object for empty strings - if (!queryString) { - return {}; - } - + + if (!queryString) return {}; + const params = queryString.split('&'); - const result = {}; - - params.forEach(param => { - // Skip empty parameters + const result: JsonObject = {}; + + params.forEach((param) => { if (!param) return; - - const [key, value] = param.split('=').map(part => decodeURIComponent(part || '')); - - // Match keys with square brackets pattern: something[property] - const matches = key.match(/^([^\[]+)\[([^\]]+)\]$/); - - if (matches) { - const mainKey = matches[1]; - const subKey = matches[2]; - - // Create nested object if it doesn't exist - if (!result[mainKey]) { - result[mainKey] = {}; - } - - // Handle array values if needed - if (value && value.includes(',')) { - result[mainKey][subKey] = value.split(','); + + const [keyStr, value] = param + .split('=') + .map((part) => decodeURIComponent(part || '')); + + // Use regex to extract all keys + const keys: string[] = []; + const mainKeyMatch = keyStr.match(/^([^\[]+)/); + const mainKey = mainKeyMatch?.[1] || ''; + keys.push(mainKey); + + // Extract all bracket contents + const bracketMatches = keyStr.matchAll(/\[([^\]]*)\]/g); + for (const match of bracketMatches) { + keys.push(match[1]); + } + + // Build the nested structure + let current: JsonObject = result; + for (let i = 0; i < keys.length; i++) { + const isLast = i === keys.length - 1; + const key = keys[i]; + + // Check if we need to create an array (numeric key) + const nextIsNumericKey = i < keys.length - 1 && /^\d+$/.test(keys[i + 1]); + + if (isLast) { + // For the final key, set the actual value + if (value && value.includes(',') && !/^\d+$/.test(key)) { + // Handle comma-separated values as arrays + // Try to convert numeric values in arrays + current[key] = value + .split(',') + .map((v) => (!isNaN(Number(v)) && v !== '' ? Number(v) : v)); + } else { + // Try to convert numeric values + current[key] = + !isNaN(Number(value)) && value !== '' ? Number(value) : value; + } } else { - result[mainKey][subKey] = value; + // For intermediate keys + if (!current[key]) { + // Create appropriate container based on next key + current[key] = nextIsNumericKey ? [] : {}; + } + // TypeScript needs this assertion since we know at this point that current[key] is an object + current = current[key] as JsonObject; } - } else { - // Handle regular key-value pairs - result[key] = value; } }); - - return result; + + // Post-processing to convert objects with sequential numeric keys to arrays + function convertNumericKeysToArrays(obj: JsonValue): JsonValue { + if (!obj || typeof obj !== 'object') return obj; + + // Handle arrays + if (Array.isArray(obj)) { + return obj.map((item) => convertNumericKeysToArrays(item)); + } + + // Handle objects + Object.keys(obj).forEach((key) => { + // Recursively process nested objects + if (obj[key] && typeof obj[key] === 'object') { + obj[key] = convertNumericKeysToArrays(obj[key]); + } + }); + + // Check if this object should be an array + const keys = Object.keys(obj); + if ( + keys.length > 0 && + keys.every((k) => /^\d+$/.test(k)) && + (keys.length === 1 || keys.every((k) => parseInt(k) < keys.length)) + ) { + // Convert to array if all keys are sequential integers + const array: JsonValue[] = []; + keys + .sort((a, b) => parseInt(a) - parseInt(b)) + .forEach((k) => (array[parseInt(k)] = obj[k])); + return array; + } + + return obj; + } + + return convertNumericKeysToArrays(result) as JsonObject; } -describe.only('Query String Parser', () => { +describe.skip('Enhanced Query String Parser', () => { describe('Basic functionality', () => { it('should handle empty strings', () => { expect(parseQueryString('')).to.deep.equal({}); expect(parseQueryString('?')).to.deep.equal({}); }); - + it('should parse simple key-value pairs', () => { expect(parseQueryString('name=value')).to.deep.equal({ name: 'value' }); - expect(parseQueryString('a=1&b=2')).to.deep.equal({ a: '1', b: '2' }); + expect(parseQueryString('a=1&b=2')).to.deep.equal({ a: 1, b: 2 }); }); - + it('should handle question mark prefix', () => { expect(parseQueryString('?name=value')).to.deep.equal({ name: 'value' }); }); }); - + describe('Bracket notation', () => { it('should parse single bracket notation', () => { - expect(parseQueryString('filter[name]=test')).to.deep.equal({ - filter: { name: 'test' } + expect(parseQueryString('filter[name]=test')).to.deep.equal({ + filter: { name: 'test' }, }); }); - + it('should parse multiple bracket notations for the same key', () => { - expect(parseQueryString('filter[name]=test&filter[age]=25')).to.deep.equal({ - filter: { name: 'test', age: '25' } + expect( + parseQueryString('filter[name]=test&filter[age]=25'), + ).to.deep.equal({ + filter: { name: 'test', age: 25 }, }); }); - + it('should handle multiple main keys with bracket notation', () => { - expect(parseQueryString('filter[name]=test&sort[field]=created_at')).to.deep.equal({ + expect( + parseQueryString('filter[name]=test&sort[field]=created_at'), + ).to.deep.equal({ filter: { name: 'test' }, - sort: { field: 'created_at' } + sort: { field: 'created_at' }, }); }); }); - + describe('Array values', () => { it('should parse comma-separated values as arrays', () => { - expect(parseQueryString('filter[colors]=red,green,blue')).to.deep.equal({ - filter: { colors: ['red', 'green', 'blue'] } + expect(parseQueryString('filter[colors]=red,green,blue')).to.deep.equal({ + filter: { colors: ['red', 'green', 'blue'] }, }); }); - + + it('should handle comma-separated numeric values', () => { + expect(parseQueryString('list=12,13,14')).to.deep.equal({ + list: [12, 13, 14], + }); + }); + + it('should handle arrays with indexed notation', () => { + expect( + parseQueryString('list[0]=12&list[1]=13&list[2]=14'), + ).to.deep.equal({ + list: [12, 13, 14], + }); + }); + it('should handle mixed array and scalar values', () => { - expect(parseQueryString('filter[colors]=red,green,blue&filter[name]=product')).to.deep.equal({ - filter: { + expect( + parseQueryString('filter[colors]=red,green,blue&filter[name]=product'), + ).to.deep.equal({ + filter: { colors: ['red', 'green', 'blue'], - name: 'product' - } + name: 'product', + }, + }); + }); + }); + + describe('Nested structures', () => { + it('should handle arbitrary depth objects', () => { + expect( + parseQueryString( + 'user[address][city]=New York&user[address][zip]=10001', + ), + ).to.deep.equal({ + user: { + address: { + city: 'New York', + zip: 10001, + }, + }, + }); + }); + + it('should handle deeply nested arrays', () => { + expect( + parseQueryString( + 'data[users][0][name]=John&data[users][0][age]=30&data[users][1][name]=Jane&data[users][1][age]=25', + ), + ).to.deep.equal({ + data: { + users: [ + { name: 'John', age: 30 }, + { name: 'Jane', age: 25 }, + ], + }, + }); + }); + + it('should handle arrays inside objects inside arrays', () => { + expect( + parseQueryString( + 'data[0][tags]=javascript,nodejs&data[1][tags]=python,django', + ), + ).to.deep.equal({ + data: [ + { tags: ['javascript', 'nodejs'] }, + { tags: ['python', 'django'] }, + ], }); }); }); - + + describe('Type conversion', () => { + it('should convert numeric values to numbers', () => { + expect(parseQueryString('age=30&price=19.99')).to.deep.equal({ + age: 30, + price: 19.99, + }); + }); + + it('should convert numeric values in arrays', () => { + expect(parseQueryString('scores=10,20,30.5')).to.deep.equal({ + scores: [10, 20, 30.5], + }); + }); + + it('should not convert numeric strings that are not actually numbers', () => { + expect( + parseQueryString('zipcode=00123&phone=123-456-7890'), + ).to.deep.equal({ + zipcode: 123, // This is numerically equivalent to 123 + phone: '123-456-7890', // This is not a valid number + }); + }); + + it('should handle empty values correctly', () => { + expect(parseQueryString('name=&age=')).to.deep.equal({ + name: '', + age: '', + }); + }); + }); + describe('Edge cases', () => { it('should handle URL encoded characters', () => { - expect(parseQueryString('filter[name]=test%20product&filter[category]=books%20%26%20media')).to.deep.equal({ - filter: { + expect( + parseQueryString( + 'filter[name]=test%20product&filter[category]=books%20%26%20media', + ), + ).to.deep.equal({ + filter: { name: 'test product', - category: 'books & media' - } - }); - }); - - it('should handle empty values', () => { - expect(parseQueryString('filter[name]=&filter[category]=')).to.deep.equal({ - filter: { - name: '', - category: '' - } + category: 'books & media', + }, }); }); - + it('should handle parameters without values', () => { - expect(parseQueryString('filter[name]&filter[active]')).to.deep.equal({ - filter: { - name: '', - active: '' - } + expect(parseQueryString('filter[name]&filter[active]')).to.deep.equal({ + filter: { + name: undefined, + active: undefined, + }, }); }); - + it('should handle malformed input', () => { - expect(parseQueryString('&&filter[name]=test&&')).to.deep.equal({ - filter: { name: 'test' } + expect(parseQueryString('&&filter[name]=test&&')).to.deep.equal({ + filter: { name: 'test' }, + }); + }); + + it('should handle arrays with missing indices', () => { + expect(parseQueryString('list[0]=first&list[2]=third')).to.deep.equal({ + list: ['first', undefined, 'third'], + }); + }); + + it('should handle non-sequential array indices', () => { + expect(parseQueryString('list[5]=five&list[10]=ten')).to.deep.equal({ + list: [ + undefined, + undefined, + undefined, + undefined, + undefined, + 'five', + undefined, + undefined, + undefined, + undefined, + 'ten', + ], + }); + }); + + it('should handle repeated keys with different values', () => { + expect(parseQueryString('multi=1&multi=2')).to.deep.equal({ + multi: 2, // The last value wins + }); + }); + + it('should handle special characters in keys', () => { + expect(parseQueryString('special@key=value')).to.deep.equal({ + 'special@key': 'value', }); }); }); - - describe('Complex examples', () => { - it('should parse a complex query string', () => { - const complexQuery = '?filter[name]=Product%20Name&filter[categories]=electronics,gadgets&sort[field]=price&sort[direction]=desc&page=2&limit=20'; - + + describe('Combined cases', () => { + it('should handle the filter names example', () => { + expect(parseQueryString('filter[names]=jim,tim')).to.deep.equal({ + filter: { + names: ['jim', 'tim'], + }, + }); + + expect( + parseQueryString('filter[names][0]=jim&filter[names][1]=tim'), + ).to.deep.equal({ + filter: { + names: ['jim', 'tim'], + }, + }); + }); + + it('should handle mixed object and array with complex nesting', () => { + const complexQuery = + 'test=test&list[0]=12&list[1]=13&list[2]=14&obj[key1]=val1&obj[nested][key2]=val2&arr[0][name]=product1&arr[0][price]=9.99&arr[1][name]=product2&arr[1][price]=19.99'; + expect(parseQueryString(complexQuery)).to.deep.equal({ + test: 'test', + list: [12, 13, 14], + obj: { + key1: 'val1', + nested: { + key2: 'val2', + }, + }, + arr: [ + { name: 'product1', price: 9.99 }, + { name: 'product2', price: 19.99 }, + ], + }); + }); + + it('should handle a complex real-world API query', () => { + const apiQuery = + 'filter[status]=active&filter[date][gte]=2023-01-01&filter[date][lte]=2023-12-31&include=user,comments&sort=-created_at&page[number]=1&page[size]=20&fields[post]=title,content,author&fields[comment]=body,date'; + + expect(parseQueryString(apiQuery)).to.deep.equal({ filter: { - name: 'Product Name', - categories: ['electronics', 'gadgets'] + status: 'active', + date: { + gte: '2023-01-01', + lte: '2023-12-31', + }, + }, + include: ['user', 'comments'], + sort: '-created_at', + page: { + number: 1, + size: 20, }, - sort: { - field: 'price', - direction: 'desc' + fields: { + post: ['title', 'content', 'author'], + comment: ['body', 'date'], }, - page: '2', - limit: '20' }); }); }); -}); \ No newline at end of file +}); From 23b7c0591083e3af2ca77a21f290de9c446a79e0 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sun, 13 Apr 2025 19:59:29 -0400 Subject: [PATCH 27/44] v6.0.0-alpha.1 --- package-lock.json | 18 +++++++++--------- package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5625d14e..d3038108 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "express-openapi-validator", - "version": "5.4.9", + "version": "6.0.0-alpha.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "express-openapi-validator", - "version": "5.4.9", + "version": "6.0.0-alpha.1", "license": "MIT", "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.9.3", @@ -1107,21 +1107,21 @@ } }, "node_modules/accepts/node_modules/mime-db": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", - "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/accepts/node_modules/mime-types": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.0.tgz", - "integrity": "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", "dev": true, "dependencies": { - "mime-db": "^1.53.0" + "mime-db": "^1.54.0" }, "engines": { "node": ">= 0.6" diff --git a/package.json b/package.json index 2ea77aa1..e729e19e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-openapi-validator", - "version": "5.4.9", + "version": "6.0.0-alpha.1", "description": "Automatically validate API requests and responses with OpenAPI 3 and Express.", "main": "dist/index.js", "scripts": { From ad0a919443c18e7cc6304b6e48b4affd2abda209 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sun, 13 Apr 2025 20:01:59 -0400 Subject: [PATCH 28/44] v6.0.0-alpha.7 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d3038108..3596a5b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "express-openapi-validator", - "version": "6.0.0-alpha.1", + "version": "6.0.0-alpha.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "express-openapi-validator", - "version": "6.0.0-alpha.1", + "version": "6.0.0-alpha.7", "license": "MIT", "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.9.3", diff --git a/package.json b/package.json index e729e19e..a91c57fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-openapi-validator", - "version": "6.0.0-alpha.1", + "version": "6.0.0-alpha.7", "description": "Automatically validate API requests and responses with OpenAPI 3 and Express.", "main": "dist/index.js", "scripts": { From 5036628ba94d62dfb17d5833ac2f30d74b60cad2 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sun, 13 Apr 2025 20:08:24 -0400 Subject: [PATCH 29/44] update README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 6605df3d..6b52076f 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,10 @@ _Express 5 support: (7 tests fail, 436 pass). Please contribute fixes to the `ex ```shell npm install express-openapi-validator + +# for v6.0.0-alpha +npm install express-openapi-validator@alpha + ``` ## Usage From 5b9932a7e976e4e19cf2861f8647b63a1126996e Mon Sep 17 00:00:00 2001 From: cdimascio Date: Mon, 14 Apr 2025 19:45:13 -0400 Subject: [PATCH 30/44] fixes wildcard path tests --- test/wildcard.path.params.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/wildcard.path.params.spec.ts b/test/wildcard.path.params.spec.ts index 1fed54ed..2ce79cc0 100644 --- a/test/wildcard.path.params.spec.ts +++ b/test/wildcard.path.params.spec.ts @@ -21,12 +21,12 @@ describe('wildcard path params', () => { ...req.params, }); }) - .get(`${app.basePath}/d2/:path(*)`, (req, res) => { + .get(`${app.basePath}/d2/*path`, (req, res) => { res.json({ ...req.params, }); }) - .get(`${app.basePath}/d3/:path(*)`, (req, res) => { + .get(`${app.basePath}/d3/*path`, (req, res) => { res.json({ ...req.params, }); @@ -36,12 +36,12 @@ describe('wildcard path params', () => { success: true, }); }) - .get(`${app.basePath}/d4/:multi/spaced/:path(*)`, (req, res) => { + .get(`${app.basePath}/d4/:multi/spaced/*path`, (req, res) => { res.json({ ...req.params, }); }) - .get(`${app.basePath}/d5/:multi/:path(*)`, (req, res) => { + .get(`${app.basePath}/d5/:multi/*path`, (req, res) => { res.json({ ...req.params, }); From 2521a75b958c19213d72736a1884e2a455c0eee7 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Mon, 14 Apr 2025 19:47:32 -0400 Subject: [PATCH 31/44] v6.0.0-alpha.8 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3596a5b2..f78a6802 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "express-openapi-validator", - "version": "6.0.0-alpha.7", + "version": "6.0.0-alpha.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "express-openapi-validator", - "version": "6.0.0-alpha.7", + "version": "6.0.0-alpha.8", "license": "MIT", "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.9.3", diff --git a/package.json b/package.json index a91c57fe..6677296a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-openapi-validator", - "version": "6.0.0-alpha.7", + "version": "6.0.0-alpha.8", "description": "Automatically validate API requests and responses with OpenAPI 3 and Express.", "main": "dist/index.js", "scripts": { From 3dfe70db56b09643fcc59474bff10e94195d28dd Mon Sep 17 00:00:00 2001 From: cdimascio Date: Mon, 14 Apr 2025 19:53:32 -0400 Subject: [PATCH 32/44] fix operation handler test suite --- test/operation.handler.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/operation.handler.spec.ts b/test/operation.handler.spec.ts index 771013a7..2076ad9f 100644 --- a/test/operation.handler.spec.ts +++ b/test/operation.handler.spec.ts @@ -21,7 +21,7 @@ describe('operation handler', () => { .to.have.property('options') .to.deep.include({ operationHandlers: false }); - defaultNumberOfRoutes = app._router.stack.length; + defaultNumberOfRoutes = app.router.stack.length; }); it('should not install handlers when nothing provided', async () => { From 476df577c11a86d706e53ff76fcc2934cab99c57 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Mon, 14 Apr 2025 20:11:25 -0400 Subject: [PATCH 33/44] fixed serializable test handling --- .../parsers/req.parameter.mutator.ts | 37 +++++++++++++++---- test/serialized.objects.spec.ts | 1 + 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/middlewares/parsers/req.parameter.mutator.ts b/src/middlewares/parsers/req.parameter.mutator.ts index 84a3d2f4..eadcd21a 100644 --- a/src/middlewares/parsers/req.parameter.mutator.ts +++ b/src/middlewares/parsers/req.parameter.mutator.ts @@ -76,10 +76,20 @@ export class RequestParameterMutator { const i = req.originalUrl.indexOf('?'); const queryString = req.originalUrl.substr(i + 1); - if (parameter.in === 'query' && !parameter.allowReserved && !!parameter.explode) { //} && !!parameter.explode) { + if ( + parameter.in === 'query' && + !parameter.allowReserved && + !!parameter.explode + ) { + //} && !!parameter.explode) { this.validateReservedCharacters(name, rawQuery); } - if (parameter.in === 'query' && !parameter.allowReserved && !parameter.explode) { //} && !!parameter.explode) { + if ( + parameter.in === 'query' && + !parameter.allowReserved && + !parameter.explode + ) { + //} && !!parameter.explode) { this.validateReservedCharacters(name, rawQuery, true); } @@ -97,7 +107,13 @@ export class RequestParameterMutator { } else if (type === 'array' && !explode) { const delimiter = ARRAY_DELIMITER[parameter.style]; this.validateArrayDelimiter(delimiter, parameter); - this.parseJsonArrayAndMutateRequest(req, parameter.in, name, delimiter, rawQuery); + this.parseJsonArrayAndMutateRequest( + req, + parameter.in, + name, + delimiter, + rawQuery, + ); } else if (type === 'array' && explode) { this.explodeJsonArrayAndMutateRequest(req, parameter.in, name); } else if (style === 'form' && explode) { @@ -266,7 +282,7 @@ export class RequestParameterMutator { * filter=foo%20bar%20baz */ const field = REQUEST_FIELDS[$in]; - const rawValues = [] + const rawValues = []; if (['query'].includes($in)) { // perhaps split query from params rawValues.concat(rawQuery.get(name) ?? []); @@ -277,11 +293,14 @@ export class RequestParameterMutator { if (Array.isArray(req[field][name])) return; const value = req[field][name].split(delimiter); const rawValue = rawValues[i++]; - if (rawValue?.includes(delimiter)) { // TODO add && !allowReserved to improve performance. When allowReserved is true, commas are common and we do not need to do this extra work + if (rawValue?.includes(delimiter)) { + // TODO add && !allowReserved to improve performance. When allowReserved is true, commas are common and we do not need to do this extra work // Currently, rawValue is only populated for query params // if the raw value contains a delimiter, decode manually // parse the decode value and update req[field][name] - const manuallyDecodedValues = rawValue.split(delimiter).map(v => decodeURIComponent(v)); + const manuallyDecodedValues = rawValue + .split(delimiter) + .map((v) => decodeURIComponent(v)); req[field][name] = manuallyDecodedValues; } else { req[field][name] = value; @@ -289,6 +308,8 @@ export class RequestParameterMutator { } } + // TODO is this method still necessary with the new qs processing introduced in the express-5 support + // (Try removing it) private explodedJsonObjectAndMutateRequest( req: Request, $in: string, @@ -301,7 +322,9 @@ export class RequestParameterMutator { const field = REQUEST_FIELDS[$in]; if (req[field]) { // check if there is at least one of the nested properties before creating the root property - const atLeastOne = properties.some((p) => req[field].hasOwnProperty(p)); + const atLeastOne = properties.some((p) => { + return Object.prototype.hasOwnProperty.call(req[field], p); + }); if (atLeastOne) { req[field][name] = {}; properties.forEach((property) => { diff --git a/test/serialized.objects.spec.ts b/test/serialized.objects.spec.ts index ec04d9e2..2e813ec8 100644 --- a/test/serialized.objects.spec.ts +++ b/test/serialized.objects.spec.ts @@ -48,6 +48,7 @@ describe(packageJson.name, () => { }) .expect(200) .then((response) => { + console.log(response.body); expect(response.body).to.deep.equal({ settings: { onlyValidated: true, From c6d87b7b4ec8ece2f7f176948df1b2682bcf49a3 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Mon, 14 Apr 2025 20:13:37 -0400 Subject: [PATCH 34/44] v6.0.0-alpha.9 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f78a6802..5e1f73c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "express-openapi-validator", - "version": "6.0.0-alpha.8", + "version": "6.0.0-alpha.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "express-openapi-validator", - "version": "6.0.0-alpha.8", + "version": "6.0.0-alpha.9", "license": "MIT", "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.9.3", diff --git a/package.json b/package.json index 6677296a..254ee4d8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-openapi-validator", - "version": "6.0.0-alpha.8", + "version": "6.0.0-alpha.9", "description": "Automatically validate API requests and responses with OpenAPI 3 and Express.", "main": "dist/index.js", "scripts": { From 4d1bc69f7a30b57c9800874998ba29e15636364d Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sat, 19 Apr 2025 10:31:08 -0400 Subject: [PATCH 35/44] fix test for express 4 and 5 --- test/path.params.spec.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/path.params.spec.ts b/test/path.params.spec.ts index 8f521d8b..9642c305 100644 --- a/test/path.params.spec.ts +++ b/test/path.params.spec.ts @@ -19,7 +19,7 @@ describe('path params', () => { 3005, (app) => { app.get( - [`${app.basePath}/users/{:id}`, `${app.basePath}/users_alt/{:id}`], + [`${app.basePath}/users/:id`, `${app.basePath}/users_alt/:id`], (req, res) => { res.json({ id: req.params.id, @@ -31,7 +31,7 @@ describe('path params', () => { id: req.params['name'], }); }); - app.get(`${app.basePath}/multi_users/{:ids}`, (req, res) => { + app.get(`${app.basePath}/multi_users/:ids`, (req, res) => { res.json({ ids: req.params.ids, }); @@ -52,14 +52,17 @@ describe('path params', () => { app.server.close(); }); + // TODO - fails with express 4 it('should url decode path parameters (type level)', async () => request(app) .get(`${app.basePath}/users/c%20dimascio`) .expect(200) .then((r) => { + console.log(r.body) expect(r.body.id).to.equal('c dimascio'); })); + // TODO - fails with express 4 it('should url decode path parameters (path level)', async () => request(app) .get(`${app.basePath}/users_alt/c%20dimascio`) @@ -68,6 +71,7 @@ describe('path params', () => { expect(r.body.id).to.equal('c dimascio'); })); + // TODO - fails with express 4 it('should handle path parameter with style=simple', async () => request(app) .get(`${app.basePath}/multi_users/aa,bb,cc`) From 052c81b88168f2faf48b6e70f7c4beedc3be9acf Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sat, 19 Apr 2025 18:21:38 -0400 Subject: [PATCH 36/44] update test to use proper router depending on express version --- test/operation.handler.spec.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/operation.handler.spec.ts b/test/operation.handler.spec.ts index 2076ad9f..be813485 100644 --- a/test/operation.handler.spec.ts +++ b/test/operation.handler.spec.ts @@ -6,6 +6,9 @@ import * as OpenApiValidator from '../src'; import * as resolvers from '../src/resolvers'; import { createApp } from './common/app'; import { OpenApiValidatorOpts } from '../src/framework/types'; +import * as pkg from '../package.json'; + +const expressVersion = pkg.devDependencies.express; describe('operation handler', () => { let defaultNumberOfRoutes = null; @@ -21,7 +24,11 @@ describe('operation handler', () => { .to.have.property('options') .to.deep.include({ operationHandlers: false }); - defaultNumberOfRoutes = app.router.stack.length; + // TODO - need _router for express 4 + const firstDigit = expressVersion.match(/\d/)?.[0]; + defaultNumberOfRoutes = firstDigit === '4' + ? app._router.stack.length + : app.router.stack.length; }); it('should not install handlers when nothing provided', async () => { From d7db832f387a7e77cd86a06b62981b4a5967146a Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sun, 20 Apr 2025 08:44:09 -0400 Subject: [PATCH 37/44] fixes serdes test path formattting --- test/serdes.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/serdes.spec.ts b/test/serdes.spec.ts index d68b25c7..9774e8d4 100644 --- a/test/serdes.spec.ts +++ b/test/serdes.spec.ts @@ -62,7 +62,7 @@ describe('serdes', () => { }, 3005, (app) => { - app.get([`${app.basePath}/users/{:id}`], (req, res) => { + app.get([`${app.basePath}/users/:id`], (req, res) => { if (typeof req.params.id !== 'object') { throw new Error("Should be deserialized to ObjectId object"); } @@ -237,7 +237,7 @@ describe('serdes serialize response components only', () => { }, 3005, (app) => { - app.get([`${app.basePath}/users/{:id}`], (req, res) => { + app.get([`${app.basePath}/users/:id`], (req, res) => { if (typeof req.params.id !== 'string') { throw new Error("Should be not be deserialized to ObjectId object"); } From b34e80a6a2b3848b2e58d32516803dbcfb82aea5 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sun, 20 Apr 2025 08:47:20 -0400 Subject: [PATCH 38/44] fixes path syntax in 699 test --- test/699.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/699.spec.ts b/test/699.spec.ts index 78b98b18..2b46554c 100644 --- a/test/699.spec.ts +++ b/test/699.spec.ts @@ -54,7 +54,7 @@ describe('699', () => { }, 3005, (app) => { - app.get([`${app.basePath}/users/{:id}`], (req, res) => { + app.get([`${app.basePath}/users/:id`], (req, res) => { if (typeof req.params.id !== 'object') { throw new Error("Should be deserialized to ObjectId object"); } @@ -182,7 +182,7 @@ describe('699 serialize response components only', () => { }, 3005, (app) => { - app.get([`${app.basePath}/users/{:id}`], (req, res) => { + app.get([`${app.basePath}/users/:id`], (req, res) => { if (typeof req.params.id !== 'string') { throw new Error("Should be not be deserialized to ObjectId object"); } From 1ce66402e02eb5c1830d41e613ff05d2d7109280 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sun, 20 Apr 2025 08:49:25 -0400 Subject: [PATCH 39/44] fix path params test --- test/path.params.spec.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/path.params.spec.ts b/test/path.params.spec.ts index 9642c305..58db9768 100644 --- a/test/path.params.spec.ts +++ b/test/path.params.spec.ts @@ -52,17 +52,14 @@ describe('path params', () => { app.server.close(); }); - // TODO - fails with express 4 it('should url decode path parameters (type level)', async () => request(app) .get(`${app.basePath}/users/c%20dimascio`) .expect(200) .then((r) => { - console.log(r.body) expect(r.body.id).to.equal('c dimascio'); })); - // TODO - fails with express 4 it('should url decode path parameters (path level)', async () => request(app) .get(`${app.basePath}/users_alt/c%20dimascio`) @@ -71,7 +68,6 @@ describe('path params', () => { expect(r.body.id).to.equal('c dimascio'); })); - // TODO - fails with express 4 it('should handle path parameter with style=simple', async () => request(app) .get(`${app.basePath}/multi_users/aa,bb,cc`) From d1d0496b26fa7c26d9390999bbe97723b9f5b42a Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sun, 20 Apr 2025 08:55:24 -0400 Subject: [PATCH 40/44] fixes multipart wildcard tests --- test/multipart.spec.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/multipart.spec.ts b/test/multipart.spec.ts index 37e159a7..2f1bc7a0 100644 --- a/test/multipart.spec.ts +++ b/test/multipart.spec.ts @@ -33,7 +33,8 @@ describe('a multipart request', () => { metadata: req.body.metadata, }); }) - .post(`/sample_*suffix`, (req, res) => { + // .post(`/sample_*suffix`, (req, res) => { + .post(/^\/sample_.*/, (req, res) => { res.json(req.body); }), ), @@ -47,6 +48,7 @@ describe('a multipart request', () => { }); describe('that contains $refs', () => { + // TODO - fails with express 4 - parse multipart it('should validate a request body with a schemaObject $ref', async () => request(app) .post(`${app.basePath}/sample_4`) @@ -54,6 +56,7 @@ describe('a multipart request', () => { .attach('image', 'package.json') .expect(200)); + // TODO - fails with express 4 - parse multipart it('should validate a requestBody $ref', async () => request(app) .post(`${app.basePath}/sample_5`) @@ -61,6 +64,7 @@ describe('a multipart request', () => { .attach('image', 'package.json') .expect(200)); + // TODO - fails with express 4 - parse multipart it('should validate a requestBody $ref that contains a schemaObject $ref', async () => request(app) .post(`${app.basePath}/sample_6`) From 99ba76cbe065b525059b4cc52ad8581d6be5a688 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sun, 20 Apr 2025 09:05:41 -0400 Subject: [PATCH 41/44] fixes wildcard test to work for both express 4 and 5 --- test/wildcard.path.params.spec.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/test/wildcard.path.params.spec.ts b/test/wildcard.path.params.spec.ts index 2ce79cc0..c492c4ea 100644 --- a/test/wildcard.path.params.spec.ts +++ b/test/wildcard.path.params.spec.ts @@ -3,6 +3,9 @@ import { expect } from 'chai'; import * as request from 'supertest'; import { createApp } from './common/app'; import { AppWithServer } from './common/app.common'; +import * as pkg from '../package.json'; + +const expressVersion = pkg.devDependencies.express; describe('wildcard path params', () => { let app: AppWithServer; @@ -15,18 +18,23 @@ describe('wildcard path params', () => { }, 3001, (app) => { + const firstDigit = expressVersion.match(/\d/)?.[0]; + const pathWildcard = firstDigit === '4' + ? ':path(*)' + : '*path'; + app .get(`${app.basePath}/d1/:id`, (req, res) => { res.json({ ...req.params, }); }) - .get(`${app.basePath}/d2/*path`, (req, res) => { + .get(`${app.basePath}/d2/${pathWildcard}`, (req, res) => { res.json({ ...req.params, }); }) - .get(`${app.basePath}/d3/*path`, (req, res) => { + .get(`${app.basePath}/d3/${pathWildcard}`, (req, res) => { res.json({ ...req.params, }); @@ -36,12 +44,12 @@ describe('wildcard path params', () => { success: true, }); }) - .get(`${app.basePath}/d4/:multi/spaced/*path`, (req, res) => { + .get(`${app.basePath}/d4/:multi/spaced/${pathWildcard}`, (req, res) => { res.json({ ...req.params, }); }) - .get(`${app.basePath}/d5/:multi/*path`, (req, res) => { + .get(`${app.basePath}/d5/:multi/${pathWildcard}`, (req, res) => { res.json({ ...req.params, }); @@ -60,6 +68,7 @@ describe('wildcard path params', () => { expect(r.body.id).to.equal('my-id'); })); + // TODO - fails with express 4 - wildcard it('should allow path param with slashes "/" using wildcard', async () => request(app) .get(`${app.basePath}/d2/some/long/path`) @@ -71,6 +80,7 @@ describe('wildcard path params', () => { it('should return not found if no path is specified', async () => request(app).get(`${app.basePath}/d2`).expect(404)); + // TODO - fails with express 4 - wildcard it('should return 200 when wildcard path includes all required params', async () => request(app) .get(`${app.basePath}/d3/long/path/file.csv`) @@ -95,6 +105,7 @@ describe('wildcard path params', () => { expect(r.body.success).to.be.true; })); + // TODO - fails with express 4 - wildcard it('should return 200 when wildcard path includes all required params and multiple path params', async () => request(app) .get(`${app.basePath}/d4/one/spaced/two/three/four`) @@ -104,6 +115,7 @@ describe('wildcard path params', () => { expect(r.body.path).to.equal('two/three/four'); })); + // TODO - fails with express 4 - wildcard it('should return 200 when wildcard path includes all required params and multiple path params', async () => request(app) .get(`${app.basePath}/d5/one/two/three/four`) From 0f42afe9eac55aa667449f385fc2c17c6f78d4c2 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Sun, 20 Apr 2025 09:08:54 -0400 Subject: [PATCH 42/44] fix wildcard test to work for express 4 and express 5 --- test/1022.spec.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test/1022.spec.ts b/test/1022.spec.ts index a576d40e..107e567d 100644 --- a/test/1022.spec.ts +++ b/test/1022.spec.ts @@ -5,6 +5,9 @@ import * as packageJson from '../package.json'; import { OpenAPIV3 } from '../src/framework/types'; import { createApp } from './common/app'; import { AppWithServer } from './common/app.common'; +import * as pkg from '../package.json'; + +const expressVersion = pkg.devDependencies.express; describe(packageJson.name, () => { let app: AppWithServer; @@ -119,7 +122,9 @@ describe(packageJson.name, () => { validateResponses: true, }, 3005, - (app) => + (app) => { + const firstDigit = expressVersion.match(/\d/)?.[0]; + const pathWildcard = firstDigit === '4' ? ':wildcard(*)' : '*wildcard'; app.use( express .Router() @@ -129,12 +134,13 @@ describe(packageJson.name, () => { .post(`/api/test/:id\\:clone`, (req, res) => { res.status(200).json({ ...req.body, id: 'id-test' }); }) - .get('/api/some/*wildcard', (req, res) => { + .get(`/api/some/${pathWildcard}`, (req, res) => { const wildcard = (req.params as { wildcard: string }).wildcard; console.log(`Wildcard: ${wildcard}`); res.status(200).send(`Matched wildcard: ${wildcard}`); }), - ), + ); + }, ); }); From efa7602a55cf2248b8061654c28dca3fd4bc8125 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Wed, 23 Apr 2025 20:40:30 -0400 Subject: [PATCH 43/44] run tests against both express4 and express@latest --- .github/workflows/default.yml | 2 +- package.json | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml index efbc4695..4b0ac588 100644 --- a/.github/workflows/default.yml +++ b/.github/workflows/default.yml @@ -15,4 +15,4 @@ jobs: - name: Build the project run: npm run compile - name: Test the project - run: npm test \ No newline at end of file + run: npm run test:all \ No newline at end of file diff --git a/package.json b/package.json index 254ee4d8..cd08315e 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,9 @@ "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/*.spec.ts'", + "test:with-express4": "npm i express@4 --save-dev && npm test", + "test:with-express": "npm i express@latest --save-dev && npm test", + "test:all": "npm run test:with-express4 && npm run test:with-express", "test:debug": "mocha -r source-map-support/register -r ts-node/register --inspect-brk --files --recursive 'test/**/*.spec.ts' 'test/*.spec.ts'", "test:coverage": "nyc mocha -r source-map-support/register -r ts-node/register --recursive 'test/**/*.spec.ts' 'test/*.spec.ts'", "test:reset": "rimraf node_modules && npm i && npm run compile && npm t", From 5be301a7f1291458e64e30ccf3627e44f0a79376 Mon Sep 17 00:00:00 2001 From: cdimascio Date: Wed, 23 Apr 2025 20:58:29 -0400 Subject: [PATCH 44/44] set version to 5.5.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5e1f73c4..3df722b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "express-openapi-validator", - "version": "6.0.0-alpha.9", + "version": "5.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "express-openapi-validator", - "version": "6.0.0-alpha.9", + "version": "5.5.0", "license": "MIT", "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.9.3", diff --git a/package.json b/package.json index cd08315e..3b36d807 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-openapi-validator", - "version": "6.0.0-alpha.9", + "version": "5.5.0", "description": "Automatically validate API requests and responses with OpenAPI 3 and Express.", "main": "dist/index.js", "scripts": {