Upgrade to Express 5

Now async routes are handled!
This commit is contained in:
Asher 2020-11-05 11:36:27 -06:00
parent 8252c372af
commit 9e09c1f92b
No known key found for this signature in database
GPG Key ID: D63C1EF81242354A
4 changed files with 54 additions and 50 deletions

View File

@ -72,7 +72,7 @@
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"cookie-parser": "^1.4.5", "cookie-parser": "^1.4.5",
"env-paths": "^2.2.0", "env-paths": "^2.2.0",
"express": "^4.17.1", "express": "^5.0.0-alpha.8",
"fs-extra": "^9.0.1", "fs-extra": "^9.0.1",
"http-proxy": "^1.18.0", "http-proxy": "^1.18.0",
"httpolyglot": "^0.1.2", "httpolyglot": "^0.1.2",

View File

@ -191,22 +191,19 @@ export const handleUpgrade = (app: express.Express, server: http.Server): void =
} }
/** /**
* Patch Express routers to handle web sockets and async routes (since we have * Patch Express routers to handle web sockets.
* to patch `get` anyway).
* *
* Not using express-ws since the ws-wrapped sockets don't work with the proxy * Not using express-ws since the ws-wrapped sockets don't work with the proxy.
* and wildcards don't work correctly.
*/ */
function patchRouter(): void { function patchRouter(): void {
// Apparently this all works because Router is also the prototype assigned to // This works because Router is also the prototype assigned to the routers it
// the routers it returns. // returns.
// Store these since the original methods will be overridden. // Store this since the original method will be overridden.
const originalGet = (express.Router as any).get const originalGet = (express.Router as any).prototype.get
const originalPost = (express.Router as any).post
// Inject the `ws` method. // Inject the `ws` method.
;(express.Router as any).ws = function ws( ;(express.Router as any).prototype.ws = function ws(
route: expressCore.PathParams, route: expressCore.PathParams,
...handlers: express.WebSocketRequestHandler[] ...handlers: express.WebSocketRequestHandler[]
) { ) {
@ -216,10 +213,9 @@ function patchRouter(): void {
const wrapped: express.Handler = (req, res, next) => { const wrapped: express.Handler = (req, res, next) => {
if (isWebSocketRequest(req)) { if (isWebSocketRequest(req)) {
req._ws_handled = true req._ws_handled = true
Promise.resolve(handler(req, res, next)).catch(next) return handler(req, res, next)
} else {
next()
} }
next()
} }
return wrapped return wrapped
}), }),
@ -227,30 +223,16 @@ function patchRouter(): void {
return this return this
} }
// Overwrite `get` so we can distinguish between websocket and non-websocket // Overwrite `get` so we can distinguish between websocket and non-websocket
// routes. While we're at it handle async responses. // routes.
;(express.Router as any).get = function get(route: expressCore.PathParams, ...handlers: express.Handler[]) { ;(express.Router as any).prototype.get = function get(route: expressCore.PathParams, ...handlers: express.Handler[]) {
originalGet.apply(this, [ originalGet.apply(this, [
route, route,
...handlers.map((handler) => { ...handlers.map((handler) => {
const wrapped: express.Handler = (req, res, next) => { const wrapped: express.Handler = (req, res, next) => {
if (!isWebSocketRequest(req)) { if (!isWebSocketRequest(req)) {
Promise.resolve(handler(req, res, next)).catch(next) return handler(req, res, next)
} else {
next()
} }
} next()
return wrapped
}),
])
return this
}
// Handle async responses for `post` as well since we're in here anyway.
;(express.Router as any).post = function post(route: expressCore.PathParams, ...handlers: express.Handler[]) {
originalPost.apply(this, [
route,
...handlers.map((handler) => {
const wrapped: express.Handler = (req, res, next) => {
Promise.resolve(handler(req, res, next)).catch(next)
} }
return wrapped return wrapped
}), }),
@ -259,5 +241,5 @@ function patchRouter(): void {
} }
} }
// This needs to happen before anything uses the router. // This needs to happen before anything creates a router.
patchRouter() patchRouter()

View File

@ -55,10 +55,6 @@ export const register = async (app: Express, server: http.Server, args: Defaulte
app.use(bodyParser.json()) app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true })) app.use(bodyParser.urlencoded({ extended: true }))
server.on("upgrade", () => {
heart.beat()
})
app.use(async (req, res, next) => { app.use(async (req, res, next) => {
heart.beat() heart.beat()

View File

@ -1421,10 +1421,10 @@ array-equal@^1.0.0:
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
array-flatten@1.1.1: array-flatten@2.1.1:
version "1.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.1.tgz#426bb9da84090c1838d812c8150af20a8331e296"
integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= integrity sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=
array-includes@^3.1.1: array-includes@^3.1.1:
version "3.1.1" version "3.1.1"
@ -2585,6 +2585,13 @@ debug@2.6.9, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
dependencies: dependencies:
ms "2.0.0" ms "2.0.0"
debug@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
debug@4.1.1: debug@4.1.1:
version "4.1.1" version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
@ -3209,19 +3216,19 @@ expand-brackets@^2.1.4:
snapdragon "^0.8.1" snapdragon "^0.8.1"
to-regex "^3.0.1" to-regex "^3.0.1"
express@^4.17.1: express@^5.0.0-alpha.8:
version "4.17.1" version "5.0.0-alpha.8"
resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" resolved "https://registry.yarnpkg.com/express/-/express-5.0.0-alpha.8.tgz#b9dd3a568eab791e3391db47f9e6ab91e61b13fe"
integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== integrity sha512-PL8wTLgaNOiq7GpXt187/yWHkrNSfbr4H0yy+V0fpqJt5wpUzBi9DprAkwGKBFOqWHylJ8EyPy34V5u9YArfng==
dependencies: dependencies:
accepts "~1.3.7" accepts "~1.3.7"
array-flatten "1.1.1" array-flatten "2.1.1"
body-parser "1.19.0" body-parser "1.19.0"
content-disposition "0.5.3" content-disposition "0.5.3"
content-type "~1.0.4" content-type "~1.0.4"
cookie "0.4.0" cookie "0.4.0"
cookie-signature "1.0.6" cookie-signature "1.0.6"
debug "2.6.9" debug "3.1.0"
depd "~1.1.2" depd "~1.1.2"
encodeurl "~1.0.2" encodeurl "~1.0.2"
escape-html "~1.0.3" escape-html "~1.0.3"
@ -3232,10 +3239,11 @@ express@^4.17.1:
methods "~1.1.2" methods "~1.1.2"
on-finished "~2.3.0" on-finished "~2.3.0"
parseurl "~1.3.3" parseurl "~1.3.3"
path-to-regexp "0.1.7" path-is-absolute "1.0.1"
proxy-addr "~2.0.5" proxy-addr "~2.0.5"
qs "6.7.0" qs "6.7.0"
range-parser "~1.2.1" range-parser "~1.2.1"
router "2.0.0-alpha.1"
safe-buffer "5.1.2" safe-buffer "5.1.2"
send "0.17.1" send "0.17.1"
serve-static "1.14.1" serve-static "1.14.1"
@ -5489,7 +5497,7 @@ parse5@5.1.0:
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2"
integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==
parseurl@~1.3.3: parseurl@~1.3.2, parseurl@~1.3.3:
version "1.3.3" version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
@ -5519,7 +5527,7 @@ path-exists@^4.0.0:
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
path-is-absolute@^1.0.0: path-is-absolute@1.0.1, path-is-absolute@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
@ -6619,6 +6627,19 @@ rotating-file-stream@^2.1.1:
resolved "https://registry.yarnpkg.com/rotating-file-stream/-/rotating-file-stream-2.1.3.tgz#4b3cc8f56ae70b3e30ccdb4ee6b14d95e66b02bb" resolved "https://registry.yarnpkg.com/rotating-file-stream/-/rotating-file-stream-2.1.3.tgz#4b3cc8f56ae70b3e30ccdb4ee6b14d95e66b02bb"
integrity sha512-zZ4Tkngxispo7DgiTqX0s4ChLtM3qET6iYsDA9tmgDEqJ3BFgRq/ZotsKEDAYQt9pAn9JwwqT27CSwQt3CTxNg== integrity sha512-zZ4Tkngxispo7DgiTqX0s4ChLtM3qET6iYsDA9tmgDEqJ3BFgRq/ZotsKEDAYQt9pAn9JwwqT27CSwQt3CTxNg==
router@2.0.0-alpha.1:
version "2.0.0-alpha.1"
resolved "https://registry.yarnpkg.com/router/-/router-2.0.0-alpha.1.tgz#9188213b972215e03ef830e0ac77837870085f6d"
integrity sha512-fz/T/qLkJM6RTtbqGqA1+uZ88ejqJoPyKeJAeXPYjebA7HzV/UyflH4gXWqW/Y6SERnp4kDwNARjqy6se3PcOw==
dependencies:
array-flatten "2.1.1"
debug "3.1.0"
methods "~1.1.2"
parseurl "~1.3.2"
path-to-regexp "0.1.7"
setprototypeof "1.1.0"
utils-merge "1.0.1"
run-parallel@^1.1.9: run-parallel@^1.1.9:
version "1.1.9" version "1.1.9"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679"
@ -6736,6 +6757,11 @@ setimmediate@^1.0.4:
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
setprototypeof@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
setprototypeof@1.1.1: setprototypeof@1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"