diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index a323f1f1..00000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-# To get started with Dependabot version updates, you'll need to specify which
-# package ecosystems to update and where the package manifests are located.
-# Please see the documentation for all configuration options:
-# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
-
-version: 2
-updates:
- # Enable version updates for npm
- - package-ecosystem: "npm"
- # Look for `package.json` and `lock` files in the `root` directory
- directory: "/"
- # Check the npm registry for updates every day (weekdays)
- schedule:
- interval: "daily"
- - package-ecosystem: "github-actions"
- # Workflow files stored in the default location of `.github/workflows`
- # You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`.
- directory: "/"
- schedule:
- interval: "weekly"
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index d311ac02..1aca6866 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -17,7 +17,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v6
with:
- node-version: "20"
+ node-version: "24"
- name: Install dependencies
run: npm ci
diff --git a/apps/juxtaposition-ui/package.json b/apps/juxtaposition-ui/package.json
index 620fea18..6df13b89 100644
--- a/apps/juxtaposition-ui/package.json
+++ b/apps/juxtaposition-ui/package.json
@@ -25,12 +25,10 @@
"connect-redis": "^9.0.0",
"cookie-parser": "^1.4.7",
"crc": "^4.3.2",
- "express": "^4.22.1",
- "express-async-errors": "^3.1.1",
+ "express": "^5.2.1",
"express-prom-bundle": "^7.0.2",
"express-rate-limit": "^8.2.1",
"express-session": "^1.19.0",
- "express-subdomain": "^1.0.6",
"hashmap": "^2.4.0",
"i18next": "^25.8.13",
"luxon": "^3.7.2",
@@ -67,7 +65,7 @@
"@types/hashmap": "^2.3.4",
"@types/luxon": "^3.7.1",
"@types/method-override": "^3.0.0",
- "@types/node": "^22.19.15",
+ "@types/node": "^24.12.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"browserslist": "^4.28.1",
@@ -82,4 +80,4 @@
"tsup": "^8.5.1",
"typescript": "^5.9.3"
}
-}
+}
\ No newline at end of file
diff --git a/apps/juxtaposition-ui/src/config.ts b/apps/juxtaposition-ui/src/config.ts
index bdfbaedf..2125a45a 100644
--- a/apps/juxtaposition-ui/src/config.ts
+++ b/apps/juxtaposition-ui/src/config.ts
@@ -69,6 +69,11 @@ const schema = z.object({
host: z.string(),
port: z.coerce.number().default(6379)
}),
+ domains: z.object({
+ web: z.hostname().default('juxt.pretendo.network'),
+ ctr: z.hostname().default('ctr.olv.pretendo.cc'),
+ portal: z.hostname().default('portal.olv.pretendo.cc')
+ }).prefault({}),
dmBanner: z.object({
text: z.string().optional(), // Add `content` to insert the url
url: z.url().optional(),
diff --git a/apps/juxtaposition-ui/src/middleware/hostLimit.ts b/apps/juxtaposition-ui/src/middleware/hostLimit.ts
new file mode 100644
index 00000000..604f0be6
--- /dev/null
+++ b/apps/juxtaposition-ui/src/middleware/hostLimit.ts
@@ -0,0 +1,14 @@
+import type express from 'express';
+
+export function restrictHostnames(
+ allowedHostnames: string[],
+ fn: TFn
+): (request: express.Request, response: express.Response, next: () => void) => void | TFn {
+ return (request: express.Request, response: express.Response, next: () => void) => {
+ if (allowedHostnames.includes(request.hostname)) {
+ return fn(request, response, next);
+ }
+
+ return next();
+ };
+}
diff --git a/apps/juxtaposition-ui/src/server.ts b/apps/juxtaposition-ui/src/server.ts
index 921f5d40..f47029fe 100644
--- a/apps/juxtaposition-ui/src/server.ts
+++ b/apps/juxtaposition-ui/src/server.ts
@@ -2,7 +2,6 @@ import express from 'express';
import cookieParser from 'cookie-parser';
import session from 'express-session';
import { RedisStore } from 'connect-redis';
-import 'express-async-errors'; // See package docs
import methodOverride from 'method-override';
import { database } from '@/database';
import { logger } from '@/logger';
diff --git a/apps/juxtaposition-ui/src/services/juxt-web/index.ts b/apps/juxtaposition-ui/src/services/juxt-web/index.ts
index 634da1f0..236e8aeb 100644
--- a/apps/juxtaposition-ui/src/services/juxt-web/index.ts
+++ b/apps/juxtaposition-ui/src/services/juxt-web/index.ts
@@ -1,12 +1,12 @@
import express from 'express';
-import subdomain from 'express-subdomain';
import { webAuth } from '@/middleware/webAuth';
import { consoleAuth } from '@/middleware/consoleAuth';
import { checkBan } from '@/middleware/checkBan';
import { detectVersion } from '@/middleware/detectVersion';
import { checkDiscovery } from '@/middleware/discovery';
-import { logger } from '@/logger';
import { routes } from '@/services/juxt-web/routes';
+import { restrictHostnames } from '@/middleware/hostLimit';
+import { config } from '@/config';
export const router = express.Router();
const consoleRouter = express.Router();
@@ -20,20 +20,8 @@ router.use(routes.ENTRYPOINT);
router.use(checkDiscovery);
// Create subdomains
-logger.info('[JUXT-WEB] Creating \'Web\' subdomain');
-router.use(subdomain('juxt', webRouter));
-router.use(subdomain('juxt-beta', webRouter));
-router.use(subdomain('juxt-dev', webRouter));
-
-logger.info('[JUXT-WEB] Creating \'Wii U\' subdomain');
-router.use(subdomain('portal.olv', consoleRouter));
-router.use(subdomain('portal-beta.olv', consoleRouter));
-router.use(subdomain('portal-dev.olv', consoleRouter));
-
-logger.info('[JUXT-WEB] Creating \'3DS\' subdomain');
-router.use(subdomain('ctr.olv', consoleRouter));
-router.use(subdomain('ctr-beta.olv', consoleRouter));
-router.use(subdomain('ctr-dev.olv', consoleRouter));
+router.use(restrictHostnames([config.domains.web], webRouter));
+router.use(restrictHostnames([config.domains.portal, config.domains.ctr], consoleRouter));
// Setup routes for console
consoleRouter.use(consoleAuth);
diff --git a/apps/miiverse-api/package.json b/apps/miiverse-api/package.json
index 4f4b9b52..fc68d644 100644
--- a/apps/miiverse-api/package.json
+++ b/apps/miiverse-api/package.json
@@ -21,11 +21,9 @@
"@repo/grpc-client": "^0.0.0",
"colors": "^1.4.0",
"crc": "^4.3.2",
- "express": "^4.22.1",
- "express-async-errors": "^3.1.1",
+ "express": "^5.2.1",
"express-prom-bundle": "^7.0.2",
"express-rate-limit": "^8.2.1",
- "express-subdomain": "^1.0.6",
"moment": "^2.24.0",
"mongoose": "^8.23.0",
"multer": "^2.1.1",
diff --git a/apps/miiverse-api/src/config.ts b/apps/miiverse-api/src/config.ts
index 4984df73..fd7a3aa2 100644
--- a/apps/miiverse-api/src/config.ts
+++ b/apps/miiverse-api/src/config.ts
@@ -52,7 +52,11 @@ const schema = z.object({
port: z.coerce.number().default(8125),
apiKey: z.string()
})
- })
+ }),
+ domains: z.object({
+ api: z.hostname().default('api.olv.pretendo.cc'),
+ discovery: z.hostname().default('discovery.olv.pretendo.cc')
+ }).prefault({})
});
export const presets: Record = {
diff --git a/apps/miiverse-api/src/middleware/hostLimit.ts b/apps/miiverse-api/src/middleware/hostLimit.ts
new file mode 100644
index 00000000..604f0be6
--- /dev/null
+++ b/apps/miiverse-api/src/middleware/hostLimit.ts
@@ -0,0 +1,14 @@
+import type express from 'express';
+
+export function restrictHostnames(
+ allowedHostnames: string[],
+ fn: TFn
+): (request: express.Request, response: express.Response, next: () => void) => void | TFn {
+ return (request: express.Request, response: express.Response, next: () => void) => {
+ if (allowedHostnames.includes(request.hostname)) {
+ return fn(request, response, next);
+ }
+
+ return next();
+ };
+}
diff --git a/apps/miiverse-api/src/server.ts b/apps/miiverse-api/src/server.ts
index f9c64e20..e7783a7c 100644
--- a/apps/miiverse-api/src/server.ts
+++ b/apps/miiverse-api/src/server.ts
@@ -1,5 +1,4 @@
import express from 'express';
-import 'express-async-errors'; // See package docs
import expressMetrics from 'express-prom-bundle';
import { connect as connectDatabase } from '@/database';
import { logger } from '@/logger';
diff --git a/apps/miiverse-api/src/services/api/index.ts b/apps/miiverse-api/src/services/api/index.ts
index da0ada28..3905bf4a 100644
--- a/apps/miiverse-api/src/services/api/index.ts
+++ b/apps/miiverse-api/src/services/api/index.ts
@@ -1,7 +1,5 @@
import express from 'express';
-import subdomain from 'express-subdomain';
import { rateLimit } from 'express-rate-limit';
-import { LOG_INFO } from '@/logger';
import postsHandlers from '@/services/api/routes/posts';
import friendMessagesHandlers from '@/services/api/routes/friend_messages';
import communitiesHandlers from '@/services/api/routes/communities';
@@ -9,6 +7,8 @@ import peopleHandlers from '@/services/api/routes/people';
import topicsHandlers from '@/services/api/routes/topics';
import usersHandlers from '@/services/api/routes/users';
import statusHandlers from '@/services/api/routes/status';
+import { restrictHostnames } from '@/middleware/hostLimit';
+import { config } from '@/config';
// Main router for endpointsindex.js
const router = express.Router();
@@ -25,11 +25,7 @@ const limiter = rateLimit({
});
router.use(limiter);
-// Create subdomains
-LOG_INFO('[MIIVERSE] Creating \'api\' subdomain');
-router.use(subdomain('api.olv', api));
-router.use(subdomain('api-test.olv', api));
-router.use(subdomain('api-dev.olv', api));
+router.use(restrictHostnames([config.domains.api], api));
// Setup routes
api.use('/v1/posts', postsHandlers);
diff --git a/apps/miiverse-api/src/services/discovery/index.ts b/apps/miiverse-api/src/services/discovery/index.ts
index c9af7471..f5db02d9 100644
--- a/apps/miiverse-api/src/services/discovery/index.ts
+++ b/apps/miiverse-api/src/services/discovery/index.ts
@@ -1,7 +1,7 @@
import express from 'express';
-import subdomain from 'express-subdomain';
-import { LOG_INFO } from '@/logger';
import discoveryHandlers from '@/services/discovery/routes/discovery';
+import { restrictHostnames } from '@/middleware/hostLimit';
+import { config } from '@/config';
// Main router for endpointsindex.js
const router = express.Router();
@@ -10,10 +10,7 @@ const router = express.Router();
const discovery = express.Router();
// Create subdomains
-LOG_INFO('[MIIVERSE] Creating \'discovery\' subdomain');
-router.use(subdomain('discovery.olv', discovery));
-router.use(subdomain('discovery-test.olv', discovery));
-router.use(subdomain('discovery-dev.olv', discovery));
+router.use(restrictHostnames([config.domains.discovery], discovery));
// Setup routes
discovery.use('/v1/endpoint', discoveryHandlers);
diff --git a/apps/miiverse-api/src/types/express-subdomain.d.ts b/apps/miiverse-api/src/types/express-subdomain.d.ts
deleted file mode 100644
index 3604bfca..00000000
--- a/apps/miiverse-api/src/types/express-subdomain.d.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-// * Credit to https://github.com/bmullan91/express-subdomain/pull/61 for the types!
-
-declare module 'express-subdomain' {
- import type { Request, Response, Router } from 'express';
-
- /**
- * @description The subdomain function.
- * @param subdomain The subdomain to listen on.
- * @param fn The listener function, takes a response and request.
- * @returns A function call to the value passed as FN, or void (the next function).
- */
- export default function subdomain(
- subdomain: string,
- fn: Router
- ): (req: Request, res: Response, next: () => void) => void | typeof fn;
-}
diff --git a/juxtaposition-ui.Dockerfile b/juxtaposition-ui.Dockerfile
index 7a9eebb9..763b64d7 100644
--- a/juxtaposition-ui.Dockerfile
+++ b/juxtaposition-ui.Dockerfile
@@ -2,7 +2,7 @@
ARG app_dir="/home/node/app"
-FROM node:22-alpine
+FROM node:24-alpine
ARG app_dir
WORKDIR ${app_dir}
diff --git a/miiverse-api.Dockerfile b/miiverse-api.Dockerfile
index b119a0d5..3574bc17 100644
--- a/miiverse-api.Dockerfile
+++ b/miiverse-api.Dockerfile
@@ -2,7 +2,7 @@
ARG app_dir="/home/node/app"
-FROM node:22-alpine
+FROM node:24-alpine
ARG app_dir
WORKDIR ${app_dir}
diff --git a/package-lock.json b/package-lock.json
index c7020171..e0daec83 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -25,12 +25,10 @@
"connect-redis": "^9.0.0",
"cookie-parser": "^1.4.7",
"crc": "^4.3.2",
- "express": "^4.22.1",
- "express-async-errors": "^3.1.1",
+ "express": "^5.2.1",
"express-prom-bundle": "^7.0.2",
"express-rate-limit": "^8.2.1",
"express-session": "^1.19.0",
- "express-subdomain": "^1.0.6",
"hashmap": "^2.4.0",
"i18next": "^25.8.13",
"luxon": "^3.7.2",
@@ -67,7 +65,7 @@
"@types/hashmap": "^2.3.4",
"@types/luxon": "^3.7.1",
"@types/method-override": "^3.0.0",
- "@types/node": "^22.19.15",
+ "@types/node": "^24.12.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"browserslist": "^4.28.1",
@@ -83,6 +81,309 @@
"typescript": "^5.9.3"
}
},
+ "apps/juxtaposition-ui/node_modules/@types/node": {
+ "version": "24.12.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz",
+ "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.16.0"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/accepts": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "^3.0.0",
+ "negotiator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/body-parser": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
+ "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^1.0.5",
+ "debug": "^4.4.3",
+ "http-errors": "^2.0.0",
+ "iconv-lite": "^0.7.0",
+ "on-finished": "^2.4.1",
+ "qs": "^6.14.1",
+ "raw-body": "^3.0.1",
+ "type-is": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/content-disposition": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
+ "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/cookie-signature": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.6.0"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/express": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
+ "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "^2.0.0",
+ "body-parser": "^2.2.1",
+ "content-disposition": "^1.0.0",
+ "content-type": "^1.0.5",
+ "cookie": "^0.7.1",
+ "cookie-signature": "^1.2.1",
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "finalhandler": "^2.1.0",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "merge-descriptors": "^2.0.0",
+ "mime-types": "^3.0.0",
+ "on-finished": "^2.4.1",
+ "once": "^1.4.0",
+ "parseurl": "^1.3.3",
+ "proxy-addr": "^2.0.7",
+ "qs": "^6.14.0",
+ "range-parser": "^1.2.1",
+ "router": "^2.2.0",
+ "send": "^1.1.0",
+ "serve-static": "^2.2.0",
+ "statuses": "^2.0.1",
+ "type-is": "^2.0.1",
+ "vary": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/finalhandler": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
+ "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "on-finished": "^2.4.1",
+ "parseurl": "^1.3.3",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/iconv-lite": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
+ "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/media-typer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/merge-descriptors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/mime-types": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
+ "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/negotiator": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/raw-body": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
+ "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "~3.1.2",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.7.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/send": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
+ "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.3",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.1",
+ "mime-types": "^3.0.2",
+ "ms": "^2.1.3",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "statuses": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/serve-static": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
+ "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "parseurl": "^1.3.3",
+ "send": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/type-is": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
+ "license": "MIT",
+ "dependencies": {
+ "content-type": "^1.0.5",
+ "media-typer": "^1.1.0",
+ "mime-types": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "apps/juxtaposition-ui/node_modules/undici-types": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "dev": true,
+ "license": "MIT"
+ },
"apps/miiverse-api": {
"version": "3.0.0",
"license": "AGPL-3.0-only",
@@ -94,11 +395,9 @@
"@repo/grpc-client": "^0.0.0",
"colors": "^1.4.0",
"crc": "^4.3.2",
- "express": "^4.22.1",
- "express-async-errors": "^3.1.1",
+ "express": "^5.2.1",
"express-prom-bundle": "^7.0.2",
"express-rate-limit": "^8.2.1",
- "express-subdomain": "^1.0.6",
"moment": "^2.24.0",
"mongoose": "^8.23.0",
"multer": "^2.1.1",
@@ -133,6 +432,292 @@
"xmlbuilder2": "^4.0.3"
}
},
+ "apps/miiverse-api/node_modules/accepts": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "^3.0.0",
+ "negotiator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "apps/miiverse-api/node_modules/body-parser": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
+ "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^1.0.5",
+ "debug": "^4.4.3",
+ "http-errors": "^2.0.0",
+ "iconv-lite": "^0.7.0",
+ "on-finished": "^2.4.1",
+ "qs": "^6.14.1",
+ "raw-body": "^3.0.1",
+ "type-is": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/miiverse-api/node_modules/content-disposition": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
+ "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/miiverse-api/node_modules/cookie-signature": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.6.0"
+ }
+ },
+ "apps/miiverse-api/node_modules/express": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
+ "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "^2.0.0",
+ "body-parser": "^2.2.1",
+ "content-disposition": "^1.0.0",
+ "content-type": "^1.0.5",
+ "cookie": "^0.7.1",
+ "cookie-signature": "^1.2.1",
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "finalhandler": "^2.1.0",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "merge-descriptors": "^2.0.0",
+ "mime-types": "^3.0.0",
+ "on-finished": "^2.4.1",
+ "once": "^1.4.0",
+ "parseurl": "^1.3.3",
+ "proxy-addr": "^2.0.7",
+ "qs": "^6.14.0",
+ "range-parser": "^1.2.1",
+ "router": "^2.2.0",
+ "send": "^1.1.0",
+ "serve-static": "^2.2.0",
+ "statuses": "^2.0.1",
+ "type-is": "^2.0.1",
+ "vary": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/miiverse-api/node_modules/finalhandler": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
+ "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "on-finished": "^2.4.1",
+ "parseurl": "^1.3.3",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/miiverse-api/node_modules/fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "apps/miiverse-api/node_modules/iconv-lite": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
+ "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/miiverse-api/node_modules/media-typer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "apps/miiverse-api/node_modules/merge-descriptors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "apps/miiverse-api/node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "apps/miiverse-api/node_modules/mime-types": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
+ "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/miiverse-api/node_modules/negotiator": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "apps/miiverse-api/node_modules/raw-body": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
+ "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "~3.1.2",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.7.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "apps/miiverse-api/node_modules/send": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
+ "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.3",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.1",
+ "mime-types": "^3.0.2",
+ "ms": "^2.1.3",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "statuses": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/miiverse-api/node_modules/serve-static": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
+ "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "parseurl": "^1.3.3",
+ "send": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "apps/miiverse-api/node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "apps/miiverse-api/node_modules/type-is": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
+ "license": "MIT",
+ "dependencies": {
+ "content-type": "^1.0.5",
+ "media-typer": "^1.1.0",
+ "mime-types": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/@aws-crypto/crc32": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz",
@@ -2357,6 +2942,7 @@
"resolved": "https://registry.npmjs.org/@redis/client/-/client-5.11.0.tgz",
"integrity": "sha512-GHoprlNQD51Xq2Ztd94HHV94MdFZQ3CVrpA04Fz8MVoHM0B7SlbmPEVIjwTbcv58z8QyjnrOuikS0rWF03k5dQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"cluster-key-slot": "1.1.2"
},
@@ -3533,6 +4119,7 @@
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
+ "peer": true,
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.33",
@@ -3693,6 +4280,7 @@
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"csstype": "^3.2.2"
}
@@ -3836,6 +4424,7 @@
"integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.56.1",
"@typescript-eslint/types": "8.56.1",
@@ -4326,6 +4915,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -4883,6 +5473,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -5971,6 +6562,7 @@
"integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
"hasInstallScript": true,
"license": "MIT",
+ "peer": true,
"bin": {
"esbuild": "bin/esbuild"
},
@@ -6090,6 +6682,7 @@
"integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -6258,6 +6851,7 @@
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.9",
@@ -6588,15 +7182,6 @@
"url": "https://opencollective.com/express"
}
},
- "node_modules/express-async-errors": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz",
- "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==",
- "license": "ISC",
- "peerDependencies": {
- "express": "^4.16.2"
- }
- },
"node_modules/express-prom-bundle": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/express-prom-bundle/-/express-prom-bundle-7.0.2.tgz",
@@ -6637,6 +7222,7 @@
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.19.0.tgz",
"integrity": "sha512-0csaMkGq+vaiZTmSMMGkfdCOabYv192VbytFypcvI0MANrp+4i/7yEkJ0sbAEhycQjntaKGzYfjfXQyVb7BHMA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"cookie": "~0.7.2",
"cookie-signature": "~1.0.7",
@@ -6673,11 +7259,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
- "node_modules/express-subdomain": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/express-subdomain/-/express-subdomain-1.0.6.tgz",
- "integrity": "sha512-A51MvQhk5L3aDV4s5XcKrn5I0bCFOk95xikJjlDWNUrtiAaCjy44RjvBz4uLRH0nCvt8Y3SKt1EvxUUmGJ5QRQ=="
- },
"node_modules/express/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -7562,6 +8143,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.28.4"
},
@@ -7950,6 +8532,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-promise": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
+ "license": "MIT"
+ },
"node_modules/is-regex": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
@@ -10695,6 +11283,7 @@
"version": "15.1.3",
"resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.1.3.tgz",
"integrity": "sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==",
+ "peer": true,
"dependencies": {
"@opentelemetry/api": "^1.4.0",
"tdigest": "^0.1.1"
@@ -10874,6 +11463,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
"integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -11003,6 +11593,7 @@
"resolved": "https://registry.npmjs.org/redis/-/redis-5.11.0.tgz",
"integrity": "sha512-YwXjATVDT+AuxcyfOwZn046aml9jMlQPvU1VXIlLDVAExe0u93aTfPYSeRgG4p9Q/Jlkj+LXJ1XEoFV+j2JKcQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@redis/bloom": "5.11.0",
"@redis/client": "5.11.0",
@@ -11191,6 +11782,32 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/router": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "is-promise": "^4.0.0",
+ "parseurl": "^1.3.3",
+ "path-to-regexp": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/router/node_modules/path-to-regexp": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
+ "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -11660,6 +12277,7 @@
"integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==",
"devOptional": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"ip-address": "^10.0.1",
"smart-buffer": "^4.2.0"
@@ -12756,6 +13374,7 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"license": "Apache-2.0",
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -12884,6 +13503,7 @@
"dev": true,
"hasInstallScript": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"napi-postinstall": "^0.3.0"
},