diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 45f769f50..000000000 --- a/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -/coverage -/dist -/node_modules -/test/fixtures -/test/outputs diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index dd5839fba..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = { - root: true, - reportUnusedDisableDirectives: true, - extends: ["@webpack-contrib/eslint-config-webpack", "prettier"], - overrides: [ - { - files: ["src/**/*.js"], - parserOptions: { - sourceType: "module", - }, - }, - ], -}; diff --git a/README.md b/README.md index ef6ed5be2..2813071b1 100644 --- a/README.md +++ b/README.md @@ -41,10 +41,13 @@ npm install webpack-dev-middleware --save-dev ```js const webpack = require("webpack"); const middleware = require("webpack-dev-middleware"); + const compiler = webpack({ // webpack options }); + const express = require("express"); + const app = express(); app.use( @@ -99,11 +102,9 @@ or ```js webpackDevMiddleware(compiler, { - headers: () => { - return { - "Last-Modified": new Date(), - }; - }, + headers: () => ({ + "Last-Modified": new Date(), + }), }); ``` @@ -250,15 +251,14 @@ The function follows the same premise as [`Array#filter`](https://developer.mozi ```js const webpack = require("webpack"); + const configuration = { /* Webpack configuration */ }; const compiler = webpack(configuration); middleware(compiler, { - writeToDisk: (filePath) => { - return /superman\.css$/.test(filePath); - }, + writeToDisk: (filePath) => /superman\.css$/.test(filePath), }); ``` @@ -276,7 +276,7 @@ This can be done simply by using `path.join`: ```js const webpack = require("webpack"); -const path = require("path"); +const path = require("node:path"); const myOutputFileSystem = require("my-fs"); const mkdirp = require("mkdirp"); @@ -296,6 +296,7 @@ Allows to set up a callback to change the response data. ```js const webpack = require("webpack"); + const configuration = { /* Webpack configuration */ }; @@ -304,11 +305,10 @@ const compiler = webpack(configuration); middleware(compiler, { // Note - if you send the `Range` header you will have `ReadStream` // Also `data` can be `string` or `Buffer` - modifyResponseData: (req, res, data, byteLength) => { + modifyResponseData: (req, res, data, byteLength) => // Your logic // Don't use `res.end()` or `res.send()` here - return { data, byteLength }; - }, + ({ data, byteLength }), }); ``` @@ -333,12 +333,16 @@ A function executed once the middleware has stopped watching. ```js const express = require("express"); const webpack = require("webpack"); + const compiler = webpack({ /* Webpack configuration */ }); + const middleware = require("webpack-dev-middleware"); + const instance = middleware(compiler); +// eslint-disable-next-line new-cap const app = new express(); app.use(instance); @@ -365,12 +369,16 @@ A function executed once the middleware has invalidated. ```js const express = require("express"); const webpack = require("webpack"); + const compiler = webpack({ /* Webpack configuration */ }); + const middleware = require("webpack-dev-middleware"); + const instance = middleware(compiler); +// eslint-disable-next-line new-cap const app = new express(); app.use(instance); @@ -402,12 +410,16 @@ If the bundle is valid at the time of calling, the callback is executed immediat ```js const express = require("express"); const webpack = require("webpack"); + const compiler = webpack({ /* Webpack configuration */ }); + const middleware = require("webpack-dev-middleware"); + const instance = middleware(compiler); +// eslint-disable-next-line new-cap const app = new express(); app.use(instance); @@ -433,12 +445,16 @@ URL for the requested file. ```js const express = require("express"); const webpack = require("webpack"); + const compiler = webpack({ /* Webpack configuration */ }); + const middleware = require("webpack-dev-middleware"); + const instance = middleware(compiler); +// eslint-disable-next-line new-cap const app = new express(); app.use(instance); @@ -461,10 +477,13 @@ But there is a solution to avoid it - mount the middleware to a non-root route, ```js const webpack = require("webpack"); const middleware = require("webpack-dev-middleware"); + const compiler = webpack({ // webpack options }); + const express = require("express"); + const app = express(); // Mounting the middleware to the non-root route allows avoids this. @@ -500,12 +519,15 @@ Example Implementation: ```js const express = require("express"); const webpack = require("webpack"); + const compiler = webpack({ /* Webpack configuration */ }); + const isObject = require("is-object"); const middleware = require("webpack-dev-middleware"); +// eslint-disable-next-line new-cap const app = new express(); // This function makes server rendering of asset references consistent with different webpack chunk/entry configurations @@ -522,7 +544,7 @@ app.use(middleware(compiler, { serverSideRender: true })); // The following middleware would not be invoked until the latest build is finished. app.use((req, res) => { const { devMiddleware } = res.locals.webpack; - const outputFileSystem = devMiddleware.outputFileSystem; + const { outputFileSystem } = devMiddleware; const jsonWebpackStats = devMiddleware.stats.toJson(); const { assetsByChunkName, outputPath } = jsonWebpackStats; @@ -585,7 +607,7 @@ Examples of use with other servers will follow here. ```js const connect = require("connect"); -const http = require("http"); +const http = require("node:http"); const webpack = require("webpack"); const webpackConfig = require("./webpack.config.js"); const devMiddleware = require("webpack-dev-middleware"); @@ -604,7 +626,7 @@ http.createServer(app).listen(3000); ### Router ```js -const http = require("http"); +const http = require("node:http"); const Router = require("router"); const finalhandler = require("finalhandler"); const webpack = require("webpack"); @@ -615,11 +637,13 @@ const compiler = webpack(webpackConfig); const devMiddlewareOptions = { /** Your webpack-dev-middleware-options */ }; + +// eslint-disable-next-line new-cap const router = Router(); router.use(devMiddleware(compiler, devMiddlewareOptions)); -var server = http.createServer((req, res) => { +const server = http.createServer((req, res) => { router(req, res, finalhandler(req, res)); }); @@ -675,22 +699,20 @@ const devMiddleware = require("webpack-dev-middleware"); const compiler = webpack(webpackConfig); const devMiddlewareOptions = {}; -(async () => { - const server = Hapi.server({ port: 3000, host: "localhost" }); +const server = Hapi.server({ port: 3000, host: "localhost" }); - await server.register({ - plugin: devMiddleware.hapiPlugin(), - options: { - // The `compiler` option is required - compiler, - ...devMiddlewareOptions, - }, - }); +await server.register({ + plugin: devMiddleware.hapiPlugin(), + options: { + // The `compiler` option is required + compiler, + ...devMiddlewareOptions, + }, +}); - await server.start(); +await server.start(); - console.log("Server running on %s", server.info.uri); -})(); +console.log("Server running on %s", server.info.uri); process.on("unhandledRejection", (err) => { console.log(err); @@ -713,11 +735,9 @@ const devMiddlewareOptions = { /** Your webpack-dev-middleware-options */ }; -(async () => { - await fastify.register(require("@fastify/express")); - await fastify.use(devMiddleware(compiler, devMiddlewareOptions)); - await fastify.listen(3000); -})(); +await fastify.register(require("@fastify/express")); +await fastify.use(devMiddleware(compiler, devMiddlewareOptions)); +await fastify.listen(3000); ``` ### Hono diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..c2279752f --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,8 @@ +import { defineConfig } from "eslint/config"; +import configs from "eslint-config-webpack/configs.js"; + +export default defineConfig([ + { + extends: [configs["recommended-dirty"]], + }, +]); diff --git a/package-lock.json b/package-lock.json index a0beddcf0..9558fd362 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,30 +22,39 @@ "@babel/preset-env": "^7.16.7", "@commitlint/cli": "^19.0.3", "@commitlint/config-conventional": "^19.0.3", + "@eslint/js": "^9.28.0", + "@eslint/markdown": "^6.5.0", "@fastify/express": "^4.0.2", "@hapi/hapi": "^21.3.7", "@hono/node-server": "^1.12.0", + "@stylistic/eslint-plugin": "^4.4.1", "@types/connect": "^3.4.35", "@types/express": "^5.0.2", "@types/mime-types": "^2.1.1", "@types/node": "^22.3.0", "@types/on-finished": "^2.3.4", - "@webpack-contrib/eslint-config-webpack": "^3.0.0", "babel-jest": "^29.3.1", "connect": "^3.7.0", "cross-env": "^7.0.3", "cspell": "^8.3.2", "deepmerge": "^4.2.2", "del-cli": "^6.0.0", - "eslint": "^8.28.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-import": "^2.25.4", + "eslint": "^9.28.0", + "eslint-config-prettier": "^10.1.5", + "eslint-config-webpack": "^4.0.4", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jest": "^28.12.0", + "eslint-plugin-jsdoc": "^50.7.1", + "eslint-plugin-n": "^17.19.0", + "eslint-plugin-prettier": "^5.4.1", + "eslint-plugin-unicorn": "^59.0.1", "execa": "^5.1.1", "express": "^5.1.0", "express-4": "npm:express@^4", "fastify": "^5.2.1", "file-loader": "^6.2.0", "finalhandler": "^2.1.0", + "globals": "^16.2.0", "hono": "^4.4.13", "husky": "^9.1.3", "jest": "^29.3.1", @@ -983,6 +992,16 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", @@ -1814,6 +1833,16 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/types": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz", @@ -2693,6 +2722,23 @@ "node": ">=18.0" } }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.50.2", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.50.2.tgz", + "integrity": "sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6", + "@typescript-eslint/types": "^8.11.0", + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~4.1.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", @@ -2722,17 +2768,55 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", + "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", + "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", + "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -2740,7 +2824,7 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2771,16 +2855,13 @@ "license": "Python-2.0" }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2806,27 +2887,60 @@ "dev": true, "license": "MIT" }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/@eslint/js": { + "version": "9.28.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.28.0.tgz", + "integrity": "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "MIT", "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://eslint.org/donate" } }, - "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "node_modules/@eslint/markdown": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@eslint/markdown/-/markdown-6.5.0.tgz", + "integrity": "sha512-oSkF0p8X21vKEEAGTZASi7q3tbdTvlGduQ02Xz2A1AFncUP4RLVcNz27XurxVW4fs1JXuh0xBtvokXdtp/nN+Q==", "dev": true, "license": "MIT", + "dependencies": { + "@eslint/core": "^0.14.0", + "@eslint/plugin-kit": "^0.3.1", + "mdast-util-from-markdown": "^2.0.2", + "mdast-util-frontmatter": "^2.0.1", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "micromark-extension-gfm": "^3.0.0" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz", + "integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.14.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@fastify/ajv-compiler": { @@ -3643,20 +3757,42 @@ "hono": "^4" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" }, "engines": { - "node": ">=10.10.0" + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/module-importer": { @@ -3673,13 +3809,19 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "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==", - "deprecated": "Use @eslint/object-schema instead", + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, - "license": "BSD-3-Clause" + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@hutson/parse-repository-url": { "version": "3.0.2", @@ -4608,6 +4750,19 @@ "@noble/hashes": "^1.1.5" } }, + "node_modules/@pkgr/core": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.7.tgz", + "integrity": "sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -4686,6 +4841,52 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@stylistic/eslint-plugin": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-4.4.1.tgz", + "integrity": "sha512-CEigAk7eOLyHvdgmpZsKFwtiqS2wFwI1fn4j09IU9GmD4euFM4jEBAViWeCqaNLlbX2k2+A/Fq9cje4HQBXuJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.32.1", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -4762,6 +4963,16 @@ "@types/node": "*" } }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/eslint": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", @@ -4873,6 +5084,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -4894,6 +5115,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "22.15.21", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz", @@ -4965,6 +5193,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/yargs": { "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", @@ -4982,90 +5217,277 @@ "dev": true, "license": "MIT" }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "dev": true, - "license": "ISC" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "node_modules/@typescript-eslint/project-service": { + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.34.0.tgz", + "integrity": "sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + "@typescript-eslint/tsconfig-utils": "^8.34.0", + "@typescript-eslint/types": "^8.34.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.34.0.tgz", + "integrity": "sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.34.0", + "@typescript-eslint/visitor-keys": "8.34.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.34.0.tgz", + "integrity": "sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA==", "dev": true, "license": "MIT", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "node_modules/@typescript-eslint/types": { + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.34.0.tgz", + "integrity": "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.34.0.tgz", + "integrity": "sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" + "@typescript-eslint/project-service": "8.34.0", + "@typescript-eslint/tsconfig-utils": "8.34.0", + "@typescript-eslint/types": "8.34.0", + "@typescript-eslint/visitor-keys": "8.34.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "license": "MIT", "dependencies": { - "@xtuc/ieee754": "^1.2.0" + "balanced-match": "^1.0.0" } }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.34.0.tgz", + "integrity": "sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.34.0", + "@typescript-eslint/types": "8.34.0", + "@typescript-eslint/typescript-estree": "8.34.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.34.0.tgz", + "integrity": "sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.34.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, "license": "Apache-2.0", @@ -5150,19 +5572,6 @@ "@xtuc/long": "4.2.2" } }, - "node_modules/@webpack-contrib/eslint-config-webpack": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@webpack-contrib/eslint-config-webpack/-/eslint-config-webpack-3.0.0.tgz", - "integrity": "sha512-3f0dwuTZ1JZpnoGQ6tAKBWluZKZZBXr1ADoaOAbPiW0OvSN7o0wXFLGyfw6J+fW756xIkZLZ8JDYP5zInIRvBA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6.9.0 || >= 8.9.0" - }, - "peerDependencies": { - "eslint": ">= 5.0.0" - } - }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -5199,9 +5608,9 @@ } }, "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -5327,6 +5736,16 @@ "node": ">= 8" } }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -5879,6 +6298,19 @@ "dev": true, "license": "MIT" }, + "node_modules/builtin-modules": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.0.0.tgz", + "integrity": "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -6035,6 +6467,17 @@ ], "license": "CC-BY-4.0" }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chalk": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", @@ -6074,6 +6517,17 @@ "node": ">=10" } }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -6133,6 +6587,29 @@ "dev": true, "license": "MIT" }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/clean-regexp/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/clear-module": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/clear-module/-/clear-module-4.1.2.tgz", @@ -6365,6 +6842,16 @@ "node": ">= 6" } }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", @@ -8366,6 +8853,20 @@ "node": ">=0.10.0" } }, + "node_modules/decode-named-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz", + "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dedent": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.6.0.tgz", @@ -8577,6 +9078,20 @@ "node": ">=8" } }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dezalgo": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", @@ -8598,19 +9113,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -9003,82 +9505,173 @@ } }, "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "version": "9.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.28.0.tgz", + "integrity": "sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.20.0", + "@eslint/config-helpers": "^0.2.1", + "@eslint/core": "^0.14.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.28.0", + "@eslint/plugin-kit": "^0.3.1", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.3.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "node_modules/eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" }, "peerDependencies": { - "eslint": ">=7.0.0" + "eslint": ">=6.0.0" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "node_modules/eslint-compat-utils/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, - "license": "MIT", - "dependencies": { + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-config-prettier": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.5.tgz", + "integrity": "sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-config-webpack": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eslint-config-webpack/-/eslint-config-webpack-4.0.4.tgz", + "integrity": "sha512-9lqfT50fulsu9d/7TYrX38cpCDevAIL7wyGAjOHHZDXNOcRxCLiPs3yMDAAxac3Qi1fV9pkMIucfiFnSGkZItQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.2" + }, + "engines": { + "node": ">= 20.18.0" + }, + "peerDependencies": { + "@eslint/js": ">= 9.28.0", + "@eslint/markdown": ">= 6.5.0", + "@stylistic/eslint-plugin": ">= 4.4.1", + "eslint": ">= 9.28.0", + "eslint-config-prettier": "^10.1.5", + "eslint-plugin-import": ">= 2.31.0", + "eslint-plugin-jest": ">= 28.12.0", + "eslint-plugin-jsdoc": ">= 50.7.1", + "eslint-plugin-n": ">= 17.19.0", + "eslint-plugin-prettier": ">= 5.4.1", + "eslint-plugin-unicorn": ">= 59.0.1", + "globals": ">= 16.2.0", + "prettier": ">= 3.5.3" + }, + "peerDependenciesMeta": { + "@eslint/markdown": { + "optional": true + }, + "eslint-plugin-jest": { + "optional": true + }, + "eslint-plugin-jsdoc": { + "optional": true + }, + "eslint-plugin-n": { + "optional": true + } + } + }, + "node_modules/eslint-config-webpack/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", "resolve": "^1.22.4" @@ -9122,6 +9715,28 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, "node_modules/eslint-plugin-import": { "version": "2.31.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", @@ -9179,210 +9794,482 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "node_modules/eslint-plugin-jest": { + "version": "28.13.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.13.0.tgz", + "integrity": "sha512-4AuBcFWOriOeEqy6s4Zup/dQ7E1EPTyyfDaMYmM2YP9xEWPWwK3yYifH1dzY6aHRvyx7y53qMSIyT5s+jrorsQ==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" }, - "funding": { - "url": "https://opencollective.com/eslint" + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", + "jest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } } }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/eslint-plugin-jsdoc": { + "version": "50.7.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.7.1.tgz", + "integrity": "sha512-XBnVA5g2kUVokTNUiE1McEPse5n9/mNUmuJcx52psT6zBs2eVcXSmQBvjfa7NZdfLVSy3u1pEDDUxoxpwy89WA==", "dev": true, - "license": "Apache-2.0", + "license": "BSD-3-Clause", + "dependencies": { + "@es-joy/jsdoccomment": "~0.50.2", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.4.1", + "escape-string-regexp": "^4.0.0", + "espree": "^10.3.0", + "esquery": "^1.6.0", + "parse-imports-exports": "^0.2.4", + "semver": "^7.7.2", + "spdx-expression-parse": "^4.0.0" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=18" }, - "funding": { - "url": "https://opencollective.com/eslint" + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/eslint-plugin-jsdoc/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/eslint-plugin-n": { + "version": "17.19.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.19.0.tgz", + "integrity": "sha512-qxn1NaDHtizbhVAPpbMT8wWFaLtPnwhfN/e+chdu2i6Vgzmo/tGM62tcJ1Hf7J5Ie4dhse3DOPMmDxduzfifzw==", "dev": true, "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@eslint-community/eslint-utils": "^4.5.0", + "@typescript-eslint/utils": "^8.26.1", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "ignore": "^5.3.2", + "minimatch": "^9.0.5", + "semver": "^7.6.3", + "ts-declaration-location": "^1.0.6" }, "engines": { - "node": ">=8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": ">=8.23.0" } }, - "node_modules/eslint/node_modules/argparse": { + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "license": "Python-2.0" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", "dev": true, "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "color-name": "~1.1.4" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=7.0.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/eslint-plugin-n/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, - "license": "MIT" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, - "node_modules/eslint/node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "node_modules/eslint-plugin-prettier": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.4.1.tgz", + "integrity": "sha512-9dF+KuU/Ilkq27A8idRP7N2DH8iUR6qXcjF3FR2wETY21PZdBrIjwCau8oboyGj9b7etWmTGEeM8e7oOed6ZWg==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.11.7" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } } }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/eslint-plugin-unicorn": { + "version": "59.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-59.0.1.tgz", + "integrity": "sha512-EtNXYuWPUmkgSU2E7Ttn57LbRREQesIP1BiLn7OZLKodopKfDXfBUkC/0j6mpw2JExwf43Uf3qLSvrSvppgy8Q==", "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "@babel/helper-validator-identifier": "^7.25.9", + "@eslint-community/eslint-utils": "^4.5.1", + "@eslint/plugin-kit": "^0.2.7", + "ci-info": "^4.2.0", + "clean-regexp": "^1.0.0", + "core-js-compat": "^3.41.0", + "esquery": "^1.6.0", + "find-up-simple": "^1.0.1", + "globals": "^16.0.0", + "indent-string": "^5.0.0", + "is-builtin-module": "^5.0.0", + "jsesc": "^3.1.0", + "pluralize": "^8.0.0", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.12.0", + "semver": "^7.7.1", + "strip-indent": "^4.0.0" }, "engines": { - "node": ">=10" + "node": "^18.20.0 || ^20.10.0 || >=21.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=9.22.0" } }, - "node_modules/eslint/node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "node_modules/eslint-plugin-unicorn/node_modules/@eslint/core": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", + "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "@types/json-schema": "^7.0.15" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "node_modules/eslint-plugin-unicorn/node_modules/@eslint/plugin-kit": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", + "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", "dev": true, - "license": "ISC", + "license": "Apache-2.0", "dependencies": { - "is-glob": "^4.0.3" + "@eslint/core": "^0.13.0", + "levn": "^0.4.1" }, "engines": { - "node": ">=10.13.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/eslint-plugin-unicorn/node_modules/ci-info": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz", + "integrity": "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { "node": ">=8" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "node_modules/eslint-plugin-unicorn/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, - "license": "MIT", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/eslint-plugin-unicorn/node_modules/strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", "dev": true, "license": "MIT", "dependencies": { - "argparse": "^2.0.1" + "min-indent": "^1.0.1" }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -9432,32 +10319,32 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, + "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -9995,6 +10882,13 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/fast-equals": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz", @@ -10168,6 +11062,20 @@ "reusify": "^1.0.4" } }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -10355,6 +11263,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/flat-cache": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-5.0.0.tgz", @@ -10431,6 +11352,15 @@ "node": ">= 0.6" } }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/formidable": { "version": "3.5.4", "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz", @@ -10892,6 +11822,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-tsconfig": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/git-raw-commits": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz", @@ -11288,13 +12231,16 @@ } }, "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.2.0.tgz", + "integrity": "sha512-O+7l9tPdHCU320IigZZPj5zmRCFG9xHmx9cU8FqU2Rp+JN714seHV+2S9+JslCpY4gJwU2vOGox0wzgae/MCEg==", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globalthis": { @@ -11391,13 +12337,6 @@ "dev": true, "license": "ISC" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, "node_modules/handlebars": { "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", @@ -11921,6 +12860,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-builtin-module": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-5.0.0.tgz", + "integrity": "sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "builtin-modules": "^5.0.0" + }, + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -13894,6 +14849,16 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", + "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -14738,6 +15703,17 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -14795,6 +15771,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -14805,96 +15792,949 @@ "node": ">= 0.4" } }, - "node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/memfs": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.2.tgz", + "integrity": "sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/memfs": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.2.tgz", - "integrity": "sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==", - "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/json-pack": "^1.0.3", - "@jsonjoy.com/util": "^1.3.0", - "tree-dump": "^1.0.1", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">= 4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" + "micromark-util-symbol": "^2.0.0" } }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", "dev": true, - "engines": { - "node": ">= 0.10.0" + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" } }, - "node_modules/meow": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", - "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT", - "engines": { - "node": ">=16.10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" } }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT" }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" }, "node_modules/micromatch": { "version": "4.0.8", @@ -15561,6 +17401,16 @@ "node": ">=8" } }, + "node_modules/parse-imports-exports": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/parse-imports-exports/-/parse-imports-exports-0.2.4.tgz", + "integrity": "sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-statements": "1.0.11" + } + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -15580,6 +17430,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-statements": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/parse-statements/-/parse-statements-1.0.11.tgz", + "integrity": "sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==", + "dev": true, + "license": "MIT" + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -15819,6 +17676,16 @@ "node": ">=8" } }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -15855,6 +17722,19 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -16301,6 +18181,16 @@ "node": ">=4" } }, + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true, + "license": "MIT", + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", @@ -16446,6 +18336,16 @@ "node": ">=8" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/resolve.exports": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", @@ -16530,23 +18430,6 @@ "dev": true, "license": "MIT" }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/router": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", @@ -17760,6 +19643,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/synckit": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.8.tgz", + "integrity": "sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.4" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, "node_modules/tapable": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", @@ -17901,13 +19800,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, "node_modules/thingies": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", @@ -18065,6 +19957,55 @@ "node": ">=8" } }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-declaration-location": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz", + "integrity": "sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==", + "dev": true, + "funding": [ + { + "type": "ko-fi", + "url": "https://ko-fi.com/rebeccastevens" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/ts-declaration-location" + } + ], + "license": "BSD-3-Clause", + "dependencies": { + "picomatch": "^4.0.2" + }, + "peerDependencies": { + "typescript": ">=4.0.0" + } + }, + "node_modules/ts-declaration-location/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -18364,6 +20305,65 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -18950,6 +20950,17 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/package.json b/package.json index 352b4d0c8..ef286cac6 100644 --- a/package.json +++ b/package.json @@ -20,11 +20,11 @@ "commitlint": "commitlint --from=master", "security": "npm audit --production", "lint:prettier": "prettier --cache --list-different .", - "lint:js": "eslint --cache .", + "lint:code": "eslint --cache .", "lint:spelling": "cspell --cache --no-must-find-files --quiet \"**/*.*\"", "lint:types": "tsc --pretty --noEmit", "lint": "npm-run-all -l -p \"lint:**\"", - "fix:js": "npm run lint:js -- --fix", + "fix:js": "npm run lint:code -- --fix", "fix:prettier": "npm run lint:prettier -- --write", "fix": "npm-run-all -l fix:js fix:prettier", "clean": "del-cli dist types", @@ -64,26 +64,35 @@ "@babel/cli": "^7.16.7", "@babel/core": "^7.16.7", "@babel/preset-env": "^7.16.7", + "@eslint/js": "^9.28.0", + "@eslint/markdown": "^6.5.0", "@commitlint/cli": "^19.0.3", "@commitlint/config-conventional": "^19.0.3", "@fastify/express": "^4.0.2", "@hapi/hapi": "^21.3.7", "@hono/node-server": "^1.12.0", + "@stylistic/eslint-plugin": "^4.4.1", "@types/connect": "^3.4.35", "@types/express": "^5.0.2", "@types/mime-types": "^2.1.1", "@types/node": "^22.3.0", "@types/on-finished": "^2.3.4", - "@webpack-contrib/eslint-config-webpack": "^3.0.0", "babel-jest": "^29.3.1", "connect": "^3.7.0", "cross-env": "^7.0.3", "cspell": "^8.3.2", "deepmerge": "^4.2.2", "del-cli": "^6.0.0", - "eslint": "^8.28.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-import": "^2.25.4", + "globals": "^16.2.0", + "eslint": "^9.28.0", + "eslint-config-webpack": "^4.0.4", + "eslint-config-prettier": "^10.1.5", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jest": "^28.12.0", + "eslint-plugin-jsdoc": "^50.7.1", + "eslint-plugin-n": "^17.19.0", + "eslint-plugin-prettier": "^5.4.1", + "eslint-plugin-unicorn": "^59.0.1", "execa": "^5.1.1", "express-4": "npm:express@^4", "express": "^5.1.0", diff --git a/src/index.js b/src/index.js index f96ff4dc6..1fdc6ed54 100644 --- a/src/index.js +++ b/src/index.js @@ -20,17 +20,18 @@ const noop = () => {}; /** @typedef {import("fs").ReadStream} ReadStream */ /** - * @typedef {Object} ExtendedServerResponse - * @property {{ webpack?: { devMiddleware?: Context } }} [locals] + * @typedef {object} ExtendedServerResponse + * @property {{ webpack?: { devMiddleware?: Context } }=} locals locals */ /** @typedef {import("http").IncomingMessage} IncomingMessage */ /** @typedef {import("http").ServerResponse & ExtendedServerResponse} ServerResponse */ +// eslint-disable-next-line jsdoc/no-restricted-syntax /** * @callback NextFunction - * @param {any} [err] - * @return {void} + * @param {any=} err error + * @returns {void} */ /** @@ -53,38 +54,38 @@ const noop = () => {}; /** * @callback Callback - * @param {Stats | MultiStats} [stats] + * @param {(Stats | MultiStats)=} stats */ /** - * @typedef {Object} ResponseData - * @property {Buffer | ReadStream} data - * @property {number} byteLength + * @typedef {object} ResponseData + * @property {Buffer | ReadStream} data data + * @property {number} byteLength byte length */ /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] * @callback ModifyResponseData - * @param {RequestInternal} req - * @param {ResponseInternal} res - * @param {Buffer | ReadStream} data - * @param {number} byteLength - * @return {ResponseData} + * @param {RequestInternal} req req + * @param {ResponseInternal} res res + * @param {Buffer | ReadStream} data data + * @param {number} byteLength byte length + * @returns {ResponseData} */ /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] - * @typedef {Object} Context - * @property {boolean} state - * @property {Stats | MultiStats | undefined} stats - * @property {Callback[]} callbacks - * @property {Options} options - * @property {Compiler | MultiCompiler} compiler - * @property {Watching | MultiWatching | undefined} watching - * @property {Logger} logger - * @property {OutputFileSystem} outputFileSystem + * @typedef {object} Context + * @property {boolean} state state + * @property {Stats | MultiStats | undefined} stats stats + * @property {Callback[]} callbacks callbacks + * @property {Options} options options + * @property {Compiler | MultiCompiler} compiler compiler + * @property {Watching | MultiWatching | undefined} watching watching + * @property {Logger} logger logger + * @property {OutputFileSystem} outputFileSystem output file system */ /** @@ -104,22 +105,22 @@ const noop = () => {}; /** * @template {IncomingMessage} [RequestInternal = IncomingMessage] * @template {ServerResponse} [ResponseInternal = ServerResponse] - * @typedef {Object} Options - * @property {{[key: string]: string}} [mimeTypes] - * @property {string | undefined} [mimeTypeDefault] - * @property {boolean | ((targetPath: string) => boolean)} [writeToDisk] - * @property {string[]} [methods] - * @property {Headers} [headers] - * @property {NonNullable["publicPath"]} [publicPath] - * @property {Configuration["stats"]} [stats] - * @property {boolean} [serverSideRender] - * @property {OutputFileSystem} [outputFileSystem] - * @property {boolean | string} [index] - * @property {ModifyResponseData} [modifyResponseData] - * @property {"weak" | "strong"} [etag] - * @property {boolean} [lastModified] - * @property {boolean | number | string | { maxAge?: number, immutable?: boolean }} [cacheControl] - * @property {boolean} [cacheImmutable] + * @typedef {object} Options + * @property {{ [key: string]: string }=} mimeTypes mime types + * @property {(string | undefined)=} mimeTypeDefault mime type default + * @property {(boolean | ((targetPath: string) => boolean))=} writeToDisk write to disk + * @property {string[]=} methods methods + * @property {Headers=} headers headers + * @property {NonNullable["publicPath"]=} publicPath public path + * @property {Configuration["stats"]=} stats stats + * @property {boolean=} serverSideRender is server side render + * @property {OutputFileSystem=} outputFileSystem output file system + * @property {(boolean | string)=} index index + * @property {ModifyResponseData=} modifyResponseData modify response data + * @property {"weak" | "strong"=} etag options to generate etag header + * @property {boolean=} lastModified options to generate last modified header + * @property {(boolean | number | string | { maxAge?: number, immutable?: boolean })=} cacheControl options to generate cache headers + * @property {boolean=} cacheImmutable is cache immutable */ /** @@ -129,7 +130,7 @@ const noop = () => {}; * @param {RequestInternal} req * @param {ResponseInternal} res * @param {NextFunction} next - * @return {Promise} + * @returns {Promise} */ /** @typedef {import("./utils/getFilenameFromUrl").Extra} Extra */ @@ -159,12 +160,12 @@ const noop = () => {}; /** * @template {IncomingMessage} RequestInternal * @template {ServerResponse} ResponseInternal - * @typedef {Object} AdditionalMethods - * @property {GetFilenameFromUrl} getFilenameFromUrl - * @property {WaitUntilValid} waitUntilValid - * @property {Invalidate} invalidate - * @property {Close} close - * @property {Context} context + * @typedef {object} AdditionalMethods + * @property {GetFilenameFromUrl} getFilenameFromUrl get filename from url + * @property {WaitUntilValid} waitUntilValid wait until valid + * @property {Invalidate} invalidate invalidate + * @property {Close} close close + * @property {Context} context context */ /** @@ -188,9 +189,9 @@ const noop = () => {}; /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] - * @param {Compiler | MultiCompiler} compiler - * @param {Options} [options] - * @returns {API} + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {API} webpack dev middleware */ function wdm(compiler, options = {}) { validate(/** @type {Schema} */ (schema), options, { @@ -205,7 +206,7 @@ function wdm(compiler, options = {}) { // mimeTypes from user provided options should take priority // over existing, known types - // @ts-ignore + // @ts-expect-error mime.types = { ...types, ...mimeTypes }; } @@ -214,7 +215,7 @@ function wdm(compiler, options = {}) { */ const context = { state: false, - // eslint-disable-next-line no-undefined + stats: undefined, callbacks: [], options, @@ -235,7 +236,7 @@ function wdm(compiler, options = {}) { context.watching = /** @type {Compiler} */ (context.compiler).watching; } else { /** - * @param {Error | null | undefined} error + * @param {Error | null | undefined} error error */ const errorHandler = (error) => { if (error) { @@ -250,15 +251,15 @@ function wdm(compiler, options = {}) { if ( Array.isArray(/** @type {MultiCompiler} */ (context.compiler).compilers) ) { - const c = /** @type {MultiCompiler} */ (context.compiler); - const watchOptions = c.compilers.map( + const compilers = /** @type {MultiCompiler} */ (context.compiler); + const watchOptions = compilers.compilers.map( (childCompiler) => childCompiler.options.watchOptions || {}, ); context.watching = compiler.watch(watchOptions, errorHandler); } else { - const c = /** @type {Compiler} */ (context.compiler); - const watchOptions = c.options.watchOptions || {}; + const oneCompiler = /** @type {Compiler} */ (context.compiler); + const watchOptions = oneCompiler.options.watchOptions || {}; context.watching = compiler.watch(watchOptions, errorHandler); } @@ -298,8 +299,8 @@ function wdm(compiler, options = {}) { /** * @template S * @template O - * @typedef {Object} HapiPluginBase - * @property {(server: S, options: O) => void | Promise} register + * @typedef {object} HapiPluginBase + * @property {(server: S, options: O) => void | Promise} register register */ /** @@ -315,7 +316,7 @@ function wdm(compiler, options = {}) { /** * @template HapiServer * @template {HapiOptions} HapiOptionsInternal - * @returns {HapiPlugin} + * @returns {HapiPlugin} hapi wrapper */ function hapiWrapper() { return { @@ -333,30 +334,31 @@ function hapiWrapper() { const devMiddleware = wdm(compiler, rest); - // @ts-ignore + // @ts-expect-error if (!server.decorations.server.includes("webpackDevMiddleware")) { - // @ts-ignore + // @ts-expect-error server.decorate("server", "webpackDevMiddleware", devMiddleware); } - // @ts-ignore + // @ts-expect-error + // eslint-disable-next-line id-length server.ext("onRequest", (request, h) => new Promise((resolve, reject) => { let isFinished = false; /** - * @param {string | Buffer} [data] + * @param {(string | Buffer)=} data */ - // eslint-disable-next-line no-param-reassign + request.raw.res.send = (data) => { isFinished = true; request.raw.res.end(data); }; /** - * @param {string | Buffer} [data] + * @param {(string | Buffer)=} data */ - // eslint-disable-next-line no-param-reassign + request.raw.res.finish = (data) => { isFinished = true; request.raw.res.end(data); @@ -384,23 +386,24 @@ function hapiWrapper() { wdm.hapiWrapper = hapiWrapper; +// eslint-disable-next-line jsdoc/no-restricted-syntax /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] - * @param {Compiler | MultiCompiler} compiler - * @param {Options} [options] - * @returns {(ctx: any, next: Function) => Promise | void} + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {(ctx: any, next: Function) => Promise | void} kow wrapper */ function koaWrapper(compiler, options) { const devMiddleware = wdm(compiler, options); + // eslint-disable-next-line jsdoc/no-restricted-syntax /** - * @param {{ req: RequestInternal, res: ResponseInternal & import("./utils/compatibleAPI").ExpectedServerResponse, status: number, body: string | Buffer | import("fs").ReadStream | { message: string }, state: Object }} ctx - * @param {Function} next + * @param {{req: RequestInternal, res: ResponseInternal & import("./utils/compatibleAPI").ExpectedServerResponse, status: number, body: string | Buffer | import("fs").ReadStream | {message: string}, state: object}} ctx context + * @param {Function} next next * @returns {Promise} */ - - const wrapper = async function webpackDevMiddleware(ctx, next) { + async function webpackDevMiddleware(ctx, next) { const { req, res } = ctx; res.locals = ctx.state; @@ -417,7 +420,7 @@ function koaWrapper(compiler, options) { */ res.setStatusCode = (statusCode) => { status = statusCode; - // eslint-disable-next-line no-param-reassign + ctx.status = statusCode; }; @@ -426,30 +429,27 @@ function koaWrapper(compiler, options) { try { await new Promise( /** - * @param {(value: void) => void} resolve - * @param {(reason?: any) => void} reject + * @param {(value: void) => void} resolve resolve + * @param {(reason?: Error) => void} reject reject */ (resolve, reject) => { /** * @param {import("fs").ReadStream} stream readable stream */ res.stream = (stream) => { - // eslint-disable-next-line no-param-reassign ctx.body = stream; }; /** * @param {string | Buffer} data data */ res.send = (data) => { - // eslint-disable-next-line no-param-reassign ctx.body = data; }; /** - * @param {string | Buffer} [data] data + * @param {(string | Buffer)=} data data */ res.finish = (data) => { - // eslint-disable-next-line no-param-reassign ctx.status = status; res.end(data); }; @@ -465,73 +465,73 @@ function koaWrapper(compiler, options) { }, ); } catch (err) { - // eslint-disable-next-line no-param-reassign ctx.status = /** @type {Error & { statusCode: number }} */ (err).statusCode || /** @type {Error & { status: number }} */ (err).status || 500; - // eslint-disable-next-line no-param-reassign + ctx.body = { message: /** @type {Error} */ (err).message, }; } await next(); - }; + } - wrapper.devMiddleware = devMiddleware; + webpackDevMiddleware.devMiddleware = devMiddleware; - return wrapper; + return webpackDevMiddleware; } wdm.koaWrapper = koaWrapper; +// eslint-disable-next-line jsdoc/no-restricted-syntax /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] - * @param {Compiler | MultiCompiler} compiler - * @param {Options} [options] - * @returns {(ctx: any, next: Function) => Promise | void} + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {(ctx: any, next: Function) => Promise | void} hono wrapper */ function honoWrapper(compiler, options) { const devMiddleware = wdm(compiler, options); + // eslint-disable-next-line jsdoc/no-restricted-syntax /** - * @param {{ env: any, body: any, json: any, status: any, set:any, req: RequestInternal & import("./utils/compatibleAPI").ExpectedIncomingMessage & { header: (name: string) => string }, res: ResponseInternal & import("./utils/compatibleAPI").ExpectedServerResponse & { headers: any, status: any } }} c - * @param {Function} next + * @param {{ env: any, body: any, json: any, status: any, set: any, req: RequestInternal & import("./utils/compatibleAPI").ExpectedIncomingMessage & { header: (name: string) => string }, res: ResponseInternal & import("./utils/compatibleAPI").ExpectedServerResponse & { headers: any, status: any } }} context context + * @param {Function} next next function * @returns {Promise} */ - // eslint-disable-next-line consistent-return - const wrapper = async function webpackDevMiddleware(c, next) { - const { req, res } = c; + async function webpackDevMiddleware(context, next) { + const { req, res } = context; - c.set("webpack", { devMiddleware: devMiddleware.context }); + context.set("webpack", { devMiddleware: devMiddleware.context }); /** - * @returns {string | undefined} + * @returns {string | undefined} method */ - req.getMethod = () => c.req.method; + req.getMethod = () => context.req.method; /** - * @param {string} name - * @returns {string | string[] | undefined} + * @param {string} name name + * @returns {string | string[] | undefined} header value */ - req.getHeader = (name) => c.req.header(name); + req.getHeader = (name) => context.req.header(name); /** - * @returns {string | undefined} + * @returns {string | undefined} URL */ - req.getURL = () => c.req.url; + req.getURL = () => context.req.url; - let { status } = c.res; + let { status } = context.res; /** - * @returns {number} code + * @returns {number} code code */ res.getStatusCode = () => status; /** - * @param {number} code + * @param {number} code code */ res.setStatusCode = (code) => { status = code; @@ -539,34 +539,37 @@ function honoWrapper(compiler, options) { /** * @param {string} name header name + * @returns {string | string[] | undefined} header */ - res.getHeader = (name) => c.res.headers.get(name); + res.getHeader = (name) => context.res.headers.get(name); + // eslint-disable-next-line jsdoc/no-restricted-syntax /** - * @param {string} name - * @param {string | number | Readonly} value + * @param {string} name header name + * @param {string | number | Readonly} value value + * @returns {ResponseInternal & import("./utils/compatibleAPI").ExpectedServerResponse & { headers: any, status: any }} response */ res.setHeader = (name, value) => { - c.res.headers.append(name, value); - return c.res; + context.res.headers.append(name, value); + return context.res; }; /** - * @param {string} name + * @param {string} name header name */ res.removeHeader = (name) => { - c.res.headers.delete(name); + context.res.headers.delete(name); }; /** - * @returns {string[]} + * @returns {string[]} response headers */ - res.getResponseHeaders = () => Array.from(c.res.headers.keys()); + res.getResponseHeaders = () => [...context.res.headers.keys()]; /** - * @returns {ServerResponse} + * @returns {ServerResponse} server response */ - res.getOutgoing = () => c.env.outgoing; + res.getOutgoing = () => context.env.outgoing; res.setState = () => { // Do nothing, because we set it before @@ -574,15 +577,15 @@ function honoWrapper(compiler, options) { res.getReadyReadableStreamState = () => "readable"; - res.getHeadersSent = () => c.env.outgoing.headersSent; + res.getHeadersSent = () => context.env.outgoing.headersSent; let body; try { await new Promise( /** - * @param {(value: void) => void} resolve - * @param {(reason?: any) => void} reject + * @param {(value: void) => void} resolve resolve + * @param {(reason?: Error) => void} reject reject */ (resolve, reject) => { /** @@ -598,20 +601,20 @@ function honoWrapper(compiler, options) { */ res.send = (data) => { // Hono sets `Content-Length` by default - c.res.headers.delete("Content-Length"); + context.res.headers.delete("Content-Length"); body = data; }; /** - * @param {string | Buffer} [data] data + * @param {(string | Buffer)=} data data */ res.finish = (data) => { const isDataExist = typeof data !== "undefined"; // Hono sets `Content-Length` by default if (isDataExist) { - c.res.headers.delete("Content-Length"); + context.res.headers.delete("Content-Length"); } body = isDataExist ? data : null; @@ -628,21 +631,21 @@ function honoWrapper(compiler, options) { }, ); } catch (err) { - c.status(500); + context.status(500); - return c.json({ message: /** @type {Error} */ (err).message }); + return context.json({ message: /** @type {Error} */ (err).message }); } if (typeof body !== "undefined") { - return c.body(body, status); + return context.body(body, status); } await next(); - }; + } - wrapper.devMiddleware = devMiddleware; + webpackDevMiddleware.devMiddleware = devMiddleware; - return wrapper; + return webpackDevMiddleware; } wdm.honoWrapper = honoWrapper; diff --git a/src/middleware.js b/src/middleware.js index 2329a0786..5716d30f1 100644 --- a/src/middleware.js +++ b/src/middleware.js @@ -1,4 +1,4 @@ -const path = require("path"); +const path = require("node:path"); const mime = require("mime-types"); @@ -38,10 +38,10 @@ const memorize = require("./utils/memorize"); const BYTES_RANGE_REGEXP = /^ *bytes/i; /** - * @param {string} type - * @param {number} size - * @param {import("range-parser").Range} [range] - * @returns {string} + * @param {"bytes"} type type + * @param {number} size size + * @param {import("range-parser").Range=} range range + * @returns {string} value of content range header */ function getValueContentRangeHeader(type, size, range) { return `${type} ${range ? `${range.start}-${range.end}` : "*"}/${size}`; @@ -49,15 +49,14 @@ function getValueContentRangeHeader(type, size, range) { /** * Parse an HTTP Date into a number. - * - * @param {string} date - * @returns {number} + * @param {string} date date + * @returns {number} timestamp */ function parseHttpDate(date) { const timestamp = date && Date.parse(date); // istanbul ignore next: guard against date.js Date.parse patching - return typeof timestamp === "number" ? timestamp : NaN; + return typeof timestamp === "number" ? timestamp : Number.NaN; } const CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/; @@ -80,7 +79,7 @@ function destroyStream(stream, suppress) { * @this {import("fs").ReadStream} */ function onOpenClose() { - // @ts-ignore + // @ts-expect-error if (typeof this.fd === "number") { // actually close down the fd this.close(); @@ -106,13 +105,12 @@ const statuses = { const parseRangeHeaders = memorize( /** - * @param {string} value - * @returns {import("range-parser").Result | import("range-parser").Ranges} + * @param {string} value value + * @returns {import("range-parser").Result | import("range-parser").Ranges} ranges */ (value) => { const [len, rangeHeader] = value.split("|"); - // eslint-disable-next-line global-require return require("range-parser")(Number(len), rangeHeader, { combine: true, }); @@ -124,7 +122,7 @@ const MAX_MAX_AGE = 31536000000; /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @typedef {Object} SendErrorOptions send error options + * @typedef {object} SendErrorOptions send error options * @property {Record=} headers headers * @property {import("./index").ModifyResponseData=} modifyResponseData modify response data callback */ @@ -132,8 +130,8 @@ const MAX_MAX_AGE = 31536000000; /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("./index.js").FilledContext} context - * @return {import("./index.js").Middleware} + * @param {import("./index.js").FilledContext} context context + * @returns {import("./index.js").Middleware} wrapper */ function wrapper(context) { return async function middleware(req, res, next) { @@ -141,6 +139,9 @@ function wrapper(context) { initState(res); + /** + * @returns {Promise} + */ async function goNext() { if (!context.options.serverSideRender) { return next(); @@ -171,8 +172,8 @@ function wrapper(context) { * @returns {void} */ function sendError(status, options) { - // eslint-disable-next-line global-require const escapeHtml = require("./utils/escapeHtml"); + const content = statuses[status] || String(status); let document = Buffer.from( ` @@ -185,7 +186,7 @@ function wrapper(context) {
${escapeHtml(content)}
`, - "utf-8", + "utf8", ); // Clear existing headers @@ -228,7 +229,8 @@ function wrapper(context) { } /** - * @param {NodeJS.ErrnoException} error + * @param {NodeJS.ErrnoException} error error + * @returns {void} */ function errorHandler(error) { switch (error.code) { @@ -247,6 +249,9 @@ function wrapper(context) { } } + /** + * @returns {string | string[] | undefined} something when conditional get exist + */ function isConditionalGET() { return ( getRequestHeader(req, "if-match") || @@ -256,6 +261,9 @@ function wrapper(context) { ); } + /** + * @returns {boolean} true when precondition failure, otherwise false + */ function isPreconditionFailure() { // if-match const ifMatch = /** @type {string} */ (getRequestHeader(req, "if-match")); @@ -290,12 +298,12 @@ function wrapper(context) { // A recipient MUST ignore the If-Unmodified-Since header field if the // received field-value is not a valid HTTP-date. - if (!isNaN(unmodifiedSince)) { + if (!Number.isNaN(unmodifiedSince)) { const lastModified = parseHttpDate( /** @type {string} */ (getResponseHeader(res, "Last-Modified")), ); - return isNaN(lastModified) || lastModified > unmodifiedSince; + return Number.isNaN(lastModified) || lastModified > unmodifiedSince; } } @@ -316,8 +324,8 @@ function wrapper(context) { } /** - * @param {import("http").OutgoingHttpHeaders} resHeaders - * @returns {boolean} + * @param {import("http").OutgoingHttpHeaders} resHeaders res header + * @returns {boolean} true when fresh, otherwise false */ function isFresh(resHeaders) { // Always return stale when Cache-Control: no-cache to support end-to-end reload requests @@ -397,6 +405,9 @@ function wrapper(context) { return true; } + /** + * @returns {boolean} true when range is fresh, otherwise false + */ function isRangeFresh() { const ifRange = /** @type {string | undefined} */ @@ -407,7 +418,7 @@ function wrapper(context) { } // if-range as etag - if (ifRange.indexOf('"') !== -1) { + if (ifRange.includes('"')) { const etag = /** @type {string | undefined} */ (getResponseHeader(res, "ETag")); @@ -416,7 +427,7 @@ function wrapper(context) { return true; } - return Boolean(etag && ifRange.indexOf(etag) !== -1); + return Boolean(etag && ifRange.includes(etag)); } // if-range as modified date @@ -432,7 +443,7 @@ function wrapper(context) { } /** - * @returns {string | undefined} + * @returns {string | undefined} range header */ function getRangeHeader() { const range = /** @type {string} */ (getRequestHeader(req, "range")); @@ -441,13 +452,12 @@ function wrapper(context) { return range; } - // eslint-disable-next-line no-undefined return undefined; } /** - * @param {import("range-parser").Range} range - * @returns {[number, number]} + * @param {import("range-parser").Range} range range + * @returns {[number, number]} offset and length */ function getOffsetAndLenFromRange(range) { const offset = range.start; @@ -457,9 +467,9 @@ function wrapper(context) { } /** - * @param {number} offset - * @param {number} len - * @returns {[number, number]} + * @param {number} offset offset + * @param {number} len len + * @returns {[number, number]} start and end */ function calcStartAndEnd(offset, len) { const start = offset; @@ -468,6 +478,9 @@ function wrapper(context) { return [start, end]; } + /** + * @returns {Promise} + */ async function processRequest() { // Pipe and SendFile /** @type {import("./utils/getFilenameFromUrl").Extra} */ @@ -644,7 +657,6 @@ function wrapper(context) { } if (value) { - // eslint-disable-next-line global-require const result = await require("./utils/etag")(value); // Because we already read stream, we can cache buffer to avoid extra read from fs diff --git a/src/utils/compatibleAPI.js b/src/utils/compatibleAPI.js index 7e5518b15..6ec7b2751 100644 --- a/src/utils/compatibleAPI.js +++ b/src/utils/compatibleAPI.js @@ -3,34 +3,35 @@ /** @typedef {import("../index").OutputFileSystem} OutputFileSystem */ /** - * @typedef {Object} ExpectedIncomingMessage - * @property {(name: string) => string | string[] | undefined} [getHeader] - * @property {() => string | undefined} [getMethod] - * @property {() => string | undefined} [getURL] + * @typedef {object} ExpectedIncomingMessage + * @property {((name: string) => string | string[] | undefined)=} getHeader get header extra method + * @property {(() => string | undefined)=} getMethod get method extra method + * @property {(() => string | undefined)=} getURL get URL extra method */ +// eslint-disable-next-line jsdoc/no-restricted-syntax /** - * @typedef {Object} ExpectedServerResponse - * @property {(status: number) => void} [setStatusCode] - * @property {() => number} [getStatusCode] - * @property {(name: string) => string | string[] | undefined | number} [getHeader] - * @property {(name: string, value: number | string | Readonly) => ExpectedServerResponse} [setHeader] - * @property {(name: string) => void} [removeHeader] - * @property {(data: string | Buffer) => void} [send] - * @property {(data?: string | Buffer) => void} [finish] - * @property {() => string[]} [getResponseHeaders] - * @property {() => boolean} [getHeadersSent] - * @property {(data: any) => void} [stream] - * @property {() => any} [getOutgoing] - * @property {(name: string, value: any) => void} [setState] - * @property {() => "ready" | "open" | "readable"} [getReadyReadableStreamState] + * @typedef {object} ExpectedServerResponse + * @property {((status: number) => void)=} setStatusCode set status code + * @property {(() => number)=} getStatusCode get status code + * @property {((name: string) => string | string[] | undefined | number)} getHeader get header + * @property {((name: string, value: number | string | Readonly) => ExpectedServerResponse)=} setHeader set header + * @property {((name: string) => void)=} removeHeader remove header + * @property {((data: string | Buffer) => void)=} send send + * @property {((data?: string | Buffer) => void)=} finish finish + * @property {(() => string[])=} getResponseHeaders get response header + * @property {(() => boolean)=} getHeadersSent get headers sent + * @property {((data: any) => void)=} stream stream + * @property {(() => any)=} getOutgoing get outgoing + * @property {((name: string, value: any) => void)=} setState set state + * @property {(() => "ready" | "open" | "readable")=} getReadyReadableStreamState get ready readable streamState */ /** * @template {IncomingMessage & ExpectedIncomingMessage} Request - * @param {Request} req - * @param {string} name - * @returns {string | string[] | undefined} + * @param {Request} req req + * @param {string} name name + * @returns {string | string[] | undefined} request header */ function getRequestHeader(req, name) { // Pseudo API @@ -43,8 +44,8 @@ function getRequestHeader(req, name) { /** * @template {IncomingMessage & ExpectedIncomingMessage} Request - * @param {Request} req - * @returns {string | undefined} + * @param {Request} req req + * @returns {string | undefined} request method */ function getRequestMethod(req) { // Pseudo API @@ -57,8 +58,8 @@ function getRequestMethod(req) { /** * @template {IncomingMessage & ExpectedIncomingMessage} Request - * @param {Request} req - * @returns {string | undefined} + * @param {Request} req req + * @returns {string | undefined} request URL */ function getRequestURL(req) { // Pseudo API @@ -71,8 +72,9 @@ function getRequestURL(req) { /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {number} code + * @param {Response} res res + * @param {number} code code + * @returns {void} */ function setStatusCode(res, code) { // Pseudo API @@ -83,14 +85,14 @@ function setStatusCode(res, code) { } // Node.js API - // eslint-disable-next-line no-param-reassign + res.statusCode = code; } /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @returns {number} + * @param {Response} res res + * @returns {number} status code */ function getStatusCode(res) { // Pseudo API @@ -103,9 +105,9 @@ function getStatusCode(res) { /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {string} name - * @returns {string | string[] | undefined | number} + * @param {Response} res res + * @param {string} name name + * @returns {string | string[] | undefined | number} header */ function getResponseHeader(res, name) { // Real and Pseudo API @@ -114,10 +116,10 @@ function getResponseHeader(res, name) { /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {string} name - * @param {number | string | Readonly} value - * @returns {Response} + * @param {Response} res res + * @param {string} name name + * @param {number | string | Readonly} value value + * @returns {Response} response */ function setResponseHeader(res, name, value) { // Real and Pseudo API @@ -126,8 +128,9 @@ function setResponseHeader(res, name, value) { /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {string} name + * @param {Response} res res + * @param {string} name name + * @returns {void} */ function removeResponseHeader(res, name) { // Real and Pseudo API @@ -136,8 +139,8 @@ function removeResponseHeader(res, name) { /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @returns {string[]} + * @param {Response} res res + * @returns {string[]} header names */ function getResponseHeaders(res) { // Pseudo API @@ -150,8 +153,8 @@ function getResponseHeaders(res) { /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @returns {boolean} + * @param {Response} res res + * @returns {boolean} true when headers were sent, otherwise false */ function getHeadersSent(res) { // Pseudo API @@ -164,8 +167,8 @@ function getHeadersSent(res) { /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {import("fs").ReadStream} bufferOrStream + * @param {Response} res res + * @param {import("fs").ReadStream} bufferOrStream buffer or stream */ function pipe(res, bufferOrStream) { // Pseudo API and Koa API @@ -181,8 +184,9 @@ function pipe(res, bufferOrStream) { /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {string | Buffer} bufferOrString + * @param {Response} res res + * @param {string | Buffer} bufferOrString buffer or string + * @returns {void} */ function send(res, bufferOrString) { // Pseudo API and Express API and Koa API @@ -196,8 +200,8 @@ function send(res, bufferOrString) { /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {string | Buffer} [data] + * @param {Response} res res + * @param {(string | Buffer)=} data data */ function finish(res, data) { // Pseudo API and Express API and Koa API @@ -211,11 +215,11 @@ function finish(res, data) { } /** - * @param {string} filename - * @param {OutputFileSystem} outputFileSystem - * @param {number} start - * @param {number} end - * @returns {{ bufferOrStream: (Buffer | import("fs").ReadStream), byteLength: number }} + * @param {string} filename filename + * @param {OutputFileSystem} outputFileSystem output file system + * @param {number} start start + * @param {number} end end + * @returns {{ bufferOrStream: (Buffer | import("fs").ReadStream), byteLength: number }} result with buffer or stream and byte length */ function createReadStreamOrReadFileSync( filename, @@ -252,8 +256,8 @@ function createReadStreamOrReadFileSync( /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @returns {Response} res + * @param {Response} res res + * @returns {Response} res res */ function getOutgoing(res) { // Pseudo API and Express API and Koa API @@ -266,7 +270,7 @@ function getOutgoing(res) { /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res + * @param {Response} res res */ function initState(res) { if (typeof res.setState === "function") { @@ -274,15 +278,16 @@ function initState(res) { } // fixes #282. credit @cexoso. in certain edge situations res.locals is undefined. - // eslint-disable-next-line no-param-reassign - res.locals = res.locals || {}; + res.locals ||= {}; } +// eslint-disable-next-line jsdoc/no-restricted-syntax /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {string} name - * @param {any} value + * @param {Response} res res + * @param {string} name name + * @param {any} value state + * @returns {void} */ function setState(res, name, value) { if (typeof res.setState === "function") { @@ -291,15 +296,15 @@ function setState(res, name, value) { return; } + // eslint-disable-next-line jsdoc/no-restricted-syntax /** @type {any} */ - // eslint-disable-next-line no-param-reassign (res.locals)[name] = value; } /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @returns {"ready" | "open" | "readable"} + * @param {Response} res res + * @returns {"ready" | "open" | "readable"} state */ function getReadyReadableStreamState(res) { // Pseudo API and Express API and Koa API diff --git a/src/utils/escapeHtml.js b/src/utils/escapeHtml.js index 4a131ef30..6e168ce64 100644 --- a/src/utils/escapeHtml.js +++ b/src/utils/escapeHtml.js @@ -40,11 +40,11 @@ function escapeHtml(string) { escape = ">"; break; default: - // eslint-disable-next-line no-continue continue; } if (lastIndex !== index) { + // eslint-disable-next-line unicorn/prefer-string-slice html += str.substring(lastIndex, index); } @@ -52,6 +52,7 @@ function escapeHtml(string) { html += escape; } + // eslint-disable-next-line unicorn/prefer-string-slice return lastIndex !== index ? html + str.substring(lastIndex, index) : html; } diff --git a/src/utils/etag.js b/src/utils/etag.js index 2aa227d8c..2f5745234 100644 --- a/src/utils/etag.js +++ b/src/utils/etag.js @@ -1,26 +1,24 @@ -const crypto = require("crypto"); +const crypto = require("node:crypto"); /** @typedef {import("fs").Stats} Stats */ /** @typedef {import("fs").ReadStream} ReadStream */ /** * Generate a tag for a stat. - * - * @param {Stats} stat - * @return {{ hash: string, buffer?: Buffer }} + * @param {Stats} stats stats + * @returns {{ hash: string, buffer?: Buffer }} etag */ -function statTag(stat) { - const mtime = stat.mtime.getTime().toString(16); - const size = stat.size.toString(16); +function statTag(stats) { + const mtime = stats.mtime.getTime().toString(16); + const size = stats.size.toString(16); return { hash: `W/"${size}-${mtime}"` }; } /** * Generate an entity tag. - * - * @param {Buffer | ReadStream} entity - * @return {Promise<{ hash: string, buffer?: Buffer }>} + * @param {Buffer | ReadStream} entity entity + * @returns {Promise<{ hash: string, buffer?: Buffer }>} etag */ async function entityTag(entity) { const sha1 = crypto.createHash("sha1"); @@ -46,7 +44,7 @@ async function entityTag(entity) { return { buffer: Buffer.concat(buffers), - hash: `"${byteLength.toString(16)}-${sha1.digest("base64").substring(0, 27)}"`, + hash: `"${byteLength.toString(16)}-${sha1.digest("base64").slice(0, 27)}"`, }; } @@ -56,7 +54,7 @@ async function entityTag(entity) { } // Compute hash of entity - const hash = sha1.update(entity).digest("base64").substring(0, 27); + const hash = sha1.update(entity).digest("base64").slice(0, 27); // Compute length of entity const { byteLength } = entity; @@ -66,9 +64,8 @@ async function entityTag(entity) { /** * Create a simple ETag. - * - * @param {Buffer | ReadStream | Stats} entity - * @return {Promise<{ hash: string, buffer?: Buffer }>} + * @param {Buffer | ReadStream | Stats} entity entity + * @returns {Promise<{ hash: string, buffer?: Buffer }>} etag */ async function etag(entity) { const isStrong = diff --git a/src/utils/getFilenameFromUrl.js b/src/utils/getFilenameFromUrl.js index d3fd80e7e..e650fd8f6 100644 --- a/src/utils/getFilenameFromUrl.js +++ b/src/utils/getFilenameFromUrl.js @@ -1,6 +1,6 @@ -const path = require("path"); -const { parse } = require("url"); -const querystring = require("querystring"); +const path = require("node:path"); +const { parse } = require("node:url"); +const querystring = require("node:querystring"); const getPaths = require("./getPaths"); const memorize = require("./memorize"); @@ -8,10 +8,16 @@ const memorize = require("./memorize"); /** @typedef {import("../index.js").IncomingMessage} IncomingMessage */ /** @typedef {import("../index.js").ServerResponse} ServerResponse */ -// eslint-disable-next-line no-undefined +/** + * @param {string} input input + * @returns {string} unescape input + */ +function decode(input) { + return querystring.unescape(input); +} + const memoizedParse = memorize(parse, undefined, (value) => { if (value.pathname) { - // eslint-disable-next-line no-param-reassign value.pathname = decode(value.pathname); } @@ -21,34 +27,29 @@ const memoizedParse = memorize(parse, undefined, (value) => { const UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/; /** - * @typedef {Object} Extra - * @property {import("fs").Stats=} stats - * @property {number=} errorCode - * @property {boolean=} immutable + * @typedef {object} Extra + * @property {import("fs").Stats=} stats stats + * @property {number=} errorCode error code + * @property {boolean=} immutable true when immutable, otherwise false */ /** * decodeURIComponent. * * Allows V8 to only deoptimize this fn instead of all of send(). - * * @param {string} input * @returns {string} */ -function decode(input) { - return querystring.unescape(input); -} - // TODO refactor me in the next major release, this function should return `{ filename, stats, error }` // TODO fix redirect logic when `/` at the end, like https://github.com/pillarjs/send/blob/master/index.js#L586 /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("../index.js").FilledContext} context - * @param {string} url - * @param {Extra=} extra - * @returns {string | undefined} + * @param {import("../index.js").FilledContext} context context + * @param {string} url url + * @param {Extra=} extra extra + * @returns {string | undefined} filename */ function getFilenameFromUrl(context, url, extra = {}) { const { options } = context; @@ -56,20 +57,20 @@ function getFilenameFromUrl(context, url, extra = {}) { /** @type {string | undefined} */ let foundFilename; - /** @type {URL} */ + /** @type {import("node:url").Url} */ let urlObject; try { // The `url` property of the `request` is contains only `pathname`, `search` and `hash` urlObject = memoizedParse(url, false, true); - } catch (_ignoreError) { + } catch { return; } for (const { publicPath, outputPath, assetsInfo } of paths) { /** @type {string | undefined} */ let filename; - /** @type {URL} */ + /** @type {import("node:url").Url} */ let publicPathObject; try { @@ -78,18 +79,20 @@ function getFilenameFromUrl(context, url, extra = {}) { false, true, ); - } catch (_ignoreError) { - // eslint-disable-next-line no-continue + } catch { continue; } const { pathname } = urlObject; const { pathname: publicPathPathname } = publicPathObject; - if (pathname && pathname.startsWith(publicPathPathname)) { + if ( + pathname && + publicPathPathname && + pathname.startsWith(publicPathPathname) + ) { // Null byte(s) if (pathname.includes("\0")) { - // eslint-disable-next-line no-param-reassign extra.errorCode = 400; return; @@ -97,7 +100,6 @@ function getFilenameFromUrl(context, url, extra = {}) { // ".." is malicious if (UP_PATH_REGEXP.test(path.normalize(`./${pathname}`))) { - // eslint-disable-next-line no-param-reassign extra.errorCode = 403; return; @@ -113,10 +115,8 @@ function getFilenameFromUrl(context, url, extra = {}) { ); try { - // eslint-disable-next-line no-param-reassign extra.stats = context.outputFileSystem.statSync(filename); - } catch (_ignoreError) { - // eslint-disable-next-line no-continue + } catch { continue; } @@ -126,10 +126,9 @@ function getFilenameFromUrl(context, url, extra = {}) { // Rspack does not yet support `assetsInfo`, so we need to check if `assetsInfo` exists here if (assetsInfo) { const assetInfo = assetsInfo.get( - pathname.slice(publicPathObject.pathname.length), + pathname.slice(publicPathPathname.length), ); - // eslint-disable-next-line no-param-reassign extra.immutable = assetInfo ? assetInfo.immutable : false; } @@ -147,10 +146,8 @@ function getFilenameFromUrl(context, url, extra = {}) { filename = path.join(filename, indexValue); try { - // eslint-disable-next-line no-param-reassign extra.stats = context.outputFileSystem.statSync(filename); - } catch (__ignoreError) { - // eslint-disable-next-line no-continue + } catch { continue; } @@ -163,7 +160,6 @@ function getFilenameFromUrl(context, url, extra = {}) { } } - // eslint-disable-next-line consistent-return return foundFilename; } diff --git a/src/utils/getPaths.js b/src/utils/getPaths.js index 9ccd72852..31eebafca 100644 --- a/src/utils/getPaths.js +++ b/src/utils/getPaths.js @@ -1,27 +1,30 @@ /** @typedef {import("webpack").Compiler} Compiler */ /** @typedef {import("webpack").Stats} Stats */ /** @typedef {import("webpack").MultiStats} MultiStats */ +/** @typedef {import("webpack").Asset} Asset */ /** @typedef {import("../index.js").IncomingMessage} IncomingMessage */ /** @typedef {import("../index.js").ServerResponse} ServerResponse */ /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("../index.js").FilledContext} context + * @param {import("../index.js").FilledContext} context context + * @returns {{ outputPath: string, publicPath: string, assetsInfo: Asset["info"] }[]} paths */ function getPaths(context) { const { stats, options } = context; /** @type {Stats[]} */ const childStats = /** @type {MultiStats} */ + // eslint-disable-next-line unicorn/prefer-logical-operator-over-ternary (stats).stats ? /** @type {MultiStats} */ (stats).stats : [/** @type {Stats} */ (stats)]; + /** @type {{ outputPath: string, publicPath: string, assetsInfo: Asset["info"] }[]} */ const publicPaths = []; for (const { compilation } of childStats) { if (compilation.options.devServer === false) { - // eslint-disable-next-line no-continue continue; } diff --git a/src/utils/memorize.js b/src/utils/memorize.js index 03bbb1c62..8a1ba674b 100644 --- a/src/utils/memorize.js +++ b/src/utils/memorize.js @@ -1,16 +1,23 @@ const cacheStore = new WeakMap(); +// eslint-disable-next-line jsdoc/no-restricted-syntax /** * @template T - * @param {Function} fn - * @param {{ cache?: Map } | undefined} cache - * @param {((value: T) => T)=} callback - * @returns {any} + * @typedef {(...args: any) => T} FunctionReturning */ -function memorize(fn, { cache = new Map() } = {}, callback) { + +/** + * @template T + * @param {FunctionReturning} fn memorized function + * @param {({ cache?: Map } | undefined)=} cache cache + * @param {((value: T) => T)=} callback callback + * @returns {FunctionReturning} new function + */ +function memorize(fn, { cache = new Map() } = {}, callback = undefined) { + // eslint-disable-next-line jsdoc/no-restricted-syntax /** - * @param {any} arguments_ - * @return {any} + * @param {any} arguments_ args + * @returns {any} result */ const memoized = (...arguments_) => { const [key] = arguments_; @@ -20,7 +27,7 @@ function memorize(fn, { cache = new Map() } = {}, callback) { return cacheItem.data; } - // @ts-ignore + // @ts-expect-error let result = fn.apply(this, arguments_); if (callback) { diff --git a/src/utils/parseTokenList.js b/src/utils/parseTokenList.js index fed6c472a..d571bcf0f 100644 --- a/src/utils/parseTokenList.js +++ b/src/utils/parseTokenList.js @@ -1,7 +1,6 @@ /** * Parse a HTTP token list. - * - * @param {string} str + * @param {string} str str * @returns {string[]} tokens */ function parseTokenList(str) { @@ -21,7 +20,7 @@ function parseTokenList(str) { break; case 0x2c /* , */: if (start !== end) { - list.push(str.substring(start, end)); + list.push(str.slice(start, end)); } end = i + 1; start = end; @@ -34,7 +33,7 @@ function parseTokenList(str) { // final token if (start !== end) { - list.push(str.substring(start, end)); + list.push(str.slice(start, end)); } return list; diff --git a/src/utils/ready.js b/src/utils/ready.js index a3a4ef97e..a466dd9b2 100644 --- a/src/utils/ready.js +++ b/src/utils/ready.js @@ -1,12 +1,13 @@ /** @typedef {import("../index.js").IncomingMessage} IncomingMessage */ /** @typedef {import("../index.js").ServerResponse} ServerResponse */ +/** @typedef {import("../index.js").Callback} Callback */ /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("../index.js").FilledContext} context - * @param {(...args: any[]) => any} callback - * @param {Request} [req] + * @param {import("../index.js").FilledContext} context context + * @param {Callback} callback callback + * @param {Request=} req req * @returns {void} */ function ready(context, callback, req) { diff --git a/src/utils/setupHooks.js b/src/utils/setupHooks.js index 38bd5bc8a..217d48b4f 100644 --- a/src/utils/setupHooks.js +++ b/src/utils/setupHooks.js @@ -13,34 +13,34 @@ /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("../index.js").WithOptional, "watching" | "outputFileSystem">} context + * @param {import("../index.js").WithOptional, "watching" | "outputFileSystem">} context context */ function setupHooks(context) { + /** + * @returns {void} + */ function invalid() { if (context.state) { context.logger.log("Compilation starting..."); } // We are now in invalid state - // eslint-disable-next-line no-param-reassign + context.state = false; - // eslint-disable-next-line no-param-reassign, no-undefined + context.stats = undefined; } /** - * @param {StatsOptions} statsOptions - * @returns {StatsObjectOptions} + * @param {StatsOptions} statsOptions stats options + * @returns {StatsObjectOptions} object stats options */ function normalizeStatsOptions(statsOptions) { if (typeof statsOptions === "undefined") { - // eslint-disable-next-line no-param-reassign statsOptions = { preset: "normal" }; } else if (typeof statsOptions === "boolean") { - // eslint-disable-next-line no-param-reassign statsOptions = statsOptions ? { preset: "normal" } : { preset: "none" }; } else if (typeof statsOptions === "string") { - // eslint-disable-next-line no-param-reassign statsOptions = { preset: statsOptions }; } @@ -48,13 +48,13 @@ function setupHooks(context) { } /** - * @param {Stats | MultiStats} stats + * @param {Stats | MultiStats} stats stats */ function done(stats) { // We are now on valid state - // eslint-disable-next-line no-param-reassign + context.state = true; - // eslint-disable-next-line no-param-reassign + context.stats = stats; // Do the stuff in nextTick, because bundle may be invalidated if a change happened while compiling @@ -102,17 +102,14 @@ function setupHooks(context) { /** @type {MultiStatsOptions} */ (statsOptions).children.map( /** - * @param {StatsOptions} childStatsOptions - * @return {StatsObjectOptions} + * @param {StatsOptions} childStatsOptions child stats options + * @returns {StatsObjectOptions} object child stats options */ (childStatsOptions) => { - // eslint-disable-next-line no-param-reassign childStatsOptions = normalizeStatsOptions(childStatsOptions); if (typeof childStatsOptions.colors === "undefined") { - // eslint-disable-next-line no-param-reassign childStatsOptions.colors = - // eslint-disable-next-line global-require require("colorette").isColorSupported; } @@ -125,7 +122,6 @@ function setupHooks(context) { ); if (typeof statsOptions.colors === "undefined") { - // eslint-disable-next-line global-require statsOptions.colors = require("colorette").isColorSupported; } } @@ -140,7 +136,6 @@ function setupHooks(context) { console.log(printedStats); } - // eslint-disable-next-line no-param-reassign context.callbacks = []; // Execute callback that are delayed diff --git a/src/utils/setupOutputFileSystem.js b/src/utils/setupOutputFileSystem.js index 9c6bbc316..29f48a783 100644 --- a/src/utils/setupOutputFileSystem.js +++ b/src/utils/setupOutputFileSystem.js @@ -7,7 +7,7 @@ const memfs = require("memfs"); /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("../index.js").WithOptional, "watching" | "outputFileSystem">} context + * @param {import("../index.js").WithOptional, "watching" | "outputFileSystem">} context context */ function setupOutputFileSystem(context) { let outputFileSystem; @@ -30,14 +30,14 @@ function setupOutputFileSystem(context) { // TODO we need to support webpack-dev-server as a plugin or revisit it const compiler = /** @type {MultiCompiler} */ - (context.compiler).compilers.filter( + (context.compiler).compilers.find( (item) => - Object.prototype.hasOwnProperty.call(item.options, "devServer") && + Object.hasOwn(item.options, "devServer") && item.options.devServer !== false, ); ({ outputFileSystem } = - compiler[0] || + compiler || /** @type {MultiCompiler} */ (context.compiler).compilers[0]); } else { @@ -51,16 +51,14 @@ function setupOutputFileSystem(context) { for (const compiler of compilers) { if (compiler.options.devServer === false) { - // eslint-disable-next-line no-continue continue; } - // @ts-ignore + // @ts-expect-error compiler.outputFileSystem = outputFileSystem; } - // @ts-ignore - // eslint-disable-next-line no-param-reassign + // @ts-expect-error context.outputFileSystem = outputFileSystem; } diff --git a/src/utils/setupWriteToDisk.js b/src/utils/setupWriteToDisk.js index 94bfedce7..f8c8bd4ae 100644 --- a/src/utils/setupWriteToDisk.js +++ b/src/utils/setupWriteToDisk.js @@ -1,5 +1,5 @@ -const fs = require("fs"); -const path = require("path"); +const fs = require("node:fs"); +const path = require("node:path"); /** @typedef {import("webpack").Compiler} Compiler */ /** @typedef {import("webpack").MultiCompiler} MultiCompiler */ @@ -10,7 +10,7 @@ const path = require("path"); /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("../index.js").WithOptional, "watching" | "outputFileSystem">} context + * @param {import("../index.js").WithOptional, "watching" | "outputFileSystem">} context context */ function setupWriteToDisk(context) { /** @@ -22,12 +22,11 @@ function setupWriteToDisk(context) { for (const compiler of compilers) { if (compiler.options.devServer === false) { - // eslint-disable-next-line no-continue continue; } compiler.hooks.emit.tap("DevMiddleware", () => { - // @ts-ignore + // @ts-expect-error if (compiler.hasWebpackDevMiddlewareAssetEmittedCallback) { return; } @@ -77,7 +76,7 @@ function setupWriteToDisk(context) { }, ); - // @ts-ignore + // @ts-expect-error compiler.hasWebpackDevMiddlewareAssetEmittedCallback = true; }); } diff --git a/test/helpers/getCompiler.js b/test/helpers/getCompiler.js index 923f54286..3ce05502c 100644 --- a/test/helpers/getCompiler.js +++ b/test/helpers/getCompiler.js @@ -2,6 +2,13 @@ import webpack from "webpack"; import defaultConfig from "../fixtures/webpack.config"; +/** @typedef {import("webpack").Configuration} Configuration */ +/** @typedef {import("webpack").Compiler} Compiler */ + +/** + * @param {Configuration} config config + * @returns {Compiler} compiler + */ function getCompiler(config) { return webpack(config || defaultConfig); } diff --git a/test/helpers/runner.js b/test/helpers/runner.js index d60246476..164cef1ed 100755 --- a/test/helpers/runner.js +++ b/test/helpers/runner.js @@ -10,9 +10,73 @@ const defaultConfig = require("../fixtures/webpack.config"); const configEntries = []; const configMiddlewareEntries = []; +/** + * @param {string} NSKey NSKey + * @param {string[]} accumulator accumulator + */ +function fillConfigEntries(NSKey, accumulator) { + for (const key of Object.keys(process.env).filter( + (key) => key.indexOf(NSKey) === 0, + )) { + let value = process.env[key]; + const keys = key.replace(NSKey, "").split("_"); + + value = value === "true" ? true : value === "false" ? false : value; + + keys.push(value); + accumulator.push(keys); + } +} + fillConfigEntries("WCF_", configEntries); fillConfigEntries("WMC_", configMiddlewareEntries); +/** + * @param {string} name name + * @returns {import("webpack").Configuration | import("webpack").Configuration[]} configuration + */ +function getWebpackConfig(name) { + try { + return require(`../fixtures/${name}`); + } catch { + return require("../fixtures/webpack.config"); + } +} + +/** + * @param {import("webpack").Configuration[]} data data + * @returns {import("webpack").Configuration} configuration + */ +function createConfig(data) { + /** + * @param {string} entry entry + * @returns {{ [string]: string }} object + */ + function getObject(entry) { + return { [entry[0]]: entry[1] }; + } + + /** + * @param {import("webpack").Configuration[]} arr arr + * @returns {import("webpack").Configuration} result + */ + function reduceObject(arr) { + if (arr.length > 1) { + const temp = []; + temp.push(arr.pop()); + temp.push(arr.pop()); + + return reduceObject([...arr, getObject(temp.reverse())]); + } + + return arr[0]; + } + + const result = data.map((el) => reduceObject([...el])); + + return merge.all(result); +} + const createdConfig = createConfig(configEntries); const unionConfig = Object.keys(createdConfig).length > 0 @@ -27,8 +91,6 @@ if (Array.isArray(config)) { const compiler = webpack(config); -let instance; - if (process.env.WEBPACK_BREAK_WATCH) { compiler.watch = function watch() { const error = new Error("Watch error"); @@ -56,20 +118,10 @@ switch (process.env.WEBPACK_DEV_MIDDLEWARE_STATS) { // Nothing } -try { - instance = middleware(compiler, configMiddleware); -} catch (error) { - throw error; -} - +const instance = middleware(compiler, configMiddleware); const app = express(); -try { - app.use(instance); -} catch (error) { - throw error; -} - +app.use(instance); app.listen((error) => { if (error) { throw error; @@ -84,10 +136,9 @@ app.listen((error) => { incompleteCommand += entries.shift(); commands.push(incompleteCommand); incompleteCommand = entries.pop(); - commands = commands.concat(entries); + commands = [...commands, ...entries]; while (commands.length > 0) { - // eslint-disable-next-line default-case switch (commands.shift()) { // case 'invalidate': // stdinInput = ''; @@ -102,49 +153,3 @@ app.listen((error) => { } }); }); - -function getWebpackConfig(name) { - try { - // eslint-disable-next-line global-require,import/no-dynamic-require - return require(`../fixtures/${name}`); - } catch (error) { - // eslint-disable-next-line global-require - return require(`../fixtures/webpack.config`); - } -} - -function createConfig(data) { - function getObject(entry) { - return { [entry[0]]: entry[1] }; - } - - function reduceObject(arr) { - if (arr.length > 1) { - const temp = []; - temp.push(arr.pop()); - temp.push(arr.pop()); - - return reduceObject([...arr, getObject(temp.reverse())]); - } - - return arr[0]; - } - - const result = data.map((el) => reduceObject([...el])); - - return merge.all(result); -} - -function fillConfigEntries(NSKey, accumulator) { - Object.keys(process.env) - .filter((key) => key.indexOf(NSKey) === 0) - .forEach((key) => { - let value = process.env[key]; - const keys = key.replace(NSKey, "").split("_"); - - value = value === "true" ? true : value === "false" ? false : value; - - keys.push(value); - accumulator.push(keys); - }); -} diff --git a/test/helpers/snapshotResolver.js b/test/helpers/snapshotResolver.js index ad8fbc823..12d4a4eb3 100644 --- a/test/helpers/snapshotResolver.js +++ b/test/helpers/snapshotResolver.js @@ -1,4 +1,4 @@ -const path = require("path"); +const path = require("node:path"); const webpack = require("webpack"); diff --git a/test/logging.test.js b/test/logging.test.js index 775b41725..ab5b0615e 100644 --- a/test/logging.test.js +++ b/test/logging.test.js @@ -1,6 +1,6 @@ -import fs from "fs"; -import path from "path"; -import os from "os"; +import fs from "node:fs"; +import path from "node:path"; +import os from "node:os"; import execa from "execa"; import stripAnsi from "strip-ansi"; @@ -15,38 +15,38 @@ function stdoutToSnapshot(stdout) { let cleanedStdout = stripAnsi(stdout.trim()); // Bugs in `strip-ansi` - cleanedStdout = cleanedStdout.replace(/null main /g, "main"); - cleanedStdout = cleanedStdout.replace(/(\d+):(\d+)-(\d+) /g, "$1:$2-$3"); - cleanedStdout = cleanedStdout.replace(/> (.+) {2}(.+)/g, "> $1 $2"); + cleanedStdout = cleanedStdout.replaceAll("null main ", "main"); + cleanedStdout = cleanedStdout.replaceAll(/(\d+):(\d+)-(\d+) /g, "$1:$2-$3"); + cleanedStdout = cleanedStdout.replaceAll(/> (.+) {2}(.+)/g, "> $1 $2"); - cleanedStdout = cleanedStdout.replace(/\| /g, "|"); - cleanedStdout = cleanedStdout.replace(/compiled-for-tests/g, ""); - cleanedStdout = cleanedStdout.replace(/\d+.\d+ KiB/g, "x KiB"); - cleanedStdout = cleanedStdout.replace(/\d+ bytes/g, "x bytes"); - cleanedStdout = cleanedStdout.replace(/\d+ assets/g, "x assets"); + cleanedStdout = cleanedStdout.replaceAll("| ", "|"); + cleanedStdout = cleanedStdout.replaceAll("compiled-for-tests", ""); + cleanedStdout = cleanedStdout.replaceAll(/\d+.\d+ KiB/g, "x KiB"); + cleanedStdout = cleanedStdout.replaceAll(/\d+ bytes/g, "x bytes"); + cleanedStdout = cleanedStdout.replaceAll(/\d+ assets/g, "x assets"); - cleanedStdout = cleanedStdout.replace(/\d+ modules/g, "x modules"); - cleanedStdout = cleanedStdout.replace(/in \d+ ms/g, "in x ms"); + cleanedStdout = cleanedStdout.replaceAll(/\d+ modules/g, "x modules"); + cleanedStdout = cleanedStdout.replaceAll(/in \d+ ms/g, "in x ms"); cleanedStdout = cleanedStdout.replace( /LOG from .+webpack/s, "LOG from xxx\n...\nwebpack", ); - cleanedStdout = cleanedStdout.replace( + cleanedStdout = cleanedStdout.replaceAll( /webpack \d+.\d+.\d+/g, "webpack x.x.x", ); - cleanedStdout = cleanedStdout.replace(/\([0-9a-z]+\)/g, "(xxxx)"); + cleanedStdout = cleanedStdout.replaceAll(/\([0-9a-z]+\)/g, "(xxxx)"); // webpack@4 - cleanedStdout = cleanedStdout.replace(/Hash: [0-9a-z]+/g, "Hash: xxxx"); - cleanedStdout = cleanedStdout.replace(/Time: \d+ms/g, "Time: Xms"); - cleanedStdout = cleanedStdout.replace(/Built at: .+/g, "Built at: x"); + cleanedStdout = cleanedStdout.replaceAll(/Hash: [0-9a-z]+/g, "Hash: xxxx"); + cleanedStdout = cleanedStdout.replaceAll(/Time: \d+ms/g, "Time: Xms"); + cleanedStdout = cleanedStdout.replaceAll(/Built at: .+/g, "Built at: x"); cleanedStdout = cleanedStdout.replace(/LOG from .+$/s, "LOG from xxx"); - cleanedStdout = cleanedStdout.replace(/ +/g, " "); - cleanedStdout = cleanedStdout.replace(/^ +/gm, ""); - cleanedStdout = cleanedStdout.replace(/ +$/gm, ""); - cleanedStdout = cleanedStdout.replace(/\[compared for emit\]/g, "[emitted]"); + cleanedStdout = cleanedStdout.replaceAll(/ +/g, " "); + cleanedStdout = cleanedStdout.replaceAll(/^ +/gm, ""); + cleanedStdout = cleanedStdout.replaceAll(/ +$/gm, ""); + cleanedStdout = cleanedStdout.replaceAll("[compared for emit]", "[emitted]"); return cleanedStdout; } @@ -67,19 +67,13 @@ const runner = path.resolve(__dirname, "./helpers/runner.js"); describe("logging", () => { it("should logging on successfully build", (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.config", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.config", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -102,7 +96,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -111,19 +105,13 @@ describe("logging", () => { }); it("should logging on successfully build and respect colors", (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.stats-colors-true.config.js", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.stats-colors-true.config.js", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -146,7 +134,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -155,19 +143,13 @@ describe("logging", () => { }); it("should logging on successfully build and respect colors #2", (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.stats-colors-false.config.js", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.stats-colors-false.config.js", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -190,7 +172,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).not.toContain("\u001b[1m"); + expect(stdout).not.toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -199,19 +181,13 @@ describe("logging", () => { }); it("should logging on successfully build when the 'stats' doesn't exist", (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.no-stats.config.js", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.no-stats.config.js", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -234,7 +210,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -243,18 +219,12 @@ describe("logging", () => { }); it('should logging on successfully build and respect the "stats" option from configuration with the "none" value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.stats-none.config.js", - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.stats-none.config.js", + }, + }); let stdout = ""; let stderr = ""; @@ -285,19 +255,13 @@ describe("logging", () => { }); it('should logging on successfully build and respect the "stats" option from configuration with the "minimal" value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.stats-minimal.config", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.stats-minimal.config", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -329,19 +293,13 @@ describe("logging", () => { }); it('should logging on successfully build and respect the "stats" option from configuration with the "verbose" value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.stats-verbose.config", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.stats-verbose.config", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -364,7 +322,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -373,19 +331,13 @@ describe("logging", () => { }); it('should logging on successfully build and respect the "stats" option from configuration with the "true" value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.stats-true.config", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.stats-true.config", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -408,7 +360,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -417,18 +369,12 @@ describe("logging", () => { }); it('should logging on successfully build and respect the "stats" option from configuration with the "false" value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.stats-false.config", - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.stats-false.config", + }, + }); let stdout = ""; let stderr = ""; @@ -459,19 +405,13 @@ describe("logging", () => { }); it('should logging on successfully build and respect the "stats" option from configuration with custom object value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.stats-object.config", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.stats-object.config", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -494,7 +434,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -503,19 +443,13 @@ describe("logging", () => { }); it("should logging on successfully build in multi-compiler mode", (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.array.config", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.array.config", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -538,7 +472,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -547,19 +481,13 @@ describe("logging", () => { }); it("should logging on unsuccessful build", (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.error.config", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.error.config", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -582,7 +510,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -591,19 +519,13 @@ describe("logging", () => { }); it("should logging on unsuccessful build in multi-compiler", (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.array.error.config", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.array.error.config", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -626,7 +548,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -635,19 +557,13 @@ describe("logging", () => { }); it("should logging an warning", (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.warning.config", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.warning.config", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -670,7 +586,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -679,19 +595,13 @@ describe("logging", () => { }); it("should logging warnings in multi-compiler mode", (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.array.warning.config", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.array.warning.config", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -714,7 +624,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -723,19 +633,13 @@ describe("logging", () => { }); it('should logging in multi-compiler and respect the "stats" option from configuration', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.array.one-error-one-warning-one-success", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.array.one-error-one-warning-one-success", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -758,7 +662,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -767,20 +671,14 @@ describe("logging", () => { }); it('should logging in multi-compiler and respect the "stats" option from configuration #2', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: - "webpack.array.one-error-one-warning-one-success-with-names", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: + "webpack.array.one-error-one-warning-one-success-with-names", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -803,7 +701,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -812,19 +710,13 @@ describe("logging", () => { }); it('should logging in multi-compiler and respect the "stats" option from configuration #3', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.array.one-error-one-warning-one-no", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.array.one-error-one-warning-one-no", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -847,7 +739,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -856,19 +748,13 @@ describe("logging", () => { }); it('should logging in multi-compiler and respect the "stats" option from configuration #4', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.array.one-error-one-warning-one-object", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.array.one-error-one-warning-one-object", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -891,7 +777,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -900,19 +786,13 @@ describe("logging", () => { }); it('should logging in multi-compiler and respect the "stats" option from configuration #5', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.array.dev-server-false", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.array.dev-server-false", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -935,7 +815,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -944,18 +824,12 @@ describe("logging", () => { }); it('should logging an error in "watch" method', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_BREAK_WATCH: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_BREAK_WATCH: true, + }, + }); let stderr = ""; @@ -985,22 +859,16 @@ describe("logging", () => { fs.mkdirSync(outputDir, { recursive: true }); fs.chmodSync(outputDir, 0o400); - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.simple.config", - WCF_output_filename: "bundle.js", - WCF_output_path: outputDir, - WCF_infrastructureLogging_level: "log", - WMC_writeToDisk: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.simple.config", + WCF_output_filename: "bundle.js", + WCF_output_path: outputDir, + WCF_infrastructureLogging_level: "log", + WMC_writeToDisk: true, + }, + }); let stderr = ""; @@ -1025,20 +893,14 @@ describe("logging", () => { } it('should logging on successfully build using the "stats" option for middleware with the "true" value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.config", - WMC_stats: true, - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.config", + WMC_stats: true, + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1061,7 +923,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -1070,20 +932,14 @@ describe("logging", () => { }); it('should logging on successfully build using the "stats" option for middleware with the "false" value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.config", - WMC_stats: false, - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.config", + WMC_stats: false, + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1114,20 +970,14 @@ describe("logging", () => { }); it('should logging on successfully build using the "stats" option for middleware with the "none" value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.config", - WMC_stats: "none", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.config", + WMC_stats: "none", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1158,20 +1008,14 @@ describe("logging", () => { }); it('should logging on successfully build using the "stats" option for middleware with the "normal" value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.config", - WMC_stats: "normal", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.config", + WMC_stats: "normal", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1194,7 +1038,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -1203,20 +1047,14 @@ describe("logging", () => { }); it('should logging on successfully build using the "stats" option for middleware with the "verbose" value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.config", - WMC_stats: "verbose", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.config", + WMC_stats: "verbose", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1239,7 +1077,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -1248,20 +1086,14 @@ describe("logging", () => { }); it('should logging on successfully build using the "stats" option for middleware with object value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.config", - WEBPACK_DEV_MIDDLEWARE_STATS: "object", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.config", + WEBPACK_DEV_MIDDLEWARE_STATS: "object", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1284,7 +1116,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -1293,20 +1125,14 @@ describe("logging", () => { }); it('should logging on successfully build using the "stats" option for middleware with the object value and colors', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.config", - WEBPACK_DEV_MIDDLEWARE_STATS: "object_colors_true", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.config", + WEBPACK_DEV_MIDDLEWARE_STATS: "object_colors_true", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1329,7 +1155,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -1338,20 +1164,14 @@ describe("logging", () => { }); it('should logging on successfully build using the "stats" option for middleware with object value and no colors', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.config", - WEBPACK_DEV_MIDDLEWARE_STATS: "object_colors_false", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.config", + WEBPACK_DEV_MIDDLEWARE_STATS: "object_colors_false", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1374,7 +1194,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).not.toContain("\u001b[1m"); + expect(stdout).not.toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -1383,20 +1203,14 @@ describe("logging", () => { }); it('should logging on successfully multi-compiler build using the "stats" option for middleware with the "true" value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.array.config", - WMC_stats: true, - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.array.config", + WMC_stats: true, + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1419,7 +1233,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -1428,20 +1242,14 @@ describe("logging", () => { }); it('should logging on successfully multi-compiler build using the "stats" option for middleware with the "false" value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.array.config", - WMC_stats: false, - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.array.config", + WMC_stats: false, + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1472,20 +1280,14 @@ describe("logging", () => { }); it('should logging on successfully multi-compiler build using the "stats" option for middleware with the "normal" value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.array.config", - WMC_stats: "normal", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.array.config", + WMC_stats: "normal", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1508,7 +1310,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -1517,20 +1319,14 @@ describe("logging", () => { }); it('should logging on successfully multi-compiler build using the "stats" option for middleware with the object value', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.array.config", - WEBPACK_DEV_MIDDLEWARE_STATS: "object", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.array.config", + WEBPACK_DEV_MIDDLEWARE_STATS: "object", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1553,7 +1349,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -1562,20 +1358,14 @@ describe("logging", () => { }); it('should logging on successfully multi-compiler build using the "stats" option for middleware with object value and colors', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.array.config", - WEBPACK_DEV_MIDDLEWARE_STATS: "object_colors_true", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.array.config", + WEBPACK_DEV_MIDDLEWARE_STATS: "object_colors_true", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1598,7 +1388,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).toContain("\u001b[1m"); + expect(stdout).toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -1607,20 +1397,14 @@ describe("logging", () => { }); it('should logging on successfully multi-compiler build using the "stats" option for middleware with object value and no colors', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.array.config", - WEBPACK_DEV_MIDDLEWARE_STATS: "object_colors_false", - FORCE_COLOR: true, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.array.config", + WEBPACK_DEV_MIDDLEWARE_STATS: "object_colors_false", + FORCE_COLOR: true, + }, + }); let stdout = ""; let stderr = ""; @@ -1643,7 +1427,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).not.toContain("\u001b[1m"); + expect(stdout).not.toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); @@ -1652,20 +1436,14 @@ describe("logging", () => { }); it('should logging on successfully build and respect the "NO_COLOR" env', (done) => { - let proc; - - try { - proc = execa(runner, [], { - stdio: "pipe", - env: { - WEBPACK_CONFIG: "webpack.config", - NO_COLOR: true, - NODE_NO_WARNINGS: 1, - }, - }); - } catch (error) { - throw error; - } + const proc = execa(runner, [], { + stdio: "pipe", + env: { + WEBPACK_CONFIG: "webpack.config", + NO_COLOR: true, + NODE_NO_WARNINGS: 1, + }, + }); let stdout = ""; let stderr = ""; @@ -1688,7 +1466,7 @@ describe("logging", () => { }); proc.on("exit", () => { - expect(stdout).not.toContain("\u001b[1m"); + expect(stdout).not.toContain("\u001B[1m"); expect(stdoutToSnapshot(stdout)).toMatchSnapshot("stdout"); expect(stderrToSnapshot(stderr)).toMatchSnapshot("stderr"); diff --git a/test/middleware.test.js b/test/middleware.test.js index 7d4c6f5ff..0e48af845 100644 --- a/test/middleware.test.js +++ b/test/middleware.test.js @@ -1,5 +1,5 @@ -import fs from "fs"; -import path from "path"; +import fs from "node:fs"; +import path from "node:path"; import connect from "connect"; import expressOld from "express-4"; @@ -34,13 +34,12 @@ import webpackMultiDevServerFalseConfig from "./fixtures/webpack.array.dev-serve import webpackConfigImmutable from "./fixtures/webpack.immutable.config"; // Suppress unnecessary stats output -global.console.log = jest.fn(); +jest.spyOn(globalThis.console, "log").mockImplementation(); async function startServer(name, app) { return new Promise((resolve, reject) => { if (name === "router") { - // eslint-disable-next-line global-require - const server = require("http").createServer((req, res) => { + const server = require("node:http").createServer((req, res) => { app(req, res, finalhandler(req, res)); }); @@ -90,7 +89,6 @@ async function frameworkFactory( await Promise.all( middlewares.map((item) => { - // eslint-disable-next-line no-shadow const { plugin, options } = item; return server.register({ @@ -158,7 +156,6 @@ async function frameworkFactory( const app = framework(); if (isFastify) { - // eslint-disable-next-line global-require await app.register(require("@fastify/express")); } @@ -226,15 +223,11 @@ async function close(server, instance) { }); }); } - - return Promise.resolve(); }) .then(() => { if (server) { return closeServer(server); } - - return Promise.resolve(); }); } @@ -278,14 +271,13 @@ function applyTestMiddleware(name, middlewares) { middlewares.push(async (ctx, next) => { if (ctx.request.url === "/file.jpg") { ctx.set("Content-Type", "text/html"); - // eslint-disable-next-line no-param-reassign + ctx.body = "welcome"; } await next(); }); } else if (name === "hono") { - // eslint-disable-next-line consistent-return middlewares.push(async (c, next) => { if (c.req.url.endsWith("/file.jpg")) { c.header("Content-Type", "text/html"); @@ -320,7 +312,7 @@ function parseHttpDate(date) { const timestamp = date && Date.parse(date); // istanbul ignore next: guard against date.js Date.parse patching - return typeof timestamp === "number" ? timestamp : NaN; + return typeof timestamp === "number" ? timestamp : Number.NaN; } describe.each([ @@ -338,7 +330,7 @@ describe.each([ let server; let req; - describe("API", () => { + describe("aPI", () => { let compiler; describe("constructor", () => { @@ -378,7 +370,7 @@ describe.each([ describe("should accept compiler in watch mode", () => { beforeEach(async () => { - compiler = getCompiler({ ...webpackConfig, ...{ watch: true } }); + compiler = getCompiler({ ...webpackConfig, watch: true }); instance = middleware(compiler); @@ -629,8 +621,8 @@ describe.each([ expect(instance.getFilenameFromUrl("/bundle.js")).toBe( path.join(webpackConfig.output.path, "/bundle.js"), ); - // eslint-disable-next-line no-undefined - expect(instance.getFilenameFromUrl("/")).toBe(undefined); + + expect(instance.getFilenameFromUrl("/")).toBeUndefined(); expect(instance.getFilenameFromUrl("/index.html")).toBe( path.join(webpackConfig.output.path, "/index.html"), ); @@ -879,7 +871,7 @@ describe.each([ ); instance.context.outputFileSystem.writeFileSync( path.resolve(outputPath, "byte-length.html"), - "\u00bd + \u00bc = \u00be", + "\u00BD + \u00BC = \u00BE", ); instance.context.outputFileSystem.mkdirSync( path.resolve(outputPath, "directory/nested-directory"), @@ -911,7 +903,7 @@ describe.each([ it("should not find the bundle file on disk", async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-type"]).toEqual( getContentTypeHeader(), ); @@ -923,7 +915,7 @@ describe.each([ it('should return the "200" code for the "GET" request to the bundle file', async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( String(Buffer.byteLength(codeContent)), ); @@ -936,7 +928,7 @@ describe.each([ it('should return the "200" code for the "HEAD" request to the bundle file', async () => { const response = await req.head("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( String(Buffer.byteLength(codeContent)), ); @@ -949,7 +941,7 @@ describe.each([ it('should return the "404" code for the "POST" request to the bundle file', async () => { const response = await req.post("/bundle.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return the "200" code for the "GET" request to the "image.svg" file', async () => { @@ -959,11 +951,11 @@ describe.each([ const response = await req.get("/image.svg"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( fileData.byteLength.toString(), ); - expect(response.headers["content-type"]).toEqual("image/svg+xml"); + expect(response.headers["content-type"]).toBe("image/svg+xml"); }); it('should return the "200" code for the "GET" request to the "image.svg" file with "/../"', async () => { @@ -973,11 +965,11 @@ describe.each([ const response = await req.get("/public/../image.svg"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( fileData.byteLength.toString(), ); - expect(response.headers["content-type"]).toEqual("image/svg+xml"); + expect(response.headers["content-type"]).toBe("image/svg+xml"); }); it('should return the "200" code for the "GET" request to the "image.svg" file with "/../../../"', async () => { @@ -989,11 +981,11 @@ describe.each([ "/public/assets/images/../../../image.svg", ); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( fileData.byteLength.toString(), ); - expect(response.headers["content-type"]).toEqual("image/svg+xml"); + expect(response.headers["content-type"]).toBe("image/svg+xml"); }); it('should return the "200" code for the "GET" request to the directory', async () => { @@ -1003,28 +995,28 @@ describe.each([ const response = await req.get("/"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( fileData.byteLength.toString(), ); - expect(response.headers["content-type"]).toEqual( + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); expect(response.text).toEqual(fileData.toString()); }); - it('should return the "200" code for the "GET" request to the subdirectory with "index.html"', async () => { + it('should return the "200" code for the "GET" request to the subdirectory with "index.html" #2', async () => { const fileData = instance.context.outputFileSystem.readFileSync( path.resolve(outputPath, "directory/nested-directory/index.html"), ); const response = await req.get("/directory/nested-directory/"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( fileData.byteLength.toString(), ); - expect(response.headers["content-type"]).toEqual( + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); expect(response.text).toEqual(fileData.toString()); @@ -1037,17 +1029,17 @@ describe.each([ const response = await req.get("/directory/nested-directory"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( fileData.byteLength.toString(), ); - expect(response.headers["content-type"]).toEqual( + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); expect(response.text).toEqual(fileData.toString()); }); - it('should return the "200" code for the "GET" request to the subdirectory with "index.html"', async () => { + it('should return the "200" code for the "GET" request to the subdirectory with "index.html" #3', async () => { const fileData = instance.context.outputFileSystem.readFileSync( path.resolve(outputPath, "directory/nested-directory/index.html"), ); @@ -1056,11 +1048,11 @@ describe.each([ "/directory/nested-directory/index.html", ); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( fileData.byteLength.toString(), ); - expect(response.headers["content-type"]).toEqual( + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); expect(response.text).toEqual(fileData.toString()); @@ -1071,14 +1063,14 @@ describe.each([ .get("/bundle.js") .set("Range", "bytes=9999999-"); - expect(response.statusCode).toEqual(416); - expect(response.headers["content-range"]).toEqual( + expect(response.statusCode).toBe(416); + expect(response.headers["content-range"]).toBe( `bytes */${Buffer.byteLength(codeContent)}`, ); - expect(response.headers["content-type"]).toEqual( + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); - expect(response.text).toEqual( + expect(response.text).toBe( ` @@ -1097,16 +1089,16 @@ describe.each([ .get("/bundle.js") .set("Range", "bytes=3000-3500"); - expect(response.statusCode).toEqual(206); - expect(response.headers["content-range"]).toEqual( + expect(response.statusCode).toBe(206); + expect(response.headers["content-range"]).toBe( `bytes 3000-3500/${Buffer.byteLength(codeContent)}`, ); - expect(response.headers["content-length"]).toEqual("501"); + expect(response.headers["content-length"]).toBe("501"); expect(response.headers["content-type"]).toEqual( getContentTypeHeader(), ); expect(response.text).toBe(codeContent.slice(3000, 3501)); - expect(response.text.length).toBe(501); + expect(response.text).toHaveLength(501); }); it('should return the "206" code for the "HEAD" request with the valid range header', async () => { @@ -1114,11 +1106,11 @@ describe.each([ .head("/bundle.js") .set("Range", "bytes=3000-3500"); - expect(response.statusCode).toEqual(206); - expect(response.headers["content-range"]).toEqual( + expect(response.statusCode).toBe(206); + expect(response.headers["content-range"]).toBe( `bytes 3000-3500/${Buffer.byteLength(codeContent)}`, ); - expect(response.headers["content-length"]).toEqual("501"); + expect(response.headers["content-length"]).toBe("501"); expect(response.headers["content-type"]).toEqual( getContentTypeHeader(), ); @@ -1130,16 +1122,16 @@ describe.each([ .get("/bundle.js") .set("range", "bytes=3000-3500"); - expect(response.statusCode).toEqual(206); - expect(response.headers["content-range"]).toEqual( + expect(response.statusCode).toBe(206); + expect(response.headers["content-range"]).toBe( `bytes 3000-3500/${Buffer.byteLength(codeContent)}`, ); - expect(response.headers["content-length"]).toEqual("501"); + expect(response.headers["content-length"]).toBe("501"); expect(response.headers["content-type"]).toEqual( getContentTypeHeader(), ); expect(response.text).toBe(codeContent.slice(3000, 3501)); - expect(response.text.length).toBe(501); + expect(response.text).toHaveLength(501); }); it('should return the "206" code for the "GET" request with the valid range header (uppercase)', async () => { @@ -1147,16 +1139,16 @@ describe.each([ .get("/bundle.js") .set("RANGE", "BYTES=3000-3500"); - expect(response.statusCode).toEqual(206); - expect(response.headers["content-range"]).toEqual( + expect(response.statusCode).toBe(206); + expect(response.headers["content-range"]).toBe( `bytes 3000-3500/${Buffer.byteLength(codeContent)}`, ); - expect(response.headers["content-length"]).toEqual("501"); + expect(response.headers["content-length"]).toBe("501"); expect(response.headers["content-type"]).toEqual( getContentTypeHeader(), ); expect(response.text).toBe(codeContent.slice(3000, 3501)); - expect(response.text.length).toBe(501); + expect(response.text).toHaveLength(501); }); it('should return the "206" code for the "GET" request with the valid range header when range starts with 0', async () => { @@ -1164,16 +1156,16 @@ describe.each([ .get("/bundle.js") .set("Range", "bytes=0-3500"); - expect(response.statusCode).toEqual(206); - expect(response.headers["content-range"]).toEqual( + expect(response.statusCode).toBe(206); + expect(response.headers["content-range"]).toBe( `bytes 0-3500/${Buffer.byteLength(codeContent)}`, ); - expect(response.headers["content-length"]).toEqual("3501"); + expect(response.headers["content-length"]).toBe("3501"); expect(response.headers["content-type"]).toEqual( getContentTypeHeader(), ); expect(response.text).toBe(codeContent.slice(0, 3501)); - expect(response.text.length).toBe(3501); + expect(response.text).toHaveLength(3501); }); it('should return the "206" code for the "GET" request with the valid range header with multiple values', async () => { @@ -1181,28 +1173,28 @@ describe.each([ .get("/bundle.js") .set("Range", "bytes=0-499, 499-800"); - expect(response.statusCode).toEqual(206); - expect(response.headers["content-range"]).toEqual( + expect(response.statusCode).toBe(206); + expect(response.headers["content-range"]).toBe( `bytes 0-800/${Buffer.byteLength(codeContent)}`, ); - expect(response.headers["content-length"]).toEqual("801"); + expect(response.headers["content-length"]).toBe("801"); expect(response.headers["content-type"]).toEqual( getContentTypeHeader(), ); expect(response.text).toBe(codeContent.slice(0, 801)); - expect(response.text.length).toBe(801); + expect(response.text).toHaveLength(801); }); it('should return the "200" code for the "GET" request with malformed range header which is ignored', async () => { const response = await req.get("/bundle.js").set("Range", "abc"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return the "200" code for the "GET" request with malformed range header which is ignored #2', async () => { const response = await req.get("/bundle.js").set("Range", "bytes"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return the "200" code for the "GET" request with multiple range header which is ignored', async () => { @@ -1210,13 +1202,13 @@ describe.each([ .get("/bundle.js") .set("Range", "bytes=3000-3100,3200-3300"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return the "404" code for the "GET" request with to the non-public path', async () => { const response = await req.get("/nonpublic/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return the "404" code for the "GET" request to the deleted file', async () => { @@ -1230,7 +1222,7 @@ describe.each([ "/public/throw-an-exception-on-readFileSync.txt/", ); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); spy.mockRestore(); }); @@ -1242,7 +1234,7 @@ describe.each([ const response = await req.get("/unknown"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( fileData.byteLength.toString(), ); @@ -1251,17 +1243,17 @@ describe.each([ it('should return "200" code for the "GET" request and "Content-Length" to the file with unicode', async () => { const response = await req.get("/byte-length.html"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); // todo bug on node.js@22 and memfs const [major] = process.versions.node.split(".").map(Number); if (major < 22) { - expect(response.text).toBe("\u00bd + \u00bc = \u00be"); - expect(response.headers["content-length"]).toEqual("12"); + expect(response.text).toBe("\u00BD + \u00BC = \u00BE"); + expect(response.headers["content-length"]).toBe("12"); } - expect(response.headers["content-type"]).toEqual( + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); expect(fs.existsSync(path.resolve(outputPath, "bundle.js"))).toBe( @@ -1272,9 +1264,9 @@ describe.each([ it('should return "200" code for the "GET" request and "Content-Length" of "0" when file is empty', async () => { const response = await req.get("/empty-file.txt"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-length"]).toEqual("0"); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-length"]).toBe("0"); + expect(response.headers["content-type"]).toBe( "text/plain; charset=utf-8", ); }); @@ -1286,17 +1278,17 @@ describe.each([ const response = await req.get("/image image.svg"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( fileData.byteLength.toString(), ); - expect(response.headers["content-type"]).toEqual("image/svg+xml"); + expect(response.headers["content-type"]).toBe("image/svg+xml"); }); it('should return the "404" code for the "GET" request to the "%FF" file', async () => { const response = await req.get("/%FF"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); expect(response.headers["content-type"]).toEqual( get404ContentTypeHeader(name), ); @@ -1332,7 +1324,7 @@ describe.each([ it('should return the "400" code for the "GET" request to the bundle file', async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); }); @@ -1354,20 +1346,20 @@ describe.each([ it('should return "200" code for GET request to the bundle file for the first compiler', async () => { const response = await req.get("/static-one/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to a non existing file for the first compiler', async () => { const response = await req.get("/static-one/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request to the "public" path for the first compiler', async () => { const response = await req.get("/static-one/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -1375,8 +1367,8 @@ describe.each([ it('should return "200" code for GET request to the "index" option for the first compiler', async () => { const response = await req.get("/static-one/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -1384,49 +1376,49 @@ describe.each([ it('should return "200" code for GET request for the bundle file for the second compiler', async () => { const response = await req.get("/static-two/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to a non existing file for the second compiler', async () => { const response = await req.get("/static-two/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to the "public" path for the second compiler', async () => { const response = await req.get("/static-two/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to the "index" option for the second compiler', async () => { const response = await req.get("/static-two/index.html"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to the non-public path', async () => { const response = await req.get("/static-three/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); expect(response.headers["content-type"]).toEqual( get404ContentTypeHeader(name), ); }); - it('should return "404" code for GET request to the non-public path', async () => { + it('should return "404" code for GET request to the non-public path #2', async () => { const response = await req.get("/static-three/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); expect(response.headers["content-type"]).toEqual( get404ContentTypeHeader(name), ); }); - it('should return "404" code for GET request to the non-public path', async () => { + it('should return "404" code for GET request to the non-public path #3', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); expect(response.headers["content-type"]).toEqual( get404ContentTypeHeader(name), ); @@ -1469,20 +1461,20 @@ describe.each([ const response = await req.get("/static-one/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to a non existing file for the first compiler', async () => { const response = await req.get("/static-one/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request to the "public" path for the first compiler', async () => { const response = await req.get("/static-one/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -1490,8 +1482,8 @@ describe.each([ it('should return "200" code for GET request to the "index" option for the first compiler', async () => { const response = await req.get("/static-one/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -1508,31 +1500,31 @@ describe.each([ const response = await req.get("/static-two/bundle.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to a non existing file for the second compiler', async () => { const response = await req.get("/static-two/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to the "public" path for the second compiler', async () => { const response = await req.get("/static-two/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to the "index" option for the second compiler', async () => { const response = await req.get("/static-two/index.html"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to the non-public path', async () => { const response = await req.get("/static-three/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); expect(response.headers["content-type"]).toEqual( get404ContentTypeHeader(name), ); @@ -1972,7 +1964,7 @@ describe.each([ name, framework, compiler, - // eslint-disable-next-line no-undefined + undefined, { setupMiddlewares: (middlewares) => { @@ -2012,7 +2004,6 @@ describe.each([ ); }); } else { - // eslint-disable-next-line no-shadow middlewares.unshift((req, res, next) => { // Express API if (res.set) { @@ -2046,8 +2037,8 @@ describe.each([ it('should not modify the "Content-Type" header', async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "application/vnd.test+octet-stream", ); }); @@ -2055,7 +2046,6 @@ describe.each([ describe('should work without "output" options', () => { beforeAll(async () => { - // eslint-disable-next-line no-undefined const compiler = getCompiler({ ...webpackConfig, output: undefined }); [server, req, instance] = await frameworkFactory( @@ -2072,20 +2062,20 @@ describe.each([ it('should return "200" code for GET request to the bundle file', async () => { const response = await req.get("/main.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to a nonexistent file', async () => { const response = await req.get("/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request to the non-public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2093,8 +2083,8 @@ describe.each([ it('should return "200" code for GET request to the "index" option', async () => { const response = await req.get("/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2124,20 +2114,20 @@ describe.each([ it('should return "200" code for GET request to the bundle file', async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to a nonexistent file', async () => { const response = await req.get("/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request to the non-public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2145,8 +2135,8 @@ describe.each([ it('should return "200" code for GET request to the "index" option', async () => { const response = await req.get("/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2170,20 +2160,20 @@ describe.each([ it('should return "200" code for GET request to the bundle file', async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to a nonexistent file', async () => { const response = await req.get("/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request to the non-public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2191,8 +2181,8 @@ describe.each([ it('should return "200" code for GET request to the "index" option', async () => { const response = await req.get("/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2223,20 +2213,20 @@ describe.each([ it('should return "200" code for GET request to the bundle file', async () => { const response = await req.get("/static/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to a nonexistent file', async () => { const response = await req.get("/static/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request to the public path', async () => { const response = await req.get("/static/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2244,8 +2234,8 @@ describe.each([ it('should return "200" code for GET request to the "index" option', async () => { const response = await req.get("/static/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2253,7 +2243,7 @@ describe.each([ it('should return "404" code for GET request to the non-public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); expect(response.headers["content-type"]).toEqual( get404ContentTypeHeader(name), ); @@ -2300,20 +2290,20 @@ describe.each([ it('should return "200" code for GET request to the bundle file', async () => { const response = await req.get(`/static/${hash}/bundle.js`); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to a nonexistent file', async () => { const response = await req.get("/static/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request to the public path', async () => { const response = await req.get(`/static/${hash}/`); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2321,8 +2311,8 @@ describe.each([ it('should return "200" code for GET request to the "index" option', async () => { const response = await req.get(`/static/${hash}/index.html`); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2330,7 +2320,7 @@ describe.each([ it('should return "404" code for GET request to the non-public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); }); @@ -2394,20 +2384,20 @@ describe.each([ it('should return "200" code for GET request to the bundle file for the first compiler', async () => { const response = await req.get(`/static-one/${hashOne}/bundle.js`); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to nonexistent file for the first compiler', async () => { const response = await req.get(`/static-one/${hashOne}/invalid.js`); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request for the second bundle file', async () => { const response = await req.get(`/static-one/${hashOne}/`); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2415,8 +2405,8 @@ describe.each([ it('should return "200" code for GET request to the "index" option for the first compiler', async () => { const response = await req.get(`/static-one/${hashOne}/index.html`); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2424,7 +2414,7 @@ describe.each([ it('should return "200" code for GET request to the bundle file for the second compiler', async () => { const response = await req.get(`/static-two/${hashTwo}/bundle.js`); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-type"]).toEqual( getContentTypeHeader(), ); @@ -2433,7 +2423,7 @@ describe.each([ it('should return "404" code for GET request to nonexistent file for the second compiler', async () => { const response = await req.get(`/static-two/${hashTwo}/invalid.js`); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); expect(response.headers["content-type"]).toEqual( get404ContentTypeHeader(name), ); @@ -2442,19 +2432,19 @@ describe.each([ it('should return "404" code for GET request to the "public" path for the second compiler', async () => { const response = await req.get(`/static-two/${hashTwo}/`); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to the "index" option for the second compiler', async () => { const response = await req.get(`/static-two/${hashTwo}/index.html`); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to non-public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); }); @@ -2476,20 +2466,20 @@ describe.each([ it('should return "200" code for GET request to the bundle file for the first compiler', async () => { const response = await req.get("/static-one/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to nonexistent file for the first compiler', async () => { const response = await req.get("/static-one/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request to the "public" path for the first compiler', async () => { const response = await req.get("/static-one/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2497,8 +2487,8 @@ describe.each([ it('should return "200" code for GET request to the "index" option for the first compiler', async () => { const response = await req.get("/static-one/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2506,37 +2496,37 @@ describe.each([ it('should return "200" code for GET request to the second bundle file', async () => { const response = await req.get("/static-two/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to nonexistent file for the second compiler', async () => { const response = await req.get("/static-two/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request to the "public" path for the second compiler', async () => { const response = await req.get("/static-two/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request to the "index" option for the second compiler', async () => { const response = await req.get("/static-two/index.html"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to nonexistent file', async () => { const response = await req.get("/static/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to non-public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); }); @@ -2575,26 +2565,26 @@ describe.each([ it('should return "200" code for GET request to the bundle file for the first compiler', async () => { const response = await req.get("/my-public/bundle-one.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "200" code for GET request to the bundle file for the second compiler', async () => { const response = await req.get("/my-public/bundle-two.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); - it('should return "404" code for GET request to nonexistent file', async () => { + it('should return "404" code for GET request to nonexistent file #1', async () => { const response = await req.get("/my-public/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request to the "public" path', async () => { const response = await req.get("/my-public/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2602,22 +2592,22 @@ describe.each([ it('should return "200" code for GET request to the "index" option', async () => { const response = await req.get("/my-public/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); - it('should return "404" code for GET request to nonexistent file', async () => { + it('should return "404" code for GET request to nonexistent file #2', async () => { const response = await req.get("/static/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to non-public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); }); @@ -2656,20 +2646,20 @@ describe.each([ it('should return "200" code for GET request to the bundle file for the first compiler', async () => { const response = await req.get("/one-public/bundle-one.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to nonexistent file to the first bundle file', async () => { const response = await req.get("/one-public/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request to the "public" path for the first compiler', async () => { const response = await req.get("/one-public/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2677,8 +2667,8 @@ describe.each([ it('should return "200" code for GET request to the "index" option for the first compiler', async () => { const response = await req.get("/one-public/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2686,7 +2676,7 @@ describe.each([ it('should return "200" code for GET request to the bundle file for the second compiler', async () => { const response = await req.get("/two-public/bundle-two.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-type"]).toEqual( getContentTypeHeader(), ); @@ -2695,14 +2685,14 @@ describe.each([ it('should return "404" code for GET request to nonexistent file to the second bundle file', async () => { const response = await req.get("/two-public/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "200" code for GET request to the "public" path for the second compiler', async () => { const response = await req.get("/two-public/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2710,8 +2700,8 @@ describe.each([ it('should return "200" code for GET request to the "index" option for the second compiler', async () => { const response = await req.get("/two-public/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2719,13 +2709,13 @@ describe.each([ it('should return "404" code for GET request to nonexistent file', async () => { const response = await req.get("/static/invalid"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to non-public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); }); @@ -2747,7 +2737,7 @@ describe.each([ it('should return "200" code for GET request to the bundle file', async () => { const response = await req.get("/static/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-type"]).toEqual( getContentTypeHeader(), ); @@ -2756,14 +2746,14 @@ describe.each([ it('should return "404" code for GET request to nonexistent file', async () => { const response = await req.get("/static/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to the public path', async () => { const response = await req.get("/static/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2771,8 +2761,8 @@ describe.each([ it('should return "404" code for GET request to the "index" option', async () => { const response = await req.get("/static/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2780,7 +2770,7 @@ describe.each([ it('should return "404" code for GET request to non-public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); }); @@ -2805,20 +2795,20 @@ describe.each([ it('should return "200" code for GET request to the bundle file', async () => { const response = await req.get("/static/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to nonexistent file', async () => { const response = await req.get("/static/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to the public path', async () => { const response = await req.get("/static/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2826,8 +2816,8 @@ describe.each([ it('should return "404" code for GET request to the "index" option', async () => { const response = await req.get("/static/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2835,7 +2825,7 @@ describe.each([ it('should return "404" code for GET request to non-public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); }); @@ -2873,26 +2863,26 @@ describe.each([ it('should return "200" code for GET request to the bundle file', async () => { const response = await req.get("/static/bundle-one.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "404" code for GET request to a nonexistent file', async () => { const response = await req.get("/static/invalid.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return "404" code for GET request to the public path', async () => { const response = await req.get("/static/"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return "200" code for GET request to the non-public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2900,8 +2890,8 @@ describe.each([ it('should return "404" code for GET request to the "index" option', async () => { const response = await req.get("/static/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -2935,7 +2925,7 @@ describe.each([ it('should return the "200" code for the "GET" request to the bundle file', async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); }); @@ -2974,7 +2964,6 @@ describe.each([ function createReadStream(...args) { const brokenStream = new this.ReadStream(...args); - // eslint-disable-next-line no-underscore-dangle brokenStream._read = function _read() { this.emit("error", new Error("test")); this.end(); @@ -2992,8 +2981,8 @@ describe.each([ it('should return the "500" code for the "GET" request to the "image.svg" file', async () => { const response = await req.get("/image.svg"); - expect(response.statusCode).toEqual(500); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(500); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); expect(response.text).toEqual( @@ -3011,7 +3000,7 @@ describe.each([ }); }); - describe("should handle known fs errors and response 404 code", () => { + describe("should handle known fs errors and response 404 code #2", () => { let compiler; const outputPath = path.resolve( @@ -3046,7 +3035,6 @@ describe.each([ function createReadStream(...args) { const brokenStream = new this.ReadStream(...args); - // eslint-disable-next-line no-underscore-dangle brokenStream._read = function _read() { const error = new Error("test"); @@ -3068,8 +3056,8 @@ describe.each([ it('should return the "404" code for the "GET" request to the "image.svg" file', async () => { const response = await req.get("/image.svg"); - expect(response.statusCode).toEqual(404); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(404); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); expect(response.text).toEqual( @@ -3132,7 +3120,7 @@ describe.each([ it('should return the "200" code for the "GET" request to the bundle file', async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( String(Buffer.byteLength(codeContent)), ); @@ -3149,11 +3137,11 @@ describe.each([ const response = await req.get("/image.svg"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( fileData.byteLength.toString(), ); - expect(response.headers["content-type"]).toEqual("image/svg+xml"); + expect(response.headers["content-type"]).toBe("image/svg+xml"); }); it('should return the "200" code for the "HEAD" request to the "image.svg" file', async () => { @@ -3163,11 +3151,11 @@ describe.each([ const response = await req.head("/image.svg"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-length"]).toEqual( fileData.byteLength.toString(), ); - expect(response.headers["content-type"]).toEqual("image/svg+xml"); + expect(response.headers["content-type"]).toBe("image/svg+xml"); expect(response.body).toEqual({}); }); }); @@ -3217,8 +3205,8 @@ describe.each([ it('should return the "500" code for the "GET" request to the "image.svg" file', async () => { const response = await req.get("/image.svg"); - expect(response.statusCode).toEqual(500); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(500); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); expect(response.text).toEqual( @@ -3285,8 +3273,8 @@ describe.each([ it('should return the "404" code for the "GET" request to the "image.svg" file', async () => { const response = await req.get("/image.svg"); - expect(response.statusCode).toEqual(404); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(404); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); expect(response.text).toEqual( @@ -3332,7 +3320,6 @@ describe.each([ // There's no such thing as "the next route handler" in hapi. One request is matched to one or no route handlers. } else if (name === "koa") { middlewares.push(async (ctx, next) => { - // eslint-disable-next-line no-param-reassign ctx.url = "/index.html"; await next(); @@ -3349,7 +3336,6 @@ describe.each([ middlewares.push({ route: "/", fn: (oldReq, res, next) => { - // eslint-disable-next-line no-param-reassign oldReq.url = "/index.html"; next(); }, @@ -3378,8 +3364,8 @@ describe.each([ it('should return the "200" code for the "GET" request to the bundle file', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -3387,8 +3373,8 @@ describe.each([ it('should return the "200" code for the "HEAD" request to the bundle file', async () => { const response = await req.head("/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); expect(response.text).toBeUndefined(); @@ -3430,11 +3416,11 @@ describe.each([ it('should return the "200" code for the "GET" request to "file.html"', async () => { const response = await req.get("/file.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); - expect(response.text).toEqual("welcome"); + expect(response.text).toBe("welcome"); }); }); @@ -3476,11 +3462,11 @@ describe.each([ it('should return the "200" code for the "GET" request "file.phtml"', async () => { const response = await req.get("/file.myhtml"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); - expect(response.text).toEqual("welcome"); + expect(response.text).toBe("welcome"); }); }); @@ -3522,10 +3508,8 @@ describe.each([ it('should return the "200" code for the "GET" request "file.jpg"', async () => { const response = await req.get("/file.jpg"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( - "image/vnd.test+jpeg", - ); + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe("image/vnd.test+jpeg"); }); }); @@ -3566,7 +3550,7 @@ describe.each([ it('should return the "200" code for the "GET" request "file.jpg" with default content type', async () => { const response = await req.get("/file.jpg"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-type"]).toMatch( name === "fastify" ? /text\/plain; charset=utf-8/ : /text\/html/, ); @@ -3611,11 +3595,11 @@ describe.each([ it('should return the "200" code for the "GET" request to "file.html"', async () => { const response = await req.get("/file.unknown"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect( response.headers["content-type"].startsWith("text/plain"), ).toBe(true); - expect(response.text).toEqual("welcome"); + expect(response.text).toBe("welcome"); }); }); }); @@ -3645,7 +3629,7 @@ describe.each([ it('should pass arguments to the "watch" method', async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(spy).toHaveBeenCalledTimes(1); expect(spy.mock.calls[0][0]).toEqual({}); }); @@ -3676,7 +3660,7 @@ describe.each([ it('should pass arguments to the "watch" method', async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(spy).toHaveBeenCalledTimes(1); expect(spy.mock.calls[0][0]).toEqual({ aggregateTimeout: 300, @@ -3710,11 +3694,11 @@ describe.each([ it('should pass arguments to the "watch" method', async () => { const response1 = await req.get("/static-one/bundle.js"); - expect(response1.statusCode).toEqual(200); + expect(response1.statusCode).toBe(200); const response2 = await req.get("/static-two/bundle.js"); - expect(response2.statusCode).toEqual(200); + expect(response2.statusCode).toBe(200); expect(spy).toHaveBeenCalledTimes(1); expect(spy.mock.calls[0][0]).toEqual([ { aggregateTimeout: 800, poll: false }, @@ -3773,8 +3757,8 @@ describe.each([ expect( compiler.hooks.assetEmitted.taps.filter( (hook) => hook.name === "DevMiddleware", - ).length, - ).toBe(1); + ), + ).toHaveLength(1); expect(fs.existsSync(bundlePath)).toBe(true); instance.invalidate(); @@ -3785,8 +3769,8 @@ describe.each([ expect( compiler.hooks.assetEmitted.taps.filter( (hook) => hook.name === "DevMiddleware", - ).length, - ).toBe(1); + ), + ).toHaveLength(1); done(); }, @@ -3797,11 +3781,11 @@ describe.each([ it("should not allow to get files above root", async () => { const response = await req.get("/public/..%2f../middleware.test.js"); - expect(response.statusCode).toEqual(403); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(403); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); - expect(response.text).toEqual(` + expect(response.text).toBe(` @@ -3868,8 +3852,8 @@ describe.each([ expect( compiler.hooks.assetEmitted.taps.filter( (hook) => hook.name === "DevMiddleware", - ).length, - ).toBe(1); + ), + ).toHaveLength(1); expect(fs.existsSync(bundlePath)).toBe(true); instance.invalidate(); @@ -3880,8 +3864,8 @@ describe.each([ expect( compiler.hooks.assetEmitted.taps.filter( (hook) => hook.name === "DevMiddleware", - ).length, - ).toBe(1); + ), + ).toHaveLength(1); done(); }, @@ -3928,8 +3912,8 @@ describe.each([ expect( compiler.hooks.assetEmitted.taps.filter( (hook) => hook.name === "DevMiddleware", - ).length, - ).toBe(0); + ), + ).toHaveLength(0); expect(fs.existsSync(bundlePath)).toBe(false); instance.invalidate(); @@ -3940,8 +3924,8 @@ describe.each([ expect( compiler.hooks.assetEmitted.taps.filter( (hook) => hook.name === "DevMiddleware", - ).length, - ).toBe(0); + ), + ).toHaveLength(0); done(); }, @@ -3988,7 +3972,7 @@ describe.each([ it("should find the bundle file on disk", async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); const bundlePath = path.resolve( __dirname, @@ -4037,7 +4021,7 @@ describe.each([ it("should not find the bundle file on disk", async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); const bundlePath = path.resolve( __dirname, @@ -4084,7 +4068,7 @@ describe.each([ it("should find the bundle file on disk with no querystring", async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); const bundlePath = path.resolve( __dirname, @@ -4148,11 +4132,11 @@ describe.each([ it("should find the bundle files on disk", async () => { const response1 = await req.get("/static-one/bundle.js"); - expect(response1.statusCode).toEqual(200); + expect(response1.statusCode).toBe(200); const response2 = await req.get("/static-two/bundle.js"); - expect(response2.statusCode).toEqual(200); + expect(response2.statusCode).toBe(200); const bundleFiles = [ "./outputs/write-to-disk-multi-compiler/static-one/bundle.js", @@ -4181,15 +4165,14 @@ describe.each([ beforeAll(async () => { compiler = getCompiler({ ...webpackConfig, - ...{ - output: { - filename: "bundle.js", - publicPath: "/static/[fullhash]/", - path: path.resolve( - __dirname, - "./outputs/write-to-disk-with-hash/dist_[fullhash]", - ), - }, + + output: { + filename: "bundle.js", + publicPath: "/static/[fullhash]/", + path: path.resolve( + __dirname, + "./outputs/write-to-disk-with-hash/dist_[fullhash]", + ), }, }); compiler.hooks.afterCompile.tap("wdm-test", ({ hash: h }) => { @@ -4225,7 +4208,7 @@ describe.each([ it("should find the bundle file on disk", async () => { const response = await req.get(`/static/${hash}/bundle.js`); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); const bundlePath = path.resolve( __dirname, @@ -4259,21 +4242,21 @@ describe.each([ }); it('should return the "200" code for the "POST" request to the bundle file', async () => { - const response = await req.post(`/public/bundle.js`); + const response = await req.post("/public/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); it('should return the "404" code for the "GET" request to the bundle file', async () => { - const response = await req.get(`/public/bundle.js`); + const response = await req.get("/public/bundle.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); it('should return the "404" code for the "HEAD" request to the bundle file', async () => { - const response = await req.head(`/public/bundle.js`); + const response = await req.head("/public/bundle.js"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); }); @@ -4304,16 +4287,16 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and return headers', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); - expect(response.headers["x-nonsense-1"]).toEqual("yes"); - expect(response.headers["x-nonsense-2"]).toEqual("no"); + expect(response.statusCode).toBe(200); + expect(response.headers["x-nonsense-1"]).toBe("yes"); + expect(response.headers["x-nonsense-2"]).toBe("no"); }); it('should return the "200" code for the "GET" request to path not in outputFileSystem but not return headers', async () => { const res = await req.get("/file.jpg"); - expect(res.statusCode).toEqual(200); + expect(res.statusCode).toBe(200); expect(res.headers["X-nonsense-1"]).toBeUndefined(); expect(res.headers["X-nonsense-2"]).toBeUndefined(); }); @@ -4354,16 +4337,16 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and return headers', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); - expect(response.headers["x-foo"]).toEqual("value1"); - expect(response.headers["x-bar"]).toEqual("value2"); + expect(response.statusCode).toBe(200); + expect(response.headers["x-foo"]).toBe("value1"); + expect(response.headers["x-bar"]).toBe("value2"); }); it('should return the "200" code for the "GET" request to path not in outputFileSystem but not return headers', async () => { const res = await req.get("/file.jpg"); - expect(res.statusCode).toEqual(200); + expect(res.statusCode).toBe(200); expect(res.headers["x-foo"]).toBeUndefined(); expect(res.headers["x-bar"]).toBeUndefined(); }); @@ -4378,9 +4361,7 @@ describe.each([ framework, compiler, { - headers: () => { - return { "X-nonsense-1": "yes", "X-nonsense-2": "no" }; - }, + headers: () => ({ "X-nonsense-1": "yes", "X-nonsense-2": "no" }), }, { setupMiddlewares: (middlewares) => { @@ -4397,16 +4378,16 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and return headers', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); - expect(response.headers["x-nonsense-1"]).toEqual("yes"); - expect(response.headers["x-nonsense-2"]).toEqual("no"); + expect(response.statusCode).toBe(200); + expect(response.headers["x-nonsense-1"]).toBe("yes"); + expect(response.headers["x-nonsense-2"]).toBe("no"); }); it('should return the "200" code for the "GET" request to path not in outputFileSystem but not return headers', async () => { const res = await req.get("/file.jpg"); - expect(res.statusCode).toEqual(200); + expect(res.statusCode).toBe(200); expect(res.headers["X-nonsense-1"]).toBeUndefined(); expect(res.headers["X-nonsense-2"]).toBeUndefined(); }); @@ -4447,16 +4428,16 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and return headers', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); - expect(response.headers["x-foo"]).toEqual("value1"); - expect(response.headers["x-bar"]).toEqual("value2"); + expect(response.statusCode).toBe(200); + expect(response.headers["x-foo"]).toBe("value1"); + expect(response.headers["x-bar"]).toBe("value2"); }); it('should return the "200" code for the "GET" request to path not in outputFileSystem but not return headers', async () => { const res = await req.get("/file.jpg"); - expect(res.statusCode).toEqual(200); + expect(res.statusCode).toBe(200); expect(res.headers["x-foo"]).toBeUndefined(); expect(res.headers["x-bar"]).toBeUndefined(); }); @@ -4471,7 +4452,7 @@ describe.each([ framework, compiler, { - // eslint-disable-next-line no-unused-vars, no-shadow + // eslint-disable-next-line no-unused-vars headers: (req, res, context) => { res.setHeader("X-nonsense-1", "yes"); res.setHeader("X-nonsense-2", "no"); @@ -4492,17 +4473,17 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and return headers', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); - expect(response.headers["x-nonsense-1"]).toEqual("yes"); - expect(response.headers["x-nonsense-2"]).toEqual("no"); + expect(response.statusCode).toBe(200); + expect(response.headers["x-nonsense-1"]).toBe("yes"); + expect(response.headers["x-nonsense-2"]).toBe("no"); }); it('should return the "200" code for the "GET" request to path not in outputFileSystem but not return headers', async () => { const res = await req.get("/file.jpg"); - expect(res.statusCode).toEqual(200); + expect(res.statusCode).toBe(200); expect(res.headers["X-nonsense-1"]).toBeUndefined(); expect(res.headers["X-nonsense-2"]).toBeUndefined(); }); @@ -4527,9 +4508,9 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file', async () => { - const response = await req.get(`/public/bundle.js`); + const response = await req.get("/public/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); }); @@ -4552,7 +4533,7 @@ describe.each([ it('should return the "200" code for the "GET" request to the bundle file', async () => { const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); }); }); @@ -4574,7 +4555,6 @@ describe.each([ middlewares.push(async (ctx, next) => { locals = ctx.state; - // eslint-disable-next-line no-param-reassign ctx.status = 200; await next(); @@ -4595,7 +4575,6 @@ describe.each([ method: "GET", path: "/foo/bar", handler(innerReq) { - // eslint-disable-next-line prefer-destructuring locals = innerReq.raw.res.locals; return "welcome"; @@ -4606,7 +4585,6 @@ describe.each([ }); } else { middlewares.push((_req, res) => { - // eslint-disable-next-line prefer-destructuring locals = res.locals; // Express API @@ -4615,7 +4593,6 @@ describe.each([ } // Connect API else { - // eslint-disable-next-line no-param-reassign res.statusCode = 200; res.end(); } @@ -4635,7 +4612,7 @@ describe.each([ it('should return the "200" code for the "GET" request', async () => { const response = await req.get("/foo/bar"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(locals.webpack.devMiddleware).toBeDefined(); }); }); @@ -4808,7 +4785,7 @@ describe.each([ it('should return the "404" code for the "GET" request to the public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); expect(response.headers["content-type"]).toEqual( get404ContentTypeHeader(name), ); @@ -4817,8 +4794,8 @@ describe.each([ it('should return the "200" code for the "GET" request to the "index.html" file', async () => { const response = await req.get("/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -4843,17 +4820,17 @@ describe.each([ it('should return the "200" code for the "GET" request to the public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); - it('should return the "200" code for the "GET" request to the public path', async () => { + it('should return the "200" code for the "GET" request to the public path #2', async () => { const response = await req.get("/index.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -4896,8 +4873,8 @@ describe.each([ it('should return the "200" code for the "GET" request to the public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -4940,7 +4917,7 @@ describe.each([ it('should return the "200" code for the "GET" request to the public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); }); @@ -4984,8 +4961,8 @@ describe.each([ it('should return the "200" code for the "GET" request to the public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); }); @@ -5025,7 +5002,7 @@ describe.each([ it('should return the "200" code for the "GET" request to the public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); }); }); @@ -5065,7 +5042,7 @@ describe.each([ it('should return the "404" code for the "GET" request to the public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); }); @@ -5088,12 +5065,10 @@ describe.each([ isDirectory = jest .spyOn(instance.context.outputFileSystem, "statSync") - .mockImplementation(() => { - return { - isFile: () => false, - isDirectory: () => false, - }; - }); + .mockImplementation(() => ({ + isFile: () => false, + isDirectory: () => false, + })); }); afterAll(async () => { @@ -5105,7 +5080,7 @@ describe.each([ it('should return the "404" code for the "GET" request to the public path', async () => { const response = await req.get("/"); - expect(response.statusCode).toEqual(404); + expect(response.statusCode).toBe(404); }); }); }); @@ -5157,11 +5132,11 @@ describe.each([ it("should modify file", async () => { const response = await req.get("/file.html"); - expect(response.statusCode).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.statusCode).toBe(200); + expect(response.headers["content-type"]).toBe( "text/html; charset=utf-8", ); - expect(response.text).toEqual("test"); + expect(response.text).toBe("test"); }); }); }); @@ -5186,112 +5161,112 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and set weak etag', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers.etag).toBeDefined(); expect(response.headers.etag.startsWith("W/")).toBe(true); }); it('should return the "304" code for the "GET" request to the bundle file with etag and "if-none-match" header', async () => { - const response1 = await req.get(`/bundle.js`); + const response1 = await req.get("/bundle.js"); - expect(response1.statusCode).toEqual(200); + expect(response1.statusCode).toBe(200); expect(response1.headers.etag).toBeDefined(); expect(response1.headers.etag.startsWith("W/")).toBe(true); const response2 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-none-match", response1.headers.etag); - expect(response2.statusCode).toEqual(304); + expect(response2.statusCode).toBe(304); expect(response2.headers.etag).toBeDefined(); expect(response2.headers.etag.startsWith("W/")).toBe(true); const response3 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-none-match", `${response1.headers.etag}, test`); - expect(response3.statusCode).toEqual(304); + expect(response3.statusCode).toBe(304); expect(response3.headers.etag).toBeDefined(); expect(response3.headers.etag.startsWith("W/")).toBe(true); const response4 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-none-match", "*"); - expect(response4.statusCode).toEqual(304); + expect(response4.statusCode).toBe(304); expect(response4.headers.etag).toBeDefined(); expect(response4.headers.etag.startsWith("W/")).toBe(true); const response5 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-none-match", "test"); - expect(response5.statusCode).toEqual(200); + expect(response5.statusCode).toBe(200); expect(response5.headers.etag).toBeDefined(); expect(response5.headers.etag.startsWith("W/")).toBe(true); }); it('should return the "200" code for the "GET" request to the bundle file with etag and "if-match" header', async () => { - const response1 = await req.get(`/bundle.js`); + const response1 = await req.get("/bundle.js"); - expect(response1.statusCode).toEqual(200); + expect(response1.statusCode).toBe(200); expect(response1.headers.etag).toBeDefined(); expect(response1.headers.etag.startsWith("W/")).toBe(true); const response2 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-match", response1.headers.etag); - expect(response2.statusCode).toEqual(200); + expect(response2.statusCode).toBe(200); expect(response2.headers.etag).toBeDefined(); expect(response2.headers.etag.startsWith("W/")).toBe(true); const response3 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-match", `${response1.headers.etag}, foo`); - expect(response3.statusCode).toEqual(200); + expect(response3.statusCode).toBe(200); expect(response3.headers.etag).toBeDefined(); expect(response3.headers.etag.startsWith("W/")).toBe(true); - const response4 = await req.get(`/bundle.js`).set("if-match", "*"); + const response4 = await req.get("/bundle.js").set("if-match", "*"); - expect(response4.statusCode).toEqual(200); + expect(response4.statusCode).toBe(200); expect(response4.headers.etag).toBeDefined(); expect(response4.headers.etag.startsWith("W/")).toBe(true); - const response5 = await req.get(`/bundle.js`).set("if-match", "test"); + const response5 = await req.get("/bundle.js").set("if-match", "test"); - expect(response5.statusCode).toEqual(412); + expect(response5.statusCode).toBe(412); }); it('should return the "412" code for the "GET" request to the bundle file with etag and wrong "if-match" header', async () => { - const response1 = await req.get(`/bundle.js`); + const response1 = await req.get("/bundle.js"); - expect(response1.statusCode).toEqual(200); + expect(response1.statusCode).toBe(200); expect(response1.headers.etag).toBeDefined(); expect(response1.headers.etag.startsWith("W/")).toBe(true); - const response2 = await req.get(`/bundle.js`).set("if-match", "test"); + const response2 = await req.get("/bundle.js").set("if-match", "test"); - expect(response2.statusCode).toEqual(412); + expect(response2.statusCode).toBe(412); }); it('should return the "200" code for the "GET" request to the bundle file with etag and "if-match" and "cache-control: no-cache" header', async () => { - const response1 = await req.get(`/bundle.js`); + const response1 = await req.get("/bundle.js"); - expect(response1.statusCode).toEqual(200); + expect(response1.statusCode).toBe(200); expect(response1.headers.etag).toBeDefined(); expect(response1.headers.etag.startsWith("W/")).toBe(true); const response2 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-match", response1.headers.etag) .set("Cache-Control", "no-cache"); - expect(response2.statusCode).toEqual(200); + expect(response2.statusCode).toBe(200); expect(response2.headers.etag).toBeDefined(); expect(response2.headers.etag.startsWith("W/")).toBe(true); }); @@ -5302,7 +5277,7 @@ describe.each([ .set("if-range", '"test"') .set("Range", "bytes=3000-3500"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-type"]).toEqual( getContentTypeHeader(), ); @@ -5339,9 +5314,9 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and set strong etag', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers.etag).toBe( /* cspell:disable-next-line */ '"191a-fDcjg9fXC+4k9zvx46niAuR6C14"', @@ -5349,9 +5324,9 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the file.txt and set strong etag on empty file', async () => { - const response = await req.get(`/file.txt`); + const response = await req.get("/file.txt"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers.etag).toBe( /* cspell:disable-next-line */ '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"', @@ -5363,12 +5338,12 @@ describe.each([ .get("/bundle.js") .set("Range", "bytes=3000-3500"); - expect(response.statusCode).toEqual(206); - expect(response.headers["content-length"]).toEqual("501"); + expect(response.statusCode).toBe(206); + expect(response.headers["content-length"]).toBe("501"); expect(response.headers["content-type"]).toEqual( getContentTypeHeader(), ); - expect(response.text.length).toBe(501); + expect(response.text).toHaveLength(501); expect(response.headers.etag).toBeDefined(); const response1 = await req @@ -5376,7 +5351,7 @@ describe.each([ .set("If-Range", '"test') .set("Range", "bytes=3000-3500"); - expect(response1.statusCode).toEqual(200); + expect(response1.statusCode).toBe(200); }); }); @@ -5401,9 +5376,9 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and set weak etag', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers.etag).toBe( /* cspell:disable-next-line */ '"191a-fDcjg9fXC+4k9zvx46niAuR6C14"', @@ -5428,10 +5403,10 @@ describe.each([ it('should return the "200" code for the "GET" request to the bundle file and `if-none-match` header without etag', async () => { const response = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-none-match", "etag"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers.etag).toBeUndefined(); }); }); @@ -5457,27 +5432,27 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and set "Last-Modified"', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["last-modified"]).toBeDefined(); }); it('should return the "304" code for the "GET" request to the bundle file with "Last-Modified" and "if-modified-since" header', async () => { - const response1 = await req.get(`/bundle.js`); + const response1 = await req.get("/bundle.js"); - expect(response1.statusCode).toEqual(200); + expect(response1.statusCode).toBe(200); expect(response1.headers["last-modified"]).toBeDefined(); const response2 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-modified-since", response1.headers["last-modified"]); - expect(response2.statusCode).toEqual(304); + expect(response2.statusCode).toBe(304); expect(response2.headers["last-modified"]).toBeDefined(); const response3 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set( "if-modified-since", new Date( @@ -5485,38 +5460,38 @@ describe.each([ ).toUTCString(), ); - expect(response3.statusCode).toEqual(200); + expect(response3.statusCode).toBe(200); expect(response3.headers["last-modified"]).toBeDefined(); }); it('should return the "200" code for the "GET" request to the bundle file with "Last-Modified" and "if-unmodified-since" header', async () => { - const response1 = await req.get(`/bundle.js`); + const response1 = await req.get("/bundle.js"); - expect(response1.statusCode).toEqual(200); + expect(response1.statusCode).toBe(200); expect(response1.headers["last-modified"]).toBeDefined(); const response2 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-unmodified-since", response1.headers["last-modified"]); - expect(response2.statusCode).toEqual(200); + expect(response2.statusCode).toBe(200); expect(response2.headers["last-modified"]).toBeDefined(); const response3 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-unmodified-since", "Fri, 29 Mar 2020 10:25:50 GMT"); - expect(response3.statusCode).toEqual(412); + expect(response3.statusCode).toBe(412); }); it('should return the "412" code for the "GET" request to the bundle file with etag and "if-unmodified-since" header', async () => { - const response1 = await req.get(`/bundle.js`); + const response1 = await req.get("/bundle.js"); - expect(response1.statusCode).toEqual(200); + expect(response1.statusCode).toBe(200); expect(response1.headers["last-modified"]).toBeDefined(); const response2 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set( "if-unmodified-since", new Date( @@ -5524,21 +5499,21 @@ describe.each([ ).toUTCString(), ); - expect(response2.statusCode).toEqual(412); + expect(response2.statusCode).toBe(412); }); it('should return the "200" code for the "GET" request to the bundle file with etag and "if-match" and "cache-control: no-cache" header', async () => { - const response1 = await req.get(`/bundle.js`); + const response1 = await req.get("/bundle.js"); - expect(response1.statusCode).toEqual(200); + expect(response1.statusCode).toBe(200); expect(response1.headers["last-modified"]).toBeDefined(); const response2 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-unmodified-since", response1.headers["last-modified"]) .set("Cache-Control", "no-cache"); - expect(response2.statusCode).toEqual(200); + expect(response2.statusCode).toBe(200); expect(response1.headers["last-modified"]).toBeDefined(); }); @@ -5548,7 +5523,7 @@ describe.each([ .set("if-range", new Date(1000).toUTCString()) .set("Range", "bytes=3000-3500"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["content-type"]).toEqual( getContentTypeHeader(), ); @@ -5576,14 +5551,14 @@ describe.each([ }); it('should return the "304" code for the "GET" request to the bundle file and prefer "if-match" over "if-unmodified-since"', async () => { - const response1 = await req.get(`/bundle.js`); + const response1 = await req.get("/bundle.js"); - expect(response1.statusCode).toEqual(200); + expect(response1.statusCode).toBe(200); expect(response1.headers["last-modified"]).toBeDefined(); expect(response1.headers.etag).toBeDefined(); const response2 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-match", response1.headers.etag) .set( "if-unmodified-since", @@ -5592,20 +5567,20 @@ describe.each([ ).toUTCString(), ); - expect(response2.statusCode).toEqual(200); + expect(response2.statusCode).toBe(200); expect(response2.headers["last-modified"]).toBeDefined(); expect(response2.headers.etag).toBeDefined(); }); it('should return the "304" code for the "GET" request to the bundle file and prefer "if-none-match" over "if-modified-since"', async () => { - const response1 = await req.get(`/bundle.js`); + const response1 = await req.get("/bundle.js"); - expect(response1.statusCode).toEqual(200); + expect(response1.statusCode).toBe(200); expect(response1.headers["last-modified"]).toBeDefined(); expect(response1.headers.etag).toBeDefined(); const response2 = await req - .get(`/bundle.js`) + .get("/bundle.js") .set("if-none-match", response1.headers.etag) .set( "if-modified-since", @@ -5614,7 +5589,7 @@ describe.each([ ).toUTCString(), ); - expect(response2.statusCode).toEqual(304); + expect(response2.statusCode).toBe(304); expect(response2.headers["last-modified"]).toBeDefined(); expect(response2.headers.etag).toBeDefined(); }); @@ -5638,9 +5613,9 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and don\'t generate `Cache-Control` header', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeUndefined(); }); }); @@ -5662,9 +5637,9 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and don\'t generate `Cache-Control` header', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeDefined(); expect(response.headers["cache-control"]).toBe( "public, max-age=31536000", @@ -5689,9 +5664,9 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and don\'t generate `Cache-Control` header', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeDefined(); expect(response.headers["cache-control"]).toBe("public, max-age=100"); }); @@ -5714,9 +5689,9 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and don\'t generate `Cache-Control` header', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeDefined(); expect(response.headers["cache-control"]).toBe("max-age=123456"); }); @@ -5744,9 +5719,9 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and don\'t generate `Cache-Control` header', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeDefined(); expect(response.headers["cache-control"]).toBe( "public, max-age=100, immutable", @@ -5775,9 +5750,9 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and don\'t generate `Cache-Control` header', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeDefined(); expect(response.headers["cache-control"]).toBe( "public, max-age=31536000, immutable", @@ -5806,9 +5781,9 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and don\'t generate `Cache-Control` header', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeDefined(); expect(response.headers["cache-control"]).toBe("public, max-age=100"); }); @@ -5833,9 +5808,9 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and don\'t generate `Cache-Control` header', async () => { - const response = await req.get(`/bundle.js`); + const response = await req.get("/bundle.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeDefined(); expect(response.headers["cache-control"]).toBe( "public, max-age=31536000", @@ -5862,16 +5837,16 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and don\'t generate `Cache-Control` header', async () => { - const response = await req.get(`/static/main.js`); + const response = await req.get("/static/main.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeUndefined(); }); it('should return the "200" code for the "GET" request to the bundle file and generate `Cache-Control` header', async () => { - const response = await req.get(`/static/6076fc274f403ebb2d09.svg`); + const response = await req.get("/static/6076fc274f403ebb2d09.svg"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeDefined(); expect(response.headers["cache-control"]).toBe( "public, max-age=31536000, immutable", @@ -5901,16 +5876,16 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and don\'t generate `Cache-Control` header', async () => { - const response = await req.get(`/main.js`); + const response = await req.get("/main.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeUndefined(); }); it('should return the "200" code for the "GET" request to the bundle file and `Cache-Control` header', async () => { - const response = await req.get(`/6076fc274f403ebb2d09.svg`); + const response = await req.get("/6076fc274f403ebb2d09.svg"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeDefined(); expect(response.headers["cache-control"]).toBe( "public, max-age=31536000, immutable", @@ -5940,19 +5915,19 @@ describe.each([ }); it('should return the "200" code for the "GET" request to the bundle file and generate `Cache-Control` header', async () => { - const response = await req.get(`/main.js`); + const response = await req.get("/main.js"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeDefined(); expect(response.headers["cache-control"]).toBe( "public, max-age=1000", ); }); - it('should return the "200" code for the "GET" request to the bundle file and generate `Cache-Control` header', async () => { - const response = await req.get(`/6076fc274f403ebb2d09.svg`); + it('should return the "200" code for the "GET" request to the bundle file and generate `Cache-Control` header #2', async () => { + const response = await req.get("/6076fc274f403ebb2d09.svg"); - expect(response.statusCode).toEqual(200); + expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBeDefined(); expect(response.headers["cache-control"]).toBe( "public, max-age=31536000, immutable", diff --git a/test/utils/ready.test.js b/test/utils/ready.test.js index eb7f52330..6e4bbd956 100644 --- a/test/utils/ready.test.js +++ b/test/utils/ready.test.js @@ -9,7 +9,7 @@ describe("ready", () => { }; ready(context, cb); - expect(cb.mock.calls.length).toEqual(1); + expect(cb.mock.calls).toHaveLength(1); expect(cb.mock.calls[0]).toEqual(["stats"]); }); @@ -28,8 +28,8 @@ describe("ready", () => { }; ready(context, cb, req); - expect(cb).not.toBeCalled(); - expect(context.logger.info.mock.calls.length).toEqual(1); + expect(cb).not.toHaveBeenCalled(); + expect(context.logger.info.mock.calls).toHaveLength(1); expect(context.logger.info.mock.calls[0]).toEqual([ "wait until bundle finished: url", ]); @@ -48,8 +48,8 @@ describe("ready", () => { }; ready(context, cb); - expect(cb).not.toBeCalled(); - expect(context.logger.info.mock.calls.length).toEqual(1); + expect(cb).not.toHaveBeenCalled(); + expect(context.logger.info.mock.calls).toHaveLength(1); // mockConstructor is the name of the jest.fn() function expect(context.logger.info.mock.calls[0]).toEqual([ "wait until bundle finished: mockConstructor", diff --git a/test/utils/setupHooks.test.js b/test/utils/setupHooks.test.js index be3132b2b..65c6bd0fa 100644 --- a/test/utils/setupHooks.test.js +++ b/test/utils/setupHooks.test.js @@ -1,7 +1,7 @@ import setupHooks from "../../src/utils/setupHooks"; // Suppress unnecessary stats output -global.console.log = jest.fn(); +jest.spyOn(globalThis.console, "log").mockImplementation(); describe("setupHooks", () => { let context; @@ -59,27 +59,27 @@ describe("setupHooks", () => { it("taps watchRun, invalid, and done", () => { setupHooks(context); - expect(watchRunHook.mock.calls.length).toEqual(1); - expect(invalidHook.mock.calls.length).toEqual(1); - expect(doneHook.mock.calls.length).toEqual(1); + expect(watchRunHook.mock.calls).toHaveLength(1); + expect(invalidHook.mock.calls).toHaveLength(1); + expect(doneHook.mock.calls).toHaveLength(1); }); it("watchRun hook invalidates", () => { setupHooks(context); // this calls invalidate watchRunHook.mock.calls[0][1](); - expect(context.state).toEqual(false); + expect(context.state).toBe(false); expect(context.stats).toBeUndefined(); - expect(loggerInfo.mock.calls.length).toEqual(0); + expect(loggerInfo.mock.calls).toHaveLength(0); }); it("invalid hook invalidates", () => { setupHooks(context); // this calls invalidate invalidHook.mock.calls[0][1](); - expect(context.state).toEqual(false); + expect(context.state).toBe(false); expect(context.stats).toBeUndefined(); - expect(loggerInfo.mock.calls.length).toEqual(0); + expect(loggerInfo.mock.calls).toHaveLength(0); }); it("logs if state is set on invalidate", () => { @@ -87,9 +87,9 @@ describe("setupHooks", () => { setupHooks(context); // this calls invalidate invalidHook.mock.calls[0][1](); - expect(context.state).toEqual(false); + expect(context.state).toBe(false); expect(context.stats).toBeUndefined(); - expect(loggerLog.mock.calls[0][0]).toEqual("Compilation starting..."); + expect(loggerLog.mock.calls[0][0]).toBe("Compilation starting..."); }); it("sets state, then logs stats and handles callbacks on nextTick from done hook", () => { @@ -101,12 +101,12 @@ describe("setupHooks", () => { }); expect(context.stats).toBeTruthy(); expect(context.state).toBeTruthy(); - expect(nextTick.mock.calls.length).toEqual(1); + expect(nextTick.mock.calls).toHaveLength(1); nextTick.mock.calls[0][0](); expect(loggerInfo.mock.calls).toMatchSnapshot(); - expect(loggerError.mock.calls.length).toEqual(0); - expect(loggerWarn.mock.calls.length).toEqual(0); + expect(loggerError.mock.calls).toHaveLength(0); + expect(loggerWarn.mock.calls).toHaveLength(0); expect(cb1.mock.calls[0][0]).toEqual(context.stats); expect(cb2.mock.calls[0][0]).toEqual(context.stats); @@ -115,12 +115,12 @@ describe("setupHooks", () => { it("stops on done if invalidated before nextTick", () => { setupHooks(context); doneHook.mock.calls[0][1]("stats"); - expect(context.stats).toEqual("stats"); + expect(context.stats).toBe("stats"); expect(context.state).toBeTruthy(); - expect(nextTick.mock.calls.length).toEqual(1); + expect(nextTick.mock.calls).toHaveLength(1); context.state = false; nextTick.mock.calls[0][0](); - expect(loggerInfo.mock.calls.length).toEqual(0); + expect(loggerInfo.mock.calls).toHaveLength(0); }); it("handles multi compiler", () => { @@ -155,7 +155,7 @@ describe("setupHooks", () => { }); expect(context.stats).toBeTruthy(); expect(context.state).toBeTruthy(); - expect(nextTick.mock.calls.length).toEqual(1); + expect(nextTick.mock.calls).toHaveLength(1); nextTick.mock.calls[0][0](); expect(loggerInfo.mock.calls).toMatchSnapshot(); diff --git a/test/utils/setupOutputFileSystem.test.js b/test/utils/setupOutputFileSystem.test.js index ce681bf57..ce0c8a8df 100644 --- a/test/utils/setupOutputFileSystem.test.js +++ b/test/utils/setupOutputFileSystem.test.js @@ -4,11 +4,9 @@ import setupOutputFileSystem from "../../src/utils/setupOutputFileSystem"; const createFsFromVolume = jest.spyOn(memfs, "createFsFromVolume"); -createFsFromVolume.mockImplementation(() => { - return { - testFs: true, - }; -}); +createFsFromVolume.mockImplementation(() => ({ + testFs: true, +})); describe("setupOutputFileSystem", () => { afterEach(() => { @@ -26,7 +24,7 @@ describe("setupOutputFileSystem", () => { // make sure that this is the default fs created expect(context.compiler.outputFileSystem.testFs).toBeTruthy(); expect(context.outputFileSystem.testFs).toBeTruthy(); - expect(createFsFromVolume.mock.calls.length).toEqual(1); + expect(createFsFromVolume.mock.calls).toHaveLength(1); }); it("should set fs for multi compiler", () => { @@ -39,9 +37,9 @@ describe("setupOutputFileSystem", () => { setupOutputFileSystem(context); - context.compiler.compilers.forEach((comp) => { + for (const comp of context.compiler.compilers) { expect(comp.outputFileSystem).toBeTruthy(); - }); + } }); it("should use provided fs with correct methods", () => { diff --git a/test/utils/setupWriteToDisk.test.js b/test/utils/setupWriteToDisk.test.js index 3fced7034..d25d8aba8 100644 --- a/test/utils/setupWriteToDisk.test.js +++ b/test/utils/setupWriteToDisk.test.js @@ -1,4 +1,4 @@ -import fs from "fs"; +import fs from "node:fs"; import setupWriteToDisk from "../../src/utils/setupWriteToDisk"; @@ -56,7 +56,7 @@ describe("setupWriteToDisk", () => { // this simulates the emit hook being called twice emitHook.mock.calls[0][1](); emitHook.mock.calls[0][1](); - expect(assetEmittedHook.mock.calls.length).toEqual(1); + expect(assetEmittedHook.mock.calls).toHaveLength(1); }); it("filters out unwanted emits with writeToDisk", () => { @@ -77,14 +77,14 @@ describe("setupWriteToDisk", () => { ); // the getPath helper is not needed for webpack@5 - expect(getPath.mock.calls.length).toEqual(0); + expect(getPath.mock.calls).toHaveLength(0); - expect(filter.mock.calls.length).toEqual(1); - expect(filter.mock.calls[0][0]).toEqual("targetPath"); + expect(filter.mock.calls).toHaveLength(1); + expect(filter.mock.calls[0][0]).toBe("targetPath"); // the callback should always be called - expect(cb.mock.calls.length).toEqual(1); + expect(cb.mock.calls).toHaveLength(1); // the filter prevents a directory from being made - expect(mkdirSpy.mock.calls.length).toEqual(0); + expect(mkdirSpy.mock.calls).toHaveLength(0); }); const writeErrors = [ @@ -105,7 +105,8 @@ describe("setupWriteToDisk", () => { }, ]; - writeErrors.forEach((writeError) => { + for (const writeError of writeErrors) { + // eslint-disable-next-line no-loop-func it(`tries to create directories and write file if not filtered out ${writeError.title}`, () => { context.options = {}; setupWriteToDisk(context); @@ -122,20 +123,20 @@ describe("setupWriteToDisk", () => { ); // the getPath helper is not needed for webpack@5 - expect(getPath.mock.calls.length).toEqual(0); + expect(getPath.mock.calls).toHaveLength(0); - expect(mkdirSpy.mock.calls.length).toEqual(1); - expect(mkdirSpy.mock.calls[0][0]).toEqual("/target/path"); + expect(mkdirSpy.mock.calls).toHaveLength(1); + expect(mkdirSpy.mock.calls[0][0]).toBe("/target/path"); // simulates the mkdir callback being called mkdirSpy.mock.calls[0][2](writeError.mkdirError); if (writeError.mkdirError) { - expect(writeFileSpy.mock.calls.length).toEqual(0); + expect(writeFileSpy.mock.calls).toHaveLength(0); } else { - expect(writeFileSpy.mock.calls.length).toEqual(1); - expect(writeFileSpy.mock.calls[0][0]).toEqual("/target/path/file"); - expect(writeFileSpy.mock.calls[0][1]).toEqual("content"); + expect(writeFileSpy.mock.calls).toHaveLength(1); + expect(writeFileSpy.mock.calls[0][0]).toBe("/target/path/file"); + expect(writeFileSpy.mock.calls[0][1]).toBe("content"); // simulates the writeFile callback being called writeFileSpy.mock.calls[0][2](writeError.writeFileError); @@ -146,9 +147,9 @@ describe("setupWriteToDisk", () => { expect(context.logger.log.mock.calls).toMatchSnapshot(); // the callback should always be called - expect(cb.mock.calls.length).toEqual(1); + expect(cb.mock.calls).toHaveLength(1); // no errors are expected expect(cb.mock.calls).toMatchSnapshot(); }); - }); + } }); diff --git a/test/validation-options.test.js b/test/validation-options.test.js index addf2b8f8..9557cbfac 100644 --- a/test/validation-options.test.js +++ b/test/validation-options.test.js @@ -1,4 +1,4 @@ -import path from "path"; +import path from "node:path"; import { createFsFromVolume, Volume } from "memfs"; @@ -7,7 +7,7 @@ import middleware from "../src"; import getCompiler from "./helpers/getCompiler"; // Suppress unnecessary stats output -global.console.log = jest.fn(); +jest.spyOn(globalThis.console, "log").mockImplementation(); const configuredFs = createFsFromVolume(new Volume()); @@ -60,11 +60,7 @@ describe("validation", () => { failure: [0], }, modifyResponseData: { - success: [ - (_ignore, _ignore1, foo, bar) => { - return { foo, bar }; - }, - ], + success: [(_ignore, _ignore1, foo, bar) => ({ foo, bar })], failure: [true], }, etag: { @@ -91,6 +87,11 @@ describe("validation", () => { }, }; + // eslint-disable-next-line jsdoc/no-restricted-syntax + /** + * @param {any} value value + * @returns {string} stringified value + */ function stringifyValue(value) { if ( Array.isArray(value) || @@ -102,7 +103,13 @@ describe("validation", () => { return value; } - async function createTestCase(key, value, type) { + // eslint-disable-next-line jsdoc/no-restricted-syntax + /** + * @param {string} key key + * @param {any} value value + * @param {"success" | "failure"} type type + */ + function createTestCase(key, value, type) { it(`should ${ type === "success" ? "successfully validate" : "throw an error on" } the "${key}" option with "${stringifyValue(value)}" value`, (done) => { @@ -113,12 +120,12 @@ describe("validation", () => { try { webpackDevMiddleware = middleware(compiler, { [key]: value }); - } catch (maybeError) { - if (maybeError.name !== "ValidationError") { - throw maybeError; + } catch (err) { + if (err.name !== "ValidationError") { + throw err; } - error = maybeError; + error = err; } finally { if (type === "success") { expect(error).toBeUndefined(); diff --git a/types/index.d.ts b/types/index.d.ts index 88775c09a..ec4c9f169 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -7,15 +7,15 @@ export = wdm; /** @typedef {import("webpack").MultiStats} MultiStats */ /** @typedef {import("fs").ReadStream} ReadStream */ /** - * @typedef {Object} ExtendedServerResponse - * @property {{ webpack?: { devMiddleware?: Context } }} [locals] + * @typedef {object} ExtendedServerResponse + * @property {{ webpack?: { devMiddleware?: Context } }=} locals locals */ /** @typedef {import("http").IncomingMessage} IncomingMessage */ /** @typedef {import("http").ServerResponse & ExtendedServerResponse} ServerResponse */ /** * @callback NextFunction - * @param {any} [err] - * @return {void} + * @param {any=} err error + * @returns {void} */ /** * @typedef {NonNullable} WatchOptions @@ -32,35 +32,35 @@ export = wdm; /** @typedef {ReturnType} Logger */ /** * @callback Callback - * @param {Stats | MultiStats} [stats] + * @param {(Stats | MultiStats)=} stats */ /** - * @typedef {Object} ResponseData - * @property {Buffer | ReadStream} data - * @property {number} byteLength + * @typedef {object} ResponseData + * @property {Buffer | ReadStream} data data + * @property {number} byteLength byte length */ /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] * @callback ModifyResponseData - * @param {RequestInternal} req - * @param {ResponseInternal} res - * @param {Buffer | ReadStream} data - * @param {number} byteLength - * @return {ResponseData} + * @param {RequestInternal} req req + * @param {ResponseInternal} res res + * @param {Buffer | ReadStream} data data + * @param {number} byteLength byte length + * @returns {ResponseData} */ /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] - * @typedef {Object} Context - * @property {boolean} state - * @property {Stats | MultiStats | undefined} stats - * @property {Callback[]} callbacks - * @property {Options} options - * @property {Compiler | MultiCompiler} compiler - * @property {Watching | MultiWatching | undefined} watching - * @property {Logger} logger - * @property {OutputFileSystem} outputFileSystem + * @typedef {object} Context + * @property {boolean} state state + * @property {Stats | MultiStats | undefined} stats stats + * @property {Callback[]} callbacks callbacks + * @property {Options} options options + * @property {Compiler | MultiCompiler} compiler compiler + * @property {Watching | MultiWatching | undefined} watching watching + * @property {Logger} logger logger + * @property {OutputFileSystem} outputFileSystem output file system */ /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] @@ -76,22 +76,22 @@ export = wdm; /** * @template {IncomingMessage} [RequestInternal = IncomingMessage] * @template {ServerResponse} [ResponseInternal = ServerResponse] - * @typedef {Object} Options - * @property {{[key: string]: string}} [mimeTypes] - * @property {string | undefined} [mimeTypeDefault] - * @property {boolean | ((targetPath: string) => boolean)} [writeToDisk] - * @property {string[]} [methods] - * @property {Headers} [headers] - * @property {NonNullable["publicPath"]} [publicPath] - * @property {Configuration["stats"]} [stats] - * @property {boolean} [serverSideRender] - * @property {OutputFileSystem} [outputFileSystem] - * @property {boolean | string} [index] - * @property {ModifyResponseData} [modifyResponseData] - * @property {"weak" | "strong"} [etag] - * @property {boolean} [lastModified] - * @property {boolean | number | string | { maxAge?: number, immutable?: boolean }} [cacheControl] - * @property {boolean} [cacheImmutable] + * @typedef {object} Options + * @property {{ [key: string]: string }=} mimeTypes mime types + * @property {(string | undefined)=} mimeTypeDefault mime type default + * @property {(boolean | ((targetPath: string) => boolean))=} writeToDisk write to disk + * @property {string[]=} methods methods + * @property {Headers=} headers headers + * @property {NonNullable["publicPath"]=} publicPath public path + * @property {Configuration["stats"]=} stats stats + * @property {boolean=} serverSideRender is server side render + * @property {OutputFileSystem=} outputFileSystem output file system + * @property {(boolean | string)=} index index + * @property {ModifyResponseData=} modifyResponseData modify response data + * @property {"weak" | "strong"=} etag options to generate etag header + * @property {boolean=} lastModified options to generate last modified header + * @property {(boolean | number | string | { maxAge?: number, immutable?: boolean })=} cacheControl options to generate cache headers + * @property {boolean=} cacheImmutable is cache immutable */ /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] @@ -100,7 +100,7 @@ export = wdm; * @param {RequestInternal} req * @param {ResponseInternal} res * @param {NextFunction} next - * @return {Promise} + * @returns {Promise} */ /** @typedef {import("./utils/getFilenameFromUrl").Extra} Extra */ /** @@ -124,12 +124,12 @@ export = wdm; /** * @template {IncomingMessage} RequestInternal * @template {ServerResponse} ResponseInternal - * @typedef {Object} AdditionalMethods - * @property {GetFilenameFromUrl} getFilenameFromUrl - * @property {WaitUntilValid} waitUntilValid - * @property {Invalidate} invalidate - * @property {Close} close - * @property {Context} context + * @typedef {object} AdditionalMethods + * @property {GetFilenameFromUrl} getFilenameFromUrl get filename from url + * @property {WaitUntilValid} waitUntilValid wait until valid + * @property {Invalidate} invalidate invalidate + * @property {Close} close close + * @property {Context} context context */ /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] @@ -149,16 +149,16 @@ export = wdm; /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] - * @param {Compiler | MultiCompiler} compiler - * @param {Options} [options] - * @returns {API} + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {API} webpack dev middleware */ declare function wdm< RequestInternal extends IncomingMessage = import("http").IncomingMessage, ResponseInternal extends ServerResponse = ServerResponse, >( compiler: Compiler | MultiCompiler, - options?: Options, + options?: Options | undefined, ): API; declare namespace wdm { export { @@ -207,8 +207,8 @@ declare namespace wdm { /** * @template S * @template O - * @typedef {Object} HapiPluginBase - * @property {(server: S, options: O) => void | Promise} register + * @typedef {object} HapiPluginBase + * @property {(server: S, options: O) => void | Promise} register register */ /** * @template S @@ -221,7 +221,7 @@ declare namespace wdm { /** * @template HapiServer * @template {HapiOptions} HapiOptionsInternal - * @returns {HapiPlugin} + * @returns {HapiPlugin} hapi wrapper */ declare function hapiWrapper< HapiServer, @@ -230,30 +230,30 @@ declare function hapiWrapper< /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] - * @param {Compiler | MultiCompiler} compiler - * @param {Options} [options] - * @returns {(ctx: any, next: Function) => Promise | void} + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {(ctx: any, next: Function) => Promise | void} kow wrapper */ declare function koaWrapper< RequestInternal extends IncomingMessage = import("http").IncomingMessage, ResponseInternal extends ServerResponse = ServerResponse, >( compiler: Compiler | MultiCompiler, - options?: Options, + options?: Options | undefined, ): (ctx: any, next: Function) => Promise | void; /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] - * @param {Compiler | MultiCompiler} compiler - * @param {Options} [options] - * @returns {(ctx: any, next: Function) => Promise | void} + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {(ctx: any, next: Function) => Promise | void} hono wrapper */ declare function honoWrapper< RequestInternal extends IncomingMessage = import("http").IncomingMessage, ResponseInternal extends ServerResponse = ServerResponse, >( compiler: Compiler | MultiCompiler, - options?: Options, + options?: Options | undefined, ): (ctx: any, next: Function) => Promise | void; type Schema = import("schema-utils/declarations/validate").Schema; type Compiler = import("webpack").Compiler; @@ -263,6 +263,9 @@ type Stats = import("webpack").Stats; type MultiStats = import("webpack").MultiStats; type ReadStream = import("fs").ReadStream; type ExtendedServerResponse = { + /** + * locals + */ locals?: | { webpack?: { @@ -273,7 +276,7 @@ type ExtendedServerResponse = { }; type IncomingMessage = import("http").IncomingMessage; type ServerResponse = import("http").ServerResponse & ExtendedServerResponse; -type NextFunction = (err?: any) => void; +type NextFunction = (err?: any | undefined) => void; type WatchOptions = NonNullable; type Watching = Compiler["watching"]; type MultiWatching = ReturnType; @@ -283,11 +286,15 @@ type OutputFileSystem = import("webpack").OutputFileSystem & { readFileSync: typeof import("fs").readFileSync; }; type Logger = ReturnType; -type Callback = ( - stats?: import("webpack").Stats | import("webpack").MultiStats | undefined, -) => any; +type Callback = (stats?: (Stats | MultiStats) | undefined) => any; type ResponseData = { + /** + * data + */ data: Buffer | ReadStream; + /** + * byte length + */ byteLength: number; }; type ModifyResponseData< @@ -303,13 +310,37 @@ type Context< RequestInternal extends IncomingMessage = import("http").IncomingMessage, ResponseInternal extends ServerResponse = ServerResponse, > = { + /** + * state + */ state: boolean; + /** + * stats + */ stats: Stats | MultiStats | undefined; + /** + * callbacks + */ callbacks: Callback[]; + /** + * options + */ options: Options; + /** + * compiler + */ compiler: Compiler | MultiCompiler; + /** + * watching + */ watching: Watching | MultiWatching | undefined; + /** + * logger + */ logger: Logger; + /** + * output file system + */ outputFileSystem: OutputFileSystem; }; type FilledContext< @@ -337,34 +368,81 @@ type Options< RequestInternal extends IncomingMessage = import("http").IncomingMessage, ResponseInternal extends ServerResponse = ServerResponse, > = { + /** + * mime types + */ mimeTypes?: | { [key: string]: string; } | undefined; - mimeTypeDefault?: string | undefined; - writeToDisk?: boolean | ((targetPath: string) => boolean) | undefined; + /** + * mime type default + */ + mimeTypeDefault?: (string | undefined) | undefined; + /** + * write to disk + */ + writeToDisk?: (boolean | ((targetPath: string) => boolean)) | undefined; + /** + * methods + */ methods?: string[] | undefined; - headers?: Headers; - publicPath?: NonNullable["publicPath"]; - stats?: Configuration["stats"]; + /** + * headers + */ + headers?: Headers | undefined; + /** + * public path + */ + publicPath?: NonNullable["publicPath"] | undefined; + /** + * stats + */ + stats?: Configuration["stats"] | undefined; + /** + * is server side render + */ serverSideRender?: boolean | undefined; + /** + * output file system + */ outputFileSystem?: OutputFileSystem | undefined; - index?: string | boolean | undefined; + /** + * index + */ + index?: (boolean | string) | undefined; + /** + * modify response data + */ modifyResponseData?: | ModifyResponseData | undefined; - etag?: "strong" | "weak" | undefined; + /** + * options to generate etag header + */ + etag?: ("weak" | "strong") | undefined; + /** + * options to generate last modified header + */ lastModified?: boolean | undefined; + /** + * options to generate cache headers + */ cacheControl?: - | string - | number - | boolean - | { - maxAge?: number; - immutable?: boolean; - } + | ( + | boolean + | number + | string + | { + maxAge?: number; + immutable?: boolean; + } + ) | undefined; + /** + * is cache immutable + */ cacheImmutable?: boolean | undefined; }; type Middleware< @@ -387,10 +465,25 @@ type AdditionalMethods< RequestInternal extends IncomingMessage, ResponseInternal extends ServerResponse, > = { + /** + * get filename from url + */ getFilenameFromUrl: GetFilenameFromUrl; + /** + * wait until valid + */ waitUntilValid: WaitUntilValid; + /** + * invalidate + */ invalidate: Invalidate; + /** + * close + */ close: Close; + /** + * context + */ context: Context; }; type API< @@ -403,6 +496,9 @@ type WithoutUndefined = T & { [P in K]: NonNullable; }; type HapiPluginBase = { + /** + * register + */ register: (server: S, options: O) => void | Promise; }; type HapiPlugin = HapiPluginBase & { diff --git a/types/middleware.d.ts b/types/middleware.d.ts index 267e2d541..cce5820ac 100644 --- a/types/middleware.d.ts +++ b/types/middleware.d.ts @@ -2,15 +2,15 @@ export = wrapper; /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @typedef {Object} SendErrorOptions send error options + * @typedef {object} SendErrorOptions send error options * @property {Record=} headers headers * @property {import("./index").ModifyResponseData=} modifyResponseData modify response data callback */ /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("./index.js").FilledContext} context - * @return {import("./index.js").Middleware} + * @param {import("./index.js").FilledContext} context context + * @returns {import("./index.js").Middleware} wrapper */ declare function wrapper< Request extends IncomingMessage, diff --git a/types/utils/compatibleAPI.d.ts b/types/utils/compatibleAPI.d.ts index 520ae8e28..5ef6ed0cb 100644 --- a/types/utils/compatibleAPI.d.ts +++ b/types/utils/compatibleAPI.d.ts @@ -2,46 +2,93 @@ export type IncomingMessage = import("../index.js").IncomingMessage; export type ServerResponse = import("../index.js").ServerResponse; export type OutputFileSystem = import("../index").OutputFileSystem; export type ExpectedIncomingMessage = { + /** + * get header extra method + */ getHeader?: ((name: string) => string | string[] | undefined) | undefined; + /** + * get method extra method + */ getMethod?: (() => string | undefined) | undefined; + /** + * get URL extra method + */ getURL?: (() => string | undefined) | undefined; }; export type ExpectedServerResponse = { + /** + * set status code + */ setStatusCode?: ((status: number) => void) | undefined; + /** + * get status code + */ getStatusCode?: (() => number) | undefined; - getHeader?: - | ((name: string) => string | string[] | undefined | number) - | undefined; + /** + * get header + */ + getHeader: (name: string) => string | string[] | undefined | number; + /** + * set header + */ setHeader?: | (( name: string, value: number | string | Readonly, ) => ExpectedServerResponse) | undefined; + /** + * remove header + */ removeHeader?: ((name: string) => void) | undefined; + /** + * send + */ send?: ((data: string | Buffer) => void) | undefined; + /** + * finish + */ finish?: ((data?: string | Buffer) => void) | undefined; + /** + * get response header + */ getResponseHeaders?: (() => string[]) | undefined; + /** + * get headers sent + */ getHeadersSent?: (() => boolean) | undefined; + /** + * stream + */ stream?: ((data: any) => void) | undefined; + /** + * get outgoing + */ getOutgoing?: (() => any) | undefined; + /** + * set state + */ setState?: ((name: string, value: any) => void) | undefined; + /** + * get ready readable streamState + */ getReadyReadableStreamState?: | (() => "ready" | "open" | "readable") | undefined; }; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {number} code + * @param {Response} res res + * @param {number} code code + * @returns {void} */ export function setStatusCode< Response extends ServerResponse & ExpectedServerResponse, >(res: Response, code: number): void; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @returns {number} + * @param {Response} res res + * @returns {number} status code */ export function getStatusCode< Response extends ServerResponse & ExpectedServerResponse, @@ -50,67 +97,67 @@ export function getStatusCode< /** @typedef {import("../index.js").ServerResponse} ServerResponse */ /** @typedef {import("../index").OutputFileSystem} OutputFileSystem */ /** - * @typedef {Object} ExpectedIncomingMessage - * @property {(name: string) => string | string[] | undefined} [getHeader] - * @property {() => string | undefined} [getMethod] - * @property {() => string | undefined} [getURL] + * @typedef {object} ExpectedIncomingMessage + * @property {((name: string) => string | string[] | undefined)=} getHeader get header extra method + * @property {(() => string | undefined)=} getMethod get method extra method + * @property {(() => string | undefined)=} getURL get URL extra method */ /** - * @typedef {Object} ExpectedServerResponse - * @property {(status: number) => void} [setStatusCode] - * @property {() => number} [getStatusCode] - * @property {(name: string) => string | string[] | undefined | number} [getHeader] - * @property {(name: string, value: number | string | Readonly) => ExpectedServerResponse} [setHeader] - * @property {(name: string) => void} [removeHeader] - * @property {(data: string | Buffer) => void} [send] - * @property {(data?: string | Buffer) => void} [finish] - * @property {() => string[]} [getResponseHeaders] - * @property {() => boolean} [getHeadersSent] - * @property {(data: any) => void} [stream] - * @property {() => any} [getOutgoing] - * @property {(name: string, value: any) => void} [setState] - * @property {() => "ready" | "open" | "readable"} [getReadyReadableStreamState] + * @typedef {object} ExpectedServerResponse + * @property {((status: number) => void)=} setStatusCode set status code + * @property {(() => number)=} getStatusCode get status code + * @property {((name: string) => string | string[] | undefined | number)} getHeader get header + * @property {((name: string, value: number | string | Readonly) => ExpectedServerResponse)=} setHeader set header + * @property {((name: string) => void)=} removeHeader remove header + * @property {((data: string | Buffer) => void)=} send send + * @property {((data?: string | Buffer) => void)=} finish finish + * @property {(() => string[])=} getResponseHeaders get response header + * @property {(() => boolean)=} getHeadersSent get headers sent + * @property {((data: any) => void)=} stream stream + * @property {(() => any)=} getOutgoing get outgoing + * @property {((name: string, value: any) => void)=} setState set state + * @property {(() => "ready" | "open" | "readable")=} getReadyReadableStreamState get ready readable streamState */ /** * @template {IncomingMessage & ExpectedIncomingMessage} Request - * @param {Request} req - * @param {string} name - * @returns {string | string[] | undefined} + * @param {Request} req req + * @param {string} name name + * @returns {string | string[] | undefined} request header */ export function getRequestHeader< Request extends IncomingMessage & ExpectedIncomingMessage, >(req: Request, name: string): string | string[] | undefined; /** * @template {IncomingMessage & ExpectedIncomingMessage} Request - * @param {Request} req - * @returns {string | undefined} + * @param {Request} req req + * @returns {string | undefined} request method */ export function getRequestMethod< Request extends IncomingMessage & ExpectedIncomingMessage, >(req: Request): string | undefined; /** * @template {IncomingMessage & ExpectedIncomingMessage} Request - * @param {Request} req - * @returns {string | undefined} + * @param {Request} req req + * @returns {string | undefined} request URL */ export function getRequestURL< Request extends IncomingMessage & ExpectedIncomingMessage, >(req: Request): string | undefined; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {string} name - * @returns {string | string[] | undefined | number} + * @param {Response} res res + * @param {string} name name + * @returns {string | string[] | undefined | number} header */ export function getResponseHeader< Response extends ServerResponse & ExpectedServerResponse, >(res: Response, name: string): string | string[] | undefined | number; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {string} name - * @param {number | string | Readonly} value - * @returns {Response} + * @param {Response} res res + * @param {string} name name + * @param {number | string | Readonly} value value + * @returns {Response} response */ export function setResponseHeader< Response extends ServerResponse & ExpectedServerResponse, @@ -121,32 +168,33 @@ export function setResponseHeader< ): Response; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {string} name + * @param {Response} res res + * @param {string} name name + * @returns {void} */ export function removeResponseHeader< Response extends ServerResponse & ExpectedServerResponse, >(res: Response, name: string): void; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @returns {string[]} + * @param {Response} res res + * @returns {string[]} header names */ export function getResponseHeaders< Response extends ServerResponse & ExpectedServerResponse, >(res: Response): string[]; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @returns {boolean} + * @param {Response} res res + * @returns {boolean} true when headers were sent, otherwise false */ export function getHeadersSent< Response extends ServerResponse & ExpectedServerResponse, >(res: Response): boolean; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {import("fs").ReadStream} bufferOrStream + * @param {Response} res res + * @param {import("fs").ReadStream} bufferOrStream buffer or stream */ export function pipe( res: Response, @@ -154,8 +202,9 @@ export function pipe( ): void; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {string | Buffer} bufferOrString + * @param {Response} res res + * @param {string | Buffer} bufferOrString buffer or string + * @returns {void} */ export function send( res: Response, @@ -163,18 +212,18 @@ export function send( ): void; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {string | Buffer} [data] + * @param {Response} res res + * @param {(string | Buffer)=} data data */ export function finish< Response extends ServerResponse & ExpectedServerResponse, ->(res: Response, data?: string | Buffer): void; +>(res: Response, data?: (string | Buffer) | undefined): void; /** - * @param {string} filename - * @param {OutputFileSystem} outputFileSystem - * @param {number} start - * @param {number} end - * @returns {{ bufferOrStream: (Buffer | import("fs").ReadStream), byteLength: number }} + * @param {string} filename filename + * @param {OutputFileSystem} outputFileSystem output file system + * @param {number} start start + * @param {number} end end + * @returns {{ bufferOrStream: (Buffer | import("fs").ReadStream), byteLength: number }} result with buffer or stream and byte length */ export function createReadStreamOrReadFileSync( filename: string, @@ -187,32 +236,33 @@ export function createReadStreamOrReadFileSync( }; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @returns {Response} res + * @param {Response} res res + * @returns {Response} res res */ export function getOutgoing< Response extends ServerResponse & ExpectedServerResponse, >(res: Response): Response; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res + * @param {Response} res res */ export function initState< Response extends ServerResponse & ExpectedServerResponse, >(res: Response): void; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @param {string} name - * @param {any} value + * @param {Response} res res + * @param {string} name name + * @param {any} value state + * @returns {void} */ export function setState< Response extends ServerResponse & ExpectedServerResponse, >(res: Response, name: string, value: any): void; /** * @template {ServerResponse & ExpectedServerResponse} Response - * @param {Response} res - * @returns {"ready" | "open" | "readable"} + * @param {Response} res res + * @returns {"ready" | "open" | "readable"} state */ export function getReadyReadableStreamState< Response extends ServerResponse & ExpectedServerResponse, diff --git a/types/utils/etag.d.ts b/types/utils/etag.d.ts index 3e17027f9..7ca5f302e 100644 --- a/types/utils/etag.d.ts +++ b/types/utils/etag.d.ts @@ -1,9 +1,8 @@ export = etag; /** * Create a simple ETag. - * - * @param {Buffer | ReadStream | Stats} entity - * @return {Promise<{ hash: string, buffer?: Buffer }>} + * @param {Buffer | ReadStream | Stats} entity entity + * @returns {Promise<{ hash: string, buffer?: Buffer }>} etag */ declare function etag(entity: Buffer | ReadStream | Stats): Promise<{ hash: string; diff --git a/types/utils/getFilenameFromUrl.d.ts b/types/utils/getFilenameFromUrl.d.ts index 08fc1dcb6..be28a0ae0 100644 --- a/types/utils/getFilenameFromUrl.d.ts +++ b/types/utils/getFilenameFromUrl.d.ts @@ -1,11 +1,24 @@ export = getFilenameFromUrl; +/** + * @typedef {object} Extra + * @property {import("fs").Stats=} stats stats + * @property {number=} errorCode error code + * @property {boolean=} immutable true when immutable, otherwise false + */ +/** + * decodeURIComponent. + * + * Allows V8 to only deoptimize this fn instead of all of send(). + * @param {string} input + * @returns {string} + */ /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("../index.js").FilledContext} context - * @param {string} url - * @param {Extra=} extra - * @returns {string | undefined} + * @param {import("../index.js").FilledContext} context context + * @param {string} url url + * @param {Extra=} extra extra + * @returns {string | undefined} filename */ declare function getFilenameFromUrl< Request extends IncomingMessage, @@ -16,12 +29,21 @@ declare function getFilenameFromUrl< extra?: Extra | undefined, ): string | undefined; declare namespace getFilenameFromUrl { - export { Extra, IncomingMessage, ServerResponse }; + export { IncomingMessage, ServerResponse, Extra }; } +type IncomingMessage = import("../index.js").IncomingMessage; +type ServerResponse = import("../index.js").ServerResponse; type Extra = { + /** + * stats + */ stats?: import("fs").Stats | undefined; + /** + * error code + */ errorCode?: number | undefined; + /** + * true when immutable, otherwise false + */ immutable?: boolean | undefined; }; -type IncomingMessage = import("../index.js").IncomingMessage; -type ServerResponse = import("../index.js").ServerResponse; diff --git a/types/utils/getPaths.d.ts b/types/utils/getPaths.d.ts index ace131cd1..f8269fbc5 100644 --- a/types/utils/getPaths.d.ts +++ b/types/utils/getPaths.d.ts @@ -2,12 +2,14 @@ export = getPaths; /** @typedef {import("webpack").Compiler} Compiler */ /** @typedef {import("webpack").Stats} Stats */ /** @typedef {import("webpack").MultiStats} MultiStats */ +/** @typedef {import("webpack").Asset} Asset */ /** @typedef {import("../index.js").IncomingMessage} IncomingMessage */ /** @typedef {import("../index.js").ServerResponse} ServerResponse */ /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("../index.js").FilledContext} context + * @param {import("../index.js").FilledContext} context context + * @returns {{ outputPath: string, publicPath: string, assetsInfo: Asset["info"] }[]} paths */ declare function getPaths< Request extends IncomingMessage, @@ -17,13 +19,21 @@ declare function getPaths< ): { outputPath: string; publicPath: string; - assetsInfo: Map; + assetsInfo: Asset["info"]; }[]; declare namespace getPaths { - export { Compiler, Stats, MultiStats, IncomingMessage, ServerResponse }; + export { + Compiler, + Stats, + MultiStats, + Asset, + IncomingMessage, + ServerResponse, + }; } type Compiler = import("webpack").Compiler; type Stats = import("webpack").Stats; type MultiStats = import("webpack").MultiStats; +type Asset = import("webpack").Asset; type IncomingMessage = import("../index.js").IncomingMessage; type ServerResponse = import("../index.js").ServerResponse; diff --git a/types/utils/memorize.d.ts b/types/utils/memorize.d.ts index 684b04cc3..f4d210781 100644 --- a/types/utils/memorize.d.ts +++ b/types/utils/memorize.d.ts @@ -1,24 +1,35 @@ export = memorize; /** * @template T - * @param {Function} fn - * @param {{ cache?: Map } | undefined} cache - * @param {((value: T) => T)=} callback - * @returns {any} + * @typedef {(...args: any) => T} FunctionReturning + */ +/** + * @template T + * @param {FunctionReturning} fn memorized function + * @param {({ cache?: Map } | undefined)=} cache cache + * @param {((value: T) => T)=} callback callback + * @returns {FunctionReturning} new function */ declare function memorize( - fn: Function, + fn: FunctionReturning, { cache, }?: - | { - cache?: Map< - string, - { - data: T; + | ( + | { + cache?: Map< + string, + { + data: T; + } + >; } - >; - } + | undefined + ) | undefined, callback?: ((value: T) => T) | undefined, -): any; +): FunctionReturning; +declare namespace memorize { + export { FunctionReturning }; +} +type FunctionReturning = (...args: any) => T; diff --git a/types/utils/parseTokenList.d.ts b/types/utils/parseTokenList.d.ts index 67b75c26e..7fa8d56b4 100644 --- a/types/utils/parseTokenList.d.ts +++ b/types/utils/parseTokenList.d.ts @@ -1,8 +1,7 @@ export = parseTokenList; /** * Parse a HTTP token list. - * - * @param {string} str + * @param {string} str str * @returns {string[]} tokens */ declare function parseTokenList(str: string): string[]; diff --git a/types/utils/ready.d.ts b/types/utils/ready.d.ts index 7f64471bf..a09f6206e 100644 --- a/types/utils/ready.d.ts +++ b/types/utils/ready.d.ts @@ -1,12 +1,13 @@ export = ready; /** @typedef {import("../index.js").IncomingMessage} IncomingMessage */ /** @typedef {import("../index.js").ServerResponse} ServerResponse */ +/** @typedef {import("../index.js").Callback} Callback */ /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("../index.js").FilledContext} context - * @param {(...args: any[]) => any} callback - * @param {Request} [req] + * @param {import("../index.js").FilledContext} context context + * @param {Callback} callback callback + * @param {Request=} req req * @returns {void} */ declare function ready< @@ -14,11 +15,12 @@ declare function ready< Response extends ServerResponse, >( context: import("../index.js").FilledContext, - callback: (...args: any[]) => any, - req?: Request, + callback: Callback, + req?: Request | undefined, ): void; declare namespace ready { - export { IncomingMessage, ServerResponse }; + export { IncomingMessage, ServerResponse, Callback }; } type IncomingMessage = import("../index.js").IncomingMessage; type ServerResponse = import("../index.js").ServerResponse; +type Callback = import("../index.js").Callback; diff --git a/types/utils/setupHooks.d.ts b/types/utils/setupHooks.d.ts index 93151bfef..1ec0e489b 100644 --- a/types/utils/setupHooks.d.ts +++ b/types/utils/setupHooks.d.ts @@ -12,7 +12,7 @@ export = setupHooks; /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("../index.js").WithOptional, "watching" | "outputFileSystem">} context + * @param {import("../index.js").WithOptional, "watching" | "outputFileSystem">} context context */ declare function setupHooks< Request extends IncomingMessage, diff --git a/types/utils/setupOutputFileSystem.d.ts b/types/utils/setupOutputFileSystem.d.ts index d784c5647..eabb467c5 100644 --- a/types/utils/setupOutputFileSystem.d.ts +++ b/types/utils/setupOutputFileSystem.d.ts @@ -5,7 +5,7 @@ export = setupOutputFileSystem; /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("../index.js").WithOptional, "watching" | "outputFileSystem">} context + * @param {import("../index.js").WithOptional, "watching" | "outputFileSystem">} context context */ declare function setupOutputFileSystem< Request extends IncomingMessage, diff --git a/types/utils/setupWriteToDisk.d.ts b/types/utils/setupWriteToDisk.d.ts index 1a476eca6..8a237c47a 100644 --- a/types/utils/setupWriteToDisk.d.ts +++ b/types/utils/setupWriteToDisk.d.ts @@ -7,7 +7,7 @@ export = setupWriteToDisk; /** * @template {IncomingMessage} Request * @template {ServerResponse} Response - * @param {import("../index.js").WithOptional, "watching" | "outputFileSystem">} context + * @param {import("../index.js").WithOptional, "watching" | "outputFileSystem">} context context */ declare function setupWriteToDisk< Request extends IncomingMessage,