From 88a3e64cb893bfa813b0e00e2b5aea03c1be5b98 Mon Sep 17 00:00:00 2001 From: Eric Newport Date: Wed, 11 Sep 2024 13:40:39 -0400 Subject: [PATCH] 0.23.2 - Removed `toobusy` feature since it is temperamental and the dependency is no longer maintained. - Refactored internal `wildcardMatch` to use `minimatch` under the hood. - Replaced `html-minifier` with `html-minifier-terser` since `html-minifier-terser` is better-maintained. - Updated various dependencies. --- CHANGELOG.md | 7 + README.md | 17 +- lib/defaults/config.json | 5 - lib/htmlMinifier.js | 10 +- lib/mapRoutes.js | 19 -- lib/preprocessStaticPages.js | 4 +- lib/scripts/configAuditor.js | 19 -- lib/sourceParams.js | 11 - lib/tools/wildcardMatch.js | 26 +- lib/viewsBundler.js | 6 +- package-lock.json | 538 ++++++++++++++++++++++++----------- package.json | 8 +- test/configAuditor.js | 4 - test/errorPages.js | 101 ------- test/htmlMinify.js | 34 +-- test/util/sampleConfig.json | 5 - test/viewsBundler.js | 14 +- 17 files changed, 421 insertions(+), 407 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03e03a64e..64bdfae45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - Put your changes here... +## 0.23.2 + +- Removed `toobusy` feature since it is temperamental and the dependency is no longer maintained. +- Refactored internal `wildcardMatch` to use `minimatch` under the hood. +- Replaced `html-minifier` with `html-minifier-terser` since `html-minifier-terser` is better-maintained. +- Updated various dependencies. + ## 0.23.1 - Added feature that scans the router stack to move the 404 route (the `*` route) to the end of the stack every time a new route is added, even if the route is added at runtime so that you can dynamically add routes while the app is running. diff --git a/README.md b/README.md index b33df3db1..4cf17f74a 100644 --- a/README.md +++ b/README.md @@ -446,21 +446,6 @@ Resolves to: - Default: *[Number]* `30000` (30 seconds). -- `toobusy`: Parameters to pass to the [node-toobusy](https://github.com/STRML/node-toobusy) module. - - - `maxLagPerRequest`: *[Number]* Maximum amount of time (in milliseconds) a given request is allowed to take before being interrupted with a [503 error](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_Server_errors). - - - `lagCheckInterval`: *[Number]* Interval (in milliseconds) for checking event loop lag in milliseconds. - - - Default: *[Object]* - - ```json - { - "maxLagPerRequest": 70, - "lagCheckInterval": 500 - } - ``` - ### App behavior parameters - `appDir`: Root directory of your application. @@ -685,7 +670,7 @@ Resolves to: - Default: *[Boolean]* `true`. - - `minifyOptions`: *[Object]* Parameters to supply to [html-minifier](https://github.com/kangax/html-minifier#options-quick-reference)'s API. + - `minifyOptions`: *[Object]* Parameters to supply to [html-minifier](https://github.com/terser/html-minifier-terser#options-quick-reference)'s API. - Uses the params you set in `html.minifier.options` if empty. diff --git a/lib/defaults/config.json b/lib/defaults/config.json index a41c7782d..986d32d89 100644 --- a/lib/defaults/config.json +++ b/lib/defaults/config.json @@ -25,11 +25,6 @@ "formidable": { "multiples": true }, - "toobusy": { - "enable": true, - "maxLagPerRequest": 70, - "lagCheckInterval": 500 - }, "helmet": {}, "csrfProtection": true, "bodyParser": { diff --git a/lib/htmlMinifier.js b/lib/htmlMinifier.js index 8e5bb3637..a508d8301 100644 --- a/lib/htmlMinifier.js +++ b/lib/htmlMinifier.js @@ -3,7 +3,7 @@ module.exports = function (app) { const params = app.get('params').html.minifier const options = params.options - const minify = require('html-minifier').minify + const minify = require('html-minifier-terser').minify // check that HTML minifier is enabled and minify is true if (app.get('params').minify && params.enable) { @@ -24,12 +24,12 @@ module.exports = function (app) { if (!exception) { res.render = function (view, opts, callback) { if (callback) { - renderer.call(this, view, opts, (err, html) => { - callback(err, minify(html, options)) + renderer.call(this, view, opts, async (err, html) => { + callback(err, await minify(html, options)) }) } else { - renderer.call(this, view, opts, (err, html) => { - res.send(err || minify(html, options)) + renderer.call(this, view, opts, async (err, html) => { + res.send(err || await minify(html, options)) }) } } diff --git a/lib/mapRoutes.js b/lib/mapRoutes.js index ebab9058e..433dd7a08 100644 --- a/lib/mapRoutes.js +++ b/lib/mapRoutes.js @@ -5,7 +5,6 @@ require('@colors/colors') const fs = require('fs-extra') const path = require('path') const klawSync = require('klaw-sync') -const toobusy = require('toobusy-js') module.exports = app => { const express = app.get('express') @@ -46,24 +45,6 @@ module.exports = app => { require('../defaultErrorPages/controllers/disableValidator')(app) } - if (params.toobusy.enable) { - // define maximum number of miliseconds to wait for a given request to finish - toobusy.maxLag(params.toobusy.maxLagPerRequest) - - // define interval in miliseconds to check for event loop lag - toobusy.interval(params.toobusy.lagCheckInterval) - - // serve 503 page if the process is too busy - app.use((req, res, next) => { - if (toobusy()) { - logger.warn('Request failed because server is too busy.') - require(params.errorPages.serviceUnavailable)(app, req, res) - } else { - next() - } - }) - } - // bind user-defined middleware which fires just before executing the controller if supplied if (params.onReqBeforeRoute && typeof params.onReqBeforeRoute === 'function') { app.use(params.onReqBeforeRoute) diff --git a/lib/preprocessStaticPages.js b/lib/preprocessStaticPages.js index 04dc2b79b..ab183c528 100644 --- a/lib/preprocessStaticPages.js +++ b/lib/preprocessStaticPages.js @@ -13,7 +13,7 @@ module.exports = async (app, callback) => { const appName = app.get('appName') const htmlPath = app.get('htmlPath') const htmlRenderedOutput = app.get('htmlRenderedOutput') - const htmlMinifier = require('html-minifier').minify + const htmlMinifier = require('html-minifier-terser').minify const expressValidator = require('express-html-validator')(params.htmlValidator) const minifyOptions = app.get('params').html.minifier.options const logger = app.get('logger') @@ -89,7 +89,7 @@ module.exports = async (app, callback) => { // minify the html if minification is enabled if (params.minify && params.html.minifier.enable) { - newHtml = htmlMinifier(newHtml, minifyOptions) + newHtml = await htmlMinifier(newHtml, minifyOptions) } // validate the html if the validator is enabled diff --git a/lib/scripts/configAuditor.js b/lib/scripts/configAuditor.js index ae486e53b..a9f2120dd 100644 --- a/lib/scripts/configAuditor.js +++ b/lib/scripts/configAuditor.js @@ -545,25 +545,6 @@ function configAudit (appDir) { } break } - case 'toobusy': { - checkTypes(userParam, key, ['object']) - const busyParam = userParam || {} - for (const busyKey of Object.keys(busyParam)) { - keyStack.push(busyKey) - switch (busyKey) { - case 'maxLagPerRequest': - checkTypes(busyParam[busyKey], busyKey, ['number']) - break - case 'lagCheckInterval': - checkTypes(busyParam[busyKey], busyKey, ['number']) - break - default: - foundExtra(['rooseveltConfig', ...keyStack]) - } - keyStack.pop(busyKey) - } - break - } default: foundExtra(['rooseveltConfig', ...keyStack]) } diff --git a/lib/sourceParams.js b/lib/sourceParams.js index 61fdc6b8d..89ae9ada6 100644 --- a/lib/sourceParams.js +++ b/lib/sourceParams.js @@ -155,17 +155,6 @@ module.exports = (params, app, appSchema) => { formidable: { default: defaults.formidable }, - toobusy: { - maxLagPerRequest: { - default: defaults.toobusy.maxLagPerRequest - }, - lagCheckInterval: { - default: defaults.toobusy.lagCheckInterval - }, - enable: { - default: defaults.toobusy.enable - } - }, helmet: { default: defaults.helmet }, diff --git a/lib/tools/wildcardMatch.js b/lib/tools/wildcardMatch.js index bfbc5c813..3faf96e5b 100644 --- a/lib/tools/wildcardMatch.js +++ b/lib/tools/wildcardMatch.js @@ -15,33 +15,13 @@ */ const path = require('path') +const { minimatch } = require('minimatch') module.exports = (str, matchList) => { - if (typeof matchList === 'string') { - matchList = [matchList] - } + if (typeof matchList === 'string') matchList = [matchList] for (let rule of matchList) { rule = path.normalize(rule).replace(/\\/g, '/') // normalize windows; including normalizing the slashes - - // for this solution to work on any string, no matter what characters it has - const escapeRegex = (str) => str.replace(/([.*+?^=!:${}()|[\]/\\])/g, '\\$1') - - // "." => find a single character, except newline or line terminator - // ".*" => matches any string that contains zero or more characters - rule = rule.split('*').map(escapeRegex).join('.*') - - // "^" => matches any string with the following at the beginning of it - // "$" => matches any string with that in front at the end of it - rule = '^' + rule + '$' - - // create a regular expression object for matching string - const regex = new RegExp(rule) - - // returns true if it finds a match, otherwise it returns false - if (regex.test(str)) { - return true - } + if (minimatch(str, rule)) return true } - return false } diff --git a/lib/viewsBundler.js b/lib/viewsBundler.js index 47d3a8cda..493d468c4 100644 --- a/lib/viewsBundler.js +++ b/lib/viewsBundler.js @@ -7,7 +7,7 @@ module.exports = app => { const path = require('path') const klaw = require('klaw-sync') const gitignoreScanner = require('./tools/gitignoreScanner') - const htmlMinifier = require('html-minifier').minify + const htmlMinifier = require('html-minifier-terser').minify const fsr = require('./tools/fsr')(app) const logger = app.get('logger') const appName = app.get('appName') @@ -171,7 +171,7 @@ module.exports = app => { fsr.writeFileSync(writePath, fileData, ['📝', `${appName} writing new JS file ${writePath}`.green]) } - function preprocess (file, name) { + async function preprocess (file, name) { const { onClientViewsProcess } = app.get('params') // if the onClientViewsProcess event is defined, pass the current file through it @@ -181,7 +181,7 @@ module.exports = app => { // minify the file if the option is turned on (and it is not a pug file since pug can't really be minified) if (willMinifyTemplates && path.extname(name) !== 'pug' && file.length > 0) { - file = htmlMinifier(file, minifyOptions) + file = await htmlMinifier(file, minifyOptions) } return file diff --git a/package-lock.json b/package-lock.json index 465302cb4..a101a9d96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "roosevelt", - "version": "0.23.1", + "version": "0.23.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "roosevelt", - "version": "0.23.1", + "version": "0.23.2", "license": "CC-BY-4.0", "dependencies": { "@colors/colors": "1.6.0", @@ -25,10 +25,11 @@ "formidable": "3.5.1", "fs-extra": "11.2.0", "helmet": "7.1.0", - "html-minifier": "4.0.0", + "html-minifier-terser": "7.2.0", "klaw": "4.1.0", "klaw-sync": "6.0.0", "method-override": "3.0.0", + "minimatch": "10.0.1", "morgan": "1.10.0", "node-forge": "1.3.1", "page": "1.11.6", @@ -38,7 +39,6 @@ "selfsigned": "2.4.1", "serve-favicon": "2.5.0", "source-configs": "0.3.6", - "toobusy-js": "0.5.1", "webpack": "5.94.0" }, "devDependencies": { @@ -52,7 +52,7 @@ "prompts": "2.4.2", "proxyquire": "2.1.3", "sass": "1.78.0", - "sinon": "18.0.0", + "sinon": "18.0.1", "standard": "17.1.0", "stylus": "0.63.0", "supertest": "7.0.0", @@ -276,6 +276,17 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/@eslint/config-array/node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", @@ -294,6 +305,19 @@ } } }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/config-array/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -332,6 +356,17 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/@eslint/eslintrc/node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", @@ -363,6 +398,19 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/eslintrc/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -431,6 +479,17 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/@humanwhocodes/config-array/node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", @@ -449,6 +508,19 @@ } } }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@humanwhocodes/config-array/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -704,13 +776,13 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "11.3.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz", - "integrity": "sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==", + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.1" + "@sinonjs/commons": "^3.0.0" } }, "node_modules/@sinonjs/samsam": { @@ -1507,13 +1579,12 @@ "license": "ISC" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -1680,13 +1751,13 @@ } }, "node_modules/camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "license": "MIT", "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" } }, "node_modules/camelcase": { @@ -2010,10 +2081,13 @@ } }, "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } }, "node_modules/component-emitter": { "version": "1.3.1", @@ -2544,6 +2618,16 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -2557,9 +2641,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.18", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.18.tgz", - "integrity": "sha512-1OfuVACu+zKlmjsNdcJuVQuVE61sZOLbNM4JAQ1Rvh6EOj0/EUKhMJjRH73InPlXSh8HIJk1cVZ8pyOV/FMdUQ==", + "version": "1.5.19", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.19.tgz", + "integrity": "sha512-kpLJJi3zxTR1U828P+LIUDZ5ohixyo68/IcYOHLqnbTPr/wdgn4i1ECvmALN9E16JPA6cvCG5UG79gVwVdEK5w==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -2609,7 +2693,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -3160,6 +3243,30 @@ "eslint": ">=7.0.0" } }, + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint-plugin-promise": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz", @@ -3209,6 +3316,30 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint-plugin-react/node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", @@ -3296,6 +3427,17 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/eslint/node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", @@ -3314,6 +3456,19 @@ } } }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -4111,32 +4266,6 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "license": "BSD-2-Clause" }, - "node_modules/glob/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": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", - "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -4279,6 +4408,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, "license": "MIT", "bin": { "he": "bin/he" @@ -4309,37 +4439,25 @@ "dev": true, "license": "MIT" }, - "node_modules/html-minifier": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", - "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", "license": "MIT", "dependencies": { - "camel-case": "^3.0.0", - "clean-css": "^4.2.1", - "commander": "^2.19.0", - "he": "^1.2.0", - "param-case": "^2.1.1", + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", "relateurl": "^0.2.7", - "uglify-js": "^3.5.1" + "terser": "^5.15.1" }, "bin": { - "html-minifier": "cli.js" + "html-minifier-terser": "cli.js" }, "engines": { - "node": ">=6" - } - }, - "node_modules/html-minifier/node_modules/clean-css": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", - "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", - "license": "MIT", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 4.0" + "node": "^14.13.1 || >=16.0.0" } }, "node_modules/html-validate": { @@ -4407,15 +4525,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/html-validate/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==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/html-validate/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -4685,6 +4794,30 @@ "minimatch": "^3.0.4" } }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/image-size": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", @@ -5721,10 +5854,13 @@ } }, "node_modules/lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", - "license": "MIT" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } }, "node_modules/lru-cache": { "version": "11.0.1", @@ -5892,15 +6028,18 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { @@ -5970,16 +6109,6 @@ "dev": true, "license": "Python-2.0" }, - "node_modules/mocha/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": { - "balanced-match": "^1.0.0" - } - }, "node_modules/mocha/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -6257,9 +6386,9 @@ "license": "ISC" }, "node_modules/nise": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", - "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.1.tgz", + "integrity": "sha512-DAyWGPQEuJVlL2eqKw6gdZKT+E/jo/ZrjEUDAslJLluCz81nWy+KSYybNp3KFm887Yvp7hv12jSM82ld8BmLxg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -6267,23 +6396,27 @@ "@sinonjs/fake-timers": "^11.2.2", "@sinonjs/text-encoding": "^0.7.2", "just-extend": "^6.2.0", - "path-to-regexp": "^6.2.1" + "path-to-regexp": "^8.1.0" } }, "node_modules/nise/node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.1.0.tgz", + "integrity": "sha512-Bqn3vc8CMHty6zuD+tG23s6v2kwxslHEhTj4eYaVKGIEB+YX/2wd0/rgXLFD9G9id9KCtbVy/3ZgmvZjpa0UdQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=16" + } }, "node_modules/no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "license": "MIT", "dependencies": { - "lower-case": "^1.1.1" + "lower-case": "^2.0.2", + "tslib": "^2.0.3" } }, "node_modules/node-abi": { @@ -6371,6 +6504,16 @@ "url": "https://opencollective.com/nodemon" } }, + "node_modules/nodemon/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/nodemon/node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", @@ -6397,6 +6540,18 @@ "node": ">=4" } }, + "node_modules/nodemon/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/nodemon/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -6745,12 +6900,13 @@ } }, "node_modules/param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "license": "MIT", "dependencies": { - "no-case": "^2.2.0" + "dot-case": "^3.0.4", + "tslib": "^2.0.3" } }, "node_modules/parent-module": { @@ -6838,6 +6994,16 @@ "node": ">= 0.8" } }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -7164,9 +7330,9 @@ "license": "MIT" }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -7560,6 +7726,17 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/rimraf/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -7582,6 +7759,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/roosevelt-logger": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/roosevelt-logger/-/roosevelt-logger-0.2.3.tgz", @@ -8053,14 +8243,14 @@ } }, "node_modules/sinon": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", - "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.1.tgz", + "integrity": "sha512-a2N2TDY1uGviajJ6r4D1CyRAkzE9NNVlYOV1wX5xQDuAk0ONgzgRl0EjCQuRCPxOwp13ghsMwt9Gdldujs39qw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/fake-timers": "11.2.2", "@sinonjs/samsam": "^8.0.0", "diff": "^5.2.0", "nise": "^6.0.0", @@ -8258,6 +8448,17 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/standard/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/standard/node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", @@ -8548,6 +8749,19 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/standard/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/standard/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -8877,6 +9091,17 @@ "url": "https://opencollective.com/stylus" } }, + "node_modules/stylus/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/stylus/node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", @@ -8917,6 +9142,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/stylus/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/stylus/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -9168,6 +9406,12 @@ } } }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, "node_modules/test-exclude": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", @@ -9183,16 +9427,6 @@ "node": ">=18" } }, - "node_modules/test-exclude/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": { - "balanced-match": "^1.0.0" - } - }, "node_modules/test-exclude/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -9326,15 +9560,6 @@ "node": ">=0.6" } }, - "node_modules/toobusy-js": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/toobusy-js/-/toobusy-js-0.5.1.tgz", - "integrity": "sha512-GiCux/c8G2TV0FTDgtxnXOxmSAndaI/9b1YxT14CqyeBDtTZAcJLx9KlXT3qECi8D0XCc78T4sN/7gWtjRyCaA==", - "license": "WTFPL", - "engines": { - "node": ">=0.9.1" - } - }, "node_modules/touch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", @@ -9377,7 +9602,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "dev": true, "license": "0BSD" }, "node_modules/tunnel-agent": { @@ -9521,18 +9745,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "license": "BSD-2-Clause", - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/uid-safe": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", @@ -9621,12 +9833,6 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", - "license": "MIT" - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/package.json b/package.json index 347d79344..fe05988f1 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "url": "https://github.com/rooseveltframework/roosevelt/graphs/contributors" } ], - "version": "0.23.1", + "version": "0.23.2", "files": [ "defaultErrorPages", "lib", @@ -38,10 +38,11 @@ "formidable": "3.5.1", "fs-extra": "11.2.0", "helmet": "7.1.0", - "html-minifier": "4.0.0", + "html-minifier-terser": "7.2.0", "klaw": "4.1.0", "klaw-sync": "6.0.0", "method-override": "3.0.0", + "minimatch": "10.0.1", "morgan": "1.10.0", "node-forge": "1.3.1", "page": "1.11.6", @@ -51,7 +52,6 @@ "selfsigned": "2.4.1", "serve-favicon": "2.5.0", "source-configs": "0.3.6", - "toobusy-js": "0.5.1", "webpack": "5.94.0" }, "devDependencies": { @@ -65,7 +65,7 @@ "prompts": "2.4.2", "proxyquire": "2.1.3", "sass": "1.78.0", - "sinon": "18.0.0", + "sinon": "18.0.1", "standard": "17.1.0", "stylus": "0.63.0", "supertest": "7.0.0", diff --git a/test/configAuditor.js b/test/configAuditor.js index efd208cd4..bca2c4683 100644 --- a/test/configAuditor.js +++ b/test/configAuditor.js @@ -80,7 +80,6 @@ describe('config auditor', () => { pkgJson.rooseveltConfig.logging.extraParam = true pkgJson.rooseveltConfig.js.extraParam = true pkgJson.rooseveltConfig.js.webpack.extraParam = true - pkgJson.rooseveltConfig.toobusy.extraParam = true // write package.json to app directory fs.ensureDirSync(path.join(appDir)) @@ -100,7 +99,6 @@ describe('config auditor', () => { assert(stderr.includes('Extra param "extraParam" found in rooseveltConfig.htmlValidator,')) assert(stderr.includes('Extra param "extraParam" found in rooseveltConfig.js,')) assert(stderr.includes('Extra param "extraParam" found in rooseveltConfig.js.webpack,')) - assert(stderr.includes('Extra param "extraParam" found in rooseveltConfig.toobusy,')) }) it('should detect and complain about a missing script', async () => { @@ -151,7 +149,6 @@ describe('config auditor', () => { configFile.logging.extraParam = true configFile.js.extraParam = true configFile.js.webpack.extraParam = true - configFile.toobusy.extraParam = true // write rooseveltConfig.json to app directory fs.ensureDirSync(path.join(appDir)) @@ -171,7 +168,6 @@ describe('config auditor', () => { assert(stderr.includes('Extra param "extraParam" found in rooseveltConfig.htmlValidator,')) assert(stderr.includes('Extra param "extraParam" found in rooseveltConfig.js,')) assert(stderr.includes('Extra param "extraParam" found in rooseveltConfig.js.webpack,')) - assert(stderr.includes('Extra param "extraParam" found in rooseveltConfig.toobusy,')) }) it('should scan and detect problems in both package.json and rooseveltConfig.json', async () => { diff --git a/test/errorPages.js b/test/errorPages.js index 60059ba22..590069410 100644 --- a/test/errorPages.js +++ b/test/errorPages.js @@ -194,107 +194,6 @@ describe('error pages', function () { }) }) - it('should respond with a 503 status when the server is busy', function (done) { - let detect503 = false - - // generate the test app - generateTestApp({ - appDir, - makeBuildArtifacts: true, - expressSession: false, - csrfProtection: false, - onServerStart: '(app) => {process.send(app.get("params"))}', - toobusy: { - maxLagPerRequest: 10, - lagCheckInterval: 16 - } - }, options) - - // fork and run app.js as a child process - const testApp = fork(path.join(appDir, 'app.js'), { stdio: ['pipe', 'pipe', 'pipe', 'ipc'] }) - - testApp.on('message', (params) => { - sendRequest() - - // spam requests until 503 is detected - function sendRequest () { - request(`http://localhost:${params.port}`) - .get('/slow') - .expect(503, (err, res) => { - if (err) { - // do nothing - } else { - if (res.text.includes('503 Service Unavailable')) { - detect503 = true - } - } - }) - if (detect503) { - testApp.send('stop') - } else { - setTimeout(sendRequest, 0) - } - } - }) - - // when the child process exits, finish the test - testApp.on('exit', () => { - done() - }) - }) - - it('should respond with a custom 503 error page when the server is busy', function (done) { - let detect503 - - // generate the test app - generateTestApp({ - appDir, - makeBuildArtifacts: true, - expressSession: false, - csrfProtection: false, - errorPages: { - serviceUnavailable: '503test.js' - }, - onServerStart: '(app) => {process.send(app.get("params"))}', - toobusy: { - maxLagPerRequest: 10, - lagCheckInterval: 16 - } - }, options) - - // fork and run app.js as a child process - const testApp = fork(path.join(appDir, 'app.js'), { stdio: ['pipe', 'pipe', 'pipe', 'ipc'] }) - - testApp.on('message', (params) => { - sendRequest() - - // spam requests until a 503 status is detected - function sendRequest () { - request(`http://localhost:${params.port}`) - .get('/slow') - .expect(503, (err, res) => { - if (err) { - // do nothing - } else { - if (res.text.includes('503 custom test error page')) { - detect503 = true - } - } - }) - if (detect503) { - testApp.send('stop') - } else { - setTimeout(sendRequest, 1) - } - } - }) - - // when the child process exits, finish the test - testApp.on('exit', () => { - done() - }) - }) - it('should complete the request even though the server was closed in the middle of it and respond 503 to any other request made afterwards', function (done) { let shuttingDownLogBool = false let successfulShutdownBool = false diff --git a/test/htmlMinify.js b/test/htmlMinify.js index 217b9e1bd..02fa7e33a 100644 --- a/test/htmlMinify.js +++ b/test/htmlMinify.js @@ -4,7 +4,7 @@ const assert = require('assert') const path = require('path') const cleanupTestApp = require('./util/cleanupTestApp') const fs = require('fs-extra') -const { minify } = require('html-minifier') +const { minify } = require('html-minifier-terser') const request = require('supertest') const roosevelt = require('../roosevelt') @@ -75,11 +75,11 @@ describe('HTML Minification Tests', function () { function onServerStart (app) { request(app) .get('/minify') - .expect(200, (err, res) => { + .expect(200, async (err, res) => { if (err) { assert.fail(err.message) } else { - const testMinify = minify(res.text, appConfig.html.minifier.options) + const testMinify = await minify(res.text, appConfig.html.minifier.options) assert.strictEqual(testMinify, res.text) } done() @@ -100,11 +100,11 @@ describe('HTML Minification Tests', function () { function onServerStart (app) { request(app) .get('/callbackRoute') - .expect(200, (err, res) => { + .expect(200, async (err, res) => { if (err) { assert.fail(err.message) } else { - const testMinify = minify(res.text, appConfig.html.minifier.options) + const testMinify = await minify(res.text, appConfig.html.minifier.options) assert.strictEqual(testMinify, res.text) } done() @@ -129,11 +129,11 @@ describe('HTML Minification Tests', function () { function onServerStart (app) { request(app) .get('/minify') - .expect(200, (err, res) => { + .expect(200, async (err, res) => { if (err) { assert.fail(err.message) } else { - const testMinify = minify(res.text, config.html.minifier.options) + const testMinify = await minify(res.text, config.html.minifier.options) assert.notStrictEqual(testMinify, res.text) } done() @@ -158,11 +158,11 @@ describe('HTML Minification Tests', function () { function onServerStart (app) { request(app) .get('/minify') - .expect(200, (err, res) => { + .expect(200, async (err, res) => { if (err) { assert.fail(err.message) } else { - const testMinify = minify(res.text, config.html.minifier.options) + const testMinify = await minify(res.text, config.html.minifier.options) assert.notStrictEqual(testMinify, res.text) } done() @@ -187,11 +187,11 @@ describe('HTML Minification Tests', function () { function onServerStart (app) { request(app) .get('/minify') - .expect(200, (err, res) => { + .expect(200, async (err, res) => { if (err) { assert.fail(err.message) } else { - const testMinify = minify(res.text, config.html.minifier.options) + const testMinify = await minify(res.text, config.html.minifier.options) assert.notStrictEqual(testMinify, res.text) // ensure minification is only disabled on the exceptionRoutes by testing another URL @@ -203,11 +203,11 @@ describe('HTML Minification Tests', function () { function checkSecondURL (app) { request(app) .get('/anotherRoute') - .expect(200, (err, res) => { + .expect(200, async (err, res) => { if (err) { assert.fail(err.message) } else { - const testMinify = minify(res.text, config.html.minifier.options) + const testMinify = await minify(res.text, config.html.minifier.options) assert.strictEqual(testMinify, res.text) } done() @@ -232,11 +232,11 @@ describe('HTML Minification Tests', function () { function onServerStart (app) { request(app) .get('/minify') - .expect(200, (err, res) => { + .expect(200, async (err, res) => { if (err) { assert.fail(err.message) } else { - const testMinify = minify(res.text, config.html.minifier.options) + const testMinify = await minify(res.text, config.html.minifier.options) assert.notStrictEqual(testMinify, res.text) // ensure minification is only disabled on the exceptionRoutes by testing another URL @@ -248,11 +248,11 @@ describe('HTML Minification Tests', function () { function checkSecondURL (app) { request(app) .get('/anotherRoute') - .expect(200, (err, res) => { + .expect(200, async (err, res) => { if (err) { assert.fail(err.message) } else { - const testMinify = minify(res.text, config.html.minifier.options) + const testMinify = await minify(res.text, config.html.minifier.options) assert.strictEqual(testMinify, res.text) } done() diff --git a/test/util/sampleConfig.json b/test/util/sampleConfig.json index 686c5964f..9438d8417 100644 --- a/test/util/sampleConfig.json +++ b/test/util/sampleConfig.json @@ -38,11 +38,6 @@ "formidable": { "multiples": "value" }, - "toobusy": { - "enable": false, - "maxLagPerRequest": "value", - "lagCheckInterval": "value" - }, "shutdownTimeout": "value", "helmet": {}, "expressSession": false, diff --git a/test/viewsBundler.js b/test/viewsBundler.js index df629f16e..cf535a4c1 100644 --- a/test/viewsBundler.js +++ b/test/viewsBundler.js @@ -8,7 +8,7 @@ const { fork } = require('child_process') const fse = require('fs-extra') const path = require('path') const klawsync = require('klaw-sync') -const htmlMinifier = require('html-minifier').minify +const htmlMinifier = require('html-minifier-terser').minify const minifyOptions = { removeComments: true, @@ -338,7 +338,7 @@ describe('Views Bundler Tests', function () { const exposedTemplatesArray = klawsync(pathToExposedTemplatesFolder) - exposedTemplatesArray.forEach((file) => { + exposedTemplatesArray.forEach(async (file) => { if (fsr.fileExists(file.path)) { delete require.cache[require.resolve(file.path)] } @@ -346,7 +346,7 @@ describe('Views Bundler Tests', function () { for (const key in templateJSON) { const template = templateJSON[key] - assert.strictEqual(htmlMinifier(template, minifyOptions), template) + assert.strictEqual(await htmlMinifier(template, minifyOptions), template) } }) @@ -380,7 +380,7 @@ describe('Views Bundler Tests', function () { const exposedTemplatesArray = klawsync(pathToExposedTemplatesFolder) - exposedTemplatesArray.forEach((file) => { + exposedTemplatesArray.forEach(async (file) => { if (fsr.fileExists(file.path)) { delete require.cache[require.resolve(file.path)] } @@ -388,7 +388,7 @@ describe('Views Bundler Tests', function () { for (const key in templateJSON) { const template = templateJSON[key] - assert.notStrictEqual(htmlMinifier(template, minifyOptions), template) + assert.notStrictEqual(await htmlMinifier(template, minifyOptions), template) } }) @@ -423,7 +423,7 @@ describe('Views Bundler Tests', function () { const exposedTemplatesArray = klawsync(pathToExposedTemplatesFolder) - exposedTemplatesArray.forEach((file) => { + exposedTemplatesArray.forEach(async (file) => { if (fsr.fileExists(file.path)) { delete require.cache[require.resolve(file.path)] } @@ -431,7 +431,7 @@ describe('Views Bundler Tests', function () { for (const key in templateJSON) { const template = templateJSON[key] - assert.strictEqual(htmlMinifier(template, minifyOptions), template) + assert.strictEqual(await htmlMinifier(template, minifyOptions), template) } })