From 590f6997cfa6bc2fd6e062d6af1a68f89c2c0b6e Mon Sep 17 00:00:00 2001 From: Ivan Borshchov Date: Wed, 15 Oct 2025 12:53:00 +0000 Subject: [PATCH 1/3] docs: add injection order control using meta.afOrder property --- .../03-Customization/08-pageInjections.md | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/adminforth/documentation/docs/tutorial/03-Customization/08-pageInjections.md b/adminforth/documentation/docs/tutorial/03-Customization/08-pageInjections.md index 3c82f72c..264c13f4 100644 --- a/adminforth/documentation/docs/tutorial/03-Customization/08-pageInjections.md +++ b/adminforth/documentation/docs/tutorial/03-Customization/08-pageInjections.md @@ -556,6 +556,55 @@ new AdminForth({ If you hide the logo with `showBrandLogoInSidebar: false`, components injected via `sidebarTop` will take the whole line width. +## Injection order + +Most of injections accept an array of components. By defult the order of components is the same as in the array. You can use standard array methods e.g. `push`, `unshift`, `splice` to put item in desired place. + +However, if you want to control the order of injections dynamically, which is very handly for plugins, you can use `meta.afOrder` property in the injection instantiation. The higher the number, the earlier the component will be rendered. For example + +```ts title="/index.ts" +{ + ... + customization: { + globalInjections: { + userMenu: [ + { + file: '@@/CustomUserMenuItem.vue', + meta: { afOrder: 10 } + }, + { + file: '@@/AnotherCustomUserMenuItem.vue', + meta: { afOrder: 20 } + }, + { + file: '@@/LastCustomUserMenuItem.vue', + meta: { afOrder: 5 } + }, + ] + } + } + ... +} +``` + +## Order of components inserted by plugins + +For plugins, the plugin developers encouraged to use `meta.afOrder` to control the order of injections and allow to pass it from plugin options. + +For example "OAuth2 plugin", when registers a login button component for login page injection, uses `meta.afOrder` and sets it equal to 'YYY' passed in plugin options: + +```ts title="/index.ts" +// plugin CODE +YYY.push({ + file: '@@/..vue', + meta: { + afOrder: this.pluginOptions.YYY || 0 + } + }) +``` + +So you can jsut pass `YYY` option to the plugin to control the order of the injection. + ## Custom scripts in head If you want to inject tags in your html head: From db28074708a4ca795e52e13cbead31f0e5ec66d6 Mon Sep 17 00:00:00 2001 From: dominicDeCoco Date: Wed, 15 Oct 2025 17:16:59 +0300 Subject: [PATCH 2/3] Rework rate-limiter --- adminforth/modules/utils.ts | 105 ++++++----------- adminforth/package-lock.json | 222 +++++++++++++++++++++++++++++++++++ adminforth/package.json | 1 + dev-demo/package-lock.json | 26 ++-- dev-demo/resources/users.ts | 10 +- 5 files changed, 277 insertions(+), 87 deletions(-) diff --git a/adminforth/modules/utils.ts b/adminforth/modules/utils.ts index 72b9b5bc..f7d643b4 100644 --- a/adminforth/modules/utils.ts +++ b/adminforth/modules/utils.ts @@ -4,6 +4,7 @@ import fs from 'fs'; import Fuse from 'fuse.js'; import crypto from 'crypto'; import AdminForth, { AdminForthConfig } from '../index.js'; +import { RateLimiterMemory, RateLimiterAbstract } from "rate-limiter-flexible"; // @ts-ignore-next-line @@ -381,90 +382,50 @@ export function md5hash(str:string) { } export class RateLimiter { - static counterData = {}; - - /** - * Very dirty version of ratelimiter for demo purposes (should not be considered as production ready) - * Will be used as RateLimiter.checkRateLimit('key', '5/24h', clientIp) - * Stores counter in this class, in RAM, resets limits on app restart. - * Also it creates setTimeout for every call, so is not optimal for high load. - * @param key - key to store rate limit for - * @param limit - limit in format '5/24h' - 5 requests per 24 hours - * @param clientIp - */ - static checkRateLimit(key: string, limit: string, clientIp: string) { - - if (!limit) { - throw new Error('Rate limit is not set'); - } + // constructor, accepts string like 10/10m, or 20/10s, or 30/1d - if (!key) { - throw new Error('Rate limit key is not set'); - } - if (!clientIp) { - throw new Error('Client IP is not set'); - } + rateLimiter: RateLimiterAbstract; - if (!limit.includes('/')) { - throw new Error('Rate limit should be in format count/period, like 5/24h'); - } - // parse limit - const [count, period] = limit.split('/'); - const [preiodAmount, periodType] = /(\d+)(\w+)/.exec(period).slice(1); - const preiodAmountNumber = parseInt(preiodAmount); - - // get current time - const whenClear = new Date(); - if (periodType === 'h') { - whenClear.setHours(whenClear.getHours() + preiodAmountNumber); - } else if (periodType === 'd') { - whenClear.setDate(whenClear.getDate() + preiodAmountNumber); - } else if (periodType === 'm') { - whenClear.setMinutes(whenClear.getMinutes() + preiodAmountNumber); - } else if (periodType === 'y') { - whenClear.setFullYear(whenClear.getFullYear() + preiodAmountNumber); - } else if (periodType === 's') { - whenClear.setSeconds(whenClear.getSeconds() + preiodAmountNumber); - } else { - throw new Error(`Unsupported period type for rate limiting: ${periodType}`); + durStringToSeconds(rate: string): number { + if (!rate) { + throw new Error('Rate duration is required'); } - - // get current counter - const counter = this.counterData[key] && this.counterData[key][clientIp] || 0; - if (counter >= count) { - return { error: true }; + + const period = rate.slice(-1); + const duration = parseInt(rate.slice(0, -1)); + if (period === 's') { + return duration; + } else if (period === 'm') { + return duration * 60; + } else if (period === 'h') { + return duration * 60 * 60; + } else if (period === 'd') { + return duration * 60 * 60 * 24; } - RateLimiter.incrementCounter(key, clientIp); - setTimeout(() => { - RateLimiter.decrementCounter(key, clientIp); - }, whenClear.getTime() - Date.now()); + throw new Error(`Invalid rate duration period: ${period}`); + } - return { error: false }; + constructor(rate: string) { + const [points, duration] = rate.split('/'); + const durationSeconds = this.durStringToSeconds(duration); + const opts = { + points: parseInt(points), + duration: durationSeconds, // Per second + }; + this.rateLimiter = new RateLimiterMemory(opts); } - static incrementCounter(key: string, ip: string) { - if (!RateLimiter.counterData[key]) { - RateLimiter.counterData[key] = {}; - } - if (!RateLimiter.counterData[key][ip]) { - RateLimiter.counterData[key][ip] = 0; - } - RateLimiter.counterData[key][ip]++; - } - static decrementCounter(key: string, ip: string) { - if (!RateLimiter.counterData[key]) { - RateLimiter.counterData[key] = {}; - } - if (!RateLimiter.counterData[key][ip]) { - RateLimiter.counterData[key][ip] = 0; - } - if (RateLimiter.counterData[key][ip] > 0) { - RateLimiter.counterData[key][ip]--; + async consume(key: string) { + try { + await this.rateLimiter.consume(key); + return true; + } catch (rejRes) { + return false; } } diff --git a/adminforth/package-lock.json b/adminforth/package-lock.json index 6ea6701b..0bef08c3 100644 --- a/adminforth/package-lock.json +++ b/adminforth/package-lock.json @@ -36,6 +36,7 @@ "mysql2": "^3.14.2", "node-fetch": "^3.3.2", "pg": "^8.11.5", + "rate-limiter-flexible": "^8.1.0", "recast": "^0.23.11", "ws": "^8.18.0" }, @@ -5084,6 +5085,7 @@ }, "node_modules/npm/node_modules/@isaacs/cliui": { "version": "8.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5100,6 +5102,7 @@ }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { "version": "6.1.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -5111,11 +5114,13 @@ }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -5132,6 +5137,7 @@ }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.1.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -5146,6 +5152,7 @@ }, "node_modules/npm/node_modules/@isaacs/fs-minipass": { "version": "4.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5157,11 +5164,13 @@ }, "node_modules/npm/node_modules/@isaacs/string-locale-compare": { "version": "1.1.0", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/@npmcli/agent": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5177,6 +5186,7 @@ }, "node_modules/npm/node_modules/@npmcli/arborist": { "version": "8.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5225,6 +5235,7 @@ }, "node_modules/npm/node_modules/@npmcli/config": { "version": "9.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5243,6 +5254,7 @@ }, "node_modules/npm/node_modules/@npmcli/fs": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5254,6 +5266,7 @@ }, "node_modules/npm/node_modules/@npmcli/git": { "version": "6.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5273,6 +5286,7 @@ }, "node_modules/npm/node_modules/@npmcli/installed-package-contents": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5288,6 +5302,7 @@ }, "node_modules/npm/node_modules/@npmcli/map-workspaces": { "version": "4.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5302,6 +5317,7 @@ }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { "version": "8.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5317,6 +5333,7 @@ }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator/node_modules/pacote": { "version": "20.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5347,6 +5364,7 @@ }, "node_modules/npm/node_modules/@npmcli/name-from-folder": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -5355,6 +5373,7 @@ }, "node_modules/npm/node_modules/@npmcli/node-gyp": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -5363,6 +5382,7 @@ }, "node_modules/npm/node_modules/@npmcli/package-json": { "version": "6.1.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5380,6 +5400,7 @@ }, "node_modules/npm/node_modules/@npmcli/promise-spawn": { "version": "8.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5391,6 +5412,7 @@ }, "node_modules/npm/node_modules/@npmcli/query": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5402,6 +5424,7 @@ }, "node_modules/npm/node_modules/@npmcli/redact": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -5410,6 +5433,7 @@ }, "node_modules/npm/node_modules/@npmcli/run-script": { "version": "9.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5426,6 +5450,7 @@ }, "node_modules/npm/node_modules/@pkgjs/parseargs": { "version": "0.11.0", + "dev": true, "inBundle": true, "license": "MIT", "optional": true, @@ -5435,6 +5460,7 @@ }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { "version": "0.3.2", + "dev": true, "inBundle": true, "license": "Apache-2.0", "engines": { @@ -5443,6 +5469,7 @@ }, "node_modules/npm/node_modules/@sigstore/tuf": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -5455,6 +5482,7 @@ }, "node_modules/npm/node_modules/@tufjs/canonical-json": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -5463,6 +5491,7 @@ }, "node_modules/npm/node_modules/abbrev": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -5471,6 +5500,7 @@ }, "node_modules/npm/node_modules/agent-base": { "version": "7.1.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -5482,6 +5512,7 @@ }, "node_modules/npm/node_modules/aggregate-error": { "version": "3.1.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -5494,6 +5525,7 @@ }, "node_modules/npm/node_modules/ansi-regex": { "version": "5.0.1", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -5502,6 +5534,7 @@ }, "node_modules/npm/node_modules/ansi-styles": { "version": "6.2.1", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -5513,21 +5546,25 @@ }, "node_modules/npm/node_modules/aproba": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/archy": { "version": "1.0.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/balanced-match": { "version": "1.0.2", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/bin-links": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5543,6 +5580,7 @@ }, "node_modules/npm/node_modules/binary-extensions": { "version": "2.3.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -5554,6 +5592,7 @@ }, "node_modules/npm/node_modules/brace-expansion": { "version": "2.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -5562,6 +5601,7 @@ }, "node_modules/npm/node_modules/cacache": { "version": "19.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5584,6 +5624,7 @@ }, "node_modules/npm/node_modules/cacache/node_modules/chownr": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "engines": { @@ -5592,6 +5633,7 @@ }, "node_modules/npm/node_modules/cacache/node_modules/minizlib": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -5604,6 +5646,7 @@ }, "node_modules/npm/node_modules/cacache/node_modules/mkdirp": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "MIT", "bin": { @@ -5618,6 +5661,7 @@ }, "node_modules/npm/node_modules/cacache/node_modules/p-map": { "version": "7.0.2", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -5629,6 +5673,7 @@ }, "node_modules/npm/node_modules/cacache/node_modules/tar": { "version": "7.4.3", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5645,6 +5690,7 @@ }, "node_modules/npm/node_modules/cacache/node_modules/yallist": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "engines": { @@ -5653,6 +5699,7 @@ }, "node_modules/npm/node_modules/chalk": { "version": "5.3.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -5664,6 +5711,7 @@ }, "node_modules/npm/node_modules/chownr": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -5672,6 +5720,7 @@ }, "node_modules/npm/node_modules/ci-info": { "version": "4.1.0", + "dev": true, "funding": [ { "type": "github", @@ -5686,6 +5735,7 @@ }, "node_modules/npm/node_modules/cidr-regex": { "version": "4.1.1", + "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { @@ -5697,6 +5747,7 @@ }, "node_modules/npm/node_modules/clean-stack": { "version": "2.2.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -5705,6 +5756,7 @@ }, "node_modules/npm/node_modules/cli-columns": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -5717,6 +5769,7 @@ }, "node_modules/npm/node_modules/cmd-shim": { "version": "7.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -5725,6 +5778,7 @@ }, "node_modules/npm/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -5736,16 +5790,19 @@ }, "node_modules/npm/node_modules/color-name": { "version": "1.1.4", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/common-ancestor-path": { "version": "1.0.1", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/cross-spawn": { "version": "7.0.6", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -5759,6 +5816,7 @@ }, "node_modules/npm/node_modules/cross-spawn/node_modules/which": { "version": "2.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5773,6 +5831,7 @@ }, "node_modules/npm/node_modules/cssesc": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "MIT", "bin": { @@ -5784,6 +5843,7 @@ }, "node_modules/npm/node_modules/debug": { "version": "4.3.7", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -5800,6 +5860,7 @@ }, "node_modules/npm/node_modules/diff": { "version": "5.2.0", + "dev": true, "inBundle": true, "license": "BSD-3-Clause", "engines": { @@ -5808,16 +5869,19 @@ }, "node_modules/npm/node_modules/eastasianwidth": { "version": "0.2.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/emoji-regex": { "version": "8.0.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/encoding": { "version": "0.1.13", + "dev": true, "inBundle": true, "license": "MIT", "optional": true, @@ -5827,6 +5891,7 @@ }, "node_modules/npm/node_modules/env-paths": { "version": "2.2.1", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -5835,16 +5900,19 @@ }, "node_modules/npm/node_modules/err-code": { "version": "2.0.3", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/exponential-backoff": { "version": "3.1.1", + "dev": true, "inBundle": true, "license": "Apache-2.0" }, "node_modules/npm/node_modules/fastest-levenshtein": { "version": "1.0.16", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -5853,6 +5921,7 @@ }, "node_modules/npm/node_modules/foreground-child": { "version": "3.3.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5868,6 +5937,7 @@ }, "node_modules/npm/node_modules/fs-minipass": { "version": "3.0.3", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5879,6 +5949,7 @@ }, "node_modules/npm/node_modules/glob": { "version": "10.4.5", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5898,11 +5969,13 @@ }, "node_modules/npm/node_modules/graceful-fs": { "version": "4.2.11", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/hosted-git-info": { "version": "8.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5914,11 +5987,13 @@ }, "node_modules/npm/node_modules/http-cache-semantics": { "version": "4.1.1", + "dev": true, "inBundle": true, "license": "BSD-2-Clause" }, "node_modules/npm/node_modules/http-proxy-agent": { "version": "7.0.2", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -5931,6 +6006,7 @@ }, "node_modules/npm/node_modules/https-proxy-agent": { "version": "7.0.5", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -5943,6 +6019,7 @@ }, "node_modules/npm/node_modules/iconv-lite": { "version": "0.6.3", + "dev": true, "inBundle": true, "license": "MIT", "optional": true, @@ -5955,6 +6032,7 @@ }, "node_modules/npm/node_modules/ignore-walk": { "version": "7.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -5966,6 +6044,7 @@ }, "node_modules/npm/node_modules/imurmurhash": { "version": "0.1.4", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -5974,6 +6053,7 @@ }, "node_modules/npm/node_modules/indent-string": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -5982,6 +6062,7 @@ }, "node_modules/npm/node_modules/ini": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -5990,6 +6071,7 @@ }, "node_modules/npm/node_modules/init-package-json": { "version": "7.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6007,6 +6089,7 @@ }, "node_modules/npm/node_modules/ip-address": { "version": "9.0.5", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -6019,6 +6102,7 @@ }, "node_modules/npm/node_modules/ip-regex": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -6030,6 +6114,7 @@ }, "node_modules/npm/node_modules/is-cidr": { "version": "5.1.0", + "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { @@ -6041,6 +6126,7 @@ }, "node_modules/npm/node_modules/is-fullwidth-code-point": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -6049,11 +6135,13 @@ }, "node_modules/npm/node_modules/isexe": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/jackspeak": { "version": "3.4.3", + "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -6068,11 +6156,13 @@ }, "node_modules/npm/node_modules/jsbn": { "version": "1.1.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/json-parse-even-better-errors": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -6081,6 +6171,7 @@ }, "node_modules/npm/node_modules/json-stringify-nice": { "version": "1.1.4", + "dev": true, "inBundle": true, "license": "ISC", "funding": { @@ -6089,6 +6180,7 @@ }, "node_modules/npm/node_modules/jsonparse": { "version": "1.3.1", + "dev": true, "engines": [ "node >= 0.2.0" ], @@ -6097,16 +6189,19 @@ }, "node_modules/npm/node_modules/just-diff": { "version": "6.0.2", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/just-diff-apply": { "version": "5.5.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/libnpmaccess": { "version": "9.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6119,6 +6214,7 @@ }, "node_modules/npm/node_modules/libnpmdiff": { "version": "7.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6137,6 +6233,7 @@ }, "node_modules/npm/node_modules/libnpmexec": { "version": "9.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6157,6 +6254,7 @@ }, "node_modules/npm/node_modules/libnpmfund": { "version": "6.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6168,6 +6266,7 @@ }, "node_modules/npm/node_modules/libnpmhook": { "version": "11.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6180,6 +6279,7 @@ }, "node_modules/npm/node_modules/libnpmorg": { "version": "7.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6192,6 +6292,7 @@ }, "node_modules/npm/node_modules/libnpmpack": { "version": "8.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6206,6 +6307,7 @@ }, "node_modules/npm/node_modules/libnpmpublish": { "version": "10.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6224,6 +6326,7 @@ }, "node_modules/npm/node_modules/libnpmsearch": { "version": "8.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6235,6 +6338,7 @@ }, "node_modules/npm/node_modules/libnpmteam": { "version": "7.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6247,6 +6351,7 @@ }, "node_modules/npm/node_modules/libnpmversion": { "version": "7.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6262,11 +6367,13 @@ }, "node_modules/npm/node_modules/lru-cache": { "version": "10.4.3", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/make-fetch-happen": { "version": "14.0.3", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6288,6 +6395,7 @@ }, "node_modules/npm/node_modules/make-fetch-happen/node_modules/negotiator": { "version": "1.0.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -6296,6 +6404,7 @@ }, "node_modules/npm/node_modules/minimatch": { "version": "9.0.5", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6310,6 +6419,7 @@ }, "node_modules/npm/node_modules/minipass": { "version": "7.1.2", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -6318,6 +6428,7 @@ }, "node_modules/npm/node_modules/minipass-collect": { "version": "2.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6329,6 +6440,7 @@ }, "node_modules/npm/node_modules/minipass-fetch": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -6345,6 +6457,7 @@ }, "node_modules/npm/node_modules/minipass-fetch/node_modules/minizlib": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -6357,6 +6470,7 @@ }, "node_modules/npm/node_modules/minipass-flush": { "version": "1.0.5", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6368,6 +6482,7 @@ }, "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { "version": "3.3.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6379,6 +6494,7 @@ }, "node_modules/npm/node_modules/minipass-pipeline": { "version": "1.2.4", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6390,6 +6506,7 @@ }, "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { "version": "3.3.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6401,6 +6518,7 @@ }, "node_modules/npm/node_modules/minipass-sized": { "version": "1.0.3", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6412,6 +6530,7 @@ }, "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { "version": "3.3.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6423,6 +6542,7 @@ }, "node_modules/npm/node_modules/minizlib": { "version": "2.1.2", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -6435,6 +6555,7 @@ }, "node_modules/npm/node_modules/minizlib/node_modules/minipass": { "version": "3.3.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6446,6 +6567,7 @@ }, "node_modules/npm/node_modules/mkdirp": { "version": "1.0.4", + "dev": true, "inBundle": true, "license": "MIT", "bin": { @@ -6457,11 +6579,13 @@ }, "node_modules/npm/node_modules/ms": { "version": "2.1.3", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/mute-stream": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -6470,6 +6594,7 @@ }, "node_modules/npm/node_modules/node-gyp": { "version": "11.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -6493,6 +6618,7 @@ }, "node_modules/npm/node_modules/node-gyp/node_modules/chownr": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "engines": { @@ -6501,6 +6627,7 @@ }, "node_modules/npm/node_modules/node-gyp/node_modules/minizlib": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -6513,6 +6640,7 @@ }, "node_modules/npm/node_modules/node-gyp/node_modules/mkdirp": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "MIT", "bin": { @@ -6527,6 +6655,7 @@ }, "node_modules/npm/node_modules/node-gyp/node_modules/tar": { "version": "7.4.3", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6543,6 +6672,7 @@ }, "node_modules/npm/node_modules/node-gyp/node_modules/yallist": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "engines": { @@ -6551,6 +6681,7 @@ }, "node_modules/npm/node_modules/nopt": { "version": "8.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6565,6 +6696,7 @@ }, "node_modules/npm/node_modules/nopt/node_modules/abbrev": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -6573,6 +6705,7 @@ }, "node_modules/npm/node_modules/normalize-package-data": { "version": "7.0.0", + "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { @@ -6586,6 +6719,7 @@ }, "node_modules/npm/node_modules/npm-audit-report": { "version": "6.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -6594,6 +6728,7 @@ }, "node_modules/npm/node_modules/npm-bundled": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6605,6 +6740,7 @@ }, "node_modules/npm/node_modules/npm-install-checks": { "version": "7.1.1", + "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { @@ -6616,6 +6752,7 @@ }, "node_modules/npm/node_modules/npm-normalize-package-bin": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -6624,6 +6761,7 @@ }, "node_modules/npm/node_modules/npm-package-arg": { "version": "12.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6638,6 +6776,7 @@ }, "node_modules/npm/node_modules/npm-packlist": { "version": "9.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6649,6 +6788,7 @@ }, "node_modules/npm/node_modules/npm-pick-manifest": { "version": "10.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6663,6 +6803,7 @@ }, "node_modules/npm/node_modules/npm-profile": { "version": "11.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6675,6 +6816,7 @@ }, "node_modules/npm/node_modules/npm-registry-fetch": { "version": "18.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6693,6 +6835,7 @@ }, "node_modules/npm/node_modules/npm-registry-fetch/node_modules/minizlib": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -6705,6 +6848,7 @@ }, "node_modules/npm/node_modules/npm-user-validate": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "BSD-2-Clause", "engines": { @@ -6713,6 +6857,7 @@ }, "node_modules/npm/node_modules/p-map": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -6727,11 +6872,13 @@ }, "node_modules/npm/node_modules/package-json-from-dist": { "version": "1.0.1", + "dev": true, "inBundle": true, "license": "BlueOak-1.0.0" }, "node_modules/npm/node_modules/pacote": { "version": "19.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6762,6 +6909,7 @@ }, "node_modules/npm/node_modules/parse-conflict-json": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6775,6 +6923,7 @@ }, "node_modules/npm/node_modules/path-key": { "version": "3.1.1", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -6783,6 +6932,7 @@ }, "node_modules/npm/node_modules/path-scurry": { "version": "1.11.1", + "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -6798,6 +6948,7 @@ }, "node_modules/npm/node_modules/postcss-selector-parser": { "version": "6.1.2", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -6810,6 +6961,7 @@ }, "node_modules/npm/node_modules/proc-log": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -6818,6 +6970,7 @@ }, "node_modules/npm/node_modules/proggy": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -6826,6 +6979,7 @@ }, "node_modules/npm/node_modules/promise-all-reject-late": { "version": "1.0.1", + "dev": true, "inBundle": true, "license": "ISC", "funding": { @@ -6834,6 +6988,7 @@ }, "node_modules/npm/node_modules/promise-call-limit": { "version": "3.0.2", + "dev": true, "inBundle": true, "license": "ISC", "funding": { @@ -6842,11 +6997,13 @@ }, "node_modules/npm/node_modules/promise-inflight": { "version": "1.0.1", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/promise-retry": { "version": "2.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -6859,6 +7016,7 @@ }, "node_modules/npm/node_modules/promzard": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6870,6 +7028,7 @@ }, "node_modules/npm/node_modules/qrcode-terminal": { "version": "0.12.0", + "dev": true, "inBundle": true, "bin": { "qrcode-terminal": "bin/qrcode-terminal.js" @@ -6877,6 +7036,7 @@ }, "node_modules/npm/node_modules/read": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6888,6 +7048,7 @@ }, "node_modules/npm/node_modules/read-cmd-shim": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -6896,6 +7057,7 @@ }, "node_modules/npm/node_modules/read-package-json-fast": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6908,6 +7070,7 @@ }, "node_modules/npm/node_modules/retry": { "version": "0.12.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -6916,6 +7079,7 @@ }, "node_modules/npm/node_modules/rimraf": { "version": "5.0.10", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -6930,12 +7094,14 @@ }, "node_modules/npm/node_modules/safer-buffer": { "version": "2.1.2", + "dev": true, "inBundle": true, "license": "MIT", "optional": true }, "node_modules/npm/node_modules/semver": { "version": "7.6.3", + "dev": true, "inBundle": true, "license": "ISC", "bin": { @@ -6947,6 +7113,7 @@ }, "node_modules/npm/node_modules/shebang-command": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -6958,6 +7125,7 @@ }, "node_modules/npm/node_modules/shebang-regex": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -6966,6 +7134,7 @@ }, "node_modules/npm/node_modules/signal-exit": { "version": "4.1.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -6977,6 +7146,7 @@ }, "node_modules/npm/node_modules/sigstore": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -6993,6 +7163,7 @@ }, "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/bundle": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -7004,6 +7175,7 @@ }, "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/core": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "Apache-2.0", "engines": { @@ -7012,6 +7184,7 @@ }, "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/sign": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -7028,6 +7201,7 @@ }, "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/verify": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -7041,6 +7215,7 @@ }, "node_modules/npm/node_modules/smart-buffer": { "version": "4.2.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -7050,6 +7225,7 @@ }, "node_modules/npm/node_modules/socks": { "version": "2.8.3", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7063,6 +7239,7 @@ }, "node_modules/npm/node_modules/socks-proxy-agent": { "version": "8.0.4", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7076,6 +7253,7 @@ }, "node_modules/npm/node_modules/spdx-correct": { "version": "3.2.0", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -7085,6 +7263,7 @@ }, "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7094,11 +7273,13 @@ }, "node_modules/npm/node_modules/spdx-exceptions": { "version": "2.5.0", + "dev": true, "inBundle": true, "license": "CC-BY-3.0" }, "node_modules/npm/node_modules/spdx-expression-parse": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7108,16 +7289,19 @@ }, "node_modules/npm/node_modules/spdx-license-ids": { "version": "3.0.20", + "dev": true, "inBundle": true, "license": "CC0-1.0" }, "node_modules/npm/node_modules/sprintf-js": { "version": "1.1.3", + "dev": true, "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/npm/node_modules/ssri": { "version": "12.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -7129,6 +7313,7 @@ }, "node_modules/npm/node_modules/string-width": { "version": "4.2.3", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7143,6 +7328,7 @@ "node_modules/npm/node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7156,6 +7342,7 @@ }, "node_modules/npm/node_modules/strip-ansi": { "version": "6.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7168,6 +7355,7 @@ "node_modules/npm/node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7179,6 +7367,7 @@ }, "node_modules/npm/node_modules/supports-color": { "version": "9.4.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -7190,6 +7379,7 @@ }, "node_modules/npm/node_modules/tar": { "version": "6.2.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -7206,6 +7396,7 @@ }, "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { "version": "2.1.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -7217,6 +7408,7 @@ }, "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { "version": "3.3.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -7228,6 +7420,7 @@ }, "node_modules/npm/node_modules/tar/node_modules/minipass": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -7236,16 +7429,19 @@ }, "node_modules/npm/node_modules/text-table": { "version": "0.2.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/tiny-relative-date": { "version": "1.3.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/treeverse": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -7254,6 +7450,7 @@ }, "node_modules/npm/node_modules/tuf-js": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7267,6 +7464,7 @@ }, "node_modules/npm/node_modules/tuf-js/node_modules/@tufjs/models": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7279,6 +7477,7 @@ }, "node_modules/npm/node_modules/unique-filename": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -7290,6 +7489,7 @@ }, "node_modules/npm/node_modules/unique-slug": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -7301,11 +7501,13 @@ }, "node_modules/npm/node_modules/util-deprecate": { "version": "1.0.2", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/validate-npm-package-license": { "version": "3.0.4", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -7315,6 +7517,7 @@ }, "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7324,6 +7527,7 @@ }, "node_modules/npm/node_modules/validate-npm-package-name": { "version": "6.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -7332,11 +7536,13 @@ }, "node_modules/npm/node_modules/walk-up-path": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/which": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -7351,6 +7557,7 @@ }, "node_modules/npm/node_modules/which/node_modules/isexe": { "version": "3.1.1", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -7359,6 +7566,7 @@ }, "node_modules/npm/node_modules/wrap-ansi": { "version": "8.1.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7376,6 +7584,7 @@ "node_modules/npm/node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7392,6 +7601,7 @@ }, "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7406,6 +7616,7 @@ }, "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.1.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -7417,11 +7628,13 @@ }, "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { "version": "9.2.2", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { "version": "5.1.2", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7438,6 +7651,7 @@ }, "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "7.1.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -7452,6 +7666,7 @@ }, "node_modules/npm/node_modules/write-file-atomic": { "version": "6.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -7464,6 +7679,7 @@ }, "node_modules/npm/node_modules/yallist": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC" }, @@ -8052,6 +8268,12 @@ "node": ">= 0.6" } }, + "node_modules/rate-limiter-flexible": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/rate-limiter-flexible/-/rate-limiter-flexible-8.1.0.tgz", + "integrity": "sha512-J+4xBdVboibP1h0Imn4nFoCLT+UM9Os9vJaWaRWkLsQxS7jrhLJeLlmzP5hyCEsLwtgFIIY5KcWiJGyyVTMaKg==", + "license": "ISC" + }, "node_modules/raw-body": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", diff --git a/adminforth/package.json b/adminforth/package.json index fa92d05f..71bbe853 100644 --- a/adminforth/package.json +++ b/adminforth/package.json @@ -82,6 +82,7 @@ "mysql2": "^3.14.2", "node-fetch": "^3.3.2", "pg": "^8.11.5", + "rate-limiter-flexible": "^8.1.0", "recast": "^0.23.11", "ws": "^8.18.0" }, diff --git a/dev-demo/package-lock.json b/dev-demo/package-lock.json index 63c5aba4..5f343b15 100644 --- a/dev-demo/package-lock.json +++ b/dev-demo/package-lock.json @@ -1711,6 +1711,7 @@ "version": "8.16.3", "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz", "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==", + "license": "MIT", "dependencies": { "pg-connection-string": "^2.9.1", "pg-pool": "^3.10.1", @@ -1737,17 +1738,20 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz", "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==", + "license": "MIT", "optional": true }, "node_modules/pg-connection-string": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz", - "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==" + "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==", + "license": "MIT" }, "node_modules/pg-int8": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", "engines": { "node": ">=4.0.0" } @@ -1756,6 +1760,7 @@ "version": "3.10.1", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz", "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==", + "license": "MIT", "peerDependencies": { "pg": ">=8.0" } @@ -1763,12 +1768,14 @@ "node_modules/pg-protocol": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", - "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==" + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "license": "MIT" }, "node_modules/pg-types": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", @@ -1784,6 +1791,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", "dependencies": { "split2": "^4.1.0" } @@ -1805,6 +1813,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", "engines": { "node": ">=4" } @@ -1813,6 +1822,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1821,6 +1831,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1829,6 +1840,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", "dependencies": { "xtend": "^4.0.0" }, @@ -2247,18 +2259,11 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", "engines": { "node": ">= 10.x" } }, - "node_modules/sqlstring": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", - "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -2464,6 +2469,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", "engines": { "node": ">=0.4" } diff --git a/dev-demo/resources/users.ts b/dev-demo/resources/users.ts index 1d99d338..07378a2d 100644 --- a/dev-demo/resources/users.ts +++ b/dev-demo/resources/users.ts @@ -18,7 +18,7 @@ import AdminForthAdapterGithubOauth2 from "../../adapters/adminforth-github-oau import AdminForthAdapterFacebookOauth2 from "../../adapters/adminforth-facebook-oauth-adapter"; import AdminForthAdapterKeycloakOauth2 from "../../adapters/adminforth-keycloak-oauth-adapter"; import AdminForthAdapterMicrosoftOauth2 from "../../adapters/adminforth-microsoft-oauth-adapter"; -import AdminForthAdapterTwitchOauth2 from "../../adapters/adminforth-twitch-oauth-adapter"; +// import AdminForthAdapterTwitchOauth2 from "../../adapters/adminforth-twitch-oauth-adapter"; import { randomUUID } from "crypto"; declare global { @@ -166,10 +166,10 @@ export default { clientSecret: process.env.MICROSOFT_CLIENT_SECRET, useOpenID: true, }), - new AdminForthAdapterTwitchOauth2({ - clientID: process.env.TWITCH_CLIENT_ID, - clientSecret: process.env.TWITCH_CLIENT_SECRET, - }), + // new AdminForthAdapterTwitchOauth2({ + // clientID: process.env.TWITCH_CLIENT_ID, + // clientSecret: process.env.TWITCH_CLIENT_SECRET, + // }), // new AdminForthAdapterKeycloakOauth2({ // name: "Keycloak", // clientID: process.env.KEYCLOAK_CLIENT_ID, From 43c16b4d9757f767dc612a25f6c399f5619c2192 Mon Sep 17 00:00:00 2001 From: yaroslav8765 Date: Thu, 16 Oct 2025 10:06:47 +0300 Subject: [PATCH 3/3] feat: add ability to style user menu --- adminforth/modules/styles.ts | 16 +++++++++++++++- adminforth/spa/src/App.vue | 6 +++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/adminforth/modules/styles.ts b/adminforth/modules/styles.ts index df3ba2bc..916b06ca 100644 --- a/adminforth/modules/styles.ts +++ b/adminforth/modules/styles.ts @@ -356,7 +356,13 @@ export const styles = () => ({ lightUserMenuSettingsButtonDropdownItemText: "alias:lightBreadcrumbsHomepageText", lightUserMenuSettingsButtonDropdownItemTextHover: "alias:lightBreadcrumbsHomepageTextHover", - + lightUserMenuBackground: "#FFFFFF", + lightUserMenuBorder: "#f3f4f6", + lightUserMenuText: "#111827", + lightUserMenuItemBackground: "alias:lightUserMenuBackground", + lightUserMenuItemBackgroundHover: "alias:lightUserMenuBackground", + lightUserMenuItemText: "#000000", + lightUserMenuItemTextHover: "#000000", // colors for dark theme darkHtml: "#111827", @@ -711,6 +717,14 @@ export const styles = () => ({ darkUserMenuSettingsButtonDropdownItemText: "#FFFFFF", darkUserMenuSettingsButtonDropdownItemTextHover: "#FFFFFF", + darkUserMenuBackground: "alias:darkSidebar", + darkUserMenuBorder: "alias:darkSidebarDevider", + darkUserMenuText: "#FFFFFF", + darkUserMenuItemBackground: "alias:darkSidebar", + darkUserMenuItemBackgroundHover: "alias:darkSidebarItemHover", + darkUserMenuItemText: "#FFFFFF", + darkUserMenuItemTextHover: "#FFFFFF", + }, boxShadow: { customLight: "0 4px 8px rgba(0, 0, 0, 0.1)", // Lighter shadow diff --git a/adminforth/spa/src/App.vue b/adminforth/spa/src/App.vue index 67a6eebd..c5901c6f 100644 --- a/adminforth/spa/src/App.vue +++ b/adminforth/spa/src/App.vue @@ -41,7 +41,7 @@ -