From 2144fa7885761f18bad180866615a20db0b8d62e Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 17 Apr 2024 16:42:39 +0300 Subject: [PATCH 01/15] feat: test with connect --- lib/Server.js | 77 +++++++++++++++++++++++++++++++++++++++++------ package-lock.json | 72 +++++++++++++++++++++++++++++++++++++++++++- package.json | 3 +- 3 files changed, 140 insertions(+), 12 deletions(-) diff --git a/lib/Server.js b/lib/Server.js index 88a051d9cf..eacdff169b 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -1732,8 +1732,13 @@ class Server { * @returns {void} */ setupApp() { + // eslint-disable-next-line import/no-extraneous-dependencies + const connect = require("connect"); + const app = connect(); + /** @type {import("express").Application | undefined}*/ - this.app = new /** @type {any} */ (getExpress())(); + this.app = /** @type {any} */ (app); + // this.app = new /** @type {any} */ (getExpress())(); } /** @@ -1789,8 +1794,7 @@ class Server { */ setupHostHeaderCheck() { /** @type {import("express").Application} */ - (this.app).all( - "*", + (this.app).use( /** * @param {Request} req * @param {Response} res @@ -1808,6 +1812,8 @@ class Server { return next(); } + // TODO add this to test + res.statusCode = 403; res.send("Invalid Host header"); }, ); @@ -1835,28 +1841,72 @@ class Server { const { app, middleware } = this; /** @type {import("express").Application} */ - (app).get("/__webpack_dev_server__/sockjs.bundle.js", (req, res) => { + (app).use("/__webpack_dev_server__/sockjs.bundle.js", (req, res, next) => { + if (req.method !== "GET" && req.method !== "HEAD") { + next(); + return; + } + + const clientPath = path.join( + __dirname, + "..", + "client/modules/sockjs-client/index.js", + ); + + // Express send Etag and other headers by default, so let's keep them for compatibility reasons + if (typeof res.sendFile === "function") { + res.sendFile(clientPath); + return; + } + + let stats; + + try { + // TODO implement `inputFileSystem.createReadStream` in webpack + stats = fs.statSync(clientPath); + } catch (err) { + next(); + return; + } + res.setHeader("Content-Type", "application/javascript"); + res.setHeader("Content-Length", stats.size); - const clientPath = path.join(__dirname, "..", "client"); + if (req.method === "HEAD") { + res.end(); + return; + } - res.sendFile(path.join(clientPath, "modules/sockjs-client/index.js")); + fs.createReadStream(clientPath).pipe(res); }); /** @type {import("express").Application} */ - (app).get("/webpack-dev-server/invalidate", (_req, res) => { + (app).use("/webpack-dev-server/invalidate", (req, res, next) => { + if (req.method !== "GET" && req.method !== "HEAD") { + next(); + return; + } + this.invalidate(); res.end(); }); /** @type {import("express").Application} */ - (app).get("/webpack-dev-server/open-editor", (req, res) => { - const fileName = req.query.fileName; + (app).use("/webpack-dev-server/open-editor", (req, res, next) => { + if (req.method !== "GET" && req.method !== "HEAD") { + next(); + return; + } + + const parsedUrl = url.parse(req.url, true); + const query = parsedUrl.query; + const fileName = query.fileName; if (typeof fileName === "string") { // @ts-ignore const launchEditor = require("launch-editor"); + launchEditor(fileName); } @@ -1864,15 +1914,22 @@ class Server { }); /** @type {import("express").Application} */ - (app).get("/webpack-dev-server", (req, res) => { + (app).use("/webpack-dev-server", (req, res, next) => { + if (req.method !== "GET" && req.method !== "HEAD") { + next(); + return; + } + /** @type {import("webpack-dev-middleware").API}*/ (middleware).waitUntilValid((stats) => { res.setHeader("Content-Type", "text/html"); + // HEAD requests should not return body content if (req.method === "HEAD") { res.end(); return; } + res.write( '', ); diff --git a/package-lock.json b/package-lock.json index 76ed88542a..b1e052e130 100644 --- a/package-lock.json +++ b/package-lock.json @@ -62,6 +62,7 @@ "babel-jest": "^29.5.0", "babel-loader": "^9.1.0", "body-parser": "^1.19.2", + "connect": "^3.7.0", "core-js": "^3.31.0", "cspell": "^8.3.2", "css-loader": "^6.8.1", @@ -95,7 +96,7 @@ "tcp-port-used": "^1.0.2", "typescript": "^5.3.3", "wait-for-expect": "^3.0.2", - "webpack": "^5.89.0", + "webpack": "^5.91.0", "webpack-cli": "^5.0.1", "webpack-merge": "^5.9.0" }, @@ -6492,6 +6493,21 @@ "typedarray-to-buffer": "^3.1.5" } }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -6500,6 +6516,60 @@ "node": ">=0.8" } }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/connect/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/connect/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", diff --git a/package.json b/package.json index be846890f4..73df97c9be 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "babel-jest": "^29.5.0", "babel-loader": "^9.1.0", "body-parser": "^1.19.2", + "connect": "^3.7.0", "core-js": "^3.31.0", "cspell": "^8.3.2", "css-loader": "^6.8.1", @@ -129,7 +130,7 @@ "tcp-port-used": "^1.0.2", "typescript": "^5.3.3", "wait-for-expect": "^3.0.2", - "webpack": "^5.89.0", + "webpack": "^5.91.0", "webpack-cli": "^5.0.1", "webpack-merge": "^5.9.0" }, From 7d1cb496702059b3fed5fe1a890df6095ce2230f Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 17 Apr 2024 16:51:01 +0300 Subject: [PATCH 02/15] fix: built-in middlewares --- lib/Server.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/Server.js b/lib/Server.js index eacdff169b..b1b7aa615b 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -2032,7 +2032,6 @@ class Server { if (typeof this.options.headers !== "undefined") { middlewares.push({ name: "set-headers", - path: "*", middleware: this.setHeaders.bind(this), }); } @@ -2312,7 +2311,6 @@ class Server { // fallback when no other middleware responses. middlewares.push({ name: "options-middleware", - path: "*", /** * @param {Request} req * @param {Response} res From 932fa43acb2674c22f8e2a3e431dc092cb641215 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 17 Apr 2024 17:33:38 +0300 Subject: [PATCH 03/15] test: fix logic --- lib/Server.js | 5 +- package-lock.json | 53 +++++++++---------- package.json | 2 +- .../allowed-hosts.test.js.snap.webpack5 | 16 ++++-- test/e2e/on-listening.test.js | 18 ++++--- test/e2e/setup-middlewares.test.js | 30 +++++++---- 6 files changed, 72 insertions(+), 52 deletions(-) diff --git a/lib/Server.js b/lib/Server.js index b1b7aa615b..edcaf548ee 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -1812,9 +1812,8 @@ class Server { return next(); } - // TODO add this to test res.statusCode = 403; - res.send("Invalid Host header"); + res.end("Invalid Host header"); }, ); } @@ -1922,7 +1921,7 @@ class Server { /** @type {import("webpack-dev-middleware").API}*/ (middleware).waitUntilValid((stats) => { - res.setHeader("Content-Type", "text/html"); + res.setHeader("Content-Type", "text/html; charset=utf-8"); // HEAD requests should not return body content if (req.method === "HEAD") { diff --git a/package-lock.json b/package-lock.json index b1e052e130..6768e193b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,7 +84,7 @@ "memfs": "^4.6.0", "npm-run-all": "^4.1.5", "prettier": "^3.2.4", - "puppeteer": "^22.1.0", + "puppeteer": "^22.6.5", "readable-stream": "^4.5.2", "require-from-string": "^2.0.2", "rimraf": "^5.0.5", @@ -4333,9 +4333,9 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.0.tgz", - "integrity": "sha512-MC7LxpcBtdfTbzwARXIkqGZ1Osn3nnZJlm+i0+VqHl72t//Xwl9wICrXT8BwtgC6s1xJNHsxOpvzISUqe92+sw==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.2.tgz", + "integrity": "sha512-hZ/JhxPIceWaGSEzUZp83/8M49CoxlkuThfTR7t4AoCu5+ZvJ3vktLm60Otww2TXeROB5igiZ8D9oPQh6ckBVg==", "dev": true, "dependencies": { "debug": "4.3.4", @@ -5630,14 +5630,13 @@ "optional": true }, "node_modules/bare-fs": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.2.2.tgz", - "integrity": "sha512-X9IqgvyB0/VA5OZJyb5ZstoN62AzD7YxVGog13kkfYWYqJYcK0kcqLZ6TrmH5qr4/8//ejVcX4x/a0UvaogXmA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.2.3.tgz", + "integrity": "sha512-amG72llr9pstfXOBOHve1WjiuKKAMnebcmMbPWDZ7BCevAoJLpugjuAPRsDINEyjT0a6tbaVx3DctkXIRbLuJw==", "dev": true, "optional": true, "dependencies": { "bare-events": "^2.0.0", - "bare-os": "^2.0.0", "bare-path": "^2.0.0", "streamx": "^2.13.0" } @@ -5650,9 +5649,9 @@ "optional": true }, "node_modules/bare-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.0.tgz", - "integrity": "sha512-DIIg7ts8bdRKwJRJrUMy/PICEaQZaPGZ26lsSx9MJSwIhSrcdHn7/C8W+XmnG/rKi6BaRcz+JO00CjZteybDtw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.1.tgz", + "integrity": "sha512-OHM+iwRDRMDBsSW7kl3dO62JyHdBKO3B25FB9vNQBPcGHMo4+eA8Yj41Lfbk3pS/seDY+siNge0LdRTulAau/A==", "dev": true, "optional": true, "dependencies": { @@ -6044,9 +6043,9 @@ } }, "node_modules/chromium-bidi": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.16.tgz", - "integrity": "sha512-IT5lnR44h/qZQ4GaCHvBxYIl4cQL2i9UvFyYeRyVdcpY04hx5H720HQfe/7Oz7ndxaYVLQFGpCO71J4X2Ye/Gw==", + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.17.tgz", + "integrity": "sha512-BqOuIWUgTPj8ayuBFJUYCCuwIcwjBsb3/614P7tt1bEPJ4i1M0kCdIl0Wi9xhtswBXnfO2bTpTMkHD71H8rJMg==", "dev": true, "dependencies": { "mitt": "3.0.1", @@ -16460,16 +16459,16 @@ } }, "node_modules/puppeteer": { - "version": "22.6.2", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.6.2.tgz", - "integrity": "sha512-3GMAJ9adPUSdIHGuYV1b1RqRB6D2UScjnq779uZsvpAP6HOWw2+9ezZiUZaAXVST+Ku7KWsxOjkctEvRasJClA==", + "version": "22.6.5", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.6.5.tgz", + "integrity": "sha512-YuoRKGj3MxHhUwrey7vmNvU4odGdUdNsj1ee8pfcqQlLWIXfMOXZCAXh8xdzpZESHH3tCGWp2xmPZE8E6iUEWg==", "dev": true, "hasInstallScript": true, "dependencies": { - "@puppeteer/browsers": "2.2.0", + "@puppeteer/browsers": "2.2.2", "cosmiconfig": "9.0.0", "devtools-protocol": "0.0.1262051", - "puppeteer-core": "22.6.2" + "puppeteer-core": "22.6.5" }, "bin": { "puppeteer": "lib/esm/puppeteer/node/cli.js" @@ -16479,13 +16478,13 @@ } }, "node_modules/puppeteer-core": { - "version": "22.6.2", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.6.2.tgz", - "integrity": "sha512-Sws/9V2/7nFrn3MSsRPHn1pXJMIFn6FWHhoMFMUBXQwVvcBstRIa9yW8sFfxePzb56W1xNfSYzPRnyAd0+qRVQ==", + "version": "22.6.5", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.6.5.tgz", + "integrity": "sha512-s0/5XkAWe0/dWISiljdrybjwDCHhgN31Nu/wznOZPKeikgcJtZtbvPKBz0t802XWqfSQnQDt3L6xiAE5JLlfuw==", "dev": true, "dependencies": { - "@puppeteer/browsers": "2.2.0", - "chromium-bidi": "0.5.16", + "@puppeteer/browsers": "2.2.2", + "chromium-bidi": "0.5.17", "debug": "4.3.4", "devtools-protocol": "0.0.1262051", "ws": "8.16.0" @@ -17537,9 +17536,9 @@ } }, "node_modules/socks": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", - "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dev": true, "dependencies": { "ip-address": "^9.0.5", diff --git a/package.json b/package.json index 73df97c9be..01164a9bb3 100644 --- a/package.json +++ b/package.json @@ -118,7 +118,7 @@ "memfs": "^4.6.0", "npm-run-all": "^4.1.5", "prettier": "^3.2.4", - "puppeteer": "^22.1.0", + "puppeteer": "^22.6.5", "readable-stream": "^4.5.2", "require-from-string": "^2.0.2", "rimraf": "^5.0.5", diff --git a/test/e2e/__snapshots__/allowed-hosts.test.js.snap.webpack5 b/test/e2e/__snapshots__/allowed-hosts.test.js.snap.webpack5 index 84b2498b57..5ab1e22dec 100644 --- a/test/e2e/__snapshots__/allowed-hosts.test.js.snap.webpack5 +++ b/test/e2e/__snapshots__/allowed-hosts.test.js.snap.webpack5 @@ -262,15 +262,23 @@ exports[`allowed hosts should connect web socket client using localhost to web s exports[`allowed hosts should connect web socket client using localhost to web socket server with the "auto" value ("ws"): page errors 1`] = `[]`; -exports[`allowed hosts should disconnect web client using localhost to web socket server with the "auto" value ("sockjs"): console messages 1`] = `[]`; +exports[`allowed hosts should disconnect web client using localhost to web socket server with the "auto" value ("sockjs"): console messages 1`] = ` +[ + "Failed to load resource: the server responded with a status of 403 (Forbidden)", +] +`; -exports[`allowed hosts should disconnect web client using localhost to web socket server with the "auto" value ("sockjs"): html 1`] = `"Invalid Host header"`; +exports[`allowed hosts should disconnect web client using localhost to web socket server with the "auto" value ("sockjs"): html 1`] = `"
Invalid Host header
"`; exports[`allowed hosts should disconnect web client using localhost to web socket server with the "auto" value ("sockjs"): page errors 1`] = `[]`; -exports[`allowed hosts should disconnect web client using localhost to web socket server with the "auto" value ("ws"): console messages 1`] = `[]`; +exports[`allowed hosts should disconnect web client using localhost to web socket server with the "auto" value ("ws"): console messages 1`] = ` +[ + "Failed to load resource: the server responded with a status of 403 (Forbidden)", +] +`; -exports[`allowed hosts should disconnect web client using localhost to web socket server with the "auto" value ("ws"): html 1`] = `"Invalid Host header"`; +exports[`allowed hosts should disconnect web client using localhost to web socket server with the "auto" value ("ws"): html 1`] = `"
Invalid Host header
"`; exports[`allowed hosts should disconnect web client using localhost to web socket server with the "auto" value ("ws"): page errors 1`] = `[]`; diff --git a/test/e2e/on-listening.test.js b/test/e2e/on-listening.test.js index 6e97561b14..4a88d908e7 100644 --- a/test/e2e/on-listening.test.js +++ b/test/e2e/on-listening.test.js @@ -26,12 +26,18 @@ describe("onListening option", () => { onListeningIsRunning = true; - devServer.app.get("/listening/some/path", (_, response) => { - response.send("listening"); - }); - - devServer.app.post("/listening/some/path", (_, response) => { - response.send("listening POST"); + devServer.app.use("/listening/some/path", (req, res, next) => { + if (req.method === "GET") { + res.setHeader("Content-Type", "text/html; charset=utf-8"); + res.end("listening"); + return; + } else if (req.method === "POST") { + res.setHeader("Content-Type", "text/html; charset=utf-8"); + res.end("listening POST"); + return; + } + + return next(); }); }, port, diff --git a/test/e2e/setup-middlewares.test.js b/test/e2e/setup-middlewares.test.js index 5ed6fece62..5187aaa8a7 100644 --- a/test/e2e/setup-middlewares.test.js +++ b/test/e2e/setup-middlewares.test.js @@ -23,35 +23,43 @@ describe("setupMiddlewares option", () => { throw new Error("webpack-dev-server is not defined"); } - devServer.app.get("/setup-middleware/some/path", (_, response) => { - response.send("setup-middlewares option GET"); - }); - - devServer.app.post("/setup-middleware/some/path", (_, response) => { - response.send("setup-middlewares option POST"); + devServer.app.use("/setup-middleware/some/path", (req, res, next) => { + if (req.method === "GET") { + res.setHeader("Content-Type", "text/html; charset=utf-8"); + res.end("setup-middlewares option GET"); + return; + } else if (req.method === "POST") { + res.setHeader("Content-Type", "text/html; charset=utf-8"); + res.end("setup-middlewares option POST"); + return; + } + + return next(); }); middlewares.push({ name: "hello-world-test-two", middleware: (req, res, next) => { - if (req.path !== "/foo/bar/baz") { + if (req.url !== "/foo/bar/baz") { next(); - return; } - res.send("Hello World without path!"); + res.setHeader("Content-Type", "text/html; charset=utf-8"); + res.end("Hello World without path!"); }, }); middlewares.push({ name: "hello-world-test-one", path: "/foo/bar", middleware: (req, res) => { - res.send("Hello World with path!"); + res.setHeader("Content-Type", "text/html; charset=utf-8"); + res.end("Hello World with path!"); }, }); middlewares.push((req, res) => { - res.send("Hello World as function!"); + res.setHeader("Content-Type", "text/html; charset=utf-8"); + res.end("Hello World as function!"); }); return middlewares; From d6d6c3600104918b548b17c6b2673a78255c9726 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 17 Apr 2024 17:42:02 +0300 Subject: [PATCH 04/15] test: update --- .../e2e/__snapshots__/built-in-routes.test.js.snap.webpack5 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/e2e/__snapshots__/built-in-routes.test.js.snap.webpack5 b/test/e2e/__snapshots__/built-in-routes.test.js.snap.webpack5 index 769c716c67..963446a662 100644 --- a/test/e2e/__snapshots__/built-in-routes.test.js.snap.webpack5 +++ b/test/e2e/__snapshots__/built-in-routes.test.js.snap.webpack5 @@ -16,7 +16,7 @@ exports[`Built in routes with multi config should handle GET request to director exports[`Built in routes with multi config should handle GET request to directory index and list all middleware directories: page errors 1`] = `[]`; -exports[`Built in routes with multi config should handle GET request to directory index and list all middleware directories: response headers content-type 1`] = `"text/html"`; +exports[`Built in routes with multi config should handle GET request to directory index and list all middleware directories: response headers content-type 1`] = `"text/html; charset=utf-8"`; exports[`Built in routes with multi config should handle GET request to directory index and list all middleware directories: response status 1`] = `200`; @@ -34,7 +34,7 @@ exports[`Built in routes with simple config should handle GET request to directo exports[`Built in routes with simple config should handle GET request to directory index and list all middleware directories: page errors 1`] = `[]`; -exports[`Built in routes with simple config should handle GET request to directory index and list all middleware directories: response headers content-type 1`] = `"text/html"`; +exports[`Built in routes with simple config should handle GET request to directory index and list all middleware directories: response headers content-type 1`] = `"text/html; charset=utf-8"`; exports[`Built in routes with simple config should handle GET request to directory index and list all middleware directories: response status 1`] = `200`; @@ -56,7 +56,7 @@ exports[`Built in routes with simple config should handle HEAD request to direct exports[`Built in routes with simple config should handle HEAD request to directory index: page errors 1`] = `[]`; -exports[`Built in routes with simple config should handle HEAD request to directory index: response headers content-type 1`] = `"text/html"`; +exports[`Built in routes with simple config should handle HEAD request to directory index: response headers content-type 1`] = `"text/html; charset=utf-8"`; exports[`Built in routes with simple config should handle HEAD request to directory index: response status 1`] = `200`; From 4080ee7bbe8347ab40d6f0aa37ad8d081ca5685d Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 17 Apr 2024 18:56:12 +0300 Subject: [PATCH 05/15] test: improve --- scripts/setupTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/setupTest.js b/scripts/setupTest.js index f3dedf9551..99a74a59bf 100644 --- a/scripts/setupTest.js +++ b/scripts/setupTest.js @@ -2,4 +2,4 @@ process.env.CHOKIDAR_USEPOLLING = true; -jest.setTimeout(300000); +jest.setTimeout(400000); From d0cddc8a1b282d35da0fe0484720f46f306eebd1 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 17 Apr 2024 19:33:24 +0300 Subject: [PATCH 06/15] test: fix --- lib/Server.js | 135 +++++++++++------ test/server/proxy-option.test.js | 20 ++- types/lib/Server.d.ts | 240 ++++++++++++++++++++----------- 3 files changed, 263 insertions(+), 132 deletions(-) diff --git a/lib/Server.js b/lib/Server.js index edcaf548ee..a8ebb9de3c 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -177,6 +177,7 @@ const schema = require("./options.json"); */ /** + * @template {BasicApplication} [T=import("express").Application] * @typedef {Object} Configuration * @property {boolean | string} [ipc] * @property {Host} [host] @@ -199,8 +200,8 @@ const schema = require("./options.json"); * @property {boolean} [setupExitSignals] * @property {boolean | ClientConfiguration} [client] * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] - * @property {(devServer: Server) => void} [onListening] - * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] + * @property {(devServer: Server) => void} [onListening] + * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] */ if (!process.env.WEBPACK_SERVE) { @@ -245,10 +246,50 @@ const encodeOverlaySettings = (setting) => ? encodeURIComponent(setting.toString()) : setting; +/** @typedef {(req: IncomingMessage, res: import("http").ServerResponse) => void} SimpleHandleFunction */ +/** @typedef {(req: IncomingMessage, res: import("http").ServerResponse, next: NextFunction) => void} NextHandleFunction */ +/** @typedef {(err: any, req: IncomingMessage, res: import("http").ServerResponse, next: NextFunction) => void} ErrorHandleFunction */ +/** @typedef {SimpleHandleFunction | NextHandleFunction | ErrorHandleFunction} HandleFunction */ + +// Working for overload, because typescript doesn't support this yes +/** + * @overload + * @param {NextHandleFunction} fn + * @returns {BasicApplication} + */ +/** + * @overload + * @param {HandleFunction} fn + * @returns {BasicApplication} + */ +/** + * @overload + * @param {string} route + * @param {NextHandleFunction} fn + * @returns {BasicApplication} + */ +/** + * @param {string} route + * @param {HandleFunction} fn + * @returns {BasicApplication} + */ +// eslint-disable-next-line no-unused-vars +function useFn(route, fn) { + return /** @type {BasicApplication} */ ({}); +} + +/** + * @typedef {Object} BasicApplication + * @property {typeof useFn} use + */ + +/** + * @template {BasicApplication} [T=import("express").Application] + */ class Server { /** - * @param {Configuration | Compiler | MultiCompiler} options - * @param {Compiler | MultiCompiler | Configuration} compiler + * @param {Configuration} options + * @param {Compiler | MultiCompiler} compiler */ constructor(options = {}, compiler) { validate(/** @type {Schema} */ (schema), options, { @@ -256,12 +297,12 @@ class Server { baseDataPath: "options", }); - this.compiler = /** @type {Compiler | MultiCompiler} */ (compiler); + this.compiler = compiler; /** * @type {ReturnType} * */ this.logger = this.compiler.getInfrastructureLogger("webpack-dev-server"); - this.options = /** @type {Configuration} */ (options); + this.options = options; /** * @type {FSWatcher[]} */ @@ -1736,7 +1777,7 @@ class Server { const connect = require("connect"); const app = connect(); - /** @type {import("express").Application | undefined}*/ + /** @type {T | undefined}*/ this.app = /** @type {any} */ (app); // this.app = new /** @type {any} */ (getExpress())(); } @@ -1793,29 +1834,22 @@ class Server { * @returns {void} */ setupHostHeaderCheck() { - /** @type {import("express").Application} */ - (this.app).use( - /** - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {void} - */ - (req, res, next) => { - if ( - this.checkHeader( - /** @type {{ [key: string]: string | undefined }} */ - (req.headers), - "host", - ) - ) { - return next(); - } + /** @type {T} */ + (this.app).use((req, res, next) => { + if ( + this.checkHeader( + /** @type {{ [key: string]: string | undefined }} */ + (req.headers), + "host", + ) + ) { + next(); + return; + } - res.statusCode = 403; - res.end("Invalid Host header"); - }, - ); + res.statusCode = 403; + res.end("Invalid Host header"); + }); } /** @@ -1839,7 +1873,7 @@ class Server { setupBuiltInRoutes() { const { app, middleware } = this; - /** @type {import("express").Application} */ + /** @type {T} */ (app).use("/__webpack_dev_server__/sockjs.bundle.js", (req, res, next) => { if (req.method !== "GET" && req.method !== "HEAD") { next(); @@ -1853,7 +1887,9 @@ class Server { ); // Express send Etag and other headers by default, so let's keep them for compatibility reasons + // @ts-ignore if (typeof res.sendFile === "function") { + // @ts-ignore res.sendFile(clientPath); return; } @@ -1879,7 +1915,7 @@ class Server { fs.createReadStream(clientPath).pipe(res); }); - /** @type {import("express").Application} */ + /** @type {T} */ (app).use("/webpack-dev-server/invalidate", (req, res, next) => { if (req.method !== "GET" && req.method !== "HEAD") { next(); @@ -1891,16 +1927,21 @@ class Server { res.end(); }); - /** @type {import("express").Application} */ + /** @type {T} */ (app).use("/webpack-dev-server/open-editor", (req, res, next) => { if (req.method !== "GET" && req.method !== "HEAD") { next(); return; } - const parsedUrl = url.parse(req.url, true); - const query = parsedUrl.query; - const fileName = query.fileName; + if (!req.url) { + next(); + return; + } + + const resolveUrl = new URL(req.url, `http://${req.headers.host}`); + const params = new URLSearchParams(resolveUrl.search); + const fileName = params.get("fileName"); if (typeof fileName === "string") { // @ts-ignore @@ -1912,7 +1953,7 @@ class Server { res.end(); }); - /** @type {import("express").Application} */ + /** @type {T} */ (app).use("/webpack-dev-server", (req, res, next) => { if (req.method !== "GET" && req.method !== "HEAD") { next(); @@ -2333,14 +2374,24 @@ class Server { middlewares.forEach((middleware) => { if (typeof middleware === "function") { - /** @type {import("express").Application} */ - (this.app).use(middleware); + /** @type {T} */ + (this.app).use( + /** @type {NextHandleFunction | HandleFunction} */ + (middleware), + ); } else if (typeof middleware.path !== "undefined") { - /** @type {import("express").Application} */ - (this.app).use(middleware.path, middleware.middleware); + /** @type {T} */ + (this.app).use( + middleware.path, + /** @type {SimpleHandleFunction | NextHandleFunction} */ + (middleware.middleware), + ); } else { - /** @type {import("express").Application} */ - (this.app).use(middleware.middleware); + /** @type {T} */ + (this.app).use( + /** @type {NextHandleFunction | HandleFunction} */ + (middleware.middleware), + ); } }); } diff --git a/test/server/proxy-option.test.js b/test/server/proxy-option.test.js index d894fdae08..e77824a371 100644 --- a/test/server/proxy-option.test.js +++ b/test/server/proxy-option.test.js @@ -27,7 +27,7 @@ const proxyOptionPathsAsProperties = [ { context: "/foo", bypass(req) { - if (/\.html$/.test(req.path)) { + if (/\.html$/.test(req.path || req.url)) { return "/index.html"; } @@ -37,7 +37,7 @@ const proxyOptionPathsAsProperties = [ { context: "proxyfalse", bypass(req) { - if (/\/proxyfalse$/.test(req.path)) { + if (/\/proxyfalse$/.test(req.path || req.url)) { return false; } }, @@ -45,7 +45,7 @@ const proxyOptionPathsAsProperties = [ { context: "/proxy/async", bypass(req, res) { - if (/\/proxy\/async$/.test(req.path)) { + if (/\/proxy\/async$/.test(req.path || req.url)) { return new Promise((resolve) => { setTimeout(() => { res.end("proxy async response"); @@ -61,7 +61,7 @@ const proxyOptionPathsAsProperties = [ changeOrigin: true, secure: false, bypass(req) { - if (/\.(html)$/i.test(req.url)) { + if (/\.(html)$/i.test(req.path || req.url)) { return req.url; } }, @@ -95,10 +95,16 @@ const proxyOptionOfArray = [ target: `http://localhost:${port2}`, pathRewrite: { "^/api": "" }, bypass: () => { - if (req && req.query.foo) { - res.end(`foo+${next.name}+${typeof next}`); + if (req) { + const resolveUrl = new URL(req.url, `http://${req.headers.host}`); + const params = new URLSearchParams(resolveUrl.search); + const foo = params.get("foo"); - return false; + if (foo) { + res.end(`foo+${next.name}+${typeof next}`); + + return false; + } } }, }; diff --git a/types/lib/Server.d.ts b/types/lib/Server.d.ts index b9eee28278..2ac793f67e 100644 --- a/types/lib/Server.d.ts +++ b/types/lib/Server.d.ts @@ -1,6 +1,15 @@ /// export = Server; -declare class Server { +/** + * @typedef {Object} BasicApplication + * @property {typeof useFn} use + */ +/** + * @template {BasicApplication} [T=import("express").Application] + */ +declare class Server< + T extends BasicApplication = import("express").Application, +> { static get schema(): { title: string; type: string; @@ -196,6 +205,7 @@ declare class Server { * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware */ /** + * @template {BasicApplication} [T=import("express").Application] * @typedef {Object} Configuration * @property {boolean | string} [ipc] * @property {Host} [host] @@ -218,8 +228,8 @@ declare class Server { * @property {boolean} [setupExitSignals] * @property {boolean | ClientConfiguration} [client] * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] - * @property {(devServer: Server) => void} [onListening] - * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] + * @property {(devServer: Server) => void} [onListening] + * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] */ overlay: { $ref: string; @@ -361,6 +371,7 @@ declare class Server { * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware */ /** + * @template {BasicApplication} [T=import("express").Application] * @typedef {Object} Configuration * @property {boolean | string} [ipc] * @property {Host} [host] @@ -383,8 +394,8 @@ declare class Server { * @property {boolean} [setupExitSignals] * @property {boolean | ClientConfiguration} [client] * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] - * @property {(devServer: Server) => void} [onListening] - * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] + * @property {(devServer: Server) => void} [onListening] + * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] */ anyOf: { $ref: string; @@ -466,7 +477,7 @@ declare class Server { Compress: { type: string; description: string; - link: string; + link: string /** @typedef {(req: IncomingMessage, res: import("http").ServerResponse, next: NextFunction) => void} NextHandleFunction */; cli: { negatedDescription: string; }; @@ -479,9 +490,6 @@ declare class Server { }; HeaderObject: { type: string; - /** - * @type {FSWatcher[]} - */ additionalProperties: boolean; properties: { key: { @@ -553,7 +561,11 @@ declare class Server { minLength?: undefined; } | { - type: string; + type: string /** + * @private + * @returns {StatsOptions} + * @constructor + */; minLength: number; enum?: undefined; } @@ -589,7 +601,10 @@ declare class Server { enum: boolean[]; minLength?: undefined; } - )[]; + )[] /** + * @param {string} gateway + * @returns {string | undefined} + */; description: string; link: string; }; @@ -671,6 +686,9 @@ declare class Server { | { type: string; minLength: number; + /** + * @type {string | undefined} + */ items?: undefined; minItems?: undefined; } @@ -731,7 +749,7 @@ declare class Server { } )[]; description: string; - link: string /** @type {WebSocketURL} */; + link: string; }; Proxy: { type: string; @@ -743,7 +761,6 @@ declare class Server { } | { instanceof: string; - /** @type {{ type: WebSocketServerConfiguration["type"], options: NonNullable }} */ type?: undefined; } )[]; @@ -770,11 +787,12 @@ declare class Server { ServerString: { type: string; minLength: number; - /** @type {string} */ + /** @type {WebSocketURL} */ cli: { exclude: boolean; }; }; + /** @type {ClientConfiguration} */ ServerObject: { type: string; properties: { @@ -785,7 +803,7 @@ declare class Server { }; options: { $ref: string; - }; + } /** @type {string} */; }; additionalProperties: boolean; }; @@ -797,6 +815,7 @@ declare class Server { type: string; description: string; }; + /** @type {ServerConfiguration} */ requestCert: { type: string; description: string; @@ -947,6 +966,7 @@ declare class Server { additionalProperties?: undefined; } | { + /** @type {string} */ instanceof: string; type?: undefined; additionalProperties?: undefined; @@ -1111,7 +1131,10 @@ declare class Server { type?: undefined; items?: undefined; } - )[]; + )[] /** + * @param {WatchOptions & { aggregateTimeout?: number, ignored?: WatchOptions["ignored"], poll?: number | boolean }} watchOptions + * @returns {WatchOptions} + */; description: string; link: string; }; @@ -1159,6 +1182,10 @@ declare class Server { description: string; link: string; }; + /** + * @param {string | Static | undefined} [optionsForStatic] + * @returns {NormalizedStatic} + */ WebSocketServerType: { enum: string[]; }; @@ -1318,23 +1345,19 @@ declare class Server { */ private static isWebTarget; /** - * @param {Configuration | Compiler | MultiCompiler} options - * @param {Compiler | MultiCompiler | Configuration} compiler + * @param {Configuration} options + * @param {Compiler | MultiCompiler} compiler */ constructor( - options: - | import("webpack").Compiler - | import("webpack").MultiCompiler - | Configuration - | undefined, - compiler: Compiler | MultiCompiler | Configuration, + options: Configuration | undefined, + compiler: Compiler | MultiCompiler, ); compiler: import("webpack").Compiler | import("webpack").MultiCompiler; /** * @type {ReturnType} * */ logger: ReturnType; - options: Configuration; + options: Configuration; /** * @type {FSWatcher[]} */ @@ -1398,8 +1421,8 @@ declare class Server { * @returns {void} */ private setupApp; - /** @type {import("express").Application | undefined}*/ - app: import("express").Application | undefined; + /** @type {T | undefined}*/ + app: T | undefined; /** * @private * @param {Stats | MultiStats} statsObj @@ -1566,6 +1589,10 @@ declare class Server { declare namespace Server { export { DEFAULT_STATS, + SimpleHandleFunction, + NextHandleFunction, + ErrorHandleFunction, + HandleFunction, Schema, Compiler, MultiCompiler, @@ -1621,6 +1648,7 @@ declare namespace Server { Headers, Middleware, Configuration, + BasicApplication, }; } type Compiler = import("webpack").Compiler; @@ -1633,6 +1661,25 @@ type WebSocketServerImplementation = { declare class DEFAULT_STATS { private constructor(); } +type SimpleHandleFunction = ( + req: IncomingMessage, + res: import("http").ServerResponse, +) => void; +type NextHandleFunction = ( + req: IncomingMessage, + res: import("http").ServerResponse, + next: NextFunction, +) => void; +type ErrorHandleFunction = ( + err: any, + req: IncomingMessage, + res: import("http").ServerResponse, + next: NextFunction, +) => void; +type HandleFunction = + | SimpleHandleFunction + | NextHandleFunction + | ErrorHandleFunction; type Schema = import("schema-utils/declarations/validate").Schema; type MultiCompiler = import("webpack").MultiCompiler; type WebpackConfiguration = import("webpack").Configuration; @@ -1819,64 +1866,91 @@ type Middleware = } | ExpressRequestHandler | ExpressErrorRequestHandler; -type Configuration = { - ipc?: string | boolean | undefined; - host?: string | undefined; - port?: Port | undefined; - hot?: boolean | "only" | undefined; - liveReload?: boolean | undefined; - devMiddleware?: - | DevMiddlewareOptions< - import("express").Request< - import("express-serve-static-core").ParamsDictionary, - any, - any, - qs.ParsedQs, - Record - >, - import("express").Response> - > - | undefined; - compress?: boolean | undefined; - allowedHosts?: string | string[] | undefined; - historyApiFallback?: - | boolean - | import("connect-history-api-fallback").Options - | undefined; - bonjour?: - | boolean - | Record - | import("bonjour-service").Service - | undefined; - watchFiles?: - | string - | string[] - | WatchFiles - | (string | WatchFiles)[] - | undefined; - static?: string | boolean | Static | (string | Static)[] | undefined; - https?: boolean | ServerOptions | undefined; - http2?: boolean | undefined; - server?: string | ServerConfiguration | undefined; - webSocketServer?: string | boolean | WebSocketServerConfiguration | undefined; - proxy?: ProxyConfigArray | undefined; - open?: string | boolean | Open | (string | Open)[] | undefined; - setupExitSignals?: boolean | undefined; - client?: boolean | ClientConfiguration | undefined; - headers?: - | Headers - | (( - req: Request, - res: Response, - context: DevMiddlewareContext, - ) => Headers) - | undefined; - onListening?: ((devServer: Server) => void) | undefined; - setupMiddlewares?: - | ((middlewares: Middleware[], devServer: Server) => Middleware[]) - | undefined; +type Configuration = + { + ipc?: string | boolean | undefined; + host?: string | undefined; + port?: Port | undefined; + hot?: boolean | "only" | undefined; + liveReload?: boolean | undefined; + devMiddleware?: + | DevMiddlewareOptions< + import("express").Request< + import("express-serve-static-core").ParamsDictionary, + any, + any, + qs.ParsedQs, + Record + >, + import("express").Response> + > + | undefined; + compress?: boolean | undefined; + allowedHosts?: string | string[] | undefined; + historyApiFallback?: + | boolean + | import("connect-history-api-fallback").Options + | undefined; + bonjour?: + | boolean + | Record + | import("bonjour-service").Service + | undefined; + watchFiles?: + | string + | string[] + | WatchFiles + | (string | WatchFiles)[] + | undefined; + static?: string | boolean | Static | (string | Static)[] | undefined; + https?: boolean | ServerOptions | undefined; + http2?: boolean | undefined; + server?: string | ServerConfiguration | undefined; + webSocketServer?: + | string + | boolean + | WebSocketServerConfiguration + | undefined; + proxy?: ProxyConfigArray | undefined; + open?: string | boolean | Open | (string | Open)[] | undefined; + setupExitSignals?: boolean | undefined; + client?: boolean | ClientConfiguration | undefined; + headers?: + | Headers + | (( + req: Request, + res: Response, + context: DevMiddlewareContext, + ) => Headers) + | undefined; + onListening?: ((devServer: Server) => void) | undefined; + setupMiddlewares?: + | ((middlewares: Middleware[], devServer: Server) => Middleware[]) + | undefined; + }; +type BasicApplication = { + use: typeof useFn; }; import path = require("path"); +/** + * @overload + * @param {NextHandleFunction} fn + * @returns {BasicApplication} + */ +declare function useFn(fn: NextHandleFunction): BasicApplication; +/** + * @overload + * @param {HandleFunction} fn + * @returns {BasicApplication} + */ +declare function useFn(fn: HandleFunction): BasicApplication; +/** + * @overload + * @param {string} route + * @param {NextHandleFunction} fn + * @returns {BasicApplication} + */ +declare function useFn(route: string, fn: NextHandleFunction): BasicApplication; // DO NOT REMOVE THIS! type DevServerConfiguration = Configuration; From bd214c2d7a1d38e1775d559c47f1c8bbea4336ad Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 17 Apr 2024 19:54:24 +0300 Subject: [PATCH 07/15] test: fix --- lib/Server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Server.js b/lib/Server.js index a8ebb9de3c..d8b80665b6 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -2200,8 +2200,8 @@ class Server { if (typeof bypassUrl === "boolean") { // skip the proxy - // @ts-ignore - req.url = null; + res.statusCode = 404; + req.url = ""; next(); } else if (typeof bypassUrl === "string") { // byPass to that url From 5bf4cabf3749b0cdbe99a16c17069d6d1606a45d Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 17 Apr 2024 20:09:51 +0300 Subject: [PATCH 08/15] feat: added the `app` option to allow to use custom application --- lib/Server.js | 17 +- lib/options.json | 8 + .../validate-options.test.js.snap.webpack5 | 14 + test/e2e/app.test.js | 0 test/validate-options.test.js | 10 + types/lib/Server.d.ts | 766 +++++++++++++++--- 6 files changed, 714 insertions(+), 101 deletions(-) create mode 100644 test/e2e/app.test.js diff --git a/lib/Server.js b/lib/Server.js index d8b80665b6..f3a97d33da 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -194,6 +194,7 @@ const schema = require("./options.json"); * @property {boolean | ServerOptions} [https] * @property {boolean} [http2] * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] + * @property {() => Promise} [app] * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] * @property {ProxyConfigArray} [proxy] * @property {boolean | string | Open | Array} [open] @@ -1711,7 +1712,7 @@ class Server { } this.setupHooks(); - this.setupApp(); + await this.setupApp(); this.setupHostHeaderCheck(); this.setupDevMiddleware(); // Should be after `webpack-dev-middleware`, otherwise other middlewares might rewrite response @@ -1770,16 +1771,14 @@ class Server { /** * @private - * @returns {void} + * @returns {Promise} */ - setupApp() { - // eslint-disable-next-line import/no-extraneous-dependencies - const connect = require("connect"); - const app = connect(); - + async setupApp() { /** @type {T | undefined}*/ - this.app = /** @type {any} */ (app); - // this.app = new /** @type {any} */ (getExpress())(); + this.app = + typeof this.options.app === "function" + ? await this.options.app() + : getExpress()(); } /** diff --git a/lib/options.json b/lib/options.json index 567245ce4c..0951aefbcf 100644 --- a/lib/options.json +++ b/lib/options.json @@ -2,6 +2,11 @@ "title": "Dev Server options", "type": "object", "definitions": { + "App": { + "instanceof": "Function", + "description": "Allows to use custom applications (i.e. 'connect', 'fastify' and etc).", + "link": " https://webpack.js.org/configuration/dev-server/#devserverapp" + }, "AllowedHosts": { "anyOf": [ { @@ -997,6 +1002,9 @@ "server": { "$ref": "#/definitions/Server" }, + "app": { + "$ref": "#/definitions/App" + }, "setupExitSignals": { "$ref": "#/definitions/SetupExitSignals" }, diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack5 b/test/__snapshots__/validate-options.test.js.snap.webpack5 index 03cf17040e..60fa07786f 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack5 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack5 @@ -52,6 +52,20 @@ exports[`options validate should throw an error on the "allowedHosts" option wit * options.allowedHosts should be a non-empty string." `; +exports[`options validate should throw an error on the "app" option with 'false' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.app should be an instance of function. + -> Allows to use custom applications (i.e. 'connect', 'fastify' and etc). + -> Read more at https://webpack.js.org/configuration/dev-server/#devserverapp" +`; + +exports[`options validate should throw an error on the "app" option with 'test' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.app should be an instance of function. + -> Allows to use custom applications (i.e. 'connect', 'fastify' and etc). + -> Read more at https://webpack.js.org/configuration/dev-server/#devserverapp" +`; + exports[`options validate should throw an error on the "bonjour" option with '' value 1`] = ` "ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. - options.bonjour should be one of these: diff --git a/test/e2e/app.test.js b/test/e2e/app.test.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/validate-options.test.js b/test/validate-options.test.js index 72bf4c933e..bc170f3dc3 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -437,6 +437,16 @@ const tests = { }, ], }, + app: { + success: [ + () => require("connect")(), + async () => + new Promise((resolve) => { + resolve(require("connect")()); + }), + ], + failure: ["test", false], + }, static: { success: [ "path", diff --git a/types/lib/Server.d.ts b/types/lib/Server.d.ts index 2ac793f67e..0755079ec0 100644 --- a/types/lib/Server.d.ts +++ b/types/lib/Server.d.ts @@ -14,12 +14,183 @@ declare class Server< title: string; type: string; definitions: { + App: { + instanceof: string; + description: string; + link: string; + }; AllowedHosts: { anyOf: ( | { type: string; minItems: number; items: { + /** @typedef {import("webpack").Configuration} WebpackConfiguration */ + /** @typedef {import("webpack").StatsOptions} StatsOptions */ + /** @typedef {import("webpack").StatsCompilation} StatsCompilation */ + /** @typedef {import("webpack").Stats} Stats */ + /** @typedef {import("webpack").MultiStats} MultiStats */ + /** @typedef {import("os").NetworkInterfaceInfo} NetworkInterfaceInfo */ + /** @typedef {import("express").NextFunction} NextFunction */ + /** @typedef {import("express").RequestHandler} ExpressRequestHandler */ + /** @typedef {import("express").ErrorRequestHandler} ExpressErrorRequestHandler */ + /** @typedef {import("chokidar").WatchOptions} WatchOptions */ + /** @typedef {import("chokidar").FSWatcher} FSWatcher */ + /** @typedef {import("connect-history-api-fallback").Options} ConnectHistoryApiFallbackOptions */ + /** @typedef {import("bonjour-service").Bonjour} Bonjour */ + /** @typedef {import("bonjour-service").Service} BonjourOptions */ + /** @typedef {import("http-proxy-middleware").RequestHandler} RequestHandler */ + /** @typedef {import("http-proxy-middleware").Options} HttpProxyMiddlewareOptions */ + /** @typedef {import("http-proxy-middleware").Filter} HttpProxyMiddlewareOptionsFilter */ + /** @typedef {import("serve-index").Options} ServeIndexOptions */ + /** @typedef {import("serve-static").ServeStaticOptions} ServeStaticOptions */ + /** @typedef {import("ipaddr.js").IPv4} IPv4 */ + /** @typedef {import("ipaddr.js").IPv6} IPv6 */ + /** @typedef {import("net").Socket} Socket */ + /** @typedef {import("http").IncomingMessage} IncomingMessage */ + /** @typedef {import("http").ServerResponse} ServerResponse */ + /** @typedef {import("open").Options} OpenOptions */ + /** @typedef {import("https").ServerOptions & { spdy?: { plain?: boolean | undefined, ssl?: boolean | undefined, 'x-forwarded-for'?: string | undefined, protocol?: string | undefined, protocols?: string[] | undefined }}} ServerOptions */ + /** @typedef {import("express").Request} Request */ + /** @typedef {import("express").Response} Response */ + /** + * @template {Request} T + * @template {Response} U + * @typedef {import("webpack-dev-middleware").Options} DevMiddlewareOptions + */ + /** + * @template {Request} T + * @template {Response} U + * @typedef {import("webpack-dev-middleware").Context} DevMiddlewareContext + */ + /** + * @typedef {"local-ip" | "local-ipv4" | "local-ipv6" | string} Host + */ + /** + * @typedef {number | string | "auto"} Port + */ + /** + * @typedef {Object} WatchFiles + * @property {string | string[]} paths + * @property {WatchOptions & { aggregateTimeout?: number, ignored?: WatchOptions["ignored"], poll?: number | boolean }} [options] + */ + /** + * @typedef {Object} Static + * @property {string} [directory] + * @property {string | string[]} [publicPath] + * @property {boolean | ServeIndexOptions} [serveIndex] + * @property {ServeStaticOptions} [staticOptions] + * @property {boolean | WatchOptions & { aggregateTimeout?: number, ignored?: WatchOptions["ignored"], poll?: number | boolean }} [watch] + */ + /** + * @typedef {Object} NormalizedStatic + * @property {string} directory + * @property {string[]} publicPath + * @property {false | ServeIndexOptions} serveIndex + * @property {ServeStaticOptions} staticOptions + * @property {false | WatchOptions} watch + */ + /** + * @typedef {Object} ServerConfiguration + * @property {"http" | "https" | "spdy" | string} [type] + * @property {ServerOptions} [options] + */ + /** + * @typedef {Object} WebSocketServerConfiguration + * @property {"sockjs" | "ws" | string | Function} [type] + * @property {Record} [options] + */ + /** + * @typedef {(import("ws").WebSocket | import("sockjs").Connection & { send: import("ws").WebSocket["send"], terminate: import("ws").WebSocket["terminate"], ping: import("ws").WebSocket["ping"] }) & { isAlive?: boolean }} ClientConnection + */ + /** + * @typedef {import("ws").WebSocketServer | import("sockjs").Server & { close: import("ws").WebSocketServer["close"] }} WebSocketServer + */ + /** + * @typedef {{ implementation: WebSocketServer, clients: ClientConnection[] }} WebSocketServerImplementation + */ + /** + * @callback ByPass + * @param {Request} req + * @param {Response} res + * @param {ProxyConfigArrayItem} proxyConfig + */ + /** + * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem + */ + /** + * @typedef {(ProxyConfigArrayItem | ((req?: Request | undefined, res?: Response | undefined, next?: NextFunction | undefined) => ProxyConfigArrayItem))[]} ProxyConfigArray + */ + /** + * @typedef {Object} OpenApp + * @property {string} [name] + * @property {string[]} [arguments] + */ + /** + * @typedef {Object} Open + * @property {string | string[] | OpenApp} [app] + * @property {string | string[]} [target] + */ + /** + * @typedef {Object} NormalizedOpen + * @property {string} target + * @property {import("open").Options} options + */ + /** + * @typedef {Object} WebSocketURL + * @property {string} [hostname] + * @property {string} [password] + * @property {string} [pathname] + * @property {number | string} [port] + * @property {string} [protocol] + * @property {string} [username] + */ + /** + * @typedef {boolean | ((error: Error) => void)} OverlayMessageOptions + */ + /** + * @typedef {Object} ClientConfiguration + * @property {"log" | "info" | "warn" | "error" | "none" | "verbose"} [logging] + * @property {boolean | { warnings?: OverlayMessageOptions, errors?: OverlayMessageOptions, runtimeErrors?: OverlayMessageOptions }} [overlay] + * @property {boolean} [progress] + * @property {boolean | number} [reconnect] + * @property {"ws" | "sockjs" | string} [webSocketTransport] + * @property {string | WebSocketURL} [webSocketURL] + */ + /** + * @typedef {Array<{ key: string; value: string }> | Record} Headers + */ + /** + * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware + */ + /** + * @template {BasicApplication} [T=import("express").Application] + * @typedef {Object} Configuration + * @property {boolean | string} [ipc] + * @property {Host} [host] + * @property {Port} [port] + * @property {boolean | "only"} [hot] + * @property {boolean} [liveReload] + * @property {DevMiddlewareOptions} [devMiddleware] + * @property {boolean} [compress] + * @property {"auto" | "all" | string | string[]} [allowedHosts] + * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback] + * @property {boolean | Record | BonjourOptions} [bonjour] + * @property {string | string[] | WatchFiles | Array} [watchFiles] + * @property {boolean | string | Static | Array} [static] + * @property {boolean | ServerOptions} [https] + * @property {boolean} [http2] + * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] + * @property {() => Promise} [app] + * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] + * @property {ProxyConfigArray} [proxy] + * @property {boolean | string | Open | Array} [open] + * @property {boolean} [setupExitSignals] + * @property {boolean | ClientConfiguration} [client] + * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] + * @property {(devServer: Server) => void} [onListening] + * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] + */ $ref: string; }; enum?: undefined; @@ -58,18 +229,165 @@ declare class Server< link?: undefined; } | { - type: string /** @typedef {import("express").ErrorRequestHandler} ExpressErrorRequestHandler */; + type: string; description: string; link: string; cli?: undefined; } - )[]; + )[] /** @typedef {import("bonjour-service").Service} BonjourOptions */; description: string; link: string; }; Client: { description: string; link: string; + /** @typedef {import("ipaddr.js").IPv4} IPv4 */ + /** @typedef {import("ipaddr.js").IPv6} IPv6 */ + /** @typedef {import("net").Socket} Socket */ + /** @typedef {import("http").IncomingMessage} IncomingMessage */ + /** @typedef {import("http").ServerResponse} ServerResponse */ + /** @typedef {import("open").Options} OpenOptions */ + /** @typedef {import("https").ServerOptions & { spdy?: { plain?: boolean | undefined, ssl?: boolean | undefined, 'x-forwarded-for'?: string | undefined, protocol?: string | undefined, protocols?: string[] | undefined }}} ServerOptions */ + /** @typedef {import("express").Request} Request */ + /** @typedef {import("express").Response} Response */ + /** + * @template {Request} T + * @template {Response} U + * @typedef {import("webpack-dev-middleware").Options} DevMiddlewareOptions + */ + /** + * @template {Request} T + * @template {Response} U + * @typedef {import("webpack-dev-middleware").Context} DevMiddlewareContext + */ + /** + * @typedef {"local-ip" | "local-ipv4" | "local-ipv6" | string} Host + */ + /** + * @typedef {number | string | "auto"} Port + */ + /** + * @typedef {Object} WatchFiles + * @property {string | string[]} paths + * @property {WatchOptions & { aggregateTimeout?: number, ignored?: WatchOptions["ignored"], poll?: number | boolean }} [options] + */ + /** + * @typedef {Object} Static + * @property {string} [directory] + * @property {string | string[]} [publicPath] + * @property {boolean | ServeIndexOptions} [serveIndex] + * @property {ServeStaticOptions} [staticOptions] + * @property {boolean | WatchOptions & { aggregateTimeout?: number, ignored?: WatchOptions["ignored"], poll?: number | boolean }} [watch] + */ + /** + * @typedef {Object} NormalizedStatic + * @property {string} directory + * @property {string[]} publicPath + * @property {false | ServeIndexOptions} serveIndex + * @property {ServeStaticOptions} staticOptions + * @property {false | WatchOptions} watch + */ + /** + * @typedef {Object} ServerConfiguration + * @property {"http" | "https" | "spdy" | string} [type] + * @property {ServerOptions} [options] + */ + /** + * @typedef {Object} WebSocketServerConfiguration + * @property {"sockjs" | "ws" | string | Function} [type] + * @property {Record} [options] + */ + /** + * @typedef {(import("ws").WebSocket | import("sockjs").Connection & { send: import("ws").WebSocket["send"], terminate: import("ws").WebSocket["terminate"], ping: import("ws").WebSocket["ping"] }) & { isAlive?: boolean }} ClientConnection + */ + /** + * @typedef {import("ws").WebSocketServer | import("sockjs").Server & { close: import("ws").WebSocketServer["close"] }} WebSocketServer + */ + /** + * @typedef {{ implementation: WebSocketServer, clients: ClientConnection[] }} WebSocketServerImplementation + */ + /** + * @callback ByPass + * @param {Request} req + * @param {Response} res + * @param {ProxyConfigArrayItem} proxyConfig + */ + /** + * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem + */ + /** + * @typedef {(ProxyConfigArrayItem | ((req?: Request | undefined, res?: Response | undefined, next?: NextFunction | undefined) => ProxyConfigArrayItem))[]} ProxyConfigArray + */ + /** + * @typedef {Object} OpenApp + * @property {string} [name] + * @property {string[]} [arguments] + */ + /** + * @typedef {Object} Open + * @property {string | string[] | OpenApp} [app] + * @property {string | string[]} [target] + */ + /** + * @typedef {Object} NormalizedOpen + * @property {string} target + * @property {import("open").Options} options + */ + /** + * @typedef {Object} WebSocketURL + * @property {string} [hostname] + * @property {string} [password] + * @property {string} [pathname] + * @property {number | string} [port] + * @property {string} [protocol] + * @property {string} [username] + */ + /** + * @typedef {boolean | ((error: Error) => void)} OverlayMessageOptions + */ + /** + * @typedef {Object} ClientConfiguration + * @property {"log" | "info" | "warn" | "error" | "none" | "verbose"} [logging] + * @property {boolean | { warnings?: OverlayMessageOptions, errors?: OverlayMessageOptions, runtimeErrors?: OverlayMessageOptions }} [overlay] + * @property {boolean} [progress] + * @property {boolean | number} [reconnect] + * @property {"ws" | "sockjs" | string} [webSocketTransport] + * @property {string | WebSocketURL} [webSocketURL] + */ + /** + * @typedef {Array<{ key: string; value: string }> | Record} Headers + */ + /** + * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware + */ + /** + * @template {BasicApplication} [T=import("express").Application] + * @typedef {Object} Configuration + * @property {boolean | string} [ipc] + * @property {Host} [host] + * @property {Port} [port] + * @property {boolean | "only"} [hot] + * @property {boolean} [liveReload] + * @property {DevMiddlewareOptions} [devMiddleware] + * @property {boolean} [compress] + * @property {"auto" | "all" | string | string[]} [allowedHosts] + * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback] + * @property {boolean | Record | BonjourOptions} [bonjour] + * @property {string | string[] | WatchFiles | Array} [watchFiles] + * @property {boolean | string | Static | Array} [static] + * @property {boolean | ServerOptions} [https] + * @property {boolean} [http2] + * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] + * @property {() => Promise} [app] + * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] + * @property {ProxyConfigArray} [proxy] + * @property {boolean | string | Open | Array} [open] + * @property {boolean} [setupExitSignals] + * @property {boolean | ClientConfiguration} [client] + * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] + * @property {(devServer: Server) => void} [onListening] + * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] + */ anyOf: ( | { enum: boolean[]; @@ -85,20 +403,162 @@ declare class Server< additionalProperties: boolean; properties: { logging: { + /** @typedef {import("open").Options} OpenOptions */ + /** @typedef {import("https").ServerOptions & { spdy?: { plain?: boolean | undefined, ssl?: boolean | undefined, 'x-forwarded-for'?: string | undefined, protocol?: string | undefined, protocols?: string[] | undefined }}} ServerOptions */ + /** @typedef {import("express").Request} Request */ + /** @typedef {import("express").Response} Response */ + /** + * @template {Request} T + * @template {Response} U + * @typedef {import("webpack-dev-middleware").Options} DevMiddlewareOptions + */ + /** + * @template {Request} T + * @template {Response} U + * @typedef {import("webpack-dev-middleware").Context} DevMiddlewareContext + */ + /** + * @typedef {"local-ip" | "local-ipv4" | "local-ipv6" | string} Host + */ + /** + * @typedef {number | string | "auto"} Port + */ + /** + * @typedef {Object} WatchFiles + * @property {string | string[]} paths + * @property {WatchOptions & { aggregateTimeout?: number, ignored?: WatchOptions["ignored"], poll?: number | boolean }} [options] + */ + /** + * @typedef {Object} Static + * @property {string} [directory] + * @property {string | string[]} [publicPath] + * @property {boolean | ServeIndexOptions} [serveIndex] + * @property {ServeStaticOptions} [staticOptions] + * @property {boolean | WatchOptions & { aggregateTimeout?: number, ignored?: WatchOptions["ignored"], poll?: number | boolean }} [watch] + */ + /** + * @typedef {Object} NormalizedStatic + * @property {string} directory + * @property {string[]} publicPath + * @property {false | ServeIndexOptions} serveIndex + * @property {ServeStaticOptions} staticOptions + * @property {false | WatchOptions} watch + */ + /** + * @typedef {Object} ServerConfiguration + * @property {"http" | "https" | "spdy" | string} [type] + * @property {ServerOptions} [options] + */ + /** + * @typedef {Object} WebSocketServerConfiguration + * @property {"sockjs" | "ws" | string | Function} [type] + * @property {Record} [options] + */ + /** + * @typedef {(import("ws").WebSocket | import("sockjs").Connection & { send: import("ws").WebSocket["send"], terminate: import("ws").WebSocket["terminate"], ping: import("ws").WebSocket["ping"] }) & { isAlive?: boolean }} ClientConnection + */ + /** + * @typedef {import("ws").WebSocketServer | import("sockjs").Server & { close: import("ws").WebSocketServer["close"] }} WebSocketServer + */ + /** + * @typedef {{ implementation: WebSocketServer, clients: ClientConnection[] }} WebSocketServerImplementation + */ + /** + * @callback ByPass + * @param {Request} req + * @param {Response} res + * @param {ProxyConfigArrayItem} proxyConfig + */ + /** + * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem + */ + /** + * @typedef {(ProxyConfigArrayItem | ((req?: Request | undefined, res?: Response | undefined, next?: NextFunction | undefined) => ProxyConfigArrayItem))[]} ProxyConfigArray + */ + /** + * @typedef {Object} OpenApp + * @property {string} [name] + * @property {string[]} [arguments] + */ + /** + * @typedef {Object} Open + * @property {string | string[] | OpenApp} [app] + * @property {string | string[]} [target] + */ + /** + * @typedef {Object} NormalizedOpen + * @property {string} target + * @property {import("open").Options} options + */ + /** + * @typedef {Object} WebSocketURL + * @property {string} [hostname] + * @property {string} [password] + * @property {string} [pathname] + * @property {number | string} [port] + * @property {string} [protocol] + * @property {string} [username] + */ + /** + * @typedef {boolean | ((error: Error) => void)} OverlayMessageOptions + */ + /** + * @typedef {Object} ClientConfiguration + * @property {"log" | "info" | "warn" | "error" | "none" | "verbose"} [logging] + * @property {boolean | { warnings?: OverlayMessageOptions, errors?: OverlayMessageOptions, runtimeErrors?: OverlayMessageOptions }} [overlay] + * @property {boolean} [progress] + * @property {boolean | number} [reconnect] + * @property {"ws" | "sockjs" | string} [webSocketTransport] + * @property {string | WebSocketURL} [webSocketURL] + */ + /** + * @typedef {Array<{ key: string; value: string }> | Record} Headers + */ + /** + * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware + */ + /** + * @template {BasicApplication} [T=import("express").Application] + * @typedef {Object} Configuration + * @property {boolean | string} [ipc] + * @property {Host} [host] + * @property {Port} [port] + * @property {boolean | "only"} [hot] + * @property {boolean} [liveReload] + * @property {DevMiddlewareOptions} [devMiddleware] + * @property {boolean} [compress] + * @property {"auto" | "all" | string | string[]} [allowedHosts] + * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback] + * @property {boolean | Record | BonjourOptions} [bonjour] + * @property {string | string[] | WatchFiles | Array} [watchFiles] + * @property {boolean | string | Static | Array} [static] + * @property {boolean | ServerOptions} [https] + * @property {boolean} [http2] + * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] + * @property {() => Promise} [app] + * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] + * @property {ProxyConfigArray} [proxy] + * @property {boolean | string | Open | Array} [open] + * @property {boolean} [setupExitSignals] + * @property {boolean | ClientConfiguration} [client] + * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] + * @property {(devServer: Server) => void} [onListening] + * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] + */ + $ref: string; + }; + overlay: { + $ref: string; + }; + progress: { + $ref: string; + }; + reconnect: { + $ref: string; + }; + webSocketTransport: { $ref: string; }; - /** @typedef {import("net").Socket} Socket */ - /** @typedef {import("http").IncomingMessage} IncomingMessage */ - /** @typedef {import("http").ServerResponse} ServerResponse */ - /** @typedef {import("open").Options} OpenOptions */ - /** @typedef {import("https").ServerOptions & { spdy?: { plain?: boolean | undefined, ssl?: boolean | undefined, 'x-forwarded-for'?: string | undefined, protocol?: string | undefined, protocols?: string[] | undefined }}} ServerOptions */ - /** @typedef {import("express").Request} Request */ - /** @typedef {import("express").Response} Response */ - /** - * @template {Request} T - * @template {Response} U - * @typedef {import("webpack-dev-middleware").Options} DevMiddlewareOptions - */ /** * @template {Request} T * @template {Response} U @@ -222,6 +682,7 @@ declare class Server< * @property {boolean | ServerOptions} [https] * @property {boolean} [http2] * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] + * @property {() => Promise} [app] * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] * @property {ProxyConfigArray} [proxy] * @property {boolean | string | Open | Array} [open] @@ -231,18 +692,6 @@ declare class Server< * @property {(devServer: Server) => void} [onListening] * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] */ - overlay: { - $ref: string; - }; - progress: { - $ref: string; - }; - reconnect: { - $ref: string; - }; - webSocketTransport: { - $ref: string; - }; webSocketURL: { $ref: string; }; @@ -291,20 +740,191 @@ declare class Server< } )[]; }; + /** + * @typedef {import("ws").WebSocketServer | import("sockjs").Server & { close: import("ws").WebSocketServer["close"] }} WebSocketServer + */ + /** + * @typedef {{ implementation: WebSocketServer, clients: ClientConnection[] }} WebSocketServerImplementation + */ + /** + * @callback ByPass + * @param {Request} req + * @param {Response} res + * @param {ProxyConfigArrayItem} proxyConfig + */ + /** + * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem + */ + /** + * @typedef {(ProxyConfigArrayItem | ((req?: Request | undefined, res?: Response | undefined, next?: NextFunction | undefined) => ProxyConfigArrayItem))[]} ProxyConfigArray + */ + /** + * @typedef {Object} OpenApp + * @property {string} [name] + * @property {string[]} [arguments] + */ + /** + * @typedef {Object} Open + * @property {string | string[] | OpenApp} [app] + * @property {string | string[]} [target] + */ + /** + * @typedef {Object} NormalizedOpen + * @property {string} target + * @property {import("open").Options} options + */ + /** + * @typedef {Object} WebSocketURL + * @property {string} [hostname] + * @property {string} [password] + * @property {string} [pathname] + * @property {number | string} [port] + * @property {string} [protocol] + * @property {string} [username] + */ + /** + * @typedef {boolean | ((error: Error) => void)} OverlayMessageOptions + */ + /** + * @typedef {Object} ClientConfiguration + * @property {"log" | "info" | "warn" | "error" | "none" | "verbose"} [logging] + * @property {boolean | { warnings?: OverlayMessageOptions, errors?: OverlayMessageOptions, runtimeErrors?: OverlayMessageOptions }} [overlay] + * @property {boolean} [progress] + * @property {boolean | number} [reconnect] + * @property {"ws" | "sockjs" | string} [webSocketTransport] + * @property {string | WebSocketURL} [webSocketURL] + */ + /** + * @typedef {Array<{ key: string; value: string }> | Record} Headers + */ + /** + * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware + */ + /** + * @template {BasicApplication} [T=import("express").Application] + * @typedef {Object} Configuration + * @property {boolean | string} [ipc] + * @property {Host} [host] + * @property {Port} [port] + * @property {boolean | "only"} [hot] + * @property {boolean} [liveReload] + * @property {DevMiddlewareOptions} [devMiddleware] + * @property {boolean} [compress] + * @property {"auto" | "all" | string | string[]} [allowedHosts] + * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback] + * @property {boolean | Record | BonjourOptions} [bonjour] + * @property {string | string[] | WatchFiles | Array} [watchFiles] + * @property {boolean | string | Static | Array} [static] + * @property {boolean | ServerOptions} [https] + * @property {boolean} [http2] + * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] + * @property {() => Promise} [app] + * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] + * @property {ProxyConfigArray} [proxy] + * @property {boolean | string | Open | Array} [open] + * @property {boolean} [setupExitSignals] + * @property {boolean | ClientConfiguration} [client] + * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] + * @property {(devServer: Server) => void} [onListening] + * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] + */ warnings: { anyOf: ( | { description: string; type: string; cli: { + /** + * @typedef {{ implementation: WebSocketServer, clients: ClientConnection[] }} WebSocketServerImplementation + */ + /** + * @callback ByPass + * @param {Request} req + * @param {Response} res + * @param {ProxyConfigArrayItem} proxyConfig + */ + /** + * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem + */ + /** + * @typedef {(ProxyConfigArrayItem | ((req?: Request | undefined, res?: Response | undefined, next?: NextFunction | undefined) => ProxyConfigArrayItem))[]} ProxyConfigArray + */ + /** + * @typedef {Object} OpenApp + * @property {string} [name] + * @property {string[]} [arguments] + */ + /** + * @typedef {Object} Open + * @property {string | string[] | OpenApp} [app] + * @property {string | string[]} [target] + */ + /** + * @typedef {Object} NormalizedOpen + * @property {string} target + * @property {import("open").Options} options + */ + /** + * @typedef {Object} WebSocketURL + * @property {string} [hostname] + * @property {string} [password] + * @property {string} [pathname] + * @property {number | string} [port] + * @property {string} [protocol] + * @property {string} [username] + */ + /** + * @typedef {boolean | ((error: Error) => void)} OverlayMessageOptions + */ + /** + * @typedef {Object} ClientConfiguration + * @property {"log" | "info" | "warn" | "error" | "none" | "verbose"} [logging] + * @property {boolean | { warnings?: OverlayMessageOptions, errors?: OverlayMessageOptions, runtimeErrors?: OverlayMessageOptions }} [overlay] + * @property {boolean} [progress] + * @property {boolean | number} [reconnect] + * @property {"ws" | "sockjs" | string} [webSocketTransport] + * @property {string | WebSocketURL} [webSocketURL] + */ + /** + * @typedef {Array<{ key: string; value: string }> | Record} Headers + */ + /** + * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware + */ + /** + * @template {BasicApplication} [T=import("express").Application] + * @typedef {Object} Configuration + * @property {boolean | string} [ipc] + * @property {Host} [host] + * @property {Port} [port] + * @property {boolean | "only"} [hot] + * @property {boolean} [liveReload] + * @property {DevMiddlewareOptions} [devMiddleware] + * @property {boolean} [compress] + * @property {"auto" | "all" | string | string[]} [allowedHosts] + * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback] + * @property {boolean | Record | BonjourOptions} [bonjour] + * @property {string | string[] | WatchFiles | Array} [watchFiles] + * @property {boolean | string | Static | Array} [static] + * @property {boolean | ServerOptions} [https] + * @property {boolean} [http2] + * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] + * @property {() => Promise} [app] + * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] + * @property {ProxyConfigArray} [proxy] + * @property {boolean | string | Open | Array} [open] + * @property {boolean} [setupExitSignals] + * @property {boolean | ClientConfiguration} [client] + * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] + * @property {(devServer: Server) => void} [onListening] + * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] + */ negatedDescription: string; }; instanceof?: undefined; } | { - instanceof: string /** - * @typedef {import("ws").WebSocketServer | import("sockjs").Server & { close: import("ws").WebSocketServer["close"] }} WebSocketServer - */; + instanceof: string; description: string; type?: undefined; cli?: undefined; @@ -367,36 +987,6 @@ declare class Server< )[]; }; ClientWebSocketTransport: { - /** - * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware - */ - /** - * @template {BasicApplication} [T=import("express").Application] - * @typedef {Object} Configuration - * @property {boolean | string} [ipc] - * @property {Host} [host] - * @property {Port} [port] - * @property {boolean | "only"} [hot] - * @property {boolean} [liveReload] - * @property {DevMiddlewareOptions} [devMiddleware] - * @property {boolean} [compress] - * @property {"auto" | "all" | string | string[]} [allowedHosts] - * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback] - * @property {boolean | Record | BonjourOptions} [bonjour] - * @property {string | string[] | WatchFiles | Array} [watchFiles] - * @property {boolean | string | Static | Array} [static] - * @property {boolean | ServerOptions} [https] - * @property {boolean} [http2] - * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] - * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] - * @property {ProxyConfigArray} [proxy] - * @property {boolean | string | Open | Array} [open] - * @property {boolean} [setupExitSignals] - * @property {boolean | ClientConfiguration} [client] - * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] - * @property {(devServer: Server) => void} [onListening] - * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] - */ anyOf: { $ref: string; }[]; @@ -477,7 +1067,7 @@ declare class Server< Compress: { type: string; description: string; - link: string /** @typedef {(req: IncomingMessage, res: import("http").ServerResponse, next: NextFunction) => void} NextHandleFunction */; + link: string; cli: { negatedDescription: string; }; @@ -561,11 +1151,7 @@ declare class Server< minLength?: undefined; } | { - type: string /** - * @private - * @returns {StatsOptions} - * @constructor - */; + type: string; minLength: number; enum?: undefined; } @@ -588,7 +1174,10 @@ declare class Server< )[]; description: string; link: string; - }; + } /** + * @param {string} gateway + * @returns {string | undefined} + */; IPC: { anyOf: ( | { @@ -601,10 +1190,7 @@ declare class Server< enum: boolean[]; minLength?: undefined; } - )[] /** - * @param {string} gateway - * @returns {string | undefined} - */; + )[]; description: string; link: string; }; @@ -686,9 +1272,6 @@ declare class Server< | { type: string; minLength: number; - /** - * @type {string | undefined} - */ items?: undefined; minItems?: undefined; } @@ -776,8 +1359,9 @@ declare class Server< description: string; }; ServerType: { - enum: string[]; + enum: string[] /** @type {WebSocketURL} */; }; + /** @type {WebSocketURL} */ ServerEnum: { enum: string[]; cli: { @@ -787,12 +1371,11 @@ declare class Server< ServerString: { type: string; minLength: number; - /** @type {WebSocketURL} */ + /** @type {{ type: WebSocketServerConfiguration["type"], options: NonNullable }} */ cli: { exclude: boolean; }; }; - /** @type {ClientConfiguration} */ ServerObject: { type: string; properties: { @@ -803,7 +1386,7 @@ declare class Server< }; options: { $ref: string; - } /** @type {string} */; + }; }; additionalProperties: boolean; }; @@ -815,7 +1398,6 @@ declare class Server< type: string; description: string; }; - /** @type {ServerConfiguration} */ requestCert: { type: string; description: string; @@ -966,7 +1548,6 @@ declare class Server< additionalProperties?: undefined; } | { - /** @type {string} */ instanceof: string; type?: undefined; additionalProperties?: undefined; @@ -1068,9 +1649,10 @@ declare class Server< minItems?: undefined; } )[]; - description: string; + /** @type {MultiCompiler} */ description: string; link: string; }; + /** @type {MultiCompiler} */ serveIndex: { anyOf: ( | { @@ -1131,10 +1713,7 @@ declare class Server< type?: undefined; items?: undefined; } - )[] /** - * @param {WatchOptions & { aggregateTimeout?: number, ignored?: WatchOptions["ignored"], poll?: number | boolean }} watchOptions - * @returns {WatchOptions} - */; + )[]; description: string; link: string; }; @@ -1178,14 +1757,13 @@ declare class Server< WebSocketServer: { anyOf: { $ref: string; - }[]; + }[] /** + * @param {string | Static | undefined} [optionsForStatic] + * @returns {NormalizedStatic} + */; description: string; link: string; }; - /** - * @param {string | Static | undefined} [optionsForStatic] - * @returns {NormalizedStatic} - */ WebSocketServerType: { enum: string[]; }; @@ -1195,14 +1773,14 @@ declare class Server< enum: boolean[]; cli: { negatedDescription: string; - exclude?: undefined; + /** @type {NormalizedStatic} */ exclude?: undefined; }; } | { enum: string[]; cli: { exclude: boolean; - negatedDescription?: undefined; + negatedDescription?: undefined /** @type {NormalizedStatic} */; }; } )[]; @@ -1286,6 +1864,9 @@ declare class Server< server: { $ref: string; }; + app: { + $ref: string; + }; setupExitSignals: { $ref: string; }; @@ -1418,7 +1999,7 @@ declare class Server< private initialize; /** * @private - * @returns {void} + * @returns {Promise} */ private setupApp; /** @type {T | undefined}*/ @@ -1906,6 +2487,7 @@ type Configuration = https?: boolean | ServerOptions | undefined; http2?: boolean | undefined; server?: string | ServerConfiguration | undefined; + app?: (() => Promise) | undefined; webSocketServer?: | string | boolean From fbbc433ba589b01fffbeeae7543ab83c2d1f13b0 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Mon, 22 Apr 2024 21:34:16 +0300 Subject: [PATCH 09/15] test: fix --- lib/Server.js | 2 +- test/e2e/__snapshots__/built-in-routes.test.js.snap.webpack5 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Server.js b/lib/Server.js index f3a97d33da..198ad1013e 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -1903,7 +1903,7 @@ class Server { return; } - res.setHeader("Content-Type", "application/javascript"); + res.setHeader("Content-Type", "application/javascript; charset=UTF-8"); res.setHeader("Content-Length", stats.size); if (req.method === "HEAD") { diff --git a/test/e2e/__snapshots__/built-in-routes.test.js.snap.webpack5 b/test/e2e/__snapshots__/built-in-routes.test.js.snap.webpack5 index 963446a662..9fa4d94d12 100644 --- a/test/e2e/__snapshots__/built-in-routes.test.js.snap.webpack5 +++ b/test/e2e/__snapshots__/built-in-routes.test.js.snap.webpack5 @@ -70,7 +70,7 @@ exports[`Built in routes with simple config should handles GET request to sockjs exports[`Built in routes with simple config should handles GET request to sockjs bundle: page errors 1`] = `[]`; -exports[`Built in routes with simple config should handles GET request to sockjs bundle: response headers content-type 1`] = `"application/javascript"`; +exports[`Built in routes with simple config should handles GET request to sockjs bundle: response headers content-type 1`] = `"application/javascript; charset=UTF-8"`; exports[`Built in routes with simple config should handles GET request to sockjs bundle: response status 1`] = `200`; @@ -78,6 +78,6 @@ exports[`Built in routes with simple config should handles HEAD request to sockj exports[`Built in routes with simple config should handles HEAD request to sockjs bundle: page errors 1`] = `[]`; -exports[`Built in routes with simple config should handles HEAD request to sockjs bundle: response headers content-type 1`] = `"application/javascript"`; +exports[`Built in routes with simple config should handles HEAD request to sockjs bundle: response headers content-type 1`] = `"application/javascript; charset=UTF-8"`; exports[`Built in routes with simple config should handles HEAD request to sockjs bundle: response status 1`] = `200`; From ff3c9bb318733e69463b638e29c3868b0a5afde3 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 24 Apr 2024 16:12:53 +0300 Subject: [PATCH 10/15] test: added --- lib/Server.js | 1 - .../__snapshots__/app.test.js.snap.webpack5 | 133 ++++++++++++++++++ test/e2e/app.test.js | 108 ++++++++++++++ test/ports-map.js | 1 + 4 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 test/e2e/__snapshots__/app.test.js.snap.webpack5 diff --git a/lib/Server.js b/lib/Server.js index 198ad1013e..28ed205b7d 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -192,7 +192,6 @@ const schema = require("./options.json"); * @property {string | string[] | WatchFiles | Array} [watchFiles] * @property {boolean | string | Static | Array} [static] * @property {boolean | ServerOptions} [https] - * @property {boolean} [http2] * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] * @property {() => Promise} [app] * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] diff --git a/test/e2e/__snapshots__/app.test.js.snap.webpack5 b/test/e2e/__snapshots__/app.test.js.snap.webpack5 new file mode 100644 index 0000000000..a11edce36f --- /dev/null +++ b/test/e2e/__snapshots__/app.test.js.snap.webpack5 @@ -0,0 +1,133 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`app option should work using "connect (async)" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): console messages 1`] = `[]`; + +exports[`app option should work using "connect (async)" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): page errors 1`] = `[]`; + +exports[`app option should work using "connect (async)" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): response status 1`] = `200`; + +exports[`app option should work using "connect (async)" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`app option should work using "connect (async)" application and "http" server should handle GET request to index route (/): console messages 1`] = `[]`; + +exports[`app option should work using "connect (async)" application and "http" server should handle GET request to index route (/): page errors 1`] = `[]`; + +exports[`app option should work using "connect (async)" application and "http" server should handle GET request to index route (/): response status 1`] = `200`; + +exports[`app option should work using "connect (async)" application and "http" server should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`app option should work using "connect (async)" application and "https" server should handle GET request to index route (/): console messages 1`] = `[]`; + +exports[`app option should work using "connect (async)" application and "https" server should handle GET request to index route (/): page errors 1`] = `[]`; + +exports[`app option should work using "connect (async)" application and "https" server should handle GET request to index route (/): response status 1`] = `200`; + +exports[`app option should work using "connect (async)" application and "https" server should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`app option should work using "connect (async)" application and "spdy" server should handle GET request to index route (/): console messages 1`] = `[]`; + +exports[`app option should work using "connect (async)" application and "spdy" server should handle GET request to index route (/): page errors 1`] = `[]`; + +exports[`app option should work using "connect (async)" application and "spdy" server should handle GET request to index route (/): response status 1`] = `200`; + +exports[`app option should work using "connect (async)" application and "spdy" server should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`app option should work using "connect" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): console messages 1`] = `[]`; + +exports[`app option should work using "connect" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): page errors 1`] = `[]`; + +exports[`app option should work using "connect" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): response status 1`] = `200`; + +exports[`app option should work using "connect" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): console messages 1`] = `[]`; + +exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): page errors 1`] = `[]`; + +exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): response status 1`] = `200`; + +exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): console messages 1`] = `[]`; + +exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): page errors 1`] = `[]`; + +exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): response status 1`] = `200`; + +exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): console messages 1`] = `[]`; + +exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): page errors 1`] = `[]`; + +exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): response status 1`] = `200`; + +exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`app option should work using "express" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): console messages 1`] = `[]`; + +exports[`app option should work using "express" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): page errors 1`] = `[]`; + +exports[`app option should work using "express" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): response status 1`] = `200`; + +exports[`app option should work using "express" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): console messages 1`] = `[]`; + +exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): page errors 1`] = `[]`; + +exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): response status 1`] = `200`; + +exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): console messages 1`] = `[]`; + +exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): page errors 1`] = `[]`; + +exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): response status 1`] = `200`; + +exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): console messages 1`] = `[]`; + +exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): page errors 1`] = `[]`; + +exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): response status 1`] = `200`; + +exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; diff --git a/test/e2e/app.test.js b/test/e2e/app.test.js index e69de29bb2..89ebbf6526 100644 --- a/test/e2e/app.test.js +++ b/test/e2e/app.test.js @@ -0,0 +1,108 @@ +"use strict"; + +const path = require("path"); +const webpack = require("webpack"); +const Server = require("../../lib/Server"); +const config = require("../fixtures/static-config/webpack.config"); +const runBrowser = require("../helpers/run-browser"); +const port = require("../ports-map").app; + +const staticDirectory = path.resolve( + __dirname, + "../fixtures/static-config/public", +); + +const apps = [ + ["express", () => require("express")()], + ["connect", () => require("connect")()], + ["connect (async)", async () => require("express")()], +]; + +const servers = [ + "http", + "https", + path.resolve(__dirname, "../helpers/custom-http.js"), + "spdy", +]; + +describe("app option", () => { + for (const [appName, app] of apps) { + for (const server of servers) { + let compiler; + let devServer; + let page; + let browser; + let pageErrors; + let consoleMessages; + + describe(`should work using "${appName}" application and "${server}" server`, () => { + beforeEach(async () => { + compiler = webpack(config); + + devServer = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + app, + server, + port, + }, + compiler, + ); + + await devServer.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await devServer.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const pageUrl = + server === "https" || server === "spdy" || server === "http2" + ? `https://127.0.0.1:${port}/` + : `http://127.0.0.1:${port}/`; + + const response = await page.goto(pageUrl, { + waitUntil: "networkidle0", + }); + + const HTTPVersion = await page.evaluate( + () => performance.getEntries()[0].nextHopProtocol, + ); + + const isSpdy = server === "spdy"; + + if (isSpdy) { + expect(HTTPVersion).toEqual("h2"); + } else { + expect(HTTPVersion).toEqual("http/1.1"); + } + + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()), + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + } + } +}); diff --git a/test/ports-map.js b/test/ports-map.js index c43004298c..00eb84a7dd 100644 --- a/test/ports-map.js +++ b/test/ports-map.js @@ -80,6 +80,7 @@ const listOfTests = { "normalize-option": 1, "setup-middlewares-option": 1, "options-request-response": 2, + app: 1, }; let startPort = 8089; From 3f1944dc876012530c1fd4d74e7ec96fcc09279f Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 24 Apr 2024 16:25:46 +0300 Subject: [PATCH 11/15] refactor: fix types --- lib/Server.js | 16 +- types/lib/Server.d.ts | 562 +++++------------------------------------- 2 files changed, 66 insertions(+), 512 deletions(-) diff --git a/lib/Server.js b/lib/Server.js index 28ed205b7d..11ee94e7e4 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -18,7 +18,6 @@ const schema = require("./options.json"); /** @typedef {import("webpack").Stats} Stats */ /** @typedef {import("webpack").MultiStats} MultiStats */ /** @typedef {import("os").NetworkInterfaceInfo} NetworkInterfaceInfo */ -/** @typedef {import("express").NextFunction} NextFunction */ /** @typedef {import("express").RequestHandler} ExpressRequestHandler */ /** @typedef {import("express").ErrorRequestHandler} ExpressErrorRequestHandler */ /** @typedef {import("chokidar").WatchOptions} WatchOptions */ @@ -38,6 +37,12 @@ const schema = require("./options.json"); /** @typedef {import("http").ServerResponse} ServerResponse */ /** @typedef {import("open").Options} OpenOptions */ +/** @typedef {(err?: any) => void} NextFunction */ +/** @typedef {(req: IncomingMessage, res: ServerResponse) => void} SimpleHandleFunction */ +/** @typedef {(req: IncomingMessage, res: ServerResponse, next: NextFunction) => void} NextHandleFunction */ +/** @typedef {(err: any, req: IncomingMessage, res: ServerResponse, next: NextFunction) => void} ErrorHandleFunction */ +/** @typedef {SimpleHandleFunction | NextHandleFunction | ErrorHandleFunction} HandleFunction */ + /** @typedef {import("https").ServerOptions & { spdy?: { plain?: boolean | undefined, ssl?: boolean | undefined, 'x-forwarded-for'?: string | undefined, protocol?: string | undefined, protocols?: string[] | undefined }}} ServerOptions */ /** @typedef {import("express").Request} Request */ @@ -173,7 +178,7 @@ const schema = require("./options.json"); */ /** - * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware + * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler | HandleFunction} Middleware */ /** @@ -246,11 +251,6 @@ const encodeOverlaySettings = (setting) => ? encodeURIComponent(setting.toString()) : setting; -/** @typedef {(req: IncomingMessage, res: import("http").ServerResponse) => void} SimpleHandleFunction */ -/** @typedef {(req: IncomingMessage, res: import("http").ServerResponse, next: NextFunction) => void} NextHandleFunction */ -/** @typedef {(err: any, req: IncomingMessage, res: import("http").ServerResponse, next: NextFunction) => void} ErrorHandleFunction */ -/** @typedef {SimpleHandleFunction | NextHandleFunction | ErrorHandleFunction} HandleFunction */ - // Working for overload, because typescript doesn't support this yes /** * @overload @@ -2897,7 +2897,7 @@ class Server { headers = headers( req, res, - /** @type {import("webpack-dev-middleware").API}*/ + /** @type {import("webpack-dev-middleware").API}*/ (this.middleware).context, ); } diff --git a/types/lib/Server.d.ts b/types/lib/Server.d.ts index 0755079ec0..0e5a48c98b 100644 --- a/types/lib/Server.d.ts +++ b/types/lib/Server.d.ts @@ -31,7 +31,6 @@ declare class Server< /** @typedef {import("webpack").Stats} Stats */ /** @typedef {import("webpack").MultiStats} MultiStats */ /** @typedef {import("os").NetworkInterfaceInfo} NetworkInterfaceInfo */ - /** @typedef {import("express").NextFunction} NextFunction */ /** @typedef {import("express").RequestHandler} ExpressRequestHandler */ /** @typedef {import("express").ErrorRequestHandler} ExpressErrorRequestHandler */ /** @typedef {import("chokidar").WatchOptions} WatchOptions */ @@ -50,6 +49,11 @@ declare class Server< /** @typedef {import("http").IncomingMessage} IncomingMessage */ /** @typedef {import("http").ServerResponse} ServerResponse */ /** @typedef {import("open").Options} OpenOptions */ + /** @typedef {(err?: any) => void} NextFunction */ + /** @typedef {(req: IncomingMessage, res: ServerResponse) => void} SimpleHandleFunction */ + /** @typedef {(req: IncomingMessage, res: ServerResponse, next: NextFunction) => void} NextHandleFunction */ + /** @typedef {(err: any, req: IncomingMessage, res: ServerResponse, next: NextFunction) => void} ErrorHandleFunction */ + /** @typedef {SimpleHandleFunction | NextHandleFunction | ErrorHandleFunction} HandleFunction */ /** @typedef {import("https").ServerOptions & { spdy?: { plain?: boolean | undefined, ssl?: boolean | undefined, 'x-forwarded-for'?: string | undefined, protocol?: string | undefined, protocols?: string[] | undefined }}} ServerOptions */ /** @typedef {import("express").Request} Request */ /** @typedef {import("express").Response} Response */ @@ -161,7 +165,7 @@ declare class Server< * @typedef {Array<{ key: string; value: string }> | Record} Headers */ /** - * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware + * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler | HandleFunction} Middleware */ /** * @template {BasicApplication} [T=import("express").Application] @@ -179,7 +183,6 @@ declare class Server< * @property {string | string[] | WatchFiles | Array} [watchFiles] * @property {boolean | string | Static | Array} [static] * @property {boolean | ServerOptions} [https] - * @property {boolean} [http2] * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] * @property {() => Promise} [app] * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] @@ -234,160 +237,13 @@ declare class Server< link: string; cli?: undefined; } - )[] /** @typedef {import("bonjour-service").Service} BonjourOptions */; + )[]; description: string; link: string; }; Client: { description: string; link: string; - /** @typedef {import("ipaddr.js").IPv4} IPv4 */ - /** @typedef {import("ipaddr.js").IPv6} IPv6 */ - /** @typedef {import("net").Socket} Socket */ - /** @typedef {import("http").IncomingMessage} IncomingMessage */ - /** @typedef {import("http").ServerResponse} ServerResponse */ - /** @typedef {import("open").Options} OpenOptions */ - /** @typedef {import("https").ServerOptions & { spdy?: { plain?: boolean | undefined, ssl?: boolean | undefined, 'x-forwarded-for'?: string | undefined, protocol?: string | undefined, protocols?: string[] | undefined }}} ServerOptions */ - /** @typedef {import("express").Request} Request */ - /** @typedef {import("express").Response} Response */ - /** - * @template {Request} T - * @template {Response} U - * @typedef {import("webpack-dev-middleware").Options} DevMiddlewareOptions - */ - /** - * @template {Request} T - * @template {Response} U - * @typedef {import("webpack-dev-middleware").Context} DevMiddlewareContext - */ - /** - * @typedef {"local-ip" | "local-ipv4" | "local-ipv6" | string} Host - */ - /** - * @typedef {number | string | "auto"} Port - */ - /** - * @typedef {Object} WatchFiles - * @property {string | string[]} paths - * @property {WatchOptions & { aggregateTimeout?: number, ignored?: WatchOptions["ignored"], poll?: number | boolean }} [options] - */ - /** - * @typedef {Object} Static - * @property {string} [directory] - * @property {string | string[]} [publicPath] - * @property {boolean | ServeIndexOptions} [serveIndex] - * @property {ServeStaticOptions} [staticOptions] - * @property {boolean | WatchOptions & { aggregateTimeout?: number, ignored?: WatchOptions["ignored"], poll?: number | boolean }} [watch] - */ - /** - * @typedef {Object} NormalizedStatic - * @property {string} directory - * @property {string[]} publicPath - * @property {false | ServeIndexOptions} serveIndex - * @property {ServeStaticOptions} staticOptions - * @property {false | WatchOptions} watch - */ - /** - * @typedef {Object} ServerConfiguration - * @property {"http" | "https" | "spdy" | string} [type] - * @property {ServerOptions} [options] - */ - /** - * @typedef {Object} WebSocketServerConfiguration - * @property {"sockjs" | "ws" | string | Function} [type] - * @property {Record} [options] - */ - /** - * @typedef {(import("ws").WebSocket | import("sockjs").Connection & { send: import("ws").WebSocket["send"], terminate: import("ws").WebSocket["terminate"], ping: import("ws").WebSocket["ping"] }) & { isAlive?: boolean }} ClientConnection - */ - /** - * @typedef {import("ws").WebSocketServer | import("sockjs").Server & { close: import("ws").WebSocketServer["close"] }} WebSocketServer - */ - /** - * @typedef {{ implementation: WebSocketServer, clients: ClientConnection[] }} WebSocketServerImplementation - */ - /** - * @callback ByPass - * @param {Request} req - * @param {Response} res - * @param {ProxyConfigArrayItem} proxyConfig - */ - /** - * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem - */ - /** - * @typedef {(ProxyConfigArrayItem | ((req?: Request | undefined, res?: Response | undefined, next?: NextFunction | undefined) => ProxyConfigArrayItem))[]} ProxyConfigArray - */ - /** - * @typedef {Object} OpenApp - * @property {string} [name] - * @property {string[]} [arguments] - */ - /** - * @typedef {Object} Open - * @property {string | string[] | OpenApp} [app] - * @property {string | string[]} [target] - */ - /** - * @typedef {Object} NormalizedOpen - * @property {string} target - * @property {import("open").Options} options - */ - /** - * @typedef {Object} WebSocketURL - * @property {string} [hostname] - * @property {string} [password] - * @property {string} [pathname] - * @property {number | string} [port] - * @property {string} [protocol] - * @property {string} [username] - */ - /** - * @typedef {boolean | ((error: Error) => void)} OverlayMessageOptions - */ - /** - * @typedef {Object} ClientConfiguration - * @property {"log" | "info" | "warn" | "error" | "none" | "verbose"} [logging] - * @property {boolean | { warnings?: OverlayMessageOptions, errors?: OverlayMessageOptions, runtimeErrors?: OverlayMessageOptions }} [overlay] - * @property {boolean} [progress] - * @property {boolean | number} [reconnect] - * @property {"ws" | "sockjs" | string} [webSocketTransport] - * @property {string | WebSocketURL} [webSocketURL] - */ - /** - * @typedef {Array<{ key: string; value: string }> | Record} Headers - */ - /** - * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware - */ - /** - * @template {BasicApplication} [T=import("express").Application] - * @typedef {Object} Configuration - * @property {boolean | string} [ipc] - * @property {Host} [host] - * @property {Port} [port] - * @property {boolean | "only"} [hot] - * @property {boolean} [liveReload] - * @property {DevMiddlewareOptions} [devMiddleware] - * @property {boolean} [compress] - * @property {"auto" | "all" | string | string[]} [allowedHosts] - * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback] - * @property {boolean | Record | BonjourOptions} [bonjour] - * @property {string | string[] | WatchFiles | Array} [watchFiles] - * @property {boolean | string | Static | Array} [static] - * @property {boolean | ServerOptions} [https] - * @property {boolean} [http2] - * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] - * @property {() => Promise} [app] - * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] - * @property {ProxyConfigArray} [proxy] - * @property {boolean | string | Open | Array} [open] - * @property {boolean} [setupExitSignals] - * @property {boolean | ClientConfiguration} [client] - * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] - * @property {(devServer: Server) => void} [onListening] - * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] - */ anyOf: ( | { enum: boolean[]; @@ -404,6 +260,11 @@ declare class Server< properties: { logging: { /** @typedef {import("open").Options} OpenOptions */ + /** @typedef {(err?: any) => void} NextFunction */ + /** @typedef {(req: IncomingMessage, res: ServerResponse) => void} SimpleHandleFunction */ + /** @typedef {(req: IncomingMessage, res: ServerResponse, next: NextFunction) => void} NextHandleFunction */ + /** @typedef {(err: any, req: IncomingMessage, res: ServerResponse, next: NextFunction) => void} ErrorHandleFunction */ + /** @typedef {SimpleHandleFunction | NextHandleFunction | ErrorHandleFunction} HandleFunction */ /** @typedef {import("https").ServerOptions & { spdy?: { plain?: boolean | undefined, ssl?: boolean | undefined, 'x-forwarded-for'?: string | undefined, protocol?: string | undefined, protocols?: string[] | undefined }}} ServerOptions */ /** @typedef {import("express").Request} Request */ /** @typedef {import("express").Response} Response */ @@ -515,7 +376,7 @@ declare class Server< * @typedef {Array<{ key: string; value: string }> | Record} Headers */ /** - * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware + * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler | HandleFunction} Middleware */ /** * @template {BasicApplication} [T=import("express").Application] @@ -533,7 +394,6 @@ declare class Server< * @property {string | string[] | WatchFiles | Array} [watchFiles] * @property {boolean | string | Static | Array} [static] * @property {boolean | ServerOptions} [https] - * @property {boolean} [http2] * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] * @property {() => Promise} [app] * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] @@ -559,139 +419,6 @@ declare class Server< webSocketTransport: { $ref: string; }; - /** - * @template {Request} T - * @template {Response} U - * @typedef {import("webpack-dev-middleware").Context} DevMiddlewareContext - */ - /** - * @typedef {"local-ip" | "local-ipv4" | "local-ipv6" | string} Host - */ - /** - * @typedef {number | string | "auto"} Port - */ - /** - * @typedef {Object} WatchFiles - * @property {string | string[]} paths - * @property {WatchOptions & { aggregateTimeout?: number, ignored?: WatchOptions["ignored"], poll?: number | boolean }} [options] - */ - /** - * @typedef {Object} Static - * @property {string} [directory] - * @property {string | string[]} [publicPath] - * @property {boolean | ServeIndexOptions} [serveIndex] - * @property {ServeStaticOptions} [staticOptions] - * @property {boolean | WatchOptions & { aggregateTimeout?: number, ignored?: WatchOptions["ignored"], poll?: number | boolean }} [watch] - */ - /** - * @typedef {Object} NormalizedStatic - * @property {string} directory - * @property {string[]} publicPath - * @property {false | ServeIndexOptions} serveIndex - * @property {ServeStaticOptions} staticOptions - * @property {false | WatchOptions} watch - */ - /** - * @typedef {Object} ServerConfiguration - * @property {"http" | "https" | "spdy" | string} [type] - * @property {ServerOptions} [options] - */ - /** - * @typedef {Object} WebSocketServerConfiguration - * @property {"sockjs" | "ws" | string | Function} [type] - * @property {Record} [options] - */ - /** - * @typedef {(import("ws").WebSocket | import("sockjs").Connection & { send: import("ws").WebSocket["send"], terminate: import("ws").WebSocket["terminate"], ping: import("ws").WebSocket["ping"] }) & { isAlive?: boolean }} ClientConnection - */ - /** - * @typedef {import("ws").WebSocketServer | import("sockjs").Server & { close: import("ws").WebSocketServer["close"] }} WebSocketServer - */ - /** - * @typedef {{ implementation: WebSocketServer, clients: ClientConnection[] }} WebSocketServerImplementation - */ - /** - * @callback ByPass - * @param {Request} req - * @param {Response} res - * @param {ProxyConfigArrayItem} proxyConfig - */ - /** - * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem - */ - /** - * @typedef {(ProxyConfigArrayItem | ((req?: Request | undefined, res?: Response | undefined, next?: NextFunction | undefined) => ProxyConfigArrayItem))[]} ProxyConfigArray - */ - /** - * @typedef {Object} OpenApp - * @property {string} [name] - * @property {string[]} [arguments] - */ - /** - * @typedef {Object} Open - * @property {string | string[] | OpenApp} [app] - * @property {string | string[]} [target] - */ - /** - * @typedef {Object} NormalizedOpen - * @property {string} target - * @property {import("open").Options} options - */ - /** - * @typedef {Object} WebSocketURL - * @property {string} [hostname] - * @property {string} [password] - * @property {string} [pathname] - * @property {number | string} [port] - * @property {string} [protocol] - * @property {string} [username] - */ - /** - * @typedef {boolean | ((error: Error) => void)} OverlayMessageOptions - */ - /** - * @typedef {Object} ClientConfiguration - * @property {"log" | "info" | "warn" | "error" | "none" | "verbose"} [logging] - * @property {boolean | { warnings?: OverlayMessageOptions, errors?: OverlayMessageOptions, runtimeErrors?: OverlayMessageOptions }} [overlay] - * @property {boolean} [progress] - * @property {boolean | number} [reconnect] - * @property {"ws" | "sockjs" | string} [webSocketTransport] - * @property {string | WebSocketURL} [webSocketURL] - */ - /** - * @typedef {Array<{ key: string; value: string }> | Record} Headers - */ - /** - * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware - */ - /** - * @template {BasicApplication} [T=import("express").Application] - * @typedef {Object} Configuration - * @property {boolean | string} [ipc] - * @property {Host} [host] - * @property {Port} [port] - * @property {boolean | "only"} [hot] - * @property {boolean} [liveReload] - * @property {DevMiddlewareOptions} [devMiddleware] - * @property {boolean} [compress] - * @property {"auto" | "all" | string | string[]} [allowedHosts] - * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback] - * @property {boolean | Record | BonjourOptions} [bonjour] - * @property {string | string[] | WatchFiles | Array} [watchFiles] - * @property {boolean | string | Static | Array} [static] - * @property {boolean | ServerOptions} [https] - * @property {boolean} [http2] - * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] - * @property {() => Promise} [app] - * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] - * @property {ProxyConfigArray} [proxy] - * @property {boolean | string | Open | Array} [open] - * @property {boolean} [setupExitSignals] - * @property {boolean | ClientConfiguration} [client] - * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] - * @property {(devServer: Server) => void} [onListening] - * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] - */ webSocketURL: { $ref: string; }; @@ -740,185 +467,12 @@ declare class Server< } )[]; }; - /** - * @typedef {import("ws").WebSocketServer | import("sockjs").Server & { close: import("ws").WebSocketServer["close"] }} WebSocketServer - */ - /** - * @typedef {{ implementation: WebSocketServer, clients: ClientConnection[] }} WebSocketServerImplementation - */ - /** - * @callback ByPass - * @param {Request} req - * @param {Response} res - * @param {ProxyConfigArrayItem} proxyConfig - */ - /** - * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem - */ - /** - * @typedef {(ProxyConfigArrayItem | ((req?: Request | undefined, res?: Response | undefined, next?: NextFunction | undefined) => ProxyConfigArrayItem))[]} ProxyConfigArray - */ - /** - * @typedef {Object} OpenApp - * @property {string} [name] - * @property {string[]} [arguments] - */ - /** - * @typedef {Object} Open - * @property {string | string[] | OpenApp} [app] - * @property {string | string[]} [target] - */ - /** - * @typedef {Object} NormalizedOpen - * @property {string} target - * @property {import("open").Options} options - */ - /** - * @typedef {Object} WebSocketURL - * @property {string} [hostname] - * @property {string} [password] - * @property {string} [pathname] - * @property {number | string} [port] - * @property {string} [protocol] - * @property {string} [username] - */ - /** - * @typedef {boolean | ((error: Error) => void)} OverlayMessageOptions - */ - /** - * @typedef {Object} ClientConfiguration - * @property {"log" | "info" | "warn" | "error" | "none" | "verbose"} [logging] - * @property {boolean | { warnings?: OverlayMessageOptions, errors?: OverlayMessageOptions, runtimeErrors?: OverlayMessageOptions }} [overlay] - * @property {boolean} [progress] - * @property {boolean | number} [reconnect] - * @property {"ws" | "sockjs" | string} [webSocketTransport] - * @property {string | WebSocketURL} [webSocketURL] - */ - /** - * @typedef {Array<{ key: string; value: string }> | Record} Headers - */ - /** - * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware - */ - /** - * @template {BasicApplication} [T=import("express").Application] - * @typedef {Object} Configuration - * @property {boolean | string} [ipc] - * @property {Host} [host] - * @property {Port} [port] - * @property {boolean | "only"} [hot] - * @property {boolean} [liveReload] - * @property {DevMiddlewareOptions} [devMiddleware] - * @property {boolean} [compress] - * @property {"auto" | "all" | string | string[]} [allowedHosts] - * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback] - * @property {boolean | Record | BonjourOptions} [bonjour] - * @property {string | string[] | WatchFiles | Array} [watchFiles] - * @property {boolean | string | Static | Array} [static] - * @property {boolean | ServerOptions} [https] - * @property {boolean} [http2] - * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] - * @property {() => Promise} [app] - * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] - * @property {ProxyConfigArray} [proxy] - * @property {boolean | string | Open | Array} [open] - * @property {boolean} [setupExitSignals] - * @property {boolean | ClientConfiguration} [client] - * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] - * @property {(devServer: Server) => void} [onListening] - * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] - */ warnings: { anyOf: ( | { description: string; type: string; cli: { - /** - * @typedef {{ implementation: WebSocketServer, clients: ClientConnection[] }} WebSocketServerImplementation - */ - /** - * @callback ByPass - * @param {Request} req - * @param {Response} res - * @param {ProxyConfigArrayItem} proxyConfig - */ - /** - * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem - */ - /** - * @typedef {(ProxyConfigArrayItem | ((req?: Request | undefined, res?: Response | undefined, next?: NextFunction | undefined) => ProxyConfigArrayItem))[]} ProxyConfigArray - */ - /** - * @typedef {Object} OpenApp - * @property {string} [name] - * @property {string[]} [arguments] - */ - /** - * @typedef {Object} Open - * @property {string | string[] | OpenApp} [app] - * @property {string | string[]} [target] - */ - /** - * @typedef {Object} NormalizedOpen - * @property {string} target - * @property {import("open").Options} options - */ - /** - * @typedef {Object} WebSocketURL - * @property {string} [hostname] - * @property {string} [password] - * @property {string} [pathname] - * @property {number | string} [port] - * @property {string} [protocol] - * @property {string} [username] - */ - /** - * @typedef {boolean | ((error: Error) => void)} OverlayMessageOptions - */ - /** - * @typedef {Object} ClientConfiguration - * @property {"log" | "info" | "warn" | "error" | "none" | "verbose"} [logging] - * @property {boolean | { warnings?: OverlayMessageOptions, errors?: OverlayMessageOptions, runtimeErrors?: OverlayMessageOptions }} [overlay] - * @property {boolean} [progress] - * @property {boolean | number} [reconnect] - * @property {"ws" | "sockjs" | string} [webSocketTransport] - * @property {string | WebSocketURL} [webSocketURL] - */ - /** - * @typedef {Array<{ key: string; value: string }> | Record} Headers - */ - /** - * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler} Middleware - */ - /** - * @template {BasicApplication} [T=import("express").Application] - * @typedef {Object} Configuration - * @property {boolean | string} [ipc] - * @property {Host} [host] - * @property {Port} [port] - * @property {boolean | "only"} [hot] - * @property {boolean} [liveReload] - * @property {DevMiddlewareOptions} [devMiddleware] - * @property {boolean} [compress] - * @property {"auto" | "all" | string | string[]} [allowedHosts] - * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback] - * @property {boolean | Record | BonjourOptions} [bonjour] - * @property {string | string[] | WatchFiles | Array} [watchFiles] - * @property {boolean | string | Static | Array} [static] - * @property {boolean | ServerOptions} [https] - * @property {boolean} [http2] - * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] - * @property {() => Promise} [app] - * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] - * @property {ProxyConfigArray} [proxy] - * @property {boolean | string | Open | Array} [open] - * @property {boolean} [setupExitSignals] - * @property {boolean | ClientConfiguration} [client] - * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] - * @property {(devServer: Server) => void} [onListening] - * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] - */ negatedDescription: string; }; instanceof?: undefined; @@ -1119,6 +673,9 @@ declare class Server< } )[]; description: string; + /** + * @type {ReturnType} + * */ link: string; }; HistoryApiFallback: { @@ -1174,10 +731,7 @@ declare class Server< )[]; description: string; link: string; - } /** - * @param {string} gateway - * @returns {string | undefined} - */; + }; IPC: { anyOf: ( | { @@ -1263,6 +817,9 @@ declare class Server< | { type: string; items: { + /** + * @type {string | undefined} + */ type: string; minLength: number; }; @@ -1356,22 +913,22 @@ declare class Server< $ref: string; }[]; link: string; - description: string; + description: string /** @type {WebSocketURL} */; }; + /** @type {WebSocketURL} */ ServerType: { - enum: string[] /** @type {WebSocketURL} */; + enum: string[]; }; - /** @type {WebSocketURL} */ ServerEnum: { enum: string[]; cli: { exclude: boolean; }; }; + /** @type {{ type: WebSocketServerConfiguration["type"], options: NonNullable }} */ ServerString: { type: string; minLength: number; - /** @type {{ type: WebSocketServerConfiguration["type"], options: NonNullable }} */ cli: { exclude: boolean; }; @@ -1388,6 +945,7 @@ declare class Server< $ref: string; }; }; + /** @type {ServerConfiguration} */ additionalProperties: boolean; }; ServerOptions: { @@ -1481,7 +1039,7 @@ declare class Server< instanceof: string; type?: undefined; } - )[]; + )[] /** @type {number | string} */; }; instanceof?: undefined; } @@ -1649,10 +1207,9 @@ declare class Server< minItems?: undefined; } )[]; - /** @type {MultiCompiler} */ description: string; + description: string; link: string; }; - /** @type {MultiCompiler} */ serveIndex: { anyOf: ( | { @@ -1695,7 +1252,10 @@ declare class Server< }; StaticString: { type: string; - minLength: number; + minLength: number /** + * @private + * @returns {Promise} + */; }; WatchFiles: { anyOf: ( @@ -1757,10 +1317,7 @@ declare class Server< WebSocketServer: { anyOf: { $ref: string; - }[] /** - * @param {string | Static | undefined} [optionsForStatic] - * @returns {NormalizedStatic} - */; + }[]; description: string; link: string; }; @@ -1773,14 +1330,14 @@ declare class Server< enum: boolean[]; cli: { negatedDescription: string; - /** @type {NormalizedStatic} */ exclude?: undefined; + exclude?: undefined; }; } | { enum: string[]; cli: { exclude: boolean; - negatedDescription?: undefined /** @type {NormalizedStatic} */; + negatedDescription?: undefined; }; } )[]; @@ -2170,10 +1727,6 @@ declare class Server< declare namespace Server { export { DEFAULT_STATS, - SimpleHandleFunction, - NextHandleFunction, - ErrorHandleFunction, - HandleFunction, Schema, Compiler, MultiCompiler, @@ -2183,7 +1736,6 @@ declare namespace Server { Stats, MultiStats, NetworkInterfaceInfo, - NextFunction, ExpressRequestHandler, ExpressErrorRequestHandler, WatchOptions, @@ -2202,6 +1754,11 @@ declare namespace Server { IncomingMessage, ServerResponse, OpenOptions, + NextFunction, + SimpleHandleFunction, + NextHandleFunction, + ErrorHandleFunction, + HandleFunction, ServerOptions, Request, Response, @@ -2242,25 +1799,6 @@ type WebSocketServerImplementation = { declare class DEFAULT_STATS { private constructor(); } -type SimpleHandleFunction = ( - req: IncomingMessage, - res: import("http").ServerResponse, -) => void; -type NextHandleFunction = ( - req: IncomingMessage, - res: import("http").ServerResponse, - next: NextFunction, -) => void; -type ErrorHandleFunction = ( - err: any, - req: IncomingMessage, - res: import("http").ServerResponse, - next: NextFunction, -) => void; -type HandleFunction = - | SimpleHandleFunction - | NextHandleFunction - | ErrorHandleFunction; type Schema = import("schema-utils/declarations/validate").Schema; type MultiCompiler = import("webpack").MultiCompiler; type WebpackConfiguration = import("webpack").Configuration; @@ -2269,7 +1807,6 @@ type StatsCompilation = import("webpack").StatsCompilation; type Stats = import("webpack").Stats; type MultiStats = import("webpack").MultiStats; type NetworkInterfaceInfo = import("os").NetworkInterfaceInfo; -type NextFunction = import("express").NextFunction; type ExpressRequestHandler = import("express").RequestHandler; type ExpressErrorRequestHandler = import("express").ErrorRequestHandler; type WatchOptions = import("chokidar").WatchOptions; @@ -2287,6 +1824,23 @@ type IPv6 = import("ipaddr.js").IPv6; type IncomingMessage = import("http").IncomingMessage; type ServerResponse = import("http").ServerResponse; type OpenOptions = import("open").Options; +type NextFunction = (err?: any) => void; +type SimpleHandleFunction = (req: IncomingMessage, res: ServerResponse) => void; +type NextHandleFunction = ( + req: IncomingMessage, + res: ServerResponse, + next: NextFunction, +) => void; +type ErrorHandleFunction = ( + err: any, + req: IncomingMessage, + res: ServerResponse, + next: NextFunction, +) => void; +type HandleFunction = + | SimpleHandleFunction + | NextHandleFunction + | ErrorHandleFunction; type ServerOptions = import("https").ServerOptions & { spdy?: { plain?: boolean | undefined; @@ -2446,7 +2000,8 @@ type Middleware = middleware: ExpressRequestHandler | ExpressErrorRequestHandler; } | ExpressRequestHandler - | ExpressErrorRequestHandler; + | ExpressErrorRequestHandler + | HandleFunction; type Configuration = { ipc?: string | boolean | undefined; @@ -2485,7 +2040,6 @@ type Configuration = | undefined; static?: string | boolean | Static | (string | Static)[] | undefined; https?: boolean | ServerOptions | undefined; - http2?: boolean | undefined; server?: string | ServerConfiguration | undefined; app?: (() => Promise) | undefined; webSocketServer?: From 2f24eb67e748e53001e2f9e2b570646dbe6d8f10 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 24 Apr 2024 16:37:20 +0300 Subject: [PATCH 12/15] chore: deps update --- package-lock.json | 427 +++++++++++++++++++++--------------------- package.json | 4 +- types/lib/Server.d.ts | 1 - 3 files changed, 217 insertions(+), 215 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6768e193b2..2dd73df4f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,7 +65,7 @@ "connect": "^3.7.0", "core-js": "^3.31.0", "cspell": "^8.3.2", - "css-loader": "^6.8.1", + "css-loader": "^7.1.1", "eslint": "^8.43.0", "eslint-config-prettier": "^9.1.0", "eslint-config-webpack": "^1.2.5", @@ -91,7 +91,7 @@ "sockjs-client": "^1.6.1", "standard-version": "^9.3.0", "strip-ansi-v6": "npm:strip-ansi@^6.0.0", - "style-loader": "^3.3.1", + "style-loader": "^4.0.0", "supertest": "^6.1.3", "tcp-port-used": "^1.0.2", "typescript": "^5.3.3", @@ -336,9 +336,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", - "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -1943,12 +1943,12 @@ "dev": true }, "node_modules/@commitlint/cli": { - "version": "19.2.2", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.2.2.tgz", - "integrity": "sha512-P8cbOHfg2PQRzfICLSrzUVOCVMqjEZ8Hlth6mtJ4yOEjT47Q5PbIGymgX3rLVylNw+3IAT2Djn9IJ2wHbXFzBg==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.3.0.tgz", + "integrity": "sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==", "dev": true, "dependencies": { - "@commitlint/format": "^19.0.3", + "@commitlint/format": "^19.3.0", "@commitlint/lint": "^19.2.2", "@commitlint/load": "^19.2.0", "@commitlint/read": "^19.2.1", @@ -2098,9 +2098,9 @@ } }, "node_modules/@commitlint/config-conventional": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.1.0.tgz", - "integrity": "sha512-KIKD2xrp6Uuk+dcZVj3++MlzIr/Su6zLE8crEDQCZNvWHNQSeeGbzOlNtsR32TUy6H3JbP7nWgduAHCaiGQ6EA==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.2.2.tgz", + "integrity": "sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==", "dev": true, "dependencies": { "@commitlint/types": "^19.0.3", @@ -2150,9 +2150,9 @@ } }, "node_modules/@commitlint/format": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.0.3.tgz", - "integrity": "sha512-QjjyGyoiVWzx1f5xOteKHNLFyhyweVifMgopozSgx1fGNrGV8+wp7k6n1t6StHdJ6maQJ+UUtO2TcEiBFRyR6Q==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.3.0.tgz", + "integrity": "sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==", "dev": true, "dependencies": { "@commitlint/types": "^19.0.3", @@ -2852,9 +2852,9 @@ "dev": true }, "node_modules/@cspell/dict-en_us": { - "version": "4.3.17", - "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.3.17.tgz", - "integrity": "sha512-CS0Tb2f2YwQZ4VZ6+WLAO5uOzb0iO/iYSRl34kX4enq6quXxLYzwdfGAwv85wSYHPdga8tGiZFP+p8GPsi2JEg==", + "version": "4.3.19", + "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.3.19.tgz", + "integrity": "sha512-tHcXdkmm0t9LlRct1vgu3+h0KW/wlXCInkTiR4D/rl730q1zu2qVEgiy1saMiTUSNmdu7Hiy+Mhb+1braVqnZQ==", "dev": true }, "node_modules/@cspell/dict-en-common-misspellings": { @@ -3041,9 +3041,9 @@ "dev": true }, "node_modules/@cspell/dict-software-terms": { - "version": "3.3.18", - "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-3.3.18.tgz", - "integrity": "sha512-LJZGGMGqS8KzgXJrSMs3T+6GoqHG9z8Bc+rqLzLzbtoR3FbsMasE9U8oP2PmS3q7jJLFjQkzmg508DrcuZuo2g==", + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-3.3.20.tgz", + "integrity": "sha512-KmPwCxYWEu7SGyT/0m/n6i6R4ZgxbmN3XcerzA6Z629Wm5iZTVfJaMWqDK2RKAyBawS7OMfxGz0W/wYU4FhJlA==", "dev": true }, "node_modules/@cspell/dict-sql": { @@ -3071,9 +3071,9 @@ "dev": true }, "node_modules/@cspell/dict-typescript": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.1.2.tgz", - "integrity": "sha512-lcNOYWjLUvDZdLa0UMNd/LwfVdxhE9rKA+agZBGjL3lTA3uNvH7IUqSJM/IXhJoBpLLMVEOk8v1N9xi+vDuCdA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.1.4.tgz", + "integrity": "sha512-jUcPa0rsPca5ur1+G56DXnSc5hbbJkzvPHHvyQtkbPXBQd3CXPMNfrTVCgzex/7cY/7FONcpFCUwgwfni9Jqbw==", "dev": true }, "node_modules/@cspell/dict-vue": { @@ -3275,9 +3275,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, "node_modules/@hutson/parse-repository-url": { @@ -4267,9 +4267,9 @@ } }, "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" }, "node_modules/@nicolo-ribaudo/chokidar-2": { "version": "2.1.8-no-fsevents.3", @@ -4526,9 +4526,9 @@ "dev": true }, "node_modules/@types/eslint": { - "version": "8.56.6", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", - "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", "devOptional": true, "dependencies": { "@types/estree": "*", @@ -4563,9 +4563,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.43", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", - "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz", + "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -4681,9 +4681,9 @@ "dev": true }, "node_modules/@types/qs": { - "version": "6.9.13", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.13.tgz", - "integrity": "sha512-iLR+1vTTJ3p0QaOUq6ACbY1mzKTODFDT/XedZI8BksOotFmL4ForwDfRQ/DZeuTHR7/2i4lI1D203gdfxuqTlA==" + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" }, "node_modules/@types/range-parser": { "version": "1.2.7", @@ -5234,15 +5234,16 @@ "dev": true }, "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -5539,13 +5540,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", - "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.1", + "@babel/helper-define-polyfill-provider": "^0.6.2", "semver": "^6.3.1" }, "peerDependencies": { @@ -5566,12 +5567,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", - "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1" + "@babel/helper-define-polyfill-provider": "^0.6.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -5630,21 +5631,21 @@ "optional": true }, "node_modules/bare-fs": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.2.3.tgz", - "integrity": "sha512-amG72llr9pstfXOBOHve1WjiuKKAMnebcmMbPWDZ7BCevAoJLpugjuAPRsDINEyjT0a6tbaVx3DctkXIRbLuJw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.0.tgz", + "integrity": "sha512-TNFqa1B4N99pds2a5NYHR15o0ZpdNKbAeKTE/+G6ED/UeOavv8RY3dr/Fu99HW3zU3pXpo2kDNO8Sjsm2esfOw==", "dev": true, "optional": true, "dependencies": { "bare-events": "^2.0.0", "bare-path": "^2.0.0", - "streamx": "^2.13.0" + "bare-stream": "^1.0.0" } }, "node_modules/bare-os": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.2.1.tgz", - "integrity": "sha512-OwPyHgBBMkhC29Hl3O4/YfxW9n7mdTr2+SsO29XBWKKJsbgj3mnorDB80r5TiCQgQstgE5ga1qNYrpes6NvX2w==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.3.0.tgz", + "integrity": "sha512-oPb8oMM1xZbhRQBngTgpcQ5gXw6kjOaRsSWsIeNyRxGed2w/ARyP7ScBYpWR1qfX2E5rS3gBw6OWcSQo+s+kUg==", "dev": true, "optional": true }, @@ -5658,6 +5659,16 @@ "bare-os": "^2.1.0" } }, + "node_modules/bare-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-1.0.0.tgz", + "integrity": "sha512-KhNUoDL40iP4gFaLSsoGE479t0jHijfYdIcxRn/XtezA2BaUD0NRf/JGRpsMq6dMNM+SrCrB0YSSo/5wBY4rOQ==", + "dev": true, + "optional": true, + "dependencies": { + "streamx": "^2.16.1" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -5941,9 +5952,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001599", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz", - "integrity": "sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==", + "version": "1.0.30001612", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", + "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", "devOptional": true, "funding": [ { @@ -6524,51 +6535,12 @@ "ms": "2.0.0" } }, - "node_modules/connect/node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/connect/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/connect/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/connect/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -7846,9 +7818,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.36.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", - "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz", + "integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==", "dev": true, "dependencies": { "browserslist": "^4.23.0" @@ -8278,9 +8250,9 @@ "dev": true }, "node_modules/css-loader": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", - "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.1.tgz", + "integrity": "sha512-OxIR5P2mjO1PSXk44bWuQ8XtMK4dpEqpIyERCx3ewOo3I8EmbcxMPUc5ScLtQfgXtOojoMv57So4V/C02HQLsw==", "dev": true, "dependencies": { "icss-utils": "^5.1.0", @@ -8293,7 +8265,7 @@ "semver": "^7.5.4" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", @@ -8301,7 +8273,7 @@ }, "peerDependencies": { "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" + "webpack": "^5.27.0" }, "peerDependenciesMeta": { "@rspack/core": { @@ -8561,9 +8533,9 @@ "dev": true }, "node_modules/dedent": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", - "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", "dev": true, "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -8734,9 +8706,9 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" }, "node_modules/devtools-protocol": { - "version": "0.0.1262051", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1262051.tgz", - "integrity": "sha512-YJe4CT5SA8on3Spa+UDtNhEqtuV6Epwz3OZ4HQVLhlRccpZ9/PAYk0/cy/oKxFKRrZPBUPyxympQci4yWNWZ9g==", + "version": "0.0.1273771", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1273771.tgz", + "integrity": "sha512-QDbb27xcTVReQQW/GHJsdQqGKwYBE7re7gxehj467kKP2DKuYBUj6i2k5LRiAC66J1yZG/9gsxooz/s9pcm0Og==", "dev": true }, "node_modules/dezalgo": { @@ -8975,9 +8947,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.711", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.711.tgz", - "integrity": "sha512-hRg81qzvUEibX2lDxnFlVCHACa+LtrCPIsWAxo161LDYIB3jauf57RGsMZV9mvGwE98yGH06icj3zBEoOkxd/w==", + "version": "1.4.747", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.747.tgz", + "integrity": "sha512-+FnSWZIAvFHbsNVmUxhEqWiaOiPMcfum1GQzlWCg/wLigVtshOsjXHyEFfmt6cFK6+HkS3QOJBv6/3OPumbBfw==", "devOptional": true }, "node_modules/emittery": { @@ -9050,9 +9022,9 @@ } }, "node_modules/envinfo": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz", - "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.12.0.tgz", + "integrity": "sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg==", "dev": true, "bin": { "envinfo": "dist/cli.js" @@ -9084,9 +9056,9 @@ } }, "node_modules/es-abstract": { - "version": "1.23.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", - "integrity": "sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", @@ -9128,11 +9100,11 @@ "safe-regex-test": "^1.0.3", "string.prototype.trim": "^1.2.9", "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.7", + "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.2", "typed-array-byte-length": "^1.0.1", "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.5", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", "which-typed-array": "^1.1.15" }, @@ -9163,9 +9135,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.2.tgz", - "integrity": "sha512-7nOqkomXZEaxUDJw21XZNtRk739QvrPSoZoRtbsEfcii00vdzZUh6zh1CQwHhrib8MdEtJfv5rJiGeb4KuV/vw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.0.tgz", + "integrity": "sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==", "devOptional": true }, "node_modules/es-object-atoms": { @@ -10025,6 +9997,23 @@ "ms": "2.0.0" } }, + "node_modules/express/node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "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" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -10224,16 +10213,17 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "2.4.1", + "on-finished": "~2.3.0", "parseurl": "~1.3.3", - "statuses": "2.0.1", + "statuses": "~1.5.0", "unpipe": "~1.0.0" }, "engines": { @@ -10244,6 +10234,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "dependencies": { "ms": "2.0.0" } @@ -10251,7 +10242,29 @@ "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } }, "node_modules/find-cache-dir": { "version": "4.0.0", @@ -14925,13 +14938,10 @@ } }, "node_modules/log-update/node_modules/ansi-escapes": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", - "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", "dev": true, - "dependencies": { - "type-fest": "^3.0.0" - }, "engines": { "node": ">=14.16" }, @@ -14982,18 +14992,6 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/log-update/node_modules/type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -15557,9 +15555,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", - "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", + "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==", "dev": true }, "node_modules/object-inspect": { @@ -15991,12 +15989,12 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", "dev": true, "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", + "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { @@ -16134,9 +16132,9 @@ } }, "node_modules/postcss": { - "version": "8.4.37", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.37.tgz", - "integrity": "sha512-7iB/v/r7Woof0glKLH8b1SPHrsX7uhdO+Geb41QpF/+mWZHU3uxxSlN+UXGVit1PawOYDToO+AbZzhBzWRDwbQ==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "funding": [ { @@ -16459,16 +16457,16 @@ } }, "node_modules/puppeteer": { - "version": "22.6.5", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.6.5.tgz", - "integrity": "sha512-YuoRKGj3MxHhUwrey7vmNvU4odGdUdNsj1ee8pfcqQlLWIXfMOXZCAXh8xdzpZESHH3tCGWp2xmPZE8E6iUEWg==", + "version": "22.7.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.7.0.tgz", + "integrity": "sha512-s1ulKFZKW3lwWCtNu0VrRLfRaanFHxIv7F8UFYpLo8dPTZcI4wB4EAOD0sKT3SKP+1Rsjodb9WFsK78yKQ6i9Q==", "dev": true, "hasInstallScript": true, "dependencies": { "@puppeteer/browsers": "2.2.2", "cosmiconfig": "9.0.0", - "devtools-protocol": "0.0.1262051", - "puppeteer-core": "22.6.5" + "devtools-protocol": "0.0.1273771", + "puppeteer-core": "22.7.0" }, "bin": { "puppeteer": "lib/esm/puppeteer/node/cli.js" @@ -16478,15 +16476,15 @@ } }, "node_modules/puppeteer-core": { - "version": "22.6.5", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.6.5.tgz", - "integrity": "sha512-s0/5XkAWe0/dWISiljdrybjwDCHhgN31Nu/wznOZPKeikgcJtZtbvPKBz0t802XWqfSQnQDt3L6xiAE5JLlfuw==", + "version": "22.7.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.7.0.tgz", + "integrity": "sha512-9Q+L3VD7cfhXnxv6AqwTHsVb/+/uXENByhPrgvwQ49wvzQwtf1d6b7v6gpoG3tpRdwYjxoV1eHTD8tFahww09g==", "dev": true, "dependencies": { "@puppeteer/browsers": "2.2.2", "chromium-bidi": "0.5.17", "debug": "4.3.4", - "devtools-protocol": "0.0.1262051", + "devtools-protocol": "0.0.1273771", "ws": "8.16.0" }, "engines": { @@ -16494,9 +16492,9 @@ } }, "node_modules/pure-rand": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", - "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true, "funding": [ { @@ -17035,16 +17033,16 @@ } }, "node_modules/rimraf/node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", + "jackspeak": "^2.3.6", "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" }, "bin": { "glob": "dist/esm/bin.mjs" @@ -17057,9 +17055,9 @@ } }, "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -18152,14 +18150,15 @@ } }, "node_modules/string.prototype.padend": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz", - "integrity": "sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", + "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -18201,14 +18200,17 @@ } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -18322,25 +18324,26 @@ } }, "node_modules/style-loader": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", - "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", + "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==", "dev": true, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^5.0.0" + "webpack": "^5.27.0" } }, "node_modules/superagent": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz", "integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==", + "deprecated": "Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net", "dev": true, "dependencies": { "component-emitter": "^1.3.0", @@ -18508,9 +18511,9 @@ } }, "node_modules/terser": { - "version": "5.29.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.2.tgz", - "integrity": "sha512-ZiGkhUBIM+7LwkNjXYJq8svgkd+QK3UUr0wJqY4MieaezBSAIPgbSPZyIx0idM6XWK5CMzSWa8MJIzmRcB8Caw==", + "version": "5.30.4", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.4.tgz", + "integrity": "sha512-xRdd0v64a8mFK9bnsKVdoNP9GQIKUAaJPTaqEQDL4w/J8WaW4sWXXoMZ+6SimPkfT5bElreXf8m9HnmPc3E1BQ==", "devOptional": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -18944,9 +18947,9 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", - "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, "dependencies": { "call-bind": "^1.0.7", @@ -18979,9 +18982,9 @@ } }, "node_modules/typescript": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", - "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 01164a9bb3..a53816ab29 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "connect": "^3.7.0", "core-js": "^3.31.0", "cspell": "^8.3.2", - "css-loader": "^6.8.1", + "css-loader": "^7.1.1", "eslint": "^8.43.0", "eslint-config-prettier": "^9.1.0", "eslint-config-webpack": "^1.2.5", @@ -125,7 +125,7 @@ "sockjs-client": "^1.6.1", "standard-version": "^9.3.0", "strip-ansi-v6": "npm:strip-ansi@^6.0.0", - "style-loader": "^3.3.1", + "style-loader": "^4.0.0", "supertest": "^6.1.3", "tcp-port-used": "^1.0.2", "typescript": "^5.3.3", diff --git a/types/lib/Server.d.ts b/types/lib/Server.d.ts index 0e5a48c98b..4ccbc765d2 100644 --- a/types/lib/Server.d.ts +++ b/types/lib/Server.d.ts @@ -2067,7 +2067,6 @@ type Configuration = type BasicApplication = { use: typeof useFn; }; -import path = require("path"); /** * @overload * @param {NextHandleFunction} fn From 3b944e8296f2e3dbb586aebc6003974a276b3c62 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 24 Apr 2024 16:40:08 +0300 Subject: [PATCH 13/15] test: update --- .../__snapshots__/app.test.js.snap.webpack5 | 33 ------------------- test/e2e/app.test.js | 7 +--- 2 files changed, 1 insertion(+), 39 deletions(-) diff --git a/test/e2e/__snapshots__/app.test.js.snap.webpack5 b/test/e2e/__snapshots__/app.test.js.snap.webpack5 index a11edce36f..9e4ab56bac 100644 --- a/test/e2e/__snapshots__/app.test.js.snap.webpack5 +++ b/test/e2e/__snapshots__/app.test.js.snap.webpack5 @@ -1,16 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`app option should work using "connect (async)" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): console messages 1`] = `[]`; - -exports[`app option should work using "connect (async)" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): page errors 1`] = `[]`; - -exports[`app option should work using "connect (async)" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): response status 1`] = `200`; - -exports[`app option should work using "connect (async)" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): response text 1`] = ` -"Heyo. -" -`; - exports[`app option should work using "connect (async)" application and "http" server should handle GET request to index route (/): console messages 1`] = `[]`; exports[`app option should work using "connect (async)" application and "http" server should handle GET request to index route (/): page errors 1`] = `[]`; @@ -44,17 +33,6 @@ exports[`app option should work using "connect (async)" application and "spdy" s " `; -exports[`app option should work using "connect" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): console messages 1`] = `[]`; - -exports[`app option should work using "connect" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): page errors 1`] = `[]`; - -exports[`app option should work using "connect" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): response status 1`] = `200`; - -exports[`app option should work using "connect" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): response text 1`] = ` -"Heyo. -" -`; - exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): console messages 1`] = `[]`; exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): page errors 1`] = `[]`; @@ -88,17 +66,6 @@ exports[`app option should work using "connect" application and "spdy" server sh " `; -exports[`app option should work using "express" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): console messages 1`] = `[]`; - -exports[`app option should work using "express" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): page errors 1`] = `[]`; - -exports[`app option should work using "express" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): response status 1`] = `200`; - -exports[`app option should work using "express" application and "/home/akait/IdeaProjects/webpack-dev-server/test/helpers/custom-http.js" server should handle GET request to index route (/): response text 1`] = ` -"Heyo. -" -`; - exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): console messages 1`] = `[]`; exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): page errors 1`] = `[]`; diff --git a/test/e2e/app.test.js b/test/e2e/app.test.js index 89ebbf6526..6bec946cef 100644 --- a/test/e2e/app.test.js +++ b/test/e2e/app.test.js @@ -18,12 +18,7 @@ const apps = [ ["connect (async)", async () => require("express")()], ]; -const servers = [ - "http", - "https", - path.resolve(__dirname, "../helpers/custom-http.js"), - "spdy", -]; +const servers = ["http", "https", "spdy"]; describe("app option", () => { for (const [appName, app] of apps) { From 52a4dc86d298c6b6b39af804d3a47d4ef6a486bb Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 24 Apr 2024 17:00:16 +0300 Subject: [PATCH 14/15] fix: types --- lib/Server.js | 28 +++- types/lib/Server.d.ts | 353 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 313 insertions(+), 68 deletions(-) diff --git a/lib/Server.js b/lib/Server.js index 11ee94e7e4..05c3c0ba82 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -18,8 +18,6 @@ const schema = require("./options.json"); /** @typedef {import("webpack").Stats} Stats */ /** @typedef {import("webpack").MultiStats} MultiStats */ /** @typedef {import("os").NetworkInterfaceInfo} NetworkInterfaceInfo */ -/** @typedef {import("express").RequestHandler} ExpressRequestHandler */ -/** @typedef {import("express").ErrorRequestHandler} ExpressErrorRequestHandler */ /** @typedef {import("chokidar").WatchOptions} WatchOptions */ /** @typedef {import("chokidar").FSWatcher} FSWatcher */ /** @typedef {import("connect-history-api-fallback").Options} ConnectHistoryApiFallbackOptions */ @@ -36,6 +34,11 @@ const schema = require("./options.json"); /** @typedef {import("http").IncomingMessage} IncomingMessage */ /** @typedef {import("http").ServerResponse} ServerResponse */ /** @typedef {import("open").Options} OpenOptions */ +/** @typedef {import("express").Application} ExpressApplication */ +/** @typedef {import("express").RequestHandler} ExpressRequestHandler */ +/** @typedef {import("express").ErrorRequestHandler} ExpressErrorRequestHandler */ +/** @typedef {import("express").Request} ExpressRequest */ +/** @typedef {import("express").Response} ExpressResponse */ /** @typedef {(err?: any) => void} NextFunction */ /** @typedef {(req: IncomingMessage, res: ServerResponse) => void} SimpleHandleFunction */ @@ -45,8 +48,14 @@ const schema = require("./options.json"); /** @typedef {import("https").ServerOptions & { spdy?: { plain?: boolean | undefined, ssl?: boolean | undefined, 'x-forwarded-for'?: string | undefined, protocol?: string | undefined, protocols?: string[] | undefined }}} ServerOptions */ -/** @typedef {import("express").Request} Request */ -/** @typedef {import("express").Response} Response */ +/** + * @template {BasicApplication} [T=ExpressApplication] + * @typedef {T extends ExpressApplication ? ExpressRequest : IncomingMessage} Request + */ +/** + * @template {BasicApplication} [T=ExpressApplication] + * @typedef {T extends ExpressApplication ? ExpressResponse : ServerResponse} Response + */ /** * @template {Request} T @@ -178,11 +187,16 @@ const schema = require("./options.json"); */ /** - * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler | HandleFunction} Middleware + * @template {BasicApplication} [T=ExpressApplication] + * @typedef {T extends ExpressApplication ? ExpressRequestHandler | ExpressErrorRequestHandler : HandleFunction} MiddlewareHandler + */ + +/** + * @typedef {{ name?: string, path?: string, middleware: MiddlewareHandler } | MiddlewareHandler } Middleware */ /** - * @template {BasicApplication} [T=import("express").Application] + * @template {BasicApplication} [T=ExpressApplication] * @typedef {Object} Configuration * @property {boolean | string} [ipc] * @property {Host} [host] @@ -284,7 +298,7 @@ function useFn(route, fn) { */ /** - * @template {BasicApplication} [T=import("express").Application] + * @template {BasicApplication} [T=ExpressApplication] */ class Server { /** diff --git a/types/lib/Server.d.ts b/types/lib/Server.d.ts index 4ccbc765d2..5742ee0b33 100644 --- a/types/lib/Server.d.ts +++ b/types/lib/Server.d.ts @@ -5,7 +5,7 @@ export = Server; * @property {typeof useFn} use */ /** - * @template {BasicApplication} [T=import("express").Application] + * @template {BasicApplication} [T=ExpressApplication] */ declare class Server< T extends BasicApplication = import("express").Application, @@ -31,8 +31,6 @@ declare class Server< /** @typedef {import("webpack").Stats} Stats */ /** @typedef {import("webpack").MultiStats} MultiStats */ /** @typedef {import("os").NetworkInterfaceInfo} NetworkInterfaceInfo */ - /** @typedef {import("express").RequestHandler} ExpressRequestHandler */ - /** @typedef {import("express").ErrorRequestHandler} ExpressErrorRequestHandler */ /** @typedef {import("chokidar").WatchOptions} WatchOptions */ /** @typedef {import("chokidar").FSWatcher} FSWatcher */ /** @typedef {import("connect-history-api-fallback").Options} ConnectHistoryApiFallbackOptions */ @@ -49,14 +47,25 @@ declare class Server< /** @typedef {import("http").IncomingMessage} IncomingMessage */ /** @typedef {import("http").ServerResponse} ServerResponse */ /** @typedef {import("open").Options} OpenOptions */ + /** @typedef {import("express").Application} ExpressApplication */ + /** @typedef {import("express").RequestHandler} ExpressRequestHandler */ + /** @typedef {import("express").ErrorRequestHandler} ExpressErrorRequestHandler */ + /** @typedef {import("express").Request} ExpressRequest */ + /** @typedef {import("express").Response} ExpressResponse */ /** @typedef {(err?: any) => void} NextFunction */ /** @typedef {(req: IncomingMessage, res: ServerResponse) => void} SimpleHandleFunction */ /** @typedef {(req: IncomingMessage, res: ServerResponse, next: NextFunction) => void} NextHandleFunction */ /** @typedef {(err: any, req: IncomingMessage, res: ServerResponse, next: NextFunction) => void} ErrorHandleFunction */ /** @typedef {SimpleHandleFunction | NextHandleFunction | ErrorHandleFunction} HandleFunction */ /** @typedef {import("https").ServerOptions & { spdy?: { plain?: boolean | undefined, ssl?: boolean | undefined, 'x-forwarded-for'?: string | undefined, protocol?: string | undefined, protocols?: string[] | undefined }}} ServerOptions */ - /** @typedef {import("express").Request} Request */ - /** @typedef {import("express").Response} Response */ + /** + * @template {BasicApplication} [T=ExpressApplication] + * @typedef {T extends ExpressApplication ? ExpressRequest : IncomingMessage} Request + */ + /** + * @template {BasicApplication} [T=ExpressApplication] + * @typedef {T extends ExpressApplication ? ExpressResponse : ServerResponse} Response + */ /** * @template {Request} T * @template {Response} U @@ -165,10 +174,14 @@ declare class Server< * @typedef {Array<{ key: string; value: string }> | Record} Headers */ /** - * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler | HandleFunction} Middleware + * @template {BasicApplication} [T=ExpressApplication] + * @typedef {T extends ExpressApplication ? ExpressRequestHandler | ExpressErrorRequestHandler : HandleFunction} MiddlewareHandler + */ + /** + * @typedef {{ name?: string, path?: string, middleware: MiddlewareHandler } | MiddlewareHandler } Middleware */ /** - * @template {BasicApplication} [T=import("express").Application] + * @template {BasicApplication} [T=ExpressApplication] * @typedef {Object} Configuration * @property {boolean | string} [ipc] * @property {Host} [host] @@ -259,15 +272,31 @@ declare class Server< additionalProperties: boolean; properties: { logging: { - /** @typedef {import("open").Options} OpenOptions */ - /** @typedef {(err?: any) => void} NextFunction */ - /** @typedef {(req: IncomingMessage, res: ServerResponse) => void} SimpleHandleFunction */ - /** @typedef {(req: IncomingMessage, res: ServerResponse, next: NextFunction) => void} NextHandleFunction */ - /** @typedef {(err: any, req: IncomingMessage, res: ServerResponse, next: NextFunction) => void} ErrorHandleFunction */ + $ref: string; + }; + overlay: { + $ref: string; + }; + progress: { + $ref: string; + }; + reconnect: { + $ref: string; + }; + webSocketTransport: { + $ref: string; + }; + webSocketURL: { /** @typedef {SimpleHandleFunction | NextHandleFunction | ErrorHandleFunction} HandleFunction */ /** @typedef {import("https").ServerOptions & { spdy?: { plain?: boolean | undefined, ssl?: boolean | undefined, 'x-forwarded-for'?: string | undefined, protocol?: string | undefined, protocols?: string[] | undefined }}} ServerOptions */ - /** @typedef {import("express").Request} Request */ - /** @typedef {import("express").Response} Response */ + /** + * @template {BasicApplication} [T=ExpressApplication] + * @typedef {T extends ExpressApplication ? ExpressRequest : IncomingMessage} Request + */ + /** + * @template {BasicApplication} [T=ExpressApplication] + * @typedef {T extends ExpressApplication ? ExpressResponse : ServerResponse} Response + */ /** * @template {Request} T * @template {Response} U @@ -376,10 +405,14 @@ declare class Server< * @typedef {Array<{ key: string; value: string }> | Record} Headers */ /** - * @typedef {{ name?: string, path?: string, middleware: ExpressRequestHandler | ExpressErrorRequestHandler } | ExpressRequestHandler | ExpressErrorRequestHandler | HandleFunction} Middleware + * @template {BasicApplication} [T=ExpressApplication] + * @typedef {T extends ExpressApplication ? ExpressRequestHandler | ExpressErrorRequestHandler : HandleFunction} MiddlewareHandler */ /** - * @template {BasicApplication} [T=import("express").Application] + * @typedef {{ name?: string, path?: string, middleware: MiddlewareHandler } | MiddlewareHandler } Middleware + */ + /** + * @template {BasicApplication} [T=ExpressApplication] * @typedef {Object} Configuration * @property {boolean | string} [ipc] * @property {Host} [host] @@ -407,21 +440,6 @@ declare class Server< */ $ref: string; }; - overlay: { - $ref: string; - }; - progress: { - $ref: string; - }; - reconnect: { - $ref: string; - }; - webSocketTransport: { - $ref: string; - }; - webSocketURL: { - $ref: string; - }; }; enum?: undefined; cli?: undefined; @@ -472,6 +490,118 @@ declare class Server< | { description: string; type: string; + /** + * @typedef {Object} NormalizedStatic + * @property {string} directory + * @property {string[]} publicPath + * @property {false | ServeIndexOptions} serveIndex + * @property {ServeStaticOptions} staticOptions + * @property {false | WatchOptions} watch + */ + /** + * @typedef {Object} ServerConfiguration + * @property {"http" | "https" | "spdy" | string} [type] + * @property {ServerOptions} [options] + */ + /** + * @typedef {Object} WebSocketServerConfiguration + * @property {"sockjs" | "ws" | string | Function} [type] + * @property {Record} [options] + */ + /** + * @typedef {(import("ws").WebSocket | import("sockjs").Connection & { send: import("ws").WebSocket["send"], terminate: import("ws").WebSocket["terminate"], ping: import("ws").WebSocket["ping"] }) & { isAlive?: boolean }} ClientConnection + */ + /** + * @typedef {import("ws").WebSocketServer | import("sockjs").Server & { close: import("ws").WebSocketServer["close"] }} WebSocketServer + */ + /** + * @typedef {{ implementation: WebSocketServer, clients: ClientConnection[] }} WebSocketServerImplementation + */ + /** + * @callback ByPass + * @param {Request} req + * @param {Response} res + * @param {ProxyConfigArrayItem} proxyConfig + */ + /** + * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem + */ + /** + * @typedef {(ProxyConfigArrayItem | ((req?: Request | undefined, res?: Response | undefined, next?: NextFunction | undefined) => ProxyConfigArrayItem))[]} ProxyConfigArray + */ + /** + * @typedef {Object} OpenApp + * @property {string} [name] + * @property {string[]} [arguments] + */ + /** + * @typedef {Object} Open + * @property {string | string[] | OpenApp} [app] + * @property {string | string[]} [target] + */ + /** + * @typedef {Object} NormalizedOpen + * @property {string} target + * @property {import("open").Options} options + */ + /** + * @typedef {Object} WebSocketURL + * @property {string} [hostname] + * @property {string} [password] + * @property {string} [pathname] + * @property {number | string} [port] + * @property {string} [protocol] + * @property {string} [username] + */ + /** + * @typedef {boolean | ((error: Error) => void)} OverlayMessageOptions + */ + /** + * @typedef {Object} ClientConfiguration + * @property {"log" | "info" | "warn" | "error" | "none" | "verbose"} [logging] + * @property {boolean | { warnings?: OverlayMessageOptions, errors?: OverlayMessageOptions, runtimeErrors?: OverlayMessageOptions }} [overlay] + * @property {boolean} [progress] + * @property {boolean | number} [reconnect] + * @property {"ws" | "sockjs" | string} [webSocketTransport] + * @property {string | WebSocketURL} [webSocketURL] + */ + /** + * @typedef {Array<{ key: string; value: string }> | Record} Headers + */ + /** + * @template {BasicApplication} [T=ExpressApplication] + * @typedef {T extends ExpressApplication ? ExpressRequestHandler | ExpressErrorRequestHandler : HandleFunction} MiddlewareHandler + */ + /** + * @typedef {{ name?: string, path?: string, middleware: MiddlewareHandler } | MiddlewareHandler } Middleware + */ + /** + * @template {BasicApplication} [T=ExpressApplication] + * @typedef {Object} Configuration + * @property {boolean | string} [ipc] + * @property {Host} [host] + * @property {Port} [port] + * @property {boolean | "only"} [hot] + * @property {boolean} [liveReload] + * @property {DevMiddlewareOptions} [devMiddleware] + * @property {boolean} [compress] + * @property {"auto" | "all" | string | string[]} [allowedHosts] + * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback] + * @property {boolean | Record | BonjourOptions} [bonjour] + * @property {string | string[] | WatchFiles | Array} [watchFiles] + * @property {boolean | string | Static | Array} [static] + * @property {boolean | ServerOptions} [https] + * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] + * @property {() => Promise} [app] + * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] + * @property {ProxyConfigArray} [proxy] + * @property {boolean | string | Open | Array} [open] + * @property {boolean} [setupExitSignals] + * @property {boolean | ClientConfiguration} [client] + * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] + * @property {(devServer: Server) => void} [onListening] + * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] + */ cli: { negatedDescription: string; }; @@ -503,6 +633,91 @@ declare class Server< } )[]; }; + /** + * @callback ByPass + * @param {Request} req + * @param {Response} res + * @param {ProxyConfigArrayItem} proxyConfig + */ + /** + * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem + */ + /** + * @typedef {(ProxyConfigArrayItem | ((req?: Request | undefined, res?: Response | undefined, next?: NextFunction | undefined) => ProxyConfigArrayItem))[]} ProxyConfigArray + */ + /** + * @typedef {Object} OpenApp + * @property {string} [name] + * @property {string[]} [arguments] + */ + /** + * @typedef {Object} Open + * @property {string | string[] | OpenApp} [app] + * @property {string | string[]} [target] + */ + /** + * @typedef {Object} NormalizedOpen + * @property {string} target + * @property {import("open").Options} options + */ + /** + * @typedef {Object} WebSocketURL + * @property {string} [hostname] + * @property {string} [password] + * @property {string} [pathname] + * @property {number | string} [port] + * @property {string} [protocol] + * @property {string} [username] + */ + /** + * @typedef {boolean | ((error: Error) => void)} OverlayMessageOptions + */ + /** + * @typedef {Object} ClientConfiguration + * @property {"log" | "info" | "warn" | "error" | "none" | "verbose"} [logging] + * @property {boolean | { warnings?: OverlayMessageOptions, errors?: OverlayMessageOptions, runtimeErrors?: OverlayMessageOptions }} [overlay] + * @property {boolean} [progress] + * @property {boolean | number} [reconnect] + * @property {"ws" | "sockjs" | string} [webSocketTransport] + * @property {string | WebSocketURL} [webSocketURL] + */ + /** + * @typedef {Array<{ key: string; value: string }> | Record} Headers + */ + /** + * @template {BasicApplication} [T=ExpressApplication] + * @typedef {T extends ExpressApplication ? ExpressRequestHandler | ExpressErrorRequestHandler : HandleFunction} MiddlewareHandler + */ + /** + * @typedef {{ name?: string, path?: string, middleware: MiddlewareHandler } | MiddlewareHandler } Middleware + */ + /** + * @template {BasicApplication} [T=ExpressApplication] + * @typedef {Object} Configuration + * @property {boolean | string} [ipc] + * @property {Host} [host] + * @property {Port} [port] + * @property {boolean | "only"} [hot] + * @property {boolean} [liveReload] + * @property {DevMiddlewareOptions} [devMiddleware] + * @property {boolean} [compress] + * @property {"auto" | "all" | string | string[]} [allowedHosts] + * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback] + * @property {boolean | Record | BonjourOptions} [bonjour] + * @property {string | string[] | WatchFiles | Array} [watchFiles] + * @property {boolean | string | Static | Array} [static] + * @property {boolean | ServerOptions} [https] + * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server] + * @property {() => Promise} [app] + * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer] + * @property {ProxyConfigArray} [proxy] + * @property {boolean | string | Open | Array} [open] + * @property {boolean} [setupExitSignals] + * @property {boolean | ClientConfiguration} [client] + * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext) => Headers)} [headers] + * @property {(devServer: Server) => void} [onListening] + * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares] + */ trustedTypesPolicyName: { description: string; type: string; @@ -620,10 +835,15 @@ declare class Server< }; Compress: { type: string; + /** + * @template T + * @param fn {(function(): any) | undefined} + * @returns {function(): T} + */ description: string; link: string; cli: { - negatedDescription: string; + negatedDescription: string /** @type {function(): any} */; }; }; DevMiddleware: { @@ -673,9 +893,6 @@ declare class Server< } )[]; description: string; - /** - * @type {ReturnType} - * */ link: string; }; HistoryApiFallback: { @@ -700,10 +917,17 @@ declare class Server< }; Host: { description: string; + /** + * @private + * @type {RequestHandler[]} + */ link: string; anyOf: ( | { enum: string[]; + /** + * @type {Socket[]} + */ type?: undefined; minLength?: undefined; } @@ -817,9 +1041,6 @@ declare class Server< | { type: string; items: { - /** - * @type {string | undefined} - */ type: string; minLength: number; }; @@ -913,11 +1134,13 @@ declare class Server< $ref: string; }[]; link: string; - description: string /** @type {WebSocketURL} */; + description: string; }; - /** @type {WebSocketURL} */ ServerType: { - enum: string[]; + enum: string[] /** + * @private + * @param {Compiler} compiler + */; }; ServerEnum: { enum: string[]; @@ -925,7 +1148,6 @@ declare class Server< exclude: boolean; }; }; - /** @type {{ type: WebSocketServerConfiguration["type"], options: NonNullable }} */ ServerString: { type: string; minLength: number; @@ -942,10 +1164,9 @@ declare class Server< }[]; }; options: { - $ref: string; + $ref: string /** @type {{ type: WebSocketServerConfiguration["type"], options: NonNullable }} */; }; }; - /** @type {ServerConfiguration} */ additionalProperties: boolean; }; ServerOptions: { @@ -954,13 +1175,14 @@ declare class Server< properties: { passphrase: { type: string; + /** @type {string} */ description: string; }; requestCert: { type: string; description: string; cli: { - negatedDescription: string; + negatedDescription: string /** @type {ServerConfiguration} */; }; }; ca: { @@ -1039,7 +1261,7 @@ declare class Server< instanceof: string; type?: undefined; } - )[] /** @type {number | string} */; + )[]; }; instanceof?: undefined; } @@ -1252,10 +1474,7 @@ declare class Server< }; StaticString: { type: string; - minLength: number /** - * @private - * @returns {Promise} - */; + minLength: number; }; WatchFiles: { anyOf: ( @@ -1266,7 +1485,7 @@ declare class Server< $ref: string; }[]; }; - $ref?: undefined; + /** @type {MultiCompiler} */ $ref?: undefined; } | { $ref: string; @@ -1736,8 +1955,6 @@ declare namespace Server { Stats, MultiStats, NetworkInterfaceInfo, - ExpressRequestHandler, - ExpressErrorRequestHandler, WatchOptions, FSWatcher, ConnectHistoryApiFallbackOptions, @@ -1754,6 +1971,11 @@ declare namespace Server { IncomingMessage, ServerResponse, OpenOptions, + ExpressApplication, + ExpressRequestHandler, + ExpressErrorRequestHandler, + ExpressRequest, + ExpressResponse, NextFunction, SimpleHandleFunction, NextHandleFunction, @@ -1784,6 +2006,7 @@ declare namespace Server { OverlayMessageOptions, ClientConfiguration, Headers, + MiddlewareHandler, Middleware, Configuration, BasicApplication, @@ -1807,8 +2030,6 @@ type StatsCompilation = import("webpack").StatsCompilation; type Stats = import("webpack").Stats; type MultiStats = import("webpack").MultiStats; type NetworkInterfaceInfo = import("os").NetworkInterfaceInfo; -type ExpressRequestHandler = import("express").RequestHandler; -type ExpressErrorRequestHandler = import("express").ErrorRequestHandler; type WatchOptions = import("chokidar").WatchOptions; type ConnectHistoryApiFallbackOptions = import("connect-history-api-fallback").Options; @@ -1824,6 +2045,11 @@ type IPv6 = import("ipaddr.js").IPv6; type IncomingMessage = import("http").IncomingMessage; type ServerResponse = import("http").ServerResponse; type OpenOptions = import("open").Options; +type ExpressApplication = import("express").Application; +type ExpressRequestHandler = import("express").RequestHandler; +type ExpressErrorRequestHandler = import("express").ErrorRequestHandler; +type ExpressRequest = import("express").Request; +type ExpressResponse = import("express").Response; type NextFunction = (err?: any) => void; type SimpleHandleFunction = (req: IncomingMessage, res: ServerResponse) => void; type NextHandleFunction = ( @@ -1850,8 +2076,10 @@ type ServerOptions = import("https").ServerOptions & { protocols?: string[] | undefined; }; }; -type Request = import("express").Request; -type Response = import("express").Response; +type Request = + T extends ExpressApplication ? ExpressRequest : IncomingMessage; +type Response = + T extends ExpressApplication ? ExpressResponse : ServerResponse; type DevMiddlewareOptions< T extends import("express").Request< import("express-serve-static-core").ParamsDictionary, @@ -1993,15 +2221,18 @@ type Headers = value: string; }> | Record; +type MiddlewareHandler< + T extends BasicApplication = import("express").Application, +> = T extends ExpressApplication + ? ExpressRequestHandler | ExpressErrorRequestHandler + : HandleFunction; type Middleware = | { name?: string; path?: string; - middleware: ExpressRequestHandler | ExpressErrorRequestHandler; + middleware: MiddlewareHandler; } - | ExpressRequestHandler - | ExpressErrorRequestHandler - | HandleFunction; + | MiddlewareHandler; type Configuration = { ipc?: string | boolean | undefined; From 975a0ecb8753b6abd48ebc121b6a4579d2f07799 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 24 Apr 2024 17:04:00 +0300 Subject: [PATCH 15/15] test: improve --- .../__snapshots__/app.test.js.snap.webpack5 | 189 ++++++++++++++++-- test/e2e/app.test.js | 2 +- 2 files changed, 172 insertions(+), 19 deletions(-) diff --git a/test/e2e/__snapshots__/app.test.js.snap.webpack5 b/test/e2e/__snapshots__/app.test.js.snap.webpack5 index 9e4ab56bac..9ac3495c9b 100644 --- a/test/e2e/__snapshots__/app.test.js.snap.webpack5 +++ b/test/e2e/__snapshots__/app.test.js.snap.webpack5 @@ -1,100 +1,253 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`app option should work using "connect (async)" application and "http" server should handle GET request to index route (/): console messages 1`] = `[]`; +exports[`app option should work using "connect (async)" application and "http" server should handle GET request to index route (/): console messages 1`] = ` +[ + "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", + "[HMR] Waiting for update signal from WDS...", + "Hey.", +] +`; exports[`app option should work using "connect (async)" application and "http" server should handle GET request to index route (/): page errors 1`] = `[]`; exports[`app option should work using "connect (async)" application and "http" server should handle GET request to index route (/): response status 1`] = `200`; exports[`app option should work using "connect (async)" application and "http" server should handle GET request to index route (/): response text 1`] = ` -"Heyo. +" + + + + + webpack-dev-server + + +

webpack-dev-server is running...

+ + + " `; -exports[`app option should work using "connect (async)" application and "https" server should handle GET request to index route (/): console messages 1`] = `[]`; +exports[`app option should work using "connect (async)" application and "https" server should handle GET request to index route (/): console messages 1`] = ` +[ + "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", + "[HMR] Waiting for update signal from WDS...", + "Hey.", +] +`; exports[`app option should work using "connect (async)" application and "https" server should handle GET request to index route (/): page errors 1`] = `[]`; exports[`app option should work using "connect (async)" application and "https" server should handle GET request to index route (/): response status 1`] = `200`; exports[`app option should work using "connect (async)" application and "https" server should handle GET request to index route (/): response text 1`] = ` -"Heyo. +" + + + + + webpack-dev-server + + +

webpack-dev-server is running...

+ + + " `; -exports[`app option should work using "connect (async)" application and "spdy" server should handle GET request to index route (/): console messages 1`] = `[]`; +exports[`app option should work using "connect (async)" application and "spdy" server should handle GET request to index route (/): console messages 1`] = ` +[ + "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", + "[HMR] Waiting for update signal from WDS...", + "Hey.", +] +`; exports[`app option should work using "connect (async)" application and "spdy" server should handle GET request to index route (/): page errors 1`] = `[]`; exports[`app option should work using "connect (async)" application and "spdy" server should handle GET request to index route (/): response status 1`] = `200`; exports[`app option should work using "connect (async)" application and "spdy" server should handle GET request to index route (/): response text 1`] = ` -"Heyo. +" + + + + + webpack-dev-server + + +

webpack-dev-server is running...

+ + + " `; -exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): console messages 1`] = `[]`; +exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): console messages 1`] = ` +[ + "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", + "[HMR] Waiting for update signal from WDS...", + "Hey.", +] +`; exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): page errors 1`] = `[]`; exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): response status 1`] = `200`; exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): response text 1`] = ` -"Heyo. +" + + + + + webpack-dev-server + + +

webpack-dev-server is running...

+ + + " `; -exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): console messages 1`] = `[]`; +exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): console messages 1`] = ` +[ + "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", + "[HMR] Waiting for update signal from WDS...", + "Hey.", +] +`; exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): page errors 1`] = `[]`; exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): response status 1`] = `200`; exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): response text 1`] = ` -"Heyo. +" + + + + + webpack-dev-server + + +

webpack-dev-server is running...

+ + + " `; -exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): console messages 1`] = `[]`; +exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): console messages 1`] = ` +[ + "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", + "[HMR] Waiting for update signal from WDS...", + "Hey.", +] +`; exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): page errors 1`] = `[]`; exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): response status 1`] = `200`; exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): response text 1`] = ` -"Heyo. +" + + + + + webpack-dev-server + + +

webpack-dev-server is running...

+ + + " `; -exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): console messages 1`] = `[]`; +exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): console messages 1`] = ` +[ + "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", + "[HMR] Waiting for update signal from WDS...", + "Hey.", +] +`; exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): page errors 1`] = `[]`; exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): response status 1`] = `200`; exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): response text 1`] = ` -"Heyo. +" + + + + + webpack-dev-server + + +

webpack-dev-server is running...

+ + + " `; -exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): console messages 1`] = `[]`; +exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): console messages 1`] = ` +[ + "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", + "[HMR] Waiting for update signal from WDS...", + "Hey.", +] +`; exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): page errors 1`] = `[]`; exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): response status 1`] = `200`; exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): response text 1`] = ` -"Heyo. +" + + + + + webpack-dev-server + + +

webpack-dev-server is running...

+ + + " `; -exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): console messages 1`] = `[]`; +exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): console messages 1`] = ` +[ + "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", + "[HMR] Waiting for update signal from WDS...", + "Hey.", +] +`; exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): page errors 1`] = `[]`; exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): response status 1`] = `200`; exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): response text 1`] = ` -"Heyo. +" + + + + + webpack-dev-server + + +

webpack-dev-server is running...

+ + + " `; diff --git a/test/e2e/app.test.js b/test/e2e/app.test.js index 6bec946cef..05e6c23a79 100644 --- a/test/e2e/app.test.js +++ b/test/e2e/app.test.js @@ -3,7 +3,7 @@ const path = require("path"); const webpack = require("webpack"); const Server = require("../../lib/Server"); -const config = require("../fixtures/static-config/webpack.config"); +const config = require("../fixtures/client-config/webpack.config"); const runBrowser = require("../helpers/run-browser"); const port = require("../ports-map").app;